This is an alternative site for discovering Elm packages. You may be looking for the official Elm package site instead.

# ECurve.Point

Handles point calculations

new : BigInt -> BigInt -> BigInt -> BigInt -> BigInt -> Point

Returns a new point from big ints

affineX : Point -> BigInt

Returns the affine of x

affineY : Point -> BigInt

Returns the affine of y

fromAffine : BigInt -> BigInt -> BigInt -> BigInt -> Point

Returns a point from affine parameters

negate : Point -> Point

Returns the negation of a point

equal : Point -> Point -> Bool

Checks if two points are equal

multiply : Point -> BigInt -> Point

Multiplies two points

twice : Point -> Point

Multiplies two points twice

add : Point -> Point -> Point

``````module ECurve.Point exposing (new, affineX, affineY, fromAffine, negate, equal, multiply, twice, add)

{-| Handles point calculations

@docs new, affineX, affineY, fromAffine, negate, equal, multiply, twice, add

-}

import BigInt exposing (BigInt, mul, mod, sub, pow)
import ECurve.Util exposing (modInverse, signum, bitLength, testBit, square, zero, one, two, three, four, eight)
import ECurve.Models exposing (Point, Curve)

{-| Returns a new point from big ints
-}
new : BigInt -> BigInt -> BigInt -> BigInt -> BigInt -> Point
new p a x y z =
{ x = x
, y = y
, z = z
, p = p
, a = a
, zInv = modInverse z p
, compressed = True
}

{-| Returns the affine of x
-}
affineX : Point -> BigInt
affineX p =
mod (mul p.x p.zInv) p.p

{-| Returns the affine of y
-}
affineY : Point -> BigInt
affineY p =
mod (mul p.y p.zInv) p.p

{-| Returns a point from affine parameters
-}
fromAffine : BigInt -> BigInt -> BigInt -> BigInt -> Point
fromAffine p a x y =
new p a x y one

{-| Returns the negation of a point
-}
negate : Point -> Point
negate p =
let
y =
sub p.p p.y
in
new p.p p.a p.x y p.z

{-| Checks if two points are equal
-}
equal : Point -> Point -> Bool
equal p1 p2 =
if p1 == p2 then
True
else
let
u =
sub (mul p2.y p1.z) (mul p1.y p2.z)
in
if signum u == EQ then
False
else
let
v =
sub (mul p2.x p1.z) (mul p1.x p2.z)
in
signum v == EQ

{-| Multiplies two points
-}
multiply : Point -> BigInt -> Point
multiply p d =
let
dMul3 =
mul d three

negP =
negate p

bitLen =
bitLength dMul3

r =
loopBits p negP d dMul3 (bitLen - 2) bitLen
in
r

loopBits : Point -> Point -> BigInt -> BigInt -> Int -> Int -> Point
loopBits p neg d dMul3 index bitLen =
if index > 0 then
p
else
let
hBit =
testBit dMul3 index

kBit =
testBit d index

r =
twice p

if hBit then
p
else
neg

rr =
if hBit /= kBit then
else
r
in
loopBits rr neg d dMul3 (index - 1) bitLen

{-| Multiplies two points twice
-}
twice : Point -> Point
twice p =
let
x1 =
p.x

y1 =
p.y

z1 =
p.z

y1z1 =
mod (mul y1 p.z) p.p

y1sqz1 =
mod (mul y1z1 y1) p.p

a =
p.a

-- w = 3 * x1^2 + a * z1^2
w =
if signum a /= EQ then
mod (BigInt.add (mul (square x1) three) (mul (square p.z) a)) p.p
else
mod (mul (square x1) three) p.p

-- x3 = 2 * y1 * z1 * (w^2 - 8 * x1 * y1^2 * z1)
x3 =
mod (mul (mul (mul two y1) z1) (sub (square w) (mul (mul (mul eight x1) (square y1)) z1))) p.p

--  y3 = 4 * y1^2 * z1 * (3 * w * x1 - 2 * y1^2 * z1) - w^3
y3 =
mod (sub (mul (mul (mul four (square y1)) z1) (sub (mul (mul three w) x1) (mul (mul two (square y1)) z1))) (pow w three)) p.p

z3 =
mod (mul (pow y1z1 three) eight) p.p
in
new p.p p.a x3 y3 z3

-}
add : Point -> Point -> Point
let
x1 =
a.x

y1 =
a.y

z1 =
a.z

x2 =
b.x

y2 =
b.y

z2 =
b.z

curveP =
a.p

-- u = Y2 * Z1 - Y1 * Z2
u =
mod (sub (mul y2 z1) (mul y1 z2)) curveP

-- v = X2 * Z1 - X1 * Z2
v =
mod (sub (mul x2 z1) (mul x1 z2)) curveP

result =
if signum v == EQ then
if signum u == EQ then
-- a == b, so double
twice a
else
-- a = -b, so infinity
new a.p a.a zero zero zero
else
let
v2 =
square v

v3 =
mul v2 v

x1v2 =
mul x1 v2

zu2 =
mul (square u) z1

-- x3 = v * (z2 * (z1 * u^2 - 2 * x1 * v^2) - v^3)
x3 =
mod (mul v (sub (mul z2 (sub zu2 (mul two x1v2))) v3)) curveP

-- y3 = z2 * (3 * x1 * u * v^2 - y1 * v^3 - z1 * u^3) + u * v^3
y3 =
mod (BigInt.add (mul (sub (sub (mul (mul x1v2 three) u) (mul y1 v3)) (mul zu2 u)) z2) (mul u v3)) curveP

-- z3 = v^3 * z1 * z2
z3 =
mod (mul (mul v3 z1) z2) curveP
in
new a.p a.a x3 y3 z3
in
result
```
```