Coverage Report

Created: 2026-02-14 08:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/serenity/Userland/Libraries/LibCrypto/BigInt/UnsignedBigInteger.cpp
Line
Count
Source
1
/*
2
 * Copyright (c) 2020, Itamar S. <itamar8910@gmail.com>
3
 * Copyright (c) 2022, David Tuin <davidot@serenityos.org>
4
 *
5
 * SPDX-License-Identifier: BSD-2-Clause
6
 */
7
8
#include "UnsignedBigInteger.h"
9
#include <AK/BuiltinWrappers.h>
10
#include <AK/CharacterTypes.h>
11
#include <AK/FloatingPoint.h>
12
#include <AK/StringBuilder.h>
13
#include <AK/StringHash.h>
14
#include <LibCrypto/BigInt/Algorithms/UnsignedBigIntegerAlgorithms.h>
15
#include <math.h>
16
17
namespace Crypto {
18
19
UnsignedBigInteger::UnsignedBigInteger(u8 const* ptr, size_t length)
20
7.98k
{
21
7.98k
    m_words.resize_and_keep_capacity((length + sizeof(u32) - 1) / sizeof(u32));
22
7.98k
    size_t in = length, out = 0;
23
6.50M
    while (in >= sizeof(u32)) {
24
6.50M
        in -= sizeof(u32);
25
6.50M
        u32 word = ((u32)ptr[in] << 24) | ((u32)ptr[in + 1] << 16) | ((u32)ptr[in + 2] << 8) | (u32)ptr[in + 3];
26
6.50M
        m_words[out++] = word;
27
6.50M
    }
28
7.98k
    if (in > 0) {
29
6.87k
        u32 word = 0;
30
16.2k
        for (size_t i = 0; i < in; i++) {
31
9.37k
            word <<= 8;
32
9.37k
            word |= (u32)ptr[i];
33
9.37k
        }
34
6.87k
        m_words[out++] = word;
35
6.87k
    }
36
7.98k
}
37
38
UnsignedBigInteger::UnsignedBigInteger(double value)
39
0
{
40
    // Because this is currently only used for LibJS we VERIFY some preconditions
41
    // also these values don't have a clear BigInteger representation.
42
0
    VERIFY(!isnan(value));
43
0
    VERIFY(!isinf(value));
44
0
    VERIFY(trunc(value) == value);
45
0
    VERIFY(value >= 0.0);
46
47
0
    if (value <= NumericLimits<u32>::max()) {
48
0
        m_words.append(static_cast<u32>(value));
49
0
        return;
50
0
    }
51
52
0
    auto extractor = FloatExtractor<double>::from_float(value);
53
0
    VERIFY(!extractor.sign);
54
55
0
    i32 real_exponent = extractor.exponent - extractor.exponent_bias;
56
0
    VERIFY(real_exponent > 0);
57
58
    // Ensure we have enough space, we will need 2^exponent bits, so round up in words
59
0
    auto word_index = (real_exponent + BITS_IN_WORD) / BITS_IN_WORD;
60
0
    m_words.resize_and_keep_capacity(word_index);
61
62
    // Now we just need to put the mantissa with explicit 1 bit at the top at the proper location
63
0
    u64 raw_mantissa = extractor.mantissa | (1ull << extractor.mantissa_bits);
64
0
    VERIFY((raw_mantissa & 0xfff0000000000000) == 0x0010000000000000);
65
    // Shift it so the bits we need are at the top
66
0
    raw_mantissa <<= 64 - extractor.mantissa_bits - 1;
67
68
    // The initial bit needs to be exactly aligned with exponent, this is 1-indexed
69
0
    auto top_word_bit_offset = real_exponent % BITS_IN_WORD + 1;
70
71
0
    auto top_word_bits_from_mantissa = raw_mantissa >> (64 - top_word_bit_offset);
72
0
    VERIFY(top_word_bits_from_mantissa <= NumericLimits<Word>::max());
73
0
    m_words[word_index - 1] = top_word_bits_from_mantissa;
74
75
0
    --word_index;
76
    // Shift used bits away
77
0
    raw_mantissa <<= top_word_bit_offset;
78
0
    i32 bits_in_mantissa = extractor.mantissa_bits + 1 - top_word_bit_offset;
79
    // Now just put everything at the top of the next words
80
81
0
    constexpr auto to_word_shift = 64 - BITS_IN_WORD;
82
83
0
    while (word_index > 0 && bits_in_mantissa > 0) {
84
0
        VERIFY((raw_mantissa >> to_word_shift) <= NumericLimits<Word>::max());
85
0
        m_words[word_index - 1] = raw_mantissa >> to_word_shift;
86
0
        raw_mantissa <<= to_word_shift;
87
88
0
        bits_in_mantissa -= BITS_IN_WORD;
89
0
        --word_index;
90
0
    }
91
92
0
    VERIFY(m_words.size() > word_index);
93
0
    VERIFY((m_words.size() - word_index) <= 3);
94
95
    // No bits left, otherwise we would have to round
96
0
    VERIFY(raw_mantissa == 0);
97
0
}
98
99
UnsignedBigInteger UnsignedBigInteger::create_invalid()
100
0
{
101
0
    UnsignedBigInteger invalid(0);
102
0
    invalid.invalidate();
103
0
    return invalid;
104
0
}
105
106
size_t UnsignedBigInteger::export_data(Bytes data, bool remove_leading_zeros) const
107
0
{
108
0
    size_t word_count = trimmed_length();
109
0
    size_t out = 0;
110
0
    if (word_count > 0) {
111
0
        ssize_t leading_zeros = -1;
112
0
        if (remove_leading_zeros) {
113
0
            UnsignedBigInteger::Word word = m_words[word_count - 1];
114
0
            u8 value[4] {};
115
0
            for (size_t i = 0; i < sizeof(u32); i++) {
116
0
                u8 byte = (u8)(word >> ((sizeof(u32) - i - 1) * 8));
117
0
                value[i] = byte;
118
0
                if (leading_zeros < 0 && byte != 0)
119
0
                    leading_zeros = (int)i;
120
0
            }
121
0
            data.overwrite(out, value, array_size(value));
122
0
            out += array_size(value);
123
0
        }
124
0
        for (size_t i = word_count - (remove_leading_zeros ? 1 : 0); i > 0; i--) {
125
0
            auto word = m_words[i - 1];
126
0
            u8 value[] { (u8)(word >> 24), (u8)(word >> 16), (u8)(word >> 8), (u8)word };
127
0
            data.overwrite(out, value, array_size(value));
128
0
            out += array_size(value);
129
0
        }
130
0
        if (leading_zeros > 0)
131
0
            out -= leading_zeros;
132
0
    }
133
0
    return out;
134
0
}
135
136
ErrorOr<UnsignedBigInteger> UnsignedBigInteger::from_base(u16 N, StringView str)
137
80
{
138
80
    VERIFY(N <= 36);
139
80
    UnsignedBigInteger result;
140
80
    UnsignedBigInteger base { N };
141
142
1.76k
    for (auto const& c : str) {
143
1.76k
        if (c == '_')
144
0
            continue;
145
1.76k
        if (!is_ascii_base36_digit(c))
146
0
            return Error::from_string_literal("Invalid Base36 digit");
147
1.76k
        auto digit = parse_ascii_base36_digit(c);
148
1.76k
        if (digit >= N)
149
0
            return Error::from_string_literal("Base36 digit out of range");
150
151
1.76k
        result = result.multiplied_by(base).plus(digit);
152
1.76k
    }
153
80
    return result;
154
80
}
155
156
ErrorOr<String> UnsignedBigInteger::to_base(u16 N) const
157
0
{
158
0
    VERIFY(N <= 36);
159
0
    if (*this == UnsignedBigInteger { 0 })
160
0
        return "0"_string;
161
162
0
    StringBuilder builder;
163
0
    UnsignedBigInteger temp(*this);
164
0
    UnsignedBigInteger quotient;
165
0
    UnsignedBigInteger remainder;
166
167
0
    while (temp != UnsignedBigInteger { 0 }) {
168
0
        UnsignedBigIntegerAlgorithms::divide_u16_without_allocation(temp, N, quotient, remainder);
169
0
        VERIFY(remainder.words()[0] < N);
170
0
        TRY(builder.try_append(to_ascii_base36_digit(remainder.words()[0])));
171
0
        temp.set_to(quotient);
172
0
    }
173
174
0
    return TRY(builder.to_string()).reverse();
175
0
}
176
177
ByteString UnsignedBigInteger::to_base_deprecated(u16 N) const
178
0
{
179
0
    return MUST(to_base(N)).to_byte_string();
180
0
}
181
182
u64 UnsignedBigInteger::to_u64() const
183
3.35k
{
184
3.35k
    static_assert(sizeof(Word) == 4);
185
3.35k
    if (!length())
186
576
        return 0;
187
2.77k
    u64 value = m_words[0];
188
2.77k
    if (length() > 1)
189
148
        value |= static_cast<u64>(m_words[1]) << 32;
190
2.77k
    return value;
191
3.35k
}
192
193
double UnsignedBigInteger::to_double(UnsignedBigInteger::RoundingMode rounding_mode) const
194
0
{
195
0
    VERIFY(!is_invalid());
196
0
    auto highest_bit = one_based_index_of_highest_set_bit();
197
0
    if (highest_bit == 0)
198
0
        return 0;
199
0
    --highest_bit;
200
201
0
    using Extractor = FloatExtractor<double>;
202
203
    // Simple case if less than 2^53 since those number are all exactly representable in doubles
204
0
    if (highest_bit < Extractor::mantissa_bits + 1)
205
0
        return static_cast<double>(to_u64());
206
207
    // If it uses too many bit to represent in a double return infinity
208
0
    if (highest_bit > Extractor::exponent_bias)
209
0
        return __builtin_huge_val();
210
211
    // Otherwise we have to take the top 53 bits, use those as the mantissa,
212
    // and the amount of bits as the exponent. Note that the mantissa has an implicit top bit of 1
213
    // so we have to ignore the very top bit.
214
215
    // Since we extract at most 53 bits it will take at most 3 words
216
0
    static_assert(BITS_IN_WORD * 3 >= (Extractor::mantissa_bits + 1));
217
0
    constexpr auto bits_in_u64 = 64;
218
0
    static_assert(bits_in_u64 > Extractor::mantissa_bits + 1);
219
220
0
    auto bits_to_read = min(static_cast<size_t>(Extractor::mantissa_bits), highest_bit);
221
222
0
    auto last_word_index = trimmed_length();
223
0
    VERIFY(last_word_index > 0);
224
225
    // Note that highest bit is 0-indexed at this point.
226
0
    auto highest_bit_index_in_top_word = highest_bit % BITS_IN_WORD;
227
228
    // Shift initial word until highest bit is just beyond top of u64.
229
0
    u64 mantissa = m_words[last_word_index - 1];
230
0
    if (highest_bit_index_in_top_word != 0)
231
0
        mantissa <<= (bits_in_u64 - highest_bit_index_in_top_word);
232
0
    else
233
0
        mantissa = 0;
234
235
0
    auto bits_written = highest_bit_index_in_top_word;
236
237
0
    --last_word_index;
238
239
0
    Optional<Word> dropped_bits_for_rounding;
240
0
    u8 bits_dropped_from_final_word = 0;
241
242
0
    if (bits_written < bits_to_read && last_word_index > 0) {
243
        // Second word can always just cleanly be shifted up to the final bit of the first word
244
        // since the first has at most BIT_IN_WORD - 1, 31
245
0
        u64 next_word = m_words[last_word_index - 1];
246
0
        VERIFY((mantissa & (next_word << (bits_in_u64 - bits_written - BITS_IN_WORD))) == 0);
247
0
        mantissa |= next_word << (bits_in_u64 - bits_written - BITS_IN_WORD);
248
0
        bits_written += BITS_IN_WORD;
249
0
        --last_word_index;
250
251
0
        if (bits_written > bits_to_read) {
252
0
            bits_dropped_from_final_word = bits_written - bits_to_read;
253
0
            dropped_bits_for_rounding = m_words[last_word_index] & ((1 << bits_dropped_from_final_word) - 1);
254
0
        } else if (bits_written < bits_to_read && last_word_index > 0) {
255
            // The final word has to be shifted down first to discard any excess bits.
256
0
            u64 final_word = m_words[last_word_index - 1];
257
0
            --last_word_index;
258
259
0
            auto bits_to_write = bits_to_read - bits_written;
260
261
0
            bits_dropped_from_final_word = BITS_IN_WORD - bits_to_write;
262
0
            dropped_bits_for_rounding = final_word & ((1 << bits_dropped_from_final_word) - 1u);
263
0
            final_word >>= bits_dropped_from_final_word;
264
265
            // Then move the bits right up to the lowest bits of the second word
266
0
            VERIFY((mantissa & (final_word << (bits_in_u64 - bits_written - bits_to_write))) == 0);
267
0
            mantissa |= final_word << (bits_in_u64 - bits_written - bits_to_write);
268
0
        }
269
0
    }
270
271
    // Now the mantissa should be complete so shift it down
272
0
    mantissa >>= bits_in_u64 - Extractor::mantissa_bits;
273
274
0
    if (rounding_mode == RoundingMode::IEEERoundAndTiesToEvenMantissa) {
275
0
        bool round_up = false;
276
277
0
        if (bits_dropped_from_final_word == 0) {
278
0
            if (last_word_index > 0) {
279
0
                Word next_word = m_words[last_word_index - 1];
280
0
                last_word_index--;
281
0
                if ((next_word & 0x80000000) != 0) {
282
                    // next top bit set check for any other bits
283
0
                    if ((next_word ^ 0x80000000) != 0) {
284
0
                        round_up = true;
285
0
                    } else {
286
0
                        while (last_word_index > 0) {
287
0
                            if (m_words[last_word_index - 1] != 0) {
288
0
                                round_up = true;
289
0
                                break;
290
0
                            }
291
0
                        }
292
293
                        // All other bits are 0 which is a tie thus round to even exponent
294
                        // Since we are halfway, if exponent ends with 1 we round up, if 0 we round down
295
0
                        round_up = (mantissa & 1) != 0;
296
0
                    }
297
0
                } else {
298
0
                    round_up = false;
299
0
                }
300
0
            } else {
301
                // If there are no words left the rest is implicitly 0 so just round down
302
0
                round_up = false;
303
0
            }
304
305
0
        } else {
306
0
            VERIFY(dropped_bits_for_rounding.has_value());
307
0
            VERIFY(bits_dropped_from_final_word >= 1);
308
309
            // In this case the top bit comes form the dropped bits
310
0
            auto top_bit_extractor = 1u << (bits_dropped_from_final_word - 1u);
311
0
            if ((*dropped_bits_for_rounding & top_bit_extractor) != 0) {
312
                // Possible tie again, if any other bit is set we round up
313
0
                if ((*dropped_bits_for_rounding ^ top_bit_extractor) != 0) {
314
0
                    round_up = true;
315
0
                } else {
316
0
                    while (last_word_index > 0) {
317
0
                        if (m_words[last_word_index - 1] != 0) {
318
0
                            round_up = true;
319
0
                            break;
320
0
                        }
321
0
                    }
322
323
0
                    round_up = (mantissa & 1) != 0;
324
0
                }
325
0
            } else {
326
0
                round_up = false;
327
0
            }
328
0
        }
329
330
0
        if (round_up) {
331
0
            ++mantissa;
332
0
            if ((mantissa & (1ull << Extractor::mantissa_bits)) != 0) {
333
                // we overflowed the mantissa
334
0
                mantissa = 0;
335
0
                highest_bit++;
336
337
                // In which case it is possible we have to round to infinity
338
0
                if (highest_bit > Extractor::exponent_bias)
339
0
                    return __builtin_huge_val();
340
0
            }
341
0
        }
342
0
    } else {
343
0
        VERIFY(rounding_mode == RoundingMode::RoundTowardZero);
344
0
    }
345
346
0
    Extractor extractor;
347
0
    extractor.exponent = highest_bit + extractor.exponent_bias;
348
349
0
    VERIFY((mantissa & 0xfff0000000000000) == 0);
350
0
    extractor.mantissa = mantissa;
351
352
0
    return extractor.to_float();
353
0
}
354
355
void UnsignedBigInteger::set_to_0()
356
28.2k
{
357
28.2k
    m_words.clear_with_capacity();
358
28.2k
    m_is_invalid = false;
359
28.2k
    m_cached_trimmed_length = {};
360
28.2k
    m_cached_hash = 0;
361
28.2k
}
362
363
void UnsignedBigInteger::set_to(UnsignedBigInteger::Word other)
364
0
{
365
0
    m_is_invalid = false;
366
0
    m_words.resize_and_keep_capacity(1);
367
0
    m_words[0] = other;
368
0
    m_cached_trimmed_length = {};
369
0
    m_cached_hash = 0;
370
0
}
371
372
void UnsignedBigInteger::set_to(UnsignedBigInteger const& other)
373
24.7k
{
374
24.7k
    m_is_invalid = other.m_is_invalid;
375
24.7k
    m_words.resize_and_keep_capacity(other.m_words.size());
376
24.7k
    __builtin_memcpy(m_words.data(), other.m_words.data(), other.m_words.size() * sizeof(u32));
377
24.7k
    m_cached_trimmed_length = {};
378
24.7k
    m_cached_hash = 0;
379
24.7k
}
380
381
bool UnsignedBigInteger::is_zero() const
382
40
{
383
40
    for (size_t i = 0; i < length(); ++i) {
384
40
        if (m_words[i] != 0)
385
40
            return false;
386
40
    }
387
388
0
    return true;
389
40
}
390
391
size_t UnsignedBigInteger::trimmed_length() const
392
38.3k
{
393
38.3k
    if (!m_cached_trimmed_length.has_value()) {
394
34.3k
        size_t num_leading_zeroes = 0;
395
39.1k
        for (int i = length() - 1; i >= 0; --i, ++num_leading_zeroes) {
396
34.7k
            if (m_words[i] != 0)
397
30.0k
                break;
398
34.7k
        }
399
34.3k
        m_cached_trimmed_length = length() - num_leading_zeroes;
400
34.3k
    }
401
38.3k
    return m_cached_trimmed_length.value();
402
38.3k
}
403
404
void UnsignedBigInteger::clamp_to_trimmed_length()
405
0
{
406
0
    auto length = trimmed_length();
407
0
    if (m_words.size() > length)
408
0
        m_words.resize(length);
409
0
}
410
411
void UnsignedBigInteger::resize_with_leading_zeros(size_t new_length)
412
26.4k
{
413
26.4k
    size_t old_length = length();
414
26.4k
    if (old_length < new_length) {
415
4.48k
        m_words.resize_and_keep_capacity(new_length);
416
4.48k
        __builtin_memset(&m_words.data()[old_length], 0, (new_length - old_length) * sizeof(u32));
417
4.48k
    }
418
26.4k
}
419
420
size_t UnsignedBigInteger::one_based_index_of_highest_set_bit() const
421
0
{
422
0
    size_t number_of_words = trimmed_length();
423
0
    size_t index = 0;
424
0
    if (number_of_words > 0) {
425
0
        index += (number_of_words - 1) * BITS_IN_WORD;
426
0
        index += BITS_IN_WORD - count_leading_zeroes(m_words[number_of_words - 1]);
427
0
    }
428
0
    return index;
429
0
}
430
431
FLATTEN UnsignedBigInteger UnsignedBigInteger::plus(UnsignedBigInteger const& other) const
432
1.76k
{
433
1.76k
    UnsignedBigInteger result;
434
435
1.76k
    UnsignedBigIntegerAlgorithms::add_without_allocation(*this, other, result);
436
437
1.76k
    return result;
438
1.76k
}
439
440
FLATTEN UnsignedBigInteger UnsignedBigInteger::minus(UnsignedBigInteger const& other) const
441
0
{
442
0
    UnsignedBigInteger result;
443
444
0
    UnsignedBigIntegerAlgorithms::subtract_without_allocation(*this, other, result);
445
446
0
    return result;
447
0
}
448
449
FLATTEN UnsignedBigInteger UnsignedBigInteger::bitwise_or(UnsignedBigInteger const& other) const
450
0
{
451
0
    UnsignedBigInteger result;
452
453
0
    UnsignedBigIntegerAlgorithms::bitwise_or_without_allocation(*this, other, result);
454
455
0
    return result;
456
0
}
457
458
FLATTEN UnsignedBigInteger UnsignedBigInteger::bitwise_and(UnsignedBigInteger const& other) const
459
0
{
460
0
    UnsignedBigInteger result;
461
462
0
    UnsignedBigIntegerAlgorithms::bitwise_and_without_allocation(*this, other, result);
463
464
0
    return result;
465
0
}
466
467
FLATTEN UnsignedBigInteger UnsignedBigInteger::bitwise_xor(UnsignedBigInteger const& other) const
468
0
{
469
0
    UnsignedBigInteger result;
470
471
0
    UnsignedBigIntegerAlgorithms::bitwise_xor_without_allocation(*this, other, result);
472
473
0
    return result;
474
0
}
475
476
FLATTEN UnsignedBigInteger UnsignedBigInteger::bitwise_not_fill_to_one_based_index(size_t size) const
477
0
{
478
0
    UnsignedBigInteger result;
479
480
0
    UnsignedBigIntegerAlgorithms::bitwise_not_fill_to_one_based_index_without_allocation(*this, size, result);
481
482
0
    return result;
483
0
}
484
485
FLATTEN UnsignedBigInteger UnsignedBigInteger::shift_left(size_t num_bits) const
486
0
{
487
0
    UnsignedBigInteger output;
488
0
    UnsignedBigInteger temp_result;
489
0
    UnsignedBigInteger temp_plus;
490
491
0
    UnsignedBigIntegerAlgorithms::shift_left_without_allocation(*this, num_bits, temp_result, temp_plus, output);
492
493
0
    return output;
494
0
}
495
496
FLATTEN UnsignedBigInteger UnsignedBigInteger::shift_right(size_t num_bits) const
497
0
{
498
0
    UnsignedBigInteger output;
499
500
0
    UnsignedBigIntegerAlgorithms::shift_right_without_allocation(*this, num_bits, output);
501
502
0
    return output;
503
0
}
504
505
FLATTEN UnsignedBigInteger UnsignedBigInteger::multiplied_by(UnsignedBigInteger const& other) const
506
1.76k
{
507
1.76k
    UnsignedBigInteger result;
508
1.76k
    UnsignedBigInteger temp_shift_result;
509
1.76k
    UnsignedBigInteger temp_shift_plus;
510
1.76k
    UnsignedBigInteger temp_shift;
511
512
1.76k
    UnsignedBigIntegerAlgorithms::multiply_without_allocation(*this, other, temp_shift_result, temp_shift_plus, temp_shift, result);
513
514
1.76k
    return result;
515
1.76k
}
516
517
FLATTEN UnsignedDivisionResult UnsignedBigInteger::divided_by(UnsignedBigInteger const& divisor) const
518
0
{
519
0
    UnsignedBigInteger quotient;
520
0
    UnsignedBigInteger remainder;
521
522
    // If we actually have a u16-compatible divisor, short-circuit to the
523
    // less computationally-intensive "divide_u16_without_allocation" method.
524
0
    if (divisor.trimmed_length() == 1 && divisor.m_words[0] < (1 << 16)) {
525
0
        UnsignedBigIntegerAlgorithms::divide_u16_without_allocation(*this, divisor.m_words[0], quotient, remainder);
526
0
        return UnsignedDivisionResult { quotient, remainder };
527
0
    }
528
529
0
    UnsignedBigInteger temp_shift_result;
530
0
    UnsignedBigInteger temp_shift_plus;
531
0
    UnsignedBigInteger temp_shift;
532
0
    UnsignedBigInteger temp_minus;
533
534
0
    UnsignedBigIntegerAlgorithms::divide_without_allocation(*this, divisor, quotient, remainder);
535
536
0
    return UnsignedDivisionResult { quotient, remainder };
537
0
}
538
539
u32 UnsignedBigInteger::hash() const
540
0
{
541
0
    if (m_cached_hash != 0)
542
0
        return m_cached_hash;
543
544
0
    return m_cached_hash = string_hash((char const*)m_words.data(), sizeof(Word) * m_words.size());
545
0
}
546
547
void UnsignedBigInteger::set_bit_inplace(size_t bit_index)
548
0
{
549
0
    size_t const word_index = bit_index / UnsignedBigInteger::BITS_IN_WORD;
550
0
    size_t const inner_word_index = bit_index % UnsignedBigInteger::BITS_IN_WORD;
551
552
0
    m_words.ensure_capacity(word_index + 1);
553
554
0
    for (size_t i = length(); i <= word_index; ++i) {
555
0
        m_words.unchecked_append(0);
556
0
    }
557
0
    m_words[word_index] |= (1 << inner_word_index);
558
559
0
    m_cached_trimmed_length = {};
560
0
    m_cached_hash = 0;
561
0
}
562
563
bool UnsignedBigInteger::operator==(UnsignedBigInteger const& other) const
564
3.98k
{
565
3.98k
    if (is_invalid() != other.is_invalid())
566
0
        return false;
567
568
3.98k
    auto length = trimmed_length();
569
570
3.98k
    if (length != other.trimmed_length())
571
1.83k
        return false;
572
573
2.15k
    return !__builtin_memcmp(m_words.data(), other.words().data(), length * (BITS_IN_WORD / 8));
574
3.98k
}
575
576
bool UnsignedBigInteger::operator!=(UnsignedBigInteger const& other) const
577
1.42k
{
578
1.42k
    return !(*this == other);
579
1.42k
}
580
581
bool UnsignedBigInteger::operator<(UnsignedBigInteger const& other) const
582
1.36k
{
583
1.36k
    auto length = trimmed_length();
584
1.36k
    auto other_length = other.trimmed_length();
585
586
1.36k
    if (length < other_length) {
587
467
        return true;
588
467
    }
589
590
899
    if (length > other_length) {
591
34
        return false;
592
34
    }
593
594
865
    if (length == 0) {
595
0
        return false;
596
0
    }
597
865
    for (int i = length - 1; i >= 0; --i) {
598
865
        if (m_words[i] == other.m_words[i])
599
0
            continue;
600
865
        return m_words[i] < other.m_words[i];
601
865
    }
602
0
    return false;
603
865
}
604
605
bool UnsignedBigInteger::operator>(UnsignedBigInteger const& other) const
606
1.42k
{
607
1.42k
    return *this != other && !(*this < other);
608
1.42k
}
609
610
bool UnsignedBigInteger::operator>=(UnsignedBigInteger const& other) const
611
0
{
612
0
    return *this > other || *this == other;
613
0
}
614
615
UnsignedBigInteger::CompareResult UnsignedBigInteger::compare_to_double(double value) const
616
0
{
617
0
    VERIFY(!isnan(value));
618
619
0
    if (isinf(value)) {
620
0
        bool is_positive_infinity = __builtin_isinf_sign(value) > 0;
621
0
        return is_positive_infinity ? CompareResult::DoubleGreaterThanBigInt : CompareResult::DoubleLessThanBigInt;
622
0
    }
623
624
0
    bool value_is_negative = value < 0;
625
626
0
    if (value_is_negative)
627
0
        return CompareResult::DoubleLessThanBigInt;
628
629
    // Value is zero.
630
0
    if (value == 0.0) {
631
0
        VERIFY(!value_is_negative);
632
        // Either we are also zero or value is certainly less than us.
633
0
        return is_zero() ? CompareResult::DoubleEqualsBigInt : CompareResult::DoubleLessThanBigInt;
634
0
    }
635
636
    // If value is not zero but we are, value must be greater.
637
0
    if (is_zero())
638
0
        return CompareResult::DoubleGreaterThanBigInt;
639
640
0
    auto extractor = FloatExtractor<double>::from_float(value);
641
642
    // Value cannot be negative at this point.
643
0
    VERIFY(extractor.sign == 0);
644
    // Exponent cannot be all set, as then we must be NaN or infinity.
645
0
    VERIFY(extractor.exponent != (1 << extractor.exponent_bits) - 1);
646
647
0
    i32 real_exponent = extractor.exponent - extractor.exponent_bias;
648
0
    if (real_exponent < 0) {
649
        // value is less than 1, and we cannot be zero so value must be less.
650
0
        return CompareResult::DoubleLessThanBigInt;
651
0
    }
652
653
0
    u64 bigint_bits_needed = one_based_index_of_highest_set_bit();
654
0
    VERIFY(bigint_bits_needed > 0);
655
656
    // Double value is `-1^sign (1.mantissa) * 2^(exponent - bias)` so we need
657
    // `exponent - bias + 1` bit to represent doubles value,
658
    // for example `exponent - bias` = 3, sign = 0 and mantissa = 0 we get
659
    // `-1^0 * 2^3 * 1 = 8` which needs 4 bits to store 8 (0b1000).
660
0
    u32 double_bits_needed = real_exponent + 1;
661
662
    // If we need more bits to represent us, we must be of greater value.
663
0
    if (bigint_bits_needed > double_bits_needed)
664
0
        return CompareResult::DoubleLessThanBigInt;
665
    // If we need less bits to represent us, we must be of less value.
666
0
    if (bigint_bits_needed < double_bits_needed)
667
0
        return CompareResult::DoubleGreaterThanBigInt;
668
669
0
    u64 mantissa_bits = extractor.mantissa;
670
671
    // We add the bit which represents the 1. of the double value calculation.
672
0
    constexpr u64 mantissa_extended_bit = 1ull << extractor.mantissa_bits;
673
674
0
    mantissa_bits |= mantissa_extended_bit;
675
676
    // Now we shift value to the left virtually, with `exponent - bias` steps
677
    // we then pretend both it and the big int are extended with virtual zeros.
678
0
    auto next_bigint_word = (BITS_IN_WORD - 1 + bigint_bits_needed) / BITS_IN_WORD;
679
680
0
    VERIFY(next_bigint_word == trimmed_length());
681
682
0
    auto msb_in_top_word_index = (bigint_bits_needed - 1) % BITS_IN_WORD;
683
0
    VERIFY(msb_in_top_word_index == (BITS_IN_WORD - count_leading_zeroes(words()[next_bigint_word - 1]) - 1));
684
685
    // We will keep the bits which are still valid in the mantissa at the top of mantissa bits.
686
0
    mantissa_bits <<= 64 - (extractor.mantissa_bits + 1);
687
688
0
    auto bits_left_in_mantissa = static_cast<size_t>(extractor.mantissa_bits) + 1;
689
690
0
    auto get_next_value_bits = [&](size_t num_bits) -> Word {
691
0
        VERIFY(num_bits < 63);
692
0
        VERIFY(bits_left_in_mantissa > 0);
693
0
        if (num_bits > bits_left_in_mantissa)
694
0
            num_bits = bits_left_in_mantissa;
695
696
0
        bits_left_in_mantissa -= num_bits;
697
698
0
        u64 extracted_bits = mantissa_bits & (((1ull << num_bits) - 1) << (64 - num_bits));
699
        // Now shift the bits down to put the most significant bit on the num_bits position
700
        // this means the rest will be "virtual" zeros.
701
0
        extracted_bits >>= 32;
702
703
        // Now shift away the used bits and fit the result into a Word.
704
0
        mantissa_bits <<= num_bits;
705
706
0
        VERIFY(extracted_bits <= NumericLimits<Word>::max());
707
0
        return static_cast<Word>(extracted_bits);
708
0
    };
709
710
0
    auto bits_in_next_bigint_word = msb_in_top_word_index + 1;
711
712
0
    while (next_bigint_word > 0 && bits_left_in_mantissa > 0) {
713
0
        Word bigint_word = words()[next_bigint_word - 1];
714
0
        Word double_word = get_next_value_bits(bits_in_next_bigint_word);
715
716
        // For the first bit we have to align it with the top bit of bigint
717
        // and for all the other cases bits_in_next_bigint_word is 32 so this does nothing.
718
0
        double_word >>= 32 - bits_in_next_bigint_word;
719
720
0
        if (bigint_word < double_word)
721
0
            return CompareResult::DoubleGreaterThanBigInt;
722
723
0
        if (bigint_word > double_word)
724
0
            return CompareResult::DoubleLessThanBigInt;
725
726
0
        --next_bigint_word;
727
0
        bits_in_next_bigint_word = BITS_IN_WORD;
728
0
    }
729
730
    // If there are still bits left in bigint than any non zero bit means it has greater value.
731
0
    if (next_bigint_word > 0) {
732
0
        VERIFY(bits_left_in_mantissa == 0);
733
0
        while (next_bigint_word > 0) {
734
0
            if (words()[next_bigint_word - 1] != 0)
735
0
                return CompareResult::DoubleLessThanBigInt;
736
0
            --next_bigint_word;
737
0
        }
738
0
    } else if (bits_left_in_mantissa > 0) {
739
0
        VERIFY(next_bigint_word == 0);
740
        // Similarly if there are still any bits set in the mantissa it has greater value.
741
0
        if (mantissa_bits != 0)
742
0
            return CompareResult::DoubleGreaterThanBigInt;
743
0
    }
744
745
    // Otherwise if both don't have bits left or the rest of the bits are zero they are equal.
746
0
    return CompareResult::DoubleEqualsBigInt;
747
0
}
748
749
}
750
751
ErrorOr<void> AK::Formatter<Crypto::UnsignedBigInteger>::format(FormatBuilder& fmtbuilder, Crypto::UnsignedBigInteger const& value)
752
0
{
753
0
    if (value.is_invalid())
754
0
        return fmtbuilder.put_string("invalid"sv);
755
756
0
    StringBuilder builder;
757
0
    for (int i = value.length() - 1; i >= 0; --i)
758
0
        TRY(builder.try_appendff("{}|", value.words()[i]));
759
760
0
    return Formatter<StringView>::format(fmtbuilder, builder.string_view());
761
0
}