def gen_dsa_params(): # FIPS L,N (1024,160), (2048,224), (2048,256), (3072,256) # choose L, multiple of 64 between 512-1024, 2048, 3072 l = 1024 # n must be less than or equal to length of hash n = SHA1_BIT_LENGTH # choose n bit prime q q = gen_seq_prime(start=pow(2, n) + pow(2, random.randint(8, 16))) # choose l bit prime p such that p-1 is multiple of q i = pow(2, l) + pow(2, random.randint(8, 16)) while True: p = q * i if is_prime(p + 1): break i += 1 p += 1 assert (is_prime(p)) assert ((p - 1) % q == 0) # chose smallest int g such that g^q = 1 mod p h = 1 x = (p - 1) / q while h < p - 1: g = modexp(h, x, p) h += 1 if g == 1: continue elif modexp(g, q, p) != 1: continue else: break return (p, q, g)
def miller_rabin_test(n): # if its even, why bother? if n % 2 == 0: return False if n in [2, 3, 5, 7, 11, 13, 17]: return True # n - 1 = 2^s * d s = 0 d = n - 1 while d % 2 == 0: d >>= 1 s += 1 # logging.debug("n: {n}".format(n=n)) # logging.debug("d: {d}".format(d=d)) # logging.debug("s: {s}".format(s=s)) a = random.randrange(2, n - 2) x = modexp(a, d, n) # needs to be +1, or -1 for first gen if x in [1, n - 1]: return True for i in xrange(s): x = modexp(x, 2, n) if x == 1: return False # needs to be -1 for rest of tests elif x == n - 1: return True return False
def dsa_verify(pkey, sig, msg): p, q, g, key = pkey r, s = sig if r < 0 or r > q: return False if s < 0 or s > q: return False w = inverse_modulo(s, q) h = int(hashlib.sha1(msg).hexdigest(), 16) u1 = (h * w) % q u2 = (r * w) % q # (A*B) Mod C == (A Mod C * B Mod C ) Mod C part1 = modexp(g, u1, p) part2 = modexp(key, u2, p) v = ((part1 * part2) % p) % q logging.debug("v: {}".format(v)) logging.debug("r: {}".format(r)) return v == r
def fermat_test(n): # if its even, why bother? if n <= 3 or n % 2 == 0: return False a = random.randint(2, n - 2) r = modexp(a, n - 1, n) if r != 1: return False return True
def dsa_sign(pkey, msg, fixedk=0): p, q, g, key = pkey r = 0 k = 0 s = 0 while s == 0: if fixedk: k = fixedk r = modexp(g, fixedk, p) % q else: while r == 0: k = random.randint(1, q) r = modexp(g, k, p) % q h = hashlib.sha1(msg).digest() h = str2int16(h) np1 = inverse_modulo(k, q) np2 = (h + r * key) % q s = (np1 * np2) % q return (r, s, k)
def dsa_sign_insecure(pkey, msg): p, q, g, key = pkey r = 0 k = 0 s = 0 while s == 0: while r == 0: k = random.randint(1, pow(2, 16)) r = modexp(g, k, p) % q h = hashlib.sha1(msg).digest() h = str2int16(h) np1 = inverse_modulo(k, q) np2 = (h + r * key) % q s = (np1 * np2) % q return (r, s, k)
def gen_user_keys(p, q, g): x = random.randint(0, q) y = modexp(g, x, p) priv_key = (p, q, g, x) pub_key = (p, q, g, y) return [pub_key, priv_key]
def simple_rsa(m, keypair): k, n = keypair return modexp(m, k, n)