david/ipxe
david
/
ipxe
Archived
1
0
Fork 0

[crypto] Add big-integer library for RSA calculations

RSA requires modular exponentiation using arbitrarily large integers.
Given the sizes of the modulus and exponent, all required calculations
can be done without any further dynamic storage allocation.  The x86
architecture allows for efficient large integer support via inline
assembly using the instructions that take advantage of the carry flag
(e.g. "adcl", "rcrl").

This implemention is approximately 80% smaller than the (more generic)
AXTLS implementation.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown 2012-03-13 16:35:21 +00:00
parent f229162749
commit 071184a6e4
5 changed files with 798 additions and 0 deletions

View File

@ -0,0 +1,90 @@
/*
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
FILE_LICENCE ( GPL2_OR_LATER );
#include <stdint.h>
#include <string.h>
#include <ipxe/bigint.h>
/** @file
*
* Big integer support
*/
/**
* Multiply big integers
*
* @v multiplicand0 Element 0 of big integer to be multiplied
* @v multiplier0 Element 0 of big integer to be multiplied
* @v result0 Element 0 of big integer to hold result
* @v size Number of elements
*/
void bigint_multiply_raw ( const uint32_t *multiplicand0,
const uint32_t *multiplier0,
uint32_t *result0, unsigned int size ) {
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
( ( const void * ) multiplicand0 );
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
( ( const void * ) multiplier0 );
bigint_t ( size * 2 ) __attribute__ (( may_alias )) *result =
( ( void * ) result0 );
unsigned int i;
unsigned int j;
uint32_t multiplicand_element;
uint32_t multiplier_element;
uint32_t *result_elements;
uint32_t discard_a;
uint32_t discard_d;
long index;
/* Zero result */
memset ( result, 0, sizeof ( *result ) );
/* Multiply integers one element at a time */
for ( i = 0 ; i < size ; i++ ) {
multiplicand_element = multiplicand->element[i];
for ( j = 0 ; j < size ; j++ ) {
multiplier_element = multiplier->element[j];
result_elements = &result->element[ i + j ];
/* Perform a single multiply, and add the
* resulting double-element into the result,
* carrying as necessary. The carry can
* never overflow beyond the end of the
* result, since:
*
* a < 2^{n}, b < 2^{n} => ab < 2^{2n}
*/
__asm__ __volatile__ ( "mull %4\n\t"
"addl %%eax, (%5,%2,4)\n\t"
"adcl %%edx, 4(%5,%2,4)\n\t"
"\n1:\n\t"
"adcl $0, 8(%5,%2,4)\n\t"
"inc %2\n\t"
/* Does not affect CF */
"jc 1b\n\t"
: "=&a" ( discard_a ),
"=&d" ( discard_d ),
"=&r" ( index )
: "0" ( multiplicand_element ),
"g" ( multiplier_element ),
"r" ( result_elements ),
"2" ( 0 ) );
}
}
}

View File

@ -0,0 +1,318 @@
#ifndef _BITS_BIGINT_H
#define _BITS_BIGINT_H
/** @file
*
* Big integer support
*/
FILE_LICENCE ( GPL2_OR_LATER );
#include <stdint.h>
#include <string.h>
/** Element of a big integer */
typedef uint32_t bigint_element_t;
/**
* Initialise big integer
*
* @v value0 Element 0 of big integer to initialise
* @v size Number of elements
* @v data Raw data
* @v len Length of raw data
*/
static inline __attribute__ (( always_inline )) void
bigint_init_raw ( uint32_t *value0, unsigned int size,
const void *data, size_t len ) {
long pad_len = ( sizeof ( bigint_t ( size ) ) - len );
void *discard_D;
long discard_c;
/* Copy raw data in reverse order, padding with zeros */
__asm__ __volatile__ ( "\n1:\n\t"
"movb -1(%2,%1), %%al\n\t"
"stosb\n\t"
"loop 1b\n\t"
"xorl %%eax, %%eax\n\t"
"mov %3, %1\n\t"
"rep stosb\n\t"
: "=&D" ( discard_D ), "=&c" ( discard_c )
: "r" ( data ), "g" ( pad_len ), "0" ( value0 ),
"1" ( len )
: "eax" );
}
/**
* Add big integers
*
* @v addend0 Element 0 of big integer to add
* @v value0 Element 0 of big integer to be added to
* @v size Number of elements
*/
static inline __attribute__ (( always_inline )) void
bigint_add_raw ( const uint32_t *addend0, uint32_t *value0,
unsigned int size ) {
long index;
void *discard_S;
long discard_c;
__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
"\n1:\n\t"
"lodsl\n\t"
"adcl %%eax, (%3,%0,4)\n\t"
"inc %0\n\t" /* Does not affect CF */
"loop 1b\n\t"
: "=&r" ( index ), "=&S" ( discard_S ),
"=&c" ( discard_c )
: "r" ( value0 ), "1" ( addend0 ), "2" ( size )
: "eax" );
}
/**
* Subtract big integers
*
* @v subtrahend0 Element 0 of big integer to subtract
* @v value0 Element 0 of big integer to be subtracted from
* @v size Number of elements
*/
static inline __attribute__ (( always_inline )) void
bigint_subtract_raw ( const uint32_t *subtrahend0, uint32_t *value0,
unsigned int size ) {
long index;
void *discard_S;
long discard_c;
__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
"\n1:\n\t"
"lodsl\n\t"
"sbbl %%eax, (%3,%0,4)\n\t"
"inc %0\n\t" /* Does not affect CF */
"loop 1b\n\t"
: "=&r" ( index ), "=&S" ( discard_S ),
"=&c" ( discard_c )
: "r" ( value0 ), "1" ( subtrahend0 ),
"2" ( size )
: "eax" );
}
/**
* Rotate big integer left
*
* @v value0 Element 0 of big integer
* @v size Number of elements
*/
static inline __attribute__ (( always_inline )) void
bigint_rol_raw ( uint32_t *value0, unsigned int size ) {
long index;
long discard_c;
__asm__ __volatile__ ( "xor %0, %0\n\t" /* Zero %0 and clear CF */
"\n1:\n\t"
"rcll $1, (%2,%0,4)\n\t"
"inc %0\n\t" /* Does not affect CF */
"loop 1b\n\t"
: "=&r" ( index ), "=&c" ( discard_c )
: "r" ( value0 ), "1" ( size ) );
}
/**
* Rotate big integer right
*
* @v value0 Element 0 of big integer
* @v size Number of elements
*/
static inline __attribute__ (( always_inline )) void
bigint_ror_raw ( uint32_t *value0, unsigned int size ) {
long discard_c;
__asm__ __volatile__ ( "clc\n\t"
"\n1:\n\t"
"rcrl $1, -4(%1,%0,4)\n\t"
"loop 1b\n\t"
: "=&c" ( discard_c )
: "r" ( value0 ), "0" ( size ) );
}
/**
* Test if big integer is equal to zero
*
* @v value0 Element 0 of big integer
* @v size Number of elements
* @ret is_zero Big integer is equal to zero
*/
static inline __attribute__ (( always_inline, pure )) int
bigint_is_zero_raw ( const uint32_t *value0, unsigned int size ) {
void *discard_D;
long discard_c;
int result;
__asm__ __volatile__ ( "xor %0, %0\n\t" /* Set ZF */
"repe scasl\n\t"
"sete %b0\n\t"
: "=&a" ( result ), "=&D" ( discard_D ),
"=&c" ( discard_c )
: "1" ( value0 ), "2" ( size ) );
return result;
}
/**
* Compare big integers
*
* @v value0 Element 0 of big integer
* @v reference0 Element 0 of reference big integer
* @v size Number of elements
* @ret geq Big integer is greater than or equal to the reference
*/
static inline __attribute__ (( always_inline, pure )) int
bigint_is_geq_raw ( const uint32_t *value0, const uint32_t *reference0,
unsigned int size ) {
const bigint_t ( size ) __attribute__ (( may_alias )) *value =
( ( const void * ) value0 );
const bigint_t ( size ) __attribute__ (( may_alias )) *reference =
( ( const void * ) reference0 );
void *discard_S;
void *discard_D;
long discard_c;
int result;
__asm__ __volatile__ ( "std\n\t"
"\n1:\n\t"
"lodsl\n\t"
"scasl\n\t"
"loope 1b\n\t"
"setae %b0\n\t"
"cld\n\t"
: "=r" ( result ), "=&S" ( discard_S ),
"=&D" ( discard_D ), "=&c" ( discard_c )
: "0" ( 0 ), "1" ( &value->element[ size - 1 ] ),
"2" ( &reference->element[ size - 1 ] ),
"3" ( size )
: "eax" );
return result;
}
/**
* Test if bit is set in big integer
*
* @v value0 Element 0 of big integer
* @v size Number of elements
* @v bit Bit to test
* @ret is_set Bit is set
*/
static inline __attribute__ (( always_inline )) int
bigint_bit_is_set_raw ( const uint32_t *value0, unsigned int size,
unsigned int bit ) {
const bigint_t ( size ) __attribute__ (( may_alias )) *value =
( ( const void * ) value0 );
unsigned int index = ( bit / ( 8 * sizeof ( value->element[0] ) ) );
unsigned int subindex = ( bit % ( 8 * sizeof ( value->element[0] ) ) );
return ( value->element[index] & ( 1 << subindex ) );
}
/**
* Find highest bit set in big integer
*
* @v value0 Element 0 of big integer
* @v size Number of elements
* @ret max_bit Highest bit set + 1 (or 0 if no bits set)
*/
static inline __attribute__ (( always_inline )) int
bigint_max_set_bit_raw ( const uint32_t *value0, unsigned int size ) {
long discard_c;
int result;
__asm__ __volatile__ ( "\n1:\n\t"
"bsrl -4(%2,%1,4), %0\n\t"
"loopz 1b\n\t"
"rol %1\n\t" /* Does not affect ZF */
"rol %1\n\t"
"leal 1(%k0,%k1,8), %k0\n\t"
"jnz 2f\n\t"
"xor %0, %0\n\t"
"\n2:\n\t"
: "=&r" ( result ), "=&c" ( discard_c )
: "r" ( value0 ), "1" ( size ) );
return result;
}
/**
* Grow big integer
*
* @v source0 Element 0 of source big integer
* @v source_size Number of elements in source big integer
* @v dest0 Element 0 of destination big integer
* @v dest_size Number of elements in destination big integer
*/
static inline __attribute__ (( always_inline )) void
bigint_grow_raw ( const uint32_t *source0, unsigned int source_size,
uint32_t *dest0, unsigned int dest_size ) {
long pad_size = ( dest_size - source_size );
void *discard_D;
void *discard_S;
long discard_c;
__asm__ __volatile__ ( "rep movsl\n\t"
"xorl %%eax, %%eax\n\t"
"mov %3, %2\n\t"
"rep stosl\n\t"
: "=&D" ( discard_D ), "=&S" ( discard_S ),
"=&c" ( discard_c )
: "g" ( pad_size ), "0" ( dest0 ),
"1" ( source0 ), "2" ( source_size )
: "eax" );
}
/**
* Shrink big integer
*
* @v source0 Element 0 of source big integer
* @v source_size Number of elements in source big integer
* @v dest0 Element 0 of destination big integer
* @v dest_size Number of elements in destination big integer
*/
static inline __attribute__ (( always_inline )) void
bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused,
uint32_t *dest0, unsigned int dest_size ) {
void *discard_D;
void *discard_S;
long discard_c;
__asm__ __volatile__ ( "rep movsl\n\t"
: "=&D" ( discard_D ), "=&S" ( discard_S ),
"=&c" ( discard_c )
: "0" ( dest0 ), "1" ( source0 ),
"2" ( dest_size )
: "eax" );
}
/**
* Finalise big integer
*
* @v value0 Element 0 of big integer to finalise
* @v size Number of elements
* @v out Output buffer
* @v len Length of output buffer
*/
static inline __attribute__ (( always_inline )) void
bigint_done_raw ( const uint32_t *value0, unsigned int size __unused,
void *out, size_t len ) {
void *discard_D;
long discard_c;
/* Copy raw data in reverse order */
__asm__ __volatile__ ( "\n1:\n\t"
"movb -1(%2,%1), %%al\n\t"
"stosb\n\t"
"loop 1b\n\t"
: "=&D" ( discard_D ), "=&c" ( discard_c )
: "r" ( value0 ), "0" ( out ), "1" ( len )
: "eax" );
}
extern void bigint_multiply_raw ( const uint32_t *multiplicand0,
const uint32_t *multiplier0,
uint32_t *value0, unsigned int size );
#endif /* _BITS_BIGINT_H */

122
src/crypto/bigint.c Normal file
View File

@ -0,0 +1,122 @@
/*
* Copyright (C) 2012 Michael Brown <mbrown@fensystems.co.uk>.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
FILE_LICENCE ( GPL2_OR_LATER );
#include <stdint.h>
#include <string.h>
#include <assert.h>
#include <ipxe/bigint.h>
/** @file
*
* Big integer support
*/
/**
* Perform modular multiplication of big integers
*
* @v multiplicand0 Element 0 of big integer to be multiplied
* @v multiplier0 Element 0 of big integer to be multiplied
* @v modulus0 Element 0 of big integer modulus
* @v result0 Element 0 of big integer to hold result
*/
void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0,
const bigint_element_t *multiplier0,
const bigint_element_t *modulus0,
bigint_element_t *result0,
unsigned int size ) {
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplicand =
( ( const void * ) multiplicand0 );
const bigint_t ( size ) __attribute__ (( may_alias )) *multiplier =
( ( const void * ) multiplier0 );
const bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
( ( const void * ) modulus0 );
bigint_t ( size ) __attribute__ (( may_alias )) *result =
( ( void * ) result0 );
bigint_t ( size * 2 ) temp_result;
bigint_t ( size * 2 ) temp_modulus;
int rotation;
int i;
/* Perform multiplication */
bigint_multiply ( multiplicand, multiplier, &temp_result );
/* Rescale modulus to match result */
bigint_grow ( modulus, &temp_modulus );
rotation = ( bigint_max_set_bit ( &temp_result ) -
bigint_max_set_bit ( &temp_modulus ) );
for ( i = 0 ; i < rotation ; i++ )
bigint_rol ( &temp_modulus );
/* Subtract multiples of modulus */
for ( i = 0 ; i <= rotation ; i++ ) {
if ( bigint_is_geq ( &temp_result, &temp_modulus ) )
bigint_subtract ( &temp_modulus, &temp_result );
bigint_ror ( &temp_modulus );
}
/* Resize result */
bigint_shrink ( &temp_result, result );
/* Sanity check */
assert ( bigint_is_geq ( modulus, result ) );
}
/**
* Perform modular exponentiation of big integers
*
* @v base0 Element 0 of big integer base
* @v modulus0 Element 0 of big integer modulus
* @v exponent0 Element 0 of big integer exponent
* @v result0 Element 0 of big integer to hold result
* @v size Number of elements in base, modulus, and result
* @v exponent_size Number of elements in exponent
*/
void bigint_mod_exp_raw ( const bigint_element_t *base0,
const bigint_element_t *modulus0,
const bigint_element_t *exponent0,
bigint_element_t *result0,
unsigned int size,
unsigned int exponent_size ) {
const bigint_t ( size ) __attribute__ (( may_alias )) *base =
( ( const void * ) base0 );
const bigint_t ( size ) __attribute__ (( may_alias )) *modulus =
( ( const void * ) modulus0 );
const bigint_t ( exponent_size ) __attribute__ (( may_alias ))
*exponent = ( ( const void * ) exponent0 );
bigint_t ( size ) __attribute__ (( may_alias )) *result =
( ( void * ) result0 );
bigint_t ( size ) temp_base;
bigint_t ( exponent_size ) temp_exponent;
static const uint8_t start[1] = { 0x01 };
memcpy ( &temp_base, base, sizeof ( temp_base ) );
memcpy ( &temp_exponent, exponent, sizeof ( temp_exponent ) );
bigint_init ( result, start, sizeof ( start ) );
while ( ! bigint_is_zero ( &temp_exponent ) ) {
if ( bigint_bit_is_set ( &temp_exponent, 0 ) ) {
bigint_mod_multiply ( result, &temp_base,
modulus, result );
}
bigint_ror ( &temp_exponent );
bigint_mod_multiply ( &temp_base, &temp_base, modulus,
&temp_base );
}
}

