xref: /aosp_15_r20/external/mbedtls/library/bignum_mod_raw.c (revision 62c56f9862f102b96d72393aff6076c951fb8148)
1*62c56f98SSadaf Ebrahimi /*
2*62c56f98SSadaf Ebrahimi  *  Low-level modular bignum functions
3*62c56f98SSadaf Ebrahimi  *
4*62c56f98SSadaf Ebrahimi  *  Copyright The Mbed TLS Contributors
5*62c56f98SSadaf Ebrahimi  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
6*62c56f98SSadaf Ebrahimi  */
7*62c56f98SSadaf Ebrahimi 
8*62c56f98SSadaf Ebrahimi #include "common.h"
9*62c56f98SSadaf Ebrahimi 
10*62c56f98SSadaf Ebrahimi #if defined(MBEDTLS_BIGNUM_C) && defined(MBEDTLS_ECP_WITH_MPI_UINT)
11*62c56f98SSadaf Ebrahimi 
12*62c56f98SSadaf Ebrahimi #include <string.h>
13*62c56f98SSadaf Ebrahimi 
14*62c56f98SSadaf Ebrahimi #include "mbedtls/error.h"
15*62c56f98SSadaf Ebrahimi #include "mbedtls/platform_util.h"
16*62c56f98SSadaf Ebrahimi 
17*62c56f98SSadaf Ebrahimi #include "mbedtls/platform.h"
18*62c56f98SSadaf Ebrahimi 
19*62c56f98SSadaf Ebrahimi #include "bignum_core.h"
20*62c56f98SSadaf Ebrahimi #include "bignum_mod_raw.h"
21*62c56f98SSadaf Ebrahimi #include "bignum_mod.h"
22*62c56f98SSadaf Ebrahimi #include "constant_time_internal.h"
23*62c56f98SSadaf Ebrahimi 
24*62c56f98SSadaf Ebrahimi #include "bignum_mod_raw_invasive.h"
25*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_mod_modulus * N,unsigned char assign)26*62c56f98SSadaf Ebrahimi void mbedtls_mpi_mod_raw_cond_assign(mbedtls_mpi_uint *X,
27*62c56f98SSadaf Ebrahimi                                      const mbedtls_mpi_uint *A,
28*62c56f98SSadaf Ebrahimi                                      const mbedtls_mpi_mod_modulus *N,
29*62c56f98SSadaf Ebrahimi                                      unsigned char assign)
30*62c56f98SSadaf Ebrahimi {
31*62c56f98SSadaf Ebrahimi     mbedtls_mpi_core_cond_assign(X, A, N->limbs, mbedtls_ct_bool(assign));
32*62c56f98SSadaf Ebrahimi }
33*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint * X,mbedtls_mpi_uint * Y,const mbedtls_mpi_mod_modulus * N,unsigned char swap)34*62c56f98SSadaf Ebrahimi void mbedtls_mpi_mod_raw_cond_swap(mbedtls_mpi_uint *X,
35*62c56f98SSadaf Ebrahimi                                    mbedtls_mpi_uint *Y,
36*62c56f98SSadaf Ebrahimi                                    const mbedtls_mpi_mod_modulus *N,
37*62c56f98SSadaf Ebrahimi                                    unsigned char swap)
38*62c56f98SSadaf Ebrahimi {
39*62c56f98SSadaf Ebrahimi     mbedtls_mpi_core_cond_swap(X, Y, N->limbs, mbedtls_ct_bool(swap));
40*62c56f98SSadaf Ebrahimi }
41*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * N,const unsigned char * input,size_t input_length,mbedtls_mpi_mod_ext_rep ext_rep)42*62c56f98SSadaf Ebrahimi int mbedtls_mpi_mod_raw_read(mbedtls_mpi_uint *X,
43*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_mod_modulus *N,
44*62c56f98SSadaf Ebrahimi                              const unsigned char *input,
45*62c56f98SSadaf Ebrahimi                              size_t input_length,
46*62c56f98SSadaf Ebrahimi                              mbedtls_mpi_mod_ext_rep ext_rep)
47*62c56f98SSadaf Ebrahimi {
48*62c56f98SSadaf Ebrahimi     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
49*62c56f98SSadaf Ebrahimi 
50*62c56f98SSadaf Ebrahimi     switch (ext_rep) {
51*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_EXT_REP_LE:
52*62c56f98SSadaf Ebrahimi             ret = mbedtls_mpi_core_read_le(X, N->limbs,
53*62c56f98SSadaf Ebrahimi                                            input, input_length);
54*62c56f98SSadaf Ebrahimi             break;
55*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_EXT_REP_BE:
56*62c56f98SSadaf Ebrahimi             ret = mbedtls_mpi_core_read_be(X, N->limbs,
57*62c56f98SSadaf Ebrahimi                                            input, input_length);
58*62c56f98SSadaf Ebrahimi             break;
59*62c56f98SSadaf Ebrahimi         default:
60*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
61*62c56f98SSadaf Ebrahimi     }
62*62c56f98SSadaf Ebrahimi 
63*62c56f98SSadaf Ebrahimi     if (ret != 0) {
64*62c56f98SSadaf Ebrahimi         goto cleanup;
65*62c56f98SSadaf Ebrahimi     }
66*62c56f98SSadaf Ebrahimi 
67*62c56f98SSadaf Ebrahimi     if (!mbedtls_mpi_core_lt_ct(X, N->p, N->limbs)) {
68*62c56f98SSadaf Ebrahimi         ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
69*62c56f98SSadaf Ebrahimi         goto cleanup;
70*62c56f98SSadaf Ebrahimi     }
71*62c56f98SSadaf Ebrahimi 
72*62c56f98SSadaf Ebrahimi cleanup:
73*62c56f98SSadaf Ebrahimi 
74*62c56f98SSadaf Ebrahimi     return ret;
75*62c56f98SSadaf Ebrahimi }
76*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint * A,const mbedtls_mpi_mod_modulus * N,unsigned char * output,size_t output_length,mbedtls_mpi_mod_ext_rep ext_rep)77*62c56f98SSadaf Ebrahimi int mbedtls_mpi_mod_raw_write(const mbedtls_mpi_uint *A,
78*62c56f98SSadaf Ebrahimi                               const mbedtls_mpi_mod_modulus *N,
79*62c56f98SSadaf Ebrahimi                               unsigned char *output,
80*62c56f98SSadaf Ebrahimi                               size_t output_length,
81*62c56f98SSadaf Ebrahimi                               mbedtls_mpi_mod_ext_rep ext_rep)
82*62c56f98SSadaf Ebrahimi {
83*62c56f98SSadaf Ebrahimi     switch (ext_rep) {
84*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_EXT_REP_LE:
85*62c56f98SSadaf Ebrahimi             return mbedtls_mpi_core_write_le(A, N->limbs,
86*62c56f98SSadaf Ebrahimi                                              output, output_length);
87*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_EXT_REP_BE:
88*62c56f98SSadaf Ebrahimi             return mbedtls_mpi_core_write_be(A, N->limbs,
89*62c56f98SSadaf Ebrahimi                                              output, output_length);
90*62c56f98SSadaf Ebrahimi         default:
91*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
92*62c56f98SSadaf Ebrahimi     }
93*62c56f98SSadaf Ebrahimi }
94*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_sub(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_uint * B,const mbedtls_mpi_mod_modulus * N)95*62c56f98SSadaf Ebrahimi void mbedtls_mpi_mod_raw_sub(mbedtls_mpi_uint *X,
96*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_uint *A,
97*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_uint *B,
98*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_mod_modulus *N)
99*62c56f98SSadaf Ebrahimi {
100*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, A, B, N->limbs);
101*62c56f98SSadaf Ebrahimi 
102*62c56f98SSadaf Ebrahimi     (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c);
103*62c56f98SSadaf Ebrahimi }
104*62c56f98SSadaf Ebrahimi 
105*62c56f98SSadaf Ebrahimi MBEDTLS_STATIC_TESTABLE
mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * N)106*62c56f98SSadaf Ebrahimi void mbedtls_mpi_mod_raw_fix_quasi_reduction(mbedtls_mpi_uint *X,
107*62c56f98SSadaf Ebrahimi                                              const mbedtls_mpi_mod_modulus *N)
108*62c56f98SSadaf Ebrahimi {
109*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint c = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
110*62c56f98SSadaf Ebrahimi 
111*62c56f98SSadaf Ebrahimi     (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) c);
112*62c56f98SSadaf Ebrahimi }
113*62c56f98SSadaf Ebrahimi 
114*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_uint * B,const mbedtls_mpi_mod_modulus * N,mbedtls_mpi_uint * T)115*62c56f98SSadaf Ebrahimi void mbedtls_mpi_mod_raw_mul(mbedtls_mpi_uint *X,
116*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_uint *A,
117*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_uint *B,
118*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_mod_modulus *N,
119*62c56f98SSadaf Ebrahimi                              mbedtls_mpi_uint *T)
120*62c56f98SSadaf Ebrahimi {
121*62c56f98SSadaf Ebrahimi     /* Standard (A * B) multiplication stored into pre-allocated T
122*62c56f98SSadaf Ebrahimi      * buffer of fixed limb size of (2N + 1).
123*62c56f98SSadaf Ebrahimi      *
124*62c56f98SSadaf Ebrahimi      * The space may not not fully filled by when
125*62c56f98SSadaf Ebrahimi      * MBEDTLS_MPI_MOD_REP_OPT_RED is used. */
126*62c56f98SSadaf Ebrahimi     const size_t T_limbs = BITS_TO_LIMBS(N->bits) * 2;
127*62c56f98SSadaf Ebrahimi     switch (N->int_rep) {
128*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
129*62c56f98SSadaf Ebrahimi             mbedtls_mpi_core_montmul(X, A, B, N->limbs, N->p, N->limbs,
130*62c56f98SSadaf Ebrahimi                                      N->rep.mont.mm, T);
131*62c56f98SSadaf Ebrahimi             break;
132*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_REP_OPT_RED:
133*62c56f98SSadaf Ebrahimi             mbedtls_mpi_core_mul(T, A, N->limbs, B, N->limbs);
134*62c56f98SSadaf Ebrahimi 
135*62c56f98SSadaf Ebrahimi             /* Optimised Reduction */
136*62c56f98SSadaf Ebrahimi             (*N->rep.ored.modp)(T, T_limbs);
137*62c56f98SSadaf Ebrahimi 
138*62c56f98SSadaf Ebrahimi             /* Convert back to canonical representation */
139*62c56f98SSadaf Ebrahimi             mbedtls_mpi_mod_raw_fix_quasi_reduction(T, N);
140*62c56f98SSadaf Ebrahimi             memcpy(X, T, N->limbs * sizeof(mbedtls_mpi_uint));
141*62c56f98SSadaf Ebrahimi             break;
142*62c56f98SSadaf Ebrahimi         default:
143*62c56f98SSadaf Ebrahimi             break;
144*62c56f98SSadaf Ebrahimi     }
145*62c56f98SSadaf Ebrahimi 
146*62c56f98SSadaf Ebrahimi }
147*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_inv_prime_working_limbs(size_t AN_limbs)148*62c56f98SSadaf Ebrahimi size_t mbedtls_mpi_mod_raw_inv_prime_working_limbs(size_t AN_limbs)
149*62c56f98SSadaf Ebrahimi {
150*62c56f98SSadaf Ebrahimi     /* mbedtls_mpi_mod_raw_inv_prime() needs a temporary for the exponent,
151*62c56f98SSadaf Ebrahimi      * which will be the same size as the modulus and input (AN_limbs),
152*62c56f98SSadaf Ebrahimi      * and additional space to pass to mbedtls_mpi_core_exp_mod(). */
153*62c56f98SSadaf Ebrahimi     return AN_limbs +
154*62c56f98SSadaf Ebrahimi            mbedtls_mpi_core_exp_mod_working_limbs(AN_limbs, AN_limbs);
155*62c56f98SSadaf Ebrahimi }
156*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_inv_prime(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_uint * N,size_t AN_limbs,const mbedtls_mpi_uint * RR,mbedtls_mpi_uint * T)157*62c56f98SSadaf Ebrahimi void mbedtls_mpi_mod_raw_inv_prime(mbedtls_mpi_uint *X,
158*62c56f98SSadaf Ebrahimi                                    const mbedtls_mpi_uint *A,
159*62c56f98SSadaf Ebrahimi                                    const mbedtls_mpi_uint *N,
160*62c56f98SSadaf Ebrahimi                                    size_t AN_limbs,
161*62c56f98SSadaf Ebrahimi                                    const mbedtls_mpi_uint *RR,
162*62c56f98SSadaf Ebrahimi                                    mbedtls_mpi_uint *T)
163*62c56f98SSadaf Ebrahimi {
164*62c56f98SSadaf Ebrahimi     /* Inversion by power: g^|G| = 1 => g^(-1) = g^(|G|-1), and
165*62c56f98SSadaf Ebrahimi      *                       |G| = N - 1, so we want
166*62c56f98SSadaf Ebrahimi      *                 g^(|G|-1) = g^(N - 2)
167*62c56f98SSadaf Ebrahimi      */
168*62c56f98SSadaf Ebrahimi 
169*62c56f98SSadaf Ebrahimi     /* Use the first AN_limbs of T to hold N - 2 */
170*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint *Nminus2 = T;
171*62c56f98SSadaf Ebrahimi     (void) mbedtls_mpi_core_sub_int(Nminus2, N, 2, AN_limbs);
172*62c56f98SSadaf Ebrahimi 
173*62c56f98SSadaf Ebrahimi     /* Rest of T is given to exp_mod for its working space */
174*62c56f98SSadaf Ebrahimi     mbedtls_mpi_core_exp_mod(X,
175*62c56f98SSadaf Ebrahimi                              A, N, AN_limbs, Nminus2, AN_limbs,
176*62c56f98SSadaf Ebrahimi                              RR, T + AN_limbs);
177*62c56f98SSadaf Ebrahimi }
178*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_add(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_uint * B,const mbedtls_mpi_mod_modulus * N)179*62c56f98SSadaf Ebrahimi void mbedtls_mpi_mod_raw_add(mbedtls_mpi_uint *X,
180*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_uint *A,
181*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_uint *B,
182*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_mod_modulus *N)
183*62c56f98SSadaf Ebrahimi {
184*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint carry, borrow;
185*62c56f98SSadaf Ebrahimi     carry  = mbedtls_mpi_core_add(X, A, B, N->limbs);
186*62c56f98SSadaf Ebrahimi     borrow = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
187*62c56f98SSadaf Ebrahimi     (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) (carry ^ borrow));
188*62c56f98SSadaf Ebrahimi }
189*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_canonical_to_modulus_rep(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * N)190*62c56f98SSadaf Ebrahimi int mbedtls_mpi_mod_raw_canonical_to_modulus_rep(
191*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint *X,
192*62c56f98SSadaf Ebrahimi     const mbedtls_mpi_mod_modulus *N)
193*62c56f98SSadaf Ebrahimi {
194*62c56f98SSadaf Ebrahimi     switch (N->int_rep) {
195*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
196*62c56f98SSadaf Ebrahimi             return mbedtls_mpi_mod_raw_to_mont_rep(X, N);
197*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_REP_OPT_RED:
198*62c56f98SSadaf Ebrahimi             return 0;
199*62c56f98SSadaf Ebrahimi         default:
200*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
201*62c56f98SSadaf Ebrahimi     }
202*62c56f98SSadaf Ebrahimi }
203*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_modulus_to_canonical_rep(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * N)204*62c56f98SSadaf Ebrahimi int mbedtls_mpi_mod_raw_modulus_to_canonical_rep(
205*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint *X,
206*62c56f98SSadaf Ebrahimi     const mbedtls_mpi_mod_modulus *N)
207*62c56f98SSadaf Ebrahimi {
208*62c56f98SSadaf Ebrahimi     switch (N->int_rep) {
209*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_REP_MONTGOMERY:
210*62c56f98SSadaf Ebrahimi             return mbedtls_mpi_mod_raw_from_mont_rep(X, N);
211*62c56f98SSadaf Ebrahimi         case MBEDTLS_MPI_MOD_REP_OPT_RED:
212*62c56f98SSadaf Ebrahimi             return 0;
213*62c56f98SSadaf Ebrahimi         default:
214*62c56f98SSadaf Ebrahimi             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
215*62c56f98SSadaf Ebrahimi     }
216*62c56f98SSadaf Ebrahimi }
217*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_random(mbedtls_mpi_uint * X,mbedtls_mpi_uint min,const mbedtls_mpi_mod_modulus * N,int (* f_rng)(void *,unsigned char *,size_t),void * p_rng)218*62c56f98SSadaf Ebrahimi int mbedtls_mpi_mod_raw_random(mbedtls_mpi_uint *X,
219*62c56f98SSadaf Ebrahimi                                mbedtls_mpi_uint min,
220*62c56f98SSadaf Ebrahimi                                const mbedtls_mpi_mod_modulus *N,
221*62c56f98SSadaf Ebrahimi                                int (*f_rng)(void *, unsigned char *, size_t),
222*62c56f98SSadaf Ebrahimi                                void *p_rng)
223*62c56f98SSadaf Ebrahimi {
224*62c56f98SSadaf Ebrahimi     int ret = mbedtls_mpi_core_random(X, min, N->p, N->limbs, f_rng, p_rng);
225*62c56f98SSadaf Ebrahimi     if (ret != 0) {
226*62c56f98SSadaf Ebrahimi         return ret;
227*62c56f98SSadaf Ebrahimi     }
228*62c56f98SSadaf Ebrahimi     return mbedtls_mpi_mod_raw_canonical_to_modulus_rep(X, N);
229*62c56f98SSadaf Ebrahimi }
230*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * N)231*62c56f98SSadaf Ebrahimi int mbedtls_mpi_mod_raw_to_mont_rep(mbedtls_mpi_uint *X,
232*62c56f98SSadaf Ebrahimi                                     const mbedtls_mpi_mod_modulus *N)
233*62c56f98SSadaf Ebrahimi {
234*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint *T;
235*62c56f98SSadaf Ebrahimi     const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs);
236*62c56f98SSadaf Ebrahimi 
237*62c56f98SSadaf Ebrahimi     if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) {
238*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
239*62c56f98SSadaf Ebrahimi     }
240*62c56f98SSadaf Ebrahimi 
241*62c56f98SSadaf Ebrahimi     mbedtls_mpi_core_to_mont_rep(X, X, N->p, N->limbs,
242*62c56f98SSadaf Ebrahimi                                  N->rep.mont.mm, N->rep.mont.rr, T);
243*62c56f98SSadaf Ebrahimi 
244*62c56f98SSadaf Ebrahimi     mbedtls_zeroize_and_free(T, t_limbs * ciL);
245*62c56f98SSadaf Ebrahimi     return 0;
246*62c56f98SSadaf Ebrahimi }
247*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint * X,const mbedtls_mpi_mod_modulus * N)248*62c56f98SSadaf Ebrahimi int mbedtls_mpi_mod_raw_from_mont_rep(mbedtls_mpi_uint *X,
249*62c56f98SSadaf Ebrahimi                                       const mbedtls_mpi_mod_modulus *N)
250*62c56f98SSadaf Ebrahimi {
251*62c56f98SSadaf Ebrahimi     const size_t t_limbs = mbedtls_mpi_core_montmul_working_limbs(N->limbs);
252*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint *T;
253*62c56f98SSadaf Ebrahimi 
254*62c56f98SSadaf Ebrahimi     if ((T = (mbedtls_mpi_uint *) mbedtls_calloc(t_limbs, ciL)) == NULL) {
255*62c56f98SSadaf Ebrahimi         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
256*62c56f98SSadaf Ebrahimi     }
257*62c56f98SSadaf Ebrahimi 
258*62c56f98SSadaf Ebrahimi     mbedtls_mpi_core_from_mont_rep(X, X, N->p, N->limbs, N->rep.mont.mm, T);
259*62c56f98SSadaf Ebrahimi 
260*62c56f98SSadaf Ebrahimi     mbedtls_zeroize_and_free(T, t_limbs * ciL);
261*62c56f98SSadaf Ebrahimi     return 0;
262*62c56f98SSadaf Ebrahimi }
263*62c56f98SSadaf Ebrahimi 
mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint * X,const mbedtls_mpi_uint * A,const mbedtls_mpi_mod_modulus * N)264*62c56f98SSadaf Ebrahimi void mbedtls_mpi_mod_raw_neg(mbedtls_mpi_uint *X,
265*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_uint *A,
266*62c56f98SSadaf Ebrahimi                              const mbedtls_mpi_mod_modulus *N)
267*62c56f98SSadaf Ebrahimi {
268*62c56f98SSadaf Ebrahimi     mbedtls_mpi_core_sub(X, N->p, A, N->limbs);
269*62c56f98SSadaf Ebrahimi 
270*62c56f98SSadaf Ebrahimi     /* If A=0 initially, then X=N now. Detect this by
271*62c56f98SSadaf Ebrahimi      * subtracting N and catching the carry. */
272*62c56f98SSadaf Ebrahimi     mbedtls_mpi_uint borrow = mbedtls_mpi_core_sub(X, X, N->p, N->limbs);
273*62c56f98SSadaf Ebrahimi     (void) mbedtls_mpi_core_add_if(X, N->p, N->limbs, (unsigned) borrow);
274*62c56f98SSadaf Ebrahimi }
275*62c56f98SSadaf Ebrahimi 
276*62c56f98SSadaf Ebrahimi #endif /* MBEDTLS_BIGNUM_C && MBEDTLS_ECP_WITH_MPI_UINT */
277