Correct PPTP server firewall rules chain.
[tomato/davidwu.git] / release / src / router / nettle / rsa-keygen.c
blob6d13500af7dc7fa9284d1a99ff8130e371548715
1 /* rsa-keygen.c
3 * Generation of RSA keypairs
4 */
6 /* nettle, low-level cryptographics library
8 * Copyright (C) 2002 Niels Möller
9 *
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,
23 * MA 02111-1301, USA.
26 #if HAVE_CONFIG_H
27 # include "config.h"
28 #endif
30 #include <assert.h>
31 #include <stdlib.h>
33 #include "rsa.h"
34 #include "bignum.h"
36 #ifndef DEBUG
37 # define DEBUG 0
38 #endif
40 #if DEBUG
41 # include <stdio.h>
42 #endif
45 int
46 rsa_generate_keypair(struct rsa_public_key *pub,
47 struct rsa_private_key *key,
48 void *random_ctx, nettle_random_func *random,
49 void *progress_ctx, nettle_progress_func *progress,
50 unsigned n_size,
51 unsigned e_size)
53 mpz_t p1;
54 mpz_t q1;
55 mpz_t phi;
56 mpz_t tmp;
58 if (e_size)
60 /* We should choose e randomly. Is the size reasonable? */
61 if ((e_size < 16) || (e_size >= n_size) )
62 return 0;
64 else
66 /* We have a fixed e. Check that it makes sense */
68 /* It must be odd */
69 if (!mpz_tstbit(pub->e, 0))
70 return 0;
72 /* And 3 or larger */
73 if (mpz_cmp_ui(pub->e, 3) < 0)
74 return 0;
76 /* And size less than n */
77 if (mpz_sizeinbase(pub->e, 2) >= n_size)
78 return 0;
81 if (n_size < RSA_MINIMUM_N_BITS)
82 return 0;
84 mpz_init(p1); mpz_init(q1); mpz_init(phi); mpz_init(tmp);
86 /* Generate primes */
87 for (;;)
89 /* Generate p, such that gcd(p-1, e) = 1 */
90 for (;;)
92 nettle_random_prime(key->p, (n_size+1)/2, 1,
93 random_ctx, random,
94 progress_ctx, progress);
96 mpz_sub_ui(p1, key->p, 1);
98 /* If e was given, we must chose p such that p-1 has no factors in
99 * common with e. */
100 if (e_size)
101 break;
103 mpz_gcd(tmp, pub->e, p1);
105 if (mpz_cmp_ui(tmp, 1) == 0)
106 break;
107 else if (progress) progress(progress_ctx, 'c');
110 if (progress)
111 progress(progress_ctx, '\n');
113 /* Generate q, such that gcd(q-1, e) = 1 */
114 for (;;)
116 nettle_random_prime(key->q, n_size/2, 1,
117 random_ctx, random,
118 progress_ctx, progress);
120 /* Very unlikely. */
121 if (mpz_cmp (key->q, key->p) == 0)
122 continue;
124 mpz_sub_ui(q1, key->q, 1);
126 /* If e was given, we must chose q such that q-1 has no factors in
127 * common with e. */
128 if (e_size)
129 break;
131 mpz_gcd(tmp, pub->e, q1);
133 if (mpz_cmp_ui(tmp, 1) == 0)
134 break;
135 else if (progress) progress(progress_ctx, 'c');
138 /* Now we have the primes. Is the product of the right size? */
139 mpz_mul(pub->n, key->p, key->q);
141 assert (mpz_sizeinbase(pub->n, 2) == n_size);
143 if (progress)
144 progress(progress_ctx, '\n');
146 /* c = q^{-1} (mod p) */
147 if (mpz_invert(key->c, key->q, key->p))
148 /* This should succeed everytime. But if it doesn't,
149 * we try again. */
150 break;
151 else if (progress) progress(progress_ctx, '?');
154 mpz_mul(phi, p1, q1);
156 /* If we didn't have a given e, generate one now. */
157 if (e_size)
159 int retried = 0;
160 for (;;)
162 nettle_mpz_random_size(pub->e,
163 random_ctx, random,
164 e_size);
166 /* Make sure it's odd and that the most significant bit is
167 * set */
168 mpz_setbit(pub->e, 0);
169 mpz_setbit(pub->e, e_size - 1);
171 /* Needs gmp-3, or inverse might be negative. */
172 if (mpz_invert(key->d, pub->e, phi))
173 break;
175 if (progress) progress(progress_ctx, 'e');
176 retried = 1;
178 if (retried && progress)
179 progress(progress_ctx, '\n');
181 else
183 /* Must always succeed, as we already that e
184 * doesn't have any common factor with p-1 or q-1. */
185 int res = mpz_invert(key->d, pub->e, phi);
186 assert(res);
189 /* Done! Almost, we must compute the auxillary private values. */
190 /* a = d % (p-1) */
191 mpz_fdiv_r(key->a, key->d, p1);
193 /* b = d % (q-1) */
194 mpz_fdiv_r(key->b, key->d, q1);
196 /* c was computed earlier */
198 pub->size = key->size = (n_size + 7) / 8;
199 assert(pub->size >= RSA_MINIMUM_N_OCTETS);
201 mpz_clear(p1); mpz_clear(q1); mpz_clear(phi); mpz_clear(tmp);
203 return 1;