github.com/sbinet/go@v0.0.0-20160827155028-54d7de7dd62b/src/crypto/dsa/dsa.go (about) 1 // 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 // ErrInvalidPublicKey results when a public key is not usable by this code. 33 // FIPS is quite strict about the format of DSA keys, but other code may be 34 // less so. Thus, when using keys which may have been generated by other code, 35 // this error must be handled. 36 var ErrInvalidPublicKey = errors.New("crypto/dsa: invalid public key") 37 38 // ParameterSizes is a enumeration of the acceptable bit lengths of the primes 39 // in a set of DSA parameters. See FIPS 186-3, section 4.2. 40 type ParameterSizes int 41 42 const ( 43 L1024N160 ParameterSizes = iota 44 L2048N224 45 L2048N256 46 L3072N256 47 ) 48 49 // numMRTests is the number of Miller-Rabin primality tests that we perform. We 50 // pick the largest recommended number from table C.1 of FIPS 186-3. 51 const numMRTests = 64 52 53 // GenerateParameters puts a random, valid set of DSA parameters into params. 54 // This function can take many seconds, even on fast machines. 55 func GenerateParameters(params *Parameters, rand io.Reader, sizes ParameterSizes) error { 56 // This function doesn't follow FIPS 186-3 exactly in that it doesn't 57 // use a verification seed to generate the primes. The verification 58 // seed doesn't appear to be exported or used by other code and 59 // omitting it makes the code cleaner. 60 61 var L, N int 62 switch sizes { 63 case L1024N160: 64 L = 1024 65 N = 160 66 case L2048N224: 67 L = 2048 68 N = 224 69 case L2048N256: 70 L = 2048 71 N = 256 72 case L3072N256: 73 L = 3072 74 N = 256 75 default: 76 return errors.New("crypto/dsa: invalid ParameterSizes") 77 } 78 79 qBytes := make([]byte, N/8) 80 pBytes := make([]byte, L/8) 81 82 q := new(big.Int) 83 p := new(big.Int) 84 rem := new(big.Int) 85 one := new(big.Int) 86 one.SetInt64(1) 87 88 GeneratePrimes: 89 for { 90 if _, err := io.ReadFull(rand, qBytes); err != nil { 91 return err 92 } 93 94 qBytes[len(qBytes)-1] |= 1 95 qBytes[0] |= 0x80 96 q.SetBytes(qBytes) 97 98 if !q.ProbablyPrime(numMRTests) { 99 continue 100 } 101 102 for i := 0; i < 4*L; i++ { 103 if _, err := io.ReadFull(rand, pBytes); err != nil { 104 return err 105 } 106 107 pBytes[len(pBytes)-1] |= 1 108 pBytes[0] |= 0x80 109 110 p.SetBytes(pBytes) 111 rem.Mod(p, q) 112 rem.Sub(rem, one) 113 p.Sub(p, rem) 114 if p.BitLen() < L { 115 continue 116 } 117 118 if !p.ProbablyPrime(numMRTests) { 119 continue 120 } 121 122 params.P = p 123 params.Q = q 124 break GeneratePrimes 125 } 126 } 127 128 h := new(big.Int) 129 h.SetInt64(2) 130 g := new(big.Int) 131 132 pm1 := new(big.Int).Sub(p, one) 133 e := new(big.Int).Div(pm1, q) 134 135 for { 136 g.Exp(h, e, p) 137 if g.Cmp(one) == 0 { 138 h.Add(h, one) 139 continue 140 } 141 142 params.G = g 143 return nil 144 } 145 } 146 147 // GenerateKey generates a public&private key pair. The Parameters of the 148 // PrivateKey must already be valid (see GenerateParameters). 149 func GenerateKey(priv *PrivateKey, rand io.Reader) error { 150 if priv.P == nil || priv.Q == nil || priv.G == nil { 151 return errors.New("crypto/dsa: parameters not set up before generating key") 152 } 153 154 x := new(big.Int) 155 xBytes := make([]byte, priv.Q.BitLen()/8) 156 157 for { 158 _, err := io.ReadFull(rand, xBytes) 159 if err != nil { 160 return err 161 } 162 x.SetBytes(xBytes) 163 if x.Sign() != 0 && x.Cmp(priv.Q) < 0 { 164 break 165 } 166 } 167 168 priv.X = x 169 priv.Y = new(big.Int) 170 priv.Y.Exp(priv.G, x, priv.P) 171 return nil 172 } 173 174 // fermatInverse calculates the inverse of k in GF(P) using Fermat's method. 175 // This has better constant-time properties than Euclid's method (implemented 176 // in math/big.Int.ModInverse) although math/big itself isn't strictly 177 // constant-time so it's not perfect. 178 func fermatInverse(k, P *big.Int) *big.Int { 179 two := big.NewInt(2) 180 pMinus2 := new(big.Int).Sub(P, two) 181 return new(big.Int).Exp(k, pMinus2, P) 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 := fermatInverse(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 pub.P.Sign() == 0 { 251 return false 252 } 253 254 if r.Sign() < 1 || r.Cmp(pub.Q) >= 0 { 255 return false 256 } 257 if s.Sign() < 1 || s.Cmp(pub.Q) >= 0 { 258 return false 259 } 260 261 w := new(big.Int).ModInverse(s, pub.Q) 262 263 n := pub.Q.BitLen() 264 if n&7 != 0 { 265 return false 266 } 267 z := new(big.Int).SetBytes(hash) 268 269 u1 := new(big.Int).Mul(z, w) 270 u1.Mod(u1, pub.Q) 271 u2 := w.Mul(r, w) 272 u2.Mod(u2, pub.Q) 273 v := u1.Exp(pub.G, u1, pub.P) 274 u2.Exp(pub.Y, u2, pub.P) 275 v.Mul(v, u2) 276 v.Mod(v, pub.P) 277 v.Mod(v, pub.Q) 278 279 return v.Cmp(r) == 0 280 }