2 This file is part of GNUnet.
3 Copyright (C) 1994, 1996, 1998, 2001, 2002, 2003 Free Software Foundation, Inc.
4 Copyright (C) 2004, 2005, 2006 Christian Grothoff (and other contributing authors)
6 GNUnet is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2, or (at your
9 option) any later version.
11 GNUnet is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNUnet; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA.
21 Note: This code is based on code from libgcrypt
22 The code was adapted for GNUnet to support RSA-key generation
23 based on weak, pseudo-random keys. Do NOT use to generate
29 * @file util/crypto_ksk.c
30 * @brief implementation of RSA-Key generation for KBlocks
31 * (do NOT use for pseudonyms or hostkeys!)
32 * @author Christian Grothoff
36 #include "gnunet_common.h"
37 #include "gnunet_crypto_lib.h"
38 #include "gnunet_os_lib.h"
43 * Log an error message at log-level 'level' that indicates
44 * a failure of the command 'cmd' with the message given
45 * by gcry_strerror(rc).
47 #define LOG_GCRY(level, cmd, rc) do { GNUNET_log(level, _("`%s' failed at %s:%d with error: %s\n"), cmd, __FILE__, __LINE__, gcry_strerror(rc)); } while(0);
52 gcry_mpi_t n; /* public modulus */
53 gcry_mpi_t e; /* public exponent */
54 gcry_mpi_t d; /* exponent */
55 gcry_mpi_t p; /* prime p. */
56 gcry_mpi_t q; /* prime q. */
57 gcry_mpi_t u; /* inverse of p mod q. */
61 * The private information of an RSA key pair.
62 * NOTE: this must match the definition in crypto_rsa.c
64 struct GNUNET_CRYPTO_RsaPrivateKey
71 mpz_randomize (gcry_mpi_t n, unsigned int nbits, GNUNET_HashCode * rnd)
75 int bits_per_hc = sizeof (GNUNET_HashCode) * 8;
79 GNUNET_assert (nbits > 0);
80 cnt = (nbits + bits_per_hc - 1) / bits_per_hc;
81 gcry_mpi_set_ui (n, 0);
84 for (i = 0; i < cnt; i++)
89 GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), &tmp);
90 for (j=0;j<sizeof(GNUNET_HashCode) / sizeof(uint32_t); j++)
92 #if HAVE_GCRY_MPI_LSHIFT
93 gcry_mpi_lshift (n, n, sizeof(uint32_t)*8);
95 gcry_mpi_mul_ui(n, n, 1 << (sizeof(uint32_t)*4));
96 gcry_mpi_mul_ui(n, n, 1 << (sizeof(uint32_t)*4));
98 gcry_mpi_add_ui(n, n, ntohl (((uint32_t *) &tmp)[j]));
102 GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), rnd);
103 i = gcry_mpi_get_nbits (n);
105 gcry_mpi_clear_bit (n, --i);
109 mpz_trailing_zeroes (gcry_mpi_t n)
111 unsigned int idx, cnt;
113 cnt = gcry_mpi_get_nbits(n);
114 for (idx = 0; idx < cnt; idx++)
116 if (gcry_mpi_test_bit(n, idx) == 0)
124 mpz_tdiv_q_2exp (gcry_mpi_t q, gcry_mpi_t n, unsigned int b)
128 u = gcry_mpi_set_ui (NULL, 1);
129 d = gcry_mpi_new (0);
130 gcry_mpi_mul_2exp (d, u, b);
131 gcry_mpi_div (q, NULL, n, d, 0);
135 * Return true if n is probably a prime
138 is_prime (gcry_mpi_t n, int steps, GNUNET_HashCode * hc)
146 unsigned int i, j, k;
150 x = gcry_mpi_new (0);
151 y = gcry_mpi_new (0);
152 z = gcry_mpi_new (0);
153 nminus1 = gcry_mpi_new (0);
154 a2 = gcry_mpi_set_ui (NULL, 2);
156 nbits = gcry_mpi_get_nbits (n);
157 gcry_mpi_sub_ui(nminus1, n, 1);
159 /* Find q and k, so that n = 1 + 2^k * q . */
160 q = gcry_mpi_set (NULL, nminus1);
161 k = mpz_trailing_zeroes (q);
162 mpz_tdiv_q_2exp (q, q, k);
164 for (i = 0; i < steps; i++)
168 gcry_mpi_set_ui (x, 2);
172 mpz_randomize (x, nbits - 1, hc);
173 GNUNET_assert (gcry_mpi_cmp (x, nminus1) < 0);
174 GNUNET_assert (gcry_mpi_cmp_ui (x, 1) > 0);
176 gcry_mpi_powm (y, x, q, n);
177 if (gcry_mpi_cmp_ui (y, 1) && gcry_mpi_cmp (y, nminus1))
179 for (j = 1; j < k && gcry_mpi_cmp (y, nminus1); j++)
181 gcry_mpi_powm (y, y, a2, n);
182 if (!gcry_mpi_cmp_ui (y, 1))
183 goto leave; /* Not a prime. */
185 if (gcry_mpi_cmp (y, nminus1))
186 goto leave; /* Not a prime. */
189 rc = 1; /* May be a prime. */
192 gcry_mpi_release (x);
193 gcry_mpi_release (y);
194 gcry_mpi_release (z);
195 gcry_mpi_release (nminus1);
196 gcry_mpi_release (q);
197 gcry_mpi_release (a2);
203 * If target != size, move target bytes to the
204 * end of the size-sized buffer and zero out the
205 * first target-size bytes.
208 adjust (unsigned char *buf, size_t size, size_t target)
212 memmove (&buf[target - size], buf, size);
213 memset (buf, 0, target - size);
219 gen_prime (gcry_mpi_t *ptest, unsigned int nbits, GNUNET_HashCode * hc)
221 /* Note: 2 is not included because it can be tested more easily by
222 looking at bit 0. The last entry in this list is marked by a zero */
223 static const uint16_t small_prime_numbers[] = {
224 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
225 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
226 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
227 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
228 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
229 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
230 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
231 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
232 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
233 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
234 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
235 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
236 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
237 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
238 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
239 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
240 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
241 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
242 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
243 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
244 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
245 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
246 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
247 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
248 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
249 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
250 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
251 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
252 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
253 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
254 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
255 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
256 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
257 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
258 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
259 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
260 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
261 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
262 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
263 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
264 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
265 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
266 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
267 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
268 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
269 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
270 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
271 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
272 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
273 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
274 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
275 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
276 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
277 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
278 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
279 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
280 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
281 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
282 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
283 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
284 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
285 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
286 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
287 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
288 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
289 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
290 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
291 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
292 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
293 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
294 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
295 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
296 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
297 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
298 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
299 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
300 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
301 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
302 4957, 4967, 4969, 4973, 4987, 4993, 4999,
305 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
306 static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
308 gcry_mpi_t prime, pminus1, val_2, val_3, result;
311 unsigned int mods[no_of_small_prime_numbers];
315 GNUNET_assert (nbits >= 16);
317 /* Make nbits fit into mpz_t implementation. */
318 val_2 = gcry_mpi_set_ui (NULL, 2);
319 val_3 = gcry_mpi_set_ui (NULL, 3);
320 prime = gcry_mpi_snew(0);
321 result = gcry_mpi_new(0);
322 pminus1 = gcry_mpi_new(0);
323 *ptest = gcry_mpi_new(0);
324 tmp = gcry_mpi_new (0);
325 sp = gcry_mpi_new (0);
328 /* generate a random number */
329 mpz_randomize (prime, nbits, hc);
330 /* Set high order bit to 1, set low order bit to 1. If we are
331 generating a secret prime we are most probably doing that
332 for RSA, to make sure that the modulus does have the
333 requested key size we set the 2 high order bits. */
334 gcry_mpi_set_bit (prime, nbits - 1);
335 gcry_mpi_set_bit (prime, nbits - 2);
336 gcry_mpi_set_bit (prime, 0);
338 /* Calculate all remainders. */
339 for (i = 0; i < no_of_small_prime_numbers; i++)
343 gcry_mpi_set_ui(sp, small_prime_numbers[i]);
344 gcry_mpi_div (NULL, tmp, prime, sp, -1);
346 written = sizeof (unsigned int);
348 gcry_mpi_print (GCRYMPI_FMT_USG,
349 (unsigned char*) &mods[i], written, &written,
351 adjust ( (unsigned char*) &mods[i], written, sizeof (unsigned int));
352 mods[i] = ntohl (mods[i]);
354 /* Now try some primes starting with prime. */
355 for (step = 0; step < 20000; step += 2)
357 /* Check against all the small primes we have in mods. */
358 for (i = 0; i < no_of_small_prime_numbers; i++)
360 uint16_t x = small_prime_numbers[i];
361 while (mods[i] + step >= x)
363 if (!(mods[i] + step))
366 if (i < no_of_small_prime_numbers)
367 continue; /* Found a multiple of an already known prime. */
369 gcry_mpi_add_ui (*ptest, prime, step);
370 if (!gcry_mpi_test_bit (*ptest, nbits - 2))
373 /* Do a fast Fermat test now. */
374 gcry_mpi_sub_ui (pminus1, *ptest, 1);
375 gcry_mpi_powm (result, val_2, pminus1, *ptest);
376 if ((!gcry_mpi_cmp_ui (result, 1)) && (is_prime (*ptest, 5, hc)))
379 gcry_mpi_release (sp);
380 gcry_mpi_release (tmp);
381 gcry_mpi_release (val_2);
382 gcry_mpi_release (val_3);
383 gcry_mpi_release (result);
384 gcry_mpi_release (pminus1);
385 gcry_mpi_release (prime);
393 * Generate a key pair with a key of size NBITS.
394 * @param sk where to store the key
395 * @param nbits the number of bits to use
396 * @param hc the HC to use for PRNG (modified!)
399 generate_kblock_key (KBlock_secret_key * sk,
400 unsigned int nbits, GNUNET_HashCode * hc)
403 gcry_mpi_t phi; /* helper: (p-1)(q-1) */
407 /* make sure that nbits is even so that we generate p, q of equal size */
411 sk->e = gcry_mpi_set_ui (NULL, 257);
412 sk->n = gcry_mpi_new(0);
413 sk->p = gcry_mpi_new(0);
414 sk->q = gcry_mpi_new(0);
415 sk->d = gcry_mpi_new(0);
416 sk->u = gcry_mpi_new(0);
418 t1 = gcry_mpi_new(0);
419 t2 = gcry_mpi_new(0);
420 phi = gcry_mpi_new(0);
428 gcry_mpi_release (sk->p);
429 gcry_mpi_release (sk->q);
430 gen_prime (&sk->p, nbits / 2, hc);
431 gen_prime (&sk->q, nbits / 2, hc);
433 if (gcry_mpi_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */
434 gcry_mpi_swap (sk->p, sk->q);
435 /* calculate the modulus */
436 gcry_mpi_mul (sk->n, sk->p, sk->q);
438 while (gcry_mpi_get_nbits (sk->n) != nbits);
440 /* calculate Euler totient: phi = (p-1)(q-1) */
441 gcry_mpi_sub_ui (t1, sk->p, 1);
442 gcry_mpi_sub_ui (t2, sk->q, 1);
443 gcry_mpi_mul (phi, t1, t2);
444 gcry_mpi_gcd (g, t1, t2);
445 gcry_mpi_div (f, NULL, phi, g, 0);
446 while (0 == gcry_mpi_gcd (t1, sk->e, phi))
447 { /* (while gcd is not 1) */
448 gcry_mpi_add_ui (sk->e, sk->e, 2);
451 /* calculate the secret key d = e^1 mod phi */
453 while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) ||
454 (0 == gcry_mpi_invm (sk->u, sk->p, sk->q)));
456 gcry_mpi_release (t1);
457 gcry_mpi_release (t2);
458 gcry_mpi_release (phi);
459 gcry_mpi_release (f);
460 gcry_mpi_release (g);
465 * Internal representation of the private key.
467 struct KskRsaPrivateKeyBinaryEncoded
470 * Total size of the structure, in bytes, in big-endian!
472 uint16_t len GNUNET_PACKED;
473 uint16_t sizen GNUNET_PACKED; /* in big-endian! */
474 uint16_t sizee GNUNET_PACKED; /* in big-endian! */
475 uint16_t sized GNUNET_PACKED; /* in big-endian! */
476 uint16_t sizep GNUNET_PACKED; /* in big-endian! */
477 uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
478 uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
479 uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
480 /* followed by the actual values */
485 * Deterministically (!) create a hostkey using only the
486 * given HashCode as input to the PRNG.
488 static struct KskRsaPrivateKeyBinaryEncoded *
489 makeKblockKeyInternal (const GNUNET_HashCode * hc)
491 KBlock_secret_key sk;
493 unsigned char *pbu[6];
496 struct KskRsaPrivateKeyBinaryEncoded *retval;
501 generate_kblock_key (&sk, 1024, /* at least 10x as fast than 2048 bits
502 -- we simply cannot afford 2048 bits
503 even on modern hardware, and especially
504 not since clearly a dictionary attack
505 will still be much cheaper
506 than breaking a 1024 bit RSA key.
507 If an adversary can spend the time to
508 break a 1024 bit RSA key just to forge
509 a signature -- SO BE IT. [ CG, 6/2005 ] */
517 size = sizeof (struct KskRsaPrivateKeyBinaryEncoded);
518 for (i = 0; i < 6; i++)
520 gcry_mpi_aprint(GCRYMPI_FMT_STD, &pbu[i], &sizes[i], *pkv[i]);
523 GNUNET_assert (size < 65536);
524 retval = GNUNET_malloc (size);
525 retval->len = htons (size);
527 retval->sizen = htons (sizes[0]);
528 memcpy (&((char *) &retval[1])[i], pbu[0], sizes[0]);
530 retval->sizee = htons (sizes[1]);
531 memcpy (&((char *) &retval[1])[i], pbu[1], sizes[1]);
533 retval->sized = htons (sizes[2]);
534 memcpy (&((char *) &retval[1])[i], pbu[2], sizes[2]);
537 retval->sizep = htons (sizes[4]);
538 memcpy (&((char *) &retval[1])[i], pbu[4], sizes[4]);
540 retval->sizeq = htons (sizes[3]);
541 memcpy (&((char *) &retval[1])[i], pbu[3], sizes[3]);
543 retval->sizedmp1 = htons (0);
544 retval->sizedmq1 = htons (0);
545 memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]);
546 for (i = 0; i < 6; i++)
548 gcry_mpi_release (*pkv[i]);
556 * Decode the internal format into the format used
559 static struct GNUNET_CRYPTO_RsaPrivateKey *
560 ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
562 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
564 gcry_mpi_t n, e, d, p, q, u;
570 size = ntohs (encoding->sizen);
571 rc = gcry_mpi_scan (&n,
573 &((const unsigned char *) (&encoding[1]))[pos],
575 pos += ntohs (encoding->sizen);
578 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
581 size = ntohs (encoding->sizee);
582 rc = gcry_mpi_scan (&e,
584 &((const unsigned char *) (&encoding[1]))[pos],
586 pos += ntohs (encoding->sizee);
589 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
590 gcry_mpi_release (n);
593 size = ntohs (encoding->sized);
594 rc = gcry_mpi_scan (&d,
596 &((const unsigned char *) (&encoding[1]))[pos],
598 pos += ntohs (encoding->sized);
601 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
602 gcry_mpi_release (n);
603 gcry_mpi_release (e);
607 size = ntohs (encoding->sizep);
610 rc = gcry_mpi_scan (&q,
612 &((const unsigned char *) (&encoding[1]))[pos],
614 pos += ntohs (encoding->sizep);
617 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
618 gcry_mpi_release (n);
619 gcry_mpi_release (e);
620 gcry_mpi_release (d);
626 size = ntohs (encoding->sizeq);
629 rc = gcry_mpi_scan (&p,
631 &((const unsigned char *) (&encoding[1]))[pos],
633 pos += ntohs (encoding->sizeq);
636 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
637 gcry_mpi_release (n);
638 gcry_mpi_release (e);
639 gcry_mpi_release (d);
641 gcry_mpi_release (q);
647 pos += ntohs (encoding->sizedmp1);
648 pos += ntohs (encoding->sizedmq1);
650 ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
654 rc = gcry_mpi_scan (&u,
656 &((const unsigned char *) (&encoding[1]))[pos],
660 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
661 gcry_mpi_release (n);
662 gcry_mpi_release (e);
663 gcry_mpi_release (d);
665 gcry_mpi_release (p);
667 gcry_mpi_release (q);
674 if ((p != NULL) && (q != NULL) && (u != NULL))
676 rc = gcry_sexp_build (&res, &size, /* erroff */
677 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
682 if ((p != NULL) && (q != NULL))
684 rc = gcry_sexp_build (&res, &size, /* erroff */
685 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
690 rc = gcry_sexp_build (&res, &size, /* erroff */
691 "(private-key(rsa(n %m)(e %m)(d %m)))",
695 gcry_mpi_release (n);
696 gcry_mpi_release (e);
697 gcry_mpi_release (d);
699 gcry_mpi_release (p);
701 gcry_mpi_release (q);
703 gcry_mpi_release (u);
706 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
708 if (gcry_pk_testkey (res))
710 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
714 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
720 struct KBlockKeyCacheLine
723 struct KskRsaPrivateKeyBinaryEncoded *pke;
726 static struct KBlockKeyCacheLine **cache;
728 static unsigned int cacheSize;
731 * Deterministically (!) create a hostkey using only the
732 * given HashCode as input to the PRNG.
734 struct GNUNET_CRYPTO_RsaPrivateKey *
735 GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
737 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
738 struct KBlockKeyCacheLine *line;
741 for (i = 0; i < cacheSize; i++)
743 if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
745 ret = ksk_decode_key (cache[i]->pke);
750 line = GNUNET_malloc (sizeof (struct KBlockKeyCacheLine));
752 line->pke = makeKblockKeyInternal (hc);
753 GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
754 cache[cacheSize - 1] = line;
755 return ksk_decode_key (line->pke);
759 void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
763 for (i = 0; i < cacheSize; i++)
765 GNUNET_free (cache[i]->pke);
766 GNUNET_free (cache[i]);
768 GNUNET_array_grow (cache, cacheSize, 0);
772 /* end of crypto_ksk.c */