382 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			382 lines
		
	
	
		
			15 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
The Big Number library.
 | 
						|
 | 
						|
#include "bn.h" when using this library.
 | 
						|
 | 
						|
This big number library was written for use in implementing the RSA and DH
 | 
						|
public key encryption algorithms.  As such, features such as negative
 | 
						|
numbers have not been extensively tested but they should work as expected.
 | 
						|
This library uses dynamic memory allocation for storing its data structures
 | 
						|
and so there are no limit on the size of the numbers manipulated by these
 | 
						|
routines but there is always the requirement to check return codes from
 | 
						|
functions just in case a memory allocation error has occurred.
 | 
						|
 | 
						|
The basic object in this library is a BIGNUM.  It is used to hold a single
 | 
						|
large integer.  This type should be considered opaque and fields should not
 | 
						|
be modified or accessed directly.
 | 
						|
typedef struct bignum_st
 | 
						|
	{
 | 
						|
	int top;	/* Index of last used d. */
 | 
						|
	BN_ULONG *d;	/* Pointer to an array of 'BITS2' bit chunks. */
 | 
						|
	int max;	/* Size of the d array. */
 | 
						|
	int neg;
 | 
						|
	} BIGNUM;
 | 
						|
The big number is stored in a malloced array of BN_ULONG's.  A BN_ULONG can
 | 
						|
be either 16, 32 or 64 bits in size, depending on the 'number of  bits'
 | 
						|
specified in bn.h. 
 | 
						|
The 'd' field is this array.  'max' is the size of the 'd' array that has
 | 
						|
been allocated.  'top' is the 'last' entry being used, so for a value of 4,
 | 
						|
bn.d[0]=4 and bn.top=1.  'neg' is 1 if the number is negative.
 | 
						|
When a BIGNUM is '0', the 'd' field can be NULL and top == 0.
 | 
						|
 | 
						|
Various routines in this library require the use of 'temporary' BIGNUM
 | 
						|
variables during their execution.  Due to the use of dynamic memory
 | 
						|
allocation to create BIGNUMs being rather expensive when used in
 | 
						|
conjunction with repeated subroutine calls, the BN_CTX structure is
 | 
						|
used.  This structure contains BN_CTX BIGNUMs.  BN_CTX
 | 
						|
is the maximum number of temporary BIGNUMs any publicly exported 
 | 
						|
function will use.
 | 
						|
 | 
						|
#define BN_CTX	12
 | 
						|
typedef struct bignum_ctx
 | 
						|
	{
 | 
						|
	int tos;			/* top of stack */
 | 
						|
	BIGNUM *bn[BN_CTX];	/* The variables */
 | 
						|
	} BN_CTX;
 | 
						|
 | 
						|
The functions that follow have been grouped according to function.  Most
 | 
						|
arithmetic functions return a result in the first argument, sometimes this
 | 
						|
first argument can also be an input parameter, sometimes it cannot.  These
 | 
						|
restrictions are documented.
 | 
						|
 | 
						|
extern BIGNUM *BN_value_one;
 | 
						|
There is one variable defined by this library, a BIGNUM which contains the
 | 
						|
number 1.  This variable is useful for use in comparisons and assignment.
 | 
						|
 | 
						|
Get Size functions.
 | 
						|
 | 
						|
int BN_num_bits(BIGNUM *a);
 | 
						|
	This function returns the size of 'a' in bits.
 | 
						|
	
 | 
						|
int BN_num_bytes(BIGNUM *a);
 | 
						|
	This function (macro) returns the size of 'a' in bytes.
 | 
						|
	For conversion of BIGNUMs to byte streams, this is the number of
 | 
						|
	bytes the output string will occupy.  If the output byte
 | 
						|
	format specifies that the 'top' bit indicates if the number is
 | 
						|
	signed, so an extra '0' byte is required if the top bit on a
 | 
						|
	positive number is being written, it is upto the application to
 | 
						|
	make this adjustment.  Like I said at the start, I don't
 | 
						|
	really support negative numbers :-).
 | 
						|
 | 
						|
Creation/Destruction routines.
 | 
						|
 | 
						|
