summaryrefslogtreecommitdiff
path: root/dsa-gen-params.c
diff options
context:
space:
mode:
authorNiels Möller <nisse@lysator.liu.se>2014-03-27 06:22:59 +0100
committerNiels Möller <nisse@lysator.liu.se>2014-03-27 06:22:59 +0100
commit27ea18ab63fed4413f7ceaea9e167f5267080648 (patch)
tree0bba4f7a3aecc902baf05161591fe608669c279f /dsa-gen-params.c
parentbf85a3dbdfbd25f02f5eff19bd508a0d54643d5e (diff)
downloadnettle-27ea18ab63fed4413f7ceaea9e167f5267080648.tar.gz
New function dsa_generate_params.
Diffstat (limited to 'dsa-gen-params.c')
-rw-r--r--dsa-gen-params.c107
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;
+}