mirror of
https://github.com/ipxe/ipxe
synced 2026-04-04 03:00:20 +03:00
[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:
@@ -314,7 +314,7 @@ bigint_done_raw ( const uint32_t *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
|
||||
@@ -324,19 +324,20 @@ bigint_multiply_one ( const uint32_t multiplicand, const uint32_t multiplier,
|
||||
uint32_t discard_high;
|
||||
|
||||
__asm__ __volatile__ ( /* Perform multiplication */
|
||||
"umull %0, %1, %5, %6\n\t"
|
||||
"umull %0, %1, %4, %5\n\t"
|
||||
/* Accumulate result */
|
||||
"adds %2, %0\n\t"
|
||||
"adcs %3, %1\n\t"
|
||||
"adc %1, #0\n\t"
|
||||
/* Accumulate carry (cannot overflow) */
|
||||
"adc %4, #0\n\t"
|
||||
"adds %2, %3\n\t"
|
||||
"adc %3, %1, #0\n\t"
|
||||
: "=r" ( discard_low ),
|
||||
"=r" ( discard_high ),
|
||||
"+r" ( result[0] ),
|
||||
"+r" ( result[1] ),
|
||||
"+r" ( *result ),
|
||||
"+r" ( *carry )
|
||||
: "r" ( multiplicand ),
|
||||
"r" ( multiplier ) );
|
||||
"r" ( multiplier )
|
||||
: "cc" );
|
||||
}
|
||||
|
||||
#endif /* _BITS_BIGINT_H */
|
||||
|
||||
@@ -315,7 +315,7 @@ bigint_done_raw ( const uint64_t *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
|
||||
@@ -325,20 +325,21 @@ bigint_multiply_one ( const uint64_t multiplicand, const uint64_t multiplier,
|
||||
uint64_t discard_high;
|
||||
|
||||
__asm__ __volatile__ ( /* Perform multiplication */
|
||||
"mul %0, %5, %6\n\t"
|
||||
"umulh %1, %5, %6\n\t"
|
||||
"mul %0, %4, %5\n\t"
|
||||
"umulh %1, %4, %5\n\t"
|
||||
/* Accumulate result */
|
||||
"adds %2, %2, %0\n\t"
|
||||
"adcs %3, %3, %1\n\t"
|
||||
"adc %1, %1, xzr\n\t"
|
||||
/* Accumulate carry (cannot overflow) */
|
||||
"adc %4, %4, xzr\n\t"
|
||||
"adds %2, %2, %3\n\t"
|
||||
"adc %3, %1, xzr\n\t"
|
||||
: "=&r" ( discard_low ),
|
||||
"=r" ( discard_high ),
|
||||
"+r" ( result[0] ),
|
||||
"+r" ( result[1] ),
|
||||
"+r" ( *result ),
|
||||
"+r" ( *carry )
|
||||
: "r" ( multiplicand ),
|
||||
"r" ( multiplier ) );
|
||||
"r" ( multiplier )
|
||||
: "cc" );
|
||||
}
|
||||
|
||||
#endif /* _BITS_BIGINT_H */
|
||||
|
||||
@@ -362,7 +362,7 @@ bigint_done_raw ( const uint64_t *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
|
||||
@@ -373,23 +373,20 @@ bigint_multiply_one ( const uint64_t multiplicand, const uint64_t multiplier,
|
||||
uint64_t discard_carry;
|
||||
|
||||
__asm__ __volatile__ ( /* Perform multiplication */
|
||||
"mul.d %0, %6, %7\n\t"
|
||||
"mulh.du %1, %6, %7\n\t"
|
||||
"mul.d %0, %5, %6\n\t"
|
||||
"mulh.du %1, %5, %6\n\t"
|
||||
/* Accumulate low half */
|
||||
"add.d %3, %3, %0\n\t"
|
||||
"sltu %2, %3, %0\n\t"
|
||||
/* Add carry to high half (cannot overflow) */
|
||||
"add.d %1, %1, %2\n\t"
|
||||
/* Accumulate high half */
|
||||
"add.d %4, %4, %1\n\t"
|
||||
"sltu %2, %4, %1\n\t"
|
||||
/* Accumulate carry (cannot overflow) */
|
||||
"add.d %5, %5, %2\n\t"
|
||||
"add.d %3, %3, %4\n\t"
|
||||
"sltu %2, %3, %4\n\t"
|
||||
"add.d %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 ) );
|
||||
|
||||
@@ -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 ) );
|
||||
|
||||
@@ -327,29 +327,28 @@ bigint_done_raw ( const uint32_t *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
|
||||
bigint_multiply_one ( const uint32_t multiplicand, const uint32_t multiplier,
|
||||
uint32_t *result, uint32_t *carry ) {
|
||||
uint32_t discard_a;
|
||||
uint32_t discard_d;
|
||||
|
||||
__asm__ __volatile__ ( /* Perform multiplication */
|
||||
"mull %6\n\t"
|
||||
"mull %3\n\t"
|
||||
/* Accumulate carry */
|
||||
"addl %5, %0\n\t"
|
||||
"adcl $0, %1\n\t"
|
||||
/* Accumulate result */
|
||||
"addl %0, %2\n\t"
|
||||
"adcl %1, %3\n\t"
|
||||
/* Accumulate carry (cannot overflow) */
|
||||
"adcl $0, %4\n\t"
|
||||
: "=a" ( discard_a ),
|
||||
"=d" ( discard_d ),
|
||||
"+m" ( result[0] ),
|
||||
"+m" ( result[1] ),
|
||||
"+m" ( *carry )
|
||||
: "0" ( multiplicand ),
|
||||
"g" ( multiplier ) );
|
||||
"adcl $0, %1\n\t"
|
||||
: "=&a" ( discard_a ),
|
||||
"=&d" ( *carry ),
|
||||
"+m" ( *result )
|
||||
: "g" ( multiplicand ),
|
||||
"0" ( multiplier ),
|
||||
"r" ( *carry ) );
|
||||
}
|
||||
|
||||
#endif /* _BITS_BIGINT_H */
|
||||
|
||||
Reference in New Issue
Block a user