-
Notifications
You must be signed in to change notification settings - Fork 0
/
sm2_verify.go
98 lines (87 loc) · 2.21 KB
/
sm2_verify.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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package sm2
import (
"math/big"
)
// VerifyBytes verify sigature is valid.
// The parameters is bytes.
func VerifyBytes(pubX, pubY, msg, uid, r, s []byte) bool {
pub := &PublicKey{
Curve: P256Sm2(),
X: new(big.Int).SetBytes(pubX),
Y: new(big.Int).SetBytes(pubY),
}
bigR := new(big.Int).SetBytes(r)
bigS := new(big.Int).SetBytes(s)
c := P256Sm2()
N := c.Params().N
one := new(big.Int).SetInt64(1)
if bigR.Cmp(one) < 0 || bigS.Cmp(one) < 0 {
return false
}
if bigR.Cmp(N) >= 0 || bigS.Cmp(N) >= 0 {
return false
}
za, err := ZA(pub, uid)
if err != nil {
return false
}
e, err := msgHash(za, msg)
if err != nil {
return false
}
t := new(big.Int).Add(bigR, bigS)
t.Mod(t, N)
if t.Sign() == 0 {
return false
}
var x *big.Int
x1, y1 := c.ScalarBaseMult(bigS.Bytes())
x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes())
x, _ = c.Add(x1, y1, x2, y2)
x.Add(x, e)
x.Mod(x, N)
return x.Cmp(bigR) == 0
}
// Sm2VerifyBytes verify sigature is valid.
// The parameters is bytes.
// PublicKey length is 64 bytes, it is uncompressed.
func Sm2VerifyBytes(publicKey, hash, signature []byte) bool {
pub := &PublicKey{
Curve: P256Sm2(),
X: new(big.Int).SetBytes(publicKey[1:33]),
Y: new(big.Int).SetBytes(publicKey[33:]),
}
bigR := new(big.Int).SetBytes(signature[:32])
bigS := new(big.Int).SetBytes(signature[32:])
c := P256Sm2()
N := c.Params().N
one := new(big.Int).SetInt64(1)
if bigR.Cmp(one) < 0 || bigS.Cmp(one) < 0 {
return false
}
if bigR.Cmp(N) >= 0 || bigS.Cmp(N) >= 0 {
return false
}
t := new(big.Int).Add(bigR, bigS)
t.Mod(t, N)
if t.Sign() == 0 {
return false
}
var x *big.Int
x1, y1 := c.ScalarBaseMult(bigS.Bytes())
x2, y2 := c.ScalarMult(pub.X, pub.Y, t.Bytes())
x, _ = c.Add(x1, y1, x2, y2)
e := new(big.Int).SetBytes(hash)
x.Add(x, e)
x.Mod(x, N)
return x.Cmp(bigR) == 0
}
// VerifyCompressedPubkey verify sigature is valid.
// The parameters is bytes.
// The publickey is compressed, the length is 33 bytes.
func VerifyCompressedPubkey(compressedPublicKey, hash, signature []byte) bool {
pubkey := Decompress(compressedPublicKey)
r := new(big.Int).SetBytes(signature[:32])
s := new(big.Int).SetBytes(signature[32:])
return Verify(pubkey, hash, r, s)
}