Path: blob/master/Elliptic-Curves/ellipticcurve.py
1402 views
#!/usr/bin/env python2.712# Reference: https://bitcointalk.org/index.php?topic=23241.034# Class for declaring an Elliptic Curve of the form y^2 = x^3 + ax + b (mod p)5class CurveFp( object ):6def __init__( self, p, a, b ):7"""8Declaring values of parameters `a`, `b`, `p` in the Elliptic Curve- y^2 = x^3 + ax + b (mod p)9"""10self.__p = p11self.__a = a12self.__b = b1314def p( self ):15return self.__p1617def a( self ):18return self.__a1920def b( self ):21return self.__b2223def contains_point( self, x, y ):24"""25To check whether a point (x, y) lies on the Elliptic Curve y^2 = x^3 + ax + b (mod p):26verify if y^2 - (x^3 + ax + b) is a multiple of p,27return True if the condition holds true,28return False if it doesn't29"""30return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 03132# Testing code for CurveFp Class33def testCurveFp():34p = 89953523493328636138979614835438769105803101293517644103178299545319142490503L35a = 8995352349332863613897961483543876910580310129351764410317829954531914249050036b = 2828529654571490383490288446715818921735472825062947047903230960310294240463937objtest = CurveFp(p, a, b)3839Gx = 0x337ef2115b4595fbd60e2ffb5ee6409463609e0e5a6611b105443e02cb82edd8L40Gy = 0x1879b8d7a68a550f58166f0d6b4e86a0873d7b709e28ee318ddadd4ccf505e1aL4142Qx = 0x2a40fd522f73dc9f7c40b2420e39e62c5742ff2f11805a1577ed7f60153a0be1L43Qy = 0x3085e99246006b71b4211eff47ff3efc0f93103ee7379dc3bcc6decdc46073a3L4445Rx = 0xbd0a442367bdc24cb09c49404e3d307ba99122e7b78e14f0d84870d0df97aa59L46Ry = 0x22c88612db6b6af6f196cd815fc5f57fe871d3b6588b0c7a59e06cc759d736b2L47assert objtest.contains_point(Gx, Gy) == True48assert objtest.contains_point(Qx, Qy) == True49assert objtest.contains_point(Rx, Ry) == True5051class Point( object ):52def __init__( self, curve, x, y, order = None ):53self.__curve = curve54self.__x = x55self.__y = y56self.__order = order57if self.__curve:58assert self.__curve.contains_point( x, y )59if order:60assert self * order == INFINITY6162def __add__( self, other ):63if other == INFINITY: return self64if self == INFINITY: return other65assert self.__curve == other.__curve66if self.__x == other.__x:67if ( self.__y + other.__y ) % self.__curve.p() == 0:68return INFINITY69else:70return self.double()7172p = self.__curve.p()73l = ( ( other.__y - self.__y ) * inverse_mod( other.__x - self.__x, p ) ) % p74x3 = ( l * l - self.__x - other.__x ) % p75y3 = ( l * ( self.__x - x3 ) - self.__y ) % p76return Point( self.__curve, x3, y3 )7778def __mul__( self, other ):79def leftmost_bit( x ):80assert x > 081result = 1L82while result <= x: result = 2 * result83return result / 28485e = other86if self.__order: e = e % self.__order87if e == 0: return INFINITY88if self == INFINITY: return INFINITY89assert e > 090e3 = 3 * e91negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )92i = leftmost_bit( e3 ) / 293result = self94while i > 1:95result = result.double()96if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self97if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self98i = i / 299return result100101def __rmul__( self, other ):102return self * other103104def __str__( self ):105if self == INFINITY: return "infinity"106return "(%d,%d)" % ( self.__x, self.__y )107108def double( self ):109if self == INFINITY:110return INFINITY111112p = self.__curve.p()113a = self.__curve.a()114l = ( ( 3 * self.__x * self.__x + a ) * inverse_mod( 2 * self.__y, p ) ) % p115x3 = ( l * l - 2 * self.__x ) % p116y3 = ( l * ( self.__x - x3 ) - self.__y ) % p117return Point( self.__curve, x3, y3 )118119def x( self ):120return self.__x121122def y( self ):123return self.__y124125def curve( self ):126return self.__curve127128def order( self ):129return self.__order130131INFINITY = Point( None, None, None )132133def inverse_mod( a, m ):134if a < 0 or m <= a: a = a % m135c, d = a, m136uc, vc, ud, vd = 1, 0, 0, 1137while c != 0:138q, c, d = divmod( d, c ) + ( c, )139uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc140assert d == 1141if ud > 0: return ud142else: return ud + m143144145