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 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
119 if r.Sign() <= 0 || s.Sign() <= 0 {
120 return false
121 }
122 sig, err := encodeSignature(r.Bytes(), s.Bytes())
123 if err != nil {
124 return false
125 }
126 return VerifyASN1(pub, hash, sig)
127 }
128
129 func verifyLegacy(pub *PublicKey, hash []byte, sig []byte) bool {
130 rBytes, sBytes, err := parseSignature(sig)
131 if err != nil {
132 return false
133 }
134 r, s := new(big.Int).SetBytes(rBytes), new(big.Int).SetBytes(sBytes)
135
136 c := pub.Curve
137 N := c.Params().N
138
139 if r.Sign() <= 0 || s.Sign() <= 0 {
140 return false
141 }
142 if r.Cmp(N) >= 0 || s.Cmp(N) >= 0 {
143 return false
144 }
145
146
147 e := hashToInt(hash, c)
148 w := new(big.Int).ModInverse(s, N)
149
150 u1 := e.Mul(e, w)
151 u1.Mod(u1, N)
152 u2 := w.Mul(r, w)
153 u2.Mod(u2, N)
154
155 x1, y1 := c.ScalarBaseMult(u1.Bytes())
156 x2, y2 := c.ScalarMult(pub.X, pub.Y, u2.Bytes())
157 x, y := c.Add(x1, y1, x2, y2)
158
159 if x.Sign() == 0 && y.Sign() == 0 {
160 return false
161 }
162 x.Mod(x, N)
163 return x.Cmp(r) == 0
164 }
165
166 var one = new(big.Int).SetInt64(1)
167
168
169
170 func randFieldElement(c elliptic.Curve, rand io.Reader) (k *big.Int, err error) {
171
172
173
174 for {
175 N := c.Params().N
176 b := make([]byte, (N.BitLen()+7)/8)
177 if _, err = io.ReadFull(rand, b); err != nil {
178 return
179 }
180 if excess := len(b)*8 - N.BitLen(); excess > 0 {
181 b[0] >>= excess
182 }
183 k = new(big.Int).SetBytes(b)
184 if k.Sign() != 0 && k.Cmp(N) < 0 {
185 return
186 }
187 }
188 }
189
View as plain text