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}