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