Elliptic curve arithmetic: Difference between revisions
Content added Content deleted
m (→{{header|Tcl}}: added zkl header) |
(→{{header|zkl}}: added code) |
||
Line 1,484: | Line 1,484: | ||
=={{header|zkl}}== |
=={{header|zkl}}== |
||
{{trans|C}} |
|||
⚫ | |||
<lang zkl> |
<lang zkl>const C=7, INFINITY=(0.0).inf; |
||
fcn zero{ T(INFINITY, INFINITY) } |
|||
// should be INFINITY, but numeric precision is very much in the way |
|||
fcn is_zero(p){ x,_:=p; (x < -1e20 or x > 1e20) } |
|||
fcn neg(p){ return(p[0], -p[1]) } |
|||
fcn dbl(p){ |
|||
if(is_zero(p)) return(p); |
|||
px,py := p; |
|||
L:=(3.0 * px * px) / (2.0 * py); |
|||
rx,ry := L * L - 2.0 * px, L * (px - rx) - py; |
|||
return(rx,ry); |
|||
} |
|||
fcn add(p,q){ |
|||
px,py := p; |
|||
qx,qy := q; |
|||
if(px == qx and py == qy) return(dbl(p)); |
|||
if(is_zero(p)) return(q); |
|||
if(is_zero(q)) return(p); |
|||
L := (qy - py) / (qx - px); |
|||
rx,ry := L * L - px - qx, L * (px - rx) - py; |
|||
return(rx,ry); |
|||
} |
|||
fcn mul(p,n){ |
|||
r := zero(); |
|||
i:=1; while(i <= n){ |
|||
if(i.bitAnd(n)) r = add(r,p); |
|||
p = dbl(p); |
|||
i*=2; |
|||
} |
|||
r |
|||
⚫ | |||
<lang zkl>fcn show(str,p) |
|||
{ println(str, is_zero(p) and "Zero" or "(%.3f, %.3f)".fmt(p.xplode())) } |
|||
fcn from_y(y){ |
|||
y3:=y * y - C; // cube root of -6 --> -1.817 |
|||
return(y3.abs().pow(1.0/3) * y3.sign, y) |
|||
} |
|||
a,b := from_y(1.0), from_y(2.0); |
|||
show("a = ", a); |
|||
show("b = ", b); |
|||
show("c = a + b = ", c := add(a, b)); |
|||
show("d = -c = ", d := neg(c)); |
|||
show("c + d = ", add(c, d)); |
|||
show("a + b + d = ", add(a, add(b, d))); |
|||
show("a * 12345 = ", mul(a, 12345.0));</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
a = (-1.817, 1.000) |
|||
b = (-1.442, 2.000) |
|||
c = a + b = (10.375, -33.525) |
|||
d = -c = (10.375, 33.525) |
|||
c + d = Zero |
|||
a + b + d = Zero |
|||
a * 12345 = (10.759, 35.387) |
|||
</pre> |
</pre> |
||