-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvalidate.go
76 lines (63 loc) · 1.6 KB
/
validate.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
package digisig
import (
"math/big"
curve "github.com/dece2183/go-digisig/ellipticCurve"
"github.com/dece2183/go-stribog"
)
type Validator struct {
// external parameters
p, a, q *big.Int
_P, _Q curve.Point
hashFunc *stribog.Stribog
// internal variables
hashSize int
curve *curve.Curve
}
func NewValidator(pubKey curve.Point, p, a, q *big.Int, P curve.Point, hashFunc *stribog.Stribog) *Validator {
v := &Validator{
p: p,
a: a,
q: q,
_P: P,
_Q: pubKey,
hashFunc: hashFunc,
hashSize: hashFunc.Size(),
curve: curve.NewCurve(p, a),
}
return v
}
func (v *Validator) Validate(msg []byte, signature []byte) bool {
r, s := v.extract(signature)
if r.Cmp(big.NewInt(0)) <= 0 || r.Cmp(v.q) >= 0 ||
s.Cmp(big.NewInt(0)) <= 0 || s.Cmp(v.q) >= 0 {
return false
}
hs := new(big.Int).SetBytes(v.hashFunc.CheckSum(msg))
e := v.calcE(hs)
C := v.calcC(e, s, r).X
R := C.Mod(C, v.q)
return R.Cmp(r) == 0
}
func (v *Validator) extract(signature []byte) (r, s *big.Int) {
r = new(big.Int).SetBytes(signature[0:v.hashSize])
s = new(big.Int).SetBytes(signature[v.hashSize:])
return
}
func (v *Validator) calcE(hs *big.Int) *big.Int {
e := hs.Mod(hs, v.q)
if e.Cmp(big.NewInt(0)) == 0 {
return big.NewInt(1)
}
return e
}
func (v *Validator) calcC(e, s, r *big.Int) curve.Point {
_v := e.ModInverse(e, v.q)
// z1 = (s * _v) % v.q
z1 := new(big.Int).Mul(s, _v)
z1 = z1.Mod(z1, v.q)
// z2 = (-1 * (r * _v)) % v.q;
z2 := new(big.Int).Mul(r, _v)
z2 = z2.Neg(z2)
z2 = z2.Mod(z2, v.q)
return v.curve.Sum(v.curve.Scalar(z1, v._P), v.curve.Scalar(z2, v._Q))
}