Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ashutosh1206
GitHub Repository: ashutosh1206/crypton
Path: blob/master/Identification/Ephemeral-Key-Auth/Challenges/EC-Auth/ecauth.py
1403 views
1
#!/usr/bin/env python2.7
2
3
# Class for declaring an Elliptic Curve of the form y^2 = x^3 + ax + b (mod p)
4
class CurveFp( object ):
5
def __init__( self, p, a, b ):
6
"""
7
Declaring values of parameters `a`, `b`, `p` in the Elliptic Curve- y^2 = x^3 + ax + b (mod p)
8
"""
9
self.__p = p
10
self.__a = a
11
self.__b = b
12
13
def p( self ):
14
return self.__p
15
16
def a( self ):
17
return self.__a
18
19
def b( self ):
20
return self.__b
21
22
def contains_point( self, x, y ):
23
"""
24
To check whether a point (x, y) lies on the Elliptic Curve y^2 = x^3 + ax + b (mod p):
25
verify if y^2 - (x^3 + ax + b) is a multiple of p,
26
return True if the condition holds true,
27
return False if it doesn't
28
"""
29
return ( y * y - ( x * x * x + self.__a * x + self.__b ) ) % self.__p == 0
30
31
# Testing code for CurveFp Class
32
def testCurveFp():
33
p = 89953523493328636138979614835438769105803101293517644103178299545319142490503L
34
a = 89953523493328636138979614835438769105803101293517644103178299545319142490500
35
b = 28285296545714903834902884467158189217354728250629470479032309603102942404639
36
objtest = CurveFp(p, a, b)
37
38
Gx = 0x337ef2115b4595fbd60e2ffb5ee6409463609e0e5a6611b105443e02cb82edd8L
39
Gy = 0x1879b8d7a68a550f58166f0d6b4e86a0873d7b709e28ee318ddadd4ccf505e1aL
40
41
Qx = 0x2a40fd522f73dc9f7c40b2420e39e62c5742ff2f11805a1577ed7f60153a0be1L
42
Qy = 0x3085e99246006b71b4211eff47ff3efc0f93103ee7379dc3bcc6decdc46073a3L
43
44
Rx = 0xbd0a442367bdc24cb09c49404e3d307ba99122e7b78e14f0d84870d0df97aa59L
45
Ry = 0x22c88612db6b6af6f196cd815fc5f57fe871d3b6588b0c7a59e06cc759d736b2L
46
assert objtest.contains_point(Gx, Gy) == True
47
assert objtest.contains_point(Qx, Qy) == True
48
assert objtest.contains_point(Rx, Ry) == True
49
50
class Point( object ):
51
def __init__( self, curve, x, y, order = None ):
52
self.__curve = curve
53
self.__x = x
54
self.__y = y
55
self.__order = order
56
if self.__curve:
57
assert self.__curve.contains_point( x, y )
58
if order:
59
assert self * order == INFINITY
60
61
def __add__( self, other ):
62
if other == INFINITY: return self
63
if self == INFINITY: return other
64
assert self.__curve == other.__curve
65
if self.__x == other.__x:
66
if ( self.__y + other.__y ) % self.__curve.p() == 0:
67
return INFINITY
68
else:
69
return self.double()
70
71
p = self.__curve.p()
72
l = ( ( other.__y - self.__y ) * inverse_mod( other.__x - self.__x, p ) ) % p
73
x3 = ( l * l - self.__x - other.__x ) % p
74
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
75
return Point( self.__curve, x3, y3 )
76
77
def __mul__( self, other ):
78
def leftmost_bit( x ):
79
assert x > 0
80
result = 1L
81
while result <= x: result = 2 * result
82
return result / 2
83
84
e = other
85
if self.__order: e = e % self.__order
86
if e == 0: return INFINITY
87
if self == INFINITY: return INFINITY
88
assert e > 0
89
e3 = 3 * e
90
negative_self = Point( self.__curve, self.__x, -self.__y, self.__order )
91
i = leftmost_bit( e3 ) / 2
92
result = self
93
while i > 1:
94
result = result.double()
95
if ( e3 & i ) != 0 and ( e & i ) == 0: result = result + self
96
if ( e3 & i ) == 0 and ( e & i ) != 0: result = result + negative_self
97
i = i / 2
98
return result
99
100
def __rmul__( self, other ):
101
return self * other
102
103
def __str__( self ):
104
if self == INFINITY: return "infinity"
105
return "(%d,%d)" % ( self.__x, self.__y )
106
107
def double( self ):
108
if self == INFINITY:
109
return INFINITY
110
111
p = self.__curve.p()
112
a = self.__curve.a()
113
l = ( ( 3 * self.__x * self.__x + a ) * inverse_mod( 2 * self.__y, p ) ) % p
114
x3 = ( l * l - 2 * self.__x ) % p
115
y3 = ( l * ( self.__x - x3 ) - self.__y ) % p
116
return Point( self.__curve, x3, y3 )
117
118
def x( self ):
119
return self.__x
120
121
def y( self ):
122
return self.__y
123
124
def curve( self ):
125
return self.__curve
126
127
def order( self ):
128
return self.__order
129
130
INFINITY = Point( None, None, None )
131
132
def inverse_mod( a, m ):
133
if a < 0 or m <= a: a = a % m
134
c, d = a, m
135
uc, vc, ud, vd = 1, 0, 0, 1
136
while c != 0:
137
q, c, d = divmod( d, c ) + ( c, )
138
uc, vc, ud, vd = ud - q*uc, vd - q*vc, uc, vc
139
assert d == 1
140
if ud > 0: return ud
141
else: return ud + m
142
143
class Handshake(object):
144
def __init__(self, Q, R, s):
145
self.Q = Q
146
self.R = R
147
self.s = s
148
149
class Public_key(object):
150
def __init__(self, generator):
151
self.generator = generator
152
self.curve = generator.curve()
153
n = generator.order()
154
if not n:
155
raise RuntimeError("Generator must have order")
156
if not n * generator == INFINITY:
157
raise RuntimeError("Generator point order is bad")
158
if generator.x() < 0 or n <= generator.x() or generator.y() < 0 or n <= generator.y():
159
raise RuntimeError("Generator point has x or y out of range")
160
161
def check(self, point):
162
k = self.generator.order()
163
if not k:
164
raise RuntimeError("Generator must have order")
165
if not k * point == INFINITY:
166
raise RuntimeError("Generator point order is bad")
167
if point.x() < 0 or k <= point.x() or point.y() < 0 or k <= point.y():
168
raise RuntimeError("Generator point has x or y out of range")
169
170
def _verify(self, handshake):
171
P = self.generator
172
Q = handshake.Q
173
R = handshake.R
174
s = handshake.s
175
try:
176
self.check(Q)
177
self.check(R)
178
except:
179
return False
180
if (s*P).x() == (Q+R).x() and (s*P).y() == (Q+R).y():
181
return True
182
else:
183
return False
184
185
class Private_key(object):
186
def __init__(self, public_key, x):
187
self.public_key = public_key
188
self.privkey = x
189
190
def _sign(self, r):
191
P = self.public_key.generator
192
Q = self.privkey * P
193
R = r * P
194
s = self.privkey + r
195
return Handshake(Q, R, s)
196
197