|
@ -1,6 +1,7 @@ |
|
|
package ecc |
|
|
package ecc |
|
|
|
|
|
|
|
|
import ( |
|
|
import ( |
|
|
|
|
|
"bytes" |
|
|
"errors" |
|
|
"errors" |
|
|
"math/big" |
|
|
"math/big" |
|
|
) |
|
|
) |
|
@ -11,10 +12,7 @@ type EC struct { |
|
|
Q *big.Int |
|
|
Q *big.Int |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
/* |
|
|
|
|
|
(y^2 = x^3 + Ax + B ) mod Q |
|
|
|
|
|
Q: prime number |
|
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
// NewEC (y^2 = x^3 + ax + b) mod q, where q is a prime number
|
|
|
func NewEC(a, b, q int) (ec EC) { |
|
|
func NewEC(a, b, q int) (ec EC) { |
|
|
ec.A = big.NewInt(int64(a)) |
|
|
ec.A = big.NewInt(int64(a)) |
|
|
ec.B = big.NewInt(int64(b)) |
|
|
ec.B = big.NewInt(int64(b)) |
|
@ -52,15 +50,41 @@ func (ec *EC) Neg(p Point) Point { |
|
|
// Add adds two points p1 and p2 and gets q
|
|
|
// Add adds two points p1 and p2 and gets q
|
|
|
func (ec *EC) Add(p1, p2 Point) (Point, error) { |
|
|
func (ec *EC) Add(p1, p2 Point) (Point, error) { |
|
|
if p1.Equal(zeroPoint) { |
|
|
if p1.Equal(zeroPoint) { |
|
|
return p2, errors.New("p1==(0, 0)") |
|
|
|
|
|
|
|
|
return p2, nil |
|
|
} |
|
|
} |
|
|
if p2.Equal(zeroPoint) { |
|
|
if p2.Equal(zeroPoint) { |
|
|
return p1, errors.New("p1==(0, 0)") |
|
|
|
|
|
|
|
|
return p1, nil |
|
|
} |
|
|
} |
|
|
// slope
|
|
|
|
|
|
numerator := new(big.Int).Sub(p1.Y, p2.Y) |
|
|
|
|
|
denominator := new(big.Int).Sub(p1.X, p2.X) |
|
|
|
|
|
s := new(big.Int).Div(numerator, denominator) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
var numerator, denominator, sRaw, s *big.Int |
|
|
|
|
|
if bytes.Equal(p1.X.Bytes(), p2.X.Bytes()) && (!bytes.Equal(p1.Y.Bytes(), p2.Y.Bytes()) || bytes.Equal(p1.Y.Bytes(), bigZero.Bytes())) { |
|
|
|
|
|
return zeroPoint, nil |
|
|
|
|
|
} else if bytes.Equal(p1.X.Bytes(), p2.X.Bytes()) { |
|
|
|
|
|
// use tangent as slope
|
|
|
|
|
|
// x^2
|
|
|
|
|
|
x2 := new(big.Int).Mul(p1.X, p1.X) |
|
|
|
|
|
// 3 * x^2
|
|
|
|
|
|
x23 := new(big.Int).Mul(big.NewInt(int64(3)), x2) |
|
|
|
|
|
// 3 * x^2 + a
|
|
|
|
|
|
numerator = new(big.Int).Add(x23, ec.A) |
|
|
|
|
|
// 2 * y
|
|
|
|
|
|
denominator = new(big.Int).Mul(big.NewInt(int64(2)), p1.Y) |
|
|
|
|
|
// (3 * x^2 + a) / (2 * y) mod ec.Q
|
|
|
|
|
|
denInv := new(big.Int).ModInverse(denominator, ec.Q) |
|
|
|
|
|
sRaw = new(big.Int).Mul(numerator, denInv) |
|
|
|
|
|
s = new(big.Int).Mod(sRaw, ec.Q) |
|
|
|
|
|
} else { |
|
|
|
|
|
// slope
|
|
|
|
|
|
// y0-y1
|
|
|
|
|
|
numerator = new(big.Int).Sub(p1.Y, p2.Y) |
|
|
|
|
|
// x0-x1
|
|
|
|
|
|
denominator = new(big.Int).Sub(p1.X, p2.X) |
|
|
|
|
|
// (y0-y1) / (x0-x1) mod ec.Q
|
|
|
|
|
|
denInv := new(big.Int).ModInverse(denominator, ec.Q) |
|
|
|
|
|
sRaw = new(big.Int).Mul(numerator, denInv) |
|
|
|
|
|
s = new(big.Int).Mod(sRaw, ec.Q) |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
// q: new point
|
|
|
// q: new point
|
|
|
var q Point |
|
|
var q Point |
|
|
// s^2
|
|
|
// s^2
|
|
@ -77,7 +101,20 @@ func (ec *EC) Add(p1, p2 Point) (Point, error) { |
|
|
sXoX2 := new(big.Int).Mul(s, xoX2) |
|
|
sXoX2 := new(big.Int).Mul(s, xoX2) |
|
|
// s(p1.X - q.X) - p1.Y
|
|
|
// s(p1.X - q.X) - p1.Y
|
|
|
sXoX2Y := new(big.Int).Sub(sXoX2, p1.Y) |
|
|
sXoX2Y := new(big.Int).Sub(sXoX2, p1.Y) |
|
|
|
|
|
// q.Y = (s(p1.X - q.X) - p1.Y) mod ec.Q
|
|
|
q.Y = new(big.Int).Mod(sXoX2Y, ec.Q) |
|
|
q.Y = new(big.Int).Mod(sXoX2Y, ec.Q) |
|
|
|
|
|
|
|
|
return q, nil |
|
|
return q, nil |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// Mul multiplies a point n times on the elliptic curve
|
|
|
|
|
|
func (ec *EC) Mul(p Point, n int) (Point, error) { |
|
|
|
|
|
var err error |
|
|
|
|
|
for i := 0; i < n; i++ { |
|
|
|
|
|
p, err = ec.Add(p, p) |
|
|
|
|
|
if err != nil { |
|
|
|
|
|
return zeroPoint, err |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
return p, nil |
|
|
|
|
|
} |