# copied from last time
# will be useful for key exhange
def exp_mod(a,e,b):
"""Return a^e % b, computed using repeated squaring."""
bin_rep=bin(e) # first find binary representation of e
prod = 1
cur_pow_two = a # this will run through a^(2^0), a^(2^1), a^(2^2),...
for i in range(len(bin_rep)-2):
if bin_rep[-1-i]=='1':
prod = prod * cur_pow_two % b # multiply by cur_pow_two if the corresponding bit is 1
cur_pow_two = (cur_pow_two)^2 % b
return prod
# runtime (for fixed a,b) is approx number of bits of e
# exp_mod is very fast
exp_mod(3, 2^1000,11)
# Diffie-Helmann algorithm for key exchange
p = next_prime(2^200); p # Alice, Bob agree on p
#Alice chooses e
e = randint((p+1)/2,p); e
# Bob chooses d
d = randint((p+1)/2,p); d
# Alice computes 3^e mod p
alice_to_bob = exp_mod(3,e,p)
# sends to Bob; Eve also sees
# Bob computes 3^d mod p
bob_to_alice = exp_mod(3,d,p)
# sends to Alice; Eve also sees
# Alice knows p,e,bob_to_alice
# She computes the shared secret:
exp_mod(bob_to_alice,e,p)
# Bob knows p,d,alice_to_bob
# He computes the shared secret:
exp_mod(alice_to_bob,d,p)
# both compute the same number
# can use as key in a symmetric key system
# Eve sees p, alice_to_bob, bob_to_alice
# To compute shared secret, she would need
# to solve a discret log problem to find d or e
# Doing this is very hard (not practically feasible)