]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Use inverse size as effective size for bigint_mod_invert()
authorMichael Brown <mcb30@ipxe.org>
Wed, 27 Nov 2024 12:56:22 +0000 (12:56 +0000)
committerMichael Brown <mcb30@ipxe.org>
Wed, 27 Nov 2024 13:16:05 +0000 (13:16 +0000)
Montgomery reduction requires only the least significant element of an
inverse modulo 2^k, which in turn depends upon only the least
significant element of the invertend.

Use the inverse size (rather than the invertend size) as the effective
size for bigint_mod_invert().  This eliminates around 97% of the loop
iterations for a typical 2048-bit RSA modulus.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/bigint.h
src/tests/bigint_test.c

index e55c536c761738c04d02ca0b9193caa7f5de98cc..14f3c5f2845a60e3b0aa0cf04286f67fa955f5c1 100644 (file)
@@ -248,7 +248,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * @v inverse          Big integer to hold result
  */
 #define bigint_mod_invert( invertend, inverse ) do {                   \
-       unsigned int size = bigint_size ( invertend );                  \
+       unsigned int size = bigint_size ( inverse );                    \
        bigint_mod_invert_raw ( (invertend)->element,                   \
                                (inverse)->element, size );             \
        } while ( 0 )
index 608d8e874ca494270fc4e1fd2c20d7fc2ec3bf7f..bee36de25be95ffedd663e597b844d0f856614a2 100644 (file)
@@ -596,14 +596,14 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
        static const uint8_t invertend_raw[] = invertend;               \
        static const uint8_t expected_raw[] = expected;                 \
        uint8_t inverse_raw[ sizeof ( expected_raw ) ];                 \
-       unsigned int size =                                             \
+       unsigned int invertend_size =                                   \
                bigint_required_size ( sizeof ( invertend_raw ) );      \
-       bigint_t ( size ) invertend_temp;                               \
-       bigint_t ( size ) inverse_temp;                                 \
+       unsigned int inverse_size =                                     \
+               bigint_required_size ( sizeof ( inverse_raw ) );        \
+       bigint_t ( invertend_size ) invertend_temp;                     \
+       bigint_t ( inverse_size ) inverse_temp;                         \
        {} /* Fix emacs alignment */                                    \
                                                                        \
-       assert ( bigint_size ( &invertend_temp ) ==                     \
-                bigint_size ( &inverse_temp ) );                       \
        bigint_init ( &invertend_temp, invertend_raw,                   \
                      sizeof ( invertend_raw ) );                       \
        DBG ( "Modular invert:\n" );                                    \
@@ -1853,6 +1853,11 @@ static void bigint_test_exec ( void ) {
                                        0xb3, 0xe1, 0x3e, 0xc6, 0x5a, 0x03,
                                        0x51, 0x6f, 0xb7, 0xe3, 0xa5, 0xd6,
                                        0xa1, 0xb9 ) );
+       bigint_mod_invert_ok ( BIGINT ( 0xfe, 0x43, 0xf6, 0xa0, 0x32, 0x02,
+                                       0x47, 0xaa, 0xaa, 0x0e, 0x33, 0x19,
+                                       0x2e, 0xe6, 0x22, 0x07 ),
+                              BIGINT ( 0x7b, 0xd1, 0x0f, 0x78, 0x0c, 0x65,
+                                       0xab, 0xb7 ) );
        bigint_mod_multiply_ok ( BIGINT ( 0x37 ),
                                 BIGINT ( 0x67 ),
                                 BIGINT ( 0x3f ),