_u64.js 3.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. /**
  2. * Internal helpers for u64. BigUint64Array is too slow as per 2025, so we implement it using Uint32Array.
  3. * @todo re-check https://issues.chromium.org/issues/42212588
  4. * @module
  5. */
  6. const U32_MASK64 = /* @__PURE__ */ BigInt(2 ** 32 - 1);
  7. const _32n = /* @__PURE__ */ BigInt(32);
  8. function fromBig(n, le = false) {
  9. if (le)
  10. return { h: Number(n & U32_MASK64), l: Number((n >> _32n) & U32_MASK64) };
  11. return { h: Number((n >> _32n) & U32_MASK64) | 0, l: Number(n & U32_MASK64) | 0 };
  12. }
  13. function split(lst, le = false) {
  14. const len = lst.length;
  15. let Ah = new Uint32Array(len);
  16. let Al = new Uint32Array(len);
  17. for (let i = 0; i < len; i++) {
  18. const { h, l } = fromBig(lst[i], le);
  19. [Ah[i], Al[i]] = [h, l];
  20. }
  21. return [Ah, Al];
  22. }
  23. const toBig = (h, l) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0);
  24. // for Shift in [0, 32)
  25. const shrSH = (h, _l, s) => h >>> s;
  26. const shrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
  27. // Right rotate for Shift in [1, 32)
  28. const rotrSH = (h, l, s) => (h >>> s) | (l << (32 - s));
  29. const rotrSL = (h, l, s) => (h << (32 - s)) | (l >>> s);
  30. // Right rotate for Shift in (32, 64), NOTE: 32 is special case.
  31. const rotrBH = (h, l, s) => (h << (64 - s)) | (l >>> (s - 32));
  32. const rotrBL = (h, l, s) => (h >>> (s - 32)) | (l << (64 - s));
  33. // Right rotate for shift===32 (just swaps l&h)
  34. const rotr32H = (_h, l) => l;
  35. const rotr32L = (h, _l) => h;
  36. // Left rotate for Shift in [1, 32)
  37. const rotlSH = (h, l, s) => (h << s) | (l >>> (32 - s));
  38. const rotlSL = (h, l, s) => (l << s) | (h >>> (32 - s));
  39. // Left rotate for Shift in (32, 64), NOTE: 32 is special case.
  40. const rotlBH = (h, l, s) => (l << (s - 32)) | (h >>> (64 - s));
  41. const rotlBL = (h, l, s) => (h << (s - 32)) | (l >>> (64 - s));
  42. // JS uses 32-bit signed integers for bitwise operations which means we cannot
  43. // simple take carry out of low bit sum by shift, we need to use division.
  44. function add(Ah, Al, Bh, Bl) {
  45. const l = (Al >>> 0) + (Bl >>> 0);
  46. return { h: (Ah + Bh + ((l / 2 ** 32) | 0)) | 0, l: l | 0 };
  47. }
  48. // Addition with more than 2 elements
  49. const add3L = (Al, Bl, Cl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0);
  50. const add3H = (low, Ah, Bh, Ch) => (Ah + Bh + Ch + ((low / 2 ** 32) | 0)) | 0;
  51. const add4L = (Al, Bl, Cl, Dl) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0);
  52. const add4H = (low, Ah, Bh, Ch, Dh) => (Ah + Bh + Ch + Dh + ((low / 2 ** 32) | 0)) | 0;
  53. const add5L = (Al, Bl, Cl, Dl, El) => (Al >>> 0) + (Bl >>> 0) + (Cl >>> 0) + (Dl >>> 0) + (El >>> 0);
  54. const add5H = (low, Ah, Bh, Ch, Dh, Eh) => (Ah + Bh + Ch + Dh + Eh + ((low / 2 ** 32) | 0)) | 0;
  55. // prettier-ignore
  56. export { add, add3H, add3L, add4H, add4L, add5H, add5L, fromBig, rotlBH, rotlBL, rotlSH, rotlSL, rotr32H, rotr32L, rotrBH, rotrBL, rotrSH, rotrSL, shrSH, shrSL, split, toBig };
  57. // prettier-ignore
  58. const u64 = {
  59. fromBig, split, toBig,
  60. shrSH, shrSL,
  61. rotrSH, rotrSL, rotrBH, rotrBL,
  62. rotr32H, rotr32L,
  63. rotlSH, rotlSL, rotlBH, rotlBL,
  64. add, add3L, add3H, add4L, add4H, add5H, add5L,
  65. };
  66. export default u64;
  67. //# sourceMappingURL=_u64.js.map