Path: blob/master/libs/tomcrypt/src/headers/tomcrypt_math.h
5971 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/89/** math functions **/1011#define LTC_MP_LT -112#define LTC_MP_EQ 013#define LTC_MP_GT 11415#define LTC_MP_NO 016#define LTC_MP_YES 11718#ifndef LTC_MECC19typedef void ecc_point;20#endif2122#ifndef LTC_MRSA23typedef void rsa_key;24#endif2526#ifndef LTC_MILLER_RABIN_REPS27/* Number of rounds of the Miller-Rabin test28* "Reasonable values of reps are between 15 and 50." c.f. gmp doc of mpz_probab_prime_p()29* As of https://security.stackexchange.com/a/4546 we should use 40 rounds */30#define LTC_MILLER_RABIN_REPS 4031#endif3233int radix_to_bin(const void *in, int radix, void *out, unsigned long *len);3435/** math descriptor */36typedef struct {37/** Name of the math provider */38const char *name;3940/** Bits per digit, amount of bits must fit in an unsigned long */41int bits_per_digit;4243/* ---- init/deinit functions ---- */4445/** initialize a bignum46@param a The number to initialize47@return CRYPT_OK on success48*/49int (*init)(void **a);5051/** init copy52@param dst The number to initialize and write to53@param src The number to copy from54@return CRYPT_OK on success55*/56int (*init_copy)(void **dst, void *src);5758/** deinit59@param a The number to free60@return CRYPT_OK on success61*/62void (*deinit)(void *a);6364/* ---- data movement ---- */6566/** negate67@param src The number to negate68@param dst The destination69@return CRYPT_OK on success70*/71int (*neg)(void *src, void *dst);7273/** copy74@param src The number to copy from75@param dst The number to write to76@return CRYPT_OK on success77*/78int (*copy)(void *src, void *dst);7980/* ---- trivial low level functions ---- */8182/** set small constant83@param a Number to write to84@param n Source upto bits_per_digit (actually meant for very small constants)85@return CRYPT_OK on success86*/87int (*set_int)(void *a, ltc_mp_digit n);8889/** get small constant90@param a Small number to read,91only fetches up to bits_per_digit from the number92@return The lower bits_per_digit of the integer (unsigned)93*/94unsigned long (*get_int)(void *a);9596/** get digit n97@param a The number to read from98@param n The number of the digit to fetch99@return The bits_per_digit sized n'th digit of a100*/101ltc_mp_digit (*get_digit)(void *a, int n);102103/** Get the number of digits that represent the number104@param a The number to count105@return The number of digits used to represent the number106*/107int (*get_digit_count)(void *a);108109/** compare two integers110@param a The left side integer111@param b The right side integer112@return LTC_MP_LT if a < b,113LTC_MP_GT if a > b and114LTC_MP_EQ otherwise. (signed comparison)115*/116int (*compare)(void *a, void *b);117118/** compare against int119@param a The left side integer120@param b The right side integer (upto bits_per_digit)121@return LTC_MP_LT if a < b,122LTC_MP_GT if a > b and123LTC_MP_EQ otherwise. (signed comparison)124*/125int (*compare_d)(void *a, ltc_mp_digit n);126127/** Count the number of bits used to represent the integer128@param a The integer to count129@return The number of bits required to represent the integer130*/131int (*count_bits)(void * a);132133/** Count the number of LSB bits which are zero134@param a The integer to count135@return The number of contiguous zero LSB bits136*/137int (*count_lsb_bits)(void *a);138139/** Compute a power of two140@param a The integer to store the power in141@param n The power of two you want to store (a = 2^n)142@return CRYPT_OK on success143*/144int (*twoexpt)(void *a , int n);145146/* ---- radix conversions ---- */147148/** read ascii string149@param a The integer to store into150@param str The string to read151@param radix The radix the integer has been represented in (2-64)152@return CRYPT_OK on success153*/154int (*read_radix)(void *a, const char *str, int radix);155156/** write number to string157@param a The integer to store158@param str The destination for the string159@param radix The radix the integer is to be represented in (2-64)160@return CRYPT_OK on success161*/162int (*write_radix)(void *a, char *str, int radix);163164/** get size as unsigned char string165@param a The integer to get the size (when stored in array of octets)166@return The length of the integer in octets167*/168unsigned long (*unsigned_size)(void *a);169170/** store an integer as an array of octets171@param src The integer to store172@param dst The buffer to store the integer in173@return CRYPT_OK on success174*/175int (*unsigned_write)(void *src, unsigned char *dst);176177/** read an array of octets and store as integer178@param dst The integer to load179@param src The array of octets180@param len The number of octets181@return CRYPT_OK on success182*/183int (*unsigned_read)( void *dst,184unsigned char *src,185unsigned long len);186187/* ---- basic math ---- */188189/** add two integers190@param a The first source integer191@param b The second source integer192@param c The destination of "a + b"193@return CRYPT_OK on success194*/195int (*add)(void *a, void *b, void *c);196197/** add two integers198@param a The first source integer199@param b The second source integer200(single digit of upto bits_per_digit in length)201@param c The destination of "a + b"202@return CRYPT_OK on success203*/204int (*addi)(void *a, ltc_mp_digit b, void *c);205206/** subtract two integers207@param a The first source integer208@param b The second source integer209@param c The destination of "a - b"210@return CRYPT_OK on success211*/212int (*sub)(void *a, void *b, void *c);213214/** subtract two integers215@param a The first source integer216@param b The second source integer217(single digit of upto bits_per_digit in length)218@param c The destination of "a - b"219@return CRYPT_OK on success220*/221int (*subi)(void *a, ltc_mp_digit b, void *c);222223/** multiply two integers224@param a The first source integer225@param b The second source integer226(single digit of upto bits_per_digit in length)227@param c The destination of "a * b"228@return CRYPT_OK on success229*/230int (*mul)(void *a, void *b, void *c);231232/** multiply two integers233@param a The first source integer234@param b The second source integer235(single digit of upto bits_per_digit in length)236@param c The destination of "a * b"237@return CRYPT_OK on success238*/239int (*muli)(void *a, ltc_mp_digit b, void *c);240241/** Square an integer242@param a The integer to square243@param b The destination244@return CRYPT_OK on success245*/246int (*sqr)(void *a, void *b);247248/** Divide an integer249@param a The dividend250@param b The divisor251@param c The quotient (can be NULL to signify don't care)252@param d The remainder (can be NULL to signify don't care)253@return CRYPT_OK on success254*/255int (*mpdiv)(void *a, void *b, void *c, void *d);256257/** divide by two258@param a The integer to divide (shift right)259@param b The destination260@return CRYPT_OK on success261*/262int (*div_2)(void *a, void *b);263264/** Get remainder (small value)265@param a The integer to reduce266@param b The modulus (upto bits_per_digit in length)267@param c The destination for the residue268@return CRYPT_OK on success269*/270int (*modi)(void *a, ltc_mp_digit b, ltc_mp_digit *c);271272/** gcd273@param a The first integer274@param b The second integer275@param c The destination for (a, b)276@return CRYPT_OK on success277*/278int (*gcd)(void *a, void *b, void *c);279280/** lcm281@param a The first integer282@param b The second integer283@param c The destination for [a, b]284@return CRYPT_OK on success285*/286int (*lcm)(void *a, void *b, void *c);287288/** Modular multiplication289@param a The first source290@param b The second source291@param c The modulus292@param d The destination (a*b mod c)293@return CRYPT_OK on success294*/295int (*mulmod)(void *a, void *b, void *c, void *d);296297/** Modular squaring298@param a The first source299@param b The modulus300@param c The destination (a*a mod b)301@return CRYPT_OK on success302*/303int (*sqrmod)(void *a, void *b, void *c);304305/** Modular inversion306@param a The value to invert307@param b The modulus308@param c The destination (1/a mod b)309@return CRYPT_OK on success310*/311int (*invmod)(void *, void *, void *);312313/* ---- reduction ---- */314315/** setup Montgomery316@param a The modulus317@param b The destination for the reduction digit318@return CRYPT_OK on success319*/320int (*montgomery_setup)(void *a, void **b);321322/** get normalization value323@param a The destination for the normalization value324@param b The modulus325@return CRYPT_OK on success326*/327int (*montgomery_normalization)(void *a, void *b);328329/** reduce a number330@param a The number [and dest] to reduce331@param b The modulus332@param c The value "b" from montgomery_setup()333@return CRYPT_OK on success334*/335int (*montgomery_reduce)(void *a, void *b, void *c);336337/** clean up (frees memory)338@param a The value "b" from montgomery_setup()339@return CRYPT_OK on success340*/341void (*montgomery_deinit)(void *a);342343/* ---- exponentiation ---- */344345/** Modular exponentiation346@param a The base integer347@param b The power (can be negative) integer348@param c The modulus integer349@param d The destination350@return CRYPT_OK on success351*/352int (*exptmod)(void *a, void *b, void *c, void *d);353354/** Primality testing355@param a The integer to test356@param b The number of Miller-Rabin tests that shall be executed357@param c The destination of the result (FP_YES if prime)358@return CRYPT_OK on success359*/360int (*isprime)(void *a, int b, int *c);361362/* ---- (optional) ecc point math ---- */363364/** ECC GF(p) point multiplication (from the NIST curves)365@param k The integer to multiply the point by366@param G The point to multiply367@param R The destination for kG368@param modulus The modulus for the field369@param map Boolean indicated whether to map back to affine or not370(can be ignored if you work in affine only)371@return CRYPT_OK on success372*/373int (*ecc_ptmul)( void *k,374ecc_point *G,375ecc_point *R,376void *modulus,377int map);378379/** ECC GF(p) point addition380@param P The first point381@param Q The second point382@param R The destination of P + Q383@param modulus The modulus384@param mp The "b" value from montgomery_setup()385@return CRYPT_OK on success386*/387int (*ecc_ptadd)(ecc_point *P,388ecc_point *Q,389ecc_point *R,390void *modulus,391void *mp);392393/** ECC GF(p) point double394@param P The first point395@param R The destination of 2P396@param modulus The modulus397@param mp The "b" value from montgomery_setup()398@return CRYPT_OK on success399*/400int (*ecc_ptdbl)(ecc_point *P,401ecc_point *R,402void *modulus,403void *mp);404405/** ECC mapping from projective to affine,406currently uses (x,y,z) => (x/z^2, y/z^3, 1)407@param P The point to map408@param modulus The modulus409@param mp The "b" value from montgomery_setup()410@return CRYPT_OK on success411@remark The mapping can be different but keep in mind a412ecc_point only has three integers (x,y,z) so if413you use a different mapping you have to make it fit.414*/415int (*ecc_map)(ecc_point *P, void *modulus, void *mp);416417/** Computes kA*A + kB*B = C using Shamir's Trick418@param A First point to multiply419@param kA What to multiple A by420@param B Second point to multiply421@param kB What to multiple B by422@param C [out] Destination point (can overlap with A or B)423@param modulus Modulus for curve424@return CRYPT_OK on success425*/426int (*ecc_mul2add)(ecc_point *A, void *kA,427ecc_point *B, void *kB,428ecc_point *C,429void *modulus);430431/* ---- (optional) rsa optimized math (for internal CRT) ---- */432433/** RSA Key Generation434@param prng An active PRNG state435@param wprng The index of the PRNG desired436@param size The size of the key in octets437@param e The "e" value (public key).438e==65537 is a good choice439@param key [out] Destination of a newly created private key pair440@return CRYPT_OK if successful, upon error all allocated ram is freed441*/442int (*rsa_keygen)(prng_state *prng,443int wprng,444int size,445long e,446rsa_key *key);447448/** RSA exponentiation449@param in The octet array representing the base450@param inlen The length of the input451@param out The destination (to be stored in an octet array format)452@param outlen The length of the output buffer and the resulting size453(zero padded to the size of the modulus)454@param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA455@param key The RSA key to use456@return CRYPT_OK on success457*/458int (*rsa_me)(const unsigned char *in, unsigned long inlen,459unsigned char *out, unsigned long *outlen, int which,460rsa_key *key);461462/* ---- basic math continued ---- */463464/** Modular addition465@param a The first source466@param b The second source467@param c The modulus468@param d The destination (a + b mod c)469@return CRYPT_OK on success470*/471int (*addmod)(void *a, void *b, void *c, void *d);472473/** Modular substraction474@param a The first source475@param b The second source476@param c The modulus477@param d The destination (a - b mod c)478@return CRYPT_OK on success479*/480int (*submod)(void *a, void *b, void *c, void *d);481482/* ---- misc stuff ---- */483484/** Make a pseudo-random mpi485@param a The mpi to make random486@param size The desired length487@return CRYPT_OK on success488*/489int (*rand)(void *a, int size);490} ltc_math_descriptor;491492extern ltc_math_descriptor ltc_mp;493494int ltc_init_multi(void **a, ...);495void ltc_deinit_multi(void *a, ...);496void ltc_cleanup_multi(void **a, ...);497498#ifdef LTM_DESC499extern const ltc_math_descriptor ltm_desc;500#endif501502#ifdef TFM_DESC503extern const ltc_math_descriptor tfm_desc;504#endif505506#ifdef GMP_DESC507extern const ltc_math_descriptor gmp_desc;508#endif509510#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE)511512#define MP_DIGIT_BIT ltc_mp.bits_per_digit513514/* some handy macros */515#define mp_init(a) ltc_mp.init(a)516#define mp_init_multi ltc_init_multi517#define mp_clear(a) ltc_mp.deinit(a)518#define mp_clear_multi ltc_deinit_multi519#define mp_cleanup_multi ltc_cleanup_multi520#define mp_init_copy(a, b) ltc_mp.init_copy(a, b)521522#define mp_neg(a, b) ltc_mp.neg(a, b)523#define mp_copy(a, b) ltc_mp.copy(a, b)524525#define mp_set(a, b) ltc_mp.set_int(a, b)526#define mp_set_int(a, b) ltc_mp.set_int(a, b)527#define mp_get_int(a) ltc_mp.get_int(a)528#define mp_get_digit(a, n) ltc_mp.get_digit(a, n)529#define mp_get_digit_count(a) ltc_mp.get_digit_count(a)530#define mp_cmp(a, b) ltc_mp.compare(a, b)531#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b)532#define mp_count_bits(a) ltc_mp.count_bits(a)533#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a)534#define mp_2expt(a, b) ltc_mp.twoexpt(a, b)535536#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c)537#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c)538#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)539#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)540#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)541542#define mp_add(a, b, c) ltc_mp.add(a, b, c)543#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c)544#define mp_sub(a, b, c) ltc_mp.sub(a, b, c)545#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c)546#define mp_mul(a, b, c) ltc_mp.mul(a, b, c)547#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)548#define mp_sqr(a, b) ltc_mp.sqr(a, b)549#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)550#define mp_div_2(a, b) ltc_mp.div_2(a, b)551#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)552#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c)553#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c)554#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c)555556#define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d)557#define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d)558#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d)559#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c)560#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c)561562#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b)563#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)564#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c)565#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a)566567#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)568#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, b, c)569570#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)571#define mp_isodd(a) (mp_get_digit_count(a) > 0 ? (mp_get_digit(a, 0) & 1 ? LTC_MP_YES : LTC_MP_NO) : LTC_MP_NO)572#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0)573574#define mp_tohex(a, b) mp_toradix(a, b, 16)575576#define mp_rand(a, b) ltc_mp.rand(a, b)577578#endif579580581