Source file
src/crypto/ecdsa/ecdsa_legacy.go
1
2
3
4
5 package ecdsa
6
7 import (
8 "crypto/elliptic"
9 "errors"
10 "io"
11 "math/big"
12
13 "golang.org/x/crypto/cryptobyte"
14 "golang.org/x/crypto/cryptobyte/asn1"
15 )
16
17
18
19
20 func generateLegacy(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
21 k, err := randFieldElement(c, rand)
22 if err != nil {
23 return nil, err
24 }
25
26 priv := new(PrivateKey)
27 priv.PublicKey.Curve = c
28 priv.D = k
29 priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
30 return priv, nil
31 }
32
33
34
35
36 func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
37 orderBits := c.Params().N.BitLen()
38 orderBytes := (orderBits + 7) / 8
39 if len(hash) > orderBytes {
40 hash = hash[:orderBytes]
41 }
42
43 ret := new(big.Int).SetBytes(hash)
44 excess := len(hash)*8 - orderBits
45 if excess > 0 {
46 ret.Rsh(ret, uint(excess))
47 }
48 return ret
49 }
50
51 var errZeroParam = errors.New("zero parameter")
52
53
54
55
56
57
58 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
59 sig, err := SignASN1(rand, priv, hash)
60 if err != nil {
61 return nil, nil, err
62 }
63
64 r, s = new(big.Int), new(big.Int)
65 var inner cryptobyte.String
66 input := cryptobyte.String(sig)
67 if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
68 !input.Empty() ||
69 !inner.ReadASN1Integer(r) ||
70 !inner.ReadASN1Integer(s) ||
71 !inner.Empty() {
72 return nil, nil, errors.New("invalid ASN.1 from SignASN1")
73 }
74 return r, s, nil
75 }
76
77 func signLegacy(priv *PrivateKey, csprng io.Reader, hash []byte) (sig []byte, err error) {
78 c := priv.Curve
79
80
81 N := c.Params().N
82 if N.Sign() == 0 {
83 return nil, errZeroParam
84 }
85 var k, kInv, r, s *big.Int
86 for {
87 for {
88 k, err = randFieldElement(c, csprng)
89 if err != nil {
90 return nil, err
91 }
92
93 kInv = new(big.Int).ModInverse(k, N)
94
95 r, _ = c.ScalarBaseMult(k.Bytes())
96 r.Mod(r, N)
97 if r.Sign() != 0 {
98 break
99 }
100 }
101
102 e := hashToInt(hash, c)
103 s = new(big.Int).Mul(priv.D, r)
104 s.Add(s, e)
105 s.Mul(s, kInv)
106 s.Mod(s, N)
107 if s.Sign() != 0 {
108 break
109 }
110 }
111
112 return encodeSignature(r.Bytes(), s.Bytes())
113 }
114
115
116
117
118
119
120
121 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
122 if r.Sign() <= 0 || s.Sign() <= 0 {
123 return false
124 }
125 sig, err := encodeSignature(r.Bytes(), s.Bytes())
126 if err != nil {
127 return false
128 }
129 return VerifyASN1(pub, hash, sig)
130 }
131
132 func verifyLegacy(pub *PublicKey, hash []byte, sig []byte) bool {
133 rBytes, sBytes, err := parseSignature(sig)
134 if err != nil {
135 return false
136 }
137 r, s := new(big.Int).SetBytes(rBytes), new(big.Int).SetBytes(sBytes)
138
139 c := pub.Curve
140 N := c.Params().N
141
142 if r.Sign() <= 0 || s.Sign() <= 0 {
143 return false
144 }
145 if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
146 return false
147 }
148
149
150 e := hashToInt(hash, c)
151 w := new(big.Int).ModInverse(s, N)
152
153 u1 := e.Mul(e, w)
154 u1.Mod(u1, N)
155 u2 := w.Mul(r, w)
156 u2.Mod(u2, N)
157
158 x1, y1 := c.ScalarBaseMult(u1.Bytes())
159 x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
160 x, y := c.Add(x1, y1, x2, y2)
161
162 if x.Sign() == 0 && y.Sign() == 0 {
163 return false
164 }
165 x.Mod(x, N)
166 return x.Cmp(r) == 0
167 }
168
169 var one = new(big.Int).SetInt64(1)
170
171
172
173 func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
174
175
176
177 for {
178 N := c.Params().N
179 b := make([]byte, (N.BitLen()+7)/8)
180 if _, err = io.ReadFull(rand, b); err != nil {
181 return
182 }
183 if excess := len(b)*8 - N.BitLen(); excess > 0 {
184 b[0] >>= excess
185 }
186 k = new(big.Int).SetBytes(b)
187 if k.Sign() != 0 && k.Cmp(N) < 0 {
188 return
189 }
190 }
191 }
192
View as plain text