MPHELL  5.0.0
mphell_tuto_eddsa.c
Go to the documentation of this file.
1 /*
2  MPHELL-5.0
3  Author(s): The MPHELL team
4 
5  (C) Copyright 2015-2021 - Institut Fourier / Univ. Grenoble Alpes (France)
6 
7  This file is part of the MPHELL Library.
8  MPHELL is free software: you can redistribute it and/or modify
9  it under the terms of the GNU Lesser General Public License as published by
10  the Free Software Foundation, version 3 of the License.
11 
12  MPHELL is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  GNU Lesser General Public License for more details.
16 
17  You should have received a copy of the GNU Lesser General Public License
18  along with MPHELL. If not, see <http://www.gnu.org/licenses/>.
19 */
20 
44 #include <stdio.h>
45 #include <time.h>
46 #include "mphell/mphell.h"
47 #if MPHELL_USE_MULTITHREADING == 1
48 #include <omp.h>
49 #endif
50 
55 struct eddsa_sig
56 {
57  ec_point R;
58  number *s;
59 };
60 
65 typedef struct eddsa_sig eddsa_sig_t;
66 
71 typedef eddsa_sig_t eddsa_sig[1];
72 
73 
74 #define PRECOMP_WIN_SIZE 9
75 #define PRECOMP_SIZE 256
76 #define HASH_SIZE 64
77 
82 struct ecdsa_precomp
83 {
84  ec_point prec_G[2*PRECOMP_SIZE];
85  ec_point prec_K[2*PRECOMP_SIZE];
86 };
87 
92 typedef struct ecdsa_precomp ecdsa_precomp_t;
93 
99 
107 void
108 eddsa_sign_alloc(eddsa_sig *sig, ec_curve_srcptr E, uint8_t size)
109 {
110  (*sig)->s = (number*)malloc(sizeof(number));
111  number_init((*sig)->s, size);
112  number_set_ui(*((*sig)->s), (block)0);
113 
114  ec_point_alloc((*sig)->R, E->k);
115  ec_point_init((*sig)->R, E->k);
116  ec_point_set_neutral((*sig)->R, E, STACK_1);
117 }
118 
124 void
126 {
127  if ((*sig)->R)
128  {
129  ec_point_free((*sig)->R, E->k);
130  }
131  if ((*sig)->s)
132  {
133  number_free((*sig)->s);
134  free((*sig)->s);
135  }
136 }
137 
145 void
147 {
148  uint16_t i;
149  uint16_t pr = 2*PRECOMP_SIZE;
150 
151  /* Allocate */
152  for(i = 0; i < pr; i++)
153  {
154  ec_point_alloc(((*precomp)->prec_G)[i], E->k);
155  ec_point_alloc(((*precomp)->prec_K)[i], E->k);
156  ec_point_init(((*precomp)->prec_G)[i], E->k);
157  ec_point_init(((*precomp)->prec_K)[i], E->k);
158  }
159  ec_point_set_neutral(((*precomp)->prec_K)[0], E, STACK_1);
160  ec_point_set_neutral(((*precomp)->prec_G)[0], E, STACK_1);
161 
162  ec_point_copy(((*precomp)->prec_G)[1], E->G, E->k); /* G[0] = G */
163  ec_point_copy(((*precomp)->prec_K)[1], *key, E->k); /* K[0] = K */
164 
165  for(i = 2; i < pr; i++)
166  {
167  /* tab[i]=(i)* P1 */
168  ec_point_add(((*precomp)->prec_G)[i], E->G, ((*precomp)->prec_G)[i-1], E, STACK_1);
169  ec_point_add(((*precomp)->prec_K)[i], *key, ((*precomp)->prec_K)[i-1], E, STACK_1);
170  }
171 }
172 
178 void
180 {
181  uint16_t i;
182  uint16_t pr = 2*PRECOMP_SIZE;
183  for(i = 0; i < pr; i++)
184  {
185  ec_point_free(((*precomp)->prec_G)[i], E->k);
186  ec_point_free(((*precomp)->prec_K)[i], E->k);
187  }
188 }
189 
200 void
201 ec_point_mul_ecdsa(ec_point dst, number_srcptr u1, ec_point_srcptr G,
202  number_srcptr u2, ec_point_srcptr key, ec_curve_srcptr E)
203 {
204 #if MPHELL_USE_MULTITHREADING == 1
205  omp_set_num_threads(2);
206  ec_point tmp;
207  ec_point_get_pool_elt(tmp, E->k, STACK_1);
208  #pragma omp parallel
209  {
210  #pragma omp sections
211  {
212  #pragma omp section
213  {
214  ec_point_mul(tmp, u2, key, E, STACK_1);
215  }
216  #pragma omp section
217  {
218  ec_point_mul(dst, u1, G, E, STACK_2);
219  }
220  }
221  }
222  ec_point_add(dst, dst, tmp, E, STACK_1);
223  ec_point_relax_pool_elt(tmp, E->k, STACK_1);
224 #else
225  ec_point tmp;
226  ec_point_get_pool_elt(tmp, E->k, STACK_1);
227  ec_point_mul(tmp, u2, key, E, STACK_1);
228  ec_point_mul(dst, u1, G, E, STACK_1);
229  ec_point_add(dst, dst, tmp, E, STACK_1);
230  ec_point_relax_pool_elt(tmp, E->k, STACK_1);
231 #endif
232 }
233 
242 void
243 eddsa_sign(unsigned char *hash, eddsa_sig *sig, number priv_key, ec_point *pub_key, ec_curve *curve)
244 {
245  number *ss = (*sig)->s;
246 
247  uint8_t size = (*curve)->k->size;
248 
249  uint32_t i;
250  unsigned char hashvalue[129];
251  unsigned char hashvaluebis[129];
252  unsigned char str[97];
253  uint8_t * message_bin;
254  char * strx;
255  char * stry;
256  char strH[321]; /* 2* 128 (representation of point in hexa) + 64 (size of the message) +1 */
257  uint8_t hashbin[64];
258  int64_t len_bin;
259  number r,s, test, test2;
260  number_init(&r, bits_to_nblock(256));
261  number_init(&test, bits_to_nblock(257));
262  number_init(&s, bits_to_nblock(256));
263  number_init(&test2, bits_to_nblock(512));
264 
265  /* Computation of the public key */
266  number_str(&strx, priv_key, 16);
267  message_bin = (uint8_t *)calloc(strlen(strx)*4, sizeof(uint8_t));
268  len_bin= hex2bin(strx, message_bin);
269  free(strx);
270 
271  /* Computation of the hash of the private key */
272  sha512(hashbin, message_bin, len_bin*8);
273  /* sha512 is used since we need to have hashes of size 512 bits, another
274  * hash function could have been used under this condition, we choosed it
275  * because sha512 is implemented already in MPHELL
276  */
277  free(message_bin);
278 
279  /* Computation of s=2^n+\sum_{i=c}^{n-1}2^ih_i (h_i are bits of the hash)*/
280  bin2hex(hashbin, 64, hashvalue);
281 
282  /* Computation of h_{bi}|M with i>=b (here 256)*/
283  for(i=0;i<32;i++)
284  {
285  str[i]=hashvalue[32+i];
286  }
287  for(i=32;i<96;i++)
288  {
289  str[i]=hash[i];
290  }
291  str[96]= '\0';
292  message_bin = (uint8_t *)calloc(strlen(str)*4, sizeof(uint8_t));
293  len_bin= hex2bin(str, message_bin);
294 
295  /* r = H(h_{bi}|M) */
296  sha512(hashbin, message_bin, len_bin*8);
297  free(message_bin);
298  bin2hex(hashbin, 64, hashvaluebis);
299  number_set_str(test2, hashvaluebis, 16);
300 
301  /* r mod l (in [EdDSA15] l represents E->n)*/
302  number_mod(r,test2,(*curve)->n);
303 
304  /* Computation of R=rB (in [EdDSA15] B represents E->G)*/
305  ec_point_mul_unified((*sig)->R, r, (*curve)->G, (*curve), STACK_1);
306  /* Remove this for optimisation */
307  ec_point_norm((*sig)->R, (*curve), STACK_1);
308 
309  field_elt_str(&strx, ((*sig)->R)->x, 16, false, (*curve)->k, STACK_1);
310  field_elt_str(&stry, ((*sig)->R)->y, 16, false, (*curve)->k, STACK_1);
311  for(i=0;i<strlen(strx);i++)
312  {
313  strH[i]=strx[i];
314  }
315  for(i=strlen(strx);i<64;i++)
316  {
317  strH[i]='0';
318  }
319  for(i=0;i<strlen(stry);i++)
320  {
321  strH[i+64]=stry[i];
322  }
323  for(i=strlen(stry);i<64;i++)
324  {
325  strH[i+64]='0';
326  }
327  free(strx);
328  free(stry);
329  /* We have to compute again s and A */
330 
331  /* Here we need to compute again the public key A*/
332  number_set_str(test, "1", 16);
333  number_lshift(test, test, 256);
334 
335  /* Computation of s=2^n+\sum_{i=c}^{n-1}2^ih_i */
336  number_set_str(test2, hashvalue, 16);
337  char *test3;
338  number_str(&test3, test2, 2);
339  test3[0]='0';
340  test3[1]='1';
341  test3[253]='0';
342  test3[254]='0';
343  test3[255]='0';
344  test3[256]='\0';
345 
346  number_set_str(test2, test3, 2);
347  free(test3);
348  /* Computation of s mod l */
349  number_mod(s, test2, (*curve)->n);
350 
351  /* Computation of A=sB */
352  /*
353  ec_point p_key;
354  ec_point_get_pool_elt(p_key, (*curve)->k, STACK_1);
355  ec_point_mul(p_key, s, (*curve)->G, (*curve), STACK_1);
356  ec_point_norm(p_key, (*curve), STACK_1);
357  */
358 
359  field_elt_str(&strx, (*pub_key)->x, 16,false, (*curve)->k, STACK_1);
360  field_elt_str(&stry, (*pub_key)->y, 16,false, (*curve)->k, STACK_1);
361 
362  for(i=0;i<strlen(strx);i++)
363  {
364  strH[i+128]=strx[i];
365  }
366  for(i=strlen(strx);i<64;i++)
367  {
368  strH[i+128]='0';
369  }
370  for(i=0;i<strlen(stry);i++)
371  {
372  strH[i+192]=stry[i];
373  }
374  for(i=strlen(stry);i<64;i++)
375  {
376  strH[i+192]='0';
377  }
378  for(i=0;i<64;i++)
379  {
380  strH[i+256]=hash[i];
381  }
382  strH[320]= '\0';
383 
384  free(strx);
385  free(stry);
386 
387  message_bin = (uint8_t *)calloc(strlen(strH)*4, sizeof(uint8_t));
388  len_bin = hex2bin(strH, message_bin);
389 
390  /* Computation of the hash of R|A|M */
391  sha512(hashbin,message_bin,len_bin*8);
392  free(message_bin);
393  bin2hex(hashbin, 64, hashvalue);
394  number_set_str(test2, hashvalue, 16);
395 
396  /* Computation of H(R,A,M) mod l */
397  number_mod(test,test2,(*curve)->n);
398 
399  /* Computation of H(R,A,M)*s mod l */
400  number_mul(test2,test,s);
401  number_mod(test,test2,(*curve)->n);
402 
403  /* Computation of r + H(R,A,M)*s mod l */
404  number_add(test2,test,r);
405  number_mod(*ss,test2,(*curve)->n);
406 
407  /* We set the signature */
408  (*sig)->s = ss;
409 
410  /* Free memory */
411  number_free(&r);
412  number_free(&s);
413  number_free(&test);
414  number_free(&test2);
415 }
416 
431 int8_t
432 eddsa_verify(unsigned char *hash, eddsa_sig *sig, ec_point *pub_key, ec_curve *curve, ecdsa_precomp precomp)
433 {
434  if(!edwards_belongs((*sig)->R, (*curve), STACK_1))
435  {
436  /* Just check that R belongs to the curve */
437  return false;
438  }
439  /* Just check that s \in {0, ... , q-1} */
440  if( number_cmp(*((*sig)->s), (*curve)->n)>=0)
441  {
442  return false;
443  }
444 
445  char * str;
446  uint8_t size = (*curve)->k->size;
447  uint8_t hashbin[64];
448  uint8_t * message_bin;
449  unsigned char hashvalue[129];
450  int64_t len_bin;
451  uint32_t i;
452  unsigned char resultat[193]; /* 2*64 + 64 (size of the message to sign) +1 */
453  char * strx;
454  char * stry;
455  char strH[321]; /* 2* 128 (representation of point in hexadecimal) + 64 (size of the message to sign) +1 */
456  number test, test2;
457  number_init(&test, bits_to_nblock(256));
458  number_init(&test2, bits_to_nblock(512));
459 
460  /* First compute R|A|M */
461  field_elt_str(&strx, ((*sig)->R)->x, 16, false, (*curve)->k, STACK_1);
462  field_elt_str(&stry, ((*sig)->R)->y, 16, false, (*curve)->k, STACK_1);
463  for(i=0;i<strlen(strx);i++)
464  {
465  strH[i]=strx[i];
466  }
467  for(i=strlen(strx);i<64;i++)
468  {
469  strH[i]='0';
470  }
471  for(i=0;i<strlen(stry);i++)
472  {
473  strH[i+64]=stry[i];
474  }
475  for(i=strlen(stry);i<64;i++)
476  {
477  strH[i+64]='0';
478  }
479  free(strx);
480  free(stry);
481 
482  field_elt_str(&strx, (*pub_key)->x, 16, false, (*curve)->k, STACK_1);
483  field_elt_str(&stry, (*pub_key)->y, 16, false, (*curve)->k, STACK_1);
484 
485  for(i=0;i<strlen(strx);i++)
486  {
487  strH[i+128]=strx[i];
488  }
489  for(i=strlen(strx);i<64;i++)
490  {
491  strH[i+128]='0';
492  }
493  for(i=0;i<strlen(stry);i++)
494  {
495  strH[i+192]=stry[i];
496  }
497  for(i=strlen(stry);i<64;i++)
498  {
499  strH[i+192]='0';
500  }
501  for(i=0;i<64;i++)
502  {
503  strH[i+256]=hash[i];
504  }
505  strH[320]= '\0';
506  free(strx);
507  free(stry);
508 
509  message_bin = (uint8_t *)calloc(strlen(strH)*4, sizeof(uint8_t));
510  len_bin= hex2bin(strH, message_bin);
511 
512  /* Computation of the hash of R,A,M */
513  sha512(hashbin,message_bin,len_bin*8);
514  /* sha512 is used since we need to have hashes of size 512 bits, another
515  * hash function could have been used under this condition, we choosed it
516  * because sha512 is implemented already in MPHELL
517  */
518  free(message_bin);
519  bin2hex(hashbin, 64, hashvalue);
520 
521  /* Computation of the values optimised */
522  number_set_str(test2,hashvalue,16);
523  /* Computation of -H(R,A,M) mod l (in [EdDSA15] l represents E->n)*/
524  number_mod(test,test2,(*curve)->n);
525  number_sub(test2,(*curve)->n,test);
526  number_mod(test,test2,(*curve)->n);
527 
528  /* Multiplication of -H(R,A,M) by the cofactor 2**c of the curve */
529  number_mul(test2,(*curve)->h, test);
530  number_mod(test, test2,(*curve)->n);
531 
532  /* x = (2**c)S*B - 2**c*H(R,A,M)*A (in [EdDSA15] B represents E->G, A is publickey)*/
533  ec_point x;
534  ec_point_get_pool_elt(x, (*curve)->k, STACK_1);
535  number_mul(test2,(*curve)->h,*((*sig)->s));
536  number_mod(test2, test2, (*curve)->n);
537  ec_point_2mul_with_precomp(x, test2, (precomp)->prec_G, test, (precomp)->prec_K, PRECOMP_WIN_SIZE, *curve, STACK_1);
538 
539  /* y = 2**c*R */
540  ec_point y;
541  ec_point_get_pool_elt(y, (*curve)->k, STACK_1);
542  ec_point_mul(y, (*curve)->h, (*sig)->R, *curve, STACK_1);
543  /*Get the result by comparing x with y */
544  bool result = ec_point_are_equal(x, y, *curve, STACK_1);
545 
546  /* Free memory */
547  ec_point_relax_pool_elt(x, (*curve)->k, STACK_1);
548  ec_point_relax_pool_elt(y, (*curve)->k, STACK_1);
549  number_free(&test);
550  number_free(&test2);
551 
552  return result;
553 }
554 
563 int8_t
565 {
566 
567  if(!ec_belongs(*pub_key, *curve, STACK_1))
568  {
569  /* pubkey does not belong to the curve */
570  return false;
571  }
572  if(ec_point_is_neutral(*pub_key, *curve, STACK_1))
573  {
574  /* pubkey is the neutral element */
575  return false;
576  }
577  /* We finally test the order of the curve */
578  ec_point x;
579  ec_point_get_pool_elt(x, (*curve)->k, STACK_1);
580  ec_point_mul(x, (*curve)->n, *pub_key, *curve, STACK_1);
581  if(!ec_point_is_neutral(x, *curve, STACK_1))
582  {
583  /* pubkey is the neutral element */
584  ec_point_relax_pool_elt(x, (*curve)->k, STACK_1);
585  return false;
586  }
587  ec_point_relax_pool_elt(x, (*curve)->k, STACK_1);
588  return true;
589 }
590 
591 int main()
592 {
593  /* Initialise MPHELL with 256 bits of security strength for the entropy, RANDOM_AES256 as DRBG and DEVURANDOM as entropy source */
594 
596  int nb_iteration = 100;
597  uint8_t message[200];
598 
599  struct timespec start, end;
600 
601  /* Allocate a field of size 4*block_SIZE = 4*64 = 256 on 64 bits architecture */
602 
603  field k;
604  field_alloc(k, FP, bits_to_nblock(256), NULL);
605 
606  /* Allocate a number of size 4*block_SIZE = 4*64 = 256 on 64 bits architecture */
607 
608  number p;
609  number_init(&p, bits_to_nblock(256));
610 
611  /* Set the number p from a string in base 16 */
612 
613  number_set_str(p, "7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffed", 16);
614 #if MPHELL_USE_AMNS == 1
615  amns AMNS;
616 #if MPHELL_USE_AMNS_32 == 0
617  amns_alloc_init_str(&AMNS, "[7, 5, [-2, 0, 0, 0, 0, 1], 54, 18452995865838783329900129877370266585014740033535441780974987498391596057242, [961252216531765, -808644316442835, 1045474214679914, 876400205157459, 80702276750246], [215521628593942615, 6036461283567564605, 7224436840646086003, 10819948880990321094, 2770174224844310327], [1261219955914665, 2245748633013857, 1942034862299073, 1713436964429893, 1484033610923007], [982299117090493, 2384806805124374, 473263249613373, 1302309306467128, 767899215173126]]", p);
618 #else
619  amns_alloc_init_str(&AMNS, "[1, 13, [-2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1], 24, 27348853913383126840958695328985844583331474485808319900533972989426705703935, [295765, -240077, -384002, 86822, 427979, -178061, 355024, 35335, -47509, 293623, -162279, 239276, -54823], [304002351, 603274027, 987322065, 611192953, 899268748, 456421020, 1804479788, 151565031, 3376928416, 3404037305, 3106617823, 3555398377, 1245081753], [420571, 1005149, 1316639, 803101, 880079, 1425571, 78727, 673803, 292695, 429454, 603140, -81310, 484327], [-78425, 649592, 1210799, 537480, 931731, 330032, 587956, 604351, 932082, 256513, 633201, 50270, 916590]]", p);
620 #endif
621  field_set_amns(k, AMNS);
622 #endif
623 
624  /* Create the field of characteristic p */
625 
626  field_create(k, "", STACK_1, 1, p);
627 
628  /* Allocate curve */
629 
630  ec_curve E;
631  ec_alloc (E, k);
632  ec_init(E, k);
633 
634  /* Create curve */
635 
636  field_elt a, b;
637  ec_point G;
638  number n, h;
639 
640  field_elt_alloc(&a, k);
641  field_elt_init(a, k);
642  field_elt_alloc(&b, k);
643  field_elt_init(b, k);
644  ec_point_alloc(G, k);
645  ec_point_init(G, k);
646  number_init(&n, bits_to_nblock(256));
647  number_init(&h, bits_to_nblock(256));
648 
649  field_elt_set_str(a, "0000000000000000000000000000000000000000000000000000000000000001", 16, false, k, STACK_1);
650  field_elt_set_str(b, "2dfc9311d490018c7338bf8688861767ff8ff5b2bebe27548a14b235eca6874a", 16, false, k, STACK_1);
651  ec_point_set_aff_str(G, "159a6849e44c3c7f061b3d570fc4ed5b5d14c8ba4253df49cc7edf80f533ad9b", "6666666666666666666666666666666666666666666666666666666666666658", false, 16, EDWARDS, k, STACK_1);
652  number_set_str(h, "8", 16);
653  number_set_str(n, "1000000000000000000000000000000014def9dea2f79cd65812631a5cf5d3ed", 16);
654 
655  ec_create (E, "Ed25519", k, a, b, G, h, n, EDWARDS, EXTENDED_EDWARDS, STACK_1);
656 
657  printf("E: \n"); ec_curve_print(E, 16, STACK_1); printf("\n");
658 
659  ec_point_free(G, k);
660  field_elt_free(&a, k);
661  field_elt_free(&b, k);
662  number_free(&h);
663  number_free(&n);
664 
665  unsigned char hashvalue[129];
666  uint8_t * message_bin;
667  char * str;
668  uint8_t hashbin[64];
669  unsigned char hashval[nb_iteration][HASH_SIZE+1];
670  int64_t len_bin;
671  eddsa_sig *lib_sig = (eddsa_sig*)malloc(sizeof(eddsa_sig)*nb_iteration);
672  int i,err;
673  number test, test2;
674  number_init(&test, bits_to_nblock(257));
675  number_init(&test2, bits_to_nblock(512));
676  number priv_key;
677  number_init(&priv_key, bits_to_nblock(256));
678  number_set_ui(test, 1);
679  number_lshift(test,test,256);
680  number_dec(test, test);
681  /* The private key is a number of b bits with b the size of the security
682  * desired.
683  * Here the private key does not need to come from a random value between
684  * 0 and the size of the group generated by G:E->n.
685  */
686 
687  number_random1(priv_key, test, STACK_1);
688  printf("\nThe private key has been created its value is:\n");
689  number_print(priv_key, 16); printf("\n");
690  printf("priv_key > n : %d\n", number_isgreater(priv_key, E->n));
691 
692  /* Create digest */
693  for(i = 0; i < nb_iteration; i++)
694  {
695  sprintf((char *)message, "This is the %d message to sign and verify on stm32F4", i);
696  len_bin=strlen((char *)message);
697  message_bin = (uint8_t *)calloc(len_bin, sizeof(uint8_t));
698  /* Convert ascii message into binary message */
699  string2bin((char *)message, message_bin);
700  /* Hash binary message */
701  sha256(hashbin, message_bin, len_bin*8);
702  free(message_bin);
703  /* Convert binary hash into hexadecimal string */
704  bin2hex(hashbin, HASH_SIZE/2, hashval[i]);
705  }
706 
707  /* Computation of the public key */
708  number_inc(test, test);
709  number_str(&str, priv_key, 16);
710  message_bin = (uint8_t *)calloc(strlen(str)*4, sizeof(uint8_t));
711  len_bin = hex2bin(str, message_bin);
712  /* Computation of the hash of the private key */
713  sha512(hashbin, message_bin, len_bin*8);
714  /* sha512 is used since we need to have hashes of size 512 bits, another
715  * hash function could have been used under this condition, we choosed it
716  * because sha512 is implemented already in MPHELL
717  */
718  free(str);
719  free(message_bin);
720  /* Computation of s=2^n+\sum_{i=c}^{n-1}2^ih_i (h_i are bits of the hash)*/
721  bin2hex(hashbin, 64, hashvalue);
722 
723  number_set_str(test2, hashvalue, 16);
724  printf("\n1: test2 = "); number_print(test2, 16); printf("\n");
725  printf("\n1: test2 = "); number_print(test2, 2); printf("\n");
726 
727  char *test3;
728  number_str(&test3, test2, 2);
729  test3[0]='0';
730  test3[1]='1';
731  test3[253]='0';
732  test3[254]='0';
733  test3[255]='0';
734  test3[256]='\0';
735 
736  number_set_str(test2, test3, 2);
737  free(test3);
738 
739  printf("2: test2 = "); number_print(test2, 16); printf("\n");
740  printf("2: test2 = "); number_print(test2, 2); printf("\n");
741 
742  /* Computation of s mod l (in [EdDSA15] l represents E->n) */
743  number_mod(test, test2, E->n);
744 
745  printf("3: test = "); number_print(test, 16); printf("\n");
746  printf("3: test = "); number_print(test, 2); printf("\n");
747 
748  /* Computation of A=sB (in [EdDSA15] B represents E->G)*/
749  ec_point pub_key;
750  ec_point_alloc(pub_key, E->k);
751  ec_point_init(pub_key, E->k);
752  ec_point_mul_unified(pub_key, test, E->G, E, STACK_1);
753 
754  /* Free memory done for the test */
755  number_free(&test);
756  number_free(&test2);
757 
758  /* Print the public key A */
759  ec_point_norm(pub_key, E, STACK_1);
760  printf("\nThe pubkey has been computed:\n");
761  ec_point_print(pub_key, 16, true, k, STACK_1);
762 
763  /* This test is optional.*/
764  printf("\nThe validity of the public key is a:\n");
765  int ret = eddsa_pub_key_validation(&pub_key, &E);
766  if( ret < 1 )
767  {
768  printf("ERROR\n");
769  }
770  else
771  {
772  printf("SUCCESS\n");
773  }
774 
775  /* Allocate ecsdsa_sig structure */
776  eddsa_sig sig;
777  eddsa_sign_alloc(&sig, E, bits_to_nblock(256));
778 
779  /* Allocate nb_iteration ecdsa_sig structure */
780  for (i = 0; i < nb_iteration; i++)
781  {
782  eddsa_sign_alloc(&(lib_sig[i]), E, bits_to_nblock(256));
783  }
784 
785  /* Precomputation (to speed up verification) */
786  ecdsa_precomp precomp;
787  ecdsa_precal(&precomp, &pub_key, E);
788 
789  /* Sign the digest */
790 
791  printf("Vector test size %d \n", nb_iteration);
792  printf("Curve \t Signature \t\t Verification \n");
793  printf("Ed25519 \t");
794 
795  clock_gettime(CLOCK_MONOTONIC_RAW, &start);
796  for(i = 0; i < nb_iteration; i++)
797  {
798  eddsa_sign((unsigned char *)hashval[i], &(lib_sig[i]), priv_key, &pub_key, &E);
799  }
800  clock_gettime(CLOCK_MONOTONIC_RAW, &end);
801  printf(" %lu.%03u \t\t\t", get_s(&start, &end), get_ns(&start, &end));
802 
803  /* Verify the signature */
804  err=0;
805 
806  clock_gettime(CLOCK_MONOTONIC_RAW, &start);
807  for(i = 0; i < nb_iteration; i++)
808  {
809  ret = eddsa_verify((unsigned char *)hashval[i], &(lib_sig[i]), &pub_key, &E, precomp);
810  if( ret < 1 )
811  {
812  err++;
813  }
814  }
815  clock_gettime(CLOCK_MONOTONIC_RAW, &end);
816  printf(" %lu.%03u \n", get_s(&start, &end), get_ns(&start, &end));
817 
818  if( ret < 1 )
819  {
820  printf("ERROR :%d\n", err);
821  }
822  else
823  {
824  printf("SUCCESS \n");
825  }
826 
827  /* Free memory */
828  ec_point_free(pub_key, k);
829  number_free(&priv_key);
830  eddsa_sign_free(&sig, E);
831  number_free(&p);
832  ecdsa_precal_free(&precomp, E);
833  field_free(k);
834 #if MPHELL_USE_AMNS == 1
835  amns_free(&AMNS);
836 #endif
837  for (i = 0; i < nb_iteration; i++)
838  {
839  eddsa_sign_free(&(lib_sig[i]), E);
840  }
841  free(lib_sig);
842  ec_free(E);
843 
844  free_mphell();
845 
846  return 0;
847 }
void amns_free(amns_ptr *AMNS)
Free the amns system.
Definition: mphell-amns.c:444
void amns_alloc_init_str(amns_ptr *AMNS, char *str, number p)
Allocate and initialise the amns system from the string generated by the Sage AMNS generator from htt...
Definition: mphell-amns.c:1242
void ec_point_2mul_with_precomp(ec_point_ptr P3, number_srcptr n1, ec_point *tab_P1, number_srcptr n2, ec_point *tab_P2, int16_t win_size, ec_curve_srcptr E, uint8_t stack)
Set P3 to n1 * P1 + n2 * P2 using 2 precomputated array.
void ec_curve_print(ec_curve_srcptr E, const uint8_t base, uint8_t stack)
Print a description of E.
bool ec_point_are_equal(ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Test if P1 and P2 are equal on E.
void ec_point_print(ec_point_srcptr P, const uint8_t base, const bool lift, field_srcptr k, uint8_t stack)
Print a description of P.
void ec_create(ec_curve_ptr E, const char *id_curve, field_srcptr k, fe_srcptr a, fe_srcptr b, ec_point_srcptr G, number_srcptr h, number_srcptr n, const ec_type type, const ec_formula f, uint8_t stack)
Create an elliptic curve E, the curve must be allocated and initialised (ec_alloc & ec_init)
Definition: mphell-curve.c:65
bool ec_belongs(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P belongs to E.
void ec_point_mul(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to n * P1 using Montgomery for Weierstrass elliptic curve, and naive method for other elliptic...
void ec_point_set_neutral(ec_point_ptr dst, ec_curve_srcptr E, uint8_t stack)
Set dst to the neutral element.
Definition: mphell-curve.c:934
void ec_point_add(ec_point_ptr P3, ec_point_srcptr P1, ec_point_srcptr P2, ec_curve_srcptr E, uint8_t stack)
Set P3 to P1 + P2, using dedicated formulae (not protected against SPA, but faster)
void ec_free(ec_curve_ptr E)
Free the elliptic curve E.
Definition: mphell-curve.c:809
void ec_point_copy(ec_point_ptr P3, ec_point_srcptr P, field_srcptr k)
Copy P into P3.
Definition: mphell-curve.c:866
void ec_init(ec_curve_ptr E, field_srcptr k)
Initialise a curve.
Definition: mphell-curve.c:55
bool ec_point_is_neutral(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P is the neutral element.
void ec_point_mul_unified(ec_point_ptr P3, number_srcptr n, ec_point_srcptr P1, ec_curve_srcptr E, uint8_t stack)
Set P3 to n * P1 using Montgomery for Weierstrass elliptic curve, and naive method for other elliptic...
void ec_point_set_aff_str(ec_point_ptr P, const char *str_x, const char *str_y, const bool is_reduced, const uint8_t base, const ec_type type, field_srcptr k, uint8_t stack)
Set a point from its affine coordinates under string format.
Definition: mphell-curve.c:913
void ec_point_init(ec_point_ptr P, field_srcptr k)
Initialise an elliptic curve point.
Definition: mphell-curve.c:842
void ec_point_free(ec_point_ptr P, field_srcptr k)
Free the point P.
Definition: mphell-curve.c:858
void ec_point_norm(ec_point_ptr P, ec_curve_srcptr E, uint8_t stack)
Convert a point in projective or jacobian coordinate to an affine point (x,y)
Definition: mphell-curve.c:953
void ec_point_alloc(ec_point_ptr P, field_srcptr k)
Allocate an elliptic curve point.
Definition: mphell-curve.c:834
void ec_alloc(ec_curve_ptr E, field_srcptr k)
Allocate a curve.
Definition: mphell-curve.c:37
static void ec_point_get_pool_elt(ec_point_ptr P, field_ptr k, uint8_t stack)
Get an initialised point from the pool.
Definition: mphell-curve.h:206
@ EDWARDS
Definition: mphell-curve.h:42
static void ec_point_relax_pool_elt(ec_point_ptr P, field_ptr k, uint8_t stack)
Relax an initialised point from the pool.
Definition: mphell-curve.h:222
@ EXTENDED_EDWARDS
Definition: mphell-curve.h:61
bool edwards_belongs(ec_point_srcptr P, ec_curve_srcptr E, uint8_t stack)
Test if P belongs to E.
@ DEVURANDOM
void field_elt_free(fe_ptr *src, field_srcptr k)
Free space used by src.
Definition: mphell-field.c:348
void field_alloc(field_ptr k, const field_type type, const uint8_t size, field_ptr base)
Allocates space for the different fields of the structure pointed by k.
Definition: mphell-field.c:37
void field_elt_set_str(fe_ptr dst, const char *str, const uint8_t base, const bool isreduced, field_srcptr k, uint8_t stack)
Set dst to str, if Montgomery arithmetic is used, is_reduced == false -> transform dst into its Montg...
Definition: mphell-field.c:516
void field_elt_init(fe_ptr dst, field_srcptr k)
Initialise the field element.
Definition: mphell-field.c:291
void field_elt_alloc(fe_ptr *dst, field_srcptr k)
Allocate space for a field element.
Definition: mphell-field.c:269
void field_elt_str(char **str, fe_srcptr src, const uint8_t base, const bool lift, field_srcptr k, uint8_t stack)
Converts src to string format in base specified by base.
Definition: mphell-field.c:702
void field_free(field_ptr k)
Free the space of the field informations structure.
Definition: mphell-field.c:194
void field_create(field_ptr k, const char *id, uint8_t stack, const uint32_t n,...)
Initialize the different fields of the structure pointed by k.
Definition: mphell-field.c:87
field_t field[1]
Address of a field structure.
Definition: mphell-field.h:86
fp_elt * field_elt
Generic field element.
Definition: mphell-field.h:37
@ FP
Definition: mphell-field.h:57
void free_mphell()
Free MPHELL memory, especially the big amount of temporary memory.
Definition: mphell-init.c:97
void init_mphell(const uint16_t security_strength, const random_type type, const entropy_type entropy)
Initialise MPHELL with security_strength bits of security (for random number only).
Definition: mphell-init.c:35
void number_random1(number_ptr dst, number_srcptr bound, uint8_t stack)
Set dst to a random number_ptr between 0 and bound, the random process is chosen at the MPHELL initia...
void number_mod(number_ptr dst, number_srcptr src1, number_srcptr src2)
Compute dst such that src1 = q * src2 + dst ; dst < src2.
void number_set_ui(number_ptr dst, const block src)
Set dst to src.
void number_lshift(number_ptr dst, number_srcptr src, const uint16_t shift)
Set dst to src << shift.
void number_free(number *dst)
Free a number_ptr allocated on the RAM memory (malloc)
Definition: mphell-number.c:75
void number_set_str(number_ptr dst, const char *str, const uint8_t base)
Set dst to str.
bool number_isgreater(number_srcptr src1, number_srcptr src2)
Test if src1 > src2.
void number_sub(number_ptr dst, number_srcptr src1, number_srcptr src2)
Set dst to src1 - src2 if src1 - src2 fit in dst.
void number_str(char **str, number_srcptr src, const uint8_t base)
Converts src to string format in base specified by base.
void number_add(number_ptr dst, number_srcptr src1, number_srcptr src2)
Set dst to src1 + src2 if src1 + src2 fit in dst.
int8_t number_cmp(number_srcptr src1, number_srcptr src2)
Compare src1 and src2.
void number_print(number_srcptr src, const uint8_t base)
Print src in base "base".
void number_dec(number_ptr dst, number_srcptr src)
Set dst to src - 1 if src - 1 fit in dst.
void number_mul(number_ptr dst, number_srcptr src1, number_srcptr src2)
Set dst to src1 * src2.
void number_inc(number_ptr dst, number_srcptr src)
Set dst to src + 1 if src + 1 fit in dst.
void number_init(number *dst, const uint8_t n)
Allocate a number_ptr on the RAM memory (malloc)
Definition: mphell-number.c:59
@ RANDOM_AES256
Definition: mphell-random.h:39
void sha256(uint8_t *hashvalue, const uint8_t *data, const uint64_t data_len)
Compute the Sha256 hash of "data".
void sha512(uint8_t *hashvalue, const uint8_t *data, const uint64_t data_len)
Compute the Sha512 hash of "data".
uint32_t hex2bin(const char *in, unsigned char *out)
Convert an hexadecimal string into a binary string.
Definition: mphell-util.c:111
time_t get_s(struct timespec *start, struct timespec *end)
Return the elapsed time in second between "start" and "end".
Definition: mphell-util.c:39
void string2bin(char *s, uint8_t *output)
Convert a string into a byte array.
Definition: mphell-util.c:271
void bin2hex(const unsigned char *old, const uint32_t oldlen, unsigned char *result)
Converts a string of ASCII characters to hexadecimal values.
Definition: mphell-util.c:95
uint8_t bits_to_nblock(const uint16_t nbits)
Return the number of blocks required to store a nbits number.
Definition: mphell-util.c:29
unsigned int get_ns(struct timespec *start, struct timespec *end)
Return the elapsed time in nano second to add to the result of get_s().
Definition: mphell-util.c:48
void ecdsa_precal_free(ecdsa_precomp *precomp, ec_curve_ptr E)
Free memory of the ecdsa_precomp structure.
void ecdsa_precal(ecdsa_precomp *precomp, ec_point *key, ec_curve_ptr E)
Compute 1*G, 2*G, 3*G, 4*G, 5*G, 6*G, 7*G and 1*Q, 2*Q, 3*Q, 4*Q, 5*Q, 6*Q, 7*Q where G is the base p...
void ec_point_mul_ecdsa(ec_point dst, number_srcptr u1, ec_point_srcptr G, number_srcptr u2, ec_point_srcptr key, ec_curve_srcptr E)
Compute u1 * G + u2 * key.
void eddsa_sign_free(eddsa_sig *sig, ec_curve_srcptr E)
Free a used signature structure.
int8_t eddsa_pub_key_validation(ec_point *pub_key, ec_curve *curve)
Verify that the public key is valid (id est check taht pub_key belongs to the curve,...
Define a AMNS.
Definition: mphell-amns.h:81
Define an elliptic curve.
Definition: mphell-curve.h:141
field_ptr k
Definition: mphell-curve.h:143
ec_point G
Definition: mphell-curve.h:148
number n
Definition: mphell-curve.h:149
Define an elliptic curve point.
Definition: mphell-curve.h:105
Precomputation structure.
ec_point prec_K[2 *PRECOMP_SIZE]
ec_point prec_G[2 *PRECOMP_SIZE]
Define an EdDSA signature.