def mod_sqrt(a, modulus): root1 = None root2 = None if legendre_symbol(a, modulus) != 1: root1 = None root2 = None elif modulus % 2 == 0: # Non-prime modulus's are not supported print("Not a prime") root1 = None root2 = None elif modulus % 8 == 1 or modulus % 8 == 5: s = 0 m = None n = modulus - 1 while n % 2 == 0: n = n / 2 s += 1 m = n e = s z = random.randint(1, modulus - 1) while legendre_symbol(z, modulus) != -1: # z is a non-quadratic residue z = random.randint(1, modulus - 1) c = fast_power(z, m, modulus) x = fast_power(a, (m + 1) / 2, modulus) t = fast_power(a, m, modulus) while t != 1: i = 1 for i in range(1, e): if fast_power(t, 2**i, modulus) == 1: break b = fast_power(c, 2**(e - i - 1), modulus) x = (b * x) % modulus t = (t * b * b) % modulus c = (b * b) % modulus e = i root1 = x root2 = modulus - x elif modulus % 8 == 3 or modulus % 8 == 7: x = fast_power(a, (modulus + 1) / 4, modulus) root1 = x root2 = (-x) % modulus return (root1, root2)
def test_legendre_symbol_7(self): p = 269 a = 0 expected = 0 self.assertEqual(legendre_symbol(a, p), expected)
def test_legendre_symbol_6(self): p = 269 a = 248 expected = 1 self.assertEqual(legendre_symbol(a, p), expected)
def test_legendre_symbol_4(self): p = 97 a = 72 expected = 1 self.assertEqual(legendre_symbol(a, p), expected)
def test_legendre_symbol_3(self): p = 97 a = 5 expected = -1 self.assertEqual(legendre_symbol(a, p), expected)
def test_legendre_symbol_2(self): p = 83 a = 7 expected = 1 self.assertEqual(legendre_symbol(a, p), expected)
def test_legendre_symbol_1(self): print("\n\nRunning test for src module: legendre_symbol") p = 83 a = 80 expected = -1 self.assertEqual(legendre_symbol(a, p), expected)