Elliptic curve arithmetic: Difference between revisions

m
(OCaml implementation)
m (→‎{{header|Wren}}: Minor tidy)
 
(11 intermediate revisions by 9 users not shown)
Line 42:
<br>for any point '''P''' and integer '''n''', &nbsp; the point '''P + P + ... + P''' &nbsp; &nbsp; ('''n''' times).
<br><br>
 
=={{header|11l}}==
{{trans|Python}}
 
<syntaxhighlight lang="11l">T Point
:b = 7
 
Float x, y
 
F (x = Float.infinity, y = Float.infinity)
.x = x
.y = y
 
F.const copy()
R Point(.x, .y)
 
F.const is_zero()
R .x > 1e20 | .x < -1e20
 
F neg()
R Point(.x, -.y)
 
F dbl()
I .is_zero()
R .copy()
I .y == 0
R Point()
V l = (3 * .x * .x) / (2 * .y)
V x = l * l - 2 * .x
R Point(x, l * (.x - x) - .y)
 
F add(q)
I .x == q.x & .y == q.y
R .dbl()
I .is_zero()
R q.copy()
I q.is_zero()
R .copy()
I q.x - .x == 0
R Point()
V l = (q.y - .y) / (q.x - .x)
V x = l * l - .x - q.x
R Point(x, l * (.x - x) - .y)
 
F mul(n)
V p = .copy()
V r = Point()
V i = 1
L i <= n
I i [&] n
r = r.add(p)
p = p.dbl()
i <<= 1
R r
 
