Browse Source

added ECDSA Sign and Verify signature

master
arnaucode 5 years ago
parent
commit
0266c94332
4 changed files with 133 additions and 2 deletions
  1. +9
    -0
      README.md
  2. +2
    -2
      ecc/ecc_test.go
  3. +71
    -0
      ecdsa/ecdsa.go
  4. +51
    -0
      ecdsa/ecdsa_test.go

+ 9
- 0
README.md

@ -34,6 +34,7 @@ https://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange
https://en.wikipedia.org/wiki/Elliptic-curve_cryptography
- [x] define elliptic curve
- [x] get point at X
- [x] get order of a Point on the elliptic curve
- [x] Add two points on the elliptic curve
- [x] Multiply a point n times on the elliptic curve
@ -43,6 +44,14 @@ https://en.wikipedia.org/wiki/ElGamal_encryption
- [x] ECC ElGamal Encrypton
- [x] ECC ElGamal Decryption
## ECC ECDSA
https://en.wikipedia.org/wiki/Elliptic_Curve_Digital_Signature_Algorithm
- [x] define ECDSA data structure
- [x] ECDSA Sign
- [x] ECDSA Verify signature
---
To run all tests:

+ 2
- 2
ecc/ecc_test.go

@ -44,11 +44,11 @@ func TestAdd(t *testing.T) {
}
// check that q exists on the elliptic curve
pt, pt_, err := ec.At(q.X)
pt, pti, err := ec.At(q.X)
if err != nil {
t.Errorf(err.Error())
}
if !q.Equal(pt) && !q.Equal(pt_) {
if !q.Equal(pt) && !q.Equal(pti) {
t.Errorf("q not exist on the elliptic curve")
}

+ 71
- 0
ecdsa/ecdsa.go

@ -0,0 +1,71 @@
package ecdsa
import (
"bytes"
"math/big"
ecc "../ecc"
)
// DSA is the ECDSA data structure
type DSA struct {
EC ecc.EC
G ecc.Point
N int
}
// NewDSA defines a new DSA data structure
func NewDSA(ec ecc.EC, g ecc.Point) (DSA, error) {
var dsa DSA
var err error
dsa.EC = ec
dsa.G = g
dsa.N, err = ec.Order(g)
return dsa, err
}
// PubK returns the public key Point calculated from the private key over the elliptic curve
func (dsa DSA) PubK(privK int) (ecc.Point, error) {
// privK: rand < ec.Q
pubK, err := dsa.EC.Mul(dsa.G, privK)
return pubK, err
}
func (dsa DSA) Sign(hashval *big.Int, privK int, r *big.Int) ([2]*big.Int, error) {
m, err := dsa.EC.Mul(dsa.G, int(r.Int64()))
if err != nil {
return [2]*big.Int{}, err
}
// inv(r) mod dsa.N
inv := new(big.Int).ModInverse(r, big.NewInt(int64(dsa.N)))
// m.X * privK
xPrivK := new(big.Int).Mul(m.X, big.NewInt(int64(privK)))
// (hashval + m.X * privK)
hashvalXPrivK := new(big.Int).Add(hashval, xPrivK)
// inv * (hashval + m.X * privK) mod dsa.N
a := new(big.Int).Mul(inv, hashvalXPrivK)
r2 := new(big.Int).Mod(a, big.NewInt(int64(dsa.N)))
return [2]*big.Int{m.X, r2}, err
}
func (dsa DSA) Verify(hashval *big.Int, sig [2]*big.Int, pubK ecc.Point) (bool, error) {
w := new(big.Int).ModInverse(sig[1], big.NewInt(int64(dsa.N)))
u1raw := new(big.Int).Mul(hashval, w)
u1 := new(big.Int).Mod(u1raw, big.NewInt(int64(dsa.N)))
u2raw := new(big.Int).Mul(sig[0], w)
u2 := new(big.Int).Mod(u2raw, big.NewInt(int64(dsa.N)))
gU1, err := dsa.EC.Mul(dsa.G, int(u1.Int64()))
if err != nil {
return false, err
}
pubKU2, err := dsa.EC.Mul(pubK, int(u2.Int64()))
if err != nil {
return false, err
}
p, err := dsa.EC.Add(gU1, pubKU2)
if err != nil {
return false, err
}
pXmodN := new(big.Int).Mod(p.X, big.NewInt(int64(dsa.N)))
return bytes.Equal(pXmodN.Bytes(), sig[0].Bytes()), nil
}

+ 51
- 0
ecdsa/ecdsa_test.go

@ -0,0 +1,51 @@
package ecdsa
import (
"math/big"
"testing"
ecc "../ecc"
)
func TestNewECDSA(t *testing.T) {
ec := ecc.NewEC(1, 18, 19)
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
dsa, err := NewDSA(ec, g)
if err != nil {
t.Errorf(err.Error())
}
privK := 5
pubK, err := dsa.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 TestECDSASignAndVerify(t *testing.T) {
ec := ecc.NewEC(1, 18, 19)
g := ecc.Point{big.NewInt(int64(7)), big.NewInt(int64(11))}
dsa, err := NewDSA(ec, g)
if err != nil {
t.Errorf(err.Error())
}
privK := 5
pubK, err := dsa.PubK(privK)
if err != nil {
t.Errorf(err.Error())
}
hashval := big.NewInt(int64(40))
r := big.NewInt(int64(11))
sig, err := dsa.Sign(hashval, privK, r)
if err != nil {
t.Errorf(err.Error())
}
verified, err := dsa.Verify(hashval, sig, pubK)
if !verified {
t.Errorf("verified == false")
}
}

Loading…
Cancel
Save