3 * Generation of DSA keypairs
6 /* nettle, low-level cryptographics library
8 * Copyright (C) 2002 Niels Möller
10 * The nettle library is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Lesser General Public License as published by
12 * the Free Software Foundation; either version 2.1 of the License, or (at your
13 * option) any later version.
15 * The nettle library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18 * License for more details.
20 * You should have received a copy of the GNU Lesser General Public License
21 * along with the nettle library; see the file COPYING.LIB. If not, write to
22 * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
36 #include "nettle-internal.h"
39 /* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048. 224),
40 (2048, 256), (3072, 256). Currenty, we use only q_bits of 160 or
43 dsa_generate_keypair(struct dsa_public_key *pub,
44 struct dsa_private_key *key,
45 void *random_ctx, nettle_random_func random,
46 void *progress_ctx, nettle_progress_func progress,
47 unsigned p_bits, unsigned q_bits)
56 if (p_bits < DSA_SHA1_MIN_P_BITS)
60 if (p_bits < DSA_SHA256_MIN_P_BITS)
71 nettle_random_prime (pub->q, q_bits, 0, random_ctx, random,
72 progress_ctx, progress);
74 p0_bits = (p_bits + 3)/2;
76 nettle_random_prime (p0, p0_bits, 0,
78 progress_ctx, progress);
81 progress (progress_ctx, 'q');
83 /* Generate p = 2 r q p0 + 1, such that 2^{n-1} < p < 2^n.
85 * We select r in the range i + 1 < r <= 2i, with i = floor (2^{n-2} / (p0 q). */
87 mpz_mul (p0q, p0, pub->q);
89 _nettle_generate_pocklington_prime (pub->p, r, p_bits, 0,
94 progress (progress_ctx, 'p');
100 mpz_set_ui (pub->g, a);
101 mpz_powm (pub->g, pub->g, r, pub->p);
102 if (mpz_cmp_ui (pub->g, 1) != 0)
107 progress (progress_ctx, 'g');
109 mpz_init_set(r, pub->q);
111 nettle_mpz_random(key->x, random_ctx, random, r);
113 mpz_add_ui(key->x, key->x, 1);
115 mpz_powm(pub->y, pub->g, key->x, pub->p);
118 progress (progress_ctx, '\n');