F String()
R ‘(#.3, #.3)’.format(.x, .y)
 
F show(s, p)
print(s‘ ’(I p.is_zero() {‘Zero’} E p))
 
F from_y(y)
V n = y * y - Point.:b
V x = I n >= 0 {n ^ (1. / 3)} E -((-n) ^ (1. / 3))
R Point(x, y)
 
V a = from_y(1)
V b = from_y(2)
show(‘a =’, a)
show(‘b =’, b)
V c = a.add(b)
show(‘c = a + b =’, c)
V d = c.neg()
show(‘d = -c =’, d)
show(‘c + d =’, c.add(d))
show(‘a + b + d =’, a.add(b.add(d)))
show(‘a * 12345 =’, a.mul(12345))</syntaxhighlight>
 
{{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>
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <math.h>
 
Line 117 ⟶ 205:
 
return 0;
}</langsyntaxhighlight>
{{out}}
<pre>
Line 131 ⟶ 219:
=={{header|C++}}==
Uses C++11 or later
<langsyntaxhighlight lang="cpp">#include <cmath>
#include <iostream>
 
Line 338 ⟶ 426:
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 367 ⟶ 455:
=={{header|D}}==
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.stdio, std.math, std.string;
 
enum bCoeff = 7;
Line 444 ⟶ 532:
writeln("a + b + d = ", a + b + d);
writeln("a * 12345 = ", a * 12345);
}</langsyntaxhighlight>
{{out}}
<pre>a = (-1.817, 1.000)
Line 456 ⟶ 544:
=={{header|EchoLisp}}==
===Arithmetic===
<langsyntaxhighlight lang="scheme">
(require 'struct)
(decimals 4)
Line 520 ⟶ 608:
(printf "%d additions a+(a+(a+...))) → %a" n e)
(printf "multiplication a x %d → %a" n (E-mul a n)))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 543 ⟶ 631:
===Plotting===
;; Result at http://www.echolalie.org/echolisp/help.html#plot-xy
<langsyntaxhighlight lang="scheme">
(define (E-plot (r 3))
(define (Ellie x y) (- (* y y) (* x x x) 7))
Line 560 ⟶ 648:
(plot-segment R.x R.y R.x (- R.y))
)
</syntaxhighlight>
</lang>
 
=={{header|Go}}==
{{trans|C}}
<langsyntaxhighlight lang="go">package main
 
import (
Line 656 ⟶ 744:
show("a + b + d = ", add(a, add(b, d)))
show("a * 12345 = ", mul(a, 12345))
}</langsyntaxhighlight>
{{out}}
<pre>a = (-1.817, 1.000)
Line 668 ⟶ 756:
=={{header|Haskell}}==
First, some useful imports:
<langsyntaxhighlight lang="haskell">import Data.Monoid
import Control.Monad (guard)
import Test.QuickCheck (quickCheck)</langsyntaxhighlight>
 
The datatype for a point on an elliptic curve:
 
<langsyntaxhighlight lang="haskell">import Data.Monoid
 
data Elliptic = Elliptic Double Double | Zero
Line 688 ⟶ 776:
 
inv Zero = Zero
inv (Elliptic x y) = Elliptic x (-y)</langsyntaxhighlight>
 
Points on elliptic curve form a monoid:
<langsyntaxhighlight lang="haskell">instance Monoid Elliptic where
mempty = Zero
 
Line 703 ⟶ 791:
mkElliptic l = let x = l^2 - x1 - x2
y = l*(x1 - x) - y1
in Elliptic x y</langsyntaxhighlight>
 
Examples given in other solutions:
 
<langsyntaxhighlight lang="haskell">ellipticX b y = Elliptic (qroot (y^2 - b)) y
where qroot x = signum x * abs x ** (1/3)</langsyntaxhighlight>
 
<pre>λ> let a = ellipticX 7 1
Line 728 ⟶ 816:
 
1. direct monoidal solution:
<langsyntaxhighlight lang="haskell">mult :: Int -> Elliptic -> Elliptic
mult n = mconcat . replicate n</langsyntaxhighlight>
 
2. efficient recursive solution:
<langsyntaxhighlight lang="haskell">n `mult` p
| n == 0 = Zero
| n == 1 = p
Line 738 ⟶ 826:
| n < 0 = inv ((-n) `mult` p)
| even n = 2 `mult` ((n `div` 2) `mult` p)
| odd n = p <> (n -1) `mult` p</langsyntaxhighlight>
 
<pre>λ> 12345 `mult` a
Line 747 ⟶ 835:
We use QuickCheck to test general properties of points on arbitrary elliptic curve.
 
<langsyntaxhighlight lang="haskell">-- for given a, b and x returns a point on the positive branch of elliptic curve (if point exists)
elliptic a b Nothing = Just Zero
elliptic a b (Just x) =
Line 765 ⟶ 853:
commutativity a b x1 x2 =
let p = elliptic a b
in p x1 <> p x2 == p x2 <> p x1</langsyntaxhighlight>
 
<pre>λ> quickCheck addition
Line 777 ⟶ 865:
Follows the C contribution.
 
<langsyntaxhighlight lang="j">zero=: _j_
isZero=: 1e20 < |@{.@+.
Line 834 ⟶ 922:
echo 'a + b + d = ', show add/ a, b, d
echo 'a * 12345 = ', show a mul 12345
)</langsyntaxhighlight>
{{out}}
<langsyntaxhighlight lang="j"> task ''
a = (_1.81712, 1)
b = (_1.44225, 2)
Line 843 ⟶ 931:
c + d = Zero
a + b + d = Zero
a * 12345 = (10.7586, 35.3874)</langsyntaxhighlight>
 
=={{header|Java}}==
{{trans|D}}
<langsyntaxhighlight lang="java">import static java.lang.Math.*;
import java.util.Locale;
 
Line 933 ⟶ 1,021:
return String.format(Locale.US, "(%.3f,%.3f)", this.x, this.y);
}
}</langsyntaxhighlight>
<pre>a = (-1.817,1.000)
b = (-1.442,2.000)
Line 941 ⟶ 1,029:
a + b + d = Zero
a * 12345 = (10.759,35.387)</pre>
 
=={{header|jq}}==
'''Adapted from [[#Wren|Wren]]'''
{{works with|jq}}
''Also works with gojq and fq''
 
'''Preliminaries'''
<syntaxhighlight lang=jq>
def round($ndec): pow(10;$ndec) as $p | . * $p | round / $p;
 
