diff --git a/14-simpleexchange/client.py b/14-simpleexchange/client.py
new file mode 100644
index 0000000000000000000000000000000000000000..d74d60705ebc1f344acc65db109c59cb54e8c274
--- /dev/null
+++ b/14-simpleexchange/client.py
@@ -0,0 +1,45 @@
+#!/usr/bin/env python3
+import os
+import os.path
+import binascii
+import struct
+import hashlib
+import nclib
+
+from Crypto.Cipher import AES
+from Crypto.Util import Counter
+from Crypto import Random
+
+nc = nclib.Netcat(('workshop.faust.ninja', 4241))
+#nc = nclib.Netcat(('localhost', 4241))
+
+GROUP = 28397751449611216856386152638704604893488016313021502645659640564689451285800984155346815239241212742250655876089753350891224226779660824735763769557687726166165224298016395911925566755062763818543701251112002337015420084071010338008840472534822459206106749211685814760944931574993226097212282111892063291339967344156771005250401211439632092364480222950969327623561587999071614346278120140894679593229940805561670584035225683287173673586166594382681326751471027116669859298597550318710320232871945120064041229923641516885877410465715453160092930760459475437352839750812216596284639932989271762184684269796196987536123
+GENERATOR = 2
+
+my_secret = int(binascii.hexlify(Random.get_random_bytes(32)), 16)
+gy = pow(GENERATOR, my_secret, GROUP)
+
+print("Sending")
+print(b"%i\n" % gy)
+nc.sendall(b"%i\n" % gy)
+
+print("Receiving")
+result = nc.recv(1024).strip()
+gx = result
+gx = int(gx, 16)
+print(gx)
+
+gxy = pow(gx, my_secret, GROUP)
+key = hashlib.sha256(b"%x" % gxy).digest()
+
+response = binascii.unhexlify(nc.recv().strip())
+iv = response[:12]
+cipher = response[12:]
+print(iv)
+print(cipher)
+
+
+print("key")
+print(gxy)
+aesthing = AES.new(key, AES.MODE_CTR, counter=Counter.new(32, prefix=iv))
+print(aesthing.decrypt(cipher))
diff --git a/14-simpleexchange/dhexchange.py b/14-simpleexchange/dhexchange.py
new file mode 100644
index 0000000000000000000000000000000000000000..4fabe598091564b72575086c897af1e3ba1f5db0
--- /dev/null
+++ b/14-simpleexchange/dhexchange.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python3
+
+import socketserver
+from socket import AF_INET6
+import os
+import os.path
+import binascii
+import struct
+import hashlib
+
+from Crypto.Cipher import AES
+from Crypto.Util import Counter
+from Crypto import Random
+
+GROUP = 28397751449611216856386152638704604893488016313021502645659640564689451285800984155346815239241212742250655876089753350891224226779660824735763769557687726166165224298016395911925566755062763818543701251112002337015420084071010338008840472534822459206106749211685814760944931574993226097212282111892063291339967344156771005250401211439632092364480222950969327623561587999071614346278120140894679593229940805561670584035225683287173673586166594382681326751471027116669859298597550318710320232871945120064041229923641516885877410465715453160092930760459475437352839750812216596284639932989271762184684269796196987536123
+GENERATOR = 2
+
+class ThreadedTCPServer(socketserver.ThreadingMixIn, socketserver.TCPServer):
+    def __init__(self, *args):
+        self.address_family = AF_INET6
+        self.allow_reuse_address = True
+        socketserver.TCPServer.__init__(self, *args)
+
+
+    def server_activate(self):
+        socketserver.TCPServer.server_activate(self)
+        try:
+            import systemd.daemon
+            systemd.daemon.notify('READY=1')
+        except ImportError:
+            pass
+
+
+os.chdir(os.path.dirname(__file__))
+
+with open('flag.txt', 'rb') as flagfd:
+    flag = flagfd.read()
+
+
+class MyTCPHandler(socketserver.BaseRequestHandler):
+    def _key_exchange(self):
+
+        gy_bytes = self.request.recv(1024).strip()
+        print(gy_bytes)
+        gy = int(gy_bytes)
+        print("got gy")
+
+        ephermal_secret = int(binascii.hexlify(Random.get_random_bytes(32)), 16)
+        gx = pow(GENERATOR, ephermal_secret, GROUP)
+        print("gx")
+        print(gx)
+        self.request.sendall(b"%x\n" % gx)
+
+        gxy = pow(gy, ephermal_secret, GROUP)
+        print("gxy")
+        print(gxy)
+        return hashlib.sha256(b"%x" % gxy).digest()
+
+
+    def handle(self):
+        print("handle")
+        key = self._key_exchange()
+        iv = Random.get_random_bytes(12)
+        cipher = AES.new(key, AES.MODE_CTR, counter=Counter.new(32, prefix=iv))
+        self.request.sendall(binascii.hexlify(iv + cipher.encrypt(b'Your flag today is %s' % flag)) + b"\n")
+
+
+
+if __name__ == "__main__":
+    HOST, PORT = "::", 4241
+
+    # Create the server
+    server = ThreadedTCPServer((HOST, PORT), MyTCPHandler)
+    # Activate the server; this will keep running until you
+    # interrupt the program with Ctrl-C
+    server.serve_forever()
diff --git a/14-simpleexchange/flag.txt b/14-simpleexchange/flag.txt
new file mode 100644
index 0000000000000000000000000000000000000000..97b095b6deb2bf815347a3b9a1666fe81acac839
--- /dev/null
+++ b/14-simpleexchange/flag.txt
@@ -0,0 +1 @@
+flag{123}