mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-22 15:40:19 +00:00
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).
This commit is contained in:
parent
a768131720
commit
005d75656e
Notes:
sideshowbarker
2024-07-18 11:20:46 +09:00
Author: https://github.com/IdanHo Commit: https://github.com/SerenityOS/serenity/commit/005d75656ef Pull-request: https://github.com/SerenityOS/serenity/pull/8314
14 changed files with 56 additions and 132 deletions
|
@ -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<u32> 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<u32> { 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));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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 });
|
||||
}
|
||||
|
|
|
@ -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<char>(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
|
||||
|
|
|
@ -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<Crypto::UnsignedBigInteger> : Formatter<StringView> {
|
|||
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 });
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -250,7 +250,7 @@ void NullLiteral::generate_bytecode(Bytecode::Generator& generator) const
|
|||
|
||||
void BigIntLiteral::generate_bytecode(Bytecode::Generator& generator) const
|
||||
{
|
||||
generator.emit<Bytecode::Op::NewBigInt>(Crypto::SignedBigInteger::from_base10(m_value.substring(0, m_value.length() - 1)));
|
||||
generator.emit<Bytecode::Op::NewBigInt>(Crypto::SignedBigInteger::from_base(10, m_value.substring(0, m_value.length() - 1)));
|
||||
}
|
||||
|
||||
void StringLiteral::generate_bytecode(Bytecode::Generator& generator) const
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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"; }
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -355,7 +355,7 @@ String Value::to_string(GlobalObject& global_object, bool legacy_null_to_empty_s
|
|||
global_object.vm().throw_exception<TypeError>(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<SyntaxError>(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<TypeError>(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;
|
||||
|
|
|
@ -119,7 +119,7 @@ Optional<Certificate> 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];
|
||||
|
|
|
@ -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<u32> { 3806301393, 954919431, 3879607298, 721 }) {
|
||||
PASS;
|
||||
} else {
|
||||
|
@ -2438,7 +2438,7 @@ static void bigint_base10()
|
|||
}
|
||||
{
|
||||
I_TEST((BigInteger | To String));
|
||||
auto result = Crypto::UnsignedBigInteger { Vector<u32> { 3806301393, 954919431, 3879607298, 721 } }.to_base10();
|
||||
auto result = Crypto::UnsignedBigInteger { Vector<u32> { 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<u32> { 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<u32> { 3806301393, 954919431, 3879607298, 721 } }, true }.to_base10();
|
||||
auto result = Crypto::SignedBigInteger { Crypto::UnsignedBigInteger { Vector<u32> { 3806301393, 954919431, 3879607298, 721 } }, true }.to_base(10);
|
||||
if (result == "-57195071295721390579057195715793") {
|
||||
PASS;
|
||||
} else {
|
||||
|
|
Loading…
Reference in a new issue