def idiv2: (. - (. % 2)) / 2;
 
def bitwise:
recurse( if . >= 2 then idiv2 else empty end) | . % 2;
 
def bitwise_and_nonzero($x; $y):
[$x|bitwise] as $x
| [$y|bitwise] as $y
| ([$x, $y] | map(length) | min) as $min
| any(range(0; $min) ; $x[.] == 1 and $y[.] == 1);
</syntaxhighlight>
'''Elliptic Curve Arithmetic'''
<syntaxhighlight lang=jq>
def Pt(x;y): [x, y];
 
def isPt: type == "array" and length == 2 and (map(type)|unique) == ["number"];
 
def zero: Pt(infinite; infinite);
 
def isZero: .[0] | (isinfinite or . == 0);
 
def C: 7;
 
def fromNum: Pt((.*. - C)|cbrt; .) ;
 
def double:
if isZero then .
else . as [$x,$y]
| ((3 * ($x * $x)) / (2 * .[1])) as $l
| ($l*$l - 2*$x) as $t
| Pt($t; $l*($x - $t) - $y)
end;
 
def minus: .[1] *= -1;
 
def plus($other):
if ($other|isPt|not) then "Argument of plus(Pt) must be a Pt object but got \(.)." | error
elif (.[0] == $other[0] and .[1] == $other[1]) then double
elif isZero then $other
elif ($other|isZero) then .
else . as [$x, $y]
| (if $other[0] == $x then infinite
else (($other[1] - $y) / ($other[0] - $x)) end) as $l
| ($l*$l - $x - $other[0]) as $t
| Pt($t; $l*($x-$t) - $y)
end;
 
def plus($a; $b): $a | plus($b);
 
def mult($n):
if ($n|type) != "number" or ($n | ( . != floor))
then "Argument must be an integer, not \($n)." | error
else { r: zero,
p: .,
i: 1 }
| until (.i > $n;
if bitwise_and_nonzero(.i; $n) then .r = plus(.r;.p) else . end
| .p |= double
| .i *= 2 )
| .r
end;
 
def toString:
if isZero then "Zero"
else map(round(3))
end;
 
 
def a: 1|fromNum;
def b: 2|fromNum;
def c: plus(a; b);
def d: c | minus;
 
def task:
"a = \(a|toString)",
"b = \(b|toString)",
"c = a + b = \(c|toString)",
"d = -c = \(d|toString)",
"c + d = \(plus(c; d)|toString)",
"(a+b) + d = \(plus(plus(a; b);d)|toString)",
"a * 12345 = \(a | mult(12345) | toString)"
;
 
task
</syntaxhighlight>
{{output}}
<pre>
a = [-1.817,1]
b = [-1.442,2]
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>
 
=={{header|Julia}}==
Line 946 ⟶ 1,139:
{{trans|Python}}
 
<langsyntaxhighlight lang="julia">struct Point{T<:AbstractFloat}
x::T
y::T
Line 1,004 ⟶ 1,197:
@show c + d
@show a + b + d
@show 12345a</langsyntaxhighlight>
 
{{out}}
Line 1,017 ⟶ 1,210:
===Julia 1.x compatible version===
Adds assertion checks for points to be on the curve.
<langsyntaxhighlight lang="julia">
using Printf
import Base.in
Line 1,102 ⟶ 1,295:
@show a + b + d
@show 12345a
</syntaxhighlight>
</lang>
Output: Same as the original, Julia 0.6 version code.
 
=={{header|Kotlin}}==
{{trans|C}}
<langsyntaxhighlight lang="scala">// version 1.1.4
 
const val C = 7
Line 1,164 ⟶ 1,357:
println("a + b + d = ${a + b + d}")
println("a * 12345 = ${a * 12345}")
}</langsyntaxhighlight>
 
{{out}}
Line 1,179 ⟶ 1,372:
=={{header|Nim}}==
{{trans|C}}
<langsyntaxhighlight Nimlang="nim">import math, strformat
 
