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.
integer.h
00001 /* integer.h 00002 * 00003 * Copyright (C) 2006-2013 wolfSSL Inc. 00004 * 00005 * This file is part of CyaSSL. 00006 * 00007 * CyaSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * CyaSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 00020 */ 00021 00022 /* 00023 * Based on public domain LibTomMath 0.38 by Tom St Denis, tomstdenis@iahu.ca, 00024 * http://math.libtomcrypt.com 00025 */ 00026 00027 00028 #ifndef CTAO_CRYPT_INTEGER_H 00029 #define CTAO_CRYPT_INTEGER_H 00030 00031 /* may optionally use fast math instead, not yet supported on all platforms and 00032 may not be faster on all 00033 */ 00034 #include <cyassl/ctaocrypt/types.h> /* will set MP_xxBIT if not default */ 00035 #ifdef USE_FAST_MATH 00036 #include <cyassl/ctaocrypt/tfm.h> 00037 #else 00038 00039 #ifndef CHAR_BIT 00040 #include <limits.h> 00041 #endif 00042 00043 #include <cyassl/ctaocrypt/mpi_class.h> 00044 00045 #ifndef MIN 00046 #define MIN(x,y) ((x)<(y)?(x):(y)) 00047 #endif 00048 00049 #ifndef MAX 00050 #define MAX(x,y) ((x)>(y)?(x):(y)) 00051 #endif 00052 00053 #ifdef __cplusplus 00054 extern "C" { 00055 00056 /* C++ compilers don't like assigning void * to mp_digit * */ 00057 #define OPT_CAST(x) (x *) 00058 00059 #else 00060 00061 /* C on the other hand doesn't care */ 00062 #define OPT_CAST(x) 00063 00064 #endif 00065 00066 00067 /* detect 64-bit mode if possible */ 00068 #if defined(__x86_64__) 00069 #if !(defined(MP_64BIT) && defined(MP_16BIT) && defined(MP_8BIT)) 00070 #define MP_64BIT 00071 #endif 00072 #endif 00073 00074 /* some default configurations. 00075 * 00076 * A "mp_digit" must be able to hold DIGIT_BIT + 1 bits 00077 * A "mp_word" must be able to hold 2*DIGIT_BIT + 1 bits 00078 * 00079 * At the very least a mp_digit must be able to hold 7 bits 00080 * [any size beyond that is ok provided it doesn't overflow the data type] 00081 */ 00082 #ifdef MP_8BIT 00083 typedef unsigned char mp_digit; 00084 typedef unsigned short mp_word; 00085 #elif defined(MP_16BIT) || defined(NO_64BIT) 00086 typedef unsigned short mp_digit; 00087 typedef unsigned int mp_word; 00088 #elif defined(MP_64BIT) 00089 /* for GCC only on supported platforms */ 00090 typedef unsigned long long mp_digit; /* 64 bit type, 128 uses mode(TI) */ 00091 typedef unsigned long mp_word __attribute__ ((mode(TI))); 00092 00093 #define DIGIT_BIT 60 00094 #else 00095 /* this is the default case, 28-bit digits */ 00096 00097 #if defined(_MSC_VER) || defined(__BORLANDC__) 00098 typedef unsigned __int64 ulong64; 00099 #else 00100 typedef unsigned long long ulong64; 00101 #endif 00102 00103 typedef unsigned int mp_digit; /* long could be 64 now, changed TAO */ 00104 typedef ulong64 mp_word; 00105 00106 #ifdef MP_31BIT 00107 /* this is an extension that uses 31-bit digits */ 00108 #define DIGIT_BIT 31 00109 #else 00110 /* default case is 28-bit digits, defines MP_28BIT as a handy test macro */ 00111 #define DIGIT_BIT 28 00112 #define MP_28BIT 00113 #endif 00114 #endif 00115 00116 00117 /* otherwise the bits per digit is calculated automatically from the size of 00118 a mp_digit */ 00119 #ifndef DIGIT_BIT 00120 #define DIGIT_BIT ((int)((CHAR_BIT * sizeof(mp_digit) - 1))) 00121 /* bits per digit */ 00122 #endif 00123 00124 #define MP_DIGIT_BIT DIGIT_BIT 00125 #define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1)) 00126 #define MP_DIGIT_MAX MP_MASK 00127 00128 /* equalities */ 00129 #define MP_LT -1 /* less than */ 00130 #define MP_EQ 0 /* equal to */ 00131 #define MP_GT 1 /* greater than */ 00132 00133 #define MP_ZPOS 0 /* positive integer */ 00134 #define MP_NEG 1 /* negative */ 00135 00136 #define MP_OKAY 0 /* ok result */ 00137 #define MP_MEM -2 /* out of mem */ 00138 #define MP_VAL -3 /* invalid input */ 00139 #define MP_RANGE MP_VAL 00140 00141 #define MP_YES 1 /* yes response */ 00142 #define MP_NO 0 /* no response */ 00143 00144 /* Primality generation flags */ 00145 #define LTM_PRIME_BBS 0x0001 /* BBS style prime */ 00146 #define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */ 00147 #define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */ 00148 00149 typedef int mp_err; 00150 00151 /* define this to use lower memory usage routines (exptmods mostly) */ 00152 #define MP_LOW_MEM 00153 00154 /* default precision */ 00155 #ifndef MP_PREC 00156 #ifndef MP_LOW_MEM 00157 #define MP_PREC 32 /* default digits of precision */ 00158 #else 00159 #define MP_PREC 1 /* default digits of precision */ 00160 #endif 00161 #endif 00162 00163 /* size of comba arrays, should be at least 2 * 2**(BITS_PER_WORD - 00164 BITS_PER_DIGIT*2) */ 00165 #define MP_WARRAY (1 << (sizeof(mp_word) * CHAR_BIT - 2 * DIGIT_BIT + 1)) 00166 00167 /* the infamous mp_int structure */ 00168 typedef struct { 00169 int used, alloc, sign; 00170 mp_digit *dp; 00171 } mp_int; 00172 00173 /* callback for mp_prime_random, should fill dst with random bytes and return 00174 how many read [upto len] */ 00175 typedef int ltm_prime_callback(unsigned char *dst, int len, void *dat); 00176 00177 00178 #define USED(m) ((m)->used) 00179 #define DIGIT(m,k) ((m)->dp[(k)]) 00180 #define SIGN(m) ((m)->sign) 00181 00182 00183 /* ---> Basic Manipulations <--- */ 00184 #define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO) 00185 #define mp_iseven(a) \ 00186 (((a)->used > 0 && (((a)->dp[0] & 1) == 0)) ? MP_YES : MP_NO) 00187 #define mp_isodd(a) \ 00188 (((a)->used > 0 && (((a)->dp[0] & 1) == 1)) ? MP_YES : MP_NO) 00189 00190 00191 /* number of primes */ 00192 #ifdef MP_8BIT 00193 #define PRIME_SIZE 31 00194 #else 00195 #define PRIME_SIZE 256 00196 #endif 00197 00198 #define mp_prime_random(a, t, size, bbs, cb, dat) \ 00199 mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat) 00200 00201 #define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len)) 00202 #define mp_raw_size(mp) mp_signed_bin_size(mp) 00203 #define mp_toraw(mp, str) mp_to_signed_bin((mp), (str)) 00204 #define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len)) 00205 #define mp_mag_size(mp) mp_unsigned_bin_size(mp) 00206 #define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str)) 00207 00208 #define mp_tobinary(M, S) mp_toradix((M), (S), 2) 00209 #define mp_tooctal(M, S) mp_toradix((M), (S), 8) 00210 #define mp_todecimal(M, S) mp_toradix((M), (S), 10) 00211 #define mp_tohex(M, S) mp_toradix((M), (S), 16) 00212 00213 #define s_mp_mul(a, b, c) s_mp_mul_digs(a, b, c, (a)->used + (b)->used + 1) 00214 00215 extern const char *mp_s_rmap; 00216 00217 /* 6 functions needed by Rsa */ 00218 int mp_init (mp_int * a); 00219 void mp_clear (mp_int * a); 00220 int mp_unsigned_bin_size(mp_int * a); 00221 int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c); 00222 int mp_to_unsigned_bin (mp_int * a, unsigned char *b); 00223 int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y); 00224 /* end functions needed by Rsa */ 00225 00226 /* functions added to support above needed, removed TOOM and KARATSUBA */ 00227 int mp_count_bits (mp_int * a); 00228 int mp_leading_bit (mp_int * a); 00229 int mp_init_copy (mp_int * a, mp_int * b); 00230 int mp_copy (mp_int * a, mp_int * b); 00231 int mp_grow (mp_int * a, int size); 00232 int mp_div_2d (mp_int * a, int b, mp_int * c, mp_int * d); 00233 void mp_zero (mp_int * a); 00234 void mp_clamp (mp_int * a); 00235 void mp_exch (mp_int * a, mp_int * b); 00236 void mp_rshd (mp_int * a, int b); 00237 void mp_rshb (mp_int * a, int b); 00238 int mp_mod_2d (mp_int * a, int b, mp_int * c); 00239 int mp_mul_2d (mp_int * a, int b, mp_int * c); 00240 int mp_lshd (mp_int * a, int b); 00241 int mp_abs (mp_int * a, mp_int * b); 00242 int mp_invmod (mp_int * a, mp_int * b, mp_int * c); 00243 int fast_mp_invmod (mp_int * a, mp_int * b, mp_int * c); 00244 int mp_invmod_slow (mp_int * a, mp_int * b, mp_int * c); 00245 int mp_cmp_mag (mp_int * a, mp_int * b); 00246 int mp_cmp (mp_int * a, mp_int * b); 00247 int mp_cmp_d(mp_int * a, mp_digit b); 00248 void mp_set (mp_int * a, mp_digit b); 00249 int mp_mod (mp_int * a, mp_int * b, mp_int * c); 00250 int mp_div(mp_int * a, mp_int * b, mp_int * c, mp_int * d); 00251 int mp_div_2(mp_int * a, mp_int * b); 00252 int mp_add (mp_int * a, mp_int * b, mp_int * c); 00253 int s_mp_add (mp_int * a, mp_int * b, mp_int * c); 00254 int s_mp_sub (mp_int * a, mp_int * b, mp_int * c); 00255 int mp_sub (mp_int * a, mp_int * b, mp_int * c); 00256 int mp_reduce_is_2k_l(mp_int *a); 00257 int mp_reduce_is_2k(mp_int *a); 00258 int mp_dr_is_modulus(mp_int *a); 00259 int mp_exptmod_fast (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int); 00260 int mp_montgomery_setup (mp_int * n, mp_digit * rho); 00261 int fast_mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); 00262 int mp_montgomery_reduce (mp_int * x, mp_int * n, mp_digit rho); 00263 void mp_dr_setup(mp_int *a, mp_digit *d); 00264 int mp_dr_reduce (mp_int * x, mp_int * n, mp_digit k); 00265 int mp_reduce_2k(mp_int *a, mp_int *n, mp_digit d); 00266 int fast_s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs); 00267 int s_mp_mul_high_digs (mp_int * a, mp_int * b, mp_int * c, int digs); 00268 int mp_reduce_2k_setup_l(mp_int *a, mp_int *d); 00269 int mp_reduce_2k_l(mp_int *a, mp_int *n, mp_int *d); 00270 int mp_reduce (mp_int * x, mp_int * m, mp_int * mu); 00271 int mp_reduce_setup (mp_int * a, mp_int * b); 00272 int s_mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y, int redmode); 00273 int mp_montgomery_calc_normalization (mp_int * a, mp_int * b); 00274 int s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); 00275 int s_mp_sqr (mp_int * a, mp_int * b); 00276 int fast_s_mp_mul_digs (mp_int * a, mp_int * b, mp_int * c, int digs); 00277 int fast_s_mp_sqr (mp_int * a, mp_int * b); 00278 int mp_init_size (mp_int * a, int size); 00279 int mp_div_3 (mp_int * a, mp_int *c, mp_digit * d); 00280 int mp_mul_2(mp_int * a, mp_int * b); 00281 int mp_mul (mp_int * a, mp_int * b, mp_int * c); 00282 int mp_sqr (mp_int * a, mp_int * b); 00283 int mp_mulmod (mp_int * a, mp_int * b, mp_int * c, mp_int * d); 00284 int mp_mul_d (mp_int * a, mp_digit b, mp_int * c); 00285 int mp_2expt (mp_int * a, int b); 00286 int mp_reduce_2k_setup(mp_int *a, mp_digit *d); 00287 int mp_add_d (mp_int* a, mp_digit b, mp_int* c); 00288 int mp_set_int (mp_int * a, unsigned long b); 00289 int mp_sub_d (mp_int * a, mp_digit b, mp_int * c); 00290 /* end support added functions */ 00291 00292 /* added */ 00293 int mp_init_multi(mp_int* a, mp_int* b, mp_int* c, mp_int* d, mp_int* e, 00294 mp_int* f); 00295 00296 #if defined(HAVE_ECC) || defined(CYASSL_KEY_GEN) 00297 int mp_sqrmod(mp_int* a, mp_int* b, mp_int* c); 00298 #endif 00299 #ifdef HAVE_ECC 00300 int mp_read_radix(mp_int* a, const char* str, int radix); 00301 #endif 00302 00303 #ifdef CYASSL_KEY_GEN 00304 int mp_prime_is_prime (mp_int * a, int t, int *result); 00305 int mp_gcd (mp_int * a, mp_int * b, mp_int * c); 00306 int mp_lcm (mp_int * a, mp_int * b, mp_int * c); 00307 #endif 00308 00309 #ifdef __cplusplus 00310 } 00311 #endif 00312 00313 00314 #endif /* USE_FAST_MATH */ 00315 00316 #endif /* CTAO_CRYPT_INTEGER_H */ 00317
Generated on Tue Jul 12 2022 20:12:50 by
