[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

@@ -358,7 +358,7 @@ bigint_done_raw ( const unsigned long *value0, unsigned int size __unused,
*
* @v multiplicand Multiplicand element
* @v multiplier Multiplier element
* @v result Result element pair
* @v result Result element
* @v carry Carry element
*/
static inline __attribute__ (( always_inline )) void
@@ -370,23 +370,20 @@ bigint_multiply_one ( const unsigned long multiplicand,
unsigned long discard_carry;
__asm__ __volatile__ ( /* Perform multiplication */
"mulhu %1, %6, %7\n\t"
"mul %0, %6, %7\n\t"
"mulhu %1, %5, %6\n\t"
"mul %0, %5, %6\n\t"
/* Accumulate low half */
"add %3, %3, %0\n\t"
"sltu %2, %3, %0\n\t"
/* Add carry to high half (cannot overflow) */
"add %1, %1, %2\n\t"
/* Accumulate high half */
"add %4, %4, %1\n\t"
"sltu %2, %4, %1\n\t"
/* Accumulate carry (cannot overflow) */
"add %5, %5, %2\n\t"
"add %3, %3, %4\n\t"
"sltu %2, %3, %4\n\t"
"add %4, %1, %2\n\t"
: "=r" ( discard_low ),
"=&r" ( discard_high ),
"=r" ( discard_carry ),
"+r" ( result[0] ),
"+r" ( result[1] ),
"+r" ( *result ),
"+r" ( *carry )
: "r" ( multiplicand ),
"r" ( multiplier ) );