Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Naive Diffie-Hellman implementation
# Based on https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
require "prime"
require "openssl"
class Client
def initialize
@private_key = rand(1..100000)
@clients = {}
end
def generate_public_key(public_base, public_modulus)
(public_base ** private_key) % public_modulus
end
def generate_shared_secret(client, public_base, public_modulus)
client_public_key = client.generate_public_key(public_base, public_modulus)
clients[client] = (client_public_key ** private_key) % public_modulus
end
def send_message(recipient, message)
encrypted = encrypt_message_for(recipient, message)
recipient.receive_message(self, encrypted)
end
def receive_message(sender, encrypted_message)
puts decrypt_message_from(sender, encrypted_message)
end
private
attr_reader :private_key, :shared_secret_key, :clients
def encrypt_message_for(recipient, message)
shared_secret_key = clients[recipient]
raise "Unable to send message" if shared_secret_key.nil?
cipher = new_cipher.encrypt
cipher.key = cipher_key(shared_secret_key)
cipher.update(message) + cipher.final
end
def decrypt_message_from(sender, encrypted_message)
shared_secret_key = clients[sender]
raise "Unable to receive message" if shared_secret_key.nil?
cipher = new_cipher.decrypt
cipher.key = cipher_key(shared_secret_key)
cipher.update(encrypted_message) + cipher.final
end
def cipher_key(shared_secret_key)
Digest::SHA256.hexdigest(shared_secret_key.to_s)[0..31]
end
def new_cipher
OpenSSL::Cipher.new("AES-256-CBC")
end
end
class DiffieHellman
def initialize(client_a, client_b)
@public_base = random_prime
@public_modulus = random_prime
@client_a = client_a
@client_b = client_b
end
def exchange
client_a.generate_shared_secret(client_b, public_base, public_modulus)
client_b.generate_shared_secret(client_a, public_base, public_modulus)
end
private
attr_reader :public_base, :public_modulus, :client_a, :client_b
def random_prime
Prime.first(10000).sample
end
end
alice = Client.new
bob = Client.new
DiffieHellman.new(alice, bob).exchange
alice.send_message(bob, "Hello there")
bob.send_message(alice, "Back atcha")
carol = Client.new
DiffieHellman.new(alice, carol).exchange
carol.send_message(alice, "Hi Alice")
alice.send_message(carol, "Hi Carol")
bob.send_message(carol, "This won't work'")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment