mirror of
https://github.com/arnaucube/cryptofun.git
synced 2026-02-28 05:16:46 +01:00
Schnorr signature implemented. ECC point multiplication with big int. Refactor of the code.
This commit is contained in:
@@ -4,14 +4,15 @@ import (
|
||||
"bytes"
|
||||
"math/big"
|
||||
|
||||
ecc "../ecc"
|
||||
// ecc "../ecc"
|
||||
"github.com/arnaucube/cryptofun/ecc"
|
||||
)
|
||||
|
||||
// DSA is the ECDSA data structure
|
||||
type DSA struct {
|
||||
EC ecc.EC
|
||||
G ecc.Point
|
||||
N int
|
||||
N *big.Int
|
||||
}
|
||||
|
||||
// NewDSA defines a new DSA data structure
|
||||
@@ -25,40 +26,48 @@ func NewDSA(ec ecc.EC, g ecc.Point) (DSA, error) {
|
||||
}
|
||||
|
||||
// PubK returns the public key Point calculated from the private key over the elliptic curve
|
||||
func (dsa DSA) PubK(privK int) (ecc.Point, error) {
|
||||
func (dsa DSA) PubK(privK *big.Int) (ecc.Point, error) {
|
||||
// privK: rand < ec.Q
|
||||
pubK, err := dsa.EC.Mul(dsa.G, privK)
|
||||
privKCopy := new(big.Int).SetBytes(privK.Bytes())
|
||||
pubK, err := dsa.EC.Mul(dsa.G, privKCopy)
|
||||
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()))
|
||||
|
||||
// Sign performs the ECDSA signature
|
||||
func (dsa DSA) Sign(hashval *big.Int, privK *big.Int, r *big.Int) ([2]*big.Int, error) {
|
||||
rCopy := new(big.Int).SetBytes(r.Bytes())
|
||||
m, err := dsa.EC.Mul(dsa.G, rCopy)
|
||||
if err != nil {
|
||||
return [2]*big.Int{}, err
|
||||
}
|
||||
// inv(r) mod dsa.N
|
||||
inv := new(big.Int).ModInverse(r, big.NewInt(int64(dsa.N)))
|
||||
inv := new(big.Int).ModInverse(r, dsa.N)
|
||||
// m.X * privK
|
||||
xPrivK := new(big.Int).Mul(m.X, big.NewInt(int64(privK)))
|
||||
privKCopy := new(big.Int).SetBytes(privK.Bytes())
|
||||
xPrivK := new(big.Int).Mul(m.X, privKCopy)
|
||||
// (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)))
|
||||
r2 := new(big.Int).Mod(a, dsa.N)
|
||||
return [2]*big.Int{m.X, r2}, err
|
||||
}
|
||||
|
||||
// Verify validates the ECDSA signature
|
||||
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)))
|
||||
w := new(big.Int).ModInverse(sig[1], dsa.N)
|
||||
wCopy := new(big.Int).SetBytes(w.Bytes())
|
||||
u1raw := new(big.Int).Mul(hashval, wCopy)
|
||||
u1 := new(big.Int).Mod(u1raw, dsa.N)
|
||||
wCopy = new(big.Int).SetBytes(w.Bytes())
|
||||
u2raw := new(big.Int).Mul(sig[0], wCopy)
|
||||
u2 := new(big.Int).Mod(u2raw, dsa.N)
|
||||
|
||||
gU1, err := dsa.EC.Mul(dsa.G, int(u1.Int64()))
|
||||
gU1, err := dsa.EC.Mul(dsa.G, u1)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
pubKU2, err := dsa.EC.Mul(pubK, int(u2.Int64()))
|
||||
pubKU2, err := dsa.EC.Mul(pubK, u2)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -66,6 +75,6 @@ func (dsa DSA) Verify(hashval *big.Int, sig [2]*big.Int, pubK ecc.Point) (bool,
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
pXmodN := new(big.Int).Mod(p.X, big.NewInt(int64(dsa.N)))
|
||||
pXmodN := new(big.Int).Mod(p.X, dsa.N)
|
||||
return bytes.Equal(pXmodN.Bytes(), sig[0].Bytes()), nil
|
||||
}
|
||||
|
||||
@@ -4,21 +4,20 @@ import (
|
||||
"math/big"
|
||||
"testing"
|
||||
|
||||
ecc "../ecc"
|
||||
"github.com/arnaucube/cryptofun/ecc"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
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
|
||||
assert.Nil(t, err)
|
||||
|
||||
privK := big.NewInt(int64(5))
|
||||
pubK, err := dsa.PubK(privK)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
if !pubK.Equal(ecc.Point{big.NewInt(int64(13)), big.NewInt(int64(9))}) {
|
||||
t.Errorf("pubK!=(13, 9)")
|
||||
}
|
||||
@@ -28,24 +27,18 @@ 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
|
||||
assert.Nil(t, err)
|
||||
|
||||
privK := big.NewInt(int64(5))
|
||||
pubK, err := dsa.PubK(privK)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
hashval := big.NewInt(int64(40))
|
||||
r := big.NewInt(int64(11))
|
||||
|
||||
sig, err := dsa.Sign(hashval, privK, r)
|
||||
if err != nil {
|
||||
t.Errorf(err.Error())
|
||||
}
|
||||
assert.Nil(t, err)
|
||||
|
||||
verified, err := dsa.Verify(hashval, sig, pubK)
|
||||
if !verified {
|
||||
t.Errorf("verified == false")
|
||||
}
|
||||
assert.True(t, verified)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user