BIGNUM *BN_new();
 | 
						|
	Return a new BIGNUM object.  The number initially has a value of 0.  If
 | 
						|
	there is an error, NULL is returned.
 | 
						|
	
 | 
						|
void	BN_free(BIGNUM *a);
 | 
						|
	Free()s a BIGNUM.
 | 
						|
	
 | 
						|
void	BN_clear(BIGNUM *a);
 | 
						|
	Sets 'a' to a value of 0 and also zeros all unused allocated
 | 
						|
	memory.  This function is used to clear a variable of 'sensitive'
 | 
						|
	data that was held in it.
 | 
						|
	
 | 
						|
void	BN_clear_free(BIGNUM *a);
 | 
						|
	This function zeros the memory used by 'a' and then free()'s it.
 | 
						|
	This function should be used to BN_free() BIGNUMS that have held
 | 
						|
	sensitive numeric values like RSA private key values.  Both this
 | 
						|
	function and BN_clear tend to only be used by RSA and DH routines.
 | 
						|
 | 
						|
BN_CTX *BN_CTX_new(void);
 | 
						|
	Returns a new BN_CTX.  NULL on error.
 | 
						|
	
 | 
						|
void	BN_CTX_free(BN_CTX *c);
 | 
						|
	Free a BN_CTX structure.  The BIGNUMs in 'c' are BN_clear_free()ed.
 | 
						|
	
 | 
						|
BIGNUM *bn_expand(BIGNUM *b, int bits);
 | 
						|
	This is an internal function that should not normally be used.  It
 | 
						|
	ensures that 'b' has enough room for a 'bits' bit number.  It is
 | 
						|
	mostly used by the various BIGNUM routines.  If there is an error,
 | 
						|
	NULL is returned. if not, 'b' is returned.
 | 
						|
	
 | 
						|
BIGNUM *BN_copy(BIGNUM *to, BIGNUM *from);
 | 
						|
	The 'from' is copied into 'to'.  NULL is returned if there is an
 | 
						|
	error, otherwise 'to' is returned.
 | 
						|
 | 
						|
BIGNUM *BN_dup(BIGNUM *a);
 | 
						|
	A new BIGNUM is created and returned containing the value of 'a'.
 | 
						|
	NULL is returned on error.
 | 
						|
 | 
						|
Comparison and Test Functions.
 | 
						|
 | 
						|
int BN_is_zero(BIGNUM *a)
 | 
						|
	Return 1 if 'a' is zero, else 0.
 | 
						|
 | 
						|
int BN_is_one(a)
 | 
						|
	Return 1 is 'a' is one, else 0.
 | 
						|
 | 
						|
int BN_is_word(a,w)
 | 
						|
	Return 1 if 'a' == w, else 0.  'w' is a BN_ULONG.
 | 
						|
 | 
						|
int BN_cmp(BIGNUM *a, BIGNUM *b);
 | 
						|
	Return -1 if 'a' is less than 'b', 0 if 'a' and 'b' are the same
 | 
						|
	and 1 is 'a' is greater than 'b'.  This is a signed comparison.
 | 
						|
	
 | 
						|
int BN_ucmp(BIGNUM *a, BIGNUM *b);
 | 
						|
	This function is the same as BN_cmp except that the comparison
 | 
						|
	ignores the sign of the numbers.
 | 
						|
	
 | 
						|
Arithmetic Functions
 | 
						|
For all of these functions, 0 is returned if there is an error and 1 is
 | 
						|
returned for success.  The return value should always be checked.  eg.
 | 
						|
if (!BN_add(r,a,b)) goto err;
 | 
						|
Unless explicitly mentioned, the 'return' value can be one of the
 | 
						|
'parameters' to the function.
 | 
						|
 | 
						|
int BN_add(BIGNUM *r, BIGNUM *a, BIGNUM *b);
 | 
						|
	Add 'a' and 'b' and return the result in 'r'.  This is r=a+b.
 | 
						|
	
 | 
						|
int BN_sub(BIGNUM *r, BIGNUM *a, BIGNUM *b);
 | 
						|
	Subtract 'a' from 'b' and put the result in 'r'. This is r=a-b.
 | 
						|
	
 | 
						|
int BN_lshift(BIGNUM *r, BIGNUM *a, int n);
 | 
						|
	Shift 'a' left by 'n' bits.  This is r=a*(2^n).
 | 
						|
	
 | 
						|
int BN_lshift1(BIGNUM *r, BIGNUM *a);
 | 
						|
	Shift 'a' left by 1 bit.  This form is more efficient than
 | 
						|
	BN_lshift(r,a,1).  This is r=a*2.
 | 
						|
	
 | 
						|
int BN_rshift(BIGNUM *r, BIGNUM *a, int n);
 | 
						|
	Shift 'a' right by 'n' bits.  This is r=int(a/(2^n)).
 | 
						|
	
 | 
						|
int BN_rshift1(BIGNUM *r, BIGNUM *a);
 | 
						|
	Shift 'a' right by 1 bit.  This form is more efficient than
 | 
						|
	BN_rshift(r,a,1).  This is r=int(a/2).
 | 
						|
	
 | 
						|
int BN_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b);
 | 
						|
	Multiply a by b and return the result in 'r'. 'r' must not be
 | 
						|
	either 'a' or 'b'.  It has to be a different BIGNUM.
 | 
						|
	This is r=a*b.
 | 
						|
 | 
						|
int BN_sqr(BIGNUM *r, BIGNUM *a, BN_CTX *ctx);
 | 
						|
	Multiply a by a and return the result in 'r'. 'r' must not be
 | 
						|
	'a'.  This function is alot faster than BN_mul(r,a,a).  This is r=a*a.
 | 
						|
 | 
						|
int BN_div(BIGNUM *dv, BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx);
 | 
						|
	Divide 'm' by 'd' and return the result in 'dv' and the remainder
 | 
						|
	in 'rem'.  Either of 'dv' or 'rem' can be NULL in which case that
 | 
						|
	value is not returned.  'ctx' needs to be passed as a source of
 | 
						|
	temporary BIGNUM variables.
 | 
						|
	This is dv=int(m/d), rem=m%d.
 | 
						|
	
 | 
						|
int BN_mod(BIGNUM *rem, BIGNUM *m, BIGNUM *d, BN_CTX *ctx);
 | 
						|
	Find the remainder of 'm' divided by 'd' and return it in 'rem'.
 | 
						|
	'ctx' holds the temporary BIGNUMs required by this function.
 | 
						|
	This function is more efficient than BN_div(NULL,rem,m,d,ctx);
 | 
						|
	This is rem=m%d.
 | 
						|
 | 
						|
int BN_mod_mul(BIGNUM *r, BIGNUM *a, BIGNUM *b, BIGNUM *m,BN_CTX *ctx);
 | 
						|
	Multiply 'a' by 'b' and return the remainder when divided by 'm'.
 | 
						|
	'ctx' holds the temporary BIGNUMs required by this function.
 | 
						|
	This is r=(a*b)%m.
 | 
						|
 | 
						|
int BN_mod_exp(BIGNUM *r, BIGNUM *a, BIGNUM *p, BIGNUM *m,BN_CTX *ctx);
 | 
						|
	Raise 'a' to the 'p' power and return the remainder when divided by
 | 
						|
	'm'.  'ctx' holds the temporary BIGNUMs required by this function.
 | 
						|
	This is r=(a^p)%m.
 | 
						|
 | 
						|
int BN_reciprocal(BIGNUM *r, BIGNUM *m, BN_CTX *ctx);
 | 
						|
	Return the reciprocal of 'm'.  'ctx' holds the temporary variables
 | 
						|
	required.  This function returns -1 on error, otherwise it returns
 | 
						|
	the number of bits 'r' is shifted left to make 'r' into an integer.
 | 
						|
	This number of bits shifted is required in BN_mod_mul_reciprocal().
 | 
						|
	This is r=(1/m)<<(BN_num_bits(m)+1).
 | 
						|
	
 | 
						|
int BN_mod_mul_reciprocal(BIGNUM *r, BIGNUM *x, BIGNUM *y, BIGNUM *m, 
 | 
						|
	BIGNUM *i, int nb, BN_CTX *ctx);
 | 
						|
	This function is used to perform an efficient BN_mod_mul()
 | 
						|
	operation.  If one is going to repeatedly perform BN_mod_mul() with
 | 
						|
	the same modulus is worth calculating the reciprocal of the modulus
 | 
						|
	and then using this function.  This operation uses the fact that
 | 
						|
	a/b == a*r where r is the reciprocal of b.  On modern computers
 | 
						|
	multiplication is very fast and big number division is very slow.
 | 
						|
	'x' is multiplied by 'y' and then divided by 'm' and the remainder
 | 
						|
	is returned.  'i' is the reciprocal of 'm' and 'nb' is the number
 | 
						|
	of bits as returned from BN_reciprocal().  Normal usage is as follows.
 | 
						|
	bn=BN_reciprocal(i,m);
 | 
						|
	for (...)
 | 
						|
		{ BN_mod_mul_reciprocal(r,x,y,m,i,bn,ctx); }
 | 
						|
	This is r=(x*y)%m.  Internally it is approximately
 | 
						|
	r=(x*y)-m*(x*y/m) or r=(x*y)-m*((x*y*i) >> bn)
 | 
						|
	This function is used in BN_mod_exp() and BN_is_prime().
 | 
						|
 | 
						|
Assignment Operations
 | 
						|
 | 
						|
int BN_one(BIGNUM *a)
 | 
						|
	Set 'a' to hold the value one.
 | 
						|
	This is a=1.
 | 
						|
	
 | 
						|
int BN_zero(BIGNUM *a)
 | 
						|
	Set 'a' to hold the value zero.
 | 
						|
	This is a=0.
 | 
						|
	
 | 
						|
int BN_set_word(BIGNUM *a, unsigned long w);
 | 
						|
	Set 'a' to hold the value of 'w'.  'w' is an unsigned long.
 | 
						|
	This is a=w.
 | 
						|
 | 
						|
unsigned long BN_get_word(BIGNUM *a);
 | 
						|
	Returns 'a' in an unsigned long.  Not remarkably, often 'a' will
 | 
						|
	be biger than a word, in which case 0xffffffffL is returned.
 | 
						|
 | 
						|
Word Operations
 | 
						|
These functions are much more efficient that the normal bignum arithmetic
 | 
						|
operations.
 | 
						|
 | 
						|
BN_ULONG BN_mod_word(BIGNUM *a, unsigned long w);
 | 
						|
	Return the remainder of 'a' divided by 'w'.
 | 
						|
	This is return(a%w).
 | 
						|
	
 | 
						|
int BN_add_word(BIGNUM *a, unsigned long w);
 | 
						|
	Add 'w' to 'a'.  This function does not take the sign of 'a' into
 | 
						|
	account.  This is a+=w;
 | 
						|
	
 | 
						|
Bit operations.
 | 
						|
 | 
						|
int BN_is_bit_set(BIGNUM *a, int n);
 | 
						|
	This function return 1 if bit 'n' is set in 'a' else 0.
 | 
						|
 | 
						|
int BN_set_bit(BIGNUM *a, int n);
 | 
						|
	This function sets bit 'n' to 1 in 'a'. 
 | 
						|
	This is a&= ~(1<<n);
 | 
						|
 | 
						|
int BN_clear_bit(BIGNUM *a, int n);
 | 
						|
	This function sets bit 'n' to zero in 'a'.  Return 0 if less
 | 
						|
	than 'n' bits in 'a' else 1.  This is a&= ~(1<<n);
 | 
						|
 | 
						|
int BN_mask_bits(BIGNUM *a, int n);
 | 
						|
	Truncate 'a' to n bits long.  This is a&= ~((~0)<<n)
 | 
						|
 | 
						|
Format conversion routines.
 | 
						|
 | 
						|
BIGNUM *BN_bin2bn(unsigned char *s, int len,BIGNUM *ret);
 | 
						|
	This function converts 'len' bytes in 's' into a BIGNUM which
 | 
						|
	is put in 'ret'.  If ret is NULL, a new BIGNUM is created.
 | 
						|
	Either this new BIGNUM or ret is returned.  The number is
 | 
						|
	assumed to be in bigendian form in 's'.  By this I mean that
 | 
						|
	to 'ret' is created as follows for 'len' == 5.
 | 
						|
	ret = s[0]*2^32 + s[1]*2^24 + s[2]*2^16 + s[3]*2^8 + s[4];
 | 
						|
	This function cannot be used to convert negative numbers.  It
 | 
						|
	is always assumed the number is positive.  The application
 | 
						|
	needs to diddle the 'neg' field of th BIGNUM its self.
 | 
						|
	The better solution would be to save the numbers in ASN.1 format
 | 
						|
	since this is a defined standard for storing big numbers.
 | 
						|
	Look at the functions
 | 
						|
 | 
						|
	ASN1_INTEGER *BN_to_ASN1_INTEGER(BIGNUM *bn, ASN1_INTEGER *ai);
 | 
						|
	BIGNUM *ASN1_INTEGER_to_BN(ASN1_INTEGER *ai,BIGNUM *bn);
 | 
						|
	int i2d_ASN1_INTEGER(ASN1_INTEGER *a,unsigned char **pp);
 | 
						|
	ASN1_INTEGER *d2i_ASN1_INTEGER(ASN1_INTEGER **a,unsigned char **pp,
 | 
						|
		long length;
 | 
						|
 | 
						|
int BN_bn2bin(BIGNUM *a, unsigned char *to);
 | 
						|
	This function converts 'a' to a byte string which is put into
 | 
						|
	'to'.  The representation is big-endian in that the most
 | 
						|
	significant byte of 'a' is put into to[0].  This function
 | 
						|
	returns the number of bytes used to hold 'a'.  BN_num_bytes(a)
 | 
						|
	would return the same value and can be used to determine how
 | 
						|
	large 'to' needs to be.  If the number is negative, this
 | 
						|
	information is lost.  Since this library was written to
 | 
						|
	manipulate large positive integers, the inability to save and
 | 
						|
	restore them is not considered to be a problem by me :-).
 | 
						|
	As for BN_bin2bn(), look at the ASN.1 integer encoding funtions
 | 
						|
	for SSLeay.  They use BN_bin2bn() and BN_bn2bin() internally.
 | 
						|
	
 | 
						|
char *BN_bn2ascii(BIGNUM *a);
 | 
						|
	This function returns a malloc()ed string that contains the
 | 
						|
	ascii hexadecimal encoding of 'a'.  The number is in bigendian
 | 
						|
	format with a '-' in front if the number is negative.
 | 
						|
 | 
						|
int BN_ascii2bn(BIGNUM **bn, char *a);
 | 
						|
	The inverse of BN_bn2ascii.  The function returns the number of
 | 
						|
	characters from 'a' were processed in generating a the bignum.
 | 
						|
	error is inticated by 0 being returned.  The number is a
 | 
						|
	hex digit string, optionally with a leading '-'.  If *bn
 | 
						|
	is null, a BIGNUM is created and returned via that variable.
 | 
						|
	
 | 
						|
int BN_print_fp(FILE *fp, BIGNUM *a);
 | 
						|
	'a' is printed to file pointer 'fp'.  It is in the same format
 | 
						|
	that is output from BN_bn2ascii().  0 is returned on error,
 | 
						|
	1 if things are ok.
 | 
						|
 | 
						|
int BN_print(BIO *bp, BIGNUM *a);
 | 
						|
	Same as BN_print except that the output is done to the SSLeay libraries
 | 
						|
	BIO routines.  BN_print_fp() actually calls this function.
 | 
						|
 | 
						|
Miscellaneous Routines.
 | 
						|
 | 
						|
