mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 00:42:44 +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
					
				
					 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.m_words.append(carry_word); | ||||
|         shift_left_by_n_words(temp_plus, temp_result.length(), temp_result); | ||||
|         add_without_allocation(output, temp_result, temp_plus); | ||||
|         output.set_to(temp_plus); | ||||
|         add_into_accumulator_without_allocation(output, temp_result); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -16,7 +16,6 @@ void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation( | |||
|     UnsignedBigInteger& temp_2, | ||||
|     UnsignedBigInteger& temp_3, | ||||
|     UnsignedBigInteger& temp_4, | ||||
|     UnsignedBigInteger& temp_plus, | ||||
|     UnsignedBigInteger& temp_minus, | ||||
|     UnsignedBigInteger& temp_quotient, | ||||
|     UnsignedBigInteger& temp_d, | ||||
|  | @ -30,8 +29,7 @@ void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation( | |||
|     temp_u.set_to(a); | ||||
|     if (a.words()[0] % 2 == 0) { | ||||
|         // u += b
 | ||||
|         add_without_allocation(temp_u, b, temp_plus); | ||||
|         temp_u.set_to(temp_plus); | ||||
|         add_into_accumulator_without_allocation(temp_u, b); | ||||
|     } | ||||
| 
 | ||||
|     temp_v.set_to(b); | ||||
|  | @ -47,14 +45,12 @@ void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation( | |||
|             temp_u.set_to(temp_minus); | ||||
| 
 | ||||
|             // d += x
 | ||||
|             add_without_allocation(temp_d, temp_x, temp_plus); | ||||
|             temp_d.set_to(temp_plus); | ||||
|             add_into_accumulator_without_allocation(temp_d, temp_x); | ||||
| 
 | ||||
|             while (temp_u.words()[0] % 2 == 0) { | ||||
|                 if (temp_d.words()[0] % 2 == 1) { | ||||
|                     // d += b
 | ||||
|                     add_without_allocation(temp_d, b, temp_plus); | ||||
|                     temp_d.set_to(temp_plus); | ||||
|                     add_into_accumulator_without_allocation(temp_d, b); | ||||
|                 } | ||||
| 
 | ||||
|                 // u /= 2
 | ||||
|  | @ -72,14 +68,12 @@ void UnsignedBigIntegerAlgorithms::modular_inverse_without_allocation( | |||
|         temp_v.set_to(temp_minus); | ||||
| 
 | ||||
|         // x += d
 | ||||
|         add_without_allocation(temp_x, temp_d, temp_plus); | ||||
|         temp_x.set_to(temp_plus); | ||||
|         add_into_accumulator_without_allocation(temp_x, temp_d); | ||||
| 
 | ||||
|         while (temp_v.words()[0] % 2 == 0) { | ||||
|             if (temp_x.words()[0] % 2 == 1) { | ||||
|                 // x += b
 | ||||
|                 add_without_allocation(temp_x, b, temp_plus); | ||||
|                 temp_x.set_to(temp_plus); | ||||
|                 add_into_accumulator_without_allocation(temp_x, b); | ||||
|             } | ||||
| 
 | ||||
|             // v /= 2
 | ||||
|  |  | |||
|  | @ -26,7 +26,7 @@ void UnsignedBigIntegerAlgorithms::destructive_modular_power_without_allocation( | |||
|     while (!(ep < 1)) { | ||||
|         if (ep.words()[0] % 2 == 1) { | ||||
|             // 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); | ||||
|             exp.set_to(temp_remainder); | ||||
|         } | ||||
|  | @ -36,7 +36,7 @@ void UnsignedBigIntegerAlgorithms::destructive_modular_power_without_allocation( | |||
|         ep.set_to(temp_quotient); | ||||
| 
 | ||||
|         // 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); | ||||
|         base.set_to(temp_remainder); | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,7 +23,6 @@ FLATTEN void UnsignedBigIntegerAlgorithms::multiply_without_allocation( | |||
|     UnsignedBigInteger& temp_shift_result, | ||||
|     UnsignedBigInteger& temp_shift_plus, | ||||
|     UnsignedBigInteger& temp_shift, | ||||
|     UnsignedBigInteger& temp_plus, | ||||
|     UnsignedBigInteger& output) | ||||
| { | ||||
|     output.set_to_0(); | ||||
|  | @ -39,8 +38,7 @@ FLATTEN void UnsignedBigIntegerAlgorithms::multiply_without_allocation( | |||
| 
 | ||||
|             // output += (right << shift_amount);
 | ||||
|             shift_left_without_allocation(right, shift_amount, temp_shift_result, temp_shift_plus, temp_shift); | ||||
|             add_without_allocation(output, temp_shift, temp_plus); | ||||
|             output.set_to(temp_plus); | ||||
|             add_into_accumulator_without_allocation(output, temp_shift); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -20,36 +20,51 @@ void UnsignedBigIntegerAlgorithms::add_without_allocation( | |||
|     const UnsignedBigInteger* const longer = (left.length() > right.length()) ? &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) { | ||||
|         u32 word_addition_result = shorter->m_words[i] + longer->m_words[i]; | ||||
|         u8 carry_out = 0; | ||||
|         // if there was a carry, the result will be smaller than any of the operands
 | ||||
|         if (word_addition_result + carry < shorter->m_words[i]) { | ||||
|             carry_out = 1; | ||||
|     // If needed, resize the accumulator so it can fit the value.
 | ||||
|     accumulator.resize_with_leading_zeros(value_length); | ||||
|     auto final_length = accumulator.length(); | ||||
| 
 | ||||
|     // Add the words of the value into the accumulator, rippling any carry as we go
 | ||||
|     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) { | ||||
|             word_addition_result++; | ||||
|         UnsignedBigInteger::Word word_addition_result = value.m_words[i] + accumulator.m_words[i]; | ||||
|         if (Checked<UnsignedBigInteger::Word>::addition_would_overflow(word_addition_result, last_carry_for_word)) { | ||||
|             current_carry_for_word = 1; | ||||
|         } | ||||
|         carry = carry_out; | ||||
|         output.m_words[i] = word_addition_result; | ||||
|         word_addition_result += last_carry_for_word; | ||||
|         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) { | ||||
|         u32 word_addition_result = longer->m_words[i] + carry; | ||||
| 
 | ||||
|         carry = 0; | ||||
|         if (word_addition_result < longer->m_words[i]) { | ||||
|             carry = 1; | ||||
|     // Ripple the carry over the remaining words in the accumulator until either there is no carry left or we run out of words
 | ||||
|     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; | ||||
|         } | ||||
|         output.m_words[i] = word_addition_result; | ||||
|         accumulator.m_words[value_length] += last_carry_for_word; | ||||
|         last_carry_for_word = current_carry_for_word; | ||||
|         value_length++; | ||||
|     } | ||||
|     if (carry) { | ||||
|         output.m_words.append(carry); | ||||
| 
 | ||||
|     if (last_carry_for_word) { | ||||
|         // Note : The accumulator couldn't add the carry directly, so we reached its end
 | ||||
|         accumulator.m_words.append(last_carry_for_word); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  |  | |||
|  | @ -13,18 +13,19 @@ namespace Crypto { | |||
| class UnsignedBigIntegerAlgorithms { | ||||
| public: | ||||
|     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 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_xor_without_allocation(UnsignedBigInteger const& left, UnsignedBigInteger const& right, 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 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_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 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); | ||||
| 
 | ||||
| private: | ||||
|  |  | |||
|  | @ -144,6 +144,15 @@ void UnsignedBigInteger::clamp_to_trimmed_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 | ||||
| { | ||||
|     UnsignedBigInteger result; | ||||
|  | @ -215,9 +224,8 @@ FLATTEN UnsignedBigInteger UnsignedBigInteger::multiplied_by(const UnsignedBigIn | |||
|     UnsignedBigInteger temp_shift_result; | ||||
|     UnsignedBigInteger temp_shift_plus; | ||||
|     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; | ||||
| } | ||||
|  |  | |||
|  | @ -65,6 +65,7 @@ public: | |||
|     size_t trimmed_length() const; | ||||
| 
 | ||||
|     void clamp_to_trimmed_length(); | ||||
|     void resize_with_leading_zeros(size_t num_words); | ||||
| 
 | ||||
|     UnsignedBigInteger plus(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_3; | ||||
|     UnsignedBigInteger temp_4; | ||||
|     UnsignedBigInteger temp_plus; | ||||
|     UnsignedBigInteger temp_minus; | ||||
|     UnsignedBigInteger temp_quotient; | ||||
|     UnsignedBigInteger temp_d; | ||||
|  | @ -29,7 +28,7 @@ UnsignedBigInteger ModularInverse(const UnsignedBigInteger& a_, const UnsignedBi | |||
|     UnsignedBigInteger temp_x; | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
|  | @ -93,7 +92,7 @@ UnsignedBigInteger LCM(const UnsignedBigInteger& a, const UnsignedBigInteger& 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::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); | ||||
| 
 | ||||
|  |  | |||
|  | @ -12,6 +12,7 @@ | |||
| #include <LibCrypto/ASN1/ASN1.h> | ||||
| #include <LibCrypto/Authentication/GHash.h> | ||||
| #include <LibCrypto/Authentication/HMAC.h> | ||||
| #include <LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h> | ||||
| #include <LibCrypto/BigInt/SignedBigInteger.h> | ||||
| #include <LibCrypto/BigInt/UnsignedBigInteger.h> | ||||
| #include <LibCrypto/Checksum/Adler32.h> | ||||
|  | @ -2244,6 +2245,94 @@ static void bigint_addition_edgecases() | |||
|             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() | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 DexesTTP
						DexesTTP