From 005d75656efd5e1934c4ee88887cff99cc811239 Mon Sep 17 00:00:00 2001 From: Idan Horowitz Date: Tue, 29 Jun 2021 17:51:52 +0300 Subject: [PATCH] LibCrypto: Replace from_base{2,8,10,16}() & to_base10 with from_base(N) This allows us to support parsing and serializing BigIntegers to and from any base N (such that 2 <= N <= 36). --- Tests/LibCrypto/TestBigInteger.cpp | 8 +-- .../LibCrypto/BigInt/SignedBigInteger.cpp | 41 +++--------- .../LibCrypto/BigInt/SignedBigInteger.h | 9 +-- .../LibCrypto/BigInt/UnsignedBigInteger.cpp | 63 +++---------------- .../LibCrypto/BigInt/UnsignedBigInteger.h | 9 +-- .../NumberTheory/ModularFunctions.cpp | 2 +- Userland/Libraries/LibJS/AST.cpp | 8 +-- .../Libraries/LibJS/Bytecode/ASTCodegen.cpp | 2 +- Userland/Libraries/LibJS/Bytecode/Op.cpp | 2 +- Userland/Libraries/LibJS/Runtime/BigInt.h | 2 +- .../LibJS/Runtime/BigIntPrototype.cpp | 2 +- Userland/Libraries/LibJS/Runtime/Value.cpp | 10 +-- Userland/Libraries/LibTLS/Certificate.cpp | 2 +- Userland/Utilities/test-crypto.cpp | 28 ++++----- 14 files changed, 56 insertions(+), 132 deletions(-) diff --git a/Tests/LibCrypto/TestBigInteger.cpp b/Tests/LibCrypto/TestBigInteger.cpp index 6b5638ee75..736dfb5715 100644 --- a/Tests/LibCrypto/TestBigInteger.cpp +++ b/Tests/LibCrypto/TestBigInteger.cpp @@ -234,7 +234,7 @@ TEST_CASE(test_unsigned_bigint_division_combined_test) TEST_CASE(test_unsigned_bigint_base10_from_string) { - auto result = Crypto::UnsignedBigInteger::from_base10("57195071295721390579057195715793"); + auto result = Crypto::UnsignedBigInteger::from_base(10, "57195071295721390579057195715793"); Vector expected_result { 3806301393, 954919431, 3879607298, 721 }; EXPECT_EQ(result.words(), expected_result); } @@ -243,7 +243,7 @@ TEST_CASE(test_unsigned_bigint_base10_to_string) { auto result = Crypto::UnsignedBigInteger { Vector { 3806301393, 954919431, 3879607298, 721 } - }.to_base10(); + }.to_base(10); EXPECT_EQ(result, "57195071295721390579057195715793"); } @@ -386,10 +386,10 @@ TEST_CASE(test_bigint_random_distribution) "100000000000000000000000000000"_bigint); // 10**29 if (actual_result < "100000000000000000000"_bigint) { // 10**20 FAIL("Too small"); - outln("The generated number {} is extremely small. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base10()); + outln("The generated number {} is extremely small. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base(10)); } else if ("99999999900000000000000000000"_bigint < actual_result) { // 10**29 - 10**20 FAIL("Too large"); - outln("The generated number {} is extremely large. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base10()); + outln("The generated number {} is extremely large. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base(10)); } } diff --git a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp index 3ee6df6fdb..f665f401c7 100644 --- a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp +++ b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.cpp @@ -27,57 +27,30 @@ size_t SignedBigInteger::export_data(Bytes data, bool remove_leading_zeros) cons return m_unsigned_data.export_data(bytes_view, remove_leading_zeros) + 1; } -static bool parse_sign(StringView& str) +SignedBigInteger SignedBigInteger::from_base(u16 N, StringView str) { - bool sign = false; + auto sign = false; if (str.length() > 1) { auto maybe_sign = str[0]; if (maybe_sign == '-') { - str = str.substring_view(1, str.length() - 1); + str = str.substring_view(1); sign = true; } if (maybe_sign == '+') - str = str.substring_view(1, str.length() - 1); + str = str.substring_view(1); } - return sign; -} - -SignedBigInteger SignedBigInteger::from_base10(StringView str) -{ - auto sign = parse_sign(str); - auto unsigned_data = UnsignedBigInteger::from_base10(str); + auto unsigned_data = UnsignedBigInteger::from_base(N, str); return { move(unsigned_data), sign }; } -SignedBigInteger SignedBigInteger::from_base2(StringView str) -{ - auto sign = parse_sign(str); - auto unsigned_data = UnsignedBigInteger::from_base2(str); - return { move(unsigned_data), sign }; -} - -SignedBigInteger SignedBigInteger::from_base8(StringView str) -{ - auto sign = parse_sign(str); - auto unsigned_data = UnsignedBigInteger::from_base8(str); - return { move(unsigned_data), sign }; -} - -SignedBigInteger SignedBigInteger::from_base16(StringView str) -{ - auto sign = parse_sign(str); - auto unsigned_data = UnsignedBigInteger::from_base16(str); - return { move(unsigned_data), sign }; -} - -String SignedBigInteger::to_base10() const +String SignedBigInteger::to_base(u16 N) const { StringBuilder builder; if (m_sign) builder.append('-'); - builder.append(m_unsigned_data.to_base10()); + builder.append(m_unsigned_data.to_base(N)); return builder.to_string(); } diff --git a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h index fdf63c4989..9e0416d607 100644 --- a/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h +++ b/Userland/Libraries/LibCrypto/BigInt/SignedBigInteger.h @@ -62,11 +62,8 @@ public: size_t export_data(Bytes, bool remove_leading_zeros = false) const; - static SignedBigInteger from_base2(StringView str); - static SignedBigInteger from_base8(StringView str); - static SignedBigInteger from_base10(StringView str); - String to_base10() const; - static SignedBigInteger from_base16(StringView str); + static SignedBigInteger from_base(u16 N, StringView str); + String to_base(u16 N) const; u64 to_u64() const; @@ -144,5 +141,5 @@ struct SignedDivisionResult { inline Crypto::SignedBigInteger operator""_sbigint(const char* string, size_t length) { - return Crypto::SignedBigInteger::from_base10({ string, length }); + return Crypto::SignedBigInteger::from_base(10, { string, length }); } diff --git a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp index 61dd2f0321..501a563337 100644 --- a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp +++ b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp @@ -66,60 +66,23 @@ size_t UnsignedBigInteger::export_data(Bytes data, bool remove_leading_zeros) co return out; } -UnsignedBigInteger UnsignedBigInteger::from_base10(const String& str) +UnsignedBigInteger UnsignedBigInteger::from_base(u16 N, const String& str) { + VERIFY(N <= 36); UnsignedBigInteger result; - UnsignedBigInteger ten { 10 }; + UnsignedBigInteger base { N }; for (auto& c : str) { if (c == '_') continue; - result = result.multiplied_by(ten).plus(parse_ascii_digit(c)); + result = result.multiplied_by(base).plus(parse_ascii_base36_digit(c)); } return result; } -UnsignedBigInteger UnsignedBigInteger::from_base2(const String& str) -{ - UnsignedBigInteger result; - UnsignedBigInteger two { 2 }; - - for (auto& c : str) { - if (c == '_') - continue; - result = result.multiplied_by(two).plus(parse_ascii_digit(c)); - } - return result; -} - -UnsignedBigInteger UnsignedBigInteger::from_base8(const String& str) -{ - UnsignedBigInteger result; - UnsignedBigInteger eight { 8 }; - - for (auto& c : str) { - if (c == '_') - continue; - result = result.multiplied_by(eight).plus(parse_ascii_digit(c)); - } - return result; -} - -UnsignedBigInteger UnsignedBigInteger::from_base16(const String& str) -{ - UnsignedBigInteger result; - UnsignedBigInteger sixteen { 16 }; - - for (auto& c : str) { - if (c == '_') - continue; - result = result.multiplied_by(sixteen).plus(parse_ascii_hex_digit(c)); - } - return result; -} - -String UnsignedBigInteger::to_base10() const +String UnsignedBigInteger::to_base(u16 N) const { + VERIFY(N <= 36); if (*this == UnsignedBigInteger { 0 }) return "0"; @@ -129,19 +92,13 @@ String UnsignedBigInteger::to_base10() const UnsignedBigInteger remainder; while (temp != UnsignedBigInteger { 0 }) { - UnsignedBigIntegerAlgorithms::divide_u16_without_allocation(temp, 10, quotient, remainder); - VERIFY(remainder.words()[0] < 10); - builder.append(static_cast(remainder.words()[0] + '0')); + UnsignedBigIntegerAlgorithms::divide_u16_without_allocation(temp, N, quotient, remainder); + VERIFY(remainder.words()[0] < N); + builder.append(to_ascii_base36_digit(remainder.words()[0])); temp.set_to(quotient); } - auto reversed_string = builder.to_string(); - builder.clear(); - for (int i = reversed_string.length() - 1; i >= 0; --i) { - builder.append(reversed_string[i]); - } - - return builder.to_string(); + return builder.to_string().reverse(); } u64 UnsignedBigInteger::to_u64() const diff --git a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h index ec05609075..80f8cf393b 100644 --- a/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h +++ b/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h @@ -53,11 +53,8 @@ public: size_t export_data(Bytes, bool remove_leading_zeros = false) const; - static UnsignedBigInteger from_base2(const String& str); - static UnsignedBigInteger from_base8(const String& str); - static UnsignedBigInteger from_base10(const String& str); - String to_base10() const; - static UnsignedBigInteger from_base16(const String& str); + static UnsignedBigInteger from_base(u16 N, const String& str); + String to_base(u16 N) const; u64 to_u64() const; @@ -131,5 +128,5 @@ struct AK::Formatter : Formatter { inline Crypto::UnsignedBigInteger operator""_bigint(const char* string, size_t length) { - return Crypto::UnsignedBigInteger::from_base10({ string, length }); + return Crypto::UnsignedBigInteger::from_base(10, { string, length }); } diff --git a/Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp b/Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp index 11c68e1538..408641323e 100644 --- a/Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp +++ b/Userland/Libraries/LibCrypto/NumberTheory/ModularFunctions.cpp @@ -218,7 +218,7 @@ bool is_probably_prime(const UnsignedBigInteger& p) UnsignedBigInteger random_big_prime(size_t bits) { VERIFY(bits >= 33); - UnsignedBigInteger min = UnsignedBigInteger::from_base10("6074001000").shift_left(bits - 33); + UnsignedBigInteger min = UnsignedBigInteger::from_base(10, "6074001000").shift_left(bits - 33); UnsignedBigInteger max = UnsignedBigInteger { 1 }.shift_left(bits).minus(1); for (;;) { auto p = random_number(min, max); diff --git a/Userland/Libraries/LibJS/AST.cpp b/Userland/Libraries/LibJS/AST.cpp index 9ad3feec02..dd32e7f7c2 100644 --- a/Userland/Libraries/LibJS/AST.cpp +++ b/Userland/Libraries/LibJS/AST.cpp @@ -1850,14 +1850,14 @@ Value BigIntLiteral::execute(Interpreter& interpreter, GlobalObject&) const Crypto::SignedBigInteger integer; if (m_value[0] == '0' && m_value.length() >= 3) { if (m_value[1] == 'x' || m_value[1] == 'X') { - return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base16(m_value.substring(2, m_value.length() - 3))); + return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base(16, m_value.substring(2, m_value.length() - 3))); } else if (m_value[1] == 'o' || m_value[1] == 'O') { - return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base8(m_value.substring(2, m_value.length() - 3))); + return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base(8, m_value.substring(2, m_value.length() - 3))); } else if (m_value[1] == 'b' || m_value[1] == 'B') { - return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base2(m_value.substring(2, m_value.length() - 3))); + return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base(2, m_value.substring(2, m_value.length() - 3))); } } - return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base10(m_value.substring(0, m_value.length() - 1))); + return js_bigint(interpreter.heap(), Crypto::SignedBigInteger::from_base(10, m_value.substring(0, m_value.length() - 1))); } Value BooleanLiteral::execute(Interpreter& interpreter, GlobalObject&) const diff --git a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp index 936faf86ee..0c9232c39f 100644 --- a/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp +++ b/Userland/Libraries/LibJS/Bytecode/ASTCodegen.cpp @@ -250,7 +250,7 @@ void NullLiteral::generate_bytecode(Bytecode::Generator& generator) const void BigIntLiteral::generate_bytecode(Bytecode::Generator& generator) const { - generator.emit(Crypto::SignedBigInteger::from_base10(m_value.substring(0, m_value.length() - 1))); + generator.emit(Crypto::SignedBigInteger::from_base(10, m_value.substring(0, m_value.length() - 1))); } void StringLiteral::generate_bytecode(Bytecode::Generator& generator) const diff --git a/Userland/Libraries/LibJS/Bytecode/Op.cpp b/Userland/Libraries/LibJS/Bytecode/Op.cpp index 6429e4494e..521d523c45 100644 --- a/Userland/Libraries/LibJS/Bytecode/Op.cpp +++ b/Userland/Libraries/LibJS/Bytecode/Op.cpp @@ -469,7 +469,7 @@ String Store::to_string_impl(Bytecode::Executable const&) const String NewBigInt::to_string_impl(Bytecode::Executable const&) const { - return String::formatted("NewBigInt \"{}\"", m_bigint.to_base10()); + return String::formatted("NewBigInt \"{}\"", m_bigint.to_base(10)); } String NewArray::to_string_impl(Bytecode::Executable const&) const diff --git a/Userland/Libraries/LibJS/Runtime/BigInt.h b/Userland/Libraries/LibJS/Runtime/BigInt.h index 2876245341..fd1673fb5b 100644 --- a/Userland/Libraries/LibJS/Runtime/BigInt.h +++ b/Userland/Libraries/LibJS/Runtime/BigInt.h @@ -17,7 +17,7 @@ public: virtual ~BigInt(); const Crypto::SignedBigInteger& big_integer() const { return m_big_integer; } - const String to_string() const { return String::formatted("{}n", m_big_integer.to_base10()); } + const String to_string() const { return String::formatted("{}n", m_big_integer.to_base(10)); } private: virtual const char* class_name() const override { return "BigInt"; } diff --git a/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp b/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp index 87a1b6832a..0f34ef351e 100644 --- a/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp +++ b/Userland/Libraries/LibJS/Runtime/BigIntPrototype.cpp @@ -53,7 +53,7 @@ JS_DEFINE_NATIVE_FUNCTION(BigIntPrototype::to_string) if (vm.exception()) return {}; // FIXME: Support radix argument - return js_string(vm, bigint_value.as_bigint().big_integer().to_base10()); + return js_string(vm, bigint_value.as_bigint().big_integer().to_base(10)); } // 21.2.3.2 BigInt.prototype.toLocaleString ( [ reserved1 [ , reserved2 ] ] ), https://tc39.es/ecma262/#sec-bigint.prototype.tolocalestring diff --git a/Userland/Libraries/LibJS/Runtime/Value.cpp b/Userland/Libraries/LibJS/Runtime/Value.cpp index 99e99b1bda..dafa672468 100644 --- a/Userland/Libraries/LibJS/Runtime/Value.cpp +++ b/Userland/Libraries/LibJS/Runtime/Value.cpp @@ -355,7 +355,7 @@ String Value::to_string(GlobalObject& global_object, bool legacy_null_to_empty_s global_object.vm().throw_exception(global_object, ErrorType::Convert, "symbol", "string"); return {}; case Type::BigInt: - return m_value.as_bigint->big_integer().to_base10(); + return m_value.as_bigint->big_integer().to_base(10); case Type::Object: { auto primitive_value = to_primitive(global_object, PreferredType::String); if (global_object.vm().exception()) @@ -547,7 +547,7 @@ BigInt* Value::to_bigint(GlobalObject& global_object) const vm.throw_exception(global_object, ErrorType::BigIntInvalidValue, string); return {}; } - return js_bigint(vm.heap(), Crypto::SignedBigInteger::from_base10(string.trim_whitespace())); + return js_bigint(vm.heap(), Crypto::SignedBigInteger::from_base(10, string.trim_whitespace())); } case Type::Symbol: vm.throw_exception(global_object, ErrorType::Convert, "symbol", "BigInt"); @@ -1398,7 +1398,7 @@ bool abstract_eq(GlobalObject& global_object, Value lhs, Value rhs) auto& rhs_string = rhs.as_string().string(); if (!is_valid_bigint_value(rhs_string)) return false; - return abstract_eq(global_object, lhs, js_bigint(global_object.heap(), Crypto::SignedBigInteger::from_base10(rhs_string))); + return abstract_eq(global_object, lhs, js_bigint(global_object.heap(), Crypto::SignedBigInteger::from_base(10, rhs_string))); } if (lhs.is_string() && rhs.is_bigint()) @@ -1490,7 +1490,7 @@ TriState abstract_relation(GlobalObject& global_object, bool left_first, Value l auto& y_string = y_primitive.as_string().string(); if (!is_valid_bigint_value(y_string)) return TriState::Unknown; - if (x_primitive.as_bigint().big_integer() < Crypto::SignedBigInteger::from_base10(y_string)) + if (x_primitive.as_bigint().big_integer() < Crypto::SignedBigInteger::from_base(10, y_string)) return TriState::True; else return TriState::False; @@ -1500,7 +1500,7 @@ TriState abstract_relation(GlobalObject& global_object, bool left_first, Value l auto& x_string = x_primitive.as_string().string(); if (!is_valid_bigint_value(x_string)) return TriState::Unknown; - if (Crypto::SignedBigInteger::from_base10(x_string) < y_primitive.as_bigint().big_integer()) + if (Crypto::SignedBigInteger::from_base(10, x_string) < y_primitive.as_bigint().big_integer()) return TriState::True; else return TriState::False; diff --git a/Userland/Libraries/LibTLS/Certificate.cpp b/Userland/Libraries/LibTLS/Certificate.cpp index 457e7dd20c..467a283c15 100644 --- a/Userland/Libraries/LibTLS/Certificate.cpp +++ b/Userland/Libraries/LibTLS/Certificate.cpp @@ -119,7 +119,7 @@ Optional Certificate::parse_asn1(ReadonlyBytes buffer, bool) ENTER_SCOPE_WITHOUT_TYPECHECK("Certificate::version"); READ_OBJECT_OR_FAIL(Integer, Crypto::UnsignedBigInteger, value, "Certificate::version"); if (!(value < 3)) { - dbgln_if(TLS_DEBUG, "Certificate::version Invalid value for version: {}", value.to_base10()); + dbgln_if(TLS_DEBUG, "Certificate::version Invalid value for version: {}", value.to_base(10)); return {}; } certificate.version = value.words()[0]; diff --git a/Userland/Utilities/test-crypto.cpp b/Userland/Utilities/test-crypto.cpp index 83cd25a0ad..82338909c7 100644 --- a/Userland/Utilities/test-crypto.cpp +++ b/Userland/Utilities/test-crypto.cpp @@ -2429,7 +2429,7 @@ static void bigint_base10() { { I_TEST((BigInteger | From String)); - auto result = Crypto::UnsignedBigInteger::from_base10("57195071295721390579057195715793"); + auto result = Crypto::UnsignedBigInteger::from_base(10, "57195071295721390579057195715793"); if (result.words() == Vector { 3806301393, 954919431, 3879607298, 721 }) { PASS; } else { @@ -2438,7 +2438,7 @@ static void bigint_base10() } { I_TEST((BigInteger | To String)); - auto result = Crypto::UnsignedBigInteger { Vector { 3806301393, 954919431, 3879607298, 721 } }.to_base10(); + auto result = Crypto::UnsignedBigInteger { Vector { 3806301393, 954919431, 3879607298, 721 } }.to_base(10); if (result == "57195071295721390579057195715793") { PASS; } else { @@ -2551,11 +2551,11 @@ static void bigint_theory_modular_power() PASS; } else { FAIL(Wrong result); - outln("b: {}", test_case.base.to_base10()); - outln("e: {}", test_case.exp.to_base10()); - outln("m: {}", test_case.mod.to_base10()); - outln("expect: {}", test_case.expected.to_base10()); - outln("actual: {}", actual.to_base10()); + outln("b: {}", test_case.base.to_base(10)); + outln("e: {}", test_case.exp.to_base(10)); + outln("m: {}", test_case.mod.to_base(10)); + outln("expect: {}", test_case.expected.to_base(10)); + outln("actual: {}", actual.to_base(10)); } } } @@ -2593,7 +2593,7 @@ static void bigint_theory_primality() } else { FAIL(Wrong primality guess); outln("The number {} is {}a prime, but the test said it is {}a prime!", - test_case.candidate.to_base10(), test_case.expected_result ? "" : "not ", actual_result ? "" : "not "); + test_case.candidate.to_base(10), test_case.expected_result ? "" : "not ", actual_result ? "" : "not "); } } } @@ -2616,10 +2616,10 @@ static void bigint_theory_random_number() auto actual_result = Crypto::NumberTheory::random_number(test_case.min, test_case.max); if (actual_result < test_case.min) { FAIL(Too small); - outln("The generated number {} is smaller than the requested minimum {}. (max = {})", actual_result.to_base10(), test_case.min.to_base10(), test_case.max.to_base10()); + outln("The generated number {} is smaller than the requested minimum {}. (max = {})", actual_result.to_base(10), test_case.min.to_base(10), test_case.max.to_base(10)); } else if (!(actual_result < test_case.max)) { FAIL(Too large); - outln("The generated number {} is larger-or-equal to the requested maximum {}. (min = {})", actual_result.to_base10(), test_case.max.to_base10(), test_case.min.to_base10()); + outln("The generated number {} is larger-or-equal to the requested maximum {}. (min = {})", actual_result.to_base(10), test_case.max.to_base(10), test_case.min.to_base(10)); } else { PASS; } @@ -2632,10 +2632,10 @@ static void bigint_theory_random_number() "100000000000000000000000000000"_bigint); // 10**29 if (actual_result < "100000000000000000000"_bigint) { // 10**20 FAIL(Too small); - outln("The generated number {} is extremely small. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base10()); + outln("The generated number {} is extremely small. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base(10)); } else if ("99999999900000000000000000000"_bigint < actual_result) { // 10**29 - 10**20 FAIL(Too large); - outln("The generated number {} is extremely large. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base10()); + outln("The generated number {} is extremely large. This *can* happen by pure chance, but should happen only once in a billion times. So it's probably an error.", actual_result.to_base(10)); } else { PASS; } @@ -2940,7 +2940,7 @@ static void bigint_signed_base10() { { I_TEST((Signed BigInteger | From String)); - auto result = Crypto::SignedBigInteger::from_base10("-57195071295721390579057195715793"); + auto result = Crypto::SignedBigInteger::from_base(10, "-57195071295721390579057195715793"); if (result.unsigned_value().words() == Vector { 3806301393, 954919431, 3879607298, 721 } && result.is_negative()) { PASS; } else { @@ -2949,7 +2949,7 @@ static void bigint_signed_base10() } { I_TEST((Signed BigInteger | To String)); - auto result = Crypto::SignedBigInteger { Crypto::UnsignedBigInteger { Vector { 3806301393, 954919431, 3879607298, 721 } }, true }.to_base10(); + auto result = Crypto::SignedBigInteger { Crypto::UnsignedBigInteger { Vector { 3806301393, 954919431, 3879607298, 721 } }, true }.to_base(10); if (result == "-57195071295721390579057195715793") { PASS; } else {