diff options
author | Niels Möller <nisse@lysator.liu.se> | 2014-03-27 06:22:59 +0100 |
---|---|---|
committer | Niels Möller <nisse@lysator.liu.se> | 2014-03-27 06:22:59 +0100 |
commit | 27ea18ab63fed4413f7ceaea9e167f5267080648 (patch) | |
tree | 0bba4f7a3aecc902baf05161591fe608669c279f /dsa-gen-params.c | |
parent | bf85a3dbdfbd25f02f5eff19bd508a0d54643d5e (diff) | |
download | nettle-27ea18ab63fed4413f7ceaea9e167f5267080648.tar.gz |
New function dsa_generate_params.
Diffstat (limited to 'dsa-gen-params.c')
-rw-r--r-- | dsa-gen-params.c | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/dsa-gen-params.c b/dsa-gen-params.c new file mode 100644 index 00000000..ddf3ae1a --- /dev/null +++ b/dsa-gen-params.c @@ -0,0 +1,107 @@ +/* dsa-gen-params.c + * + * Generation of DSA parameters + */ + +/* nettle, low-level cryptographics library + * + * Copyright (C) 2002, 2013, 2014 Niels Möller + * + * The nettle library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or (at your + * option) any later version. + * + * The nettle library is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + * License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with the nettle library; see the file COPYING.LIB. If not, write to + * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02111-1301, USA. + */ + +#if HAVE_CONFIG_H +# include "config.h" +#endif + +#include <assert.h> +#include <stdlib.h> + +#include "dsa.h" + +#include "bignum.h" +#include "nettle-internal.h" + + +/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048, 224), + (2048, 256), (3072, 256). */ +int +dsa_generate_params(struct dsa_params *params, + void *random_ctx, nettle_random_func *random, + void *progress_ctx, nettle_progress_func *progress, + unsigned p_bits, unsigned q_bits) +{ + mpz_t r; + unsigned p0_bits; + unsigned a; + + if (q_bits < 30 || p_bits < q_bits + 30) + return 0; + + mpz_init (r); + + nettle_random_prime (params->q, q_bits, 0, random_ctx, random, + progress_ctx, progress); + + if (q_bits >= (p_bits + 2)/3) + _nettle_generate_pocklington_prime (params->p, r, p_bits, 0, + random_ctx, random, + params->q, NULL, params->q); + else + { + mpz_t p0, p0q; + mpz_init (p0); + mpz_init (p0q); + + p0_bits = (p_bits + 3)/2; + + nettle_random_prime (p0, p0_bits, 0, + random_ctx, random, + progress_ctx, progress); + + if (progress) + progress (progress_ctx, 'q'); + + /* Generate p = 2 r q p0 + 1, such that 2^{n-1} < p < 2^n. */ + mpz_mul (p0q, p0, params->q); + + _nettle_generate_pocklington_prime (params->p, r, p_bits, 0, + random_ctx, random, + p0, params->q, p0q); + + mpz_mul (r, r, p0); + + mpz_clear (p0); + mpz_clear (p0q); + } + if (progress) + progress (progress_ctx, 'p'); + + for (a = 2; ; a++) + { + mpz_set_ui (params->g, a); + mpz_powm (params->g, params->g, r, params->p); + if (mpz_cmp_ui (params->g, 1) != 0) + break; + } + + mpz_clear (r); + + if (progress) + progress (progress_ctx, 'g'); + + return 1; +} |