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-2014, Brainspark B.V. 00007 * 00008 * This file is part of PolarSSL (http://www.polarssl.org) 00009 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org> 00010 * 00011 * All rights reserved. 00012 * 00013 * This program is free software; you can redistribute it and/or modify 00014 * it under the terms of the GNU General Public License as published by 00015 * the Free Software Foundation; either version 2 of the License, or 00016 * (at your option) any later version. 00017 * 00018 * This program is distributed in the hope that it will be useful, 00019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 * GNU General Public License for more details. 00022 * 00023 * You should have received a copy of the GNU General Public License along 00024 * with this program; if not, write to the Free Software Foundation, Inc., 00025 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00026 */ 00027 #ifndef POLARSSL_BIGNUM_H 00028 #define POLARSSL_BIGNUM_H 00029 00030 #include <stdio.h> 00031 #include <string.h> 00032 00033 #if !defined(POLARSSL_CONFIG_FILE) 00034 #include "config.h" 00035 #else 00036 #include POLARSSL_CONFIG_FILE 00037 #endif 00038 00039 #if defined(_MSC_VER) && !defined(EFIX64) && !defined(EFI32) 00040 #include <basetsd.h> 00041 #if (_MSC_VER <= 1200) 00042 typedef signed short int16_t; 00043 typedef unsigned short uint16_t; 00044 #else 00045 typedef INT16 int16_t; 00046 typedef UINT16 uint16_t; 00047 #endif 00048 typedef INT32 int32_t; 00049 typedef INT64 int64_t; 00050 typedef UINT32 uint32_t; 00051 typedef UINT64 uint64_t; 00052 #else 00053 #include <inttypes.h> 00054 #endif /* _MSC_VER && !EFIX64 && !EFI32 */ 00055 00056 #define POLARSSL_ERR_MPI_FILE_IO_ERROR -0x0002 /**< An error occurred while reading from or writing to a file. */ 00057 #define POLARSSL_ERR_MPI_BAD_INPUT_DATA -0x0004 /**< Bad input parameters to function. */ 00058 #define POLARSSL_ERR_MPI_INVALID_CHARACTER -0x0006 /**< There is an invalid character in the digit string. */ 00059 #define POLARSSL_ERR_MPI_BUFFER_TOO_SMALL -0x0008 /**< The buffer is too small to write to. */ 00060 #define POLARSSL_ERR_MPI_NEGATIVE_VALUE -0x000A /**< The input arguments are negative or result in illegal output. */ 00061 #define POLARSSL_ERR_MPI_DIVISION_BY_ZERO -0x000C /**< The input argument for division is zero, which is not allowed. */ 00062 #define POLARSSL_ERR_MPI_NOT_ACCEPTABLE -0x000E /**< The input arguments are not acceptable. */ 00063 #define POLARSSL_ERR_MPI_MALLOC_FAILED -0x0010 /**< Memory allocation failed. */ 00064 00065 #define MPI_CHK(f) do { if( ( ret = f ) != 0 ) goto cleanup; } while( 0 ) 00066 00067 /* 00068 * Maximum size MPIs are allowed to grow to in number of limbs. 00069 */ 00070 #define POLARSSL_MPI_MAX_LIMBS 10000 00071 00072 #if !defined(POLARSSL_CONFIG_OPTIONS) 00073 /* 00074 * Maximum window size used for modular exponentiation. Default: 6 00075 * Minimum value: 1. Maximum value: 6. 00076 * 00077 * Result is an array of ( 2 << POLARSSL_MPI_WINDOW_SIZE ) MPIs used 00078 * for the sliding window calculation. (So 64 by default) 00079 * 00080 * Reduction in size, reduces speed. 00081 */ 00082 #define POLARSSL_MPI_WINDOW_SIZE 6 /**< Maximum windows size used. */ 00083 00084 /* 00085 * Maximum size of MPIs allowed in bits and bytes for user-MPIs. 00086 * ( Default: 512 bytes => 4096 bits, Maximum tested: 2048 bytes => 16384 bits ) 00087 * 00088 * Note: Calculations can results temporarily in larger MPIs. So the number 00089 * of limbs required (POLARSSL_MPI_MAX_LIMBS) is higher. 00090 */ 00091 #define POLARSSL_MPI_MAX_SIZE 512 /**< Maximum number of bytes for usable MPIs. */ 00092 00093 #endif /* !POLARSSL_CONFIG_OPTIONS */ 00094 00095 #define POLARSSL_MPI_MAX_BITS ( 8 * POLARSSL_MPI_MAX_SIZE ) /**< Maximum number of bits for usable MPIs. */ 00096 00097 /* 00098 * When reading from files with mpi_read_file() and writing to files with 00099 * mpi_write_file() the buffer should have space 00100 * for a (short) label, the MPI (in the provided radix), the newline 00101 * characters and the '\0'. 00102 * 00103 * By default we assume at least a 10 char label, a minimum radix of 10 00104 * (decimal) and a maximum of 4096 bit numbers (1234 decimal chars). 00105 * Autosized at compile time for at least a 10 char label, a minimum radix 00106 * of 10 (decimal) for a number of POLARSSL_MPI_MAX_BITS size. 00107 * 00108 * This used to be statically sized to 1250 for a maximum of 4096 bit 00109 * numbers (1234 decimal chars). 00110 * 00111 * Calculate using the formula: 00112 * POLARSSL_MPI_RW_BUFFER_SIZE = ceil(POLARSSL_MPI_MAX_BITS / ln(10) * ln(2)) + 00113 * LabelSize + 6 00114 */ 00115 #define POLARSSL_MPI_MAX_BITS_SCALE100 ( 100 * POLARSSL_MPI_MAX_BITS ) 00116 #define LN_2_DIV_LN_10_SCALE100 332 00117 #define POLARSSL_MPI_RW_BUFFER_SIZE ( ((POLARSSL_MPI_MAX_BITS_SCALE100 + LN_2_DIV_LN_10_SCALE100 - 1) / LN_2_DIV_LN_10_SCALE100) + 10 + 6 ) 00118 00119 /* 00120 * Define the base integer type, architecture-wise 00121 */ 00122 #if defined(POLARSSL_HAVE_INT8) 00123 typedef signed char t_sint; 00124 typedef unsigned char t_uint; 00125 typedef uint16_t t_udbl; 00126 #define POLARSSL_HAVE_UDBL 00127 #else 00128 #if defined(POLARSSL_HAVE_INT16) 00129 typedef int16_t t_sint; 00130 typedef uint16_t t_uint; 00131 typedef uint32_t t_udbl; 00132 #define POLARSSL_HAVE_UDBL 00133 #else 00134 /* 00135 * 32-bit integers can be forced on 64-bit arches (eg. for testing purposes) 00136 * by defining POLARSSL_HAVE_INT32 and undefining POARSSL_HAVE_ASM 00137 */ 00138 #if ( ! defined(POLARSSL_HAVE_INT32) && \ 00139 defined(_MSC_VER) && defined(_M_AMD64) ) 00140 #define POLARSSL_HAVE_INT64 00141 typedef int64_t t_sint; 00142 typedef uint64_t t_uint; 00143 #else 00144 #if ( ! defined(POLARSSL_HAVE_INT32) && \ 00145 defined(__GNUC__) && ( \ 00146 defined(__amd64__) || defined(__x86_64__) || \ 00147 defined(__ppc64__) || defined(__powerpc64__) || \ 00148 defined(__ia64__) || defined(__alpha__) || \ 00149 (defined(__sparc__) && defined(__arch64__)) || \ 00150 defined(__s390x__) ) ) 00151 #define POLARSSL_HAVE_INT64 00152 typedef int64_t t_sint; 00153 typedef uint64_t t_uint; 00154 typedef unsigned int t_udbl __attribute__((mode(TI))); 00155 #define POLARSSL_HAVE_UDBL 00156 #else 00157 #define POLARSSL_HAVE_INT32 00158 typedef int32_t t_sint; 00159 typedef uint32_t t_uint; 00160 #if ( defined(_MSC_VER) && defined(_M_IX86) ) 00161 typedef uint64_t t_udbl; 00162 #define POLARSSL_HAVE_UDBL 00163 #else 00164 #if defined( POLARSSL_HAVE_LONGLONG ) 00165 typedef unsigned long long t_udbl; 00166 #define POLARSSL_HAVE_UDBL 00167 #endif 00168 #endif 00169 #endif 00170 #endif 00171 #endif /* POLARSSL_HAVE_INT16 */ 00172 #endif /* POLARSSL_HAVE_INT8 */ 00173 00174 #ifdef __cplusplus 00175 extern "C" { 00176 #endif 00177 00178 /** 00179 * \brief MPI structure 00180 */ 00181 typedef struct 00182 { 00183 int s ; /*!< integer sign */ 00184 size_t n ; /*!< total # of limbs */ 00185 t_uint *p ; /*!< pointer to limbs */ 00186 } 00187 mpi; 00188 00189 /** 00190 * \brief Initialize one MPI 00191 * 00192 * \param X One MPI to initialize. 00193 */ 00194 void mpi_init( mpi *X ); 00195 00196 /** 00197 * \brief Unallocate one MPI 00198 * 00199 * \param X One MPI to unallocate. 00200 */ 00201 void mpi_free( 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 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00211 */ 00212 int mpi_grow( 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 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00222 */ 00223 int mpi_shrink( 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 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00233 */ 00234 int mpi_copy( mpi *X, const 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 mpi_swap( mpi *X, 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 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00253 * 00254 * \note This function is equivalent to 00255 * if( assign ) 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 mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign ); 00262 00263 /** 00264 * \brief Safe conditional swap X <-> Y if swap is 1 00265 * 00266 * \param X First mpi value 00267 * \param Y Second mpi value 00268 * \param assign 1: perform the swap, 0: keep X and Y's original values 00269 * 00270 * \return 0 if successful, 00271 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00272 * 00273 * \note This function is equivalent to 00274 * if( assign ) 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 mpi_safe_cond_swap( mpi *X, 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 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00290 */ 00291 int mpi_lset( mpi *X, t_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 mpi_get_bit( const 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 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00315 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if val is not 0 or 1 00316 */ 00317 int mpi_set_bit( 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 mpi_lsb( const 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 mpi_msb( const mpi *X ); 00338 00339 /** 00340 * \brief Return the total size in bytes 00341 * 00342 * \param X MPI to use 00343 */ 00344 size_t mpi_size( const 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 POLARSSL_ERR_MPI_XXX error code 00354 */ 00355 int mpi_read_string( 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 s String buffer 00363 * \param slen String buffer size 00364 * 00365 * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code. 00366 * *slen is always updated to reflect the amount 00367 * of data that has (or would have) been written. 00368 * 00369 * \note Call this function with *slen = 0 to obtain the 00370 * minimum required buffer size in *slen. 00371 */ 00372 int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen ); 00373 00374 #if defined(POLARSSL_FS_IO) 00375 /** 00376 * \brief Read X from an opened file 00377 * 00378 * \param X Destination MPI 00379 * \param radix Input numeric base 00380 * \param fin Input file handle 00381 * 00382 * \return 0 if successful, POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if 00383 * the file read buffer is too small or a 00384 * POLARSSL_ERR_MPI_XXX error code 00385 */ 00386 int mpi_read_file( mpi *X, int radix, FILE *fin ); 00387 00388 /** 00389 * \brief Write X into an opened file, or stdout if fout is NULL 00390 * 00391 * \param p Prefix, can be NULL 00392 * \param X Source MPI 00393 * \param radix Output numeric base 00394 * \param fout Output file handle (can be NULL) 00395 * 00396 * \return 0 if successful, or a POLARSSL_ERR_MPI_XXX error code 00397 * 00398 * \note Set fout == NULL to print X on the console. 00399 */ 00400 int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout ); 00401 #endif /* POLARSSL_FS_IO */ 00402 00403 /** 00404 * \brief Import X from unsigned binary data, big endian 00405 * 00406 * \param X Destination MPI 00407 * \param buf Input buffer 00408 * \param buflen Input buffer size 00409 * 00410 * \return 0 if successful, 00411 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00412 */ 00413 int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen ); 00414 00415 /** 00416 * \brief Export X into unsigned binary data, big endian 00417 * 00418 * \param X Source MPI 00419 * \param buf Output buffer 00420 * \param buflen Output buffer size 00421 * 00422 * \return 0 if successful, 00423 * POLARSSL_ERR_MPI_BUFFER_TOO_SMALL if buf isn't large enough 00424 */ 00425 int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen ); 00426 00427 /** 00428 * \brief Left-shift: X <<= count 00429 * 00430 * \param X MPI to shift 00431 * \param count Amount to shift 00432 * 00433 * \return 0 if successful, 00434 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00435 */ 00436 int mpi_shift_l( mpi *X, size_t count ); 00437 00438 /** 00439 * \brief Right-shift: X >>= count 00440 * 00441 * \param X MPI to shift 00442 * \param count Amount to shift 00443 * 00444 * \return 0 if successful, 00445 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00446 */ 00447 int mpi_shift_r( mpi *X, size_t count ); 00448 00449 /** 00450 * \brief Compare unsigned values 00451 * 00452 * \param X Left-hand MPI 00453 * \param Y Right-hand MPI 00454 * 00455 * \return 1 if |X| is greater than |Y|, 00456 * -1 if |X| is lesser than |Y| or 00457 * 0 if |X| is equal to |Y| 00458 */ 00459 int mpi_cmp_abs( const mpi *X, const mpi *Y ); 00460 00461 /** 00462 * \brief Compare signed values 00463 * 00464 * \param X Left-hand MPI 00465 * \param Y Right-hand MPI 00466 * 00467 * \return 1 if X is greater than Y, 00468 * -1 if X is lesser than Y or 00469 * 0 if X is equal to Y 00470 */ 00471 int mpi_cmp_mpi( const mpi *X, const mpi *Y ); 00472 00473 /** 00474 * \brief Compare signed values 00475 * 00476 * \param X Left-hand MPI 00477 * \param z The integer value to compare to 00478 * 00479 * \return 1 if X is greater than z, 00480 * -1 if X is lesser than z or 00481 * 0 if X is equal to z 00482 */ 00483 int mpi_cmp_int( const mpi *X, t_sint z ); 00484 00485 /** 00486 * \brief Unsigned addition: X = |A| + |B| 00487 * 00488 * \param X Destination MPI 00489 * \param A Left-hand MPI 00490 * \param B Right-hand MPI 00491 * 00492 * \return 0 if successful, 00493 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00494 */ 00495 int mpi_add_abs( mpi *X, const mpi *A, const mpi *B ); 00496 00497 /** 00498 * \brief Unsigned subtraction: X = |A| - |B| 00499 * 00500 * \param X Destination MPI 00501 * \param A Left-hand MPI 00502 * \param B Right-hand MPI 00503 * 00504 * \return 0 if successful, 00505 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B is greater than A 00506 */ 00507 int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B ); 00508 00509 /** 00510 * \brief Signed addition: X = A + B 00511 * 00512 * \param X Destination MPI 00513 * \param A Left-hand MPI 00514 * \param B Right-hand MPI 00515 * 00516 * \return 0 if successful, 00517 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00518 */ 00519 int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B ); 00520 00521 /** 00522 * \brief Signed subtraction: X = A - B 00523 * 00524 * \param X Destination MPI 00525 * \param A Left-hand MPI 00526 * \param B Right-hand MPI 00527 * 00528 * \return 0 if successful, 00529 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00530 */ 00531 int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B ); 00532 00533 /** 00534 * \brief Signed addition: X = A + b 00535 * 00536 * \param X Destination MPI 00537 * \param A Left-hand MPI 00538 * \param b The integer value to add 00539 * 00540 * \return 0 if successful, 00541 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00542 */ 00543 int mpi_add_int( mpi *X, const mpi *A, t_sint b ); 00544 00545 /** 00546 * \brief Signed subtraction: X = A - b 00547 * 00548 * \param X Destination MPI 00549 * \param A Left-hand MPI 00550 * \param b The integer value to subtract 00551 * 00552 * \return 0 if successful, 00553 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00554 */ 00555 int mpi_sub_int( mpi *X, const mpi *A, t_sint b ); 00556 00557 /** 00558 * \brief Baseline multiplication: X = A * B 00559 * 00560 * \param X Destination MPI 00561 * \param A Left-hand MPI 00562 * \param B Right-hand MPI 00563 * 00564 * \return 0 if successful, 00565 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00566 */ 00567 int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B ); 00568 00569 /** 00570 * \brief Baseline multiplication: X = A * b 00571 * Note: despite the functon signature, b is treated as a 00572 * t_uint. Negative values of b are treated as large positive 00573 * values. 00574 * 00575 * \param X Destination MPI 00576 * \param A Left-hand MPI 00577 * \param b The integer value to multiply with 00578 * 00579 * \return 0 if successful, 00580 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00581 */ 00582 int mpi_mul_int( mpi *X, const mpi *A, t_sint b ); 00583 00584 /** 00585 * \brief Division by mpi: A = Q * B + R 00586 * 00587 * \param Q Destination MPI for the quotient 00588 * \param R Destination MPI for the rest value 00589 * \param A Left-hand MPI 00590 * \param B Right-hand MPI 00591 * 00592 * \return 0 if successful, 00593 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00594 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0 00595 * 00596 * \note Either Q or R can be NULL. 00597 */ 00598 int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B ); 00599 00600 /** 00601 * \brief Division by int: A = Q * b + R 00602 * 00603 * \param Q Destination MPI for the quotient 00604 * \param R Destination MPI for the rest value 00605 * \param A Left-hand MPI 00606 * \param b Integer to divide by 00607 * 00608 * \return 0 if successful, 00609 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00610 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0 00611 * 00612 * \note Either Q or R can be NULL. 00613 */ 00614 int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b ); 00615 00616 /** 00617 * \brief Modulo: R = A mod B 00618 * 00619 * \param R Destination MPI for the rest value 00620 * \param A Left-hand MPI 00621 * \param B Right-hand MPI 00622 * 00623 * \return 0 if successful, 00624 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00625 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if B == 0, 00626 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if B < 0 00627 */ 00628 int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B ); 00629 00630 /** 00631 * \brief Modulo: r = A mod b 00632 * 00633 * \param r Destination t_uint 00634 * \param A Left-hand MPI 00635 * \param b Integer to divide by 00636 * 00637 * \return 0 if successful, 00638 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00639 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0, 00640 * POLARSSL_ERR_MPI_NEGATIVE_VALUE if b < 0 00641 */ 00642 int mpi_mod_int( t_uint *r, const mpi *A, t_sint b ); 00643 00644 /** 00645 * \brief Sliding-window exponentiation: X = A^E mod N 00646 * 00647 * \param X Destination MPI 00648 * \param A Left-hand MPI 00649 * \param E Exponent MPI 00650 * \param N Modular MPI 00651 * \param _RR Speed-up MPI used for recalculations 00652 * 00653 * \return 0 if successful, 00654 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00655 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or even or 00656 * if E is negative 00657 * 00658 * \note _RR is used to avoid re-computing R*R mod N across 00659 * multiple calls, which speeds up things a bit. It can 00660 * be set to NULL if the extra performance is unneeded. 00661 */ 00662 int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR ); 00663 00664 /** 00665 * \brief Fill an MPI X with size bytes of random 00666 * 00667 * \param X Destination MPI 00668 * \param size Size in bytes 00669 * \param f_rng RNG function 00670 * \param p_rng RNG parameter 00671 * 00672 * \return 0 if successful, 00673 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00674 */ 00675 int mpi_fill_random( mpi *X, size_t size, 00676 int (*f_rng)(void *, unsigned char *, size_t), 00677 void *p_rng ); 00678 00679 /** 00680 * \brief Greatest common divisor: G = gcd(A, B) 00681 * 00682 * \param G Destination MPI 00683 * \param A Left-hand MPI 00684 * \param B Right-hand MPI 00685 * 00686 * \return 0 if successful, 00687 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed 00688 */ 00689 int mpi_gcd( mpi *G, const mpi *A, const mpi *B ); 00690 00691 /** 00692 * \brief Modular inverse: X = A^-1 mod N 00693 * 00694 * \param X Destination MPI 00695 * \param A Left-hand MPI 00696 * \param N Right-hand MPI 00697 * 00698 * \return 0 if successful, 00699 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00700 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if N is negative or nil 00701 POLARSSL_ERR_MPI_NOT_ACCEPTABLE if A has no inverse mod N 00702 */ 00703 int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N ); 00704 00705 /** 00706 * \brief Miller-Rabin primality test 00707 * 00708 * \param X MPI to check 00709 * \param f_rng RNG function 00710 * \param p_rng RNG parameter 00711 * 00712 * \return 0 if successful (probably prime), 00713 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00714 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE if X is not prime 00715 */ 00716 int mpi_is_prime( mpi *X, 00717 int (*f_rng)(void *, unsigned char *, size_t), 00718 void *p_rng ); 00719 00720 /** 00721 * \brief Prime number generation 00722 * 00723 * \param X Destination MPI 00724 * \param nbits Required size of X in bits 00725 * ( 3 <= nbits <= POLARSSL_MPI_MAX_BITS ) 00726 * \param dh_flag If 1, then (X-1)/2 will be prime too 00727 * \param f_rng RNG function 00728 * \param p_rng RNG parameter 00729 * 00730 * \return 0 if successful (probably prime), 00731 * POLARSSL_ERR_MPI_MALLOC_FAILED if memory allocation failed, 00732 * POLARSSL_ERR_MPI_BAD_INPUT_DATA if nbits is < 3 00733 */ 00734 int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag, 00735 int (*f_rng)(void *, unsigned char *, size_t), 00736 void *p_rng ); 00737 00738 /** 00739 * \brief Checkup routine 00740 * 00741 * \return 0 if successful, or 1 if the test failed 00742 */ 00743 int mpi_self_test( int verbose ); 00744 00745 #ifdef __cplusplus 00746 } 00747 #endif 00748 00749 #endif /* bignum.h */ 00750 00751
Generated on Tue Jul 12 2022 19:40:15 by
1.7.2