Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
bignum.h
00001 /** 00002 * \file bignum.h 00003 * 00004 * \brief Multi-precision integer library 00005 */ 00006 /* 00007 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved 00008 * SPDX-License-Identifier: Apache-2.0 00009 * 00010 * Licensed under the Apache License, Version 2.0 (the "License"); you may 00011 * not use this file except in compliance with the License. 00012 * You may obtain a copy of the License at 00013 * 00014 * http://www.apache.org/licenses/LICENSE-2.0 00015 * 00016 * Unless required by applicable law or agreed to in writing, software 00017 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 00018 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00019 * See the License for the specific language governing permissions and 00020 * limitations under the License. 00021 * 00022 * This file is part of mbed TLS (https://tls.mbed.org) 00023 */ 00024 #ifndef MBEDTLS_BIGNUM_H 00025 #define MBEDTLS_BIGNUM_H 00026 00027 #if !defined(MBEDTLS_CONFIG_FILE) 00028 #include "config.h" 00029 #else 00030 #include MBEDTLS_CONFIG_FILE 00031 #endif 00032 00033 #include <stddef.h> 00034 #include <stdint.h> 00035 00036 #if defined(MBEDTLS_FS_IO) 00037 #include <stdio.h> 00038 #endif 00039 00040 #define MBEDTLS_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ 00041 #define MBEDTLS_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ 00042 #define MBEDTLS_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */ 00043 #define MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */ 00044 #define MBEDTLS_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */ 00045 #define MBEDTLS_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */ 00046 #define MBEDTLS_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ 00047 #define MBEDTLS_ERR_MPI_ALLOC_FAILED -0x0010 /**< Memory allocation failed. */ 00048 00049 #define MBEDTLS_MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 ) 00050 00051 /* 00052 * Maximum size MPIs are allowed to grow to in number of limbs. 00053 */ 00054 #define MBEDTLS_MPI_MAX_LIMBS 10000 00055 00056 #if !defined(MBEDTLS_MPI_WINDOW_SIZE) 00057 /* 00058 * Maximum window size used for modular exponentiation. Default: 6 00059 * Minimum value: 1. Maximum value: 6. 00060 * 00061 * Result is an array of ( 2 << MBEDTLS_MPI_WINDOW_SIZE ) MPIs used 00062 * for the sliding window calculation. (So 64 by default) 00063 * 00064 * Reduction in size, reduces speed. 00065 */ 00066 #define MBEDTLS_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ 00067 #endif /* !MBEDTLS_MPI_WINDOW_SIZE */ 00068 00069 #if !defined(MBEDTLS_MPI_MAX_SIZE) 00070 /* 00071 * Maximum size of MPIs allowed in bits and bytes for user-MPIs. 00072 * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) 00073 * 00074 * Note: Calculations can temporarily result in larger MPIs. So the number 00075 * of limbs required (MBEDTLS_MPI_MAX_LIMBS) is higher. 00076 */ 00077 #define MBEDTLS_MPI_MAX_SIZE 1024 /**< Maximum number of bytes for usable MPIs. */ 00078 #endif /* !MBEDTLS_MPI_MAX_SIZE */ 00079 00080 #define MBEDTLS_MPI_MAX_BITS ( 8 * MBEDTLS_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */ 00081 00082 /* 00083 * When reading from files with mbedtls_mpi_read_file() and writing to files with 00084 * mbedtls_mpi_write_file() the buffer should have space 00085 * for a (short) label, the MPI (in the provided radix), the newline 00086 * characters and the '\0'. 00087 * 00088 * By default we assume at least a 10 char label, a minimum radix of 10 00089 * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). 00090 * Autosized at compile time for at least a 10 char label, a minimum radix 00091 * of 10 (decimal) for a number of MBEDTLS_MPI_MAX_BITS size. 00092 * 00093 * This used to be statically sized to 1250 for a maximum of 4096 bit 00094 * numbers (1234 decimal chars). 00095 * 00096 * Calculate using the formula: 00097 * MBEDTLS_MPI_RW_BUFFER_SIZE = ceil(MBEDTLS_MPI_MAX_BITS / ln(10) * ln(2)) + 00098 * LabelSize + 6 00099 */ 00100 #define MBEDTLS_MPI_MAX_BITS_SCALE100 ( 100 * MBEDTLS_MPI_MAX_BITS ) 00101 #define MBEDTLS_LN_2_DIV_LN_10_SCALE100 332 00102 #define MBEDTLS_MPI_RW_BUFFER_SIZE ( ((MBEDTLS_MPI_MAX_BITS_SCALE100 + MBEDTLS_LN_2_DIV_LN_10_SCALE100 - 1) / MBEDTLS_LN_2_DIV_LN_10_SCALE100) + 10 + 6 ) 00103 00104 /* 00105 * Define the base integer type, architecture-wise. 00106 * 00107 * 32 or 64-bit integer types can be forced regardless of the underlying 00108 * architecture by defining MBEDTLS_HAVE_INT32 or MBEDTLS_HAVE_INT64 00109 * respectively and undefining MBEDTLS_HAVE_ASM. 00110 * 00111 * Double-width integers (e.g. 128-bit in 64-bit architectures) can be 00112 * disabled by defining MBEDTLS_NO_UDBL_DIVISION. 00113 */ 00114 #if !defined(MBEDTLS_HAVE_INT32) 00115 #if defined(_MSC_VER) && defined(_M_AMD64) 00116 /* Always choose 64-bit when using MSC */ 00117 #if !defined(MBEDTLS_HAVE_INT64) 00118 #define MBEDTLS_HAVE_INT64 00119 #endif /* !MBEDTLS_HAVE_INT64 */ 00120 typedef int64_t mbedtls_mpi_sint; 00121 typedef uint64_t mbedtls_mpi_uint; 00122 #elif defined(__GNUC__) && ( \ 00123 defined(__amd64__) || defined(__x86_64__) || \ 00124 defined(__ppc64__) || defined(__powerpc64__) || \ 00125 defined(__ia64__) || defined(__alpha__) || \ 00126 ( defined(__sparc__) && defined(__arch64__) ) || \ 00127 defined(__s390x__) || defined(__mips64) ) 00128 #if !defined(MBEDTLS_HAVE_INT64) 00129 #define MBEDTLS_HAVE_INT64 00130 #endif /* MBEDTLS_HAVE_INT64 */ 00131 typedef int64_t mbedtls_mpi_sint; 00132 typedef uint64_t mbedtls_mpi_uint; 00133 #if !defined(MBEDTLS_NO_UDBL_DIVISION) 00134 /* mbedtls_t_udbl defined as 128-bit unsigned int */ 00135 typedef unsigned int mbedtls_t_udbl __attribute__((mode(TI))); 00136 #define MBEDTLS_HAVE_UDBL 00137 #endif /* !MBEDTLS_NO_UDBL_DIVISION */ 00138 #elif defined(__ARMCC_VERSION) && defined(__aarch64__) 00139 /* 00140 * __ARMCC_VERSION is defined for both armcc and armclang and 00141 * __aarch64__ is only defined by armclang when compiling 64-bit code 00142 */ 00143 #if !defined(MBEDTLS_HAVE_INT64) 00144 #define MBEDTLS_HAVE_INT64 00145 #endif /* !MBEDTLS_HAVE_INT64 */ 00146 typedef int64_t mbedtls_mpi_sint; 00147 typedef uint64_t mbedtls_mpi_uint; 00148 #if !defined(MBEDTLS_NO_UDBL_DIVISION) 00149 /* mbedtls_t_udbl defined as 128-bit unsigned int */ 00150 typedef __uint128_t mbedtls_t_udbl; 00151 #define MBEDTLS_HAVE_UDBL 00152 #endif /* !MBEDTLS_NO_UDBL_DIVISION */ 00153 #elif defined(MBEDTLS_HAVE_INT64) 00154 /* Force 64-bit integers with unknown compiler */ 00155 typedef int64_t mbedtls_mpi_sint; 00156 typedef uint64_t mbedtls_mpi_uint; 00157 #endif 00158 #endif /* !MBEDTLS_HAVE_INT32 */ 00159 00160 #if !defined(MBEDTLS_HAVE_INT64) 00161 /* Default to 32-bit compilation */ 00162 #if !defined(MBEDTLS_HAVE_INT32) 00163 #define MBEDTLS_HAVE_INT32 00164 #endif /* !MBEDTLS_HAVE_INT32 */ 00165 typedef int32_t mbedtls_mpi_sint; 00166 typedef uint32_t mbedtls_mpi_uint; 00167 #if !defined(MBEDTLS_NO_UDBL_DIVISION) 00168 typedef uint64_t mbedtls_t_udbl; 00169 #define MBEDTLS_HAVE_UDBL 00170 #endif /* !MBEDTLS_NO_UDBL_DIVISION */ 00171 #endif /* !MBEDTLS_HAVE_INT64 */ 00172 00173 #ifdef __cplusplus 00174 extern "C" { 00175 #endif 00176 00177 /** 00178 * \brief MPI structure 00179 */ 00180 typedef struct 00181 { 00182 int s ; /*!< integer sign */ 00183 size_t n ; /*!< total # of limbs */ 00184 mbedtls_mpi_uint *p ; /*!< pointer to limbs */ 00185 } 00186 mbedtls_mpi; 00187 00188 /** 00189 * \brief Initialize one MPI (make internal references valid) 00190 * This just makes it ready to be set or freed, 00191 * but does not define a value for the MPI. 00192 * 00193 * \param X One MPI to initialize. 00194 */ 00195 void mbedtls_mpi_init( mbedtls_mpi *X ); 00196 00197 /** 00198 * \brief Unallocate one MPI 00199 * 00200 * \param X One MPI to unallocate. 00201 */ 00202 void mbedtls_mpi_free( mbedtls_mpi *X ); 00203 00204 /** 00205 * \brief Enlarge to the specified number of limbs 00206 * 00207 * This function does nothing if the MPI is already large enough. 00208 * 00209 * \param X MPI to grow 00210 * \param nblimbs The target number of limbs 00211 * 00212 * \return 0 if successful, 00213 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00214 */ 00215 int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs ); 00216 00217 /** 00218 * \brief Resize down, keeping at least the specified number of limbs 00219 * 00220 * If \c X is smaller than \c nblimbs, it is resized up 00221 * instead. 00222 * 00223 * \param X MPI to shrink 00224 * \param nblimbs The minimum number of limbs to keep 00225 * 00226 * \return 0 if successful, 00227 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00228 * (this can only happen when resizing up). 00229 */ 00230 int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs ); 00231 00232 /** 00233 * \brief Copy the contents of Y into X 00234 * 00235 * \param X Destination MPI. It is enlarged if necessary. 00236 * \param Y Source MPI. 00237 * 00238 * \return 0 if successful, 00239 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00240 */ 00241 int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y ); 00242 00243 /** 00244 * \brief Swap the contents of X and Y 00245 * 00246 * \param X First MPI value 00247 * \param Y Second MPI value 00248 */ 00249 void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y ); 00250 00251 /** 00252 * \brief Safe conditional assignement X = Y if assign is 1 00253 * 00254 * \param X MPI to conditionally assign to 00255 * \param Y Value to be assigned 00256 * \param assign 1: perform the assignment, 0: keep X's original value 00257 * 00258 * \return 0 if successful, 00259 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00260 * 00261 * \note This function is equivalent to 00262 * if( assign ) mbedtls_mpi_copy( X, Y ); 00263 * except that it avoids leaking any information about whether 00264 * the assignment was done or not (the above code may leak 00265 * information through branch prediction and/or memory access 00266 * patterns analysis). 00267 */ 00268 int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign ); 00269 00270 /** 00271 * \brief Safe conditional swap X <-> Y if swap is 1 00272 * 00273 * \param X First mbedtls_mpi value 00274 * \param Y Second mbedtls_mpi value 00275 * \param assign 1: perform the swap, 0: keep X and Y's original values 00276 * 00277 * \return 0 if successful, 00278 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00279 * 00280 * \note This function is equivalent to 00281 * if( assign ) mbedtls_mpi_swap( X, Y ); 00282 * except that it avoids leaking any information about whether 00283 * the assignment was done or not (the above code may leak 00284 * information through branch prediction and/or memory access 00285 * patterns analysis). 00286 */ 00287 int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char assign ); 00288 00289 /** 00290 * \brief Set value from integer 00291 * 00292 * \param X MPI to set 00293 * \param z Value to use 00294 * 00295 * \return 0 if successful, 00296 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00297 */ 00298 int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z ); 00299 00300 /** 00301 * \brief Get a specific bit from X 00302 * 00303 * \param X MPI to use 00304 * \param pos Zero-based index of the bit in X 00305 * 00306 * \return Either a 0 or a 1 00307 */ 00308 int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos ); 00309 00310 /** 00311 * \brief Set a bit of X to a specific value of 0 or 1 00312 * 00313 * \note Will grow X if necessary to set a bit to 1 in a not yet 00314 * existing limb. Will not grow if bit should be set to 0 00315 * 00316 * \param X MPI to use 00317 * \param pos Zero-based index of the bit in X 00318 * \param val The value to set the bit to (0 or 1) 00319 * 00320 * \return 0 if successful, 00321 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00322 * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1 00323 */ 00324 int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val ); 00325 00326 /** 00327 * \brief Return the number of zero-bits before the least significant 00328 * '1' bit 00329 * 00330 * Note: Thus also the zero-based index of the least significant '1' bit 00331 * 00332 * \param X MPI to use 00333 */ 00334 size_t mbedtls_mpi_lsb( const mbedtls_mpi *X ); 00335 00336 /** 00337 * \brief Return the number of bits up to and including the most 00338 * significant '1' bit' 00339 * 00340 * Note: Thus also the one-based index of the most significant '1' bit 00341 * 00342 * \param X MPI to use 00343 */ 00344 size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X ); 00345 00346 /** 00347 * \brief Return the total size in bytes 00348 * 00349 * \param X MPI to use 00350 */ 00351 size_t mbedtls_mpi_size( const mbedtls_mpi *X ); 00352 00353 /** 00354 * \brief Import from an ASCII string 00355 * 00356 * \param X Destination MPI 00357 * \param radix Input numeric base 00358 * \param s Null-terminated string buffer 00359 * 00360 * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code 00361 */ 00362 int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s ); 00363 00364 /** 00365 * \brief Export into an ASCII string 00366 * 00367 * \param X Source MPI 00368 * \param radix Output numeric base 00369 * \param buf Buffer to write the string to 00370 * \param buflen Length of buf 00371 * \param olen Length of the string written, including final NUL byte 00372 * 00373 * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code. 00374 * *olen is always updated to reflect the amount 00375 * of data that has (or would have) been written. 00376 * 00377 * \note Call this function with buflen = 0 to obtain the 00378 * minimum required buffer size in *olen. 00379 */ 00380 int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix, 00381 char *buf, size_t buflen, size_t *olen ); 00382 00383 #if defined(MBEDTLS_FS_IO) 00384 /** 00385 * \brief Read MPI from a line in an opened file 00386 * 00387 * \param X Destination MPI 00388 * \param radix Input numeric base 00389 * \param fin Input file handle 00390 * 00391 * \return 0 if successful, MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if 00392 * the file read buffer is too small or a 00393 * MBEDTLS_ERR_MPI_XXX error code 00394 * 00395 * \note On success, this function advances the file stream 00396 * to the end of the current line or to EOF. 00397 * 00398 * The function returns 0 on an empty line. 00399 * 00400 * Leading whitespaces are ignored, as is a 00401 * '0x' prefix for radix 16. 00402 * 00403 */ 00404 int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin ); 00405 00406 /** 00407 * \brief Write X into an opened file, or stdout if fout is NULL 00408 * 00409 * \param p Prefix, can be NULL 00410 * \param X Source MPI 00411 * \param radix Output numeric base 00412 * \param fout Output file handle (can be NULL) 00413 * 00414 * \return 0 if successful, or a MBEDTLS_ERR_MPI_XXX error code 00415 * 00416 * \note Set fout == NULL to print X on the console. 00417 */ 00418 int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout ); 00419 #endif /* MBEDTLS_FS_IO */ 00420 00421 /** 00422 * \brief Import X from unsigned binary data, big endian 00423 * 00424 * \param X Destination MPI 00425 * \param buf Input buffer 00426 * \param buflen Input buffer size 00427 * 00428 * \return 0 if successful, 00429 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00430 */ 00431 int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen ); 00432 00433 /** 00434 * \brief Export X into unsigned binary data, big endian. 00435 * Always fills the whole buffer, which will start with zeros 00436 * if the number is smaller. 00437 * 00438 * \param X Source MPI 00439 * \param buf Output buffer 00440 * \param buflen Output buffer size 00441 * 00442 * \return 0 if successful, 00443 * MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough 00444 */ 00445 int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen ); 00446 00447 /** 00448 * \brief Left-shift: X <<= count 00449 * 00450 * \param X MPI to shift 00451 * \param count Amount to shift 00452 * 00453 * \return 0 if successful, 00454 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00455 */ 00456 int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count ); 00457 00458 /** 00459 * \brief Right-shift: X >>= count 00460 * 00461 * \param X MPI to shift 00462 * \param count Amount to shift 00463 * 00464 * \return 0 if successful, 00465 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00466 */ 00467 int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count ); 00468 00469 /** 00470 * \brief Compare unsigned values 00471 * 00472 * \param X Left-hand MPI 00473 * \param Y Right-hand MPI 00474 * 00475 * \return 1 if |X| is greater than |Y|, 00476 * -1 if |X| is lesser than |Y| or 00477 * 0 if |X| is equal to |Y| 00478 */ 00479 int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y ); 00480 00481 /** 00482 * \brief Compare signed values 00483 * 00484 * \param X Left-hand MPI 00485 * \param Y Right-hand MPI 00486 * 00487 * \return 1 if X is greater than Y, 00488 * -1 if X is lesser than Y or 00489 * 0 if X is equal to Y 00490 */ 00491 int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y ); 00492 00493 /** 00494 * \brief Compare signed values 00495 * 00496 * \param X Left-hand MPI 00497 * \param z The integer value to compare to 00498 * 00499 * \return 1 if X is greater than z, 00500 * -1 if X is lesser than z or 00501 * 0 if X is equal to z 00502 */ 00503 int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z ); 00504 00505 /** 00506 * \brief Unsigned addition: X = |A| + |B| 00507 * 00508 * \param X Destination MPI 00509 * \param A Left-hand MPI 00510 * \param B Right-hand MPI 00511 * 00512 * \return 0 if successful, 00513 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00514 */ 00515 int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); 00516 00517 /** 00518 * \brief Unsigned subtraction: X = |A| - |B| 00519 * 00520 * \param X Destination MPI 00521 * \param A Left-hand MPI 00522 * \param B Right-hand MPI 00523 * 00524 * \return 0 if successful, 00525 * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B is greater than A 00526 */ 00527 int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); 00528 00529 /** 00530 * \brief Signed addition: X = A + B 00531 * 00532 * \param X Destination MPI 00533 * \param A Left-hand MPI 00534 * \param B Right-hand MPI 00535 * 00536 * \return 0 if successful, 00537 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00538 */ 00539 int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); 00540 00541 /** 00542 * \brief Signed subtraction: X = A - B 00543 * 00544 * \param X Destination MPI 00545 * \param A Left-hand MPI 00546 * \param B Right-hand MPI 00547 * 00548 * \return 0 if successful, 00549 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00550 */ 00551 int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); 00552 00553 /** 00554 * \brief Signed addition: X = A + b 00555 * 00556 * \param X Destination MPI 00557 * \param A Left-hand MPI 00558 * \param b The integer value to add 00559 * 00560 * \return 0 if successful, 00561 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00562 */ 00563 int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ); 00564 00565 /** 00566 * \brief Signed subtraction: X = A - b 00567 * 00568 * \param X Destination MPI 00569 * \param A Left-hand MPI 00570 * \param b The integer value to subtract 00571 * 00572 * \return 0 if successful, 00573 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00574 */ 00575 int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b ); 00576 00577 /** 00578 * \brief Baseline multiplication: X = A * B 00579 * 00580 * \param X Destination MPI 00581 * \param A Left-hand MPI 00582 * \param B Right-hand MPI 00583 * 00584 * \return 0 if successful, 00585 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00586 */ 00587 int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B ); 00588 00589 /** 00590 * \brief Baseline multiplication: X = A * b 00591 * 00592 * \param X Destination MPI 00593 * \param A Left-hand MPI 00594 * \param b The unsigned integer value to multiply with 00595 * 00596 * \note b is unsigned 00597 * 00598 * \return 0 if successful, 00599 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00600 */ 00601 int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b ); 00602 00603 /** 00604 * \brief Division by mbedtls_mpi: A = Q * B + R 00605 * 00606 * \param Q Destination MPI for the quotient 00607 * \param R Destination MPI for the rest value 00608 * \param A Left-hand MPI 00609 * \param B Right-hand MPI 00610 * 00611 * \return 0 if successful, 00612 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00613 * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0 00614 * 00615 * \note Either Q or R can be NULL. 00616 */ 00617 int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ); 00618 00619 /** 00620 * \brief Division by int: A = Q * b + R 00621 * 00622 * \param Q Destination MPI for the quotient 00623 * \param R Destination MPI for the rest value 00624 * \param A Left-hand MPI 00625 * \param b Integer to divide by 00626 * 00627 * \return 0 if successful, 00628 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00629 * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0 00630 * 00631 * \note Either Q or R can be NULL. 00632 */ 00633 int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b ); 00634 00635 /** 00636 * \brief Modulo: R = A mod B 00637 * 00638 * \param R Destination MPI for the rest value 00639 * \param A Left-hand MPI 00640 * \param B Right-hand MPI 00641 * 00642 * \return 0 if successful, 00643 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00644 * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if B == 0, 00645 * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if B < 0 00646 */ 00647 int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B ); 00648 00649 /** 00650 * \brief Modulo: r = A mod b 00651 * 00652 * \param r Destination mbedtls_mpi_uint 00653 * \param A Left-hand MPI 00654 * \param b Integer to divide by 00655 * 00656 * \return 0 if successful, 00657 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00658 * MBEDTLS_ERR_MPI_DIVISION_BY_ZERO if b == 0, 00659 * MBEDTLS_ERR_MPI_NEGATIVE_VALUE if b < 0 00660 */ 00661 int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b ); 00662 00663 /** 00664 * \brief Sliding-window exponentiation: X = A^E mod N 00665 * 00666 * \param X Destination MPI 00667 * \param A Left-hand MPI 00668 * \param E Exponent MPI 00669 * \param N Modular MPI 00670 * \param _RR Speed-up MPI used for recalculations 00671 * 00672 * \return 0 if successful, 00673 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00674 * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is negative or even or 00675 * if E is negative 00676 * 00677 * \note _RR is used to avoid re-computing R*R mod N across 00678 * multiple calls, which speeds up things a bit. It can 00679 * be set to NULL if the extra performance is unneeded. 00680 */ 00681 int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR ); 00682 00683 /** 00684 * \brief Fill an MPI X with size bytes of random 00685 * 00686 * \param X Destination MPI 00687 * \param size Size in bytes 00688 * \param f_rng RNG function 00689 * \param p_rng RNG parameter 00690 * 00691 * \return 0 if successful, 00692 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00693 * 00694 * \note The bytes obtained from the PRNG are interpreted 00695 * as a big-endian representation of an MPI; this can 00696 * be relevant in applications like deterministic ECDSA. 00697 */ 00698 int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size, 00699 int (*f_rng)(void *, unsigned char *, size_t), 00700 void *p_rng ); 00701 00702 /** 00703 * \brief Greatest common divisor: G = gcd(A, B) 00704 * 00705 * \param G Destination MPI 00706 * \param A Left-hand MPI 00707 * \param B Right-hand MPI 00708 * 00709 * \return 0 if successful, 00710 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed 00711 */ 00712 int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B ); 00713 00714 /** 00715 * \brief Modular inverse: X = A^-1 mod N 00716 * 00717 * \param X Destination MPI 00718 * \param A Left-hand MPI 00719 * \param N Right-hand MPI 00720 * 00721 * \return 0 if successful, 00722 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00723 * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if N is <= 1, 00724 MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N. 00725 */ 00726 int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N ); 00727 00728 /** 00729 * \brief Miller-Rabin primality test 00730 * 00731 * \param X MPI to check 00732 * \param f_rng RNG function 00733 * \param p_rng RNG parameter 00734 * 00735 * \return 0 if successful (probably prime), 00736 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00737 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE if X is not prime 00738 */ 00739 int mbedtls_mpi_is_prime( const mbedtls_mpi *X, 00740 int (*f_rng)(void *, unsigned char *, size_t), 00741 void *p_rng ); 00742 00743 /** 00744 * \brief Prime number generation 00745 * 00746 * \param X Destination MPI 00747 * \param nbits Required size of X in bits 00748 * ( 3 <= nbits <= MBEDTLS_MPI_MAX_BITS ) 00749 * \param dh_flag If 1, then (X-1)/2 will be prime too 00750 * \param f_rng RNG function 00751 * \param p_rng RNG parameter 00752 * 00753 * \return 0 if successful (probably prime), 00754 * MBEDTLS_ERR_MPI_ALLOC_FAILED if memory allocation failed, 00755 * MBEDTLS_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 00756 */ 00757 int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag, 00758 int (*f_rng)(void *, unsigned char *, size_t), 00759 void *p_rng ); 00760 00761 /** 00762 * \brief Checkup routine 00763 * 00764 * \return 0 if successful, or 1 if the test failed 00765 */ 00766 int mbedtls_mpi_self_test( int verbose ); 00767 00768 #ifdef __cplusplus 00769 } 00770 #endif 00771 00772 #endif /* bignum.h */
Generated on Tue Jul 12 2022 12:43:36 by
