]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[crypto] Eliminate temporary carry space for big integer multiplication
authorMichael Brown <mcb30@ipxe.org>
Thu, 26 Sep 2024 15:24:57 +0000 (16:24 +0100)
committerMichael Brown <mcb30@ipxe.org>
Fri, 27 Sep 2024 12:51:24 +0000 (13:51 +0100)
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>
src/arch/arm32/include/bits/bigint.h
src/arch/arm64/include/bits/bigint.h
src/arch/loong64/include/bits/bigint.h
src/arch/riscv/include/bits/bigint.h
src/arch/x86/include/bits/bigint.h
src/crypto/bigint.c
src/crypto/x25519.c
src/include/ipxe/bigint.h
src/tests/bigint_test.c

index 0a368a0c014a90c92bd0bf7809674e4f1294422a..c148d6be22ae36d8d8c74f3ee92a1917b9087fc1 100644 (file)
@@ -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 */
index ca9feafbed4c764b20b05a7b46a5d4498fd253e0..6b62c809ec641abb1e27744ec8f22c75d8153c18 100644 (file)
@@ -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 */
index ec6ca4b8999b17b45f7b596a07eeb579f812673d..23edaeea59e92ea5fe79cecbdab0070d834b08dc 100644 (file)
@@ -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 ) );
index c582334699b9fc55655d46336c05d7a3cd2723c8..13fd1675923bac089ef7a26d2907ee0f210f9f10 100644 (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 ) );
index a481e90f74ec94b627e63a5b1a9053498be13e72..320d49498895c4107b43e482f5bd429b9d02e695 100644 (file)
@@ -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 */
index 5b7116e281d638ba7ffc89c6f4c09a9b3aa93e0b..b63f7ccc1ce17469138fa672f33d14fa784203f8 100644 (file)
@@ -83,14 +83,12 @@ void bigint_swap_raw ( bigint_element_t *first0, bigint_element_t *second0,
  * @v multiplier0      Element 0 of big integer to be multiplied
  * @v multiplier_size  Number of elements in multiplier
  * @v result0          Element 0 of big integer to hold result
- * @v carry0           Element 0 of big integer to hold temporary carry
  */
 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 ) {
        unsigned int result_size = ( multiplicand_size + multiplier_size );
        const bigint_t ( multiplicand_size ) __attribute__ (( may_alias ))
                *multiplicand = ( ( const void * ) multiplicand0 );
@@ -98,89 +96,51 @@ void bigint_multiply_raw ( const bigint_element_t *multiplicand0,
                *multiplier = ( ( const void * ) multiplier0 );
        bigint_t ( result_size ) __attribute__ (( may_alias ))
                *result = ( ( void * ) result0 );
-       bigint_t ( result_size ) __attribute__ (( may_alias ))
-               *carry = ( ( void * ) carry0 );
        bigint_element_t multiplicand_element;
        const bigint_element_t *multiplier_element;
-       bigint_element_t *result_elements;
-       bigint_element_t *carry_element;
+       bigint_element_t *result_element;
+       bigint_element_t carry_element;
        unsigned int i;
        unsigned int j;
 
-       /* Zero result and temporary carry space */
-       memset ( result, 0, sizeof ( *result ) );
-       memset ( carry, 0, sizeof ( *carry ) );
+       /* Zero required portion of result
+        *
+        * All elements beyond the length of the multiplier will be
+        * written before they are read, and so do not need to be
+        * zeroed in advance.
+        */
+       memset ( result, 0, sizeof ( *multiplier ) );
 
-       /* Multiply integers one element at a time, adding the double
-        * element directly into the result and accumulating any
-        * overall carry out from this double-element addition into
-        * the temporary carry space.
+       /* Multiply integers one element at a time, adding the low
+        * half of the double-element product directly into the
+        * result, and maintaining a running single-element carry.
+        *
+        * The running carry can never overflow beyond a single
+        * element.  At each step, the calculation we perform is:
         *
-        * We could propagate the carry immediately instead of using a
-        * temporary carry space.  However, this would cause the
-        * multiplication to run in non-constant time, which is
-        * undesirable.
+        *   carry:result[i+j] := ( ( multiplicand[i] * multiplier[j] )
+        *                          + result[i+j] + carry )
         *
-        * The carry elements can never overflow, provided that the
-        * element size is large enough to accommodate any plausible
-        * big integer.  The total number of potential carries (across
-        * all elements) is the sum of the number of elements in the
-        * multiplicand and multiplier.  With a 16-bit element size,
-        * this therefore allows for up to a 1Mbit multiplication
-        * result (e.g. a 512kbit integer multiplied by another
-        * 512kbit integer), which is around 100x higher than could be
-        * needed in practice.  With a more realistic 32-bit element
-        * size, the limit becomes a totally implausible 128Gbit
-        * multiplication result.
+        * The maximum value (for n-bit elements) is therefore:
+        *
+        *   (2^n - 1)*(2^n - 1) + (2^n - 1) + (2^n - 1) = 2^(2n) - 1
+        *
+        * This is precisely the maximum value for a 2n-bit integer,
+        * and so the carry out remains within the range of an n-bit
+        * integer, i.e. a single element.
         */
        for ( i = 0 ; i < multiplicand_size ; i++ ) {
                multiplicand_element = multiplicand->element[i];
                multiplier_element = &multiplier->element[0];
-               result_elements = &result->element[i];
-               carry_element = &carry->element[i];
+               result_element = &result->element[i];
+               carry_element = 0;
                for ( j = 0 ; j < multiplier_size ; j++ ) {
                        bigint_multiply_one ( multiplicand_element,
                                              *(multiplier_element++),
-                                             result_elements++,
-                                             carry_element++ );
+                                             result_element++,
+                                             &carry_element );
                }
-       }
-
-       /* Add the temporary carry into the result.  The least
-        * significant element of the carry represents the carry out
-        * from multiplying the least significant elements of the
-        * multiplicand and multiplier, and therefore must be added to
-        * the third-least significant element of the result (i.e. the
-        * carry needs to be shifted left by two elements before being
-        * adding to the result).
-        *
-        * The most significant two elements of the carry are
-        * guaranteed to be zero, since:
-        *
-        *     a < 2^{n}, b < 2^{m} => ab < 2^{n+m}
-        *
-        * and the overall result of the multiplication (including
-        * adding in the shifted carries) is therefore guaranteed not
-        * to overflow beyond the end of the result.
-        *
-        * We could avoid this shifting by writing the carry directly
-        * into the "correct" element during the element-by-element
-        * multiplication stage above.  However, this would add
-        * complexity to the loop since we would have to arrange for
-        * the (provably zero) most significant two carry out results
-        * to be discarded, in order to avoid writing beyond the end
-        * of the temporary carry space.
-        *
-        * Performing the logical shift is essentially free, since we
-        * simply adjust the element pointers.
-        *
-        * To avoid requiring additional checks in each architecture's
-        * implementation of bigint_add_raw(), we explicitly avoid
-        * calling bigint_add_raw() with a size of zero.
-        */
-       if ( result_size > 2 ) {
-               bigint_add_raw ( &carry->element[0], &result->element[2],
-                                ( result_size - 2 ) );
+               *result_element = carry_element;
        }
 }
 