268
src/include/ipxe/bigint.h Normal file
View File

@ -0,0 +1,268 @@
#ifndef _IPXE_BIGINT_H
#define _IPXE_BIGINT_H
/** @file
*
* Big integer support
*/
FILE_LICENCE ( GPL2_OR_LATER );
/**
* Define a big-integer type
*
* @v size Number of elements
* @ret bigint_t Big integer type
*/
#define bigint_t( size ) \
struct { \
bigint_element_t element[ (size) ]; \
}
/**
* Determine number of elements required for a big-integer type
*
* @v len Maximum length of big integer, in bytes
* @ret size Number of elements
*/
#define bigint_required_size( len ) \
( ( (len) + sizeof ( bigint_element_t ) - 1 ) / \
sizeof ( bigint_element_t ) )
/**
* Determine number of elements in big-integer type
*
* @v bigint Big integer
* @ret size Number of elements
*/
#define bigint_size( bigint ) \
( sizeof ( *(bigint) ) / sizeof ( (bigint)->element[0] ) )
/**
* Initialise big integer
*
* @v value Big integer to initialise
* @v data Raw data
* @v len Length of raw data
*/
#define bigint_init( value, data, len ) do { \
unsigned int size = bigint_size (value); \
assert ( (len) <= ( size * sizeof ( (value)->element[0] ) ) ); \
bigint_init_raw ( (value)->element, size, (data), (len) ); \
} while ( 0 )
/**
* Finalise big integer
*
* @v value Big integer to finalise
* @v out Output buffer
* @v len Length of output buffer
*/
#define bigint_done( value, out, len ) do { \
unsigned int size = bigint_size (value); \
bigint_done_raw ( (value)->element, size, (out), (len) ); \
} while ( 0 )
/**
* Add big integers
*
* @v addend Big integer to add
* @v value Big integer to be added to
*/
#define bigint_add( addend, value ) do { \
unsigned int size = bigint_size (addend); \
bigint_add_raw ( (addend)->element, (value)->element, size ); \
} while ( 0 )
/**
* Subtract big integers
*
* @v subtrahend Big integer to subtract
* @v value Big integer to be subtracted from
*/
#define bigint_subtract( subtrahend, value ) do { \
unsigned int size = bigint_size (subtrahend); \
bigint_subtract_raw ( (subtrahend)->element, (value)->element, \
size ); \
} while ( 0 )
/**
* Rotate big integer left
*
* @v value Big integer
*/
#define bigint_rol( value ) do { \
unsigned int size = bigint_size (value); \
bigint_rol_raw ( (value)->element, size ); \
} while ( 0 )
/**
* Rotate big integer right
*
* @v value Big integer
*/
#define bigint_ror( value ) do { \
unsigned int size = bigint_size (value); \
bigint_ror_raw ( (value)->element, size ); \
} while ( 0 )
/**
* Test if big integer is equal to zero
*
* @v value Big integer
* @v size Number of elements
* @ret is_zero Big integer is equal to zero
*/
#define bigint_is_zero( value ) ( { \
unsigned int size = bigint_size (value); \
bigint_is_zero_raw ( (value)->element, size ); } )
/**
* Compare big integers
*
* @v value Big integer
* @v reference Reference big integer
* @ret geq Big integer is greater than or equal to the reference
*/
#define bigint_is_geq( value, reference ) ( { \
unsigned int size = bigint_size (value); \
bigint_is_geq_raw ( (value)->element, (reference)->element, \
size ); } )
/**
* Test if bit is set in big integer
*
* @v value Big integer
* @v bit Bit to test
* @ret is_set Bit is set
*/
#define bigint_bit_is_set( value, bit ) ( { \
unsigned int size = bigint_size (value); \
bigint_bit_is_set_raw ( (value)->element, size, bit ); } )
/**
* Find highest bit set in big integer
*
* @v value Big integer
* @ret max_bit Highest bit set + 1 (or 0 if no bits set)
*/
#define bigint_max_set_bit( value ) ( { \
unsigned int size = bigint_size (value); \
bigint_max_set_bit_raw ( (value)->element, size ); } )
/**
* Grow big integer
*
* @v source Source big integer
* @v dest Destination big integer
*/
#define bigint_grow( source, dest ) do { \
unsigned int source_size = bigint_size (source); \
unsigned int dest_size = bigint_size (dest); \
bigint_grow_raw ( (source)->element, source_size, \
(dest)->element, dest_size ); \
} while ( 0 )
/**
* Shrink big integer
*
* @v source Source big integer
* @v dest Destination big integer
*/
#define bigint_shrink( source, dest ) do { \
unsigned int source_size = bigint_size (source); \
unsigned int dest_size = bigint_size (dest); \
bigint_shrink_raw ( (source)->element, source_size, \
(dest)->element, dest_size ); \
} while ( 0 )
/**
* Multiply big integers
*
* @v multiplicand Big integer to be multiplied
* @v multiplier Big integer to be multiplied
* @v result Big integer to hold result
*/
#define bigint_multiply( multiplicand, multiplier, result ) do { \
unsigned int size = bigint_size (multiplicand); \
bigint_multiply_raw ( (multiplicand)->element, \
(multiplier)->element, (result)->element, \
size ); \
} while ( 0 )
/**
* Perform modular multiplication of big integers
*
* @v multiplicand Big integer to be multiplied
* @v multiplier Big integer to be multiplied
* @v modulus Big integer modulus
* @v result Big integer to hold result
*/
#define bigint_mod_multiply( multiplicand, multiplier, modulus, \
result ) do { \
unsigned int size = bigint_size (multiplicand); \
bigint_mod_multiply_raw ( (multiplicand)->element, \
(multiplier)->element, \
(modulus)->element, \
(result)->element, size ); \
} while ( 0 )
/**
* Perform modular exponentiation of big integers
*
* @v base Big integer base
* @v modulus Big integer modulus
* @v exponent Big integer exponent
* @v result Big integer to hold result
*/
#define bigint_mod_exp( base, modulus, exponent, result ) do { \
unsigned int size = bigint_size (base); \
unsigned int exponent_size = bigint_size (exponent); \
bigint_mod_exp_raw ( (base)->element, (modulus)->element, \
(exponent)->element, (result)->element, \
size, exponent_size ); \
} while ( 0 )
#include <bits/bigint.h>
void bigint_init_raw ( bigint_element_t *value0, unsigned int size,
const void *data, size_t len );
void bigint_done_raw ( const bigint_element_t *value0, unsigned int size,
void *out, size_t len );
void bigint_add_raw ( const bigint_element_t *addend0,
bigint_element_t *value0, unsigned int size );
void bigint_subtract_raw ( const bigint_element_t *subtrahend0,
bigint_element_t *value0, unsigned int size );
void bigint_rol_raw ( bigint_element_t *value0, unsigned int size );
void bigint_ror_raw ( bigint_element_t *value0, unsigned int size );
int bigint_is_zero_raw ( const bigint_element_t *value0, unsigned int size );
int bigint_is_geq_raw ( const bigint_element_t *value0,
const bigint_element_t *reference0,
unsigned int size );
int bigint_bit_is_set_raw ( const bigint_element_t *value0, unsigned int size,
unsigned int bit );
int bigint_max_set_bit_raw ( const bigint_element_t *value0,
unsigned int size );
void bigint_grow_raw ( const bigint_element_t *source0,
unsigned int source_size, bigint_element_t *dest0,
unsigned int dest_size );
void bigint_shrink_raw ( const bigint_element_t *source0,
unsigned int source_size, bigint_element_t *dest0,
unsigned int dest_size );
void bigint_multiply_raw ( const bigint_element_t *multiplicand0,
const bigint_element_t *multiplier0,
bigint_element_t *result0,
unsigned int size );
void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0,
const bigint_element_t *multiplier0,
const bigint_element_t *modulus0,
bigint_element_t *result0,
unsigned int size );
void bigint_mod_exp_raw ( const bigint_element_t *base0,
const bigint_element_t *modulus0,
const bigint_element_t *exponent0,
bigint_element_t *result0,
unsigned int size,
unsigned int exponent_size );
#endif /* _IPXE_BIGINT_H */