def public_keygen(self, E=None, P=None, private_key=None, output_type="x only"): if E is not None: self.E = E if P is not None: if isinstance(P, int): y2 = (fast_power(P, 3, self.E.modulus) + (P * self.E.A) + self.E.B) % self.E.modulus y = mod_sqrt(y2, self.E.modulus)[0] self.P = (P, mod_sqrt(y, self.E.modulus)[0]) self.P = P if private_key is not None: self.private_key = private_key if None in [self.E, self.P, self.private_key]: return None self.QA = self.E.multiply(self.P, self.private_key) if output_type == self.style[0]: return self.QA elif output_type == self.style[1]: return self.QA[0] else: print("invalid type") return None
def encrypt(self, plain_text, QB, E=None, P=None, output_type="x only"): if E is not None: self.E = E if P is not None: if isinstance(P, int): y2 = (fast_power(P, 3, self.E.modulus) + (P * self.E.A) + self.E.B) % self.E.modulus y = mod_sqrt(y2, self.E.modulus)[0] self.P = (P, mod_sqrt(y, self.E.modulus)[0]) self.P = P if QB is not None: if isinstance(QB, int): y2 = (fast_power(QB, 3, self.E.modulus) + (QB * self.E.A) + self.E.B) % self.E.modulus y = mod_sqrt(y2, self.E.modulus)[0] QB = (QB, mod_sqrt(y, self.E.modulus)[0]) M = self.E.msg_to_point(plain_text) k = random.randint(1, self.E.modulus) C1 = self.E.multiply(k, P) C2 = self.E.add(M, E.multiply(k, QB)) if output_type == self.style[0]: return (C1, C2) elif output_type == self.style[1]: return (C1[0], C2[0]) else: print("Invalid type") return None
def __init__(self, E, P): self.E = E self.style = ["whole point", "x only"] if isinstance(P, int): y2 = (fast_power(P, 3, self.E.modulus) + (P * self.E.A) + self.E.B) % self.E.modulus y = mod_sqrt(y2, self.E.modulus)[0] self.P = (P, mod_sqrt(y, self.E.modulus)[0]) self.P = P
def test_mod_sqrt_5(self): # Test where there is no sqrt m = 3623 a = 88 expected_x = (None, None) x = mod_sqrt(a, m) self.assertEqual(expected_x, x)
def test_mod_sqrt_3(self): #test with prime 3 mod 8, where there is a sqrt for a m = 563 orig_x = 109 a = (orig_x * orig_x) % m x = mod_sqrt(a, m) self.assertIn(orig_x, x)
def test_mod_sqrt_4(self): #test with prime 7 mod 8, where there is a sqrt for a m = 719 orig_x = 230 a = (orig_x * orig_x) % m x = mod_sqrt(a, m) self.assertIn(orig_x, x)
def is_point_on_curve(self, P): y2 = self.calculate_y2(P[0]) y = mod_sqrt(y2, self.modulus) if y is not (None, None): if y[0] == P[1] or y[1] == P[1]: return True return False
def calculate_point(self, x): y2 = self.calculate_y2(x) y = mod_sqrt(y2) if y is (None, None): return None else: return [(x, y[0]), (x, y[1])]
def decrypt(self, c1, c2, QA=None): if QA is not None: self.QA = QA if isinstance(c1, int): y2 = (fast_power(c1, 3, self.E.modulus) + (c1 * self.E.A) + self.E.B) % self.E.modulus y = mod_sqrt(y2, self.E.modulus)[0] c1 = (c1, y) if isinstance(c2, int): y2 = (fast_power(c2, 3, self.E.modulus) + (c2 * self.E.A) + self.E.B) % self.E.modulus y = mod_sqrt(y2, self.E.modulus)[0] c2 = (c2, y) param2 = self.E.multiply(self.private_key, c1) param2[1] = -param2[1] return self.E.point_to_msg(self.E.add(c2, param2))
def test_mod_sqrt_1(self): print("\n\nRunning test for src module: mod_sqrt") # test with prime 1 mod 8, where there is a sqrt for a m = 977 orig_x = 745 a = (orig_x * orig_x) % m x = mod_sqrt(a, m) self.assertIn(orig_x, x)
def test_mod_sqrt_2(self): # Bulk test with all the primes under 1000 orig_x = None primes = small_primes_generator(1000) del primes[0] for m in primes: for i in range(1, m): orig_x = i a = (orig_x * orig_x) % m x = mod_sqrt(a, m) self.assertIn(orig_x, x)
def symmetric_keygen(self, QB, private_key=None, output_type="x only"): if private_key is not None: self.private_key = private_key if QB is not None: self.QB = QB if None in [self.E, self.private_key]: return None if isinstance(self.QB, int): y2 = (fast_power(self.QB, 3, self.E.modulus) + (self.QB * self.E.A) + self.E.B) % self.E.modulus y = mod_sqrt(y2, self.E.modulus)[0] self.QB = (self.QB, y) print("QB:") print(QB) sym_point = self.E.multiply(self.QB, self.private_key) sym_key = sym_point[0] if output_type == self.style[0]: return sym_point elif output_type == self.style[1]: return sym_key else: print("invalid output type") return None