bn128 finite fields operations

This commit is contained in:
arnaucube
2018-10-07 00:16:23 +02:00
parent 4acca94c9e
commit 151ca78806
14 changed files with 712 additions and 54 deletions

View File

@@ -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")
}

View File

@@ -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)

View File

@@ -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