@@ -209,10 +169,7 @@ void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0,
                ( ( void * ) result0 );
        struct {
                bigint_t ( size * 2 ) result;
-               union {
-                       bigint_t ( size * 2 ) modulus;
-                       bigint_t ( size * 2 ) carry;
-               };
+               bigint_t ( size * 2 ) modulus;
        } *temp = tmp;
        int rotation;
        int i;
@@ -225,8 +182,7 @@ void bigint_mod_multiply_raw ( const bigint_element_t *multiplicand0,
 
        /* Perform multiplication */
        profile_start ( &bigint_mod_multiply_multiply_profiler );
-       bigint_multiply ( multiplicand, multiplier, &temp->result,
-                         &temp->carry );
+       bigint_multiply ( multiplicand, multiplier, &temp->result );
        profile_stop ( &bigint_mod_multiply_multiply_profiler );
 
        /* Rescale modulus to match result */
index 553f43d345870300021303f2adccd721333be27a..d58f7168c37629d4e23429fb2983dba3320a000c 100644 (file)
@@ -43,7 +43,7 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
  * Storage size of each big integer         128              40
  * (in bytes)
  *
- * Stack usage for key exchange                    1144             424
+ * Stack usage for key exchange                    1144             360
  * (in bytes, large objects only)
  *
  * Cost of big integer addition                      16               5
@@ -207,60 +207,35 @@ union x25519_multiply_step3 {
  * We overlap the buffers used by each step of the multiplication
  * calculation to reduce the total stack space required:
  *
- * |--------------------------------------------------------------------------|
- * | <------- step 1 carry ------> | <----------- step 1 result ------------> |
- * |                               | <- low 256 bits -> | <- high 260 bits -> |
- * | <- step 2 carry -> | <-- step 2 result --> | <pad> |                     |
- * | <- s3 carry -> | <--------- pad ---------> | <- step 3 result -> |       |
- * |--------------------------------------------------------------------------|
+ * |--------------------------------------------------------|
+ * | <- pad -> | <------------ step 1 result -------------> |
+ * |           | <- low 256 bits -> | <-- high 260 bits --> |
+ * | <------- step 2 result ------> | <-- step 3 result --> |
+ * |--------------------------------------------------------|
  */
 union x25519_multiply_workspace {
-       /** Step 1 */
+       /** Step 1 result */
        struct {
-               /** Step 1 temporary carry workspace */
-               union x25519_multiply_step1 carry;
+               /** Padding to avoid collision between steps 1 and 2
+                *
+                * The step 2 multiplication consumes the high 260
+                * bits of step 1, and so the step 2 multiplication
+                * result must not overlap this portion of the step 1
+                * result.
+                */
+               uint8_t pad[ sizeof ( union x25519_multiply_step2 ) -
+                            offsetof ( union x25519_multiply_step1,
+                                       parts.high_260bit ) ];
                /** Step 1 result */
-               union x25519_multiply_step1 result;
-       } __attribute__ (( packed )) step1;
-       /** Step 2
-        *
-        * The step 2 multiplication consumes the high 260 bits of
-        * step 1, and so the step 2 multiplication result (and
-        * temporary carry workspace) must not overlap this portion of
-        * the step 1 result.
-        */
+               union x25519_multiply_step1 step1;
+       } __attribute__ (( packed ));
+       /** Steps 2 and 3 results */
        struct {
-               /** Step 2 temporary carry workspace */
-               union x25519_multiply_step2 carry;
                /** Step 2 result */
-               union x25519_multiply_step2 result;
-               /** Avoid collision between step 1 result and step 2 result */
-               uint8_t pad[ ( int )
-                            ( sizeof ( union x25519_multiply_step1 ) +
-                              offsetof ( union x25519_multiply_step1,
-                                         parts.high_260bit ) -
-                              sizeof ( union x25519_multiply_step2 ) -
-                              sizeof ( union x25519_multiply_step2 ) ) ];
-       } __attribute__ (( packed )) step2;
-       /** Step 3
-        *
-        * The step 3 multiplication consumes the high 11 bits of step
-        * 2, and so the step 3 multiplication result (and temporary
-        * carry workspace) must not overlap this portion of the step
-        * 2 result.
-        */
-       struct {
-               /** Step 3 temporary carry workspace */
-               union x25519_multiply_step3 carry;
-               /** Avoid collision between step 2 result and step 3 carry */
-               uint8_t pad1[ ( int )
-                             ( sizeof ( union x25519_multiply_step2 ) -
-                               sizeof ( union x25519_multiply_step3 ) ) ];
-               /** Avoid collision between step 2 result and step 3 result */
-               uint8_t pad2[ sizeof ( union x25519_multiply_step2 ) ];
+               union x25519_multiply_step2 step2;
                /** Step 3 result */
-               union x25519_multiply_step3 result;
-       } __attribute__ (( packed )) step3;
+               union x25519_multiply_step3 step3;
+       } __attribute__ (( packed ));
 };
 
 /** An X25519 elliptic curve point in projective coordinates
@@ -451,9 +426,9 @@ void x25519_multiply ( const union x25519_oct258 *multiplicand,
                       const union x25519_oct258 *multiplier,
                       union x25519_quad257 *result ) {
        union x25519_multiply_workspace tmp;
-       union x25519_multiply_step1 *step1 = &tmp.step1.result;
-       union x25519_multiply_step2 *step2 = &tmp.step2.result;
-       union x25519_multiply_step3 *step3 = &tmp.step3.result;
+       union x25519_multiply_step1 *step1 = &tmp.step1;
+       union x25519_multiply_step2 *step2 = &tmp.step2;
+       union x25519_multiply_step3 *step3 = &tmp.step3;
 
        /* Step 1: perform raw multiplication
         *
@@ -464,7 +439,7 @@ void x25519_multiply ( const union x25519_oct258 *multiplicand,
         */
        static_assert ( sizeof ( step1->product ) >= sizeof ( step1->parts ) );
        bigint_multiply ( &multiplicand->value, &multiplier->value,
-                         &step1->product, &tmp.step1.carry.product );
+                         &step1->product );
 
        /* Step 2: reduce high-order 516-256=260 bits of step 1 result
         *
@@ -490,7 +465,7 @@ void x25519_multiply ( const union x25519_oct258 *multiplicand,
        static_assert ( sizeof ( step2->product ) >= sizeof ( step2->parts ) );
        bigint_grow ( &step1->parts.low_256bit, &result->value );
        bigint_multiply ( &step1->parts.high_260bit, &x25519_reduce_256,
-                         &step2->product, &tmp.step2.carry.product );
+                         &step2->product );
        bigint_add ( &result->value, &step2->value );
 
        /* Step 3: reduce high-order 267-256=11 bits of step 2 result
@@ -528,7 +503,7 @@ void x25519_multiply ( const union x25519_oct258 *multiplicand,
        memset ( &step3->value, 0, sizeof ( step3->value ) );
        bigint_grow ( &step2->parts.low_256bit, &result->value );
        bigint_multiply ( &step2->parts.high_11bit, &x25519_reduce_256,
-                         &step3->product, &tmp.step3.carry.product );
+                         &step3->product );
        bigint_add ( &step3->value, &result->value );
 
        /* Step 1 calculates the product of the input operands, and
index efe1565962db8ab08678b97cf7cf93211f90a341..bcb7af5ec6a2f855a4858114bdc2a63b738df440 100644 (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,
index fcc77f25f4c744e0712b2c088e47771243a9f21d..76aca1059e3d943cd07444f7d33ad98c080e68d7 100644 (file)
@@ -173,8 +173,7 @@ void bigint_multiply_sample ( 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 ) {
        unsigned int result_size = ( multiplicand_size + multiplier_size );
        const bigint_t ( multiplicand_size ) __attribute__ (( may_alias ))
                *multiplicand = ( ( const void * ) multiplicand0 );
@@ -182,10 +181,8 @@ void bigint_multiply_sample ( const bigint_element_t *multiplicand0,
                *multiplier = ( ( const void * ) multiplier0 );
        bigint_t ( result_size ) __attribute__ (( may_alias ))
                *result = ( ( void * ) result0 );
-       bigint_t ( result_size ) __attribute__ (( may_alias ))
-               *carry = ( ( void * ) carry0 );
 
-       bigint_multiply ( multiplicand, multiplier, result, carry );
+       bigint_multiply ( multiplicand, multiplier, result );
 }
 
 void bigint_mod_multiply_sample ( const bigint_element_t *multiplicand0,
@@ -498,14 +495,11 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
        bigint_t ( multiplicand_size ) multiplicand_temp;               \
        bigint_t ( multiplier_size ) multiplier_temp;                   \
        bigint_t ( multiplicand_size + multiplier_size ) result_temp;   \
-       bigint_t ( multiplicand_size + multiplier_size ) carry_temp;    \
        {} /* Fix emacs alignment */                                    \
                                                                        \
        assert ( bigint_size ( &result_temp ) ==                        \
                 ( bigint_size ( &multiplicand_temp ) +                 \
                   bigint_size ( &multiplier_temp ) ) );                \
-       assert ( bigint_size ( &carry_temp ) ==                         \
-                bigint_size ( &result_temp ) );                        \
        bigint_init ( &multiplicand_temp, multiplicand_raw,             \
                      sizeof ( multiplicand_raw ) );                    \
        bigint_init ( &multiplier_temp, multiplier_raw,                 \
@@ -514,7 +508,7 @@ void bigint_mod_exp_sample ( const bigint_element_t *base0,
        DBG_HDA ( 0, &multiplicand_temp, sizeof ( multiplicand_temp ) );\
        DBG_HDA ( 0, &multiplier_temp, sizeof ( multiplier_temp ) );    \
        bigint_multiply ( &multiplicand_temp, &multiplier_temp,         \
-                         &result_temp, &carry_temp );                  \
+                         &result_temp );                               \
        DBG_HDA ( 0, &result_temp, sizeof ( result_temp ) );            \
        bigint_done ( &result_temp, result_raw, sizeof ( result_raw ) );\
                                                                        \