@ -0,0 +1 @@ |
|||||
|
package dh |
@ -0,0 +1,45 @@ |
|||||
|
package dh |
||||
|
|
||||
|
import ( |
||||
|
"crypto/rand" |
||||
|
"math/big" |
||||
|
"testing" |
||||
|
) |
||||
|
|
||||
|
const ( |
||||
|
bits = 2048 |
||||
|
) |
||||
|
|
||||
|
func TestDiffieHellman(t *testing.T) { |
||||
|
p, err := rand.Prime(rand.Reader, bits/2) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
g, err := rand.Prime(rand.Reader, bits/2) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
|
||||
|
max, err := rand.Prime(rand.Reader, bits/2) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
a, err := rand.Int(rand.Reader, max) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
b, err := rand.Int(rand.Reader, max) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
|
||||
|
A := new(big.Int).Exp(g, a, p) |
||||
|
B := new(big.Int).Exp(g, b, p) |
||||
|
|
||||
|
sA := new(big.Int).Exp(B, a, p) |
||||
|
sB := new(big.Int).Exp(A, b, p) |
||||
|
|
||||
|
if sA.Int64() != sB.Int64() { |
||||
|
t.Errorf("secret not equal") |
||||
|
} |
||||
|
} |
@ -0,0 +1,23 @@ |
|||||
|
package ecc |
||||
|
|
||||
|
import "math/big" |
||||
|
|
||||
|
var ( |
||||
|
bigZero = big.NewInt(int64(0)) |
||||
|
zeroPoint = Point{bigZero, bigZero} |
||||
|
) |
||||
|
|
||||
|
type Point struct { |
||||
|
X *big.Int |
||||
|
Y *big.Int |
||||
|
} |
||||
|
|
||||
|
func (c1 *Point) Equal(c2 Point) bool { |
||||
|
if c1.X.Int64() != c2.X.Int64() { |
||||
|
return false |
||||
|
} |
||||
|
if c1.Y.Int64() != c2.Y.Int64() { |
||||
|
return false |
||||
|
} |
||||
|
return true |
||||
|
} |
@ -0,0 +1,83 @@ |
|||||
|
package ecc |
||||
|
|
||||
|
import ( |
||||
|
"errors" |
||||
|
"math/big" |
||||
|
) |
||||
|
|
||||
|
type EC struct { |
||||
|
A *big.Int |
||||
|
B *big.Int |
||||
|
Q *big.Int |
||||
|
} |
||||
|
|
||||
|
/* |
||||
|
(y^2 = x^3 + Ax + B ) mod Q |
||||
|
Q: 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)) |
||||
|
return ec |
||||
|
} |
||||
|
|
||||
|
// At gets a point x in the curve
|
||||
|
func (ec *EC) At(x *big.Int) (Point, Point, error) { |
||||
|
if x.Cmp(ec.Q) > 0 { |
||||
|
return Point{}, Point{}, errors.New("x<ec.Q") |
||||
|
} |
||||
|
// y^2 = (x^3 + ax + b) mod q
|
||||
|
// y = sqrt (x^3 + ax + b) mod q
|
||||
|
// x^3
|
||||
|
x3 := new(big.Int).Exp(x, big.NewInt(int64(3)), nil) |
||||
|
// a^x
|
||||
|
aX := new(big.Int).Mul(ec.A, x) |
||||
|
// x^3 + a^x
|
||||
|
x3aX := new(big.Int).Add(x3, aX) |
||||
|
// x^3 + a^x + b
|
||||
|
x3aXb := new(big.Int).Add(x3aX, ec.B) |
||||
|
// y = sqrt (x^3 + ax + b) mod q
|
||||
|
y := new(big.Int).ModSqrt(x3aXb, ec.Q) |
||||
|
return Point{x, y}, Point{x, new(big.Int).Sub(ec.Q, y)}, nil |
||||
|
} |
||||
|
|
||||
|
// TODO add valid checker point function
|
||||
|
|
||||
|
func (ec *EC) Neg(p Point) Point { |
||||
|
// TODO get error when point not found on the ec
|
||||
|
return Point{p.X, new(big.Int).Sub(ec.Q, p.Y)} |
||||
|
} |
||||
|
|
||||
|
// Add adds two points p1 and p2 and gets q
|
||||
|
func (ec *EC) Add(p1, p2 Point) (Point, error) { |
||||
|
if p1.Equal(zeroPoint) { |
||||
|
return p2, errors.New("p1==(0, 0)") |
||||
|
} |
||||
|
if p2.Equal(zeroPoint) { |
||||
|
return p1, errors.New("p1==(0, 0)") |
||||
|
} |
||||
|
// 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) |
||||
|
// q: new point
|
||||
|
var q Point |
||||
|
// s^2
|
||||
|
s2 := new(big.Int).Exp(s, big.NewInt(int64(2)), nil) |
||||
|
// s^2 - p1.X
|
||||
|
x2Xo := new(big.Int).Sub(s2, p1.X) |
||||
|
// s^2 - p1.X - p2.X
|
||||
|
x2XoX2 := new(big.Int).Sub(x2Xo, p2.X) |
||||
|
q.X = new(big.Int).Mod(x2XoX2, ec.Q) |
||||
|
|
||||
|
// p1.X - q.X
|
||||
|
xoX2 := new(big.Int).Sub(p1.X, q.X) |
||||
|
// s(p1.X - q.X)
|
||||
|
sXoX2 := new(big.Int).Mul(s, xoX2) |
||||
|
// s(p1.X - q.X) - p1.Y
|
||||
|
sXoX2Y := new(big.Int).Sub(sXoX2, p1.Y) |
||||
|
q.Y = new(big.Int).Mod(sXoX2Y, ec.Q) |
||||
|
|
||||
|
return q, nil |
||||
|
} |
@ -0,0 +1,71 @@ |
|||||
|
package ecc |
||||
|
|
||||
|
import ( |
||||
|
"fmt" |
||||
|
"math/big" |
||||
|
"testing" |
||||
|
) |
||||
|
|
||||
|
func TestECC(t *testing.T) { |
||||
|
ec := NewEC(0, 7, 11) |
||||
|
p1, p1_, err := ec.At(big.NewInt(int64(7))) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
if !p1.Equal(Point{big.NewInt(int64(7)), big.NewInt(int64(3))}) { |
||||
|
t.Errorf("p1!=(7, 11)") |
||||
|
} |
||||
|
if !p1_.Equal(Point{big.NewInt(int64(7)), big.NewInt(int64(8))}) { |
||||
|
t.Errorf("p1_!=(7, 8)") |
||||
|
} |
||||
|
} |
||||
|
func TestNeg(t *testing.T) { |
||||
|
ec := NewEC(0, 7, 11) |
||||
|
p1, p1_, err := ec.At(big.NewInt(int64(7))) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
p1Neg := ec.Neg(p1) |
||||
|
if !p1Neg.Equal(p1_) { |
||||
|
t.Errorf("p1Neg!=p1_") |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
func TestAdd(t *testing.T) { |
||||
|
fmt.Println("y^2 = x^3 + 7") |
||||
|
fmt.Print("ec: ") |
||||
|
ec := NewEC(0, 7, 11) |
||||
|
fmt.Println(ec) |
||||
|
p1, _, err := ec.At(big.NewInt(int64(7))) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
fmt.Print("p1: ") |
||||
|
fmt.Println(p1) |
||||
|
p2, _, err := ec.At(big.NewInt(int64(6))) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
fmt.Print("p2: ") |
||||
|
fmt.Println(p2) |
||||
|
|
||||
|
q, err := ec.Add(p1, p2) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
fmt.Print("q: ") |
||||
|
fmt.Println(q) |
||||
|
if !q.Equal(Point{big.NewInt(int64(2)), big.NewInt(int64(9))}) { |
||||
|
t.Errorf("q!=(2, 9)") |
||||
|
} |
||||
|
|
||||
|
// check that q exists on the elliptic curve
|
||||
|
pt, pt_, err := ec.At(q.X) |
||||
|
if err != nil { |
||||
|
t.Errorf(err.Error()) |
||||
|
} |
||||
|
if !q.Equal(pt) && !q.Equal(pt_) { |
||||
|
t.Errorf("q not exist on the elliptic curve") |
||||
|
} |
||||
|
|
||||
|
} |