Use BigInt only via xglobal (#1272)

* Use BigInt only via xglobal

* Adjust

* yarn
This commit is contained in:
Jaco
2021-12-01 20:37:11 +02:00
committed by GitHub
parent ee99ffdbb4
commit 776a653f42
14 changed files with 49 additions and 27 deletions
+4 -4
View File
@@ -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)));
+1
View File
@@ -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",
+6 -2
View File
@@ -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;
}
+5 -4
View File
@@ -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 <ExtToBn extends ToBigInt | ToBn> (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);
}
+3 -1
View File
@@ -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';
+2 -1
View File
@@ -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(
+4 -4
View File
@@ -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);
+1 -1
View File
@@ -90,7 +90,7 @@ export abstract class SHA2<T extends SHA2<T>> extends Hash<T> {
// 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));
+1 -1
View File
@@ -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);
+2 -2
View File
@@ -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<BLAKE2b> {
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
+2 -2
View File
@@ -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<BLAKE2s> {
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(
+3 -3
View File
@@ -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<BLAKE3> implements HashXOF<BLAKE3> {
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<BLAKE3> implements HashXOF<BLAKE3> {
// 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(
+14 -2
View File
@@ -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;
}
+1
View File
@@ -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