Gabor Mezei | c5328cf | 2022-07-18 23:13:13 +0200 | [diff] [blame] | 1 | /** |
Janos Follath | a95f204 | 2022-08-19 12:09:17 +0100 | [diff] [blame] | 2 | * Low-level modular bignum functions |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame] | 3 | * |
Janos Follath | af3f39c | 2022-08-22 09:06:32 +0100 | [diff] [blame] | 4 | * This interface should only be used by the higher-level modular bignum |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame] | 5 | * module (bignum_mod.c) and the ECP module (ecp.c, ecp_curves.c). All other |
Janos Follath | af3f39c | 2022-08-22 09:06:32 +0100 | [diff] [blame] | 6 | * modules should use the high-level modular bignum interface (bignum_mod.h) |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame] | 7 | * or the legacy bignum interface (bignum.h). |
Gabor Mezei | c5328cf | 2022-07-18 23:13:13 +0200 | [diff] [blame] | 8 | * |
Gilles Peskine | 7aab2fb | 2022-09-27 13:19:13 +0200 | [diff] [blame] | 9 | * This is a low-level interface to operations on integers modulo which |
| 10 | * has no protection against passing invalid arguments such as arrays of |
| 11 | * the wrong size. The functions in bignum_mod.h provide a higher-level |
| 12 | * interface that includes protections against accidental misuse, at the |
| 13 | * expense of code size and sometimes more cumbersome memory management. |
Gilles Peskine | 7f887bd | 2022-09-27 13:12:30 +0200 | [diff] [blame] | 14 | */ |
| 15 | |
| 16 | /* |
Gabor Mezei | c5328cf | 2022-07-18 23:13:13 +0200 | [diff] [blame] | 17 | * Copyright The Mbed TLS Contributors |
| 18 | * SPDX-License-Identifier: Apache-2.0 |
| 19 | * |
| 20 | * Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 21 | * not use this file except in compliance with the License. |
| 22 | * You may obtain a copy of the License at |
| 23 | * |
| 24 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 25 | * |
| 26 | * Unless required by applicable law or agreed to in writing, software |
| 27 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 28 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 29 | * See the License for the specific language governing permissions and |
| 30 | * limitations under the License. |
| 31 | */ |
| 32 | |
Janos Follath | 5005edb | 2022-07-19 12:45:13 +0100 | [diff] [blame] | 33 | #ifndef MBEDTLS_BIGNUM_MOD_RAW_H |
| 34 | #define MBEDTLS_BIGNUM_MOD_RAW_H |
Gabor Mezei | c5328cf | 2022-07-18 23:13:13 +0200 | [diff] [blame] | 35 | |
| 36 | #include "common.h" |
| 37 | |
| 38 | #if defined(MBEDTLS_BIGNUM_C) |
| 39 | #include "mbedtls/bignum.h" |
| 40 | #endif |
| 41 | |
Janos Follath | 0ded631 | 2022-08-09 13:34:54 +0100 | [diff] [blame] | 42 | #include "bignum_mod.h" |
| 43 | |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 44 | /** |
Gabor Mezei | 4086de6 | 2022-10-14 16:29:42 +0200 | [diff] [blame] | 45 | * \brief Perform a safe conditional copy of an MPI which doesn't reveal |
| 46 | * whether the assignment was done or not. |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 47 | * |
Gabor Mezei | dba2677 | 2022-10-03 17:01:02 +0200 | [diff] [blame] | 48 | * The size to copy is determined by \p N. |
| 49 | * |
Gabor Mezei | 4086de6 | 2022-10-14 16:29:42 +0200 | [diff] [blame] | 50 | * \param[out] X The address of the destination MPI. |
| 51 | * This must be initialized. Must have enough limbs to |
| 52 | * store the full value of \p A. |
| 53 | * \param[in] A The address of the source MPI. This must be initialized. |
Gabor Mezei | 86dfe38 | 2022-09-30 14:03:04 +0200 | [diff] [blame] | 54 | * \param[in] N The address of the modulus related to \p X and \p A. |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 55 | * \param assign The condition deciding whether to perform the |
| 56 | * assignment or not. Must be either 0 or 1: |
Gabor Mezei | 1c628d5 | 2022-09-27 12:13:51 +0200 | [diff] [blame] | 57 | * * \c 1: Perform the assignment `X = A`. |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 58 | * * \c 0: Keep the original value of \p X. |
| 59 | * |
| 60 | * \note This function avoids leaking any information about whether |
| 61 | * the assignment was done or not. |
| 62 | * |
| 63 | * \warning If \p assign is neither 0 nor 1, the result of this function |
| 64 | * is indeterminate, and the resulting value in \p X might be |
Gabor Mezei | 4086de6 | 2022-10-14 16:29:42 +0200 | [diff] [blame] | 65 | * neither its original value nor the value in \p A. |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 66 | */ |
Gabor Mezei | 63c3282 | 2022-09-15 20:01:31 +0200 | [diff] [blame] | 67 | void mbedtls_mpi_mod_raw_cond_assign( mbedtls_mpi_uint *X, |
Gabor Mezei | 1c628d5 | 2022-09-27 12:13:51 +0200 | [diff] [blame] | 68 | const mbedtls_mpi_uint *A, |
Gabor Mezei | e5b8585 | 2022-09-30 13:54:02 +0200 | [diff] [blame] | 69 | const mbedtls_mpi_mod_modulus *N, |
Gabor Mezei | 63c3282 | 2022-09-15 20:01:31 +0200 | [diff] [blame] | 70 | unsigned char assign ); |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 71 | |
| 72 | /** |
Gabor Mezei | 4086de6 | 2022-10-14 16:29:42 +0200 | [diff] [blame] | 73 | * \brief Perform a safe conditional swap of two MPIs which doesn't reveal |
| 74 | * whether the swap was done or not. |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 75 | * |
Gabor Mezei | dba2677 | 2022-10-03 17:01:02 +0200 | [diff] [blame] | 76 | * The size to swap is determined by \p N. |
| 77 | * |
Gabor Mezei | 86dfe38 | 2022-09-30 14:03:04 +0200 | [diff] [blame] | 78 | * \param[in,out] X The address of the first MPI. This must be initialized. |
| 79 | * \param[in,out] Y The address of the second MPI. This must be initialized. |
| 80 | * \param[in] N The address of the modulus related to \p X and \p Y. |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 81 | * \param swap The condition deciding whether to perform |
| 82 | * the swap or not. Must be either 0 or 1: |
Gabor Mezei | e5b8585 | 2022-09-30 13:54:02 +0200 | [diff] [blame] | 83 | * * \c 1: Swap the values of \p X and \p Y. |
| 84 | * * \c 0: Keep the original values of \p X and \p Y. |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 85 | * |
| 86 | * \note This function avoids leaking any information about whether |
| 87 | * the swap was done or not. |
| 88 | * |
| 89 | * \warning If \p swap is neither 0 nor 1, the result of this function |
Gabor Mezei | e5b8585 | 2022-09-30 13:54:02 +0200 | [diff] [blame] | 90 | * is indeterminate, and both \p X and \p Y might end up with |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 91 | * values different to either of the original ones. |
Gabor Mezei | 63c3282 | 2022-09-15 20:01:31 +0200 | [diff] [blame] | 92 | */ |
Gabor Mezei | e5b8585 | 2022-09-30 13:54:02 +0200 | [diff] [blame] | 93 | void mbedtls_mpi_mod_raw_cond_swap( mbedtls_mpi_uint *X, |
| 94 | mbedtls_mpi_uint *Y, |
| 95 | const mbedtls_mpi_mod_modulus *N, |
Gabor Mezei | 63c3282 | 2022-09-15 20:01:31 +0200 | [diff] [blame] | 96 | unsigned char swap ); |
Gabor Mezei | 12071d4 | 2022-09-12 16:35:58 +0200 | [diff] [blame] | 97 | |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 98 | /** Import X from unsigned binary data. |
| 99 | * |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame] | 100 | * The MPI needs to have enough limbs to store the full value (including any |
| 101 | * most significant zero bytes in the input). |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 102 | * |
Janos Follath | b7a88ec | 2022-08-19 12:24:40 +0100 | [diff] [blame] | 103 | * \param[out] X The address of the MPI. The size is determined by \p m. |
| 104 | * (In particular, it must have at least as many limbs as |
| 105 | * the modulus \p m.) |
| 106 | * \param[in] m The address of the modulus related to \p X. |
| 107 | * \param[in] input The input buffer to import from. |
| 108 | * \param input_length The length in bytes of \p input. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 109 | * |
| 110 | * \return \c 0 if successful. |
| 111 | * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't |
Janos Follath | b7a88ec | 2022-08-19 12:24:40 +0100 | [diff] [blame] | 112 | * large enough to hold the value in \p input. |
Janos Follath | 8ff0729 | 2022-08-08 08:39:52 +0100 | [diff] [blame] | 113 | * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation |
Janos Follath | dae1147 | 2022-08-08 11:50:02 +0100 | [diff] [blame] | 114 | * of \p m is invalid or \p X is not less than \p m. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 115 | */ |
Gabor Mezei | c5328cf | 2022-07-18 23:13:13 +0200 | [diff] [blame] | 116 | int mbedtls_mpi_mod_raw_read( mbedtls_mpi_uint *X, |
Janos Follath | 6b8a4ad | 2022-08-19 10:58:34 +0100 | [diff] [blame] | 117 | const mbedtls_mpi_mod_modulus *m, |
Janos Follath | b7a88ec | 2022-08-19 12:24:40 +0100 | [diff] [blame] | 118 | const unsigned char *input, |
| 119 | size_t input_length ); |
Gabor Mezei | c5328cf | 2022-07-18 23:13:13 +0200 | [diff] [blame] | 120 | |
Janos Follath | b7a88ec | 2022-08-19 12:24:40 +0100 | [diff] [blame] | 121 | /** Export A into unsigned binary data. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 122 | * |
Janos Follath | b7a88ec | 2022-08-19 12:24:40 +0100 | [diff] [blame] | 123 | * \param[in] A The address of the MPI. The size is determined by \p m. |
| 124 | * (In particular, it must have at least as many limbs as |
| 125 | * the modulus \p m.) |
| 126 | * \param[in] m The address of the modulus related to \p A. |
| 127 | * \param[out] output The output buffer to export to. |
| 128 | * \param output_length The length in bytes of \p output. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 129 | * |
| 130 | * \return \c 0 if successful. |
Janos Follath | b7a88ec | 2022-08-19 12:24:40 +0100 | [diff] [blame] | 131 | * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p output isn't |
| 132 | * large enough to hold the value of \p A. |
Janos Follath | 8ff0729 | 2022-08-08 08:39:52 +0100 | [diff] [blame] | 133 | * \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the external representation |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 134 | * of \p m is invalid. |
| 135 | */ |
Janos Follath | b7a88ec | 2022-08-19 12:24:40 +0100 | [diff] [blame] | 136 | int mbedtls_mpi_mod_raw_write( const mbedtls_mpi_uint *A, |
Janos Follath | 6b8a4ad | 2022-08-19 10:58:34 +0100 | [diff] [blame] | 137 | const mbedtls_mpi_mod_modulus *m, |
Janos Follath | b7a88ec | 2022-08-19 12:24:40 +0100 | [diff] [blame] | 138 | unsigned char *output, |
| 139 | size_t output_length ); |
Gabor Mezei | c5328cf | 2022-07-18 23:13:13 +0200 | [diff] [blame] | 140 | |
Janos Follath | 5933f69 | 2022-11-02 14:35:17 +0000 | [diff] [blame] | 141 | /* BEGIN MERGE SLOT 1 */ |
| 142 | |
| 143 | /* END MERGE SLOT 1 */ |
| 144 | |
| 145 | /* BEGIN MERGE SLOT 2 */ |
| 146 | |
Gabor Mezei | 4c7cf7d | 2022-11-09 14:07:43 +0100 | [diff] [blame] | 147 | /** \brief Perform a subtraction of two MPIs and return the modulus |
| 148 | * of the result. |
| 149 | * |
| 150 | * The size of the operation is determined by \p N. |
| 151 | * |
| 152 | * \param[out] X The address of the result MPI. |
| 153 | * This must be initialized. Must have enough limbs to |
| 154 | * store the full value of the result. |
| 155 | * \param[in] A The address of the first MPI. This must be initialized. |
| 156 | * \param[in] B The address of the second MPI. This must be initialized. |
| 157 | * \param[in] N The address of the modulus. Use to perform a modulu |
| 158 | * operation on the result of the subtraction. |
| 159 | * |
| 160 | * \note Both \p A and \p B must be smaller than the modulus \p N. |
| 161 | */ |
| 162 | void mbedtls_mpi_mod_raw_sub( mbedtls_mpi_uint *X, |
| 163 | const mbedtls_mpi_uint *A, |
| 164 | const mbedtls_mpi_uint *B, |
| 165 | const mbedtls_mpi_mod_modulus *N ); |
| 166 | |
Janos Follath | 5933f69 | 2022-11-02 14:35:17 +0000 | [diff] [blame] | 167 | /* END MERGE SLOT 2 */ |
| 168 | |
| 169 | /* BEGIN MERGE SLOT 3 */ |
| 170 | |
| 171 | /* END MERGE SLOT 3 */ |
| 172 | |
| 173 | /* BEGIN MERGE SLOT 4 */ |
| 174 | |
| 175 | /* END MERGE SLOT 4 */ |
| 176 | |
| 177 | /* BEGIN MERGE SLOT 5 */ |
| 178 | |
| 179 | /* END MERGE SLOT 5 */ |
| 180 | |
| 181 | /* BEGIN MERGE SLOT 6 */ |
| 182 | |
| 183 | /* END MERGE SLOT 6 */ |
| 184 | |
| 185 | /* BEGIN MERGE SLOT 7 */ |
Minos Galanakis | d9299c3 | 2022-11-01 16:19:07 +0000 | [diff] [blame] | 186 | /** Convert an MPI into Montgomery form. |
Hanno Becker | 5ad4a93 | 2022-08-09 14:45:53 +0100 | [diff] [blame] | 187 | * |
| 188 | * \param X The address of the MPI. |
Minos Galanakis | d9299c3 | 2022-11-01 16:19:07 +0000 | [diff] [blame] | 189 | * Must have the same number of limbs as \p m. |
| 190 | * \param m The address of the modulus, which gives the size of |
| 191 | * the base `R` = 2^(biL*m->limbs). |
Hanno Becker | 5ad4a93 | 2022-08-09 14:45:53 +0100 | [diff] [blame] | 192 | * |
| 193 | * \return \c 0 if successful. |
| 194 | */ |
Minos Galanakis | d9299c3 | 2022-11-01 16:19:07 +0000 | [diff] [blame] | 195 | int mbedtls_mpi_mod_raw_to_mont_rep( mbedtls_mpi_uint *X, |
| 196 | const mbedtls_mpi_mod_modulus *m ); |
Janos Follath | 5933f69 | 2022-11-02 14:35:17 +0000 | [diff] [blame] | 197 | |
Minos Galanakis | d9299c3 | 2022-11-01 16:19:07 +0000 | [diff] [blame] | 198 | /** Convert an MPI back from Montgomery representation. |
Hanno Becker | 5ad4a93 | 2022-08-09 14:45:53 +0100 | [diff] [blame] | 199 | * |
| 200 | * \param X The address of the MPI. |
Minos Galanakis | d9299c3 | 2022-11-01 16:19:07 +0000 | [diff] [blame] | 201 | * Must have the same number of limbs as \p m. |
| 202 | * \param m The address of the modulus, which gives the size of |
| 203 | * the base `R`= 2^(biL*m->limbs). |
Hanno Becker | 5ad4a93 | 2022-08-09 14:45:53 +0100 | [diff] [blame] | 204 | * |
| 205 | * \return \c 0 if successful. |
| 206 | */ |
Minos Galanakis | d9299c3 | 2022-11-01 16:19:07 +0000 | [diff] [blame] | 207 | int mbedtls_mpi_mod_raw_from_mont_rep( mbedtls_mpi_uint *X, |
| 208 | const mbedtls_mpi_mod_modulus *m ); |
Janos Follath | 5933f69 | 2022-11-02 14:35:17 +0000 | [diff] [blame] | 209 | /* END MERGE SLOT 7 */ |
| 210 | |
| 211 | /* BEGIN MERGE SLOT 8 */ |
| 212 | |
| 213 | /* END MERGE SLOT 8 */ |
| 214 | |
| 215 | /* BEGIN MERGE SLOT 9 */ |
| 216 | |
| 217 | /* END MERGE SLOT 9 */ |
| 218 | |
| 219 | /* BEGIN MERGE SLOT 10 */ |
| 220 | |
| 221 | /* END MERGE SLOT 10 */ |
| 222 | |
Janos Follath | 5005edb | 2022-07-19 12:45:13 +0100 | [diff] [blame] | 223 | #endif /* MBEDTLS_BIGNUM_MOD_RAW_H */ |