def _init_parameters(self, bits): p, q = self._init_primes(bits) totient = (p - 1) * (q - 1) self.n = p * q self.modexp = ModularExp(self.n) self.e = self._choose_e_from(totient) self.d = ModularInverse(totient).value(self.e) self.public_key = (self.e, self.n)
class DSA(DigitalSignatureScheme): # Based on Wikipedia pseudocode. def __init__(self, hash_function=SHA256, parameters=None): DigitalSignatureScheme.__init__(self) self.hash_function = hash_function() self._init_params_from(parameters) self.modexp_p = ModularExp(self.p) self._init_keys() def _init_params_from(self, parameters): if parameters is None: self.p, self.q, self.g = DSAParameterGenerator().generate() else: self.p, self.q, self.g = parameters def _init_keys(self): self.x = random.randint(1, self.q-1) self.y = self.modexp_p.value(self.g, self.x) self.public_key = (self.p, self.q, self.g, self.y) def sign(self, message): h = self.hash_function.int_hash(message) while True: k = random.randint(1, self.q-1) r = self.modexp_p.value(self.g, k) % self.q if r == 0: continue k_inv = ModularInverse(self.q).value(k) s = k_inv*(h + self.x*r) % self.q if s != 0: break return r, s def verify(self, message, signature): r, s = signature if (r <= 0 or r >= self.q) or (s <= 0 or s >= self.q): return False h = self.hash_function.int_hash(message) w = ModularInverse(self.q).value(s) u1 = (h*w) % self.q u2 = (r*w) % self.q g_u1 = self.modexp_p.value(self.g, u1) y_u2 = self.modexp_p.value(self.y, u2) v_mod_p = (g_u1*y_u2) % self.p v = v_mod_p % self.q return r == v
def _choose_g_from(self, p, q): h = self.DEFAULT_H while True: g = ModularExp(p).value(h, (p-1)/q) if g != 1: break return g
def _init_parameters(self, bits): p, q = self._init_primes(bits) totient = (p-1)*(q-1) self.n = p*q self.modexp = ModularExp(self.n) self.e = self._choose_e_from(totient) self.d = ModularInverse(totient).value(self.e) self.public_key = (self.e, self.n)
def value(self, dsa): # z should be chosen s.t. it has modular inverse mod q. # Any integer < q is coprime with q (since q is prime). # Thus, any integer will have inverse. z = 11 p, q, _, y = dsa.get_public_key() r = ModularExp(p).value(y, z) % q z_inv = ModularInverse(q).value(z) s = (r * z_inv) % q return r, s
class DiffieHellman(object): MAX_INT = 2**64 - 1 def __init__(self, p, g): self.p = p self.g = g self.modexp = ModularExp(self.p) self.exp = self._choose_secret_exponent() self.public_key = self._compute_public_key() def _choose_secret_exponent(self): return random.randint(1, self.MAX_INT) def _compute_public_key(self): return self.modexp.value(self.g, self.exp) def get_public_key(self): return self.public_key def get_secret_from(self, key): return self.modexp.value(key, self.exp)
class RSA(PublicKeyCipher): DEFAULT_E = 65537 DEFAULT_BITS = 2048 def __init__(self, bits=None): PublicKeyCipher.__init__(self) bits = bits if bits is not None else self.DEFAULT_BITS self._init_parameters(bits) def _init_primes(self, bits): prime_generator = RandPrime() bitsize = 1 + bits / 2 if bits % 2 else bits / 2 p = prime_generator.value(n=bitsize) q = prime_generator.value(n=bitsize) return p, q def _init_parameters(self, bits): p, q = self._init_primes(bits) totient = (p - 1) * (q - 1) self.n = p * q self.modexp = ModularExp(self.n) self.e = self._choose_e_from(totient) self.d = ModularInverse(totient).value(self.e) self.public_key = (self.e, self.n) def _choose_e_from(self, totient): # Choose 1 < e < totient s.t. e and totient are coprime. e = self.DEFAULT_E gcd = GCD() while gcd.value(e, totient) != 1: e += 2 return e def _encrypt(self, int_plaintext): return self._exp_with(int_plaintext, self.e) def _decrypt(self, int_ciphertext): return self._exp_with(int_ciphertext, self.d) def _exp_with(self, integer, exponent): return self.modexp.value(integer, exponent)
class RSA(PublicKeyCipher): DEFAULT_E = 65537 DEFAULT_BITS = 2048 def __init__(self, bits=None): PublicKeyCipher.__init__(self) bits = bits if bits is not None else self.DEFAULT_BITS self._init_parameters(bits) def _init_primes(self, bits): prime_generator = RandPrime() bitsize = 1+bits/2 if bits%2 else bits/2 p = prime_generator.value(n=bitsize) q = prime_generator.value(n=bitsize) return p, q def _init_parameters(self, bits): p, q = self._init_primes(bits) totient = (p-1)*(q-1) self.n = p*q self.modexp = ModularExp(self.n) self.e = self._choose_e_from(totient) self.d = ModularInverse(totient).value(self.e) self.public_key = (self.e, self.n) def _choose_e_from(self, totient): # Choose 1 < e < totient s.t. e and totient are coprime. e = self.DEFAULT_E gcd = GCD() while gcd.value(e, totient) != 1: e += 2 return e def _encrypt(self, int_plaintext): return self._exp_with(int_plaintext, self.e) def _decrypt(self, int_ciphertext): return self._exp_with(int_ciphertext, self.d) def _exp_with(self, integer, exponent): return self.modexp.value(integer, exponent)
def __init__(self, hash_function=SHA256, parameters=None): DigitalSignatureScheme.__init__(self) self.hash_function = hash_function() self._init_params_from(parameters) self.modexp_p = ModularExp(self.p) self._init_keys()
def _get_r_from(self, k): return ModularExp(self.p).value(self.g, k) % self.q
def __init__(self, email, password): self.email = email self.password = password self.sha256 = SHA256() self.modexp = ModularExp(self.p) self._init_state()
def __init__(self, p, g): self.p = p self.g = g self.modexp = ModularExp(self.p) self.exp = self._choose_secret_exponent() self.public_key = self._compute_public_key()
def _encrypt(self, m): return ModularExp(self.n).value(m, self.e)