aboutsummaryrefslogtreecommitdiff
path: root/crypto.c
diff options
context:
space:
mode:
authorMarkus Teich <markus.teich@stusta.mhn.de>2016-06-19 22:37:31 +0200
committerMarkus Teich <markus.teich@stusta.mhn.de>2016-06-19 22:41:03 +0200
commit0d2f95ffba76a338b5820f862d826a7ac1812ec3 (patch)
tree8eaf9b97f41999920043d46911270295f053aec0 /crypto.c
parent3f81885ee3e44486505935760da7c812efc4c76f (diff)
downloadlibbrandt-0d2f95ffba76a338b5820f862d826a7ac1812ec3.tar.gz
libbrandt-0d2f95ffba76a338b5820f862d826a7ac1812ec3.zip
merge smc into crypto module. add 2dim array helpers
Diffstat (limited to 'crypto.c')
-rw-r--r--crypto.c485
1 files changed, 433 insertions, 52 deletions
diff --git a/crypto.c b/crypto.c
index 31ba396..0c2597d 100644
--- a/crypto.c
+++ b/crypto.c
@@ -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
29struct brandt_ec_skey {
30 unsigned char d[256 / 8];
31};
32 32
33struct brandt_ec_pkey { 33static gcry_ctx_t ec_ctx;
34 unsigned char q_y[256 / 8]; 34static gcry_mpi_point_t ec_gen;
35}; 35static gcry_mpi_point_t ec_zero;
36static gcry_mpi_t ec_n;
36 37
37gcry_ctx_t ec_ctx;
38gcry_mpi_point_t ec_gen;
39gcry_mpi_point_t ec_zero;
40gcry_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 */
209void 183void
210brandt_ec_skey_create (gcry_mpi_t skey) 184ec_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 */
249void 223void
250brandt_ec_keypair_create (gcry_mpi_point_t pkey, gcry_mpi_t skey) 224ec_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 */
267void 241void
268brandt_ec_keypair_create_base (gcry_mpi_point_t pkey, 242ec_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 */
289int 263int
290brandt_ec_point_cmp (const gcry_mpi_point_t a, const gcry_mpi_point_t b) 264ec_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
293static gcry_mpi_point_t **
294smc_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
313static void
314smc_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 */
335static void
336smc_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 */
356static void
357smc_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 */
324void 374void
325brandt_ec_key_clear (struct brandt_ec_skey *skey) 375smc_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 */
392void
393smc_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 */
426int
427smc_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
449void
450smc_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
477int
478smc_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
508void
509smc_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
616int
617smc_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//{