#ifndef _BIG_H_ #define _BIG_H_ #include "typedef.h" #define VLI_DIGIT_BITS 64 #define VLI_DIGIT_BYTES (VLI_DIGIT_BITS/8) #ifdef __cplusplus extern "C" { #endif void vli_clear(u64 *vli, u8 ndigits); /* Returns true if vli == 0, false otherwise. */ int vli_is_zero(u64 *vli, u8 ndigits); /* Returns nonzero if bit bit of vli is set. */ u64 vli_test_bit(u64 *vli, u8 bit, u8 ndigits); /* Counts the number of 8-bit "digits" in vli. */ u32 vli_num_digits(u64 *vli, u8 ndigits); /* Counts the number of bits required for vli. */ u32 vli_num_bits(u64 *vli, u8 ndigits); /* Sets dest = src. */ void vli_set(u64 *dest, u64 *src, u8 ndigits); /* Returns sign of left - right. */ int vli_cmp(u64 *left, u64 *right, u8 ndigits); /* Computes result = in << c, returning carry. Can modify in place * (if result == in). 0 < shift < 8. */ u64 vli_lshift(u64 *result, u64 *in, u32 shift, u8 ndigits); /* Computes result = (left * right) % curve->p. */ void vli_mod_mult_fast(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits); /* Computes result = left^2 % curve->p. */ void vli_mod_square_fast(u64 *result, u64 *left, u64 *mod, u8 ndigits); /* Computes result = in >> c, returning carry. Can modify in place * (if result == in). 0 < shift < 64. */ u64 vli_rshift(u64 *result, u64 *in, u32 shift, u8 ndigits); /* Computes result = left + right, returning carry. Can modify in place. */ u64 vli_add(u64 *result, u64 *left, u64 *right, u8 ndigits); /* Computes result = left - right, returning borrow. Can modify in place. */ u64 vli_sub(u64 *result, u64 *left, u64 *right, u8 ndigits); /* Computes result = left * right. */ void vli_mult(u64 *result, u64 *left, u64 *right, u8 ndigits); /* Computes result = left^2. */ void vli_square(u64 *result, u64 *left, u8 ndigits); /* Computes result = (left + right) % mod. Assumes that left < mod and right < mod, result != mod. */ void vli_mod_add(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits); /* Computes result = (left - right) % mod. Assumes that left < mod and right < mod, result != mod. */ void vli_mod_sub(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits); /* Computes result = (left * right) % mod. */ void vli_mod_mult(u64 *result, u64 *left, u64 *right, u64 *mod, u8 ndigits); /* Computes result = left^2 % mod. */ void vli_mod_square(u64 *result, u64 *left, u64 *mod, u8 ndigits); /* Computes result = left^p % mod. */ void vli_mod_exp(u64 *result, u64 *left, u64 *p, u64 *mod, u8 ndigits); /* Computes result = (product) % mod. */ void vli_mod(u64 *result, u64 *product, u64 *mod, u8 ndigits); /* Computes result = (1 / input) % mod. All VLIs are the same size. * See "From Euclid's GCD to Montgomery Multiplication to the Great Divide" * https://labs.oracle.com/techrep/2001/smli_tr-2001-95.pdf */ void vli_mod_inv(u64 *result, u64 *input, u64 *mod, u8 ndigits); /* Computes result = (left / right). * remainder = (left % right). */ void vli_div(u64 *result, u64 *remainder, u64 *left, u64 cdigits, u64 *right, u8 ddigits); #ifdef __cplusplus } #endif #endif