def test_multiply_by_number(self): ec = EllipticCurve('A') a = ec.get_forming() for k in [-1233535, 1231, 0, -1, 1, 1231341]: self.assertTrue(ec.is_on_curve(ec.multiply_by_number(a, k))) mul = ec.multiply_by_number self.assertEqual(mul(mul(a, 10), 10), mul(a, 100)) self.assertEqual(mul(mul(a, 2), -3), mul(a, -6)) self.assertEqual(mul(mul(a, -4), 7), mul(a, -28)) self.assertEqual(ec.summ(mul(a, 123), mul(a, -122)), mul(a, 1)) ec = EllipticCurve('test') point = Point(3, 6) n_s = range(7) rights = [ Point(0, 1, 0), Point(3, 6), Point(80, 10), Point(80, 87), Point(3, 91), Point(0, 1, 0), Point(3, 6) ] for n, right in zip(n_s, rights): print(right) print(ec.multiply_by_number(point, n)) self.assertEqual(ec.multiply_by_number(point, n), right)
def test_double(self): ec = EllipticCurve("test") point = Point(3, 6) ref = Point(80, 10) result = ec.double(point) print(result) print(ref) self.assertTrue(result == ref)
def test_summ(self): ec = EllipticCurve("test") point_a = Point(17, 10) point_b = Point(95, 31) ref = Point(1, 54) result = ec.summ(point_a, point_b) self.assertTrue(result == ref) point_a = Point(80, 10) point_b = Point(80, 87) ref = Point(0, 1, 0) self.assertEqual(ec.summ(point_a, point_b), ref) ec = EllipticCurve('A') a = ec.get_forming() self.assertEqual(ec.summ(a, ec.get_zero()), a)
def create_curve(self): """ :return: random Elliptic curve and init Point """ for i in range(10): try: self.X = self._generate_random_number() self.Y = self._generate_random_number() self.A = self._generate_random_number() self.B = f_mod((self.Y * self.Y - self.X * self.X * self.X - self.A * self.X), self.N) curve = EllipticCurve(self.N, self.A, self.B) return curve except Exception as e: print("Error when curve is generated %s" % str(e)) raise Exception
return Ideal(self.curve) m = ((y_2 - y_1) / mod_inverse((x_2 - x_1), self.mod)) % self.mod self.x = (m ** 2 - x_2 - x_1) % self.mod self.y = (m * (self.x - x_1) + y_1) % self.mod class Ideal: def __init__(self, curve): self.curve = curve def __str__(self): return "Ideal" def __neg__(self): return self def __add__(self, other): return other curve = EllipticCurve(-2, 4) P = Point(curve, 3, 5, 6) A = Point(curve, -2, 0, 6) print(P) P + A print(P)
def test_bsgs(): curve = EllipticCurve(10177, 1, -1, 10331, (1, 1)) priv_key = bsgs(curve) print('calculated key:', priv_key, 'actual key:', curve._d, 'is equal:', priv_key == curve._d)
from elliptic_curve import EllipticCurve from point import Point from ideal import Ideal from lenstra import Lenstra c = EllipticCurve(P=17, A=200,B=-137) # test addition p = Point(curve=c, X=47,Y=125) pp = Point(curve=c, X=1, Y=9) l = Lenstra(221) l.curve = c l.point = p print(l.partial_addition(p,pp))
import copy from elliptic_curve import EllipticCurve from helpers import plot from point import Point C = EllipticCurve(a=-2, b=4) print(C) # case where P + Q + r = 0 ( tree points on curve) P = Point(C, 3, 5) P_copy = copy.copy(P) Q = Point(C, -2, 0) U = P+Q print(U) plot(C, P_copy, Q, U) # case where P + P + 0 = 0 (only one point on curve) P = Point(C, -2, 0) P_copy = copy.copy(P) Q = Point(C, -2, 0) U = P+Q print(U) plot(C, P_copy, Q, U) # case where P + Q + 0 = 0 (vertical line) P = Point(C, 0, 2) P_copy = copy.copy(P) Q = Point(C, 0, -2) U = P+Q print(U)
def atkin_morain(n): """ Atkin-Morain ECPP Algorithm. Args: n: Probable Prime Returns: Certificate of primality, or False. """ if n < arbitrary_bound: if prime.trialDivision(n): return [n] else: return False d = 0 m_found = False while m_found is False: try: d, ms = choose_discriminant(n, d) except ValueError: return False for m in ms: factors = factor_orders(m, n) if factors is not None: k, q = factors params = curve_parameters(d, n) try: # Test to see if the order of the curve is really m a, b = params.pop() ec = EllipticCurve(a, b, n) while not test_order(ec, m): a, b = params.pop() ec = EllipticCurve(a, b, n) #print n, a, b m_found = True break except IndexError: pass # if no proper m can be found. Go back to choose_discriminant() ''' If this step fails need to return false. ''' try: # operate on point while True: P = choose_point(ec) U = ec.mul(k, P) # U = [m/q]P if U != 0: break V = ec.mul(q, U) except (ZeroDivisionError, ValueError): return False if V != 0: return False else: if q > arbitrary_bound: cert = atkin_morain(q) if cert: cert.insert(0, (q, m, a, b)) return cert else: if prime.trialDivision(q): return [q] else: return False
return self.point * private_key def encrypt(self, data_point, public_key, random_number): """ Encrypt the msg """ return self.point * random_number, data_point + public_key * random_number def decrypt(self, data_point_pair, private_key): """ Decrypt the msg """ return data_point_pair[1] + -(data_point_pair[0] * private_key) # Example of encrypting and decrypting by D.H's algo if __name__ == "__main__": # Elliptic curve initilization base_point = EllipticCurve(3, 345, 19).point_at(8) # Algo D.H. intitializing and private/public keys are created dh = AlgoDH(base_point) priv_key = random.randint(1, 100) pub_key = dh.get_public_key(priv_key) # Data is encrypted/decrypted by D.H. algorithm data = base_point * 2 encrypted = dh.encrypt(data, pub_key, random.randint(1, 100)) decrypted = dh.decrypt(encrypted, priv_key) print('Is Valid? ', decrypted == data)
import rsa_keys from elliptic_curve import EllipticCurve from ec_dsa import ECDSA from sha1 import SHA1 from diffie_hellman import DiffieHellman from rsa_dsa import RSADSA # RSA DSA keys = rsa_keys.generate_rsa_keys(256) rsa_dsa = RSADSA(keys['n']) sign = rsa_dsa.sign(SHA1, 'ARTYOM', keys['d']) print(rsa_dsa.verify(SHA1, sign, keys['e'])) curve = EllipticCurve(67) # Diffie-Hellman dh = DiffieHellman(curve, curve.points[3]) a_private = 7 a_public = dh.gen_public(a_private) b_private = 13 b_public = dh.gen_public(b_private) secret = dh.gen_secret(a_private, b_public) print(dh.gen_secret(a_private, b_public) == dh.gen_secret(b_private, a_public)) # EC DSA point = curve.prime_order_point()
def test_correctness_of_parameters(self): ec = EllipticCurve('A') self.assertTrue(ec.is_on_curve(ec.get_forming())) ec = EllipticCurve('B') self.assertTrue(ec.is_on_curve(ec.get_forming()))
if MultiplyCurvePoint(E, P, n) == identity(E) ] L.sort(key=lambda P: ec_point_coords(E, P)) l = len(L) M = [[''] * (l + 1) for _ in xrange(l + 1)] for i, P in enumerate(L): if P != identity(E): M[0][i + 1] = M[i + 1][0] = '(%s, %s)' % (str(x(P)), str(y(P))) else: M[0][i + 1] = M[i + 1][0] = 'identity' for j, Q in enumerate(L): w = WeilPairing(E, n, P, Q) M[i + 1][j + 1] = str(w) W = [0] * (l + 1) for i in xrange(l + 1): for j in xrange(l + 1): W[j] = max(W[j], len(M[i][j])) for i in xrange(l + 1): for j in xrange(l + 1): p = W[j] - len(M[i][j]) print ' ' * ((p + 1) // 2) + M[i][j] + ' ' * (p // 2), print print example(EllipticCurve(FiniteField(13), 0, 5), 4) example(EllipticCurve(FiniteField(13), 7, 0), 6) example(EllipticCurve(FiniteField(17), 16, 0), 2) example(EllipticCurve(FiniteField(19), 0, 16), 9) example(EllipticCurve(FiniteField(19), 3, 12), 6)
from utils import EllipticCurveException, logger # Elliptic curve parameters A = -0x3 B = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B FP = 0xFFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF # Starting point (generator) S = Point( x=0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296, y=0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5, ) if __name__ == '__main__': # Get eliptic curve EC ec = EllipticCurve(a=A, b=B, fp=FP) logger.info('Elliptic curve: EC = {}'.format(ec)) logger.info('Staring point: S = {}'.format(S)) if len(argv) != 2: raise EllipticCurveException('Invalid input') # Get public key PK PK = Point.from_string(argv[1]) logger.info('Public key: PK = {}'.format(PK)) # Check whether starting point S is on the elliptic curve EC if ec.is_on_curve(S): logger.info('S is on the Elliptic curve') else: raise EllipticCurveException('S is not on the Elliptic curve')
def secp256k1_demo(): # secp256k1 domain parameters # The proven prime Pcurve = 2**256 - 2**32 - 2**9 - 2**8 - 2**7 - 2**6 - 2**4 - 1 # These two defines the elliptic curve. y^2 = x^3 + Acurve * x + Bcurve Acurve = 0 Bcurve = 7 # Generator point Gx = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798 Gy = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8 point_generator = (int(Gx), int(Gy)) # Number of points in the field (order of the field) N = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 ec_curve = EllipticCurve(Pcurve, Acurve, Bcurve, Gx, Gy, N) # int("hex_string" ,16) # Replace with any private key (randomly generated) priv_key = 0x5712f72ca98165625fe652f1911e7e5795a86d56e724f7cd4bf3375c5fcc26b8 print("The private key: 0x{:064x}".format(priv_key)) print("The private key: {}".format(hex(priv_key))) print(f"The private key: 0x{priv_key:064x}") print("\r\n\r\n******* ECDLP Public Key Generation *********") point_public_key = ec_curve.EC_multiply(point_generator, priv_key) print( f"The public key: (x = 0x{point_public_key[0]:064x}, y = {point_public_key[1]:064x})" ) print("\r\n\r\n*****ECDSA Vulnerability Demo*****") raw_int_1_to_sign = string_to_int( "\xC8\xDB\x87>t\xC4\xC8\r\x1E\xF7c\xDC@]\xDB\xCF\xE8%\x89\xB1\xDE?\x87:C1\x02F?Xl|" ) raw_int_2_to_sign = string_to_int( "\x9B$j^KA\xF2\xB32\xE0\xD3\n43|\xF4\xEFL\xDB\tV\xAF\xCB\xD6dB\x90}\xD9\x05\xC6\x0F" ) ecdsa_sign_1_r = 21505829891763648114329055987619236494102133314575206970830385799158076338148 ecdsa_sign_2_r = 21505829891763648114329055987619236494102133314575206970830385799158076338148 ecdsa_sign_1_s = 29982806498908468698285880421449377990633260409100070838917643476964059158422 ecdsa_sign_2_s = 2688866553165465396487518855200337458372728620912733016156314344402296269120 if ecdsa_sign_1_r == ecdsa_sign_2_r: print("Signature with same r -> VULNERABLE") # Use same r vulnerability to get private key k = ((raw_int_1_to_sign - raw_int_2_to_sign) % ec_curve.n_curve) * \ modulo_inv(ecdsa_sign_1_s - ecdsa_sign_2_s, ec_curve.n_curve) k = k % ec_curve.n_curve cracked_priv_key = ( ((((ecdsa_sign_1_s * k) % ec_curve.n_curve) - raw_int_1_to_sign) % ec_curve.n_curve) * modulo_inv(ecdsa_sign_1_r, ec_curve.n_curve)) % ec_curve.n_curve print(f"The cracked private key: 0x{cracked_priv_key:064x}") # should be 0x5712f72ca98165625fe652f1911e7e5795a86d56e724f7cd4bf3375c5fcc26b8 print(f"\r\n\r\nUsing the cracked private key to sign") raw_int_3_to_sign = string_to_int(hashlib.sha256(b"admin").digest()) r, s = ec_curve.ecdsa_sign(cracked_priv_key, raw_int_3_to_sign, k) print(f"ECDSA signature for 0x{raw_int_3_to_sign:064x}: ") print(f"(r = 0x{r:064x}, s=0x{s:064x})") # r should be: 0x2f8bde4d1a07209355b4a7250a5c5128e88b84bddc619ab7cba8d569b240efe4 # s should be: 0x9c99411b74e3bc2d6ffc3b86530dc3e135402567104c146aeb4581772e518a9c print("\r\n\r\nVerifying ECDSA signature") public_key_point = ec_curve.EC_multiply(ec_curve.point_generator, cracked_priv_key) signature_verify_result = ec_curve.ecdsa_verify(public_key_point, raw_int_3_to_sign, (r, s)) print(f"Signature: (r = 0x{r:064x}, s=0x{s:064x})") print(f"Raw int to sign: 0x{raw_int_3_to_sign:064x}") print(f"Verifying result: {signature_verify_result}")