LibCrypto: Improve efficiency of UnsignedBigInteger::shift_left

Before:
- a separate Word element allocation of the underlying Vector<Word> was
necessary for every new word in a multi-word shift
- two additional temporary UnsignedBigInteger buffers were allocated
and passed through, including in downstream calls (e.g. Multiplication)
- an additional allocation and word shift for the carry
- FIXME note seems to point to some of these issues

After:
- main change is in LibCrypto/BigInt/Algorithms/BitwiseOperations.cpp
- one single allocation per call, using shift_left_by_n_words
- only the input "number" and "output" need to be allocated by the
  caller
- downstream calls are adapted not to allocate or pass temporary
  buffers
- noticeable performance improvement when running TestBigInteger:
  0.41-0.42s (before) to 0.28-0.29s (after) Intel Core i9 laptop

Bonus: remove unused variables from UnsignedBigInteger::divided_by
- These were likely cut-and-paste artifacts from
  UnsignedBigInteger::multiplied_by; not caught by "unused-varible".

NOTE: making this change in a separate commit than shift_right, even if
it touches the same file BitwiseOperations.cpp since:
- it is a "bonus" addition: not necessary for fixing the shift_right
  bug, but logically unrelated to the shift_right code
- it brings a chain of downstream interface modifications (7 files),
  unrelated to shift_right
This commit is contained in:
Manuel Zahariev 2025-01-08 08:51:40 -08:00 committed by Ali Mohammad Pur
parent 05cfbdd6fb
commit d2ea77c099
Notes: github-actions[bot] 2025-03-23 18:34:27 +00:00
9 changed files with 60 additions and 74 deletions

View file

@ -46,8 +46,6 @@ void UnsignedBigIntegerAlgorithms::extended_GCD_without_allocation(
UnsignedBigInteger& temp_quotient,
UnsignedBigInteger& temp_1,
UnsignedBigInteger& temp_2,
UnsignedBigInteger& temp_shift_result,
UnsignedBigInteger& temp_shift_plus,
UnsignedBigInteger& temp_shift,
UnsignedBigInteger& temp_r,
UnsignedBigInteger& temp_s,
@ -66,7 +64,7 @@ void UnsignedBigIntegerAlgorithms::extended_GCD_without_allocation(
divide_without_allocation(gcd, temp_r, temp_quotient, temp_1);
temp_2.set_to(temp_r);
multiply_without_allocation(temp_quotient, temp_r, temp_shift_result, temp_shift_plus, temp_shift, temp_1);
multiply_without_allocation(temp_quotient, temp_r, temp_shift, temp_1);
while (gcd < temp_1) {
add_into_accumulator_without_allocation(gcd, b);
}
@ -75,7 +73,7 @@ void UnsignedBigIntegerAlgorithms::extended_GCD_without_allocation(
// (old_s, s) := (s, old_s quotient × s)
temp_2.set_to(temp_s);
multiply_without_allocation(temp_quotient, temp_s, temp_shift_result, temp_shift_plus, temp_shift, temp_1);
multiply_without_allocation(temp_quotient, temp_s, temp_shift, temp_1);
while (x < temp_1) {
add_into_accumulator_without_allocation(x, b);
}
@ -84,7 +82,7 @@ void UnsignedBigIntegerAlgorithms::extended_GCD_without_allocation(
// (old_t, t) := (t, old_t quotient × t)
temp_2.set_to(temp_t);
multiply_without_allocation(temp_quotient, temp_t, temp_shift_result, temp_shift_plus, temp_shift, temp_1);
multiply_without_allocation(temp_quotient, temp_t, temp_shift, temp_1);
while (y < temp_1) {
add_into_accumulator_without_allocation(y, b);
}