294 lines
10 KiB
C
294 lines
10 KiB
C
/* bigint.h - include file for bigint package
|
||
**
|
||
** This library lets you do math on arbitrarily large integers. It's
|
||
** pretty fast - compared with the multi-precision routines in the "bc"
|
||
** calculator program, these routines are between two and twelve times faster,
|
||
** except for division which is maybe half as fast.
|
||
**
|
||
** The calling convention is a little unusual. There's a basic problem
|
||
** with writing a math library in a language that doesn't do automatic
|
||
** garbage collection - what do you do about intermediate results?
|
||
** You'd like to be able to write code like this:
|
||
**
|
||
** d = bi_sqrt( bi_add( bi_multiply( x, x ), bi_multiply( y, y ) ) );
|
||
**
|
||
** That works fine when the numbers being passed back and forth are
|
||
** actual values - ints, floats, or even fixed-size structs. However,
|
||
** when the numbers can be any size, as in this package, then you have
|
||
** to pass them around as pointers to dynamically-allocated objects.
|
||
** Those objects have to get de-allocated after you are done with them.
|
||
** But how do you de-allocate the intermediate results in a complicated
|
||
** multiple-call expression like the above?
|
||
**
|
||
** There are two common solutions to this problem. One, switch all your
|
||
** code to a language that provides automatic garbage collection, for
|
||
** example Java. This is a fine idea and I recommend you do it wherever
|
||
** it's feasible. Two, change your routines to use a calling convention
|
||
** that prevents people from writing multiple-call expressions like that.
|
||
** The resulting code will be somewhat clumsy-looking, but it will work
|
||
** just fine.
|
||
**
|
||
** This package uses a third method, which I haven't seen used anywhere
|
||
** before. It's simple: each number can be used precisely once, after
|
||
** which it is automatically de-allocated. This handles the anonymous
|
||
** intermediate values perfectly. Named values still need to be copied
|
||
** and freed explicitly. Here's the above example using this convention:
|
||
**
|
||
** d = bi_sqrt( bi_add(
|
||
** bi_multiply( bi_copy( x ), bi_copy( x ) ),
|
||
** bi_multiply( bi_copy( y ), bi_copy( y ) ) ) );
|
||
** bi_free( x );
|
||
** bi_free( y );
|
||
**
|
||
** Or, since the package contains a square routine, you could just write:
|
||
**
|
||
** d = bi_sqrt( bi_add( bi_square( x ), bi_square( y ) ) );
|
||
**
|
||
** This time the named values are only being used once, so you don't
|
||
** have to copy and free them.
|
||
**
|
||
** This really works, however you do have to be very careful when writing
|
||
** your code. If you leave out a bi_copy() and use a value more than once,
|
||
** you'll get a runtime error about "zero refs" and a SIGFPE. Run your
|
||
** code in a debugger, get a backtrace to see where the call was, and then
|
||
** eyeball the code there to see where you need to add the bi_copy().
|
||
**
|
||
**
|
||
** Copyright <20> 2000 by Jef Poskanzer <jef@mail.acme.com>.
|
||
** All rights reserved.
|
||
**
|
||
** Redistribution and use in source and binary forms, with or without
|
||
** modification, are permitted provided that the following conditions
|
||
** are met:
|
||
** 1. Redistributions of source code must retain the above copyright
|
||
** notice, this list of conditions and the following disclaimer.
|
||
** 2. Redistributions in binary form must reproduce the above copyright
|
||
** notice, this list of conditions and the following disclaimer in the
|
||
** documentation and/or other materials provided with the distribution.
|
||
**
|
||
** THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||
** ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||
** IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||
** ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||
** FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||
** DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||
** OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||
** HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||
** LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||
** OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||
** SUCH DAMAGE.
|
||
*/
|
||
|
||
|
||
/* Type definition for bigints - it's an opaque type, the real definition
|
||
** is in bigint.c.
|
||
*/
|
||
typedef void* bigint;
|
||
|
||
|
||
/* Some convenient pre-initialized numbers. These are all permanent,
|
||
** so you can use them as many times as you want without calling bi_copy().
|
||
*/
|
||
extern bigint bi_0, bi_1, bi_2, bi_10, bi_m1, bi_maxint, bi_minint;
|
||
|
||
|
||
/* Initialize the bigint package. You must call this when your program
|
||
** starts up.
|
||
*/
|
||
void bi_initialize( void );
|
||
|
||
/* Shut down the bigint package. You should call this when your program
|
||
** exits. It's not actually required, but it does do some consistency
|
||
** checks which help keep your program bug-free, so you really ought
|
||
** to call it.
|
||
*/
|
||
void bi_terminate( void );
|
||
|
||
/* Run in unsafe mode, skipping most runtime checks. Slightly faster.
|
||
** Once your code is debugged you can add this call after bi_initialize().
|
||
*/
|
||
void bi_no_check( void );
|
||
|
||
/* Make a copy of a bigint. You must call this if you want to use a
|
||
** bigint more than once. (Or you can make the bigint permanent.)
|
||
** Note that this routine is very cheap - all it actually does is
|
||
** increment a reference counter.
|
||
*/
|
||
bigint bi_copy( bigint bi );
|
||
|
||
/* Make a bigint permanent, so it doesn't get automatically freed when
|
||
** used as an operand.
|
||
*/
|
||
void bi_permanent( bigint bi );
|
||
|
||
/* Undo bi_permanent(). The next use will free the bigint. */
|
||
void bi_depermanent( bigint bi );
|
||
|
||
/* Explicitly free a bigint. Normally bigints get freed automatically
|
||
** when they are used as an operand. This routine lets you free one
|
||
** without using it. If the bigint is permanent, this doesn't do
|
||
** anything, you have to depermanent it first.
|
||
*/
|
||
void bi_free( bigint bi );
|
||
|
||
/* Compare two bigints. Returns -1, 0, or 1. */
|
||
int bi_compare( bigint bia, bigint bib );
|
||
|
||
/* Convert an int to a bigint. */
|
||
bigint int_to_bi( int i );
|
||
|
||
/* Convert a string to a bigint. */
|
||
bigint str_to_bi( char* str );
|
||
|
||
/* Convert a bigint to an int. SIGFPE on overflow. */
|
||
int bi_to_int( bigint bi );
|
||
|
||
/* Write a bigint to a file. */
|
||
void bi_print( FILE* f, bigint bi );
|
||
|
||
/* Read a bigint from a file. */
|
||
bigint bi_scan( FILE* f );
|
||
|
||
|
||
/* Operations on a bigint and a regular int. */
|
||
|
||
/* Add an int to a bigint. */
|
||
bigint bi_int_add( bigint bi, int i );
|
||
|
||
/* Subtract an int from a bigint. */
|
||
bigint bi_int_subtract( bigint bi, int i );
|
||
|
||
/* Multiply a bigint by an int. */
|
||
bigint bi_int_multiply( bigint bi, int i );
|
||
|
||
/* Divide a bigint by an int. SIGFPE on divide-by-zero. */
|
||
bigint bi_int_divide( bigint binumer, int denom );
|
||
|
||
/* Take the remainder of a bigint by an int, with an int result.
|
||
** SIGFPE if m is zero.
|
||
*/
|
||
int bi_int_rem( bigint bi, int m );
|
||
|
||
/* Take the modulus of a bigint by an int, with an int result.
|
||
** Note that mod is not rem: mod is always within [0..m), while
|
||
** rem can be negative. SIGFPE if m is zero or negative.
|
||
*/
|
||
int bi_int_mod( bigint bi, int m );
|
||
|
||
|
||
/* Basic operations on two bigints. */
|
||
|
||
/* Add two bigints. */
|
||
bigint bi_add( bigint bia, bigint bib );
|
||
|
||
/* Subtract bib from bia. */
|
||
bigint bi_subtract( bigint bia, bigint bib );
|
||
|
||
/* Multiply two bigints. */
|
||
bigint bi_multiply( bigint bia, bigint bib );
|
||
|
||
/* Divide one bigint by another. SIGFPE on divide-by-zero. */
|
||
bigint bi_divide( bigint binumer, bigint bidenom );
|
||
|
||
/* Binary division of one bigint by another. SIGFPE on divide-by-zero.
|
||
** This is here just for testing. It's about five times slower than
|
||
** regular division.
|
||
*/
|
||
bigint bi_binary_divide( bigint binumer, bigint bidenom );
|
||
|
||
/* Take the remainder of one bigint by another. SIGFPE if bim is zero. */
|
||
bigint bi_rem( bigint bia, bigint bim );
|
||
|
||
/* Take the modulus of one bigint by another. Note that mod is not rem:
|
||
** mod is always within [0..bim), while rem can be negative. SIGFPE if
|
||
** bim is zero or negative.
|
||
*/
|
||
bigint bi_mod( bigint bia, bigint bim );
|
||
|
||
|
||
/* Some less common operations. */
|
||
|
||
/* Negate a bigint. */
|
||
bigint bi_negate( bigint bi );
|
||
|
||
/* Absolute value of a bigint. */
|
||
bigint bi_abs( bigint bi );
|
||
|
||
/* Divide a bigint in half. */
|
||
bigint bi_half( bigint bi );
|
||
|
||
/* Multiply a bigint by two. */
|
||
bigint bi_double( bigint bi );
|
||
|
||
/* Square a bigint. */
|
||
bigint bi_square( bigint bi );
|
||
|
||
/* Raise bi to the power of biexp. SIGFPE if biexp is negative. */
|
||
bigint bi_power( bigint bi, bigint biexp );
|
||
|
||
/* Integer square root. */
|
||
bigint bi_sqrt( bigint bi );
|
||
|
||
/* Factorial. */
|
||
bigint bi_factorial( bigint bi );
|
||
|
||
|
||
/* Some predicates. */
|
||
|
||
/* 1 if the bigint is odd, 0 if it's even. */
|
||
int bi_is_odd( bigint bi );
|
||
|
||
/* 1 if the bigint is even, 0 if it's odd. */
|
||
int bi_is_even( bigint bi );
|
||
|
||
/* 1 if the bigint equals zero, 0 if it's nonzero. */
|
||
int bi_is_zero( bigint bi );
|
||
|
||
/* 1 if the bigint equals one, 0 otherwise. */
|
||
int bi_is_one( bigint bi );
|
||
|
||
/* 1 if the bigint is less than zero, 0 if it's zero or greater. */
|
||
int bi_is_negative( bigint bi );
|
||
|
||
|
||
/* Now we get into the esoteric number-theory stuff used for cryptography. */
|
||
|
||
/* Modular exponentiation. Much faster than bi_mod(bi_power(bi,biexp),bim).
|
||
** Also, biexp can be negative.
|
||
*/
|
||
bigint bi_mod_power( bigint bi, bigint biexp, bigint bim );
|
||
|
||
/* Modular inverse. mod( bi * modinv(bi), bim ) == 1. SIGFPE if bi is not
|
||
** relatively prime to bim.
|
||
*/
|
||
bigint bi_mod_inverse( bigint bi, bigint bim );
|
||
|
||
/* Produce a random number in the half-open interval [0..bi). You need
|
||
** to have called srandom() before using this.
|
||
*/
|
||
bigint bi_random( bigint bi );
|
||
|
||
/* Greatest common divisor of two bigints. Euclid's algorithm. */
|
||
bigint bi_gcd( bigint bim, bigint bin );
|
||
|
||
/* Greatest common divisor of two bigints, plus the corresponding multipliers.
|
||
** Extended Euclid's algorithm.
|
||
*/
|
||
bigint bi_egcd( bigint bim, bigint bin, bigint* bim_mul, bigint* bin_mul );
|
||
|
||
/* Least common multiple of two bigints. */
|
||
bigint bi_lcm( bigint bia, bigint bib );
|
||
|
||
/* The Jacobi symbol. SIGFPE if bib is even. */
|
||
bigint bi_jacobi( bigint bia, bigint bib );
|
||
|
||
/* Probabalistic prime checking. A non-zero return means the probability
|
||
** that bi is prime is at least 1 - 1/2 ^ certainty.
|
||
*/
|
||
int bi_is_probable_prime( bigint bi, int certainty );
|
||
|
||
/* Random probabilistic prime with the specified number of bits. */
|
||
bigint bi_generate_prime( int bits, int certainty );
|
||
|
||
/* Number of bits in the number. The log base 2, approximately. */
|
||
int bi_bits( bigint bi );
|