dsa-keygen.c 2.92 KB
Newer Older
Niels Möller's avatar
Niels Möller committed
1
2
3
4
5
6
7
/* dsa-keygen.c
 *
 * Generation of DSA keypairs
 */

/* nettle, low-level cryptographics library
 *
Niels Möller's avatar
Niels Möller committed
8
 * Copyright (C) 2002 Niels Möller
Niels Möller's avatar
Niels Möller committed
9
10
11
12
13
14
15
16
17
18
19
20
21
 *  
 * 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
22
23
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02111-1301, USA.
Niels Möller's avatar
Niels Möller committed
24
25
26
 */

#if HAVE_CONFIG_H
27
# include "config.h"
Niels Möller's avatar
Niels Möller committed
28
29
#endif

30
#include <assert.h>
31
32
#include <stdlib.h>

Niels Möller's avatar
Niels Möller committed
33
34
35
#include "dsa.h"

#include "bignum.h"
36
#include "nettle-internal.h"
Niels Möller's avatar
Niels Möller committed
37

38

39
/* Valid sizes, according to FIPS 186-3 are (1024, 160), (2048, 224),
40
41
42
43
44
   (2048, 256), (3072, 256). Currenty, we use only q_bits of 160 or
   256. */
int
dsa_generate_keypair(struct dsa_public_key *pub,
		     struct dsa_private_key *key,
45
46
		     void *random_ctx, nettle_random_func *random,
		     void *progress_ctx, nettle_progress_func *progress,
47
48
		     unsigned p_bits, unsigned q_bits)
{
49
  mpz_t p0, p0q, r;
50
51
52
53
54
55
  unsigned p0_bits;
  unsigned a;

  switch (q_bits)
    {
    case 160:
56
      if (p_bits < DSA_SHA1_MIN_P_BITS)
57
58
	return 0;
      break;
59
    case 224:
60
    case 256:
61
      if (p_bits < DSA_SHA256_MIN_P_BITS)
62
63
64
65
66
67
68
	return 0;
      break;
    default:
      return 0;
    }

  mpz_init (p0);
69
70
71
72
73
74
  mpz_init (p0q);
  mpz_init (r);

  nettle_random_prime (pub->q, q_bits, 0, random_ctx, random,
		       progress_ctx, progress);

75
76
  p0_bits = (p_bits + 3)/2;
  
77
78
79
80
81
82
  nettle_random_prime (p0, p0_bits, 0,
		       random_ctx, random,
		       progress_ctx, progress);

  if (progress)
    progress (progress_ctx, 'q');
83
  
Niels Möller's avatar
Niels Möller committed
84
  /* Generate p = 2 r q p0 + 1, such that 2^{n-1} < p < 2^n.
85
   *
Niels Möller's avatar
Niels Möller committed
86
   * We select r in the range i + 1 < r <= 2i, with i = floor (2^{n-2} / (p0 q). */
87
88
89

  mpz_mul (p0q, p0, pub->q);

90
91
  _nettle_generate_pocklington_prime (pub->p, r, p_bits, 0,
				      random_ctx, random,
92
				      p0, pub->q, p0q);
93

94
95
96
  if (progress)
    progress (progress_ctx, 'p');

97
98
99
100
  mpz_mul (r, r, p0);

  for (a = 2; ; a++)
    {
101
102
      mpz_set_ui (pub->g, a);
      mpz_powm (pub->g, pub->g, r, pub->p);
103
104
105
106
      if (mpz_cmp_ui (pub->g, 1) != 0)
	break;
    }

107
108
109
  if (progress)
    progress (progress_ctx, 'g');

110
  mpz_set(r, pub->q);
111
  mpz_sub_ui(r, r, 2);
112
  nettle_mpz_random(key->x, random_ctx, random, r);
113
114
115
116

  mpz_add_ui(key->x, key->x, 1);

  mpz_powm(pub->y, pub->g, key->x, pub->p);
117
118
119

  if (progress)
    progress (progress_ctx, '\n');
120
121
122
123
124
125
126
  
  mpz_clear (p0);
  mpz_clear (p0q);
  mpz_clear (r);

  return 1;
}