1
2
3
4
5
6
7
8
9
10
11
12
13
14 package dsa
15
16 import (
17 "errors"
18 "io"
19 "math/big"
20
21 "crypto/internal/randutil"
22 )
23
24
25
26 type Parameters struct {
27 P, Q, G *big.Int
28 }
29
30
31 type PublicKey struct {
32 Parameters
33 Y *big.Int
34 }
35
36
37 type PrivateKey struct {
38 PublicKey
39 X *big.Int
40 }
41
42
43
44
45
46 var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key")
47
48
49
50 type ParameterSizes int
51
52 const (
53 L1024N160 ParameterSizes = iota
54 L2048N224
55 L2048N256
56 L3072N256
57 )
58
59
60
61 const numMRTests = 64
62
63
64
65 func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) error {
66
67
68
69
70
71 var L, N int
72 switch sizes {
73 case L1024N160:
74 L = 1024
75 N = 160
76 case L2048N224:
77 L = 2048
78 N = 224
79 case L2048N256:
80 L = 2048
81 N = 256
82 case L3072N256:
83 L = 3072
84 N = 256
85 default:
86 return errors.New("crypto/dsa: invalid ParameterSizes")
87 }
88
89 qBytes := make([]byte, N/8)
90 pBytes := make([]byte, L/8)
91
92 q := new(big.Int)
93 p := new(big.Int)
94 rem := new(big.Int)
95 one := new(big.Int)
96 one.SetInt64(1)
97
98 GeneratePrimes:
99 for {
100 if _, err := io.ReadFull(rand, qBytes); err != nil {
101 return err
102 }
103
104 qBytes[len(qBytes)-1] |= 1
105 qBytes[0] |= 0x80
106 q.SetBytes(qBytes)
107
108 if !q.ProbablyPrime(numMRTests) {
109 continue
110 }
111
112 for i := 0; i < 4*L; i++ {
113 if _, err := io.ReadFull(rand, pBytes); err != nil {
114 return err
115 }
116
117 pBytes[len(pBytes)-1] |= 1
118 pBytes[0] |= 0x80
119
120 p.SetBytes(pBytes)
121 rem.Mod(p, q)
122 rem.Sub(rem, one)
123 p.Sub(p, rem)
124 if p.BitLen() < L {
125 continue
126 }
127
128 if !p.ProbablyPrime(numMRTests) {
129 continue
130 }
131
132 params.P = p
133 params.Q = q
134 break GeneratePrimes
135 }
136 }
137
138 h := new(big.Int)
139 h.SetInt64(2)
140 g := new(big.Int)
141
142 pm1 := new(big.Int).Sub(p, one)
143 e := new(big.Int).Div(pm1, q)
144
145 for {
146 g.Exp(h, e, p)
147 if g.Cmp(one) == 0 {
148 h.Add(h, one)
149 continue
150 }
151
152 params.G = g
153 return nil
154 }
155 }
156
157
158
159 func GenerateKey(priv *PrivateKey, rand io.Reader) error {
160 if priv.P == nil || priv.Q == nil || priv.G == nil {
161 return errors.New("crypto/dsa: parameters not set up before generating key")
162 }
163
164 x := new(big.Int)
165 xBytes := make([]byte, priv.Q.BitLen()/8)
166
167 for {
168 _, err := io.ReadFull(rand, xBytes)
169 if err != nil {
170 return err
171 }
172 x.SetBytes(xBytes)
173 if x.Sign() != 0 && x.Cmp(priv.Q) < 0 {
174 break
175 }
176 }
177
178 priv.X = x
179 priv.Y = new(big.Int)
180 priv.Y.Exp(priv.G, x, priv.P)
181 return nil
182 }
183
184
185
186
187
188 func fermatInverse(k, P *big.Int) *big.Int {
189 two := big.NewInt(2)
190 pMinus2 := new(big.Int).Sub(P, two)
191 return new(big.Int).Exp(k, pMinus2, P)
192 }
193
194
195
196
197
198
199
200
201
202
203
204
205 func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
206 randutil.MaybeReadByte(rand)
207
208
209
210 n := priv.Q.BitLen()
211 if priv.Q.Sign() <= 0 || priv.P.Sign() <= 0 || priv.G.Sign() <= 0 || priv.X.Sign() <= 0 || n%8 != 0 {
212 err = ErrInvalidPublicKey
213 return
214 }
215 n >>= 3
216
217 var attempts int
218 for attempts = 10; attempts > 0; attempts-- {
219 k := new(big.Int)
220 buf := make([]byte, n)
221 for {
222 _, err = io.ReadFull(rand, buf)
223 if err != nil {
224 return
225 }
226 k.SetBytes(buf)
227
228
229
230
231 if k.Sign() > 0 && k.Cmp(priv.Q) < 0 {
232 break
233 }
234 }
235
236 kInv := fermatInverse(k, priv.Q)
237
238 r = new(big.Int).Exp(priv.G, k, priv.P)
239 r.Mod(r, priv.Q)
240
241 if r.Sign() == 0 {
242 continue
243 }
244
245 z := k.SetBytes(hash)
246
247 s = new(big.Int).Mul(priv.X, r)
248 s.Add(s, z)
249 s.Mod(s, priv.Q)
250 s.Mul(s, kInv)
251 s.Mod(s, priv.Q)
252
253 if s.Sign() != 0 {
254 break
255 }
256 }
257
258
259
260 if attempts == 0 {
261 return nil, nil, ErrInvalidPublicKey
262 }
263
264 return
265 }
266
267
268
269
270
271
272
273 func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
274
275
276 if pub.P.Sign() == 0 {
277 return false
278 }
279
280 if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 {
281 return false
282 }
283 if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 {
284 return false
285 }
286
287 w := new(big.Int).ModInverse(s, pub.Q)
288 if w == nil {
289 return false
290 }
291
292 n := pub.Q.BitLen()
293 if n%8 != 0 {
294 return false
295 }
296 z := new(big.Int).SetBytes(hash)
297
298 u1 := new(big.Int).Mul(z, w)
299 u1.Mod(u1, pub.Q)
300 u2 := w.Mul(r, w)
301 u2.Mod(u2, pub.Q)
302 v := u1.Exp(pub.G, u1, pub.P)
303 u2.Exp(pub.Y, u2, pub.P)
304 v.Mul(v, u2)
305 v.Mod(v, pub.P)
306 v.Mod(v, pub.Q)
307
308 return v.Cmp(r) == 0
309 }
310
View as plain text