mirror of
https://github.com/arnaucube/cryptofun.git
synced 2026-02-28 05:16:46 +01:00
added ECC ElGamal Encryption and Decryption
This commit is contained in:
60
ElGamal/elGamal.go
Normal file
60
ElGamal/elGamal.go
Normal file
@@ -0,0 +1,60 @@
|
|||||||
|
package elgamal
|
||||||
|
|
||||||
|
import (
|
||||||
|
ecc "../ecc"
|
||||||
|
)
|
||||||
|
|
||||||
|
// EG is the ElGamal data structure
|
||||||
|
type EG struct {
|
||||||
|
EC ecc.EC
|
||||||
|
G ecc.Point
|
||||||
|
N int
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewEG defines a new EG data structure
|
||||||
|
func NewEG(ec ecc.EC, g ecc.Point) (EG, error) {
|
||||||
|
var eg EG
|
||||||
|
var err error
|
||||||
|
eg.EC = ec
|
||||||
|
eg.G = g
|
||||||
|
eg.N, err = ec.Order(g)
|
||||||
|
return eg, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// PubK returns the public key Point calculated from the private key over the elliptic curve
|
||||||
|
func (eg EG) PubK(privK int) (ecc.Point, error) {
|
||||||
|
// privK: rand < ec.Q
|
||||||
|
pubK, err := eg.EC.Mul(eg.G, privK)
|
||||||
|
return pubK, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Encrypt encrypts a point m with the public key point, returns two points
|
||||||
|
func (eg EG) Encrypt(m ecc.Point, pubK ecc.Point, r int) ([2]ecc.Point, error) {
|
||||||
|
p1, err := eg.EC.Mul(eg.G, r)
|
||||||
|
if err != nil {
|
||||||
|
return [2]ecc.Point{}, err
|
||||||
|
}
|
||||||
|
p2, err := eg.EC.Mul(pubK, r)
|
||||||
|
if err != nil {
|
||||||
|
return [2]ecc.Point{}, err
|
||||||
|
}
|
||||||
|
p3, err := eg.EC.Add(m, p2)
|
||||||
|
if err != nil {
|
||||||
|
return [2]ecc.Point{}, err
|
||||||
|
}
|
||||||
|
c := [2]ecc.Point{p1, p3}
|
||||||
|
return c, err
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decrypt decrypts c (two points) with the private key, returns the point decrypted
|
||||||
|
func (eg EG) Decrypt(c [2]ecc.Point, privK int) (ecc.Point, error) {
|
||||||
|
c1 := c[0]
|
||||||
|
c2 := c[1]
|
||||||
|
c1PrivK, err := eg.EC.Mul(c1, privK)
|
||||||
|
if err != nil {
|
||||||
|
return ecc.Point{}, err
|
||||||
|
}
|
||||||
|
c1PrivKNeg := eg.EC.Neg(c1PrivK)
|
||||||
|
d, err := eg.EC.Add(c2, c1PrivKNeg)
|
||||||
|
return d, err
|
||||||
|
}
|
||||||
77
ElGamal/elGamal_test.go
Normal file
77
ElGamal/elGamal_test.go
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
package elgamal
|
||||||
|
|
||||||
|
import (
|
||||||
|
"math/big"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
ecc "../ecc"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNewEG(t *testing.T) {
|
||||||
|
ec := ecc.NewEC(1, 18, 19)
|
||||||
|
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
|
||||||
|
eg, err := NewEG(ec, g)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
privK := 5
|
||||||
|
pubK, err := eg.PubK(privK)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
if !pubK.Equal(ecc.Point{big.NewInt(int64(13)), big.NewInt(int64(9))}) {
|
||||||
|
t.Errorf("pubK!=(13, 9)")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func TestEGEncrypt(t *testing.T) {
|
||||||
|
ec := ecc.NewEC(1, 18, 19)
|
||||||
|
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
|
||||||
|
eg, err := NewEG(ec, g)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
privK := 5
|
||||||
|
pubK, err := eg.PubK(privK)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
// m: point to encrypt
|
||||||
|
m := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(12))}
|
||||||
|
c, err := eg.Encrypt(m, pubK, 15)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
if !c[0].Equal(ecc.Point{big.NewInt(int64(8)), big.NewInt(int64(5))}) {
|
||||||
|
t.Errorf("c[0] != (8, 5), encryption failed")
|
||||||
|
}
|
||||||
|
if !c[1].Equal(ecc.Point{big.NewInt(int64(2)), big.NewInt(int64(16))}) {
|
||||||
|
t.Errorf("c[1] != (2, 16), encryption failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestEGDecrypt(t *testing.T) {
|
||||||
|
ec := ecc.NewEC(1, 18, 19)
|
||||||
|
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
|
||||||
|
eg, err := NewEG(ec, g)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
privK := 5
|
||||||
|
pubK, err := eg.PubK(privK)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
// m: point to encrypt
|
||||||
|
m := ecc.Point{big.NewInt(int64(11)), big.NewInt(int64(12))}
|
||||||
|
c, err := eg.Encrypt(m, pubK, 15)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
d, err := eg.Decrypt(c, privK)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
if !m.Equal(d) {
|
||||||
|
t.Errorf("m != d, decrypting failed")
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -37,6 +37,13 @@ https://en.wikipedia.org/wiki/Elliptic-curve_cryptography
|
|||||||
- [x] Add two points on the elliptic curve
|
- [x] Add two points on the elliptic curve
|
||||||
- [x] Multiply a point n times on the elliptic curve
|
- [x] Multiply a point n times on the elliptic curve
|
||||||
|
|
||||||
|
## ECC ElGamal
|
||||||
|
https://en.wikipedia.org/wiki/ElGamal_encryption
|
||||||
|
- [x] ECC ElGamal key generation
|
||||||
|
- [x] ECC ElGamal Encrypton
|
||||||
|
- [x] ECC ElGamal Decryption
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
To run all tests:
|
To run all tests:
|
||||||
```
|
```
|
||||||
|
|||||||
46
ecc/ecc.go
46
ecc/ecc.go
@@ -6,6 +6,7 @@ import (
|
|||||||
"math/big"
|
"math/big"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// EC is the data structure for the elliptic curve parameters
|
||||||
type EC struct {
|
type EC struct {
|
||||||
A *big.Int
|
A *big.Int
|
||||||
B *big.Int
|
B *big.Int
|
||||||
@@ -40,14 +41,29 @@ func (ec *EC) At(x *big.Int) (Point, Point, error) {
|
|||||||
return Point{x, y}, Point{x, new(big.Int).Sub(ec.Q, y)}, nil
|
return Point{x, y}, Point{x, new(big.Int).Sub(ec.Q, y)}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO add valid checker point function
|
// TODO add valid checker point function Valid()
|
||||||
|
|
||||||
|
// Neg returns the inverse of the P point on the elliptic curve
|
||||||
func (ec *EC) Neg(p Point) Point {
|
func (ec *EC) Neg(p Point) Point {
|
||||||
// TODO get error when point not found on the ec
|
// TODO get error when point not found on the ec
|
||||||
return Point{p.X, new(big.Int).Sub(ec.Q, p.Y)}
|
return Point{p.X, new(big.Int).Sub(ec.Q, p.Y)}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add adds two points p1 and p2 and gets q
|
// 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) {
|
func (ec *EC) Add(p1, p2 Point) (Point, error) {
|
||||||
if p1.Equal(zeroPoint) {
|
if p1.Equal(zeroPoint) {
|
||||||
return p2, nil
|
return p2, nil
|
||||||
@@ -69,7 +85,7 @@ func (ec *EC) Add(p1, p2 Point) (Point, error) {
|
|||||||
numerator = new(big.Int).Add(x23, ec.A)
|
numerator = new(big.Int).Add(x23, ec.A)
|
||||||
// 2 * y
|
// 2 * y
|
||||||
denominator = new(big.Int).Mul(big.NewInt(int64(2)), p1.Y)
|
denominator = new(big.Int).Mul(big.NewInt(int64(2)), p1.Y)
|
||||||
// (3 * x^2 + a) / (2 * y) mod ec.Q
|
// s = (3 * x^2 + a) / (2 * y) mod ec.Q
|
||||||
denInv := new(big.Int).ModInverse(denominator, ec.Q)
|
denInv := new(big.Int).ModInverse(denominator, ec.Q)
|
||||||
sRaw = new(big.Int).Mul(numerator, denInv)
|
sRaw = new(big.Int).Mul(numerator, denInv)
|
||||||
s = new(big.Int).Mod(sRaw, ec.Q)
|
s = new(big.Int).Mod(sRaw, ec.Q)
|
||||||
@@ -79,7 +95,7 @@ func (ec *EC) Add(p1, p2 Point) (Point, error) {
|
|||||||
numerator = new(big.Int).Sub(p1.Y, p2.Y)
|
numerator = new(big.Int).Sub(p1.Y, p2.Y)
|
||||||
// x0-x1
|
// x0-x1
|
||||||
denominator = new(big.Int).Sub(p1.X, p2.X)
|
denominator = new(big.Int).Sub(p1.X, p2.X)
|
||||||
// (y0-y1) / (x0-x1) mod ec.Q
|
// s = (y0-y1) / (x0-x1) mod ec.Q
|
||||||
denInv := new(big.Int).ModInverse(denominator, ec.Q)
|
denInv := new(big.Int).ModInverse(denominator, ec.Q)
|
||||||
sRaw = new(big.Int).Mul(numerator, denInv)
|
sRaw = new(big.Int).Mul(numerator, denInv)
|
||||||
s = new(big.Int).Mod(sRaw, ec.Q)
|
s = new(big.Int).Mod(sRaw, ec.Q)
|
||||||
@@ -104,17 +120,29 @@ func (ec *EC) Add(p1, p2 Point) (Point, error) {
|
|||||||
// q.Y = (s(p1.X - q.X) - p1.Y) mod ec.Q
|
// 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)
|
||||||
|
|
||||||
|
// negate q
|
||||||
|
// q = ec.Neg(q)
|
||||||
return q, nil
|
return q, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mul multiplies a point n times on the elliptic curve
|
// 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 int) (Point, error) {
|
||||||
var err error
|
var err error
|
||||||
for i := 0; i < n; i++ {
|
p2 := p
|
||||||
p, err = ec.Add(p, p)
|
r := zeroPoint
|
||||||
if err != nil {
|
for 0 < n {
|
||||||
return zeroPoint, err
|
if n&1 == 1 {
|
||||||
|
r, err = ec.Add(r, p2)
|
||||||
|
if err != nil {
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
n = n >> 1
|
||||||
|
p2, err = ec.Add(p2, p2)
|
||||||
|
if err != nil {
|
||||||
|
return p, err
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return p, nil
|
return r, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,46 @@
|
|||||||
package ecc
|
package ecc
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"math/big"
|
"math/big"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestECC(t *testing.T) {
|
func TestECC(t *testing.T) {
|
||||||
ec := NewEC(0, 7, 11)
|
ec := NewEC(0, 7, 11)
|
||||||
p1, p1_, err := ec.At(big.NewInt(int64(7)))
|
p1, p1i, err := ec.At(big.NewInt(int64(7)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if !p1.Equal(Point{big.NewInt(int64(7)), big.NewInt(int64(3))}) {
|
if !p1.Equal(Point{big.NewInt(int64(7)), big.NewInt(int64(3))}) {
|
||||||
t.Errorf("p1!=(7, 11)")
|
t.Errorf("p1!=(7, 11)")
|
||||||
}
|
}
|
||||||
if !p1_.Equal(Point{big.NewInt(int64(7)), big.NewInt(int64(8))}) {
|
if !p1i.Equal(Point{big.NewInt(int64(7)), big.NewInt(int64(8))}) {
|
||||||
t.Errorf("p1_!=(7, 8)")
|
t.Errorf("p1i!=(7, 8)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func TestNeg(t *testing.T) {
|
func TestNeg(t *testing.T) {
|
||||||
ec := NewEC(0, 7, 11)
|
ec := NewEC(0, 7, 11)
|
||||||
p1, p1_, err := ec.At(big.NewInt(int64(7)))
|
p1, p1i, err := ec.At(big.NewInt(int64(7)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
p1Neg := ec.Neg(p1)
|
p1Neg := ec.Neg(p1)
|
||||||
if !p1Neg.Equal(p1_) {
|
if !p1Neg.Equal(p1i) {
|
||||||
t.Errorf("p1Neg!=p1_")
|
t.Errorf("p1Neg!=p1i")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
func TestAdd(t *testing.T) {
|
func TestAdd(t *testing.T) {
|
||||||
ec := NewEC(0, 7, 11)
|
ec := NewEC(0, 7, 11)
|
||||||
p1, _, err := ec.At(big.NewInt(int64(7)))
|
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(7))}
|
||||||
if err != nil {
|
p2 := Point{big.NewInt(int64(2)), big.NewInt(int64(2))}
|
||||||
t.Errorf(err.Error())
|
|
||||||
}
|
|
||||||
p2, _, err := ec.At(big.NewInt(int64(6)))
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf(err.Error())
|
|
||||||
}
|
|
||||||
q, err := ec.Add(p1, p2)
|
q, err := ec.Add(p1, p2)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if !q.Equal(Point{big.NewInt(int64(2)), big.NewInt(int64(9))}) {
|
if !q.Equal(Point{big.NewInt(int64(3)), big.NewInt(int64(1))}) {
|
||||||
t.Errorf("q!=(2, 9)")
|
t.Errorf("q!=(3, 1)")
|
||||||
}
|
}
|
||||||
|
|
||||||
// check that q exists on the elliptic curve
|
// check that q exists on the elliptic curve
|
||||||
@@ -61,47 +56,50 @@ func TestAdd(t *testing.T) {
|
|||||||
|
|
||||||
func TestAddSamePoint(t *testing.T) {
|
func TestAddSamePoint(t *testing.T) {
|
||||||
ec := NewEC(0, 7, 11)
|
ec := NewEC(0, 7, 11)
|
||||||
p1, p1_, err := ec.At(big.NewInt(int64(4)))
|
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(7))}
|
||||||
if err != nil {
|
p1i := Point{big.NewInt(int64(4)), big.NewInt(int64(4))}
|
||||||
t.Errorf(err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
q, err := ec.Add(p1, p1)
|
q, err := ec.Add(p1, p1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if !q.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(6))}) {
|
if !q.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(5))}) {
|
||||||
t.Errorf("q!=(6, 6)")
|
t.Errorf("q!=(6, 5)")
|
||||||
}
|
}
|
||||||
|
|
||||||
q_, err := ec.Add(p1_, p1_)
|
q_, err := ec.Add(p1i, p1i)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if !q_.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(5))}) {
|
if !q_.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(6))}) {
|
||||||
t.Errorf("q_!=(6, 5)")
|
t.Errorf("q_!=(6, 6)")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMulEqualSelfAdd(t *testing.T) {
|
func TestMulEqualSelfAdd(t *testing.T) {
|
||||||
ec := NewEC(0, 7, 11)
|
ec := NewEC(0, 7, 29)
|
||||||
p1, _, err := ec.At(big.NewInt(int64(4)))
|
p1 := Point{big.NewInt(int64(11)), big.NewInt(int64(27))}
|
||||||
if err != nil {
|
|
||||||
t.Errorf(err.Error())
|
|
||||||
}
|
|
||||||
p1p1, err := ec.Add(p1, p1)
|
p1p1, err := ec.Add(p1, p1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
q, err := ec.Mul(p1, 1)
|
p1p1, err = ec.Add(p1p1, p1)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf(err.Error())
|
||||||
|
}
|
||||||
|
q, err := ec.Mul(p1, 3)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if !q.Equal(p1p1) {
|
if !q.Equal(p1p1) {
|
||||||
|
fmt.Println(q)
|
||||||
|
fmt.Println(p1p1)
|
||||||
t.Errorf("q!=p1*p1")
|
t.Errorf("q!=p1*p1")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMul(t *testing.T) {
|
func TestMul(t *testing.T) {
|
||||||
ec := NewEC(0, 7, 29)
|
ec := NewEC(0, 7, 29)
|
||||||
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(19))}
|
p1 := Point{big.NewInt(int64(4)), big.NewInt(int64(19))}
|
||||||
@@ -109,22 +107,22 @@ func TestMul(t *testing.T) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if !q3.Equal(Point{big.NewInt(int64(19)), big.NewInt(int64(15))}) {
|
if !q3.Equal(Point{big.NewInt(int64(6)), big.NewInt(int64(7))}) {
|
||||||
t.Errorf("q3!=(19, 15)")
|
t.Errorf("q3!=(6, 7)")
|
||||||
}
|
}
|
||||||
q7, err := ec.Mul(p1, 7)
|
q7, err := ec.Mul(p1, 7)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if !q7.Equal(Point{big.NewInt(int64(19)), big.NewInt(int64(15))}) {
|
if !q7.Equal(Point{big.NewInt(int64(19)), big.NewInt(int64(14))}) {
|
||||||
t.Errorf("q7!=(19, 15)")
|
t.Errorf("q7!=(19, 14)")
|
||||||
}
|
}
|
||||||
|
|
||||||
q8, err := ec.Mul(p1, 8)
|
q8, err := ec.Mul(p1, 8)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf(err.Error())
|
t.Errorf(err.Error())
|
||||||
}
|
}
|
||||||
if !q8.Equal(Point{big.NewInt(int64(4)), big.NewInt(int64(19))}) {
|
if !q8.Equal(Point{big.NewInt(int64(19)), big.NewInt(int64(15))}) {
|
||||||
t.Errorf("q8!=(4, 19)")
|
t.Errorf("q8!=(19, 15)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,13 @@ var (
|
|||||||
zeroPoint = Point{bigZero, bigZero}
|
zeroPoint = Point{bigZero, bigZero}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Point is the data structure for a point, containing the X and Y coordinates
|
||||||
type Point struct {
|
type Point struct {
|
||||||
X *big.Int
|
X *big.Int
|
||||||
Y *big.Int
|
Y *big.Int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Equal compares the X and Y coord of a Point and returns true if are the same
|
||||||
func (c1 *Point) Equal(c2 Point) bool {
|
func (c1 *Point) Equal(c2 Point) bool {
|
||||||
if !bytes.Equal(c1.X.Bytes(), c2.X.Bytes()) {
|
if !bytes.Equal(c1.X.Bytes(), c2.X.Bytes()) {
|
||||||
return false
|
return false
|
||||||
Reference in New Issue
Block a user