Skip to content

Instantly share code, notes, and snippets.

@tylerkerr
Created March 1, 2016 23:05
Show Gist options
  • Save tylerkerr/369de9cbfb434f5bbfa8 to your computer and use it in GitHub Desktop.
Save tylerkerr/369de9cbfb434f5bbfa8 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# toy diffie-hellman key exchange.
from random import SystemRandom
p = 0x00964738809dbecd4bcb9ba1d18de0f5a6fbd595383c2dbe460f8dfd6dea62d2a6bca4016806c788e89872e888137d767030c72a17ac7d6cc33e5b44a9c17ad32412656ac0770829412b502dc6010545cc26043b55bbccf7946de94c0a4c1c0386a255d9101a235e0427aefb003cc7a6e64c0860349fc6e220fc7fef110a60ad727e6af317cefbeab4216e0f76dadb816cfdf2cd90549340dc7eef977a7c3133f854088b0390a4d55d6244bc2f8f532401f6d224379b475fd1e30e4de0e52fba9273b742773dcea2c427804d3273d2f2cbcfb4d5deeb80c05282563a37777cabb4c0de696f41f622f6e59b613925ba6ec21b5b380d42f36aa6997fb6f4efcc5b4b
print("safe prime p = %s" % format(p, 'x')) # p is a 2048 bit safe prime - "safe" meaning (p-1)/2 is also prime
g = 2
print("generator g = %s" % g) # 2 is a generator of the group of order p
# g and p are the "parameters", and are provided by the server (public knowledge).
a = SystemRandom().randrange(pow(2, 256))
print("random secret a = %s" % format(a, 'x')) # alice picks a random 256-bit secret "a"
b = SystemRandom().randrange(pow(2, 256))
print("random secret b = %s" % format(b, 'x')) # bob picks a random 256-bit secret "b"
ga = pow(g, a, p)
print("\ng ^ a mod p = %s" % format(ga, 'x')) # alice calculates g ^ a mod p and sends this in the clear to bob
gb = pow(g, b, p)
print("g ^ b mod p = %s" % format(gb, 'x')) # bob calculates g ^ b mod p and sends this in the clear to alice
alicepremaster = pow(gb, a, p)
print("\nalice derives premaster secret via (g^b)^a mod p: %s" % format(alicepremaster, 'x')) # alice derives g^ab mod p via (g^b)^a mod p
bobpremaster = pow(ga, b, p)
print("bob derives premaster secret via (g^a)^b mod p: %s" % format(bobpremaster, 'x')) # bob derives g^ab mod p via (g^a)^b mod p
assert alicepremaster == bobpremaster # these premaster secrets will be identical, but deriving them from what was sent over the wire (g, p, g^a, g^b) is an intractable problem
print("\nsecrets match, and can be used to derive a session key for symmetric encryption")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment