| 604 | // will result in the lower N * 64 bits of the result being set. |
| 605 | template <int N> |
| 606 | inline void MultiplyUnsignedArray(const std::array<uint64_t, N>& lh, |
| 607 | const std::array<uint64_t, N>& rh, |
| 608 | std::array<uint64_t, N>* result) { |
| 609 | const auto lh_le = bit_util::little_endian::Make(lh); |
| 610 | const auto rh_le = bit_util::little_endian::Make(rh); |
| 611 | auto result_le = bit_util::little_endian::Make(result); |
| 612 | |
| 613 | for (int j = 0; j < N; ++j) { |
| 614 | uint64_t carry = 0; |
| 615 | for (int i = 0; i < N - j; ++i) { |
| 616 | uint128_t tmp(lh_le[i]); |
| 617 | tmp *= uint128_t(rh_le[j]); |
| 618 | tmp += uint128_t(result_le[i + j]); |
| 619 | tmp += uint128_t(carry); |
| 620 | result_le[i + j] = tmp.lo(); |
| 621 | carry = tmp.hi(); |
| 622 | } |
| 623 | } |
| 624 | } |
| 625 | |
| 626 | } // namespace |
| 627 | |