Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ashutosh1206
GitHub Repository: ashutosh1206/crypton
Path: blob/master/Elliptic-Curves/ellipticcurve.py
1402 views
1
#!/usr/bin/env python2.7
2
3
# Reference: https://bitcointalk.org/index.php?topic=23241.0
4
5
# Class for declaring an Elliptic Curve of the form y^2 = x^3 + ax + b (mod p)
6
class CurveFp( object ):
7
def __init__( self, p, a, b ):
8
"""
9
Declaring values of parameters `a`, `b`, `p` in the Elliptic Curve- y^2 = x^3 + ax + b (mod p)
10
"""
11
self.__p = p
12
self.__a = a
13
self.__b = b
14
15
def p( self ):
16
return self.__p
17
18
def a( self ):
19
return self.__a
20
21
def b( self ):
22
return self.__b
23
24
def contains_point( self, x, y ):
25
"""
26
To check whether a point (x, y) lies on the Elliptic Curve y^2 = x^3 + ax + b (mod p):
27
verify if y^2 - (x^3 + ax + b) is a multiple of p,
28
return True if the condition holds true,
29
return False if it doesn't
30
"""
31
return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
32
33
# Testing code for CurveFp Class
34
def testCurveFp():
35
p = 89953523493328636138979614835438769105803101293517644103178299545319142490503L
36
a = 89953523493328636138979614835438769105803101293517644103178299545319142490500
37
b = 28285296545714903834902884467158189217354728250629470479032309603102942404639
38
objtest = CurveFp(p, a, b)
39
40
Gx = 0x337ef2115b4595fbd60e2ffb5ee6409463609e0e5a6611b105443e02cb82edd8L
41
Gy = 0x1879b8d7a68a550f58166f0d6b4e86a0873d7b709e28ee318ddadd4ccf505e1aL
42
43
Qx = 0x2a40fd522f73dc9f7c40b2420e39e62c5742ff2f11805a1577ed7f60153a0be1L
44
Qy = 0x3085e99246006b71b4211eff47ff3efc0f93103ee7379dc3bcc6decdc46073a3L
45
46
Rx = 0xbd0a442367bdc24cb09c49404e3d307ba99122e7b78e14f0d84870d0df97aa59L
47
Ry = 0x22c88612db6b6af6f196cd815fc5f57fe871d3b6588b0c7a59e06cc759d736b2L
48
assert objtest.contains_point(Gx, Gy) == True
49
assert objtest.contains_point(Qx, Qy) == True
50
assert objtest.contains_point(Rx, Ry) == True
51
52
class Point( object ):
53
def __init__( self, curve, x, y, order = None ):
54
self.__curve = curve
55
self.__x = x
56
self.__y = y
57
self.__order = order
58
if self.__curve:
59
assert self.__curve.contains_point( x, y )
60
if order:
61
assert self * order == INFINITY
62
63
def __add__( self, other ):
64
if other == INFINITY: return self
65
if self == INFINITY: return other
66
assert self.__curve == other.__curve
67
if self.__x == other.__x:
68
if ( self.__y + other.__y ) % self.__curve.p() == 0:
69
return INFINITY
70
else:
71
return self.double()
72
73
p = self.__curve.p()
74
l = ( ( other.__y - self.__y ) * inverse_mod( other.__x - self.__x, p ) ) % p
75
x3 = ( l * l - self.__x - other.__x ) % p
76
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
77
return Point( self.__curve, x3, y3 )
78
79
def __mul__( self, other ):
80
def leftmost_bit( x ):
81
assert x > 0
82
result = 1L
83
while result <= x: result = 2 * result
84
return result / 2
85
86
e = other
87
if self.__order: e = e % self.__order
88
if e == 0: return INFINITY
89
if self == INFINITY: return INFINITY
90
assert e > 0
91
e3 = 3 * e
92
negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
93
i = leftmost_bit( e3 ) / 2
94
result = self
95
while i > 1:
96
result = result.double()
97
if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
98
if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
99
i = i / 2
100
return result
101
102
def __rmul__( self, other ):
103
return self * other
104
105
def __str__( self ):
106
if self == INFINITY: return "infinity"
107
return "(%d,%d)" % ( self.__x, self.__y )
108
109
def double( self ):
110
if self == INFINITY:
111
return INFINITY
112
113
p = self.__curve.p()
114
a = self.__curve.a()
115
l = ( ( 3 * self.__x * self.__x + a ) * inverse_mod( 2 * self.__y, p ) ) % p
116
x3 = ( l * l - 2 * self.__x ) % p
117
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
118
return Point( self.__curve, x3, y3 )
119
120
def x( self ):
121
return self.__x
122
123
def y( self ):
124
return self.__y
125
126
def curve( self ):
127
return self.__curve
128
129
def order( self ):
130
return self.__order
131
132
INFINITY = Point( None, None, None )
133
134
def inverse_mod( a, m ):
135
if a < 0 or m <= a: a = a % m
136
c, d = a, m
137
uc, vc, ud, vd = 1, 0, 0, 1
138
while c != 0:
139
q, c, d = divmod( d, c ) + ( c, )
140
uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
141
assert d == 1
142
if ud > 0: return ud
143
else: return ud + m
144
145