From: Michael Brown Date: Sat, 13 Jun 2026 14:28:52 +0000 (+0100) Subject: [crypto] Use generic implementations of slow-path big integer functions X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e68ca57f46efdeebbf72893b35aab2b18a34d2e7;p=thirdparty%2Fipxe.git [crypto] Use generic implementations of slow-path big integer functions In the original big integer implementation, big integers were entirely opaque to the caller and only the architecture-dependent code knew any details of the internal structure. This has long since ceased to be the case: for the sake of arithmetic efficiency, many portions of the codebase now presume that big integers are represented as an array of elements, with each element being a native-endian unsigned value (with the precise type being chosen by the architecture-specific header file) and with the least significant element being first in the array. The functions bigint_init(), bigint_done(), bigint_is_zero(), bigint_is_geq(), and bigint_max_bit_set() are never used on fast code paths, and most architectures use a generic C implementation of these functions. Provide generic implementations of these slow-path functions to be used on all architectures. Signed-off-by: Michael Brown --- diff --git a/src/arch/arm32/include/bits/bigint.h b/src/arch/arm32/include/bits/bigint.h index 988bef5ff..da6cfbf30 100644 --- a/src/arch/arm32/include/bits/bigint.h +++ b/src/arch/arm32/include/bits/bigint.h @@ -10,33 +10,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); #include #include -#include /** 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 ) { - size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len ); - uint8_t *value_byte = ( ( void * ) value0 ); - const uint8_t *data_byte = ( data + len ); - - /* Copy raw data in reverse order, padding with zeros */ - while ( len-- ) - *(value_byte++) = *(--data_byte); - while ( pad_len-- ) - *(value_byte++) = 0; -} - /** * Add big integers * @@ -182,76 +159,6 @@ bigint_shr_raw ( uint32_t *value0, unsigned int size ) { return carry; } -/** - * 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 ) { - const uint32_t *value = value0; - uint32_t value_i; - - do { - value_i = *(value++); - if ( value_i ) - break; - } while ( --size ); - - return ( value_i == 0 ); -} - -/** - * 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 uint32_t *value = ( value0 + size ); - const uint32_t *reference = ( reference0 + size ); - uint32_t value_i; - uint32_t reference_i; - - do { - value_i = *(--value); - reference_i = *(--reference); - if ( value_i != reference_i ) - break; - } while ( --size ); - - return ( value_i >= reference_i ); -} - -/** - * 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 ) { - const uint32_t *value = ( value0 + size ); - int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) ); - uint32_t value_i; - - do { - value_i = *(--value); - max_bit -= ( 32 - fls ( value_i ) ); - if ( value_i ) - break; - } while ( --size ); - - return max_bit; -} - /** * Grow big integer * @@ -284,25 +191,6 @@ bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused, memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) ); } -/** - * 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 ) { - const uint8_t *value_byte = ( ( const void * ) value0 ); - uint8_t *out_byte = ( out + len ); - - /* Copy raw data in reverse order */ - while ( len-- ) - *(--out_byte) = *(value_byte++); -} - /** * Multiply big integer elements * diff --git a/src/arch/arm64/include/bits/bigint.h b/src/arch/arm64/include/bits/bigint.h index a4c351c93..8d7a79531 100644 --- a/src/arch/arm64/include/bits/bigint.h +++ b/src/arch/arm64/include/bits/bigint.h @@ -11,33 +11,10 @@ FILE_SECBOOT ( PERMITTED ); #include #include -#include /** Element of a big integer */ typedef uint64_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 ( uint64_t *value0, unsigned int size, - const void *data, size_t len ) { - size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len ); - uint8_t *value_byte = ( ( void * ) value0 ); - const uint8_t *data_byte = ( data + len ); - - /* Copy raw data in reverse order, padding with zeros */ - while ( len-- ) - *(value_byte++) = *(--data_byte); - while ( pad_len-- ) - *(value_byte++) = 0; -} - /** * Add big integers * @@ -183,76 +160,6 @@ bigint_shr_raw ( uint64_t *value0, unsigned int size ) { return ( low & 1 ); } -/** - * 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 uint64_t *value0, unsigned int size ) { - const uint64_t *value = value0; - uint64_t value_i; - - do { - value_i = *(value++); - if ( value_i ) - break; - } while ( --size ); - - return ( value_i == 0 ); -} - -/** - * 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 uint64_t *value0, const uint64_t *reference0, - unsigned int size ) { - const uint64_t *value = ( value0 + size ); - const uint64_t *reference = ( reference0 + size ); - uint64_t value_i; - uint64_t reference_i; - - do { - value_i = *(--value); - reference_i = *(--reference); - if ( value_i != reference_i ) - break; - } while ( --size ); - - return ( value_i >= reference_i ); -} - -/** - * 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 uint64_t *value0, unsigned int size ) { - const uint64_t *value = ( value0 + size ); - int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) ); - uint64_t value_i; - - do { - value_i = *(--value); - max_bit -= ( 64 - fls ( value_i ) ); - if ( value_i ) - break; - } while ( --size ); - - return max_bit; -} - /** * Grow big integer * @@ -285,25 +192,6 @@ bigint_shrink_raw ( const uint64_t *source0, unsigned int source_size __unused, memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) ); } -/** - * 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 uint64_t *value0, unsigned int size __unused, - void *out, size_t len ) { - const uint8_t *value_byte = ( ( const void * ) value0 ); - uint8_t *out_byte = ( out + len ); - - /* Copy raw data in reverse order */ - while ( len-- ) - *(--out_byte) = *(value_byte++); -} - /** * Multiply big integer elements * diff --git a/src/arch/loong64/include/bits/bigint.h b/src/arch/loong64/include/bits/bigint.h index ac475da67..b2938f849 100644 --- a/src/arch/loong64/include/bits/bigint.h +++ b/src/arch/loong64/include/bits/bigint.h @@ -11,33 +11,10 @@ FILE_SECBOOT ( PERMITTED ); #include #include -#include /** Element of a big integer */ typedef uint64_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 ( uint64_t *value0, unsigned int size, - const void *data, size_t len ) { - size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len ); - uint8_t *value_byte = ( ( void * ) value0 ); - const uint8_t *data_byte = ( data + len ); - - /* Copy raw data in reverse order, padding with zeros */ - while ( len-- ) - *(value_byte++) = *(--data_byte); - while ( pad_len-- ) - *(value_byte++) = 0; -} - /** * Add big integers * @@ -226,76 +203,6 @@ bigint_shr_raw ( uint64_t *value0, unsigned int size ) { return ( carry & 1 ); } -/** - * 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 uint64_t *value0, unsigned int size ) { - const uint64_t *value = value0; - uint64_t value_i; - - do { - value_i = *(value++); - if ( value_i ) - break; - } while ( --size ); - - return ( value_i == 0 ); -} - -/** - * 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 uint64_t *value0, const uint64_t *reference0, - unsigned int size ) { - const uint64_t *value = ( value0 + size ); - const uint64_t *reference = ( reference0 + size ); - uint64_t value_i; - uint64_t reference_i; - - do { - value_i = *(--value); - reference_i = *(--reference); - if ( value_i != reference_i ) - break; - } while ( --size ); - - return ( value_i >= reference_i ); -} - -/** - * 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 uint64_t *value0, unsigned int size ) { - const uint64_t *value = ( value0 + size ); - int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) ); - uint64_t value_i; - - do { - value_i = *(--value); - max_bit -= ( 64 - fls ( value_i ) ); - if ( value_i ) - break; - } while ( --size ); - - return max_bit; -} - /** * Grow big integer * @@ -328,25 +235,6 @@ bigint_shrink_raw ( const uint64_t *source0, unsigned int source_size __unused, memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) ); } -/** - * 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 uint64_t *value0, unsigned int size __unused, - void *out, size_t len ) { - const uint8_t *value_byte = ( ( const void * ) value0 ); - uint8_t *out_byte = ( out + len ); - - /* Copy raw data in reverse order */ - while ( len-- ) - *(--out_byte) = *(value_byte++); -} - /** * Multiply big integer elements * diff --git a/src/arch/riscv/include/bits/bigint.h b/src/arch/riscv/include/bits/bigint.h index 89718f3eb..70a267bbe 100644 --- a/src/arch/riscv/include/bits/bigint.h +++ b/src/arch/riscv/include/bits/bigint.h @@ -11,33 +11,10 @@ FILE_SECBOOT ( PERMITTED ); #include #include -#include /** Element of a big integer */ typedef unsigned long 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 ( unsigned long *value0, unsigned int size, - const void *data, size_t len ) { - size_t pad_len = ( sizeof ( bigint_t ( size ) ) - len ); - uint8_t *value_byte = ( ( void * ) value0 ); - const uint8_t *data_byte = ( data + len ); - - /* Copy raw data in reverse order, padding with zeros */ - while ( len-- ) - *(value_byte++) = *(--data_byte); - while ( pad_len-- ) - *(value_byte++) = 0; -} - /** * Add big integers * @@ -221,76 +198,6 @@ bigint_shr_raw ( unsigned long *value0, unsigned int size ) { return ( !! carry ); } -/** - * 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 unsigned long *value0, unsigned int size ) { - const unsigned long *value = value0; - unsigned long value_i; - - do { - value_i = *(value++); - if ( value_i ) - break; - } while ( --size ); - - return ( value_i == 0 ); -} - -/** - * 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 unsigned long *value0, - const unsigned long *reference0, unsigned int size ) { - const unsigned long *value = ( value0 + size ); - const unsigned long *reference = ( reference0 + size ); - unsigned long value_i; - unsigned long reference_i; - - do { - value_i = *(--value); - reference_i = *(--reference); - if ( value_i != reference_i ) - break; - } while ( --size ); - - return ( value_i >= reference_i ); -} - -/** - * 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 unsigned long *value0, unsigned int size ) { - const unsigned long *value = ( value0 + size ); - int max_bit = ( 8 * sizeof ( bigint_t ( size ) ) ); - unsigned long value_i; - - do { - value_i = *(--value); - max_bit -= ( ( 8 * sizeof ( *value0 ) ) - fls ( value_i ) ); - if ( value_i ) - break; - } while ( --size ); - - return max_bit; -} - /** * Grow big integer * @@ -324,25 +231,6 @@ bigint_shrink_raw ( const unsigned long *source0, memcpy ( dest0, source0, sizeof ( bigint_t ( dest_size ) ) ); } -/** - * 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 unsigned long *value0, unsigned int size __unused, - void *out, size_t len ) { - const uint8_t *value_byte = ( ( const void * ) value0 ); - uint8_t *out_byte = ( out + len ); - - /* Copy raw data in reverse order */ - while ( len-- ) - *(--out_byte) = *(value_byte++); -} - /** * Multiply big integer elements * diff --git a/src/arch/x86/include/bits/bigint.h b/src/arch/x86/include/bits/bigint.h index 21cffa0cf..e4ac52d1e 100644 --- a/src/arch/x86/include/bits/bigint.h +++ b/src/arch/x86/include/bits/bigint.h @@ -10,45 +10,10 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); FILE_SECBOOT ( PERMITTED ); #include -#include /** 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 ) { - bigint_t ( size ) __attribute__ (( may_alias )) *value = - ( ( void * ) value0 ); - long pad_len = ( sizeof ( *value ) - len ); - void *discard_D; - long discard_c; - - /* Copy raw data in reverse order, padding with zeros */ - __asm__ __volatile__ ( "jecxz 2f\n\t" - "\n1:\n\t" - "movb -1(%3,%1), %%al\n\t" - "stosb\n\t" - "loop 1b\n\t" - "\n2:\n\t" - "xorl %%eax, %%eax\n\t" - "mov %4, %1\n\t" - "rep stosb\n\t" - : "=&D" ( discard_D ), "=&c" ( discard_c ), - "+m" ( *value ) - : "r" ( data ), "g" ( pad_len ), "0" ( value0 ), - "1" ( len ) - : "eax" ); -} - /** * Add big integers * @@ -164,81 +129,6 @@ bigint_shr_raw ( uint32_t *value0, unsigned int size ) { return out; } -/** - * 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 ) { - long discard_c; - long discard_tmp; - int result; - - __asm__ __volatile__ ( "\n1:\n\t" - "movl -4(%3, %1, 4), %k2\n\t" - "cmpl -4(%4, %1, 4), %k2\n\t" - "loope 1b\n\t" - "setae %b0\n\t" - : "=q" ( result ), "=&c" ( discard_c ), - "=&r" ( discard_tmp ) - : "r" ( value0 ), "r" ( reference0 ), - "0" ( 0 ), "1" ( size ) ); - return result; -} - -/** - * 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 * @@ -293,36 +183,6 @@ bigint_shrink_raw ( const uint32_t *source0, unsigned int source_size __unused, : "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 ) { - struct { - uint8_t bytes[len]; - } __attribute__ (( may_alias )) *out_bytes = out; - void *discard_D; - long discard_c; - - /* Copy raw data in reverse order */ - __asm__ __volatile__ ( "jecxz 2f\n\t" - "\n1:\n\t" - "movb -1(%3,%1), %%al\n\t" - "stosb\n\t" - "loop 1b\n\t" - "\n2:\n\t" - : "=&D" ( discard_D ), "=&c" ( discard_c ), - "+m" ( *out_bytes ) - : "r" ( value0 ), "0" ( out ), "1" ( len ) - : "eax" ); -} - /** * Multiply big integer elements * diff --git a/src/crypto/bigint.c b/src/crypto/bigint.c index 5d2f7b560..d3eafe19a 100644 --- a/src/crypto/bigint.c +++ b/src/crypto/bigint.c @@ -26,7 +26,9 @@ FILE_SECBOOT ( PERMITTED ); #include #include +#include #include +#include #include #include @@ -81,6 +83,138 @@ const char * bigint_ntoa_raw ( const bigint_element_t *value0, return buf; } +/** + * 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 + */ +void bigint_init_raw ( bigint_element_t *value0, unsigned int size, + const void *data, size_t len ) { + bigint_t ( size ) __attribute__ (( may_alias )) + *value = ( ( void * ) value0 ); + uint8_t *value_byte = ( ( void * ) value0 ); + const uint8_t *data_byte = data; + unsigned int toggle; + unsigned int i; + + /* Zero big integer */ + memset ( value, 0, sizeof ( *value ) ); + + /* Copy data, byte-swapping as needed */ + toggle = ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ? 0 : + ( sizeof ( value->element[0] ) - 1 ) ); + for ( i = 0 ; len-- ; i++ ) + value_byte[ i ^ toggle ] = data_byte[len]; +} + +/** + * 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 + */ +void bigint_done_raw ( const bigint_element_t *value0, unsigned int size, + void *out, size_t len ) { + const bigint_t ( size ) __attribute__ (( may_alias )) + *value = ( ( const void * ) value0 ); + const uint8_t *value_byte = ( ( const void * ) value0 ); + uint8_t *out_byte = out; + unsigned int toggle; + unsigned int i; + + /* Zero output buffer */ + memset ( out, 0, len ); + + /* Copy data, byte-swapping as needed */ + toggle = ( ( __BYTE_ORDER == __LITTLE_ENDIAN ) ? 0 : + ( sizeof ( value->element[0] ) - 1 ) ); + for ( i = 0 ; len-- ; i++ ) + out_byte[len] = value_byte[ i ^ toggle ]; +} + +/** + * 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 + */ +int bigint_is_zero_raw ( const bigint_element_t *value0, unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) *value = + ( ( const void * ) value0 ); + bigint_element_t or; + unsigned int i; + + /* Construct binary OR of all elements */ + for ( i = 0, or = 0 ; i < size ; i++ ) + or |= value->element[i]; + + return ( or == 0 ); +} + +/** + * 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 + */ +int bigint_is_geq_raw ( const bigint_element_t *value0, + const bigint_element_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 ); + bigint_element_t value_element; + bigint_element_t reference_element; + + /* Find highest differing element */ + do { + value_element = value->element[ size - 1 ]; + reference_element = reference->element[ size - 1 ]; + if ( value_element != reference_element ) + break; + } while ( --size ); + + return ( value_element >= reference_element ); +} + +/** + * 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) + */ +int bigint_max_set_bit_raw ( const bigint_element_t *value0, + unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) *value = + ( ( const void * ) value0 ); + bigint_element_t element; + unsigned int max_bit; + unsigned int i; + + /* Find highest set bit in highest non-zero element */ + max_bit = ( sizeof ( *value ) * 8 ); + for ( i = 0 ; i < size ; i++ ) { + element = value->element[ size - i - 1 ]; + max_bit -= ( sizeof ( element) * 8 ); + if ( element ) { + max_bit += flsll ( element ); + break; + } + } + + return max_bit; +} + /** * Conditionally swap big integers (in constant time) * diff --git a/src/crypto/ffdhe.c b/src/crypto/ffdhe.c index 7dc9457fc..41bd90813 100644 --- a/src/crypto/ffdhe.c +++ b/src/crypto/ffdhe.c @@ -42,6 +42,7 @@ FILE_SECBOOT ( PERMITTED ); */ #include +#include #include #include diff --git a/src/crypto/weierstrass.c b/src/crypto/weierstrass.c index 783e07a90..ab2df2407 100644 --- a/src/crypto/weierstrass.c +++ b/src/crypto/weierstrass.c @@ -45,6 +45,7 @@ FILE_SECBOOT ( PERMITTED ); * implementation of the big integer operations. */ +#include #include #include