OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libgo/] [go/] [crypto/] [dsa/] [dsa.go] - Blame information for rev 801

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 747 jeremybenn
// Copyright 2011 The Go Authors. All rights reserved.
2
// Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4
 
5
// Package dsa implements the Digital Signature Algorithm, as defined in FIPS 186-3
6
package dsa
7
 
8
import (
9
        "errors"
10
        "io"
11
        "math/big"
12
)
13
 
14
// Parameters represents the domain parameters for a key. These parameters can
15
// be shared across many keys. The bit length of Q must be a multiple of 8.
16
type Parameters struct {
17
        P, Q, G *big.Int
18
}
19
 
20
// PublicKey represents a DSA public key.
21
type PublicKey struct {
22
        Parameters
23
        Y *big.Int
24
}
25
 
26
// PrivateKey represents a DSA private key.
27
type PrivateKey struct {
28
        PublicKey
29
        X *big.Int
30
}
31
 
32
type invalidPublicKeyError int
33
 
34
func (invalidPublicKeyError) Error() string {
35
        return "crypto/dsa: invalid public key"
36
}
37
 
38
// ErrInvalidPublicKey results when a public key is not usable by this code.
39
// FIPS is quite strict about the format of DSA keys, but other code may be
40
// less so. Thus, when using keys which may have been generated by other code,
41
// this error must be handled.
42
var ErrInvalidPublicKey error = invalidPublicKeyError(0)
43
 
44
// ParameterSizes is a enumeration of the acceptable bit lengths of the primes
45
// in a set of DSA parameters. See FIPS 186-3, section 4.2.
46
type ParameterSizes int
47
 
48
const (
49
        L1024N160 ParameterSizes = iota
50
        L2048N224
51
        L2048N256
52
        L3072N256
53
)
54
 
55
// numMRTests is the number of Miller-Rabin primality tests that we perform. We
56
// pick the largest recommended number from table C.1 of FIPS 186-3.
57
const numMRTests = 64
58
 
59
// GenerateParameters puts a random, valid set of DSA parameters into params.
60
// This function takes many seconds, even on fast machines.
61
func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) (err error) {
62
        // This function doesn't follow FIPS 186-3 exactly in that it doesn't
63
        // use a verification seed to generate the primes. The verification
64
        // seed doesn't appear to be exported or used by other code and
65
        // omitting it makes the code cleaner.
66
 
67
        var L, N int
68
        switch sizes {
69
        case L1024N160:
70
                L = 1024
71
                N = 160
72
        case L2048N224:
73
                L = 2048
74
                N = 224
75
        case L2048N256:
76
                L = 2048
77
                N = 256
78
        case L3072N256:
79
                L = 3072
80
                N = 256
81
        default:
82
                return errors.New("crypto/dsa: invalid ParameterSizes")
83
        }
84
 
85
        qBytes := make([]byte, N/8)
86
        pBytes := make([]byte, L/8)
87
 
88
        q := new(big.Int)
89
        p := new(big.Int)
90
        rem := new(big.Int)
91
        one := new(big.Int)
92
        one.SetInt64(1)
93
 
94
GeneratePrimes:
95
        for {
96
                _, err = io.ReadFull(rand, qBytes)
97
                if err != nil {
98
                        return
99
                }
100
 
101
                qBytes[len(qBytes)-1] |= 1
102
                qBytes[0] |= 0x80
103
                q.SetBytes(qBytes)
104
 
105
                if !q.ProbablyPrime(numMRTests) {
106
                        continue
107
                }
108
 
109
                for i := 0; i < 4*L; i++ {
110
                        _, err = io.ReadFull(rand, pBytes)
111
                        if err != nil {
112
                                return
113
                        }
114
 
115
                        pBytes[len(pBytes)-1] |= 1
116
                        pBytes[0] |= 0x80
117
 
118
                        p.SetBytes(pBytes)
119
                        rem.Mod(p, q)
120
                        rem.Sub(rem, one)
121
                        p.Sub(p, rem)
122
                        if p.BitLen() < L {
123
                                continue
124
                        }
125
 
126
                        if !p.ProbablyPrime(numMRTests) {
127
                                continue
128
                        }
129
 
130
                        params.P = p
131
                        params.Q = q
132
                        break GeneratePrimes
133
                }
134
        }
135
 
136
        h := new(big.Int)
137
        h.SetInt64(2)
138
        g := new(big.Int)
139
 
140
        pm1 := new(big.Int).Sub(p, one)
141
        e := new(big.Int).Div(pm1, q)
142
 
143
        for {
144
                g.Exp(h, e, p)
145
                if g.Cmp(one) == 0 {
146
                        h.Add(h, one)
147
                        continue
148
                }
149
 
150
                params.G = g
151
                return
152
        }
153
 
154
        panic("unreachable")
155
}
156
 
