Source file src/pkg/crypto/ecdsa/ecdsa.go
1
2
3
4
5
6
7
8
9
10
11 package ecdsa
12
13
14
15
16
17
18
19 import (
20 "crypto"
21 "crypto/aes"
22 "crypto/cipher"
23 "crypto/elliptic"
24 "crypto/internal/randutil"
25 "crypto/sha512"
26 "encoding/asn1"
27 "errors"
28 "io"
29 "math/big"
30 )
31
32
33 type invertible interface {
34
35 Inverse(k *big.Int) *big.Int
36 }
37
38
39 type combinedMult interface {
40 CombinedMult(bigX, bigY *big.Int, baseScalar, scalar []byte) (x, y *big.Int)
41 }
42
43 const (
44 aesIV = "IV for ECDSA CTR"
45 )
46
47
48 type PublicKey struct {
49 elliptic.Curve
50 X, Y *big.Int
51 }
52
53
54 type PrivateKey struct {
55 PublicKey
56 D *big.Int
57 }
58
59 type ecdsaSignature struct {
60 R, S *big.Int
61 }
62
63
64 func (priv *PrivateKey) Public() crypto.PublicKey {
65 return &priv.PublicKey
66 }
67
68
69
70
71
72
73
74
75 func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
76 r, s, err := Sign(rand, priv, digest)
77 if err != nil {
78 return nil, err
79 }
80
81 return asn1.Marshal(ecdsaSignature{r, s})
82 }
83
84 var one = new(big.Int).SetInt64(1)
85
86
87
88 func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
89 params := c.Params()
90 b := make([]byte, params.BitSize/8+8)
91 _, err = io.ReadFull(rand, b)
92 if err != nil {
93 return
94 }
95
96 k = new(big.Int).SetBytes(b)
97 n := new(big.Int).Sub(params.N, one)
98 k.Mod(k, n)
99 k.Add(k, one)
100 return
101 }
102
103
104 func GenerateKey(c elliptic.Curve, rand io.Reader) (*PrivateKey, error) {
105 k, err := randFieldElement(c, rand)
106 if err != nil {
107 return nil, err
108 }
109
110 priv := new(PrivateKey)
111 priv.PublicKey.Curve = c
112 priv.D = k
113 priv.PublicKey.X, priv.PublicKey.Y = c.ScalarBaseMult(k.Bytes())
114 return priv, nil
115 }
116
117
118
119
120
121
122
123 func hashToInt(hash []byte, c elliptic.Curve) *big.Int {
124 orderBits := c.Params().N.BitLen()
125 orderBytes := (orderBits + 7) / 8
126 if len(hash) > orderBytes {
127 hash = hash[:orderBytes]
128 }
129
130 ret := new(big.Int).SetBytes(hash)
131 excess := len(hash)*8 - orderBits
132 if excess > 0 {
133 ret.Rsh(ret, uint(excess))
134 }
135 return ret
136 }
137
138
139
140
141
142 func fermatInverse(k, N *big.Int) *big.Int {
143 two := big.NewInt(2)
144 nMinus2 := new(big.Int).Sub(N, two)
145 return new(big.Int).Exp(k, nMinus2, N)
146 }
147
148 var errZeroParam = errors.New("zero parameter")
149
150
151
152
153
154
155 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
156 randutil.MaybeReadByte(rand)
157
158
159 entropylen := (priv.Curve.Params().BitSize + 7) / 16
160 if entropylen > 32 {
161 entropylen = 32
162 }
163 entropy := make([]byte, entropylen)
164 _, err = io.ReadFull(rand, entropy)
165 if err != nil {
166 return
167 }
168
169
170 md := sha512.New()
171 md.Write(priv.D.Bytes())
172 md.Write(entropy)
173 md.Write(hash)
174 key := md.Sum(nil)[:32]
175
176
177
178 block, err := aes.NewCipher(key)
179 if err != nil {
180 return nil, nil, err
181 }
182
183
184
185 csprng := cipher.StreamReader{
186 R: zeroReader,
187 S: cipher.NewCTR(block, []byte(aesIV)),
188 }
189
190
191 c := priv.PublicKey.Curve
192 N := c.Params().N
193 if N.Sign() == 0 {
194 return nil, nil, errZeroParam
195 }
196 var k, kInv *big.Int
197 for {
198 for {
199 k, err = randFieldElement(c, csprng)
200 if err != nil {
201 r = nil
202 return
203 }
204
205 if in, ok := priv.Curve.(invertible); ok {
206 kInv = in.Inverse(k)
207 } else {
208 kInv = fermatInverse(k, N)
209 }
210
211 r, _ = priv.Curve.ScalarBaseMult(k.Bytes())
212 r.Mod(r, N)
213 if r.Sign() != 0 {
214 break
215 }
216 }
217
218 e := hashToInt(hash, c)
219 s = new(big.Int).Mul(priv.D, r)
220 s.Add(s, e)
221 s.Mul(s, kInv)
222 s.Mod(s, N)
223 if s.Sign() != 0 {
224 break
225 }
226 }
227
228 return
229 }
230
231
232
233 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
234
235 c := pub.Curve
236 N := c.Params().N
237
238 if r.Sign() <= 0 || s.Sign() <= 0 {
239 return false
240 }
241 if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
242 return false
243 }
244 e := hashToInt(hash, c)
245
246 var w *big.Int
247 if in, ok := c.(invertible); ok {
248 w = in.Inverse(s)
249 } else {
250 w = new(big.Int).ModInverse(s, N)
251 }
252
253 u1 := e.Mul(e, w)
254 u1.Mod(u1, N)
255 u2 := w.Mul(r, w)
256 u2.Mod(u2, N)
257
258
259 var x, y *big.Int
260 if opt, ok := c.(combinedMult); ok {
261 x, y = opt.CombinedMult(pub.X, pub.Y, u1.Bytes(), u2.Bytes())
262 } else {
263 x1, y1 := c.ScalarBaseMult(u1.Bytes())
264 x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
265 x, y = c.Add(x1, y1, x2, y2)
266 }
267
268 if x.Sign() == 0 && y.Sign() == 0 {
269 return false
270 }
271 x.Mod(x, N)
272 return x.Cmp(r) == 0
273 }
274
275 type zr struct {
276 io.Reader
277 }
278
279
280 func (z *zr) Read(dst []byte) (n int, err error) {
281 for i := range dst {
282 dst[i] = 0
283 }
284 return len(dst), nil
285 }
286
287 var zeroReader = &zr{}
288
View as plain text