1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-05-31 07:48:11 +00:00

LibCrypto+LibJS: Better bigint bitwise_or binop

Similar to the bitwise_and change, but we have to be careful to
sign-extend two's complement numbers only up to the highest set bit
in the positive number.
This commit is contained in:
Nico Weber 2022-01-18 08:46:42 -05:00 committed by Ali Mohammad Pur
parent 1f98639396
commit 013799a4dd
8 changed files with 77 additions and 23 deletions

View file

@ -131,9 +131,9 @@ FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_xor_without_allocation(
/**
* Complexity: O(N) where N is the number of words
*/
FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_fill_to_size_without_allocation(
FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_fill_to_one_based_index_without_allocation(
UnsignedBigInteger const& right,
size_t size,
size_t index,
UnsignedBigInteger& output)
{
// If the value is invalid, the output value is invalid as well.
@ -141,17 +141,23 @@ FLATTEN void UnsignedBigIntegerAlgorithms::bitwise_not_fill_to_size_without_allo
output.invalidate();
return;
}
if (size == 0) {
if (index == 0) {
output.set_to_0();
return;
}
size_t size = (index + UnsignedBigInteger::BITS_IN_WORD - 1) / UnsignedBigInteger::BITS_IN_WORD;
output.m_words.resize_and_keep_capacity(size);
size_t i;
for (i = 0; i < min(size, right.length()); ++i)
output.m_words[i] = ~right.words()[i];
for (; i < size; ++i)
output.m_words[i] = NumericLimits<UnsignedBigInteger::Word>::max();
VERIFY(size > 0);
for (size_t i = 0; i < size - 1; ++i)
output.m_words[i] = ~(i < right.length() ? right.words()[i] : 0);
index -= (size - 1) * UnsignedBigInteger::BITS_IN_WORD;
auto last_word_index = size - 1;
auto last_word = last_word_index < right.length() ? right.words()[last_word_index] : 0;
output.m_words[last_word_index] = (NumericLimits<UnsignedBigInteger::Word>::max() >> (UnsignedBigInteger::BITS_IN_WORD - index)) & ~last_word;
}
/**