MPHELL  5.0.0
mphell_tuto_eddsa-448+25519.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 {
58  number *s;
59 };
60 
65 typedef struct eddsa_sig eddsa_sig_t;
66 
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  uint8_t b;
247 
248 
249  uint8_t size = (*curve)->k->size;
250 
251  if(size==bits_to_nblock(448)) /* b=114 for Ed448 b=64 for Ed25519 byte size of the filed elements.. */
252  {
253  b=114;
254  }
255  else if (size==bits_to_nblock(256))
256  {
257  b=64;
258  }
259 
260  uint32_t i;
261  unsigned char hashvalue[2*b+1]; /*2*b+1 hex */
262  unsigned char hashvaluebis[2*b+1];
263  unsigned char str[b+64+1]; /* b + 64 hex hashes + 1 */
264  uint8_t * message_bin;
265  unsigned char hashbin2[b]; /* of the size of the output of hash function */
266  char * strx;
267  char * stry; /* of the size of the field we are working on */
268  char strH[4*b+64+1]; /* 2* 2*b (representation of point in hexa) + 64 (size of the message) +1 */
269  uint8_t hashbin[64]; /* we use shake256 with an output of 114*8 bits */
270  int64_t len_bin;
271  number r,s, test, test2;
272  number_tmp_alloc(&r, size, STACK_1);
273  number_tmp_alloc(&test, size+1, STACK_1);
274  number_tmp_alloc(&s, size, STACK_1);
275  number_tmp_alloc(&test2, 2*size+1, STACK_1);
276 
277 
278  /* Computation of the public key */
279  number_str(&strx, priv_key, 16);
280  message_bin = (uint8_t *)calloc(strlen(strx)*2, sizeof(uint8_t));
281  len_bin= hex2bin(strx, message_bin);
282  free(strx);
283 
284  if(size==bits_to_nblock(448))
285  {
286  /* Computation of the hash of the private key */
287  FIPS202_SHAKE256((unsigned char *)message_bin, len_bin ,hashbin2, 114);
288  /* shake256 is used according to standards (e.g. rfc8032) */
289  }
290  else if(size==bits_to_nblock(256))
291  {
292  /* Computation of the hash of the private key */
293  sha512(hashbin2, message_bin, len_bin*8);
294  /* sha512 is used since we need to have hashes of size 512 bits, another
295  * hash function could have been used under this condition, we choosed it
296  * because sha512 is implemented already in MPHELL
297  */
298  }
299 
300  free(message_bin);
301 
302  /* Computation of s=2^n+\sum_{i=c}^{n-1}2^ih_i (h_i are bits of the hash)*/
303  bin2hex(hashbin2, b, hashvalue);
304  /* The input has size b*8 bits we work only with 1st half for pubkey and 2nd half for r*/
305 
306  /* Computation of h_{bi}|M with i>=b (hashvalue has size 114*2=228 hex)*/
307  for(i=0;i<b;i++)
308  {
309  str[i]=hashvalue[b+i];
310  }
311  for(i=b;i<b+64;i++) /*114 + 64 (here M is replaced by its hash ) */
312  {
313  str[i]=hash[i-b];
314  }
315  str[b+64]= '\0';
316  message_bin = (uint8_t *)calloc((b+64)*2, sizeof(uint8_t));
317  len_bin= hex2bin(str, message_bin);
318 
319  /* r = H(h_{bi}|M) */
320  if(size==bits_to_nblock(448))
321  {
322  FIPS202_SHAKE256((unsigned char *)message_bin, len_bin ,hashbin2, 114);
323  }
324  else if(size==bits_to_nblock(256))
325  {
326 
327  sha512(hashbin2, message_bin, len_bin*8);
328  }
329  free(message_bin);
330  bin2hex(hashbin2, b, hashvaluebis); /* The input has size b*8 bytes */
331  number_set_str(test2, hashvaluebis, 16);
332 
333  /* r mod l (in [EdDSA15] l represents E->n)*/
334  number_mod(r,test2,(*curve)->n);
335 
336  /* Computation of R=rB (in [EdDSA15] B represents E->G)*/
337  ec_point_mul_unified((*sig)->R, r, (*curve)->G, (*curve), STACK_1);
338  /* Remove this for optimisation */
339  ec_point_norm((*sig)->R, (*curve), STACK_1);
340 
341  /* We copy R in strH */
342  field_elt_str(&strx, ((*sig)->R)->x, 16, false, (*curve)->k, STACK_1);
343  field_elt_str(&stry, ((*sig)->R)->y, 16, false, (*curve)->k, STACK_1);
344  for(i=0;i<strlen(strx);i++)
345  {
346  strH[i]=strx[i];
347  }
348  for(i=strlen(strx);i<b;i++)
349  {
350  strH[i]='0';
351  }
352  for(i=0;i<strlen(stry);i++)
353  {
354  strH[i+b]=stry[i];
355  }
356  for(i=strlen(stry);i<b;i++)
357  {
358  strH[i+b]='0';
359  }
360  /* We have to compute again s and A */
361 
362  /* Here we need to compute again the public key A*/
363 
364  /* Computation of s=2^n+\sum_{i=c}^{n-1}2^ih_i */
365  number_set_str(test2, hashvalue, 16);
366  number_rshift(test2, test2, 4*b);
367  number_set_str(test, "1", 16);
368  number_lshift(test,test,4*b-1);
369  /* we make sure that test2 is of size 4*b*4 bits*/
370  if(number_cmp(test,test2)>0)
371  {
372  number_add(test2, test2, test);
373  }
374  /* as said before we take only the 1st half of the hashvalue*/
375  free(strx);
376  number_str(&strx, test2, 2);
377  if(size==bits_to_nblock(448))
378  {
379  strx[0]='0';
380  strx[1]='0';
381  strx[2]='0';
382  strx[3]='0';
383  strx[4]='0';
384  strx[5]='0';
385  strx[6]='0';
386  strx[7]='0';
387  strx[8]='1';
388  strx[454]='0';
389  strx[455]='0';
390  }
391  else if(size==bits_to_nblock(256))
392  {
393  strx[0]='0';
394  strx[1]='1';
395  strx[253]='0';
396  strx[254]='0';
397  strx[255]='0';
398  strx[256]='\0';
399  }
400  number_set_str(test2, strx, 2);
401 
402  /* Computation of s mod l */
403  number_mod(s, test2, (*curve)->n);
404 
405  /* We concatenate the public key A = sB in strH */
406 
407  free(strx);
408  free(stry);
409  field_elt_str(&strx, (*pub_key)->x, 16,false, (*curve)->k, STACK_1);
410  field_elt_str(&stry, (*pub_key)->y, 16,false, (*curve)->k, STACK_1);
411  for(i=0;i<strlen(strx);i++)
412  {
413  strH[i+2*b]=strx[i];
414  }
415  for(i=strlen(strx);i<b;i++)
416  {
417  strH[i+2*b]='0';
418  }
419  for(i=0;i<strlen(stry);i++)
420  {
421  strH[i+3*b]=stry[i];
422  }
423  for(i=strlen(stry);i<b;i++)
424  {
425  strH[i+3*b]='0';
426  }
427  /* We concatenate the M in strH */
428  for(i=0;i<64;i++)
429  {
430  strH[i+4*b]=hash[i];
431  }
432  strH[4*b+64]= '\0';
433 
434  message_bin = (uint8_t *)calloc((4*b+64)*2, sizeof(unsigned char));
435  len_bin = hex2bin(strH, message_bin);
436 
437  if(size==bits_to_nblock(448))
438  {
439  /* Computation of the hash of R|A|M */
440  FIPS202_SHAKE256((unsigned char *)message_bin, len_bin ,hashbin2, 114);
441  /* shake 256 is used according to standards (e.g. rfc8032) */
442  }
443  else if(size==bits_to_nblock(256))
444  {
445  sha512(hashbin2, message_bin, len_bin*8);
446  }
447  free(message_bin);
448 
449  bin2hex(hashbin2, b, hashvalue); /* The input has size 114*8 bytes */
450  number_set_str(test2, hashvalue, 16);
451 
452  /* Computation of H(R,A,M) mod l */
453  number_mod(test,test2,(*curve)->n);
454 
455  /* Computation of H(R,A,M)*s mod l */
456  number_mul(test2,test,s);
457  number_mod(test,test2,(*curve)->n);
458 
459  /* Computation of r + H(R,A,M)*s mod l */
460  number_add(test2,test,r);
461  number_mod(*ss,test2,(*curve)->n);
462 
463  /* We set the signature */
464  (*sig)->s = ss;
465 
466  /* Free memory */
467  free(strx);
468  free(stry);
469  number_tmp_free(&r, size, STACK_1);
470  number_tmp_free(&test, size+1, STACK_1);
471  number_tmp_free(&s, size, STACK_1);
472  number_tmp_free(&test2, 2*size+1, STACK_1);
473 }
474 
489 int8_t
490 eddsa_verify(unsigned char *hash, eddsa_sig *sig, ec_point *pub_key, ec_curve *curve, ecdsa_precomp precomp)
491 {
492  if(!edwards_belongs((*sig)->R, (*curve), STACK_1))
493  {
494  /* Just check that R belongs to the curve */
495  return false;
496  }
497  /* Just check that s \in {0, ... , q-1} */
498  if( number_cmp(*((*sig)->s), (*curve)->n)>=0)
499  {
500  return false;
501  }
502 
503  uint8_t size = (*curve)->k->size;
504  uint8_t b;
505  if(size==bits_to_nblock(448)) /* b=114 for Ed448 b=64 for Ed25519 byte size of the filed elements.. */
506  {
507  b=114;
508  }
509  else if(size==bits_to_nblock(256))
510  {
511  b=64;
512  }
513 
514  uint8_t hashbin[b+1];
515  uint8_t message_bin[(4*b+64)*2];
516  unsigned char hashvalue[2*b+1];
517  int64_t len_bin;
518  uint32_t i;
519  char * strx;
520  char * stry;
521  char strH[4*b+64+1]; /* 2* 224 (representation of point in hexadecimal) + 64 (size of the message to sign) +1 */
522  number test, test2;
523  number_tmp_alloc(&test, size+1, STACK_1);
524  number_tmp_alloc(&test2, 2*size+1, STACK_1);
525 
526  /* First compute R|A|M */
527  field_elt_str(&strx, ((*sig)->R)->x, 16, false, (*curve)->k, STACK_1);
528  field_elt_str(&stry, ((*sig)->R)->y, 16, false, (*curve)->k, STACK_1);
529  for(i=0;i<strlen(strx);i++)
530  {
531  strH[i]=strx[i];
532  }
533  for(i=strlen(strx);i<b;i++)
534  {
535  strH[i]='0';
536  }
537  for(i=0;i<strlen(stry);i++)
538  {
539  strH[i+b]=stry[i];
540  }
541  for(i=strlen(stry);i<b;i++)
542  {
543  strH[i+b]='0';
544  }
545 
546  free(strx);
547  free(stry);
548 
549  field_elt_str(&strx, (*pub_key)->x, 16, false, (*curve)->k, STACK_1);
550  field_elt_str(&stry, (*pub_key)->y, 16, false, (*curve)->k, STACK_1);
551 
552  for(i=0;i<strlen(strx);i++)
553  {
554  strH[i+2*b]=strx[i];
555  }
556  for(i=strlen(strx);i<b;i++)
557  {
558  strH[i+2*b]='0';
559  }
560  for(i=0;i<strlen(stry);i++)
561  {
562  strH[i+3*b]=stry[i];
563  }
564  for(i=strlen(stry);i<b;i++)
565  {
566  strH[i+3*b]='0';
567  }
568  for(i=0;i<64;i++)
569  {
570  strH[i+4*b]=hash[i];
571  }
572  strH[4*b+64]= '\0';
573  free(strx);
574  free(stry);
575 
576  /*message_bin = (uint8_t *)calloc(strlen(strH)*4, sizeof(uint8_t));*/
577  len_bin = hex2bin(strH, message_bin);
578  /* Computation of the hash of R,A,M */
579  if(size==bits_to_nblock(448)) /* b=114 for Ed448 b=64 for Ed25519 byte size of the filed elements.. */
580  {
581  FIPS202_SHAKE256((unsigned char *)message_bin, len_bin ,hashbin, 114);
582  /* shake256 is used according to standards (e.g. rfc 8032) */
583  }
584  else if (size==bits_to_nblock(256))
585  {
586  sha512(hashbin,message_bin,len_bin*8);
587  }
588  bin2hex(hashbin, b, hashvalue);
589 
590  /* Computation of the values optimised */
591  number_set_str(test2,hashvalue,16);
592  /* Computation of -H(R,A,M) mod l (in [EdDSA15] l represents E->n)*/
593  number_mod(test,test2,(*curve)->n);
594  number_sub(test2,(*curve)->n,test);
595  number_mod(test,test2,(*curve)->n);
596 
597  /* Multiplication of -H(R,A,M) by the cofactor 2**c of the curve */
598  number_mul(test2,(*curve)->h, test);
599  number_mod(test, test2,(*curve)->n);
600 
601  /* x = (2**c)S*B - 2**c*H(R,A,M)*A (in [EdDSA15] B represents E->G, A is publickey)*/
602  ec_point x;
603  ec_point_get_pool_elt(x, (*curve)->k, STACK_1);
604  number_mul(test2,(*curve)->h,*((*sig)->s));
605  number_mod(test2, test2, (*curve)->n);
606  ec_point_2mul_with_precomp(x, test2, (precomp)->prec_G, test, (precomp)->prec_K, PRECOMP_WIN_SIZE, *curve, STACK_1);
607 
608  /* y = 2**c*R */
609  ec_point y;
610  ec_point_get_pool_elt(y, (*curve)->k, STACK_1);
611  ec_point_mul(y, (*curve)->h, (*sig)->R, *curve, STACK_1);
612  /*Get the result by comparing x with y */
613  bool result = ec_point_are_equal(x, y, *curve, STACK_1);
614 
615  /* Free memory */
616  ec_point_relax_pool_elt(x, (*curve)->k, STACK_1);
617  ec_point_relax_pool_elt(y, (*curve)->k, STACK_1);
618  number_tmp_free(&test, size+1, STACK_1);
619  number_tmp_free(&test2, 2*size+1, STACK_1);
620 
621  return result;
622 }
623 
632 int8_t
634 {
635 
636  if(!ec_belongs(*pub_key, *curve, STACK_1))
637  {
638  /* pubkey does not belong to the curve */
639  return false;
640  }
641  if(ec_point_is_neutral(*pub_key, *curve, STACK_1))
642  {
643  /* pubkey is the neutral element */
644  return false;
645  }
646  /* We finally test the order of the curve */
647  ec_point x;
648  ec_point_get_pool_elt(x, (*curve)->k, STACK_1);
649  ec_point_mul(x, (*curve)->n, *pub_key, *curve, STACK_1);
650  if(!ec_point_is_neutral(x, *curve, STACK_1))
651  {
652  /* pubkey is the neutral element */
653  ec_point_relax_pool_elt(x, (*curve)->k, STACK_1);
654  return false;
655  }
656  ec_point_relax_pool_elt(x, (*curve)->k, STACK_1);
657  return true;
658 }
659 
660 /* If no arguments are given the function is used on Ed448 otherwise on Ed25519 */
661 int main(int argc, char **argv)
662 {
663  /* Initialise MPHELL with 256 bits of security strength for the entropy, RANDOM_AES256 as DRBG and DEVURANDOM as entropy source */
664 
666  int nb_iteration = 10000;
667  uint8_t message[200];
668 
669  struct timespec start, end;
670  field k;
671  ec_curve E;
672  if(argc<2 || (argc>1 && atoi(argv[1])==448))
673  {
674  field_alloc(k, FP, bits_to_nblock(448), NULL);
675 
676  ec_alloc(E, k);
677  ec_use_curve(E, k, ED_448, EXTENDED_EDWARDS, STACK_1);
678  printf("Ed448 \t");
679  }
680  else
681  {
682  /* Code for Ed25519 */
683 
684  field_alloc(k, FP, bits_to_nblock(256), NULL);
685 
686  ec_alloc(E, k);
687  ec_use_curve(E, k, ED_25519, EXTENDED_EDWARDS, STACK_1);
688  printf("Ed25519 \t");
689  }
690 
691  uint8_t b2;
692  uint8_t size = (E)->k->size;;
693 
694  if(size==bits_to_nblock(448))
695  {
696  b2=114;
697  }
698  else if(size==bits_to_nblock(256))
699  {
700  b2=64;
701  }
702 
703  unsigned char hashvalue[2*b2+1];
704  unsigned char hashvaluebis[2*b2+1];
705  uint8_t * message_bin;
706  char * str;
707  char test3[4*b2];
708  uint8_t hashbin[b2];
709  uint8_t hashbin2[b2];
710  unsigned char hashval[nb_iteration][HASH_SIZE+1];
711  int64_t len_bin;
712  eddsa_sig *lib_sig = (eddsa_sig*)malloc(sizeof(eddsa_sig)*nb_iteration);
713  int i,err;
714  number test, test2;
715  number_init(&test, size + 1);
716  number_init(&test2, 2*size + 1);
717  number priv_key;
718  number_init(&priv_key, size + 1);
719  number_set_ui(test, 1);
720  number_lshift(test,test,4*b2);
721  number_dec(test, test);
722  /* The private key is a number of b bits with b the size of the security
723  * desired.
724  * Here the private key does not need to come from a random value between
725  * 0 and the size of the group generated by G:E->n.
726  */
727 
728  number_random1(priv_key, test, STACK_1);
729  printf("\nThe private key has been created its value is:\n");
730  number_print(priv_key, 16); printf("\n");
731  printf("priv_key > n : %d\n", number_isgreater(priv_key, E->n));
732 
733  /* Create digest */
734  for(i = 0; i < nb_iteration; i++)
735  {
736  sprintf((char *)message, "This is the %d message to sign and verify on stm32F4", i);
737  len_bin=strlen((char *)message);
738  message_bin = (uint8_t *)calloc(len_bin, sizeof(uint8_t));
739  /* Convert ascii message into binary message */
740  string2bin((char *)message, message_bin);
741  /* Hash binary message */
742  sha256(hashbin, message_bin, len_bin*8);
743  free(message_bin);
744  /* Convert binary hash into hexadecimal string */
745  bin2hex(hashbin, HASH_SIZE/2, hashval[i]);
746  }
747 
748  /* Computation of the public key */
749  number_inc(test, test);
750  number_rshift(test,test,1);
751  number_str(&str, priv_key, 16);
752  message_bin = (uint8_t *)calloc(strlen(str)*2, sizeof(uint8_t));
753  len_bin = hex2bin(str, message_bin);
754  printf("\nBefore loop: len_bin: %d strlen(str): %d", len_bin, strlen(str));
755  if(size==bits_to_nblock(448))
756  {
757  /* Computation of the hash of the private key */
758  FIPS202_SHAKE256((unsigned char *)message_bin, len_bin , hashbin2, 114);
759  /* sha3 is used according to standards (e.g. rfc 8032)*/
760  }
761  else if(size==bits_to_nblock(256))
762  {
763  /* Computation of the hash of the private key */
764  sha512(hashbin2, message_bin, len_bin*8);
765  /* sha512 is used according to standards (e.g. rfc 8032) */
766  }
767  free(message_bin);
768  /* Computation of s=2^n+\sum_{i=c}^{n-1}2^ih_i (h_i are bits of the hash)*/
769  bin2hex(hashbin2, b2, hashvaluebis);
770  /*2nd half of the hash bits are necessary for the public hence 114 in input */
771 
772  number_set_str(test2, hashvaluebis, 16);
773  printf("\n0: test2 = "); number_print(test2, 16); printf("\n");
774 
775  printf("1: test2 = "); number_print(test2, 16); printf("\n");
776 
777  number_rshift(test2, test2, 4*b2);
778  /* we make sure that test2 is of size 4*4*b bits*/
779  if(number_cmp(test,test2)>0)
780  {
781  number_add(test2, test2, test);
782  }
783  free(str);
784  number_str(&str, test2, 2);
785  if(size==bits_to_nblock(448))
786  {
787  str[0]='0';
788  str[1]='0';
789  str[2]='0';
790  str[3]='0';
791  str[4]='0';
792  str[5]='0';
793  str[6]='0';
794  str[7]='0';
795  str[8]='1';
796  str[454]='0';
797  str[455]='0';
798  }
799  else if(size==bits_to_nblock(256))
800  {
801  str[0]='0';
802  str[1]='1';
803  str[253]='0';
804  str[254]='0';
805  str[255]='0';
806  str[256]='\0';
807  }
808  number_set_str(test2, str, 2);
809  free(str);
810 
811  printf("\n2: test2 = "); number_print(test2, 16); printf("\n");
812  /* Computation of s mod l (in [EdDSA15] l represents E->n) */
813  number_mod(test, test2, E->n);
814 
815  printf("3: test = "); number_print(test, 16); printf("\n");
816 
817  /* Computation of A=sB (in [EdDSA15] B represents E->G)*/
818  ec_point pub_key;
819  ec_point_alloc(pub_key, E->k);
820  ec_point_init(pub_key, E->k);
821  ec_point_mul_unified(pub_key, test, E->G, E, STACK_1);
822 
823  /* Free memory done for the test */
824  number_free(&test);
825  number_free(&test2);
826 
827  /* Print the public key A */
828  ec_point_norm(pub_key, E, STACK_1);
829  printf("\nThe pubkey has been computed:\n");
830  ec_point_print(pub_key, 16, true, k, STACK_1);
831 
832  /* This test is optional.*/
833  printf("\nThe validity of the public key is a:\n");
834  int ret = eddsa_pub_key_validation(&pub_key, &E);
835  if( ret < 1 )
836  {
837  printf("ERROR\n");
838  }
839  else
840  {
841  printf("SUCCESS\n");
842  }
843 
844  /* Allocate ecsdsa_sig structure */
845  eddsa_sig sig;
846  eddsa_sign_alloc(&sig, E, bits_to_nblock(456));
847 
848  /* Allocate nb_iteration ecdsa_sig structure */
849  for (i = 0; i < nb_iteration; i++)
850  {
851  eddsa_sign_alloc(&(lib_sig[i]), E, bits_to_nblock(456));
852  }
853 
854  /* Precomputation (to speed up verification) */
855  ecdsa_precomp precomp;
856  ecdsa_precal(&precomp, &pub_key, E);
857 
858  /* Sign the digest */
859 
860  printf("Vector test size %d \n", nb_iteration);
861  printf("Curve \t Signature \t\t Verification \n");
862  if(argc<2 || (argc>1 && atoi(argv[1])==448))
863  {
864  printf("Ed448 \t\t");
865  }
866  else
867  {
868  printf("Ed25519 \t\t");
869  }
870 
871  clock_gettime(CLOCK_MONOTONIC_RAW, &start);
872  for(i = 0; i < nb_iteration; i++)
873  {
874  eddsa_sign((unsigned char *)hashval[i], &(lib_sig[i]), priv_key, &pub_key, &E);
875  }
876  clock_gettime(CLOCK_MONOTONIC_RAW, &end);
877  printf(" %lu.%03u \t\t\t", get_s(&start, &end), get_ns(&start, &end));
878 
879  /* Verify the signature */
880  err=0;
881 
882  clock_gettime(CLOCK_MONOTONIC_RAW, &start);
883  for(i = 0; i < nb_iteration; i++)
884  {
885  ret = eddsa_verify((unsigned char *)hashval[i], &(lib_sig[i]), &pub_key, &E, precomp);
886  if( ret < 1 )
887  {
888  err++;
889  }
890  }
891  clock_gettime(CLOCK_MONOTONIC_RAW, &end);
892  printf(" %lu.%03u \n", get_s(&start, &end), get_ns(&start, &end));
893 
894  if( ret < 1 )
895  {
896  printf("ERROR :%d\n", err);
897  }
898  else
899  {
900  printf("SUCCESS \n");
901  }
902 
903  /* Free memory */
904  ec_point_free(pub_key, k);
905  number_free(&priv_key);
906  eddsa_sign_free(&sig, E);
907  ecdsa_precal_free(&precomp, E);
908  field_free(k);
909  for (i = 0; i < nb_iteration; i++)
910  {
911  eddsa_sign_free(&(lib_sig[i]), E);
912  }
913  free(lib_sig);
914  ec_free(E);
915 
916  free_mphell();
917 
918  return 0;
919 }
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.
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.
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
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_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_use_curve(ec_curve_ptr E, field_ptr k, const ec_known_curve id_curve, const ec_formula f, uint8_t stack)
Create the elliptic curve (and the associated base field) id_curve, the curve and the field must me a...
Definition: mphell-curve.c:117
void ec_alloc(ec_curve_ptr E, field_srcptr k)
Allocate a curve.
Definition: mphell-curve.c:37
@ ED_448
Definition: mphell-curve.h:91
@ ED_25519
Definition: mphell-curve.h:90
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
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_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_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
field_t field[1]
Address of a field structure.
Definition: mphell-field.h:86
@ 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_tmp_free(number *t, const uint8_t size, uint8_t stack)
Free a temporary number.
Definition: mphell-number.c:45
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_rshift(number_ptr dst, number_srcptr src, const uint16_t shift)
Set dst to src >> shift.
void number_tmp_alloc(number *t, const uint8_t size, uint8_t stack)
Allocate a temporary number.
Definition: mphell-number.c:31
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 FIPS202_SHAKE256(const unsigned char *input, unsigned int inputByteLen, unsigned char *output, int outputByteLen)
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 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.