/* * mp.h * * This code is in the public domain. I would appreciate bug reports and * enhancements. * * Duncan S Wong * * Feb 11, 2001 - v0.2 - CRT special case of two moduli (MP_crt2) * - Primality test algorithm (MP_probab_prime) * Dec 14, 2000 - v0.1 - Initial Version */ #ifndef __MP_H__ #define __MP_H__ #include #define MP_DEFAULT_BITS 1280 // Only one for the following should be defined. #undef THIRTY_TWO_BIT #define SIXTEEN_BIT // so far this one gives the fastest result on my Palm III, remember to add CodeWarrior Runtime (2i) library #undef EIGHT_BIT #ifdef THIRTY_TWO_BIT #define DIGIT unsigned long // the radix is 4294967296 (32 bits) #define DOUBLE_DIGIT unsigned long long // 64 bits #define DIGIT_BITS 32 #define DIGIT_BITSl 16 #define DIGIT_BYTES 4 #define DIGIT_MASK (0xffffffffL) #define DIGIT_MASKl (0xffff) #define DIGIT_HBIT (0x80000000L) #define DOUBLE_DIGIT_HBIT (0x8000000000000000) #endif #ifdef SIXTEEN_BIT #define DIGIT unsigned short // the radix is 65536 (16 bits) #define DOUBLE_DIGIT unsigned long // 32 bits #define TETRA_DIGIT unsigned long long // 64 bits #define DIGIT_BITS 16 #define DIGIT_BITSl 8 #define DIGIT_BYTES 2 #define DIGIT_MASK (0xffff) #define DIGIT_MASKl (0xff) #define DIGIT_HBIT (0x8000) #define DOUBLE_DIGIT_MASK (0xffffffffL) #define DOUBLE_DIGIT_HBIT (0x80000000L) #endif #ifdef EIGHT_BIT #define DIGIT unsigned char // the radix is 256 (8 bits) #define DOUBLE_DIGIT unsigned short // 16 bits #define TETRA_DIGIT unsigned long // 32 bits #define DIGIT_BITS 8 #define DIGIT_BITSl 4 #define DIGIT_BYTES 1 #define DIGIT_MASK (0xff) #define DIGIT_MASKl (0xf) #define DIGIT_HBIT (0x80) #define DOUBLE_DIGIT_MASK (0xffff) #define DOUBLE_DIGIT_HBIT (0x8000) #endif typedef struct strutINT { DIGIT *d; Int16 top; // Index of last used digit + 1 (Int16 limits the max # digits that this MP library can support to 32767 digits) Int16 max; // Size of the d array (Int16 limits the max # digits that this MP library can support to 32767 digits) Int16 neg; // one if the number is negative } INT; // Used as temp buffers #define MP_CTX_NUM 12 typedef struct structMP_CTX { Int16 tos; INT *t[MP_CTX_NUM+1]; } MP_CTX; // Used for Montgomery multiplication typedef struct structMP_MONT_CTX { Int16 n; // R = b^n where b = 2^ DIGIT_BITS, the radix INT *R_m; // R mod m INT *R2_m; // R^2 mod m INT *m; // The modulus DIGIT mi; // -m^{-1} mod b where b = 2^DIGIT_BITS } MP_MONT_CTX; /**************************************** * Functions Exported to MPLib Interface ****************************************/ // Initialization Functions INT *MP_new(void); void MP_clear(INT *integer); void MP_free(INT *integer); void MP_clear_free(INT *integer); MP_CTX *MP_CTX_new(void); void MP_CTX_free(MP_CTX *c); MP_MONT_CTX *MP_MONT_CTX_new(void ); void MP_MONT_CTX_free(MP_MONT_CTX *mont); Int16 MP_MONT_CTX_set(MP_MONT_CTX *mont, INT *modulus, MP_CTX *ctx); // Assignment Functions Int16 MP_mask_bits(INT *a, Int16 n); INT *MP_copy(INT *dest, INT *src); // Arithmetic Functions Int16 MP_add(INT *s, INT *a, INT *b); void MP_qadd(INT *s, INT *a, INT *b); Int16 MP_sub(INT *r, INT *a, INT *b); void MP_qsub(INT *r, INT *a, INT *b); Int16 MP_mul(INT *r, INT *a, INT *b); DIGIT MP_mul_digit(DIGIT *rp, DIGIT *ap, Int16 num, DIGIT w); DIGIT MP_mul_add_digit(DIGIT *rp, DIGIT *ap, Int16 num, DIGIT w); Int16 MP_sqr(INT *r, INT *a); Int16 MP_div(INT *q, INT *r, INT *dividend, INT *divisor, MP_CTX *ctx); // Logical Functions Int16 MP_lshift(INT *to, INT *from, Int16 n); Int16 MP_lshift1(INT *r, INT *a); Int16 MP_rshift(INT *r, INT *a, Int16 n); Int16 MP_rshift1(INT *r, INT *a); // Comparison Functions Int16 MP_cmp(INT *a, INT *b); Int16 MP_ucmp(INT *a, INT *b); Int16 MP_is_bit_set(INT *a, Int16 n); // Number Theoretic Functions Int16 MP_mod_mul(INT *r, INT *a, INT *b, INT *m, MP_CTX *ctx); Int16 MP_mont_mul(INT *r, INT *a, INT *b, MP_MONT_CTX *mont, MP_CTX *ctx); INT *MP_mod_inverse(INT *a, INT *n, MP_CTX *ctx); Int16 MP_mod_exp(INT *r, INT *a, INT *b, INT *m, MP_CTX *ctx); Int16 MP_mont_exp(INT *r, INT *a, INT *e, MP_MONT_CTX *mont, MP_CTX *ctx); Int16 MP_gcd(INT *d, INT *a, INT *b, MP_CTX *ctx); Int16 MP_binary_gcd(INT *d, INT *a, INT *b, MP_CTX *ctx); Int16 MP_crt2(INT *x, INT *v1, INT *v2, INT *p, INT *q, MP_CTX *ctx); Int16 MP_probab_prime(INT *n, UInt16 reps, MP_CTX *ctx); // Conversion Functions INT *MP_bin2bn(UInt8 *s, UInt16 len); UInt16 MP_bn2bin(INT *a, UInt8 *to); INT *MP_ascii2bn(Char *str); Char *MP_bn2ascii(INT *a); UInt32 MP_num_bits(INT *a); UInt16 MP_num_bits_digit(DIGIT l); /**************** * Macros ****************/ #define MP_is_zero(a) (((a)->top <= 1) && ((a)->d[0] == (DIGIT)0)) #define MP_is_one(a) (((a)->top == 1) && ((a)->d[0] == (DIGIT)1)) #define MP_is_odd(a) ((a)->d[0] & 1) #define MP_zero(a) { (a)->top = 0; (a)->d[0] = (DIGIT)0; } #define MP_one(a) { (a)->top = 1; (a)->d[0] = (DIGIT)1; } #endif