const B = 7
Line 1,260 ⟶ 1,453:
echo "c + d = ", c + d
echo "a + b + d = ", a + b + d
echo "a * 12345 = ", a * 12345</langsyntaxhighlight>
 
{{out}}
Line 1,274 ⟶ 1,467:
Original version by [http://rosettacode.org/wiki/User:Vanyamil User:Vanyamil].
Some float-precision issues but overall works.
<syntaxhighlight lang="ocaml">
<lang OCaml>
(* Task : Elliptic_curve_arithmetic *)
 
Line 1,408 ⟶ 1,601:
print_output ();
print_output ()
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,430 ⟶ 1,623:
=={{header|PARI/GP}}==
The examples were borrowed from C, though the coding is built-in for GP and so not ported.
<langsyntaxhighlight lang="parigp">e=ellinit([0,7]);
a=[-6^(1/3),1]
b=[-3^(1/3),2]
Line 1,437 ⟶ 1,630:
elladd(e,c,d)
elladd(e,elladd(e,a,b),d)
ellmul(e,a,12345)</langsyntaxhighlight>
{{output}}
<pre>%1 = [-1.8171205928321396588912117563272605024, 1]
Line 1,449 ⟶ 1,642:
=={{header|Perl}}==
{{trans|C}}
<langsyntaxhighlight lang="perl">package EC;
{
our ($A, $B) = (0, 7);
Line 1,489 ⟶ 1,682:
print "check alignment... ";
print abs(($q->x - $p->x)*(-$s->y - $p->y) - ($q->y - $p->y)*($s->x - $p->x)) < 0.001
? "ok" : "wrong";</langsyntaxhighlight>
{{out}}
<pre>EC-point at x=-1.817121, y=1.000000
Line 1,499 ⟶ 1,692:
=={{header|Phix}}==
{{Trans|C}}
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>constant X=1, Y=2, bCoeff=7, INF = 1e300*1e300
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">X</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">Y</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">bCoeff</span><span style="color: #0000FF;">=</span><span style="color: #000000;">7</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">INF</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1e300</span><span style="color: #0000FF;">*</span><span style="color: #000000;">1e300</span>
<span style="color: #008080;">type</span> <span style="color: #000000;">point</span><span style="color: #0000FF;">(</span><span style="color: #004080;">object</span> <span style="color: #000000;">pt</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #004080;">sequence</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">and</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">2</span> <span style="color: #008080;">and</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">])</span> <span style="color: #008080;">and</span> <span style="color: #004080;">atom</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pt</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">])</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">type</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">zero</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">point</span> <span style="color: #000000;">pt</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">INF</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">INF</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">pt</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">is_zero</span><span style="color: #0000FF;">(</span><span style="color: #000000;">point</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]></span><span style="color: #000000;">1e20</span> <span style="color: #008080;">or</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]<-</span><span style="color: #000000;">1e20</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">neg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">point</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">],</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">p</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">dbl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">point</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">point</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p</span>
<span style="color: #008080;">if</span> <span style="color: #008080;">not</span> <span style="color: #000000;">is_zero</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">L</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">*</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]*</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">])/(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">])</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">L</span><span style="color: #0000FF;">*</span><span style="color: #000000;">L</span><span style="color: #0000FF;">-</span><span style="color: #000000;">2</span><span style="color: #0000FF;">*</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">L</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">point</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">point</span> <span style="color: #000000;">q</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">==</span><span style="color: #000000;">q</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">dbl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">is_zero</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">q</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">is_zero</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">p</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">L</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">])/(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">])</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">x</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">L</span><span style="color: #0000FF;">*</span><span style="color: #000000;">L</span><span style="color: #0000FF;">-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">q</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]</span>
<span style="color: #000000;">point</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">x</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">L</span><span style="color: #0000FF;">*(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">X</span><span style="color: #0000FF;">]-</span><span style="color: #000000;">x</span><span style="color: #0000FF;">)-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">Y</span><span style="color: #0000FF;">]}</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">point</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">point</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">zero</span><span style="color: #0000FF;">()</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">i</span><span style="color: #0000FF;"><=</span><span style="color: #000000;">n</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">if</span> <span style="color: #7060A8;">and_bits</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">n</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">r</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">dbl</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">*</span><span style="color: #000000;">2</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #004080;">string</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">point</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #7060A8;">puts</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">&</span><span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">is_zero</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)?</span><span style="color: #008000;">"Zero\n"</span><span style="color: #0000FF;">:</span><span style="color: #7060A8;">sprintf</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"(%.3f, %.3f)\n"</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">cbrt</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #008080;">return</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">>=</span><span style="color: #000000;">0</span><span style="color: #0000FF;">?</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">):-</span><span style="color: #7060A8;">power</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">/</span><span style="color: #000000;">3</span><span style="color: #0000FF;">))</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #008080;">function</span> <span style="color: #000000;">from_y</span><span style="color: #0000FF;">(</span><span style="color: #004080;">atom</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">point</span> <span style="color: #000000;">r</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">cbrt</span><span style="color: #0000FF;">(</span><span style="color: #000000;">y</span><span style="color: #0000FF;">*</span><span style="color: #000000;">y</span><span style="color: #0000FF;">-</span><span style="color: #000000;">bCoeff</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">y</span><span style="color: #0000FF;">}</span>
<span style="color: #008080;">return</span> <span style="color: #000000;">r</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
<span style="color: #000000;">point</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span>
<span style="color: #000000;">a</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">from_y</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">b</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">from_y</span><span style="color: #0000FF;">(</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">c</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">d</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">neg</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"a = "</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">a</span><span style="color: #0000FF;">)</span>
type point(object pt)
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"b = "</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">b</span><span style="color: #0000FF;">)</span>
return sequence(pt) and length(pt)=2 and atom(pt[X]) and atom(pt[Y])
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"c = a + b = "</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">c</span><span style="color: #0000FF;">)</span>
end type
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"d = -c = "</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">)</span>
 
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"c + d = "</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">c</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">))</span>
function zero()
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"a + b + d = "</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">b</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">d</span><span style="color: #0000FF;">)))</span>
point pt = {INF, INF}
<span style="color: #000000;">show</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"a * 12345 = "</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">a</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">12345</span><span style="color: #0000FF;">))</span>
return pt
<!--</syntaxhighlight>-->
end function
 
function is_zero(point p)
return p[X]>1e20 or p[X]<-1e20
end function
function neg(point p)
p = {p[X], -p[Y]}
return p
end function
 
function dbl(point p)
point r = p
if not is_zero(p) then
atom L = (3*p[X]*p[X])/(2*p[Y])
atom x = L*L-2*p[X]
r = {x, L*(p[X]-x)-p[Y]}
end if
return r
end function
function add(point p, point q)
if p==q then return dbl(p) end if
if is_zero(p) then return q end if
if is_zero(q) then return p end if
atom L = (q[Y]-p[Y])/(q[X]-p[X])
atom x = L*L-p[X]-q[X]
point r = {x, L*(p[X]-x)-p[Y]}
return r
end function
function mul(point p, integer n)
point r = zero()
integer i = 1
while i<=n do
if and_bits(i, n) then r = add(r, p) end if
p = dbl(p)
i = i*2
end while
return r
end function
procedure show(string s, point p)
puts(1, s&iff(is_zero(p)?"Zero\n":sprintf("(%.3f, %.3f)\n", p)))
end procedure
function cbrt(atom c)
return iff(c>=0?power(c,1/3):-power(-c,1/3))
end function
 
function from_y(atom y)
point r = {cbrt(y*y-bCoeff), y}
return r
end function
point a, b, c, d
a = from_y(1)
b = from_y(2)
c = add(a, b)
d = neg(c)
show("a = ", a)
show("b = ", b)
show("c = a + b = ", c)
show("d = -c = ", d)
show("c + d = ", add(c, d))
show("a + b + d = ", add(a, add(b, d)))
show("a * 12345 = ", mul(a, 12345))
</lang>
{{out}}
<pre>
Line 1,590 ⟶ 1,785:
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(scl 16)
(load "@lib/math.l")
(setq *B 7)
Line 1,668 ⟶ 1,863:
(prinl "D + C: " (prn (add C D)))
(prinl "A + B + D: " (prn (add A (add B D))))
(prinl "A * 12345: " (prn (mul A 12345)))</langsyntaxhighlight>
{{out}}
<pre>
Line 1,682 ⟶ 1,877:
=={{header|Python}}==
{{trans|C}}
<langsyntaxhighlight lang="python">#!/usr/bin/env python3
 
