Gabor Mezei | b903070 | 2022-07-18 23:09:45 +0200 | [diff] [blame] | 1 | /** |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame^] | 2 | * Core bignum functions |
| 3 | * |
| 4 | * This interface only should be used by the legacy bignum module (bignum.h) |
| 5 | * and the modular bignum modules (bignum_mod.c, bignum_mod_raw.c). All other |
| 6 | * modules should use the high level modular bignum interface (bignum_mod.h) |
| 7 | * or the legacy bignum interface (bignum.h). |
Gabor Mezei | b903070 | 2022-07-18 23:09:45 +0200 | [diff] [blame] | 8 | * |
| 9 | * Copyright The Mbed TLS Contributors |
| 10 | * SPDX-License-Identifier: Apache-2.0 |
| 11 | * |
| 12 | * Licensed under the Apache License, Version 2.0 (the "License"); you may |
| 13 | * not use this file except in compliance with the License. |
| 14 | * You may obtain a copy of the License at |
| 15 | * |
| 16 | * http://www.apache.org/licenses/LICENSE-2.0 |
| 17 | * |
| 18 | * Unless required by applicable law or agreed to in writing, software |
| 19 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
| 20 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 21 | * See the License for the specific language governing permissions and |
| 22 | * limitations under the License. |
| 23 | */ |
| 24 | |
| 25 | #ifndef MBEDTLS_BIGNUM_CORE_H |
| 26 | #define MBEDTLS_BIGNUM_CORE_H |
| 27 | |
| 28 | #include "common.h" |
| 29 | |
| 30 | #if defined(MBEDTLS_BIGNUM_C) |
| 31 | #include "mbedtls/bignum.h" |
| 32 | #endif |
| 33 | |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 34 | /** Count leading zero bits in a given integer. |
| 35 | * |
| 36 | * \param x Integer to count leading zero bits. |
| 37 | * |
Janos Follath | 8ff0729 | 2022-08-08 08:39:52 +0100 | [diff] [blame] | 38 | * \return The number of leading zero bits in \p x. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 39 | */ |
Janos Follath | 4670f88 | 2022-07-21 18:25:42 +0100 | [diff] [blame] | 40 | size_t mbedtls_mpi_core_clz( const mbedtls_mpi_uint x ); |
| 41 | |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame^] | 42 | /** Return the the minimum number of bits required to represent the value held |
| 43 | * in the MPI. |
| 44 | * |
| 45 | * \note This function returns 0 if all the limbs of \p X are 0. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 46 | * |
| 47 | * \param X The address of the MPI. |
| 48 | * \param nx The number of limbs of \p X. |
| 49 | * |
Janos Follath | 8ff0729 | 2022-08-08 08:39:52 +0100 | [diff] [blame] | 50 | * \return The number of bits in \p X. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 51 | */ |
Janos Follath | 4670f88 | 2022-07-21 18:25:42 +0100 | [diff] [blame] | 52 | size_t mbedtls_mpi_core_bitlen( const mbedtls_mpi_uint *X, size_t nx ); |
| 53 | |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 54 | /** Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint |
| 55 | * into the storage form used by mbedtls_mpi. |
| 56 | * |
| 57 | * \param X The address of the MPI. |
| 58 | * \param limbs The number of limbs of \p X. |
| 59 | */ |
Janos Follath | 4670f88 | 2022-07-21 18:25:42 +0100 | [diff] [blame] | 60 | void mbedtls_mpi_core_bigendian_to_host( mbedtls_mpi_uint * const X, |
| 61 | size_t limbs ); |
| 62 | |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 63 | /** Import X from unsigned binary data, little endian. |
| 64 | * |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame^] | 65 | * The MPI needs to have enough limbs to store the full value (including any |
| 66 | * most significant zero bytes in the input). |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 67 | * |
| 68 | * \param X The address of the MPI. |
| 69 | * \param nx The number of limbs of \p X. |
| 70 | * \param buf The input buffer to import from. |
Janos Follath | 8ff0729 | 2022-08-08 08:39:52 +0100 | [diff] [blame] | 71 | * \param buflen The length in bytes of \p buf. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 72 | * |
| 73 | * \return \c 0 if successful. |
| 74 | * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't |
| 75 | * large enough to hold the value in \p buf. |
| 76 | */ |
Gabor Mezei | b903070 | 2022-07-18 23:09:45 +0200 | [diff] [blame] | 77 | int mbedtls_mpi_core_read_le( mbedtls_mpi_uint *X, |
| 78 | size_t nx, |
| 79 | const unsigned char *buf, |
| 80 | size_t buflen ); |
| 81 | |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 82 | /** Import X from unsigned binary data, big endian. |
| 83 | * |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame^] | 84 | * The MPI needs to have enough limbs to store the full value (including any |
| 85 | * most significant zero bytes in the input). |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 86 | * |
| 87 | * \param X The address of the MPI. |
| 88 | * \param nx The number of limbs of \p X. |
| 89 | * \param buf The input buffer to import from. |
Janos Follath | 8ff0729 | 2022-08-08 08:39:52 +0100 | [diff] [blame] | 90 | * \param buflen The length in bytes of \p buf. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 91 | * |
| 92 | * \return \c 0 if successful. |
| 93 | * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p X isn't |
| 94 | * large enough to hold the value in \p buf. |
| 95 | */ |
Gabor Mezei | b903070 | 2022-07-18 23:09:45 +0200 | [diff] [blame] | 96 | int mbedtls_mpi_core_read_be( mbedtls_mpi_uint *X, |
| 97 | size_t nx, |
| 98 | const unsigned char *buf, |
| 99 | size_t buflen ); |
| 100 | |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 101 | /** Export X into unsigned binary data, little endian. |
| 102 | * |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame^] | 103 | * \note If \p buf is shorter than \p X the export is still successful if the |
| 104 | * value held in \p X fits in the buffer (that is, if enough of the most |
| 105 | * significant bytes of \p X are 0). |
| 106 | * |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 107 | * \param X The address of the MPI. |
| 108 | * \param nx The number of limbs of \p X. |
Janos Follath | dae1147 | 2022-08-08 11:50:02 +0100 | [diff] [blame] | 109 | * \param buf The output buffer to export to. |
Janos Follath | 8ff0729 | 2022-08-08 08:39:52 +0100 | [diff] [blame] | 110 | * \param buflen The length in bytes of \p buf. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 111 | * |
| 112 | * \return \c 0 if successful. |
| 113 | * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't |
| 114 | * large enough to hold the value of \p X. |
| 115 | */ |
Gabor Mezei | b903070 | 2022-07-18 23:09:45 +0200 | [diff] [blame] | 116 | int mbedtls_mpi_core_write_le( const mbedtls_mpi_uint *X, |
| 117 | size_t nx, |
| 118 | unsigned char *buf, |
| 119 | size_t buflen ); |
| 120 | |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 121 | /** Export X into unsigned binary data, big endian. |
| 122 | * |
Janos Follath | 6318468 | 2022-08-11 17:42:59 +0100 | [diff] [blame^] | 123 | * \note If \p buf is shorter than \p X the export is still successful if the |
| 124 | * value held in \p X fits in the buffer (that is, if enough of the most |
| 125 | * significant bytes of \p X are 0). |
| 126 | * |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 127 | * \param X The address of the MPI. |
| 128 | * \param nx The number of limbs of \p X. |
Janos Follath | dae1147 | 2022-08-08 11:50:02 +0100 | [diff] [blame] | 129 | * \param buf The output buffer to export to. |
Janos Follath | 8ff0729 | 2022-08-08 08:39:52 +0100 | [diff] [blame] | 130 | * \param buflen The length in bytes of \p buf. |
Gabor Mezei | 37b0636 | 2022-08-02 17:22:18 +0200 | [diff] [blame] | 131 | * |
| 132 | * \return \c 0 if successful. |
| 133 | * \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't |
| 134 | * large enough to hold the value of \p X. |
| 135 | */ |
Gabor Mezei | b903070 | 2022-07-18 23:09:45 +0200 | [diff] [blame] | 136 | int mbedtls_mpi_core_write_be( const mbedtls_mpi_uint *X, |
| 137 | size_t nx, |
| 138 | unsigned char *buf, |
| 139 | size_t buflen ); |
| 140 | |
Janos Follath | d089570 | 2022-08-10 13:32:16 +0100 | [diff] [blame] | 141 | #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */ |
| 142 | #define biL (ciL << 3) /* bits in limb */ |
| 143 | #define biH (ciL << 2) /* half limb size */ |
| 144 | |
| 145 | /* |
| 146 | * Convert between bits/chars and number of limbs |
| 147 | * Divide first in order to avoid potential overflows |
| 148 | */ |
| 149 | #define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) ) |
| 150 | #define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) ) |
| 151 | /* Get a specific byte, without range checks. */ |
| 152 | #define GET_BYTE( X, i ) \ |
| 153 | ( ( ( X )[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff ) |
| 154 | |
Gabor Mezei | b903070 | 2022-07-18 23:09:45 +0200 | [diff] [blame] | 155 | #endif /* MBEDTLS_BIGNUM_CORE_H */ |