mirror of
https://github.com/arnaucube/cryptofun.git
synced 2026-02-28 13:26:40 +01:00
bn128 finite fields operations
This commit is contained in:
32
ecc/ecc.go
32
ecc/ecc.go
@@ -14,10 +14,10 @@ type EC struct {
|
||||
}
|
||||
|
||||
// NewEC (y^2 = x^3 + ax + b) mod q, where q is a prime number
|
||||
func NewEC(a, b, q int) (ec EC) {
|
||||
ec.A = big.NewInt(int64(a))
|
||||
ec.B = big.NewInt(int64(b))
|
||||
ec.Q = big.NewInt(int64(q))
|
||||
func NewEC(a, b, q *big.Int) (ec EC) {
|
||||
ec.A = a
|
||||
ec.B = b
|
||||
ec.Q = q
|
||||
return ec
|
||||
}
|
||||
|
||||
@@ -51,16 +51,16 @@ func (ec *EC) Neg(p Point) Point {
|
||||
|
||||
// Add adds two points p1 and p2 and gets q, returns the negate of q
|
||||
func (ec *EC) Add(p1, p2 Point) (Point, error) {
|
||||
if p1.Equal(zeroPoint) {
|
||||
if p1.Equal(ZeroPoint) {
|
||||
return p2, nil
|
||||
}
|
||||
if p2.Equal(zeroPoint) {
|
||||
if p2.Equal(ZeroPoint) {
|
||||
return p1, nil
|
||||
}
|
||||
|
||||
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
|
||||
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
|
||||
@@ -115,10 +115,10 @@ func (ec *EC) Add(p1, p2 Point) (Point, error) {
|
||||
func (ec *EC) Mul(p Point, n *big.Int) (Point, error) {
|
||||
var err error
|
||||
p2 := p
|
||||
r := zeroPoint
|
||||
for bigZero.Cmp(n) == -1 { // 0<n
|
||||
z := new(big.Int).And(n, bigOne) // n&1
|
||||
if bytes.Equal(z.Bytes(), bigOne.Bytes()) { // n&1==1
|
||||
r := ZeroPoint
|
||||
for BigZero.Cmp(n) == -1 { // 0<n
|
||||
z := new(big.Int).And(n, BigOne) // n&1
|
||||
if bytes.Equal(z.Bytes(), BigOne.Bytes()) { // n&1==1
|
||||
r, err = ec.Add(r, p2)
|
||||
if err != nil {
|
||||
return p, err
|
||||
@@ -137,16 +137,16 @@ func (ec *EC) Mul(p Point, n *big.Int) (Point, error) {
|
||||
func (ec *EC) Order(g Point) (*big.Int, error) {
|
||||
// loop from i:=1 to i<ec.Q+1
|
||||
start := big.NewInt(1)
|
||||
end := new(big.Int).Add(ec.Q, bigOne)
|
||||
for i := new(big.Int).Set(start); i.Cmp(end) <= 0; i.Add(i, bigOne) {
|
||||
end := new(big.Int).Add(ec.Q, BigOne)
|
||||
for i := new(big.Int).Set(start); i.Cmp(end) <= 0; i.Add(i, BigOne) {
|
||||
iCopy := new(big.Int).SetBytes(i.Bytes())
|
||||
mPoint, err := ec.Mul(g, iCopy)
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
if mPoint.Equal(zeroPoint) {
|
||||
if mPoint.Equal(ZeroPoint) {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return bigZero, errors.New("invalid order")
|
||||
return BigZero, errors.New("invalid order")
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
)
|
||||
|
||||
func TestECC(t *testing.T) {
|
||||
ec := NewEC(0, 7, 11)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
|
||||
p1, p1i, err := ec.At(big.NewInt(int64(7)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
@@ -20,7 +20,7 @@ func TestECC(t *testing.T) {
|
||||
}
|
||||
}
|
||||
func TestNeg(t *testing.T) {
|
||||
ec := NewEC(0, 7, 11)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
|
||||
p1, p1i, err := ec.At(big.NewInt(int64(7)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
@@ -32,7 +32,7 @@ func TestNeg(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
ec := NewEC(0, 7, 11)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
|
||||
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(7))}
|
||||
p2 := Point{big.NewInt(int64(2)), big.NewInt(int64(2))}
|
||||
q, err := ec.Add(p1, p2)
|
||||
@@ -53,7 +53,7 @@ func TestAdd(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestAddSamePoint(t *testing.T) {
|
||||
ec := NewEC(0, 7, 11)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
|
||||
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(7))}
|
||||
p1i := Point{big.NewInt(int64(4)), big.NewInt(int64(4))}
|
||||
|
||||
@@ -74,7 +74,7 @@ func TestAddSamePoint(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMulPoint1(t *testing.T) {
|
||||
ec := NewEC(0, 7, 29)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(29)))
|
||||
p := Point{big.NewInt(int64(11)), big.NewInt(int64(27))}
|
||||
|
||||
q, err := ec.Mul(p, big.NewInt(int64(1)))
|
||||
@@ -107,7 +107,7 @@ func TestMulPoint1(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMulPoint2(t *testing.T) {
|
||||
ec := NewEC(0, 7, 29)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(29)))
|
||||
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(19))}
|
||||
q3, err := ec.Mul(p1, big.NewInt(int64(3)))
|
||||
assert.Nil(t, err)
|
||||
@@ -132,7 +132,7 @@ func TestMulPoint2(t *testing.T) {
|
||||
|
||||
func TestMulPoint3(t *testing.T) {
|
||||
// in this test we will multiply by a high number
|
||||
ec := NewEC(0, 7, 11)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
|
||||
p := Point{big.NewInt(int64(7)), big.NewInt(int64(3))}
|
||||
|
||||
q, err := ec.Mul(p, big.NewInt(int64(100)))
|
||||
@@ -149,7 +149,7 @@ func TestMulPoint3(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestMulEqualSelfAdd(t *testing.T) {
|
||||
ec := NewEC(0, 7, 29)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(29)))
|
||||
p1 := Point{big.NewInt(int64(11)), big.NewInt(int64(27))}
|
||||
|
||||
p1_2, err := ec.Add(p1, p1)
|
||||
@@ -185,7 +185,7 @@ func TestMulEqualSelfAdd(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestOrder(t *testing.T) {
|
||||
ec := NewEC(0, 7, 11)
|
||||
ec := NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(11)))
|
||||
g := Point{big.NewInt(int64(7)), big.NewInt(int64(8))}
|
||||
order, err := ec.Order(g)
|
||||
assert.Nil(t, err)
|
||||
@@ -198,7 +198,7 @@ func TestOrder(t *testing.T) {
|
||||
assert.Equal(t, order.Int64(), int64(4))
|
||||
|
||||
// another test with another curve
|
||||
ec = NewEC(0, 7, 29)
|
||||
ec = NewEC(big.NewInt(int64(0)), big.NewInt(int64(7)), big.NewInt(int64(29)))
|
||||
g = Point{big.NewInt(int64(6)), big.NewInt(int64(22))}
|
||||
order, err = ec.Order(g)
|
||||
assert.Nil(t, err)
|
||||
|
||||
12
ecc/point.go
12
ecc/point.go
@@ -6,9 +6,9 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
bigZero = big.NewInt(int64(0))
|
||||
bigOne = big.NewInt(int64(1))
|
||||
zeroPoint = Point{bigZero, bigZero}
|
||||
BigZero = big.NewInt(int64(0))
|
||||
BigOne = big.NewInt(int64(1))
|
||||
ZeroPoint = Point{BigZero, BigZero}
|
||||
)
|
||||
|
||||
// Point is the data structure for a point, containing the X and Y coordinates
|
||||
@@ -18,11 +18,11 @@ type Point struct {
|
||||
}
|
||||
|
||||
// Equal compares the X and Y coord of a Point and returns true if are the same
|
||||
func (c1 *Point) Equal(c2 Point) bool {
|
||||
if !bytes.Equal(c1.X.Bytes(), c2.X.Bytes()) {
|
||||
func (p1 *Point) Equal(p2 Point) bool {
|
||||
if !bytes.Equal(p1.X.Bytes(), p2.X.Bytes()) {
|
||||
return false
|
||||
}
|
||||
if !bytes.Equal(c1.Y.Bytes(), c2.Y.Bytes()) {
|
||||
if !bytes.Equal(p1.Y.Bytes(), p2.Y.Bytes()) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user