Add a helper for de-dupe of *AsHex (#1224)

* Add a helper for de-dupe of *AsHex

* Update packages/util-crypto/src/random/asU8a.ts

* lint

* isWasmOnly helper

* bit hasher
This commit is contained in:
Jaco
2021-11-21 20:21:20 +02:00
committed by GitHub
parent 1606dfd9ca
commit e8af9b5a1e
25 changed files with 112 additions and 165 deletions
-28
View File
@@ -1,28 +0,0 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { HexString } from '@polkadot/util/types';
import { u8aToHex } from '@polkadot/util';
import { blake2AsU8a } from './asU8a';
/**
* @name blake2AsHex
* @summary Creates a blake2b hex from the input.
* @description
* From a `Uint8Array` input, create the blake2b and return the result as a hex string with the specified `bitLength`.
* @example
* <BR>
*
* ```javascript
* import { blake2AsHex } from '@polkadot/util-crypto';
*
* blake2AsHex('abc'); // => 0xba80a53f981c4d0d
* ```
*/
export function blake2AsHex (data: HexString | Uint8Array | string, bitLength = 256, key?: Uint8Array | null, onlyJs?: boolean): HexString {
return u8aToHex(
blake2AsU8a(data, bitLength, key, onlyJs)
);
}
+10 -2
View File
@@ -6,7 +6,9 @@ import type { HexString } from '@polkadot/util/types';
import js from 'blakejs';
import { u8aToU8a } from '@polkadot/util';
import { blake2b, isReady } from '@polkadot/wasm-crypto';
import { blake2b } from '@polkadot/wasm-crypto';
import { createAsHex, isWasmOnly } from '../helpers';
/**
* @name blake2AsU8a
@@ -26,7 +28,13 @@ export function blake2AsU8a (data: HexString | Uint8Array | string, bitLength =
const byteLength = Math.ceil(bitLength / 8);
const u8a = u8aToU8a(data);
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? blake2b(u8a, u8aToU8a(key), byteLength)
: js.blake2b(u8a, key || undefined, byteLength);
}
/**
* @name blake2AsHex
* @description Creates a blake2b hex from the input.
*/
export const blake2AsHex = createAsHex(blake2AsU8a);
+1 -2
View File
@@ -5,5 +5,4 @@
* @summary Create blake2b values with specified bitlengths
*/
export { blake2AsHex } from './asHex';
export { blake2AsU8a } from './asU8a';
export { blake2AsHex, blake2AsU8a } from './asU8a';
+22
View File
@@ -0,0 +1,22 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { HexString } from '@polkadot/util/types';
import { u8aToHex } from '@polkadot/util';
import { isReady } from '@polkadot/wasm-crypto';
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function createAsHex <T extends (...args: any[]) => Uint8Array> (fn: T): (...args: Parameters<T>) => HexString {
return (...args: Parameters<T>): HexString =>
u8aToHex(fn(...args));
}
export function createBitHasher <T> (bitLength: T, fn: (data: HexString | Buffer | Uint8Array | string, bitLength: T, onlyJs?: boolean) => Uint8Array): (data: HexString | Buffer | Uint8Array | string, onlyJs?: boolean) => Uint8Array {
return (data: HexString | Buffer | Uint8Array | string, onlyJs?: boolean): Uint8Array =>
fn(data, bitLength, onlyJs);
}
export function isWasmOnly (onlyJs?: boolean): boolean {
return isReady() && !onlyJs;
}
+4 -2
View File
@@ -4,7 +4,9 @@
import hash from 'hash.js';
import { u8aToU8a } from '@polkadot/util';
import { hmacSha256, hmacSha512, isReady } from '@polkadot/wasm-crypto';
import { hmacSha256, hmacSha512 } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
type HashFn = (key: Uint8Array | string, data: Uint8Array, onlyJs?: boolean) => Uint8Array;
@@ -17,7 +19,7 @@ export function hmacShaAsU8a (key: Uint8Array | string, data: Uint8Array, bitLen
const is256 = bitLength === 256;
const u8aKey = u8aToU8a(key);
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? is256
? hmacSha256(u8aKey, data)
: hmacSha512(u8aKey, data)
-28
View File
@@ -1,28 +0,0 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { HexString } from '@polkadot/util/types';
import { u8aToHex } from '@polkadot/util';
import { keccakAsU8a } from './asU8a';
/**
* @name keccakAsHex
* @summary Creates a keccak hex string from the input.
* @description
* From either a `string` or a `Buffer` input, create the keccak and return the result as a `0x` prefixed hex string.
* @example
* <BR>
*
* ```javascript
* import { keccakAsHex } from '@polkadot/util-crypto';
*
* keccakAsHex('123'); // => 0x...
* ```
*/
export function keccakAsHex (value: HexString | Buffer | Uint8Array | string, bitLength?: 256 | 512): HexString {
return u8aToHex(
keccakAsU8a(value, bitLength)
);
}
+20 -10
View File
@@ -6,14 +6,9 @@ import type { HexString } from '@polkadot/util/types';
import js from 'js-sha3';
import { u8aToU8a } from '@polkadot/util';
import { isReady, keccak256, keccak512 } from '@polkadot/wasm-crypto';
import { keccak256, keccak512 } from '@polkadot/wasm-crypto';
type HashFn = (value: HexString | Buffer | Uint8Array | string, onlyJs?: boolean) => Uint8Array;
function createKeccak (bitLength: 256 | 512 = 256): HashFn {
return (value: HexString | Buffer | Uint8Array | string, onlyJs?: boolean): Uint8Array =>
keccakAsU8a(value, bitLength, onlyJs);
}
import { createAsHex, createBitHasher, isWasmOnly } from '../helpers';
/**
* @name keccakAsU8a
@@ -33,7 +28,7 @@ export function keccakAsU8a (value: HexString | Buffer | Uint8Array | string, bi
const is256 = bitLength === 256;
const u8a = u8aToU8a(value);
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? is256
? keccak256(u8a)
: keccak512(u8a)
@@ -44,5 +39,20 @@ export function keccakAsU8a (value: HexString | Buffer | Uint8Array | string, bi
);
}
export const keccak256AsU8a = createKeccak(256);
export const keccak512AsU8a = createKeccak(512);
/**
* @name keccak256AsU8a
* @description Creates a keccak256 Uint8Array from the input.
*/
export const keccak256AsU8a = createBitHasher(256, keccakAsU8a);
/**
* @name keccak512AsU8a
* @description Creates a keccak512 Uint8Array from the input.
*/
export const keccak512AsU8a = createBitHasher(512, keccakAsU8a);
/**
* @name keccakAsHex
* @description Creates a keccak hex string from the input.
*/
export const keccakAsHex = createAsHex(keccakAsU8a);
+1 -2
View File
@@ -5,5 +5,4 @@
* @summary Create Keccak256/512 values as hex & Uint8Array output
*/
export { keccakAsHex } from './asHex';
export { keccakAsU8a, keccak256AsU8a, keccak512AsU8a } from './asU8a';
export { keccakAsHex, keccakAsU8a, keccak256AsU8a, keccak512AsU8a } from './asU8a';
@@ -1,8 +1,9 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { bip39Generate, isReady } from '@polkadot/wasm-crypto';
import { bip39Generate } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
import { generateMnemonic } from './bip39';
export type WordCount = 12 | 15 | 18 | 21 | 24;
@@ -29,7 +30,7 @@ const STRENGTH_MAP = {
* ```
*/
export function mnemonicGenerate (numWords: WordCount = 12, onlyJs?: boolean): string {
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? bip39Generate(numWords)
: generateMnemonic(STRENGTH_MAP[numWords]);
}
@@ -1,12 +1,13 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { bip39ToEntropy, isReady } from '@polkadot/wasm-crypto';
import { bip39ToEntropy } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
import { mnemonicToEntropy as jsToEntropy } from './bip39';
export function mnemonicToEntropy (mnemonic: string, onlyJs?: boolean): Uint8Array {
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? bip39ToEntropy(mnemonic)
: jsToEntropy(mnemonic);
}
@@ -2,8 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
import { assert } from '@polkadot/util';
import { bip39ToSeed, isReady } from '@polkadot/wasm-crypto';
import { bip39ToSeed } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
import { mnemonicToSeedSync } from './bip39';
import { mnemonicValidate } from './validate';
@@ -29,7 +30,7 @@ export function mnemonicToLegacySeed (mnemonic: string, password = '', onlyJs?:
assert([32, 64].includes(byteLength), () => `Invalid seed length ${byteLength}, expected 32 or 64`);
if (byteLength === 32) {
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? bip39ToSeed(mnemonic, password)
: mnemonicToSeedSync(mnemonic, password).subarray(0, 32);
} else if (byteLength === 64) {
@@ -2,8 +2,9 @@
// SPDX-License-Identifier: Apache-2.0
import { assert, stringToU8a } from '@polkadot/util';
import { bip39ToMiniSecret, isReady } from '@polkadot/wasm-crypto';
import { bip39ToMiniSecret } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
import { pbkdf2Encode } from '../pbkdf2';
import { mnemonicToEntropy } from './toEntropy';
import { mnemonicValidate } from './validate';
@@ -11,7 +12,7 @@ import { mnemonicValidate } from './validate';
export function mnemonicToMiniSecret (mnemonic: string, password = '', onlyJs?: boolean): Uint8Array {
assert(mnemonicValidate(mnemonic), 'Invalid bip39 mnemonic specified');
if (isReady() && !onlyJs) {
if (isWasmOnly(onlyJs)) {
return bip39ToMiniSecret(mnemonic, password);
}
@@ -1,8 +1,9 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import { bip39Validate, isReady } from '@polkadot/wasm-crypto';
import { bip39Validate } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
import { validateMnemonic } from './bip39';
/**
@@ -19,7 +20,7 @@ import { validateMnemonic } from './bip39';
* ```
*/
export function mnemonicValidate (mnemonic: string, onlyJs?: boolean): boolean {
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? bip39Validate(mnemonic)
: validateMnemonic(mnemonic);
}
+4 -2
View File
@@ -7,7 +7,9 @@ import type { Keypair } from '../types';
import nacl from 'tweetnacl';
import { assert, u8aToU8a } from '@polkadot/util';
import { ed25519Sign, isReady } from '@polkadot/wasm-crypto';
import { ed25519Sign } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
/**
* @name naclSign
@@ -28,7 +30,7 @@ export function naclSign (message: HexString | Uint8Array | string, { publicKey,
const messageU8a = u8aToU8a(message);
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? ed25519Sign(publicKey as Uint8Array, secretKey.subarray(0, 32), messageU8a)
: nacl.sign.detached(messageU8a, secretKey);
}
+4 -2
View File
@@ -6,7 +6,9 @@ import type { HexString } from '@polkadot/util/types';
import nacl from 'tweetnacl';
import { assert, u8aToU8a } from '@polkadot/util';
import { ed25519Verify, isReady } from '@polkadot/wasm-crypto';
import { ed25519Verify } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
/**
* @name naclSign
@@ -30,7 +32,7 @@ export function naclVerify (message: HexString | Uint8Array | string, signature:
assert(publicKeyU8a.length === 32, () => `Invalid publicKey, received ${publicKeyU8a.length}, expected 32`);
assert(signatureU8a.length === 64, () => `Invalid signature, received ${signatureU8a.length} bytes, expected 64`);
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? ed25519Verify(signatureU8a, messageU8a, publicKeyU8a)
: nacl.sign.detached.verify(messageU8a, signatureU8a, publicKeyU8a);
}
+3 -2
View File
@@ -4,8 +4,9 @@
import type { HexString } from '@polkadot/util/types';
import { u8aToU8a } from '@polkadot/util';
import { isReady, pbkdf2 } from '@polkadot/wasm-crypto';
import { pbkdf2 } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
import { randomAsU8a } from '../random/asU8a';
import { pbkdf2Sync } from './pbkdf2';
@@ -20,7 +21,7 @@ export function pbkdf2Encode (passphrase?: HexString | Buffer | Uint8Array | str
const u8aSalt = u8aToU8a(salt);
return {
password: isReady() && !onlyJs
password: isWasmOnly(onlyJs)
? pbkdf2(u8aPass, u8aSalt, rounds)
: pbkdf2Sync(u8aPass, u8aSalt, rounds),
rounds,
-28
View File
@@ -1,28 +0,0 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { HexString } from '@polkadot/util/types';
import { u8aToHex } from '@polkadot/util';
import { randomAsU8a } from './asU8a';
/**
* @name randomAsHex
* @summary Creates a hex string filled with random bytes.
* @description
* Returns a hex string with the specified (optional) length filled with random bytes.
* @example
* <BR>
*
* ```javascript
* import { randomAsHex } from '@polkadot/util-crypto';
*
* randomAsHex(); // => 0x...
* ```
*/
export function randomAsHex (length = 32): HexString {
return u8aToHex(
randomAsU8a(length)
);
}
+1 -1
View File
@@ -3,7 +3,7 @@
import { BN, hexToBn } from '@polkadot/util';
import { randomAsHex } from './asHex';
import { randomAsHex } from './asU8a';
const BN_53 = new BN(0b11111111111111111111111111111111111111111111111111111);
+8
View File
@@ -3,6 +3,8 @@
import { getRandomValues } from '@polkadot/x-randomvalues';
import { createAsHex } from '../helpers';
/**
* @name randomAsU8a
* @summary Creates a Uint8Array filled with random bytes.
@@ -20,3 +22,9 @@ import { getRandomValues } from '@polkadot/x-randomvalues';
export function randomAsU8a (length = 32): Uint8Array {
return getRandomValues(new Uint8Array(length));
}
/**
* @name randomAsHex
* @description Creates a hex string filled with random bytes.
*/
export const randomAsHex = createAsHex(randomAsU8a);
+1 -2
View File
@@ -5,6 +5,5 @@
* @summary Returns a sequence of secure random bytes in a variety of formats
*/
export { randomAsHex } from './asHex';
export { randomAsNumber } from './asNumber';
export { randomAsU8a } from './asU8a';
export { randomAsHex, randomAsU8a } from './asU8a';
+3 -2
View File
@@ -7,8 +7,9 @@ import type { Params } from './types';
import scryptsy from 'scryptsy';
import { bufferToU8a, u8aToBuffer, u8aToU8a } from '@polkadot/util';
import { isReady, scrypt } from '@polkadot/wasm-crypto';
import { scrypt } from '@polkadot/wasm-crypto';
import { isWasmOnly } from '../helpers';
import { randomAsU8a } from '../random/asU8a';
import { DEFAULT_PARAMS } from './defaults';
@@ -21,7 +22,7 @@ interface Result {
export function scryptEncode (passphrase?: HexString | Uint8Array | string, salt = randomAsU8a(), params = DEFAULT_PARAMS, onlyJs?: boolean): Result {
const u8a = u8aToU8a(passphrase);
const password = isReady() && !onlyJs
const password = isWasmOnly(onlyJs)
? scrypt(u8a, salt, Math.log2(params.N), params.r, params.p)
: bufferToU8a(
scryptsy(u8aToBuffer(u8a), u8aToBuffer(salt), params.N, params.r, params.p, 64)
+5 -10
View File
@@ -6,14 +6,9 @@ import type { HexString } from '@polkadot/util/types';
import hash from 'hash.js';
import { u8aToU8a } from '@polkadot/util';
import { isReady, sha256, sha512 } from '@polkadot/wasm-crypto';
import { sha256, sha512 } from '@polkadot/wasm-crypto';
type HashFn = (value: HexString | Buffer | Uint8Array | string, onlyJs?: boolean) => Uint8Array;
function createSha (bitLength: 256 | 512 = 256): HashFn {
return (value: HexString | Buffer | Uint8Array | string, onlyJs?: boolean): Uint8Array =>
shaAsU8a(value, bitLength, onlyJs);
}
import { createBitHasher, isWasmOnly } from '../helpers';
/**
* @name shaAsU8a
@@ -23,7 +18,7 @@ export function shaAsU8a (value: HexString | Buffer | Uint8Array | string, bitLe
const is256 = bitLength === 256;
const u8a = u8aToU8a(value);
return isReady() && !onlyJs
return isWasmOnly(onlyJs)
? is256
? sha256(u8a)
: sha512(u8a)
@@ -34,5 +29,5 @@ export function shaAsU8a (value: HexString | Buffer | Uint8Array | string, bitLe
);
}
export const sha256AsU8a = createSha(256);
export const sha512AsU8a = createSha(512);
export const sha256AsU8a = createBitHasher(256, shaAsU8a);
export const sha512AsU8a = createBitHasher(512, shaAsU8a);
-28
View File
@@ -1,28 +0,0 @@
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
// SPDX-License-Identifier: Apache-2.0
import type { HexString } from '@polkadot/util/types';
import { u8aToHex } from '@polkadot/util';
import { xxhashAsU8a } from './asU8a';
/**
* @name xxhashAsHex
* @summary Creates a xxhash64 hex from the input.
* @description
* From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash64 and return the result as a hex string with the specified `bitLength`.
* @example
* <BR>
*
* ```javascript
* import { xxhashAsHex } from '@polkadot/util-crypto';
*
* xxhashAsHex('abc'); // => 0x44bc2cf5ad770999
* ```
*/
export function xxhashAsHex (data: HexString | Buffer | Uint8Array | string, bitLength = 64): HexString {
return u8aToHex(
xxhashAsU8a(data, bitLength)
);
}
+9 -2
View File
@@ -4,8 +4,9 @@
import type { HexString } from '@polkadot/util/types';
import { u8aToU8a } from '@polkadot/util';
import { isReady, twox } from '@polkadot/wasm-crypto';
import { twox } from '@polkadot/wasm-crypto';
import { createAsHex, isWasmOnly } from '../helpers';
import xxhash64AsBn from './xxhash64/asBn';
/**
@@ -26,7 +27,7 @@ export function xxhashAsU8a (data: HexString | Buffer | Uint8Array | string, bit
const iterations = Math.ceil(bitLength / 64);
const u8a = u8aToU8a(data);
if (isReady() && !onlyJs) {
if (isWasmOnly(onlyJs)) {
return twox(u8a, iterations);
}
@@ -38,3 +39,9 @@ export function xxhashAsU8a (data: HexString | Buffer | Uint8Array | string, bit
return result;
}
/**
* @name xxhashAsHex
* @description Creates a xxhash64 hex from the input.
*/
export const xxhashAsHex = createAsHex(xxhashAsU8a);
+1 -2
View File
@@ -5,5 +5,4 @@
* @summary Create xxhash64 values with specified bitlengths
*/
export { xxhashAsHex } from './asHex';
export { xxhashAsU8a } from './asU8a';
export { xxhashAsHex, xxhashAsU8a } from './asU8a';