aboutsummaryrefslogtreecommitdiff
path: root/src/util/crypto_ksk.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/util/crypto_ksk.c')
-rw-r--r--src/util/crypto_ksk.c319
1 files changed, 165 insertions, 154 deletions
diff --git a/src/util/crypto_ksk.c b/src/util/crypto_ksk.c
index 1aa493ca8..5107647ac 100644
--- a/src/util/crypto_ksk.c
+++ b/src/util/crypto_ksk.c
@@ -36,8 +36,8 @@
36#include "gnunet_common.h" 36#include "gnunet_common.h"
37#include "gnunet_crypto_lib.h" 37#include "gnunet_crypto_lib.h"
38#include "gnunet_os_lib.h" 38#include "gnunet_os_lib.h"
39#include <gmp.h>
40#include <gcrypt.h> 39#include <gcrypt.h>
40#include <limits.h>
41 41
42/** 42/**
43 * Log an error message at log-level 'level' that indicates 43 * Log an error message at log-level 'level' that indicates
@@ -49,12 +49,12 @@
49 49
50typedef struct 50typedef struct
51{ 51{
52 mpz_t n; /* public modulus */ 52 gcry_mpi_t n; /* public modulus */
53 mpz_t e; /* public exponent */ 53 gcry_mpi_t e; /* public exponent */
54 mpz_t d; /* exponent */ 54 gcry_mpi_t d; /* exponent */
55 mpz_t p; /* prime p. */ 55 gcry_mpi_t p; /* prime p. */
56 mpz_t q; /* prime q. */ 56 gcry_mpi_t q; /* prime q. */
57 mpz_t u; /* inverse of p mod q. */ 57 gcry_mpi_t u; /* inverse of p mod q. */
58} KBlock_secret_key; 58} KBlock_secret_key;
59 59
60/** 60/**
@@ -67,107 +67,139 @@ struct GNUNET_CRYPTO_RsaPrivateKey
67}; 67};
68 68
69 69
70static unsigned int
71get_nbits (mpz_t a)
72{
73 return mpz_sizeinbase (a, 2);
74}
75
76
77static void 70static void
78mpz_randomize (mpz_t n, unsigned int nbits, GNUNET_HashCode * rnd) 71mpz_randomize (gcry_mpi_t n, unsigned int nbits, GNUNET_HashCode * rnd)
79{ 72{
80 GNUNET_HashCode *tmp; 73 GNUNET_HashCode hc;
74 GNUNET_HashCode tmp;
81 int bits_per_hc = sizeof (GNUNET_HashCode) * 8; 75 int bits_per_hc = sizeof (GNUNET_HashCode) * 8;
82 int cnt; 76 int cnt;
83 int i; 77 int i;
84 78
85 GNUNET_assert (nbits > 0); 79 GNUNET_assert (nbits > 0);
86 cnt = (nbits + bits_per_hc - 1) / bits_per_hc; 80 cnt = (nbits + bits_per_hc - 1) / bits_per_hc;
87 tmp = GNUNET_malloc (sizeof (GNUNET_HashCode) * cnt); 81 gcry_mpi_set_ui (n, 0);
88 82
89 tmp[0] = *rnd; 83 tmp = *rnd;
90 for (i = 0; i < cnt - 1; i++) 84 for (i = 0; i < cnt; i++)
91 { 85 {
92 GNUNET_CRYPTO_hash (&tmp[i], sizeof (GNUNET_HashCode), &tmp[i + 1]); 86 int j;
87
88 if (i > 0)
89 GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), &tmp);
90 for (j = sizeof(GNUNET_HashCode) / sizeof(unsigned int); j > 0; j--)
91 {
92#if HAVE_GCRY_MPI_LSHIFT
93 gcry_mpi_lshift (n, n, sizeof(unsigned int));
94#else
95 gcry_mpi_mul_ui(n, n, pow (2, sizeof(unsigned int)));
96#endif
97 gcry_mpi_add_ui(n, n, ((unsigned int *) &tmp)[j]);
98 }
99 hc = tmp;
93 } 100 }
94 GNUNET_CRYPTO_hash (&tmp[i], sizeof (GNUNET_HashCode), rnd); 101 GNUNET_CRYPTO_hash (&hc, sizeof (GNUNET_HashCode), rnd);
95 mpz_import (n, cnt * sizeof (GNUNET_HashCode) / sizeof (unsigned int), 102 i = gcry_mpi_get_nbits (n);
96 1, sizeof (unsigned int), 1, 0, tmp);
97 GNUNET_free (tmp);
98 i = get_nbits (n);
99 while (i > nbits) 103 while (i > nbits)
100 mpz_clrbit (n, --i); 104 gcry_mpi_clear_bit (n, --i);
105}
106
107static unsigned int
108mpz_trailing_zeroes (gcry_mpi_t n)
109{
110 unsigned int idx, cnt;
111
112 cnt = gcry_mpi_get_nbits(n);
113 for (idx = 0; idx < cnt; idx++)
114 {
115 if (gcry_mpi_test_bit(n, idx) == 0)
116 return idx;
117 }
118
119 return ULONG_MAX;
120}
121
122static void
123mpz_tdiv_q_2exp (gcry_mpi_t q, gcry_mpi_t n, unsigned int b)
124{
125 gcry_mpi_t u, d;
126
127 u = gcry_mpi_set_ui (NULL, 1);
128 d = gcry_mpi_new (0);
129 gcry_mpi_mul_2exp (d, u, b);
130 gcry_mpi_div (q, NULL, n, d, 0);
101} 131}
102 132
103/** 133/**
104 * Return true if n is probably a prime 134 * Return true if n is probably a prime
105 */ 135 */
106static int 136static int
107is_prime (mpz_t n, int steps, GNUNET_HashCode * hc) 137is_prime (gcry_mpi_t n, int steps, GNUNET_HashCode * hc)
108{ 138{
109 mpz_t x; 139 gcry_mpi_t x;
110 mpz_t y; 140 gcry_mpi_t y;
111 mpz_t z; 141 gcry_mpi_t z;
112 mpz_t nminus1; 142 gcry_mpi_t nminus1;
113 mpz_t a2; 143 gcry_mpi_t a2;
114 mpz_t q; 144 gcry_mpi_t q;
115 unsigned int i, j, k; 145 unsigned int i, j, k;
116 int rc = 0; 146 int rc = 0;
117 unsigned int nbits; 147 unsigned int nbits;
118 148
119 mpz_init (x); 149 x = gcry_mpi_new (0);
120 mpz_init (y); 150 y = gcry_mpi_new (0);
121 mpz_init (z); 151 z = gcry_mpi_new (0);
122 mpz_init (nminus1); 152 nminus1 = gcry_mpi_new (0);
123 mpz_init_set_ui (a2, 2); 153 a2 = gcry_mpi_set_ui (NULL, 2);
124 nbits = get_nbits (n); 154
125 mpz_sub_ui (nminus1, n, 1); 155 nbits = gcry_mpi_get_nbits (n);
156 gcry_mpi_sub_ui(nminus1, n, 1);
126 157
127 /* Find q and k, so that n = 1 + 2^k * q . */ 158 /* Find q and k, so that n = 1 + 2^k * q . */
128 mpz_init_set (q, nminus1); 159 q = gcry_mpi_set (NULL, nminus1);
129 k = mpz_scan1 (q, 0); 160 k = mpz_trailing_zeroes (q);
130 mpz_tdiv_q_2exp (q, q, k); 161 mpz_tdiv_q_2exp (q, q, k);
131 162
132 for (i = 0; i < steps; i++) 163 for (i = 0; i < steps; i++)
133 { 164 {
134 if (!i) 165 if (!i)
135 { 166 {
136 mpz_set_ui (x, 2); 167 gcry_mpi_set_ui (x, 2);
137 } 168 }
138 else 169 else
139 { 170 {
140 mpz_randomize (x, nbits - 1, hc); 171 mpz_randomize (x, nbits - 1, hc);
141 GNUNET_assert (mpz_cmp (x, nminus1) < 0 && mpz_cmp_ui (x, 1) > 0); 172 GNUNET_assert (gcry_mpi_cmp (x, nminus1) < 0);
173 GNUNET_assert (gcry_mpi_cmp_ui (x, 1) > 0);
142 } 174 }
143 mpz_powm (y, x, q, n); 175 gcry_mpi_powm (y, x, q, n);
144 if (mpz_cmp_ui (y, 1) && mpz_cmp (y, nminus1)) 176 if (gcry_mpi_cmp_ui (y, 1) && gcry_mpi_cmp (y, nminus1))
145 { 177 {
146 for (j = 1; j < k && mpz_cmp (y, nminus1); j++) 178 for (j = 1; j < k && gcry_mpi_cmp (y, nminus1); j++)
147 { 179 {
148 mpz_powm (y, y, a2, n); 180 gcry_mpi_powm (y, y, a2, n);
149 if (!mpz_cmp_ui (y, 1)) 181 if (!gcry_mpi_cmp_ui (y, 1))
150 goto leave; /* Not a prime. */ 182 goto leave; /* Not a prime. */
151 } 183 }
152 if (mpz_cmp (y, nminus1)) 184 if (gcry_mpi_cmp (y, nminus1))
153 goto leave; /* Not a prime. */ 185 goto leave; /* Not a prime. */
154 } 186 }
155 } 187 }
156 rc = 1; /* May be a prime. */ 188 rc = 1; /* May be a prime. */
157 189
158leave: 190leave:
159 mpz_clear (x); 191 gcry_mpi_release (x);
160 mpz_clear (y); 192 gcry_mpi_release (y);
161 mpz_clear (z); 193 gcry_mpi_release (z);
162 mpz_clear (nminus1); 194 gcry_mpi_release (nminus1);
163 mpz_clear (q); 195 gcry_mpi_release (q);
164 mpz_clear (a2); 196 gcry_mpi_release (a2);
165 197
166 return rc; 198 return rc;
167} 199}
168 200
169static void 201static void
170gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc) 202gen_prime (gcry_mpi_t *ptest, unsigned int nbits, GNUNET_HashCode * hc)
171{ 203{
172 /* Note: 2 is not included because it can be tested more easily by 204 /* Note: 2 is not included because it can be tested more easily by
173 looking at bit 0. The last entry in this list is marked by a zero */ 205 looking at bit 0. The last entry in this list is marked by a zero */
@@ -256,22 +288,23 @@ gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc)
256#define DIM(v) (sizeof(v)/sizeof((v)[0])) 288#define DIM(v) (sizeof(v)/sizeof((v)[0]))
257 static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1; 289 static int no_of_small_prime_numbers = DIM (small_prime_numbers) - 1;
258 290
259 mpz_t prime, pminus1, val_2, val_3, result; 291 gcry_mpi_t prime, pminus1, val_2, val_3, result;
260 int i; 292 int i;
261 unsigned x, step; 293 unsigned x, step;
262 int *mods; 294 unsigned int *mods;
263 mpz_t tmp; 295 gcry_mpi_t tmp;
296 gcry_mpi_t sp;
264 297
265 GNUNET_assert (nbits >= 16); 298 GNUNET_assert (nbits >= 16);
266 299
267 mods = GNUNET_malloc (no_of_small_prime_numbers * sizeof (*mods)); 300 mods = GNUNET_malloc (no_of_small_prime_numbers * sizeof (*mods));
268 /* Make nbits fit into mpz_t implementation. */ 301 /* Make nbits fit into mpz_t implementation. */
269 mpz_init_set_ui (val_2, 2); 302 val_2 = gcry_mpi_set_ui (NULL, 2);
270 mpz_init_set_ui (val_3, 3); 303 val_3 = gcry_mpi_set_ui (NULL, 3);
271 mpz_init (prime); 304 prime = gcry_mpi_new(0);
272 mpz_init (result); 305 result = gcry_mpi_new(0);
273 mpz_init (pminus1); 306 pminus1 = gcry_mpi_new(0);
274 mpz_init (ptest); 307 *ptest = gcry_mpi_new(0);
275 while (1) 308 while (1)
276 { 309 {
277 /* generate a random number */ 310 /* generate a random number */
@@ -280,15 +313,23 @@ gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc)
280 generating a secret prime we are most probably doing that 313 generating a secret prime we are most probably doing that
281 for RSA, to make sure that the modulus does have the 314 for RSA, to make sure that the modulus does have the
282 requested key size we set the 2 high order bits. */ 315 requested key size we set the 2 high order bits. */
283 mpz_setbit (prime, nbits - 1); 316 gcry_mpi_set_bit (prime, nbits - 1);
284 mpz_setbit (prime, nbits - 2); 317 gcry_mpi_set_bit (prime, nbits - 2);
285 mpz_setbit (prime, 0); 318 gcry_mpi_set_bit (prime, 0);
286 319
287 /* Calculate all remainders. */ 320 /* Calculate all remainders. */
288 mpz_init (tmp); 321 tmp = gcry_mpi_new (0);
322 sp = gcry_mpi_new (0);
289 for (i = 0; (x = small_prime_numbers[i]); i++) 323 for (i = 0; (x = small_prime_numbers[i]); i++)
290 mods[i] = mpz_fdiv_r_ui (tmp, prime, x); 324 {
291 mpz_clear (tmp); 325 size_t written;
326
327 gcry_mpi_set_ui(sp, x);
328 gcry_mpi_div (NULL, tmp, prime, sp, -1 /* TODO CG: is this correct? */);
329 gcry_mpi_print (GCRYMPI_FMT_USG, (unsigned char *) &mods[i], sizeof(*mods), &written, tmp);
330 }
331 gcry_mpi_release (sp);
332 gcry_mpi_release (tmp);
292 /* Now try some primes starting with prime. */ 333 /* Now try some primes starting with prime. */
293 for (step = 0; step < 20000; step += 2) 334 for (step = 0; step < 20000; step += 2)
294 { 335 {
@@ -303,21 +344,21 @@ gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc)
303 if (x) 344 if (x)
304 continue; /* Found a multiple of an already known prime. */ 345 continue; /* Found a multiple of an already known prime. */
305 346
306 mpz_add_ui (ptest, prime, step); 347 gcry_mpi_add_ui (*ptest, prime, step);
307 if (!mpz_tstbit (ptest, nbits - 2)) 348 if (!gcry_mpi_test_bit (*ptest, nbits - 2))
308 break; 349 break;
309 350
310 /* Do a fast Fermat test now. */ 351 /* Do a fast Fermat test now. */
311 mpz_sub_ui (pminus1, ptest, 1); 352 gcry_mpi_sub_ui (pminus1, *ptest, 1);
312 mpz_powm (result, val_2, pminus1, ptest); 353 gcry_mpi_powm (result, val_2, pminus1, *ptest);
313 if ((!mpz_cmp_ui (result, 1)) && (is_prime (ptest, 5, hc))) 354 if ((!gcry_mpi_cmp_ui (result, 1)) && (is_prime (*ptest, 5, hc)))
314 { 355 {
315 /* Got it. */ 356 /* Got it. */
316 mpz_clear (val_2); 357 gcry_mpi_release (val_2);
317 mpz_clear (val_3); 358 gcry_mpi_release (val_3);
318 mpz_clear (result); 359 gcry_mpi_release (result);
319 mpz_clear (pminus1); 360 gcry_mpi_release (pminus1);
320 mpz_clear (prime); 361 gcry_mpi_release (prime);
321 GNUNET_free (mods); 362 GNUNET_free (mods);
322 return; 363 return;
323 } 364 }
@@ -326,32 +367,6 @@ gen_prime (mpz_t ptest, unsigned int nbits, GNUNET_HashCode * hc)
326} 367}
327 368
328/** 369/**
329 * Find the greatest common divisor G of A and B.
330 * Return: 1 if this 1, 0 in all other cases
331 */
332static int
333test_gcd (mpz_t g, mpz_t xa, mpz_t xb)
334{
335 mpz_t a, b;
336
337 mpz_init_set (a, xa);
338 mpz_init_set (b, xb);
339
340 /* TAOCP Vol II, 4.5.2, Algorithm A */
341 while (mpz_cmp_ui (b, 0))
342 {
343 mpz_fdiv_r (g, a, b); /* g used as temorary variable */
344 mpz_set (a, b);
345 mpz_set (b, g);
346 }
347 mpz_set (g, a);
348
349 mpz_clear (a);
350 mpz_clear (b);
351 return (0 == mpz_cmp_ui (g, 1));
352}
353
354/**
355 * Generate a key pair with a key of size NBITS. 370 * Generate a key pair with a key of size NBITS.
356 * @param sk where to store the key 371 * @param sk where to store the key
357 * @param nbits the number of bits to use 372 * @param nbits the number of bits to use
@@ -361,66 +376,66 @@ static void
361generate_kblock_key (KBlock_secret_key * sk, 376generate_kblock_key (KBlock_secret_key * sk,
362 unsigned int nbits, GNUNET_HashCode * hc) 377 unsigned int nbits, GNUNET_HashCode * hc)
363{ 378{
364 mpz_t t1, t2; 379 gcry_mpi_t t1, t2;
365 mpz_t phi; /* helper: (p-1)(q-1) */ 380 gcry_mpi_t phi; /* helper: (p-1)(q-1) */
366 mpz_t g; 381 gcry_mpi_t g;
367 mpz_t f; 382 gcry_mpi_t f;
368 383
369 /* make sure that nbits is even so that we generate p, q of equal size */ 384 /* make sure that nbits is even so that we generate p, q of equal size */
370 if ((nbits & 1)) 385 if ((nbits & 1))
371 nbits++; 386 nbits++;
372 387
373 mpz_init_set_ui (sk->e, 257); 388 sk->e = gcry_mpi_set_ui (NULL, 257);
374 mpz_init (sk->n); 389 sk->n = gcry_mpi_new(0);
375 mpz_init (sk->p); 390 sk->p = gcry_mpi_new(0);
376 mpz_init (sk->q); 391 sk->q = gcry_mpi_new(0);
377 mpz_init (sk->d); 392 sk->d = gcry_mpi_new(0);
378 mpz_init (sk->u); 393 sk->u = gcry_mpi_new(0);
379 394
380 mpz_init (t1); 395 t1 = gcry_mpi_new(0);
381 mpz_init (t2); 396 t2 = gcry_mpi_new(0);
382 mpz_init (phi); 397 phi = gcry_mpi_new(0);
383 mpz_init (g); 398 g = gcry_mpi_new(0);
384 mpz_init (f); 399 f = gcry_mpi_new(0);
385 400
386 do 401 do
387 { 402 {
388 do 403 do
389 { 404 {
390 mpz_clear (sk->p); 405 gcry_mpi_release (sk->p);
391 mpz_clear (sk->q); 406 gcry_mpi_release (sk->q);
392 gen_prime (sk->p, nbits / 2, hc); 407 gen_prime (&sk->p, nbits / 2, hc);
393 gen_prime (sk->q, nbits / 2, hc); 408 gen_prime (&sk->q, nbits / 2, hc);
394 409
395 if (mpz_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */ 410 if (gcry_mpi_cmp (sk->p, sk->q) > 0) /* p shall be smaller than q (for calc of u) */
396 mpz_swap (sk->p, sk->q); 411 gcry_mpi_swap (sk->p, sk->q);
397 /* calculate the modulus */ 412 /* calculate the modulus */
398 mpz_mul (sk->n, sk->p, sk->q); 413 gcry_mpi_mul (sk->n, sk->p, sk->q);
399 } 414 }
400 while (get_nbits (sk->n) != nbits); 415 while (gcry_mpi_get_nbits (sk->n) != nbits);
401 416
402 /* calculate Euler totient: phi = (p-1)(q-1) */ 417 /* calculate Euler totient: phi = (p-1)(q-1) */
403 mpz_sub_ui (t1, sk->p, 1); 418 gcry_mpi_sub_ui (t1, sk->p, 1);
404 mpz_sub_ui (t2, sk->q, 1); 419 gcry_mpi_sub_ui (t2, sk->q, 1);
405 mpz_mul (phi, t1, t2); 420 gcry_mpi_mul (phi, t1, t2);
406 mpz_gcd (g, t1, t2); 421 gcry_mpi_gcd (g, t1, t2);
407 mpz_fdiv_q (f, phi, g); 422 gcry_mpi_div (f, NULL, phi, g, -1 /* TODO CG: is this correct? */);
408 423
409 while (0 == test_gcd (t1, sk->e, phi)) 424 while (0 == gcry_mpi_gcd (t1, sk->e, phi))
410 { /* (while gcd is not 1) */ 425 { /* (while gcd is not 1) */
411 mpz_add_ui (sk->e, sk->e, 2); 426 gcry_mpi_add_ui (sk->e, sk->e, 2);
412 } 427 }
413 428
414 /* calculate the secret key d = e^1 mod phi */ 429 /* calculate the secret key d = e^1 mod phi */
415 } 430 }
416 while ((0 == mpz_invert (sk->d, sk->e, f)) || 431 while ((0 == gcry_mpi_invm (sk->d, sk->e, f)) ||
417 (0 == mpz_invert (sk->u, sk->p, sk->q))); 432 (0 == gcry_mpi_invm (sk->u, sk->p, sk->q)));
418 433
419 mpz_clear (t1); 434 gcry_mpi_release (t1);
420 mpz_clear (t2); 435 gcry_mpi_release (t2);
421 mpz_clear (phi); 436 gcry_mpi_release (phi);
422 mpz_clear (f); 437 gcry_mpi_release (f);
423 mpz_clear (g); 438 gcry_mpi_release (g);
424} 439}
425 440
426 441
@@ -453,8 +468,8 @@ makeKblockKeyInternal (const GNUNET_HashCode * hc)
453{ 468{
454 KBlock_secret_key sk; 469 KBlock_secret_key sk;
455 GNUNET_HashCode hx; 470 GNUNET_HashCode hx;
456 void *pbu[6]; 471 unsigned char *pbu[6];
457 mpz_t *pkv[6]; 472 gcry_mpi_t *pkv[6];
458 size_t sizes[6]; 473 size_t sizes[6];
459 struct KskRsaPrivateKeyBinaryEncoded *retval; 474 struct KskRsaPrivateKeyBinaryEncoded *retval;
460 int i; 475 int i;
@@ -480,11 +495,7 @@ makeKblockKeyInternal (const GNUNET_HashCode * hc)
480 size = sizeof (struct KskRsaPrivateKeyBinaryEncoded); 495 size = sizeof (struct KskRsaPrivateKeyBinaryEncoded);
481 for (i = 0; i < 6; i++) 496 for (i = 0; i < 6; i++)
482 { 497 {
483 pbu[i] = mpz_export (NULL, &sizes[i], 1, /* most significant word first */ 498 gcry_mpi_aprint(GCRYMPI_FMT_STD, &pbu[i], &sizes[i], *pkv[i]);
484 1, /* unit is bytes */
485 1, /* big endian */
486 0, /* nails */
487 *pkv[i]);
488 size += sizes[i]; 499 size += sizes[i];
489 } 500 }
490 GNUNET_assert (size < 65536); 501 GNUNET_assert (size < 65536);
@@ -512,7 +523,7 @@ makeKblockKeyInternal (const GNUNET_HashCode * hc)
512 memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]); 523 memcpy (&((char *) &retval[1])[i], pbu[5], sizes[5]);
513 for (i = 0; i < 6; i++) 524 for (i = 0; i < 6; i++)
514 { 525 {
515 mpz_clear (*pkv[i]); 526 gcry_mpi_release (*pkv[i]);
516 free (pbu[i]); 527 free (pbu[i]);
517 } 528 }
518 return retval; 529 return retval;