Browse Source

added Diffie-Hellman. Started impl ECC

master
arnaucode 5 years ago
parent
commit
57d3547cd8
7 changed files with 234 additions and 3 deletions
  1. +10
    -2
      README.md
  2. +1
    -0
      dh/dh.go
  3. +45
    -0
      dh/dh_test.go
  4. +23
    -0
      ecc/coord.go
  5. +83
    -0
      ecc/ecc.go
  6. +71
    -0
      ecc/ecc_test.go
  7. +1
    -1
      secrets/sercrets.go

+ 10
- 2
README.md

@ -1,4 +1,4 @@
# cryptofun
# cryptofun [![Go Report Card](https://goreportcard.com/badge/github.com/arnaucode/cryptofun)](https://goreportcard.com/report/github.com/arnaucode/cryptofun)
Crypto algorithms from scratch. Academic purposes only.
@ -23,7 +23,15 @@ https://en.wikipedia.org/wiki/Paillier_cryptosystem
## 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

+ 1
- 0
dh/dh.go

@ -0,0 +1 @@
package dh

+ 45
- 0
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")
}
}

+ 23
- 0
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
}

+ 83
- 0
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
}

+ 71
- 0
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")
}
}

+ 1
- 1
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())

Loading…
Cancel
Save