diff options
-rw-r--r-- | Makefile.am | 3 | ||||
-rw-r--r-- | configure.ac | 2 | ||||
-rw-r--r-- | crypto.c | 485 | ||||
-rw-r--r-- | crypto.h | 78 | ||||
-rw-r--r-- | smc.c | 403 | ||||
-rw-r--r-- | smc.h | 83 | ||||
-rw-r--r-- | test_crypto.c | 45 |
7 files changed, 539 insertions, 560 deletions
diff --git a/Makefile.am b/Makefile.am index 76820c6..0f9dd23 100644 --- a/Makefile.am +++ b/Makefile.am | |||
@@ -7,8 +7,7 @@ lib_LTLIBRARIES = \ | |||
7 | libbrandt_la_SOURCES = \ | 7 | libbrandt_la_SOURCES = \ |
8 | brandt.c \ | 8 | brandt.c \ |
9 | crypto.c \ | 9 | crypto.c \ |
10 | util.c \ | 10 | util.c |
11 | smc.c | ||
12 | 11 | ||
13 | libbrandt_la_LIBADD = \ | 12 | libbrandt_la_LIBADD = \ |
14 | -lgcrypt -lgpg-error | 13 | -lgcrypt -lgpg-error |
diff --git a/configure.ac b/configure.ac index 14b04b4..7045a2f 100644 --- a/configure.ac +++ b/configure.ac | |||
@@ -6,7 +6,7 @@ AC_INIT([libbrandt], [0.1], [teichm@net.in.tum.de]) | |||
6 | 6 | ||
7 | AM_INIT_AUTOMAKE([1.15]) | 7 | AM_INIT_AUTOMAKE([1.15]) |
8 | 8 | ||
9 | AC_CONFIG_SRCDIR([smc.c]) | 9 | AC_CONFIG_SRCDIR([brandt.c]) |
10 | #AC_CONFIG_HEADERS([config.h]) | 10 | #AC_CONFIG_HEADERS([config.h]) |
11 | 11 | ||
12 | # Checks for programs. | 12 | # Checks for programs. |
@@ -19,25 +19,22 @@ | |||
19 | * @brief Implementation of the crypto primitives. | 19 | * @brief Implementation of the crypto primitives. |
20 | */ | 20 | */ |
21 | 21 | ||
22 | |||
22 | #include <arpa/inet.h> | 23 | #include <arpa/inet.h> |
24 | #include <gcrypt.h> | ||
23 | 25 | ||
24 | #include "crypto.h" | 26 | #include "crypto.h" |
27 | #include "internals.h" | ||
25 | #include "util.h" | 28 | #include "util.h" |
26 | 29 | ||
27 | #define CURVE "Ed25519" | 30 | #define CURVE "Ed25519" |
28 | 31 | ||
29 | struct brandt_ec_skey { | ||
30 | unsigned char d[256 / 8]; | ||
31 | }; | ||
32 | 32 | ||
33 | struct brandt_ec_pkey { | 33 | static gcry_ctx_t ec_ctx; |
34 | unsigned char q_y[256 / 8]; | 34 | static gcry_mpi_point_t ec_gen; |
35 | }; | 35 | static gcry_mpi_point_t ec_zero; |
36 | static gcry_mpi_t ec_n; | ||
36 | 37 | ||
37 | gcry_ctx_t ec_ctx; | ||
38 | gcry_mpi_point_t ec_gen; | ||
39 | gcry_mpi_point_t ec_zero; | ||
40 | gcry_mpi_t ec_n; | ||
41 | 38 | ||
42 | /** | 39 | /** |
43 | * brandt_crypto_init | 40 | * brandt_crypto_init |
@@ -175,39 +172,16 @@ brandt_mpi_scan_unsigned (gcry_mpi_t *result, const void *data, size_t size) | |||
175 | } | 172 | } |
176 | 173 | ||
177 | 174 | ||
178 | //gcry_mpi_point_t | ||
179 | //deserialize_point(const struct brandt_point* data, const int len) | ||
180 | //{ | ||
181 | // gcry_sexp_t s; | ||
182 | // gcry_ctx_t ctx; | ||
183 | // gcry_mpi_point_t ret; | ||
184 | // gcry_error_t rc; | ||
185 | // | ||
186 | // rc = gcry_sexp_build(&s, NULL, "(public-key(ecc(curve " CURVE ")(q %b)))", | ||
187 | // len, data); | ||
188 | // brandt_assert_gpgerr(rc); | ||
189 | // | ||
190 | // rc = gcry_mpi_ec_new(&ctx, s, NULL); | ||
191 | // brandt_assert_gpgerr(rc); | ||
192 | // gcry_sexp_release(s); | ||
193 | // | ||
194 | // ret = gcry_mpi_ec_get_point("q", ctx, 0); | ||
195 | // brandt_assert(ret); | ||
196 | // gcry_ctx_release(ctx); | ||
197 | // return ret; | ||
198 | //} | ||
199 | |||
200 | |||
201 | /* --- EC --- */ | 175 | /* --- EC --- */ |
202 | 176 | ||
203 | /** | 177 | /** |
204 | * brandt_ec_skey_create | 178 | * ec_skey_create |
205 | * | 179 | * |
206 | * @param[out] skey where to store the generated secret key. This has to be an | 180 | * @param[out] skey where to store the generated secret key. This has to be an |
207 | * already initialized mpi. | 181 | * already initialized mpi. |
208 | */ | 182 | */ |
209 | void | 183 | void |
210 | brandt_ec_skey_create (gcry_mpi_t skey) | 184 | ec_skey_create (gcry_mpi_t skey) |
211 | { | 185 | { |
212 | gcry_mpi_t ret; | 186 | gcry_mpi_t ret; |
213 | gcry_sexp_t s_keyparam; | 187 | gcry_sexp_t s_keyparam; |
@@ -241,45 +215,45 @@ brandt_ec_skey_create (gcry_mpi_t skey) | |||
241 | 215 | ||
242 | 216 | ||
243 | /** | 217 | /** |
244 | * brandt_ec_keypair_create | 218 | * ec_keypair_create |
245 | * | 219 | * |
246 | * @param[out] pkey where to store the generated public key | 220 | * @param[out] pkey where to store the generated public key |
247 | * @param[out] skey where to store the generated secret key | 221 | * @param[out] skey where to store the generated secret key |
248 | */ | 222 | */ |
249 | void | 223 | void |
250 | brandt_ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey) | 224 | ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey) |
251 | { | 225 | { |
252 | brandt_assert (NULL != pkey); | 226 | brandt_assert (NULL != pkey); |
253 | brandt_assert (NULL != skey); | 227 | brandt_assert (NULL != skey); |
254 | 228 | ||
255 | brandt_ec_skey_create (skey); | 229 | ec_skey_create (skey); |
256 | gcry_mpi_ec_mul (pkey, skey, ec_gen, ec_ctx); | 230 | gcry_mpi_ec_mul (pkey, skey, ec_gen, ec_ctx); |
257 | } | 231 | } |
258 | 232 | ||
259 | 233 | ||
260 | /** | 234 | /** |
261 | * brandt_ec_keypair_create_base | 235 | * ec_keypair_create_base |
262 | * | 236 | * |
263 | * @param[out] pkey where to store the generated public key | 237 | * @param[out] pkey where to store the generated public key |
264 | * @param[out] skey where to store the generated secret key | 238 | * @param[out] skey where to store the generated secret key |
265 | * @param[in] base which base point should be used to calculate the public key | 239 | * @param[in] base which base point should be used to calculate the public key |
266 | */ | 240 | */ |
267 | void | 241 | void |
268 | brandt_ec_keypair_create_base (gcry_mpi_point_t pkey, | 242 | ec_keypair_create_base (gcry_mpi_point_t pkey, |
269 | gcry_mpi_t skey, | 243 | gcry_mpi_t skey, |
270 | const gcry_mpi_point_t base) | 244 | const gcry_mpi_point_t base) |
271 | { | 245 | { |
272 | brandt_assert (NULL != pkey); | 246 | brandt_assert (NULL != pkey); |
273 | brandt_assert (NULL != skey); | 247 | brandt_assert (NULL != skey); |
274 | brandt_assert (NULL != base); | 248 | brandt_assert (NULL != base); |
275 | 249 | ||
276 | brandt_ec_skey_create (skey); | 250 | ec_skey_create (skey); |
277 | gcry_mpi_ec_mul (pkey, skey, base, ec_ctx); | 251 | gcry_mpi_ec_mul (pkey, skey, base, ec_ctx); |
278 | } | 252 | } |
279 | 253 | ||
280 | 254 | ||
281 | /** | 255 | /** |
282 | * brandt_ec_point_cmp compares two curve points | 256 | * ec_point_cmp compares two curve points |
283 | * | 257 | * |
284 | * @param[in] a the first point | 258 | * @param[in] a the first point |
285 | * @param[in] b the second point | 259 | * @param[in] b the second point |
@@ -287,7 +261,7 @@ brandt_ec_keypair_create_base (gcry_mpi_point_t pkey, | |||
287 | * else otherwise | 261 | * else otherwise |
288 | */ | 262 | */ |
289 | int | 263 | int |
290 | brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) | 264 | ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) |
291 | { | 265 | { |
292 | int ret = 1; | 266 | int ret = 1; |
293 | gcry_mpi_t ax = gcry_mpi_new (0); | 267 | gcry_mpi_t ax = gcry_mpi_new (0); |
@@ -316,24 +290,431 @@ brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) | |||
316 | } | 290 | } |
317 | 291 | ||
318 | 292 | ||
293 | static gcry_mpi_point_t ** | ||
294 | smc_init2 (uint16_t size1, uint16_t size2) | ||
295 | { | ||
296 | uint16_t i, j; | ||
297 | gcry_mpi_point_t **ret; | ||
298 | gcry_mpi_point_t *data; | ||
299 | |||
300 | ret = calloc (size1, sizeof (*ret) + (size2 * sizeof (**ret))); | ||
301 | brandt_assert (NULL != ret); | ||
302 | data = (gcry_mpi_point_t *)&ret[size1]; | ||
303 | for (i = 0; i < size1; i++) | ||
304 | { | ||
305 | ret[i] = &data[i * size2]; | ||
306 | for (j = 0; j < size2; j++) | ||
307 | ret[i][j] = gcry_mpi_point_new (0); | ||
308 | } | ||
309 | return ret; | ||
310 | } | ||
311 | |||
312 | |||
313 | static void | ||
314 | smc_free2 (gcry_mpi_point_t **dst, uint16_t size1, uint16_t size2) | ||
315 | { | ||
316 | uint16_t i, j; | ||
317 | |||
318 | for (i = 0; i < size1; i++) | ||
319 | for (j = 0; j < size2; j++) | ||
320 | gcry_mpi_point_release (dst[i][j]); | ||
321 | free (dst); | ||
322 | } | ||
323 | |||
324 | |||
325 | /** | ||
326 | * smc_sums_partial calculates sums up until the current index and stores them | ||
327 | * in @a out. @$f\forall i \leq len: out_i=sum_{h=1}^iin_h@$f | ||
328 | * | ||
329 | * @param[out] out Where to store the resulting sums. Points may be given | ||
330 | * uninitialized, but the appropriate amount of memory has to be allocated | ||
331 | * beforehand. | ||
332 | * @param[in] in Input points. | ||
333 | * @param[in] len The length of both @a out and @a in. | ||
334 | */ | ||
335 | static void | ||
336 | smc_sums_partial (gcry_mpi_point_t out[], gcry_mpi_point_t in[], uint16_t len) | ||
337 | { | ||
338 | uint16_t i; | ||
339 | |||
340 | for (i = 0; i < len; i++) | ||
341 | { | ||
342 | out[i] = gcry_mpi_point_new (0); | ||
343 | gcry_mpi_ec_add (out[i], in[i], (i ? out[i - 1] : ec_zero), ec_ctx); | ||
344 | brandt_assert (NULL != out[i]); | ||
345 | } | ||
346 | } | ||
347 | |||
348 | |||
319 | /** | 349 | /** |
320 | * Clear memory that was used to store a private key. | 350 | * smc_sum calculates the sum of all input points. @$fout=sum_{i=1}^{len}in_i@$f |
321 | * | 351 | * |
322 | * @param skey location of the key | 352 | * @param[out] out Where to store the result |
353 | * @param[in] in Input points. | ||
354 | * @param[in] len The length of @a in. | ||
355 | */ | ||
356 | static void | ||
357 | smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len) | ||
358 | { | ||
359 | uint16_t i; | ||
360 | |||
361 | brandt_assert (NULL != out); | ||
362 | /**TODO: how to copy a point more efficiently? */ | ||
363 | gcry_mpi_ec_add (out, ec_zero, ec_zero, ec_ctx); | ||
364 | for (i = 0; i < len; i++) | ||
365 | gcry_mpi_ec_add (out, out, in[i], ec_ctx); | ||
366 | } | ||
367 | |||
368 | |||
369 | /** | ||
370 | * smc_compute_pkey calculates the shared public key | ||
371 | * | ||
372 | * @param[in,out] ad The struct AuctionData used | ||
323 | */ | 373 | */ |
324 | void | 374 | void |
325 | brandt_ec_key_clear (struct brandt_ec_skey *skey) | 375 | smc_compute_pkey (struct AuctionData *ad) |
326 | { | 376 | { |
327 | memset (skey, 0, sizeof (struct brandt_ec_skey)); | 377 | ad->Y = gcry_mpi_point_new (0); |
378 | smc_sum (ad->Y, ad->y, ad->n); | ||
379 | } | ||
380 | |||
381 | |||
382 | /** | ||
383 | * smc_zkp_dl | ||
384 | * | ||
385 | * @param v TODO | ||
386 | * @param g TODO | ||
387 | * @param x TODO | ||
388 | * @param a TODO | ||
389 | * @param c TODO | ||
390 | * @param r TODO | ||
391 | */ | ||
392 | void | ||
393 | smc_zkp_dl (const gcry_mpi_point_t v, | ||
394 | const gcry_mpi_point_t g, | ||
395 | const gcry_mpi_t x, | ||
396 | const gcry_mpi_point_t a, | ||
397 | gcry_mpi_t c, | ||
398 | gcry_mpi_t r) | ||
399 | { | ||
400 | gcry_mpi_t z = gcry_mpi_new (0); | ||
401 | |||
402 | ec_keypair_create_base (a, z, g); | ||
403 | |||
404 | /* compute challange c */ | ||
405 | /**TODO: generate c from HASH(g,v,a) and don't output it */ | ||
406 | ec_skey_create (c); | ||
407 | gcry_mpi_mod (c, c, ec_n); | ||
408 | |||
409 | gcry_mpi_mulm (r, c, x, ec_n); | ||
410 | gcry_mpi_addm (r, r, z, ec_n); | ||
411 | |||
412 | gcry_mpi_release (z); | ||
328 | } | 413 | } |
329 | 414 | ||
330 | 415 | ||
331 | /** | 416 | /** |
332 | * Generate a random value mod n. | 417 | * smc_zkp_dl_check |
333 | * | 418 | * |
334 | * @param edc ECC context | 419 | * @param v TODO |
335 | * @return random value mod n. | 420 | * @param g TODO |
421 | * @param a TODO | ||
422 | * @param c TODO | ||
423 | * @param r TODO | ||
424 | * @return 0 if the proof is correct, something else otherwise | ||
336 | */ | 425 | */ |
426 | int | ||
427 | smc_zkp_dl_check (const gcry_mpi_point_t v, | ||
428 | const gcry_mpi_point_t g, | ||
429 | const gcry_mpi_point_t a, | ||
430 | const gcry_mpi_t c, | ||
431 | const gcry_mpi_t r) | ||
432 | { | ||
433 | int ret; | ||
434 | gcry_mpi_point_t left = gcry_mpi_point_new (0); | ||
435 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | ||
436 | |||
437 | gcry_mpi_ec_mul (left, r, g, ec_ctx); | ||
438 | gcry_mpi_ec_mul (right, c, v, ec_ctx); | ||
439 | gcry_mpi_ec_add (right, a, right, ec_ctx); | ||
440 | |||
441 | ret = ec_point_cmp (left, right); | ||
442 | gcry_mpi_point_release (left); | ||
443 | gcry_mpi_point_release (right); | ||
444 | |||
445 | return ret; | ||
446 | } | ||
447 | |||
448 | |||
449 | void | ||
450 | smc_zkp_2dle (const gcry_mpi_point_t v, | ||
451 | const gcry_mpi_point_t w, | ||
452 | const gcry_mpi_point_t g1, | ||
453 | const gcry_mpi_point_t g2, | ||
454 | const gcry_mpi_t x, | ||
455 | gcry_mpi_point_t a, | ||
456 | gcry_mpi_point_t b, | ||
457 | gcry_mpi_t c, | ||
458 | gcry_mpi_t r) | ||
459 | { | ||
460 | gcry_mpi_t z = gcry_mpi_new (0); | ||
461 | |||
462 | ec_keypair_create_base (a, z, g1); | ||
463 | gcry_mpi_ec_mul (b, z, g2, ec_ctx); | ||
464 | |||
465 | /* compute challange c */ | ||
466 | /**TODO: generate c from HASH(g1,g2,v,w,a,b) and don't output it */ | ||
467 | ec_skey_create (c); | ||
468 | gcry_mpi_mod (c, c, ec_n); | ||
469 | |||
470 | gcry_mpi_mulm (r, c, x, ec_n); | ||
471 | gcry_mpi_addm (r, r, z, ec_n); | ||
472 | |||
473 | gcry_mpi_release (z); | ||
474 | } | ||
475 | |||
476 | |||
477 | int | ||
478 | smc_zkp_2dle_check (const gcry_mpi_point_t v, | ||
479 | const gcry_mpi_point_t w, | ||
480 | const gcry_mpi_point_t g1, | ||
481 | const gcry_mpi_point_t g2, | ||
482 | const gcry_mpi_point_t a, | ||
483 | const gcry_mpi_point_t b, | ||
484 | const gcry_mpi_t c, | ||
485 | const gcry_mpi_t r) | ||
486 | { | ||
487 | int ret; | ||
488 | gcry_mpi_point_t left = gcry_mpi_point_new (0); | ||
489 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | ||
490 | |||
491 | gcry_mpi_ec_mul (left, r, g1, ec_ctx); | ||
492 | gcry_mpi_ec_mul (right, c, v, ec_ctx); | ||
493 | gcry_mpi_ec_add (right, a, right, ec_ctx); | ||
494 | ret = ec_point_cmp (left, right); | ||
495 | |||
496 | gcry_mpi_ec_mul (left, r, g2, ec_ctx); | ||
497 | gcry_mpi_ec_mul (right, c, w, ec_ctx); | ||
498 | gcry_mpi_ec_add (right, b, right, ec_ctx); | ||
499 | ret |= ec_point_cmp (left, right); | ||
500 | |||
501 | gcry_mpi_point_release (left); | ||
502 | gcry_mpi_point_release (right); | ||
503 | |||
504 | return ret; | ||
505 | } | ||
506 | |||
507 | |||
508 | void | ||
509 | smc_zkp_0og (gcry_mpi_point_t alpha, | ||
510 | const gcry_mpi_point_t m, | ||
511 | const gcry_mpi_point_t y, | ||
512 | gcry_mpi_point_t beta, | ||
513 | gcry_mpi_point_t a1, | ||
514 | gcry_mpi_point_t a2, | ||
515 | gcry_mpi_point_t b1, | ||
516 | gcry_mpi_point_t b2, | ||
517 | gcry_mpi_t c, | ||
518 | gcry_mpi_t d1, | ||
519 | gcry_mpi_t d2, | ||
520 | gcry_mpi_t r1, | ||
521 | gcry_mpi_t r2) | ||
522 | { | ||
523 | gcry_mpi_t r = gcry_mpi_new (0); | ||
524 | gcry_mpi_t w = gcry_mpi_new (0); | ||
525 | int eq0 = !ec_point_cmp (m, ec_zero); | ||
526 | int eqg = !ec_point_cmp (m, ec_gen); | ||
527 | |||
528 | if (!(eq0 ^ eqg)) | ||
529 | eprintf ("zero knowledge proof: m is neither 0 nor g"); | ||
530 | |||
531 | /* beta = r*g */ | ||
532 | ec_keypair_create (beta, r); | ||
533 | gcry_mpi_mod (r, r, ec_n); | ||
534 | |||
535 | /* alpha = m + r*y */ | ||
536 | gcry_mpi_ec_mul (alpha, r, y, ec_ctx); | ||
537 | gcry_mpi_ec_add (alpha, m, alpha, ec_ctx); | ||
538 | |||
539 | if (eq0) | ||
540 | { /* m == 0 */ | ||
541 | ec_keypair_create_base (a1, d1, beta); | ||
542 | gcry_mpi_mod (d1, d1, ec_n); | ||
543 | ec_keypair_create_base (b1, r1, y); | ||
544 | gcry_mpi_mod (r1, r1, ec_n); | ||
545 | |||
546 | /* a1 = r1*g + d1*beta */ | ||
547 | gcry_mpi_ec_mul (a2, r1, ec_gen, ec_ctx); | ||
548 | gcry_mpi_ec_add (a1, a2, a1, ec_ctx); | ||
549 | |||
550 | /* b1 = r1*y + d1*(alpha-g) */ | ||
551 | gcry_mpi_ec_sub (b2, alpha, ec_gen, ec_ctx); | ||
552 | gcry_mpi_ec_mul (a2, d1, b2, ec_ctx); | ||
553 | gcry_mpi_ec_add (b1, b1, a2, ec_ctx); | ||
554 | |||
555 | /* a2 = w * g */ | ||
556 | ec_keypair_create_base (a2, w, ec_gen); | ||
557 | gcry_mpi_mod (w, w, ec_n); | ||
558 | |||
559 | /* b2 = w * y */ | ||
560 | gcry_mpi_ec_mul (b2, w, y, ec_ctx); | ||
561 | |||
562 | /* compute challange c */ | ||
563 | /**TODO: generate c from HASH(alpha,beta,a1,b1,a2,b2) and don't output it */ | ||
564 | ec_skey_create (c); | ||
565 | gcry_mpi_mod (c, c, ec_n); | ||
566 | |||
567 | /* d2 = c - d1 */ | ||
568 | gcry_mpi_subm (d2, c, d1, ec_n); | ||
569 | |||
570 | /* r2 = w - r*d2 */ | ||
571 | gcry_mpi_mulm (r2, r, d2, ec_n); | ||
572 | gcry_mpi_subm (r2, w, r2, ec_n); | ||
573 | } | ||
574 | else | ||
575 | { /* m == g */ | ||
576 | ec_keypair_create_base (a2, d2, beta); | ||
577 | gcry_mpi_mod (d2, d2, ec_n); | ||
578 | ec_keypair_create_base (b2, r2, y); | ||
579 | gcry_mpi_mod (r2, r2, ec_n); | ||
580 | |||
581 | /* a2 = r2*g + d2*beta */ | ||
582 | gcry_mpi_ec_mul (a1, r2, ec_gen, ec_ctx); | ||
583 | gcry_mpi_ec_add (a2, a1, a2, ec_ctx); | ||
584 | |||
585 | /* b2 = r2*y + d2*(alpha-0) */ | ||
586 | /* useless subtraction to have same amount of operations as in m == 0 */ | ||
587 | gcry_mpi_ec_sub (b1, alpha, ec_zero, ec_ctx); | ||
588 | gcry_mpi_ec_mul (a1, d2, b1, ec_ctx); | ||
589 | gcry_mpi_ec_add (b2, b2, a1, ec_ctx); | ||
590 | |||
591 | /* a1 = w * g */ | ||
592 | ec_keypair_create_base (a1, w, ec_gen); | ||
593 | gcry_mpi_mod (w, w, ec_n); | ||
594 | |||
595 | /* b1 = w * y */ | ||
596 | gcry_mpi_ec_mul (b1, w, y, ec_ctx); | ||
597 | |||
598 | /* compute challange c */ | ||
599 | /**TODO: generate c from HASH(alpha,beta,a1,b1,a2,b2) and don't output it */ | ||
600 | ec_skey_create (c); | ||
601 | gcry_mpi_mod (c, c, ec_n); | ||
602 | |||
603 | /* d1 = c - d2 */ | ||
604 | gcry_mpi_subm (d1, c, d2, ec_n); | ||
605 | |||
606 | /* r1 = w - r*d1 */ | ||
607 | gcry_mpi_mulm (r1, r, d1, ec_n); | ||
608 | gcry_mpi_subm (r1, w, r1, ec_n); | ||
609 | } | ||
610 | |||
611 | gcry_mpi_release (r); | ||
612 | gcry_mpi_release (w); | ||
613 | } | ||
614 | |||
615 | |||
616 | int | ||
617 | smc_zkp_0og_check (const gcry_mpi_point_t alpha, | ||
618 | const gcry_mpi_point_t y, | ||
619 | const gcry_mpi_point_t beta, | ||
620 | const gcry_mpi_point_t a1, | ||
621 | const gcry_mpi_point_t a2, | ||
622 | const gcry_mpi_point_t b1, | ||
623 | const gcry_mpi_point_t b2, | ||
624 | const gcry_mpi_t c, | ||
625 | const gcry_mpi_t d1, | ||
626 | const gcry_mpi_t d2, | ||
627 | const gcry_mpi_t r1, | ||
628 | const gcry_mpi_t r2) | ||
629 | { | ||
630 | int ret; | ||
631 | gcry_mpi_t sum = gcry_mpi_new (0); | ||
632 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | ||
633 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | ||
634 | |||
635 | /* c == d1 + d2 */ | ||
636 | gcry_mpi_addm (sum, d1, d2, ec_n); | ||
637 | ret = gcry_mpi_cmp (c, sum); | ||
638 | |||
639 | /* a1 == r1*g + d1*beta */ | ||
640 | gcry_mpi_ec_mul (tmp, r1, ec_gen, ec_ctx); | ||
641 | gcry_mpi_ec_mul (right, d1, beta, ec_ctx); | ||
642 | gcry_mpi_ec_add (right, tmp, right, ec_ctx); | ||
643 | ret |= ec_point_cmp (a1, right) << 1; | ||
644 | |||
645 | /* b1 == r1*y + d1*(alpha-g) */ | ||
646 | gcry_mpi_ec_sub (right, alpha, ec_gen, ec_ctx); | ||
647 | gcry_mpi_ec_mul (tmp, d1, right, ec_ctx); | ||
648 | gcry_mpi_ec_mul (right, r1, y, ec_ctx); | ||
649 | gcry_mpi_ec_add (right, right, tmp, ec_ctx); | ||
650 | ret |= ec_point_cmp (b1, right) << 2; | ||
651 | |||
652 | /* a2 == r2*g + d2*beta */ | ||
653 | gcry_mpi_ec_mul (tmp, d2, beta, ec_ctx); | ||
654 | gcry_mpi_ec_mul (right, r2, ec_gen, ec_ctx); | ||
655 | gcry_mpi_ec_add (right, right, tmp, ec_ctx); | ||
656 | ret |= ec_point_cmp (a2, right) << 3; | ||
657 | |||
658 | /* b2 == r2*y + d2*alpha */ | ||
659 | gcry_mpi_ec_mul (tmp, d2, alpha, ec_ctx); | ||
660 | gcry_mpi_ec_mul (right, r2, y, ec_ctx); | ||
661 | gcry_mpi_ec_add (right, right, tmp, ec_ctx); | ||
662 | ret |= ec_point_cmp (b2, right) << 4; | ||
663 | |||
664 | gcry_mpi_release (sum); | ||
665 | gcry_mpi_point_release (right); | ||
666 | gcry_mpi_point_release (tmp); | ||
667 | |||
668 | if (ret) | ||
669 | weprintf ("ret: 0x%x", ret); | ||
670 | return ret; | ||
671 | } | ||
672 | |||
673 | |||
674 | /* --- unused stuff, might become useful later --- */ | ||
675 | |||
676 | ///** | ||
677 | // * Clear memory that was used to store a private key. | ||
678 | // * | ||
679 | // * @param skey the key | ||
680 | // */ | ||
681 | //void | ||
682 | //brandt_ec_key_clear (gcry_mpi_t skey) | ||
683 | //{ | ||
684 | // gcry_mpi_randomize (skey, 256, GCRY_WEAK_RANDOM); | ||
685 | // gcry_mpi_release (skey); | ||
686 | //} | ||
687 | |||
688 | |||
689 | //gcry_mpi_point_t | ||
690 | //deserialize_point(const struct brandt_point* data, const int len) | ||
691 | //{ | ||
692 | // gcry_sexp_t s; | ||
693 | // gcry_ctx_t ctx; | ||
694 | // gcry_mpi_point_t ret; | ||
695 | // gcry_error_t rc; | ||
696 | // | ||
697 | // rc = gcry_sexp_build(&s, NULL, "(public-key(ecc(curve " CURVE ")(q %b)))", | ||
698 | // len, data); | ||
699 | // brandt_assert_gpgerr(rc); | ||
700 | // | ||
701 | // rc = gcry_mpi_ec_new(&ctx, s, NULL); | ||
702 | // brandt_assert_gpgerr(rc); | ||
703 | // gcry_sexp_release(s); | ||
704 | // | ||
705 | // ret = gcry_mpi_ec_get_point("q", ctx, 0); | ||
706 | // brandt_assert(ret); | ||
707 | // gcry_ctx_release(ctx); | ||
708 | // return ret; | ||
709 | //} | ||
710 | |||
711 | |||
712 | ///** | ||
713 | // * Generate a random value mod n. | ||
714 | // * | ||
715 | // * @param edc ECC context | ||
716 | // * @return random value mod n. | ||
717 | // */ | ||
337 | //gcry_mpi_t | 718 | //gcry_mpi_t |
338 | //GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc) | 719 | //GNUNET_CRYPTO_ecc_random_mod_n (struct GNUNET_CRYPTO_EccDlogContext *edc) |
339 | //{ | 720 | //{ |
@@ -52,12 +52,76 @@ void brandt_mpi_scan_unsigned (gcry_mpi_t *result, | |||
52 | 52 | ||
53 | /* --- EC --- */ | 53 | /* --- EC --- */ |
54 | 54 | ||
55 | void brandt_ec_skey_create (gcry_mpi_t skey); | 55 | struct ec_point { |
56 | void brandt_ec_pkey_compute (gcry_mpi_point_t *pkey, const gcry_mpi_t skey); | 56 | unsigned char data[256 / 8]; |
57 | void brandt_ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey); | 57 | }; |
58 | void brandt_ec_keypair_create_base (gcry_mpi_point_t pkey, | 58 | |
59 | gcry_mpi_t skey, | 59 | int ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b); |
60 | const gcry_mpi_point_t base); | 60 | void ec_skey_create (gcry_mpi_t skey); |
61 | int brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b); | 61 | void ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey); |
62 | void ec_keypair_create_base (gcry_mpi_point_t pkey, | ||
63 | gcry_mpi_t skey, | ||
64 | const gcry_mpi_point_t base); | ||
65 | |||
66 | |||
67 | |||
68 | |||
69 | /* --- Zero knowledge proofs --- */ | ||
70 | |||
71 | void smc_zkp_dl (const gcry_mpi_point_t v, | ||
72 | const gcry_mpi_point_t g, | ||
73 | const gcry_mpi_t x, | ||
74 | const gcry_mpi_point_t a, | ||
75 | gcry_mpi_t c, | ||
76 | gcry_mpi_t r); | ||
77 | int smc_zkp_dl_check (const gcry_mpi_point_t v, | ||
78 | const gcry_mpi_point_t g, | ||
79 | const gcry_mpi_point_t a, | ||
80 | const gcry_mpi_t c, | ||
81 | const gcry_mpi_t r); | ||
82 | |||
83 | void smc_zkp_2dle (const gcry_mpi_point_t v, | ||
84 | const gcry_mpi_point_t w, | ||
85 | const gcry_mpi_point_t g1, | ||
86 | const gcry_mpi_point_t g2, | ||
87 | const gcry_mpi_t x, | ||
88 | gcry_mpi_point_t a, | ||
89 | gcry_mpi_point_t b, | ||
90 | gcry_mpi_t c, | ||
91 | gcry_mpi_t r); | ||
92 | int smc_zkp_2dle_check (const gcry_mpi_point_t v, | ||
93 | const gcry_mpi_point_t w, | ||
94 | const gcry_mpi_point_t g1, | ||
95 | const gcry_mpi_point_t g2, | ||
96 | const gcry_mpi_point_t a, | ||
97 | const gcry_mpi_point_t b, | ||
98 | const gcry_mpi_t c, | ||
99 | const gcry_mpi_t r); | ||
100 | |||
101 | void smc_zkp_0og (gcry_mpi_point_t alpha, | ||
102 | const gcry_mpi_point_t m, | ||
103 | const gcry_mpi_point_t y, | ||
104 | gcry_mpi_point_t beta, | ||
105 | gcry_mpi_point_t a1, | ||
106 | gcry_mpi_point_t a2, | ||
107 | gcry_mpi_point_t b1, | ||
108 | gcry_mpi_point_t b2, | ||
109 | gcry_mpi_t c, | ||
110 | gcry_mpi_t d1, | ||
111 | gcry_mpi_t d2, | ||
112 | gcry_mpi_t r1, | ||
113 | gcry_mpi_t r2); | ||
114 | int smc_zkp_0og_check (const gcry_mpi_point_t alpha, | ||
115 | const gcry_mpi_point_t y, | ||
116 | const gcry_mpi_point_t beta, | ||
117 | const gcry_mpi_point_t a1, | ||
118 | const gcry_mpi_point_t a2, | ||
119 | const gcry_mpi_point_t b1, | ||
120 | const gcry_mpi_point_t b2, | ||
121 | const gcry_mpi_t c, | ||
122 | const gcry_mpi_t d1, | ||
123 | const gcry_mpi_t d2, | ||
124 | const gcry_mpi_t r1, | ||
125 | const gcry_mpi_t r2); | ||
62 | 126 | ||
63 | #endif /* ifndef _BRANDT_CRYPTO_H */ | 127 | #endif /* ifndef _BRANDT_CRYPTO_H */ |
@@ -1,403 +0,0 @@ | |||
1 | /* This file is part of libbrandt. | ||
2 | * Copyright (C) 2016 GNUnet e.V. | ||
3 | * | ||
4 | * libbrandt is free software: you can redistribute it and/or modify it under | ||
5 | * the terms of the GNU General Public License as published by the Free Software | ||
6 | * Foundation, either version 3 of the License, or (at your option) any later | ||
7 | * version. | ||
8 | * | ||
9 | * libbrandt is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along with | ||
14 | * libbrandt. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file smc.c | ||
19 | * @brief Implementation of the smc primitives. | ||
20 | */ | ||
21 | |||
22 | #include <gcrypt.h> | ||
23 | |||
24 | #include "crypto.h" | ||
25 | #include "internals.h" | ||
26 | #include "smc.h" | ||
27 | #include "util.h" | ||
28 | |||
29 | extern gcry_ctx_t ec_ctx; | ||
30 | extern gcry_mpi_point_t ec_gen; | ||
31 | extern gcry_mpi_point_t ec_zero; | ||
32 | extern gcry_mpi_t ec_n; | ||
33 | |||
34 | |||
35 | /** | ||
36 | * smc_sums_partial calculates sums up until the current index and stores them | ||
37 | * in @a out. @$f\forall i \leq len: out_i=sum_{h=1}^iin_h@$f | ||
38 | * | ||
39 | * @param[out] out Where to store the resulting sums. Points may be given | ||
40 | * uninitialized, but the appropriate amount of memory has to be allocated | ||
41 | * beforehand. | ||
42 | * @param[in] in Input points. | ||
43 | * @param[in] len The length of both @a out and @a in. | ||
44 | */ | ||
45 | static void | ||
46 | smc_sums_partial (gcry_mpi_point_t out[], gcry_mpi_point_t in[], uint16_t len) | ||
47 | { | ||
48 | uint16_t i; | ||
49 | |||
50 | for (i = 0; i < len; i++) | ||
51 | { | ||
52 | out[i] = gcry_mpi_point_new (0); | ||
53 | gcry_mpi_ec_add (out[i], in[i], (i ? out[i - 1] : ec_zero), ec_ctx); | ||
54 | brandt_assert (NULL != out[i]); | ||
55 | } | ||
56 | } | ||
57 | |||
58 | |||
59 | /** | ||
60 | * smc_sum calculates the sum of all input points. @$fout=sum_{i=1}^{len}in_i@$f | ||
61 | * | ||
62 | * @param[out] out Where to store the result | ||
63 | * @param[in] in Input points. | ||
64 | * @param[in] len The length of @a in. | ||
65 | */ | ||
66 | static void | ||
67 | smc_sum (gcry_mpi_point_t out, gcry_mpi_point_t in[], uint16_t len) | ||
68 | { | ||
69 | uint16_t i; | ||
70 | |||
71 | brandt_assert (NULL != out); | ||
72 | /**TODO: how to copy a point more efficiently? */ | ||
73 | gcry_mpi_ec_add (out, ec_zero, ec_zero, ec_ctx); | ||
74 | for (i = 0; i < len; i++) | ||
75 | gcry_mpi_ec_add (out, out, in[i], ec_ctx); | ||
76 | } | ||
77 | |||
78 | |||
79 | /** | ||
80 | * smc_compute_pkey calculates the shared public key | ||
81 | * | ||
82 | * @param[in,out] ad The struct AuctionData used | ||
83 | */ | ||
84 | void | ||
85 | smc_compute_pkey (struct AuctionData *ad) | ||
86 | { | ||
87 | ad->Y = gcry_mpi_point_new (0); | ||
88 | smc_sum (ad->Y, ad->y, ad->n); | ||
89 | } | ||
90 | |||
91 | |||
92 | /** | ||
93 | * smc_zkp_dl | ||
94 | * | ||
95 | * @param v TODO | ||
96 | * @param g TODO | ||
97 | * @param x TODO | ||
98 | * @param a TODO | ||
99 | * @param c TODO | ||
100 | * @param r TODO | ||
101 | */ | ||
102 | void | ||
103 | smc_zkp_dl (const gcry_mpi_point_t v, | ||
104 | const gcry_mpi_point_t g, | ||
105 | const gcry_mpi_t x, | ||
106 | const gcry_mpi_point_t a, | ||
107 | gcry_mpi_t c, | ||
108 | gcry_mpi_t r) | ||
109 | { | ||
110 | gcry_mpi_t z = gcry_mpi_new (0); | ||
111 | |||
112 | brandt_ec_keypair_create_base (a, z, g); | ||
113 | |||
114 | /* compute challange c */ | ||
115 | /**TODO: generate c from HASH(g,v,a) and don't output it */ | ||
116 | brandt_ec_skey_create (c); | ||
117 | gcry_mpi_mod (c, c, ec_n); | ||
118 | |||
119 | gcry_mpi_mulm (r, c, x, ec_n); | ||
120 | gcry_mpi_addm (r, r, z, ec_n); | ||
121 | |||
122 | gcry_mpi_release (z); | ||
123 | } | ||
124 | |||
125 | |||
126 | /** | ||
127 | * smc_zkp_dl_check | ||
128 | * | ||
129 | * @param v TODO | ||
130 | * @param g TODO | ||
131 | * @param a TODO | ||
132 | * @param c TODO | ||
133 | * @param r TODO | ||
134 | * @return 0 if the proof is correct, something else otherwise | ||
135 | */ | ||
136 | int | ||
137 | smc_zkp_dl_check (const gcry_mpi_point_t v, | ||
138 | const gcry_mpi_point_t g, | ||
139 | const gcry_mpi_point_t a, | ||
140 | const gcry_mpi_t c, | ||
141 | const gcry_mpi_t r) | ||
142 | { | ||
143 | int ret; | ||
144 | gcry_mpi_point_t left = gcry_mpi_point_new (0); | ||
145 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | ||
146 | |||
147 | gcry_mpi_ec_mul (left, r, g, ec_ctx); | ||
148 | gcry_mpi_ec_mul (right, c, v, ec_ctx); | ||
149 | gcry_mpi_ec_add (right, a, right, ec_ctx); | ||
150 | |||
151 | ret = brandt_ec_point_cmp (left, right); | ||
152 | gcry_mpi_point_release (left); | ||
153 | gcry_mpi_point_release (right); | ||
154 | |||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | |||
159 | void | ||
160 | smc_zkp_2dle (const gcry_mpi_point_t v, | ||
161 | const gcry_mpi_point_t w, | ||
162 | const gcry_mpi_point_t g1, | ||
163 | const gcry_mpi_point_t g2, | ||
164 | const gcry_mpi_t x, | ||
165 | gcry_mpi_point_t a, | ||
166 | gcry_mpi_point_t b, | ||
167 | gcry_mpi_t c, | ||
168 | gcry_mpi_t r) | ||
169 | { | ||
170 | gcry_mpi_t z = gcry_mpi_new (0); | ||
171 | |||
172 | brandt_ec_keypair_create_base (a, z, g1); | ||
173 | gcry_mpi_ec_mul (b, z, g2, ec_ctx); | ||
174 | |||
175 | /* compute challange c */ | ||
176 | /**TODO: generate c from HASH(g1,g2,v,w,a,b) and don't output it */ | ||
177 | brandt_ec_skey_create (c); | ||
178 | gcry_mpi_mod (c, c, ec_n); | ||
179 | |||
180 | gcry_mpi_mulm (r, c, x, ec_n); | ||
181 | gcry_mpi_addm (r, r, z, ec_n); | ||
182 | |||
183 | gcry_mpi_release (z); | ||
184 | } | ||
185 | |||
186 | |||
187 | int | ||
188 | smc_zkp_2dle_check (const gcry_mpi_point_t v, | ||
189 | const gcry_mpi_point_t w, | ||
190 | const gcry_mpi_point_t g1, | ||
191 | const gcry_mpi_point_t g2, | ||
192 | const gcry_mpi_point_t a, | ||
193 | const gcry_mpi_point_t b, | ||
194 | const gcry_mpi_t c, | ||
195 | const gcry_mpi_t r) | ||
196 | { | ||
197 | int ret; | ||
198 | gcry_mpi_point_t left = gcry_mpi_point_new (0); | ||
199 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | ||
200 | |||
201 | gcry_mpi_ec_mul (left, r, g1, ec_ctx); | ||
202 | gcry_mpi_ec_mul (right, c, v, ec_ctx); | ||
203 | gcry_mpi_ec_add (right, a, right, ec_ctx); | ||
204 | ret = brandt_ec_point_cmp (left, right); | ||
205 | |||
206 | gcry_mpi_ec_mul (left, r, g2, ec_ctx); | ||
207 | gcry_mpi_ec_mul (right, c, w, ec_ctx); | ||
208 | gcry_mpi_ec_add (right, b, right, ec_ctx); | ||
209 | ret |= brandt_ec_point_cmp (left, right); | ||
210 | |||
211 | gcry_mpi_point_release (left); | ||
212 | gcry_mpi_point_release (right); | ||
213 | |||
214 | return ret; | ||
215 | } | ||
216 | |||
217 | |||
218 | void | ||
219 | smc_zkp_0og (gcry_mpi_point_t alpha, | ||
220 | const gcry_mpi_point_t m, | ||
221 | const gcry_mpi_point_t y, | ||
222 | gcry_mpi_point_t beta, | ||
223 | gcry_mpi_point_t a1, | ||
224 | gcry_mpi_point_t a2, | ||
225 | gcry_mpi_point_t b1, | ||
226 | gcry_mpi_point_t b2, | ||
227 | gcry_mpi_t c, | ||
228 | gcry_mpi_t d1, | ||
229 | gcry_mpi_t d2, | ||
230 | gcry_mpi_t r1, | ||
231 | gcry_mpi_t r2) | ||
232 | { | ||
233 | gcry_mpi_t r = gcry_mpi_new (0); | ||
234 | gcry_mpi_t w = gcry_mpi_new (0); | ||
235 | int eq0 = !brandt_ec_point_cmp (m, ec_zero); | ||
236 | int eqg = !brandt_ec_point_cmp (m, ec_gen); | ||
237 | |||
238 | if (!(eq0 ^ eqg)) | ||
239 | eprintf ("zero knowledge proof: m is neither 0 nor g"); | ||
240 | |||
241 | /* beta = r*g */ | ||
242 | brandt_ec_keypair_create (beta, r); | ||
243 | gcry_mpi_mod (r, r, ec_n); | ||
244 | |||
245 | /* alpha = m + r*y */ | ||
246 | gcry_mpi_ec_mul (alpha, r, y, ec_ctx); | ||
247 | gcry_mpi_ec_add (alpha, m, alpha, ec_ctx); | ||
248 | |||
249 | if (eq0) | ||
250 | { /* m == 0 */ | ||
251 | brandt_ec_keypair_create_base (a1, d1, beta); | ||
252 | gcry_mpi_mod (d1, d1, ec_n); | ||
253 | brandt_ec_keypair_create_base (b1, r1, y); | ||
254 | gcry_mpi_mod (r1, r1, ec_n); | ||
255 | |||
256 | /* a1 = r1*g + d1*beta */ | ||
257 | gcry_mpi_ec_mul (a2, r1, ec_gen, ec_ctx); | ||
258 | gcry_mpi_ec_add (a1, a2, a1, ec_ctx); | ||
259 | |||
260 | /* b1 = r1*y + d1*(alpha-g) */ | ||
261 | gcry_mpi_ec_sub (b2, alpha, ec_gen, ec_ctx); | ||
262 | gcry_mpi_ec_mul (a2, d1, b2, ec_ctx); | ||
263 | gcry_mpi_ec_add (b1, b1, a2, ec_ctx); | ||
264 | |||
265 | /* a2 = w * g */ | ||
266 | brandt_ec_keypair_create_base (a2, w, ec_gen); | ||
267 | gcry_mpi_mod (w, w, ec_n); | ||
268 | |||
269 | /* b2 = w * y */ | ||
270 | gcry_mpi_ec_mul (b2, w, y, ec_ctx); | ||
271 | |||
272 | /* compute challange c */ | ||
273 | /**TODO: generate c from HASH(alpha,beta,a1,b1,a2,b2) and don't output it */ | ||
274 | brandt_ec_skey_create (c); | ||
275 | gcry_mpi_mod (c, c, ec_n); | ||
276 | |||
277 | /* d2 = c - d1 */ | ||
278 | gcry_mpi_subm (d2, c, d1, ec_n); | ||
279 | |||
280 | /* r2 = w - r*d2 */ | ||
281 | gcry_mpi_mulm (r2, r, d2, ec_n); | ||
282 | gcry_mpi_subm (r2, w, r2, ec_n); | ||
283 | } | ||
284 | else | ||
285 | { /* m == g */ | ||
286 | brandt_ec_keypair_create_base (a2, d2, beta); | ||
287 | gcry_mpi_mod (d2, d2, ec_n); | ||
288 | brandt_ec_keypair_create_base (b2, r2, y); | ||
289 | gcry_mpi_mod (r2, r2, ec_n); | ||
290 | |||
291 | /* a2 = r2*g + d2*beta */ | ||
292 | gcry_mpi_ec_mul (a1, r2, ec_gen, ec_ctx); | ||
293 | gcry_mpi_ec_add (a2, a1, a2, ec_ctx); | ||
294 | |||
295 | /* b2 = r2*y + d2*(alpha-0) */ | ||
296 | /* useless subtraction to have same amount of operations as in m == 0 */ | ||
297 | gcry_mpi_ec_sub (b1, alpha, ec_zero, ec_ctx); | ||
298 | gcry_mpi_ec_mul (a1, d2, b1, ec_ctx); | ||
299 | gcry_mpi_ec_add (b2, b2, a1, ec_ctx); | ||
300 | |||
301 | /* a1 = w * g */ | ||
302 | brandt_ec_keypair_create_base (a1, w, ec_gen); | ||
303 | gcry_mpi_mod (w, w, ec_n); | ||
304 | |||
305 | /* b1 = w * y */ | ||
306 | gcry_mpi_ec_mul (b1, w, y, ec_ctx); | ||
307 | |||
308 | /* compute challange c */ | ||
309 | /**TODO: generate c from HASH(alpha,beta,a1,b1,a2,b2) and don't output it */ | ||
310 | brandt_ec_skey_create (c); | ||
311 | gcry_mpi_mod (c, c, ec_n); | ||
312 | |||
313 | /* d1 = c - d2 */ | ||
314 | gcry_mpi_subm (d1, c, d2, ec_n); | ||
315 | |||
316 | /* r1 = w - r*d1 */ | ||
317 | gcry_mpi_mulm (r1, r, d1, ec_n); | ||
318 | gcry_mpi_subm (r1, w, r1, ec_n); | ||
319 | } | ||
320 | |||
321 | gcry_mpi_release (r); | ||
322 | gcry_mpi_release (w); | ||
323 | } | ||
324 | |||
325 | |||
326 | int | ||
327 | smc_zkp_0og_check (const gcry_mpi_point_t alpha, | ||
328 | const gcry_mpi_point_t y, | ||
329 | const gcry_mpi_point_t beta, | ||
330 | const gcry_mpi_point_t a1, | ||
331 | const gcry_mpi_point_t a2, | ||
332 | const gcry_mpi_point_t b1, | ||
333 | const gcry_mpi_point_t b2, | ||
334 | const gcry_mpi_t c, | ||
335 | const gcry_mpi_t d1, | ||
336 | const gcry_mpi_t d2, | ||
337 | const gcry_mpi_t r1, | ||
338 | const gcry_mpi_t r2) | ||
339 | { | ||
340 | int ret; | ||
341 | gcry_mpi_t sum = gcry_mpi_new (0); | ||
342 | gcry_mpi_point_t right = gcry_mpi_point_new (0); | ||
343 | gcry_mpi_point_t tmp = gcry_mpi_point_new (0); | ||
344 | |||
345 | /* c == d1 + d2 */ | ||
346 | gcry_mpi_addm (sum, d1, d2, ec_n); | ||
347 | ret = gcry_mpi_cmp (c, sum); | ||
348 | |||
349 | /* a1 == r1*g + d1*beta */ | ||
350 | gcry_mpi_ec_mul (tmp, r1, ec_gen, ec_ctx); | ||
351 | gcry_mpi_ec_mul (right, d1, beta, ec_ctx); | ||
352 | gcry_mpi_ec_add (right, tmp, right, ec_ctx); | ||
353 | ret |= brandt_ec_point_cmp (a1, right) << 1; | ||
354 | |||
355 | /* b1 == r1*y + d1*(alpha-g) */ | ||
356 | gcry_mpi_ec_sub (right, alpha, ec_gen, ec_ctx); | ||
357 | gcry_mpi_ec_mul (tmp, d1, right, ec_ctx); | ||
358 | gcry_mpi_ec_mul (right, r1, y, ec_ctx); | ||
359 | gcry_mpi_ec_add (right, right, tmp, ec_ctx); | ||
360 | ret |= brandt_ec_point_cmp (b1, right) << 2; | ||
361 | |||
362 | /* a2 == r2*g + d2*beta */ | ||
363 | gcry_mpi_ec_mul (tmp, d2, beta, ec_ctx); | ||
364 | gcry_mpi_ec_mul (right, r2, ec_gen, ec_ctx); | ||
365 | gcry_mpi_ec_add (right, right, tmp, ec_ctx); | ||
366 | ret |= brandt_ec_point_cmp (a2, right) << 3; | ||
367 | |||
368 | /* b2 == r2*y + d2*alpha */ | ||
369 | gcry_mpi_ec_mul (tmp, d2, alpha, ec_ctx); | ||
370 | gcry_mpi_ec_mul (right, r2, y, ec_ctx); | ||
371 | gcry_mpi_ec_add (right, right, tmp, ec_ctx); | ||
372 | ret |= brandt_ec_point_cmp (b2, right) << 4; | ||
373 | |||
374 | gcry_mpi_release (sum); | ||
375 | gcry_mpi_point_release (right); | ||
376 | gcry_mpi_point_release (tmp); | ||
377 | |||
378 | if (ret) | ||
379 | weprintf ("ret: 0x%x", ret); | ||
380 | return ret; | ||
381 | } | ||
382 | |||
383 | |||
384 | //GEN | ||
385 | //smc_hextodec (const char *s) | ||
386 | //{ | ||
387 | // size_t i; | ||
388 | // char c; | ||
389 | // pari_sp ltop = avma; | ||
390 | // GEN ret = gen_0; | ||
391 | // | ||
392 | // for (i = 0; i < strlen (s); i++) | ||
393 | // { | ||
394 | // errno = 0; | ||
395 | // if (1 != sscanf (&s[i], "%1hhx", &c)) | ||
396 | // { | ||
397 | // brandt_eprintf ("failed to parse hex (\"%s\") to decimal:", s); | ||
398 | // return NULL; | ||
399 | // } | ||
400 | // ret = addis (shifti (ret, 4), c); | ||
401 | // } | ||
402 | // return gerepilecopy (ltop, ret); | ||
403 | //} | ||
@@ -1,83 +0,0 @@ | |||
1 | /* This file is part of libbrandt. | ||
2 | * Copyright (C) 2016 GNUnet e.V. | ||
3 | * | ||
4 | * libbrandt is free software: you can redistribute it and/or modify it under | ||
5 | * the terms of the GNU General Public License as published by the Free Software | ||
6 | * Foundation, either version 3 of the License, or (at your option) any later | ||
7 | * version. | ||
8 | * | ||
9 | * libbrandt is distributed in the hope that it will be useful, but WITHOUT ANY | ||
10 | * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR | ||
11 | * A PARTICULAR PURPOSE. See the GNU General Public License for more details. | ||
12 | * | ||
13 | * You should have received a copy of the GNU General Public License along with | ||
14 | * libbrandt. If not, see <http://www.gnu.org/licenses/>. | ||
15 | */ | ||
16 | |||
17 | /** | ||
18 | * @file smc.h | ||
19 | * @brief describes the secure multiparty computation interface. | ||
20 | */ | ||
21 | |||
22 | #ifndef _BRANDT_SMC_H | ||
23 | #define _BRANDT_SMC_H | ||
24 | |||
25 | #include <gcrypt.h> | ||
26 | |||
27 | void smc_zkp_dl (const gcry_mpi_point_t v, | ||
28 | const gcry_mpi_point_t g, | ||
29 | const gcry_mpi_t x, | ||
30 | const gcry_mpi_point_t a, | ||
31 | gcry_mpi_t c, | ||
32 | gcry_mpi_t r); | ||
33 | int smc_zkp_dl_check (const gcry_mpi_point_t v, | ||
34 | const gcry_mpi_point_t g, | ||
35 | const gcry_mpi_point_t a, | ||
36 | const gcry_mpi_t c, | ||
37 | const gcry_mpi_t r); | ||
38 | |||
39 | void smc_zkp_2dle (const gcry_mpi_point_t v, | ||
40 | const gcry_mpi_point_t w, | ||
41 | const gcry_mpi_point_t g1, | ||
42 | const gcry_mpi_point_t g2, | ||
43 | const gcry_mpi_t x, | ||
44 | gcry_mpi_point_t a, | ||
45 | gcry_mpi_point_t b, | ||
46 | gcry_mpi_t c, | ||
47 | gcry_mpi_t r); | ||
48 | int smc_zkp_2dle_check (const gcry_mpi_point_t v, | ||
49 | const gcry_mpi_point_t w, | ||
50 | const gcry_mpi_point_t g1, | ||
51 | const gcry_mpi_point_t g2, | ||
52 | const gcry_mpi_point_t a, | ||
53 | const gcry_mpi_point_t b, | ||
54 | const gcry_mpi_t c, | ||
55 | const gcry_mpi_t r); | ||
56 | |||
57 | void smc_zkp_0og (gcry_mpi_point_t alpha, | ||
58 | const gcry_mpi_point_t m, | ||
59 | const gcry_mpi_point_t y, | ||
60 | gcry_mpi_point_t beta, | ||
61 | gcry_mpi_point_t a1, | ||
62 | gcry_mpi_point_t a2, | ||
63 | gcry_mpi_point_t b1, | ||
64 | gcry_mpi_point_t b2, | ||
65 | gcry_mpi_t c, | ||
66 | gcry_mpi_t d1, | ||
67 | gcry_mpi_t d2, | ||
68 | gcry_mpi_t r1, | ||
69 | gcry_mpi_t r2); | ||
70 | int smc_zkp_0og_check (const gcry_mpi_point_t alpha, | ||
71 | const gcry_mpi_point_t y, | ||
72 | const gcry_mpi_point_t beta, | ||
73 | const gcry_mpi_point_t a1, | ||
74 | const gcry_mpi_point_t a2, | ||
75 | const gcry_mpi_point_t b1, | ||
76 | const gcry_mpi_point_t b2, | ||
77 | const gcry_mpi_t c, | ||
78 | const gcry_mpi_t d1, | ||
79 | const gcry_mpi_t d2, | ||
80 | const gcry_mpi_t r1, | ||
81 | const gcry_mpi_t r2); | ||
82 | |||
83 | #endif // ifndef _BRANDT_SMC_H | ||
diff --git a/test_crypto.c b/test_crypto.c index 5cc2ed1..a42a643 100644 --- a/test_crypto.c +++ b/test_crypto.c | |||
@@ -18,15 +18,33 @@ | |||
18 | * @file test_crypto.c | 18 | * @file test_crypto.c |
19 | * @brief testing crypto and smc functions. | 19 | * @brief testing crypto and smc functions. |
20 | */ | 20 | */ |
21 | |||
22 | /* For testing static functions and variables we include the whole source */ | ||
23 | #include "crypto.c" | ||
24 | |||
21 | #include "brandt.h" | 25 | #include "brandt.h" |
22 | #include "crypto.h" | 26 | #include "crypto.h" |
23 | #include "smc.h" | ||
24 | #include "test.h" | 27 | #include "test.h" |
25 | 28 | ||
26 | extern gcry_ctx_t ec_ctx; | 29 | |
27 | extern gcry_mpi_point_t ec_gen; | 30 | int |
28 | extern gcry_mpi_point_t ec_zero; | 31 | test_smc_2d_array () |
29 | extern gcry_mpi_t ec_n; | 32 | { |
33 | gcry_mpi_point_t **array; | ||
34 | uint16_t size1 = 3; | ||
35 | uint16_t size2 = 7; | ||
36 | uint16_t i, j; | ||
37 | |||
38 | array = smc_init2 (size1, size2); | ||
39 | check (array, "memory allocation failed"); | ||
40 | |||
41 | for (i = 0; i < size1; i++) | ||
42 | for (j = 0; j < size2; j++) | ||
43 | check (array[i][j], "point has not been initialized"); | ||
44 | |||
45 | smc_free2 (array, size1, size2); | ||
46 | } | ||
47 | |||
30 | 48 | ||
31 | int | 49 | int |
32 | test_smc_zkp_dl () | 50 | test_smc_zkp_dl () |
@@ -38,7 +56,7 @@ test_smc_zkp_dl () | |||
38 | gcry_mpi_point_t g = gcry_mpi_point_new (0); | 56 | gcry_mpi_point_t g = gcry_mpi_point_new (0); |
39 | gcry_mpi_point_t v = gcry_mpi_point_new (0); | 57 | gcry_mpi_point_t v = gcry_mpi_point_new (0); |
40 | 58 | ||
41 | brandt_ec_keypair_create (g, c); | 59 | ec_keypair_create (g, c); |
42 | 60 | ||
43 | if (0 == tests_run) | 61 | if (0 == tests_run) |
44 | { | 62 | { |
@@ -46,7 +64,7 @@ test_smc_zkp_dl () | |||
46 | gcry_mpi_ec_mul (g, GCRYMPI_CONST_ONE, ec_gen, ec_ctx); | 64 | gcry_mpi_ec_mul (g, GCRYMPI_CONST_ONE, ec_gen, ec_ctx); |
47 | } | 65 | } |
48 | 66 | ||
49 | brandt_ec_keypair_create_base (v, x, g); | 67 | ec_keypair_create_base (v, x, g); |
50 | 68 | ||
51 | smc_zkp_dl (v, g, x, a, c, r); | 69 | smc_zkp_dl (v, g, x, a, c, r); |
52 | check (!smc_zkp_dl_check (v, g, a, c, r), "zkp dl wrong"); | 70 | check (!smc_zkp_dl_check (v, g, a, c, r), "zkp dl wrong"); |
@@ -77,8 +95,8 @@ test_smc_zkp_2dle () | |||
77 | gcry_mpi_point_t v = gcry_mpi_point_new (0); | 95 | gcry_mpi_point_t v = gcry_mpi_point_new (0); |
78 | gcry_mpi_point_t w = gcry_mpi_point_new (0); | 96 | gcry_mpi_point_t w = gcry_mpi_point_new (0); |
79 | 97 | ||
80 | brandt_ec_keypair_create (g1, c); | 98 | ec_keypair_create (g1, c); |
81 | brandt_ec_keypair_create (g2, c); | 99 | ec_keypair_create (g2, c); |
82 | 100 | ||
83 | if (0 == tests_run) | 101 | if (0 == tests_run) |
84 | { | 102 | { |
@@ -87,7 +105,7 @@ test_smc_zkp_2dle () | |||
87 | gcry_mpi_ec_mul (g2, GCRYMPI_CONST_ONE, ec_gen, ec_ctx); | 105 | gcry_mpi_ec_mul (g2, GCRYMPI_CONST_ONE, ec_gen, ec_ctx); |
88 | } | 106 | } |
89 | 107 | ||
90 | brandt_ec_keypair_create_base (v, x, g1); | 108 | ec_keypair_create_base (v, x, g1); |
91 | gcry_mpi_ec_mul (w, x, g2, ec_ctx); | 109 | gcry_mpi_ec_mul (w, x, g2, ec_ctx); |
92 | 110 | ||
93 | smc_zkp_2dle (v, w, g1, g2, x, a, b, c, r); | 111 | smc_zkp_2dle (v, w, g1, g2, x, a, b, c, r); |
@@ -128,7 +146,7 @@ test_smc_zkp_0og () | |||
128 | gcry_mpi_point_t b1 = gcry_mpi_point_new (0); | 146 | gcry_mpi_point_t b1 = gcry_mpi_point_new (0); |
129 | gcry_mpi_point_t b2 = gcry_mpi_point_new (0); | 147 | gcry_mpi_point_t b2 = gcry_mpi_point_new (0); |
130 | 148 | ||
131 | brandt_ec_keypair_create (y, c); | 149 | ec_keypair_create (y, c); |
132 | 150 | ||
133 | smc_zkp_0og (alpha, (tests_run % 2 ? ec_zero : ec_gen), y, beta, a1, a2, b1, | 151 | smc_zkp_0og (alpha, (tests_run % 2 ? ec_zero : ec_gen), y, beta, a1, a2, b1, |
134 | b2, c, d1, d2, r1, r2); | 152 | b2, c, d1, d2, r1, r2); |
@@ -161,10 +179,13 @@ test_smc_zkp_0og () | |||
161 | int | 179 | int |
162 | main (int argc, char *argv[]) | 180 | main (int argc, char *argv[]) |
163 | { | 181 | { |
164 | int repeat = 32; | 182 | int repeat = 8; |
165 | 183 | ||
166 | BRANDT_init (); | 184 | BRANDT_init (); |
167 | 185 | ||
186 | /* tests that need to run only once */ | ||
187 | run (test_smc_2d_array); | ||
188 | |||
168 | for (tests_run = 0; tests_run < repeat; tests_run++) | 189 | for (tests_run = 0; tests_run < repeat; tests_run++) |
169 | { | 190 | { |
170 | run (test_smc_zkp_dl); | 191 | run (test_smc_zkp_dl); |