Path: blob/master/Identification/Ephemeral-Key-Auth/Challenges/EC-Auth/ecauth.py
1403 views
#!/usr/bin/env python2.712# Class for declaring an Elliptic Curve of the form y^2 = x^3 + ax + b (mod p)3class CurveFp( object ):4def __init__( self, p, a, b ):5"""6Declaring values of parameters `a`, `b`, `p` in the Elliptic Curve- y^2 = x^3 + ax + b (mod p)7"""8self.__p = p9self.__a = a10self.__b = b1112def p( self ):13return self.__p1415def a( self ):16return self.__a1718def b( self ):19return self.__b2021def contains_point( self, x, y ):22"""23To check whether a point (x, y) lies on the Elliptic Curve y^2 = x^3 + ax + b (mod p):24verify if y^2 - (x^3 + ax + b) is a multiple of p,25return True if the condition holds true,26return False if it doesn't27"""28return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 02930# Testing code for CurveFp Class31def testCurveFp():32p = 89953523493328636138979614835438769105803101293517644103178299545319142490503L33a = 8995352349332863613897961483543876910580310129351764410317829954531914249050034b = 2828529654571490383490288446715818921735472825062947047903230960310294240463935objtest = CurveFp(p, a, b)3637Gx = 0x337ef2115b4595fbd60e2ffb5ee6409463609e0e5a6611b105443e02cb82edd8L38Gy = 0x1879b8d7a68a550f58166f0d6b4e86a0873d7b709e28ee318ddadd4ccf505e1aL3940Qx = 0x2a40fd522f73dc9f7c40b2420e39e62c5742ff2f11805a1577ed7f60153a0be1L41Qy = 0x3085e99246006b71b4211eff47ff3efc0f93103ee7379dc3bcc6decdc46073a3L4243Rx = 0xbd0a442367bdc24cb09c49404e3d307ba99122e7b78e14f0d84870d0df97aa59L44Ry = 0x22c88612db6b6af6f196cd815fc5f57fe871d3b6588b0c7a59e06cc759d736b2L45assert objtest.contains_point(Gx, Gy) == True46assert objtest.contains_point(Qx, Qy) == True47assert objtest.contains_point(Rx, Ry) == True4849class Point( object ):50def __init__( self, curve, x, y, order = None ):51self.__curve = curve52self.__x = x53self.__y = y54self.__order = order55if self.__curve:56assert self.__curve.contains_point( x, y )57if order:58assert self * order == INFINITY5960def __add__( self, other ):61if other == INFINITY: return self62if self == INFINITY: return other63assert self.__curve == other.__curve64if self.__x == other.__x:65if ( self.__y + other.__y ) % self.__curve.p() == 0:66return INFINITY67else:68return self.double()6970p = self.__curve.p()71l = ( ( other.__y - self.__y ) * inverse_mod( other.__x - self.__x, p ) ) % p72x3 = ( l * l - self.__x - other.__x ) % p73y3 = ( l * ( self.__x - x3 ) - self.__y ) % p74return Point( self.__curve, x3, y3 )7576def __mul__( self, other ):77def leftmost_bit( x ):78assert x > 079result = 1L80while result <= x: result = 2 * result81return result / 28283e = other84if self.__order: e = e % self.__order85if e == 0: return INFINITY86if self == INFINITY: return INFINITY87assert e > 088e3 = 3 * e89negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )90i = leftmost_bit( e3 ) / 291result = self92while i > 1:93result = result.double()94if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self95if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self96i = i / 297return result9899def __rmul__( self, other ):100return self * other101102def __str__( self ):103if self == INFINITY: return "infinity"104return "(%d,%d)" % ( self.__x, self.__y )105106def double( self ):107if self == INFINITY:108return INFINITY109110p = self.__curve.p()111a = self.__curve.a()112l = ( ( 3 * self.__x * self.__x + a ) * inverse_mod( 2 * self.__y, p ) ) % p113x3 = ( l * l - 2 * self.__x ) % p114y3 = ( l * ( self.__x - x3 ) - self.__y ) % p115return Point( self.__curve, x3, y3 )116117def x( self ):118return self.__x119120def y( self ):121return self.__y122123def curve( self ):124return self.__curve125126def order( self ):127return self.__order128129INFINITY = Point( None, None, None )130131def inverse_mod( a, m ):132if a < 0 or m <= a: a = a % m133c, d = a, m134uc, vc, ud, vd = 1, 0, 0, 1135while c != 0:136q, c, d = divmod( d, c ) + ( c, )137uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc138assert d == 1139if ud > 0: return ud140else: return ud + m141142class Handshake(object):143def __init__(self, Q, R, s):144self.Q = Q145self.R = R146self.s = s147148class Public_key(object):149def __init__(self, generator):150self.generator = generator151self.curve = generator.curve()152n = generator.order()153if not n:154raise RuntimeError("Generator must have order")155if not n * generator == INFINITY:156raise RuntimeError("Generator point order is bad")157if generator.x() < 0 or n <= generator.x() or generator.y() < 0 or n <= generator.y():158raise RuntimeError("Generator point has x or y out of range")159160def check(self, point):161k = self.generator.order()162if not k:163raise RuntimeError("Generator must have order")164if not k * point == INFINITY:165raise RuntimeError("Generator point order is bad")166if point.x() < 0 or k <= point.x() or point.y() < 0 or k <= point.y():167raise RuntimeError("Generator point has x or y out of range")168169def _verify(self, handshake):170P = self.generator171Q = handshake.Q172R = handshake.R173s = handshake.s174try:175self.check(Q)176self.check(R)177except:178return False179if (s*P).x() == (Q+R).x() and (s*P).y() == (Q+R).y():180return True181else:182return False183184class Private_key(object):185def __init__(self, public_key, x):186self.public_key = public_key187self.privkey = x188189def _sign(self, r):190P = self.public_key.generator191Q = self.privkey * P192R = r * P193s = self.privkey + r194return Handshake(Q, R, s)195196197