[crypto] Use Montgomery reduction for modular exponentiation

Speed up modular exponentiation by using Montgomery reduction rather
than direct modular reduction.

Montgomery reduction in base 2^n requires the modulus to be coprime to
2^n, which would limit us to requiring that the modulus is an odd
number.  Extend the implementation to include support for
exponentiation with even moduli via Garner's algorithm as described in
"Montgomery reduction with even modulus" (Koç, 1994).

Since almost all use cases for modular exponentation require a large
prime (and hence odd) modulus, the support for even moduli could
potentially be removed in future.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Michael Brown
2024-11-25 15:59:22 +00:00
parent 4f7dd7fbba
commit 83ac98ce22
5 changed files with 164 additions and 29 deletions

View File

@@ -746,8 +746,7 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
bigint_t ( size ) modulus_temp; \
bigint_t ( exponent_size ) exponent_temp; \
bigint_t ( size ) result_temp; \
size_t tmp_len = bigint_mod_exp_tmp_len ( &modulus_temp, \
&exponent_temp ); \
size_t tmp_len = bigint_mod_exp_tmp_len ( &modulus_temp ); \
uint8_t tmp[tmp_len]; \
{} /* Fix emacs alignment */ \
\
@@ -2070,6 +2069,14 @@ static void bigint_test_exec ( void ) {
BIGINT ( 0xb9 ),
BIGINT ( 0x39, 0x68, 0xba, 0x7d ),
BIGINT ( 0x17 ) );
bigint_mod_exp_ok ( BIGINT ( 0x71, 0x4d, 0x02, 0xe9 ),
BIGINT ( 0x00, 0x00, 0x00, 0x00 ),
BIGINT ( 0x91, 0x7f, 0x4e, 0x3a, 0x5d, 0x5c ),
BIGINT ( 0x00, 0x00, 0x00, 0x00 ) );
bigint_mod_exp_ok ( BIGINT ( 0x2b, 0xf5, 0x07, 0xaf ),
BIGINT ( 0x6e, 0xb5, 0xda, 0x5a ),
BIGINT ( 0x00, 0x00, 0x00, 0x00, 0x00 ),
BIGINT ( 0x00, 0x00, 0x00, 0x01 ) );
bigint_mod_exp_ok ( BIGINT ( 0x2e ),
BIGINT ( 0xb7 ),
BIGINT ( 0x39, 0x07, 0x1b, 0x49, 0x5b, 0xea,
@@ -2774,6 +2781,25 @@ static void bigint_test_exec ( void ) {
0xfa, 0x83, 0xd4, 0x7c, 0xe9, 0x77,
0x46, 0x91, 0x3a, 0x50, 0x0d, 0x6a,
0x25, 0xd0 ) );
bigint_mod_exp_ok ( BIGINT ( 0x5b, 0x80, 0xc5, 0x03, 0xb3, 0x1e,
0x46, 0x9b, 0xa3, 0x0a, 0x70, 0x43,
0x51, 0x2a, 0x4a, 0x44, 0xcb, 0x87,
0x3e, 0x00, 0x2a, 0x48, 0x46, 0xf5,
0xb3, 0xb9, 0x73, 0xa7, 0x77, 0xfc,
0x2a, 0x1d ),
BIGINT ( 0x5e, 0x8c, 0x80, 0x03, 0xe7, 0xb0,
0x45, 0x23, 0x8f, 0xe0, 0x77, 0x02,
0xc0, 0x7e, 0xfb, 0xc4, 0xbe, 0x7b,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00 ),
BIGINT ( 0x71, 0xd9, 0x38, 0xb6 ),
BIGINT ( 0x52, 0xfc, 0x73, 0x55, 0x2f, 0x86,
0x0f, 0xde, 0x04, 0xbc, 0x6d, 0xb8,
0xfd, 0x48, 0xf8, 0x8c, 0x91, 0x1c,
0xa0, 0x8a, 0x70, 0xa8, 0xc6, 0x20,
0x0a, 0x0d, 0x3b, 0x2a, 0x92, 0x65,
0x9c, 0x59 ) );
}
/** Big integer self-test */