mirror of
https://github.com/arnaucube/cryptofun.git
synced 2026-02-28 13:26:40 +01:00
added Diffie-Hellman. Started impl ECC
This commit is contained in:
12
README.md
12
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 @@ 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
|
||||
|
||||
45
dh/dh_test.go
Normal file
45
dh/dh_test.go
Normal file
@@ -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
ecc/coord.go
Normal file
23
ecc/coord.go
Normal file
@@ -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
ecc/ecc.go
Normal file
83
ecc/ecc.go
Normal file
@@ -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
ecc/ecc_test.go
Normal file
71
ecc/ecc_test.go
Normal file
@@ -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")
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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())
|
||||
|
||||
Reference in New Issue
Block a user