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., 51 Franklin Street, Fifth Floor, 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');
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');