class Point:
Line 1,756 ⟶ 1,951:
show("c + d =", c.add(d))
show("a + b + d =", a.add(b.add(d)))
show("a * 12345 =", a.mul(12345))</langsyntaxhighlight>
{{out}}
<pre>
Line 1,769 ⟶ 1,964:
 
=={{header|Racket}}==
<langsyntaxhighlight lang="racket">
#lang racket
(define a 0) (define b 7)
Line 1,796 ⟶ 1,991:
[(even? n) (⊗ (⊗ p (/ n 2)) 2)]
[(odd? n) (⊕ p (⊗ p (- n 1)))]))
</syntaxhighlight>
</lang>
Test:
<langsyntaxhighlight lang="racket">
(define (root3 x) (* (sgn x) (expt (abs x) 1/3)))
(define (y->point y) (vector (root3 (- (* y y) b)) y))
Line 1,810 ⟶ 2,005:
(displayln (~a "p+(q+(-(p+q))) = 0 " (zero? (⊕ p (⊕ q (neg (⊕ p q)))))))
(displayln (~a "p*12345 " (⊗ p 12345)))
</syntaxhighlight>
</lang>
Output:
<langsyntaxhighlight lang="racket">
p = #(-1.8171205928321397 1)
q = #(-1.4422495703074083 2)
Line 1,820 ⟶ 2,015:
p+(q+(-(p+q))) = 0 #t
p*12345 #(10.758570529320806 35.387434774282106)
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
<syntaxhighlight lang="raku" perl6line>unit module EC; {
our ($A, $B) = (0, 7);
 
our class Point {
role Horizon { method gist { 'EC Point at horizon' } }
class Point {
has ($.x, $.y);
multi method new(
$x, $y where $y**2 ~~== $x**3 + $A*$x + $B
) { self.bless(samewith :$x, :$y) }
multi method new(Horizon $)gist { self.bless"EC butPoint Horizonat x=$.x, y=$.y" }
multi method gist(::?CLASS:U:) { "EC 'Point at x=$.x, y=$.y"horizon' }
}
 
multi prefix:<->(Point $p) is export { Point.new: x => $p.x, y => -$p.y }
multi prefix:<->(Horizon $Point:U) is export { HorizonPoint }
multi infix:<->(Point $a, Point $b) is export { $a + -$b }
 
multi infix:<+>(HorizonPoint:U $, Point $p) is export { $p }
multi infix:<+>(Point $p, HorizonPoint:U) is export { $p }
 
multi infix:<*>(Point $u, Int $n) is export { $n * $u }
multi infix:<*>(Int $n, HorizonPoint:U) is export { HorizonPoint }
multi infix:<*>(0, Point) is export { HorizonPoint }
multi infix:<*>(1, Point $p) is export { $p }
multi infix:<*>(2, Point $p) is export {
my $l = (3*$p.x**2 + $A) / (2 *$p.y);
my $y = $l*($p.x - my $x = $l**2 - 2*$p.x) - $p.y;
$p.blessnew(:$x, :$y);
}
multi infix:<*>(Int $n where $n > 2, Point $p) is export {
2 * ($n div 2 * $p) + $n % 2 * $p;
}
 
multi infix:<+>(Point $p, Point $q) is export {
if $p.x ~~ $q.x {
return $p.y ~~ $q.y ?? 2 * $p !! HorizonPoint;
}
else {
my $slope = ($q.y - $p.y) / ($q.x - $p.x);
my $y = $slope*($p.x - my $x = $slope**2 - $p.x - $q.x) - $p.y;
return $p.new(:$x, :$y);
}
}
 
}
 
import EC;
say my $p = Point.new: x => $_, y => sqrt(abs($_**3 + $A*$_ + $B)) given 1;
 
say my $q = Point.new: x => $_, y => sqrt(abs($_**3 + $A*$_ + $B)) given 2;
say my $p = EC::Point.new: x => $_, y => sqrt(abs($_**3 + $EC::A*$_ + $EC::B)) given 1;
say my $q = EC::Point.new: x => $_, y => sqrt(abs($_**3 + $EC::A*$_ + $EC::B)) given 2;
say my $s = $p + $q;
 
use Test;
say "checking alignment: ", abs ($p.x - $q.x)*(-$s.y - $q.y) - ($p.y - $q.y)*($s.x - $q.x);</lang>
is abs(($p.x - $q.x)*(-$s.y - $q.y) - ($p.y - $q.y)*($s.x - $q.x)), 0, "S, P and Q are aligned";</syntaxhighlight>
{{out}}
<pre>EC Point at x=1, y=2.8284271247461903
EC Point at x=2, y=3.872983346207417
EC Point at x=-1.9089023002066448, y=0.21008487055753378
ok 1 - S, P and Q are aligned</pre>
checking alignment: 0</pre>
 
=={{header|REXX}}==
Line 1,884 ⟶ 2,083:
 
Also, some code was added to have the output better aligned &nbsp; (for instance, negative and positive numbers).
<langsyntaxhighlight lang="rexx">/*REXX program defines (for any 2 points on the curve), returns the sum of the 2 points.*/
numeric digits 100 /*try to ensure a min. of accuracy loss*/
a= func(1) ; say ' a = ' show(a)
Line 1,919 ⟶ 2,118:
do until d==a; d=min(d+d,a); numeric digits d; o=0
do until o=g; o=g; g=format((m*g**y+x)/y/g**m,,d-2); end /*until o=g*/
end /*until d==a*/; _=g*sign(ox); if oy<0 then _=1/_; return _</langsyntaxhighlight>
{{out|output}}
<pre>
Line 1,932 ⟶ 2,131:
=={{header|Sage}}==
Examples from C, using the built-in Elliptic curves library.
<syntaxhighlight lang="sage">Ellie = EllipticCurve(RR,[0,7]) # RR = field of real numbers
<lang sage>
Ellie = EllipticCurve(RR,[0,7]) # RR = field of real numbers
 
# a point (x,y) on Ellie, given y
Line 1,942 ⟶ 2,140:
return P
 
print (Ellie)
P = point(1)
print ('P',P)
Q = point(2)
print ('Q',Q)
S = P+Q
print ('S = P + Q',S)
print ('P+Q-S', P+Q-S)
print ('P*12345' ,P*12345)</syntaxhighlight>
 
</lang>
{{out}}
<pre>
Line 1,967 ⟶ 2,163:
=={{header|Sidef}}==
{{trans|Raku}}
<langsyntaxhighlight lang="ruby">module EC {
 
var A = 0
Line 2,062 ⟶ 2,258:
say var s = (p + q)
 
say ("checking alignment: ", abs((p.x - q.x)*(-s.y - q.y) - (p.y - q.y)*(s.x - q.x)) < 1e-20)</langsyntaxhighlight>
{{out}}
<pre>
Line 2,073 ⟶ 2,269:
=={{header|Tcl}}==
{{trans|C}}
<langsyntaxhighlight lang="tcl">set C 7
set zero {x inf y inf}
proc tcl::mathfunc::cuberoot n {
Line 2,116 ⟶ 2,312:
}
return $r
}</langsyntaxhighlight>
Demonstrating:
<langsyntaxhighlight lang="tcl">proc show {s p} {
if {[iszero $p]} {
puts "${s}Zero"
Line 2,140 ⟶ 2,336:
show "c + d = " [add $c $d]
show "a + b + d = " [add $a [add $b $d]]
show "a * 12345 = " [multiply $a 12345]</langsyntaxhighlight>
{{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>
 
=={{header|V (Vlang)}}==
{{trans|go}}
<syntaxhighlight lang="v (vlang)">import math
 
const b_coeff = 7
struct Pt {
x f64
y f64
}
fn zero() Pt {
return Pt{math.inf(1), math.inf(1)}
}
fn is_zero(p Pt) bool {
return p.x > 1e20 || p.x < -1e20
}
fn neg(p Pt) Pt {
return Pt{p.x, -p.y}
}
fn dbl(p Pt) Pt {
if is_zero(p) {
return p
}
l := (3 * p.x * p.x) / (2 * p.y)
x := l*l - 2*p.x
return Pt{
x: x,
y: l*(p.x-x) - p.y,
}
}
fn add(p Pt, q Pt) Pt {
if p.x == q.x && p.y == q.y {
return dbl(p)
}
if is_zero(p) {
return q
}
if is_zero(q) {
return p
}
l := (q.y - p.y) / (q.x - p.x)
x := l*l - p.x - q.x
return Pt{
x: x,
y: l*(p.x-x) - p.y,
}
}
fn mul(mut p Pt, n int) Pt {
mut r := zero()
for i := 1; i <= n; i <<= 1 {
if i&n != 0 {
r = add(r, p)
}
p = dbl(p)
}
return r
}
fn show(s string, p Pt) {
print("$s")
if is_zero(p) {
println("Zero")
} else {
println("(${p.x:.3f}, ${p.y:.3f})")
}
}
fn from_y(y f64) Pt {
return Pt{
x: math.cbrt(y*y - b_coeff),
y: y,
}
}
fn main() {
mut a := from_y(1)
b := from_y(2)
show("a = ", a)
show("b = ", b)
c := add(a, b)
show("c = a + b = ", c)
d := neg(c)
show("d = -c = ", d)
show("c + d = ", add(c, d))
show("a + b + d = ", add(a, add(b, d)))
show("a * 12345 = ", mul(mut a, 12345))
}</syntaxhighlight>
 
{{out}}
<pre>
Line 2,155 ⟶ 2,456:
{{trans|C}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
{{libheader|Wren-math}}
<lang ecmascript>import "/fmt" for Fmt
import "/math" for Math
 
var C = 7
Line 2,172 ⟶ 2,471:
y { _y }
 
static fromNum(n) { Pt.new(Math.cbrt(n*n - C).cbrt, n) }
 
isZero { x > 1e20 || x < -1e20 }
Line 2,223 ⟶ 2,522:
System.print("c + d = %(c + d)")
System.print("a + b + d = %(a + b + d)")
System.print("a * 12345 = %(a * 12345)")</langsyntaxhighlight>
 
{{out}}
Line 2,233 ⟶ 2,532:
c + d = Zero
a + b + d = Zero
a * 12345 = (10.759, 35.387388)
</pre>
 
=={{header|zkl}}==
{{trans|C}}
<langsyntaxhighlight lang="zkl">const C=7, INFINITY=(0.0).inf;
 
fcn zero{ T(INFINITY, INFINITY) }
Line 2,276 ⟶ 2,575:
}
r
}</langsyntaxhighlight>
<langsyntaxhighlight lang="zkl">fcn show(str,p)
{ println(str, is_zero(p) and "Zero" or "(%.3f, %.3f)".fmt(p.xplode())) }
Line 2,292 ⟶ 2,591:
show("c + d = ", add(c, d));
show("a + b + d = ", add(a, add(b, d)));
show("a * 12345 = ", mul(a, 12345.0));</langsyntaxhighlight>
{{out}}
<pre>
9,476

edits