mpi_misc.c
Go to the documentation of this file.
1 /**
2  * @file mpi_misc.c
3  * @brief Helper routines for MPI
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 Montgomery multiplication
46  * @param[out] r Resulting integer R = A * B / 2^k mod P
47  * @param[in] a An integer A such as 0 <= A < 2^k
48  * @param[in] b An integer B such as 0 <= B < 2^k
49  * @param[in] k An integer k such as P < 2^k
50  * @param[in] p Modulus P
51  * @param[in] t An preallocated integer T (for internal operation)
52  * @return Error code
53  **/
54 
55 error_t mpiMontgomeryMul(Mpi *r, const Mpi *a, const Mpi *b, uint_t k,
56  const Mpi *p, Mpi *t)
57 {
58  error_t error;
59  uint_t i;
60  uint_t n;
61  mpi_word_t m;
62  mpi_word_t q;
63 
64  //Use Newton's method to compute the inverse of P[0] mod 2^32
65  for(m = p->data[0], i = 0; i < 4; i++)
66  {
67  m = m * (2U - m * p->data[0]);
68  }
69 
70  //Precompute -1/P[0] mod 2^32;
71  m = ~m + 1U;
72 
73  //We assume that B is always less than 2^k
74  n = MIN(b->size, k);
75 
76  //Make sure T is large enough
77  MPI_CHECK(mpiGrow(t, 2 * k + 1));
78  //Let T = 0
79  MPI_CHECK(mpiSetValue(t, 0));
80 
81  //Perform Montgomery multiplication
82  for(i = 0; i < k; i++)
83  {
84  //Check current index
85  if(i < a->size)
86  {
87  //Compute q = ((T[i] + A[i] * B[0]) * m) mod 2^32
88  q = (t->data[i] + a->data[i] * b->data[0]) * m;
89  //Compute T = T + A[i] * B
90  mpiMulAccCore(t->data + i, b->data, n, a->data[i]);
91  }
92  else
93  {
94  //Compute q = (T[i] * m) mod 2^32
95  q = t->data[i] * m;
96  }
97 
98  //Compute T = T + q * P
99  mpiMulAccCore(t->data + i, p->data, k, q);
100  }
101 
102  //Compute R = T / 2^(32 * k)
104  MPI_CHECK(mpiCopy(r, t));
105 
106  //A final subtraction is required
107  if(mpiComp(r, p) >= 0)
108  {
109  MPI_CHECK(mpiSub(r, r, p));
110  }
111 
112 end:
113  //Return status code
114  return error;
115 }
116 
117 
118 /**
119  * @brief Montgomery reduction
120  * @param[out] r Resulting integer R = A / 2^k mod P
121  * @param[in] a An integer A such as 0 <= A < 2^k
122  * @param[in] k An integer k such as P < 2^k
123  * @param[in] p Modulus P
124  * @param[in] t An preallocated integer T (for internal operation)
125  * @return Error code
126  **/
127 
128 error_t mpiMontgomeryRed(Mpi *r, const Mpi *a, uint_t k, const Mpi *p, Mpi *t)
129 {
131  Mpi b;
132 
133  //Let B = 1
134  value = 1;
135  b.sign = 1;
136  b.size = 1;
137 
138 #if (CRYPTO_STATIC_MEM_SUPPORT == DISABLED)
139  b.data = &value;
140 #else
141  b.data[0] = value;
142 #endif
143 
144  //Compute R = A / 2^k mod P
145  return mpiMontgomeryMul(r, a, &b, k, p, t);
146 }
147 
148 
149 #if (MPI_ASM_SUPPORT == DISABLED)
150 
151 /**
152  * @brief Multiply-accumulate operation
153  * @param[out] r Resulting integer
154  * @param[in] a First operand A
155  * @param[in] m Size of A in words
156  * @param[in] b Second operand B
157  **/
158 
160  const mpi_word_t b)
161 {
162  int_t i;
163  mpi_word_t c;
164  mpi_word_t u;
165  mpi_word_t v;
166  mpi_dword_t p;
167 
168  //Clear variables
169  c = 0;
170  u = 0;
171  v = 0;
172 
173  //Perform multiplication
174  for(i = 0; i < m; i++)
175  {
176  p = (mpi_dword_t) a[i] * b;
177  u = (mpi_word_t) p;
178  v = (mpi_word_t) (p >> MPI_BITS_PER_WORD);
179 
180  u += c;
181 
182  if(u < c)
183  {
184  v++;
185  }
186 
187  u += r[i];
188 
189  if(u < r[i])
190  {
191  v++;
192  }
193 
194  r[i] = u;
195  c = v;
196  }
197 
198  //Propagate carry
199  for(; c != 0; i++)
200  {
201  r[i] += c;
202  c = (r[i] < c);
203  }
204 }
205 
206 #endif
207 #endif
error_t mpiMontgomeryRed(Mpi *r, const Mpi *a, uint_t k, const Mpi *p, Mpi *t)
Montgomery reduction.
Definition: mpi_misc.c:128
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
uint8_t p
Definition: ndp.h:300
uint8_t t
Definition: lldp_ext_med.h:212
error_t mpiShiftRight(Mpi *r, uint_t n)
Right shift operation.
Definition: mpi.c:1312
uint8_t r
Definition: ndp.h:346
error_t mpiSub(Mpi *r, const Mpi *a, const Mpi *b)
Multiple precision subtraction.
Definition: mpi.c:971
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
#define MPI_CHECK(f)
Definition: mpi.h:74
MPI (Multiple Precision Integer Arithmetic)
#define mpi_dword_t
Definition: mpi.h:70
General definitions for cryptographic algorithms.
uint8_t u
Definition: lldp_ext_med.h:213
#define MPI_BITS_PER_WORD
Definition: mpi.h:47
#define MIN(a, b)
Definition: os_port.h:63
#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
Helper routines for MPI.
uint8_t m
Definition: ndp.h:304
uint8_t n
uint8_t value[]
Definition: tcp.h:376
int_t mpiComp(const Mpi *a, const Mpi *b)
Compare two multiple precision integers.
Definition: mpi.c:359
unsigned int uint_t
Definition: compiler_port.h:57
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
uint8_t c
Definition: ndp.h:514
Debugging facilities.