int BN_rand(BIGNUM *rnd, int bits, int top, int bottom);
 | 
						|
	This function returns in 'rnd' a random BIGNUM that is bits
 | 
						|
	long.  If bottom is 1, the number returned is odd.  If top is set,
 | 
						|
	the top 2 bits of the number are set.  This is useful because if
 | 
						|
	this is set, 2 'n; bit numbers multiplied together will return a 2n
 | 
						|
	bit number.  If top was not set, they could produce a 2n-1 bit
 | 
						|
	number.
 | 
						|
 | 
						|
BIGNUM *BN_mod_inverse(BIGNUM *a, BIGNUM *n,BN_CTX *ctx);
 | 
						|
	This function create a new BIGNUM and returns it.  This number
 | 
						|
	is the inverse mod 'n' of 'a'.  By this it is meant that the
 | 
						|
	returned value 'r' satisfies (a*r)%n == 1.  This function is
 | 
						|
	used in the generation of RSA keys.  'ctx', as per usual,
 | 
						|
	is used to hold temporary variables that are required by the
 | 
						|
	function.  NULL is returned on error.
 | 
						|
 | 
						|
int BN_gcd(BIGNUM *r,BIGNUM *a,BIGNUM *b,BN_CTX *ctx);
 | 
						|
	'r' has the greatest common divisor of 'a' and 'b'.  'ctx' is
 | 
						|
	used for temporary variables and 0 is returned on error.
 | 
						|
 | 
						|
int BN_is_prime(BIGNUM *p,int nchecks,void (*callback)(),BN_CTX *ctx,
 | 
						|
	char *cb_arg);
 | 
						|
	This function is used to check if a BIGNUM ('p') is prime.
 | 
						|
	It performs this test by using the Miller-Rabin randomised
 | 
						|
	primality test.  This is a probalistic test that requires a
 | 
						|
	number of rounds to ensure the number is prime to a high
 | 
						|
	degree of probability.  Since this can take quite some time, a
 | 
						|
	callback function can be passed and it will be called each
 | 
						|
	time 'p' passes a round of the prime testing.  'callback' will
 | 
						|
	be called as follows, callback(1,n,cb_arg) where n is the number of
 | 
						|
	the round, just passed.  As per usual 'ctx' contains temporary
 | 
						|
	variables used.  If ctx is NULL, it does not matter, a local version
 | 
						|
	will be malloced.  This parameter is present to save some mallocing
 | 
						|
	inside the function but probably could be removed.
 | 
						|
	0 is returned on error.
 | 
						|
	'ncheck' is the number of Miller-Rabin tests to run.  It is
 | 
						|
	suggested to use the value 'BN_prime_checks' by default.
 | 
						|
 | 
						|
BIGNUM *BN_generate_prime(
 | 
						|
int bits,
 | 
						|
int strong,
 | 
						|
BIGNUM *a,
 | 
						|
BIGNUM *rems,
 | 
						|
void (*callback)());
 | 
						|
char *cb_arg
 | 
						|
	This function is used to generate prime numbers.  It returns a
 | 
						|
	new BIGNUM that has a high probability of being a prime.
 | 
						|
	'bits' is the number of bits that
 | 
						|
	are to be in the prime.  If 'strong' is true, the returned prime
 | 
						|
	will also be a strong prime ((p-1)/2 is also prime).
 | 
						|
	While searching for the prime ('p'), we
 | 
						|
	can add the requirement that the prime fill the following
 | 
						|
	condition p%a == rem.  This can be used to help search for
 | 
						|
	primes with specific features, which is required when looking
 | 
						|
	for primes suitable for use with certain 'g' values in the
 | 
						|
	Diffie-Hellman key exchange algorithm.  If 'a' is NULL,
 | 
						|
	this condition is not checked.  If rem is NULL, rem is assumed
 | 
						|
	to be 1.  Since this search for a prime
 | 
						|
	can take quite some time, if callback is not NULL, it is called
 | 
						|
	in the following situations.
 | 
						|
	We have a suspected prime (from a quick sieve),
 | 
						|
	callback(0,sus_prime++,cb_arg). Each item to be passed to BN_is_prime().
 | 
						|
	callback(1,round++,cb_arg).  Each successful 'round' in BN_is_prime().
 | 
						|
	callback(2,round,cb_arg). For each successful BN_is_prime() test.
 | 
						|
 |