157
// GenerateKey generates a public&private key pair. The Parameters of the
158
// PrivateKey must already be valid (see GenerateParameters).
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
// Sign signs an arbitrary length hash (which should be the result of hashing a
185
// larger message) using the private key, priv. It returns the signature as a
186
// pair of integers. The security of the private key depends on the entropy of
187
// rand.
188
//
189
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
190
// to the byte-length of the subgroup. This function does not perform that
191
// truncation itself.
192
func Sign(rand io.Reader, priv *PrivateKey, hash []byte) (r, s *big.Int, err error) {
193
        // FIPS 186-3, section 4.6
194
 
195
        n := priv.Q.BitLen()
196
        if n&7 != 0 {
197
                err = ErrInvalidPublicKey
198
                return
199
        }
200
        n >>= 3
201
 
202
        for {
203
                k := new(big.Int)
204
                buf := make([]byte, n)
205
                for {
206
                        _, err = io.ReadFull(rand, buf)
207
                        if err != nil {
208
                                return
209
                        }
210
                        k.SetBytes(buf)
211
                        if k.Sign() > 0 && k.Cmp(priv.Q) < 0 {
212
                                break
213
                        }
214
                }
215
 
216
                kInv := new(big.Int).ModInverse(k, priv.Q)
217
 
218
                r = new(big.Int).Exp(priv.G, k, priv.P)
219
                r.Mod(r, priv.Q)
220
 
221
                if r.Sign() == 0 {
222
                        continue
223
                }
224
 
225
                z := k.SetBytes(hash)
226
 
227
                s = new(big.Int).Mul(priv.X, r)
228
                s.Add(s, z)
229
                s.Mod(s, priv.Q)
230
                s.Mul(s, kInv)
231
                s.Mod(s, priv.Q)
232
 
233
                if s.Sign() != 0 {
234
                        break
235
                }
236
        }
237
 
238
        return
239
}
240
 
241
// Verify verifies the signature in r, s of hash using the public key, pub. It
242
// reports whether the signature is valid.
243
//
244
// Note that FIPS 186-3 section 4.6 specifies that the hash should be truncated
245
// to the byte-length of the subgroup. This function does not perform that
246
// truncation itself.
247
func Verify(pub *PublicKey, hash []byte, r, s *big.Int) bool {
248
        // FIPS 186-3, section 4.7
249
 
250
        if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 {
251
                return false
252
        }
253
        if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 {
254
                return false
255
        }
256
 
257
        w := new(big.Int).ModInverse(s, pub.Q)
258
 
259
        n := pub.Q.BitLen()
260
        if n&7 != 0 {
261
                return false
262
        }
263
        z := new(big.Int).SetBytes(hash)
264
 
265
        u1 := new(big.Int).Mul(z, w)
266
        u1.Mod(u1, pub.Q)
267
        u2 := w.Mul(r, w)
268
        u2.Mod(u2, pub.Q)
269
        v := u1.Exp(pub.G, u1, pub.P)
270
        u2.Exp(pub.Y, u2, pub.P)
271
        v.Mul(v, u2)
272
        v.Mod(v, pub.P)
273
        v.Mod(v, pub.Q)
274
 
275
        return v.Cmp(r) == 0
276
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.