tomcrypt/src/headers/tomcrypt_math.h

564 lines
18 KiB
C
Raw Normal View History

2005-08-01 16:36:47 +00:00
/** math functions **/
#define LTC_MP_LT -1
#define LTC_MP_EQ 0
#define LTC_MP_GT 1
#define LTC_MP_NO 0
#define LTC_MP_YES 1
2007-07-20 17:48:02 +00:00
#ifndef LTC_MECC
2005-08-01 16:36:47 +00:00
typedef void ecc_point;
#endif
2007-07-20 17:48:02 +00:00
#ifndef LTC_MRSA
2005-11-18 05:15:37 +00:00
typedef void rsa_key;
#endif
2005-08-01 16:36:47 +00:00
/** math descriptor */
typedef struct {
/** Name of the math provider */
char *name;
/** Bits per digit, amount of bits must fit in an unsigned long */
int bits_per_digit;
/* ---- init/deinit functions ---- */
/** initialize a bignum
@param a The number to initialize
@return CRYPT_OK on success
*/
int (*init)(void **a);
2012-07-26 14:43:15 +02:00
/** init copy
2005-08-01 16:36:47 +00:00
@param dst The number to initialize and write to
@param src The number to copy from
@return CRYPT_OK on success
*/
int (*init_copy)(void **dst, void *src);
2012-07-26 14:43:15 +02:00
/** deinit
2005-08-01 16:36:47 +00:00
@param a The number to free
@return CRYPT_OK on success
*/
void (*deinit)(void *a);
/* ---- data movement ---- */
2005-11-18 05:15:37 +00:00
/** negate
@param src The number to negate
@param dst The destination
@return CRYPT_OK on success
*/
int (*neg)(void *src, void *dst);
2012-07-26 14:43:15 +02:00
/** copy
2005-08-01 16:36:47 +00:00
@param src The number to copy from
2012-07-26 14:43:15 +02:00
@param dst The number to write to
2005-08-01 16:36:47 +00:00
@return CRYPT_OK on success
*/
int (*copy)(void *src, void *dst);
/* ---- trivial low level functions ---- */
2012-07-26 14:43:15 +02:00
/** set small constant
2005-08-01 16:36:47 +00:00
@param a Number to write to
2012-07-26 14:43:15 +02:00
@param n Source upto bits_per_digit (actually meant for very small constants)
2017-06-12 12:02:10 +02:00
@return CRYPT_OK on success
2005-08-01 16:36:47 +00:00
*/
int (*set_int)(void *a, ltc_mp_digit n);
2005-08-01 16:36:47 +00:00
2012-07-26 14:43:15 +02:00
/** get small constant
2017-06-12 12:02:10 +02:00
@param a Small number to read,
only fetches up to bits_per_digit from the number
@return The lower bits_per_digit of the integer (unsigned)
2005-08-01 16:36:47 +00:00
*/
unsigned long (*get_int)(void *a);
2012-07-26 14:43:15 +02:00
/** get digit n
2005-08-01 16:36:47 +00:00
@param a The number to read from
@param n The number of the digit to fetch
@return The bits_per_digit sized n'th digit of a
*/
ltc_mp_digit (*get_digit)(void *a, int n);
2005-08-01 16:36:47 +00:00
/** Get the number of digits that represent the number
@param a The number to count
@return The number of digits used to represent the number
*/
int (*get_digit_count)(void *a);
/** compare two integers
@param a The left side integer
@param b The right side integer
2017-06-12 12:02:10 +02:00
@return LTC_MP_LT if a < b,
LTC_MP_GT if a > b and
LTC_MP_EQ otherwise. (signed comparison)
2005-08-01 16:36:47 +00:00
*/
int (*compare)(void *a, void *b);
2012-07-26 14:43:15 +02:00
/** compare against int
2005-08-01 16:36:47 +00:00
@param a The left side integer
@param b The right side integer (upto bits_per_digit)
2017-06-12 12:02:10 +02:00
@return LTC_MP_LT if a < b,
LTC_MP_GT if a > b and
LTC_MP_EQ otherwise. (signed comparison)
2005-08-01 16:36:47 +00:00
*/
int (*compare_d)(void *a, ltc_mp_digit n);
2005-08-01 16:36:47 +00:00
/** Count the number of bits used to represent the integer
@param a The integer to count
@return The number of bits required to represent the integer
*/
int (*count_bits)(void * a);
2012-07-26 14:43:15 +02:00
/** Count the number of LSB bits which are zero
2006-05-29 23:12:56 +00:00
@param a The integer to count
@return The number of contiguous zero LSB bits
*/
int (*count_lsb_bits)(void *a);
2005-08-01 16:36:47 +00:00
/** Compute a power of two
@param a The integer to store the power in
@param n The power of two you want to store (a = 2^n)
@return CRYPT_OK on success
*/
int (*twoexpt)(void *a , int n);
/* ---- radix conversions ---- */
2012-07-26 14:43:15 +02:00
/** read ascii string
2005-08-01 16:36:47 +00:00
@param a The integer to store into
@param str The string to read
@param radix The radix the integer has been represented in (2-64)
@return CRYPT_OK on success
*/
int (*read_radix)(void *a, const char *str, int radix);
/** write number to string
@param a The integer to store
@param str The destination for the string
@param radix The radix the integer is to be represented in (2-64)
@return CRYPT_OK on success
*/
int (*write_radix)(void *a, char *str, int radix);
2012-07-26 14:43:15 +02:00
/** get size as unsigned char string
2017-06-12 12:02:10 +02:00
@param a The integer to get the size (when stored in array of octets)
@return The length of the integer in octets
2005-08-01 16:36:47 +00:00
*/
unsigned long (*unsigned_size)(void *a);
2012-07-26 14:43:15 +02:00
/** store an integer as an array of octets
2005-08-01 16:36:47 +00:00
@param src The integer to store
@param dst The buffer to store the integer in
@return CRYPT_OK on success
*/
int (*unsigned_write)(void *src, unsigned char *dst);
/** read an array of octets and store as integer
@param dst The integer to load
2012-07-26 14:43:15 +02:00
@param src The array of octets
@param len The number of octets
2005-08-01 16:36:47 +00:00
@return CRYPT_OK on success
*/
2017-06-12 12:02:10 +02:00
int (*unsigned_read)( void *dst,
unsigned char *src,
unsigned long len);
2005-08-01 16:36:47 +00:00
/* ---- basic math ---- */
2012-07-26 14:43:15 +02:00
/** add two integers
2005-08-01 16:36:47 +00:00
@param a The first source integer
@param b The second source integer
@param c The destination of "a + b"
@return CRYPT_OK on success
*/
int (*add)(void *a, void *b, void *c);
2012-07-26 14:43:15 +02:00
/** add two integers
2005-08-01 16:36:47 +00:00
@param a The first source integer
2017-06-12 12:02:10 +02:00
@param b The second source integer
(single digit of upto bits_per_digit in length)
2005-08-01 16:36:47 +00:00
@param c The destination of "a + b"
@return CRYPT_OK on success
*/
int (*addi)(void *a, ltc_mp_digit b, void *c);
2005-08-01 16:36:47 +00:00
2012-07-26 14:43:15 +02:00
/** subtract two integers
2005-08-01 16:36:47 +00:00
@param a The first source integer
@param b The second source integer
@param c The destination of "a - b"
@return CRYPT_OK on success
*/
int (*sub)(void *a, void *b, void *c);
2012-07-26 14:43:15 +02:00
/** subtract two integers
2005-08-01 16:36:47 +00:00
@param a The first source integer
2017-06-12 12:02:10 +02:00
@param b The second source integer
(single digit of upto bits_per_digit in length)
2005-08-01 16:36:47 +00:00
@param c The destination of "a - b"
@return CRYPT_OK on success
*/
int (*subi)(void *a, ltc_mp_digit b, void *c);
2005-08-01 16:36:47 +00:00
2012-07-26 14:43:15 +02:00
/** multiply two integers
2005-08-01 16:36:47 +00:00
@param a The first source integer
2017-06-12 12:02:10 +02:00
@param b The second source integer
(single digit of upto bits_per_digit in length)
2005-08-01 16:36:47 +00:00
@param c The destination of "a * b"
@return CRYPT_OK on success
*/
int (*mul)(void *a, void *b, void *c);
2012-07-26 14:43:15 +02:00
/** multiply two integers
2005-08-01 16:36:47 +00:00
@param a The first source integer
2017-06-12 12:02:10 +02:00
@param b The second source integer
(single digit of upto bits_per_digit in length)
2005-08-01 16:36:47 +00:00
@param c The destination of "a * b"
@return CRYPT_OK on success
*/
int (*muli)(void *a, ltc_mp_digit b, void *c);
2005-08-01 16:36:47 +00:00
/** Square an integer
@param a The integer to square
@param b The destination
@return CRYPT_OK on success
*/
int (*sqr)(void *a, void *b);
/** Divide an integer
@param a The dividend
@param b The divisor
@param c The quotient (can be NULL to signify don't care)
@param d The remainder (can be NULL to signify don't care)
@return CRYPT_OK on success
*/
2006-06-18 01:37:50 +00:00
int (*mpdiv)(void *a, void *b, void *c, void *d);
2005-08-01 16:36:47 +00:00
2012-07-26 14:43:15 +02:00
/** divide by two
2005-08-01 16:36:47 +00:00
@param a The integer to divide (shift right)
2012-07-26 14:43:15 +02:00
@param b The destination
2005-08-01 16:36:47 +00:00
@return CRYPT_OK on success
*/
int (*div_2)(void *a, void *b);
/** Get remainder (small value)
@param a The integer to reduce
@param b The modulus (upto bits_per_digit in length)
@param c The destination for the residue
@return CRYPT_OK on success
*/
int (*modi)(void *a, ltc_mp_digit b, ltc_mp_digit *c);
2005-08-01 16:36:47 +00:00
2012-07-26 14:43:15 +02:00
/** gcd
2005-08-01 16:36:47 +00:00
@param a The first integer
@param b The second integer
@param c The destination for (a, b)
@return CRYPT_OK on success
*/
int (*gcd)(void *a, void *b, void *c);
2012-07-26 14:43:15 +02:00
/** lcm
2005-08-01 16:36:47 +00:00
@param a The first integer
@param b The second integer
@param c The destination for [a, b]
@return CRYPT_OK on success
*/
int (*lcm)(void *a, void *b, void *c);
/** Modular multiplication
@param a The first source
2012-07-26 14:43:15 +02:00
@param b The second source
2005-08-01 16:36:47 +00:00
@param c The modulus
@param d The destination (a*b mod c)
@return CRYPT_OK on success
*/
int (*mulmod)(void *a, void *b, void *c, void *d);
2006-06-18 01:37:50 +00:00
/** Modular squaring
@param a The first source
@param b The modulus
@param c The destination (a*a mod b)
@return CRYPT_OK on success
*/
int (*sqrmod)(void *a, void *b, void *c);
2005-08-01 16:36:47 +00:00
/** Modular inversion
@param a The value to invert
2012-07-26 14:43:15 +02:00
@param b The modulus
2005-08-01 16:36:47 +00:00
@param c The destination (1/a mod b)
@return CRYPT_OK on success
*/
int (*invmod)(void *, void *, void *);
/* ---- reduction ---- */
2017-06-12 12:02:10 +02:00
/** setup Montgomery
2012-07-26 14:43:15 +02:00
@param a The modulus
@param b The destination for the reduction digit
2005-08-01 16:36:47 +00:00
@return CRYPT_OK on success
*/
int (*montgomery_setup)(void *a, void **b);
2012-07-26 14:43:15 +02:00
/** get normalization value
2005-08-01 16:36:47 +00:00
@param a The destination for the normalization value
@param b The modulus
@return CRYPT_OK on success
*/
int (*montgomery_normalization)(void *a, void *b);
/** reduce a number
@param a The number [and dest] to reduce
@param b The modulus
@param c The value "b" from montgomery_setup()
@return CRYPT_OK on success
*/
int (*montgomery_reduce)(void *a, void *b, void *c);
/** clean up (frees memory)
@param a The value "b" from montgomery_setup()
@return CRYPT_OK on success
2012-07-26 14:43:15 +02:00
*/
2005-08-01 16:36:47 +00:00
void (*montgomery_deinit)(void *a);
/* ---- exponentiation ---- */
/** Modular exponentiation
@param a The base integer
@param b The power (can be negative) integer
@param c The modulus integer
@param d The destination
@return CRYPT_OK on success
*/
int (*exptmod)(void *a, void *b, void *c, void *d);
/** Primality testing
@param a The integer to test
@param b The number of tests that shall be executed
@param c The destination of the result (FP_YES if prime)
2005-08-01 16:36:47 +00:00
@return CRYPT_OK on success
*/
int (*isprime)(void *a, int b, int *c);
2005-08-01 16:36:47 +00:00
/* ---- (optional) ecc point math ---- */
/** ECC GF(p) point multiplication (from the NIST curves)
@param k The integer to multiply the point by
@param G The point to multiply
2012-07-26 14:43:15 +02:00
@param R The destination for kG
2005-08-01 16:36:47 +00:00
@param modulus The modulus for the field
2017-06-12 12:02:10 +02:00
@param map Boolean indicated whether to map back to affine or not
(can be ignored if you work in affine only)
2005-08-01 16:36:47 +00:00
@return CRYPT_OK on success
*/
2017-06-12 12:02:10 +02:00
int (*ecc_ptmul)( void *k,
ecc_point *G,
ecc_point *R,
void *modulus,
int map);
2005-08-01 16:36:47 +00:00
2012-07-26 14:43:15 +02:00
/** ECC GF(p) point addition
2005-08-01 16:36:47 +00:00
@param P The first point
@param Q The second point
@param R The destination of P + Q
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
*/
2017-06-12 12:02:10 +02:00
int (*ecc_ptadd)(ecc_point *P,
ecc_point *Q,
ecc_point *R,
void *modulus,
void *mp);
2005-08-01 16:36:47 +00:00
2012-07-26 14:43:15 +02:00
/** ECC GF(p) point double
2006-04-06 19:48:32 +00:00
@param P The first point
@param R The destination of 2P
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
*/
2017-06-12 12:02:10 +02:00
int (*ecc_ptdbl)(ecc_point *P,
ecc_point *R,
void *modulus,
void *mp);
2006-04-06 19:48:32 +00:00
2017-06-12 12:02:10 +02:00
/** ECC mapping from projective to affine,
currently uses (x,y,z) => (x/z^2, y/z^3, 1)
2005-08-01 16:36:47 +00:00
@param P The point to map
@param modulus The modulus
@param mp The "b" value from montgomery_setup()
@return CRYPT_OK on success
2017-06-12 12:02:10 +02:00
@remark The mapping can be different but keep in mind a
ecc_point only has three integers (x,y,z) so if
you use a different mapping you have to make it fit.
2005-08-01 16:36:47 +00:00
*/
int (*ecc_map)(ecc_point *P, void *modulus, void *mp);
2006-12-16 18:10:04 +00:00
/** Computes kA*A + kB*B = C using Shamir's Trick
@param A First point to multiply
@param kA What to multiple A by
@param B Second point to multiply
@param kB What to multiple B by
2017-06-12 12:02:10 +02:00
@param C [out] Destination point (can overlap with A or B)
2012-07-26 14:43:15 +02:00
@param modulus Modulus for curve
2006-12-16 18:10:04 +00:00
@return CRYPT_OK on success
2012-07-26 14:43:15 +02:00
*/
2006-12-16 18:10:04 +00:00
int (*ecc_mul2add)(ecc_point *A, void *kA,
ecc_point *B, void *kB,
ecc_point *C,
void *modulus);
2005-08-01 16:36:47 +00:00
/* ---- (optional) rsa optimized math (for internal CRT) ---- */
2012-07-26 14:43:15 +02:00
/** RSA Key Generation
2005-11-18 05:15:37 +00:00
@param prng An active PRNG state
@param wprng The index of the PRNG desired
2017-06-12 12:02:10 +02:00
@param size The size of the key in octets
@param e The "e" value (public key).
e==65537 is a good choice
2005-11-18 05:15:37 +00:00
@param key [out] Destination of a newly created private key pair
@return CRYPT_OK if successful, upon error all allocated ram is freed
*/
2017-06-12 12:02:10 +02:00
int (*rsa_keygen)(prng_state *prng,
int wprng,
int size,
long e,
rsa_key *key);
2005-11-18 05:15:37 +00:00
2005-08-01 16:36:47 +00:00
/** RSA exponentiation
@param in The octet array representing the base
@param inlen The length of the input
@param out The destination (to be stored in an octet array format)
2017-06-12 12:02:10 +02:00
@param outlen The length of the output buffer and the resulting size
(zero padded to the size of the modulus)
2005-08-01 16:36:47 +00:00
@param which PK_PUBLIC for public RSA and PK_PRIVATE for private RSA
2012-07-26 14:43:15 +02:00
@param key The RSA key to use
2005-08-01 16:36:47 +00:00
@return CRYPT_OK on success
*/
int (*rsa_me)(const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen, int which,
rsa_key *key);
/* ---- basic math continued ---- */
/** Modular addition
@param a The first source
2012-07-26 14:43:15 +02:00
@param b The second source
@param c The modulus
@param d The destination (a + b mod c)
@return CRYPT_OK on success
*/
int (*addmod)(void *a, void *b, void *c, void *d);
/** Modular substraction
@param a The first source
2012-07-26 14:43:15 +02:00
@param b The second source
@param c The modulus
@param d The destination (a - b mod c)
@return CRYPT_OK on success
*/
int (*submod)(void *a, void *b, void *c, void *d);
/* ---- misc stuff ---- */
/** Make a pseudo-random mpi
@param a The mpi to make random
@param size The desired length
@return CRYPT_OK on success
*/
int (*rand)(void *a, int size);
2005-08-01 16:36:47 +00:00
} ltc_math_descriptor;
extern ltc_math_descriptor ltc_mp;
int ltc_init_multi(void **a, ...);
void ltc_deinit_multi(void *a, ...);
#ifdef LTM_DESC
extern const ltc_math_descriptor ltm_desc;
#endif
#ifdef TFM_DESC
extern const ltc_math_descriptor tfm_desc;
#endif
2006-04-06 19:48:32 +00:00
#ifdef GMP_DESC
extern const ltc_math_descriptor gmp_desc;
#endif
2005-08-01 16:36:47 +00:00
#if !defined(DESC_DEF_ONLY) && defined(LTC_SOURCE)
#define MP_DIGIT_BIT ltc_mp.bits_per_digit
/* some handy macros */
#define mp_init(a) ltc_mp.init(a)
#define mp_init_multi ltc_init_multi
#define mp_clear(a) ltc_mp.deinit(a)
#define mp_clear_multi ltc_deinit_multi
2005-11-18 05:15:37 +00:00
#define mp_init_copy(a, b) ltc_mp.init_copy(a, b)
2005-08-01 16:36:47 +00:00
2005-11-18 05:15:37 +00:00
#define mp_neg(a, b) ltc_mp.neg(a, b)
2005-08-01 16:36:47 +00:00
#define mp_copy(a, b) ltc_mp.copy(a, b)
#define mp_set(a, b) ltc_mp.set_int(a, b)
#define mp_set_int(a, b) ltc_mp.set_int(a, b)
#define mp_get_int(a) ltc_mp.get_int(a)
#define mp_get_digit(a, n) ltc_mp.get_digit(a, n)
#define mp_get_digit_count(a) ltc_mp.get_digit_count(a)
#define mp_cmp(a, b) ltc_mp.compare(a, b)
#define mp_cmp_d(a, b) ltc_mp.compare_d(a, b)
#define mp_count_bits(a) ltc_mp.count_bits(a)
2006-05-29 23:12:56 +00:00
#define mp_cnt_lsb(a) ltc_mp.count_lsb_bits(a)
2005-08-01 16:36:47 +00:00
#define mp_2expt(a, b) ltc_mp.twoexpt(a, b)
#define mp_read_radix(a, b, c) ltc_mp.read_radix(a, b, c)
#define mp_toradix(a, b, c) ltc_mp.write_radix(a, b, c)
#define mp_unsigned_bin_size(a) ltc_mp.unsigned_size(a)
#define mp_to_unsigned_bin(a, b) ltc_mp.unsigned_write(a, b)
#define mp_read_unsigned_bin(a, b, c) ltc_mp.unsigned_read(a, b, c)
#define mp_add(a, b, c) ltc_mp.add(a, b, c)
#define mp_add_d(a, b, c) ltc_mp.addi(a, b, c)
#define mp_sub(a, b, c) ltc_mp.sub(a, b, c)
#define mp_sub_d(a, b, c) ltc_mp.subi(a, b, c)
#define mp_mul(a, b, c) ltc_mp.mul(a, b, c)
#define mp_mul_d(a, b, c) ltc_mp.muli(a, b, c)
#define mp_sqr(a, b) ltc_mp.sqr(a, b)
2006-06-18 01:37:50 +00:00
#define mp_div(a, b, c, d) ltc_mp.mpdiv(a, b, c, d)
2005-08-01 16:36:47 +00:00
#define mp_div_2(a, b) ltc_mp.div_2(a, b)
2006-06-18 01:37:50 +00:00
#define mp_mod(a, b, c) ltc_mp.mpdiv(a, b, NULL, c)
2005-08-01 16:36:47 +00:00
#define mp_mod_d(a, b, c) ltc_mp.modi(a, b, c)
#define mp_gcd(a, b, c) ltc_mp.gcd(a, b, c)
#define mp_lcm(a, b, c) ltc_mp.lcm(a, b, c)
#define mp_addmod(a, b, c, d) ltc_mp.addmod(a, b, c, d)
#define mp_submod(a, b, c, d) ltc_mp.submod(a, b, c, d)
2005-08-01 16:36:47 +00:00
#define mp_mulmod(a, b, c, d) ltc_mp.mulmod(a, b, c, d)
2006-06-18 01:37:50 +00:00
#define mp_sqrmod(a, b, c) ltc_mp.sqrmod(a, b, c)
2005-08-01 16:36:47 +00:00
#define mp_invmod(a, b, c) ltc_mp.invmod(a, b, c)
#define mp_montgomery_setup(a, b) ltc_mp.montgomery_setup(a, b)
#define mp_montgomery_normalization(a, b) ltc_mp.montgomery_normalization(a, b)
#define mp_montgomery_reduce(a, b, c) ltc_mp.montgomery_reduce(a, b, c)
#define mp_montgomery_free(a) ltc_mp.montgomery_deinit(a)
#define mp_exptmod(a,b,c,d) ltc_mp.exptmod(a,b,c,d)
#define mp_prime_is_prime(a, b, c) ltc_mp.isprime(a, b, c)
2005-08-01 16:36:47 +00:00
#define mp_iszero(a) (mp_cmp_d(a, 0) == LTC_MP_EQ ? LTC_MP_YES : LTC_MP_NO)
#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)
2014-07-15 20:26:40 +02:00
#define mp_exch(a, b) do { void *ABC__tmp = a; a = b; b = ABC__tmp; } while(0)
2005-08-01 16:36:47 +00:00
#define mp_tohex(a, b) mp_toradix(a, b, 16)
#define mp_rand(a, b) ltc_mp.rand(a, b)
2005-08-01 16:36:47 +00:00
#endif
2017-06-19 13:43:49 +02:00
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */