Elliptic curve arithmetic: Difference between revisions

m (→‎{{header|Tcl}}: added zkl header)
(→‎{{header|zkl}}: added code)
Line 1,484:
 
=={{header|zkl}}==
{{trans|C}}
<lang zkl></lang>
<lang zkl></lang>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>}</lang>
<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}}
<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>
 
Anonymous user