1 // generate P, Q, G parameters of DSA with verifiable, deterministic algorithm
13 const usage = "usage: ./genpqg"
20 // od -An -tx1 -N20 /dev/urandom |sed 's/^ //;s/[^ ]*/0x&,/g'
22 0xef, 0xba, 0x22, 0x1b, 0x07, 0x2c, 0xe8, 0x2f, 0xbe, 0x20, 0x77, 0x5d, 0xd0, 0x5c, 0x33, 0xd5,
23 0xee, 0x66, 0x27, 0x0f,
26 // iterated sha1 generator
27 func (r *prng) Read(p []byte) (n int, err error) {
35 // copied from crypto/dsa and slightly modified the generation of q
38 func GenerateParameters(params *dsa.Parameters, rand io.Reader) (err error) {
39 // This function doesn't follow FIPS 186-3 exactly in that it doesn't
40 // use a verification seed to generate the primes. The verification
41 // seed doesn't appear to be exported or used by other code and
42 // omitting it makes the code cleaner.
46 qBytes := make([]byte, N/8)
47 pBytes := make([]byte, L/8)
57 // make q > 2^160 - 2^81 so sha1 sum of random bytes
58 // are in [1, q-1] with high probability
59 for i := 0; i < 10; i++ {
62 _, err = io.ReadFull(rand, qBytes[10:])
66 qBytes[len(qBytes)-1] |= 1
69 if !big.ProbablyPrime(q, numMRTests) {
73 for i := 0; i < 4*L; i++ {
74 _, err = io.ReadFull(rand, pBytes)
79 pBytes[len(pBytes)-1] |= 1
90 if !big.ProbablyPrime(p, numMRTests) {
104 pm1 := new(big.Int).Sub(p, one)
105 e := new(big.Int).Div(pm1, q)
122 params := new(dsa.Parameters)
123 err := GenerateParameters(params, r)
127 fmt.Printf("P: %X\nQ: %X\nG: %X\n", params.P, params.Q, params.G)