def sqrt_mod_p(p, a): """Give all x, such that x**2=a (mod p), where p is odd prime.""" if legendre_symbol(p, a) == -1: return [] if legendre_symbol(p, a) == 0: return [0] # if legendre_symbol(p, a) == 1: s = 0 while (p - 1) % 2**(s + 1) == 0: s += 1 t = (p - 1) >> s # Finding the biggest 's' such that (2**s) divides p n = random_residue(p, False) # Find a quadratic non-residue 'n' b = mod(p, n, t) # Find b = n**t (mod p) a_inverse = multiplicative_inverse(p, a) x = mod(p, a, (t + 1) >> 1) for k in range(1, s): c = mod(p, a_inverse * x**2, 1 << (s - k - 1)) if (c == 1): j = 0 elif (c == p - 1): j = 1 else: raise Exception("Unexpected error.") x = x * mod(p, b, j << (k - 1)) x %= p return [x, p - x]
def encrypt(cls, message, public_key): b = randint(1, public_key.p - 1) s = mod(public_key.p, public_key.A, b) # Generate the random secret c = mod(public_key.p, message * s) B = mod(public_key.p, public_key.g, b) # Give the receiver hints return ElGamal_cipher(c, B)
def decrypt(cls, cipher, private_key): """Decode cipher text into plain text""" if isinstance(cipher, RSA_cipher) \ and isinstance(private_key, RSA_private_key): return mod(private_key.n, cipher.c, private_key.d); else: raise Exception("Argument type mismatch");
def miller_rabin_test(n, trials=DEFAULT_TRIALS, show_witness=False): """Using Miller-Rabin test, to check (with very high confidence) whether a positive odd integer 'n'(>=3) is prime.""" if (n % 2 == 0 or n == 1): raise Exception("Miller-Rabin test only checks odd integers.") s = 0 while (n - 1) % 2**(s + 1) == 0: s += 1 t = (n - 1) >> s # Finding the biggest 's' such that (2**s) divides n for i in range(trials): witness = randint(1, n - 1) temp = mod(n, witness, t) if (temp % n) == 1: continue possibly_prime = 0 for j in range(s): if (temp % n) == (n - 1): possibly_prime = 1 break temp = (temp**2) % n if not possibly_prime: if show_witness: print("Witness:", witness) return 0 return 1
def generate_keys(cls, digit): p = generate_large_prime(digit) g = randint(1, p - 1) # This needs update a = randint(1, p - 1) A = mod(p, g, a) # Give the sender hints return (ElGamal_public_key(p, g, A), ElGamal_private_key(p, g, a))
def legendre_symbol(p, a): """Compute the Legendre symbol (a/p) where p is an odd prime.""" if (p == 1) or (p % 2 == 0) or (primality.miller_rabin_test(p) == 0): raise Exception("Invalid Legendre symbol") # Check that p is indeed an odd prime result = mod(p, a, (p - 1) >> 1) if result == (p - 1): result = -1 return result
def lucas_lehmer_test(base): """Determines whether (2**base)-1 is Mersenne prime""" modular = (2**base) - 1 for i in range(1, base): if (i == 1): residue = 4 else: residue = mod(modular, (residue**2) - 2) if (residue == 0): return 1 else: return 0
def solovay_strassen_test(n, trials=DEFAULT_TRIALS, show_witness=False): """Using Solovay-Strassen test, to check (with high confidence) whether a positive odd integer 'n'(>=3) is prime.""" if (n % 2 == 0 or n == 1): raise Exception("Solovay Strassen test only checks odd integers.") for i in range(trials): witness = randint(1, n - 1) j_s = quadratic_residue.jacobi_symbol(n, witness) if (j_s == 0 or j_s % n != mod(n, witness, (n - 1) >> 1)): if show_witness: print("Witness:", witness) return 0 return 1
def fermat_test(n, trials=DEFAULT_TRIALS, show_witness=False): """Using Fermet test, to check (with certain confidence) whether a positive integer 'n'(>=3) is prime. Carmichael numbers, which are composites satisfying the korselt criterion, can fool this algorithm.""" for i in range(trials): while True: witness = randint(2, n - 1) if gcd(n, witness) == 1: break if (mod(n, witness, n - 1) != 1): if show_witness: print("Witness:", witness) return 0 return 1
def encrypt(cls, message, public_key): """Encode plain text into cipher text""" if isinstance(public_key, RSA_public_key): return RSA_cipher(mod(public_key.n, message, public_key.e)); else: raise Exception("Argument type mismatch");
def decrypt(cls, cipher, private_key): s = mod(private_key.p, cipher.B, private_key.a) # Derive the shared secret inverse = multiplicative_inverse(private_key.p, s) return mod(private_key.p, cipher.c * inverse)