There's a lot of talk lately about end-to-end encryption, and pressure on companies to remove it from their products. I'm not interested in the rights-and-wrongs of that, but I wondered: how short can code be that would get a company pressured into not using it?
The challenge here is to implement a Diffie Hellman key exchange between two networked systems, then allow the users to communicate back-and-forth using the generated symmetric key. For the purpose of this task, no other protections are required (e.g. no need to cycle the key, verify identities, protect against DoS, etc.) and you can assume an open internet (any ports you listen on are available to everyone). Use of builtins is allowed and encouraged!
You may choose one of two models:
- A server and a client: the client connects to the server, then server or client can send messages to the other. Third-parties in between the two must be unable to read the messages. An example flow could be:
- User A launches server
- User B launches client and directs it to user A's server (e.g. via IP/port), the program opens a connection
- User A's program acknowledges the connection (optionally asking the user for consent first)
- User B's program begins generation of a DH secret, and sends the required data (public key, prime, generator, anything else your implementation needs) to User A
- User A's program uses the sent data to complete generation of the shared secret and sends back the required data (public key) to User B. From this point, User A can enter messages (e.g. via stdin) which will be encrypted and sent to User B (e.g. to stdout).
- User B's program completes generation of the shared secret. From this point, User B can send messages to User A.
- Or: A server with two clients connected to it: each client talks to the server, which forwards their message to the other client. The server itself (and any third-parties in between) must be unable to read the messages. Other than the initial connection, the process is the same as that described in the first option.
- You can provide a single program, or multiple programs (e.g. server & client). Your score is the total code size across all programs.
- Your program must be theoretically capable of communicating over a network (but for testing, localhost is fine). If your language of choice doesn't support networking, you can combine it with something that does (e.g. a shell script); in this case your score is the total code size across all languages used.
- The Diffie Hellman key generation can use hard-coded "p" and "g" values.
- The generated shared key must be at least 1024 bits.
- Once the key is shared, the choice of symmetric-key encryption is up to you, but you must not pick a method which is currently known to have a practical attack against it (e.g. a caesar shift is trivial to reverse without knowledge of the key). Example permitted algorithms:
- AES (any key size)
- RC4 (theoretically broken, but no practical attacks that I can find mention of, so it's allowable here)
- Users A and B must both be able to send messages to each other (two-way communication) interactively (e.g. reading lines from stdin, continually prompting, or events such as pressing a button). If it makes it easier, you may assume an alternating conversation (i.e. after a user sends a message, they must wait for a response before sending their next message)
- Language builtins are permitted (no need to write your own cryptographic or networking methods if they're already supported).
- The underlying communication format is up to you.
- The communication steps given above are an example, but you are not required to follow them (as long as the necessary information is shared, and no middle-men are able to calculate the shared key or messages)
- If the details needed to connect to your server are not known in advance (e.g. if it listens on a random port), these details must be printed. You can assume that the IP address of the machine is known.
- Error handling (e.g. invalid addresses, lost connections, etc.) is not required.
- The challenge is code golf, so the shortest code in bytes wins.