cryptofun/ecc/ecc.go
ecc/ecc.goRaw
1package ecc
2
3import (
4 "errors"
5 "math/big"
6)
7
8type EC struct {
9 A *big.Int
10 B *big.Int
11 Q *big.Int
12}
13
14/*
15 (y^2 = x^3 + Ax + B ) mod Q
16 Q: prime number
17*/
18func NewEC(a, b, q int) (ec EC) {
19 ec.A = big.NewInt(int64(a))
20 ec.B = big.NewInt(int64(b))
21 ec.Q = big.NewInt(int64(q))
22 return ec
23}
24
25// At gets a point x in the curve
26func (ec *EC) At(x *big.Int) (Point, Point, error) {
27 if x.Cmp(ec.Q) > 0 {
28 return Point{}, Point{}, errors.New("x<ec.Q")
29 }
30 // y^2 = (x^3 + ax + b) mod q
31 // y = sqrt (x^3 + ax + b) mod q
32 // x^3
33 x3 := new(big.Int).Exp(x, big.NewInt(int64(3)), nil)
34 // a^x
35 aX := new(big.Int).Mul(ec.A, x)
36 // x^3 + a^x
37 x3aX := new(big.Int).Add(x3, aX)
38 // x^3 + a^x + b
39 x3aXb := new(big.Int).Add(x3aX, ec.B)
40 // y = sqrt (x^3 + ax + b) mod q
41 y := new(big.Int).ModSqrt(x3aXb, ec.Q)
42 return Point{x, y}, Point{x, new(big.Int).Sub(ec.Q, y)}, nil
43}
44
45// TODO add valid checker point function
46
47func (ec *EC) Neg(p Point) Point {
48 // TODO get error when point not found on the ec
49 return Point{p.X, new(big.Int).Sub(ec.Q, p.Y)}
50}
51
52// Add adds two points p1 and p2 and gets q
53func (ec *EC) Add(p1, p2 Point) (Point, error) {
54 if p1.Equal(zeroPoint) {
55 return p2, errors.New("p1==(0, 0)")
56 }
57 if p2.Equal(zeroPoint) {
58 return p1, errors.New("p1==(0, 0)")
59 }
60 // slope
61 numerator := new(big.Int).Sub(p1.Y, p2.Y)
62 denominator := new(big.Int).Sub(p1.X, p2.X)
63 s := new(big.Int).Div(numerator, denominator)
64 // q: new point
65 var q Point
66 // s^2
67 s2 := new(big.Int).Exp(s, big.NewInt(int64(2)), nil)
68 // s^2 - p1.X
69 x2Xo := new(big.Int).Sub(s2, p1.X)
70 // s^2 - p1.X - p2.X
71 x2XoX2 := new(big.Int).Sub(x2Xo, p2.X)
72 q.X = new(big.Int).Mod(x2XoX2, ec.Q)
73
74 // p1.X - q.X
75 xoX2 := new(big.Int).Sub(p1.X, q.X)
76 // s(p1.X - q.X)
77 sXoX2 := new(big.Int).Mul(s, xoX2)
78 // s(p1.X - q.X) - p1.Y
79 sXoX2Y := new(big.Int).Sub(sXoX2, p1.Y)
80 q.Y = new(big.Int).Mod(sXoX2Y, ec.Q)
81
82 return q, nil
83}