mpi.c
Go to the documentation of this file.
1 /**
2  * @file mpi.c
3  * @brief MPI (Multiple Precision Integer Arithmetic)
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.4
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 "mpi/mpi.h"
37 #include "mpi/mpi_misc.h"
38 #include "debug.h"
39 
40 //Check crypto library configuration
41 #if (MPI_SUPPORT == ENABLED)
42 
43 
44 /**
45  * @brief Initialize a multiple precision integer
46  * @param[in,out] r Pointer to the multiple precision integer to be initialized
47  **/
48 
49 void mpiInit(Mpi *r)
50 {
51  //Initialize structure
52  r->sign = 1;
53  r->size = 0;
54 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
55  r->data = NULL;
56 #endif
57 }
58 
59 
60 /**
61  * @brief Release a multiple precision integer
62  * @param[in,out] r Pointer to the multiple precision integer to be freed
63  **/
64 
65 void mpiFree(Mpi *r)
66 {
67  uint_t i;
68 
69 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
70  //Any memory previously allocated?
71  if(r->data != NULL)
72  {
73  //Erase contents
74  for(i = 0; i < r->size; i++)
75  {
76  r->data[i] = 0;
77  }
78 
79  //Release memory buffer
80  cryptoFreeMem(r->data);
81  r->data = NULL;
82  }
83 #else
84  //Erase contents
85  for(i = 0; i < r->size; i++)
86  {
87  r->data[i] = 0;
88  }
89 #endif
90 
91  //Reset size to zero
92  r->size = 0;
93 }
94 
95 
96 /**
97  * @brief Adjust the size of multiple precision integer
98  * @param[in,out] r A multiple precision integer whose size is to be increased
99  * @param[in] size Desired size in words
100  * @return Error code
101  **/
102 
104 {
105  error_t error;
106  uint_t i;
107 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
108  mpi_word_t *data;
109 #endif
110 
111  //Initialize status code
112  error = NO_ERROR;
113 
114  //Ensure the parameter is valid
115  size = MAX(size, 1);
116 
117  //Check whether the size of the multiple precision integer must be increased
118  if(size > r->size)
119  {
120 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
121  //Allocate a new memory buffer
122  data = cryptoAllocMem(size * sizeof(mpi_word_t));
123 
124  //Successful memory allocation?
125  if(data != NULL)
126  {
127  //Any data to copy?
128  if(r->size > 0)
129  {
130  //Copy original data
131  for(i = 0; i < r->size; i++)
132  {
133  data[i] = r->data[i];
134  r->data[i] = 0;
135  }
136 
137  //Release old memory buffer
138  cryptoFreeMem(r->data);
139  }
140 
141  //Clear upper words
142  for(i = r->size; i < size; i++)
143  {
144  data[i] = 0;
145  }
146 
147  //Attach new memory buffer
148  r->data = data;
149  //Update the size of the multiple precision integer
150  r->size = size;
151  }
152  else
153  {
154  //Failed to allocate memory
155  error = ERROR_OUT_OF_MEMORY;
156  }
157 #else
158  //Check parameter
159  if(size <= MPI_MAX_WORDS)
160  {
161  //Clear upper words
162  for(i = r->size; i < size; i++)
163  {
164  r->data[i] = 0;
165  }
166 
167  //Update the size of the multiple precision integer
168  r->size = size;
169  }
170  else
171  {
172  //Report an error
173  error = ERROR_BUFFER_OVERFLOW;
174  }
175 #endif
176  }
177 
178  //Return status code
179  return error;
180 }
181 
182 
183 /**
184  * @brief Get the actual length in words
185  * @param[in] a Pointer to a multiple precision integer
186  * @return The actual length in words
187  **/
188 
190 {
191  int_t i;
192 
193  //Check whether the specified multiple precision integer is empty
194  if(a->size == 0)
195  return 0;
196 
197  //Start from the most significant word
198  for(i = a->size - 1; i >= 0; i--)
199  {
200  //Loop as long as the current word is zero
201  if(a->data[i] != 0)
202  break;
203  }
204 
205  //Return the actual length
206  return i + 1;
207 }
208 
209 
210 /**
211  * @brief Get the actual length in bytes
212  * @param[in] a Pointer to a multiple precision integer
213  * @return The actual byte count
214  **/
215 
217 {
218  uint_t n;
219  uint32_t m;
220 
221  //Check whether the specified multiple precision integer is empty
222  if(a->size == 0)
223  return 0;
224 
225  //Start from the most significant word
226  for(n = a->size - 1; n > 0; n--)
227  {
228  //Loop as long as the current word is zero
229  if(a->data[n] != 0)
230  break;
231  }
232 
233  //Get the current word
234  m = a->data[n];
235  //Convert the length to a byte count
237 
238  //Adjust the byte count
239  for(; m != 0; m >>= 8)
240  {
241  n++;
242  }
243 
244  //Return the actual length in bytes
245  return n;
246 }
247 
248 
249 /**
250  * @brief Get the actual length in bits
251  * @param[in] a Pointer to a multiple precision integer
252  * @return The actual bit count
253  **/
254 
256 {
257  uint_t n;
258  uint32_t m;
259 
260  //Check whether the specified multiple precision integer is empty
261  if(a->size == 0)
262  return 0;
263 
264  //Start from the most significant word
265  for(n = a->size - 1; n > 0; n--)
266  {
267  //Loop as long as the current word is zero
268  if(a->data[n] != 0)
269  break;
270  }
271 
272  //Get the current word
273  m = a->data[n];
274  //Convert the length to a bit count
275  n *= MPI_BITS_PER_WORD;
276 
277  //Adjust the bit count
278  for(; m != 0; m >>= 1)
279  {
280  n++;
281  }
282 
283  //Return the actual length in bits
284  return n;
285 }
286 
287 
288 /**
289  * @brief Set the bit value at the specified index
290  * @param[in] r Pointer to a multiple precision integer
291  * @param[in] index Position of the bit to be written
292  * @param[in] value Bit value
293  * @return Error code
294  **/
295 
297 {
298  error_t error;
299  uint_t n1;
300  uint_t n2;
301 
302  //Retrieve the position of the bit to be written
303  n1 = index / MPI_BITS_PER_WORD;
304  n2 = index % MPI_BITS_PER_WORD;
305 
306  //Ajust the size of the multiple precision integer if necessary
307  error = mpiGrow(r, n1 + 1);
308  //Failed to adjust the size?
309  if(error)
310  return error;
311 
312  //Set bit value
313  if(value != 0)
314  {
315  r->data[n1] |= (1U << n2);
316  }
317  else
318  {
319  r->data[n1] &= ~(1U << n2);
320  }
321 
322  //Successful operation
323  return NO_ERROR;
324 }
325 
326 
327 /**
328  * @brief Get the bit value at the specified index
329  * @param[in] a Pointer to a multiple precision integer
330  * @param[in] index Position where to read the bit
331  * @return The actual bit value
332  **/
333 
335 {
336  uint_t n1;
337  uint_t n2;
338 
339  //Retrieve the position of the bit to be read
340  n1 = index / MPI_BITS_PER_WORD;
341  n2 = index % MPI_BITS_PER_WORD;
342 
343  //Index out of range?
344  if(n1 >= a->size)
345  return 0;
346 
347  //Return the actual bit value
348  return (a->data[n1] >> n2) & 0x01;
349 }
350 
351 
352 /**
353  * @brief Compare two multiple precision integers
354  * @param[in] a The first multiple precision integer to be compared
355  * @param[in] b The second multiple precision integer to be compared
356  * @return Comparison result
357  **/
358 
359 int_t mpiComp(const Mpi *a, const Mpi *b)
360 {
361  uint_t m;
362  uint_t n;
363  int_t res;
364 
365  //Initialize variable
366  res = 0;
367 
368  //Determine the actual length of A and B
369  m = mpiGetLength(a);
370  n = mpiGetLength(b);
371 
372  //Compare lengths
373  if(m == 0 && n == 0)
374  {
375  res = 0;
376  }
377  else if(m > n)
378  {
379  res = a->sign;
380  }
381  else if(m < n)
382  {
383  res = -b->sign;
384  }
385  else
386  {
387  //Compare signs
388  if(a->sign > 0 && b->sign < 0)
389  {
390  res = 1;
391  }
392  else if(a->sign < 0 && b->sign > 0)
393  {
394  res = -1;
395  }
396  else
397  {
398  //Compare values
399  while(n-- > 0)
400  {
401  if(a->data[n] > b->data[n])
402  {
403  res = a->sign;
404  break;
405  }
406  else if(a->data[n] < b->data[n])
407  {
408  res = -a->sign;
409  break;
410  }
411  else
412  {
413  }
414  }
415  }
416  }
417 
418  //Return comparison result
419  return res;
420 }
421 
422 
423 /**
424  * @brief Compare a multiple precision integer with an integer
425  * @param[in] a Multiple precision integer to be compared
426  * @param[in] b Integer to be compared
427  * @return Comparison result
428  **/
429 
431 {
433  Mpi t;
434 
435  //Initialize a temporary multiple precision integer
436  value = (b >= 0) ? b : -b;
437  t.sign = (b >= 0) ? 1 : -1;
438  t.size = 1;
439 
440 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
441  t.data = &value;
442 #else
443  t.data[0] = value;
444 #endif
445 
446  //Return comparison result
447  return mpiComp(a, &t);
448 }
449 
450 
451 /**
452  * @brief Compare the absolute value of two multiple precision integers
453  * @param[in] a The first multiple precision integer to be compared
454  * @param[in] b The second multiple precision integer to be compared
455  * @return Comparison result
456  **/
457 
458 int_t mpiCompAbs(const Mpi *a, const Mpi *b)
459 {
460  uint_t m;
461  uint_t n;
462  int_t res;
463 
464  //Initialize variable
465  res = 0;
466 
467  //Determine the actual length of A and B
468  m = mpiGetLength(a);
469  n = mpiGetLength(b);
470 
471  //Compare lengths
472  if(m == 0 && n == 0)
473  {
474  res = 0;
475  }
476  else if(m > n)
477  {
478  res = 1;
479  }
480  else if(m < n)
481  {
482  res = -1;
483  }
484  else
485  {
486  //Compare values
487  while(n-- > 0)
488  {
489  if(a->data[n] > b->data[n])
490  {
491  res = 1;
492  break;
493  }
494  else if(a->data[n] < b->data[n])
495  {
496  res = -1;
497  break;
498  }
499  else
500  {
501  }
502  }
503  }
504 
505  //Return comparison result
506  return res;
507 }
508 
509 
510 /**
511  * @brief Copy a multiple precision integer
512  * @param[out] r Pointer to a multiple precision integer (destination)
513  * @param[in] a Pointer to a multiple precision integer (source)
514  * @return Error code
515  **/
516 
518 {
519  error_t error;
520  uint_t i;
521  uint_t n;
522 
523  //R and A are the same instance?
524  if(r == a)
525  return NO_ERROR;
526 
527  //Determine the actual length of A
528  n = mpiGetLength(a);
529 
530  //Ajust the size of the destination operand
531  error = mpiGrow(r, n);
532  //Any error to report?
533  if(error)
534  return error;
535 
536  //Set the sign of R
537  r->sign = a->sign;
538 
539  //Let R = A
540  for(i = 0; i < n; i++)
541  {
542  r->data[i] = a->data[i];
543  }
544 
545  //Clear upper words
546  for(; i < r->size; i++)
547  {
548  r->data[i] = 0;
549  }
550 
551  //Successful operation
552  return NO_ERROR;
553 }
554 
555 
556 /**
557  * @brief Set the value of a multiple precision integer
558  * @param[out] r Pointer to a multiple precision integer
559  * @param[in] a Value to be assigned to the multiple precision integer
560  * @return Error code
561  **/
562 
564 {
565  error_t error;
566  uint_t i;
567 
568  //Ajust the size of the destination operand
569  error = mpiGrow(r, 1);
570  //Failed to adjust the size?
571  if(error)
572  return error;
573 
574  //Clear the contents of the multiple precision integer
575  for(i = 0; i < r->size; i++)
576  {
577  r->data[i] = 0;
578  }
579 
580  //Set the value or R
581  r->data[0] = (a >= 0) ? a : -a;
582  //Set the sign of R
583  r->sign = (a >= 0) ? 1 : -1;
584 
585  //Successful operation
586  return NO_ERROR;
587 }
588 
589 
590 /**
591  * @brief Generate a random value
592  * @param[out] r Pointer to a multiple precision integer
593  * @param[in] length Desired length in bits
594  * @param[in] prngAlgo PRNG algorithm
595  * @param[in] prngContext Pointer to the PRNG context
596  * @return Error code
597  **/
598 
599 error_t mpiRand(Mpi *r, uint_t length, const PrngAlgo *prngAlgo,
600  void *prngContext)
601 {
602  error_t error;
603  uint_t i;
604  uint_t m;
605  uint_t n;
606 
607  //Compute the required length, in words
609  //Number of bits in the most significant word
611 
612  //Ajust the size of the multiple precision integer if necessary
613  error = mpiGrow(r, n);
614  //Failed to adjust the size?
615  if(error)
616  return error;
617 
618  //Clear the contents of the multiple precision integer
619  for(i = 0; i < r->size; i++)
620  {
621  r->data[i] = 0;
622  }
623 
624  //Set the sign of R
625  r->sign = 1;
626 
627  //Generate a random pattern
628  error = prngAlgo->generate(prngContext, (uint8_t *) r->data,
629  n * sizeof(mpi_word_t));
630  //Any error to report?
631  if(error)
632  return error;
633 
634  //Remove the meaningless bits in the most significant word
635  if(n > 0 && m > 0)
636  {
637  r->data[n - 1] &= (1U << m) - 1;
638  }
639 
640  //Successful operation
641  return NO_ERROR;
642 }
643 
644 
645 /**
646  * @brief Generate a random value in the range 1 to p-1
647  * @param[out] r Pointer to a multiple precision integer
648  * @param[in] p The upper bound of the range
649  * @param[in] prngAlgo PRNG algorithm
650  * @param[in] prngContext Pointer to the PRNG context
651  * @return Error code
652  **/
653 
654 error_t mpiRandRange(Mpi *r, const Mpi *p, const PrngAlgo *prngAlgo,
655  void *prngContext)
656 {
657  error_t error;
658  uint_t n;
659  Mpi a;
660 
661  //Make sure p is greater than 1
662  if(mpiCompInt(p, 1) <= 0)
664 
665  //Initialize multiple precision integer
666  mpiInit(&a);
667 
668  //Get the actual length of p
669  n = mpiGetBitLength(p);
670 
671  //Generate extra random bits so that the bias produced by the modular
672  //reduction is negligible
673  MPI_CHECK(mpiRand(r, n + 64, prngAlgo, prngContext));
674 
675  //Compute r = (r mod (p - 1)) + 1
676  MPI_CHECK(mpiSubInt(&a, p, 1));
677  MPI_CHECK(mpiMod(r, r, &a));
678  MPI_CHECK(mpiAddInt(r, r, 1));
679 
680 end:
681  //Release previously allocated memory
682  mpiFree(&a);
683 
684  //Return status code
685  return error;
686 }
687 
688 
689 /**
690  * @brief Test whether a number is probable prime
691  * @param[in] a Pointer to a multiple precision integer
692  * @return Error code
693  **/
694 
695 __weak_func error_t mpiCheckProbablePrime(const Mpi *a)
696 {
697  //This function is a placeholder for hardware implementation
698  return ERROR_NOT_IMPLEMENTED;
699 }
700 
701 
702 /**
703  * @brief Octet string to integer conversion
704  *
705  * Converts an octet string to a non-negative integer
706  *
707  * @param[out] r Non-negative integer resulting from the conversion
708  * @param[in] input Octet string to be converted
709  * @param[in] length Length of the octet string
710  * @param[in] format Input format
711  * @return Error code
712  **/
713 
714 error_t mpiImport(Mpi *r, const uint8_t *input, size_t length,
715  MpiFormat format)
716 {
717  error_t error;
718  uint_t i;
719  mpi_word_t temp;
720 
721  //Check input format
722  if(format == MPI_FORMAT_LITTLE_ENDIAN)
723  {
724  //Skip trailing zeroes
725  while(length > 0 && input[length - 1] == 0)
726  {
727  length--;
728  }
729 
730  //Ajust the size of the multiple precision integer
732 
733  //Check status code
734  if(!error)
735  {
736  //Clear the contents of the multiple precision integer
737  for(i = 0; i < r->size; i++)
738  {
739  r->data[i] = 0;
740  }
741 
742  //Set sign
743  r->sign = 1;
744 
745  //Import data
746  for(i = 0; i < length; i++, input++)
747  {
748  temp = *input & 0xFF;
749  r->data[i / MPI_BYTES_PER_WORD] |= temp << ((i % MPI_BYTES_PER_WORD) * 8);
750  }
751  }
752  }
753  else if(format == MPI_FORMAT_BIG_ENDIAN)
754  {
755  //Skip leading zeroes
756  while(length > 1 && *input == 0)
757  {
758  input++;
759  length--;
760  }
761 
762  //Ajust the size of the multiple precision integer
764 
765  //Check status code
766  if(!error)
767  {
768  //Clear the contents of the multiple precision integer
769  for(i = 0; i < r->size; i++)
770  {
771  r->data[i] = 0;
772  }
773 
774  //Set sign
775  r->sign = 1;
776 
777  //Start from the least significant byte
778  input += length - 1;
779 
780  //Import data
781  for(i = 0; i < length; i++, input--)
782  {
783  temp = *input & 0xFF;
784  r->data[i / MPI_BYTES_PER_WORD] |= temp << ((i % MPI_BYTES_PER_WORD) * 8);
785  }
786  }
787  }
788  else
789  {
790  //Report an error
791  error = ERROR_INVALID_PARAMETER;
792  }
793 
794  //Return status code
795  return error;
796 }
797 
798 
799 /**
800  * @brief Integer to octet string conversion
801  *
802  * Converts an integer to an octet string of a specified length
803  *
804  * @param[in] a Non-negative integer to be converted
805  * @param[out] output Octet string resulting from the conversion
806  * @param[in] length Intended length of the resulting octet string
807  * @param[in] format Output format
808  * @return Error code
809  **/
810 
811 error_t mpiExport(const Mpi *a, uint8_t *output, size_t length,
812  MpiFormat format)
813 {
814  error_t error;
815  uint_t i;
816  uint_t n;
817  mpi_word_t temp;
818 
819  //Initialize status code
820  error = NO_ERROR;
821 
822  //Check input format
823  if(format == MPI_FORMAT_LITTLE_ENDIAN)
824  {
825  //Get the actual length in bytes
826  n = mpiGetByteLength(a);
827 
828  //Make sure the output buffer is large enough
829  if(n <= length)
830  {
831  //Clear output buffer
832  osMemset(output, 0, length);
833 
834  //Export data
835  for(i = 0; i < n; i++, output++)
836  {
837  temp = a->data[i / MPI_BYTES_PER_WORD] >> ((i % MPI_BYTES_PER_WORD) * 8);
838  *output = temp & 0xFF;
839  }
840  }
841  else
842  {
843  //Report an error
844  error = ERROR_INVALID_LENGTH;
845  }
846  }
847  else if(format == MPI_FORMAT_BIG_ENDIAN)
848  {
849  //Get the actual length in bytes
850  n = mpiGetByteLength(a);
851 
852  //Make sure the output buffer is large enough
853  if(n <= length)
854  {
855  //Clear output buffer
856  osMemset(output, 0, length);
857 
858  //Point to the least significant word
859  output += length - 1;
860 
861  //Export data
862  for(i = 0; i < n; i++, output--)
863  {
864  temp = a->data[i / MPI_BYTES_PER_WORD] >> ((i % MPI_BYTES_PER_WORD) * 8);
865  *output = temp & 0xFF;
866  }
867  }
868  else
869  {
870  //Report an error
871  error = ERROR_INVALID_LENGTH;
872  }
873  }
874  else
875  {
876  //Report an error
877  error = ERROR_INVALID_PARAMETER;
878  }
879 
880  //Return status code
881  return error;
882 }
883 
884 
885 /**
886  * @brief Multiple precision addition
887  * @param[out] r Resulting integer R = A + B
888  * @param[in] a First operand A
889  * @param[in] b Second operand B
890  * @return Error code
891  **/
892 
893 error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
894 {
895  error_t error;
896  int_t sign;
897 
898  //Retrieve the sign of A
899  sign = a->sign;
900 
901  //Both operands have the same sign?
902  if(a->sign == b->sign)
903  {
904  //Perform addition
905  error = mpiAddAbs(r, a, b);
906  //Set the sign of the resulting number
907  r->sign = sign;
908  }
909  //Operands have different signs?
910  else
911  {
912  //Compare the absolute value of A and B
913  if(mpiCompAbs(a, b) >= 0)
914  {
915  //Perform subtraction
916  error = mpiSubAbs(r, a, b);
917  //Set the sign of the resulting number
918  r->sign = sign;
919  }
920  else
921  {
922  //Perform subtraction
923  error = mpiSubAbs(r, b, a);
924  //Set the sign of the resulting number
925  r->sign = -sign;
926  }
927  }
928 
929  //Return status code
930  return error;
931 }
932 
933 
934 /**
935  * @brief Add an integer to a multiple precision integer
936  * @param[out] r Resulting integer R = A + B
937  * @param[in] a First operand A
938  * @param[in] b Second operand B
939  * @return Error code
940  **/
941 
943 {
945  Mpi t;
946 
947  //Convert the second operand to a multiple precision integer
948  value = (b >= 0) ? b : -b;
949  t.sign = (b >= 0) ? 1 : -1;
950  t.size = 1;
951 
952 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
953  t.data = &value;
954 #else
955  t.data[0] = value;
956 #endif
957 
958  //Perform addition
959  return mpiAdd(r, a, &t);
960 }
961 
962 
963 /**
964  * @brief Multiple precision subtraction
965  * @param[out] r Resulting integer R = A - B
966  * @param[in] a First operand A
967  * @param[in] b Second operand B
968  * @return Error code
969  **/
970 
971 error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
972 {
973  error_t error;
974  int_t sign;
975 
976  //Retrieve the sign of A
977  sign = a->sign;
978 
979  //Both operands have the same sign?
980  if(a->sign == b->sign)
981  {
982  //Compare the absolute value of A and B
983  if(mpiCompAbs(a, b) >= 0)
984  {
985  //Perform subtraction
986  error = mpiSubAbs(r, a, b);
987  //Set the sign of the resulting number
988  r->sign = sign;
989  }
990  else
991  {
992  //Perform subtraction
993  error = mpiSubAbs(r, b, a);
994  //Set the sign of the resulting number
995  r->sign = -sign;
996  }
997  }
998  //Operands have different signs?
999  else
1000  {
1001  //Perform addition
1002  error = mpiAddAbs(r, a, b);
1003  //Set the sign of the resulting number
1004  r->sign = sign;
1005  }
1006 
1007  //Return status code
1008  return error;
1009 }
1010 
1011 
1012 /**
1013  * @brief Subtract an integer from a multiple precision integer
1014  * @param[out] r Resulting integer R = A - B
1015  * @param[in] a First operand A
1016  * @param[in] b Second operand B
1017  * @return Error code
1018  **/
1019 
1021 {
1022  mpi_word_t value;
1023  Mpi t;
1024 
1025  //Convert the second operand to a multiple precision integer
1026  value = (b >= 0) ? b : -b;
1027  t.sign = (b >= 0) ? 1 : -1;
1028  t.size = 1;
1029 
1030 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1031  t.data = &value;
1032 #else
1033  t.data[0] = value;
1034 #endif
1035 
1036  //Perform subtraction
1037  return mpiSub(r, a, &t);
1038 }
1039 
1040 
1041 /**
1042  * @brief Helper routine for multiple precision addition
1043  * @param[out] r Resulting integer R = |A + B|
1044  * @param[in] a First operand A
1045  * @param[in] b Second operand B
1046  * @return Error code
1047  **/
1048 
1049 error_t mpiAddAbs(Mpi *r, const Mpi *a, const Mpi *b)
1050 {
1051  error_t error;
1052  uint_t i;
1053  uint_t n;
1054  mpi_word_t c;
1055  mpi_word_t d;
1056 
1057  //R and B are the same instance?
1058  if(r == b)
1059  {
1060  //Swap A and B
1061  const Mpi *t = a;
1062  a = b;
1063  b = t;
1064  }
1065  //R is neither A nor B?
1066  else if(r != a)
1067  {
1068  //Copy the first operand to R
1069  MPI_CHECK(mpiCopy(r, a));
1070  }
1071 
1072  //Determine the actual length of B
1073  n = mpiGetLength(b);
1074  //Extend the size of the destination register as needed
1075  MPI_CHECK(mpiGrow(r, n));
1076 
1077  //The result is always positive
1078  r->sign = 1;
1079  //Clear carry bit
1080  c = 0;
1081 
1082  //Add operands
1083  for(i = 0; i < n; i++)
1084  {
1085  //Add carry bit
1086  d = r->data[i] + c;
1087 
1088  //Update carry bit
1089  if(d != 0)
1090  {
1091  c = 0;
1092  }
1093 
1094  //Perform addition
1095  d += b->data[i];
1096 
1097  //Update carry bit
1098  if(d < b->data[i])
1099  {
1100  c = 1;
1101  }
1102 
1103  //Save result
1104  r->data[i] = d;
1105  }
1106 
1107  //Loop as long as the carry bit is set
1108  for(i = n; c && i < r->size; i++)
1109  {
1110  //Add carry bit
1111  r->data[i] += c;
1112 
1113  //Update carry bit
1114  if(r->data[i] != 0)
1115  {
1116  c = 0;
1117  }
1118  }
1119 
1120  //Check the final carry bit
1121  if(c && n >= r->size)
1122  {
1123  //Extend the size of the destination register
1124  MPI_CHECK(mpiGrow(r, n + 1));
1125  //Add carry bit
1126  r->data[n] = 1;
1127  }
1128 
1129 end:
1130  //Return status code
1131  return error;
1132 }
1133 
1134 
1135 /**
1136  * @brief Helper routine for multiple precision subtraction
1137  * @param[out] r Resulting integer R = |A - B|
1138  * @param[in] a First operand A
1139  * @param[in] b Second operand B
1140  * @return Error code
1141  **/
1142 
1143 error_t mpiSubAbs(Mpi *r, const Mpi *a, const Mpi *b)
1144 {
1145  error_t error;
1146  uint_t i;
1147  uint_t m;
1148  uint_t n;
1149  mpi_word_t c;
1150  mpi_word_t d;
1151 
1152  //Check input parameters
1153  if(mpiCompAbs(a, b) < 0)
1154  {
1155  //Swap A and B if necessary
1156  const Mpi *t = a;
1157  a = b;
1158  b = t;
1159  }
1160 
1161  //Determine the actual length of A
1162  m = mpiGetLength(a);
1163  //Determine the actual length of B
1164  n = mpiGetLength(b);
1165 
1166  //Extend the size of the destination register as needed
1167  MPI_CHECK(mpiGrow(r, m));
1168 
1169  //The result is always positive
1170  r->sign = 1;
1171  //Clear carry bit
1172  c = 0;
1173 
1174  //Subtract operands
1175  for(i = 0; i < n; i++)
1176  {
1177  //Read first operand
1178  d = a->data[i];
1179 
1180  //Check the carry bit
1181  if(c != 0)
1182  {
1183  //Update carry bit
1184  if(d != 0)
1185  {
1186  c = 0;
1187  }
1188 
1189  //Propagate carry bit
1190  d -= 1;
1191  }
1192 
1193  //Update carry bit
1194  if(d < b->data[i])
1195  {
1196  c = 1;
1197  }
1198 
1199  //Perform subtraction
1200  r->data[i] = d - b->data[i];
1201  }
1202 
1203  //Loop as long as the carry bit is set
1204  for(i = n; c && i < m; i++)
1205  {
1206  //Update carry bit
1207  if(a->data[i] != 0)
1208  {
1209  c = 0;
1210  }
1211 
1212  //Propagate carry bit
1213  r->data[i] = a->data[i] - 1;
1214  }
1215 
1216  //R and A are not the same instance?
1217  if(r != a)
1218  {
1219  //Copy the remaining words
1220  for(; i < m; i++)
1221  {
1222  r->data[i] = a->data[i];
1223  }
1224 
1225  //Zero the upper part
1226  for(; i < r->size; i++)
1227  {
1228  r->data[i] = 0;
1229  }
1230  }
1231 
1232 end:
1233  //Return status code
1234  return error;
1235 }
1236 
1237 
1238 /**
1239  * @brief Left shift operation
1240  * @param[in,out] r The multiple precision integer to be shifted to the left
1241  * @param[in] n The number of bits to shift
1242  * @return Error code
1243  **/
1244 
1246 {
1247  error_t error;
1248  uint_t i;
1249  uint_t k;
1250  uint_t n1;
1251  uint_t n2;
1252 
1253  //Check parameters
1254  if(r->size == 0 || n == 0)
1255  return NO_ERROR;
1256 
1257  //Determine the actual length of r
1258  k = mpiGetBitLength(r);
1259 
1260  //Number of 32-bit words to shift
1261  n1 = n / MPI_BITS_PER_WORD;
1262  //Number of bits to shift
1263  n2 = n % MPI_BITS_PER_WORD;
1264 
1265  //Increase the size of the multiple-precision number
1266  error = mpiGrow(r, (k + n + (MPI_BITS_PER_WORD - 1)) / MPI_BITS_PER_WORD);
1267  //Check return code
1268  if(error)
1269  return error;
1270 
1271  //First, shift words
1272  if(n1 > 0)
1273  {
1274  //Process the most significant words
1275  for(i = r->size - 1; i >= n1; i--)
1276  {
1277  r->data[i] = r->data[i - n1];
1278  }
1279 
1280  //Fill the rest with zeroes
1281  for(i = 0; i < n1; i++)
1282  {
1283  r->data[i] = 0;
1284  }
1285  }
1286 
1287  //Then shift bits
1288  if(n2 > 0)
1289  {
1290  //Process the most significant words
1291  for(i = r->size - 1; i >= 1; i--)
1292  {
1293  r->data[i] = (r->data[i] << n2) | (r->data[i - 1] >> (MPI_BITS_PER_WORD - n2));
1294  }
1295 
1296  //The least significant word requires a special handling
1297  r->data[0] <<= n2;
1298  }
1299 
1300  //Shift operation is complete
1301  return NO_ERROR;
1302 }
1303 
1304 
1305 /**
1306  * @brief Right shift operation
1307  * @param[in,out] r The multiple precision integer to be shifted to the right
1308  * @param[in] n The number of bits to shift
1309  * @return Error code
1310  **/
1311 
1313 {
1314  uint_t i;
1315  uint_t m;
1316 
1317  //Number of 32-bit words to shift
1318  uint_t n1 = n / MPI_BITS_PER_WORD;
1319  //Number of bits to shift
1320  uint_t n2 = n % MPI_BITS_PER_WORD;
1321 
1322  //Check parameters
1323  if(n1 >= r->size)
1324  {
1325  //Clear the contents of the multiple precision integer
1326  for(i = 0; i < r->size; i++)
1327  {
1328  r->data[i] = 0;
1329  }
1330 
1331  //We are done
1332  return NO_ERROR;
1333  }
1334 
1335  //First, shift words
1336  if(n1 > 0)
1337  {
1338  //Process the least significant words
1339  for(m = r->size - n1, i = 0; i < m; i++)
1340  {
1341  r->data[i] = r->data[i + n1];
1342  }
1343 
1344  //Fill the rest with zeroes
1345  for(i = m; i < r->size; i++)
1346  {
1347  r->data[i] = 0;
1348  }
1349  }
1350 
1351  //Then shift bits
1352  if(n2 > 0)
1353  {
1354  //Process the least significant words
1355  for(m = r->size - n1 - 1, i = 0; i < m; i++)
1356  {
1357  r->data[i] = (r->data[i] >> n2) | (r->data[i + 1] << (MPI_BITS_PER_WORD - n2));
1358  }
1359 
1360  //The most significant word requires a special handling
1361  r->data[m] >>= n2;
1362  }
1363 
1364  //Shift operation is complete
1365  return NO_ERROR;
1366 }
1367 
1368 
1369 /**
1370  * @brief Multiple precision multiplication
1371  * @param[out] r Resulting integer R = A * B
1372  * @param[in] a First operand A
1373  * @param[in] b Second operand B
1374  * @return Error code
1375  **/
1376 
1377 __weak_func error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
1378 {
1379  error_t error;
1380  uint_t i;
1381  uint_t m;
1382  uint_t n;
1383  Mpi ta;
1384  Mpi tb;
1385 
1386  //Initialize multiple precision integers
1387  mpiInit(&ta);
1388  mpiInit(&tb);
1389 
1390  //R and A are the same instance?
1391  if(r == a)
1392  {
1393  //Copy A to TA
1394  MPI_CHECK(mpiCopy(&ta, a));
1395  //Use TA instead of A
1396  a = &ta;
1397  }
1398 
1399  //R and B are the same instance?
1400  if(r == b)
1401  {
1402  //Copy B to TB
1403  MPI_CHECK(mpiCopy(&tb, b));
1404  //Use TB instead of B
1405  b = &tb;
1406  }
1407 
1408  //Determine the actual length of A and B
1409  m = mpiGetLength(a);
1410  n = mpiGetLength(b);
1411 
1412  //Adjust the size of R
1413  MPI_CHECK(mpiGrow(r, m + n));
1414  //Set the sign of R
1415  r->sign = (a->sign == b->sign) ? 1 : -1;
1416 
1417  //Clear the contents of the destination integer
1418  for(i = 0; i < r->size; i++)
1419  {
1420  r->data[i] = 0;
1421  }
1422 
1423  //Perform multiplication
1424  if(m < n)
1425  {
1426  for(i = 0; i < m; i++)
1427  {
1428  mpiMulAccCore(&r->data[i], b->data, n, a->data[i]);
1429  }
1430  }
1431  else
1432  {
1433  for(i = 0; i < n; i++)
1434  {
1435  mpiMulAccCore(&r->data[i], a->data, m, b->data[i]);
1436  }
1437  }
1438 
1439 end:
1440  //Release multiple precision integers
1441  mpiFree(&ta);
1442  mpiFree(&tb);
1443 
1444  //Return status code
1445  return error;
1446 }
1447 
1448 
1449 /**
1450  * @brief Multiply a multiple precision integer by an integer
1451  * @param[out] r Resulting integer R = A * B
1452  * @param[in] a First operand A
1453  * @param[in] b Second operand B
1454  * @return Error code
1455  **/
1456 
1458 {
1459  mpi_word_t value;
1460  Mpi t;
1461 
1462  //Convert the second operand to a multiple precision integer
1463  value = (b >= 0) ? b : -b;
1464  t.sign = (b >= 0) ? 1 : -1;
1465  t.size = 1;
1466 
1467 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1468  t.data = &value;
1469 #else
1470  t.data[0] = value;
1471 #endif
1472 
1473  //Perform multiplication
1474  return mpiMul(r, a, &t);
1475 }
1476 
1477 
1478 /**
1479  * @brief Multiple precision division
1480  * @param[out] q The quotient Q = A / B
1481  * @param[out] r The remainder R = A mod B
1482  * @param[in] a The dividend A
1483  * @param[in] b The divisor B
1484  * @return Error code
1485  **/
1486 
1487 error_t mpiDiv(Mpi *q, Mpi *r, const Mpi *a, const Mpi *b)
1488 {
1489  error_t error;
1490  uint_t m;
1491  uint_t n;
1492  Mpi c;
1493  Mpi d;
1494  Mpi e;
1495 
1496  //Check whether the divisor is equal to zero
1497  if(!mpiCompInt(b, 0))
1498  return ERROR_INVALID_PARAMETER;
1499 
1500  //Initialize multiple precision integers
1501  mpiInit(&c);
1502  mpiInit(&d);
1503  mpiInit(&e);
1504 
1505  MPI_CHECK(mpiCopy(&c, a));
1506  MPI_CHECK(mpiCopy(&d, b));
1507  MPI_CHECK(mpiSetValue(&e, 0));
1508 
1509  m = mpiGetBitLength(&c);
1510  n = mpiGetBitLength(&d);
1511 
1512  if(m > n)
1513  {
1514  MPI_CHECK(mpiShiftLeft(&d, m - n));
1515  }
1516 
1517  while(n++ <= m)
1518  {
1519  MPI_CHECK(mpiShiftLeft(&e, 1));
1520 
1521  if(mpiComp(&c, &d) >= 0)
1522  {
1523  MPI_CHECK(mpiSetBitValue(&e, 0, 1));
1524  MPI_CHECK(mpiSub(&c, &c, &d));
1525  }
1526 
1527  MPI_CHECK(mpiShiftRight(&d, 1));
1528  }
1529 
1530  if(q != NULL)
1531  {
1532  MPI_CHECK(mpiCopy(q, &e));
1533  }
1534 
1535  if(r != NULL)
1536  {
1537  MPI_CHECK(mpiCopy(r, &c));
1538  }
1539 
1540 end:
1541  //Release previously allocated memory
1542  mpiFree(&c);
1543  mpiFree(&d);
1544  mpiFree(&e);
1545 
1546  //Return status code
1547  return error;
1548 }
1549 
1550 
1551 /**
1552  * @brief Divide a multiple precision integer by an integer
1553  * @param[out] q The quotient Q = A / B
1554  * @param[out] r The remainder R = A mod B
1555  * @param[in] a The dividend A
1556  * @param[in] b The divisor B
1557  * @return Error code
1558  **/
1559 
1561 {
1562  mpi_word_t value;
1563  Mpi t;
1564 
1565  //Convert the divisor to a multiple precision integer
1566  value = (b >= 0) ? b : -b;
1567  t.sign = (b >= 0) ? 1 : -1;
1568  t.size = 1;
1569 
1570 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
1571  t.data = &value;
1572 #else
1573  t.data[0] = value;
1574 #endif
1575 
1576  //Perform division
1577  return mpiDiv(q, r, a, &t);
1578 }
1579 
1580 
1581 /**
1582  * @brief Modulo operation
1583  * @param[out] r Resulting integer R = A mod P
1584  * @param[in] a The multiple precision integer to be reduced
1585  * @param[in] p The modulus P
1586  * @return Error code
1587  **/
1588 
1589 error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
1590 {
1591  error_t error;
1592  int_t sign;
1593  uint_t m;
1594  uint_t n;
1595  Mpi c;
1596 
1597  //Make sure the modulus is positive
1598  if(mpiCompInt(p, 0) <= 0)
1599  return ERROR_INVALID_PARAMETER;
1600 
1601  //Initialize multiple precision integer
1602  mpiInit(&c);
1603 
1604  //Save the sign of A
1605  sign = a->sign;
1606  //Determine the actual length of A
1607  m = mpiGetBitLength(a);
1608  //Determine the actual length of P
1609  n = mpiGetBitLength(p);
1610 
1611  //Let R = A
1612  MPI_CHECK(mpiCopy(r, a));
1613 
1614  if(m >= n)
1615  {
1616  MPI_CHECK(mpiCopy(&c, p));
1617  MPI_CHECK(mpiShiftLeft(&c, m - n));
1618 
1619  while(mpiCompAbs(r, p) >= 0)
1620  {
1621  if(mpiCompAbs(r, &c) >= 0)
1622  {
1623  MPI_CHECK(mpiSubAbs(r, r, &c));
1624  }
1625 
1626  MPI_CHECK(mpiShiftRight(&c, 1));
1627  }
1628  }
1629 
1630  if(sign < 0)
1631  {
1632  MPI_CHECK(mpiSubAbs(r, p, r));
1633  }
1634 
1635 end:
1636  //Release previously allocated memory
1637  mpiFree(&c);
1638 
1639  //Return status code
1640  return error;
1641 }
1642 
1643 
1644 /**
1645  * @brief Modular addition
1646  * @param[out] r Resulting integer R = A + B mod P
1647  * @param[in] a The first operand A
1648  * @param[in] b The second operand B
1649  * @param[in] p The modulus P
1650  * @return Error code
1651  **/
1652 
1653 error_t mpiAddMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
1654 {
1655  error_t error;
1656 
1657  //Perform modular addition
1658  MPI_CHECK(mpiAdd(r, a, b));
1659  MPI_CHECK(mpiMod(r, r, p));
1660 
1661 end:
1662  //Return status code
1663  return error;
1664 }
1665 
1666 
1667 /**
1668  * @brief Modular subtraction
1669  * @param[out] r Resulting integer R = A - B mod P
1670  * @param[in] a The first operand A
1671  * @param[in] b The second operand B
1672  * @param[in] p The modulus P
1673  * @return Error code
1674  **/
1675 
1676 error_t mpiSubMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
1677 {
1678  error_t error;
1679 
1680  //Perform modular subtraction
1681  MPI_CHECK(mpiSub(r, a, b));
1682  MPI_CHECK(mpiMod(r, r, p));
1683 
1684 end:
1685  //Return status code
1686  return error;
1687 }
1688 
1689 
1690 /**
1691  * @brief Modular multiplication
1692  * @param[out] r Resulting integer R = A * B mod P
1693  * @param[in] a The first operand A
1694  * @param[in] b The second operand B
1695  * @param[in] p The modulus P
1696  * @return Error code
1697  **/
1698 
1699 __weak_func error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
1700 {
1701  error_t error;
1702 
1703  //Perform modular multiplication
1704  MPI_CHECK(mpiMul(r, a, b));
1705  MPI_CHECK(mpiMod(r, r, p));
1706 
1707 end:
1708  //Return status code
1709  return error;
1710 }
1711 
1712 
1713 /**
1714  * @brief Modular inverse
1715  * @param[out] r Resulting integer R = A^-1 mod P
1716  * @param[in] a The multiple precision integer A
1717  * @param[in] p The modulus P
1718  * @return Error code
1719  **/
1720 
1721 __weak_func error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
1722 {
1723  error_t error;
1724  Mpi b;
1725  Mpi c;
1726  Mpi q0;
1727  Mpi r0;
1728  Mpi t;
1729  Mpi u;
1730  Mpi v;
1731 
1732  //Initialize multiple precision integers
1733  mpiInit(&b);
1734  mpiInit(&c);
1735  mpiInit(&q0);
1736  mpiInit(&r0);
1737  mpiInit(&t);
1738  mpiInit(&u);
1739  mpiInit(&v);
1740 
1741  MPI_CHECK(mpiCopy(&b, p));
1742  MPI_CHECK(mpiCopy(&c, a));
1743  MPI_CHECK(mpiSetValue(&u, 0));
1744  MPI_CHECK(mpiSetValue(&v, 1));
1745 
1746  while(mpiCompInt(&c, 0) > 0)
1747  {
1748  MPI_CHECK(mpiDiv(&q0, &r0, &b, &c));
1749 
1750  MPI_CHECK(mpiCopy(&b, &c));
1751  MPI_CHECK(mpiCopy(&c, &r0));
1752 
1753  MPI_CHECK(mpiCopy(&t, &v));
1754  MPI_CHECK(mpiMul(&q0, &q0, &v));
1755  MPI_CHECK(mpiSub(&v, &u, &q0));
1756  MPI_CHECK(mpiCopy(&u, &t));
1757  }
1758 
1759  if(mpiCompInt(&b, 1))
1760  {
1762  }
1763 
1764  if(mpiCompInt(&u, 0) > 0)
1765  {
1766  MPI_CHECK(mpiCopy(r, &u));
1767  }
1768  else
1769  {
1770  MPI_CHECK(mpiAdd(r, &u, p));
1771  }
1772 
1773 end:
1774  //Release previously allocated memory
1775  mpiFree(&b);
1776  mpiFree(&c);
1777  mpiFree(&q0);
1778  mpiFree(&r0);
1779  mpiFree(&t);
1780  mpiFree(&u);
1781  mpiFree(&v);
1782 
1783  //Return status code
1784  return error;
1785 }
1786 
1787 
1788 /**
1789  * @brief Modular exponentiation
1790  * @param[out] r Resulting integer R = A ^ E mod P
1791  * @param[in] a Pointer to a multiple precision integer
1792  * @param[in] e Exponent
1793  * @param[in] p Modulus
1794  * @return Error code
1795  **/
1796 
1797 __weak_func error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
1798 {
1799  error_t error;
1800  int_t i;
1801  int_t j;
1802  int_t n;
1803  uint_t d;
1804  uint_t k;
1805  uint_t u;
1806  Mpi b;
1807  Mpi c2;
1808  Mpi t;
1809  Mpi s[8];
1810 
1811  //Initialize multiple precision integers
1812  mpiInit(&b);
1813  mpiInit(&c2);
1814  mpiInit(&t);
1815 
1816  //Initialize precomputed values
1817  for(i = 0; (uint_t) i < arraysize(s); i++)
1818  {
1819  mpiInit(&s[i]);
1820  }
1821 
1822  //Very small exponents are often selected with low Hamming weight. The
1823  //sliding window mechanism should be disabled in that case
1824  d = (mpiGetBitLength(e) <= 32) ? 1 : 4;
1825 
1826  //Even modulus?
1827  if(mpiIsEven(p))
1828  {
1829  //Let S[0] = A
1830  MPI_CHECK(mpiMod(&s[0], a, p));
1831  //Let B = A^2
1832  MPI_CHECK(mpiMulMod(&b, &s[0], &s[0], p));
1833 
1834  //Precompute S[i] = A^(2 * i + 1)
1835  for(i = 1; i < (1 << (d - 1)); i++)
1836  {
1837  MPI_CHECK(mpiMulMod(&s[i], &s[i - 1], &b, p));
1838  }
1839 
1840  //Let R = 1
1841  MPI_CHECK(mpiSetValue(r, 1));
1842 
1843  //The exponent is processed in a left-to-right fashion
1844  i = mpiGetBitLength(e) - 1;
1845 
1846  //Perform sliding window exponentiation
1847  while(i >= 0)
1848  {
1849  //The sliding window exponentiation algorithm decomposes E
1850  //into zero and nonzero windows
1851  if(!mpiGetBitValue(e, i))
1852  {
1853  //Compute R = R^2
1854  MPI_CHECK(mpiMulMod(r, r, r, p));
1855  //Next bit to be processed
1856  i--;
1857  }
1858  else
1859  {
1860  //Find the longest window
1861  n = MAX(i - d + 1, 0);
1862 
1863  //The least significant bit of the window must be equal to 1
1864  while(!mpiGetBitValue(e, n))
1865  {
1866  n++;
1867  }
1868 
1869  //The algorithm processes more than one bit per iteration
1870  for(u = 0, j = i; j >= n; j--)
1871  {
1872  //Compute R = R^2
1873  MPI_CHECK(mpiMulMod(r, r, r, p));
1874  //Compute the relevant index to be used in the precomputed table
1875  u = (u << 1) | mpiGetBitValue(e, j);
1876  }
1877 
1878  //Perform a single multiplication per iteration
1879  MPI_CHECK(mpiMulMod(r, r, &s[u >> 1], p));
1880  //Next bit to be processed
1881  i = n - 1;
1882  }
1883  }
1884  }
1885  else
1886  {
1887  //Compute the smaller C = (2^32)^k such as C > P
1888  k = mpiGetLength(p);
1889 
1890  //Compute C^2 mod P
1891  MPI_CHECK(mpiSetValue(&c2, 1));
1892  MPI_CHECK(mpiShiftLeft(&c2, 2 * k * MPI_BITS_PER_WORD));
1893  MPI_CHECK(mpiMod(&c2, &c2, p));
1894 
1895  //Let B = A * C mod P
1896  if(mpiComp(a, p) >= 0)
1897  {
1898  MPI_CHECK(mpiMod(&b, a, p));
1899  MPI_CHECK(mpiMontgomeryMul(&b, &b, &c2, k, p, &t));
1900  }
1901  else
1902  {
1903  MPI_CHECK(mpiMontgomeryMul(&b, a, &c2, k, p, &t));
1904  }
1905 
1906  //Let R = B^2 * C^-1 mod P
1907  MPI_CHECK(mpiMontgomeryMul(r, &b, &b, k, p, &t));
1908  //Let S[0] = B
1909  MPI_CHECK(mpiCopy(&s[0], &b));
1910 
1911  //Precompute S[i] = B^(2 * i + 1) * C^-1 mod P
1912  for(i = 1; i < (1 << (d - 1)); i++)
1913  {
1914  MPI_CHECK(mpiMontgomeryMul(&s[i], &s[i - 1], r, k, p, &t));
1915  }
1916 
1917  //Let R = C mod P
1918  MPI_CHECK(mpiCopy(r, &c2));
1919  MPI_CHECK(mpiMontgomeryRed(r, r, k, p, &t));
1920 
1921  //The exponent is processed in a left-to-right fashion
1922  i = mpiGetBitLength(e) - 1;
1923 
1924  //Perform sliding window exponentiation
1925  while(i >= 0)
1926  {
1927  //The sliding window exponentiation algorithm decomposes E
1928  //into zero and nonzero windows
1929  if(!mpiGetBitValue(e, i))
1930  {
1931  //Compute R = R^2 * C^-1 mod P
1932  MPI_CHECK(mpiMontgomeryMul(r, r, r, k, p, &t));
1933  //Next bit to be processed
1934  i--;
1935  }
1936  else
1937  {
1938  //Find the longest window
1939  n = MAX(i - d + 1, 0);
1940 
1941  //The least significant bit of the window must be equal to 1
1942  while(!mpiGetBitValue(e, n))
1943  {
1944  n++;
1945  }
1946 
1947  //The algorithm processes more than one bit per iteration
1948  for(u = 0, j = i; j >= n; j--)
1949  {
1950  //Compute R = R^2 * C^-1 mod P
1951  MPI_CHECK(mpiMontgomeryMul(r, r, r, k, p, &t));
1952  //Compute the relevant index to be used in the precomputed table
1953  u = (u << 1) | mpiGetBitValue(e, j);
1954  }
1955 
1956  //Compute R = R * T[u/2] * C^-1 mod P
1957  MPI_CHECK(mpiMontgomeryMul(r, r, &s[u >> 1], k, p, &t));
1958  //Next bit to be processed
1959  i = n - 1;
1960  }
1961  }
1962 
1963  //Compute R = R * C^-1 mod P
1964  MPI_CHECK(mpiMontgomeryRed(r, r, k, p, &t));
1965  }
1966 
1967 end:
1968  //Release multiple precision integers
1969  mpiFree(&b);
1970  mpiFree(&c2);
1971  mpiFree(&t);
1972 
1973  //Release precomputed values
1974  for(i = 0; (uint_t) i < arraysize(s); i++)
1975  {
1976  mpiFree(&s[i]);
1977  }
1978 
1979  //Return status code
1980  return error;
1981 }
1982 
1983 
1984 /**
1985  * @brief Modular exponentiation (fast calculation)
1986  * @param[out] r Resulting integer R = A ^ E mod P
1987  * @param[in] a Pointer to a multiple precision integer
1988  * @param[in] e Exponent
1989  * @param[in] p Modulus
1990  * @return Error code
1991  **/
1992 
1993 __weak_func error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
1994 {
1995  //Perform modular exponentiation
1996  return mpiExpMod(r, a, e, p);
1997 }
1998 
1999 
2000 /**
2001  * @brief Modular exponentiation (regular calculation)
2002  * @param[out] r Resulting integer R = A ^ E mod P
2003  * @param[in] a Pointer to a multiple precision integer
2004  * @param[in] e Exponent
2005  * @param[in] p Modulus
2006  * @return Error code
2007  **/
2008 
2009 __weak_func error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
2010 {
2011  //Perform modular exponentiation
2012  return mpiExpMod(r, a, e, p);
2013 }
2014 
2015 
2016 /**
2017  * @brief Display the contents of a multiple precision integer
2018  * @param[in] stream Pointer to a FILE object that identifies an output stream
2019  * @param[in] prepend String to prepend to the left of each line
2020  * @param[in] a Pointer to a multiple precision integer
2021  **/
2022 
2023 void mpiDump(FILE *stream, const char_t *prepend, const Mpi *a)
2024 {
2025  uint_t i;
2026 
2027  //Process each word
2028  for(i = 0; i < a->size; i++)
2029  {
2030  //Beginning of a new line?
2031  if(i == 0 || ((a->size - i - 1) % 8) == 7)
2032  {
2033  fprintf(stream, "%s", prepend);
2034  }
2035 
2036  //Display current data
2037 #if (MPI_BITS_PER_WORD == 8)
2038  fprintf(stream, "%02" PRIX8 " ", a->data[a->size - 1 - i]);
2039 #elif (MPI_BITS_PER_WORD == 16)
2040  fprintf(stream, "%04" PRIX16 " ", a->data[a->size - 1 - i]);
2041 #elif (MPI_BITS_PER_WORD == 32)
2042  fprintf(stream, "%08" PRIX32 " ", a->data[a->size - 1 - i]);
2043 #endif
2044 
2045  //End of current line?
2046  if(((a->size - i - 1) % 8) == 0 || i == (a->size - 1))
2047  {
2048  fprintf(stream, "\r\n");
2049  }
2050  }
2051 }
2052 
2053 #endif
error_t mpiShiftLeft(Mpi *r, uint_t n)
Left shift operation.
Definition: mpi.c:1245
error_t mpiMontgomeryRed(Mpi *r, const Mpi *a, uint_t k, const Mpi *p, Mpi *t)
Montgomery reduction.
Definition: mpi_misc.c:128
__weak_func error_t mpiExpMod(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation.
Definition: mpi.c:1797
uint8_t b
Definition: nbns_common.h:122
uint8_t a
Definition: ndp.h:411
Arbitrary precision integer.
Definition: mpi.h:102
signed int int_t
Definition: compiler_port.h:56
@ ERROR_BUFFER_OVERFLOW
Definition: error.h:143
@ ERROR_NOT_IMPLEMENTED
Definition: error.h:66
#define PrngAlgo
Definition: crypto.h:1008
error_t mpiSubAbs(Mpi *r, const Mpi *a, const Mpi *b)
Helper routine for multiple precision subtraction.
Definition: mpi.c:1143
uint8_t p
Definition: ndp.h:300
uint8_t t
Definition: lldp_ext_med.h:212
uint8_t data[]
Definition: ethernet.h:224
__weak_func error_t mpiMulMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular multiplication.
Definition: mpi.c:1699
#define mpiIsEven(a)
Definition: mpi.h:77
@ ERROR_OUT_OF_MEMORY
Definition: error.h:63
error_t mpiSetBitValue(Mpi *r, uint_t index, uint_t value)
Set the bit value at the specified index.
Definition: mpi.c:296
error_t mpiAddAbs(Mpi *r, const Mpi *a, const Mpi *b)
Helper routine for multiple precision addition.
Definition: mpi.c:1049
void mpiDump(FILE *stream, const char_t *prepend, const Mpi *a)
Display the contents of a multiple precision integer.
Definition: mpi.c:2023
error_t mpiRandRange(Mpi *r, const Mpi *p, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value in the range 1 to p-1.
Definition: mpi.c:654
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1312
error_t mpiRand(Mpi *r, uint_t length, const PrngAlgo *prngAlgo, void *prngContext)
Generate a random value.
Definition: mpi.c:599
int_t mpiCompAbs(const Mpi *a, const Mpi *b)
Compare the absolute value of two multiple precision integers.
Definition: mpi.c:458
error_t mpiSubInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Subtract an integer from a multiple precision integer.
Definition: mpi.c:1020
const uint8_t res[]
void mpiInit(Mpi *r)
Initialize a multiple precision integer.
Definition: mpi.c:49
uint8_t r
Definition: ndp.h:346
error_t mpiMod(Mpi *r, const Mpi *a, const Mpi *p)
Modulo operation.
Definition: mpi.c:1589
error_t mpiMulInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Multiply a multiple precision integer by an integer.
Definition: mpi.c:1457
__weak_func error_t mpiExpModRegular(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (regular calculation)
Definition: mpi.c:2009
@ ERROR_INVALID_PARAMETER
Invalid parameter.
Definition: error.h:47
error_t mpiSubMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular subtraction.
Definition: mpi.c:1676
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:971
__weak_func error_t mpiInvMod(Mpi *r, const Mpi *a, const Mpi *p)
Modular inverse.
Definition: mpi.c:1721
@ MPI_FORMAT_LITTLE_ENDIAN
Definition: mpi.h:92
error_t
Error codes.
Definition: error.h:43
error_t mpiSetValue(Mpi *r, mpi_sword_t a)
Set the value of a multiple precision integer.
Definition: mpi.c:563
error_t mpiAddInt(Mpi *r, const Mpi *a, mpi_sword_t b)
Add an integer to a multiple precision integer.
Definition: mpi.c:942
#define MPI_CHECK(f)
Definition: mpi.h:74
error_t mpiAdd(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision addition.
Definition: mpi.c:893
@ ERROR_FAILURE
Generic error code.
Definition: error.h:45
#define MPI_BYTES_PER_WORD
Definition: mpi.h:56
error_t mpiImport(Mpi *r, const uint8_t *input, size_t length, MpiFormat format)
Octet string to integer conversion.
Definition: mpi.c:714
MPI (Multiple Precision Integer Arithmetic)
@ ERROR_INVALID_LENGTH
Definition: error.h:111
General definitions for cryptographic algorithms.
uint8_t u
Definition: lldp_ext_med.h:213
error_t mpiExport(const Mpi *a, uint8_t *output, size_t length, MpiFormat format)
Integer to octet string conversion.
Definition: mpi.c:811
uint8_t length
Definition: tcp.h:375
#define MPI_BITS_PER_WORD
Definition: mpi.h:47
error_t mpiDiv(Mpi *q, Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision division.
Definition: mpi.c:1487
uint_t mpiGetBitLength(const Mpi *a)
Get the actual length in bits.
Definition: mpi.c:255
#define mpi_word_t
Definition: mpi.h:68
error_t mpiCopy(Mpi *r, const Mpi *a)
Copy a multiple precision integer.
Definition: mpi.c:517
void mpiMulAccCore(mpi_word_t *r, const mpi_word_t *a, int_t m, const mpi_word_t b)
Multiply-accumulate operation.
Definition: mpi_misc.c:159
MpiFormat
MPI import/export format.
Definition: mpi.h:91
#define MAX(a, b)
Definition: os_port.h:67
uint_t mpiGetLength(const Mpi *a)
Get the actual length in words.
Definition: mpi.c:189
char char_t
Definition: compiler_port.h:55
Helper routines for MPI.
error_t mpiDivInt(Mpi *q, Mpi *r, const Mpi *a, mpi_sword_t b)
Divide a multiple precision integer by an integer.
Definition: mpi.c:1560
uint8_t m
Definition: ndp.h:304
uint8_t n
#define MPI_MAX_WORDS
Definition: mpi.h:53
#define cryptoFreeMem(p)
Definition: crypto.h:861
uint8_t value[]
Definition: tcp.h:376
@ MPI_FORMAT_BIG_ENDIAN
Definition: mpi.h:93
#define cryptoAllocMem(size)
Definition: crypto.h:856
uint8_t s
Definition: igmp_common.h:234
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:359
#define mpi_sword_t
Definition: mpi.h:69
int_t mpiCompInt(const Mpi *a, mpi_sword_t b)
Compare a multiple precision integer with an integer.
Definition: mpi.c:430
unsigned int uint_t
Definition: compiler_port.h:57
__weak_func error_t mpiMul(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision multiplication.
Definition: mpi.c:1377
#define osMemset(p, value, length)
Definition: os_port.h:138
uint_t mpiGetBitValue(const Mpi *a, uint_t index)
Get the bit value at the specified index.
Definition: mpi.c:334
error_t mpiAddMod(Mpi *r, const Mpi *a, const Mpi *b, const Mpi *p)
Modular addition.
Definition: mpi.c:1653
error_t mpiGrow(Mpi *r, uint_t size)
Adjust the size of multiple precision integer.
Definition: mpi.c:103
error_t mpiMontgomeryMul(Mpi *r, const Mpi *a, const Mpi *b, uint_t k, const Mpi *p, Mpi *t)
Montgomery multiplication.
Definition: mpi_misc.c:55
__weak_func error_t mpiExpModFast(Mpi *r, const Mpi *a, const Mpi *e, const Mpi *p)
Modular exponentiation (fast calculation)
Definition: mpi.c:1993
@ NO_ERROR
Success.
Definition: error.h:44
uint8_t c
Definition: ndp.h:514
Debugging facilities.
#define arraysize(a)
Definition: os_port.h:71
uint_t mpiGetByteLength(const Mpi *a)
Get the actual length in bytes.
Definition: mpi.c:216
void mpiFree(Mpi *r)
Release a multiple precision integer.
Definition: mpi.c:65
__weak_func error_t mpiCheckProbablePrime(const Mpi *a)
Test whether a number is probable prime.
Definition: mpi.c:695