Created
January 31, 2014 14:41
-
-
Save rdm/8733290 to your computer and use it in GitHub Desktop.
Buggy transliteration of https://github.com/warner/python-ecdsa/blob/master/ecdsa/ellipticcurve.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
cocurrent 'CurveFp' | |
Help=: 'Elliptic Curve over the field of integers modulo a prime.' | |
create=:3 :0 | |
NB. The curve of points satisfying y^2 = x^3 + a*x + b (mod p). | |
'P A B'=: x:&> y | |
poly=: B,A,0,1 | |
) | |
p=:3 :'P' | |
a=:3 :'A' | |
b=:3 :'B' | |
containsPoint=:4 :0 | |
0 = P|(0 0 1 p. y) - poly p. x | |
) | |
cocurrent 'Point' | |
Help=:'A point on an elliptic curve' | |
create=:3 :0 | |
This=: coname'' | |
'Curve X Y Order'=: args=. 4{.y,<'' assert. (#y) e. 3 4 | |
ORDERED=: -. '' -: 3 {:: args | |
if.#Curve do. | |
NB. assert. X containsPoint__Curve Y | |
end. | |
if. ORDERED do. | |
assert. infinite mul__This Order | |
end. | |
) | |
infinite=:3 :0 | |
(''-:Curve__y)*.(''-:X__y)*.''-:Y__y | |
) | |
invmod=: 4 : 0 | |
NB. inverse of y mod x (x|y) | |
NB. uc vc ud vd d c where d c init as x y | |
NB. q =. d<.@%c -- (4&{ <.@%~ {:) | |
a=. imw^:_ ] 1x,0x,0x,1x,x,y | |
if. 1~: 4{a do. 0 return. end. | |
if.0< 2{ a do. 2{ a else. x+2{a end. | |
) | |
imw =: ((2&{ - {. * 4&{ <.@% {:),(3&{ - 1&{ * 4&{ <.@% {:), 2&{., ({: | 4&{) ,~{:)^:(0 ~: {:) | |
eq=:3 :0 | |
if. #cy=. Curve__y do. | |
if.-.#Curve do. 0 return. end. | |
if. A__Curve ~: A__cy do. 0 return. end. | |
if. B__Curve ~: B__cy do. 0 return. end. | |
if. P__Curve ~: P__cy do. 0 return. end. | |
else. if. #Curve do. 0 return. end. | |
end. | |
(xy'')-: xy__y'' | |
) | |
add=:3 :0 | |
NB. add another point to this point | |
if. infinite y do. This return. end. NB. infinity is the new zero | |
if. infinite This do. y return. end. | |
assert. Curve -: Curve__y NB. can only add points on same curve | |
p=. p__Curve'' NB. add | |
if. X = X__y do. | |
if. 0 = p | Y + Y__y do. | |
INFINITY return. | |
else. | |
double'' return. | |
end. | |
end. | |
l=. p | (Y__y - Y) * p invmod X__y-X | |
x3=. p | (0 0 1 p. l) - X+X__y | |
y3=. p | (l * (X - x3)) - Y | |
(Curve; x3; y3) conew 'Point' return. | |
) | |
leftmostBit=: </\&.#: | |
bitAnd=: *./@,:&.|.&.#: | |
mul=: 3 :0 | |
e=. y | |
if. ORDERED do. e=. Order|e end. | |
if. 0 = e do. INFINITY return. end. | |
if. infinite This do. INFINITY return. end. | |
assert. e > 0 | |
e3=. e*3 | |
negativeSelf=. (Curve;X;(-Y);Order) conew 'Point' | |
i =. leftmostBit e3 | |
result=. This | |
while. 1 < i=. <. -: i do. | |
result=. double__result'' | |
if. (0 ~: e3 bitAnd i) *. (0 = e bitAnd i) do. result=. add__This result end. | |
if. (0 = e3 bitAnd i) *. (0 ~: e bitAnd i) do. result=. add__negativeSelf result end. | |
end. | |
) | |
str=:3 :0 | |
if. infinite This do. 'infinity' return. end. | |
'(',(":X),',',(":Y),')' | |
) | |
double=:3 :0 | |
NB. Return a new point that is twice this one | |
if. infinite This do. INFINITY return. end. | |
p=. p__Curve'' | |
a=. a__Curve'' | |
l=. p | ((a,0,3) p. X) * p invmod 2*Y | |
x3=. p | (l*l) - 2*X | |
y3=. p | (l*(X-x3)) - Y | |
(Curve; x3; y3) conew 'Point' | |
) | |
x0=: 3 :'X' | |
y0=: 3 :'Y' | |
xy=: 3 :'X,Y' | |
curve=: 3 :'Curve' | |
order=: 3 :'Order' | |
INFINITY=: ('';'';'') conew 'Point' | |
cocurrent 'test' | |
test_add=: 3 :0 | |
'c x1 y1 x2 y2 x3 y3'=: y | |
p1=. (c;x1;y1) conew 'Point' | |
p2=. (c;x2;y2) conew 'Point' | |
p3=. add__p1 p2 | |
prefix=. (str__p1''),' + ',(str__p2''),' = ',(str__p3''),' ' | |
if. (x3 ~: x0__p3'') +. (y3 ~: y0__p3'') do. | |
smoutput prefix,'Failure: should give (',(":x3),',',(":y3),')' | |
else. | |
smoutput prefix,' Good.' | |
end. | |
) | |
test_double=: 3 :0 | |
NB. We expect that on curve c, 2*(x1,y1) = (x3, y3). | |
'c x1 y1 x3 y3'=: y | |
p1=. (c;x1;y1) conew 'Point' | |
p3=. double__p1'' | |
prefix=. (str__p1''),' doubled = ',(str__p3''),' ' | |
if. (x3 ~: x0__p3'') +. y3 ~: y0__p3'' do. | |
smoutput prefix,'Failure: should give (',(":x3),',',(":y3),').' | |
else. | |
smoutput prefix,' Good.' | |
end. | |
) | |
test_double_infinity=: 3 :0 | |
NB. We expect that on curve c, 2*INFINITY = INFINITY. | |
p1=. INFINITY_Point_ | |
p3=. double__p1'' | |
prefix=: (str__p1''),' doubled = ',(str__p3''),' ' | |
if. -. (xy__p1'') -: xy__p3'' do. | |
smoutput prefix,'Failure: should give (',(":x0__p1''),',',(":y0__p1''),').' | |
else. | |
smoutput prefix,' Good.' | |
end. | |
) | |
test_multiply=: 3 :0 | |
'c x1 y1 m x3 y3'=: y | |
p1=. (c;x1;y1) conew 'Point' | |
p3=. mul__p1 m | |
prefix=. (str__p1''),' * ',(":m),' = ',(str__p3''),' ' | |
if. (x3 ~: x0__p3'') +. (y3 ~: y0__p3'') do. | |
smoutput prefix,'Failure: should give (',(":x3),',',(":y3),')' | |
else. | |
smoutput prefix,' Good.' | |
end. | |
) | |
main=:3 :0 | |
c=. (23;1;1) conew 'CurveFp' | |
test_add c;3;10;9;7;17;20 | |
test_double c;3;10;7;12 | |
test_add c;3;10;3;10;7;12 | |
test_multiply c;3;10;2;7;12 | |
test_double_infinity c | |
g=. (c;13;7;7) conew 'Point' | |
check=. INFINITY_Point_ | |
for_i. i. 7+1 do. | |
p=. mul__g 7 | i | |
prefix=. (str__g''),' * ',(":i),' = ',(str__p''),', expected ',(str__check''),' . . . ' | |
if. eq__p check do. | |
smoutput prefix,' Good.' | |
else. | |
smoutput prefix,'Bad.' | |
end. | |
check=. add__check g | |
end. | |
p=. 6277101735386680763835789423207666416083908700390324961279x | |
r=. 6277101735386680763835789423176059013767194773182842284081x | |
dfhx=. 16x #. 16 | '0123456789ABCDEF0123456789abcdef' i. ] | |
c=. dfhx '3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65' | |
b=. dfhx '3099d2bbbfcb2538542dcd5fb078b6ef5f3d6fe2c745de65' | |
Gx=. dfhx '188da80eb03090f67cbf20eb43a18800f4ff0afd82ff1012' | |
Gy=. dfhx '07192b95ffc8da78631011ed6b24cdd573f977a11e794811' | |
c192=. (p;_3;b) conew 'CurveFp' | |
p192=. (c192;Gx;Gy;r) conew 'Point' | |
d=. 651056770906015076056810763456358567190100156695615665659x | |
Q=. mul__p192 d | |
if. (x0__Q'') ~: dfhx '62B12D60690CDCF330BABAB6E69763B471F994DD702D16A5' do. | |
smoutput 'p192 * d came out wrong.' | |
else. | |
smoutput 'p192 * d came out right.' | |
end. | |
k=. 6140507067065001063065065565667405560006161556565665656654x | |
R=. k * x0__p192'' | |
if. (xy__R'') ~: dfhx&> '885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD';'9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835' do. | |
smoutput 'k * p192 came out wrong.' | |
else. | |
smoutput 'k * p192 came out right.' | |
end. | |
u1=. 2563697409189434185194736134579731015366492496392189760599x | |
u2=. 6266643813348617967186477710235785849136406323338782220568x | |
temp=. mul__p192 u1 | |
temp=. add_temp_ mul__Q u2 | |
if. (xy_temp_'') ~: dfhx&> '885052380FF147B734C330C43D39B2C4A89F29B0F749FEAD';'9CF9FA1CBEFEFB917747A3BB29C072B9289C2547884FD835' do. | |
smoutput '(u1 * p192) + (u2 * Q) came out wrong.' | |
else. | |
smoutput '(u1 * p192) + (u2 * Q) came out right.' | |
end. | |
) | |
main'' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment