# copied from last time
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
# Digital signatures using RSA
# Setup stage for RSA. Alice generats public, private keys
p = next_prime(2^100 + randint(1,10000)); p
q = next_prime(2^100 + randint(1,10000)); q
n = p*q
e = 17; gcd(e,(p-1)*(q-1)) # check that e, (p-1)(q-1) are relatively prime
# Alice's public key
public_key = (e,n)
# Now Alice computes her private key
# want d to be inverse of e mod (p-1)(q-1)
xgcd(e, (p-1)*(q-1))
d = xgcd(e, (p-1)*(q-1))[1]% ((p-1)*(q-1))
d
private_key = d
# Alice has message M, wants to sign and send to Bob; make sure to pad with random digits
M = 12340083712397197237
def RSA_encrypt(m, (e,n)):
"""Computes RSA encryption of m with public-key (e,n)"""
return exp_mod(m,e,n)
def RSA_decrypt(c, d, (e,n)):
"""Computes RSA decryption of c with private-key d, public-key (e,n)
and public-key (e,n)"""
return exp_mod(c,d,n)
# checking encryption and decryption
RSA_decrypt(RSA_encrypt(M, (e,n)), d, (e,n))
# Now to digitally sign M, Alice decrypts with RSA, using her private key
signature = RSA_decrypt(M, d, (e,n)); signature
# to verify the signature, Bob encrypts with RSA, using Alice's
# public key
# checks whether this equals the original message
RSA_encrypt(signature, (e,n))
# Hash functions
import hashlib # python library that contains hash functions
# Hash function SHA
hexhash = hashlib.sha224("12dsf lsdfjge").hexdigest(); hexhash
# outputs a hexadecimal (base 16) string
hexhash = hashlib.sha224("03dsf lsdfjge").hexdigest(); hexhash
# changing the input string a little dramatically changes hash
int(hexhash,16) #convert hexadecimal string to an integer
# Hashing a longer message; hash value will still have the same length
m = "WASHINGTON — Democratic leaders are planning to put a resolution condemning anti-Semitism and bigotry on the House floor for a vote on Thursday, hoping to put to rest the internal uproar that erupted after Representative Ilhan Omar indinuated that backers of Israel exhibit dual loyalty."
m
len(bin(int(hashlib.sha224(m).hexdigest(),16))) #length in bits
# key property of hash function: hard to find two different messages with same hash