arnaucube
arnaucube/cryptofunPublic Self-hosted repository
cryptofun/ecdsa/ecdsa.go
ecdsa/ecdsa.goRaw
 1package ecdsa
 2
 3import (
 4	"bytes"
 5	"math/big"
 6
 7	// ecc "../ecc"
 8	"github.com/arnaucube/cryptofun/ecc"
 9)
10
11// DSA is the ECDSA data structure
12type DSA struct {
13	EC ecc.EC
14	G  ecc.Point
15	N  *big.Int
16}
17
18// NewDSA defines a new DSA data structure
19func NewDSA(ec ecc.EC, g ecc.Point) (DSA, error) {
20	var dsa DSA
21	var err error
22	dsa.EC = ec
23	dsa.G = g
24	dsa.N, err = ec.Order(g)
25	return dsa, err
26}
27
28// PubK returns the public key Point calculated from the private key over the elliptic curve
29func (dsa DSA) PubK(privK *big.Int) (ecc.Point, error) {
30	// privK: rand < ec.Q
31	privKCopy := new(big.Int).SetBytes(privK.Bytes())
32	pubK, err := dsa.EC.Mul(dsa.G, privKCopy)
33	return pubK, err
34}
35
36// Sign performs the ECDSA signature
37func (dsa DSA) Sign(hashval *big.Int, privK *big.Int, r *big.Int) ([2]*big.Int, error) {
38	rCopy := new(big.Int).SetBytes(r.Bytes())
39	m, err := dsa.EC.Mul(dsa.G, rCopy)
40	if err != nil {
41		return [2]*big.Int{}, err
42	}
43	// inv(r) mod dsa.N
44	inv := new(big.Int).ModInverse(r, dsa.N)
45	// m.X * privK
46	privKCopy := new(big.Int).SetBytes(privK.Bytes())
47	xPrivK := new(big.Int).Mul(m.X, privKCopy)
48	// (hashval + m.X * privK)
49	hashvalXPrivK := new(big.Int).Add(hashval, xPrivK)
50	// inv * (hashval + m.X * privK) mod dsa.N
51	a := new(big.Int).Mul(inv, hashvalXPrivK)
52	r2 := new(big.Int).Mod(a, dsa.N)
53	return [2]*big.Int{m.X, r2}, err
54}
55
56// Verify validates the ECDSA signature
57func (dsa DSA) Verify(hashval *big.Int, sig [2]*big.Int, pubK ecc.Point) (bool, error) {
58	w := new(big.Int).ModInverse(sig[1], dsa.N)
59	wCopy := new(big.Int).SetBytes(w.Bytes())
60	u1raw := new(big.Int).Mul(hashval, wCopy)
61	u1 := new(big.Int).Mod(u1raw, dsa.N)
62	wCopy = new(big.Int).SetBytes(w.Bytes())
63	u2raw := new(big.Int).Mul(sig[0], wCopy)
64	u2 := new(big.Int).Mod(u2raw, dsa.N)
65
66	gU1, err := dsa.EC.Mul(dsa.G, u1)
67	if err != nil {
68		return false, err
69	}
70	pubKU2, err := dsa.EC.Mul(pubK, u2)
71	if err != nil {
72		return false, err
73	}
74	p, err := dsa.EC.Add(gU1, pubKU2)
75	if err != nil {
76		return false, err
77	}
78	pXmodN := new(big.Int).Mod(p.X, dsa.N)
79	return bytes.Equal(pXmodN.Bytes(), sig[0].Bytes()), nil
80}