1 /** math functions **/ 2 module tomcrypt.math; 3 4 import core.stdc.config; 5 import tomcrypt.prng; 6 import tomcrypt.pk; 7 8 extern(C) nothrow: 9 10 enum LTC_MP_LT = -1; 11 enum LTC_MP_EQ = 0; 12 enum LTC_MP_GT = 1; 13 14 enum LTC_MP_NO = 0; 15 enum LTC_MP_YES = 1; 16 17 version(LTC_MECC) {} 18 else 19 { 20 alias void ecc_point; 21 } 22 23 version(LTC_MRSA) {} 24 else 25 { 26 alias void rsa_key; 27 } 28 29 /** math descriptor */ 30 struct ltc_math_descriptor 31 { 32 /** Name of the math provider */ 33 char *name; 34 35 /** Bits per digit, amount of bits must fit in an c_ulong */ 36 int bits_per_digit; 37 38 /* ---- init/deinit functions ---- */ 39 40 /** initialize a bignum 41 @param a The number to initialize 42 @return CRYPT_OK on success 43 */ 44 int function(void **a) nothrow init; 45 46 /** init copy 47 @param dst The number to initialize and write to 48 @param src The number to copy from 49 @return CRYPT_OK on success 50 */ 51 int function(void **dst, void *src) nothrow init_copy; 52 53 /** deinit 54 @param a The number to free 55 @return CRYPT_OK on success 56 */ 57 void function(void *a) nothrow deinit; 58 59 /* ---- data movement ---- */ 60 61 /** negate 62 @param src The number to negate 63 @param dst The destination 64 @return CRYPT_OK on success 65 */ 66 int function(void *src, void *dst) nothrow neg; 67 68 /** copy 69 @param src The number to copy from 70 @param dst The number to write to 71 @return CRYPT_OK on success 72 */ 73 int function(void *src, void *dst) nothrow copy; 74 75 /* ---- trivial low level functions ---- */ 76 77 /** set small constant 78 @param a Number to write to 79 @param n Source upto bits_per_digit (actually meant for very small constants) 80 @return CRYPT_OK on succcess 81 */ 82 int function(void *a, c_ulong n) nothrow set_int; 83 84 /** get small constant 85 @param a Number to read, only fetches upto bits_per_digit from the number 86 @return The lower bits_per_digit of the integer (unsigned) 87 */ 88 c_ulong function(void *a) nothrow get_int; 89 90 /** get digit n 91 @param a The number to read from 92 @param n The number of the digit to fetch 93 @return The bits_per_digit sized n'th digit of a 94 */ 95 c_ulong function(void *a, int n) nothrow get_digit; 96 97 /** Get the number of digits that represent the number 98 @param a The number to count 99 @return The number of digits used to represent the number 100 */ 101 int function(void *a) nothrow get_digit_count; 102 103 /** compare two integers 104 @param a The left side integer 105 @param b The right side integer 106 @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) 107 */ 108 int function(void *a, void *b) nothrow compare; 109 110 /** compare against int 111 @param a The left side integer 112 @param b The right side integer (upto bits_per_digit) 113 @return LTC_MP_LT if a < b, LTC_MP_GT if a > b and LTC_MP_EQ otherwise. (signed comparison) 114 */ 115 int function(void *a, c_ulong n) nothrow compare_d; 116 117 /** Count the number of bits used to represent the integer 118 @param a The integer to count 119 @return The number of bits required to represent the integer 120 */ 121 int function(void * a) nothrow count_bits; 122 123 /** Count the number of LSB bits which are zero 124 @param a The integer to count 125 @return The number of contiguous zero LSB bits 126 */ 127 int function(void *a) nothrow count_lsb_bits; 128 129 /** Compute a power of two 130 @param a The integer to store the power in 131 @param n The power of two you want to store (a = 2^n) 132 @return CRYPT_OK on success 133 */ 134 int function(void *a , int n) nothrow twoexpt; 135 136 /* ---- radix conversions ---- */ 137 138 /** read ascii string 139 @param a The integer to store into 140 @param str The string to read 141 @param radix The radix the integer has been represented in (2-64) 142 @return CRYPT_OK on success 143 */ 144 int function(void *a, const char *str, int radix) nothrow read_radix; 145 146 /** write number to string 147 @param a The integer to store 148 @param str The destination for the string 149 @param radix The radix the integer is to be represented in (2-64) 150 @return CRYPT_OK on success 151 */ 152 int function(void *a, char *str, int radix) nothrow write_radix; 153 154 /** get size as unsigned char string 155 @param a The integer to get the size (when stored in array of octets) 156 @return The length of the integer 157 */ 158 c_ulong function(void *a) nothrow unsigned_size; 159 160 /** store an integer as an array of octets 161 @param src The integer to store 162 @param dst The buffer to store the integer in 163 @return CRYPT_OK on success 164 */ 165 int function(void *src, ubyte* dst) nothrow unsigned_write; 166 167 /** read an array of octets and store as integer 168 @param dst The integer to load 169 @param src The array of octets 170 @param len The number of octets 171 @return CRYPT_OK on success 172 */ 173 int function(void *dst, ubyte* src, c_ulong len) nothrow unsigned_read; 174 175 /* ---- basic math ---- */ 176 177 /** add two integers 178 @param a The first source integer 179 @param b The second source integer 180 @param c The destination of "a + b" 181 @return CRYPT_OK on success 182 */ 183 int function(void *a, void *b, void *c) nothrow add; 184 185 186 /** add two integers 187 @param a The first source integer 188 @param b The second source integer (single digit of upto bits_per_digit in length) 189 @param c The destination of "a + b" 190 @return CRYPT_OK on success 191 */ 192 int function(void *a, c_ulong b, void *c) nothrow addi; 193 194 /** subtract two integers 195 @param a The first source integer 196 @param b The second source integer 197 @param c The destination of "a - b" 198 @return CRYPT_OK on success 199 */ 200 int function(void *a, void *b, void *c) nothrow sub; 201 202 /** subtract two integers 203 @param a The first source integer 204 @param b The second source integer (single digit of upto bits_per_digit in length) 205 @param c The destination of "a - b" 206 @return CRYPT_OK on success 207 */ 208 int function(void *a, c_ulong b, void *c) nothrow subi; 209 210 /** multiply two integers 211 @param a The first source integer 212 @param b The second source integer (single digit of upto bits_per_digit in length) 213 @param c The destination of "a * b" 214 @return CRYPT_OK on success 215 */ 216 int function(void *a, void *b, void *c) nothrow mul; 217 218 /** multiply two integers 219 @param a The first source integer 220 @param b The second source integer (single digit of upto bits_per_digit in length) 221 @param c The destination of "a * b" 222 @return CRYPT_OK on success 223 */ 224 int function(void *a, c_ulong b, void *c) nothrow muli; 225 226 /** Square an integer 227 @param a The integer to square 228 @param b The destination 229 @return CRYPT_OK on success 230 */ 231 int function(void *a, void *b) nothrow sqr; 232 233 /** Divide an integer 234 @param a The dividend 235 @param b The divisor 236 @param c The quotient (can be NULL to signify don't care) 237 @param d The remainder (can be NULL to signify don't care) 238 @return CRYPT_OK on success 239 */ 240 int function(void *a, void *b, void *c, void *d) nothrow mpdiv; 241 242 /** divide by two 243 @param a The integer to divide (shift right) 244 @param b The destination 245 @return CRYPT_OK on success 246 */ 247 int function(void *a, void *b) nothrow div_2; 248 249 /** Get remainder (small value) 250 @param a The integer to reduce 251 @param b The modulus (upto bits_per_digit in length) 252 @param c The destination for the residue 253 @return CRYPT_OK on success 254 */ 255 int function(void *a, c_ulong b, c_ulong *c) nothrow modi; 256 257 /** gcd 258 @param a The first integer 259 @param b The second integer 260 @param c The destination for (a, b) 261 @return CRYPT_OK on success 262 */ 263 int function(void *a, void *b, void *c) nothrow gcd; 264 265 /** lcm 266 @param a The first integer 267 @param b The second integer 268 @param c The destination for [a, b] 269 @return CRYPT_OK on success 270 */ 271 int function(void *a, void *b, void *c) nothrow lcm; 272 273 /** Modular multiplication 274 @param a The first source 275 @param b The second source 276 @param c The modulus 277 @param d The destination (a*b mod c) 278 @return CRYPT_OK on success 279 */ 280 int function(void *a, void *b, void *c, void *d) nothrow mulmod; 281 282 /** Modular squaring 283 @param a The first source 284 @param b The modulus 285 @param c The destination (a*a mod b) 286 @return CRYPT_OK on success 287 */ 288 int function(void *a, void *b, void *c) nothrow sqrmod; 289 290 /** Modular inversion 291 @param a The value to invert 292 @param b The modulus 293 @param c The destination (1/a mod b) 294 @return CRYPT_OK on success 295 */ 296 int function(void *, void *, void *) nothrow invmod; 297 298 /* ---- reduction ---- */ 299 300 /** setup montgomery 301 @param a The modulus 302 @param b The destination for the reduction digit 303 @return CRYPT_OK on success 304 */ 305 int function(void *a, void **b) nothrow montgomery_setup; 306 307 /** get normalization value 308 @param a The destination for the normalization value 309 @param b The modulus 310 @return CRYPT_OK on success 311 */ 312 int function(void *a, void *b) nothrow montgomery_normalization; 313 314 /** reduce a number 315 @param a The number [and dest] to reduce 316 @param b The modulus 317 @param c The value "b" from montgomery_setup() 318 @return CRYPT_OK on success 319 */ 320 int function(void *a, void *b, void *c) nothrow montgomery_reduce; 321 322 /** clean up (frees memory) 323 @param a The value "b" from montgomery_setup() 324 @return CRYPT_OK on success 325 */ 326 void function(void *a) nothrow montgomery_deinit; 327 328 /* ---- exponentiation ---- */ 329 330 /** Modular exponentiation 331 @param a The base integer 332 @param b The power (can be negative) integer 333 @param c The modulus integer 334 @param d The destination 335 @return CRYPT_OK on success 336 */ 337 int function(void *a, void *b, void *c, void *d) nothrow exptmod; 338 339 /** Primality testing 340 @param a The integer to test 341 @param b The destination of the result (FP_YES if prime) 342 @return CRYPT_OK on success 343 */ 344 int function(void *a, int *b) nothrow isprime; 345 346 /* ---- (optional) ecc point math ---- */ 347 348 /** ECC GF(p) point multiplication (from the NIST curves) 349 @param k The integer to multiply the point by 350 @param G The point to multiply 351 @param R The destination for kG 352 @param modulus The modulus for the field 353 @param map Boolean indicated whether to map back to affine or not (can be ignored if you work in affine only) 354 @return CRYPT_OK on success 355 */ 356 int function(void *k, ecc_point *G, ecc_point *R, void *modulus, int map) nothrow ecc_ptmul; 357 358 /** ECC GF(p) point addition 359 @param P The first point 360 @param Q The second point 361 @param R The destination of P + Q 362 @param modulus The modulus 363 @param mp The "b" value from montgomery_setup() 364 @return CRYPT_OK on success 365 */ 366 int function(ecc_point *P, ecc_point *Q, ecc_point *R, void *modulus, void *mp) nothrow ecc_ptadd; 367 368 /** ECC GF(p) point double 369 @param P The first point 370 @param R The destination of 2P 371 @param modulus The modulus 372 @param mp The "b" value from montgomery_setup() 373 @return CRYPT_OK on success 374 */ 375 int function(ecc_point *P, ecc_point *R, void *modulus, void *mp) nothrow ecc_ptdbl; 376 377 /** ECC mapping from projective to affine, currently uses (x,y,z) => (x/z^2, y/z^3, 1) 378 @param P The point to map 379 @param modulus The modulus 380 @param mp The "b" value from montgomery_setup() 381 @return CRYPT_OK on success 382 @remark The mapping can be different but keep in mind a ecc_point only has three 383 integers (x,y,z) so if you use a different mapping you have to make it fit. 384 */ 385 int function(ecc_point *P, void *modulus, void *mp) nothrow ecc_map; 386 387 /** Computes kA*A + kB*B = C using Shamir's Trick 388 @param A First point to multiply 389 @param kA What to multiple A by 390 @param B Second point to multiply 391 @param kB What to multiple B by 392 @param C [out] Destination point (can overlap with A or B 393 @param modulus Modulus for curve 394 @return CRYPT_OK on success 395 */ 396 int function(ecc_point *A, void *kA, 397 ecc_point *B, void *kB, 398 ecc_point *C, 399 void *modulus) nothrow ecc_mul2add; 400 401 /* ---- (optional) rsa optimized math (for internal CRT) ---- */ 402 403 /** RSA Key Generation 404 @param prng An active PRNG state 405 @param wprng The index of the PRNG desired 406 @param size The size of the modulus (key size) desired (octets) 407 @param e The "e" value (public key). e==65537 is a good choice 408 @param key [out] Destination of a newly created private key pair 409 @return CRYPT_OK if successful, upon error all allocated ram is freed 410 */ 411 int function(prng_state *prng, int wprng, int size, long e, rsa_key *key) nothrow rsa_keygen; 412 413 414 /** RSA exponentiation 415 @param in The octet array representing the base 416 @param inlen The length of the input 417 @param out The destination (to be stored in an octet array format) 418 @param outlen The length of the output buffer and the resulting size (zero padded to the size of the modulus) 419 @param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA 420 @param key The RSA key to use 421 @return CRYPT_OK on success 422 */ 423 int function(const ubyte* _in, c_ulong inlen, 424 ubyte* _out, c_ulong *outlen, int which, 425 rsa_key *key) nothrow rsa_me; 426 } 427 428 extern __gshared ltc_math_descriptor ltc_mp; 429 430 int ltc_init_multi(void **a, ...); 431 void ltc_deinit_multi(void *a, ...); 432 433 version(LTM_DESC) 434 { 435 extern const __gshared ltc_math_descriptor ltm_desc; 436 } 437 438 version(TFM_DESC) 439 { 440 extern const __gshared ltc_math_descriptor tfm_desc; 441 } 442 443 version(GMP_DESC) 444 { 445 extern const __gshared ltc_math_descriptor gmp_desc; 446 } 447 448 version(DESC_DEF_ONLY) {} 449 else version(LTC_SOURCE) 450 { 451 452 alias MP_DIGIT_BIT = ltc_mp.bits_per_digit; 453 454 /* some handy macros */ 455 int mp_init(void **a) { return ltc_mp.init(a); } 456 alias mp_init_multi = ltc_init_multi; 457 void mp_clear(void *a) { ltc_mp.deinit(a); } 458 alias mp_clear_multi = ltc_deinit_multi; 459 int mp_init_copy(void **dst, void *src) { return ltc_mp.init_copy(dst, src); } 460 461 int mp_neg(void *src, void *dst) { return ltc_mp.neg(src, dst); } 462 int mp_copy(void *src, void *dst) { return ltc_mp.copy(src, dst); } 463 464 int mp_set(void *a, c_ulong n) { return ltc_mp.set_int(a, n); } 465 alias mp_set_int = mp_set; 466 467 c_ulong mp_get_int(void *a) { return ltc_mp.get_int(a); } 468 c_ulong mp_get_digit(void *a, int n) { return ltc_mp.get_digit(a, n); } 469 int mp_get_digit_count(void *a) { return ltc_mp.get_digit_count(a); } 470 int mp_cmp(void *a, void *b) { return ltc_mp.compare(a, b); } 471 int mp_cmp_d(void *a, c_ulong n) { return ltc_mp.compare_d(a, n); } 472 int mp_count_bits(void * a) { return ltc_mp.count_bits(a); } 473 int mp_cnt_lsb(void *a) { return ltc_mp.count_lsb_bits(a); } 474 int mp_2expt(void *a , int n) { return ltc_mp.twoexpt(a, n); } 475 476 int mp_read_radix(void *a, const char *str, int radix) { return ltc_mp.read_radix(a, str, radix); } 477 int mp_toradix(void *a, char *str, int radix) { return ltc_mp.write_radix(a, str, radix); } 478 c_ulong mp_unsigned_bin_size(void *a) { return ltc_mp.unsigned_size(a); } 479 int mp_to_unsigned_bin(void *src, ubyte* dst) { return ltc_mp.unsigned_write(src, dst); } 480 int mp_read_unsigned_bin(void *dst, ubyte* src, c_ulong len) { return ltc_mp.unsigned_read(dst, src, len); } 481 482 int mp_add(void *a, void *b, void *c) { return ltc_mp.add(a, b, c); } 483 int mp_add_d(void *a, c_ulong b, void *c) { return ltc_mp.addi(a, b, c); } 484 int mp_sub(void *a, void *b, void *c) { return ltc_mp.sub(a, b, c); } 485 int mp_sub_d(void *a, c_ulong b, void *c) { return ltc_mp.subi(a, b, c); } 486 int mp_mul(void *a, void *b, void *c) { return ltc_mp.mul(a, b, c); } 487 int mp_mul_d(void *a, c_ulong b, void *c) { return ltc_mp.muli(a, b, c); } 488 int mp_sqr(void *a, void *b) { return ltc_mp.sqr(a, b); } 489 int mp_div(void *a, void *b, void *c, void *d) { return ltc_mp.mpdiv(a, b, c, d); } 490 int mp_div_2(void *a, void *b) { return ltc_mp.div_2(a, b); } 491 int mp_mod(void *a, void *b, void *c) { return ltc_mp.mpdiv(a, b, null, c);} 492 int mp_mod_d(void *a, c_ulong b, c_ulong *c) { return ltc_mp.modi(a, b, c); } 493 int mp_gcd(void *a, void *b, void *c) { return ltc_mp.gcd(a, b, c); } 494 int mp_lcm(void *a, void *b, void *c) { return ltc_mp.lcm(a, b, c); } 495 496 int mp_mulmod(void *a, void *b, void *c, void *d) { return ltc_mp.mulmod(a, b, c, d); } 497 int mp_sqrmod(void *a, void *b, void *c) { return ltc_mp.sqrmod(a, b, c); } 498 int mp_invmod(void *a, void *b, void *c) { return ltc_mp.invmod(a, b, c); } 499 500 int mp_montgomery_setup(void *a, void **b) { return ltc_mp.montgomery_setup(a, b);} 501 int mp_montgomery_normalization(void *a, void *b) { return ltc_mp.montgomery_normalization(a, b);} 502 int mp_montgomery_reduce(void *a, void *b, void *c) { return ltc_mp.montgomery_reduce(a, b, c);} 503 void mp_montgomery_free(void *a) { return ltc_mp.montgomery_deinit(a);} 504 505 int mp_exptmod(void *a, void *b, void *c, void *d) { return ltc_mp.exptmod(a, b, c, d);} 506 int mp_prime_is_prime(void *a, int *b) { return ltc_mp.isprime(a, b);} 507 508 bool mp_iszero(void* a) {return (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO);} 509 bool mp_isodd(void *a) {return (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO);} 510 void mp_exch(T)(T a, T b) {void *ABC__tmp = a; a = b; b = ABC__tmp;} 511 512 int mp_tohex(void *a, char *str) {return mp_toradix(a, str, 16);} 513 } 514 515 /* $Source: /cvs/libtom/libtomcrypt/src/headers/tomcrypt_math.h,v $ */ 516 /* $Revision: 1.44 $ */ 517 /* $Date: 2007/05/12 14:32:35 $ */