LCOV - code coverage report
Current view: top level - os_stub/mbedtlslib/mbedtls/library - bignum.c (source / functions) Coverage Total Hit
Test: coverage.info Lines: 47.3 % 941 445
Test Date: 2025-11-23 08:10:21 Functions: 65.6 % 61 40

            Line data    Source code
       1              : /*
       2              :  *  Multi-precision integer library
       3              :  *
       4              :  *  Copyright The Mbed TLS Contributors
       5              :  *  SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later
       6              :  */
       7              : 
       8              : /*
       9              :  *  The following sources were referenced in the design of this Multi-precision
      10              :  *  Integer library:
      11              :  *
      12              :  *  [1] Handbook of Applied Cryptography - 1997
      13              :  *      Menezes, van Oorschot and Vanstone
      14              :  *
      15              :  *  [2] Multi-Precision Math
      16              :  *      Tom St Denis
      17              :  *      https://github.com/libtom/libtommath/blob/develop/tommath.pdf
      18              :  *
      19              :  *  [3] GNU Multi-Precision Arithmetic Library
      20              :  *      https://gmplib.org/manual/index.html
      21              :  *
      22              :  */
      23              : 
      24              : #include "common.h"
      25              : 
      26              : #if defined(MBEDTLS_BIGNUM_C)
      27              : 
      28              : #include "mbedtls/bignum.h"
      29              : #include "bignum_core.h"
      30              : #include "bignum_internal.h"
      31              : #include "bn_mul.h"
      32              : #include "mbedtls/platform_util.h"
      33              : #include "mbedtls/error.h"
      34              : #include "constant_time_internal.h"
      35              : 
      36              : #include <limits.h>
      37              : #include <string.h>
      38              : 
      39              : #include "mbedtls/platform.h"
      40              : 
      41              : 
      42              : 
      43              : /*
      44              :  * Conditionally select an MPI sign in constant time.
      45              :  * (MPI sign is the field s in mbedtls_mpi. It is unsigned short and only 1 and -1 are valid
      46              :  * values.)
      47              :  */
      48      4923341 : static inline signed short mbedtls_ct_mpi_sign_if(mbedtls_ct_condition_t cond,
      49              :                                                   signed short sign1, signed short sign2)
      50              : {
      51      4923341 :     return (signed short) mbedtls_ct_uint_if(cond, sign1 + 1, sign2 + 1) - 1;
      52              : }
      53              : 
      54              : /*
      55              :  * Compare signed values in constant time
      56              :  */
      57            0 : int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X,
      58              :                           const mbedtls_mpi *Y,
      59              :                           unsigned *ret)
      60              : {
      61              :     mbedtls_ct_condition_t different_sign, X_is_negative, Y_is_negative, result;
      62              : 
      63            0 :     if (X->n != Y->n) {
      64            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
      65              :     }
      66              : 
      67              :     /*
      68              :      * Set N_is_negative to MBEDTLS_CT_FALSE if N >= 0, MBEDTLS_CT_TRUE if N < 0.
      69              :      * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
      70              :      */
      71            0 :     X_is_negative = mbedtls_ct_bool((X->s & 2) >> 1);
      72            0 :     Y_is_negative = mbedtls_ct_bool((Y->s & 2) >> 1);
      73              : 
      74              :     /*
      75              :      * If the signs are different, then the positive operand is the bigger.
      76              :      * That is if X is negative (X_is_negative == 1), then X < Y is true and it
      77              :      * is false if X is positive (X_is_negative == 0).
      78              :      */
      79            0 :     different_sign = mbedtls_ct_bool_ne(X_is_negative, Y_is_negative); // true if different sign
      80            0 :     result = mbedtls_ct_bool_and(different_sign, X_is_negative);
      81              : 
      82              :     /*
      83              :      * Assuming signs are the same, compare X and Y. We switch the comparison
      84              :      * order if they are negative so that we get the right result, regardles of
      85              :      * sign.
      86              :      */
      87              : 
      88              :     /* This array is used to conditionally swap the pointers in const time */
      89            0 :     void * const p[2] = { X->p, Y->p };
      90            0 :     size_t i = mbedtls_ct_size_if_else_0(X_is_negative, 1);
      91            0 :     mbedtls_ct_condition_t lt = mbedtls_mpi_core_lt_ct(p[i], p[i ^ 1], X->n);
      92              : 
      93              :     /*
      94              :      * Store in result iff the signs are the same (i.e., iff different_sign == false). If
      95              :      * the signs differ, result has already been set, so we don't change it.
      96              :      */
      97            0 :     result = mbedtls_ct_bool_or(result,
      98              :                                 mbedtls_ct_bool_and(mbedtls_ct_bool_not(different_sign), lt));
      99              : 
     100            0 :     *ret = mbedtls_ct_uint_if_else_0(result, 1);
     101              : 
     102            0 :     return 0;
     103              : }
     104              : 
     105              : /*
     106              :  * Conditionally assign X = Y, without leaking information
     107              :  * about whether the assignment was made or not.
     108              :  * (Leaking information about the respective sizes of X and Y is ok however.)
     109              :  */
     110              : #if defined(_MSC_VER) && defined(MBEDTLS_PLATFORM_IS_WINDOWS_ON_ARM64) && \
     111              :     (_MSC_FULL_VER < 193131103)
     112              : /*
     113              :  * MSVC miscompiles this function if it's inlined prior to Visual Studio 2022 version 17.1. See:
     114              :  * https://developercommunity.visualstudio.com/t/c-compiler-miscompiles-part-of-mbedtls-library-on/1646989
     115              :  */
     116              : __declspec(noinline)
     117              : #endif
     118      4923341 : int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X,
     119              :                                  const mbedtls_mpi *Y,
     120              :                                  unsigned char assign)
     121              : {
     122      4923341 :     int ret = 0;
     123              : 
     124      4923341 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
     125              : 
     126              :     {
     127      4923341 :         mbedtls_ct_condition_t do_assign = mbedtls_ct_bool(assign);
     128              : 
     129      4923341 :         X->s = mbedtls_ct_mpi_sign_if(do_assign, Y->s, X->s);
     130              : 
     131      4923341 :         mbedtls_mpi_core_cond_assign(X->p, Y->p, Y->n, do_assign);
     132              : 
     133      4923341 :         mbedtls_ct_condition_t do_not_assign = mbedtls_ct_bool_not(do_assign);
     134      4940296 :         for (size_t i = Y->n; i < X->n; i++) {
     135        16955 :             X->p[i] = mbedtls_ct_mpi_uint_if_else_0(do_not_assign, X->p[i]);
     136              :         }
     137              :     }
     138              : 
     139      4923341 : cleanup:
     140      4923341 :     return ret;
     141              : }
     142              : 
     143              : /*
     144              :  * Conditionally swap X and Y, without leaking information
     145              :  * about whether the swap was made or not.
     146              :  * Here it is not ok to simply swap the pointers, which would lead to
     147              :  * different memory access patterns when X and Y are used afterwards.
     148              :  */
     149            0 : int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X,
     150              :                                mbedtls_mpi *Y,
     151              :                                unsigned char swap)
     152              : {
     153            0 :     int ret = 0;
     154              :     int s;
     155              : 
     156            0 :     if (X == Y) {
     157            0 :         return 0;
     158              :     }
     159              : 
     160            0 :     mbedtls_ct_condition_t do_swap = mbedtls_ct_bool(swap);
     161              : 
     162            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
     163            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
     164              : 
     165            0 :     s = X->s;
     166            0 :     X->s = mbedtls_ct_mpi_sign_if(do_swap, Y->s, X->s);
     167            0 :     Y->s = mbedtls_ct_mpi_sign_if(do_swap, s, Y->s);
     168              : 
     169            0 :     mbedtls_mpi_core_cond_swap(X->p, Y->p, X->n, do_swap);
     170              : 
     171            0 : cleanup:
     172            0 :     return ret;
     173              : }
     174              : 
     175              : /* Implementation that should never be optimized out by the compiler */
     176              : #define mbedtls_mpi_zeroize_and_free(v, n) mbedtls_zeroize_and_free(v, ciL * (n))
     177              : 
     178              : /*
     179              :  * Initialize one MPI
     180              :  */
     181     13542782 : void mbedtls_mpi_init(mbedtls_mpi *X)
     182              : {
     183     13542782 :     X->s = 1;
     184     13542782 :     X->n = 0;
     185     13542782 :     X->p = NULL;
     186     13542782 : }
     187              : 
     188              : /*
     189              :  * Unallocate one MPI
     190              :  */
     191     13500417 : void mbedtls_mpi_free(mbedtls_mpi *X)
     192              : {
     193     13500417 :     if (X == NULL) {
     194            0 :         return;
     195              :     }
     196              : 
     197     13500417 :     if (X->p != NULL) {
     198      2283870 :         mbedtls_mpi_zeroize_and_free(X->p, X->n);
     199              :     }
     200              : 
     201     13500417 :     X->s = 1;
     202     13500417 :     X->n = 0;
     203     13500417 :     X->p = NULL;
     204              : }
     205              : 
     206              : /*
     207              :  * Enlarge to the specified number of limbs
     208              :  */
     209     41695373 : int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs)
     210              : {
     211              :     mbedtls_mpi_uint *p;
     212              : 
     213     41695373 :     if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
     214            0 :         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     215              :     }
     216              : 
     217     41695373 :     if (X->n < nblimbs) {
     218      2477091 :         if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(nblimbs, ciL)) == NULL) {
     219            0 :             return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     220              :         }
     221              : 
     222      2477091 :         if (X->p != NULL) {
     223       192461 :             memcpy(p, X->p, X->n * ciL);
     224       192461 :             mbedtls_mpi_zeroize_and_free(X->p, X->n);
     225              :         }
     226              : 
     227              :         /* nblimbs fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
     228              :          * fits, and we've checked that nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */
     229      2477091 :         X->n = (unsigned short) nblimbs;
     230      2477091 :         X->p = p;
     231              :     }
     232              : 
     233     41695373 :     return 0;
     234              : }
     235              : 
     236              : /*
     237              :  * Resize down as much as possible,
     238              :  * while keeping at least the specified number of limbs
     239              :  */
     240        31952 : int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs)
     241              : {
     242              :     mbedtls_mpi_uint *p;
     243              :     size_t i;
     244              : 
     245        31952 :     if (nblimbs > MBEDTLS_MPI_MAX_LIMBS) {
     246            0 :         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     247              :     }
     248              : 
     249              :     /* Actually resize up if there are currently fewer than nblimbs limbs. */
     250        31952 :     if (X->n <= nblimbs) {
     251            0 :         return mbedtls_mpi_grow(X, nblimbs);
     252              :     }
     253              :     /* After this point, then X->n > nblimbs and in particular X->n > 0. */
     254              : 
     255       212010 :     for (i = X->n - 1; i > 0; i--) {
     256       212010 :         if (X->p[i] != 0) {
     257        31952 :             break;
     258              :         }
     259              :     }
     260        31952 :     i++;
     261              : 
     262        31952 :     if (i < nblimbs) {
     263          281 :         i = nblimbs;
     264              :     }
     265              : 
     266        31952 :     if ((p = (mbedtls_mpi_uint *) mbedtls_calloc(i, ciL)) == NULL) {
     267            0 :         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
     268              :     }
     269              : 
     270        31952 :     if (X->p != NULL) {
     271        31952 :         memcpy(p, X->p, i * ciL);
     272        31952 :         mbedtls_mpi_zeroize_and_free(X->p, X->n);
     273              :     }
     274              : 
     275              :     /* i fits in n because we ensure that MBEDTLS_MPI_MAX_LIMBS
     276              :      * fits, and we've checked that i <= nblimbs <= MBEDTLS_MPI_MAX_LIMBS. */
     277        31952 :     X->n = (unsigned short) i;
     278        31952 :     X->p = p;
     279              : 
     280        31952 :     return 0;
     281              : }
     282              : 
     283              : /* Resize X to have exactly n limbs and set it to 0. */
     284        34749 : static int mbedtls_mpi_resize_clear(mbedtls_mpi *X, size_t limbs)
     285              : {
     286        34749 :     if (limbs == 0) {
     287            0 :         mbedtls_mpi_free(X);
     288            0 :         return 0;
     289        34749 :     } else if (X->n == limbs) {
     290          110 :         memset(X->p, 0, limbs * ciL);
     291          110 :         X->s = 1;
     292          110 :         return 0;
     293              :     } else {
     294        34639 :         mbedtls_mpi_free(X);
     295        34639 :         return mbedtls_mpi_grow(X, limbs);
     296              :     }
     297              : }
     298              : 
     299              : /*
     300              :  * Copy the contents of Y into X.
     301              :  *
     302              :  * This function is not constant-time. Leading zeros in Y may be removed.
     303              :  *
     304              :  * Ensure that X does not shrink. This is not guaranteed by the public API,
     305              :  * but some code in the bignum module might still rely on this property.
     306              :  */
     307      4702031 : int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y)
     308              : {
     309      4702031 :     int ret = 0;
     310              :     size_t i;
     311              : 
     312      4702031 :     if (X == Y) {
     313        67388 :         return 0;
     314              :     }
     315              : 
     316      4634643 :     if (Y->n == 0) {
     317         2247 :         if (X->n != 0) {
     318            0 :             X->s = 1;
     319            0 :             memset(X->p, 0, X->n * ciL);
     320              :         }
     321         2247 :         return 0;
     322              :     }
     323              : 
     324     27236970 :     for (i = Y->n - 1; i > 0; i--) {
     325     27219704 :         if (Y->p[i] != 0) {
     326      4615130 :             break;
     327              :         }
     328              :     }
     329      4632396 :     i++;
     330              : 
     331      4632396 :     X->s = Y->s;
     332              : 
     333      4632396 :     if (X->n < i) {
     334      1900654 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i));
     335              :     } else {
     336      2731742 :         memset(X->p + i, 0, (X->n - i) * ciL);
     337              :     }
     338              : 
     339      4632396 :     memcpy(X->p, Y->p, i * ciL);
     340              : 
     341      4632396 : cleanup:
     342              : 
     343      4632396 :     return ret;
     344              : }
     345              : 
     346              : /*
     347              :  * Swap the contents of X and Y
     348              :  */
     349            0 : void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y)
     350              : {
     351              :     mbedtls_mpi T;
     352              : 
     353            0 :     memcpy(&T,  X, sizeof(mbedtls_mpi));
     354            0 :     memcpy(X,  Y, sizeof(mbedtls_mpi));
     355            0 :     memcpy(Y, &T, sizeof(mbedtls_mpi));
     356            0 : }
     357              : 
     358     15046979 : static inline mbedtls_mpi_uint mpi_sint_abs(mbedtls_mpi_sint z)
     359              : {
     360     15046979 :     if (z >= 0) {
     361     15043979 :         return z;
     362              :     }
     363              :     /* Take care to handle the most negative value (-2^(biL-1)) correctly.
     364              :      * A naive -z would have undefined behavior.
     365              :      * Write this in a way that makes popular compilers happy (GCC, Clang,
     366              :      * MSVC). */
     367         3000 :     return (mbedtls_mpi_uint) 0 - (mbedtls_mpi_uint) z;
     368              : }
     369              : 
     370              : /* Convert x to a sign, i.e. to 1, if x is positive, or -1, if x is negative.
     371              :  * This looks awkward but generates smaller code than (x < 0 ? -1 : 1) */
     372              : #define TO_SIGN(x) ((mbedtls_mpi_sint) (((mbedtls_mpi_uint) x) >> (biL - 1)) * -2 + 1)
     373              : 
     374              : /*
     375              :  * Set value from integer
     376              :  */
     377      6742495 : int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z)
     378              : {
     379      6742495 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     380              : 
     381      6742495 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1));
     382      6742495 :     memset(X->p, 0, X->n * ciL);
     383              : 
     384      6742495 :     X->p[0] = mpi_sint_abs(z);
     385      6742495 :     X->s    = TO_SIGN(z);
     386              : 
     387      6742495 : cleanup:
     388              : 
     389      6742495 :     return ret;
     390              : }
     391              : 
     392              : /*
     393              :  * Get a specific bit
     394              :  */
     395       896840 : int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos)
     396              : {
     397       896840 :     if (X->n * biL <= pos) {
     398         7264 :         return 0;
     399              :     }
     400              : 
     401       889576 :     return (X->p[pos / biL] >> (pos % biL)) & 0x01;
     402              : }
     403              : 
     404              : /*
     405              :  * Set a bit to a specific value of 0 or 1
     406              :  */
     407            0 : int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val)
     408              : {
     409            0 :     int ret = 0;
     410            0 :     size_t off = pos / biL;
     411            0 :     size_t idx = pos % biL;
     412              : 
     413            0 :     if (val != 0 && val != 1) {
     414            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     415              :     }
     416              : 
     417            0 :     if (X->n * biL <= pos) {
     418            0 :         if (val == 0) {
     419            0 :             return 0;
     420              :         }
     421              : 
     422            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, off + 1));
     423              :     }
     424              : 
     425            0 :     X->p[off] &= ~((mbedtls_mpi_uint) 0x01 << idx);
     426            0 :     X->p[off] |= (mbedtls_mpi_uint) val << idx;
     427              : 
     428            0 : cleanup:
     429              : 
     430            0 :     return ret;
     431              : }
     432              : 
     433              : #if defined(__has_builtin)
     434              : #if (MBEDTLS_MPI_UINT_MAX == UINT_MAX) && __has_builtin(__builtin_ctz)
     435              :     #define mbedtls_mpi_uint_ctz __builtin_ctz
     436              : #elif (MBEDTLS_MPI_UINT_MAX == ULONG_MAX) && __has_builtin(__builtin_ctzl)
     437              :     #define mbedtls_mpi_uint_ctz __builtin_ctzl
     438              : #elif (MBEDTLS_MPI_UINT_MAX == ULLONG_MAX) && __has_builtin(__builtin_ctzll)
     439              :     #define mbedtls_mpi_uint_ctz __builtin_ctzll
     440              : #endif
     441              : #endif
     442              : 
     443              : #if !defined(mbedtls_mpi_uint_ctz)
     444              : static size_t mbedtls_mpi_uint_ctz(mbedtls_mpi_uint x)
     445              : {
     446              :     size_t count = 0;
     447              :     mbedtls_ct_condition_t done = MBEDTLS_CT_FALSE;
     448              : 
     449              :     for (size_t i = 0; i < biL; i++) {
     450              :         mbedtls_ct_condition_t non_zero = mbedtls_ct_bool((x >> i) & 1);
     451              :         done = mbedtls_ct_bool_or(done, non_zero);
     452              :         count = mbedtls_ct_size_if(done, count, i + 1);
     453              :     }
     454              : 
     455              :     return count;
     456              : }
     457              : #endif
     458              : 
     459              : /*
     460              :  * Return the number of less significant zero-bits
     461              :  */
     462            2 : size_t mbedtls_mpi_lsb(const mbedtls_mpi *X)
     463              : {
     464              :     size_t i;
     465              : 
     466            2 :     for (i = 0; i < X->n; i++) {
     467            2 :         if (X->p[i] != 0) {
     468            2 :             return i * biL + mbedtls_mpi_uint_ctz(X->p[i]);
     469              :         }
     470              :     }
     471              : 
     472            0 :     return 0;
     473              : }
     474              : 
     475              : /*
     476              :  * Return the number of bits
     477              :  */
     478      8740358 : size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X)
     479              : {
     480      8740358 :     return mbedtls_mpi_core_bitlen(X->p, X->n);
     481              : }
     482              : 
     483              : /*
     484              :  * Return the total size in bytes
     485              :  */
     486        18215 : size_t mbedtls_mpi_size(const mbedtls_mpi *X)
     487              : {
     488        18215 :     return (mbedtls_mpi_bitlen(X) + 7) >> 3;
     489              : }
     490              : 
     491              : /*
     492              :  * Convert an ASCII character to digit value
     493              :  */
     494            0 : static int mpi_get_digit(mbedtls_mpi_uint *d, int radix, char c)
     495              : {
     496            0 :     *d = 255;
     497              : 
     498            0 :     if (c >= 0x30 && c <= 0x39) {
     499            0 :         *d = c - 0x30;
     500              :     }
     501            0 :     if (c >= 0x41 && c <= 0x46) {
     502            0 :         *d = c - 0x37;
     503              :     }
     504            0 :     if (c >= 0x61 && c <= 0x66) {
     505            0 :         *d = c - 0x57;
     506              :     }
     507              : 
     508            0 :     if (*d >= (mbedtls_mpi_uint) radix) {
     509            0 :         return MBEDTLS_ERR_MPI_INVALID_CHARACTER;
     510              :     }
     511              : 
     512            0 :     return 0;
     513              : }
     514              : 
     515              : /*
     516              :  * Import from an ASCII string
     517              :  */
     518            0 : int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s)
     519              : {
     520            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     521              :     size_t i, j, slen, n;
     522            0 :     int sign = 1;
     523              :     mbedtls_mpi_uint d;
     524              :     mbedtls_mpi T;
     525              : 
     526            0 :     if (radix < 2 || radix > 16) {
     527            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     528              :     }
     529              : 
     530            0 :     mbedtls_mpi_init(&T);
     531              : 
     532            0 :     if (s[0] == 0) {
     533            0 :         mbedtls_mpi_free(X);
     534            0 :         return 0;
     535              :     }
     536              : 
     537            0 :     if (s[0] == '-') {
     538            0 :         ++s;
     539            0 :         sign = -1;
     540              :     }
     541              : 
     542            0 :     slen = strlen(s);
     543              : 
     544            0 :     if (radix == 16) {
     545            0 :         if (slen > SIZE_MAX >> 2) {
     546            0 :             return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     547              :         }
     548              : 
     549            0 :         n = BITS_TO_LIMBS(slen << 2);
     550              : 
     551            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n));
     552            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
     553              : 
     554            0 :         for (i = slen, j = 0; i > 0; i--, j++) {
     555            0 :             MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i - 1]));
     556            0 :             X->p[j / (2 * ciL)] |= d << ((j % (2 * ciL)) << 2);
     557              :         }
     558              :     } else {
     559            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
     560              : 
     561            0 :         for (i = 0; i < slen; i++) {
     562            0 :             MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i]));
     563            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T, X, radix));
     564            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, &T, d));
     565              :         }
     566              :     }
     567              : 
     568            0 :     if (sign < 0 && mbedtls_mpi_bitlen(X) != 0) {
     569            0 :         X->s = -1;
     570              :     }
     571              : 
     572            0 : cleanup:
     573              : 
     574            0 :     mbedtls_mpi_free(&T);
     575              : 
     576            0 :     return ret;
     577              : }
     578              : 
     579              : /*
     580              :  * Helper to write the digits high-order first.
     581              :  */
     582            0 : static int mpi_write_hlp(mbedtls_mpi *X, int radix,
     583              :                          char **p, const size_t buflen)
     584              : {
     585            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     586              :     mbedtls_mpi_uint r;
     587            0 :     size_t length = 0;
     588            0 :     char *p_end = *p + buflen;
     589              : 
     590              :     do {
     591            0 :         if (length >= buflen) {
     592            0 :             return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
     593              :         }
     594              : 
     595            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, radix));
     596            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(X, NULL, X, radix));
     597              :         /*
     598              :          * Write the residue in the current position, as an ASCII character.
     599              :          */
     600            0 :         if (r < 0xA) {
     601            0 :             *(--p_end) = (char) ('0' + r);
     602              :         } else {
     603            0 :             *(--p_end) = (char) ('A' + (r - 0xA));
     604              :         }
     605              : 
     606            0 :         length++;
     607            0 :     } while (mbedtls_mpi_cmp_int(X, 0) != 0);
     608              : 
     609            0 :     memmove(*p, p_end, length);
     610            0 :     *p += length;
     611              : 
     612            0 : cleanup:
     613              : 
     614            0 :     return ret;
     615              : }
     616              : 
     617              : /*
     618              :  * Export into an ASCII string
     619              :  */
     620            0 : int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,
     621              :                              char *buf, size_t buflen, size_t *olen)
     622              : {
     623            0 :     int ret = 0;
     624              :     size_t n;
     625              :     char *p;
     626              :     mbedtls_mpi T;
     627              : 
     628            0 :     if (radix < 2 || radix > 16) {
     629            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     630              :     }
     631              : 
     632            0 :     n = mbedtls_mpi_bitlen(X);   /* Number of bits necessary to present `n`. */
     633            0 :     if (radix >=  4) {
     634            0 :         n >>= 1;                 /* Number of 4-adic digits necessary to present
     635              :                                   * `n`. If radix > 4, this might be a strict
     636              :                                   * overapproximation of the number of
     637              :                                   * radix-adic digits needed to present `n`. */
     638              :     }
     639            0 :     if (radix >= 16) {
     640            0 :         n >>= 1;                 /* Number of hexadecimal digits necessary to
     641              :                                   * present `n`. */
     642              : 
     643              :     }
     644            0 :     n += 1; /* Terminating null byte */
     645            0 :     n += 1; /* Compensate for the divisions above, which round down `n`
     646              :              * in case it's not even. */
     647            0 :     n += 1; /* Potential '-'-sign. */
     648            0 :     n += (n & 1);   /* Make n even to have enough space for hexadecimal writing,
     649              :                      * which always uses an even number of hex-digits. */
     650              : 
     651            0 :     if (buflen < n) {
     652            0 :         *olen = n;
     653            0 :         return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
     654              :     }
     655              : 
     656            0 :     p = buf;
     657            0 :     mbedtls_mpi_init(&T);
     658              : 
     659            0 :     if (X->s == -1) {
     660            0 :         *p++ = '-';
     661            0 :         buflen--;
     662              :     }
     663              : 
     664            0 :     if (radix == 16) {
     665              :         int c;
     666              :         size_t i, j, k;
     667              : 
     668            0 :         for (i = X->n, k = 0; i > 0; i--) {
     669            0 :             for (j = ciL; j > 0; j--) {
     670            0 :                 c = (X->p[i - 1] >> ((j - 1) << 3)) & 0xFF;
     671              : 
     672            0 :                 if (c == 0 && k == 0 && (i + j) != 2) {
     673            0 :                     continue;
     674              :                 }
     675              : 
     676            0 :                 *(p++) = "0123456789ABCDEF" [c / 16];
     677            0 :                 *(p++) = "0123456789ABCDEF" [c % 16];
     678            0 :                 k = 1;
     679              :             }
     680              :         }
     681              :     } else {
     682            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T, X));
     683              : 
     684            0 :         if (T.s == -1) {
     685            0 :             T.s = 1;
     686              :         }
     687              : 
     688            0 :         MBEDTLS_MPI_CHK(mpi_write_hlp(&T, radix, &p, buflen));
     689              :     }
     690              : 
     691            0 :     *p++ = '\0';
     692            0 :     *olen = (size_t) (p - buf);
     693              : 
     694            0 : cleanup:
     695              : 
     696            0 :     mbedtls_mpi_free(&T);
     697              : 
     698            0 :     return ret;
     699              : }
     700              : 
     701              : #if defined(MBEDTLS_FS_IO)
     702              : /*
     703              :  * Read X from an opened file
     704              :  */
     705              : int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin)
     706              : {
     707              :     mbedtls_mpi_uint d;
     708              :     size_t slen;
     709              :     char *p;
     710              :     /*
     711              :      * Buffer should have space for (short) label and decimal formatted MPI,
     712              :      * newline characters and '\0'
     713              :      */
     714              :     char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
     715              : 
     716              :     if (radix < 2 || radix > 16) {
     717              :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     718              :     }
     719              : 
     720              :     memset(s, 0, sizeof(s));
     721              :     if (fgets(s, sizeof(s) - 1, fin) == NULL) {
     722              :         return MBEDTLS_ERR_MPI_FILE_IO_ERROR;
     723              :     }
     724              : 
     725              :     slen = strlen(s);
     726              :     if (slen == sizeof(s) - 2) {
     727              :         return MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL;
     728              :     }
     729              : 
     730              :     if (slen > 0 && s[slen - 1] == '\n') {
     731              :         slen--; s[slen] = '\0';
     732              :     }
     733              :     if (slen > 0 && s[slen - 1] == '\r') {
     734              :         slen--; s[slen] = '\0';
     735              :     }
     736              : 
     737              :     p = s + slen;
     738              :     while (p-- > s) {
     739              :         if (mpi_get_digit(&d, radix, *p) != 0) {
     740              :             break;
     741              :         }
     742              :     }
     743              : 
     744              :     return mbedtls_mpi_read_string(X, radix, p + 1);
     745              : }
     746              : 
     747              : /*
     748              :  * Write X into an opened file (or stdout if fout == NULL)
     749              :  */
     750              : int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE *fout)
     751              : {
     752              :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     753              :     size_t n, slen, plen;
     754              :     /*
     755              :      * Buffer should have space for (short) label and decimal formatted MPI,
     756              :      * newline characters and '\0'
     757              :      */
     758              :     char s[MBEDTLS_MPI_RW_BUFFER_SIZE];
     759              : 
     760              :     if (radix < 2 || radix > 16) {
     761              :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
     762              :     }
     763              : 
     764              :     memset(s, 0, sizeof(s));
     765              : 
     766              :     MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(X, radix, s, sizeof(s) - 2, &n));
     767              : 
     768              :     if (p == NULL) {
     769              :         p = "";
     770              :     }
     771              : 
     772              :     plen = strlen(p);
     773              :     slen = strlen(s);
     774              :     s[slen++] = '\r';
     775              :     s[slen++] = '\n';
     776              : 
     777              :     if (fout != NULL) {
     778              :         if (fwrite(p, 1, plen, fout) != plen ||
     779              :             fwrite(s, 1, slen, fout) != slen) {
     780              :             return MBEDTLS_ERR_MPI_FILE_IO_ERROR;
     781              :         }
     782              :     } else {
     783              :         mbedtls_printf("%s%s", p, s);
     784              :     }
     785              : 
     786              : cleanup:
     787              : 
     788              :     return ret;
     789              : }
     790              : #endif /* MBEDTLS_FS_IO */
     791              : 
     792              : /*
     793              :  * Import X from unsigned binary data, little endian
     794              :  *
     795              :  * This function is guaranteed to return an MPI with exactly the necessary
     796              :  * number of limbs (in particular, it does not skip 0s in the input).
     797              :  */
     798            0 : int mbedtls_mpi_read_binary_le(mbedtls_mpi *X,
     799              :                                const unsigned char *buf, size_t buflen)
     800              : {
     801            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     802            0 :     const size_t limbs = CHARS_TO_LIMBS(buflen);
     803              : 
     804              :     /* Ensure that target MPI has exactly the necessary number of limbs */
     805            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
     806              : 
     807            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_le(X->p, X->n, buf, buflen));
     808              : 
     809            0 : cleanup:
     810              : 
     811              :     /*
     812              :      * This function is also used to import keys. However, wiping the buffers
     813              :      * upon failure is not necessary because failure only can happen before any
     814              :      * input is copied.
     815              :      */
     816            0 :     return ret;
     817              : }
     818              : 
     819              : /*
     820              :  * Import X from unsigned binary data, big endian
     821              :  *
     822              :  * This function is guaranteed to return an MPI with exactly the necessary
     823              :  * number of limbs (in particular, it does not skip 0s in the input).
     824              :  */
     825        33926 : int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen)
     826              : {
     827        33926 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     828        33926 :     const size_t limbs = CHARS_TO_LIMBS(buflen);
     829              : 
     830              :     /* Ensure that target MPI has exactly the necessary number of limbs */
     831        33926 :     MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
     832              : 
     833        33926 :     MBEDTLS_MPI_CHK(mbedtls_mpi_core_read_be(X->p, X->n, buf, buflen));
     834              : 
     835        33926 : cleanup:
     836              : 
     837              :     /*
     838              :      * This function is also used to import keys. However, wiping the buffers
     839              :      * upon failure is not necessary because failure only can happen before any
     840              :      * input is copied.
     841              :      */
     842        33926 :     return ret;
     843              : }
     844              : 
     845              : /*
     846              :  * Export X into unsigned binary data, little endian
     847              :  */
     848            0 : int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X,
     849              :                                 unsigned char *buf, size_t buflen)
     850              : {
     851            0 :     return mbedtls_mpi_core_write_le(X->p, X->n, buf, buflen);
     852              : }
     853              : 
     854              : /*
     855              :  * Export X into unsigned binary data, big endian
     856              :  */
     857         1118 : int mbedtls_mpi_write_binary(const mbedtls_mpi *X,
     858              :                              unsigned char *buf, size_t buflen)
     859              : {
     860         1118 :     return mbedtls_mpi_core_write_be(X->p, X->n, buf, buflen);
     861              : }
     862              : 
     863              : /*
     864              :  * Left-shift: X <<= count
     865              :  */
     866      2248440 : int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count)
     867              : {
     868      2248440 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
     869              :     size_t i;
     870              : 
     871      2248440 :     i = mbedtls_mpi_bitlen(X) + count;
     872              : 
     873      2248440 :     if (X->n * biL < i) {
     874        11276 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, BITS_TO_LIMBS(i)));
     875              :     }
     876              : 
     877      2248440 :     ret = 0;
     878              : 
     879      2248440 :     mbedtls_mpi_core_shift_l(X->p, X->n, count);
     880      2248440 : cleanup:
     881              : 
     882      2248440 :     return ret;
     883              : }
     884              : 
     885              : /*
     886              :  * Right-shift: X >>= count
     887              :  */
     888         7557 : int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count)
     889              : {
     890         7557 :     if (X->n != 0) {
     891         7557 :         mbedtls_mpi_core_shift_r(X->p, X->n, count);
     892              :     }
     893         7557 :     return 0;
     894              : }
     895              : 
     896              : /*
     897              :  * Compare unsigned values
     898              :  */
     899     11085845 : int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y)
     900              : {
     901              :     size_t i, j;
     902              : 
     903     62916378 :     for (i = X->n; i > 0; i--) {
     904     62916378 :         if (X->p[i - 1] != 0) {
     905     11085845 :             break;
     906              :         }
     907              :     }
     908              : 
     909     30458889 :     for (j = Y->n; j > 0; j--) {
     910     30458887 :         if (Y->p[j - 1] != 0) {
     911     11085843 :             break;
     912              :         }
     913              :     }
     914              : 
     915              :     /* If i == j == 0, i.e. abs(X) == abs(Y),
     916              :      * we end up returning 0 at the end of the function. */
     917              : 
     918     11085845 :     if (i > j) {
     919      1529272 :         return 1;
     920              :     }
     921      9556573 :     if (j > i) {
     922            0 :         return -1;
     923              :     }
     924              : 
     925      9587113 :     for (; i > 0; i--) {
     926      9587111 :         if (X->p[i - 1] > Y->p[i - 1]) {
     927      2096535 :             return 1;
     928              :         }
     929      7490576 :         if (X->p[i - 1] < Y->p[i - 1]) {
     930      7460036 :             return -1;
     931              :         }
     932              :     }
     933              : 
     934            2 :     return 0;
     935              : }
     936              : 
     937              : /*
     938              :  * Compare signed values
     939              :  */
     940     21067062 : int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y)
     941              : {
     942              :     size_t i, j;
     943              : 
     944    120664407 :     for (i = X->n; i > 0; i--) {
     945    120655928 :         if (X->p[i - 1] != 0) {
     946     21058583 :             break;
     947              :         }
     948              :     }
     949              : 
     950     29192293 :     for (j = Y->n; j > 0; j--) {
     951     21151168 :         if (Y->p[j - 1] != 0) {
     952     13025937 :             break;
     953              :         }
     954              :     }
     955              : 
     956     21067062 :     if (i == 0 && j == 0) {
     957         8472 :         return 0;
     958              :     }
     959              : 
     960     21058590 :     if (i > j) {
     961     11037160 :         return X->s;
     962              :     }
     963     10021430 :     if (j > i) {
     964        18467 :         return -Y->s;
     965              :     }
     966              : 
     967     10002963 :     if (X->s > 0 && Y->s < 0) {
     968            0 :         return 1;
     969              :     }
     970     10002963 :     if (Y->s > 0 && X->s < 0) {
     971            0 :         return -1;
     972              :     }
     973              : 
     974     10364390 :     for (; i > 0; i--) {
     975     10119141 :         if (X->p[i - 1] > Y->p[i - 1]) {
     976        29019 :             return X->s;
     977              :         }
     978     10090122 :         if (X->p[i - 1] < Y->p[i - 1]) {
     979      9728695 :             return -X->s;
     980              :         }
     981              :     }
     982              : 
     983       245249 :     return 0;
     984              : }
     985              : 
     986              : /*
     987              :  * Compare signed values
     988              :  */
     989      8288246 : int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z)
     990              : {
     991              :     mbedtls_mpi Y;
     992              :     mbedtls_mpi_uint p[1];
     993              : 
     994      8288246 :     *p  = mpi_sint_abs(z);
     995      8288246 :     Y.s = TO_SIGN(z);
     996      8288246 :     Y.n = 1;
     997      8288246 :     Y.p = p;
     998              : 
     999      8288246 :     return mbedtls_mpi_cmp_mpi(X, &Y);
    1000              : }
    1001              : 
    1002              : /*
    1003              :  * Unsigned addition: X = |A| + |B|  (HAC 14.7)
    1004              :  */
    1005       514083 : int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1006              : {
    1007       514083 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1008              :     size_t j;
    1009              :     mbedtls_mpi_uint *p;
    1010              :     mbedtls_mpi_uint c;
    1011              : 
    1012       514083 :     if (X == B) {
    1013            0 :         const mbedtls_mpi *T = A; A = X; B = T;
    1014              :     }
    1015              : 
    1016       514083 :     if (X != A) {
    1017       497670 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
    1018              :     }
    1019              : 
    1020              :     /*
    1021              :      * X must always be positive as a result of unsigned additions.
    1022              :      */
    1023       514083 :     X->s = 1;
    1024              : 
    1025      3016007 :     for (j = B->n; j > 0; j--) {
    1026      3016007 :         if (B->p[j - 1] != 0) {
    1027       514083 :             break;
    1028              :         }
    1029              :     }
    1030              : 
    1031              :     /* Exit early to avoid undefined behavior on NULL+0 when X->n == 0
    1032              :      * and B is 0 (of any size). */
    1033       514083 :     if (j == 0) {
    1034            0 :         return 0;
    1035              :     }
    1036              : 
    1037       514083 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j));
    1038              : 
    1039              :     /* j is the number of non-zero limbs of B. Add those to X. */
    1040              : 
    1041       514083 :     p = X->p;
    1042              : 
    1043       514083 :     c = mbedtls_mpi_core_add(p, p, B->p, j);
    1044              : 
    1045       514083 :     p += j;
    1046              : 
    1047              :     /* Now propagate any carry */
    1048              : 
    1049       762222 :     while (c != 0) {
    1050       248139 :         if (j >= X->n) {
    1051          193 :             MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j + 1));
    1052          193 :             p = X->p + j;
    1053              :         }
    1054              : 
    1055       248139 :         *p += c; c = (*p < c); j++; p++;
    1056              :     }
    1057              : 
    1058       514083 : cleanup:
    1059              : 
    1060       514083 :     return ret;
    1061              : }
    1062              : 
    1063              : /*
    1064              :  * Unsigned subtraction: X = |A| - |B|  (HAC 14.9, 14.10)
    1065              :  */
    1066     14061706 : int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1067              : {
    1068     14061706 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1069              :     size_t n;
    1070              :     mbedtls_mpi_uint carry;
    1071              : 
    1072     60572133 :     for (n = B->n; n > 0; n--) {
    1073     60572131 :         if (B->p[n - 1] != 0) {
    1074     14061704 :             break;
    1075              :         }
    1076              :     }
    1077     14061706 :     if (n > A->n) {
    1078              :         /* B >= (2^ciL)^n > A */
    1079            0 :         ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
    1080            0 :         goto cleanup;
    1081              :     }
    1082              : 
    1083     14061706 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, A->n));
    1084              : 
    1085              :     /* Set the high limbs of X to match A. Don't touch the lower limbs
    1086              :      * because X might be aliased to B, and we must not overwrite the
    1087              :      * significant digits of B. */
    1088     14061706 :     if (A->n > n && A != X) {
    1089      2080458 :         memcpy(X->p + n, A->p + n, (A->n - n) * ciL);
    1090              :     }
    1091     14061706 :     if (X->n > A->n) {
    1092      5728301 :         memset(X->p + A->n, 0, (X->n - A->n) * ciL);
    1093              :     }
    1094              : 
    1095     14061706 :     carry = mbedtls_mpi_core_sub(X->p, A->p, B->p, n);
    1096     14061706 :     if (carry != 0) {
    1097              :         /* Propagate the carry through the rest of X. */
    1098      4485961 :         carry = mbedtls_mpi_core_sub_int(X->p + n, X->p + n, carry, X->n - n);
    1099              : 
    1100              :         /* If we have further carry/borrow, the result is negative. */
    1101      4485961 :         if (carry != 0) {
    1102            0 :             ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
    1103            0 :             goto cleanup;
    1104              :         }
    1105              :     }
    1106              : 
    1107              :     /* X should always be positive as a result of unsigned subtractions. */
    1108     14061706 :     X->s = 1;
    1109              : 
    1110     14061706 : cleanup:
    1111     14061706 :     return ret;
    1112              : }
    1113              : 
    1114              : /* Common function for signed addition and subtraction.
    1115              :  * Calculate A + B * flip_B where flip_B is 1 or -1.
    1116              :  */
    1117     11594477 : static int add_sub_mpi(mbedtls_mpi *X,
    1118              :                        const mbedtls_mpi *A, const mbedtls_mpi *B,
    1119              :                        int flip_B)
    1120              : {
    1121              :     int ret, s;
    1122              : 
    1123     11594477 :     s = A->s;
    1124     11594477 :     if (A->s * B->s * flip_B < 0) {
    1125     11080433 :         int cmp = mbedtls_mpi_cmp_abs(A, B);
    1126     11080433 :         if (cmp >= 0) {
    1127      3622050 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B));
    1128              :             /* If |A| = |B|, the result is 0 and we must set the sign bit
    1129              :              * to +1 regardless of which of A or B was negative. Otherwise,
    1130              :              * since |A| > |B|, the sign is the sign of A. */
    1131      3622050 :             X->s = cmp == 0 ? 1 : s;
    1132              :         } else {
    1133      7458383 :             MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A));
    1134              :             /* Since |A| < |B|, the sign is the opposite of A. */
    1135      7458383 :             X->s = -s;
    1136              :         }
    1137              :     } else {
    1138       514044 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B));
    1139       514044 :         X->s = s;
    1140              :     }
    1141              : 
    1142     11594477 : cleanup:
    1143              : 
    1144     11594477 :     return ret;
    1145              : }
    1146              : 
    1147              : /*
    1148              :  * Signed addition: X = A + B
    1149              :  */
    1150      7599217 : int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1151              : {
    1152      7599217 :     return add_sub_mpi(X, A, B, 1);
    1153              : }
    1154              : 
    1155              : /*
    1156              :  * Signed subtraction: X = A - B
    1157              :  */
    1158      3995260 : int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1159              : {
    1160      3995260 :     return add_sub_mpi(X, A, B, -1);
    1161              : }
    1162              : 
    1163              : /*
    1164              :  * Signed addition: X = A + b
    1165              :  */
    1166            2 : int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
    1167              : {
    1168              :     mbedtls_mpi B;
    1169              :     mbedtls_mpi_uint p[1];
    1170              : 
    1171            2 :     p[0] = mpi_sint_abs(b);
    1172            2 :     B.s = TO_SIGN(b);
    1173            2 :     B.n = 1;
    1174            2 :     B.p = p;
    1175              : 
    1176            2 :     return mbedtls_mpi_add_mpi(X, A, &B);
    1177              : }
    1178              : 
    1179              : /*
    1180              :  * Signed subtraction: X = A - b
    1181              :  */
    1182        16236 : int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b)
    1183              : {
    1184              :     mbedtls_mpi B;
    1185              :     mbedtls_mpi_uint p[1];
    1186              : 
    1187        16236 :     p[0] = mpi_sint_abs(b);
    1188        16236 :     B.s = TO_SIGN(b);
    1189        16236 :     B.n = 1;
    1190        16236 :     B.p = p;
    1191              : 
    1192        16236 :     return mbedtls_mpi_sub_mpi(X, A, &B);
    1193              : }
    1194              : 
    1195              : /*
    1196              :  * Baseline multiplication: X = A * B  (HAC 14.12)
    1197              :  */
    1198      6440638 : int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1199              : {
    1200      6440638 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1201              :     size_t i, j;
    1202              :     mbedtls_mpi TA, TB;
    1203      6440638 :     int result_is_zero = 0;
    1204              : 
    1205      6440638 :     mbedtls_mpi_init(&TA);
    1206      6440638 :     mbedtls_mpi_init(&TB);
    1207              : 
    1208      6440638 :     if (X == A) {
    1209      1832504 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA;
    1210              :     }
    1211      6440638 :     if (X == B) {
    1212        21032 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); B = &TB;
    1213              :     }
    1214              : 
    1215     21901612 :     for (i = A->n; i > 0; i--) {
    1216     21901612 :         if (A->p[i - 1] != 0) {
    1217      6440638 :             break;
    1218              :         }
    1219              :     }
    1220      6440638 :     if (i == 0) {
    1221            0 :         result_is_zero = 1;
    1222              :     }
    1223              : 
    1224     28945132 :     for (j = B->n; j > 0; j--) {
    1225     28945132 :         if (B->p[j - 1] != 0) {
    1226      6440638 :             break;
    1227              :         }
    1228              :     }
    1229      6440638 :     if (j == 0) {
    1230            0 :         result_is_zero = 1;
    1231              :     }
    1232              : 
    1233      6440638 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + j));
    1234      6440638 :     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
    1235              : 
    1236      6440638 :     mbedtls_mpi_core_mul(X->p, A->p, i, B->p, j);
    1237              : 
    1238              :     /* If the result is 0, we don't shortcut the operation, which reduces
    1239              :      * but does not eliminate side channels leaking the zero-ness. We do
    1240              :      * need to take care to set the sign bit properly since the library does
    1241              :      * not fully support an MPI object with a value of 0 and s == -1. */
    1242      6440638 :     if (result_is_zero) {
    1243            0 :         X->s = 1;
    1244              :     } else {
    1245      6440638 :         X->s = A->s * B->s;
    1246              :     }
    1247              : 
    1248      6440638 : cleanup:
    1249              : 
    1250      6440638 :     mbedtls_mpi_free(&TB); mbedtls_mpi_free(&TA);
    1251              : 
    1252      6440638 :     return ret;
    1253              : }
    1254              : 
    1255              : /*
    1256              :  * Baseline multiplication: X = A * b
    1257              :  */
    1258       601559 : int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b)
    1259              : {
    1260       601559 :     size_t n = A->n;
    1261      9215552 :     while (n > 0 && A->p[n - 1] == 0) {
    1262      8613993 :         --n;
    1263              :     }
    1264              : 
    1265              :     /* The general method below doesn't work if b==0. */
    1266       601559 :     if (b == 0 || n == 0) {
    1267            4 :         return mbedtls_mpi_lset(X, 0);
    1268              :     }
    1269              : 
    1270              :     /* Calculate A*b as A + A*(b-1) to take advantage of mbedtls_mpi_core_mla */
    1271       601555 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1272              :     /* In general, A * b requires 1 limb more than b. If
    1273              :      * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same
    1274              :      * number of limbs as A and the call to grow() is not required since
    1275              :      * copy() will take care of the growth if needed. However, experimentally,
    1276              :      * making the call to grow() unconditional causes slightly fewer
    1277              :      * calls to calloc() in ECP code, presumably because it reuses the
    1278              :      * same mpi for a while and this way the mpi is more likely to directly
    1279              :      * grow to its final size.
    1280              :      *
    1281              :      * Note that calculating A*b as 0 + A*b doesn't work as-is because
    1282              :      * A,X can be the same. */
    1283       601555 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n + 1));
    1284       601555 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
    1285       601555 :     mbedtls_mpi_core_mla(X->p, X->n, A->p, n, b - 1);
    1286              : 
    1287       601555 : cleanup:
    1288       601555 :     return ret;
    1289              : }
    1290              : 
    1291              : /*
    1292              :  * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
    1293              :  * mbedtls_mpi_uint divisor, d
    1294              :  */
    1295        38426 : static mbedtls_mpi_uint mbedtls_int_div_int(mbedtls_mpi_uint u1,
    1296              :                                             mbedtls_mpi_uint u0,
    1297              :                                             mbedtls_mpi_uint d,
    1298              :                                             mbedtls_mpi_uint *r)
    1299              : {
    1300              : #if defined(MBEDTLS_HAVE_UDBL)
    1301              :     mbedtls_t_udbl dividend, quotient;
    1302              : #else
    1303              :     const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
    1304              :     const mbedtls_mpi_uint uint_halfword_mask = ((mbedtls_mpi_uint) 1 << biH) - 1;
    1305              :     mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
    1306              :     mbedtls_mpi_uint u0_msw, u0_lsw;
    1307              :     size_t s;
    1308              : #endif
    1309              : 
    1310              :     /*
    1311              :      * Check for overflow
    1312              :      */
    1313        38426 :     if (0 == d || u1 >= d) {
    1314            0 :         if (r != NULL) {
    1315            0 :             *r = ~(mbedtls_mpi_uint) 0u;
    1316              :         }
    1317              : 
    1318            0 :         return ~(mbedtls_mpi_uint) 0u;
    1319              :     }
    1320              : 
    1321              : #if defined(MBEDTLS_HAVE_UDBL)
    1322        38426 :     dividend  = (mbedtls_t_udbl) u1 << biL;
    1323        38426 :     dividend |= (mbedtls_t_udbl) u0;
    1324        38426 :     quotient = dividend / d;
    1325        38426 :     if (quotient > ((mbedtls_t_udbl) 1 << biL) - 1) {
    1326            0 :         quotient = ((mbedtls_t_udbl) 1 << biL) - 1;
    1327              :     }
    1328              : 
    1329        38426 :     if (r != NULL) {
    1330            0 :         *r = (mbedtls_mpi_uint) (dividend - (quotient * d));
    1331              :     }
    1332              : 
    1333        38426 :     return (mbedtls_mpi_uint) quotient;
    1334              : #else
    1335              : 
    1336              :     /*
    1337              :      * Algorithm D, Section 4.3.1 - The Art of Computer Programming
    1338              :      *   Vol. 2 - Seminumerical Algorithms, Knuth
    1339              :      */
    1340              : 
    1341              :     /*
    1342              :      * Normalize the divisor, d, and dividend, u0, u1
    1343              :      */
    1344              :     s = mbedtls_mpi_core_clz(d);
    1345              :     d = d << s;
    1346              : 
    1347              :     u1 = u1 << s;
    1348              :     u1 |= (u0 >> (biL - s)) & (-(mbedtls_mpi_sint) s >> (biL - 1));
    1349              :     u0 =  u0 << s;
    1350              : 
    1351              :     d1 = d >> biH;
    1352              :     d0 = d & uint_halfword_mask;
    1353              : 
    1354              :     u0_msw = u0 >> biH;
    1355              :     u0_lsw = u0 & uint_halfword_mask;
    1356              : 
    1357              :     /*
    1358              :      * Find the first quotient and remainder
    1359              :      */
    1360              :     q1 = u1 / d1;
    1361              :     r0 = u1 - d1 * q1;
    1362              : 
    1363              :     while (q1 >= radix || (q1 * d0 > radix * r0 + u0_msw)) {
    1364              :         q1 -= 1;
    1365              :         r0 += d1;
    1366              : 
    1367              :         if (r0 >= radix) {
    1368              :             break;
    1369              :         }
    1370              :     }
    1371              : 
    1372              :     rAX = (u1 * radix) + (u0_msw - q1 * d);
    1373              :     q0 = rAX / d1;
    1374              :     r0 = rAX - q0 * d1;
    1375              : 
    1376              :     while (q0 >= radix || (q0 * d0 > radix * r0 + u0_lsw)) {
    1377              :         q0 -= 1;
    1378              :         r0 += d1;
    1379              : 
    1380              :         if (r0 >= radix) {
    1381              :             break;
    1382              :         }
    1383              :     }
    1384              : 
    1385              :     if (r != NULL) {
    1386              :         *r = (rAX * radix + u0_lsw - q0 * d) >> s;
    1387              :     }
    1388              : 
    1389              :     quotient = q1 * radix + q0;
    1390              : 
    1391              :     return quotient;
    1392              : #endif
    1393              : }
    1394              : 
    1395              : /*
    1396              :  * Division by mbedtls_mpi: A = Q * B + R  (HAC 14.20)
    1397              :  */
    1398         5412 : int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
    1399              :                         const mbedtls_mpi *B)
    1400              : {
    1401         5412 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1402              :     size_t i, n, t, k;
    1403              :     mbedtls_mpi X, Y, Z, T1, T2;
    1404              :     mbedtls_mpi_uint TP2[3];
    1405              : 
    1406         5412 :     if (mbedtls_mpi_cmp_int(B, 0) == 0) {
    1407            0 :         return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
    1408              :     }
    1409              : 
    1410         5412 :     mbedtls_mpi_init(&X); mbedtls_mpi_init(&Y); mbedtls_mpi_init(&Z);
    1411         5412 :     mbedtls_mpi_init(&T1);
    1412              :     /*
    1413              :      * Avoid dynamic memory allocations for constant-size T2.
    1414              :      *
    1415              :      * T2 is used for comparison only and the 3 limbs are assigned explicitly,
    1416              :      * so nobody increase the size of the MPI and we're safe to use an on-stack
    1417              :      * buffer.
    1418              :      */
    1419         5412 :     T2.s = 1;
    1420         5412 :     T2.n = sizeof(TP2) / sizeof(*TP2);
    1421         5412 :     T2.p = TP2;
    1422              : 
    1423         5412 :     if (mbedtls_mpi_cmp_abs(A, B) < 0) {
    1424         1653 :         if (Q != NULL) {
    1425            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_lset(Q, 0));
    1426              :         }
    1427         1653 :         if (R != NULL) {
    1428         1653 :             MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, A));
    1429              :         }
    1430         1653 :         return 0;
    1431              :     }
    1432              : 
    1433         3759 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&X, A));
    1434         3759 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, B));
    1435         3759 :     X.s = Y.s = 1;
    1436              : 
    1437         3759 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&Z, A->n + 2));
    1438         3759 :     MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Z,  0));
    1439         3759 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T1, A->n + 2));
    1440              : 
    1441         3759 :     k = mbedtls_mpi_bitlen(&Y) % biL;
    1442         3759 :     if (k < biL - 1) {
    1443         3759 :         k = biL - 1 - k;
    1444         3759 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&X, k));
    1445         3759 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, k));
    1446              :     } else {
    1447            0 :         k = 0;
    1448              :     }
    1449              : 
    1450         3759 :     n = X.n - 1;
    1451         3759 :     t = Y.n - 1;
    1452         3759 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, biL * (n - t)));
    1453              : 
    1454         4212 :     while (mbedtls_mpi_cmp_mpi(&X, &Y) >= 0) {
    1455          453 :         Z.p[n - t]++;
    1456          453 :         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &Y));
    1457              :     }
    1458         3759 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, biL * (n - t)));
    1459              : 
    1460        42185 :     for (i = n; i > t; i--) {
    1461        38426 :         if (X.p[i] >= Y.p[t]) {
    1462            0 :             Z.p[i - t - 1] = ~(mbedtls_mpi_uint) 0u;
    1463              :         } else {
    1464        38426 :             Z.p[i - t - 1] = mbedtls_int_div_int(X.p[i], X.p[i - 1],
    1465        38426 :                                                  Y.p[t], NULL);
    1466              :         }
    1467              : 
    1468        38426 :         T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
    1469        38426 :         T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
    1470        38426 :         T2.p[2] = X.p[i];
    1471              : 
    1472        38426 :         Z.p[i - t - 1]++;
    1473              :         do {
    1474        65501 :             Z.p[i - t - 1]--;
    1475              : 
    1476        65501 :             MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&T1, 0));
    1477        65501 :             T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
    1478        65501 :             T1.p[1] = Y.p[t];
    1479        65501 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &T1, Z.p[i - t - 1]));
    1480        65501 :         } while (mbedtls_mpi_cmp_mpi(&T1, &T2) > 0);
    1481              : 
    1482        38426 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &Y, Z.p[i - t - 1]));
    1483        38426 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1,  biL * (i - t - 1)));
    1484        38426 :         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &T1));
    1485              : 
    1486        38426 :         if (mbedtls_mpi_cmp_int(&X, 0) < 0) {
    1487            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T1, &Y));
    1488            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));
    1489            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&X, &X, &T1));
    1490            0 :             Z.p[i - t - 1]--;
    1491              :         }
    1492              :     }
    1493              : 
    1494         3759 :     if (Q != NULL) {
    1495            2 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(Q, &Z));
    1496            2 :         Q->s = A->s * B->s;
    1497              :     }
    1498              : 
    1499         3759 :     if (R != NULL) {
    1500         3757 :         MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&X, k));
    1501         3757 :         X.s = A->s;
    1502         3757 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, &X));
    1503              : 
    1504         3757 :         if (mbedtls_mpi_cmp_int(R, 0) == 0) {
    1505            0 :             R->s = 1;
    1506              :         }
    1507              :     }
    1508              : 
    1509         3759 : cleanup:
    1510              : 
    1511         3759 :     mbedtls_mpi_free(&X); mbedtls_mpi_free(&Y); mbedtls_mpi_free(&Z);
    1512         3759 :     mbedtls_mpi_free(&T1);
    1513         3759 :     mbedtls_platform_zeroize(TP2, sizeof(TP2));
    1514              : 
    1515         3759 :     return ret;
    1516              : }
    1517              : 
    1518              : /*
    1519              :  * Division by int: A = Q * b + R
    1520              :  */
    1521            0 : int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
    1522              :                         const mbedtls_mpi *A,
    1523              :                         mbedtls_mpi_sint b)
    1524              : {
    1525              :     mbedtls_mpi B;
    1526              :     mbedtls_mpi_uint p[1];
    1527              : 
    1528            0 :     p[0] = mpi_sint_abs(b);
    1529            0 :     B.s = TO_SIGN(b);
    1530            0 :     B.n = 1;
    1531            0 :     B.p = p;
    1532              : 
    1533            0 :     return mbedtls_mpi_div_mpi(Q, R, A, &B);
    1534              : }
    1535              : 
    1536              : /*
    1537              :  * Modulo: R = A mod B
    1538              :  */
    1539         5410 : int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1540              : {
    1541         5410 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1542              : 
    1543         5410 :     if (mbedtls_mpi_cmp_int(B, 0) < 0) {
    1544            0 :         return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
    1545              :     }
    1546              : 
    1547         5410 :     MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(NULL, R, A, B));
    1548              : 
    1549         5428 :     while (mbedtls_mpi_cmp_int(R, 0) < 0) {
    1550           18 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(R, R, B));
    1551              :     }
    1552              : 
    1553         5410 :     while (mbedtls_mpi_cmp_mpi(R, B) >= 0) {
    1554            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(R, R, B));
    1555              :     }
    1556              : 
    1557         5410 : cleanup:
    1558              : 
    1559         5410 :     return ret;
    1560              : }
    1561              : 
    1562              : /*
    1563              :  * Modulo: r = A mod b
    1564              :  */
    1565            0 : int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b)
    1566              : {
    1567              :     size_t i;
    1568              :     mbedtls_mpi_uint x, y, z;
    1569              : 
    1570            0 :     if (b == 0) {
    1571            0 :         return MBEDTLS_ERR_MPI_DIVISION_BY_ZERO;
    1572              :     }
    1573              : 
    1574            0 :     if (b < 0) {
    1575            0 :         return MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
    1576              :     }
    1577              : 
    1578              :     /*
    1579              :      * handle trivial cases
    1580              :      */
    1581            0 :     if (b == 1 || A->n == 0) {
    1582            0 :         *r = 0;
    1583            0 :         return 0;
    1584              :     }
    1585              : 
    1586            0 :     if (b == 2) {
    1587            0 :         *r = A->p[0] & 1;
    1588            0 :         return 0;
    1589              :     }
    1590              : 
    1591              :     /*
    1592              :      * general case
    1593              :      */
    1594            0 :     for (i = A->n, y = 0; i > 0; i--) {
    1595            0 :         x  = A->p[i - 1];
    1596            0 :         y  = (y << biH) | (x >> biH);
    1597            0 :         z  = y / b;
    1598            0 :         y -= z * b;
    1599              : 
    1600            0 :         x <<= biH;
    1601            0 :         y  = (y << biH) | (x >> biH);
    1602            0 :         z  = y / b;
    1603            0 :         y -= z * b;
    1604              :     }
    1605              : 
    1606              :     /*
    1607              :      * If A is negative, then the current y represents a negative value.
    1608              :      * Flipping it to the positive side.
    1609              :      */
    1610            0 :     if (A->s < 0 && y != 0) {
    1611            0 :         y = b - y;
    1612              :     }
    1613              : 
    1614            0 :     *r = y;
    1615              : 
    1616            0 :     return 0;
    1617              : }
    1618              : 
    1619              : /*
    1620              :  * Warning! If the parameter E_public has MBEDTLS_MPI_IS_PUBLIC as its value,
    1621              :  * this function is not constant time with respect to the exponent (parameter E).
    1622              :  */
    1623          503 : static int mbedtls_mpi_exp_mod_optionally_safe(mbedtls_mpi *X, const mbedtls_mpi *A,
    1624              :                                                const mbedtls_mpi *E, int E_public,
    1625              :                                                const mbedtls_mpi *N, mbedtls_mpi *prec_RR)
    1626              : {
    1627          503 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1628              : 
    1629          503 :     if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0) {
    1630            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1631              :     }
    1632              : 
    1633          503 :     if (mbedtls_mpi_cmp_int(E, 0) < 0) {
    1634            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1635              :     }
    1636              : 
    1637         1006 :     if (mbedtls_mpi_bitlen(E) > MBEDTLS_MPI_MAX_BITS ||
    1638          503 :         mbedtls_mpi_bitlen(N) > MBEDTLS_MPI_MAX_BITS) {
    1639            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1640              :     }
    1641              : 
    1642              :     /*
    1643              :      * Ensure that the exponent that we are passing to the core is not NULL.
    1644              :      */
    1645          503 :     if (E->n == 0) {
    1646            0 :         ret = mbedtls_mpi_lset(X, 1);
    1647            0 :         return ret;
    1648              :     }
    1649              : 
    1650              :     /*
    1651              :      * Allocate working memory for mbedtls_mpi_core_exp_mod()
    1652              :      */
    1653          503 :     size_t T_limbs = mbedtls_mpi_core_exp_mod_working_limbs(N->n, E->n);
    1654          503 :     mbedtls_mpi_uint *T = (mbedtls_mpi_uint *) mbedtls_calloc(T_limbs, sizeof(mbedtls_mpi_uint));
    1655          503 :     if (T == NULL) {
    1656            0 :         return MBEDTLS_ERR_MPI_ALLOC_FAILED;
    1657              :     }
    1658              : 
    1659              :     mbedtls_mpi RR;
    1660          503 :     mbedtls_mpi_init(&RR);
    1661              : 
    1662              :     /*
    1663              :      * If 1st call, pre-compute R^2 mod N
    1664              :      */
    1665          503 :     if (prec_RR == NULL || prec_RR->p == NULL) {
    1666          414 :         MBEDTLS_MPI_CHK(mbedtls_mpi_core_get_mont_r2_unsafe(&RR, N));
    1667              : 
    1668          414 :         if (prec_RR != NULL) {
    1669          414 :             *prec_RR = RR;
    1670              :         }
    1671              :     } else {
    1672           89 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(prec_RR, N->n));
    1673           89 :         RR = *prec_RR;
    1674              :     }
    1675              : 
    1676              :     /*
    1677              :      * To preserve constness we need to make a copy of A. Using X for this to
    1678              :      * save memory.
    1679              :      */
    1680          503 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
    1681              : 
    1682              :     /*
    1683              :      * Compensate for negative A (and correct at the end).
    1684              :      */
    1685          503 :     X->s = 1;
    1686              : 
    1687              :     /*
    1688              :      * Make sure that X is in a form that is safe for consumption by
    1689              :      * the core functions.
    1690              :      *
    1691              :      * - The core functions will not touch the limbs of X above N->n. The
    1692              :      *   result will be correct if those limbs are 0, which the mod call
    1693              :      *   ensures.
    1694              :      * - Also, X must have at least as many limbs as N for the calls to the
    1695              :      *   core functions.
    1696              :      */
    1697          503 :     if (mbedtls_mpi_cmp_mpi(X, N) >= 0) {
    1698           76 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(X, X, N));
    1699              :     }
    1700          503 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, N->n));
    1701              : 
    1702              :     /*
    1703              :      * Convert to and from Montgomery around mbedtls_mpi_core_exp_mod().
    1704              :      */
    1705              :     {
    1706          503 :         mbedtls_mpi_uint mm = mbedtls_mpi_core_montmul_init(N->p);
    1707          503 :         mbedtls_mpi_core_to_mont_rep(X->p, X->p, N->p, N->n, mm, RR.p, T);
    1708          503 :         if (E_public == MBEDTLS_MPI_IS_PUBLIC) {
    1709          345 :             mbedtls_mpi_core_exp_mod_unsafe(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
    1710              :         } else {
    1711          158 :             mbedtls_mpi_core_exp_mod(X->p, X->p, N->p, N->n, E->p, E->n, RR.p, T);
    1712              :         }
    1713          503 :         mbedtls_mpi_core_from_mont_rep(X->p, X->p, N->p, N->n, mm, T);
    1714              :     }
    1715              : 
    1716              :     /*
    1717              :      * Correct for negative A.
    1718              :      */
    1719          503 :     if (A->s == -1 && (E->p[0] & 1) != 0) {
    1720            0 :         mbedtls_ct_condition_t is_x_non_zero = mbedtls_mpi_core_check_zero_ct(X->p, X->n);
    1721            0 :         X->s = mbedtls_ct_mpi_sign_if(is_x_non_zero, -1, 1);
    1722              : 
    1723            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
    1724              :     }
    1725              : 
    1726          503 : cleanup:
    1727              : 
    1728          503 :     mbedtls_mpi_zeroize_and_free(T, T_limbs);
    1729              : 
    1730          503 :     if (prec_RR == NULL || prec_RR->p == NULL) {
    1731            0 :         mbedtls_mpi_free(&RR);
    1732              :     }
    1733              : 
    1734          503 :     return ret;
    1735              : }
    1736              : 
    1737          158 : int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
    1738              :                         const mbedtls_mpi *E, const mbedtls_mpi *N,
    1739              :                         mbedtls_mpi *prec_RR)
    1740              : {
    1741          158 :     return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_SECRET, N, prec_RR);
    1742              : }
    1743              : 
    1744          345 : int mbedtls_mpi_exp_mod_unsafe(mbedtls_mpi *X, const mbedtls_mpi *A,
    1745              :                                const mbedtls_mpi *E, const mbedtls_mpi *N,
    1746              :                                mbedtls_mpi *prec_RR)
    1747              : {
    1748          345 :     return mbedtls_mpi_exp_mod_optionally_safe(X, A, E, MBEDTLS_MPI_IS_PUBLIC, N, prec_RR);
    1749              : }
    1750              : 
    1751              : /* Constant-time GCD and/or modinv with odd modulus and A <= N */
    1752         9733 : int mbedtls_mpi_gcd_modinv_odd(mbedtls_mpi *G,
    1753              :                                mbedtls_mpi *I,
    1754              :                                const mbedtls_mpi *A,
    1755              :                                const mbedtls_mpi *N)
    1756              : {
    1757         9733 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1758              :     mbedtls_mpi local_g;
    1759         9733 :     mbedtls_mpi_uint *T = NULL;
    1760         9733 :     const size_t T_factor = I != NULL ? 5 : 4;
    1761         9733 :     const mbedtls_mpi_uint zero = 0;
    1762              : 
    1763              :     /* Check requirements on A and N */
    1764        19466 :     if (mbedtls_mpi_cmp_int(A, 0) < 0 ||
    1765        19466 :         mbedtls_mpi_cmp_mpi(A, N) > 0 ||
    1766        19466 :         mbedtls_mpi_get_bit(N, 0) != 1 ||
    1767         9729 :         (I != NULL && mbedtls_mpi_cmp_int(N, 1) == 0)) {
    1768            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1769              :     }
    1770              : 
    1771              :     /* Check aliasing requirements */
    1772         9733 :     if (A == N || (I != NULL && (I == N || G == N))) {
    1773            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1774              :     }
    1775              : 
    1776         9733 :     mbedtls_mpi_init(&local_g);
    1777              : 
    1778         9733 :     if (G == NULL) {
    1779         9689 :         G = &local_g;
    1780              :     }
    1781              : 
    1782              :     /* We can't modify the values of G or I before use in the main function,
    1783              :      * as they could be aliased to A or N. */
    1784         9733 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(G, N->n));
    1785         9733 :     if (I != NULL) {
    1786         9729 :         MBEDTLS_MPI_CHK(mbedtls_mpi_grow(I, N->n));
    1787              :     }
    1788              : 
    1789         9733 :     T = mbedtls_calloc(sizeof(mbedtls_mpi_uint) * N->n, T_factor);
    1790         9733 :     if (T == NULL) {
    1791            0 :         ret = MBEDTLS_ERR_MPI_ALLOC_FAILED;
    1792            0 :         goto cleanup;
    1793              :     }
    1794              : 
    1795         9733 :     mbedtls_mpi_uint *Ip = I != NULL ? I->p : NULL;
    1796              :     /* If A is 0 (null), then A->p would be null, and A->n would be 0,
    1797              :      * which would be an issue if A->p and A->n were passed to
    1798              :      * mbedtls_mpi_core_gcd_modinv_odd below. */
    1799         9733 :     const mbedtls_mpi_uint *Ap = A->p != NULL ? A->p : &zero;
    1800         9733 :     size_t An = A->n >= N->n ? N->n : A->p != NULL ? A->n : 1;
    1801         9733 :     mbedtls_mpi_core_gcd_modinv_odd(G->p, Ip, Ap, An, N->p, N->n, T);
    1802              : 
    1803         9733 :     G->s = 1;
    1804         9733 :     if (I != NULL) {
    1805         9729 :         I->s = 1;
    1806              :     }
    1807              : 
    1808         9733 :     if (G->n > N->n) {
    1809            0 :         memset(G->p + N->n, 0, ciL * (G->n - N->n));
    1810              :     }
    1811         9733 :     if (I != NULL && I->n > N->n) {
    1812         3298 :         memset(I->p + N->n, 0, ciL * (I->n - N->n));
    1813              :     }
    1814              : 
    1815         6435 : cleanup:
    1816         9733 :     mbedtls_mpi_free(&local_g);
    1817         9733 :     mbedtls_free(T);
    1818         9733 :     return ret;
    1819              : }
    1820              : 
    1821              : /*
    1822              :  * Greatest common divisor: G = gcd(A, B)
    1823              :  * Wrapper around mbedtls_mpi_gcd_modinv() that removes its restrictions.
    1824              :  */
    1825            0 : int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B)
    1826              : {
    1827            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1828              :     mbedtls_mpi TA, TB;
    1829              : 
    1830            0 :     mbedtls_mpi_init(&TA); mbedtls_mpi_init(&TB);
    1831              : 
    1832              :     /* Make copies and take absolute values */
    1833            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));
    1834            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));
    1835            0 :     TA.s = TB.s = 1;
    1836              : 
    1837              :     /* Make the two values the same (non-zero) number of limbs.
    1838              :      * This is needed to use mbedtls_mpi_core functions below. */
    1839            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&TA, TB.n != 0 ? TB.n : 1));
    1840            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&TB, TA.n)); // non-zero from above
    1841              : 
    1842              :     /* Handle special cases (that don't happen in crypto usage) */
    1843            0 :     if (mbedtls_mpi_core_check_zero_ct(TA.p, TA.n) == MBEDTLS_CT_FALSE) {
    1844            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB)); // GCD(0, B) = abs(B)
    1845            0 :         goto cleanup;
    1846              :     }
    1847            0 :     if (mbedtls_mpi_core_check_zero_ct(TB.p, TB.n) == MBEDTLS_CT_FALSE) {
    1848            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TA)); // GCD(A, 0) = abs(A)
    1849            0 :         goto cleanup;
    1850              :     }
    1851              : 
    1852              :     /* Make boths inputs odd by putting powers of 2 on the side */
    1853            0 :     const size_t za = mbedtls_mpi_lsb(&TA);
    1854            0 :     const size_t zb = mbedtls_mpi_lsb(&TB);
    1855            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, za));
    1856            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, zb));
    1857              : 
    1858              :     /* Ensure A <= B: if B < A, swap them */
    1859            0 :     mbedtls_ct_condition_t swap = mbedtls_mpi_core_lt_ct(TB.p, TA.p, TA.n);
    1860            0 :     mbedtls_mpi_core_cond_swap(TA.p, TB.p, TA.n, swap);
    1861              : 
    1862            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(G, NULL, &TA, &TB));
    1863              : 
    1864              :     /* Re-inject the power of 2 we had previously put aside */
    1865            0 :     size_t zg = za > zb ? zb : za; // zg = min(za, zb)
    1866            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(G, zg));
    1867              : 
    1868            0 : cleanup:
    1869              : 
    1870            0 :     mbedtls_mpi_free(&TA); mbedtls_mpi_free(&TB);
    1871              : 
    1872            0 :     return ret;
    1873              : }
    1874              : 
    1875              : /*
    1876              :  * Fill X with size bytes of random.
    1877              :  * The bytes returned from the RNG are used in a specific order which
    1878              :  * is suitable for deterministic ECDSA (see the specification of
    1879              :  * mbedtls_mpi_random() and the implementation in mbedtls_mpi_fill_random()).
    1880              :  */
    1881           76 : int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
    1882              :                             int (*f_rng)(void *, unsigned char *, size_t),
    1883              :                             void *p_rng)
    1884              : {
    1885           76 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1886           76 :     const size_t limbs = CHARS_TO_LIMBS(size);
    1887              : 
    1888              :     /* Ensure that target MPI has exactly the necessary number of limbs */
    1889           76 :     MBEDTLS_MPI_CHK(mbedtls_mpi_resize_clear(X, limbs));
    1890           76 :     if (size == 0) {
    1891            0 :         return 0;
    1892              :     }
    1893              : 
    1894           76 :     ret = mbedtls_mpi_core_fill_random(X->p, X->n, size, f_rng, p_rng);
    1895              : 
    1896           76 : cleanup:
    1897           76 :     return ret;
    1898              : }
    1899              : 
    1900          747 : int mbedtls_mpi_random(mbedtls_mpi *X,
    1901              :                        mbedtls_mpi_sint min,
    1902              :                        const mbedtls_mpi *N,
    1903              :                        int (*f_rng)(void *, unsigned char *, size_t),
    1904              :                        void *p_rng)
    1905              : {
    1906          747 :     if (min < 0) {
    1907            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1908              :     }
    1909          747 :     if (mbedtls_mpi_cmp_int(N, min) <= 0) {
    1910            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    1911              :     }
    1912              : 
    1913              :     /* Ensure that target MPI has exactly the same number of limbs
    1914              :      * as the upper bound, even if the upper bound has leading zeros.
    1915              :      * This is necessary for mbedtls_mpi_core_random. */
    1916          747 :     int ret = mbedtls_mpi_resize_clear(X, N->n);
    1917          747 :     if (ret != 0) {
    1918            0 :         return ret;
    1919              :     }
    1920              : 
    1921          747 :     return mbedtls_mpi_core_random(X->p, min, N->p, X->n, f_rng, p_rng);
    1922              : }
    1923              : 
    1924              : /*
    1925              :  * Modular inverse: X = A^-1 mod N with N odd (and A any range)
    1926              :  */
    1927            2 : int mbedtls_mpi_inv_mod_odd(mbedtls_mpi *X,
    1928              :                             const mbedtls_mpi *A,
    1929              :                             const mbedtls_mpi *N)
    1930              : {
    1931            2 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1932              :     mbedtls_mpi T, G;
    1933              : 
    1934            2 :     mbedtls_mpi_init(&T);
    1935            2 :     mbedtls_mpi_init(&G);
    1936              : 
    1937            2 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&T, A, N));
    1938            2 :     MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &T, &T, N));
    1939            2 :     if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
    1940            0 :         ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    1941            0 :         goto cleanup;
    1942              :     }
    1943              : 
    1944            2 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &T));
    1945              : 
    1946            2 : cleanup:
    1947            2 :     mbedtls_mpi_free(&T);
    1948            2 :     mbedtls_mpi_free(&G);
    1949              : 
    1950            2 :     return ret;
    1951              : }
    1952              : 
    1953              : /*
    1954              :  * Compute X = A^-1 mod N with N even, A odd and 1 < A < N.
    1955              :  *
    1956              :  * This is not obvious because our constant-time modinv function only works with
    1957              :  * an odd modulus, and here the modulus is even. The idea is that computing a
    1958              :  * a^-1 mod b is really just computing the u coefficient in the Bézout relation
    1959              :  * a*u + b*v = 1 (assuming gcd(a,b) = 1, i.e. the inverse exists). But if we know
    1960              :  * one of u, v in this relation then the other is easy to find. So we can
    1961              :  * actually start by computing N^-1 mod A with gives us "the wrong half" of the
    1962              :  * Bézout relation, from which we'll deduce the interesting half A^-1 mod N.
    1963              :  *
    1964              :  * Return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the inverse doesn't exist.
    1965              :  */
    1966            0 : int mbedtls_mpi_inv_mod_even_in_range(mbedtls_mpi *X,
    1967              :                                       mbedtls_mpi const *A,
    1968              :                                       mbedtls_mpi const *N)
    1969              : {
    1970            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    1971              :     mbedtls_mpi I, G;
    1972              : 
    1973            0 :     mbedtls_mpi_init(&I);
    1974            0 :     mbedtls_mpi_init(&G);
    1975              : 
    1976              :     /* Set I = N^-1 mod A */
    1977            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&I, N, A));
    1978            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_gcd_modinv_odd(&G, &I, &I, A));
    1979            0 :     if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
    1980            0 :         ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    1981            0 :         goto cleanup;
    1982              :     }
    1983              : 
    1984              :     /* We know N * I = 1 + k * A for some k, which we can easily compute
    1985              :      * as k = (N*I - 1) / A (we know there will be no remainder). */
    1986            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&I, &I, N));
    1987            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&I, &I, 1));
    1988            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&G, NULL, &I, A));
    1989              : 
    1990              :     /* Now we have a Bézout relation N * (previous value of I) - G * A = 1,
    1991              :      * so A^-1 mod N is -G mod N, which is N - G.
    1992              :      * Note that 0 < k < N since 0 < I < A, so G (k) is already in range. */
    1993            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(X, N, &G));
    1994              : 
    1995            0 : cleanup:
    1996            0 :     mbedtls_mpi_free(&I);
    1997            0 :     mbedtls_mpi_free(&G);
    1998            0 :     return ret;
    1999              : }
    2000              : 
    2001              : /*
    2002              :  * Compute X = A^-1 mod N with N even and A odd (but in any range).
    2003              :  *
    2004              :  * Return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the inverse doesn't exist.
    2005              :  */
    2006            0 : static int mbedtls_mpi_inv_mod_even(mbedtls_mpi *X,
    2007              :                                     mbedtls_mpi const *A,
    2008              :                                     mbedtls_mpi const *N)
    2009              : {
    2010            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    2011              :     mbedtls_mpi AA;
    2012              : 
    2013            0 :     mbedtls_mpi_init(&AA);
    2014              : 
    2015              :     /* Bring A in the range [0, N). */
    2016            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&AA, A, N));
    2017              : 
    2018              :     /* We know A >= 0 but the next function wants A > 1 */
    2019            0 :     int cmp = mbedtls_mpi_cmp_int(&AA, 1);
    2020            0 :     if (cmp < 0) { // AA == 0
    2021            0 :         ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2022            0 :         goto cleanup;
    2023              :     }
    2024            0 :     if (cmp == 0) { // AA = 1
    2025            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 1));
    2026            0 :         goto cleanup;
    2027              :     }
    2028              : 
    2029              :     /* Now we know 1 < A < N, N is even and AA is still odd */
    2030            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod_even_in_range(X, &AA, N));
    2031              : 
    2032            0 : cleanup:
    2033            0 :     mbedtls_mpi_free(&AA);
    2034            0 :     return ret;
    2035              : }
    2036              : 
    2037              : /*
    2038              :  * Modular inverse: X = A^-1 mod N
    2039              :  *
    2040              :  * Wrapper around mbedtls_mpi_gcd_modinv_odd() that lifts its limitations.
    2041              :  */
    2042            0 : int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N)
    2043              : {
    2044            0 :     if (mbedtls_mpi_cmp_int(N, 1) <= 0) {
    2045            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    2046              :     }
    2047              : 
    2048            0 :     if (mbedtls_mpi_get_bit(N, 0) == 1) {
    2049            0 :         return mbedtls_mpi_inv_mod_odd(X, A, N);
    2050              :     }
    2051              : 
    2052            0 :     if (mbedtls_mpi_get_bit(A, 0) == 1) {
    2053            0 :         return mbedtls_mpi_inv_mod_even(X, A, N);
    2054              :     }
    2055              : 
    2056              :     /* If A and N are both even, 2 divides their GCD, so no inverse. */
    2057            0 :     return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2058              : }
    2059              : 
    2060              : #if defined(MBEDTLS_GENPRIME)
    2061              : 
    2062              : /* Gaps between primes, starting at 3. https://oeis.org/A001223 */
    2063              : static const unsigned char small_prime_gaps[] = {
    2064              :     2, 2, 4, 2, 4, 2, 4, 6,
    2065              :     2, 6, 4, 2, 4, 6, 6, 2,
    2066              :     6, 4, 2, 6, 4, 6, 8, 4,
    2067              :     2, 4, 2, 4, 14, 4, 6, 2,
    2068              :     10, 2, 6, 6, 4, 6, 6, 2,
    2069              :     10, 2, 4, 2, 12, 12, 4, 2,
    2070              :     4, 6, 2, 10, 6, 6, 6, 2,
    2071              :     6, 4, 2, 10, 14, 4, 2, 4,
    2072              :     14, 6, 10, 2, 4, 6, 8, 6,
    2073              :     6, 4, 6, 8, 4, 8, 10, 2,
    2074              :     10, 2, 6, 4, 6, 8, 4, 2,
    2075              :     4, 12, 8, 4, 8, 4, 6, 12,
    2076              :     2, 18, 6, 10, 6, 6, 2, 6,
    2077              :     10, 6, 6, 2, 6, 6, 4, 2,
    2078              :     12, 10, 2, 4, 6, 6, 2, 12,
    2079              :     4, 6, 8, 10, 8, 10, 8, 6,
    2080              :     6, 4, 8, 6, 4, 8, 4, 14,
    2081              :     10, 12, 2, 10, 2, 4, 2, 10,
    2082              :     14, 4, 2, 4, 14, 4, 2, 4,
    2083              :     20, 4, 8, 10, 8, 4, 6, 6,
    2084              :     14, 4, 6, 6, 8, 6, /*reaches 997*/
    2085              :     0 /* the last entry is effectively unused */
    2086              : };
    2087              : 
    2088              : /*
    2089              :  * Small divisors test (X must be positive)
    2090              :  *
    2091              :  * Return values:
    2092              :  * 0: no small factor (possible prime, more tests needed)
    2093              :  * 1: certain prime
    2094              :  * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
    2095              :  * other negative: error
    2096              :  */
    2097            0 : static int mpi_check_small_factors(const mbedtls_mpi *X)
    2098              : {
    2099            0 :     int ret = 0;
    2100              :     size_t i;
    2101              :     mbedtls_mpi_uint r;
    2102            0 :     unsigned p = 3; /* The first odd prime */
    2103              : 
    2104            0 :     if ((X->p[0] & 1) == 0) {
    2105            0 :         return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2106              :     }
    2107              : 
    2108            0 :     for (i = 0; i < sizeof(small_prime_gaps); p += small_prime_gaps[i], i++) {
    2109            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, p));
    2110            0 :         if (r == 0) {
    2111            0 :             if (mbedtls_mpi_cmp_int(X, p) == 0) {
    2112            0 :                 return 1;
    2113              :             } else {
    2114            0 :                 return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2115              :             }
    2116              :         }
    2117              :     }
    2118              : 
    2119            0 : cleanup:
    2120            0 :     return ret;
    2121              : }
    2122              : 
    2123              : /*
    2124              :  * Miller-Rabin pseudo-primality test  (HAC 4.24)
    2125              :  */
    2126            0 : static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds,
    2127              :                             int (*f_rng)(void *, unsigned char *, size_t),
    2128              :                             void *p_rng)
    2129              : {
    2130              :     int ret, count;
    2131              :     size_t i, j, k, s;
    2132              :     mbedtls_mpi W, R, T, A, RR;
    2133              : 
    2134            0 :     mbedtls_mpi_init(&W); mbedtls_mpi_init(&R);
    2135            0 :     mbedtls_mpi_init(&T); mbedtls_mpi_init(&A);
    2136            0 :     mbedtls_mpi_init(&RR);
    2137              : 
    2138              :     /*
    2139              :      * W = |X| - 1
    2140              :      * R = W >> lsb( W )
    2141              :      */
    2142            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&W, X, 1));
    2143            0 :     s = mbedtls_mpi_lsb(&W);
    2144            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&R, &W));
    2145            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&R, s));
    2146              : 
    2147            0 :     for (i = 0; i < rounds; i++) {
    2148              :         /*
    2149              :          * pick a random A, 1 < A < |X| - 1
    2150              :          */
    2151            0 :         count = 0;
    2152              :         do {
    2153            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&A, X->n * ciL, f_rng, p_rng));
    2154              : 
    2155            0 :             j = mbedtls_mpi_bitlen(&A);
    2156            0 :             k = mbedtls_mpi_bitlen(&W);
    2157            0 :             if (j > k) {
    2158            0 :                 A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1;
    2159              :             }
    2160              : 
    2161            0 :             if (count++ > 30) {
    2162            0 :                 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2163            0 :                 goto cleanup;
    2164              :             }
    2165              : 
    2166            0 :         } while (mbedtls_mpi_cmp_mpi(&A, &W) >= 0 ||
    2167            0 :                  mbedtls_mpi_cmp_int(&A, 1)  <= 0);
    2168              : 
    2169              :         /*
    2170              :          * A = A^R mod |X|
    2171              :          */
    2172            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&A, &A, &R, X, &RR));
    2173              : 
    2174            0 :         if (mbedtls_mpi_cmp_mpi(&A, &W) == 0 ||
    2175            0 :             mbedtls_mpi_cmp_int(&A,  1) == 0) {
    2176            0 :             continue;
    2177              :         }
    2178              : 
    2179            0 :         j = 1;
    2180            0 :         while (j < s && mbedtls_mpi_cmp_mpi(&A, &W) != 0) {
    2181              :             /*
    2182              :              * A = A * A mod |X|
    2183              :              */
    2184            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &A, &A));
    2185            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&A, &T, X));
    2186              : 
    2187            0 :             if (mbedtls_mpi_cmp_int(&A, 1) == 0) {
    2188            0 :                 break;
    2189              :             }
    2190              : 
    2191            0 :             j++;
    2192              :         }
    2193              : 
    2194              :         /*
    2195              :          * not prime if A != |X| - 1 or A == 1
    2196              :          */
    2197            0 :         if (mbedtls_mpi_cmp_mpi(&A, &W) != 0 ||
    2198            0 :             mbedtls_mpi_cmp_int(&A,  1) == 0) {
    2199            0 :             ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2200            0 :             break;
    2201              :         }
    2202              :     }
    2203              : 
    2204            0 : cleanup:
    2205            0 :     mbedtls_mpi_free(&W); mbedtls_mpi_free(&R);
    2206            0 :     mbedtls_mpi_free(&T); mbedtls_mpi_free(&A);
    2207            0 :     mbedtls_mpi_free(&RR);
    2208              : 
    2209            0 :     return ret;
    2210              : }
    2211              : 
    2212              : /*
    2213              :  * Pseudo-primality test: small factors, then Miller-Rabin
    2214              :  */
    2215            0 : int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
    2216              :                              int (*f_rng)(void *, unsigned char *, size_t),
    2217              :                              void *p_rng)
    2218              : {
    2219            0 :     int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
    2220              :     mbedtls_mpi XX;
    2221              : 
    2222            0 :     XX.s = 1;
    2223            0 :     XX.n = X->n;
    2224            0 :     XX.p = X->p;
    2225              : 
    2226            0 :     if (mbedtls_mpi_cmp_int(&XX, 0) == 0 ||
    2227            0 :         mbedtls_mpi_cmp_int(&XX, 1) == 0) {
    2228            0 :         return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2229              :     }
    2230              : 
    2231            0 :     if (mbedtls_mpi_cmp_int(&XX, 2) == 0) {
    2232            0 :         return 0;
    2233              :     }
    2234              : 
    2235            0 :     if ((ret = mpi_check_small_factors(&XX)) != 0) {
    2236            0 :         if (ret == 1) {
    2237            0 :             return 0;
    2238              :         }
    2239              : 
    2240            0 :         return ret;
    2241              :     }
    2242              : 
    2243            0 :     return mpi_miller_rabin(&XX, rounds, f_rng, p_rng);
    2244              : }
    2245              : 
    2246              : /*
    2247              :  * Prime number generation
    2248              :  *
    2249              :  * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
    2250              :  * be either 1024 bits or 1536 bits long, and flags must contain
    2251              :  * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
    2252              :  */
    2253            0 : int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
    2254              :                           int (*f_rng)(void *, unsigned char *, size_t),
    2255              :                           void *p_rng)
    2256              : {
    2257              : #ifdef MBEDTLS_HAVE_INT64
    2258              : // ceil(2^63.5)
    2259              : #define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
    2260              : #else
    2261              : // ceil(2^31.5)
    2262              : #define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
    2263              : #endif
    2264            0 :     int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
    2265              :     size_t k, n;
    2266              :     int rounds;
    2267              :     mbedtls_mpi_uint r;
    2268              :     mbedtls_mpi Y;
    2269              : 
    2270            0 :     if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS) {
    2271            0 :         return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
    2272              :     }
    2273              : 
    2274            0 :     mbedtls_mpi_init(&Y);
    2275              : 
    2276            0 :     n = BITS_TO_LIMBS(nbits);
    2277              : 
    2278            0 :     if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR) == 0) {
    2279              :         /*
    2280              :          * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
    2281              :          */
    2282            0 :         rounds = ((nbits >= 1300) ?  2 : (nbits >=  850) ?  3 :
    2283            0 :                   (nbits >=  650) ?  4 : (nbits >=  350) ?  8 :
    2284            0 :                   (nbits >=  250) ? 12 : (nbits >=  150) ? 18 : 27);
    2285              :     } else {
    2286              :         /*
    2287              :          * 2^-100 error probability, number of rounds computed based on HAC,
    2288              :          * fact 4.48
    2289              :          */
    2290            0 :         rounds = ((nbits >= 1450) ?  4 : (nbits >=  1150) ?  5 :
    2291            0 :                   (nbits >= 1000) ?  6 : (nbits >=   850) ?  7 :
    2292            0 :                   (nbits >=  750) ?  8 : (nbits >=   500) ? 13 :
    2293            0 :                   (nbits >=  250) ? 28 : (nbits >=   150) ? 40 : 51);
    2294              :     }
    2295              : 
    2296              :     while (1) {
    2297            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(X, n * ciL, f_rng, p_rng));
    2298              :         /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
    2299            0 :         if (X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2) {
    2300            0 :             continue;
    2301              :         }
    2302              : 
    2303            0 :         k = n * biL;
    2304            0 :         if (k > nbits) {
    2305            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(X, k - nbits));
    2306              :         }
    2307            0 :         X->p[0] |= 1;
    2308              : 
    2309            0 :         if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) == 0) {
    2310            0 :             ret = mbedtls_mpi_is_prime_ext(X, rounds, f_rng, p_rng);
    2311              : 
    2312            0 :             if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
    2313            0 :                 goto cleanup;
    2314              :             }
    2315              :         } else {
    2316              :             /*
    2317              :              * A necessary condition for Y and X = 2Y + 1 to be prime
    2318              :              * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
    2319              :              * Make sure it is satisfied, while keeping X = 3 mod 4
    2320              :              */
    2321              : 
    2322            0 :             X->p[0] |= 2;
    2323              : 
    2324            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, 3));
    2325            0 :             if (r == 0) {
    2326            0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 8));
    2327            0 :             } else if (r == 1) {
    2328            0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 4));
    2329              :             }
    2330              : 
    2331              :             /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
    2332            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, X));
    2333            0 :             MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, 1));
    2334              : 
    2335              :             while (1) {
    2336              :                 /*
    2337              :                  * First, check small factors for X and Y
    2338              :                  * before doing Miller-Rabin on any of them
    2339              :                  */
    2340            0 :                 if ((ret = mpi_check_small_factors(X)) == 0 &&
    2341            0 :                     (ret = mpi_check_small_factors(&Y)) == 0 &&
    2342            0 :                     (ret = mpi_miller_rabin(X, rounds, f_rng, p_rng))
    2343            0 :                     == 0 &&
    2344            0 :                     (ret = mpi_miller_rabin(&Y, rounds, f_rng, p_rng))
    2345              :                     == 0) {
    2346            0 :                     goto cleanup;
    2347              :                 }
    2348              : 
    2349            0 :                 if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE) {
    2350            0 :                     goto cleanup;
    2351              :                 }
    2352              : 
    2353              :                 /*
    2354              :                  * Next candidates. We want to preserve Y = (X-1) / 2 and
    2355              :                  * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
    2356              :                  * so up Y by 6 and X by 12.
    2357              :                  */
    2358            0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X,  X, 12));
    2359            0 :                 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&Y, &Y, 6));
    2360              :             }
    2361              :         }
    2362              :     }
    2363              : 
    2364            0 : cleanup:
    2365              : 
    2366            0 :     mbedtls_mpi_free(&Y);
    2367              : 
    2368            0 :     return ret;
    2369              : }
    2370              : 
    2371              : #endif /* MBEDTLS_GENPRIME */
    2372              : 
    2373              : #if defined(MBEDTLS_SELF_TEST)
    2374              : 
    2375              : #define GCD_PAIR_COUNT  3
    2376              : 
    2377              : static const int gcd_pairs[GCD_PAIR_COUNT][3] =
    2378              : {
    2379              :     { 693, 609, 21 },
    2380              :     { 1764, 868, 28 },
    2381              :     { 768454923, 542167814, 1 }
    2382              : };
    2383              : 
    2384              : /*
    2385              :  * Checkup routine
    2386              :  */
    2387            0 : int mbedtls_mpi_self_test(int verbose)
    2388              : {
    2389              :     int ret, i;
    2390              :     mbedtls_mpi A, E, N, X, Y, U, V;
    2391              : 
    2392            0 :     mbedtls_mpi_init(&A); mbedtls_mpi_init(&E); mbedtls_mpi_init(&N); mbedtls_mpi_init(&X);
    2393            0 :     mbedtls_mpi_init(&Y); mbedtls_mpi_init(&U); mbedtls_mpi_init(&V);
    2394              : 
    2395            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16,
    2396              :                                             "EFE021C2645FD1DC586E69184AF4A31E" \
    2397              :                                             "D5F53E93B5F123FA41680867BA110131" \
    2398              :                                             "944FE7952E2517337780CB0DB80E61AA" \
    2399              :                                             "E7C8DDC6C5C6AADEB34EB38A2F40D5E6"));
    2400              : 
    2401            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&E, 16,
    2402              :                                             "B2E7EFD37075B9F03FF989C7C5051C20" \
    2403              :                                             "34D2A323810251127E7BF8625A4F49A5" \
    2404              :                                             "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
    2405              :                                             "5B5C25763222FEFCCFC38B832366C29E"));
    2406              : 
    2407            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16,
    2408              :                                             "0066A198186C18C10B2F5ED9B522752A" \
    2409              :                                             "9830B69916E535C8F047518A889A43A5" \
    2410              :                                             "94B6BED27A168D31D4A52F88925AA8F5"));
    2411              : 
    2412            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&X, &A, &N));
    2413              : 
    2414            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
    2415              :                                             "602AB7ECA597A3D6B56FF9829A5E8B85" \
    2416              :                                             "9E857EA95A03512E2BAE7391688D264A" \
    2417              :                                             "A5663B0341DB9CCFD2C4C5F421FEC814" \
    2418              :                                             "8001B72E848A38CAE1C65F78E56ABDEF" \
    2419              :                                             "E12D3C039B8A02D6BE593F0BBBDA56F1" \
    2420              :                                             "ECF677152EF804370C1A305CAF3B5BF1" \
    2421              :                                             "30879B56C61DE584A0F53A2447A51E"));
    2422              : 
    2423            0 :     if (verbose != 0) {
    2424            0 :         mbedtls_printf("  MPI test #1 (mul_mpi): ");
    2425              :     }
    2426              : 
    2427            0 :     if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
    2428            0 :         if (verbose != 0) {
    2429            0 :             mbedtls_printf("failed\n");
    2430              :         }
    2431              : 
    2432            0 :         ret = 1;
    2433            0 :         goto cleanup;
    2434              :     }
    2435              : 
    2436            0 :     if (verbose != 0) {
    2437            0 :         mbedtls_printf("passed\n");
    2438              :     }
    2439              : 
    2440            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&X, &Y, &A, &N));
    2441              : 
    2442            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
    2443              :                                             "256567336059E52CAE22925474705F39A94"));
    2444              : 
    2445            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&V, 16,
    2446              :                                             "6613F26162223DF488E9CD48CC132C7A" \
    2447              :                                             "0AC93C701B001B092E4E5B9F73BCD27B" \
    2448              :                                             "9EE50D0657C77F374E903CDFA4C642"));
    2449              : 
    2450            0 :     if (verbose != 0) {
    2451            0 :         mbedtls_printf("  MPI test #2 (div_mpi): ");
    2452              :     }
    2453              : 
    2454            0 :     if (mbedtls_mpi_cmp_mpi(&X, &U) != 0 ||
    2455            0 :         mbedtls_mpi_cmp_mpi(&Y, &V) != 0) {
    2456            0 :         if (verbose != 0) {
    2457            0 :             mbedtls_printf("failed\n");
    2458              :         }
    2459              : 
    2460            0 :         ret = 1;
    2461            0 :         goto cleanup;
    2462              :     }
    2463              : 
    2464            0 :     if (verbose != 0) {
    2465            0 :         mbedtls_printf("passed\n");
    2466              :     }
    2467              : 
    2468            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL));
    2469              : 
    2470            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
    2471              :                                             "36E139AEA55215609D2816998ED020BB" \
    2472              :                                             "BD96C37890F65171D948E9BC7CBAA4D9" \
    2473              :                                             "325D24D6A3C12710F10A09FA08AB87"));
    2474              : 
    2475            0 :     if (verbose != 0) {
    2476            0 :         mbedtls_printf("  MPI test #3 (exp_mod): ");
    2477              :     }
    2478              : 
    2479            0 :     if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
    2480            0 :         if (verbose != 0) {
    2481            0 :             mbedtls_printf("failed\n");
    2482              :         }
    2483              : 
    2484            0 :         ret = 1;
    2485            0 :         goto cleanup;
    2486              :     }
    2487              : 
    2488            0 :     if (verbose != 0) {
    2489            0 :         mbedtls_printf("passed\n");
    2490              :     }
    2491              : 
    2492            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&X, &A, &N));
    2493              : 
    2494            0 :     MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
    2495              :                                             "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
    2496              :                                             "C3DBA76456363A10869622EAC2DD84EC" \
    2497              :                                             "C5B8A74DAC4D09E03B5E0BE779F2DF61"));
    2498              : 
    2499            0 :     if (verbose != 0) {
    2500            0 :         mbedtls_printf("  MPI test #4 (inv_mod): ");
    2501              :     }
    2502              : 
    2503            0 :     if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
    2504            0 :         if (verbose != 0) {
    2505            0 :             mbedtls_printf("failed\n");
    2506              :         }
    2507              : 
    2508            0 :         ret = 1;
    2509            0 :         goto cleanup;
    2510              :     }
    2511              : 
    2512            0 :     if (verbose != 0) {
    2513            0 :         mbedtls_printf("passed\n");
    2514              :     }
    2515              : 
    2516            0 :     if (verbose != 0) {
    2517            0 :         mbedtls_printf("  MPI test #5 (simple gcd): ");
    2518              :     }
    2519              : 
    2520            0 :     for (i = 0; i < GCD_PAIR_COUNT; i++) {
    2521            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, gcd_pairs[i][0]));
    2522            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Y, gcd_pairs[i][1]));
    2523              : 
    2524            0 :         MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&A, &X, &Y));
    2525              : 
    2526            0 :         if (mbedtls_mpi_cmp_int(&A, gcd_pairs[i][2]) != 0) {
    2527            0 :             if (verbose != 0) {
    2528            0 :                 mbedtls_printf("failed at %d\n", i);
    2529              :             }
    2530              : 
    2531            0 :             ret = 1;
    2532            0 :             goto cleanup;
    2533              :         }
    2534              :     }
    2535              : 
    2536            0 :     if (verbose != 0) {
    2537            0 :         mbedtls_printf("passed\n");
    2538              :     }
    2539              : 
    2540            0 : cleanup:
    2541              : 
    2542            0 :     if (ret != 0 && verbose != 0) {
    2543            0 :         mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret);
    2544              :     }
    2545              : 
    2546            0 :     mbedtls_mpi_free(&A); mbedtls_mpi_free(&E); mbedtls_mpi_free(&N); mbedtls_mpi_free(&X);
    2547            0 :     mbedtls_mpi_free(&Y); mbedtls_mpi_free(&U); mbedtls_mpi_free(&V);
    2548              : 
    2549            0 :     if (verbose != 0) {
    2550            0 :         mbedtls_printf("\n");
    2551              :     }
    2552              : 
    2553            0 :     return ret;
    2554              : }
    2555              : 
    2556              : #endif /* MBEDTLS_SELF_TEST */
    2557              : 
    2558              : #endif /* MBEDTLS_BIGNUM_C */
        

Generated by: LCOV version 2.0-1