#ifndef BN_H_
#define BN_H_
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include <tommath_class.h>
#ifdef __cplusplus
extern
"C"
{
#endif
#if defined(_MSC_VER) || defined(__LLP64__) || defined(__e2k__) || defined(__LCC__)
# define MP_32BIT
#endif
#if defined(__x86_64__) || defined(_M_X64) || defined(_M_AMD64) || \
defined(__powerpc64__) || defined(__ppc64__) || defined(__PPC64__) || \
defined(__s390x__) || defined(__arch64__) || defined(__aarch64__) || \
defined(__sparcv9) || defined(__sparc_v9__) || defined(__sparc64__) || \
defined(__ia64) || defined(__ia64__) || defined(__itanium__) || defined(_M_IA64) || \
defined(__LP64__) || defined(_LP64) || defined(__64BIT__)
# if !(defined(MP_32BIT) || defined(MP_16BIT) || defined(MP_8BIT))
# if defined(__GNUC__)
# define MP_64BIT
# else
# define MP_32BIT
# endif
# endif
#endif
#ifdef MP_8BIT
typedef
unsigned
char
mp_digit;
typedef
unsigned
short
mp_word;
# define MP_SIZEOF_MP_DIGIT 1
# ifdef DIGIT_BIT
# error You must not define DIGIT_BIT when using MP_8BIT
# endif
#elif defined(MP_16BIT)
typedef
unsigned
short
mp_digit;
typedef
unsigned
int
mp_word;
# define MP_SIZEOF_MP_DIGIT 2
# ifdef DIGIT_BIT
# error You must not define DIGIT_BIT when using MP_16BIT
# endif
#elif defined(MP_64BIT)
typedef
unsigned
long
long
mp_digit;
typedef
unsigned
long
mp_word __attribute__((mode(TI)));
# define DIGIT_BIT 60
#else
typedef
unsigned
int
mp_digit;
#ifdef _MSC_VER
typedef
unsigned
__int64
mp_word;
#else
typedef
unsigned
long
long
mp_word;
#endif
# ifdef MP_31BIT
# define DIGIT_BIT 31
# else
# define DIGIT_BIT 28
# define MP_28BIT
# endif
#endif
#ifndef DIGIT_BIT
# define DIGIT_BIT (((CHAR_BIT * MP_SIZEOF_MP_DIGIT) - 1)) /* bits per digit */
typedef
unsigned
long
mp_min_u32;
#else
typedef
mp_digit mp_min_u32;
#endif
#define MP_DIGIT_BIT DIGIT_BIT
#define MP_MASK ((((mp_digit)1)<<((mp_digit)DIGIT_BIT))-((mp_digit)1))
#define MP_DIGIT_MAX MP_MASK
#define MP_LT -1 /* less than */
#define MP_EQ 0 /* equal to */
#define MP_GT 1 /* greater than */
#define MP_ZPOS 0 /* positive integer */
#define MP_NEG 1 /* negative */
#define MP_OKAY 0 /* ok result */
#define MP_MEM -2 /* out of mem */
#define MP_VAL -3 /* invalid input */
#define MP_RANGE MP_VAL
#define MP_YES 1 /* yes response */
#define MP_NO 0 /* no response */
#define LTM_PRIME_BBS 0x0001 /* BBS style prime */
#define LTM_PRIME_SAFE 0x0002 /* Safe prime (p-1)/2 == prime */
#define LTM_PRIME_2MSB_ON 0x0008 /* force 2nd MSB to 1 */
typedef
int
mp_err;
extern
int
KARATSUBA_MUL_CUTOFF,
KARATSUBA_SQR_CUTOFF,
TOOM_MUL_CUTOFF,
TOOM_SQR_CUTOFF;
#ifndef MP_PREC
# ifndef MP_LOW_MEM
# define MP_PREC 32 /* default digits of precision */
# else
# define MP_PREC 8 /* default digits of precision */
# endif
#endif
#define MP_WARRAY (1u << (((sizeof(mp_word) * CHAR_BIT) - (2 * DIGIT_BIT)) + 1))
typedef
struct
{
int
used, alloc, sign;
mp_digit *dp;
} mp_int;
typedef
int
ltm_prime_callback(unsigned
char
*dst,
int
len,
void
*dat);
#define USED(m) ((m)->used)
#define DIGIT(m, k) ((m)->dp[(k)])
#define SIGN(m) ((m)->sign)
const
char
*mp_error_to_string(
int
code);
int
mp_init(mp_int *a);
void
mp_clear(mp_int *a);
int
mp_init_multi(mp_int *mp, ...);
void
mp_clear_multi(mp_int *mp, ...);
void
mp_exch(mp_int *a, mp_int *b);
int
mp_shrink(mp_int *a);
int
mp_grow(mp_int *a,
int
size);
int
mp_init_size(mp_int *a,
int
size);
#define mp_iszero(a) (((a)->used == 0) ? MP_YES : MP_NO)
#define mp_iseven(a) ((((a)->used == 0) || (((a)->dp[0] & 1u) == 0u)) ? MP_YES : MP_NO)
#define mp_isodd(a) ((((a)->used > 0) && (((a)->dp[0] & 1u) == 1u)) ? MP_YES : MP_NO)
#define mp_isneg(a) (((a)->sign != MP_ZPOS) ? MP_YES : MP_NO)
void
mp_zero(mp_int *a);
void
mp_set(mp_int *a, mp_digit b);
int
mp_set_int(mp_int *a, unsigned
long
b);
int
mp_set_long(mp_int *a, unsigned
long
b);
unsigned
long
mp_get_int(
const
mp_int *a);
unsigned
long
mp_get_long(
const
mp_int *a);
int
mp_init_set(mp_int *a, mp_digit b);
int
mp_init_set_int(mp_int *a, unsigned
long
b);
int
mp_copy(
const
mp_int *a, mp_int *b);
int
mp_init_copy(mp_int *a,
const
mp_int *b);
void
mp_clamp(mp_int *a);
int
mp_import(mp_int *rop,
size_t
count,
int
order,
size_t
size,
int
endian,
size_t
nails,
const
void
*op);
int
mp_export(
void
*rop,
size_t
*countp,
int
order,
size_t
size,
int
endian,
size_t
nails,
const
mp_int *op);
void
mp_rshd(mp_int *a,
int
b);
int
mp_lshd(mp_int *a,
int
b);
int
mp_div_2d(
const
mp_int *a,
int
b, mp_int *c, mp_int *d);
int
mp_div_2(
const
mp_int *a, mp_int *b);
int
mp_mul_2d(
const
mp_int *a,
int
b, mp_int *c);
int
mp_mul_2(
const
mp_int *a, mp_int *b);
int
mp_mod_2d(
const
mp_int *a,
int
b, mp_int *c);
int
mp_2expt(mp_int *a,
int
b);
int
mp_cnt_lsb(
const
mp_int *a);
int
mp_rand(mp_int *a,
int
digits);
#ifdef MP_PRNG_ENABLE_LTM_RNG
extern
unsigned
long
(*ltm_rng)(unsigned
char
*out, unsigned
long
outlen,
void
(*callback)(
void
));
extern
void
(*ltm_rng_callback)(
void
);
#endif
int
mp_xor(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_or(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_and(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_tc_xor(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_tc_or(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_tc_and(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_tc_div_2d(
const
mp_int *a,
int
b, mp_int *c);
int
mp_complement(
const
mp_int *a, mp_int *b);
int
mp_neg(
const
mp_int *a, mp_int *b);
int
mp_abs(
const
mp_int *a, mp_int *b);
int
mp_cmp(
const
mp_int *a,
const
mp_int *b);
int
mp_cmp_mag(
const
mp_int *a,
const
mp_int *b);
int
mp_add(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_sub(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_mul(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_sqr(
const
mp_int *a, mp_int *b);
int
mp_div(
const
mp_int *a,
const
mp_int *b, mp_int *c, mp_int *d);
int
mp_mod(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_cmp_d(
const
mp_int *a, mp_digit b);
int
mp_add_d(
const
mp_int *a, mp_digit b, mp_int *c);
int
mp_sub_d(
const
mp_int *a, mp_digit b, mp_int *c);
int
mp_mul_d(
const
mp_int *a, mp_digit b, mp_int *c);
int
mp_div_d(
const
mp_int *a, mp_digit b, mp_int *c, mp_digit *d);
int
mp_div_3(
const
mp_int *a, mp_int *c, mp_digit *d);
int
mp_expt_d(
const
mp_int *a, mp_digit b, mp_int *c);
int
mp_expt_d_ex(
const
mp_int *a, mp_digit b, mp_int *c,
int
fast);
int
mp_mod_d(
const
mp_int *a, mp_digit b, mp_digit *c);
int
mp_addmod(
const
mp_int *a,
const
mp_int *b,
const
mp_int *c, mp_int *d);
int
mp_submod(
const
mp_int *a,
const
mp_int *b,
const
mp_int *c, mp_int *d);
int
mp_mulmod(
const
mp_int *a,
const
mp_int *b,
const
mp_int *c, mp_int *d);
int
mp_sqrmod(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_invmod(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_gcd(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_exteuclid(
const
mp_int *a,
const
mp_int *b, mp_int *U1, mp_int *U2, mp_int *U3);
int
mp_lcm(
const
mp_int *a,
const
mp_int *b, mp_int *c);
int
mp_n_root(
const
mp_int *a, mp_digit b, mp_int *c);
int
mp_n_root_ex(
const
mp_int *a, mp_digit b, mp_int *c,
int
fast);
int
mp_sqrt(
const
mp_int *arg, mp_int *ret);
int
mp_sqrtmod_prime(
const
mp_int *n,
const
mp_int *prime, mp_int *ret);
int
mp_is_square(
const
mp_int *arg,
int
*ret);
int
mp_jacobi(
const
mp_int *a,
const
mp_int *n,
int
*c);
int
mp_reduce_setup(mp_int *a,
const
mp_int *b);
int
mp_reduce(mp_int *x,
const
mp_int *m,
const
mp_int *mu);
int
mp_montgomery_setup(
const
mp_int *n, mp_digit *rho);
int
mp_montgomery_calc_normalization(mp_int *a,
const
mp_int *b);
int
mp_montgomery_reduce(mp_int *x,
const
mp_int *n, mp_digit rho);
int
mp_dr_is_modulus(
const
mp_int *a);
void
mp_dr_setup(
const
mp_int *a, mp_digit *d);
int
mp_dr_reduce(mp_int *x,
const
mp_int *n, mp_digit k);
int
mp_reduce_is_2k(
const
mp_int *a);
int
mp_reduce_2k_setup(
const
mp_int *a, mp_digit *d);
int
mp_reduce_2k(mp_int *a,
const
mp_int *n, mp_digit d);
int
mp_reduce_is_2k_l(
const
mp_int *a);
int
mp_reduce_2k_setup_l(
const
mp_int *a, mp_int *d);
int
mp_reduce_2k_l(mp_int *a,
const
mp_int *n,
const
mp_int *d);
int
mp_exptmod(
const
mp_int *G,
const
mp_int *X,
const
mp_int *P, mp_int *Y);
#ifdef MP_8BIT
# define PRIME_SIZE 31
#else
# define PRIME_SIZE 256
#endif
extern
const
mp_digit ltm_prime_tab[PRIME_SIZE];
int
mp_prime_is_divisible(
const
mp_int *a,
int
*result);
int
mp_prime_fermat(
const
mp_int *a,
const
mp_int *b,
int
*result);
int
mp_prime_miller_rabin(
const
mp_int *a,
const
mp_int *b,
int
*result);
int
mp_prime_rabin_miller_trials(
int
size);
int
mp_prime_is_prime(
const
mp_int *a,
int
t,
int
*result);
int
mp_prime_next_prime(mp_int *a,
int
t,
int
bbs_style);
#define mp_prime_random(a, t, size, bbs, cb, dat) mp_prime_random_ex(a, t, ((size) * 8) + 1, (bbs==1)?LTM_PRIME_BBS:0, cb, dat)
int
mp_prime_random_ex(mp_int *a,
int
t,
int
size,
int
flags, ltm_prime_callback cb,
void
*dat);
int
mp_count_bits(
const
mp_int *a);
int
mp_unsigned_bin_size(
const
mp_int *a);
int
mp_read_unsigned_bin(mp_int *a,
const
unsigned
char
*b,
int
c);
int
mp_to_unsigned_bin(
const
mp_int *a, unsigned
char
*b);
int
mp_to_unsigned_bin_n(
const
mp_int *a, unsigned
char
*b, unsigned
long
*outlen);
int
mp_signed_bin_size(
const
mp_int *a);
int
mp_read_signed_bin(mp_int *a,
const
unsigned
char
*b,
int
c);
int
mp_to_signed_bin(
const
mp_int *a, unsigned
char
*b);
int
mp_to_signed_bin_n(
const
mp_int *a, unsigned
char
*b, unsigned
long
*outlen);
int
mp_read_radix(mp_int *a,
const
char
*str,
int
radix);
int
mp_toradix(
const
mp_int *a,
char
*str,
int
radix);
int
mp_toradix_n(
const
mp_int *a,
char
*str,
int
radix,
int
maxlen);
int
mp_radix_size(
const
mp_int *a,
int
radix,
int
*size);
#ifndef LTM_NO_FILE
int
mp_fread(mp_int *a,
int
radix,
FILE
*stream);
int
mp_fwrite(
const
mp_int *a,
int
radix,
FILE
*stream);
#endif
#define mp_read_raw(mp, str, len) mp_read_signed_bin((mp), (str), (len))
#define mp_raw_size(mp) mp_signed_bin_size(mp)
#define mp_toraw(mp, str) mp_to_signed_bin((mp), (str))
#define mp_read_mag(mp, str, len) mp_read_unsigned_bin((mp), (str), (len))
#define mp_mag_size(mp) mp_unsigned_bin_size(mp)
#define mp_tomag(mp, str) mp_to_unsigned_bin((mp), (str))
#define mp_tobinary(M, S) mp_toradix((M), (S), 2)
#define mp_tooctal(M, S) mp_toradix((M), (S), 8)
#define mp_todecimal(M, S) mp_toradix((M), (S), 10)
#define mp_tohex(M, S) mp_toradix((M), (S), 16)
#ifdef __cplusplus
}
#endif
#endif