added Diffie-Hellman. Started impl ECC
arnaucode arnaucode@gmail.com
Sat, 28 Jul 2018 11:43:34 +0200
7 files changed,
234 insertions(+),
3 deletions(-)
M
README.md
→
README.md
@@ -1,4 +1,4 @@
-# cryptofun +# cryptofun [](https://goreportcard.com/report/github.com/arnaucode/cryptofun) Crypto algorithms from scratch. Academic purposes only.@@ -23,7 +23,15 @@ - [x] Homomorphic Addition
## Shamir Secret Sharing https://en.wikipedia.org/wiki/Shamir%27s_Secret_Sharing -- [x] create secret sharing from NumOfSecretsNeed, NumOfShares, RandPointP, SecretToShare +- [x] create secret sharing from number of secrets needed, number of shares, random point p, secret to share - [x] Lagrange Interpolation to restore the secret from the shares +## Diffie-Hellman +https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange +- [x] key exchange + ## ECC +https://en.wikipedia.org/wiki/Elliptic-curve_cryptography +- [x] define elliptic curve +- [x] get point at X +- [x] Add two points on the elliptic curve
A
dh/dh_test.go
@@ -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") + } +}
A
ecc/coord.go
@@ -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 +}
A
ecc/ecc.go
@@ -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 +}
A
ecc/ecc_test.go
@@ -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") + } + +}
M
secrets/sercrets.go
→
secrets/sercrets.go
@@ -10,11 +10,11 @@ const (
bits = 1024 ) +// Create calculates the secrets to share from given parameters // t: number of secrets needed // n: number of shares // p: random point // k: secret to share -// Create calculates the secrets to share from given parameters func Create(t, n, p, k *big.Int) (result [][]*big.Int, err error) { if k.Cmp(p) > 0 { return nil, errors.New("Error: need k<p. k: " + k.String() + ", p: " + p.String())