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