1745 lines
49 KiB
Groff
1745 lines
49 KiB
Groff
.TH LIBTOMMATH 3 "2003-28-02"
|
|
.SH NAME
|
|
libtommath - a big integer library
|
|
.SH SYNOPSIS
|
|
.sp
|
|
.ft B
|
|
.nf
|
|
#include <tommath\&.h>
|
|
.fi
|
|
.ft
|
|
.SH DESCRIPTION
|
|
.I LibTomMath
|
|
provides a series of efficient and carefully written functions
|
|
for manipulating large integer numbers.
|
|
.br
|
|
Functions are in alphabetical order.
|
|
.LP
|
|
\fBNOTE:\fP The errors listed are not the only ones possible, just the interesting ones.
|
|
|
|
.LP
|
|
.BI "mp_err mp_2expt(mp_int * " a ", int " b ")"
|
|
.in 1i
|
|
Computes 2^b with b >= 0 and puts the result in \fIa\fP. This functions uses a faster method than \fBmp_mul_2\fP.
|
|
.br
|
|
Returns \fBMP_OVF\fP if the result would be larger than a \fBmp_int\fP can hold. The macro \fBMP_MAX_DIGIT_COUNT\fP holds
|
|
the maximal number of limbs: ((INT_MAX - 2) / MP_DIGIT_BIT).
|
|
.br
|
|
Returns \fBMP_VAL\fP if b < 0
|
|
.in -1i
|
|
|
|
|
|
.LP
|
|
.BI "mp_err mp_abs (const mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Computes the absolute value of \fBa\fP and puts the result in \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_add (const mp_int *" a ", const mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes \fBa + b = c\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_add_d(const mp_int *" a ", mp_digit " b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes \fBa + b = c\fP where \fBb\fP is of type \fBmp_digit\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_addmod(const mp_int *" a ", const mp_int *" b ", const mp_int *" c ", mp_int *" d ")"
|
|
.in 1i
|
|
Computes \fB(a + b) % c = d\fP. No optimizations.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_and (const mp_int *" a ", mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes bitwise or \fBa & b = c\fP. Negative numbers
|
|
are treated as if they are in two-complement representation.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_clamp(mp_int *" a ");
|
|
.in 1i
|
|
This is used to ensure that leading zero digits are trimmed and the leading \fBused\fP digit will be
|
|
non-zero. It also fixes the sign if there are no more leading digits.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_clear (mp_int *" a ")"
|
|
.in 1i
|
|
Frees the heap memory of \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "int mp_cnt_lsb(const mp_int *" a ")"
|
|
.in 1i
|
|
Returns the position of the lowest bit set.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_ord mp_cmp(const mp_int *" a ", const mp_int *" b ")"
|
|
.in 1i
|
|
Compare \fBa\fP to \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_ord mp_cmp_d(const mp_int *" a ", mp_digit " b ")"
|
|
.in 1i
|
|
Compare \fBa\fP to a single digit \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_ord mp_cmp_mag(const mp_int *" a ", const mp_int *" b ")"
|
|
.in 1i
|
|
Compares the absolute values of \fBa\fP and \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_complement(const mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Computes the 2-complement \fIb = ~a\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_copy (const mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Makes a deep copy of \fBa\fP into \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "int mp_count_bits(const mp_int *" a ")"
|
|
.in 1i
|
|
Returns the position of the highest bit set.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_decr(mp_int *" a ")"
|
|
.in 1i
|
|
Computes \fBa--\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_div_2(const mp_int *" a ", mp_int *" b ");
|
|
.in 1i
|
|
Computes \fBa >> 1 = b\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_div_2d (const mp_int *" a ", int " b ", mp_int *" c ", mp_int *" d ");
|
|
.in 1i
|
|
Computes \fBa >> b = c + d\fP with \fBc\fP the optional quotient and \fBd\fP the optional remainder.
|
|
.br
|
|
Set the argument for quotient and/or remainder to \fBNULL\fP to ignore the respective output.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBb < 0\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_div (const mp_int *" a ", const mp_int *" b ", mp_int *" c ", mp_int *" d ")"
|
|
.in 1i
|
|
Computes \fBa / b = c + d\fP with \fBc\fP the optional quotient and \fBd\fP the optional remainder.
|
|
.br
|
|
Set the argument for quotient and/or remainder to \fBNULL\fP to ignore the respective output.
|
|
.br
|
|
This function calls one of either: \fBs_mp_div_recursive\fP, \fBs_mp_div_school\fP, or
|
|
\fBs_mp_div_small\fP.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBb = 0\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_div_d(const mp_int *" a ", mp_digit " b ", mp_int *" c ", mp_digit *" d ")"
|
|
.in 1i
|
|
Computes \fBa / b = c + d\fP with \fBc\fP the optional quotient and \fBd\fP the optional remainder.
|
|
.br
|
|
Set the argument for quotient and/or remainder to \fBNULL\fP to ignore the respective output.
|
|
Returns \fBMP_VAL\fP if \fBb = 0\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "bool mp_dr_is_modulus(const mp_int *" a ")"
|
|
.in 1i
|
|
Returns \fBtrue\fP if the modulus \fBa\fP is of the form below that allows for a diminished radix reduction, \fBfalse\fP otherwise.
|
|
.br
|
|
\fB\[*b]^k - p\fP for some \fBk >= 0\fP and \fB0 < p < \[*b]\fP where \fB\[*b]\fP is the radix.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_dr_reduce(mp_int *" a ", const mp_int *" b ", mp_digit " mp ")"
|
|
.in 1i
|
|
This reduces \fBa\fP in place modulo \fBb\fP with the pre-computed value \fBmp\fP. \fBb\fP must be of a restricted
|
|
diminished radix form and \fBa\fP must be in the range \fB0 <= a < b^2\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_dr_setup(const mp_int *" a ", mp_digit *" d ")"
|
|
.in 1i
|
|
This computes the value required for the modulus \fBa\fP and stores it in \fBd\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_exch (mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Swaps, but just the pointers.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "const char *mp_error_to_string(mp_err " code ")"
|
|
.in 1i
|
|
Returns a short ASCII message describing the error code given in \fBcode\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_exptmod (const mp_int *" G ", const mp_int *" X ", const mp_int *" P ", mp_int *" Y ")"
|
|
.in 1i
|
|
This computes \fBY \[==] G^X (mod P)\fP using a variable width sliding window
|
|
algorithm. This function will automatically detect the fastest modular reduction technique to use
|
|
during the operation. For negative values of \fBX\fP the operation is performed as \fBY \[==] (G^-1 mod P)^(|X| (mod P))\fP
|
|
provided that \fBgcd(G, P) = 1\fP.
|
|
.br
|
|
This function is actually a shell around the two internal exponentiation functions. This routine
|
|
will automatically detect when Barrett, Montgomery, Restricted and Unrestricted Diminished Radix
|
|
based exponentiation can be used. Generally moduli of the a "restricted diminished radix" form
|
|
lead to the fastest modular exponentiations. Followed by Montgomery and the other two algorithms.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBP < 0\fP.
|
|
.br
|
|
Returns \fBMP_VAL\fP if none of the underlying internal functions have been compiled in.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_expt_n(const mp_int *" a ", int " b ", int *" c ")"
|
|
.in 1i
|
|
Computes \fBa^b = c\fP. Simple binary exponentiation, no further optimizations.
|
|
.br
|
|
\fBb\fP must be positive.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_exteuclid(const mp_int *" a ", const mp_int *" b ", mp_int *" U1 ", mp_int *" U2 ", mp_int *" U3 ")"
|
|
.in 1i
|
|
Computes the extended Euclidean algorithm: \fBa * U1 + b * U2 = U3\fP
|
|
.br
|
|
Set the argument for \fBU1, U2, U3\fP to \fBNULL\fP to ignore the respective output.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_fread(mp_int *" a ", int " radix ", FILE *" stream ")"
|
|
.in 1i
|
|
Reads a number in radix \fBradix\fP from file \fBstream\fP and converts it into the big integer \fBa\fP.
|
|
.br
|
|
Returns \fBMP_VAL\fP if radix is not in the range \fB2 <= radix <= 64\fP.
|
|
.br
|
|
Returns \fBMP_ERR\fP if no digits were found in \fBstream\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_from_sbin(mp_int *" a ", const uint8_t *" b ", size_t " size ")"
|
|
.in 1i
|
|
This will read in an big-endian array of octets from \fBb\fP of length
|
|
\fBsize\fP into \fBa\fP.
|
|
.br
|
|
If the first octet of the data is zero, the sign of the big-integer will be \fBMP_NEG\fP and \fBMP_ZPOS\fP otherwise.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_from_ubin(mp_int *" a ", uint8_t *" b ", size_t " size ")"
|
|
.in 1i
|
|
This will read in an big-endian array of octets from \fBb\fP of length
|
|
\fBsize\fP into \fBa\fP. The resulting big-integer \fBa\fP will always be positive.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_fwrite(const mp_int *" a ", int " radix ", FILE *" stream ")"
|
|
.in 1i
|
|
Writes \fBa\fP as a string representing the big integer in radix \fBradix\fP to file \fBstream\fP.
|
|
.br
|
|
Returns \fBMP_MEM\fP if the functions fails to allocate memory for the buffer.
|
|
.br
|
|
Returns \fBMP_ERR\fP if there was a problem writing to the file.
|
|
.br
|
|
Returns \fBMP_VAL\fP if radix is not in the range \fB2 <= radix <= 64\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_gcd (const mp_int *" a ", const mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Compute the greatest common divisor of \fBa\fP and \fBb\fP and store it in \fBc\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "double mp_get_double(const mp_int *" a ")"
|
|
.in 1i
|
|
Returns a float of type \fBdouble\fP (binary64).
|
|
.br
|
|
Will overflow if the big integer is too big.
|
|
.br
|
|
\fBNOTE:\fP rounding mode is not set just taken. Use e.g.: \fBfesetround(3)\fP in \fBfenv.h\fP to
|
|
change the rounding mode.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "int32_t mp_get_i32 (const mp_int *" a ")"
|
|
.in 1i
|
|
Returns a signed 32-bit integer from big-integer \fBa\fP.
|
|
.br
|
|
\fBNOTE:\fP This group of functions is truncating. Example:
|
|
.br
|
|
.TS
|
|
tab(;), allbox;
|
|
l r.
|
|
Input;123456789101112131415161718192021222324252627282930
|
|
mp_get_i32;-1073632270
|
|
mp_get_i64;5543444065158278130
|
|
mp_get_mag_u32;3221335026
|
|
mp_get_mag_u64;5543444065158278130
|
|
mp_get_l;5543444065158278130
|
|
mp_get_ul;5543444065158278130
|
|
mp_get_mag_ul;5543444065158278130
|
|
.TE
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "int64_t mp_get_i64 (const mp_int *" a ")"
|
|
.in 1i
|
|
Returns a signed 64-bit integer from big-integer \fBa\fP.
|
|
.br
|
|
\fBNOTE:\fP This function is truncating. See \fBmp_get_i32\fP for details.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "long mp_get_l (const mp_int *" a ")"
|
|
.in 1i
|
|
Returns a signed \fBlong\fP from big-integer \fBa\fP.
|
|
.br
|
|
\fBNOTE:\fP This function is truncating. See \fBmp_get_i32\fP for details.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "uint32_t mp_get_mag_u32 (const mp_int *" a ")"
|
|
.in 1i
|
|
Returns an unsigned 32 bit integer from big-integer \fBa\fP.
|
|
.br
|
|
\fBNOTE:\fP This function is truncating. See \fBmp_get_i32\fP for details.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "uint64_t mp_get_mag_u64 (const mp_int *" a ")"
|
|
.in 1i
|
|
Returns an unsigned 64 bit integer from big-integer \fBa\fP.
|
|
.br
|
|
\fBNOTE:\fP This function is truncating. See \fBmp_get_i32\fP for details.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "unsigned long mp_get_mag_ul (const mp_int *" a ")"
|
|
.in 1i
|
|
Returns an unsigned long from big-integer \fBa\fP.
|
|
.br
|
|
\fBNOTE:\fP This function is truncating. See \fBmp_get_i32\fP for details.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "uint32_t mp_get_u32 (const mp_int *" a ")"
|
|
.in 1i
|
|
Convenience macro for \fBmp_get_mag_u32()\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "uint64_t mp_get_u64 (const mp_int *" a ")"
|
|
.in 1i
|
|
Convenience macro for \fBmp_get_mag_u64()\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "unsigned long mp_get_ul (const mp_int *" a ")"
|
|
.in 1i
|
|
Convenience macro for \fBmp_get_mag_ul()\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_grow (mp_int *" a ", int " size ")"
|
|
.in 1i
|
|
This will grow the array of digits of \fBa\fP to \fBsize\fP.
|
|
.br
|
|
Returns \fBMP_MEM\fP if the functions fails to allocate enough memory.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_hash (const mp_int *" a ", mp_hval *" hash ")"
|
|
.in 1i
|
|
This will create the hash of \fBa\fP following the \fIFNV-1a\fP algorithm as described on
|
|
\fIhttp://www.isthe.com/chongo/tech/comp/fnv/index.html#FNV-1a\fP. With the
|
|
help of this function one can use an \fBmp_int\fP as a key in a hash table.
|
|
.br
|
|
\fBNOTE:\fP The hashing is not stable over different widths of a \fBmp_digit\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_incr(mp_int *" a ")"
|
|
.in 1i
|
|
Computes \fBa++\fP.
|
|
.br
|
|
Returns \fBMP_MEM\fP if the reallocation of memory in \fBmp_grow\fP failed.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_copy (mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Initializes \fBa\fP and copies \fBb\fP into \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_i32 (mp_int *" a ", int32_t " b ");
|
|
.in 1i
|
|
Initializes \fBa\fP and copies the signed 32 bit integer \fBb\fP into \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_i64 (mp_int *" a ", int64_t " b ")"
|
|
.in 1i
|
|
Initializes \fBa\fP and copies the signed 64 bit integer \fBb\fP into \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_l (mp_int *" a ", long " b ")"
|
|
.in 1i
|
|
Initializes \fBa\fP and copies the signed integer \fBb\fP of type \fBlong\fP into \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init (mp_int *" a ")"
|
|
.in 1i
|
|
Initializes \fBa\fP.
|
|
.br
|
|
It allocates a certain amount of memory such that the \fBmp_set_u64\fP setter can
|
|
store an \fBuint64_t\fP in the \fBmp_int\fP. To be able to take advantage of the algorithm used for
|
|
\fBmp_school_div\fP the \fBmp_int\fP must have at least three limbs.
|
|
.br
|
|
It actively sets all limbs to zero, overwriting what was there before, sets the \fBa.sign\fP to \fBMP_ZPOS\fP,
|
|
and \fBa.used\fP to zero.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_multi(mp_int *" mp ", " ... ")"
|
|
.in 1i
|
|
Initialize a \fBNULL\fP terminated series of \fBmp_int\fPs.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_set (mp_int *" a ", mp_digit " b ")"
|
|
.in 1i
|
|
Initializes \fBa\fP and sets it to the \fBmp_digit\fP \fBb\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_size (mp_int *" a ", int " size ")"
|
|
.in 1i
|
|
Initializes \fBa\fP with pre-grown to a \fBsize\fP number of limbs.
|
|
.br
|
|
If \fBsize\fP is smaller than the minimum (see \fBmp_init\fP for details) \fBsize\fP will be increased to that minimum.
|
|
.br
|
|
Returns \fBMP_OVF\fP if \fBsize\fP is larger than an \fBmp_int\fP is able to hold.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_u32 (mp_int *" a ", uint32_t " b ")"
|
|
.in 1i
|
|
Initializes \fBa\fP and copies the unsigned 32 bit integer \fBb\fP into \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_u64 (mp_int *" a ", uint64_t " b ")"
|
|
.in 1i
|
|
Initializes \fBa\fP and copies the unsigned 64 bit integer \fBb\fP into \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_init_ul (mp_int *" a ", unsigned long " b ")"
|
|
.in 1i
|
|
Initializes \fBa\fP and copies the unsigned integer \fBb\fP of type \fBunsigned long\fP into \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_invmod (const mp_int *" a ", const mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes the multiplicative inverse of \fBa\fP modulo \fBb\fP and stores the result in \fBv\fP such that
|
|
\fBac \[==] 1 (mod b)\fP.
|
|
.br
|
|
Does use a faster algorithm if the modulus \fBb\fP is odd.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBb <= 1\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "bool mp_iseven(const mp_int *" a ")"
|
|
.in 1i
|
|
Returns \fBtrue\fP if \fBa\fP is even, \fBfalse\fP otherwise.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "bool mp_isneg(mp_int *" a ")"
|
|
.in 1i
|
|
Returns \fBtrue\fP if \fBa < 0\fP, \fBfalse\fP otherwise.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "bool mp_isodd(const mp_int *" a ")"
|
|
.in 1i
|
|
Returns \fBtrue\fP if \fBa\fP is odd, \fBfalse\fP otherwise.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_is_square(const mp_int *" arg ", bool *" ret ")"
|
|
.in 1i
|
|
Sets \fBret\fP to \fBtrue\fP if \fBarg\fP is a square, \fBfalse\fP otherwise.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "bool mp_iszero(mp_int *" a ")"
|
|
.in 1i
|
|
Returns \fBtrue\fP if \fBa = 0\fP, \fBfalse\fP otherwise.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "bool mp_isone(mp_int *" a ")"
|
|
.in 1i
|
|
Returns \fBtrue\fP if \fBa = 1\fP, \fBfalse\fP otherwise.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_kronecker (const mp_int *" a ", const mp_int *" p ", int *" c ")"
|
|
.in 1i
|
|
Computes the Kronecker symbol (an extension of the Jacobi symbol) for \fBa\fP with respect to
|
|
\fBp\fP with \fB(a, p) in Z\fP. If \fBp\fP is prime this essentially computes the
|
|
Legendre symbol. The result is stored in \fBc\fP and can take on one of three values \fB{-1, 0, 1}\fP.
|
|
.TS
|
|
tab(;);
|
|
r l.
|
|
-1 ;if \fBa\fP is not a quadratic residue modulo \fBp\fP and \fBp\fP is prime.
|
|
0 ;if \fBa\fP divides \fBp\fP
|
|
1 ;if \fBa\fP is a quadratic residue modulo \fBp\fP.
|
|
.TE
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_lcm (const mp_int *" a ", const mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes the least common multiple as \fB|a * b|/gcd(a, b)\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_log(const mp_int *" a ", const mp_int *" base ", int *" c ")"
|
|
.in 1i
|
|
Computes \fBlog_b(a)\fP such that \fB(log_b a)^b <= a\fP.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBa <= 0\fP or \fBb < 2\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_log_n(const mp_int *" a ", int " base ", int *" c ")"
|
|
.in 1i
|
|
Computes \fBlog_b(a)\fP such that \fB(log_b a)^b <= a\fP.
|
|
.br
|
|
Convenience function that is a wrapper for \fBmp_log\fP doing the conversion of \fBb\fP
|
|
to a big integer.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_lshd (mp_int *" a ", int " b ")"
|
|
.in 1i
|
|
Shift \fBa\fP left by \fBb\fP limbs: \fBa * 2^(b*MP_DIGIT_BIT)\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_mod_2d(const mp_int *" a ", int " b ", mp_int *" c ")"
|
|
.in 1i
|
|
Compute \fBa % 2^b\fP.
|
|
.br
|
|
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_mod(const mp_int *" a ",const mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Compute \fBa \[==] c mod b\fP.
|
|
.br
|
|
\fB0 <= c < b\fP if \fBb > 0\fP and \fBb < c <= 0\fP if \fBb < 0\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_mod_d(const mp_int *" a ", mp_digit " b ", mp_digit *" c ")"
|
|
.in 1i
|
|
Computes the remainder of \fBa / b\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_montgomery_calc_normalization(mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Computes \fBR = r^n\fP for Montgomery reduction where \fBn\fP is size of \fBa\fP in bits and
|
|
\fBr\fP is the radix (\fBMP_DIGIT_MAX + 1\fP).
|
|
.br
|
|
See \fBmp_montgomery_reduce\fP for some example code.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_montgomery_reduce(mp_int *" a ", mp_int *" m ", mp_digit " mp ")"
|
|
.in 1i
|
|
Reduces \fBa\fP in place modulo \fBm\fP with the pre-computed value \fBmp\fP (\fBa*mp^(-1) \[==] x (mod m) \fP).
|
|
Pre-computation of \fBmp\fP can be done with \fBmp_montgomery_setup\fP. Example:
|
|
|
|
.nf
|
|
int main(void)
|
|
{
|
|
mp_int a, b, c, R;
|
|
mp_digit mp;
|
|
mp_err result;
|
|
|
|
/* initialize a,b to desired values,
|
|
* mp_init R, c and set c to 1....
|
|
*/
|
|
|
|
/* get normalization */
|
|
if ((result = mp_montgomery_calc_normalization(&R, b)) != MP_OKAY) {
|
|
printf("Error getting norm. %s",
|
|
mp_error_to_string(result));
|
|
return EXIT_FAILURE;
|
|
}
|
|
/* get mp value */
|
|
if ((result = mp_montgomery_setup(&c, &mp)) != MP_OKAY) {
|
|
printf("Error setting up montgomery. %s",
|
|
mp_error_to_string(result));
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
/* normalize `a' so now a is equal to aR */
|
|
if ((result = mp_mulmod(&a, &R, &b, &a)) != MP_OKAY) {
|
|
printf("Error computing aR. %s",
|
|
mp_error_to_string(result));
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
/* square a to get c = a^2R^2 */
|
|
if ((result = mp_sqr(&a, &c)) != MP_OKAY) {
|
|
printf("Error squaring. %s",
|
|
mp_error_to_string(result));
|
|
return EXIT_FAILURE;
|
|
}
|
|
/* now reduce `c' back down to c = a^2R^2 * R^-1 == a^2R */
|
|
if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) {
|
|
printf("Error reducing. %s",
|
|
mp_error_to_string(result));
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
/* multiply a to get c = a^3R^2 */
|
|
if ((result = mp_mul(&a, &c, &c)) != MP_OKAY) {
|
|
printf("Error reducing. %s",
|
|
mp_error_to_string(result));
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
/* now reduce `c' back down to c = a^3R^2 * R^-1 == a^3R */
|
|
if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) {
|
|
printf("Error reducing. %s",
|
|
mp_error_to_string(result));
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
/* now reduce (again) `c' back down to c = a^3R * R^-1 == a^3 */
|
|
if ((result = mp_montgomery_reduce(&c, &b, mp)) != MP_OKAY) {
|
|
printf("Error reducing. %s",
|
|
mp_error_to_string(result));
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
/* c now equals a^3 mod b */
|
|
|
|
return EXIT_SUCCESS;
|
|
\}
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_montgomery_setup(const mp_int *" a ", mp_digit *" mp ")"
|
|
.in 1i
|
|
For the given odd modulus \fBa\fP the pre-computation value is placed in \fBmp\fP.
|
|
.br
|
|
\fBmp = 1/a mod 2^k\fP with \fBk\fP the number of bits in the underlying native type used for \fBmp_digit\fP.
|
|
.br
|
|
See \fBmp_montgomery_reduce\fP for some example code.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_mul_2(const mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Computes \fBb = 2 * a\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_mul_2d(const mp_int *" a ", int " b ", mp_int *" c ")"
|
|
.in 1i
|
|
Shifts \fBa\fP left by \fBb\fP bits \fBb = a * 2^b\fP.
|
|
.br
|
|
Condition: \fBb >= 0\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_mul (const mp_int *" a ", const mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes \fBc = a * b\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_mul_d(const mp_int *" a ", mp_digit " b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes \fBc = a * b\fP with \fBb\fP and \fBmp_digit\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_mulmod(const mp_int *" a ", const mp_int *" b ", const mp_int *" c ", mp_int *" d ")"
|
|
.in 1i
|
|
Computes \fBd = a * b (mod c)\fP. No optimizations.
|
|
.br
|
|
For special forms of the input libtommath offers other, optimized algorithms. See for example
|
|
\fBmp_montgomery_reduce\fP for some example code with Montgomery reduction. There is also Barret
|
|
reduction, which is more generic (\fBmp_reduce\fP), diminished radix reduction (\fBmp_dr_reduce\fP) and
|
|
unrestricted diminished radix reduction (\fBmp_reduce_2k\fP)
|
|
.br
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_neg (const mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Computes \fBb = -a\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_or (const mp_int *" a ", mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes bit-wise or \fBa | b = c\fP. Negative numbers
|
|
are treated as if they are in two-complement representation.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "size_t mp_pack_count(const mp_int *" a ", size_t " nails ", size_t " size ")"
|
|
.in 1i
|
|
Returns the size in bytes necessary to be put in \fBmp_pack\fP's \fBmaxsize\fP. See \fBmp_pack\fP for details.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_pack(void *" rop ", size_t *" countp ", mp_order " order ", size_t " size ", mp_endian " endian ", size_t " nails ", const mp_int *" op ")"
|
|
.in 1i
|
|
Export binary data.
|
|
.br
|
|
Implements the similarly working GMP functions as described at \fIhttp://gmplib.org/manual/Integer-Import-and-Export.html\fP with
|
|
the exception that \fBmp_pack\fP will not allocate memory if \fBrop\fP is \fBNULL\fP.
|
|
.br
|
|
To make things a bit more comfortable libtommath offers two \fBenum\fPs:
|
|
|
|
.br
|
|
.in 1.5i
|
|
typedef enum {
|
|
MP_LSB_FIRST = -1,
|
|
MP_MSB_FIRST = 1
|
|
} mp_order;
|
|
|
|
.br
|
|
|
|
typedef enum {
|
|
MP_LITTLE_ENDIAN = -1,
|
|
MP_NATIVE_ENDIAN = 0,
|
|
MP_BIG_ENDIAN = 1
|
|
} mp_ndian;
|
|
.in -1.5i
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_prime_fermat(const mp_int *" a ", const mp_int *" b ", bool *" result ")"
|
|
.in 1i
|
|
Performs one Fermat test of \fBa\fP using base \fBb\fP.
|
|
.br
|
|
Sets \fBresult\fP to \fBtrue\fP if \fBa\fP is probably prime, \fBfalse\fP if composite.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_prime_strong_lucas_selfridge(const mp_int *" a ", bool *" result ")"
|
|
.in 1i
|
|
Sets \fBresult\fP to \fBtrue\fP if \fBa\fP is a strong Lucas-Selfridge pseudoprime, \fBfalse\fP otherwise.
|
|
.br
|
|
It has been verified that this function together with one round of Miller-Rabin to the base 2 (two) is
|
|
deterministic up to 2^64.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_prime_frobenius_underwood(const mp_int *" N ", bool *" result ")"
|
|
.in 1i
|
|
Sets \fBresult\fP to \fBtrue\fP if \fBa\fP is a Frobenius-Underwood pseudoprime, \fBfalse\fP otherwise.
|
|
.br
|
|
It has been verified that this function (as a stand-alone) is deterministic up to at least 2^50.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_prime_is_prime(const mp_int *" a ", int " t ", bool *" result ")"
|
|
.in 1i
|
|
Sets \fBresult\fP to \fBtrue\fP if \fBa\fP is a pseudoprime, \fBfalse\fP otherwise.
|
|
.br
|
|
The argument \fBt\fP holds the number of random Miller-Rabin tests to be executed.
|
|
.br
|
|
.nr step 1 1
|
|
Uses a stack of different tests to detect composites:
|
|
.RS
|
|
.IP \n[step] 0.3i
|
|
Direct test: checks if input is one of the values 0, 1, 2.
|
|
.IP \n+[step]
|
|
The only even prime has been handled, reject even input from now on
|
|
.IP \n+[step]
|
|
Check if input is a square. (some of the algorithms used later do not like square input)
|
|
.IP \n+[step]
|
|
Check if input is equal to one of the primes in the table \fBs_mp_prime_tab\fP
|
|
.IP \n+[step]
|
|
Check if input is divisible by one of the primes in the table \fBs_mp_prime_tab\fP
|
|
.IP \n+[step]
|
|
Run a Miller-Rabin test with base 2
|
|
.IP \n+[step]
|
|
Run a Miller-Rabin test with base 3
|
|
.IP \n+[step]
|
|
If \fBt <= 0\fP and the macro \fBLTM_USE_ONLY_MR\fP is not defined we run either a Frobenius-Underwood
|
|
test if the macro \fBLTM_USE_FROBENIUS_TEST\fP is defined or a Lucas-Selfridge test.
|
|
.br
|
|
The Lucas-Selfridge test together with the two Miller-Rabin tests earlier is deterministic up to at least 2^64.
|
|
.br
|
|
The Frobenius-Underwood test as a stand-alone is deterministic up to at least 2^50. But it is different from
|
|
the Lucas-Selfridge test so the additional cost (about two times the time a Lucas-Selfridge test would need) might be worthwhile.
|
|
.IP \n+[step]
|
|
Even if \fBt = 0\fP we run at least one Miler-Rabin test with a random base.
|
|
.IP \n+[step]
|
|
If \fBt < 0\fP and input smaller than 3,317,044,064,679,887,385,961,981 (< 82 bits) several Miller-Rabin tests
|
|
are run with bases according to Sorenson, Jonathan; Webster, Jonathan (2015) "Strong Pseudoprimes to Twelve Prime Bases".
|
|
.br
|
|
Here ends the deterministic part of this function.
|
|
.IP \n+[step]
|
|
If \fBt > 0\fP: run the given number of Miller-Rabin tests with random bases.
|
|
.RE
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_prime_miller_rabin (const mp_int *" a ", const mp_int *" b ", int *" result ")"
|
|
.in 1i
|
|
Run the Miller-Rabin pseudoprime test of \fBa\fP with base \fBb\fP and set \fBresult\fP to \fBtrue\fP
|
|
if \fBa\fP is a strong pseudprime for base \fBb\fP and \fBfalse\fP otherwise.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_prime_next_prime(mp_int *" a ", int " t ", bool " bbs_style ")"
|
|
.in 1i
|
|
Sets \fBa\fP to the next prime, even if \fBa\fP is prime itself.
|
|
.br
|
|
Argument \fBt\fP holds the number of Miller-Rabin tests to random bases and can also be used to steer
|
|
\fBmp_prime_is_prime\fP as described there.
|
|
.br
|
|
Argument \fBbbs_style\fP returns only primes \fBa \[==] 3 (mod 4)\fP if set to \fBtrue\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_prime_rabin_miller_trials(int " size ")"
|
|
.in 1i
|
|
Returns the number of Miller-Rabin tests to random bases necessary for RSA according to
|
|
FIPS 186-4.
|
|
.br
|
|
\fBsize\fP is the size of the prime in bits.
|
|
.br
|
|
The entries are pre-computed:
|
|
.br
|
|
.TS
|
|
tab(;), allbox;
|
|
c c c
|
|
r r l.
|
|
\fB<=size\fP;\fB#tests\fP ;\fBError\fP
|
|
.SP
|
|
80;-1;Use deterministic algorithm for size <= 80 bits
|
|
81;37;2^(-96)
|
|
96;32;2^(-96)
|
|
128;40;2^(-112)
|
|
160;35;2^(-112)
|
|
256;27;2^(-128)
|
|
384;16;2^(-128)
|
|
512;18;2^(-160)
|
|
768;11;2^(-160)
|
|
896;10;2^(-160)
|
|
1024;12;2^(-192)
|
|
1536;8;2^(-192)
|
|
2048;6;2^(-192)
|
|
3072;4;2^(-192)
|
|
4096;5;2^(-256)
|
|
5120;4;2^(-256)
|
|
6144;4;2^(-256)
|
|
8192;3;2^(-256)
|
|
9216;3;2^(-256)
|
|
10240;2;For bigger keysizes use always at least 2 Rounds
|
|
.TE
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_prime_rand(mp_int *" a ", int " t ", int " size ", int " flags ")"
|
|
.in 1i
|
|
Generates a random big prime \fBa\fP with \fBsize\fP bits.
|
|
.br
|
|
Argument \fBt\fP holds the number of Miller-Rabin tests to random bases and can also be used to steer
|
|
\fBmp_prime_is_prime\fP as described there.
|
|
.br
|
|
Argument \fBflags\fP determines the kind of prime:
|
|
.br
|
|
.TS
|
|
tab(;), allbox;
|
|
c c
|
|
l l.
|
|
\fBFlag\fP;\fBCondition\fP
|
|
MP_PRIME_BBS;make prime congruent to 3 mod 4
|
|
MP_PRIME_SAFE;make sure (p-1)/2 is prime as well (implies MP_PRIME_BBS)
|
|
MP_PRIME_2MSB_ON;make the 2nd highest bit one
|
|
.TE
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_radix_size (const mp_int *" a ", int " radix ", int *" size ")"
|
|
.in 1i
|
|
Sets \fBsize\fP to the length of the ASCII string of the representation of big integer \fBa\fP in radix \fBradix\fP.
|
|
This includes the sign and the terminatong \fBNUL\fP.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBradix\fP is not in the range \fB2 <= radix <= 64\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_radix_size_overestimate (const mp_int *" a ", int " radix ", int *" size ")"
|
|
.in 1i
|
|
Same as \fBmp_radix_size\fP but uses a rough, table based approximation instead of calling \fBmp_log_n\fP.
|
|
.br
|
|
Overestimates the result by some units: relative error is about \fB10^(-8)\fP. Experiments showed that
|
|
the absolute error should not go pass \fB5\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_rand(mp_int *" a ", int " digits ")"
|
|
.in 1i
|
|
Generates a random big integer \fBa\fP with a \fBdigits\fP number of limbs.
|
|
.br
|
|
\fBNOTE:\fP This function uses the same (P)RNG as the prime generating/testing functions. If that entropy
|
|
is precious see \fBmp_rand_source\fP to set another (P)RNG.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_rand_source(mp_err(*" source ")(void *" out ", size_t " size "));
|
|
.in 1i
|
|
Sets the (P)RNG used for \fIall\fP functions in Libtommath, that need some random bytes.
|
|
.br
|
|
Set \fBsource\fP to \fBNULL\fP to get the original (Libtommath) source back.
|
|
.br
|
|
Example:
|
|
.br
|
|
.in +.5i
|
|
.nf
|
|
uint32_t prng_state = 0xdeadbeef;
|
|
uint32_t bad_prng(void) {
|
|
prng_state = (1103515245ul * prng_state + 12345ul) % 2147483648ul;
|
|
return prng_state;
|
|
}
|
|
mp_err myprng(void *p, size_t n)
|
|
{
|
|
char *q = (char *)p;
|
|
while (n > 0u) {
|
|
int i;
|
|
uint32_t x = bad_prng();
|
|
for (i = 0; (i < 4) && (n > 0u); ++i, --n) {
|
|
*q++ = (char)(x & 0xFFu);
|
|
x >>= 8;
|
|
}
|
|
}
|
|
return MP_OKAY;
|
|
}
|
|
mp_err some_monte_carlo_function(...)
|
|
{
|
|
/* Use the the bad but fast P(R)NG */
|
|
mp_rand_source(myprng);
|
|
...
|
|
while(big_number--) {
|
|
mp_rand(a_bigint, n_bits);
|
|
...
|
|
}
|
|
/* Reset and use (P)RNG provided by the platform */
|
|
mp_rand_source(NULL);
|
|
...
|
|
}
|
|
.in -.5i
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_read_radix (mp_int *" a ", const char *" str ", int " radix ")"
|
|
.in 1i
|
|
This will read a \fBNUL\fP terminated string in base \fBradix\fP from \fBstr\fP into \fBa\fP.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBradix\fP is not in the range \fB2 <= radix <= 64\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_reduce_2k_l(mp_int *" a ", const mp_int *" n ", const mp_int *" d ")"
|
|
.in 1i
|
|
Reduces \fBa\fP modulo \fBn\fP where \fBn\fP is of the form \fB2^p - d\fP where \fBd\fP
|
|
is a big integer.
|
|
.br
|
|
Belongs to the "unrestricted diminished radix reduction" method.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_reduce_2k(mp_int *" a ", const mp_int *" n ", mp_digit " d ")"
|
|
.in 1i
|
|
Reduces \fBa\fP modulo \fBn\fP where \fBn\fP is of the form \fB2^p - d\fP where \fBd\fP
|
|
is a \fBmp_digit\fP.
|
|
.br
|
|
Belongs to the "unrestricted diminished radix reduction" method.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_reduce_2k_setup(const mp_int *" a ", mp_digit *" d ")"
|
|
.in 1i
|
|
This will compute the required \fBd\fP value in \fB2^p - d\fP for the given moduli \fBa\fP where \fBd\fP
|
|
is a \fBmp_digit\fP.
|
|
.br
|
|
Belongs to the "unrestricted diminished radix reduction" method.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_reduce_2k_setup_l(const mp_int *" a ", mp_int *" d ")"
|
|
.in 1i
|
|
This will compute the required \fBd\fP value in \fB2^p - d\fP for the given moduli \fBa\fP where \fBd\fP
|
|
is a big integer.
|
|
.br
|
|
Belongs to the "unrestricted diminished radix reduction" method.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_reduce(const mp_int *" a ", const mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
This will reduce \fBa\fP in place modulo \fBb\fP with the precomputed \fBmu\fP value in \fBc\fP. \fBa\fPmust be in
|
|
the range \fB0 <= a < b^2\fP.
|
|
.br
|
|
Belongs to the "Barrett reduction" method.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "bool mp_reduce_is_2k(const mp_int *" a ")"
|
|
.in 1i
|
|
Determines if \fBmp_reduce_2k\fP can be used with a \fBmp_digit\fP.
|
|
.br
|
|
Belongs to the "unrestricted diminished radix reduction" method.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "bool mp_reduce_is_2k_l(const mp_int *" a ")"
|
|
.in 1i
|
|
Determines if \fBmp_reduce_2k\fP can be used with a big integer.
|
|
.br
|
|
Belongs to the "unrestricted diminished radix reduction" method.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_reduce_setup(const mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Compute \fBmu\fP for Barrett reduction.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_root_n(const mp_int *" a ", int " b ", mp_int *" c ")"
|
|
.in 1i
|
|
This computes \fBc = a^(1/b)\fP such that \fBc^b <= a\fP and \fB(c+1)^b > a\fP. Will return a positive root
|
|
only for even roots and return a root with the sign of the input for odd roots. For example,
|
|
performing \fB4^(1/2)\fP will return \fB2\fP whereas \fB(-8)^(1/3)\fP will return \fB-2\fP.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBb < 0\fP or \fBb > MP_DIGIT_MAX\fP or when \fBb\fP is even and \fBa < 0\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_rshd (mp_int *" a ", int " b ")"
|
|
.in 1i
|
|
Shift \fBa\fP right by \fBb\fP limbs: \fBa / 2^(b*MP_DIGIT_BIT)\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "size_t mp_sbin_size(const mp_int *" a ")"
|
|
.in 1i
|
|
Returns the number of bytes (octets) required to store the signed copy of the integer \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_set_double(mp_int *" a ", double " b ")"
|
|
.in 1i
|
|
If the platform supports the floating point data type \fBdouble\fP (binary64) this function will
|
|
assign the integer part of \fBb\fP to the big integer \fBa\fP.
|
|
.br
|
|
Returns \fBMP_VAL\fP if \fBb\fP is \fB+/-infinity\fP or \fBNaN\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_set_i32 (mp_int *" a ", int32_t " b ")"
|
|
.in 1i
|
|
Sets big integer \fBa\fP to the value of the signed 32 bit integer \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_set_i64 (mp_int *" a ", int64_t " b ")"
|
|
.in 1i
|
|
Sets big integer \fBa\fP to the value of the signed 64 bit integer \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_set_l (mp_int *" a ", long " b ")"
|
|
.in 1i
|
|
Sets big integer \fBa\fP to the value of the integer \fBb\fP of type \fIsigned long\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_set (mp_int *" a ", mp_digit " b ")"
|
|
.in 1i
|
|
Sets big integer \fBa\fP to the value of the integer \fBb\fP of type \fImp_digit\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_set_u32 (mp_int *" a ", uint32_t " b ")"
|
|
.in 1i
|
|
Sets big integer \fBa\fP to the value of the unsigned 32 bit integer \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_set_u64 (mp_int *" a ", uint64_t " b ")"
|
|
.in 1i
|
|
Sets big integer \fBa\fP to the value of the unsigned 64 bit integer \fBb\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_set_ul (mp_int *" a ", unsigned long " b ")"
|
|
.in 1i
|
|
Sets big integer \fBa\fP to the value of the integer \fBb\fP of type \fIunsigned long\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_shrink (mp_int *" a ")"
|
|
.in 1i
|
|
This will remove excess digits of the \fImp_int\fP \fBa\fP.
|
|
.br
|
|
This method uses \fBrealloc\fP with all its problems, use with caution.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_signed_rsh(const mp_int *" a ", int " b ", mp_int *" c ")"
|
|
.in 1i
|
|
Shifts right \fBa\fP by \fBb\fP bits with sign extension.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_sqr (const mp_int *" a ", mp_int *" b ")"
|
|
.in 1i
|
|
Computes \fBa^2 = b\fP
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_sqrmod(const mp_int *" a ", const mp_int *" b ", const mp_int *" c ")"
|
|
.in 1i
|
|
Computes \fBa^2 % b = c\fP. No optimization.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_sqrt(const mp_int *" arg ", mp_int *" ret ")"
|
|
.in 1i
|
|
Computes \fBa^(1/2) = b\fP such that \fBb^2 <= a\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_sqrtmod_prime(const mp_int *" n ", const mp_int *" p ", mp_int *" r ")"
|
|
.in 1i
|
|
Computes\fBa^(1/2) % p = r\fP with \fBp\fP prime. Uses the Tonelli-Shanks algorithm.
|
|
.br
|
|
Does do some checks for \fBp\fP but no actual primality test.
|
|
.br
|
|
The prime \fBp\fP must be odd.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_sub (const mp_int *" a ", const mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes \fBa - b = c\fP with \fBb\fP a big integer.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_sub_d(const mp_int *" a ", mp_digit " b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes \fBa - b = c\fP with \fBb\fP of type \fImp_digit\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_submod(const mp_int *" a ", const mp_int *" b ", const mp_int *" c ", mp_int *" d ")"
|
|
.in 1i
|
|
Computes \fB(a - b) % c = d\fP. No optimization.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_to_binary(" M ", " S ", " N ")"
|
|
.in 1i
|
|
Macro that calls \fBmp_to_radix\fP with fixed \fBradix = 2\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_to_decimal(" M ", " S ", " N ")"
|
|
.in 1i
|
|
Macro that calls \fBmp_to_radix\fP with fixed \fBradix = 10\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_to_hex(" M ", " S ", " N ")"
|
|
.in 1i
|
|
Macro that calls \fBmp_to_radix\fP with fixed \fBradix = 16\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_to_octal(" M ", " S ", " N ")"
|
|
.in 1i
|
|
Macro that calls \fBmp_to_radix\fP with fixed \fBradix = 8\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_to_radix (const mp_int *" a ", char *" str ", size_t " maxlen ", size_t *" written ", int " radix ")"
|
|
.in 1i
|
|
Stores upto \fBsize - 1\fP chars and always a \fBNULL\fP byte in \fBstr\fP and puts the number of characters written,
|
|
including \fBNUL\fP, in \fBwritten\fP.
|
|
.br
|
|
The caller is responsible to allocate a sufficient amount of memory for the buffer \fBstr\fP. Use \fBmp_radix_size\fP or
|
|
\fBmp_radix_size_overestimate\fP to have that number computed.
|
|
.br
|
|
Returns \fBMP_BUF\fP if \fBmaxlen < 2\fP
|
|
.br
|
|
Return \fBMP_VAL\fP if \fBradix\fP is not in the range \fB2 <= radix <= 64\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_to_sbin(const mp_int *" a ", uint8_t *" b ", size_t " maxsize ", size_t *" len ")"
|
|
.in 1i
|
|
Store a \fBmaxlen\fP amount of the big integer in buffer \fBb\fP and puts the number of bytes written in \fBlen\fP.
|
|
.br
|
|
If \fBa\fP is negative \fBb0] = 1\fP and \fBb[0] = 0\fP otherwise.
|
|
.br
|
|
Returns \fBMP_BUF\fP if \fBmaxlen\fP is too small. Use \fBmp_sbin_size\fP to have that number computed.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_to_ubin(const mp_int *" a ", uint8_t *" buf ", size_t " maxlen ", size_t *" written ")"
|
|
.in 1i
|
|
Store a \fBmaxlen\fP amount of the big integer in buffer \fBb\fP and puts the number of bytes written in \fBlen\fP.
|
|
.br
|
|
Returns \fBMP_BUF\fP if \fBmaxlen\fP is too small. Use \fBmp_sbin_size\fP to have that number computed.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "size_t mp_ubin_size(const mp_int *" a ")"
|
|
.in 1i
|
|
Returns the number of bytes (octets) required to store the unsigned copy of the big integer \fBa\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_unpack(mp_int *" rop ", size_t " count ", mp_order " order ", size_t " size ", mp_endian " endian ", size_t " nails ", const void *" op ")"
|
|
.in 1i
|
|
Implements the similarly working GMP functions as described at \fIhttp://gmplib.org/manual/Integer-Import-and-Export.html\fP.
|
|
See also: \fBmp_pack\fP for more details.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "mp_err mp_xor (const mp_int *" a ", mp_int *" b ", mp_int *" c ")"
|
|
.in 1i
|
|
Computes bit-wise xor \fBa ^ b = c\fP. Negative numbers are treated as if they are in two-complement representation.
|
|
.br
|
|
Returns \fBMP_MEM\fP if the reallocation of memory in \fBmp_grow\fP failed.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI "void mp_zero(mp_int *" a ")"
|
|
.in 1i
|
|
Sets \fBa\fP to zero.
|
|
.in -1i
|
|
|
|
.LP
|
|
.SS "TYPES"
|
|
.\"TODO: sort alphabetically
|
|
.BI mp_digit
|
|
.in 1i
|
|
An unsigned machine integer able to hold \fBMP_DIGIT_BIT + 1\fP bits.
|
|
.br
|
|
This type is defined in \fBtommath.h\fP
|
|
.in -1i
|
|
.LP
|
|
.BI mp_word
|
|
.in 1i
|
|
An unsigned integer able to hold a value of size \fB2 * MP_DIGIT_MAX + 1\fP.
|
|
This type is defined in \fBtommath_private.h\fP
|
|
.in -1i
|
|
.LP
|
|
.BI mp_int
|
|
.in 1i
|
|
The internal structure of Libtommath's big integer type \fBmp_int\fP.
|
|
|
|
.in 1.5i
|
|
.nf
|
|
typedef struct {
|
|
int used, alloc;
|
|
mp_sign sign;
|
|
mp_digit *dp;
|
|
} mp_int;
|
|
.in -1.5i
|
|
.in -1i
|
|
.LP
|
|
.BI mp_sign
|
|
.in 1i
|
|
The sign of Libtommath's big integer type \fBmp_int\fP
|
|
|
|
.in 1.5i
|
|
.nf
|
|
typedef enum {
|
|
MP_ZPOS = 0, /* positive */
|
|
MP_NEG = 1 /* negative */
|
|
} mp_sign;
|
|
.in -1.5i
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI mp_ord
|
|
.in 1i
|
|
Results of comparing with the functions \fBmp_cmp()\fP and \fBmp_cmp_d()\fP.
|
|
|
|
.in 1.5i
|
|
.nf
|
|
typedef enum {
|
|
MP_LT = -1, /* less than */
|
|
MP_EQ = 0, /* equal */
|
|
MP_GT = 1 /* greater than */
|
|
} mp_ord;
|
|
.in -1.5i
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI mp_err
|
|
.in 1i
|
|
The handful of different errors Libtommath can throw.
|
|
|
|
.in 1.5i
|
|
.nf
|
|
typedef enum {
|
|
MP_OKAY = 0, /* no error */
|
|
MP_ERR = -1, /* unknown error */
|
|
MP_MEM = -2, /* out of mem */
|
|
MP_VAL = -3, /* invalid input */
|
|
MP_ITER = -4, /* maximum iterations reached */
|
|
MP_BUF = -5, /* buffer overflow, supplied buffer too small */
|
|
MP_OVF = -6 /* mp_int overflow, too many digits */
|
|
} mp_err;
|
|
.in -1.5i
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI mp_order
|
|
.in 1i
|
|
Bit order. If the most signifcant bit comes first or the least significant one.
|
|
.br
|
|
Not to be mistaken for \fBmp_ord\fP.
|
|
|
|
.in 1.5i
|
|
.nf
|
|
typedef enum {
|
|
MP_LSB_FIRST = -1,
|
|
MP_MSB_FIRST = 1
|
|
} mp_order;
|
|
.in -1.5i
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI mp_endian
|
|
.in 1i
|
|
Byte order. Only big and little endian are supported. \fBMP_NATIVE_ENDIAN\fP refers to the local (detected)
|
|
endianess.
|
|
|
|
.in 1.5i
|
|
.nf
|
|
typedef enum {
|
|
MP_LITTLE_ENDIAN = -1,
|
|
MP_NATIVE_ENDIAN = 0,
|
|
MP_BIG_ENDIAN = 1
|
|
} mp_endian;
|
|
.in -1.5i
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI hval
|
|
.in 1i
|
|
Type holding the hash produced by \fBmp_hash\fP. Either a 32 bit or a 64 bit unsigned type.
|
|
.in -1i
|
|
|
|
.LP
|
|
.SS "MACROS"
|
|
.LP
|
|
.BI MP_DIGIT_BIT
|
|
.in 1i
|
|
The size in bits of a limb.
|
|
.br
|
|
The value depends on the size of the biggest available native integer type.
|
|
.TS
|
|
tab(;) allbox;
|
|
c c c
|
|
c l l.
|
|
\fBarch bits\fP;\fBMP_DIGIT_BIT\fP;\fBMACRO\fP
|
|
16;15;MP_16BIT
|
|
32;28, (31);MP_32BIT, (MP_31BIT) (1)
|
|
64;60, (28);MP_64BIT, (MP_64BIT) (2)
|
|
32/64;28;MP_28BIT (3)
|
|
.TE
|
|
|
|
(1) The size 31 bit reduces some of the optimizations, especially COMBA.
|
|
.br
|
|
(2) Some C-compilers do not offer 16 byte integers. One of them is very famous.
|
|
.br
|
|
(3) Default when all tests to search for something better fail.
|
|
|
|
.br
|
|
\fBNOTE:\fP ISO C 23 introduced \fB_BitInt(n)\fP which would allow 16 byte integers even
|
|
on non 64 bit architectures. Not much support as of the time of this writing (LLVM does, for example).
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI MP_PRIME_BBS
|
|
.in 1i
|
|
Generate a BBS style prime. (See: mp_prime_rand)
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI MP_PRIME_SAFE
|
|
.in 1i
|
|
Generate a safe prime such that (p-1)/2 == prime. (See: mp_prime_rand)
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI MP_PRIME_2MSB_ON
|
|
.in 1i
|
|
Force 2nd most siginficant bit to be 1 (one). when generating primes. (See: mp_prime_rand)
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI MP_DIGIT_MAX
|
|
.in 1i
|
|
Largest value a \fBmp_digit\fP can hold: \fB-1 + 2^MP_DIGIT_BIT\fP.
|
|
.in -1i
|
|
|
|
.LP
|
|
.BI MP_MASK
|
|
.in 1i
|
|
Holds the same value as \fBMP_DIGIT_MAX\fP.
|
|
.br
|
|
\fBNOTE:\fP this macro computes the value, \fBMP_DIGIT_MAX\fP is a copy.
|
|
.in -1i
|
|
|
|
|
|
.LP
|
|
.SS "GLOBAL VARIABLES"
|
|
.\" TODO: change if COMBA gets its heap alternative
|
|
Libtommath uses no global variables, it is threadsafe.
|
|
.br
|
|
But some global variables are there to allow for e.g.: tuning and can hence be abused. But shouldn't.
|
|
|
|
.LP
|
|
.BI "extern int MP_MUL_KARATSUBA_CUTOFF"
|
|
.in 1i
|
|
Sets the cutoff value when Karatsuba multiplication comes in if the macro \fBMP_FIXED_CUTOFFS\fP is not defined.
|
|
.in -1i
|
|
|
|
|
|
.LP
|
|
.BI "extern int MP_SQR_KARATSUBA_CUTOFF"
|
|
.in 1i
|
|
Sets the cutoff value when Karatsuba squaring comes in if the macro \fBMP_FIXED_CUTOFFS\fP is not defined.
|
|
.in -1i
|
|
|
|
|
|
.LP
|
|
.BI "extern int MP_MUL_TOOM_CUTOFF"
|
|
.in 1i
|
|
Sets the cutoff value when Toom-Cook 3-way multiplication comes in if the macro \fBMP_FIXED_CUTOFFS\fP is not defined.
|
|
.in -1i
|
|
|
|
|
|
.LP
|
|
.BI "extern int MP_SQR_TOOM_CUTOFF"
|
|
.in 1i
|
|
Sets the cutoff value when Toom-Cook 3-way squaring comes in if the macro \fBMP_FIXED_CUTOFFS\fP is not defined.
|
|
.in -1i
|
|
|
|
.LP
|
|
.SH "EXAMPLES"
|
|
.\" TODO: does it even make sense to have examples?
|
|
.LP
|
|
.SS "Is \fIn\fP a Perfect Power"
|
|
A function that uses a mix of libtommath's functions.
|
|
|
|
.nf
|
|
static mp_err mp_is_perfect_power(const mp_int *n, bool *result,
|
|
mp_int *rootout, mp_int *exponent)
|
|
{
|
|
mp_int root, power, prime, max;
|
|
int highbit, lowbit, p;
|
|
mp_err err = MP_OKAY;
|
|
|
|
*result = false;
|
|
|
|
/* No negative numbers. For now. */
|
|
if (mp_cmp_d(n, 4) == MP_LT) {
|
|
err = MP_VAL;
|
|
goto LTM_OUT;
|
|
}
|
|
|
|
/* Compute floor(log_2(n)) */
|
|
highbit = mp_count_bits(n) - 1;
|
|
|
|
/* MP_IS_POWER_OF_TWO(n) is a macro in tommath_private.h */
|
|
if (MP_IS_POWER_OF_TWO(n)) {
|
|
*result = true;
|
|
if (exponent != NULL) {
|
|
if ((err = mp_set_l(exponent, (long)highbit)) != MP_OKAY) {
|
|
return err;
|
|
}
|
|
}
|
|
if (rootout != NULL) {
|
|
if ((err = mp_set_l(rootout, 2l)) != MP_OKAY) {
|
|
return err;
|
|
}
|
|
}
|
|
return err;
|
|
}
|
|
/* Initialize the needed variables all at once */
|
|
if ((err = mp_init_multi(&root, &power, &prime, &max, NULL)) != MP_OKAY) {
|
|
return err;
|
|
}
|
|
/* a long is at least as big as an int */
|
|
if( (err = mp_set_l(&max, (long)highbit) ) != MP_OKAY) goto LTM_ERR;
|
|
|
|
/* mp_prime_next_prime() returns the next prime, so start with a preceding value */
|
|
mp_set(&prime, 2u);
|
|
|
|
while (mp_cmp(&prime, &max) != MP_GT) {
|
|
/* Deterministic up to 2^82 but the largest value possible is < INT_MAX */
|
|
if ((err = mp_prime_next_prime(&prime, -1, false)) != MP_OKAY) goto LTM_ERR;
|
|
p = (int)mp_get_l(&prime);
|
|
if ((err = mp_root_n(n, p, &root)) != MP_OKAY) goto LTM_ERR;
|
|
if ((err = mp_expt_n(&root, p, &power)) != MP_OKAY) goto LTM_ERR;
|
|
|
|
if (mp_cmp(n, &power) == MP_EQ) {
|
|
*result = true;
|
|
if (rootout != NULL) {
|
|
mp_exch(&root, rootout);
|
|
}
|
|
if (exponent != NULL) {
|
|
if ((e = mp_set_l(exponent, (long)p)) != MP_OKAY) goto LTM_ERR;
|
|
}
|
|
}
|
|
}
|
|
|
|
LTM_OUT:
|
|
if (rootout != NULL) {
|
|
if ((err = mp_set(rootout, 0u)) != MP_OKAY) goto LTM_ERR;
|
|
}
|
|
if (exponent != NULL) {
|
|
if ((err = mp_set(exponent, 0u)) != MP_OKAY) goto LTM_ERR;
|
|
}
|
|
LTM_ERR:
|
|
mp_clear_multi(&root, &power,&prime, NULL);
|
|
return err;
|
|
}
|
|
.LP
|
|
.SS "Pi by Binary Splitting"
|
|
Compute digits of pi using Manchin's formula from 1706. A classic.
|
|
|
|
.nf
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <errno.h>
|
|
#include <string.h>
|
|
#include <limits.h>
|
|
#include <tommath.h>
|
|
|
|
static int mp_acot_binary_splitting(
|
|
mp_int * q, mp_int * a, mp_int * b, mp_int * P,
|
|
mp_int * Q, mp_int * R, int * idx)
|
|
{
|
|
mp_err err;
|
|
mp_int p1, q1, r1, p2, q2, r2, t1, t2, one;
|
|
if ((err = mp_init_multi(
|
|
&p1, &q1, &r1, &p2, &q2,
|
|
&r2, &t1, &t2, &one, NULL)) != MP_OKAY) {
|
|
return err;
|
|
}
|
|
|
|
err = MP_OKAY;
|
|
mp_set(&one, 1);
|
|
|
|
if ((err = mp_sub(b, a, &t1)) != MP_OKAY) goto LTM_ERR;
|
|
if (mp_cmp(&t1, &one) == MP_EQ) {
|
|
if ((err = mp_mul_2d(a, 1, &t1)) != MP_OKAY) goto LTM_ERR;
|
|
if ((err = mp_add_d(&t1, 3, &t1)) != MP_OKAY) goto LTM_ERR;
|
|
mp_set(P, 1);
|
|
if ( ((*idx) & 1) == 0 ) {
|
|
P->sign = MP_NEG;
|
|
}
|
|
(*idx)++;
|
|
if ((err = mp_mul(&t1, q, Q)) != MP_OKAY) goto LTM_ERR;
|
|
if ((err = mp_copy(&t1, R)) != MP_OKAY) goto LTM_ERR;
|
|
/* Done */
|
|
goto LTM_ERR;
|
|
}
|
|
|
|
if ((err = mp_add(a, b, &t1)) != MP_OKAY) goto LTM_ERR;
|
|
if ((err = mp_div_2d(&t1, 1, &t1, NULL)) != MP_OKAY) goto LTM_ERR;
|
|
|
|
|
|
if ((err = mp_acot_binary_splitting(
|
|
q, a, &t1, &p1, &q1, &r1, idx)) != MP_OKAY) goto LTM_ERR;
|
|
if ((err = mp_acot_binary_splitting(
|
|
q, &t1, b, &p2, &q2, &r2, idx)) != MP_OKAY) goto LTM_ERR;
|
|
|
|
/* P = q2*p1 + r1*p2 */
|
|
if ((err = mp_mul(&q2, &p1, &t1)) != MP_OKAY) goto LTM_ERR;
|
|
if ((err = mp_mul(&r1, &p2, &t2)) != MP_OKAY) goto LTM_ERR;
|
|
if ((err = mp_add(&t1, &t2, P)) != MP_OKAY) goto LTM_ERR;
|
|
/* Q = q1*q2 */
|
|
if ((err = mp_mul(&q1, &q2, Q)) != MP_OKAY) goto LTM_ERR;
|
|
/* R = r1*r2 */
|
|
if ((err = mp_mul(&r1, &r2, R)) != MP_OKAY) goto LTM_ERR;
|
|
|
|
LTM_ERR:
|
|
mp_clear_multi(&p1, &q1, &r1, &p2, &q2, &r2, &t1, &t2, &one, NULL);
|
|
return err;
|
|
}
|
|
|
|
|
|
int main(int argc, char **argv)
|
|
{
|
|
mp_int N, P, Q, R, zero, EPS, t1, t2, t5, t239;
|
|
mp_err err = MP_OKAY;
|
|
int idx = 0;
|
|
long eps, dec;
|
|
|
|
if(argc != 2) {
|
|
fprintf(stderr, "Usage %s bits of precision", argv[0]);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
errno = 0;
|
|
eps = strtol(argv[1],NULL,10);
|
|
if ((errno == ERANGE && (eps == LONG_MAX || eps == LONG_MIN))
|
|
|| (errno != 0 && eps == 0)) {
|
|
fprintf(stderr,"Error reading precision. Reason: %s\n",
|
|
strerror(errno));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if( (err = mp_init_multi(
|
|
&N, &P, &Q, &R, &zero, &EPS, &t1, &t2, &t5, &t239, NULL) ) != MP_OKAY) {
|
|
fprintf(stderr,"Error initializing mp_ints. Reason: %s\n",
|
|
mp_error_to_string(err));
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
/* Machin's 1706 */
|
|
mp_set(&t5, 5u);
|
|
mp_set(&t239, 239u);
|
|
mp_set_l(&EPS, eps);
|
|
|
|
if( (err = mp_sqr(&t5, &t1) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_acot_binary_splitting(
|
|
&t1, &zero, &EPS, &P, &Q, &R, &idx) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_add(&P, &Q, &t1) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_mul_2d(&t1, (int)eps, &t1) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_mul(&Q, &t5, &t2) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_div(&t1, &t2, &t5, NULL) ) != MP_OKAY) goto LTM_ERR;
|
|
|
|
if( (err = mp_sqr(&t239, &t1) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_acot_binary_splitting(
|
|
&t1, &zero, &EPS, &P, &Q, &R, &idx) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_add(&P, &Q, &t1) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_mul_2d(&t1, (int)eps, &t1) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_mul(&Q, &t239, &t2) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_div(&t1, &t2, &t239, NULL) ) != MP_OKAY) goto LTM_ERR;
|
|
|
|
if( (err = mp_mul_2d(&t5, 2, &t5) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_sub(&t5, &t239, &t1) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_mul_2d(&t1, 2, &t1) ) != MP_OKAY) goto LTM_ERR;
|
|
|
|
/* 146/485 ~ 1/log_2(10) for about 7 decimal digits */
|
|
dec = (eps * 146) / 485;
|
|
mp_set(&t2, 10);
|
|
if( (err = mp_expt_n(&t2, (int)dec, &t2) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_mul(&t1,&t2,&t1) ) != MP_OKAY) goto LTM_ERR;
|
|
if( (err = mp_div_2d(&t1, (int)eps, &t1, NULL) ) != MP_OKAY) goto LTM_ERR;
|
|
|
|
if( (err = mp_fwrite(&t1,10,stdout) ) != MP_OKAY) goto LTM_ERR;
|
|
|
|
mp_clear_multi(&N, &P, &Q, &R, &zero, &EPS, &t1, &t2, &t5, &t239, NULL);
|
|
exit(EXIT_SUCCESS);
|
|
LTM_ERR:
|
|
mp_clear_multi(&N, &P, &Q, &R, &zero, &EPS, &t1, &t2, &t5, &t239, NULL);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
|
|
|
|
.LP
|
|
.SH "SEE ALSO"
|
|
|
|
.IR https://github.com/libtom/libtommath
|
|
|
|
.SH BUGS
|
|
|
|
Please report all bugs and other incommodities at
|
|
.IR https://github.com/libtom/libtommath/issues
|
|
|
|
.SH AUTHORS AND LICENSE
|
|
Version 1.2.0
|
|
.LP
|
|
Copyright (C) 2002 Tom St Denis
|
|
|
|
.ad c
|
|
|
|
The LibTom license
|
|
|
|
.ad n
|
|
.LP
|
|
This is free and unencumbered software released into the public domain.
|
|
.LP
|
|
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
distribute this software, either in source code form or as a compiled
|
|
binary, for any purpose, commercial or non-commercial, and by any
|
|
means.
|
|
.LP
|
|
In jurisdictions that recognize copyright laws, the author or authors
|
|
of this software dedicate any and all copyright interest in the
|
|
software to the public domain. We make this dedication for the benefit
|
|
of the public at large and to the detriment of our heirs and
|
|
successors. We intend this dedication to be an overt act of
|
|
relinquishment in perpetuity of all present and future rights to this
|
|
software under copyright law.
|
|
.LP
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
OTHER DEALINGS IN THE SOFTWARE.
|
|
.LP
|
|
For more information, please refer to <http://unlicense.org/>
|
|
|
|
." end of man page
|