mirror of
https://github.com/arnaucube/cryptofun.git
synced 2026-02-28 05:16:46 +01:00
Schnorr signature implemented. ECC point multiplication with big int. Refactor of the code.
This commit is contained in:
42
ecc/ecc.go
42
ecc/ecc.go
@@ -49,20 +49,6 @@ func (ec *EC) Neg(p Point) Point {
|
||||
return Point{p.X, new(big.Int).Sub(ec.Q, p.Y)}
|
||||
}
|
||||
|
||||
// Order returns smallest n where nG = O (point at zero)
|
||||
func (ec *EC) Order(g Point) (int, error) {
|
||||
for i := 1; i < int(ec.Q.Int64())+1; i++ {
|
||||
mPoint, err := ec.Mul(g, i)
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
if mPoint.Equal(zeroPoint) {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return -1, errors.New("invalid order")
|
||||
}
|
||||
|
||||
// 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) {
|
||||
@@ -126,23 +112,41 @@ func (ec *EC) Add(p1, p2 Point) (Point, error) {
|
||||
}
|
||||
|
||||
// Mul multiplies a point n times on the elliptic curve
|
||||
func (ec *EC) Mul(p Point, n int) (Point, error) {
|
||||
func (ec *EC) Mul(p Point, n *big.Int) (Point, error) {
|
||||
var err error
|
||||
p2 := p
|
||||
r := zeroPoint
|
||||
for 0 < n {
|
||||
if n&1 == 1 {
|
||||
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
|
||||
}
|
||||
}
|
||||
n = n >> 1
|
||||
n = n.Rsh(n, 1) // n = n>>1
|
||||
p2, err = ec.Add(p2, p2)
|
||||
if err != nil {
|
||||
return p, err
|
||||
}
|
||||
|
||||
}
|
||||
return r, nil
|
||||
}
|
||||
|
||||
// Order returns smallest n where nG = O (point at zero)
|
||||
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) {
|
||||
iCopy := new(big.Int).SetBytes(i.Bytes())
|
||||
mPoint, err := ec.Mul(g, iCopy)
|
||||
if err != nil {
|
||||
return i, err
|
||||
}
|
||||
if mPoint.Equal(zeroPoint) {
|
||||
return i, nil
|
||||
}
|
||||
}
|
||||
return bigZero, errors.New("invalid order")
|
||||
}
|
||||
|
||||
200
ecc/ecc_test.go
200
ecc/ecc_test.go
@@ -1,17 +1,17 @@
|
||||
package ecc
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestECC(t *testing.T) {
|
||||
ec := NewEC(0, 7, 11)
|
||||
p1, p1i, err := ec.At(big.NewInt(int64(7)))
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !p1.Equal(Point{big.NewInt(int64(7)), big.NewInt(int64(3))}) {
|
||||
t.Errorf("p1!=(7, 11)")
|
||||
}
|
||||
@@ -22,32 +22,30 @@ func TestECC(t *testing.T) {
|
||||
func TestNeg(t *testing.T) {
|
||||
ec := NewEC(0, 7, 11)
|
||||
p1, p1i, err := ec.At(big.NewInt(int64(7)))
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
p1Neg := ec.Neg(p1)
|
||||
if !p1Neg.Equal(p1i) {
|
||||
t.Errorf("p1Neg!=p1i")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestAdd(t *testing.T) {
|
||||
ec := NewEC(0, 7, 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)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(Point{big.NewInt(int64(3)), big.NewInt(int64(1))}) {
|
||||
t.Errorf("q!=(3, 1)")
|
||||
}
|
||||
|
||||
// check that q exists on the elliptic curve
|
||||
pt, pti, err := ec.At(q.X)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(pt) && !q.Equal(pti) {
|
||||
t.Errorf("q not exist on the elliptic curve")
|
||||
}
|
||||
@@ -60,69 +58,155 @@ func TestAddSamePoint(t *testing.T) {
|
||||
p1i := Point{big.NewInt(int64(4)), big.NewInt(int64(4))}
|
||||
|
||||
q, err := ec.Add(p1, p1)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(5))}) {
|
||||
t.Errorf("q!=(6, 5)")
|
||||
t.Errorf(q.String() + " == q != (6, 5)")
|
||||
}
|
||||
|
||||
q_, err := ec.Add(p1i, p1i)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q_.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(6))}) {
|
||||
t.Errorf("q_!=(6, 6)")
|
||||
t.Errorf(q_.String() + " == q_ != (6, 6)")
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func TestMulPoint1(t *testing.T) {
|
||||
ec := NewEC(0, 7, 29)
|
||||
p := Point{big.NewInt(int64(11)), big.NewInt(int64(27))}
|
||||
|
||||
q, err := ec.Mul(p, big.NewInt(int64(1)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(Point{big.NewInt(int64(11)), big.NewInt(int64(27))}) {
|
||||
t.Errorf(q.String() + " == q != (11, 27)")
|
||||
}
|
||||
|
||||
q, err = ec.Mul(p, big.NewInt(int64(2)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(Point{big.NewInt(int64(12)), big.NewInt(int64(13))}) {
|
||||
t.Errorf(q.String() + " == q != (12, 13)")
|
||||
}
|
||||
|
||||
q, err = ec.Mul(p, big.NewInt(int64(3)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(Point{big.NewInt(int64(28)), big.NewInt(int64(8))}) {
|
||||
t.Errorf(q.String() + " == q != (28, 8)")
|
||||
}
|
||||
|
||||
q, err = ec.Mul(p, big.NewInt(int64(4)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(22))}) {
|
||||
t.Errorf(q.String() + " == q != (6, 22)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMulPoint2(t *testing.T) {
|
||||
ec := NewEC(0, 7, 29)
|
||||
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(19))}
|
||||
q3, err := ec.Mul(p1, big.NewInt(int64(3)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q3.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(7))}) {
|
||||
t.Errorf(q3.String() + " == q3 != (6, 7)")
|
||||
}
|
||||
q7, err := ec.Mul(p1, big.NewInt(int64(7)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q7.Equal(Point{big.NewInt(int64(19)), big.NewInt(int64(14))}) {
|
||||
t.Errorf(q7.String() + " == q7 != (19, 14)")
|
||||
}
|
||||
|
||||
q8, err := ec.Mul(p1, big.NewInt(int64(8)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q8.Equal(Point{big.NewInt(int64(19)), big.NewInt(int64(15))}) {
|
||||
t.Errorf(q8.String() + " == q8 != (12, 16)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMulPoint3(t *testing.T) {
|
||||
// in this test we will multiply by a high number
|
||||
ec := NewEC(0, 7, 11)
|
||||
p := Point{big.NewInt(int64(7)), big.NewInt(int64(3))}
|
||||
|
||||
q, err := ec.Mul(p, big.NewInt(int64(100)))
|
||||
assert.Nil(t, err)
|
||||
if !q.Equal(Point{big.NewInt(int64(3)), big.NewInt(int64(1))}) {
|
||||
t.Errorf(q.String() + " == q != (3, 1)")
|
||||
}
|
||||
|
||||
q, err = ec.Mul(p, big.NewInt(int64(100)))
|
||||
assert.Nil(t, err)
|
||||
if !q.Equal(Point{big.NewInt(int64(3)), big.NewInt(int64(1))}) {
|
||||
t.Errorf(q.String() + " == q != (3, 1)")
|
||||
}
|
||||
}
|
||||
|
||||
func TestMulEqualSelfAdd(t *testing.T) {
|
||||
ec := NewEC(0, 7, 29)
|
||||
p1 := Point{big.NewInt(int64(11)), big.NewInt(int64(27))}
|
||||
|
||||
p1p1, err := ec.Add(p1, p1)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
p1_2, err := ec.Add(p1, p1)
|
||||
assert.Nil(t, err)
|
||||
|
||||
p1_3, err := ec.Add(p1_2, p1)
|
||||
assert.Nil(t, err)
|
||||
|
||||
// q * 3
|
||||
q, err := ec.Mul(p1, big.NewInt(int64(3)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(Point{big.NewInt(int64(28)), big.NewInt(int64(8))}) {
|
||||
t.Errorf(q.String() + " == q != (28, 8)")
|
||||
}
|
||||
p1p1, err = ec.Add(p1p1, p1)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
if !q.Equal(p1_3) {
|
||||
t.Errorf("p*3 == " + q.String() + ", p+p+p == " + p1_3.String())
|
||||
}
|
||||
q, err := ec.Mul(p1, 3)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
|
||||
// q * 4
|
||||
p1_4, err := ec.Add(p1_3, p1)
|
||||
assert.Nil(t, err)
|
||||
|
||||
q, err = ec.Mul(p1, big.NewInt(int64(4)))
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !q.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(22))}) {
|
||||
t.Errorf(q.String() + " == q != (6, 22)")
|
||||
}
|
||||
if !q.Equal(p1p1) {
|
||||
fmt.Println(q)
|
||||
fmt.Println(p1p1)
|
||||
t.Errorf("q!=p1*p1")
|
||||
if !q.Equal(p1_4) {
|
||||
t.Errorf("p*4 == " + q.String() + ", p+p+p+p == " + p1_4.String())
|
||||
}
|
||||
}
|
||||
|
||||
func TestMul(t *testing.T) {
|
||||
ec := NewEC(0, 7, 29)
|
||||
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(19))}
|
||||
q3, err := ec.Mul(p1, 3)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
if !q3.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(7))}) {
|
||||
t.Errorf("q3!=(6, 7)")
|
||||
}
|
||||
q7, err := ec.Mul(p1, 7)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
if !q7.Equal(Point{big.NewInt(int64(19)), big.NewInt(int64(14))}) {
|
||||
t.Errorf("q7!=(19, 14)")
|
||||
}
|
||||
func TestOrder(t *testing.T) {
|
||||
ec := NewEC(0, 7, 11)
|
||||
g := Point{big.NewInt(int64(7)), big.NewInt(int64(8))}
|
||||
order, err := ec.Order(g)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, order.Int64(), int64(12))
|
||||
|
||||
q8, err := ec.Mul(p1, 8)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
if !q8.Equal(Point{big.NewInt(int64(19)), big.NewInt(int64(15))}) {
|
||||
t.Errorf("q8!=(19, 15)")
|
||||
}
|
||||
// another test
|
||||
g = Point{big.NewInt(int64(2)), big.NewInt(int64(9))}
|
||||
order, err = ec.Order(g)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, order.Int64(), int64(4))
|
||||
|
||||
// another test with another curve
|
||||
ec = NewEC(0, 7, 29)
|
||||
g = Point{big.NewInt(int64(6)), big.NewInt(int64(22))}
|
||||
order, err = ec.Order(g)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, order.Int64(), int64(5))
|
||||
|
||||
// another test
|
||||
g = Point{big.NewInt(int64(23)), big.NewInt(int64(9))}
|
||||
order, err = ec.Order(g)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, order.Int64(), int64(30))
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
|
||||
var (
|
||||
bigZero = big.NewInt(int64(0))
|
||||
bigOne = big.NewInt(int64(1))
|
||||
zeroPoint = Point{bigZero, bigZero}
|
||||
)
|
||||
|
||||
@@ -26,3 +27,8 @@ func (c1 *Point) Equal(c2 Point) bool {
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// String returns the components of the point in a string
|
||||
func (p *Point) String() string {
|
||||
return "(" + p.X.String() + ", " + p.Y.String() + ")"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user