Remove unused bigint from runtime

This commit is contained in:
Brian Anderson 2013-01-08 13:53:45 -08:00
parent 2791877009
commit b43e639bf6
5 changed files with 1 additions and 3345 deletions

2
configure vendored
View File

@ -578,7 +578,7 @@ for t in $CFG_TARGET_TRIPLES
do
make_dir rt/$t
for i in \
isaac linenoise bigint sync test arch/i386 arch/x86_64 \
isaac linenoise sync test arch/i386 arch/x86_64 \
libuv libuv/src/ares libuv/src/eio libuv/src/ev
do
make_dir rt/$t/$i

View File

@ -1,294 +0,0 @@
/* 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 © 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 );

View File

@ -1,553 +0,0 @@
/* bigint_ext - external portion of large integer package
**
** Copyright © 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.
*/
#include <sys/types.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <time.h>
#include "bigint.h"
#include "low_primes.h"
bigint bi_0, bi_1, bi_2, bi_10, bi_m1, bi_maxint, bi_minint;
/* Forwards. */
static void print_pos( FILE* f, bigint bi );
bigint
str_to_bi( char* str )
{
int sign;
bigint biR;
sign = 1;
if ( *str == '-' )
{
sign = -1;
++str;
}
for ( biR = bi_0; *str >= '0' && *str <= '9'; ++str )
biR = bi_int_add( bi_int_multiply( biR, 10 ), *str - '0' );
if ( sign == -1 )
biR = bi_negate( biR );
return biR;
}
void
bi_print( FILE* f, bigint bi )
{
if ( bi_is_negative( bi_copy( bi ) ) )
{
putc( '-', f );
bi = bi_negate( bi );
}
print_pos( f, bi );
}
bigint
bi_scan( FILE* f )
{
int sign;
int c;
bigint biR;
sign = 1;
c = getc( f );
if ( c == '-' )
sign = -1;
else
ungetc( c, f );
biR = bi_0;
for (;;)
{
c = getc( f );
if ( c < '0' || c > '9' )
break;
biR = bi_int_add( bi_int_multiply( biR, 10 ), c - '0' );
}
if ( sign == -1 )
biR = bi_negate( biR );
return biR;
}
static void
print_pos( FILE* f, bigint bi )
{
if ( bi_compare( bi_copy( bi ), bi_10 ) >= 0 )
print_pos( f, bi_int_divide( bi_copy( bi ), 10 ) );
putc( bi_int_mod( bi, 10 ) + '0', f );
}
int
bi_int_mod( bigint bi, int m )
{
int r;
if ( m <= 0 )
{
(void) fprintf( stderr, "bi_int_mod: zero or negative modulus\n" );
(void) kill( getpid(), SIGFPE );
}
r = bi_int_rem( bi, m );
if ( r < 0 )
r += m;
return r;
}
bigint
bi_rem( bigint bia, bigint bim )
{
return bi_subtract(
bia, bi_multiply( bi_divide( bi_copy( bia ), bi_copy( bim ) ), bim ) );
}
bigint
bi_mod( bigint bia, bigint bim )
{
bigint biR;
if ( bi_compare( bi_copy( bim ), bi_0 ) <= 0 )
{
(void) fprintf( stderr, "bi_mod: zero or negative modulus\n" );
(void) kill( getpid(), SIGFPE );
}
biR = bi_rem( bia, bi_copy( bim ) );
if ( bi_is_negative( bi_copy( biR ) ) )
biR = bi_add( biR, bim );
else
bi_free( bim );
return biR;
}
bigint
bi_square( bigint bi )
{
bigint biR;
biR = bi_multiply( bi_copy( bi ), bi_copy( bi ) );
bi_free( bi );
return biR;
}
bigint
bi_power( bigint bi, bigint biexp )
{
bigint biR;
if ( bi_is_negative( bi_copy( biexp ) ) )
{
(void) fprintf( stderr, "bi_power: negative exponent\n" );
(void) kill( getpid(), SIGFPE );
}
biR = bi_1;
for (;;)
{
if ( bi_is_odd( bi_copy( biexp ) ) )
biR = bi_multiply( biR, bi_copy( bi ) );
biexp = bi_half( biexp );
if ( bi_compare( bi_copy( biexp ), bi_0 ) <= 0 )
break;
bi = bi_multiply( bi_copy( bi ), bi );
}
bi_free( bi );
bi_free( biexp );
return biR;
}
bigint
bi_factorial( bigint bi )
{
bigint biR;
biR = bi_1;
while ( bi_compare( bi_copy( bi ), bi_1 ) > 0 )
{
biR = bi_multiply( biR, bi_copy( bi ) );
bi = bi_int_subtract( bi, 1 );
}
bi_free( bi );
return biR;
}
int
bi_is_even( bigint bi )
{
return ! bi_is_odd( bi );
}
bigint
bi_mod_power( bigint bi, bigint biexp, bigint bim )
{
int invert;
bigint biR;
invert = 0;
if ( bi_is_negative( bi_copy( biexp ) ) )
{
biexp = bi_negate( biexp );
invert = 1;
}
biR = bi_1;
for (;;)
{
if ( bi_is_odd( bi_copy( biexp ) ) )
biR = bi_mod( bi_multiply( biR, bi_copy( bi ) ), bi_copy( bim ) );
biexp = bi_half( biexp );
if ( bi_compare( bi_copy( biexp ), bi_0 ) <= 0 )
break;
bi = bi_mod( bi_multiply( bi_copy( bi ), bi ), bi_copy( bim ) );
}
bi_free( bi );
bi_free( biexp );
if ( invert )
biR = bi_mod_inverse( biR, bim );
else
bi_free( bim );
return biR;
}
bigint
bi_mod_inverse( bigint bi, bigint bim )
{
bigint gcd, mul0, mul1;
gcd = bi_egcd( bi_copy( bim ), bi, &mul0, &mul1 );
/* Did we get gcd == 1? */
if ( ! bi_is_one( gcd ) )
{
(void) fprintf( stderr, "bi_mod_inverse: not relatively prime\n" );
(void) kill( getpid(), SIGFPE );
}
bi_free( mul0 );
return bi_mod( mul1, bim );
}
/* Euclid's algorithm. */
bigint
bi_gcd( bigint bim, bigint bin )
{
bigint bit;
bim = bi_abs( bim );
bin = bi_abs( bin );
while ( ! bi_is_zero( bi_copy( bin ) ) )
{
bit = bi_mod( bim, bi_copy( bin ) );
bim = bin;
bin = bit;
}
bi_free( bin );
return bim;
}
/* Extended Euclidean algorithm. */
bigint
bi_egcd( bigint bim, bigint bin, bigint* bim_mul, bigint* bin_mul )
{
bigint a0, b0, c0, a1, b1, c1, q, t;
if ( bi_is_negative( bi_copy( bim ) ) )
{
bigint biR;
biR = bi_egcd( bi_negate( bim ), bin, &t, bin_mul );
*bim_mul = bi_negate( t );
return biR;
}
if ( bi_is_negative( bi_copy( bin ) ) )
{
bigint biR;
biR = bi_egcd( bim, bi_negate( bin ), bim_mul, &t );
*bin_mul = bi_negate( t );
return biR;
}
a0 = bi_1; b0 = bi_0; c0 = bim;
a1 = bi_0; b1 = bi_1; c1 = bin;
while ( ! bi_is_zero( bi_copy( c1 ) ) )
{
q = bi_divide( bi_copy( c0 ), bi_copy( c1 ) );
t = a0;
a0 = bi_copy( a1 );
a1 = bi_subtract( t, bi_multiply( bi_copy( q ), a1 ) );
t = b0;
b0 = bi_copy( b1 );
b1 = bi_subtract( t, bi_multiply( bi_copy( q ), b1 ) );
t = c0;
c0 = bi_copy( c1 );
c1 = bi_subtract( t, bi_multiply( bi_copy( q ), c1 ) );
bi_free( q );
}
bi_free( a1 );
bi_free( b1 );
bi_free( c1 );
*bim_mul = a0;
*bin_mul = b0;
return c0;
}
bigint
bi_lcm( bigint bia, bigint bib )
{
bigint biR;
biR = bi_divide(
bi_multiply( bi_copy( bia ), bi_copy( bib ) ),
bi_gcd( bi_copy( bia ), bi_copy( bib ) ) );
bi_free( bia );
bi_free( bib );
return biR;
}
/* The Jacobi symbol. */
bigint
bi_jacobi( bigint bia, bigint bib )
{
bigint biR;
if ( bi_is_even( bi_copy( bib ) ) )
{
(void) fprintf( stderr, "bi_jacobi: don't know how to compute Jacobi(n, even)\n" );
(void) kill( getpid(), SIGFPE );
}
if ( bi_compare( bi_copy( bia ), bi_copy( bib ) ) >= 0 )
return bi_jacobi( bi_mod( bia, bi_copy( bib ) ), bib );
if ( bi_is_zero( bi_copy( bia ) ) || bi_is_one( bi_copy( bia ) ) )
{
bi_free( bib );
return bia;
}
if ( bi_compare( bi_copy( bia ), bi_2 ) == 0 )
{
bi_free( bia );
switch ( bi_int_mod( bib, 8 ) )
{
case 1: case 7:
return bi_1;
case 3: case 5:
return bi_m1;
}
}
if ( bi_is_even( bi_copy( bia ) ) )
{
biR = bi_multiply(
bi_jacobi( bi_2, bi_copy( bib ) ),
bi_jacobi( bi_half( bia ), bi_copy( bib ) ) );
bi_free( bib );
return biR;
}
if ( bi_int_mod( bi_copy( bia ), 4 ) == 3 &&
bi_int_mod( bi_copy( bib ), 4 ) == 3 )
return bi_negate( bi_jacobi( bib, bia ) );
else
return bi_jacobi( bib, bia );
}
/* Probabalistic prime checking. */
int
bi_is_probable_prime( bigint bi, int certainty )
{
int i, p;
bigint bim1;
/* First do trial division by a list of small primes. This eliminates
** many candidates.
*/
for ( i = 0; i < sizeof(low_primes)/sizeof(*low_primes); ++i )
{
p = low_primes[i];
switch ( bi_compare( int_to_bi( p ), bi_copy( bi ) ) )
{
case 0:
bi_free( bi );
return 1;
case 1:
bi_free( bi );
return 0;
}
if ( bi_int_mod( bi_copy( bi ), p ) == 0 )
{
bi_free( bi );
return 0;
}
}
/* Now do the probabilistic tests. */
bim1 = bi_int_subtract( bi_copy( bi ), 1 );
for ( i = 0; i < certainty; ++i )
{
bigint a, j, jac;
/* Pick random test number. */
a = bi_random( bi_copy( bi ) );
/* Decide whether to run the Fermat test or the Solovay-Strassen
** test. The Fermat test is fast but lets some composite numbers
** through. Solovay-Strassen runs slower but is more certain.
** So the compromise here is we run the Fermat test a couple of
** times to quickly reject most composite numbers, and then do
** the rest of the iterations with Solovay-Strassen so nothing
** slips through.
*/
if ( i < 2 && certainty >= 5 )
{
/* Fermat test. Note that this is not state of the art. There's a
** class of numbers called Carmichael numbers which are composite
** but look prime to this test - it lets them slip through no
** matter how many reps you run. However, it's nice and fast so
** we run it anyway to help quickly reject most of the composites.
*/
if ( ! bi_is_one( bi_mod_power( bi_copy( a ), bi_copy( bim1 ), bi_copy( bi ) ) ) )
{
bi_free( bi );
bi_free( bim1 );
bi_free( a );
return 0;
}
}
else
{
/* GCD test. This rarely hits, but we need it for Solovay-Strassen. */
if ( ! bi_is_one( bi_gcd( bi_copy( bi ), bi_copy( a ) ) ) )
{
bi_free( bi );
bi_free( bim1 );
bi_free( a );
return 0;
}
/* Solovay-Strassen test. First compute pseudo Jacobi. */
j = bi_mod_power(
bi_copy( a ), bi_half( bi_copy( bim1 ) ), bi_copy( bi ) );
if ( bi_compare( bi_copy( j ), bi_copy( bim1 ) ) == 0 )
{
bi_free( j );
j = bi_m1;
}
/* Now compute real Jacobi. */
jac = bi_jacobi( bi_copy( a ), bi_copy( bi ) );
/* If they're not equal, the number is definitely composite. */
if ( bi_compare( j, jac ) != 0 )
{
bi_free( bi );
bi_free( bim1 );
bi_free( a );
return 0;
}
}
bi_free( a );
}
bi_free( bim1 );
bi_free( bi );
return 1;
}
bigint
bi_generate_prime( int bits, int certainty )
{
bigint bimo2, bip;
int i, inc = 0;
bimo2 = bi_power( bi_2, int_to_bi( bits - 1 ) );
for (;;)
{
bip = bi_add( bi_random( bi_copy( bimo2 ) ), bi_copy( bimo2 ) );
/* By shoving the candidate numbers up to the next highest multiple
** of six plus or minus one, we pre-eliminate all multiples of
** two and/or three.
*/
switch ( bi_int_mod( bi_copy( bip ), 6 ) )
{
case 0: inc = 4; bip = bi_int_add( bip, 1 ); break;
case 1: inc = 4; break;
case 2: inc = 2; bip = bi_int_add( bip, 3 ); break;
case 3: inc = 2; bip = bi_int_add( bip, 2 ); break;
case 4: inc = 2; bip = bi_int_add( bip, 1 ); break;
case 5: inc = 2; break;
}
/* Starting from the generated random number, check a bunch of
** numbers in sequence. This is just to avoid calls to bi_random(),
** which is more expensive than a simple add.
*/
for ( i = 0; i < 1000; ++i ) /* arbitrary */
{
if ( bi_is_probable_prime( bi_copy( bip ), certainty ) )
{
bi_free( bimo2 );
return bip;
}
bip = bi_int_add( bip, inc );
inc = 6 - inc;
}
/* We ran through the whole sequence and didn't find a prime.
** Shrug, just try a different random starting point.
*/
bi_free( bip );
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff