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