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)
 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}