Path: blob/master/thirdparty/mbedtls/library/bignum_mod.h
9903 views
/**1* Modular bignum functions2*3* This module implements operations on integers modulo some fixed modulus.4*5* The functions in this module obey the following conventions unless6* explicitly indicated otherwise:7*8* - **Modulus parameters**: the modulus is passed as a pointer to a structure9* of type #mbedtls_mpi_mod_modulus. The structure must be set up with an10* array of limbs storing the bignum value of the modulus. The modulus must11* be odd and is assumed to have no leading zeroes. The modulus is usually12* named \c N and is usually input-only. Functions which take a parameter13* of type \c const #mbedtls_mpi_mod_modulus* must not modify its value.14* - **Bignum parameters**: Bignums are passed as pointers to an array of15* limbs or to a #mbedtls_mpi_mod_residue structure. A limb has the type16* #mbedtls_mpi_uint. Residues must be initialized before use, and must be17* associated with the modulus \c N. Unless otherwise specified:18* - Bignum parameters called \c A, \c B, ... are inputs and are not19* modified by the function. Functions which take a parameter of20* type \c const #mbedtls_mpi_mod_residue* must not modify its value.21* - Bignum parameters called \c X, \c Y, ... are outputs or input-output.22* The initial bignum value of output-only parameters is ignored, but23* they must be set up and associated with the modulus \c N. Some24* functions (typically constant-flow) require that the limbs in an25* output residue are initialized.26* - Bignum parameters called \c p are inputs used to set up a modulus or27* residue. These must be pointers to an array of limbs.28* - \c T is a temporary storage area. The initial content of such a29* parameter is ignored and the final content is unspecified.30* - Some functions use different names, such as \c r for the residue.31* - **Bignum sizes**: bignum sizes are always expressed in limbs. Both32* #mbedtls_mpi_mod_modulus and #mbedtls_mpi_mod_residue have a \c limbs33* member storing its size. All bignum parameters must have the same34* number of limbs as the modulus. All bignum sizes must be at least 1 and35* must be significantly less than #SIZE_MAX. The behavior if a size is 0 is36* undefined.37* - **Bignum representation**: the representation of inputs and outputs is38* specified by the \c int_rep field of the modulus.39* - **Parameter ordering**: for bignum parameters, outputs come before inputs.40* The modulus is passed after residues. Temporaries come last.41* - **Aliasing**: in general, output bignums may be aliased to one or more42* inputs. Modulus values may not be aliased to any other parameter. Outputs43* may not be aliased to one another. Temporaries may not be aliased to any44* other parameter.45* - **Overlap**: apart from aliasing of residue pointers (where two residue46* arguments are equal pointers), overlap is not supported and may result47* in undefined behavior.48* - **Error handling**: functions generally check compatibility of input49* sizes. Most functions will not check that input values are in canonical50* form (i.e. that \c A < \c N), this is only checked during setup of a51* residue structure.52* - **Modular representatives**: all functions expect inputs to be in the53* range [0, \c N - 1] and guarantee outputs in the range [0, \c N - 1].54* Residues are set up with an associated modulus, and operations are only55* guaranteed to work if the modulus is associated with all residue56* parameters. If a residue is passed with a modulus other than the one it57* is associated with, then it may be out of range. If an input is out of58* range, outputs are fully unspecified, though bignum values out of range59* should not cause buffer overflows (beware that this is not extensively60* tested).61*/6263/*64* Copyright The Mbed TLS Contributors65* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0-or-later66*/6768#ifndef MBEDTLS_BIGNUM_MOD_H69#define MBEDTLS_BIGNUM_MOD_H7071#include "common.h"7273#if defined(MBEDTLS_BIGNUM_C)74#include "mbedtls/bignum.h"75#endif7677/** How residues associated with a modulus are represented.78*79* This also determines which fields of the modulus structure are valid and80* what their contents are (see #mbedtls_mpi_mod_modulus).81*/82typedef enum {83/** Representation not chosen (makes the modulus structure invalid). */84MBEDTLS_MPI_MOD_REP_INVALID = 0,85/* Skip 1 as it is slightly easier to accidentally pass to functions. */86/** Montgomery representation. */87MBEDTLS_MPI_MOD_REP_MONTGOMERY = 2,88/* Optimised reduction available. This indicates a coordinate modulus (P)89* and one or more of the following have been configured:90* - A nist curve (MBEDTLS_ECP_DP_SECPXXXR1_ENABLED) & MBEDTLS_ECP_NIST_OPTIM.91* - A Kobliz Curve.92* - A Fast Reduction Curve CURVE25519 or CURVE448. */93MBEDTLS_MPI_MOD_REP_OPT_RED,94} mbedtls_mpi_mod_rep_selector;9596/* Make mbedtls_mpi_mod_rep_selector and mbedtls_mpi_mod_ext_rep disjoint to97* make it easier to catch when they are accidentally swapped. */98typedef enum {99MBEDTLS_MPI_MOD_EXT_REP_INVALID = 0,100MBEDTLS_MPI_MOD_EXT_REP_LE = 8,101MBEDTLS_MPI_MOD_EXT_REP_BE102} mbedtls_mpi_mod_ext_rep;103104typedef struct {105mbedtls_mpi_uint *p;106size_t limbs;107} mbedtls_mpi_mod_residue;108109typedef struct {110mbedtls_mpi_uint const *rr; /* The residue for 2^{2*n*biL} mod N */111mbedtls_mpi_uint mm; /* Montgomery const for -N^{-1} mod 2^{ciL} */112} mbedtls_mpi_mont_struct;113114typedef int (*mbedtls_mpi_modp_fn)(mbedtls_mpi_uint *X, size_t X_limbs);115116typedef struct {117mbedtls_mpi_modp_fn modp; /* The optimised reduction function pointer */118} mbedtls_mpi_opt_red_struct;119120typedef struct {121const mbedtls_mpi_uint *p;122size_t limbs; // number of limbs123size_t bits; // bitlen of p124mbedtls_mpi_mod_rep_selector int_rep; // selector to signal the active member of the union125union rep {126/* if int_rep == #MBEDTLS_MPI_MOD_REP_MONTGOMERY */127mbedtls_mpi_mont_struct mont;128/* if int_rep == #MBEDTLS_MPI_MOD_REP_OPT_RED */129mbedtls_mpi_opt_red_struct ored;130} rep;131} mbedtls_mpi_mod_modulus;132133/** Setup a residue structure.134*135* The residue will be set up with the buffer \p p and modulus \p N.136*137* The memory pointed to by \p p will be used by the resulting residue structure.138* The value at the pointed-to memory will be the initial value of \p r and must139* hold a value that is less than the modulus. This value will be used as-is140* and interpreted according to the value of the `N->int_rep` field.141*142* The modulus \p N will be the modulus associated with \p r. The residue \p r143* should only be used in operations where the modulus is \p N.144*145* \param[out] r The address of the residue to setup.146* \param[in] N The address of the modulus related to \p r.147* \param[in] p The address of the limb array containing the value of \p r.148* The memory pointed to by \p p will be used by \p r and must149* not be modified in any way until after150* mbedtls_mpi_mod_residue_release() is called. The data151* pointed to by \p p must be less than the modulus (the value152* pointed to by `N->p`) and already in the representation153* indicated by `N->int_rep`.154* \param p_limbs The number of limbs of \p p. Must be the same as the number155* of limbs in the modulus \p N.156*157* \return \c 0 if successful.158* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p p_limbs is less than the159* limbs in \p N or if \p p is not less than \p N.160*/161int mbedtls_mpi_mod_residue_setup(mbedtls_mpi_mod_residue *r,162const mbedtls_mpi_mod_modulus *N,163mbedtls_mpi_uint *p,164size_t p_limbs);165166/** Unbind elements of a residue structure.167*168* This function removes the reference to the limb array that was passed to169* mbedtls_mpi_mod_residue_setup() to make it safe to free or use again.170*171* This function invalidates \p r and it must not be used until after172* mbedtls_mpi_mod_residue_setup() is called on it again.173*174* \param[out] r The address of residue to release.175*/176void mbedtls_mpi_mod_residue_release(mbedtls_mpi_mod_residue *r);177178/** Initialize a modulus structure.179*180* \param[out] N The address of the modulus structure to initialize.181*/182void mbedtls_mpi_mod_modulus_init(mbedtls_mpi_mod_modulus *N);183184/** Setup a modulus structure.185*186* \param[out] N The address of the modulus structure to populate.187* \param[in] p The address of the limb array storing the value of \p N.188* The memory pointed to by \p p will be used by \p N and must189* not be modified in any way until after190* mbedtls_mpi_mod_modulus_free() is called.191* \param p_limbs The number of limbs of \p p.192*193* \return \c 0 if successful.194*/195int mbedtls_mpi_mod_modulus_setup(mbedtls_mpi_mod_modulus *N,196const mbedtls_mpi_uint *p,197size_t p_limbs);198199/** Setup an optimised-reduction compatible modulus structure.200*201* \param[out] N The address of the modulus structure to populate.202* \param[in] p The address of the limb array storing the value of \p N.203* The memory pointed to by \p p will be used by \p N and must204* not be modified in any way until after205* mbedtls_mpi_mod_modulus_free() is called.206* \param p_limbs The number of limbs of \p p.207* \param modp A pointer to the optimised reduction function to use. \p p.208*209* \return \c 0 if successful.210*/211int mbedtls_mpi_mod_optred_modulus_setup(mbedtls_mpi_mod_modulus *N,212const mbedtls_mpi_uint *p,213size_t p_limbs,214mbedtls_mpi_modp_fn modp);215216/** Free elements of a modulus structure.217*218* This function frees any memory allocated by mbedtls_mpi_mod_modulus_setup().219*220* \warning This function does not free the limb array passed to221* mbedtls_mpi_mod_modulus_setup() only removes the reference to it,222* making it safe to free or to use it again.223*224* \param[in,out] N The address of the modulus structure to free.225*/226void mbedtls_mpi_mod_modulus_free(mbedtls_mpi_mod_modulus *N);227228/** \brief Multiply two residues, returning the residue modulo the specified229* modulus.230*231* \note Currently handles the case when `N->int_rep` is232* MBEDTLS_MPI_MOD_REP_MONTGOMERY.233*234* The size of the operation is determined by \p N. \p A, \p B and \p X must235* all be associated with the modulus \p N and must all have the same number236* of limbs as \p N.237*238* \p X may be aliased to \p A or \p B, or even both, but may not overlap239* either otherwise. They may not alias \p N (since they must be in canonical240* form, they cannot == \p N).241*242* \param[out] X The address of the result MPI. Must have the same243* number of limbs as \p N.244* On successful completion, \p X contains the result of245* the multiplication `A * B * R^-1` mod N where246* `R = 2^(biL * N->limbs)`.247* \param[in] A The address of the first MPI.248* \param[in] B The address of the second MPI.249* \param[in] N The address of the modulus. Used to perform a modulo250* operation on the result of the multiplication.251*252* \return \c 0 if successful.253* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if all the parameters do not254* have the same number of limbs or \p N is invalid.255* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED on memory-allocation failure.256*/257int mbedtls_mpi_mod_mul(mbedtls_mpi_mod_residue *X,258const mbedtls_mpi_mod_residue *A,259const mbedtls_mpi_mod_residue *B,260const mbedtls_mpi_mod_modulus *N);261262/**263* \brief Perform a fixed-size modular subtraction.264*265* Calculate `A - B modulo N`.266*267* \p A, \p B and \p X must all have the same number of limbs as \p N.268*269* \p X may be aliased to \p A or \p B, or even both, but may not overlap270* either otherwise.271*272* \note This function does not check that \p A or \p B are in canonical273* form (that is, are < \p N) - that will have been done by274* mbedtls_mpi_mod_residue_setup().275*276* \param[out] X The address of the result MPI. Must be initialized.277* Must have the same number of limbs as the modulus \p N.278* \param[in] A The address of the first MPI.279* \param[in] B The address of the second MPI.280* \param[in] N The address of the modulus. Used to perform a modulo281* operation on the result of the subtraction.282*283* \return \c 0 if successful.284* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the given MPIs do not285* have the correct number of limbs.286*/287int mbedtls_mpi_mod_sub(mbedtls_mpi_mod_residue *X,288const mbedtls_mpi_mod_residue *A,289const mbedtls_mpi_mod_residue *B,290const mbedtls_mpi_mod_modulus *N);291292/**293* \brief Perform modular inversion of an MPI with respect to a modulus \p N.294*295* \p A and \p X must be associated with the modulus \p N and will therefore296* have the same number of limbs as \p N.297*298* \p X may be aliased to \p A.299*300* \warning Currently only supports prime moduli, but does not check for them.301*302* \param[out] X The modular inverse of \p A with respect to \p N.303* \param[in] A The number to calculate the modular inverse of.304* Must not be 0.305* \param[in] N The modulus to use.306*307* \return \c 0 if successful.308* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p A and \p N do not309* have the same number of limbs.310* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p A is zero.311* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if couldn't allocate enough312* memory (needed for conversion to and from Mongtomery form313* when not in Montgomery form already, and for temporary use314* by the inversion calculation itself).315*/316317int mbedtls_mpi_mod_inv(mbedtls_mpi_mod_residue *X,318const mbedtls_mpi_mod_residue *A,319const mbedtls_mpi_mod_modulus *N);320/**321* \brief Perform a fixed-size modular addition.322*323* Calculate `A + B modulo N`.324*325* \p A, \p B and \p X must all be associated with the modulus \p N and must326* all have the same number of limbs as \p N.327*328* \p X may be aliased to \p A or \p B, or even both, but may not overlap329* either otherwise.330*331* \note This function does not check that \p A or \p B are in canonical332* form (that is, are < \p N) - that will have been done by333* mbedtls_mpi_mod_residue_setup().334*335* \param[out] X The address of the result residue. Must be initialized.336* Must have the same number of limbs as the modulus \p N.337* \param[in] A The address of the first input residue.338* \param[in] B The address of the second input residue.339* \param[in] N The address of the modulus. Used to perform a modulo340* operation on the result of the addition.341*342* \return \c 0 if successful.343* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if the given MPIs do not344* have the correct number of limbs.345*/346int mbedtls_mpi_mod_add(mbedtls_mpi_mod_residue *X,347const mbedtls_mpi_mod_residue *A,348const mbedtls_mpi_mod_residue *B,349const mbedtls_mpi_mod_modulus *N);350351/** Generate a random number uniformly in a range.352*353* This function generates a random number between \p min inclusive and354* \p N exclusive.355*356* The procedure complies with RFC 6979 §3.3 (deterministic ECDSA)357* when the RNG is a suitably parametrized instance of HMAC_DRBG358* and \p min is \c 1.359*360* \note There are `N - min` possible outputs. The lower bound361* \p min can be reached, but the upper bound \p N cannot.362*363* \param X The destination residue.364* \param min The minimum value to return. It must be strictly smaller365* than \b N.366* \param N The modulus.367* This is the upper bound of the output range, exclusive.368* \param f_rng The RNG function to use. This must not be \c NULL.369* \param p_rng The RNG parameter to be passed to \p f_rng.370*371* \return \c 0 if successful.372* \return #MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if the implementation was373* unable to find a suitable value within a limited number374* of attempts. This has a negligible probability if \p N375* is significantly larger than \p min, which is the case376* for all usual cryptographic applications.377*/378int mbedtls_mpi_mod_random(mbedtls_mpi_mod_residue *X,379mbedtls_mpi_uint min,380const mbedtls_mpi_mod_modulus *N,381int (*f_rng)(void *, unsigned char *, size_t),382void *p_rng);383384/** Read a residue from a byte buffer.385*386* The residue will be automatically converted to the internal representation387* based on the value of the `N->int_rep` field.388*389* The modulus \p N will be the modulus associated with \p r. The residue \p r390* should only be used in operations where the modulus is \p N or a modulus391* equivalent to \p N (in the sense that all their fields or memory pointed by392* their fields hold the same value).393*394* \param[out] r The address of the residue. It must have exactly the same395* number of limbs as the modulus \p N.396* \param[in] N The address of the modulus.397* \param[in] buf The input buffer to import from.398* \param buflen The length in bytes of \p buf.399* \param ext_rep The endianness of the number in the input buffer.400*401* \return \c 0 if successful.402* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p r isn't403* large enough to hold the value in \p buf.404* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep405* is invalid or the value in the buffer is not less than \p N.406*/407int mbedtls_mpi_mod_read(mbedtls_mpi_mod_residue *r,408const mbedtls_mpi_mod_modulus *N,409const unsigned char *buf,410size_t buflen,411mbedtls_mpi_mod_ext_rep ext_rep);412413/** Write a residue into a byte buffer.414*415* The modulus \p N must be the modulus associated with \p r (see416* mbedtls_mpi_mod_residue_setup() and mbedtls_mpi_mod_read()).417*418* The residue will be automatically converted from the internal representation419* based on the value of `N->int_rep` field.420*421* \warning If the buffer is smaller than `N->bits`, the number of422* leading zeroes is leaked through timing. If \p r is423* secret, the caller must ensure that \p buflen is at least424* (`N->bits`+7)/8.425*426* \param[in] r The address of the residue. It must have the same number of427* limbs as the modulus \p N. (\p r is an input parameter, but428* its value will be modified during execution and restored429* before the function returns.)430* \param[in] N The address of the modulus associated with \p r.431* \param[out] buf The output buffer to export to.432* \param buflen The length in bytes of \p buf.433* \param ext_rep The endianness in which the number should be written into434* the output buffer.435*436* \return \c 0 if successful.437* \return #MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if \p buf isn't438* large enough to hold the value of \p r (without leading439* zeroes).440* \return #MBEDTLS_ERR_MPI_BAD_INPUT_DATA if \p ext_rep is invalid.441* \return #MBEDTLS_ERR_MPI_ALLOC_FAILED if couldn't allocate enough442* memory for conversion. Can occur only for moduli with443* MBEDTLS_MPI_MOD_REP_MONTGOMERY.444*/445int mbedtls_mpi_mod_write(const mbedtls_mpi_mod_residue *r,446const mbedtls_mpi_mod_modulus *N,447unsigned char *buf,448size_t buflen,449mbedtls_mpi_mod_ext_rep ext_rep);450451#endif /* MBEDTLS_BIGNUM_MOD_H */452453454