diff --git a/packages/util-crypto/src/xxhash/xxhash64.ts b/packages/util-crypto/src/xxhash/xxhash64.ts index f450d1a65..492b42409 100644 --- a/packages/util-crypto/src/xxhash/xxhash64.ts +++ b/packages/util-crypto/src/xxhash/xxhash64.ts @@ -61,7 +61,7 @@ function fromU8a (u8a: Uint8Array, p: number, count: 2 | 4): bigint { let offset = 0; for (let i = 0; i < count; i++, offset += 2) { - bigints[i] = BigInt(u8a[p + offset] | (u8a[p + 1 + offset] << 8)); + bigints[i] = _n(u8a[p + offset] | (u8a[p + 1 + offset] << 8)); } let result = _0n; @@ -86,7 +86,7 @@ function toU8a (h64: bigint): Uint8Array { } function state (initSeed: bigint | number): State { - const seed = BigInt(initSeed); + const seed = _n(initSeed); return { seed, @@ -133,7 +133,7 @@ function init (state: State, input: Uint8Array): State { export function xxhash64 (input: Uint8Array, initSeed: bigint | number): Uint8Array { const { seed, u8a, u8asize, v1, v2, v3, v4 } = init(state(initSeed), input); let p = 0; - let h64 = U64 & (BigInt(input.length) + ( + let h64 = U64 & (_n(input.length) + ( input.length >= 32 ? (((((((((rotl(v1, _1n) + rotl(v2, _7n) + rotl(v3, _12n) + rotl(v4, _18n)) ^ (P64_1 * rotl(v1 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v2 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v3 * P64_2, _31n))) * P64_1 + P64_4) ^ (P64_1 * rotl(v4 * P64_2, _31n))) * P64_1 + P64_4) : (seed + P64_5) @@ -150,7 +150,7 @@ export function xxhash64 (input: Uint8Array, initSeed: bigint | number): Uint8Ar } while (p < u8asize) { - h64 = U64 & (P64_1 * rotl(h64 ^ (P64_5 * BigInt(u8a[p++])), _11n)); + h64 = U64 & (P64_1 * rotl(h64 ^ (P64_5 * _n(u8a[p++])), _11n)); } h64 = U64 & (P64_2 * (h64 ^ (h64 >> _33n))); diff --git a/packages/util/package.json b/packages/util/package.json index 34d31f11f..19ba9a3c7 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -38,6 +38,7 @@ "main": "index.js", "dependencies": { "@babel/runtime": "^7.16.3", + "@polkadot/x-global": "8.0.6-6", "@polkadot/x-textdecoder": "8.0.6-6", "@polkadot/x-textencoder": "8.0.6-6", "@types/bn.js": "^4.11.6", diff --git a/packages/util/src/bi/consts.ts b/packages/util/src/bi/consts.ts index f0a3b2ee9..ed6cba467 100644 --- a/packages/util/src/bi/consts.ts +++ b/packages/util/src/bi/consts.ts @@ -1,13 +1,17 @@ // Copyright 2017-2021 @polkadot/util authors & contributors // SPDX-License-Identifier: Apache-2.0 +import { xglobal } from '@polkadot/x-global'; + +import { hasBigInt } from '../has'; + /** * @name _n * @description Creates a new instance of BigInt in environments that do support it */ export function _n (n: string | number | bigint | boolean): bigint { - return typeof BigInt === 'function' && typeof BigInt.asIntN === 'function' - ? BigInt(n) + return hasBigInt + ? xglobal.BigInt(n) : Number.NaN as unknown as bigint; } diff --git a/packages/util/src/bi/toBigInt.ts b/packages/util/src/bi/toBigInt.ts index 1824e408f..ecddd2f2b 100644 --- a/packages/util/src/bi/toBigInt.ts +++ b/packages/util/src/bi/toBigInt.ts @@ -4,6 +4,7 @@ import type { BN } from '../bn/bn'; import type { HexString, ToBigInt, ToBn } from '../types'; +import { _n } from '../bi/consts'; import { hexToBigInt } from '../hex/toBigInt'; import { isBn } from '../is/bn'; import { isHex } from '../is/hex'; @@ -18,14 +19,14 @@ export function nToBigInt (value?: HexString | return typeof value === 'bigint' ? value : !value - ? BigInt(0) + ? _n(0) : isHex(value) ? hexToBigInt(value.toString()) : isBn(value) - ? BigInt(value.toString()) + ? _n(value.toString()) : isToBigInt(value) ? value.toBigInt() : isToBn(value) - ? BigInt(value.toBn().toString()) - : BigInt(value); + ? _n(value.toBn().toString()) + : _n(value); } diff --git a/packages/util/src/has.ts b/packages/util/src/has.ts index 8f0625ae3..865b8c5c4 100644 --- a/packages/util/src/has.ts +++ b/packages/util/src/has.ts @@ -1,7 +1,9 @@ // Copyright 2017-2021 @polkadot/util authors & contributors // SPDX-License-Identifier: Apache-2.0 -export const hasBigInt = typeof BigInt === 'function' && typeof BigInt.asIntN === 'function'; +import { xglobal } from '@polkadot/x-global'; + +export const hasBigInt = typeof xglobal.BigInt === 'function' && typeof xglobal.BigInt.asIntN === 'function'; export const hasBuffer = typeof Buffer !== 'undefined'; export const hasDirname = typeof __dirname !== 'undefined'; export const hasProcess = typeof process === 'object'; diff --git a/packages/util/src/hex/toBigInt.ts b/packages/util/src/hex/toBigInt.ts index fe9b6fd84..ed147b1f5 100644 --- a/packages/util/src/hex/toBigInt.ts +++ b/packages/util/src/hex/toBigInt.ts @@ -3,6 +3,7 @@ import type { ToBnOptions } from '../types'; +import { _n } from '../bi/consts'; import { objectSpread } from '../object/spread'; import { u8aToBigInt } from '../u8a/toBigInt'; import { hexToU8a } from './toU8a'; @@ -13,7 +14,7 @@ import { hexToU8a } from './toU8a'; */ export function hexToBigInt (value?: string | null, options: ToBnOptions = {}): bigint { if (!value || value === '0x') { - return BigInt(0); + return _n(0); } return u8aToBigInt( diff --git a/packages/util/src/u8a/toBigInt.ts b/packages/util/src/u8a/toBigInt.ts index 1a52ce6f8..8a696dfc6 100644 --- a/packages/util/src/u8a/toBigInt.ts +++ b/packages/util/src/u8a/toBigInt.ts @@ -31,14 +31,14 @@ function toBigInt (input: Uint8Array): bigint { const dvI = new DataView(input.buffer, input.byteOffset); const mod = input.length % 2; const length = input.length - mod; - let result = BigInt(0); + let result = _n(0); for (let i = 0; i < length; i += 2) { - result = (result * U16_MAX) + BigInt(dvI.getUint16(i)); + result = (result * U16_MAX) + _n(dvI.getUint16(i)); } if (mod) { - result = (result * U8_MAX) + BigInt(dvI.getUint8(length)); + result = (result * U8_MAX) + _n(dvI.getUint8(length)); } return result; @@ -50,7 +50,7 @@ function toBigInt (input: Uint8Array): bigint { */ export function u8aToBigInt (value: Uint8Array, options: ToBnOptions = {}): bigint { if (!value || !value.length) { - return BigInt(0); + return _n(0); } const { isLe, isNegative }: ToBnOptions = objectSpread({ isLe: true, isNegative: false }, options); diff --git a/packages/x-noble-hashes/src/_sha2.ts b/packages/x-noble-hashes/src/_sha2.ts index 232cce34f..ecdcda182 100644 --- a/packages/x-noble-hashes/src/_sha2.ts +++ b/packages/x-noble-hashes/src/_sha2.ts @@ -90,7 +90,7 @@ export abstract class SHA2> extends Hash { // NOTE: sha512 requires length to be 128bit integer, but length in JS will overflow before that // You need to write around 2 exabytes (u64_max / 8 / (1024**6)) for this to happen. // So we just write lowest 64bit of that value. - setBigUint64(view, blockLen - 8, BigInt(this.length * 8), isLE); + setBigUint64(view, blockLen - 8, _n(this.length * 8), isLE); this.process(view, 0); const oview = createView(out); this.get().forEach((v, i) => oview.setUint32(4 * i, v, isLE)); diff --git a/packages/x-noble-hashes/src/_u64.ts b/packages/x-noble-hashes/src/_u64.ts index 18b7553ae..7f576a89e 100644 --- a/packages/x-noble-hashes/src/_u64.ts +++ b/packages/x-noble-hashes/src/_u64.ts @@ -20,7 +20,7 @@ export function split(lst: bigint[], le = false) { return [Ah, Al]; } -export const toBig = (h: number, l: number) => (BigInt(h >>> 0) << _32n) | BigInt(l >>> 0); +export const toBig = (h: number, l: number) => (_n(h >>> 0) << _32n) | _n(l >>> 0); // for Shift in [0, 32) export const shrSH = (h: number, l: number, s: number) => h >>> s; export const shrSL = (h: number, l: number, s: number) => (h << (32 - s)) | (l >>> s); diff --git a/packages/x-noble-hashes/src/blake2b.ts b/packages/x-noble-hashes/src/blake2b.ts index 530b170c6..9d073d22e 100644 --- a/packages/x-noble-hashes/src/blake2b.ts +++ b/packages/x-noble-hashes/src/blake2b.ts @@ -2,7 +2,7 @@ // https://github.com/paulmillr/noble-hashes/pull/13 import * as blake2 from './_blake2'; import * as u64 from './_u64'; -import { toBytes, u32, wrapConstructorWithOpts } from './utils'; +import { _n, toBytes, u32, wrapConstructorWithOpts } from './utils'; // Same as SHA-512 but LE // prettier-ignore @@ -143,7 +143,7 @@ class BLAKE2b extends blake2.BLAKE2 { protected compress(msg: Uint32Array, offset: number, isLast: boolean) { this.get().forEach((v, i) => (BUF[i] = v)); // First half from state. BUF.set(IV, 16); // Second half from IV. - let { h, l } = u64.fromBig(BigInt(this.length)); + let { h, l } = u64.fromBig(_n(this.length)); BUF[24] = IV[8] ^ l; // Low word of the offset. BUF[25] = IV[9] ^ h; // High word. // Invert all bits for last block diff --git a/packages/x-noble-hashes/src/blake2s.ts b/packages/x-noble-hashes/src/blake2s.ts index 19d056366..0273041a6 100644 --- a/packages/x-noble-hashes/src/blake2s.ts +++ b/packages/x-noble-hashes/src/blake2s.ts @@ -2,7 +2,7 @@ // https://github.com/paulmillr/noble-hashes/pull/13 import * as u64 from './_u64'; import * as blake2 from './_blake2'; -import { rotr, toBytes, wrapConstructorWithOpts, u32 } from './utils'; +import { _n, rotr, toBytes, wrapConstructorWithOpts, u32 } from './utils'; // Initial state: // first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19) @@ -106,7 +106,7 @@ class BLAKE2s extends blake2.BLAKE2 { this.v7 = v7 | 0; } protected compress(msg: Uint32Array, offset: number, isLast: boolean) { - const { h, l } = u64.fromBig(BigInt(this.length)); + const { h, l } = u64.fromBig(_n(this.length)); // prettier-ignore const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = compress( diff --git a/packages/x-noble-hashes/src/blake3.ts b/packages/x-noble-hashes/src/blake3.ts index c96f2d75b..bf76f05f0 100644 --- a/packages/x-noble-hashes/src/blake3.ts +++ b/packages/x-noble-hashes/src/blake3.ts @@ -3,7 +3,7 @@ import * as u64 from './_u64'; import * as blake2 from './_blake2'; import * as blake2s from './blake2s'; -import { Input, u8, u32, toBytes, wrapConstructorWithOpts, assertNumber, HashXOF } from './utils'; +import { _n, Input, u8, u32, toBytes, wrapConstructorWithOpts, assertNumber, HashXOF } from './utils'; // Flag bitset enum Flags { @@ -84,7 +84,7 @@ class BLAKE3 extends blake2.BLAKE2 implements HashXOF { protected set() {} private b2Compress(counter: number, flags: number, buf: Uint32Array, bufPos: number = 0) { const { state, pos } = this; - const { h, l } = u64.fromBig(BigInt(counter), true); + const { h, l } = u64.fromBig(_n(counter), true); // prettier-ignore const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = blake2s.compress( @@ -160,7 +160,7 @@ class BLAKE3 extends blake2.BLAKE2 implements HashXOF { // Same as b2Compress, but doesn't modify state and returns 16 u32 array (instead of 8) private b2CompressOut() { const { state, pos, flags, buffer32, bufferOut32 } = this; - const { h, l } = u64.fromBig(BigInt(this.chunkOut++)); + const { h, l } = u64.fromBig(_n(this.chunkOut++)); // prettier-ignore const { v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15 } = blake2s.compress( diff --git a/packages/x-noble-hashes/src/utils.ts b/packages/x-noble-hashes/src/utils.ts index 1c07c3b7c..cc24735f9 100644 --- a/packages/x-noble-hashes/src/utils.ts +++ b/packages/x-noble-hashes/src/utils.ts @@ -5,10 +5,22 @@ export type TypedArray = Int8Array | Uint8ClampedArray | Uint8Array | Uint16Array | Int16Array | Uint32Array | Int32Array; +const xglobal = ( + typeof globalThis !== 'undefined' + ? globalThis + : typeof global !== 'undefined' + ? global + : typeof self !== 'undefined' + ? self + : typeof window !== 'undefined' + ? window + : this as unknown as typeof globalThis +); + // helper to protect against older bundlers export function _n (n: string | number | bigint | boolean): bigint { - return typeof BigInt === 'function' && typeof BigInt.asIntN === 'function' - ? BigInt(n) + return typeof xglobal.BigInt === 'function' && typeof xglobal.BigInt.asIntN === 'function' + ? xglobal.BigInt(n) : Number.NaN as unknown as bigint; } diff --git a/yarn.lock b/yarn.lock index ed881fc6e..6cef13e91 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2115,6 +2115,7 @@ __metadata: resolution: "@polkadot/util@workspace:packages/util" dependencies: "@babel/runtime": ^7.16.3 + "@polkadot/x-global": 8.0.6-6 "@polkadot/x-textdecoder": 8.0.6-6 "@polkadot/x-textencoder": 8.0.6-6 "@types/bn.js": ^4.11.6