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,
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];
362 while (mods[i] + step >= x)
364 if (!(mods[i] + step))
367 if (i < no_of_small_prime_numbers)
368 continue; /* Found a multiple of an already known prime. */
370 gcry_mpi_add_ui (*ptest, prime, step);
371 if (!gcry_mpi_test_bit (*ptest, nbits - 2))
374 /* Do a fast Fermat test now. */
375 gcry_mpi_sub_ui (pminus1, *ptest, 1);
376 gcry_mpi_powm (result, val_2, pminus1, *ptest);
377 if ((!gcry_mpi_cmp_ui (result, 1)) && (is_prime (*ptest, 5, hc)))
380 gcry_mpi_release (sp);
381 gcry_mpi_release (tmp);
382 gcry_mpi_release (val_2);
383 gcry_mpi_release (val_3);
384 gcry_mpi_release (result);
385 gcry_mpi_release (pminus1);
386 gcry_mpi_release (prime);
394 * Generate a key pair with a key of size NBITS.
395 * @param sk where to store the key
396 * @param nbits the number of bits to use
397 * @param hc the HC to use for PRNG (modified!)
400 generate_kblock_key (KBlock_secret_key *sk, unsigned int nbits,
401 GNUNET_HashCode * hc)
404 gcry_mpi_t phi; /* helper: (p-1)(q-1) */
408 /* make sure that nbits is even so that we generate p, q of equal size */
412 sk->e = gcry_mpi_set_ui (NULL, 257);
413 sk->n = gcry_mpi_new (0);
414 sk->p = gcry_mpi_new (0);
415 sk->q = gcry_mpi_new (0);
416 sk->d = gcry_mpi_new (0);
417 sk->u = gcry_mpi_new (0);
419 t1 = gcry_mpi_new (0);
420 t2 = gcry_mpi_new (0);
421 phi = gcry_mpi_new (0);
422 g = gcry_mpi_new (0);
423 f = gcry_mpi_new (0);
429 gcry_mpi_release (sk->p);
430 gcry_mpi_release (sk->q);
431 gen_prime (&sk->p, nbits / 2, hc);
432 gen_prime (&sk->q, nbits / 2, hc);
434 if (gcry_mpi_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */
435 gcry_mpi_swap (sk->p, sk->q);
436 /* calculate the modulus */
437 gcry_mpi_mul (sk->n, sk->p, sk->q);
439 while (gcry_mpi_get_nbits (sk->n) != nbits);
441 /* calculate Euler totient: phi = (p-1)(q-1) */
442 gcry_mpi_sub_ui (t1, sk->p, 1);
443 gcry_mpi_sub_ui (t2, sk->q, 1);
444 gcry_mpi_mul (phi, t1, t2);
445 gcry_mpi_gcd (g, t1, t2);
446 gcry_mpi_div (f, NULL, phi, g, 0);
447 while (0 == gcry_mpi_gcd (t1, sk->e, phi))
448 { /* (while gcd is not 1) */
449 gcry_mpi_add_ui (sk->e, sk->e, 2);
452 /* calculate the secret key d = e^1 mod phi */
454 while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) ||
455 (0 == gcry_mpi_invm (sk->u, sk->p, sk->q)));
457 gcry_mpi_release (t1);
458 gcry_mpi_release (t2);
459 gcry_mpi_release (phi);
460 gcry_mpi_release (f);
461 gcry_mpi_release (g);
466 * Internal representation of the private key.
468 struct KskRsaPrivateKeyBinaryEncoded
471 * Total size of the structure, in bytes, in big-endian!
473 uint16_t len GNUNET_PACKED;
474 uint16_t sizen GNUNET_PACKED; /* in big-endian! */
475 uint16_t sizee GNUNET_PACKED; /* in big-endian! */
476 uint16_t sized GNUNET_PACKED; /* in big-endian! */
477 uint16_t sizep GNUNET_PACKED; /* in big-endian! */
478 uint16_t sizeq GNUNET_PACKED; /* in big-endian! */
479 uint16_t sizedmp1 GNUNET_PACKED; /* in big-endian! */
480 uint16_t sizedmq1 GNUNET_PACKED; /* in big-endian! */
481 /* followed by the actual values */
486 * Deterministically (!) create a hostkey using only the
487 * given HashCode as input to the PRNG.
489 static struct KskRsaPrivateKeyBinaryEncoded *
490 makeKblockKeyInternal (const GNUNET_HashCode * hc)
492 KBlock_secret_key sk;
494 unsigned char *pbu[6];
497 struct KskRsaPrivateKeyBinaryEncoded *retval;
502 generate_kblock_key (&sk, 1024, /* at least 10x as fast than 2048 bits
503 * -- we simply cannot afford 2048 bits
504 * even on modern hardware, and especially
505 * not since clearly a dictionary attack
506 * will still be much cheaper
507 * than breaking a 1024 bit RSA key.
508 * If an adversary can spend the time to
509 * break a 1024 bit RSA key just to forge
510 * a signature -- SO BE IT. [ CG, 6/2005 ] */
518 size = sizeof (struct KskRsaPrivateKeyBinaryEncoded);
519 for (i = 0; i < 6; i++)
521 gcry_mpi_aprint (GCRYMPI_FMT_STD, &pbu[i], &sizes[i], *pkv[i]);
524 GNUNET_assert (size < 65536);
525 retval = GNUNET_malloc (size);
526 retval->len = htons (size);
528 retval->sizen = htons (sizes[0]);
529 memcpy (&((char *) &retval[1])[i], pbu[0], sizes[0]);
531 retval->sizee = htons (sizes[1]);
532 memcpy (&((char *) &retval[1])[i], pbu[1], sizes[1]);
534 retval->sized = htons (sizes[2]);
535 memcpy (&((char *) &retval[1])[i], pbu[2], sizes[2]);
538 retval->sizep = htons (sizes[4]);
539 memcpy (&((char *) &retval[1])[i], pbu[4], sizes[4]);
541 retval->sizeq = htons (sizes[3]);
542 memcpy (&((char *) &retval[1])[i], pbu[3], sizes[3]);
544 retval->sizedmp1 = htons (0);
545 retval->sizedmq1 = htons (0);
546 memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]);
547 for (i = 0; i < 6; i++)
549 gcry_mpi_release (*pkv[i]);
557 * Decode the internal format into the format used
560 static struct GNUNET_CRYPTO_RsaPrivateKey *
561 ksk_decode_key (const struct KskRsaPrivateKeyBinaryEncoded *encoding)
563 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
565 gcry_mpi_t n, e, d, p, q, u;
571 size = ntohs (encoding->sizen);
572 rc = gcry_mpi_scan (&n, GCRYMPI_FMT_USG,
573 &((const unsigned char *) (&encoding[1]))[pos], size,
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, GCRYMPI_FMT_USG,
583 &((const unsigned char *) (&encoding[1]))[pos], size,
585 pos += ntohs (encoding->sizee);
588 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
589 gcry_mpi_release (n);
592 size = ntohs (encoding->sized);
593 rc = gcry_mpi_scan (&d, GCRYMPI_FMT_USG,
594 &((const unsigned char *) (&encoding[1]))[pos], size,
596 pos += ntohs (encoding->sized);
599 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
600 gcry_mpi_release (n);
601 gcry_mpi_release (e);
605 size = ntohs (encoding->sizep);
608 rc = gcry_mpi_scan (&q, GCRYMPI_FMT_USG,
609 &((const unsigned char *) (&encoding[1]))[pos], size,
611 pos += ntohs (encoding->sizep);
614 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
615 gcry_mpi_release (n);
616 gcry_mpi_release (e);
617 gcry_mpi_release (d);
623 size = ntohs (encoding->sizeq);
626 rc = gcry_mpi_scan (&p, GCRYMPI_FMT_USG,
627 &((const unsigned char *) (&encoding[1]))[pos], size,
629 pos += ntohs (encoding->sizeq);
632 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
633 gcry_mpi_release (n);
634 gcry_mpi_release (e);
635 gcry_mpi_release (d);
637 gcry_mpi_release (q);
643 pos += ntohs (encoding->sizedmp1);
644 pos += ntohs (encoding->sizedmq1);
646 ntohs (encoding->len) - sizeof (struct KskRsaPrivateKeyBinaryEncoded) -
650 rc = gcry_mpi_scan (&u, GCRYMPI_FMT_USG,
651 &((const unsigned char *) (&encoding[1]))[pos], size,
655 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_mpi_scan", rc);
656 gcry_mpi_release (n);
657 gcry_mpi_release (e);
658 gcry_mpi_release (d);
660 gcry_mpi_release (p);
662 gcry_mpi_release (q);
669 if ((p != NULL) && (q != NULL) && (u != NULL))
671 rc = gcry_sexp_build (&res, &size, /* erroff */
672 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)(u %m)))",
677 if ((p != NULL) && (q != NULL))
679 rc = gcry_sexp_build (&res, &size, /* erroff */
680 "(private-key(rsa(n %m)(e %m)(d %m)(p %m)(q %m)))",
685 rc = gcry_sexp_build (&res, &size, /* erroff */
686 "(private-key(rsa(n %m)(e %m)(d %m)))", n, e, d);
689 gcry_mpi_release (n);
690 gcry_mpi_release (e);
691 gcry_mpi_release (d);
693 gcry_mpi_release (p);
695 gcry_mpi_release (q);
697 gcry_mpi_release (u);
700 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_sexp_build", rc);
702 if (gcry_pk_testkey (res))
704 LOG_GCRY (GNUNET_ERROR_TYPE_ERROR, "gcry_pk_testkey", rc);
708 ret = GNUNET_malloc (sizeof (struct GNUNET_CRYPTO_RsaPrivateKey));
714 struct KBlockKeyCacheLine
717 struct KskRsaPrivateKeyBinaryEncoded *pke;
720 static struct KBlockKeyCacheLine **cache;
722 static unsigned int cacheSize;
725 * Deterministically (!) create a hostkey using only the
726 * given HashCode as input to the PRNG.
728 struct GNUNET_CRYPTO_RsaPrivateKey *
729 GNUNET_CRYPTO_rsa_key_create_from_hash (const GNUNET_HashCode * hc)
731 struct GNUNET_CRYPTO_RsaPrivateKey *ret;
732 struct KBlockKeyCacheLine *line;
735 for (i = 0; i < cacheSize; i++)
737 if (0 == memcmp (hc, &cache[i]->hc, sizeof (GNUNET_HashCode)))
739 ret = ksk_decode_key (cache[i]->pke);
744 line = GNUNET_malloc (sizeof (struct KBlockKeyCacheLine));
746 line->pke = makeKblockKeyInternal (hc);
747 GNUNET_array_grow (cache, cacheSize, cacheSize + 1);
748 cache[cacheSize - 1] = line;
749 return ksk_decode_key (line->pke);
753 void __attribute__ ((destructor)) GNUNET_CRYPTO_ksk_fini ()
757 for (i = 0; i < cacheSize; i++)
759 GNUNET_free (cache[i]->pke);
760 GNUNET_free (cache[i]);
762 GNUNET_array_grow (cache, cacheSize, 0);
766 /* end of crypto_ksk.c */