| ... | @@ -142,21 +142,6 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) { | ... | @@ -142,21 +142,6 @@ void bigint_init_unsigned(BigInt *dest, uint64_t x) { |
| 142 | dest->is_negative = false; | 142 | dest->is_negative = false; |
| 143 | } | 143 | } |
| 144 | | 144 | |
| 145 | void bigint_init_u128(BigInt *dest, uint128_t x) { | | |
| 146 | uint64_t low = (uint64_t)(x & UINT64_MAX); | | |
| 147 | uint64_t high = (uint64_t)(x >> 64); | | |
| 148 | | | |
| 149 | if (high == 0) { | | |
| 150 | return bigint_init_unsigned(dest, low); | | |
| 151 | } | | |
| 152 | | | |
| 153 | dest->digit_count = 2; | | |
| 154 | dest->data.digits = allocate_nonzero<uint64_t>(2); | | |
| 155 | dest->data.digits[0] = low; | | |
| 156 | dest->data.digits[1] = high; | | |
| 157 | dest->is_negative = false; | | |
| 158 | } | | |
| 159 | | | |
| 160 | void bigint_init_signed(BigInt *dest, int64_t x) { | 145 | void bigint_init_signed(BigInt *dest, int64_t x) { |
| 161 | if (x >= 0) { | 146 | if (x >= 0) { |
| 162 | return bigint_init_unsigned(dest, x); | 147 | return bigint_init_unsigned(dest, x); |
| ... | @@ -580,16 +565,24 @@ void bigint_sub_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t | ... | @@ -580,16 +565,24 @@ void bigint_sub_wrap(BigInt *dest, const BigInt *op1, const BigInt *op2, size_t |
| 580 | return bigint_add_wrap(dest, op1, &op2_negated, bit_count, is_signed); | 565 | return bigint_add_wrap(dest, op1, &op2_negated, bit_count, is_signed); |
| 581 | } | 566 | } |
| 582 | | 567 | |
| 583 | static void mul_overflow(uint64_t x, uint64_t y, uint64_t *result, uint64_t *carry) { | 568 | static void mul_overflow(uint64_t op1, uint64_t op2, uint64_t *lo, uint64_t *hi) { |
| 584 | if (!mul_u64_overflow(x, y, result)) { | 569 | uint64_t u1 = (op1 & 0xffffffff); |
| 585 | *carry = 0; | 570 | uint64_t v1 = (op2 & 0xffffffff); |
| 586 | return; | 571 | uint64_t t = (u1 * v1); |
| 587 | } | 572 | uint64_t w3 = (t & 0xffffffff); |
| | 573 | uint64_t k = (t >> 32); |
| | 574 | |
| | 575 | op1 >>= 32; |
| | 576 | t = (op1 * v1) + k; |
| | 577 | k = (t & 0xffffffff); |
| | 578 | uint64_t w1 = (t >> 32); |
| | 579 | |
| | 580 | op2 >>= 32; |
| | 581 | t = (u1 * op2) + k; |
| | 582 | k = (t >> 32); |
| 588 | | 583 | |
| 589 | uint128_t big_x = x; | 584 | *hi = (op1 * op2) + w1 + k; |
| 590 | uint128_t big_y = y; | 585 | *lo = (t << 32) + w3; |
| 591 | uint128_t big_result = big_x * big_y; | | |
| 592 | *carry = big_result >> 64; | | |
| 593 | } | 586 | } |
| 594 | | 587 | |
| 595 | static void mul_scalar(BigInt *dest, const BigInt *op, uint64_t scalar) { | 588 | static void mul_scalar(BigInt *dest, const BigInt *op, uint64_t scalar) { |