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 fprintf (stderr, "H: %s\n", GNUNET_h2s (&tmp));
92 for (j=0;j<sizeof(GNUNET_HashCode) / sizeof(uint32_t); j++)
94 #if HAVE_GCRY_MPI_LSHIFT
95 gcry_mpi_lshift (n, n, sizeof(uint32_t)*8);
97 gcry_mpi_mul_ui(n, n, 1 << (sizeof(uint32_t)*4));
98 gcry_mpi_mul_ui(n, n, 1 << (sizeof(uint32_t)*4));
100 gcry_mpi_add_ui(n, n, ntohl (((uint32_t *) &tmp)[j]));
104 GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), rnd);
105 i = gcry_mpi_get_nbits (n);
107 gcry_mpi_clear_bit (n, --i);
111 mpz_trailing_zeroes (gcry_mpi_t n)
113 unsigned int idx, cnt;
115 cnt = gcry_mpi_get_nbits(n);
116 for (idx = 0; idx < cnt; idx++)
118 if (gcry_mpi_test_bit(n, idx) == 0)
126 mpz_tdiv_q_2exp (gcry_mpi_t q, gcry_mpi_t n, unsigned int b)
130 u = gcry_mpi_set_ui (NULL, 1);
131 d = gcry_mpi_new (0);
132 gcry_mpi_mul_2exp (d, u, b);
133 gcry_mpi_div (q, NULL, n, d, 0);
137 * Return true if n is probably a prime
140 is_prime (gcry_mpi_t n, int steps, GNUNET_HashCode * hc)
148 unsigned int i, j, k;
152 x = gcry_mpi_new (0);
153 y = gcry_mpi_new (0);
154 z = gcry_mpi_new (0);
155 nminus1 = gcry_mpi_new (0);
156 a2 = gcry_mpi_set_ui (NULL, 2);
158 nbits = gcry_mpi_get_nbits (n);
159 gcry_mpi_sub_ui(nminus1, n, 1);
161 /* Find q and k, so that n = 1 + 2^k * q . */
162 q = gcry_mpi_set (NULL, nminus1);
163 k = mpz_trailing_zeroes (q);
164 mpz_tdiv_q_2exp (q, q, k);
166 for (i = 0; i < steps; i++)
170 gcry_mpi_set_ui (x, 2);
174 mpz_randomize (x, nbits - 1, hc);
175 GNUNET_assert (gcry_mpi_cmp (x, nminus1) < 0);
176 GNUNET_assert (gcry_mpi_cmp_ui (x, 1) > 0);
178 gcry_mpi_powm (y, x, q, n);
179 if (gcry_mpi_cmp_ui (y, 1) && gcry_mpi_cmp (y, nminus1))
181 for (j = 1; j < k && gcry_mpi_cmp (y, nminus1); j++)
183 gcry_mpi_powm (y, y, a2, n);
184 if (!gcry_mpi_cmp_ui (y, 1))
185 goto leave; /* Not a prime. */
187 if (gcry_mpi_cmp (y, nminus1))
188 goto leave; /* Not a prime. */
191 rc = 1; /* May be a prime. */
194 gcry_mpi_release (x);
195 gcry_mpi_release (y);
196 gcry_mpi_release (z);
197 gcry_mpi_release (nminus1);
198 gcry_mpi_release (q);
199 gcry_mpi_release (a2);
205 gen_prime (gcry_mpi_t *ptest, unsigned int nbits, GNUNET_HashCode * hc)
207 /* Note: 2 is not included because it can be tested more easily by
208 looking at bit 0. The last entry in this list is marked by a zero */
209 static const uint16_t small_prime_numbers[] = {
210 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43,
211 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101,
212 103, 107, 109, 113, 127, 131, 137, 139, 149, 151,
213 157, 163, 167, 173, 179, 181, 191, 193, 197, 199,
214 211, 223, 227, 229, 233, 239, 241, 251, 257, 263,
215 269, 271, 277, 281, 283, 293, 307, 311, 313, 317,
216 331, 337, 347, 349, 353, 359, 367, 373, 379, 383,
217 389, 397, 401, 409, 419, 421, 431, 433, 439, 443,
218 449, 457, 461, 463, 467, 479, 487, 491, 499, 503,
219 509, 521, 523, 541, 547, 557, 563, 569, 571, 577,
220 587, 593, 599, 601, 607, 613, 617, 619, 631, 641,
221 643, 647, 653, 659, 661, 673, 677, 683, 691, 701,
222 709, 719, 727, 733, 739, 743, 751, 757, 761, 769,
223 773, 787, 797, 809, 811, 821, 823, 827, 829, 839,
224 853, 857, 859, 863, 877, 881, 883, 887, 907, 911,
225 919, 929, 937, 941, 947, 953, 967, 971, 977, 983,
226 991, 997, 1009, 1013, 1019, 1021, 1031, 1033,
227 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091,
228 1093, 1097, 1103, 1109, 1117, 1123, 1129, 1151,
229 1153, 1163, 1171, 1181, 1187, 1193, 1201, 1213,
230 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277,
231 1279, 1283, 1289, 1291, 1297, 1301, 1303, 1307,
232 1319, 1321, 1327, 1361, 1367, 1373, 1381, 1399,
233 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451,
234 1453, 1459, 1471, 1481, 1483, 1487, 1489, 1493,
235 1499, 1511, 1523, 1531, 1543, 1549, 1553, 1559,
236 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609,
237 1613, 1619, 1621, 1627, 1637, 1657, 1663, 1667,
238 1669, 1693, 1697, 1699, 1709, 1721, 1723, 1733,
239 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789,
240 1801, 1811, 1823, 1831, 1847, 1861, 1867, 1871,
241 1873, 1877, 1879, 1889, 1901, 1907, 1913, 1931,
242 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997,
243 1999, 2003, 2011, 2017, 2027, 2029, 2039, 2053,
244 2063, 2069, 2081, 2083, 2087, 2089, 2099, 2111,
245 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161,
246 2179, 2203, 2207, 2213, 2221, 2237, 2239, 2243,
247 2251, 2267, 2269, 2273, 2281, 2287, 2293, 2297,
248 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357,
249 2371, 2377, 2381, 2383, 2389, 2393, 2399, 2411,
250 2417, 2423, 2437, 2441, 2447, 2459, 2467, 2473,
251 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551,
252 2557, 2579, 2591, 2593, 2609, 2617, 2621, 2633,
253 2647, 2657, 2659, 2663, 2671, 2677, 2683, 2687,
254 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729,
255 2731, 2741, 2749, 2753, 2767, 2777, 2789, 2791,
256 2797, 2801, 2803, 2819, 2833, 2837, 2843, 2851,
257 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917,
258 2927, 2939, 2953, 2957, 2963, 2969, 2971, 2999,
259 3001, 3011, 3019, 3023, 3037, 3041, 3049, 3061,
260 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137,
261 3163, 3167, 3169, 3181, 3187, 3191, 3203, 3209,
262 3217, 3221, 3229, 3251, 3253, 3257, 3259, 3271,
263 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331,
264 3343, 3347, 3359, 3361, 3371, 3373, 3389, 3391,
265 3407, 3413, 3433, 3449, 3457, 3461, 3463, 3467,
266 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533,
267 3539, 3541, 3547, 3557, 3559, 3571, 3581, 3583,
268 3593, 3607, 3613, 3617, 3623, 3631, 3637, 3643,
269 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709,
270 3719, 3727, 3733, 3739, 3761, 3767, 3769, 3779,
271 3793, 3797, 3803, 3821, 3823, 3833, 3847, 3851,
272 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917,
273 3919, 3923, 3929, 3931, 3943, 3947, 3967, 3989,
274 4001, 4003, 4007, 4013, 4019, 4021, 4027, 4049,
275 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111,
276 4127, 4129, 4133, 4139, 4153, 4157, 4159, 4177,
277 4201, 4211, 4217, 4219, 4229, 4231, 4241, 4243,
278 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297,
279 4327, 4337, 4339, 4349, 4357, 4363, 4373, 4391,
280 4397, 4409, 4421, 4423, 4441, 4447, 4451, 4457,
281 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519,
282 4523, 4547, 4549, 4561, 4567, 4583, 4591, 4597,
283 4603, 4621, 4637, 4639, 4643, 4649, 4651, 4657,
284 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729,
285 4733, 4751, 4759, 4783, 4787, 4789, 4793, 4799,
286 4801, 4813, 4817, 4831, 4861, 4871, 4877, 4889,
287 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951,
288 4957, 4967, 4969, 4973, 4987, 4993, 4999,
291 #define DIM(v) (sizeof(v)/sizeof((v)[0]))
292 static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
294 gcry_mpi_t prime, pminus1, val_2, val_3, result;
297 unsigned int mods[no_of_small_prime_numbers];
301 GNUNET_assert (nbits >= 16);
303 /* Make nbits fit into mpz_t implementation. */
304 val_2 = gcry_mpi_set_ui (NULL, 2);
305 val_3 = gcry_mpi_set_ui (NULL, 3);
306 prime = gcry_mpi_snew(0);
307 result = gcry_mpi_new(0);
308 pminus1 = gcry_mpi_new(0);
309 *ptest = gcry_mpi_new(0);
310 tmp = gcry_mpi_new (0);
311 sp = gcry_mpi_new (0);
314 /* generate a random number */
315 mpz_randomize (prime, nbits, hc);
316 /* Set high order bit to 1, set low order bit to 1. If we are
317 generating a secret prime we are most probably doing that
318 for RSA, to make sure that the modulus does have the
319 requested key size we set the 2 high order bits. */
320 gcry_mpi_set_bit (prime, nbits - 1);
321 gcry_mpi_set_bit (prime, nbits - 2);
322 gcry_mpi_set_bit (prime, 0);
324 /* Calculate all remainders. */
325 for (i = 0; i < no_of_small_prime_numbers; i++)
329 gcry_mpi_set_ui(sp, small_prime_numbers[i]);
330 gcry_mpi_div (NULL, tmp, prime, sp, -1);
332 written = sizeof (unsigned int);
334 gcry_mpi_print (GCRYMPI_FMT_USG,
335 (unsigned char*) &mods[i], written, &written,
338 /* Now try some primes starting with prime. */
339 for (step = 0; step < 20000; step += 2)
341 /* Check against all the small primes we have in mods. */
342 for (i = 0; i < no_of_small_prime_numbers; i++)
344 uint16_t x = small_prime_numbers[i];
345 while (mods[i] + step >= x)
347 if (!(mods[i] + step))
350 if (i < no_of_small_prime_numbers)
351 continue; /* Found a multiple of an already known prime. */
353 gcry_mpi_add_ui (*ptest, prime, step);
354 if (!gcry_mpi_test_bit (*ptest, nbits - 2))
357 /* Do a fast Fermat test now. */
358 gcry_mpi_sub_ui (pminus1, *ptest, 1);
359 gcry_mpi_powm (result, val_2, pminus1, *ptest);
360 if ((!gcry_mpi_cmp_ui (result, 1)) && (is_prime (*ptest, 5, hc)))
363 gcry_mpi_release (sp);
364 gcry_mpi_release (tmp);
365 gcry_mpi_release (val_2);
366 gcry_mpi_release (val_3);
367 gcry_mpi_release (result);
368 gcry_mpi_release (pminus1);
369 gcry_mpi_release (prime);
377 * Generate a key pair with a key of size NBITS.
378 * @param sk where to store the key
379 * @param nbits the number of bits to use
380 * @param hc the HC to use for PRNG (modified!)
383 generate_kblock_key (KBlock_secret_key * sk,
384 unsigned int nbits, GNUNET_HashCode * hc)
387 gcry_mpi_t phi; /* helper: (p-1)(q-1) */
391 /* make sure that nbits is even so that we generate p, q of equal size */
395 sk->e = gcry_mpi_set_ui (NULL, 257);
396 sk->n = gcry_mpi_new(0);
397 sk->p = gcry_mpi_new(0);
398 sk->q = gcry_mpi_new(0);
399 sk->d = gcry_mpi_new(0);
400 sk->u = gcry_mpi_new(0);
402 t1 = gcry_mpi_new(0);
403 t2 = gcry_mpi_new(0);
404 phi = gcry_mpi_new(0);
412 gcry_mpi_release (sk->p);
413 gcry_mpi_release (sk->q);
414 gen_prime (&sk->p, nbits / 2, hc);
415 gen_prime (&sk->q, nbits / 2, hc);
417 if (gcry_mpi_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */
418 gcry_mpi_swap (sk->p, sk->q);
419 /* calculate the modulus */
420 gcry_mpi_mul (sk->n, sk->p, sk->q);
422 while (gcry_mpi_get_nbits (sk->n) != nbits);
424 /* calculate Euler totient: phi = (p-1)(q-1) */
425 gcry_mpi_sub_ui (t1, sk->p, 1);
426 gcry_mpi_sub_ui (t2, sk->q, 1);
427 gcry_mpi_mul (phi, t1, t2);
428 gcry_mpi_gcd (g, t1, t2);
429 gcry_mpi_div (f, NULL, phi, g, 0);
430 while (0 == gcry_mpi_gcd (t1, sk->e, phi))
431 { /* (while gcd is not 1) */
432 gcry_mpi_add_ui (sk->e, sk->e, 2);
435 /* calculate the secret key d = e^1 mod phi */
437 while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) ||
438 (0 == gcry_mpi_invm (sk->u, sk->p, sk->q)));
440 gcry_mpi_release (t1);
441 gcry_mpi_release (t2);
442 gcry_mpi_release (phi);
443 gcry_mpi_release (f);
444 gcry_mpi_release (g);
449 * Internal representation of the private key.
451 struct KskRsaPrivateKeyBinaryEncoded
454 * Total size of the structure, in bytes, in big-endian!
456 uint16_t len GNUNET_PACKED;
457 uint16_t sizen GNUNET_PACKED; /* in big-endian! */
458 uint16_t sizee GNUNET_PACKED; /* in big-endian! */
459 uint16_t sized GNUNET_PACKED; /* in big-endian! */
460 uint16_t sizep GNUNET_PACKED; /* in big-endian! */
461 uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
462 uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
463 uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
464 /* followed by the actual values */
469 * Deterministically (!) create a hostkey using only the
470 * given HashCode as input to the PRNG.
472 static struct KskRsaPrivateKeyBinaryEncoded *
473 makeKblockKeyInternal (const GNUNET_HashCode * hc)
475 KBlock_secret_key sk;
477 unsigned char *pbu[6];
480 struct KskRsaPrivateKeyBinaryEncoded *retval;
485 generate_kblock_key (&sk, 1024, /* at least 10x as fast than 2048 bits
486 -- we simply cannot afford 2048 bits
487 even on modern hardware, and especially
488 not since clearly a dictionary attack
489 will still be much cheaper
490 than breaking a 1024 bit RSA key.
491 If an adversary can spend the time to
492 break a 1024 bit RSA key just to forge
493 a signature -- SO BE IT. [ CG, 6/2005 ] */
501 size = sizeof (struct KskRsaPrivateKeyBinaryEncoded);
502 for (i = 0; i < 6; i++)
504 gcry_mpi_aprint(GCRYMPI_FMT_STD, &pbu[i], &sizes[i], *pkv[i]);
507 GNUNET_assert (size < 65536);
508 retval = GNUNET_malloc (size);
509 retval->len = htons (size);
511 retval->sizen = htons (sizes[0]);
512 memcpy (&((char *) &retval[1])[i], pbu[0], sizes[0]);
514 retval->sizee = htons (sizes[1]);
515 memcpy (&((char *) &retval[1])[i], pbu[1], sizes[1]);
517 retval->sized = htons (sizes[2]);
518 memcpy (&((char *) &retval[1])[i], pbu[2], sizes[2]);
521 retval->sizep = htons (sizes[4]);
522 memcpy (&((char *) &retval[1])[i], pbu[4], sizes[4]);
524 retval->sizeq = htons (sizes[3]);
525 memcpy (&((char *) &retval[1])[i], pbu[3], sizes[3]);
527 retval->sizedmp1 = htons (0);
528 retval->sizedmq1 = htons (0);
529 memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]);
530 for (i = 0; i < 6; i++)
532 gcry_mpi_release (*pkv[i]);
540 * Decode the internal format into the format used
543 static struct GNUNET_CRYPTO_RsaPrivateKey *
544 ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
546 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
548 gcry_mpi_t n, e, d, p, q, u;
554 size = ntohs (encoding->sizen);
555 rc = gcry_mpi_scan (&n,
557 &((const unsigned char *) (&encoding[1]))[pos],
559 pos += ntohs (encoding->sizen);
562 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
565 size = ntohs (encoding->sizee);
566 rc = gcry_mpi_scan (&e,
568 &((const unsigned char *) (&encoding[1]))[pos],
570 pos += ntohs (encoding->sizee);
573 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
574 gcry_mpi_release (n);
577 size = ntohs (encoding->sized);
578 rc = gcry_mpi_scan (&d,
580 &((const unsigned char *) (&encoding[1]))[pos],
582 pos += ntohs (encoding->sized);
585 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
586 gcry_mpi_release (n);
587 gcry_mpi_release (e);
591 size = ntohs (encoding->sizep);
594 rc = gcry_mpi_scan (&q,
596 &((const unsigned char *) (&encoding[1]))[pos],
598 pos += ntohs (encoding->sizep);
601 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
602 gcry_mpi_release (n);
603 gcry_mpi_release (e);
604 gcry_mpi_release (d);
610 size = ntohs (encoding->sizeq);
613 rc = gcry_mpi_scan (&p,
615 &((const unsigned char *) (&encoding[1]))[pos],
617 pos += ntohs (encoding->sizeq);
620 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
621 gcry_mpi_release (n);
622 gcry_mpi_release (e);
623 gcry_mpi_release (d);
625 gcry_mpi_release (q);
631 pos += ntohs (encoding->sizedmp1);
632 pos += ntohs (encoding->sizedmq1);
634 ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
638 rc = gcry_mpi_scan (&u,
640 &((const unsigned char *) (&encoding[1]))[pos],
644 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
645 gcry_mpi_release (n);
646 gcry_mpi_release (e);
647 gcry_mpi_release (d);
649 gcry_mpi_release (p);
651 gcry_mpi_release (q);
658 if ((p != NULL) && (q != NULL) && (u != NULL))
660 rc = gcry_sexp_build (&res, &size, /* erroff */
661 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
666 if ((p != NULL) && (q != NULL))
668 rc = gcry_sexp_build (&res, &size, /* erroff */
669 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
674 rc = gcry_sexp_build (&res, &size, /* erroff */
675 "(private-key(rsa(n %m)(e %m)(d %m)))",
679 gcry_mpi_release (n);
680 gcry_mpi_release (e);
681 gcry_mpi_release (d);
683 gcry_mpi_release (p);
685 gcry_mpi_release (q);
687 gcry_mpi_release (u);
690 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
692 if (gcry_pk_testkey (res))
694 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
698 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
704 struct KBlockKeyCacheLine
707 struct KskRsaPrivateKeyBinaryEncoded *pke;
710 static struct KBlockKeyCacheLine **cache;
712 static unsigned int cacheSize;
715 * Deterministically (!) create a hostkey using only the
716 * given HashCode as input to the PRNG.
718 struct GNUNET_CRYPTO_RsaPrivateKey *
719 GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
721 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
722 struct KBlockKeyCacheLine *line;
725 for (i = 0; i < cacheSize; i++)
727 if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
729 ret = ksk_decode_key (cache[i]->pke);
734 line = GNUNET_malloc (sizeof (struct KBlockKeyCacheLine));
736 line->pke = makeKblockKeyInternal (hc);
737 GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
738 cache[cacheSize - 1] = line;
739 return ksk_decode_key (line->pke);
743 void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
747 for (i = 0; i < cacheSize; i++)
749 GNUNET_free (cache[i]->pke);
750 GNUNET_free (cache[i]);
752 GNUNET_array_grow (cache, cacheSize, 0);
756 /* end of crypto_ksk.c */