From da6da6eb3b83fe92002e9c8e245933498ba19a48 Mon Sep 17 00:00:00 2001 From: Michael Brown Date: Thu, 7 Nov 2024 14:43:56 +0000 Subject: [crypto] Add bigint_msb_is_set() to clarify code Add a dedicated bigint_msb_is_set() to reduce the amount of open coding required in the common case of testing the sign of a two's complement big integer. Signed-off-by: Michael Brown --- src/crypto/bigint.c | 5 ++--- src/crypto/x25519.c | 3 +-- src/include/ipxe/bigint.h | 27 +++++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/crypto/bigint.c b/src/crypto/bigint.c index 3f5db8517..35701a1d0 100644 --- a/src/crypto/bigint.c +++ b/src/crypto/bigint.c @@ -162,14 +162,13 @@ void bigint_reduce_raw ( const bigint_element_t *minuend0, bigint_t ( minuend_size ) modulus; } *temp = tmp; const unsigned int width = ( 8 * sizeof ( bigint_element_t ) ); - const bigint_element_t msb_mask = ( 1UL << ( width - 1 ) ); bigint_element_t *element; unsigned int minuend_max; unsigned int modulus_max; unsigned int subshift; - bigint_element_t msb; int offset; int shift; + int msb; int i; /* Start profiling */ @@ -289,7 +288,7 @@ void bigint_reduce_raw ( const bigint_element_t *minuend0, } else { bigint_subtract ( &temp->modulus, &temp->minuend ); } - msb = ( temp->minuend.element[ minuend_size - 1 ] & msb_mask ); + msb = bigint_msb_is_set ( &temp->minuend ); if ( shift > 0 ) bigint_shr ( &temp->modulus ); } diff --git a/src/crypto/x25519.c b/src/crypto/x25519.c index d58f7168c..19f9a2c02 100644 --- a/src/crypto/x25519.c +++ b/src/crypto/x25519.c @@ -563,7 +563,6 @@ void x25519_invert ( const union x25519_oct258 *invertend, * @v value Big integer to be subtracted from, if possible */ static void x25519_reduce_by ( const x25519_t *subtrahend, x25519_t *value ) { - unsigned int max_bit = ( ( 8 * sizeof ( *value ) ) - 1 ); x25519_t tmp; /* Conditionally subtract subtrahend @@ -573,7 +572,7 @@ static void x25519_reduce_by ( const x25519_t *subtrahend, x25519_t *value ) { */ bigint_copy ( value, &tmp ); bigint_subtract ( subtrahend, value ); - bigint_swap ( value, &tmp, bigint_bit_is_set ( value, max_bit ) ); + bigint_swap ( value, &tmp, bigint_msb_is_set ( value ) ); } /** diff --git a/src/include/ipxe/bigint.h b/src/include/ipxe/bigint.h index f7900e0e6..a85761815 100644 --- a/src/include/ipxe/bigint.h +++ b/src/include/ipxe/bigint.h @@ -142,6 +142,16 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL ); unsigned int size = bigint_size (value); \ bigint_bit_is_set_raw ( (value)->element, size, bit ); } ) +/** + * Test if most significant bit is set in big integer + * + * @v value Big integer + * @ret is_set Most significant bit is set + */ +#define bigint_msb_is_set( value ) ( { \ + unsigned int size = bigint_size (value); \ + bigint_msb_is_set_raw ( (value)->element, size ); } ) + /** * Find highest bit set in big integer * @@ -358,6 +368,23 @@ bigint_bit_is_set_raw ( const bigint_element_t *value0, unsigned int size, return ( !! ( value->element[index] & ( 1UL << subindex ) ) ); } +/** + * Test if most significant bit is set in big integer + * + * @v value0 Element 0 of big integer + * @v size Number of elements + * @ret is_set Most significant bit is set + */ +static inline __attribute__ (( always_inline )) int +bigint_msb_is_set_raw ( const bigint_element_t *value0, unsigned int size ) { + const bigint_t ( size ) __attribute__ (( may_alias )) *value = + ( ( const void * ) value0 ); + unsigned int index = ( size - 1 ); + unsigned int subindex = ( ( 8 * sizeof ( value->element[0] ) ) - 1 ); + + return ( !! ( value->element[index] & ( 1UL << subindex ) ) ); +} + 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, -- cgit