1 2 /* 3 * Licensed Materials - Property of IBM 4 * 5 * trousers - An open source TCG Software Stack 6 * 7 * (C) Copyright International Business Machines Corp. 2006 8 * 9 */ 10 11 #ifndef BI_GMP_ 12 #define BI_GMP_ 13 14 #include <gmp.h> 15 // needed for OPENSSL_free 16 #include <openssl/crypto.h> 17 18 typedef mpz_t bi_t; 19 typedef mpz_ptr bi_ptr; 20 21 extern gmp_randstate_t state; 22 23 /* initialized the given big integer */ 24 INLINE_DECL bi_ptr bi_new(bi_t i) { 25 mpz_init( i); 26 return i; 27 } 28 29 /* create a big integer pointer */ 30 INLINE_DECL bi_ptr bi_new_ptr(void) { 31 mpz_ptr res; 32 33 res = (mpz_ptr)malloc( sizeof( mpz_t)); 34 if( res == NULL) return NULL; 35 mpz_init( res); 36 return res; 37 } 38 39 /* free resources allocated to the big integer <i> */ 40 INLINE_DECL void bi_free(const bi_ptr i) { 41 mpz_clear( i); 42 } 43 44 /* free resources allocated to the big integer pointer <i> */ 45 INLINE_DECL void bi_free_ptr(const bi_ptr i) { 46 mpz_clear( i); 47 free( i); 48 } 49 50 /* return the current number of bits of the number */ 51 INLINE_DECL long bi_length( const bi_ptr res) { 52 return mpz_sizeinbase( res, 2); 53 } 54 55 /*********************************************************************************** 56 CONVERSIONS 57 *************************************************************************************/ 58 59 60 /* return an hex dump of the given big integer */ 61 INLINE_DECL char *bi_2_hex_char(const bi_ptr i) { 62 char *ret; 63 64 gmp_asprintf( &ret, "%ZX", i); 65 list_add( allocs, ret); 66 return ret; 67 } 68 69 /* return an hex dump of the given big integer */ 70 INLINE_DECL char *bi_2_dec_char(const bi_ptr i) { 71 char *ret; 72 73 gmp_asprintf( &ret, "%Zd", i); 74 list_add( allocs, ret); 75 return ret; 76 } 77 78 /* set <i> to the same value as the big integer <value> */ 79 INLINE_DECL bi_ptr bi_set( bi_ptr result, const bi_ptr value) { 80 mpz_set( result, value); 81 return result; 82 } 83 84 /* set the initialized variable to the value represented by the given hex format stirng */ 85 INLINE_DECL bi_ptr bi_set_as_hex( bi_ptr result, const char *value) { 86 mpz_set_str( result, value, 16); 87 return result; 88 } 89 90 /* set the initialized variable to the value represented by the given hex format stirng */ 91 INLINE_DECL bi_ptr bi_set_as_dec( bi_ptr result, const char *value) { 92 mpz_set_str( result, value, 10); 93 return result; 94 } 95 96 /* set <i> with the value represented by unsigned int <value> */ 97 /* <i> := <value> */ 98 INLINE_DECL bi_ptr bi_set_as_si( bi_ptr result, const int value) { 99 mpz_set_si( result, value); 100 return result; 101 } 102 103 /* return (long)bi_t */ 104 INLINE_DECL long bi_get_si(const bi_ptr i) { 105 return mpz_get_si( i); 106 } 107 108 /* convert a bi type to a openssl BIGNUM struct */ 109 INLINE_DECL BIGNUM *bi_2_BIGNUM( const bi_ptr i) { 110 BIGNUM *result; 111 char *value = bi_2_hex_char( i); 112 113 BN_hex2bn( &result, value); 114 return result; 115 } 116 117 /* set <i> with the value represented by the given openssl BIGNUM struct */ 118 INLINE_DECL bi_ptr bi_set_as_BIGNUM( bi_ptr i, BIGNUM *bn) { 119 char *value = BN_bn2hex( bn); 120 121 if( value == NULL) return NULL; 122 bi_set_as_hex( i, value); 123 OPENSSL_free( value); 124 return i; 125 } 126 127 /*********************************************************************************** 128 BASIC MATH OPERATION 129 *************************************************************************************/ 130 131 /* <result> := result + 1 */ 132 INLINE_DECL bi_ptr bi_inc(bi_ptr result) { 133 mpz_add_ui( result, result, 1); 134 return result; 135 } 136 137 /* <result> := result - 1 */ 138 INLINE_DECL bi_ptr bi_dec(bi_ptr result) { 139 mpz_sub_ui( result, result, 1); 140 return result; 141 } 142 143 /* set <result> by the division of <i> by the long <n> */ 144 /* <result> := <i> / <n> */ 145 INLINE_DECL bi_ptr bi_div_si( bi_ptr result, const bi_ptr i, const long n) { 146 mpz_div_ui( result, i, n); 147 return result; 148 } 149 150 /* <result> := <i> / <n> */ 151 INLINE_DECL bi_ptr bi_div( bi_ptr result, const bi_ptr i, const bi_ptr n) { 152 mpz_div( result, i, n); 153 return result; 154 } 155 156 /* <result> := - <result> */ 157 INLINE_DECL bi_ptr bi_negate( bi_ptr result) { 158 mpz_neg( result, result); 159 return result; 160 } 161 162 /* multiply the given big integer <i> by the give long <n> and return the result in <result> */ 163 INLINE_DECL bi_ptr bi_mul_si( bi_ptr result, const bi_ptr i, const long n) { 164 mpz_mul_si( result, i, n); 165 return result; 166 } 167 168 /* <result> := <i> * <n> */ 169 INLINE_DECL bi_ptr bi_mul( bi_ptr result, const bi_ptr i, const bi_ptr n) { 170 mpz_mul( result, i, n); 171 return result; 172 } 173 174 /* <result> := <i> + <n> */ 175 INLINE_DECL bi_ptr bi_add_si( bi_ptr result, const bi_ptr i, const long n) { 176 mpz_add_ui( result, i, n); 177 return result; 178 } 179 180 /* <result> := <i> + <n> */ 181 INLINE_DECL bi_ptr bi_add( bi_ptr result, const bi_ptr i, const bi_ptr n) { 182 mpz_add( result, i, n); 183 return result; 184 } 185 186 /* <result> := <i> - <n> */ 187 INLINE_DECL bi_ptr bi_sub_si( bi_ptr result, const bi_ptr i, const long n) { 188 // n should be unsigned 189 mpz_sub_ui( result, i, n); 190 return result; 191 } 192 193 /* <result> := <i> - <n> */ 194 INLINE_DECL bi_ptr bi_sub( bi_ptr result, const bi_ptr i, const bi_ptr n) { 195 mpz_sub( result, result, n); 196 return result; 197 } 198 199 /* <result> := ( <g> ^ <e> ) mod <m> */ 200 INLINE_DECL bi_ptr bi_mod_exp( bi_ptr result, const bi_ptr g, const bi_ptr e, const bi_ptr m) { 201 mpz_powm( result, g, e, m); 202 return result; 203 } 204 205 /* <result> := ( <g> ^ <e> ) mod <m> */ 206 INLINE_DECL bi_ptr bi_mod_exp_si( bi_ptr result, const bi_ptr g, const bi_ptr e, const long m) { 207 mpz_t bi_m; 208 209 mpz_init( bi_m); 210 mpz_set_si( bi_m, m); 211 mpz_powm( result, g, e, bi_m); 212 mpz_clear( bi_m); 213 return result; 214 } 215 216 /*********************************************************************************** 217 BITS OPERATION 218 *************************************************************************************/ 219 /* set the bit to 1 */ 220 INLINE_DECL bi_ptr bi_setbit(bi_ptr result, const int bit) { 221 mpz_setbit( result, bit); 222 return result; 223 } 224 225 /* <result> := <i> << <n> */ 226 INLINE_DECL bi_ptr bi_shift_left( bi_ptr result, const bi_ptr i, const int n) { 227 mpz_mul_2exp( result, i, n); 228 return result; 229 } 230 231 /* <result> := <i> >> <n> */ 232 INLINE_DECL bi_ptr bi_shift_right( bi_ptr result, const bi_ptr i, const int n) { 233 mpz_div_2exp( result, i, n); 234 return result; 235 } 236 237 /*********************************************************************************** 238 COMPARAISON 239 *************************************************************************************/ 240 /* n1<n2 return negative value 241 * n1 = n2 return 0 242 * n1>n2 return positive value 243 */ 244 INLINE_DECL int bi_cmp( const bi_ptr n1, const bi_ptr n2) { 245 return mpz_cmp( n1, n2); 246 } 247 248 /* n1<n2 return negative value 249 * n1 = n2 return 0 250 * n1>n2 return positive value 251 */ 252 INLINE_DECL int bi_cmp_si( const bi_ptr n1, const int n2) { 253 return mpz_cmp_ui( n1, n2); 254 } 255 256 /* n1 == n2 return 1 (true) 257 * else return 0 258 */ 259 INLINE_DECL int bi_equals( const bi_ptr n1, const bi_ptr n2) { 260 return mpz_cmp( n1, n2) == 0 ? 1 : 0; 261 } 262 263 /* n1 == n2 return 1 (true) 264 * else return 0 265 */ 266 INLINE_DECL int bi_equals_si( const bi_ptr n1, const int n2) { 267 return mpz_cmp_ui( n1, n2) == 0 ? 1 : 0; 268 } 269 270 /* create a random of length <length> bits */ 271 /* res := random( length) */ 272 INLINE_DECL bi_ptr bi_urandom( bi_ptr result, const long length) { 273 mpz_urandomb( result, state, length); 274 return result; 275 } 276 277 /* res := <n> mod <m> */ 278 INLINE_DECL bi_ptr bi_mod_si( bi_ptr result, const bi_ptr n, const long m) { 279 mpz_mod_ui( result, n, m); 280 return result; 281 } 282 283 /* res := <n> mod <m> */ 284 INLINE_DECL bi_ptr bi_mod( bi_ptr result, const bi_ptr n, const bi_ptr m) { 285 mpz_mod( result, n, m); 286 return result; 287 } 288 289 /* result := (inverse of <i>) mod <m> */ 290 /* if the inverse exist, return >0, otherwise 0 */ 291 INLINE_DECL int bi_invert_mod( bi_ptr result, const bi_ptr i, const bi_ptr m) { 292 return mpz_invert( result, i, m); 293 } 294 295 #endif /*BI_GMP_*/ 296