[crypto] Eliminate temporary carry space for big integer multiplication

An n-bit multiplication product may be added to up to two n-bit
integers without exceeding the range of a (2n)-bit integer:

  (2^n - 1)*(2^n - 1) + (2^n - 1) + (2^n - 1) = 2^(2n) - 1

Exploit this to perform big integer multiplication in constant time
without requiring the caller to provide temporary carry space.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2024-09-26 16:24:57 +01:00
parent 8844a3d546
commit 3f4f843920
9 changed files with 111 additions and 197 deletions

View File

@@ -208,15 +208,13 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
* @v multiplicand Big integer to be multiplied
* @v multiplier Big integer to be multiplied
* @v result Big integer to hold result
* @v carry Big integer to hold temporary carry space
*/
#define bigint_multiply( multiplicand, multiplier, result, carry ) do { \
#define bigint_multiply( multiplicand, multiplier, result ) do { \
unsigned int multiplicand_size = bigint_size (multiplicand); \
unsigned int multiplier_size = bigint_size (multiplier); \
bigint_multiply_raw ( (multiplicand)->element, \
multiplicand_size, (multiplier)->element, \
multiplier_size, (result)->element, \
(carry)->element ); \
multiplier_size, (result)->element ); \
} while ( 0 )
/**
@@ -247,10 +245,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
unsigned int size = bigint_size (modulus); \
sizeof ( struct { \
bigint_t ( size * 2 ) temp_result; \
union { \
bigint_t ( size * 2 ) temp_modulus; \
bigint_t ( size * 2 ) temp_carry; \
}; \
bigint_t ( size * 2 ) temp_modulus; \
} ); } )
/**
@@ -324,8 +319,7 @@ void bigint_multiply_raw ( const bigint_element_t *multiplicand0,
unsigned int multiplicand_size,
const bigint_element_t *multiplier0,
unsigned int multiplier_size,
bigint_element_t *result0,
bigint_element_t *carry0 );
bigint_element_t *result0 );
void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0,
const bigint_element_t *multiplier0,
const bigint_element_t *modulus0,