mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-05-12 22:22:55 +00:00
LibCrypto: Add a += operation to UnsignedBigIntegerAlgorithms
This new operation is immediately used in several existing algorithms.
This commit is contained in:
parent
f4e6f58cc6
commit
5071989545
Notes:
sideshowbarker
2024-07-18 18:13:44 +09:00
Author: https://github.com/Dexesttp
Commit: 5071989545
Pull-request: https://github.com/SerenityOS/serenity/pull/7067
Reviewed-by: https://github.com/alimpfard
10 changed files with 151 additions and 47 deletions
|
@ -199,8 +199,7 @@ FLATTEN void UnsignedBigIntegerAlgorithms::shift_left_without_allocation(
|
||||||
temp_plus.set_to_0();
|
temp_plus.set_to_0();
|
||||||
temp_plus.m_words.append(carry_word);
|
temp_plus.m_words.append(carry_word);
|
||||||
shift_left_by_n_words(temp_plus, temp_result.length(), temp_result);
|
shift_left_by_n_words(temp_plus, temp_result.length(), temp_result);
|
||||||
add_without_allocation(output, temp_result, temp_plus);
|
add_into_accumulator_without_allocation(output, temp_result);
|
||||||
output.set_to(temp_plus);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,6 @@ void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation(
|
||||||
UnsignedBigInteger& temp_2,
|
UnsignedBigInteger& temp_2,
|
||||||
UnsignedBigInteger& temp_3,
|
UnsignedBigInteger& temp_3,
|
||||||
UnsignedBigInteger& temp_4,
|
UnsignedBigInteger& temp_4,
|
||||||
UnsignedBigInteger& temp_plus,
|
|
||||||
UnsignedBigInteger& temp_minus,
|
UnsignedBigInteger& temp_minus,
|
||||||
UnsignedBigInteger& temp_quotient,
|
UnsignedBigInteger& temp_quotient,
|
||||||
UnsignedBigInteger& temp_d,
|
UnsignedBigInteger& temp_d,
|
||||||
|
@ -30,8 +29,7 @@ void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation(
|
||||||
temp_u.set_to(a);
|
temp_u.set_to(a);
|
||||||
if (a.words()[0] % 2 == 0) {
|
if (a.words()[0] % 2 == 0) {
|
||||||
// u += b
|
// u += b
|
||||||
add_without_allocation(temp_u, b, temp_plus);
|
add_into_accumulator_without_allocation(temp_u, b);
|
||||||
temp_u.set_to(temp_plus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
temp_v.set_to(b);
|
temp_v.set_to(b);
|
||||||
|
@ -47,14 +45,12 @@ void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation(
|
||||||
temp_u.set_to(temp_minus);
|
temp_u.set_to(temp_minus);
|
||||||
|
|
||||||
// d += x
|
// d += x
|
||||||
add_without_allocation(temp_d, temp_x, temp_plus);
|
add_into_accumulator_without_allocation(temp_d, temp_x);
|
||||||
temp_d.set_to(temp_plus);
|
|
||||||
|
|
||||||
while (temp_u.words()[0] % 2 == 0) {
|
while (temp_u.words()[0] % 2 == 0) {
|
||||||
if (temp_d.words()[0] % 2 == 1) {
|
if (temp_d.words()[0] % 2 == 1) {
|
||||||
// d += b
|
// d += b
|
||||||
add_without_allocation(temp_d, b, temp_plus);
|
add_into_accumulator_without_allocation(temp_d, b);
|
||||||
temp_d.set_to(temp_plus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// u /= 2
|
// u /= 2
|
||||||
|
@ -72,14 +68,12 @@ void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation(
|
||||||
temp_v.set_to(temp_minus);
|
temp_v.set_to(temp_minus);
|
||||||
|
|
||||||
// x += d
|
// x += d
|
||||||
add_without_allocation(temp_x, temp_d, temp_plus);
|
add_into_accumulator_without_allocation(temp_x, temp_d);
|
||||||
temp_x.set_to(temp_plus);
|
|
||||||
|
|
||||||
while (temp_v.words()[0] % 2 == 0) {
|
while (temp_v.words()[0] % 2 == 0) {
|
||||||
if (temp_x.words()[0] % 2 == 1) {
|
if (temp_x.words()[0] % 2 == 1) {
|
||||||
// x += b
|
// x += b
|
||||||
add_without_allocation(temp_x, b, temp_plus);
|
add_into_accumulator_without_allocation(temp_x, b);
|
||||||
temp_x.set_to(temp_plus);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// v /= 2
|
// v /= 2
|
||||||
|
|
|
@ -26,7 +26,7 @@ void UnsignedBigIntegerAlgorithms::destructive_modular_power_without_allocation(
|
||||||
while (!(ep < 1)) {
|
while (!(ep < 1)) {
|
||||||
if (ep.words()[0] % 2 == 1) {
|
if (ep.words()[0] % 2 == 1) {
|
||||||
// exp = (exp * base) % m;
|
// exp = (exp * base) % m;
|
||||||
multiply_without_allocation(exp, base, temp_1, temp_2, temp_3, temp_4, temp_multiply);
|
multiply_without_allocation(exp, base, temp_1, temp_2, temp_3, temp_multiply);
|
||||||
divide_without_allocation(temp_multiply, m, temp_1, temp_2, temp_3, temp_4, temp_quotient, temp_remainder);
|
divide_without_allocation(temp_multiply, m, temp_1, temp_2, temp_3, temp_4, temp_quotient, temp_remainder);
|
||||||
exp.set_to(temp_remainder);
|
exp.set_to(temp_remainder);
|
||||||
}
|
}
|
||||||
|
@ -36,7 +36,7 @@ void UnsignedBigIntegerAlgorithms::destructive_modular_power_without_allocation(
|
||||||
ep.set_to(temp_quotient);
|
ep.set_to(temp_quotient);
|
||||||
|
|
||||||
// base = (base * base) % m;
|
// base = (base * base) % m;
|
||||||
multiply_without_allocation(base, base, temp_1, temp_2, temp_3, temp_4, temp_multiply);
|
multiply_without_allocation(base, base, temp_1, temp_2, temp_3, temp_multiply);
|
||||||
divide_without_allocation(temp_multiply, m, temp_1, temp_2, temp_3, temp_4, temp_quotient, temp_remainder);
|
divide_without_allocation(temp_multiply, m, temp_1, temp_2, temp_3, temp_4, temp_quotient, temp_remainder);
|
||||||
base.set_to(temp_remainder);
|
base.set_to(temp_remainder);
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,6 @@ FLATTEN void UnsignedBigIntegerAlgorithms::multiply_without_allocation(
|
||||||
UnsignedBigInteger& temp_shift_result,
|
UnsignedBigInteger& temp_shift_result,
|
||||||
UnsignedBigInteger& temp_shift_plus,
|
UnsignedBigInteger& temp_shift_plus,
|
||||||
UnsignedBigInteger& temp_shift,
|
UnsignedBigInteger& temp_shift,
|
||||||
UnsignedBigInteger& temp_plus,
|
|
||||||
UnsignedBigInteger& output)
|
UnsignedBigInteger& output)
|
||||||
{
|
{
|
||||||
output.set_to_0();
|
output.set_to_0();
|
||||||
|
@ -39,8 +38,7 @@ FLATTEN void UnsignedBigIntegerAlgorithms::multiply_without_allocation(
|
||||||
|
|
||||||
// output += (right << shift_amount);
|
// output += (right << shift_amount);
|
||||||
shift_left_without_allocation(right, shift_amount, temp_shift_result, temp_shift_plus, temp_shift);
|
shift_left_without_allocation(right, shift_amount, temp_shift_result, temp_shift_plus, temp_shift);
|
||||||
add_without_allocation(output, temp_shift, temp_plus);
|
add_into_accumulator_without_allocation(output, temp_shift);
|
||||||
output.set_to(temp_plus);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,36 +20,51 @@ void UnsignedBigIntegerAlgorithms::add_without_allocation(
|
||||||
const UnsignedBigInteger* const longer = (left.length() > right.length()) ? &left : &right;
|
const UnsignedBigInteger* const longer = (left.length() > right.length()) ? &left : &right;
|
||||||
const UnsignedBigInteger* const shorter = (longer == &right) ? &left : &right;
|
const UnsignedBigInteger* const shorter = (longer == &right) ? &left : &right;
|
||||||
|
|
||||||
u8 carry = 0;
|
output.set_to(*longer);
|
||||||
|
add_into_accumulator_without_allocation(output, *shorter);
|
||||||
|
}
|
||||||
|
|
||||||
output.set_to_0();
|
/**
|
||||||
output.m_words.resize_and_keep_capacity(longer->length());
|
* Complexity: O(N) where N is the number of words in the larger number
|
||||||
|
*/
|
||||||
|
void UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(UnsignedBigInteger& accumulator, UnsignedBigInteger const& value)
|
||||||
|
{
|
||||||
|
auto value_length = value.trimmed_length();
|
||||||
|
|
||||||
for (size_t i = 0; i < shorter->length(); ++i) {
|
// If needed, resize the accumulator so it can fit the value.
|
||||||
u32 word_addition_result = shorter->m_words[i] + longer->m_words[i];
|
accumulator.resize_with_leading_zeros(value_length);
|
||||||
u8 carry_out = 0;
|
auto final_length = accumulator.length();
|
||||||
// if there was a carry, the result will be smaller than any of the operands
|
|
||||||
if (word_addition_result + carry < shorter->m_words[i]) {
|
// Add the words of the value into the accumulator, rippling any carry as we go
|
||||||
carry_out = 1;
|
UnsignedBigInteger::Word last_carry_for_word = 0;
|
||||||
|
for (size_t i = 0; i < value_length; ++i) {
|
||||||
|
UnsignedBigInteger::Word current_carry_for_word = 0;
|
||||||
|
if (Checked<UnsignedBigInteger::Word>::addition_would_overflow(value.m_words[i], accumulator.m_words[i])) {
|
||||||
|
current_carry_for_word = 1;
|
||||||
}
|
}
|
||||||
if (carry) {
|
UnsignedBigInteger::Word word_addition_result = value.m_words[i] + accumulator.m_words[i];
|
||||||
word_addition_result++;
|
if (Checked<UnsignedBigInteger::Word>::addition_would_overflow(word_addition_result, last_carry_for_word)) {
|
||||||
|
current_carry_for_word = 1;
|
||||||
}
|
}
|
||||||
carry = carry_out;
|
word_addition_result += last_carry_for_word;
|
||||||
output.m_words[i] = word_addition_result;
|
last_carry_for_word = current_carry_for_word;
|
||||||
|
accumulator.m_words[i] = word_addition_result;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = shorter->length(); i < longer->length(); ++i) {
|
// Ripple the carry over the remaining words in the accumulator until either there is no carry left or we run out of words
|
||||||
u32 word_addition_result = longer->m_words[i] + carry;
|
while (last_carry_for_word && final_length > value_length) {
|
||||||
|
UnsignedBigInteger::Word current_carry_for_word = 0;
|
||||||
|
if (Checked<UnsignedBigInteger::Word>::addition_would_overflow(accumulator.m_words[value_length], last_carry_for_word)) {
|
||||||
|
current_carry_for_word = 1;
|
||||||
|
}
|
||||||
|
accumulator.m_words[value_length] += last_carry_for_word;
|
||||||
|
last_carry_for_word = current_carry_for_word;
|
||||||
|
value_length++;
|
||||||
|
}
|
||||||
|
|
||||||
carry = 0;
|
if (last_carry_for_word) {
|
||||||
if (word_addition_result < longer->m_words[i]) {
|
// Note : The accumulator couldn't add the carry directly, so we reached its end
|
||||||
carry = 1;
|
accumulator.m_words.append(last_carry_for_word);
|
||||||
}
|
|
||||||
output.m_words[i] = word_addition_result;
|
|
||||||
}
|
|
||||||
if (carry) {
|
|
||||||
output.m_words.append(carry);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,18 +13,19 @@ namespace Crypto {
|
||||||
class UnsignedBigIntegerAlgorithms {
|
class UnsignedBigIntegerAlgorithms {
|
||||||
public:
|
public:
|
||||||
static void add_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
static void add_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
||||||
|
static void add_into_accumulator_without_allocation(UnsignedBigInteger& accumulator, UnsignedBigInteger const& value);
|
||||||
static void subtract_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
static void subtract_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
||||||
static void bitwise_or_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
static void bitwise_or_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
||||||
static void bitwise_and_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
static void bitwise_and_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
||||||
static void bitwise_xor_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
static void bitwise_xor_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& output);
|
||||||
static void bitwise_not_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger& output);
|
static void bitwise_not_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger& output);
|
||||||
static void shift_left_without_allocation(UnsignedBigInteger const& number, size_t bits_to_shift_by, UnsignedBigInteger& temp_result, UnsignedBigInteger& temp_plus, UnsignedBigInteger& output);
|
static void shift_left_without_allocation(UnsignedBigInteger const& number, size_t bits_to_shift_by, UnsignedBigInteger& temp_result, UnsignedBigInteger& temp_plus, UnsignedBigInteger& output);
|
||||||
static void multiply_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_plus, UnsignedBigInteger& output);
|
static void multiply_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& output);
|
||||||
static void divide_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger const& denominator, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_minus, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder);
|
static void divide_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger const& denominator, UnsignedBigInteger& temp_shift_result, UnsignedBigInteger& temp_shift_plus, UnsignedBigInteger& temp_shift, UnsignedBigInteger& temp_minus, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder);
|
||||||
static void divide_u16_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger::Word denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder);
|
static void divide_u16_without_allocation(UnsignedBigInteger const& numerator, UnsignedBigInteger::Word denominator, UnsignedBigInteger& quotient, UnsignedBigInteger& remainder);
|
||||||
|
|
||||||
static void destructive_GCD_without_allocation(UnsignedBigInteger& temp_a, UnsignedBigInteger& temp_b, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_3, UnsignedBigInteger& temp_4, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_remainder, UnsignedBigInteger& output);
|
static void destructive_GCD_without_allocation(UnsignedBigInteger& temp_a, UnsignedBigInteger& temp_b, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_3, UnsignedBigInteger& temp_4, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_remainder, UnsignedBigInteger& output);
|
||||||
static void modular_inverse_without_allocation(UnsignedBigInteger const& a_, UnsignedBigInteger const& b, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_3, UnsignedBigInteger& temp_4, UnsignedBigInteger& temp_plus, UnsignedBigInteger& temp_minus, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_d, UnsignedBigInteger& temp_u, UnsignedBigInteger& temp_v, UnsignedBigInteger& temp_x, UnsignedBigInteger& result);
|
static void modular_inverse_without_allocation(UnsignedBigInteger const& a_, UnsignedBigInteger const& b, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_3, UnsignedBigInteger& temp_4, UnsignedBigInteger& temp_minus, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_d, UnsignedBigInteger& temp_u, UnsignedBigInteger& temp_v, UnsignedBigInteger& temp_x, UnsignedBigInteger& result);
|
||||||
static void destructive_modular_power_without_allocation(UnsignedBigInteger& ep, UnsignedBigInteger& base, UnsignedBigInteger const& m, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_3, UnsignedBigInteger& temp_4, UnsignedBigInteger& temp_multiply, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_remainder, UnsignedBigInteger& result);
|
static void destructive_modular_power_without_allocation(UnsignedBigInteger& ep, UnsignedBigInteger& base, UnsignedBigInteger const& m, UnsignedBigInteger& temp_1, UnsignedBigInteger& temp_2, UnsignedBigInteger& temp_3, UnsignedBigInteger& temp_4, UnsignedBigInteger& temp_multiply, UnsignedBigInteger& temp_quotient, UnsignedBigInteger& temp_remainder, UnsignedBigInteger& result);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -144,6 +144,15 @@ void UnsignedBigInteger::clamp_to_trimmed_length()
|
||||||
m_words.resize(length);
|
m_words.resize(length);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void UnsignedBigInteger::resize_with_leading_zeros(size_t new_length)
|
||||||
|
{
|
||||||
|
size_t old_length = length();
|
||||||
|
if (old_length < new_length) {
|
||||||
|
m_words.resize_and_keep_capacity(new_length);
|
||||||
|
__builtin_memset(&m_words.data()[old_length], 0, (new_length - old_length) * sizeof(u32));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
FLATTEN UnsignedBigInteger UnsignedBigInteger::plus(const UnsignedBigInteger& other) const
|
FLATTEN UnsignedBigInteger UnsignedBigInteger::plus(const UnsignedBigInteger& other) const
|
||||||
{
|
{
|
||||||
UnsignedBigInteger result;
|
UnsignedBigInteger result;
|
||||||
|
@ -215,9 +224,8 @@ FLATTEN UnsignedBigInteger UnsignedBigInteger::multiplied_by(const UnsignedBigIn
|
||||||
UnsignedBigInteger temp_shift_result;
|
UnsignedBigInteger temp_shift_result;
|
||||||
UnsignedBigInteger temp_shift_plus;
|
UnsignedBigInteger temp_shift_plus;
|
||||||
UnsignedBigInteger temp_shift;
|
UnsignedBigInteger temp_shift;
|
||||||
UnsignedBigInteger temp_plus;
|
|
||||||
|
|
||||||
UnsignedBigIntegerAlgorithms::multiply_without_allocation(*this, other, temp_shift_result, temp_shift_plus, temp_shift, temp_plus, result);
|
UnsignedBigIntegerAlgorithms::multiply_without_allocation(*this, other, temp_shift_result, temp_shift_plus, temp_shift, result);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -65,6 +65,7 @@ public:
|
||||||
size_t trimmed_length() const;
|
size_t trimmed_length() const;
|
||||||
|
|
||||||
void clamp_to_trimmed_length();
|
void clamp_to_trimmed_length();
|
||||||
|
void resize_with_leading_zeros(size_t num_words);
|
||||||
|
|
||||||
UnsignedBigInteger plus(const UnsignedBigInteger& other) const;
|
UnsignedBigInteger plus(const UnsignedBigInteger& other) const;
|
||||||
UnsignedBigInteger minus(const UnsignedBigInteger& other) const;
|
UnsignedBigInteger minus(const UnsignedBigInteger& other) const;
|
||||||
|
|
|
@ -20,7 +20,6 @@ UnsignedBigInteger ModularInverse(const UnsignedBigInteger& a_, const UnsignedBi
|
||||||
UnsignedBigInteger temp_2;
|
UnsignedBigInteger temp_2;
|
||||||
UnsignedBigInteger temp_3;
|
UnsignedBigInteger temp_3;
|
||||||
UnsignedBigInteger temp_4;
|
UnsignedBigInteger temp_4;
|
||||||
UnsignedBigInteger temp_plus;
|
|
||||||
UnsignedBigInteger temp_minus;
|
UnsignedBigInteger temp_minus;
|
||||||
UnsignedBigInteger temp_quotient;
|
UnsignedBigInteger temp_quotient;
|
||||||
UnsignedBigInteger temp_d;
|
UnsignedBigInteger temp_d;
|
||||||
|
@ -29,7 +28,7 @@ UnsignedBigInteger ModularInverse(const UnsignedBigInteger& a_, const UnsignedBi
|
||||||
UnsignedBigInteger temp_x;
|
UnsignedBigInteger temp_x;
|
||||||
UnsignedBigInteger result;
|
UnsignedBigInteger result;
|
||||||
|
|
||||||
UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation(a_, b, temp_1, temp_2, temp_3, temp_4, temp_plus, temp_minus, temp_quotient, temp_d, temp_u, temp_v, temp_x, result);
|
UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation(a_, b, temp_1, temp_2, temp_3, temp_4, temp_minus, temp_quotient, temp_d, temp_u, temp_v, temp_x, result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +92,7 @@ UnsignedBigInteger LCM(const UnsignedBigInteger& a, const UnsignedBigInteger& b)
|
||||||
|
|
||||||
// output = (a / gcd_output) * b
|
// output = (a / gcd_output) * b
|
||||||
UnsignedBigIntegerAlgorithms::divide_without_allocation(a, gcd_output, temp_1, temp_2, temp_3, temp_4, temp_quotient, temp_remainder);
|
UnsignedBigIntegerAlgorithms::divide_without_allocation(a, gcd_output, temp_1, temp_2, temp_3, temp_4, temp_quotient, temp_remainder);
|
||||||
UnsignedBigIntegerAlgorithms::multiply_without_allocation(temp_quotient, b, temp_1, temp_2, temp_3, temp_4, output);
|
UnsignedBigIntegerAlgorithms::multiply_without_allocation(temp_quotient, b, temp_1, temp_2, temp_3, output);
|
||||||
|
|
||||||
dbgln_if(NT_DEBUG, "quot: {} rem: {} out: {}", temp_quotient, temp_remainder, output);
|
dbgln_if(NT_DEBUG, "quot: {} rem: {} out: {}", temp_quotient, temp_remainder, output);
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include <LibCrypto/ASN1/ASN1.h>
|
#include <LibCrypto/ASN1/ASN1.h>
|
||||||
#include <LibCrypto/Authentication/GHash.h>
|
#include <LibCrypto/Authentication/GHash.h>
|
||||||
#include <LibCrypto/Authentication/HMAC.h>
|
#include <LibCrypto/Authentication/HMAC.h>
|
||||||
|
#include <LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h>
|
||||||
#include <LibCrypto/BigInt/SignedBigInteger.h>
|
#include <LibCrypto/BigInt/SignedBigInteger.h>
|
||||||
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
#include <LibCrypto/BigInt/UnsignedBigInteger.h>
|
||||||
#include <LibCrypto/Checksum/Adler32.h>
|
#include <LibCrypto/Checksum/Adler32.h>
|
||||||
|
@ -2244,6 +2245,94 @@ static void bigint_addition_edgecases()
|
||||||
FAIL(Incorrect Result);
|
FAIL(Incorrect Result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | Basic add to accumulator));
|
||||||
|
Crypto::UnsignedBigInteger num1(10);
|
||||||
|
Crypto::UnsignedBigInteger num2(70);
|
||||||
|
Crypto::UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(num1, num2);
|
||||||
|
if (num1.words() == Vector<u32> { 80 }) {
|
||||||
|
PASS;
|
||||||
|
} else {
|
||||||
|
FAIL(Incorrect Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | Add to empty accumulator));
|
||||||
|
Crypto::UnsignedBigInteger num1({});
|
||||||
|
Crypto::UnsignedBigInteger num2(10);
|
||||||
|
Crypto::UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(num1, num2);
|
||||||
|
if (num1.words() == Vector<u32> { 10 }) {
|
||||||
|
PASS;
|
||||||
|
} else {
|
||||||
|
FAIL(Incorrect Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | Add to smaller accumulator));
|
||||||
|
Crypto::UnsignedBigInteger num1(10);
|
||||||
|
Crypto::UnsignedBigInteger num2({ 10, 10 });
|
||||||
|
Crypto::UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(num1, num2);
|
||||||
|
if (num1.words() == Vector<u32> { 20, 10 }) {
|
||||||
|
PASS;
|
||||||
|
} else {
|
||||||
|
FAIL(Incorrect Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | Add to accumulator with carry));
|
||||||
|
Crypto::UnsignedBigInteger num1(UINT32_MAX - 1);
|
||||||
|
Crypto::UnsignedBigInteger num2(2);
|
||||||
|
Crypto::UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(num1, num2);
|
||||||
|
if (num1.words() == Vector<u32> { 0, 1 }) {
|
||||||
|
PASS;
|
||||||
|
} else {
|
||||||
|
FAIL(Incorrect Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | Add to accumulator with multiple carries));
|
||||||
|
Crypto::UnsignedBigInteger num1({ UINT32_MAX - 2, UINT32_MAX - 1 });
|
||||||
|
Crypto::UnsignedBigInteger num2({ 5, 1 });
|
||||||
|
Crypto::UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(num1, num2);
|
||||||
|
if (num1.words() == Vector<u32> { 2, 0, 1 }) {
|
||||||
|
PASS;
|
||||||
|
} else {
|
||||||
|
FAIL(Incorrect Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | Add to accumulator with multiple carry levels));
|
||||||
|
Crypto::UnsignedBigInteger num1({ UINT32_MAX - 2, UINT32_MAX });
|
||||||
|
Crypto::UnsignedBigInteger num2(5);
|
||||||
|
Crypto::UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(num1, num2);
|
||||||
|
if (num1.words() == Vector<u32> { 2, 0, 1 }) {
|
||||||
|
PASS;
|
||||||
|
} else {
|
||||||
|
FAIL(Incorrect Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | Add to accumulator with leading zero));
|
||||||
|
Crypto::UnsignedBigInteger num1(1);
|
||||||
|
Crypto::UnsignedBigInteger num2({ 1, 0 });
|
||||||
|
Crypto::UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(num1, num2);
|
||||||
|
if (num1.words() == Vector<u32> { 2 }) {
|
||||||
|
PASS;
|
||||||
|
} else {
|
||||||
|
FAIL(Incorrect Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
I_TEST((BigInteger | Add to accumulator with carry and leading zero));
|
||||||
|
Crypto::UnsignedBigInteger num1({ UINT32_MAX, 0, 0, 0 });
|
||||||
|
Crypto::UnsignedBigInteger num2({ 1, 0 });
|
||||||
|
Crypto::UnsignedBigIntegerAlgorithms::add_into_accumulator_without_allocation(num1, num2);
|
||||||
|
if (num1.words() == Vector<u32> { 0, 1, 0, 0 }) {
|
||||||
|
PASS;
|
||||||
|
} else {
|
||||||
|
FAIL(Incorrect Result);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bigint_subtraction()
|
static void bigint_subtraction()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue