ladybird/Libraries/LibCrypto/BigInt/UnsignedBigInteger.h
Andreas Kling b6bef6b688 Libraries: Use UTF-16 for JS-visible runtime strings
Produce JS-visible string results as UTF-16 at their source, including
numeric formatting, BigInt and BigFraction formatting, URI encoding,
console formatting, parser errors, regular expression errors, Intl and
Temporal records, LibUnicode locale boundaries, and LibWeb bindings.

Handle fractional radix formatting through the UTF-16 builder view.
2026-06-22 19:51:25 +02:00

146 lines
5.2 KiB
C++

/*
* Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
* Copyright (c) 2022, the SerenityOS developers.
* Copyright (c) 2022, David Tuin <davidot@serenityos.org>
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
*
* SPDX-License-Identifier: BSD-2-Clause
*/
#pragma once
#include <AK/String.h>
#include <AK/Utf16String.h>
#include <AK/Utf16View.h>
#include <LibCrypto/BigInt/TommathForward.h>
namespace Crypto {
struct UnsignedDivisionResult;
class UnsignedBigInteger {
public:
template<Integral T>
UnsignedBigInteger(T value)
: UnsignedBigInteger(static_cast<u64>(value))
{
}
UnsignedBigInteger(ReadonlyBytes);
explicit UnsignedBigInteger(Vector<u32> const& words);
explicit UnsignedBigInteger(double value);
explicit UnsignedBigInteger(u64 value);
UnsignedBigInteger(UnsignedBigInteger const&);
UnsignedBigInteger(UnsignedBigInteger&&);
UnsignedBigInteger& operator=(UnsignedBigInteger const&);
UnsignedBigInteger& operator=(UnsignedBigInteger&&);
UnsignedBigInteger();
~UnsignedBigInteger();
[[nodiscard]] static UnsignedBigInteger import_data(ReadonlyBytes data) { return UnsignedBigInteger(data); }
// Exports in big-endian (msb stored first), trimmed (no leading zeros) format
[[nodiscard]] Bytes export_data(Bytes) const;
[[nodiscard]] static ErrorOr<UnsignedBigInteger> from_base(u16 N, StringView str);
[[nodiscard]] static ErrorOr<UnsignedBigInteger> from_base(u16 N, Utf16View str);
[[nodiscard]] ErrorOr<String> to_base(u16 N) const;
[[nodiscard]] ErrorOr<Utf16String> to_base_utf16(u16 N) const;
[[nodiscard]] size_t count_digits_in_base(u16 base) const;
[[nodiscard]] u64 to_u64() const;
enum class RoundingMode {
IEEERoundAndTiesToEvenMantissa,
RoundTowardZero,
// “the Number value for x”, https://tc39.es/ecma262/#number-value-for
ECMAScriptNumberValueFor = IEEERoundAndTiesToEvenMantissa,
};
[[nodiscard]] double to_double(RoundingMode rounding_mode = RoundingMode::IEEERoundAndTiesToEvenMantissa) const;
[[nodiscard]] Vector<u32> words() const;
void set_to_0();
void set_to(u64 other);
void set_to(UnsignedBigInteger const& other);
[[nodiscard]] bool is_zero() const;
[[nodiscard]] bool is_odd() const;
[[nodiscard]] size_t byte_length() const;
[[nodiscard]] size_t external_memory_size() const { return m_mp.alloc * sizeof(mp_digit); }
size_t one_based_index_of_highest_set_bit() const;
[[nodiscard]] UnsignedBigInteger plus(UnsignedBigInteger const& other) const;
[[nodiscard]] ErrorOr<UnsignedBigInteger> minus(UnsignedBigInteger const& other) const;
[[nodiscard]] UnsignedBigInteger bitwise_or(UnsignedBigInteger const& other) const;
[[nodiscard]] UnsignedBigInteger bitwise_and(UnsignedBigInteger const& other) const;
[[nodiscard]] UnsignedBigInteger bitwise_xor(UnsignedBigInteger const& other) const;
[[nodiscard]] ErrorOr<UnsignedBigInteger> bitwise_not_fill_to_one_based_index(size_t) const;
[[nodiscard]] ErrorOr<UnsignedBigInteger> shift_left(size_t num_bits) const;
[[nodiscard]] UnsignedBigInteger shift_right(size_t num_bits) const;
[[nodiscard]] UnsignedBigInteger multiplied_by(UnsignedBigInteger const& other) const;
[[nodiscard]] UnsignedDivisionResult divided_by(UnsignedBigInteger const& divisor) const;
[[nodiscard]] UnsignedBigInteger pow(u32 exponent) const;
[[nodiscard]] UnsignedBigInteger gcd(UnsignedBigInteger const& other) const;
[[nodiscard]] UnsignedBigInteger lcm(UnsignedBigInteger const& other) const;
[[nodiscard]] u32 hash() const;
[[nodiscard]] bool operator==(UnsignedBigInteger const& other) const;
[[nodiscard]] bool operator!=(UnsignedBigInteger const& other) const;
[[nodiscard]] bool operator<(UnsignedBigInteger const& other) const;
[[nodiscard]] bool operator<=(UnsignedBigInteger const& other) const;
[[nodiscard]] bool operator>(UnsignedBigInteger const& other) const;
[[nodiscard]] bool operator>=(UnsignedBigInteger const& other) const;
enum class CompareResult {
DoubleEqualsBigInt,
DoubleLessThanBigInt,
DoubleGreaterThanBigInt
};
[[nodiscard]] CompareResult compare_to_double(double) const;
private:
friend class SignedBigInteger;
mp_int m_mp;
mutable Optional<u32> m_hash {};
};
struct UnsignedDivisionResult {
Crypto::UnsignedBigInteger quotient;
Crypto::UnsignedBigInteger remainder;
};
}
template<>
struct AK::Formatter<Crypto::UnsignedBigInteger> : Formatter<StringView> {
ErrorOr<void> format(FormatBuilder&, Crypto::UnsignedBigInteger const&);
};
inline Crypto::UnsignedBigInteger operator""_bigint(char const* string, size_t length)
{
return MUST(Crypto::UnsignedBigInteger::from_base(10, StringView { string, length }));
}
inline Crypto::UnsignedBigInteger operator""_bigint(unsigned long long value)
{
return Crypto::UnsignedBigInteger { static_cast<u64>(value) };
}
inline Crypto::UnsignedBigInteger operator""_bigint(long double value)
{
VERIFY(value >= 0);
VERIFY(value < static_cast<long double>(NumericLimits<double>::max()));
return Crypto::UnsignedBigInteger { static_cast<double>(value) };
}