ec_misc.c
Go to the documentation of this file.
1 /**
2  * @file ec_misc.c
3  * @brief Helper routines for ECC
4  *
5  * @section License
6  *
7  * SPDX-License-Identifier: GPL-2.0-or-later
8  *
9  * Copyright (C) 2010-2025 Oryx Embedded SARL. All rights reserved.
10  *
11  * This file is part of CycloneCRYPTO Open.
12  *
13  * This program is free software; you can redistribute it and/or
14  * modify it under the terms of the GNU General Public License
15  * as published by the Free Software Foundation; either version 2
16  * of the License, or (at your option) any later version.
17  *
18  * This program is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21  * GNU General Public License for more details.
22  *
23  * You should have received a copy of the GNU General Public License
24  * along with this program; if not, write to the Free Software Foundation,
25  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
26  *
27  * @author Oryx Embedded SARL (www.oryx-embedded.com)
28  * @version 2.5.0
29  **/
30 
31 //Switch to the appropriate trace level
32 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL
33 
34 //Dependencies
35 #include "core/crypto.h"
36 #include "ecc/ec.h"
37 #include "ecc/ec_misc.h"
38 #include "debug.h"
39 
40 //Check crypto library configuration
41 #if (EC_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Octet string to integer conversion
46  * @param[out] r Integer resulting from the conversion
47  * @param[in] n Size of the integer, in words
48  * @param[in] input Octet string to be converted
49  * @param[in] length Length of the octet string
50  * @param[in] format Input format
51  * @return Error code
52  **/
53 
54 error_t ecScalarImport(uint32_t *r, uint_t n, const uint8_t *input,
55  size_t length, EcScalarFormat format)
56 {
57  error_t error;
58  uint_t i;
59  uint32_t temp;
60 
61  //Initialize status code
62  error = NO_ERROR;
63 
64  //Check input format
65  if(format == EC_SCALAR_FORMAT_LITTLE_ENDIAN)
66  {
67  //Skip trailing zeroes
68  while(length > 0 && input[length - 1] == 0)
69  {
70  length--;
71  }
72 
73  //Make sure the integer is large enough
74  if(length <= (n * 4))
75  {
76  //Clear the contents of the integer
77  for(i = 0; i < n; i++)
78  {
79  r[i] = 0;
80  }
81 
82  //Import data
83  for(i = 0; i < length; i++, input++)
84  {
85  temp = *input & 0xFF;
86  r[i / 4] |= temp << ((i % 4) * 8);
87  }
88  }
89  else
90  {
91  //Report an error
92  error = ERROR_INVALID_LENGTH;
93  }
94  }
95  else if(format == EC_SCALAR_FORMAT_BIG_ENDIAN)
96  {
97  //Skip leading zeroes
98  while(length > 1 && *input == 0)
99  {
100  input++;
101  length--;
102  }
103 
104  //Make sure the integer is large enough
105  if(length <= (n * 4))
106  {
107  //Clear the contents of the integer
108  for(i = 0; i < n; i++)
109  {
110  r[i] = 0;
111  }
112 
113  //Start from the least significant byte
114  input += length - 1;
115 
116  //Import data
117  for(i = 0; i < length; i++, input--)
118  {
119  temp = *input & 0xFF;
120  r[i / 4] |= temp << ((i % 4) * 8);
121  }
122  }
123  else
124  {
125  //Report an error
126  error = ERROR_INVALID_LENGTH;
127  }
128  }
129  else
130  {
131  //Report an error
132  error = ERROR_INVALID_PARAMETER;
133  }
134 
135  //Return status code
136  return error;
137 }
138 
139 
140 /**
141  * @brief Integer to octet string conversion
142  * @param[in] a Integer to be converted
143  * @param[in] n Size of the integer, in words
144  * @param[out] output Octet string resulting from the conversion
145  * @param[in] length Intended length of the resulting octet string
146  * @param[in] format Output format
147  * @return Error code
148  **/
149 
150 error_t ecScalarExport(const uint32_t *a, uint_t n, uint8_t *output,
151  size_t length, EcScalarFormat format)
152 {
153  error_t error;
154  uint_t i;
155  uint_t k;
156  uint32_t temp;
157 
158  //Initialize status code
159  error = NO_ERROR;
160 
161  //Check input format
162  if(format == EC_SCALAR_FORMAT_LITTLE_ENDIAN)
163  {
164  //Get the actual length in bytes
165  k = ecScalarGetByteLength(a, n);
166 
167  //Make sure the output buffer is large enough
168  if(k <= length)
169  {
170  //Clear output buffer
171  osMemset(output, 0, length);
172 
173  //Export data
174  for(i = 0; i < k; i++, output++)
175  {
176  temp = a[i / 4] >> ((i % 4) * 8);
177  *output = temp & 0xFF;
178  }
179  }
180  else
181  {
182  //Report an error
183  error = ERROR_INVALID_LENGTH;
184  }
185  }
186  else if(format == EC_SCALAR_FORMAT_BIG_ENDIAN)
187  {
188  //Get the actual length in bytes
189  k = ecScalarGetByteLength(a, n);
190 
191  //Make sure the output buffer is large enough
192  if(k <= length)
193  {
194  //Clear output buffer
195  osMemset(output, 0, length);
196 
197  //Point to the least significant word
198  output += length - 1;
199 
200  //Export data
201  for(i = 0; i < k; i++, output--)
202  {
203  temp = a[i / 4] >> ((i % 4) * 8);
204  *output = temp & 0xFF;
205  }
206  }
207  else
208  {
209  //Report an error
210  error = ERROR_INVALID_LENGTH;
211  }
212  }
213  else
214  {
215  //Report an error
216  error = ERROR_INVALID_PARAMETER;
217  }
218 
219  //Return status code
220  return error;
221 }
222 
223 
224 /**
225  * @brief Get the actual length in bytes
226  * @param[in] a Pointer to an integer
227  * @param[in] n Size of the integer, in words
228  * @return The actual byte count
229  **/
230 
232 {
233  uint_t k;
234  uint32_t m;
235 
236  //Check the size of the integer
237  if(n == 0)
238  return 0;
239 
240  //Start from the most significant word
241  for(k = n - 1; k > 0; k--)
242  {
243  //Loop as long as the current word is zero
244  if(a[k] != 0)
245  {
246  break;
247  }
248  }
249 
250  //Get the current word
251  m = a[k];
252  //Convert the length to a byte count
253  k *= 4;
254 
255  //Adjust the byte count
256  for(; m != 0; m >>= 8)
257  {
258  k++;
259  }
260 
261  //Return the actual length in bytes
262  return k;
263 }
264 
265 
266 /**
267  * @brief Get the actual length in bits
268  * @param[in] a Pointer to an integer
269  * @param[in] n Size of the integer, in words
270  * @return The actual bit count
271  **/
272 
274 {
275  uint_t k;
276  uint32_t m;
277 
278  //Check the size of the integer
279  if(n == 0)
280  return 0;
281 
282  //Start from the most significant word
283  for(k = n - 1; k > 0; k--)
284  {
285  //Loop as long as the current word is zero
286  if(a[k] != 0)
287  {
288  break;
289  }
290  }
291 
292  //Get the current word
293  m = a[k];
294  //Convert the length to a bit count
295  k *= 32;
296 
297  //Adjust the bit count
298  for(; m != 0; m >>= 1)
299  {
300  k++;
301  }
302 
303  //Return the actual length in bits
304  return k;
305 }
306 
307 
308 /**
309  * @brief Get the bit value at the specified index
310  * @param[in] a Pointer to an integer
311  * @param[in] index Position where to read the bit
312  * @return The actual bit value
313  **/
314 
315 uint32_t ecScalarGetBitValue(const uint32_t *a, int_t index)
316 {
317  //Valid index?
318  if(index >= 0)
319  {
320  return (a[index / 32] >> (index % 32)) & 1;
321  }
322  else
323  {
324  return 0;
325  }
326 }
327 
328 
329 /**
330  * @brief Compare integers
331  * @param[in] a Pointer to the first integer
332  * @param[in] b Pointer to the second integer
333  * @param[in] n Size of the integers, in words
334  * @return Comparison result
335  **/
336 
337 int_t ecScalarComp(const uint32_t *a, const uint32_t *b, uint_t n)
338 {
339  int_t i;
340  int_t res;
341 
342  //Initialize variable
343  res = 0;
344 
345  //Compare A and B
346  for(i = n - 1; i >= 0 && res == 0; i--)
347  {
348  if(a[i] > b[i])
349  {
350  res = 1;
351  }
352  else if(a[i] < b[i])
353  {
354  res = -1;
355  }
356  else
357  {
358  }
359  }
360 
361  //Return comparison result
362  return res;
363 }
364 
365 
366 /**
367  * @brief Compare integers
368  * @param[in] a Pointer to the first integer
369  * @param[in] b An integer such as 0 <= B < (2^32 - 1)
370  * @param[in] n Size of the integers, in words
371  * @return Comparison result
372  **/
373 
374 int_t ecScalarCompInt(const uint32_t *a, uint32_t b, uint_t n)
375 {
376  int_t i;
377  int_t res;
378 
379  //Initialize variable
380  res = 0;
381 
382  //Compare the upper words
383  for(i = n - 1; i > 0 && res == 0; i--)
384  {
385  if(a[i] > 0)
386  {
387  res = 1;
388  }
389  }
390 
391  //Compare the lower word
392  if(res == 0)
393  {
394  if(a[0] > b)
395  {
396  res = 1;
397  }
398  else if(a[0] < b)
399  {
400  res = -1;
401  }
402  else
403  {
404  }
405  }
406 
407  //Return comparison result
408  return res;
409 }
410 
411 
412 /**
413  * @brief Test if two integers are equal
414  * @param[in] a Pointer to the first integer
415  * @param[in] b Pointer to the second integer
416  * @param[in] n Size of the integers, in words
417  * @return The function returns 1 if the A = B, else 0
418  **/
419 
420 uint32_t ecScalarTestEqual(const uint32_t *a, const uint32_t *b, uint_t n)
421 {
422  //Perform comparison
423  return ecScalarTestNotEqual(a, b, n) ^ 1;
424 }
425 
426 
427 /**
428  * @brief Test if two integers are equal
429  * @param[in] a Pointer to the first integer
430  * @param[in] b An integer such as 0 <= B < (2^32 - 1)
431  * @param[in] n Size of the integers, in words
432  * @return The function returns 1 if the A = B, else 0
433  **/
434 
435 uint32_t ecScalarTestEqualInt(const uint32_t *a, uint32_t b, uint_t n)
436 {
437  //Perform comparison
438  return ecScalarTestNotEqualInt(a, b, n) ^ 1;
439 }
440 
441 
442 /**
443  * @brief Test if two integers are different
444  * @param[in] a Pointer to the first integer
445  * @param[in] b Pointer to the second integer
446  * @param[in] n Size of the integers, in words
447  * @return The function returns 1 if the A != B, else 0
448  **/
449 
450 uint32_t ecScalarTestNotEqual(const uint32_t *a, const uint32_t *b, uint_t n)
451 {
452  uint_t i;
453  uint32_t mask;
454 
455  //Initialize mask
456  mask = 0;
457 
458  //Compare A and B
459  for(i = 0; i < n; i++)
460  {
461  //Constant time implementation
462  mask |= a[i] ^ b[i];
463  }
464 
465  //Return 1 if A != B, else 0
466  return ((uint32_t) (mask | (~mask + 1))) >> 31;
467 }
468 
469 
470 /**
471  * @brief Test if two integers are different
472  * @param[in] a Pointer to the first integer
473  * @param[in] b An integer such as 0 <= B < (2^32 - 1)
474  * @param[in] n Size of the integers, in words
475  * @return The function returns 1 if the A != B, else 0
476  **/
477 
478 uint32_t ecScalarTestNotEqualInt(const uint32_t *a, uint32_t b, uint_t n)
479 {
480  uint_t i;
481  uint32_t mask;
482 
483  //Initialize mask
484  mask = a[0] ^ b;
485 
486  //Compare A and B
487  for(i = 1; i < n; i++)
488  {
489  //Constant time implementation
490  mask |= a[i];
491  }
492 
493  //Return 1 if A != B, else 0
494  return ((uint32_t) (mask | (~mask + 1))) >> 31;
495 }
496 
497 
498 /**
499  * @brief Set integer value
500  * @param[out] a Pointer to the integer to be initialized
501  * @param[in] b An integer such as 0 <= B < (2^32 - 1)
502  * @param[in] n Size of the integer A, in words
503  **/
504 
505 void ecScalarSetInt(uint32_t *a, uint32_t b, uint_t n)
506 {
507  uint_t i;
508 
509  //Set the value of the least significant word
510  a[0] = b;
511 
512  //Initialize the rest of the integer
513  for(i = 1; i < n; i++)
514  {
515  a[i] = 0;
516  }
517 }
518 
519 
520 /**
521  * @brief Copy an integer
522  * @param[out] a Pointer to the destination integer
523  * @param[in] b Pointer to the source integer
524  * @param[in] n Size of the integers, in words
525  **/
526 
527 void ecScalarCopy(uint32_t *a, const uint32_t *b, uint_t n)
528 {
529  uint_t i;
530 
531  //Copy the value of the integer
532  for(i = 0; i < n; i++)
533  {
534  a[i] = b[i];
535  }
536 }
537 
538 
539 /**
540  * @brief Conditional swap
541  * @param[in,out] a Pointer to the first integer
542  * @param[in,out] b Pointer to the second integer
543  * @param[in] c Condition variable
544  * @param[in] n Size of the integers, in words
545  **/
546 
547 void ecScalarSwap(uint32_t *a, uint32_t *b, uint32_t c, uint_t n)
548 {
549  uint_t i;
550  uint32_t mask;
551  uint32_t dummy;
552 
553  //The mask is the all-1 or all-0 word
554  mask = ~c + 1;
555 
556  //Conditional swap
557  for(i = 0; i < n; i++)
558  {
559  //Constant time implementation
560  dummy = mask & (a[i] ^ b[i]);
561  a[i] ^= dummy;
562  b[i] ^= dummy;
563  }
564 }
565 
566 
567 /**
568  * @brief Select an integer
569  * @param[out] r Pointer to the destination integer
570  * @param[in] a Pointer to the first source integer
571  * @param[in] b Pointer to the second source integer
572  * @param[in] c Condition variable
573  * @param[in] n Size of the integers, in words
574  **/
575 
576 void ecScalarSelect(uint32_t *r, const uint32_t *a, const uint32_t *b,
577  uint32_t c, uint_t n)
578 {
579  uint_t i;
580  uint32_t mask;
581 
582  //The mask is the all-1 or all-0 word
583  mask = c - 1;
584 
585  //Select between A and B
586  for(i = 0; i < n; i++)
587  {
588  //Constant time implementation
589  r[i] = (a[i] & mask) | (b[i] & ~mask);
590  }
591 }
592 
593 
594 /**
595  * @brief Generate a random value
596  * @param[in] curve Elliptic curve parameters
597  * @param[out] r Random integer in range such as 1 < R < q - 1
598  * @param[in] prngAlgo PRNG algorithm
599  * @param[in] prngContext Pointer to the PRNG context
600  * @return Error code
601  **/
602 
603 error_t ecScalarRand(const EcCurve *curve, uint32_t *r,
604  const PrngAlgo *prngAlgo, void *prngContext)
605 {
606  error_t error;
607  uint_t n;
608  uint32_t a[EC_MAX_ORDER_SIZE];
609  uint32_t t[EC_MAX_ORDER_SIZE + 2];
610 
611  //Check parameters
612  if(prngAlgo != NULL && prngContext != NULL)
613  {
614  //Get the length of the order, in words
615  n = (curve->orderSize + 31) / 32;
616 
617  //Generate extra random bits so that the bias produced by the modular
618  //reduction is negligible
619  error = prngAlgo->read(prngContext, (uint8_t *) t,
620  (n + 2) * sizeof(uint32_t));
621 
622  //Check status code
623  if(!error)
624  {
625  //Compute r = (t mod (q - 2)) + 1
626  ecScalarSubInt(a, curve->q, 2, n);
627  ecScalarMod(r, t, n + 2, a, n);
628  ecScalarAddInt(r, r, 1, n);
629  }
630  }
631  else
632  {
633  //Report an error
634  error = ERROR_INVALID_PARAMETER;
635  }
636 
637  //Return status code
638  return error;
639 }
640 
641 
642 /**
643  * @brief Addition of two integers
644  * @param[out] r Resulting integer R = A + B
645  * @param[in] a An integer such as 0 <= A < (2^32)^n
646  * @param[in] b An integer such as 0 <= B < (2^32)^n
647  * @param[in] n Size of the operands, in words
648  * @return Value of the carry bit
649  **/
650 
651 uint32_t ecScalarAdd(uint32_t *r, const uint32_t *a, const uint32_t *b,
652  uint_t n)
653 {
654  uint_t i;
655  uint64_t temp;
656 
657  //Compute R = A + B
658  for(temp = 0, i = 0; i < n; i++)
659  {
660  temp += a[i];
661  temp += b[i];
662  r[i] = (uint32_t) temp;
663  temp >>= 32;
664  }
665 
666  //Return the value of the carry bit
667  return temp & 1;
668 }
669 
670 
671 /**
672  * @brief Addition of two integers
673  * @param[out] r Resulting integer R = A + B
674  * @param[in] a An integer such as 0 <= A < (2^32)^n
675  * @param[in] b An integer such as 0 <= B < (2^32 - 1)
676  * @param[in] n Size of the operands, in words
677  * @return Value of the carry bit
678  **/
679 
680 uint32_t ecScalarAddInt(uint32_t *r, const uint32_t *a, uint32_t b, uint_t n)
681 {
682  uint_t i;
683  uint64_t temp;
684 
685  //Compute R = A + B
686  for(temp = b, i = 0; i < n; i++)
687  {
688  temp += a[i];
689  r[i] = (uint32_t) temp;
690  temp >>= 32;
691  }
692 
693  //Return the value of the carry bit
694  return temp & 1;
695 }
696 
697 
698 /**
699  * @brief Subtraction of two integers
700  * @param[out] r Resulting integer R = A - B
701  * @param[in] a An integer such as 0 <= A < (2^32)^n
702  * @param[in] b An integer such as 0 <= B < (2^32)^n
703  * @param[in] n Size of the operands, in words
704  * @return 1 if the result is negative, else 0
705  **/
706 
707 uint32_t ecScalarSub(uint32_t *r, const uint32_t *a, const uint32_t *b,
708  uint_t n)
709 {
710  uint_t i;
711  int64_t temp;
712 
713  //Compute R = A - B
714  for(temp = 0, i = 0; i < n; i++)
715  {
716  temp += a[i];
717  temp -= b[i];
718  r[i] = (uint32_t) temp;
719  temp >>= 32;
720  }
721 
722  //Return 1 if the result of the subtraction is negative
723  return temp & 1;
724 }
725 
726 
727 /**
728  * @brief Subtraction of two integers
729  * @param[out] r Resulting integer R = A - B
730  * @param[in] a An integer such as 0 <= A < (2^32)^n
731  * @param[in] b An integer such as 0 <= B < (2^32 - 1)
732  * @param[in] n Size of the operands, in words
733  * @return 1 if the result is negative, else 0
734  **/
735 
736 uint32_t ecScalarSubInt(uint32_t *r, const uint32_t *a, uint32_t b, uint_t n)
737 {
738  uint_t i;
739  int64_t temp;
740 
741  //Initialize variable
742  temp = b;
743 
744  //Compute R = A - B
745  for(temp = -temp, i = 0; i < n; i++)
746  {
747  temp += a[i];
748  r[i] = (uint32_t) temp;
749  temp >>= 32;
750  }
751 
752  //Return 1 if the result of the subtraction is negative
753  return temp & 1;
754 }
755 
756 
757 /**
758  * @brief Multiplication of two integers
759  * @param[out] rl Low part of the result R = (A * B) mod (2^32)^n
760  * @param[out] rh High part of the result R = (A * B) / (2^32)^n
761  * @param[in] a An integer such as 0 <= A < (2^32)^n
762  * @param[in] b An integer such as 0 <= B < (2^32)^n
763  * @param[in] n Size of the operands, in words
764  **/
765 
766 __weak_func void ecScalarMul(uint32_t *rl, uint32_t *rh, const uint32_t *a,
767  const uint32_t *b, uint_t n)
768 {
769  uint_t i;
770  uint_t j;
771  uint64_t c;
772  uint64_t temp;
773 
774  //Initialize variables
775  temp = 0;
776  c = 0;
777 
778  //Compute the low part of the multiplication
779  for(i = 0; i < n; i++)
780  {
781  //The Comba's algorithm computes the products, column by column
782  for(j = 0; j <= i; j++)
783  {
784  temp += (uint64_t) a[j] * b[i - j];
785  c += temp >> 32;
786  temp &= 0xFFFFFFFF;
787  }
788 
789  //At the bottom of each column, the final result is written to memory
790  if(rl != NULL)
791  {
792  rl[i] = temp & 0xFFFFFFFF;
793  }
794 
795  //Propagate the carry upwards
796  temp = c & 0xFFFFFFFF;
797  c >>= 32;
798  }
799 
800  //Check whether the high part of the multiplication should be calculated
801  if(rh != NULL)
802  {
803  //Compute the high part of the multiplication
804  for(i = n; i < (2 * n); i++)
805  {
806  //The Comba's algorithm computes the products, column by column
807  for(j = i + 1 - n; j < n; j++)
808  {
809  temp += (uint64_t) a[j] * b[i - j];
810  c += temp >> 32;
811  temp &= 0xFFFFFFFF;
812  }
813 
814  //At the bottom of each column, the final result is written to memory
815  rh[i - n] = (uint32_t) temp;
816 
817  //Propagate the carry upwards
818  temp = c & 0xFFFFFFFF;
819  c >>= 32;
820  }
821  }
822 }
823 
824 
825 /**
826  * @brief Squaring operation
827  * @param[out] r Result R = A ^ 2
828  * @param[in] a An integer such as 0 <= A < (2^32)^n
829  * @param[in] n Size of the integer A, in words
830  **/
831 
832 __weak_func void ecScalarSqr(uint32_t *r, const uint32_t *a, uint_t n)
833 {
834  uint_t i;
835  uint_t j;
836  uint64_t b;
837  uint64_t c;
838  uint64_t temp;
839 
840  //Initialize variables
841  temp = 0;
842  c = 0;
843 
844  //Comba's method is used to perform multiplication
845  for(i = 0; i < (2 * n); i++)
846  {
847  //Calculate lower bound
848  j = (i < n) ? 0 : (i + 1 - n);
849 
850  //The algorithm computes the products, column by column
851  for(; j <= i && j <= (i - j); j++)
852  {
853  b = (uint64_t) a[j] * a[i - j];
854  temp += b;
855  c += temp >> 32;
856  temp &= 0xFFFFFFFF;
857 
858  if(j < (i - j))
859  {
860  temp += b;
861  c += temp >> 32;
862  temp &= 0xFFFFFFFF;
863  }
864  }
865 
866  //At the bottom of each column, the final result is written to memory
867  r[i] = temp & 0xFFFFFFFF;
868 
869  //Propagate the carry upwards
870  temp = c & 0xFFFFFFFF;
871  c >>= 32;
872  }
873 }
874 
875 
876 /**
877  * @brief Left shift operation
878  * @param[out] r Result R = A << k
879  * @param[in] a An integer such as 0 <= A < (2^32)^n
880  * @param[in] k The number of bits to shift
881  * @param[in] n Size of the integer A, in words
882  **/
883 
884 void ecScalarShiftLeft(uint32_t *r, const uint32_t *a, uint_t k, uint_t n)
885 {
886  uint_t i;
887 
888  //Number of 32-bit words to shift
889  uint_t k1 = k / 32;
890  //Number of bits to shift
891  uint_t k2 = k % 32;
892 
893  //First, shift words
894  if(k1 > 0)
895  {
896  //Process the most significant words
897  for(i = n - 1; i >= k1; i--)
898  {
899  r[i] = a[i - k1];
900  }
901 
902  //Fill the rest with zeroes
903  for(i = 0; i < k1; i++)
904  {
905  r[i] = 0;
906  }
907  }
908  else
909  {
910  //Copy words
911  for(i = 0; i < n; i++)
912  {
913  r[i] = a[i];
914  }
915  }
916 
917  //Then shift bits
918  if(k2 > 0)
919  {
920  //Process the most significant words
921  for(i = n - 1; i >= 1; i--)
922  {
923  r[i] = (r[i] << k2) | (r[i - 1] >> (32 - k2));
924  }
925 
926  //The least significant word requires a special handling
927  r[0] <<= k2;
928  }
929 }
930 
931 
932 /**
933  * @brief Right shift operation
934  * @param[out] r Result R = A >> k
935  * @param[in] a An integer such as 0 <= A < (2^32)^n
936  * @param[in] k The number of bits to shift
937  * @param[in] n Size of the integer A, in words
938  **/
939 
940 void ecScalarShiftRight(uint32_t *r, const uint32_t *a, uint_t k, uint_t n)
941 {
942  uint_t i;
943 
944  //Number of 32-bit words to shift
945  uint_t k1 = k / 32;
946  //Number of bits to shift
947  uint_t k2 = k % 32;
948 
949  //Check parameters
950  if(k1 >= n)
951  {
952  //Clear words
953  for(i = 0; i < n; i++)
954  {
955  r[i] = 0;
956  }
957  }
958  else
959  {
960  //First, shift words
961  if(k1 > 0)
962  {
963  //Process the least significant words
964  for(i = 0; i < (n - k1); i++)
965  {
966  r[i] = a[i + k1];
967  }
968 
969  //Fill the rest with zeroes
970  for(i = n - k1; i < n; i++)
971  {
972  r[i] = 0;
973  }
974  }
975  else
976  {
977  //Copy words
978  for(i = 0; i < n; i++)
979  {
980  r[i] = a[i];
981  }
982  }
983 
984  //Then shift bits
985  if(k2 > 0)
986  {
987  //Process the least significant words
988  for(i = 0; i < (n - k1 - 1); i++)
989  {
990  r[i] = (r[i] >> k2) | (r[i + 1] << (32 - k2));
991  }
992 
993  //The most significant word requires a special handling
994  r[i] >>= k2;
995  }
996  }
997 }
998 
999 
1000 /**
1001  * @brief Modulo operation
1002  * @param[out] r Resulting integer R = A mod P
1003  * @param[in] a An integer such as 0 <= A < (2^32)^m
1004  * @param[in] m Size of integer A, in words
1005  * @param[in] p An integer such as 0 <= P < (2^32)^n
1006  * @param[in] n Size of integers P and R, in words
1007  **/
1008 
1009 void ecScalarMod(uint32_t *r, const uint32_t *a, uint_t m, const uint32_t *p,
1010  uint_t n)
1011 {
1012  uint_t i;
1013  uint_t k;
1014  uint32_t c;
1015  uint32_t u[EC_MAX_ORDER_SIZE + 2];
1016  uint32_t v[EC_MAX_ORDER_SIZE + 2];
1017  uint32_t w[EC_MAX_ORDER_SIZE + 2];
1018 
1019  //Get the length of P, in bits
1020  k = ecScalarGetBitLength(p, n);
1021 
1022  //Check the length of P
1023  if(k <= (m * 32))
1024  {
1025  //Set U = A
1026  ecScalarSetInt(u, 0, m);
1027  ecScalarCopy(u, a, m);
1028 
1029  //Pad P with zeroes on the right
1030  ecScalarSetInt(v, 0, m);
1031  ecScalarCopy(v, p, n);
1032  ecScalarShiftLeft(v, v, (m * 32) - k, m);
1033 
1034  //Compute R = A mod P
1035  for(i = 0; i <= (m * 32) - k; i++)
1036  {
1037  c = ecScalarSub(w, u, v, m);
1038  ecScalarSelect(u, w, u, c, m);
1039  ecScalarShiftRight(v, v, 1, m);
1040  }
1041 
1042  //Copy the resulting integer
1043  ecScalarCopy(r, u, n);
1044  }
1045  else
1046  {
1047  //Set R = A
1048  ecScalarSetInt(r, 0, n);
1049  ecScalarCopy(r, a, m);
1050  }
1051 }
1052 
1053 
1054 /**
1055  * @brief Modular addition
1056  * @param[in] curve Elliptic curve parameters
1057  * @param[out] r Resulting integer R = (A + B) mod q
1058  * @param[in] a An integer such as 0 <= A < q
1059  * @param[in] b An integer such as 0 <= B < q
1060  **/
1061 
1062 void ecScalarAddMod(const EcCurve *curve, uint32_t *r, const uint32_t *a,
1063  const uint32_t *b)
1064 {
1065  uint_t qLen;
1066  uint32_t c;
1067  uint32_t u[EC_MAX_ORDER_SIZE + 1];
1068  uint32_t v[EC_MAX_ORDER_SIZE + 1];
1069 
1070  //Get the length of the order, in words
1071  qLen = (curve->orderSize + 31) / 32;
1072 
1073  //Compute R = (A + B) mod q
1074  u[qLen] = ecScalarAdd(u, a, b, qLen);
1075  c = ecScalarSub(v, u, curve->q, qLen + 1);
1076  ecScalarSelect(r, v, u, c, qLen);
1077 }
1078 
1079 
1080 /**
1081  * @brief Modular subtraction
1082  * @param[in] curve Elliptic curve parameters
1083  * @param[out] r Resulting integer R = (A - B) mod q
1084  * @param[in] a An integer such as 0 <= A < q
1085  * @param[in] b An integer such as 0 <= B < q
1086  **/
1087 
1088 void ecScalarSubMod(const EcCurve *curve, uint32_t *r, const uint32_t *a,
1089  const uint32_t *b)
1090 {
1091  uint_t qLen;
1092  uint32_t c;
1093  uint32_t u[EC_MAX_ORDER_SIZE];
1094 
1095  //Get the length of the order, in words
1096  qLen = (curve->orderSize + 31) / 32;
1097 
1098  //Compute R = (A - B) mod q
1099  c = ecScalarSub(r, a, b, qLen);
1100  ecScalarAdd(u, r, curve->q, qLen);
1101  ecScalarSelect(r, r, u, c, qLen);
1102 }
1103 
1104 
1105 /**
1106  * @brief Modular multiplication
1107  * @param[in] curve Elliptic curve parameters
1108  * @param[out] r Resulting integer R = (A * B) mod q
1109  * @param[in] a An integer such as 0 <= A < q
1110  * @param[in] b An integer such as 0 <= B < q
1111  **/
1112 
1113 __weak_func void ecScalarMulMod(const EcCurve *curve, uint32_t *r,
1114  const uint32_t *a, const uint32_t *b)
1115 {
1116  uint_t qLen;
1117  uint32_t u[EC_MAX_ORDER_SIZE * 2];
1118 
1119  //Get the length of the order, in words
1120  qLen = (curve->orderSize + 31) / 32;
1121 
1122  //Compute R = (A * B) mod q
1123  ecScalarMul(u, u + qLen, a, b, qLen);
1124  curve->scalarMod(curve, r, u);
1125 }
1126 
1127 
1128 /**
1129  * @brief Modular squaring
1130  * @param[in] curve Elliptic curve parameters
1131  * @param[out] r Resulting integer R = A^2 mod q
1132  * @param[in] a An integer such as 0 <= A < q
1133  **/
1134 
1135 __weak_func void ecScalarSqrMod(const EcCurve *curve, uint32_t *r,
1136  const uint32_t *a)
1137 {
1138  uint_t qLen;
1139  uint32_t u[EC_MAX_ORDER_SIZE * 2];
1140 
1141  //Get the length of the order, in words
1142  qLen = (curve->orderSize + 31) / 32;
1143 
1144  //Compute R = (A ^ 2) mod q
1145  ecScalarSqr(u, a, qLen);
1146  curve->scalarMod(curve, r, u);
1147 }
1148 
1149 
1150 /**
1151  * @brief Raise an integer to power 2^n
1152  * @param[in] curve Elliptic curve parameters
1153  * @param[out] r Resulting integer R = (A ^ (2^n)) mod q
1154  * @param[in] a An integer such as 0 <= A < q
1155  * @param[in] n An integer such as n >= 1
1156  **/
1157 
1158 void ecScalarPwr2Mod(const EcCurve *curve, uint32_t *r, const uint32_t *a,
1159  uint_t n)
1160 {
1161  uint_t i;
1162 
1163  //Pre-compute (A ^ 2) mod q
1164  ecScalarSqrMod(curve, r, a);
1165 
1166  //Compute R = (A ^ (2^n)) mod q
1167  for(i = 1; i < n; i++)
1168  {
1169  ecScalarSqrMod(curve, r, r);
1170  }
1171 }
1172 
1173 
1174 /**
1175  * @brief Modular inversion
1176  * @param[in] curve Elliptic curve parameters
1177  * @param[out] r Resulting integer R = A^-1 mod q
1178  * @param[in] a An integer such as 0 <= A < q
1179  **/
1180 
1181 void ecScalarInvMod(const EcCurve *curve, uint32_t *r,
1182  const uint32_t *a)
1183 {
1184  //Curve-specific implementation?
1185  if(curve->scalarInv != NULL)
1186  {
1187  //Compute R = A^-1 mod q
1188  curve->scalarInv(curve, r, a);
1189  }
1190  else
1191  {
1192  int_t i;
1193  uint_t qLen;
1194  uint32_t q[EC_MAX_ORDER_SIZE];
1195  uint32_t u[EC_MAX_ORDER_SIZE];
1196 
1197  //Get the length of the order, in words
1198  qLen = (curve->orderSize + 31) / 32;
1199 
1200  //Pre-compute q' = q - 2
1201  ecScalarSubInt(q, curve->q, 2, qLen);
1202 
1203  //Let U = 1
1204  ecScalarSetInt(u, 1, qLen);
1205 
1206  //Since q is prime, the multiplicative inverse of A modulo p can be found
1207  //using Fermat's little theorem
1208  for(i = curve->orderSize - 1; i >= 0; i--)
1209  {
1210  //Calculate U = U^2
1211  ecScalarSqrMod(curve, u, u);
1212 
1213  //Check the value of q'(i)
1214  if(((q[i / 32] >> (i % 32)) & 1) != 0)
1215  {
1216  //Calculate U = U * A
1217  ecScalarMulMod(curve, u, u, a);
1218  }
1219  }
1220 
1221  //Copy the resulting value
1222  ecScalarCopy(r, u, qLen);
1223  }
1224 }
1225 
1226 
1227 /**
1228  * @brief Modular addition
1229  * @param[in] curve Elliptic curve parameters
1230  * @param[out] r Resulting integer R = (A + B) mod p
1231  * @param[in] a An integer such as 0 <= A < p
1232  * @param[in] b An integer such as 0 <= B < p
1233  **/
1234 
1235 __weak_func void ecFieldAddMod(const EcCurve *curve, uint32_t *r,
1236  const uint32_t *a, const uint32_t *b)
1237 {
1238  uint_t pLen;
1239  uint32_t c;
1240  uint32_t u[EC_MAX_MODULUS_SIZE + 1];
1241  uint32_t v[EC_MAX_MODULUS_SIZE + 1];
1242 
1243  //Get the length of the modulus, in words
1244  pLen = (curve->fieldSize + 31) / 32;
1245 
1246  //Compute R = (A + B) mod p
1247  u[pLen] = ecScalarAdd(u, a, b, pLen);
1248  c = ecScalarSub(v, u, curve->p, pLen + 1);
1249  ecScalarSelect(r, v, u, c, pLen);
1250 }
1251 
1252 
1253 /**
1254  * @brief Modular subtraction
1255  * @param[in] curve Elliptic curve parameters
1256  * @param[out] r Resulting integer R = (A - B) mod p
1257  * @param[in] a An integer such as 0 <= A < p
1258  * @param[in] b An integer such as 0 <= B < p
1259  **/
1260 
1261 __weak_func void ecFieldSubMod(const EcCurve *curve, uint32_t *r,
1262  const uint32_t *a, const uint32_t *b)
1263 {
1264  uint_t pLen;
1265  uint32_t c;
1266  uint32_t u[EC_MAX_MODULUS_SIZE];
1267 
1268  //Get the length of the modulus, in words
1269  pLen = (curve->fieldSize + 31) / 32;
1270 
1271  //Compute R = (A - B) mod p
1272  c = ecScalarSub(r, a, b, pLen);
1273  ecScalarAdd(u, r, curve->p, pLen);
1274  ecScalarSelect(r, r, u, c, pLen);
1275 }
1276 
1277 
1278 /**
1279  * @brief Modular multiplication
1280  * @param[in] curve Elliptic curve parameters
1281  * @param[out] r Resulting integer R = (A * B) mod p
1282  * @param[in] a An integer such as 0 <= A < p
1283  * @param[in] b An integer such as 0 <= B < p
1284  **/
1285 
1286 __weak_func void ecFieldMulMod(const EcCurve *curve, uint32_t *r,
1287  const uint32_t *a, const uint32_t *b)
1288 {
1289  uint_t pLen;
1290  uint32_t u[EC_MAX_MODULUS_SIZE * 2];
1291 
1292  //Get the length of the modulus, in words
1293  pLen = (curve->fieldSize + 31) / 32;
1294 
1295  //Compute R = (A * B) mod p
1296  ecScalarMul(u, u + pLen, a, b, pLen);
1297  curve->fieldMod(curve, r, u);
1298 }
1299 
1300 
1301 /**
1302  * @brief Modular squaring
1303  * @param[in] curve Elliptic curve parameters
1304  * @param[out] r Resulting integer R = A^2 mod p
1305  * @param[in] a An integer such as 0 <= A < p
1306  **/
1307 
1308 __weak_func void ecFieldSqrMod(const EcCurve *curve, uint32_t *r,
1309  const uint32_t *a)
1310 {
1311  uint_t pLen;
1312  uint32_t u[EC_MAX_MODULUS_SIZE * 2];
1313 
1314  //Get the length of the modulus, in words
1315  pLen = (curve->fieldSize + 31) / 32;
1316 
1317  //Compute R = (A ^ 2) mod p
1318  ecScalarSqr(u, a, pLen);
1319  curve->fieldMod(curve, r, u);
1320 }
1321 
1322 
1323 /**
1324  * @brief Raise an integer to power 2^n
1325  * @param[in] curve Elliptic curve parameters
1326  * @param[out] r Resulting integer R = (A ^ (2^n)) mod p
1327  * @param[in] a An integer such as 0 <= A < p
1328  * @param[in] n An integer such as n >= 1
1329  **/
1330 
1331 void ecFieldPwr2Mod(const EcCurve *curve, uint32_t *r, const uint32_t *a,
1332  uint_t n)
1333 {
1334  uint_t i;
1335 
1336  //Pre-compute (A ^ 2) mod p
1337  ecFieldSqrMod(curve, r, a);
1338 
1339  //Compute R = (A ^ (2^n)) mod p
1340  for(i = 1; i < n; i++)
1341  {
1342  ecFieldSqrMod(curve, r, r);
1343  }
1344 }
1345 
1346 
1347 /**
1348  * @brief Modular inversion
1349  * @param[in] curve Elliptic curve parameters
1350  * @param[out] r Resulting integer R = A^-1 mod p
1351  * @param[in] a An integer such as 0 <= A < p
1352  **/
1353 
1354 void ecFieldInvMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
1355 {
1356  //Curve-specific implementation?
1357  if(curve->fieldInv != NULL)
1358  {
1359  //Compute R = A^-1 mod p
1360  curve->fieldInv(curve, r, a);
1361  }
1362  else
1363  {
1364  int_t i;
1365  uint_t pLen;
1366  uint32_t p[EC_MAX_MODULUS_SIZE];
1367  uint32_t u[EC_MAX_MODULUS_SIZE];
1368 
1369  //Get the length of the modulus, in words
1370  pLen = (curve->fieldSize + 31) / 32;
1371 
1372  //Pre-compute p' = p - 2
1373  ecScalarSubInt(p, curve->p, 2, pLen);
1374 
1375  //Let U = 1
1376  ecScalarSetInt(u, 1, pLen);
1377 
1378  //Since p is prime, the multiplicative inverse of A modulo p can be found
1379  //using Fermat's little theorem
1380  for(i = curve->fieldSize - 1; i >= 0; i--)
1381  {
1382  //Calculate U = U^2
1383  ecFieldSqrMod(curve, u, u);
1384 
1385  //Check the value of p'(i)
1386  if(((p[i / 32] >> (i % 32)) & 1) != 0)
1387  {
1388  ecFieldMulMod(curve, u, u, a);
1389  }
1390  }
1391 
1392  //Copy the resulting value
1393  ecScalarCopy(r, u, pLen);
1394  }
1395 }
1396 
1397 
1398 /**
1399  * @brief Reduce non-canonical value
1400  * @param[in] curve Elliptic curve parameters
1401  * @param[out] r Resulting integer R = A mod p
1402  * @param[in] a Input integer
1403  **/
1404 
1405 void ecFieldCanonicalize(const EcCurve *curve, uint32_t *r, const uint32_t *a)
1406 {
1407  uint_t pLen;
1408  uint32_t c;
1409  uint32_t b[EC_MAX_MODULUS_SIZE];
1410 
1411  //Get the length of the modulus, in words
1412  pLen = (curve->fieldSize + 31) / 32;
1413 
1414  //Compute R = A mod p
1415  c = ecScalarSub(b, a, curve->p, pLen);
1416  ecScalarSelect(r, b, a, c, pLen);
1417 }
1418 
1419 
1420 /**
1421  * @brief An auxiliary function for the twin multiplication
1422  * @param[in] t An integer T such as 0 <= T <= 31
1423  * @return Output value
1424  **/
1425 
1427 {
1428  uint_t h;
1429 
1430  //Check the value of T
1431  if(18 <= t && t < 22)
1432  {
1433  h = 9;
1434  }
1435  else if(14 <= t && t < 18)
1436  {
1437  h = 10;
1438  }
1439  else if(22 <= t && t < 24)
1440  {
1441  h = 11;
1442  }
1443  else if(4 <= t && t < 12)
1444  {
1445  h = 14;
1446  }
1447  else
1448  {
1449  h = 12;
1450  }
1451 
1452  //Return value
1453  return h;
1454 }
1455 
1456 
1457 /**
1458  * @brief Co-Z addition with update
1459  * @param[in] state Pointer to the working state
1460  * @param[out] r Output integer R
1461  * @param[out] s Output integer S
1462  * @param[in] p Output integer P
1463  * @param[in] q Output integer Q
1464  **/
1465 
1466 void ecZaddu(EcState *state, EcPoint3 *r, EcPoint3 *s, const EcPoint3 *p,
1467  const EcPoint3 *q)
1468 {
1469  uint_t pLen;
1470 
1471  //Get the length of the modulus, in words
1472  pLen = (state->curve->fieldSize + 31) / 32;
1473 
1474  //T1 = X1
1475  ecScalarCopy(state->t1, p->x, pLen);
1476  //T2 = Y1
1477  ecScalarCopy(state->t2, p->y, pLen);
1478  //T3 = Z
1479  ecScalarCopy(state->t3, p->z, pLen);
1480  //T4 = X2
1481  ecScalarCopy(state->t4, q->x, pLen);
1482  //T5 = Y2
1483  ecScalarCopy(state->t5, q->y, pLen);
1484 
1485  //1. T6 = T1 - T4
1486  ecFieldSubMod(state->curve, state->t6, state->t1, state->t4);
1487  //2. T3 = T3 * T6
1488  ecFieldMulMod(state->curve, state->t3, state->t3, state->t6);
1489  //3. T6 = T6 ^ 2
1490  ecFieldSqrMod(state->curve, state->t6, state->t6);
1491  //4. T1 = T1 * T6
1492  ecFieldMulMod(state->curve, state->t1, state->t1, state->t6);
1493  //5. T6 = T6 * T4
1494  ecFieldMulMod(state->curve, state->t6, state->t6, state->t4);
1495  //6. T5 = T2 - T5
1496  ecFieldSubMod(state->curve, state->t5, state->t2, state->t5);
1497  //7. T4 = T5 ^ 2
1498  ecFieldSqrMod(state->curve, state->t4, state->t5);
1499  //8. T4 = T4 - T1
1500  ecFieldSubMod(state->curve, state->t4, state->t4, state->t1);
1501  //9. T4 = T4 - T6
1502  ecFieldSubMod(state->curve, state->t4, state->t4, state->t6);
1503  //10. T6 = T1 - T6
1504  ecFieldSubMod(state->curve, state->t6, state->t1, state->t6);
1505  //11. T2 = T2 * T6
1506  ecFieldMulMod(state->curve, state->t2, state->t2, state->t6);
1507  //12. T6 = T1 - T4
1508  ecFieldSubMod(state->curve, state->t6, state->t1, state->t4);
1509  //13. T5 = T5 * T6
1510  ecFieldMulMod(state->curve, state->t5, state->t5, state->t6);
1511  //14. T5 = T5 - T2
1512  ecFieldSubMod(state->curve, state->t5, state->t5, state->t2);
1513 
1514  //R = (T4 : T5 : T3)
1515  ecScalarCopy(r->x, state->t4, pLen);
1516  ecScalarCopy(r->y, state->t5, pLen);
1517  ecScalarCopy(r->z, state->t3, pLen);
1518 
1519  //S = (T1 : T2 : T3)
1520  ecScalarCopy(s->x, state->t1, pLen);
1521  ecScalarCopy(s->y, state->t2, pLen);
1522  ecScalarCopy(s->z, state->t3, pLen);
1523 }
1524 
1525 
1526 /**
1527  * @brief Conjugate co-Z addition
1528  * @param[in] state Pointer to the working state
1529  * @param[out] r Output integer R
1530  * @param[out] s Output integer S
1531  * @param[in] p Output integer P
1532  * @param[in] q Output integer Q
1533  **/
1534 
1535 void ecZaddc(EcState *state, EcPoint3 *r, EcPoint3 *s, const EcPoint3 *p,
1536  const EcPoint3 *q)
1537 {
1538  uint_t pLen;
1539 
1540  //Get the length of the modulus, in words
1541  pLen = (state->curve->fieldSize + 31) / 32;
1542 
1543  //T1 = X1
1544  ecScalarCopy(state->t1, p->x, pLen);
1545  //T2 = Y1
1546  ecScalarCopy(state->t2, p->y, pLen);
1547  //T3 = Z
1548  ecScalarCopy(state->t3, p->z, pLen);
1549  //T4 = X2
1550  ecScalarCopy(state->t4, q->x, pLen);
1551  //T5 = Y2
1552  ecScalarCopy(state->t5, q->y, pLen);
1553 
1554  //1. T6 = T1 - T4
1555  ecFieldSubMod(state->curve, state->t6, state->t1, state->t4);
1556  //2. T3 = T3 * T6
1557  ecFieldMulMod(state->curve, state->t3, state->t3, state->t6);
1558  //3. T6 = T6 ^ 2
1559  ecFieldSqrMod(state->curve, state->t6, state->t6);
1560  //4. T7 = T1 * T6
1561  ecFieldMulMod(state->curve, state->t7, state->t1, state->t6);
1562  //5. T6 = T6 * T4
1563  ecFieldMulMod(state->curve, state->t6, state->t6, state->t4);
1564  //6. T1 = T2 + T5
1565  ecFieldAddMod(state->curve, state->t1, state->t2, state->t5);
1566  //7. T4 = T1 ^ 2
1567  ecFieldSqrMod(state->curve, state->t4, state->t1);
1568  //8. T4 = T4 - T7
1569  ecFieldSubMod(state->curve, state->t4, state->t4, state->t7);
1570  //9. T4 = T4 - T6
1571  ecFieldSubMod(state->curve, state->t4, state->t4, state->t6);
1572  //10. T1 = T2 - T5
1573  ecFieldSubMod(state->curve, state->t1, state->t2, state->t5);
1574  //11. T1 = T1 ^ 2
1575  ecFieldSqrMod(state->curve, state->t1, state->t1);
1576  //12. T1 = T1 - T7
1577  ecFieldSubMod(state->curve, state->t1, state->t1, state->t7);
1578  //13. T1 = T1 - T6
1579  ecFieldSubMod(state->curve, state->t1, state->t1, state->t6);
1580  //14. T6 = T6 - T7
1581  ecFieldSubMod(state->curve, state->t6, state->t6, state->t7);
1582  //15. T6 = T6 * T2
1583  ecFieldMulMod(state->curve, state->t6, state->t6, state->t2);
1584  //16. T2 = T2 - T5
1585  ecFieldSubMod(state->curve, state->t2, state->t2, state->t5);
1586  //17. T5 = 2 * T5
1587  ecFieldAddMod(state->curve, state->t5, state->t5, state->t5);
1588  //18. T5 = T2 + T5
1589  ecFieldAddMod(state->curve, state->t5, state->t2, state->t5);
1590  //19. T7 = T7 - T4
1591  ecFieldSubMod(state->curve, state->t7, state->t7, state->t4);
1592  //20. T5 = T5 * T7
1593  ecFieldMulMod(state->curve, state->t5, state->t5, state->t7);
1594  //21. T5 = T5 + T6
1595  ecFieldAddMod(state->curve, state->t5, state->t5, state->t6);
1596  //22. T7 = T4 + T7
1597  ecFieldAddMod(state->curve, state->t7, state->t4, state->t7);
1598  //23. T7 = T7 - T1
1599  ecFieldSubMod(state->curve, state->t7, state->t7, state->t1);
1600  //24. T2 = T2 * T7
1601  ecFieldMulMod(state->curve, state->t2, state->t2, state->t7);
1602  //25. T2 = T2 + T6
1603  ecFieldAddMod(state->curve, state->t2, state->t2, state->t6);
1604 
1605  //R = (T1 : T2 : T3)
1606  ecScalarCopy(r->x, state->t1, pLen);
1607  ecScalarCopy(r->y, state->t2, pLen);
1608  ecScalarCopy(r->z, state->t3, pLen);
1609 
1610  //S = (T4 : T5 : T3)
1611  ecScalarCopy(s->x, state->t4, pLen);
1612  ecScalarCopy(s->y, state->t5, pLen);
1613  ecScalarCopy(s->z, state->t3, pLen);
1614 }
1615 
1616 
1617 /**
1618  *@brief Co-Z doubling with update
1619  * @param[in] state Pointer to the working state
1620  * @param[out] r Output integer R
1621  * @param[out] s Output integer S
1622  * @param[in] p Output integer P
1623  **/
1624 
1625 void ecDblu(EcState *state, EcPoint3 *r, EcPoint3 *s, const EcPoint3 *p)
1626 {
1627  uint_t pLen;
1628 
1629  //Get the length of the modulus, in words
1630  pLen = (state->curve->fieldSize + 31) / 32;
1631 
1632  //T0 = a
1633  ecScalarCopy(state->t0, state->curve->a, pLen);
1634  //T1 = X1
1635  ecScalarCopy(state->t1, p->x, pLen);
1636  //T2 = Y1
1637  ecScalarCopy(state->t2, p->y, pLen);
1638 
1639  //1. T3 = 2 * T2
1640  ecFieldAddMod(state->curve, state->t3, state->t2, state->t2);
1641  //2. T2 = T2 ^ 2
1642  ecFieldSqrMod(state->curve, state->t2, state->t2);
1643  //3. T4 = T1 + T2
1644  ecFieldAddMod(state->curve, state->t4, state->t1, state->t2);
1645  //4. T4 = T4 ^ 2
1646  ecFieldSqrMod(state->curve, state->t4, state->t4);
1647  //5. T5 = T1 ^ 2
1648  ecFieldSqrMod(state->curve, state->t5, state->t1);
1649  //6. T4 = T4 - T5
1650  ecFieldSubMod(state->curve, state->t4, state->t4, state->t5);
1651  //7. T2 = T2 ^ 2
1652  ecFieldSqrMod(state->curve, state->t2, state->t2);
1653  //8. T4 = T4 - T2
1654  ecFieldSubMod(state->curve, state->t4, state->t4, state->t2);
1655  //9. T1 = 2 * T4
1656  ecFieldAddMod(state->curve, state->t1, state->t4, state->t4);
1657  //10. T0 = T0 + T5
1658  ecFieldAddMod(state->curve, state->t0, state->t0, state->t5);
1659  //11. T5 = 2 * T5
1660  ecFieldAddMod(state->curve, state->t5, state->t5, state->t5);
1661  //12. T0 = T0 + T5
1662  ecFieldAddMod(state->curve, state->t0, state->t0, state->t5);
1663  //13. T4 = T0 ^ 2
1664  ecFieldSqrMod(state->curve, state->t4, state->t0);
1665  //14. T5 = 2 * T1
1666  ecFieldAddMod(state->curve, state->t5, state->t1, state->t1);
1667  //15. T4 = T4 - T5
1668  ecFieldSubMod(state->curve, state->t4, state->t4, state->t5);
1669  //16. T2 = 8 * T2
1670  ecFieldAddMod(state->curve, state->t2, state->t2, state->t2);
1671  ecFieldAddMod(state->curve, state->t2, state->t2, state->t2);
1672  ecFieldAddMod(state->curve, state->t2, state->t2, state->t2);
1673  //17. T5 = T1 - T4
1674  ecFieldSubMod(state->curve, state->t5, state->t1, state->t4);
1675  //18. T5 = T5 * T0
1676  ecFieldMulMod(state->curve, state->t5, state->t5, state->t0);
1677  //19. T5 = T5 - T2
1678  ecFieldSubMod(state->curve, state->t5, state->t5, state->t2);
1679 
1680  //R = (T4 : T5 : T3)
1681  ecScalarCopy(r->x, state->t4, pLen);
1682  ecScalarCopy(r->y, state->t5, pLen);
1683  ecScalarCopy(r->z, state->t3, pLen);
1684 
1685  //S = (T1 : T2 : T3)
1686  ecScalarCopy(s->x, state->t1, pLen);
1687  ecScalarCopy(s->y, state->t2, pLen);
1688  ecScalarCopy(s->z, state->t3, pLen);
1689 }
1690 
1691 
1692 /**
1693  * @brief Co-Z tripling with update
1694  * @param[in] state Pointer to the working state
1695  * @param[out] r Output integer R
1696  * @param[out] s Output integer S
1697  * @param[in] p Output integer P
1698  **/
1699 
1700 void ecTplu(EcState *state, EcPoint3 *r, EcPoint3 *s, const EcPoint3 *p)
1701 {
1702  //(R, P) = DBLU(P)
1703  ecDblu(state, r, s, p);
1704  //(R, P) = ZADDU(P, R)
1705  ecZaddu(state, r, s, s, r);
1706 }
1707 
1708 
1709 /**
1710  * @brief Display the contents of an integer
1711  * @param[in] stream Pointer to a FILE object that identifies an output stream
1712  * @param[in] prepend String to prepend to the left of each line
1713  * @param[in] a Pointer to the integer to dump
1714  * @param[in] n Size of the integer, in words
1715  **/
1716 
1717 void ecScalarDump(FILE *stream, const char_t *prepend, const uint32_t *a,
1718  uint_t n)
1719 {
1720  uint_t i;
1721 
1722  //Process each word
1723  for(i = 0; i < n; i++)
1724  {
1725  //Beginning of a new line?
1726  if(i == 0 || ((n - i - 1) % 8) == 7)
1727  {
1728  fprintf(stream, "%s", prepend);
1729  }
1730 
1731  //Display current data
1732  fprintf(stream, "%08" PRIX32 " ", a[n - 1 - i]);
1733 
1734  //End of current line?
1735  if(((n - i - 1) % 8) == 0 || i == (n - 1))
1736  {
1737  fprintf(stream, "\r\n");
1738  }
1739  }
1740 }
1741 
1742 #endif
error_t ecScalarImport(uint32_t *r, uint_t n, const uint8_t *input, size_t length, EcScalarFormat format)
Octet string to integer conversion.
Definition: ec_misc.c:54
uint8_t b
Definition: nbns_common.h:104
__weak_func void ecScalarSqr(uint32_t *r, const uint32_t *a, uint_t n)
Squaring operation.
Definition: ec_misc.c:832
uint_t ecScalarGetByteLength(const uint32_t *a, uint_t n)
Get the actual length in bytes.
Definition: ec_misc.c:231
uint32_t t4[EC_MAX_MODULUS_SIZE]
Definition: ec.h:451
uint8_t a
Definition: ndp.h:411
error_t ecScalarExport(const uint32_t *a, uint_t n, uint8_t *output, size_t length, EcScalarFormat format)
Integer to octet string conversion.
Definition: ec_misc.c:150
signed int int_t
Definition: compiler_port.h:56
void ecZaddc(EcState *state, EcPoint3 *r, EcPoint3 *s, const EcPoint3 *p, const EcPoint3 *q)
Conjugate co-Z addition.
Definition: ec_misc.c:1535
#define PrngAlgo
Definition: crypto.h:973
uint8_t p
Definition: ndp.h:300
uint32_t ecScalarGetBitValue(const uint32_t *a, int_t index)
Get the bit value at the specified index.
Definition: ec_misc.c:315
uint8_t t
Definition: lldp_ext_med.h:212
#define EC_MAX_ORDER_SIZE
Definition: ec.h:315
uint_t ecScalarGetBitLength(const uint32_t *a, uint_t n)
Get the actual length in bits.
Definition: ec_misc.c:273
uint32_t t7[EC_MAX_MODULUS_SIZE]
Definition: ec.h:454
uint32_t t0[EC_MAX_MODULUS_SIZE]
Definition: ec.h:447
uint32_t ecScalarAdd(uint32_t *r, const uint32_t *a, const uint32_t *b, uint_t n)
Addition of two integers.
Definition: ec_misc.c:651
const uint8_t res[]
void ecScalarShiftLeft(uint32_t *r, const uint32_t *a, uint_t k, uint_t n)
Left shift operation.
Definition: ec_misc.c:884
uint32_t t6[EC_MAX_MODULUS_SIZE]
Definition: ec.h:453
__weak_func void ecFieldAddMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular addition.
Definition: ec_misc.c:1235
uint8_t r
Definition: ndp.h:346
uint8_t h
Definition: ndp.h:302
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
__weak_func void ecScalarSqrMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular squaring.
Definition: ec_misc.c:1135
error_t
Error codes.
Definition: error.h:43
uint32_t ecScalarSub(uint32_t *r, const uint32_t *a, const uint32_t *b, uint_t n)
Subtraction of two integers.
Definition: ec_misc.c:707
void ecScalarSetInt(uint32_t *a, uint32_t b, uint_t n)
Set integer value.
Definition: ec_misc.c:505
Helper routines for ECC.
uint32_t ecScalarSubInt(uint32_t *r, const uint32_t *a, uint32_t b, uint_t n)
Subtraction of two integers.
Definition: ec_misc.c:736
void ecScalarCopy(uint32_t *a, const uint32_t *b, uint_t n)
Copy an integer.
Definition: ec_misc.c:527
@ ERROR_INVALID_LENGTH
Definition: error.h:111
void ecScalarPwr2Mod(const EcCurve *curve, uint32_t *r, const uint32_t *a, uint_t n)
Raise an integer to power 2^n.
Definition: ec_misc.c:1158
@ EC_SCALAR_FORMAT_LITTLE_ENDIAN
Definition: ec_misc.h:50
General definitions for cryptographic algorithms.
void ecScalarInvMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular inversion.
Definition: ec_misc.c:1181
uint8_t mask
Definition: web_socket.h:319
__weak_func void ecFieldSqrMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular squaring.
Definition: ec_misc.c:1308
uint8_t u
Definition: lldp_ext_med.h:213
uint32_t ecScalarTestEqual(const uint32_t *a, const uint32_t *b, uint_t n)
Test if two integers are equal.
Definition: ec_misc.c:420
uint8_t length
Definition: tcp.h:375
void ecScalarSelect(uint32_t *r, const uint32_t *a, const uint32_t *b, uint32_t c, uint_t n)
Select an integer.
Definition: ec_misc.c:576
__weak_func void ecFieldMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
Definition: ec_misc.c:1286
char char_t
Definition: compiler_port.h:55
const EcCurve * curve
Definition: ec.h:446
void ecScalarSubMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular subtraction.
Definition: ec_misc.c:1088
uint32_t t5[EC_MAX_MODULUS_SIZE]
Definition: ec.h:452
uint32_t ecScalarTestEqualInt(const uint32_t *a, uint32_t b, uint_t n)
Test if two integers are equal.
Definition: ec_misc.c:435
void ecScalarAddMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular addition.
Definition: ec_misc.c:1062
uint32_t ecScalarTestNotEqual(const uint32_t *a, const uint32_t *b, uint_t n)
Test if two integers are different.
Definition: ec_misc.c:450
int_t ecScalarCompInt(const uint32_t *a, uint32_t b, uint_t n)
Compare integers.
Definition: ec_misc.c:374
Working state (point addition/subtraction/doubling)
Definition: ec.h:445
uint8_t m
Definition: ndp.h:304
uint8_t n
@ EC_SCALAR_FORMAT_BIG_ENDIAN
Definition: ec_misc.h:51
void ecFieldCanonicalize(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Reduce non-canonical value.
Definition: ec_misc.c:1405
EC point (projective coordinates)
Definition: ec.h:409
void ecFieldInvMod(const EcCurve *curve, uint32_t *r, const uint32_t *a)
Modular inversion.
Definition: ec_misc.c:1354
void ecZaddu(EcState *state, EcPoint3 *r, EcPoint3 *s, const EcPoint3 *p, const EcPoint3 *q)
Co-Z addition with update.
Definition: ec_misc.c:1466
uint32_t t3[EC_MAX_MODULUS_SIZE]
Definition: ec.h:450
void ecScalarShiftRight(uint32_t *r, const uint32_t *a, uint_t k, uint_t n)
Right shift operation.
Definition: ec_misc.c:940
error_t ecScalarRand(const EcCurve *curve, uint32_t *r, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: ec_misc.c:603
uint8_t s
Definition: igmp_common.h:234
void ecTplu(EcState *state, EcPoint3 *r, EcPoint3 *s, const EcPoint3 *p)
Co-Z tripling with update.
Definition: ec_misc.c:1700
uint32_t t1[EC_MAX_MODULUS_SIZE]
Definition: ec.h:448
#define EcCurve
Definition: ec.h:346
void ecScalarMod(uint32_t *r, const uint32_t *a, uint_t m, const uint32_t *p, uint_t n)
Modulo operation.
Definition: ec_misc.c:1009
void ecFieldPwr2Mod(const EcCurve *curve, uint32_t *r, const uint32_t *a, uint_t n)
Raise an integer to power 2^n.
Definition: ec_misc.c:1331
void ecScalarSwap(uint32_t *a, uint32_t *b, uint32_t c, uint_t n)
Conditional swap.
Definition: ec_misc.c:547
__weak_func void ecFieldSubMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular subtraction.
Definition: ec_misc.c:1261
int_t ecScalarComp(const uint32_t *a, const uint32_t *b, uint_t n)
Compare integers.
Definition: ec_misc.c:337
uint32_t ecScalarTestNotEqualInt(const uint32_t *a, uint32_t b, uint_t n)
Test if two integers are different.
Definition: ec_misc.c:478
__weak_func void ecScalarMul(uint32_t *rl, uint32_t *rh, const uint32_t *a, const uint32_t *b, uint_t n)
Multiplication of two integers.
Definition: ec_misc.c:766
unsigned int uint_t
Definition: compiler_port.h:57
uint32_t t2[EC_MAX_MODULUS_SIZE]
Definition: ec.h:449
#define osMemset(p, value, length)
Definition: os_port.h:138
uint_t ecTwinMulF(uint_t t)
An auxiliary function for the twin multiplication.
Definition: ec_misc.c:1426
ECC (Elliptic Curve Cryptography)
uint32_t ecScalarAddInt(uint32_t *r, const uint32_t *a, uint32_t b, uint_t n)
Addition of two integers.
Definition: ec_misc.c:680
__weak_func void ecScalarMulMod(const EcCurve *curve, uint32_t *r, const uint32_t *a, const uint32_t *b)
Modular multiplication.
Definition: ec_misc.c:1113
uint32_t x[EC_MAX_MODULUS_SIZE]
x-coordinate
Definition: ec.h:410
#define EC_MAX_MODULUS_SIZE
Definition: ec.h:284
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
void ecDblu(EcState *state, EcPoint3 *r, EcPoint3 *s, const EcPoint3 *p)
Co-Z doubling with update.
Definition: ec_misc.c:1625
Debugging facilities.
EcScalarFormat
Scalar import/export format.
Definition: ec_misc.h:49
uint32_t y[EC_MAX_MODULUS_SIZE]
y-coordinate
Definition: ec.h:411
void ecScalarDump(FILE *stream, const char_t *prepend, const uint32_t *a, uint_t n)
Display the contents of an integer.
Definition: ec_misc.c:1717