21#if !defined(__RLIB_H_INCLUDE_GUARD__) && !defined(RLIB_COMPILATION)
22#error "#include <rlib.h> only please."
71#define RMPINT_DEF_DIGITS 64
73#define RMPINT_DEF_ISPRIME_T 8
105#define R_MPINT_FLAG_SECURE_CLEAR (1u << 0)
108#define R_MPINT_INIT { 0, 0, 0, 0, NULL }
110#define r_mpint_init(mpi) r_mpint_init_size (mpi, RMPINT_DEF_DIGITS)
222#define r_mpint_iszero(mpi) ((mpi)->dig_used == 0)
224#define r_mpint_iseven(mpi) ((mpi)->dig_used > 0 && (((mpi)->data[0] & 1) == 0))
226#define r_mpint_isodd(mpi) ((mpi)->dig_used > 0 && (((mpi)->data[0] & 1) == 1))
228#define r_mpint_isneg(mpi) ((mpi)->dig_used > 0 && (mpi)->sign)
231#define r_mpint_digits_used(mpi) (mpi)->dig_used
233#define r_mpint_bytes_used(mpi) ((ruint)((mpi)->dig_used > 0 ? \
234 (ruint)(((ruint)(mpi)->dig_used * sizeof (rmpint_digit)) - \
235 (ruint)RUINT32_CLZ (r_mpint_get_digit (mpi, (mpi)->dig_used - 1)) / 8) : \
238#define r_mpint_bits_used(mpi) ((ruint)((mpi)->dig_used > 0 ? \
239 (ruint)(((ruint)(mpi)->dig_used * sizeof (rmpint_digit) * 8) - \
240 (ruint)RUINT32_CLZ (r_mpint_get_digit (mpi, (mpi)->dig_used - 1))) : \
250#define r_mpint_clamp(mpi) R_STMT_START { \
251 while ((mpi)->dig_used > 0 && (mpi)->data[(mpi)->dig_used-1] == 0) \
253 (mpi)->sign = (mpi)->dig_used > 0 ? (mpi)->sign : 0; \
273#define r_mpint_gen_prime(mpi, bits, prng) r_mpint_gen_prime_full (mpi, bits, FALSE, prng)
298#define r_mpint_isprime(mpi) r_mpint_isprime_t (mpi, RMPINT_DEF_ISPRIME_T)
350#define r_mpint_get_digit(mpi, d) \
351 ((d) < (mpi)->dig_used ? (mpi)->data[d] : (rmpint_digit)0)
449#define r_mpint_mod(dst, n, d) r_mpint_div (NULL, dst, n, d)
451#define r_mpint_mod_i32(dst, n, d) r_mpint_div_i32 (NULL, dst, n, d)
453#define r_mpint_mod_u32(dst, n, d) r_mpint_div_u32 (NULL, dst, n, d)
456#define r_mpint_mulmod(dst, a, b, d) (r_mpint_mul (dst, a, b) && r_mpint_mod (dst, dst, d))
458#define r_mpint_mulmod_i32(dst, a, b, d) (r_mpint_mul (dst, a, b) && r_mpint_mod_i32 (dst, dst, d))
460#define r_mpint_mulmod_u32(dst, a, b, d) (r_mpint_mul (dst, a, b) && r_mpint_mod_u32 (dst, dst, d))
566#define R_MPINT_FE_MAX_DIGITS 18
600#define R_MPINT_FE_BIG_MAX_DIGITS 257
#define R_ATTR_NULL_TERMINATED
Mark a variadic function as requiring a NULL sentinel.
Definition rmacros.h:336
#define R_API
Public-API decoration: resolves to R_API_EXPORT while building rlib and R_API_IMPORT for consumers.
Definition rmacros.h:115
#define R_BEGIN_DECLS
Open an extern "C" block under C++ (no-op in C).
Definition rmacros.h:196
void r_mpint_init_secure(rmpint *mpi)
Initialise with the secure-clear flag set.
void r_mpint_fe_from_mpint(RMpintFE *fe, const rmpint *mpi, ruint16 n)
Copy mpi -> fe, zero-padded to n digits. Truncates beyond n.
rmpint_digit r_mpint_fe_big_iszero_ct(const RMpintFE_Big *x, ruint16 n)
See r_mpint_fe_iszero_ct.
void r_mpint_fe_add_ct(RMpintFE *out, const RMpintFE *a, ruint16 a_n, const RMpintFE *b, ruint16 b_n)
Wide add.
void r_mpint_init_binary(rmpint *mpi, rconstpointer data, rsize size)
Initialise from a big-endian byte buffer.
void r_mpint_fe_sub(RMpintFE *out, const RMpintFE *a, const RMpintFE *b, const RMpintFEMontCtx *ctx)
Modular subtraction.
RMpintPrimeTest
Result of a Miller-Rabin primality test.
Definition rmpint.h:283
void r_mpint_set_i32(rmpint *mpi, rint32 value)
Set from a signed 32-bit value.
rboolean r_mpint_lcm(rmpint *dst, const rmpint *a, const rmpint *b)
Least common multiple.
void r_mpint_fe_big_sub(RMpintFE_Big *out, const RMpintFE_Big *a, const RMpintFE_Big *b, const RMpintFE_BigMontCtx *ctx)
See r_mpint_fe_sub.
rboolean r_mpint_shr(rmpint *dst, const rmpint *a, ruint32 bits)
dst = a >> bits.
void r_mpint_fe_sqr_mont(RMpintFE *out, const RMpintFE *a, const RMpintFEMontCtx *ctx)
Montgomery squaring.
rboolean r_mpint_shl_digit(rmpint *dst, const rmpint *a, ruint16 d)
dst = a shifted left by d whole digits.
void r_mpint_fe_big_mul_ct(RMpintFE_Big *out, const RMpintFE_Big *a, ruint16 a_n, const RMpintFE_Big *b, ruint16 b_n)
See r_mpint_fe_mul_ct.
void r_mpint_set_binary(rmpint *mpi, rconstpointer data, rsize size)
Set mpi from a big-endian byte buffer.
ruint32 rmpint_digit
Digit machine word backing rmpint storage.
Definition rmpint.h:76
void r_mpint_fe_big_from_mpint(RMpintFE_Big *fe, const rmpint *mpi, ruint16 n)
See r_mpint_fe_from_mpint.
void r_mpint_fe_big_copy(RMpintFE_Big *dst, const RMpintFE_Big *src)
See r_mpint_fe_copy.
rboolean r_mpint_div(rmpint *q, rmpint *r, const rmpint *n, const rmpint *d)
Quotient + remainder of n / d.
void r_mpint_fe_big_mod_ct(RMpintFE_Big *out, const RMpintFE_Big *a, const RMpintFE_BigMontCtx *ctx)
See r_mpint_fe_mod_ct.
void r_mpint_fe_mul_mont(RMpintFE *out, const RMpintFE *a, const RMpintFE *b, const RMpintFEMontCtx *ctx)
Montgomery multiplication via CIOS: out := a * b * R^-1 mod p, where R = 2^(32 * n_digits).
ruint64 rmpint_word
Double-width word for digit multiplications.
Definition rmpint.h:78
rboolean r_mpint_fe_to_mpint(rmpint *mpi, const RMpintFE *fe, ruint16 n)
Copy fe -> mpi, ending with r_mpint_clamp so the mpint side stays canonical.
void r_mpint_set(rmpint *mpi, const rmpint *b)
Copy b's value into mpi.
void r_mpint_fe_big_sqr_mont(RMpintFE_Big *out, const RMpintFE_Big *a, const RMpintFE_BigMontCtx *ctx)
See r_mpint_fe_sqr_mont.
void r_mpint_fe_invmod_mont(RMpintFE *out, const RMpintFE *a_M, const RMpintFE *p_minus_2, ruint p_minus_2_bits, const RMpintFE *mont_r_squared, const RMpintFEMontCtx *ctx)
Fermat-based modular inversion in Mont form: out := a_M^(p-2) mod p (also in Mont form).
rboolean r_mpint_fe_compute_r_squared(RMpintFE *out, const rmpint *m, ruint16 n)
Compute R^2 mod m for the supplied n-digit modulus (R = 2^(32*n)).
void r_mpint_fe_big_mont_in(RMpintFE_Big *out, const RMpintFE_Big *a, const RMpintFE_Big *mont_r_squared, const RMpintFE_BigMontCtx *ctx)
See r_mpint_fe_mont_in.
rboolean r_mpint_expmod_ct(rmpint *dst, const rmpint *b, const rmpint *e, const rmpint *m, ruint exp_bits)
Constant-time modular exponentiation.
rboolean r_mpint_mul_i32(rmpint *dst, const rmpint *a, rint32 b)
dst = a * b (b is a signed 32-bit immediate).
void r_mpint_init_from(rmpint *dst, const rmpint *src1,...)
Initialise dst with the default size and OR in R_MPINT_FLAG_SECURE_CLEAR if any source in the NULL-te...
rboolean r_mpint_fe_mont_ctx_init(RMpintFEMontCtx *ctx, const rmpint *m)
Fill ctx (p, mp, n_digits) from an mpint modulus.
rboolean r_mpint_expmod(rmpint *dst, const rmpint *b, const rmpint *e, const rmpint *m)
Modular exponentiation: dst = b^e mod m.
rboolean r_mpint_mul_u32(rmpint *dst, const rmpint *a, ruint32 b)
dst = a * b (b is an unsigned 32-bit immediate).
rboolean r_mpint_sub_i32(rmpint *dst, const rmpint *a, rint32 b)
dst = a - b (b is a signed 32-bit immediate).
void r_mpint_init_size_from(rmpint *dst, ruint16 digits, const rmpint *src1,...)
Same as r_mpint_init_from but with a caller-chosen initial digit capacity, for call sites that alloca...
rboolean r_mpint_fe_big_mont_ctx_init(RMpintFE_BigMontCtx *ctx, const rmpint *m)
See r_mpint_fe_mont_ctx_init.
rboolean r_mpint_shr_digit(rmpint *dst, const rmpint *a, ruint16 d)
dst = a shifted right by d whole digits.
void r_mpint_fe_zero(RMpintFE *x)
Zero x's first R_MPINT_FE_MAX_DIGITS digits.
void r_mpint_init_size(rmpint *mpi, ruint16 digits)
Initialise mpi with a caller-chosen digit capacity.
void r_mpint_fe_big_invmod_mont(RMpintFE_Big *out, const RMpintFE_Big *a_M, const RMpintFE_Big *p_minus_2, ruint p_minus_2_bits, const RMpintFE_Big *mont_r_squared, const RMpintFE_BigMontCtx *ctx)
See r_mpint_fe_invmod_mont.
void r_mpint_fe_mont_out(RMpintFE *out, const RMpintFE *a, const RMpintFEMontCtx *ctx)
Lift from Montgomery form back into normal form.
void r_mpint_init_copy(rmpint *dst, const rmpint *src)
Initialise as a copy of src.
int r_mpint_cmp_i32(const rmpint *a, rint32 b)
Signed compare against a 32-bit value.
rboolean r_mpint_div_u32(rmpint *q, rmpint *r, const rmpint *n, ruint32 d)
Divide by an unsigned 32-bit divisor.
rboolean r_mpint_div_i32(rmpint *q, rmpint *r, const rmpint *n, rint32 d)
Divide by a signed 32-bit divisor.
void r_mpint_fe_mul_ct(RMpintFE *out, const RMpintFE *a, ruint16 a_n, const RMpintFE *b, ruint16 b_n)
Wide multiply (operands of different digit widths).
rboolean r_mpint_mul(rmpint *dst, const rmpint *a, const rmpint *b)
dst = a * b.
rboolean r_mpint_shl(rmpint *dst, const rmpint *a, ruint32 bits)
dst = a << bits.
rboolean r_mpint_fe_big_to_mpint(rmpint *mpi, const RMpintFE_Big *fe, ruint16 n)
See r_mpint_fe_to_mpint.
void r_mpint_fe_big_mont_out(RMpintFE_Big *out, const RMpintFE_Big *a, const RMpintFE_BigMontCtx *ctx)
See r_mpint_fe_mont_out.
rboolean r_mpint_gen_prime_full(rmpint *mpi, rsize bits, rboolean safe, RPrng *prng)
Generate a random prime of bits bits.
int r_mpint_ucmp_u32(const rmpint *a, ruint32 b)
Unsigned compare against a 32-bit value.
void r_mpint_init_str(rmpint *mpi, const rchar *str, const rchar **endptr, ruint base)
Initialise by parsing str in base.
void r_mpint_fe_big_mul_mont(RMpintFE_Big *out, const RMpintFE_Big *a, const RMpintFE_Big *b, const RMpintFE_BigMontCtx *ctx)
See r_mpint_fe_mul_mont.
rboolean r_mpint_add_i32(rmpint *dst, const rmpint *a, rint32 b)
dst = a + b (b is a signed 32-bit immediate).
void r_mpint_zero(rmpint *mpi)
Set mpi to zero (preserves capacity and flags).
rboolean r_mpint_sub(rmpint *dst, const rmpint *a, const rmpint *b)
dst = a - b.
rboolean r_mpint_sub_u32(rmpint *dst, const rmpint *a, ruint32 b)
dst = a - b (b is an unsigned 32-bit immediate).
rboolean r_mpint_add(rmpint *dst, const rmpint *a, const rmpint *b)
dst = a + b.
void r_mpint_fe_big_add(RMpintFE_Big *out, const RMpintFE_Big *a, const RMpintFE_Big *b, const RMpintFE_BigMontCtx *ctx)
See r_mpint_fe_add.
void r_mpint_fe_mod_ct(RMpintFE *out, const RMpintFE *a, const RMpintFEMontCtx *ctx)
Conditional-subtract-once reduce: out = (a < p) ? a : a - p.
rboolean r_mpint_fe_big_expmod_ct(rmpint *dst, const rmpint *base, const rmpint *exp, const rmpint *m, const RMpintFE_BigMontCtx *ctx, const RMpintFE_Big *mont_r_squared, ruint exp_bits)
Modular exponentiation in Z_m: dst = base^exp mod m.
void r_mpint_fe_big_add_ct(RMpintFE_Big *out, const RMpintFE_Big *a, ruint16 a_n, const RMpintFE_Big *b, ruint16 b_n)
See r_mpint_fe_add_ct.
rboolean r_mpint_gcd(rmpint *dst, const rmpint *a, const rmpint *b)
Greatest common divisor.
int r_mpint_cmp(const rmpint *a, const rmpint *b)
Signed compare: returns <0 / 0 / >0 like memcmp.
void r_mpint_fe_big_select_ct(RMpintFE_Big *out, rmpint_digit mask, const RMpintFE_Big *a, const RMpintFE_Big *b, ruint16 n)
See r_mpint_fe_select_ct.
void r_mpint_set_u64(rmpint *mpi, ruint64 value)
Set from an unsigned 64-bit value.
void r_mpint_fe_big_zero(RMpintFE_Big *x)
See r_mpint_fe_zero.
void r_mpint_init_copy_secure(rmpint *mpi, const rmpint *b)
One-shot init-from-copy with the secure flag set, for cloning a key into a fresh secure-clear mpint.
void r_mpint_set_u32(rmpint *mpi, ruint32 value)
Set from an unsigned 32-bit value.
rboolean r_mpint_to_binary(const rmpint *mpi, ruint8 *bin, rsize *size)
Write mpi's absolute value into a caller buffer.
rboolean r_mpint_exp(rmpint *dst, const rmpint *b, ruint16 e)
dst = b^e for a small unsigned exponent e.
rboolean r_mpint_to_binary_with_size(const rmpint *mpi, ruint8 *bin, rsize size)
Write mpi's absolute value left-zero-padded to exactly size bytes.
rboolean r_mpint_fe_big_compute_r_squared(RMpintFE_Big *out, const rmpint *m, ruint16 n)
See r_mpint_fe_compute_r_squared.
void r_mpint_clear(rmpint *mpi)
Release mpi's digit storage.
void r_mpint_set_secure_clear(rmpint *mpi)
Flip R_MPINT_FLAG_SECURE_CLEAR on an existing mpint.
void r_mpint_fe_big_swap_ct(RMpintFE_Big *a, RMpintFE_Big *b, ruint32 bit, ruint16 n)
See r_mpint_fe_swap_ct.
rmpint_digit r_mpint_fe_iszero_ct(const RMpintFE *x, ruint16 n)
All-ones mask iff x's low n digits are zero; all-zeros otherwise.
ruint32 r_mpint_ctz(const rmpint *mpi)
Count trailing zero bits in the magnitude of mpi.
#define R_MPINT_FE_BIG_MAX_DIGITS
Maximum digit width for RMpintFE_Big.
Definition rmpint.h:600
void r_mpint_fe_select_ct(RMpintFE *out, rmpint_digit mask, const RMpintFE *a, const RMpintFE *b, ruint16 n)
out := (mask == all-ones) ? a : b, digit-wise over n digits.
void r_mpint_fe_add(RMpintFE *out, const RMpintFE *a, const RMpintFE *b, const RMpintFEMontCtx *ctx)
Modular addition.
void r_mpint_swap_ct(rmpint *a, rmpint *b, ruint32 bit)
Constant-time conditional swap.
rchar * r_mpint_to_str(const rmpint *mpi)
Allocate a decimal string representation of mpi. Caller frees with r_free.
void r_mpint_fe_mont_in(RMpintFE *out, const RMpintFE *a, const RMpintFE *mont_r_squared, const RMpintFEMontCtx *ctx)
Lift from normal form into Montgomery form.
void r_mpint_set_i64(rmpint *mpi, rint64 value)
Set from a signed 64-bit value.
rboolean r_mpint_invmod(rmpint *dst, const rmpint *a, const rmpint *m)
Modular inverse: dst = a^-1 mod m.
RMpintPrimeTest r_mpint_isprime_t(const rmpint *mpi, ruint t)
Miller-Rabin primality test with t rounds.
void r_mpint_init_binary_secure(rmpint *mpi, rconstpointer data, rsize size)
One-shot init from raw bytes with the secure flag set, so a key imported from a buffer never spends a...
rboolean r_mpint_add_u32(rmpint *dst, const rmpint *a, ruint32 b)
dst = a + b (b is an unsigned 32-bit immediate).
void r_mpint_fe_swap_ct(RMpintFE *a, RMpintFE *b, ruint32 bit, ruint16 n)
Branchless XOR-swap of two FEs gated on bit.
ruint8 * r_mpint_to_binary_new(const rmpint *mpi, rsize *size)
Allocate a fresh big-endian byte buffer holding mpi's absolute value.
static rmpint_digit r_mpint_get_digit_ct(const rmpint *mpi, ruint32 d)
Constant-time digit accessor.
Definition rmpint.h:369
rboolean r_mpint_expmod_ct_with_mp(rmpint *dst, const rmpint *b, const rmpint *e, const rmpint *m, rmpint_digit mp, ruint exp_bits)
Variant of r_mpint_expmod_ct that takes the per-modulus Montgomery inverse mp as input rather than de...
#define R_MPINT_FE_MAX_DIGITS
Maximum digit width for RMpintFE.
Definition rmpint.h:566
rboolean r_mpint_montgomery_setup(rmpint_digit *mp, const rmpint *m)
Compute the per-modulus Montgomery inverse mp = -m^-1 mod 2^digit_bits.
void r_mpint_fe_copy(RMpintFE *dst, const RMpintFE *src)
Copy src -> dst (full width).
int r_mpint_ucmp(const rmpint *a, const rmpint *b)
Unsigned (magnitude) compare.
@ R_MPINT_CERTAIN_PRIME
Definition rmpint.h:286
@ R_MPINT_NON_PRIME
Definition rmpint.h:285
@ R_MPINT_POSSIBLE_PRIME
Definition rmpint.h:287
@ R_MPINT_ERROR
Definition rmpint.h:284
struct RPrng RPrng
Opaque, refcounted PRNG handle.
Definition rrand.h:106
char rchar
Default character type (char).
Definition rtypes.h:137
signed long rint64
Signed 64-bit integer.
Definition rtypes.h:188
int rboolean
Boolean type (typedef'd to int).
Definition rtypes.h:59
unsigned int ruint
Unsigned int.
Definition rtypes.h:157
unsigned int ruint32
Unsigned 32-bit integer.
Definition rtypes.h:192
unsigned char ruint8
Unsigned 8-bit integer.
Definition rtypes.h:190
const void * rconstpointer
Generic const pointer (alias for const void *).
Definition rtypes.h:329
signed int rint32
Signed 32-bit integer.
Definition rtypes.h:187
unsigned long rsize
Unsigned pointer-sized size type (like size_t).
Definition rtypes.h:290
unsigned long ruint64
Unsigned 64-bit integer.
Definition rtypes.h:193
unsigned short ruint16
Unsigned 16-bit integer.
Definition rtypes.h:191
OS-entropy sources plus cryptographic (ChaCha20 DRBG, system) and statistical (KISS,...
Foundational type aliases used by every rlib header.
Per-modulus Montgomery context.
Definition rmpint.h:587
RMpintFE p
Definition rmpint.h:588
ruint16 n_digits
Definition rmpint.h:590
rmpint_digit mp
Definition rmpint.h:589
Per-modulus Montgomery context for RMpintFE_Big.
Definition rmpint.h:614
rmpint_digit mp
Definition rmpint.h:616
RMpintFE_Big p
Definition rmpint.h:615
ruint16 n_digits
Definition rmpint.h:617
RSA-width parallel to RMpintFE.
Definition rmpint.h:609
Fixed-width inline-storage field element used by the ECC scalar-mul ladder.
Definition rmpint.h:576
Heap-backed multi-precision integer.
Definition rmpint.h:88
ruint16 dig_used
Definition rmpint.h:90
ruint32 flags
Behaviour flags, currently only R_MPINT_FLAG_SECURE_CLEAR.
Definition rmpint.h:100
ruint32 sign
Definition rmpint.h:91
ruint16 dig_alloc
Definition rmpint.h:89
rmpint_digit * data
Definition rmpint.h:101