Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a7606b6514 | ||
|
|
871b20c90a | ||
|
|
5d93642093 | ||
|
|
2b2fefb2bb | ||
|
|
1ede65db38 | ||
|
|
7090c3daec | ||
|
|
c03f53e097 | ||
|
|
2ec02e2580 | ||
|
|
6b4f9b3d2f | ||
|
|
d20c37ddd0 | ||
|
|
23d46b063c | ||
|
|
085862ce79 | ||
|
|
88580b98a6 | ||
|
|
fb8b80afd7 | ||
|
|
d3b5b4ad38 | ||
|
|
049e8dfde8 | ||
|
|
8230e3ceac | ||
|
|
37358d4d05 | ||
|
|
2cf6ffa3b1 | ||
|
|
d7f2a70071 | ||
|
|
eb96e2a7aa | ||
|
|
6965709351 | ||
|
|
1677d3eace | ||
|
|
4d77bf3c5b | ||
|
|
222bb74a81 | ||
|
|
90b4b61852 | ||
|
|
b1e209dfeb | ||
|
|
88beb4d81c | ||
|
|
3b2ecb87e9 | ||
|
|
79a2cd0e8f | ||
|
|
0c2d105f9d | ||
|
|
944d77c5f2 | ||
|
|
0fdf83effe | ||
|
|
66866e1a8e | ||
|
|
9abcc72143 | ||
|
|
6f0aa35098 | ||
|
|
93fb633ea6 | ||
|
|
5524e50baf | ||
|
|
e1354746b1 | ||
|
|
309722f285 | ||
|
|
4efd88869d | ||
|
|
ee0436a612 | ||
|
|
b4ca8219d9 | ||
|
|
d30a3ddedb | ||
|
|
fa5b5bca7e | ||
|
|
87afdb1d86 | ||
|
|
23f68c63f4 | ||
|
|
184dbccf39 | ||
|
|
06c06a8b73 | ||
|
|
82f5fec822 | ||
|
|
a953b3a78a | ||
|
|
19283b3c28 | ||
|
|
ac06f38118 | ||
|
|
f9e5c033ab | ||
|
|
de7817e6b5 | ||
|
|
5972551313 | ||
|
|
cf0aab479a | ||
|
|
5ab0b173b6 | ||
|
|
cf990dd4ec | ||
|
|
8a6fd0812a | ||
|
|
e93f8d7418 | ||
|
|
36f6407796 | ||
|
|
8ede488aec | ||
|
|
eb9d5b9585 | ||
|
|
20821aad40 | ||
|
|
23fa2b90a8 | ||
|
|
f94a1ea730 | ||
|
|
fc98cd9b45 | ||
|
|
5fdd967666 | ||
|
|
9043f335d4 | ||
|
|
d9231d26aa | ||
|
|
445e0f7ea6 | ||
|
|
ba0a183bd9 | ||
|
|
46beaa1151 | ||
|
|
31d55b218a | ||
|
|
9b30b4b09e | ||
|
|
cc0dd2a2b5 | ||
|
|
31a0a9b9d1 | ||
|
|
9e1e49a1b8 | ||
|
|
313b44388a | ||
|
|
30dd8169bc | ||
|
|
67450bc225 | ||
|
|
e9285e9ccd | ||
|
|
2a45652ce0 | ||
|
|
6d923da266 | ||
|
|
d55b48566b | ||
|
|
3ac567e1c4 | ||
|
|
d19713f548 |
@@ -1,5 +1,28 @@
|
|||||||
# CHANGELOG
|
# CHANGELOG
|
||||||
|
|
||||||
|
## 7.9.1 Nov 21, 2021
|
||||||
|
|
||||||
|
Contributed:
|
||||||
|
|
||||||
|
- Updated Polymesh genesisHash (Thanks to https://github.com/adamdossa)
|
||||||
|
|
||||||
|
Changes:
|
||||||
|
|
||||||
|
- Add strongly typed `object{Entries, Keys, Values}` utilities
|
||||||
|
- Add `{hex, u8a}ToBigInt` utilities
|
||||||
|
- Add `bi*` utilities for `bigint` operations (mirror of `bn*`)
|
||||||
|
- Add `stringPascalCase` utility
|
||||||
|
- Add `isCodec` to check for Codec-like structures
|
||||||
|
- Add `has*` detection shortcuts (e.g. `hasWasm` or `hasBuffer`)
|
||||||
|
- Add `sha256AsU8a` util (& replace use internally)
|
||||||
|
- Optimize for `hexToU8a` and `u8aToHex` functions
|
||||||
|
- Optimize `u8aEq` to use `DataView` for compares
|
||||||
|
- Align `base{32, 58, 64}*` around (audited) `micro-base`
|
||||||
|
- Space optimization for bip39 wordlists
|
||||||
|
- Sync with upstream Substrate ss58 registry
|
||||||
|
- Expand tests for uncovered functions
|
||||||
|
|
||||||
|
|
||||||
## 7.8.2 Nov 7, 2021
|
## 7.8.2 Nov 7, 2021
|
||||||
|
|
||||||
Changes:
|
Changes:
|
||||||
|
|||||||
+5
-6
@@ -10,7 +10,7 @@
|
|||||||
"url": "https://github.com/polkadot-js/common.git"
|
"url": "https://github.com/polkadot-js/common.git"
|
||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"version": "7.8.2",
|
"version": "7.9.1",
|
||||||
"workspaces": [
|
"workspaces": [
|
||||||
"packages/*"
|
"packages/*"
|
||||||
],
|
],
|
||||||
@@ -29,12 +29,11 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.16.0",
|
"@babel/core": "^7.16.0",
|
||||||
"@polkadot/dev": "^0.63.27",
|
"@polkadot/dev": "^0.63.29",
|
||||||
"@polkadot/ts": "^0.4.13",
|
"@polkadot/ts": "^0.4.14",
|
||||||
"@types/ed2curve": "^0.2.2",
|
"@types/jest": "^27.0.3"
|
||||||
"@types/jest": "^27.0.2"
|
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
"typescript": "^4.4.4"
|
"typescript": "^4.5.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,12 @@
|
|||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "7.8.2",
|
"version": "7.9.1",
|
||||||
"browser": "browser.js",
|
"browser": "browser.js",
|
||||||
"main": "node.js",
|
"main": "node.js",
|
||||||
"react-native": "react-native.js",
|
"react-native": "react-native.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.16.0",
|
"@babel/runtime": "^7.16.3",
|
||||||
"@ledgerhq/hw-transport": "^6.11.2",
|
"@ledgerhq/hw-transport": "^6.11.2",
|
||||||
"@ledgerhq/hw-transport-webhid": "^6.11.2",
|
"@ledgerhq/hw-transport-webhid": "^6.11.2",
|
||||||
"@ledgerhq/hw-transport-webusb": "^6.11.2"
|
"@ledgerhq/hw-transport-webusb": "^6.11.2"
|
||||||
|
|||||||
@@ -10,13 +10,6 @@ import LedgerWebUsb from '@ledgerhq/hw-transport-webusb';
|
|||||||
export { packageInfo } from './packageInfo';
|
export { packageInfo } from './packageInfo';
|
||||||
|
|
||||||
export const transports: TransportDef[] = [
|
export const transports: TransportDef[] = [
|
||||||
// deprecated
|
|
||||||
// import LedgerU2F from '@ledgerhq/hw-transport-u2f';
|
|
||||||
// {
|
|
||||||
// create: (): Promise<Transport> =>
|
|
||||||
// LedgerU2F.create(),
|
|
||||||
// type: 'u2f'
|
|
||||||
// },
|
|
||||||
{
|
{
|
||||||
create: (): Promise<Transport> =>
|
create: (): Promise<Transport> =>
|
||||||
LedgerWebUsb.create(),
|
LedgerWebUsb.create(),
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Auto-generated by @polkadot/dev, do not edit
|
// Auto-generated by @polkadot/dev, do not edit
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/hw-ledger-transports', version: '7.8.2' };
|
export const packageInfo = { name: '@polkadot/hw-ledger-transports', version: '7.9.1' };
|
||||||
|
|||||||
@@ -19,12 +19,12 @@
|
|||||||
"./detectPackage.cjs"
|
"./detectPackage.cjs"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "7.8.2",
|
"version": "7.9.1",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.16.0",
|
"@babel/runtime": "^7.16.3",
|
||||||
"@polkadot/hw-ledger-transports": "7.8.2",
|
"@polkadot/hw-ledger-transports": "7.9.1",
|
||||||
"@polkadot/util": "7.8.2",
|
"@polkadot/util": "7.9.1",
|
||||||
"@zondax/ledger-substrate": "^0.18.0"
|
"@zondax/ledger-substrate": "^0.18.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Auto-generated by @polkadot/dev, do not edit
|
// Auto-generated by @polkadot/dev, do not edit
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/hw-ledger', version: '7.8.2' };
|
export const packageInfo = { name: '@polkadot/hw-ledger', version: '7.9.1' };
|
||||||
|
|||||||
@@ -20,15 +20,15 @@
|
|||||||
"./detectPackage.cjs"
|
"./detectPackage.cjs"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "7.8.2",
|
"version": "7.9.1",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.16.0",
|
"@babel/runtime": "^7.16.3",
|
||||||
"@polkadot/util": "7.8.2",
|
"@polkadot/util": "7.9.1",
|
||||||
"@polkadot/util-crypto": "7.8.2"
|
"@polkadot/util-crypto": "7.9.1"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@polkadot/util": "7.8.2",
|
"@polkadot/util": "7.9.1",
|
||||||
"@polkadot/util-crypto": "7.8.2"
|
"@polkadot/util-crypto": "7.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Auto-generated by @polkadot/dev, do not edit
|
// Auto-generated by @polkadot/dev, do not edit
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/keyring', version: '7.8.2' };
|
export const packageInfo = { name: '@polkadot/keyring', version: '7.9.1' };
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ interface PairStateJson {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function pairToJson (type: KeypairType, { address, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json {
|
export function pairToJson (type: KeypairType, { address, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json {
|
||||||
return objectSpread({}, jsonEncryptFormat(encoded, ['pkcs8', type], isEncrypted), {
|
return objectSpread(jsonEncryptFormat(encoded, ['pkcs8', type], isEncrypted), {
|
||||||
address,
|
address,
|
||||||
meta
|
meta
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,13 +17,13 @@
|
|||||||
},
|
},
|
||||||
"sideEffects": false,
|
"sideEffects": false,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "7.8.2",
|
"version": "7.9.1",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.16.0"
|
"@babel/runtime": "^7.16.3"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@polkadot/util": "7.8.2",
|
"@polkadot/util": "7.9.1",
|
||||||
"@polkadot/x-fetch": "7.8.2"
|
"@polkadot/x-fetch": "7.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
// Copyright 2017-2021 @polkadot/networks authors & contributors
|
// Copyright 2017-2021 @polkadot/networks authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import type { KnownSubstrate, Ss58Registry } from './types';
|
import type { Ss58Registry } from './types';
|
||||||
|
|
||||||
import fs from 'fs';
|
import fs from 'fs';
|
||||||
|
|
||||||
import { stringify } from '@polkadot/util';
|
import { objectKeys, stringify } from '@polkadot/util';
|
||||||
import { fetch } from '@polkadot/x-fetch';
|
import { fetch } from '@polkadot/x-fetch';
|
||||||
|
|
||||||
import { substrateRegistry } from './defaults';
|
import { substrateRegistry } from './defaults';
|
||||||
@@ -52,7 +52,7 @@ describe('check latest Substrate ss58 registry', (): void => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('has the same values as the original', (): void => {
|
it('has the same values as the original', (): void => {
|
||||||
const fields = Object.keys(original.schema) as (keyof KnownSubstrate)[];
|
const fields = objectKeys(original.schema);
|
||||||
const errors = original.registry
|
const errors = original.registry
|
||||||
.map((n): [string, string[]] => {
|
.map((n): [string, string[]] => {
|
||||||
const other = allNetworks.find(({ prefix }) => prefix === n.prefix);
|
const other = allNetworks.find(({ prefix }) => prefix === n.prefix);
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ export const knownGenesis: KnownGenesis = {
|
|||||||
'0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'
|
'0x91b171bb158e2d3848fa23a9f1c25182fb8e20313b2c1eb49219da7a70ce90c3'
|
||||||
],
|
],
|
||||||
polymesh: [
|
polymesh: [
|
||||||
'0x9deeb940c92ae02111c3bd5baca89970384f4c9849f02a1b2e53e66414d30f9f'
|
'0x6fbd74e5e1d0a61d52ccfe9d4adaed16dd3a7caa37c6bc4d0c2fa12e8b2f4063'
|
||||||
],
|
],
|
||||||
stafi: [
|
stafi: [
|
||||||
'0x290a4149f09ea0e402c74c1c7e96ae4239588577fe78932f94f5404c68243d80'
|
'0x290a4149f09ea0e402c74c1c7e96ae4239588577fe78932f94f5404c68243d80'
|
||||||
@@ -104,5 +104,6 @@ export const knownTestnet: KnownTestnet = {
|
|||||||
'dock-testnet': true,
|
'dock-testnet': true,
|
||||||
jupiter: true,
|
jupiter: true,
|
||||||
'mathchain-testnet': true,
|
'mathchain-testnet': true,
|
||||||
|
subspace_testnet: true,
|
||||||
'zero-alphaville': true
|
'zero-alphaville': true
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Auto-generated by @polkadot/dev, do not edit
|
// Auto-generated by @polkadot/dev, do not edit
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/networks', version: '7.8.2' };
|
export const packageInfo = { name: '@polkadot/networks', version: '7.9.1' };
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ export const knownSubstrate: KnownSubstrate[] = [
|
|||||||
network: 'totem',
|
network: 'totem',
|
||||||
prefix: 14,
|
prefix: 14,
|
||||||
standardAccount: '*25519',
|
standardAccount: '*25519',
|
||||||
symbols: ['XTX'],
|
symbols: ['TOTEM'],
|
||||||
website: 'https://totemaccounting.com'
|
website: 'https://totemaccounting.com'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -467,6 +467,15 @@ export const knownSubstrate: KnownSubstrate[] = [
|
|||||||
symbols: ['LAYR'],
|
symbols: ['LAYR'],
|
||||||
website: 'https://composable.finance'
|
website: 'https://composable.finance'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
decimals: [9],
|
||||||
|
displayName: 'xx network',
|
||||||
|
network: 'xxnetwork',
|
||||||
|
prefix: 55,
|
||||||
|
standardAccount: '*25519',
|
||||||
|
symbols: ['XX'],
|
||||||
|
website: 'https://xx.network'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
decimals: [12],
|
decimals: [12],
|
||||||
displayName: 'HydraDX',
|
displayName: 'HydraDX',
|
||||||
@@ -575,6 +584,15 @@ export const knownSubstrate: KnownSubstrate[] = [
|
|||||||
symbols: ['TRAC'],
|
symbols: ['TRAC'],
|
||||||
website: 'https://origintrail.io'
|
website: 'https://origintrail.io'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
decimals: [10],
|
||||||
|
displayName: 'Pontem Network',
|
||||||
|
network: 'pontem-network',
|
||||||
|
prefix: 105,
|
||||||
|
standardAccount: '*25519',
|
||||||
|
symbols: ['PONT'],
|
||||||
|
website: 'https://pontem.network'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
decimals: [12],
|
decimals: [12],
|
||||||
displayName: 'Heiko',
|
displayName: 'Heiko',
|
||||||
@@ -665,6 +683,33 @@ export const knownSubstrate: KnownSubstrate[] = [
|
|||||||
symbols: ['MOVR'],
|
symbols: ['MOVR'],
|
||||||
website: 'https://moonbeam.network'
|
website: 'https://moonbeam.network'
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
decimals: [12],
|
||||||
|
displayName: 'Kapex',
|
||||||
|
network: 'kapex',
|
||||||
|
prefix: 2007,
|
||||||
|
standardAccount: '*25519',
|
||||||
|
symbols: ['KAPEX'],
|
||||||
|
website: 'https://totemaccounting.com'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
decimals: [18],
|
||||||
|
displayName: 'Subspace testnet',
|
||||||
|
network: 'subspace_testnet',
|
||||||
|
prefix: 2254,
|
||||||
|
standardAccount: '*25519',
|
||||||
|
symbols: ['tSSC'],
|
||||||
|
website: 'https://subspace.network'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
decimals: [18],
|
||||||
|
displayName: 'Subspace',
|
||||||
|
network: 'subspace',
|
||||||
|
prefix: 6094,
|
||||||
|
standardAccount: '*25519',
|
||||||
|
symbols: ['SSC'],
|
||||||
|
website: 'https://subspace.network'
|
||||||
|
},
|
||||||
{
|
{
|
||||||
decimals: [12],
|
decimals: [12],
|
||||||
displayName: 'Basilisk',
|
displayName: 'Basilisk',
|
||||||
|
|||||||
@@ -37,5 +37,5 @@ export interface Network extends SubstrateNetwork {
|
|||||||
export interface Ss58Registry {
|
export interface Ss58Registry {
|
||||||
registry: KnownSubstrate[];
|
registry: KnownSubstrate[];
|
||||||
specification: string;
|
specification: string;
|
||||||
schema: Record<string, string>;
|
schema: Record<keyof KnownSubstrate, string>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,16 +22,14 @@
|
|||||||
"./detectPackage.cjs"
|
"./detectPackage.cjs"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "7.8.2",
|
"version": "7.9.1",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.16.0",
|
"@babel/runtime": "^7.16.3",
|
||||||
"@polkadot/networks": "7.8.2",
|
"@polkadot/networks": "7.9.1",
|
||||||
"@polkadot/util": "7.8.2",
|
"@polkadot/util": "7.9.1",
|
||||||
"@polkadot/wasm-crypto": "^4.2.1",
|
"@polkadot/wasm-crypto": "^4.3.1",
|
||||||
"@polkadot/x-randomvalues": "7.8.2",
|
"@polkadot/x-randomvalues": "7.9.1",
|
||||||
"base-x": "^3.0.9",
|
|
||||||
"base64-js": "^1.5.1",
|
|
||||||
"blakejs": "^1.1.1",
|
"blakejs": "^1.1.1",
|
||||||
"bn.js": "^4.12.0",
|
"bn.js": "^4.12.0",
|
||||||
"create-hash": "^1.2.0",
|
"create-hash": "^1.2.0",
|
||||||
@@ -39,6 +37,7 @@
|
|||||||
"elliptic": "^6.5.4",
|
"elliptic": "^6.5.4",
|
||||||
"hash.js": "^1.1.7",
|
"hash.js": "^1.1.7",
|
||||||
"js-sha3": "^0.8.0",
|
"js-sha3": "^0.8.0",
|
||||||
|
"micro-base": "^0.9.0",
|
||||||
"scryptsy": "^2.1.0",
|
"scryptsy": "^2.1.0",
|
||||||
"tweetnacl": "^1.0.3",
|
"tweetnacl": "^1.0.3",
|
||||||
"xxhashjs": "^0.2.2"
|
"xxhashjs": "^0.2.2"
|
||||||
@@ -46,11 +45,12 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bn.js": "^4.11.6",
|
"@types/bn.js": "^4.11.6",
|
||||||
"@types/create-hash": "^1.2.2",
|
"@types/create-hash": "^1.2.2",
|
||||||
|
"@types/ed2curve": "^0.2.2",
|
||||||
"@types/elliptic": "^6.4.14",
|
"@types/elliptic": "^6.4.14",
|
||||||
"@types/scryptsy": "^2.0.0",
|
"@types/scryptsy": "^2.0.0",
|
||||||
"@types/xxhashjs": "^0.2.2"
|
"@types/xxhashjs": "^0.2.2"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@polkadot/util": "7.8.2"
|
"@polkadot/util": "7.9.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import type { HexString } from '@polkadot/util/types';
|
import type { HexString } from '@polkadot/util/types';
|
||||||
import type { Prefix } from './types';
|
import type { Prefix } from './types';
|
||||||
|
|
||||||
import { base58Decode } from '../base58/decode';
|
import { base58Decode } from '../base58';
|
||||||
import { checkAddressChecksum } from './checksum';
|
import { checkAddressChecksum } from './checksum';
|
||||||
import { defaults } from './defaults';
|
import { defaults } from './defaults';
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { base58Decode } from '../base58/decode';
|
import { base58Decode } from '../base58';
|
||||||
import { checkAddressChecksum } from './checksum';
|
import { checkAddressChecksum } from './checksum';
|
||||||
|
|
||||||
describe('checkAddressChecksum', (): void => {
|
describe('checkAddressChecksum', (): void => {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import type { Prefix } from './types';
|
|||||||
// Original implementation: https://github.com/paritytech/polka-ui/blob/4858c094684769080f5811f32b081dd7780b0880/src/polkadot.js#L6
|
// Original implementation: https://github.com/paritytech/polka-ui/blob/4858c094684769080f5811f32b081dd7780b0880/src/polkadot.js#L6
|
||||||
import { assert, isHex, isU8a, u8aToU8a } from '@polkadot/util';
|
import { assert, isHex, isU8a, u8aToU8a } from '@polkadot/util';
|
||||||
|
|
||||||
import { base58Decode } from '../base58/decode';
|
import { base58Decode } from '../base58';
|
||||||
import { checkAddressChecksum } from './checksum';
|
import { checkAddressChecksum } from './checksum';
|
||||||
import { defaults } from './defaults';
|
import { defaults } from './defaults';
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import type { Prefix } from './types';
|
|||||||
// Original implementation: https://github.com/paritytech/polka-ui/blob/4858c094684769080f5811f32b081dd7780b0880/src/polkadot.js#L34
|
// Original implementation: https://github.com/paritytech/polka-ui/blob/4858c094684769080f5811f32b081dd7780b0880/src/polkadot.js#L34
|
||||||
import { assert, u8aConcat } from '@polkadot/util';
|
import { assert, u8aConcat } from '@polkadot/util';
|
||||||
|
|
||||||
import { base58Encode } from '../base58/encode';
|
import { base58Encode } from '../base58';
|
||||||
import { decodeAddress } from './decode';
|
import { decodeAddress } from './decode';
|
||||||
import { defaults } from './defaults';
|
import { defaults } from './defaults';
|
||||||
import { sshash } from './sshash';
|
import { sshash } from './sshash';
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { isAddress } from '.';
|
||||||
|
|
||||||
|
describe('isAddress', (): void => {
|
||||||
|
it('decodes an address', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes the council address', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('F3opxRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts a publicKey (hex) as-is', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('0x01020304')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a short address', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('F7NZ')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 1-byte accountId (with prefix)', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('g4b', false, 2)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte accountId', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('3xygo', false, 2)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('encodes a 4-byte address', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('zswfoZa', false, 2)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 8-byte address', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('848Gh2GcGaZia', false, 2)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 33-byte address', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('KWCv1L3QX9LDPwY4VzvLmarEmXjVJidUzZcinvVnmxAJJCBou')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (65)', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('cLtA6nCDyvwKcEHH4QkZDSHMhS9s78BvUJUsKUbUAn1Jc2SCF')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (69)', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('cnUaoo5wodnTVA4bnr4woSweto8hWZADUvLFXkR9Q6U7BRsbF')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (252)', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('xw9Hca4RJTmBRgzJT4ieJBh7XCK9gE3NXBDSEmgGHd4TCrbnG')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (255)', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('yGHU8YKprxHbHdEv7oUK4rzMZXtsdhcXVG2CAMyC9WhzhjH2k')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (ecdsa, from Substrate)', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('4pbsSkWcBaYoFHrKJZp5fDVUKbqSYD9dhZZGvpp3vQ5ysVs5ybV')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when length is invalid', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('y9EMHt34JJo4rWLSaxoLGdYXvjgSXEd4zHUnQgfNzwES8b')
|
||||||
|
).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when the checksum does not match', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMa9cj')
|
||||||
|
).toEqual(false);
|
||||||
|
expect(
|
||||||
|
isAddress('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDwU')
|
||||||
|
).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when invalid base58 encoded address is found', (): void => {
|
||||||
|
expect(
|
||||||
|
isAddress('F3opIRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29')
|
||||||
|
).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -7,6 +7,7 @@ import type { HexString } from '@polkadot/util/types';
|
|||||||
import { bnToU8a, stringToU8a, u8aConcat } from '@polkadot/util';
|
import { bnToU8a, stringToU8a, u8aConcat } from '@polkadot/util';
|
||||||
|
|
||||||
import { blake2AsU8a } from '../blake2/asU8a';
|
import { blake2AsU8a } from '../blake2/asU8a';
|
||||||
|
import { BN_LE_16_OPTS } from '../bn';
|
||||||
import { decodeAddress } from './decode';
|
import { decodeAddress } from './decode';
|
||||||
|
|
||||||
const PREFIX = stringToU8a('modlpy/utilisuba');
|
const PREFIX = stringToU8a('modlpy/utilisuba');
|
||||||
@@ -16,7 +17,7 @@ export function createKeyDerived (who: HexString | Uint8Array | string, index: b
|
|||||||
u8aConcat(
|
u8aConcat(
|
||||||
PREFIX,
|
PREFIX,
|
||||||
decodeAddress(who),
|
decodeAddress(who),
|
||||||
bnToU8a(index, { bitLength: 16, isLe: true })
|
bnToU8a(index, BN_LE_16_OPTS)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import type { HexString } from '@polkadot/util/types';
|
|||||||
import { bnToU8a, compactToU8a, stringToU8a, u8aConcat, u8aSorted } from '@polkadot/util';
|
import { bnToU8a, compactToU8a, stringToU8a, u8aConcat, u8aSorted } from '@polkadot/util';
|
||||||
|
|
||||||
import { blake2AsU8a } from '../blake2/asU8a';
|
import { blake2AsU8a } from '../blake2/asU8a';
|
||||||
|
import { BN_LE_16_OPTS } from '../bn';
|
||||||
import { addressToU8a } from './util';
|
import { addressToU8a } from './util';
|
||||||
|
|
||||||
const PREFIX = stringToU8a('modlpy/utilisuba');
|
const PREFIX = stringToU8a('modlpy/utilisuba');
|
||||||
@@ -17,7 +18,7 @@ export function createKeyMulti (who: (HexString | Uint8Array | string)[], thresh
|
|||||||
PREFIX,
|
PREFIX,
|
||||||
compactToU8a(who.length),
|
compactToU8a(who.length),
|
||||||
...u8aSorted(who.map(addressToU8a)),
|
...u8aSorted(who.map(addressToU8a)),
|
||||||
bnToU8a(threshold, { bitLength: 16, isLe: true })
|
bnToU8a(threshold, BN_LE_16_OPTS)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { validateAddress } from '.';
|
||||||
|
|
||||||
|
describe('validateAddress', (): void => {
|
||||||
|
it('decodes an address', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes the council address', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('F3opxRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('converts a publicKey (hex) as-is', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('0x01020304')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a short address', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('F7NZ')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 1-byte accountId (with prefix)', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('g4b', false, 2)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte accountId', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('3xygo', false, 2)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('encodes a 4-byte address', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('zswfoZa', false, 2)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 8-byte address', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('848Gh2GcGaZia', false, 2)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 33-byte address', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('KWCv1L3QX9LDPwY4VzvLmarEmXjVJidUzZcinvVnmxAJJCBou')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (65)', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('cLtA6nCDyvwKcEHH4QkZDSHMhS9s78BvUJUsKUbUAn1Jc2SCF')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (69)', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('cnUaoo5wodnTVA4bnr4woSweto8hWZADUvLFXkR9Q6U7BRsbF')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (252)', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('xw9Hca4RJTmBRgzJT4ieJBh7XCK9gE3NXBDSEmgGHd4TCrbnG')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (255)', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('yGHU8YKprxHbHdEv7oUK4rzMZXtsdhcXVG2CAMyC9WhzhjH2k')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('decodes a 2-byte prefix (ecdsa, from Substrate)', (): void => {
|
||||||
|
expect(
|
||||||
|
validateAddress('4pbsSkWcBaYoFHrKJZp5fDVUKbqSYD9dhZZGvpp3vQ5ysVs5ybV')
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when length is invalid', (): void => {
|
||||||
|
expect(
|
||||||
|
() => validateAddress('y9EMHt34JJo4rWLSaxoLGdYXvjgSXEd4zHUnQgfNzwES8b')
|
||||||
|
).toThrow(/address length/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when the checksum does not match', (): void => {
|
||||||
|
expect(
|
||||||
|
() => validateAddress('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMa9cj')
|
||||||
|
).toThrow(/address checksum/);
|
||||||
|
expect(
|
||||||
|
() => validateAddress('5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaDwU')
|
||||||
|
).toThrow(/address checksum/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails when invalid base58 encoded address is found', (): void => {
|
||||||
|
expect(
|
||||||
|
() => validateAddress('F3opIRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29')
|
||||||
|
).toThrow(/Decoding F3opIRbN5ZbjJNU511Kj2TLuzFcDq9BGduA9TgiECafpg29: Invalid base58 character "I" \(0x49\) at index 4/);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,6 +1,53 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
// https://github.com/multiformats/js-multibase/blob/master/src/constants.js
|
import { utils } from 'micro-base';
|
||||||
export const BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
|
|
||||||
export const BITS_PER_CHAR = 5;
|
import { createDecode, createEncode, createIs, createValidate } from './helpers';
|
||||||
|
|
||||||
|
const BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
|
||||||
|
|
||||||
|
const BASE32_CONFIG = {
|
||||||
|
alphabet: BASE32_ALPHABET,
|
||||||
|
coder: utils.chain(
|
||||||
|
// We define our own chain, the default base32 has padding
|
||||||
|
utils.radix2(5),
|
||||||
|
utils.alphabet(BASE32_ALPHABET),
|
||||||
|
{
|
||||||
|
decode: (input: string) => input.split(''),
|
||||||
|
encode: (input: string[]) => input.join('')
|
||||||
|
}
|
||||||
|
),
|
||||||
|
ipfsChar: 'b',
|
||||||
|
type: 'base32'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base32Validate
|
||||||
|
* @summary Validates a base32 value.
|
||||||
|
* @description
|
||||||
|
* Validates that the supplied value is valid base32, throwing exceptions if not
|
||||||
|
*/
|
||||||
|
export const base32Validate = createValidate(BASE32_CONFIG);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name isBase32
|
||||||
|
* @description Checks if the input is in base32, returning true/false
|
||||||
|
*/
|
||||||
|
export const isBase32 = createIs(base32Validate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base32Decode
|
||||||
|
* @summary Delookup a base32 value.
|
||||||
|
* @description
|
||||||
|
* From the provided input, decode the base32 and return the result as an `Uint8Array`.
|
||||||
|
*/
|
||||||
|
export const base32Decode = createDecode(BASE32_CONFIG, base32Validate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base32Encode
|
||||||
|
* @summary Creates a base32 value.
|
||||||
|
* @description
|
||||||
|
* From the provided input, create the base32 and return the result as a string.
|
||||||
|
*/
|
||||||
|
export const base32Encode = createEncode(BASE32_CONFIG);
|
||||||
|
|||||||
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
import { u8aToString } from '@polkadot/util';
|
import { u8aToString } from '@polkadot/util';
|
||||||
|
|
||||||
import { base32Decode } from './';
|
import { base32Decode } from '.';
|
||||||
|
|
||||||
describe('base32Decode', (): void => {
|
describe('base32Decode', (): void => {
|
||||||
it('decodes a base32', (): void => {
|
it('decodes a base32', (): void => {
|
||||||
|
|||||||
@@ -1,56 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
// adapted from https://github.com/multiformats/js-multibase/blob/424709195b46ffb1d6f2f69a7707598ebe751e5e/src/rfc4648.js
|
|
||||||
|
|
||||||
import { assert } from '@polkadot/util';
|
|
||||||
|
|
||||||
import { BASE32_ALPHABET, BITS_PER_CHAR } from './bs32';
|
|
||||||
import { base32Validate } from './validate';
|
|
||||||
|
|
||||||
// Build the character lookup table:
|
|
||||||
const LOOKUP = BASE32_ALPHABET.split('').reduce<Record<string, number>>((lookup, a, i) => {
|
|
||||||
lookup[a] = i;
|
|
||||||
|
|
||||||
return lookup;
|
|
||||||
}, {});
|
|
||||||
|
|
||||||
/** @internal */
|
|
||||||
function decode (output: Uint8Array, input: string, offset: number): [Uint8Array, number, number] {
|
|
||||||
let bits = 0;
|
|
||||||
let buffer = 0;
|
|
||||||
let written = 0;
|
|
||||||
|
|
||||||
for (let i = offset; i < input.length; i++) {
|
|
||||||
buffer = (buffer << BITS_PER_CHAR) | LOOKUP[input[i]];
|
|
||||||
bits += BITS_PER_CHAR;
|
|
||||||
|
|
||||||
if (bits >= 8) {
|
|
||||||
bits -= 8;
|
|
||||||
output[written++] = 0xff & (buffer >> bits);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return [output, bits, buffer];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base32Decode
|
|
||||||
* @summary Delookup a base32 value.
|
|
||||||
* @description
|
|
||||||
* From the provided input, decode the base32 and return the result as an `Uint8Array`.
|
|
||||||
*/
|
|
||||||
export function base32Decode (value: string, ipfsCompat = false): Uint8Array {
|
|
||||||
base32Validate(value, ipfsCompat);
|
|
||||||
|
|
||||||
const offset = (ipfsCompat ? 1 : 0);
|
|
||||||
const [output, bits, buffer] = decode(
|
|
||||||
new Uint8Array(((value.length - offset) * BITS_PER_CHAR / 8) | 0),
|
|
||||||
value,
|
|
||||||
offset
|
|
||||||
);
|
|
||||||
|
|
||||||
assert(!(bits >= BITS_PER_CHAR || 0xff & (buffer << (8 - bits))), 'Unexpected end of data');
|
|
||||||
|
|
||||||
return output;
|
|
||||||
}
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { base58Decode } from '../base58';
|
import { base58Decode } from '../base58';
|
||||||
import { base32Encode } from './';
|
import { base32Encode } from '.';
|
||||||
|
|
||||||
describe('base32Encode', (): void => {
|
describe('base32Encode', (): void => {
|
||||||
it('encodes to a base32', (): void => {
|
it('encodes to a base32', (): void => {
|
||||||
@@ -11,6 +11,12 @@ describe('base32Encode', (): void => {
|
|||||||
).toEqual('irswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb');
|
).toEqual('irswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('encodes to a base32 (ipfs-compat)', (): void => {
|
||||||
|
expect(
|
||||||
|
base32Encode('Decentralize everything!!', true)
|
||||||
|
).toEqual('birswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb');
|
||||||
|
});
|
||||||
|
|
||||||
it('encodes a base58 to a base32', (): void => {
|
it('encodes a base58 to a base32', (): void => {
|
||||||
expect(
|
expect(
|
||||||
base32Encode(
|
base32Encode(
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
// adapted from https://github.com/multiformats/js-multibase/blob/424709195b46ffb1d6f2f69a7707598ebe751e5e/src/rfc4648.js
|
|
||||||
|
|
||||||
import type { U8aLike } from '@polkadot/util/types';
|
|
||||||
|
|
||||||
import { u8aToU8a } from '@polkadot/util';
|
|
||||||
|
|
||||||
import { BASE32_ALPHABET, BITS_PER_CHAR } from './bs32';
|
|
||||||
|
|
||||||
const MASK = (1 << BITS_PER_CHAR) - 1;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base32Encode
|
|
||||||
* @summary Creates a base32 value.
|
|
||||||
* @description
|
|
||||||
* From the provided input, create the base32 and return the result as a string.
|
|
||||||
*/
|
|
||||||
export function base32Encode (value: U8aLike, ipfsCompat = false): string {
|
|
||||||
const u8a = u8aToU8a(value);
|
|
||||||
let out = '';
|
|
||||||
let bits = 0;
|
|
||||||
let buffer = 0;
|
|
||||||
|
|
||||||
for (let i = 0; i < u8a.length; ++i) {
|
|
||||||
buffer = (buffer << 8) | u8a[i];
|
|
||||||
bits += 8;
|
|
||||||
|
|
||||||
while (bits > BITS_PER_CHAR) {
|
|
||||||
bits -= BITS_PER_CHAR;
|
|
||||||
out += BASE32_ALPHABET[MASK & (buffer >> bits)];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (bits) {
|
|
||||||
out += BASE32_ALPHABET[MASK & (buffer << (BITS_PER_CHAR - bits))];
|
|
||||||
}
|
|
||||||
|
|
||||||
return ipfsCompat
|
|
||||||
? `b${out}`
|
|
||||||
: out;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,77 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import type { U8aLike } from '@polkadot/util/types';
|
||||||
|
|
||||||
|
import { assert, u8aToU8a } from '@polkadot/util';
|
||||||
|
|
||||||
|
interface Coder {
|
||||||
|
decode: (value: string) => Uint8Array;
|
||||||
|
encode: (value: Uint8Array) => string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Config {
|
||||||
|
alphabet: string;
|
||||||
|
coder: Coder;
|
||||||
|
ipfsChar?: string;
|
||||||
|
regex?: RegExp;
|
||||||
|
type: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
type DecodeFn = (value: string, ipfsCompat?: boolean) => Uint8Array;
|
||||||
|
|
||||||
|
type EncodeFn = (value: U8aLike, ipfsCompat?: boolean) => string;
|
||||||
|
|
||||||
|
type ValidateFn = (value?: unknown, ipfsCompat?: boolean) => value is string;
|
||||||
|
|
||||||
|
export function createDecode ({ coder, ipfsChar }: Config, validate: ValidateFn): DecodeFn {
|
||||||
|
return (value: string, ipfsCompat?: boolean): Uint8Array => {
|
||||||
|
validate(value, ipfsCompat);
|
||||||
|
|
||||||
|
return coder.decode(
|
||||||
|
ipfsChar && ipfsCompat
|
||||||
|
? value.substr(1)
|
||||||
|
: value
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createEncode ({ coder, ipfsChar }: Config): EncodeFn {
|
||||||
|
return (value: U8aLike, ipfsCompat?: boolean): string => {
|
||||||
|
const out = coder.encode(u8aToU8a(value));
|
||||||
|
|
||||||
|
return ipfsChar && ipfsCompat
|
||||||
|
? `${ipfsChar}${out}`
|
||||||
|
: out;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createIs (validate: ValidateFn): ValidateFn {
|
||||||
|
return (value?: unknown, ipfsCompat?: boolean): value is string => {
|
||||||
|
try {
|
||||||
|
return validate(value, ipfsCompat);
|
||||||
|
} catch (error) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createValidate ({ alphabet, ipfsChar, regex, type }: Config): ValidateFn {
|
||||||
|
return (value?: unknown, ipfsCompat?: boolean): value is string => {
|
||||||
|
assert(value && typeof value === 'string', () => `Expected non-null, non-empty ${type} string input`);
|
||||||
|
|
||||||
|
if (ipfsChar && ipfsCompat) {
|
||||||
|
assert(value[0] === ipfsChar, () => `Expected ipfs-compatible ${type} to start with '${ipfsChar}'`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (regex) {
|
||||||
|
assert(regex.test(value), `Invalid ${type} encoding`);
|
||||||
|
} else {
|
||||||
|
for (let i = (ipfsCompat ? 1 : 0); i < value.length; i++) {
|
||||||
|
assert(alphabet.includes(value[i]), () => `Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -5,7 +5,4 @@
|
|||||||
* @summary Encode and decode base32 values
|
* @summary Encode and decode base32 values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { base32Decode } from './decode';
|
export { base32Decode, base32Encode, base32Validate, isBase32 } from './bs32';
|
||||||
export { base32Encode } from './encode';
|
|
||||||
export { base32Validate } from './validate';
|
|
||||||
export { isBase32 } from './is';
|
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { isBase32 } from '.';
|
||||||
|
|
||||||
|
describe('isBase32', (): void => {
|
||||||
|
it('validates encoded', (): void => {
|
||||||
|
expect(
|
||||||
|
isBase32('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', false)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('validates ipfs-compat encoded', (): void => {
|
||||||
|
expect(
|
||||||
|
isBase32('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', false)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails on invalid', (): void => {
|
||||||
|
expect(
|
||||||
|
isBase32('not in base32')
|
||||||
|
).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails on non-ipfs', (): void => {
|
||||||
|
expect(
|
||||||
|
isBase32('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
|
||||||
|
).toEqual(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import { base32Validate } from './validate';
|
|
||||||
|
|
||||||
export function testValidator (validate: (value?: string | null, ipfsCompat?: boolean) => boolean, value?: string | null, ipfsCompat?: boolean): boolean {
|
|
||||||
try {
|
|
||||||
return validate(value, ipfsCompat);
|
|
||||||
} catch (error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function isBase32 (value?: string | null, ipfsCompat?: boolean): value is string {
|
|
||||||
return testValidator(base32Validate, value, ipfsCompat);
|
|
||||||
}
|
|
||||||
@@ -4,9 +4,39 @@
|
|||||||
import { base32Validate } from '.';
|
import { base32Validate } from '.';
|
||||||
|
|
||||||
describe('base32Validate', (): void => {
|
describe('base32Validate', (): void => {
|
||||||
|
it('validates encoded', (): void => {
|
||||||
|
expect(
|
||||||
|
base32Validate('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', false)
|
||||||
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
it('validates ipfs-compat encoded', (): void => {
|
it('validates ipfs-compat encoded', (): void => {
|
||||||
expect(
|
expect(
|
||||||
() => base32Validate('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
|
base32Validate('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
|
||||||
).not.toThrow();
|
).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails on empty', (): void => {
|
||||||
|
expect(
|
||||||
|
() => base32Validate('')
|
||||||
|
).toThrow(/Expected/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails on non-string', (): void => {
|
||||||
|
expect(
|
||||||
|
() => base32Validate(true)
|
||||||
|
).toThrow(/Expected/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails on invalid', (): void => {
|
||||||
|
expect(
|
||||||
|
() => base32Validate('not in base32')
|
||||||
|
).toThrow(/Invalid/);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('fails on non-ipfs', (): void => {
|
||||||
|
expect(
|
||||||
|
() => base32Validate('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
|
||||||
|
).toThrow(/Expected/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,13 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import { createValidateFn } from '../base58/validate';
|
|
||||||
import { BASE32_ALPHABET } from './bs32';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base32Validate
|
|
||||||
* @summary Validates a base32 value.
|
|
||||||
* @description
|
|
||||||
* Validates that the supplied value is valid base32
|
|
||||||
*/
|
|
||||||
export const base32Validate = createValidateFn({ alphabet: BASE32_ALPHABET, ipfsChar: 'b', type: 'base32' });
|
|
||||||
@@ -1,9 +1,43 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import baseX from 'base-x';
|
import { base58 } from 'micro-base';
|
||||||
|
|
||||||
// https://github.com/cryptocoinjs/base-x#alphabets
|
import { createDecode, createEncode, createIs, createValidate } from '../base32/helpers';
|
||||||
export const BASE58_ALPHABET = '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz';
|
|
||||||
|
|
||||||
export const bs58 = baseX(BASE58_ALPHABET);
|
const BASE58_CONFIG = {
|
||||||
|
alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz',
|
||||||
|
coder: base58,
|
||||||
|
ipfsChar: 'z',
|
||||||
|
type: 'base58'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base58Validate
|
||||||
|
* @summary Validates a base58 value.
|
||||||
|
* @description
|
||||||
|
* Validates that the supplied value is valid base58, throwing exceptions if not
|
||||||
|
*/
|
||||||
|
export const base58Validate = createValidate(BASE58_CONFIG);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base58Decode
|
||||||
|
* @summary Decodes a base58 value.
|
||||||
|
* @description
|
||||||
|
* From the provided input, decode the base58 and return the result as an `Uint8Array`.
|
||||||
|
*/
|
||||||
|
export const base58Decode = createDecode(BASE58_CONFIG, base58Validate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base58Encode
|
||||||
|
* @summary Creates a base58 value.
|
||||||
|
* @description
|
||||||
|
* From the provided input, create the base58 and return the result as a string.
|
||||||
|
*/
|
||||||
|
export const base58Encode = createEncode(BASE58_CONFIG);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name isBase58
|
||||||
|
* @description Checks if the input is in base58, returning true/false
|
||||||
|
*/
|
||||||
|
export const isBase58 = createIs(base58Validate);
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { base32Decode } from '../base32';
|
||||||
|
import { base58Decode } from './';
|
||||||
|
|
||||||
|
describe('base58Encode', (): void => {
|
||||||
|
it('encodes a base58 to a base32', (): void => {
|
||||||
|
expect(
|
||||||
|
base58Decode('b2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV')
|
||||||
|
).toEqual(
|
||||||
|
base32Decode('afkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy')
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('encodes a base58 to a base32 (ipfs-compat)', (): void => {
|
||||||
|
expect(
|
||||||
|
base58Decode('zb2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV', true)
|
||||||
|
).toEqual(
|
||||||
|
base32Decode('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -1,19 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import { bufferToU8a } from '@polkadot/util';
|
|
||||||
|
|
||||||
import { bs58 } from './bs58';
|
|
||||||
import { base58Validate } from './validate';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base58Decode
|
|
||||||
* @summary Decodes a base58 value.
|
|
||||||
* @description
|
|
||||||
* From the provided input, decode the base58 and return the result as an `Uint8Array`.
|
|
||||||
*/
|
|
||||||
export function base58Decode (value: string, ipfsCompat?: boolean): Uint8Array {
|
|
||||||
base58Validate(value, ipfsCompat);
|
|
||||||
|
|
||||||
return bufferToU8a(bs58.decode(value.substr(ipfsCompat ? 1 : 0)));
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,15 @@ import { base32Decode } from '../base32';
|
|||||||
import { base58Encode } from './';
|
import { base58Encode } from './';
|
||||||
|
|
||||||
describe('base58Encode', (): void => {
|
describe('base58Encode', (): void => {
|
||||||
it('encodes a base32 to a base38', (): void => {
|
it('encodes a base32 to a base58', (): void => {
|
||||||
|
expect(
|
||||||
|
base58Encode(
|
||||||
|
base32Decode('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true)
|
||||||
|
)
|
||||||
|
).toEqual('b2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('encodes a base32 to a base58 (ipfs-compat)', (): void => {
|
||||||
expect(
|
expect(
|
||||||
base58Encode(
|
base58Encode(
|
||||||
base32Decode('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true),
|
base32Decode('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true),
|
||||||
|
|||||||
@@ -1,22 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import type { U8aLike } from '@polkadot/util/types';
|
|
||||||
|
|
||||||
import { u8aToU8a } from '@polkadot/util';
|
|
||||||
|
|
||||||
import { bs58 } from './bs58';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base58Encode
|
|
||||||
* @summary Creates a base58 value.
|
|
||||||
* @description
|
|
||||||
* From the provided input, create the base58 and return the result as a string.
|
|
||||||
*/
|
|
||||||
export function base58Encode (value: U8aLike, ipfsCompat?: boolean): string {
|
|
||||||
const out = bs58.encode(u8aToU8a(value));
|
|
||||||
|
|
||||||
return ipfsCompat
|
|
||||||
? `z${out}`
|
|
||||||
: out;
|
|
||||||
}
|
|
||||||
@@ -5,7 +5,4 @@
|
|||||||
* @summary Encode and decode base58 values
|
* @summary Encode and decode base58 values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { base58Decode } from './decode';
|
export { base58Decode, base58Encode, base58Validate, isBase58 } from './bs58';
|
||||||
export { base58Encode } from './encode';
|
|
||||||
export { base58Validate } from './validate';
|
|
||||||
export { isBase58 } from './is';
|
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import { testValidator } from '../base32/is';
|
|
||||||
import { base58Validate } from './validate';
|
|
||||||
|
|
||||||
export function isBase58 (value?: string | null, ipfsCompat?: boolean): value is string {
|
|
||||||
return testValidator(base58Validate, value, ipfsCompat);
|
|
||||||
}
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import { assert } from '@polkadot/util';
|
|
||||||
|
|
||||||
import { BASE58_ALPHABET } from './bs58';
|
|
||||||
|
|
||||||
interface CheckConfig {
|
|
||||||
alphabet: string;
|
|
||||||
ipfsChar: string;
|
|
||||||
type: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createValidateFn ({ alphabet, ipfsChar, type }: CheckConfig): (value?: unknown, ipfsCompat?: boolean) => value is string {
|
|
||||||
return (value?: unknown, ipfsCompat?: boolean): value is string => {
|
|
||||||
assert(value && typeof value === 'string', () => `Expected non-null, non-empty ${type} string input`);
|
|
||||||
assert(!ipfsCompat || value[0] === ipfsChar, () => `Expected ${type} to start with '${ipfsChar}'`);
|
|
||||||
|
|
||||||
for (let i = (ipfsCompat ? 1 : 0); i < value.length; i++) {
|
|
||||||
assert(alphabet.includes(value[i]), () => `Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base58Validate
|
|
||||||
* @summary Validates a base58 value.
|
|
||||||
* @description
|
|
||||||
* Validates that the supplied value is valid base58
|
|
||||||
*/
|
|
||||||
export const base58Validate = createValidateFn({ alphabet: BASE58_ALPHABET, ipfsChar: 'z', type: 'base58' });
|
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { base64 } from 'micro-base';
|
||||||
|
|
||||||
|
import { createDecode, createEncode, createIs, createValidate } from '../base32/helpers';
|
||||||
|
|
||||||
|
const BASE64_CONFIG = {
|
||||||
|
alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
|
||||||
|
coder: base64,
|
||||||
|
regex: /^(?:[A-Za-z0-9+/]{2}[A-Za-z0-9+/]{2})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/,
|
||||||
|
type: 'base64'
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base64Validate
|
||||||
|
* @summary Validates a base64 value.
|
||||||
|
* @description
|
||||||
|
* Validates that the supplied value is valid base64
|
||||||
|
*/
|
||||||
|
export const base64Validate = createValidate(BASE64_CONFIG);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name isBase64
|
||||||
|
* @description Checks if the input is in base64, returning true/false
|
||||||
|
*/
|
||||||
|
export const isBase64 = createIs(base64Validate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base64Decode
|
||||||
|
* @summary Decodes a base64 value.
|
||||||
|
* @description
|
||||||
|
* From the provided input, decode the base64 and return the result as an `Uint8Array`.
|
||||||
|
*/
|
||||||
|
export const base64Decode = createDecode(BASE64_CONFIG, base64Validate);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base64Encode
|
||||||
|
* @summary Creates a base64 value.
|
||||||
|
* @description
|
||||||
|
* From the provided input, create the base64 and return the result as a string.
|
||||||
|
*/
|
||||||
|
export const base64Encode = createEncode(BASE64_CONFIG);
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import base64 from 'base64-js';
|
|
||||||
|
|
||||||
import { base64Validate } from './validate';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base64Decode
|
|
||||||
* @summary Decodes a base64 value.
|
|
||||||
* @description
|
|
||||||
* From the provided input, decode the base64 and return the result as an `Uint8Array`.
|
|
||||||
*/
|
|
||||||
export function base64Decode (value: string): Uint8Array {
|
|
||||||
base64Validate(value);
|
|
||||||
|
|
||||||
return base64.toByteArray(value);
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import type { U8aLike } from '@polkadot/util/types';
|
|
||||||
|
|
||||||
import base64 from 'base64-js';
|
|
||||||
|
|
||||||
import { u8aToU8a } from '@polkadot/util';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base64Encode
|
|
||||||
* @summary Creates a base64 value.
|
|
||||||
* @description
|
|
||||||
* From the provided input, create the base64 and return the result as a string.
|
|
||||||
*/
|
|
||||||
export function base64Encode (value: U8aLike): string {
|
|
||||||
return base64.fromByteArray(u8aToU8a(value));
|
|
||||||
}
|
|
||||||
@@ -5,9 +5,6 @@
|
|||||||
* @summary Encode and decode base64 values
|
* @summary Encode and decode base64 values
|
||||||
*/
|
*/
|
||||||
|
|
||||||
export { base64Decode } from './decode';
|
export { base64Decode, base64Encode, base64Validate, isBase64 } from './bs64';
|
||||||
export { base64Encode } from './encode';
|
|
||||||
export { base64Pad } from './pad';
|
export { base64Pad } from './pad';
|
||||||
export { base64Trim } from './trim';
|
export { base64Trim } from './trim';
|
||||||
export { base64Validate } from './validate';
|
|
||||||
export { isBase64 } from './is';
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import { base64Validate } from './validate';
|
|
||||||
|
|
||||||
export function isBase64 (value?: string | null): value is string {
|
|
||||||
try {
|
|
||||||
return base64Validate(value);
|
|
||||||
} catch (error) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base64Pad
|
||||||
|
* @description Adds padding characters for correct length
|
||||||
|
*/
|
||||||
export function base64Pad (value: string): string {
|
export function base64Pad (value: string): string {
|
||||||
return value.padEnd(value.length + (value.length % 4), '=');
|
return value.padEnd(value.length + (value.length % 4), '=');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name base64Trim
|
||||||
|
* @description Trims padding characters
|
||||||
|
*/
|
||||||
export function base64Trim (value: string): string {
|
export function base64Trim (value: string): string {
|
||||||
while (value.length && value[value.length - 1] === '=') {
|
while (value.length && value[value.length - 1] === '=') {
|
||||||
value = value.slice(0, -1);
|
value = value.slice(0, -1);
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import { assert } from '@polkadot/util';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name base64Validate
|
|
||||||
* @summary Validates a base64 value.
|
|
||||||
* @description
|
|
||||||
* Validates that the supplied value is valid base64
|
|
||||||
*/
|
|
||||||
export function base64Validate (value?: string | null): value is string {
|
|
||||||
assert(value && typeof value === 'string', 'Expected non-null, non-empty base64 string input');
|
|
||||||
assert(/^(?:[A-Za-z0-9+/]{2}[A-Za-z0-9+/]{2})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(value), 'Invalid base64 encoding');
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
import { hexToU8a } from '@polkadot/util';
|
import { hexToU8a } from '@polkadot/util';
|
||||||
import { waitReady } from '@polkadot/wasm-crypto';
|
import { waitReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
|
import { performanceTest } from '../../test/performance';
|
||||||
import { blake2AsU8a } from '.';
|
import { blake2AsU8a } from '.';
|
||||||
|
|
||||||
describe('blake2AsU8a', (): void => {
|
describe('blake2AsU8a', (): void => {
|
||||||
@@ -58,4 +59,10 @@ describe('blake2AsU8a', (): void => {
|
|||||||
|
|
||||||
expect(a).toEqual(b);
|
expect(a).toEqual(b);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe.each([256, 512] as (256 | 512)[])('bitLength=$p', (bitLength): void => {
|
||||||
|
performanceTest(`blake2AsU8a, bitLength=${bitLength}`, 64000, (input, onlyJs) =>
|
||||||
|
blake2AsU8a(input, bitLength, null, onlyJs)
|
||||||
|
);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -24,8 +24,9 @@ import { blake2b, isReady } from '@polkadot/wasm-crypto';
|
|||||||
*/
|
*/
|
||||||
export function blake2AsU8a (data: HexString | Uint8Array | string, bitLength = 256, key?: Uint8Array | null, onlyJs = false): Uint8Array {
|
export function blake2AsU8a (data: HexString | Uint8Array | string, bitLength = 256, key?: Uint8Array | null, onlyJs = false): Uint8Array {
|
||||||
const byteLength = Math.ceil(bitLength / 8);
|
const byteLength = Math.ceil(bitLength / 8);
|
||||||
|
const u8a = u8aToU8a(data);
|
||||||
|
|
||||||
return isReady() && !onlyJs
|
return isReady() && !onlyJs
|
||||||
? blake2b(u8aToU8a(data), u8aToU8a(key), byteLength)
|
? blake2b(u8a, u8aToU8a(key), byteLength)
|
||||||
: js.blake2b(u8aToU8a(data), key || undefined, byteLength);
|
: js.blake2b(u8a, key || undefined, byteLength);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
export const BN_LE_OPTS = { isLe: true };
|
||||||
|
|
||||||
|
export const BN_LE_16_OPTS = { bitLength: 16, isLe: true };
|
||||||
|
|
||||||
|
export const BN_BE_32_OPTS = { bitLength: 32, isLe: false };
|
||||||
|
export const BN_LE_32_OPTS = { bitLength: 32, isLe: true };
|
||||||
|
|
||||||
|
export const BN_BE_256_OPTS = { bitLength: 256, isLe: false };
|
||||||
|
export const BN_LE_256_OPTS = { bitLength: 256, isLe: true };
|
||||||
|
|
||||||
|
export const BN_LE_512_OPTS = { bitLength: 512, isLe: true };
|
||||||
@@ -26,6 +26,6 @@ export * from './random';
|
|||||||
export * from './schnorrkel';
|
export * from './schnorrkel';
|
||||||
export * from './scrypt';
|
export * from './scrypt';
|
||||||
export * from './secp256k1';
|
export * from './secp256k1';
|
||||||
export * from './sha512';
|
export * from './sha';
|
||||||
export * from './signature';
|
export * from './signature';
|
||||||
export * from './xxhash';
|
export * from './xxhash';
|
||||||
|
|||||||
@@ -3,9 +3,7 @@
|
|||||||
|
|
||||||
import { isReady, waitReady } from '@polkadot/wasm-crypto';
|
import { isReady, waitReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
export function cryptoIsReady (): boolean {
|
export const cryptoIsReady = isReady;
|
||||||
return isReady();
|
|
||||||
}
|
|
||||||
|
|
||||||
export function cryptoWaitReady (): Promise<boolean> {
|
export function cryptoWaitReady (): Promise<boolean> {
|
||||||
return waitReady()
|
return waitReady()
|
||||||
|
|||||||
@@ -29,8 +29,8 @@ export function ethereumEncode (addressOrPublic?: HexString | string | Uint8Arra
|
|||||||
const hash = u8aToHex(keccakAsU8a(address), -1, false);
|
const hash = u8aToHex(keccakAsU8a(address), -1, false);
|
||||||
let result = '';
|
let result = '';
|
||||||
|
|
||||||
for (let index = 0; index < 40; index++) {
|
for (let i = 0; i < 40; i++) {
|
||||||
result = `${result}${parseInt(hash[index], 16) > 7 ? address[index].toUpperCase() : address[index]}`;
|
result = `${result}${parseInt(hash[i], 16) > 7 ? address[i].toUpperCase() : address[i]}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
return `0x${result}`;
|
return `0x${result}`;
|
||||||
|
|||||||
@@ -17,8 +17,8 @@ export function isEthereumChecksum (_address: string): boolean {
|
|||||||
const address = _address.replace('0x', '');
|
const address = _address.replace('0x', '');
|
||||||
const hash = u8aToHex(keccakAsU8a(address.toLowerCase()), -1, false);
|
const hash = u8aToHex(keccakAsU8a(address.toLowerCase()), -1, false);
|
||||||
|
|
||||||
for (let index = 0; index < 40; index++) {
|
for (let i = 0; i < 40; i++) {
|
||||||
if (isInvalidChar(address[index], parseInt(hash[index], 16))) {
|
if (isInvalidChar(address[i], parseInt(hash[i], 16))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type { Keypair } from '../../types';
|
|||||||
|
|
||||||
import { assert, bnToU8a, stringToU8a, u8aConcat } from '@polkadot/util';
|
import { assert, bnToU8a, stringToU8a, u8aConcat } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { BN_BE_32_OPTS } from '../../bn';
|
||||||
import { hmacSha512 } from '../../hmac';
|
import { hmacSha512 } from '../../hmac';
|
||||||
import { secp256k1KeypairFromSeed, secp256k1PrivateKeyTweakAdd } from '../../secp256k1';
|
import { secp256k1KeypairFromSeed, secp256k1PrivateKeyTweakAdd } from '../../secp256k1';
|
||||||
import { HARDENED, hdValidatePath } from '../validatePath';
|
import { HARDENED, hdValidatePath } from '../validatePath';
|
||||||
@@ -24,7 +25,7 @@ function createCoded (secretKey: Uint8Array, chainCode: Uint8Array): CodedKeypai
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deriveChild (hd: CodedKeypair, index: number): CodedKeypair {
|
function deriveChild (hd: CodedKeypair, index: number): CodedKeypair {
|
||||||
const indexBuffer = bnToU8a(index, { bitLength: 32, isLe: false });
|
const indexBuffer = bnToU8a(index, BN_BE_32_OPTS);
|
||||||
const data = index >= HARDENED
|
const data = index >= HARDENED
|
||||||
? u8aConcat(new Uint8Array(1), hd.secretKey, indexBuffer)
|
? u8aConcat(new Uint8Array(1), hd.secretKey, indexBuffer)
|
||||||
: u8aConcat(hd.publicKey, indexBuffer);
|
: u8aConcat(hd.publicKey, indexBuffer);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import { BN_EIGHT, bnToU8a, u8aConcat, u8aToBn } from '@polkadot/util';
|
import { BN_EIGHT, bnToU8a, u8aConcat, u8aToBn } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { BN_LE_32_OPTS, BN_LE_512_OPTS, BN_LE_OPTS } from '../../bn';
|
||||||
import { hmacSha512 } from '../../hmac';
|
import { hmacSha512 } from '../../hmac';
|
||||||
|
|
||||||
// performs hard-only derivation on the xprv
|
// performs hard-only derivation on the xprv
|
||||||
@@ -10,19 +11,23 @@ export function ledgerDerivePrivate (xprv: Uint8Array, index: number): Uint8Arra
|
|||||||
const kl = xprv.subarray(0, 32);
|
const kl = xprv.subarray(0, 32);
|
||||||
const kr = xprv.subarray(32, 64);
|
const kr = xprv.subarray(32, 64);
|
||||||
const cc = xprv.subarray(64, 96);
|
const cc = xprv.subarray(64, 96);
|
||||||
const data = u8aConcat([0], kl, kr, bnToU8a(index, { bitLength: 32, isLe: true }));
|
const data = u8aConcat([0], kl, kr, bnToU8a(index, BN_LE_32_OPTS));
|
||||||
const z = hmacSha512(cc, data);
|
const z = hmacSha512(cc, data);
|
||||||
|
|
||||||
data[0] = 0x01;
|
data[0] = 0x01;
|
||||||
|
|
||||||
return u8aConcat(
|
return u8aConcat(
|
||||||
bnToU8a(
|
bnToU8a(
|
||||||
u8aToBn(kl, { isLe: true }).iadd(u8aToBn(z.subarray(0, 28), { isLe: true }).imul(BN_EIGHT)),
|
u8aToBn(kl, BN_LE_OPTS).iadd(
|
||||||
{ bitLength: 512, isLe: true }
|
u8aToBn(z.subarray(0, 28), BN_LE_OPTS).imul(BN_EIGHT)
|
||||||
|
),
|
||||||
|
BN_LE_512_OPTS
|
||||||
).subarray(0, 32),
|
).subarray(0, 32),
|
||||||
bnToU8a(
|
bnToU8a(
|
||||||
u8aToBn(kr, { isLe: true }).iadd(u8aToBn(z.subarray(32, 64), { isLe: true })),
|
u8aToBn(kr, BN_LE_OPTS).iadd(
|
||||||
{ bitLength: 512, isLe: true }
|
u8aToBn(z.subarray(32, 64), BN_LE_OPTS)
|
||||||
|
),
|
||||||
|
BN_LE_512_OPTS
|
||||||
).subarray(0, 32),
|
).subarray(0, 32),
|
||||||
hmacSha512(cc, data).subarray(32, 64)
|
hmacSha512(cc, data).subarray(32, 64)
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { stringToU8a, u8aToHex } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { hmacSha256 } from '.';
|
||||||
|
|
||||||
|
describe('hmacSha256', (): void => {
|
||||||
|
it('has a known output', (): void => {
|
||||||
|
const key = stringToU8a('secret');
|
||||||
|
const data = stringToU8a('some message');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
u8aToHex(
|
||||||
|
hmacSha256(key, data)
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
'0xf28a70b41263840e5c059a0a733336e0957efba87902aa8cca11441d4b0c96d7'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { stringToU8a, u8aToHex } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { hmacSha512 } from '.';
|
||||||
|
|
||||||
|
describe('hmacSha512', (): void => {
|
||||||
|
it('has a known output', (): void => {
|
||||||
|
const key = stringToU8a('secret');
|
||||||
|
const data = stringToU8a('some message');
|
||||||
|
|
||||||
|
expect(
|
||||||
|
u8aToHex(
|
||||||
|
hmacSha512(key, data)
|
||||||
|
)
|
||||||
|
).toEqual(
|
||||||
|
'0x295832e97ed77be75a9fa98029497e4a722c4b9a2f21b39d34f1befa931a39ec520fd24711d6f5c03501384ea66b83066a01a82c57a0460f8cd1f471fcce5841'
|
||||||
|
);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
import { hexToU8a, stringToU8a } from '@polkadot/util';
|
import { hexToU8a, stringToU8a } from '@polkadot/util';
|
||||||
import { waitReady } from '@polkadot/wasm-crypto';
|
import { waitReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
|
import { performanceTest } from '../../test/performance';
|
||||||
import { keccakAsU8a } from '.';
|
import { keccakAsU8a } from '.';
|
||||||
|
|
||||||
describe('keccakAsU8a', (): void => {
|
describe('keccakAsU8a', (): void => {
|
||||||
@@ -21,8 +22,8 @@ describe('keccakAsU8a', (): void => {
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
describe.each([false, true])('onlyJs=%p', (onlyJs): void => {
|
describe.each([256, 512] as (256 | 512)[])('bitLength=$p', (bitLength): void => {
|
||||||
describe.each([256, 512] as (256 | 512)[])('bitLength=$p', (bitLength): void => {
|
describe.each([false, true])('onlyJs=%p', (onlyJs): void => {
|
||||||
it('returns an hex representation (string)', (): void => {
|
it('returns an hex representation (string)', (): void => {
|
||||||
expect(
|
expect(
|
||||||
keccakAsU8a(input, bitLength, onlyJs)
|
keccakAsU8a(input, bitLength, onlyJs)
|
||||||
@@ -41,5 +42,9 @@ describe('keccakAsU8a', (): void => {
|
|||||||
).toEqual(output[bitLength]);
|
).toEqual(output[bitLength]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
performanceTest(`keccakAsU8a, bitLength=${bitLength}`, 128000, (input, onlyJs) =>
|
||||||
|
keccakAsU8a(input, bitLength, onlyJs)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import type { HexString } from '@polkadot/util/types';
|
|||||||
import js from 'js-sha3';
|
import js from 'js-sha3';
|
||||||
|
|
||||||
import { u8aToU8a } from '@polkadot/util';
|
import { u8aToU8a } from '@polkadot/util';
|
||||||
import { isReady, keccak256 } from '@polkadot/wasm-crypto';
|
import { isReady, keccak256, keccak512 } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name keccakAsU8a
|
* @name keccakAsU8a
|
||||||
@@ -24,10 +24,15 @@ import { isReady, keccak256 } from '@polkadot/wasm-crypto';
|
|||||||
*/
|
*/
|
||||||
export function keccakAsU8a (value: HexString | Buffer | Uint8Array | string, bitLength: 256 | 512 = 256, onlyJs = false): Uint8Array {
|
export function keccakAsU8a (value: HexString | Buffer | Uint8Array | string, bitLength: 256 | 512 = 256, onlyJs = false): Uint8Array {
|
||||||
const is256 = bitLength === 256;
|
const is256 = bitLength === 256;
|
||||||
|
const u8a = u8aToU8a(value);
|
||||||
|
|
||||||
return isReady() && is256 && !onlyJs
|
return isReady() && !onlyJs
|
||||||
? keccak256(u8aToU8a(value))
|
? is256
|
||||||
|
? keccak256(u8a)
|
||||||
|
: keccak512(u8a)
|
||||||
: new Uint8Array(
|
: new Uint8Array(
|
||||||
(is256 ? js.keccak256 : js.keccak512).update(u8aToU8a(value)).arrayBuffer()
|
is256
|
||||||
|
? js.keccak256.update(u8a).arrayBuffer()
|
||||||
|
: js.keccak512.update(u8a).arrayBuffer()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,14 +6,11 @@ import type { HexString } from '@polkadot/util/types';
|
|||||||
import { BN, bnToU8a, compactAddLength, hexToU8a, isBigInt, isBn, isHex, isNumber, isString, stringToU8a } from '@polkadot/util';
|
import { BN, bnToU8a, compactAddLength, hexToU8a, isBigInt, isBn, isHex, isNumber, isString, stringToU8a } from '@polkadot/util';
|
||||||
|
|
||||||
import { blake2AsU8a } from '../blake2/asU8a';
|
import { blake2AsU8a } from '../blake2/asU8a';
|
||||||
|
import { BN_LE_256_OPTS } from '../bn';
|
||||||
|
|
||||||
const RE_NUMBER = /^\d+$/;
|
const RE_NUMBER = /^\d+$/;
|
||||||
|
|
||||||
const JUNCTION_ID_LEN = 32;
|
const JUNCTION_ID_LEN = 32;
|
||||||
const BN_OPTIONS = {
|
|
||||||
bitLength: 256,
|
|
||||||
isLe: true
|
|
||||||
};
|
|
||||||
|
|
||||||
export class DeriveJunction {
|
export class DeriveJunction {
|
||||||
readonly #chainCode: Uint8Array = new Uint8Array(32);
|
readonly #chainCode: Uint8Array = new Uint8Array(32);
|
||||||
@@ -61,7 +58,7 @@ export class DeriveJunction {
|
|||||||
|
|
||||||
public soft (value: HexString | number | string | bigint | BN | Uint8Array): DeriveJunction {
|
public soft (value: HexString | number | string | bigint | BN | Uint8Array): DeriveJunction {
|
||||||
if (isNumber(value) || isBn(value) || isBigInt(value)) {
|
if (isNumber(value) || isBn(value) || isBigInt(value)) {
|
||||||
return this.soft(bnToU8a(value, BN_OPTIONS));
|
return this.soft(bnToU8a(value, BN_LE_256_OPTS));
|
||||||
} else if (isHex(value)) {
|
} else if (isHex(value)) {
|
||||||
return this.soft(hexToU8a(value));
|
return this.soft(hexToU8a(value));
|
||||||
} else if (isString(value)) {
|
} else if (isString(value)) {
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -13,12 +13,11 @@
|
|||||||
// - Remove setting of wordlist passing of wordlist in functions
|
// - Remove setting of wordlist passing of wordlist in functions
|
||||||
// - Remove mnemonicToSeed (we only use the sync variant)
|
// - Remove mnemonicToSeed (we only use the sync variant)
|
||||||
|
|
||||||
import hash from 'hash.js';
|
|
||||||
|
|
||||||
import { assert, stringToU8a, u8aToU8a } from '@polkadot/util';
|
import { assert, stringToU8a, u8aToU8a } from '@polkadot/util';
|
||||||
|
|
||||||
import { pbkdf2Encode } from '../pbkdf2';
|
import { pbkdf2Encode } from '../pbkdf2';
|
||||||
import { randomAsU8a } from '../random/asU8a';
|
import { randomAsU8a } from '../random';
|
||||||
|
import { sha256AsU8a } from '../sha';
|
||||||
import DEFAULT_WORDLIST from './bip39-en';
|
import DEFAULT_WORDLIST from './bip39-en';
|
||||||
|
|
||||||
const INVALID_MNEMONIC = 'Invalid mnemonic';
|
const INVALID_MNEMONIC = 'Invalid mnemonic';
|
||||||
@@ -38,18 +37,16 @@ function bytesToBinary (bytes: number[]): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function deriveChecksumBits (entropyBuffer: Uint8Array): string {
|
function deriveChecksumBits (entropyBuffer: Uint8Array): string {
|
||||||
const ENT = entropyBuffer.length * 8;
|
return bytesToBinary(
|
||||||
const CS = ENT / 32;
|
Array.from(sha256AsU8a(entropyBuffer))
|
||||||
const result = hash.sha256().update(entropyBuffer).digest();
|
).slice(0, (entropyBuffer.length * 8) / 32);
|
||||||
|
|
||||||
return bytesToBinary(Array.from(result)).slice(0, CS);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mnemonicToSeedSync (mnemonic: string, password?: string): Uint8Array {
|
export function mnemonicToSeedSync (mnemonic: string, password?: string): Uint8Array {
|
||||||
const mnemonicBuffer = stringToU8a(normalize(mnemonic));
|
return pbkdf2Encode(
|
||||||
const saltBuffer = stringToU8a(`mnemonic${normalize(password)}`);
|
stringToU8a(normalize(mnemonic)),
|
||||||
|
stringToU8a(`mnemonic${normalize(password)}`)
|
||||||
return pbkdf2Encode(mnemonicBuffer, saltBuffer).password;
|
).password;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
export function mnemonicToEntropy (mnemonic: string): Uint8Array {
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { u8aToHex } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { convertPublicKeyToCurve25519, convertSecretKeyToCurve25519 } from '.';
|
||||||
|
|
||||||
|
describe('convertPublicKeyToCurve25519', (): void => {
|
||||||
|
it('converts a known key correctly', (): void => {
|
||||||
|
expect(
|
||||||
|
u8aToHex(convertPublicKeyToCurve25519(
|
||||||
|
new Uint8Array([
|
||||||
|
180, 114, 93, 155, 165, 255, 217, 82,
|
||||||
|
16, 250, 209, 11, 193, 10, 88, 218,
|
||||||
|
190, 190, 41, 193, 236, 252, 1, 152,
|
||||||
|
216, 214, 0, 41, 45, 138, 13, 53
|
||||||
|
])
|
||||||
|
))
|
||||||
|
).toEqual('0x5e05848ceeef4f306d6e285a26faf1a8070cf0c89f8d28ab966002fe4ad17746');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('convertSecretKeyToCurve25519', (): void => {
|
||||||
|
it('converts a known key correctly', (): void => {
|
||||||
|
expect(
|
||||||
|
u8aToHex(convertSecretKeyToCurve25519(
|
||||||
|
new Uint8Array([
|
||||||
|
1, 2, 3, 4, 5, 6, 7, 8,
|
||||||
|
1, 2, 3, 4, 5, 6, 7, 8,
|
||||||
|
1, 2, 3, 4, 5, 6, 7, 8,
|
||||||
|
1, 2, 3, 4, 5, 6, 7, 8
|
||||||
|
])
|
||||||
|
))
|
||||||
|
).toEqual('0xd875a82940b9174dabb1c0c895485810cc2870f5808565b59d4ef708bdcf526c');
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -3,10 +3,12 @@
|
|||||||
|
|
||||||
import ed2curve from 'ed2curve';
|
import ed2curve from 'ed2curve';
|
||||||
|
|
||||||
|
import { assertReturn } from '@polkadot/util';
|
||||||
|
|
||||||
export function convertSecretKeyToCurve25519 (secretKey: Uint8Array): Uint8Array {
|
export function convertSecretKeyToCurve25519 (secretKey: Uint8Array): Uint8Array {
|
||||||
return ed2curve.convertSecretKey(secretKey);
|
return ed2curve.convertSecretKey(secretKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function convertPublicKeyToCurve25519 (publicKey: Uint8Array): Uint8Array {
|
export function convertPublicKeyToCurve25519 (publicKey: Uint8Array): Uint8Array {
|
||||||
return ed2curve.convertPublicKey(publicKey) as Uint8Array;
|
return assertReturn(ed2curve.convertPublicKey(publicKey), 'Unable to convert publicKey to ed25519');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,19 +32,19 @@ describe('naclOpen', (): void => {
|
|||||||
// Receiver sends encrypting public key to receive message to decrypt with his private key
|
// Receiver sends encrypting public key to receive message to decrypt with his private key
|
||||||
const receiverIdBoxKey = naclBoxKeypairFromSecret(receiverIdKey.secretKey);
|
const receiverIdBoxKey = naclBoxKeypairFromSecret(receiverIdKey.secretKey);
|
||||||
|
|
||||||
console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey.publicKey.toString()}`);
|
// console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey.publicKey.toString()}`);
|
||||||
|
|
||||||
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
|
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
|
||||||
const senderIdBoxKey = naclBoxKeypairFromSecret(senderIdKey.secretKey);
|
const senderIdBoxKey = naclBoxKeypairFromSecret(senderIdKey.secretKey);
|
||||||
const message = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
|
const message = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
|
||||||
const { nonce, sealed } = naclSeal(message, senderIdBoxKey.secretKey, receiverIdBoxKey.publicKey);
|
const { nonce, sealed } = naclSeal(message, senderIdBoxKey.secretKey, receiverIdBoxKey.publicKey);
|
||||||
|
|
||||||
console.log(`Sender sends encrypted message to receiver ${sealed.toString()}, ${nonce.toString()}`);
|
// console.log(`Sender sends encrypted message to receiver ${sealed.toString()}, ${nonce.toString()}`);
|
||||||
|
|
||||||
// Receiver opens encrypted message from the sender
|
// Receiver opens encrypted message from the sender
|
||||||
let opened = naclOpen(sealed, nonce, senderIdBoxKey.publicKey, receiverIdBoxKey.secretKey);
|
let opened = naclOpen(sealed, nonce, senderIdBoxKey.publicKey, receiverIdBoxKey.secretKey);
|
||||||
|
|
||||||
console.log(`The sealed message is ${opened?.toString() || 'null'}`);
|
// console.log(`The sealed message is ${opened?.toString() || 'null'}`);
|
||||||
|
|
||||||
// Oh no the Id key is hacked, derive Id key again from another index
|
// Oh no the Id key is hacked, derive Id key again from another index
|
||||||
const senderIdKey2 = keyFromPath(sender, keyExtractPath('//1//1//1//2').path, 'ed25519');
|
const senderIdKey2 = keyFromPath(sender, keyExtractPath('//1//1//1//2').path, 'ed25519');
|
||||||
@@ -53,7 +53,7 @@ describe('naclOpen', (): void => {
|
|||||||
// Receiver sends encrypting public key to receive message to decrypt with his private key
|
// Receiver sends encrypting public key to receive message to decrypt with his private key
|
||||||
const receiverIdBoxKey2 = naclBoxKeypairFromSecret(receiverIdKey2.secretKey);
|
const receiverIdBoxKey2 = naclBoxKeypairFromSecret(receiverIdKey2.secretKey);
|
||||||
|
|
||||||
console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey2.publicKey.toString()}`);
|
// console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey2.publicKey.toString()}`);
|
||||||
|
|
||||||
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
|
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
|
||||||
const senderIdBoxKey2 = naclBoxKeypairFromSecret(senderIdKey2.secretKey);
|
const senderIdBoxKey2 = naclBoxKeypairFromSecret(senderIdKey2.secretKey);
|
||||||
@@ -62,17 +62,17 @@ describe('naclOpen', (): void => {
|
|||||||
const sealed2 = ctx.sealed;
|
const sealed2 = ctx.sealed;
|
||||||
const nonce2 = ctx.nonce;
|
const nonce2 = ctx.nonce;
|
||||||
|
|
||||||
console.log(`Sender sends encrypted message to receiver ${sealed.toString()}, ${nonce.toString()}`);
|
// console.log(`Sender sends encrypted message to receiver ${sealed.toString()}, ${nonce.toString()}`);
|
||||||
|
|
||||||
// Receiver opens encrypted message from the sender
|
// Receiver opens encrypted message from the sender
|
||||||
opened = naclOpen(sealed2, nonce2, senderIdBoxKey2.publicKey, receiverIdBoxKey2.secretKey);
|
opened = naclOpen(sealed2, nonce2, senderIdBoxKey2.publicKey, receiverIdBoxKey2.secretKey);
|
||||||
console.log(`The sealed message is ${opened?.toString() || 'null'}`);
|
// console.log(`The sealed message is ${opened?.toString() || 'null'}`);
|
||||||
|
|
||||||
// This time derive key for each message to send and receive
|
// This time derive key for each message to send and receive
|
||||||
// Receiver sends encrypting public key to receive message to decrypt with his private key
|
// Receiver sends encrypting public key to receive message to decrypt with his private key
|
||||||
const receiverIdBoxKey2One = naclBoxKeypairFromSecret(receiverIdBoxKey2.secretKey);
|
const receiverIdBoxKey2One = naclBoxKeypairFromSecret(receiverIdBoxKey2.secretKey);
|
||||||
|
|
||||||
console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey2One.publicKey.toString()}`);
|
// console.log(`Receiver sends receiver's public key to sender ${receiverIdBoxKey2One.publicKey.toString()}`);
|
||||||
|
|
||||||
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
|
// Sender encrypts message to send with the public key the receiver sent and send it to receiver
|
||||||
const senderIdBoxKey2One = naclBoxKeypairFromSecret(senderIdBoxKey2.secretKey);
|
const senderIdBoxKey2One = naclBoxKeypairFromSecret(senderIdBoxKey2.secretKey);
|
||||||
@@ -80,14 +80,16 @@ describe('naclOpen', (): void => {
|
|||||||
|
|
||||||
ctx = naclSeal(message3, senderIdBoxKey2One.secretKey, receiverIdBoxKey2One.publicKey);
|
ctx = naclSeal(message3, senderIdBoxKey2One.secretKey, receiverIdBoxKey2One.publicKey);
|
||||||
|
|
||||||
const sealed3 = ctx.sealed;
|
// const sealed3 = ctx.sealed;
|
||||||
const nonce3 = ctx.nonce;
|
// const nonce3 = ctx.nonce;
|
||||||
|
|
||||||
console.log(`Sender sends encrypted message to receiver ${sealed3.toString()}, ${nonce3.toString()}`);
|
// console.log(`Sender sends encrypted message to receiver ${sealed3.toString()}, ${nonce3.toString()}`);
|
||||||
|
|
||||||
// Receiver opens encrypted message from the sender
|
// Receiver opens encrypted message from the sender
|
||||||
opened = naclOpen(sealed2, nonce2, senderIdBoxKey2One.publicKey, receiverIdBoxKey2One.secretKey);
|
opened = naclOpen(sealed2, nonce2, senderIdBoxKey2One.publicKey, receiverIdBoxKey2One.secretKey);
|
||||||
console.log(`The sealed message is ${opened?.toString() || 'null'}`);
|
|
||||||
|
expect(opened).toEqual(message3);
|
||||||
|
// console.log(`The sealed message is ${opened?.toString() || 'null'}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('returns null on invalid', (): void => {
|
it('returns null on invalid', (): void => {
|
||||||
|
|||||||
@@ -4,8 +4,13 @@
|
|||||||
import { stringToU8a } from '@polkadot/util';
|
import { stringToU8a } from '@polkadot/util';
|
||||||
import { waitReady } from '@polkadot/wasm-crypto';
|
import { waitReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
|
import { performanceTest } from '../../test/performance';
|
||||||
import { naclKeypairFromSeed, naclSign } from '.';
|
import { naclKeypairFromSeed, naclSign } from '.';
|
||||||
|
|
||||||
|
const PAIR = naclKeypairFromSeed(
|
||||||
|
stringToU8a('12345678901234567890123456789012')
|
||||||
|
);
|
||||||
|
|
||||||
describe('naclSign', (): void => {
|
describe('naclSign', (): void => {
|
||||||
beforeEach(async (): Promise<void> => {
|
beforeEach(async (): Promise<void> => {
|
||||||
await waitReady();
|
await waitReady();
|
||||||
@@ -16,9 +21,7 @@ describe('naclSign', (): void => {
|
|||||||
expect(
|
expect(
|
||||||
naclSign(
|
naclSign(
|
||||||
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
||||||
naclKeypairFromSeed(
|
PAIR,
|
||||||
stringToU8a('12345678901234567890123456789012')
|
|
||||||
),
|
|
||||||
onlyJs
|
onlyJs
|
||||||
)
|
)
|
||||||
).toEqual(
|
).toEqual(
|
||||||
@@ -26,4 +29,8 @@ describe('naclSign', (): void => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
performanceTest('naclSign', 250, (input, onlyJs) =>
|
||||||
|
naclSign(input, PAIR, onlyJs)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -3,4 +3,4 @@
|
|||||||
|
|
||||||
// Auto-generated by @polkadot/dev, do not edit
|
// Auto-generated by @polkadot/dev, do not edit
|
||||||
|
|
||||||
export const packageInfo = { name: '@polkadot/util-crypto', version: '7.8.2' };
|
export const packageInfo = { name: '@polkadot/util-crypto', version: '7.9.1' };
|
||||||
|
|||||||
@@ -7,7 +7,12 @@ import { waitReady } from '@polkadot/wasm-crypto';
|
|||||||
import { randomAsU8a } from '../random/asU8a';
|
import { randomAsU8a } from '../random/asU8a';
|
||||||
import { pbkdf2Encode } from '.';
|
import { pbkdf2Encode } from '.';
|
||||||
|
|
||||||
const KNOWN_SALT = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]);
|
const KNOWN_SALT = new Uint8Array([
|
||||||
|
1, 2, 3, 4, 5, 6, 7, 8,
|
||||||
|
9, 10, 11, 12, 13, 14, 15, 16,
|
||||||
|
17, 18, 19, 20, 21, 22, 23, 24,
|
||||||
|
25, 26, 27, 28, 29, 30, 31, 32
|
||||||
|
]);
|
||||||
const TEST_PASSWORD = 'test password';
|
const TEST_PASSWORD = 'test password';
|
||||||
|
|
||||||
describe('pbkdf2Encode', (): void => {
|
describe('pbkdf2Encode', (): void => {
|
||||||
|
|||||||
@@ -18,9 +18,12 @@ interface Result {
|
|||||||
export function pbkdf2Encode (passphrase?: HexString | Buffer | Uint8Array | string, salt: Buffer | Uint8Array = randomAsU8a(), rounds = 2048, onlyJs = false): Result {
|
export function pbkdf2Encode (passphrase?: HexString | Buffer | Uint8Array | string, salt: Buffer | Uint8Array = randomAsU8a(), rounds = 2048, onlyJs = false): Result {
|
||||||
const u8aPass = u8aToU8a(passphrase);
|
const u8aPass = u8aToU8a(passphrase);
|
||||||
const u8aSalt = u8aToU8a(salt);
|
const u8aSalt = u8aToU8a(salt);
|
||||||
const password = isReady() && !onlyJs
|
|
||||||
? pbkdf2(u8aPass, u8aSalt, rounds)
|
|
||||||
: pbkdf2Sync(u8aPass, u8aSalt, rounds);
|
|
||||||
|
|
||||||
return { password, rounds, salt };
|
return {
|
||||||
|
password: isReady() && !onlyJs
|
||||||
|
? pbkdf2(u8aPass, u8aSalt, rounds)
|
||||||
|
: pbkdf2Sync(u8aPass, u8aSalt, rounds),
|
||||||
|
rounds,
|
||||||
|
salt
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
import { bnToU8a, u8aConcat } from '@polkadot/util';
|
import { bnToU8a, u8aConcat } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { BN_BE_32_OPTS } from '../bn';
|
||||||
import { hmacSha512 } from '../hmac';
|
import { hmacSha512 } from '../hmac';
|
||||||
|
|
||||||
export function pbkdf2Sync (password: Uint8Array, salt: Uint8Array, rounds: number, len = 64): Uint8Array {
|
export function pbkdf2Sync (password: Uint8Array, salt: Uint8Array, rounds: number, len = 64): Uint8Array {
|
||||||
@@ -14,7 +15,7 @@ export function pbkdf2Sync (password: Uint8Array, salt: Uint8Array, rounds: numb
|
|||||||
|
|
||||||
while (out.length < len) {
|
while (out.length < len) {
|
||||||
num++;
|
num++;
|
||||||
block.set(bnToU8a(num, { bitLength: 32, isLe: false }), salt.length);
|
block.set(bnToU8a(num, BN_BE_32_OPTS), salt.length);
|
||||||
|
|
||||||
let prev = hmacSha512(password, block);
|
let prev = hmacSha512(password, block);
|
||||||
const md = prev;
|
const md = prev;
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { waitReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
|
import { performanceTest } from '../../test/performance';
|
||||||
|
import { DEFAULT_PARAMS } from './defaults';
|
||||||
|
import { scryptEncode } from '.';
|
||||||
|
|
||||||
|
export const KNOWN_TEST = 'testing, 123';
|
||||||
|
|
||||||
|
export const KNOWN_PASS = new Uint8Array([223, 185, 241, 135, 125, 17, 195, 27, 64, 64, 154, 69, 47, 82, 123, 38, 255, 230, 199, 200, 101, 115, 21, 116, 119, 59, 67, 43, 58, 220, 112, 70, 124, 139, 240, 206, 42, 148, 140, 132, 64, 226, 164, 25, 104, 80, 49, 92, 144, 132, 109, 178, 76, 225, 171, 116, 151, 181, 34, 243, 177, 235, 134, 76]);
|
||||||
|
|
||||||
|
export const KNOWN_SALT = new Uint8Array([1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8, 1, 2, 3, 4, 5, 6, 7, 8]);
|
||||||
|
|
||||||
|
describe('scryptEncode', (): void => {
|
||||||
|
beforeEach(async (): Promise<void> => {
|
||||||
|
await waitReady();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.each([false, true])('onlyJs=%p', (onlyJs): void => {
|
||||||
|
it('generates a known output', (): void => {
|
||||||
|
expect(
|
||||||
|
scryptEncode(KNOWN_TEST, KNOWN_SALT, undefined, onlyJs)
|
||||||
|
).toEqual({
|
||||||
|
params: DEFAULT_PARAMS,
|
||||||
|
password: KNOWN_PASS,
|
||||||
|
salt: KNOWN_SALT
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
performanceTest('scryptEncode', 2, (input, onlyJs) =>
|
||||||
|
scryptEncode(input, input, undefined, onlyJs)
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -18,11 +18,13 @@ interface Result {
|
|||||||
salt: Uint8Array;
|
salt: Uint8Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function scryptEncode (passphrase?: HexString | Uint8Array | string, salt = randomAsU8a(), params = DEFAULT_PARAMS): Result {
|
export function scryptEncode (passphrase?: HexString | Uint8Array | string, salt = randomAsU8a(), params = DEFAULT_PARAMS, onlyJs = false): Result {
|
||||||
const password = isReady()
|
const u8a = u8aToU8a(passphrase);
|
||||||
? scrypt(u8aToU8a(passphrase), salt, Math.log2(params.N), params.r, params.p)
|
|
||||||
|
const password = isReady() && !onlyJs
|
||||||
|
? scrypt(u8a, salt, Math.log2(params.N), params.r, params.p)
|
||||||
: bufferToU8a(
|
: bufferToU8a(
|
||||||
scryptsy(u8aToBuffer(u8aToU8a(passphrase)), u8aToBuffer(salt), params.N, params.r, params.p, 64)
|
scryptsy(u8aToBuffer(u8a), u8aToBuffer(salt), params.N, params.r, params.p, 64)
|
||||||
);
|
);
|
||||||
|
|
||||||
return { params, password, salt };
|
return { params, password, salt };
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import type { Params } from './types';
|
|||||||
|
|
||||||
import { assert, u8aToBn } from '@polkadot/util';
|
import { assert, u8aToBn } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { BN_LE_OPTS } from '../bn';
|
||||||
import { DEFAULT_PARAMS } from './defaults';
|
import { DEFAULT_PARAMS } from './defaults';
|
||||||
|
|
||||||
interface Result {
|
interface Result {
|
||||||
@@ -14,9 +15,9 @@ interface Result {
|
|||||||
|
|
||||||
export function scryptFromU8a (data: Uint8Array): Result {
|
export function scryptFromU8a (data: Uint8Array): Result {
|
||||||
const salt = data.subarray(0, 32);
|
const salt = data.subarray(0, 32);
|
||||||
const N = u8aToBn(data.subarray(32 + 0, 32 + 4), { isLe: true }).toNumber();
|
const N = u8aToBn(data.subarray(32 + 0, 32 + 4), BN_LE_OPTS).toNumber();
|
||||||
const p = u8aToBn(data.subarray(32 + 4, 32 + 8), { isLe: true }).toNumber();
|
const p = u8aToBn(data.subarray(32 + 4, 32 + 8), BN_LE_OPTS).toNumber();
|
||||||
const r = u8aToBn(data.subarray(32 + 8, 32 + 12), { isLe: true }).toNumber();
|
const r = u8aToBn(data.subarray(32 + 8, 32 + 12), BN_LE_OPTS).toNumber();
|
||||||
|
|
||||||
// FIXME At this moment we assume these to be fixed params, this is not a great idea since we lose flexibility
|
// FIXME At this moment we assume these to be fixed params, this is not a great idea since we lose flexibility
|
||||||
// and updates for greater security. However we need some protection against carefully-crafted params that can
|
// and updates for greater security. However we need some protection against carefully-crafted params that can
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import type { Params } from './types';
|
|||||||
|
|
||||||
import { bnToU8a, u8aConcat } from '@polkadot/util';
|
import { bnToU8a, u8aConcat } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { BN_LE_32_OPTS } from '../bn';
|
||||||
|
|
||||||
export function scryptToU8a (salt: Uint8Array, { N, p, r }: Params): Uint8Array {
|
export function scryptToU8a (salt: Uint8Array, { N, p, r }: Params): Uint8Array {
|
||||||
return u8aConcat(
|
return u8aConcat(
|
||||||
salt,
|
salt,
|
||||||
bnToU8a(N, { bitLength: 32, isLe: true }),
|
bnToU8a(N, BN_LE_32_OPTS),
|
||||||
bnToU8a(p, { bitLength: 32, isLe: true }),
|
bnToU8a(p, BN_LE_32_OPTS),
|
||||||
bnToU8a(r, { bitLength: 32, isLe: true })
|
bnToU8a(r, BN_LE_32_OPTS)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
import { assert, bnToU8a, u8aConcat } from '@polkadot/util';
|
import { assert, bnToU8a, u8aConcat } from '@polkadot/util';
|
||||||
|
|
||||||
import { EXPAND_OPT, secp256k1 } from './secp256k1';
|
import { BN_BE_256_OPTS } from '../bn';
|
||||||
|
import { secp256k1 } from './secp256k1';
|
||||||
|
|
||||||
export function secp256k1Expand (publicKey: Uint8Array): Uint8Array {
|
export function secp256k1Expand (publicKey: Uint8Array): Uint8Array {
|
||||||
assert([33, 65].includes(publicKey.length), 'Invalid publicKey provided');
|
assert([33, 65].includes(publicKey.length), 'Invalid publicKey provided');
|
||||||
@@ -13,7 +14,7 @@ export function secp256k1Expand (publicKey: Uint8Array): Uint8Array {
|
|||||||
.getPublic();
|
.getPublic();
|
||||||
|
|
||||||
return u8aConcat(
|
return u8aConcat(
|
||||||
bnToU8a(expanded.getX(), EXPAND_OPT),
|
bnToU8a(expanded.getX(), BN_BE_256_OPTS),
|
||||||
bnToU8a(expanded.getY(), EXPAND_OPT)
|
bnToU8a(expanded.getY(), BN_BE_256_OPTS)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,8 @@ import type { Keypair } from '../../types';
|
|||||||
|
|
||||||
import { assert, bnToU8a } from '@polkadot/util';
|
import { assert, bnToU8a } from '@polkadot/util';
|
||||||
|
|
||||||
import { EXPAND_OPT, secp256k1 } from '../secp256k1';
|
import { BN_BE_256_OPTS } from '../../bn';
|
||||||
|
import { secp256k1 } from '../secp256k1';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name secp256k1KeypairFromSeed
|
* @name secp256k1KeypairFromSeed
|
||||||
@@ -18,6 +19,6 @@ export function secp256k1KeypairFromSeed (seed: Uint8Array): Keypair {
|
|||||||
|
|
||||||
return {
|
return {
|
||||||
publicKey: new Uint8Array(key.getPublic().encodeCompressed()),
|
publicKey: new Uint8Array(key.getPublic().encodeCompressed()),
|
||||||
secretKey: bnToU8a(key.getPrivate(), EXPAND_OPT)
|
secretKey: bnToU8a(key.getPrivate(), BN_BE_256_OPTS)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,5 @@
|
|||||||
|
|
||||||
import elliptic from 'elliptic';
|
import elliptic from 'elliptic';
|
||||||
|
|
||||||
const EC = elliptic.ec;
|
// eslint-disable-next-line new-cap
|
||||||
|
export const secp256k1 = new elliptic.ec('secp256k1');
|
||||||
export const secp256k1 = new EC('secp256k1');
|
|
||||||
|
|
||||||
export const EXPAND_OPT = { bitLength: 256, isLe: false };
|
|
||||||
|
|||||||
@@ -6,8 +6,9 @@ import type { HashType } from './types';
|
|||||||
|
|
||||||
import { assert, bnToU8a, u8aConcat } from '@polkadot/util';
|
import { assert, bnToU8a, u8aConcat } from '@polkadot/util';
|
||||||
|
|
||||||
|
import { BN_BE_256_OPTS } from '../bn';
|
||||||
import { secp256k1Hasher } from './hasher';
|
import { secp256k1Hasher } from './hasher';
|
||||||
import { EXPAND_OPT, secp256k1 } from './secp256k1';
|
import { secp256k1 } from './secp256k1';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @name secp256k1Sign
|
* @name secp256k1Sign
|
||||||
@@ -20,8 +21,8 @@ export function secp256k1Sign (message: Uint8Array | string, { secretKey }: Part
|
|||||||
const ecsig = key.sign(secp256k1Hasher(hashType, message));
|
const ecsig = key.sign(secp256k1Hasher(hashType, message));
|
||||||
|
|
||||||
return u8aConcat(
|
return u8aConcat(
|
||||||
bnToU8a(ecsig.r, EXPAND_OPT),
|
bnToU8a(ecsig.r, BN_BE_256_OPTS),
|
||||||
bnToU8a(ecsig.s, EXPAND_OPT),
|
bnToU8a(ecsig.s, BN_BE_256_OPTS),
|
||||||
new Uint8Array([ecsig.recoveryParam || 0])
|
new Uint8Array([ecsig.recoveryParam || 0])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,14 @@
|
|||||||
|
|
||||||
import { assert, BN, bnToU8a, isU8a } from '@polkadot/util';
|
import { assert, BN, bnToU8a, isU8a } from '@polkadot/util';
|
||||||
|
|
||||||
import { secp256k1 } from './secp256k1';
|
import { BN_BE_256_OPTS } from '../bn';
|
||||||
|
|
||||||
const ecparams = secp256k1.curve as { n: BN };
|
// pre-defined curve param as lifted form elliptic
|
||||||
|
// https://github.com/indutny/elliptic/blob/e71b2d9359c5fe9437fbf46f1f05096de447de57/lib/elliptic/curves.js#L182
|
||||||
|
const N = new BN(
|
||||||
|
'ffffffff ffffffff ffffffff fffffffe baaedce6 af48a03b bfd25e8c d0364141'.replace(/ /g, ''),
|
||||||
|
'hex'
|
||||||
|
);
|
||||||
|
|
||||||
export function secp256k1PrivateKeyTweakAdd (seckey: Uint8Array, tweak: Uint8Array): Uint8Array {
|
export function secp256k1PrivateKeyTweakAdd (seckey: Uint8Array, tweak: Uint8Array): Uint8Array {
|
||||||
assert(isU8a(seckey) && seckey.length === 32, 'Expected seckey to be an Uint8Array with length 32');
|
assert(isU8a(seckey) && seckey.length === 32, 'Expected seckey to be an Uint8Array with length 32');
|
||||||
@@ -13,15 +18,15 @@ export function secp256k1PrivateKeyTweakAdd (seckey: Uint8Array, tweak: Uint8Arr
|
|||||||
|
|
||||||
const bn = new BN(tweak);
|
const bn = new BN(tweak);
|
||||||
|
|
||||||
assert(bn.cmp(ecparams.n) < 0, 'Tweak parameter is out of range');
|
assert(bn.cmp(N) < 0, 'Tweak parameter is out of range');
|
||||||
|
|
||||||
bn.iadd(new BN(seckey));
|
bn.iadd(new BN(seckey));
|
||||||
|
|
||||||
if (bn.cmp(ecparams.n) >= 0) {
|
if (bn.cmp(N) >= 0) {
|
||||||
bn.isub(ecparams.n);
|
bn.isub(N);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!bn.isZero(), 'Invalid resulting private key');
|
assert(!bn.isZero(), 'Invalid resulting private key');
|
||||||
|
|
||||||
return bnToU8a(bn, { bitLength: 256, isLe: false });
|
return bnToU8a(bn, BN_BE_256_OPTS);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name shaAsU8a
|
||||||
|
* @summary Creates a sha Uint8Array from the input.
|
||||||
|
*/
|
||||||
|
export function shaAsU8a (value: HexString | Buffer | Uint8Array | string, bitLength: 256 | 512 = 256, onlyJs = false): Uint8Array {
|
||||||
|
const is256 = bitLength === 256;
|
||||||
|
const u8a = u8aToU8a(value);
|
||||||
|
|
||||||
|
return isReady() && !onlyJs
|
||||||
|
? is256
|
||||||
|
? sha256(u8a)
|
||||||
|
: sha512(u8a)
|
||||||
|
: new Uint8Array(
|
||||||
|
is256
|
||||||
|
? hash.sha256().update(u8a).digest()
|
||||||
|
: hash.sha512().update(u8a).digest()
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { hexToU8a } from '@polkadot/util';
|
||||||
|
import { waitReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
|
import { performanceTest } from '../../test/performance';
|
||||||
|
import { sha256AsU8a } from '.';
|
||||||
|
|
||||||
|
const TESTS = [
|
||||||
|
{
|
||||||
|
input: '0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855',
|
||||||
|
output: '0x5df6e0e2761359d30a8275058e299fcc0381534545f55cf43e41983f5d4c9456'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: '0x7941cb07924fdc7b710e11d98d82850e89566e1c3cb980517ffe4b430f86dfd5',
|
||||||
|
output: '0xe668668fa102ccd4d3cf50e4472be8426e7dc52d6d355bee8c5e2177d1de81f7'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: '0x5d9a905bc3ca7c153623af0a05231960eb3f5bdd5b8b7b55ede8b2deac689d65',
|
||||||
|
output: '0x6721bc38e80d03f4f45f1544819d17e0c33674eb6efcddf6c6192cd78194dd9f'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: '0xb0cd6528ae4d5baf7c6f0d202e7f372b6488d22b2a5bd72f794f8f1e6031b31f',
|
||||||
|
output: '0x353f5a030af27885aed3571cd9e2cac9f4331c51d31cef496a586496aec32256'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
input: '0x841267bd4110e1b634e17cd019abc6ae4f9a6dd097fb063000c1615a643b5463',
|
||||||
|
output: '0x8174a30d921978e7055516189872cca737b49468c6bcf7fdfe59d4a54c489a1f'
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
describe('sha256AsU8a', (): void => {
|
||||||
|
beforeEach(async (): Promise<void> => {
|
||||||
|
await waitReady();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe.each([false, true])('onlyJs=%p', (onlyJs): void => {
|
||||||
|
it.each(TESTS)('creates known sha-256 hash', ({ input, output }): void => {
|
||||||
|
expect(
|
||||||
|
sha256AsU8a(hexToU8a(input), onlyJs)
|
||||||
|
).toEqual(hexToU8a(output));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
performanceTest('sha256AsU8a', 128000, (input, onlyJs) =>
|
||||||
|
sha256AsU8a(input, onlyJs)
|
||||||
|
);
|
||||||
|
});
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import type { HexString } from '@polkadot/util/types';
|
||||||
|
|
||||||
|
import { shaAsU8a } from './asU8a';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name sha256AsU8a
|
||||||
|
* @summary Creates a sha256 Uint8Array from the input.
|
||||||
|
*/
|
||||||
|
export function sha256AsU8a (value: HexString | Buffer | Uint8Array | string, onlyJs = false): Uint8Array {
|
||||||
|
return shaAsU8a(value, 256, onlyJs);
|
||||||
|
}
|
||||||
+5
@@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
import { waitReady } from '@polkadot/wasm-crypto';
|
import { waitReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
|
import { performanceTest } from '../../test/performance';
|
||||||
import { sha512AsU8a } from '.';
|
import { sha512AsU8a } from '.';
|
||||||
|
|
||||||
describe('sha512AsU8a', (): void => {
|
describe('sha512AsU8a', (): void => {
|
||||||
@@ -21,4 +22,8 @@ describe('sha512AsU8a', (): void => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
performanceTest('sha512AsU8a', 64000, (input, onlyJs) =>
|
||||||
|
sha512AsU8a(input, onlyJs)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import type { HexString } from '@polkadot/util/types';
|
||||||
|
|
||||||
|
import { shaAsU8a } from './asU8a';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name sha512AsU8a
|
||||||
|
* @summary Creates a sha256 Uint8Array from the input.
|
||||||
|
*/
|
||||||
|
export function sha512AsU8a (value: HexString | Buffer | Uint8Array | string, onlyJs = false): Uint8Array {
|
||||||
|
return shaAsU8a(value, 512, onlyJs);
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @summary Implements Sha-256/512 hashing functions for a variety of input and outputs
|
||||||
|
*/
|
||||||
|
|
||||||
|
export { shaAsU8a } from './asU8a';
|
||||||
|
export { sha256AsU8a } from './asU8a256';
|
||||||
|
export { sha512AsU8a } from './asU8a512';
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
import nacl from 'tweetnacl';
|
|
||||||
|
|
||||||
import { isReady, sha512 } from '@polkadot/wasm-crypto';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @name sha512AsU8a
|
|
||||||
* @summary Creates sha-512 hash of the input.
|
|
||||||
* @description
|
|
||||||
* Returns a sha-512 `Uint8Array` from the supplied data.
|
|
||||||
* @example
|
|
||||||
* <BR>
|
|
||||||
*
|
|
||||||
* ```javascript
|
|
||||||
* import { sha512AsU8a } from '@polkadot/util-crypto';
|
|
||||||
*
|
|
||||||
* sha512AsU8a(Uint8Array.from([...])); // => Uint8Array([...])
|
|
||||||
* ```
|
|
||||||
*/
|
|
||||||
export function sha512AsU8a (data: Uint8Array, onlyJs = false): Uint8Array {
|
|
||||||
return isReady() && !onlyJs
|
|
||||||
? sha512(data)
|
|
||||||
: nacl.hash(data);
|
|
||||||
}
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @summary Implements Sha-512 hashing functions for a variety of input and outputs
|
|
||||||
*/
|
|
||||||
|
|
||||||
export { sha512AsU8a } from './asU8a';
|
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
import { hexToU8a } from '@polkadot/util';
|
import { hexToU8a } from '@polkadot/util';
|
||||||
import { waitReady } from '@polkadot/wasm-crypto';
|
import { waitReady } from '@polkadot/wasm-crypto';
|
||||||
|
|
||||||
|
import { performanceTest } from '../../test/performance';
|
||||||
import { xxhashAsU8a } from '.';
|
import { xxhashAsU8a } from '.';
|
||||||
|
|
||||||
describe('xxhashAsU8a', (): void => {
|
describe('xxhashAsU8a', (): void => {
|
||||||
@@ -36,4 +37,8 @@ describe('xxhashAsU8a', (): void => {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
performanceTest('xxhashAsU8a', 8000, (input, onlyJs) =>
|
||||||
|
xxhashAsU8a(input, 128, onlyJs)
|
||||||
|
);
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
// Copyright 2017-2021 @polkadot/util-crypto authors & contributors
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
import { arrayRange } from '@polkadot/util';
|
||||||
|
import { randomAsU8a } from '@polkadot/util-crypto';
|
||||||
|
|
||||||
|
const GENERATED = arrayRange(64).map(() => randomAsU8a());
|
||||||
|
|
||||||
|
function loop (count: number, onlyJs: boolean, exec: (input: Uint8Array, onlyJs: boolean) => unknown): number {
|
||||||
|
const start = Date.now();
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
exec(GENERATED[i % GENERATED.length], onlyJs);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Date.now() - start;
|
||||||
|
}
|
||||||
|
|
||||||
|
function perSecond (count: number, time: number): string {
|
||||||
|
const micro = (time * 1000) / count;
|
||||||
|
const ops = 1_000_000 / micro;
|
||||||
|
|
||||||
|
return `
|
||||||
|
${ops.toFixed(2).padStart(10)} ops/s
|
||||||
|
${micro.toFixed(2).padStart(10)} μs/op`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function performanceTest (name: string, count: number, exec: (input: Uint8Array, onlyJs: boolean) => unknown): void {
|
||||||
|
it(`performance: ${name}`, (): void => {
|
||||||
|
const ws = loop(count, false, exec);
|
||||||
|
const js = loop(count, true, exec);
|
||||||
|
|
||||||
|
console.log(`
|
||||||
|
performance run for ${name} completed with ${count} iterations.
|
||||||
|
|
||||||
|
WebAssembly: ${ws.toString().padStart(10)} ms ${ws < js ? '(fastest)' : `(slowest, ${(ws / js).toFixed(2)}x)`}${perSecond(count, ws)}
|
||||||
|
|
||||||
|
JavaScript: ${js.toString().padStart(10)} ms ${ws > js ? '(fastest)' : `(slowest, ${(js / ws).toFixed(2)}x)`}${perSecond(count, js)}
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
}
|
||||||
@@ -6,6 +6,26 @@
|
|||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=14.0.0"
|
"node": ">=14.0.0"
|
||||||
},
|
},
|
||||||
|
"exports": {
|
||||||
|
"./hex/toU8a": {
|
||||||
|
"node": {
|
||||||
|
"require": "./hex/toU8aBuffer.cjs",
|
||||||
|
"default": "./hex/toU8aBuffer.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"./u8a/concat": {
|
||||||
|
"node": {
|
||||||
|
"require": "./u8a/concatBuffer.cjs",
|
||||||
|
"default": "./u8a/concatBuffer.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"./u8a/toHex": {
|
||||||
|
"node": {
|
||||||
|
"require": "./u8a/toHexBuffer.cjs",
|
||||||
|
"default": "./u8a/toHexBuffer.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util#readme",
|
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util#readme",
|
||||||
"license": "Apache-2.0",
|
"license": "Apache-2.0",
|
||||||
"maintainers": [],
|
"maintainers": [],
|
||||||
@@ -20,15 +40,15 @@
|
|||||||
"./detectPackage.cjs"
|
"./detectPackage.cjs"
|
||||||
],
|
],
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"version": "7.8.2",
|
"version": "7.9.1",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@babel/runtime": "^7.16.0",
|
"@babel/runtime": "^7.16.3",
|
||||||
"@polkadot/x-textdecoder": "7.8.2",
|
"@polkadot/x-textdecoder": "7.9.1",
|
||||||
"@polkadot/x-textencoder": "7.8.2",
|
"@polkadot/x-textencoder": "7.9.1",
|
||||||
"@types/bn.js": "^4.11.6",
|
"@types/bn.js": "^4.11.6",
|
||||||
"bn.js": "^4.12.0",
|
"bn.js": "^4.12.0",
|
||||||
"camelcase": "^6.2.0",
|
"camelcase": "^6.2.1",
|
||||||
"ip-regex": "^4.3.0"
|
"ip-regex": "^4.3.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,10 +19,10 @@ export function arrayChunk <T> (array: T[], chunkSize: number): T[][] {
|
|||||||
const outputSize = Math.ceil(array.length / chunkSize);
|
const outputSize = Math.ceil(array.length / chunkSize);
|
||||||
const output = Array<T[]>(outputSize);
|
const output = Array<T[]>(outputSize);
|
||||||
|
|
||||||
for (let index = 0; index < outputSize; index++) {
|
for (let i = 0; i < outputSize; i++) {
|
||||||
const offset = index * chunkSize;
|
const offset = i * chunkSize;
|
||||||
|
|
||||||
output[index] = array.slice(offset, offset + chunkSize);
|
output[i] = array.slice(offset, offset + chunkSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return output;
|
return output;
|
||||||
|
|||||||
@@ -22,17 +22,19 @@ export function arrayFlatten <T> (arrays: T[][]): T[] {
|
|||||||
// pre-allocate based on the combined size
|
// pre-allocate based on the combined size
|
||||||
let size = 0;
|
let size = 0;
|
||||||
|
|
||||||
for (const a of arrays) {
|
for (let i = 0; i < arrays.length; i++) {
|
||||||
size += a.length;
|
size += arrays[i].length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const output = new Array<T>(size);
|
const output = new Array<T>(size);
|
||||||
let index = -1;
|
let i = -1;
|
||||||
|
|
||||||
|
for (let j = 0; j < arrays.length; j++) {
|
||||||
|
const a = arrays[j];
|
||||||
|
|
||||||
for (const a of arrays) {
|
|
||||||
// instead of pushing, we just set the entries
|
// instead of pushing, we just set the entries
|
||||||
for (let e = 0; e < a.length; e++) {
|
for (let e = 0; e < a.length; e++) {
|
||||||
output[++index] = a[e];
|
output[++i] = a[e];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
export function arrayShuffle <T> (input: T[]): T[] {
|
export function arrayShuffle <T> (input: T[]): T[] {
|
||||||
const result = [...input];
|
const result = input.slice();
|
||||||
let curr = result.length;
|
let curr = result.length;
|
||||||
|
|
||||||
if (curr === 1) {
|
if (curr === 1) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
// Copyright 2017-2021 @polkadot/util authors & contributors
|
// Copyright 2017-2021 @polkadot/util authors & contributors
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
import { assert } from '.';
|
import { assert, assertReturn } from '.';
|
||||||
|
|
||||||
describe('assert', (): void => {
|
describe('assert', (): void => {
|
||||||
it('should not throw an error when test is true', (): void => {
|
it('should not throw an error when test is true', (): void => {
|
||||||
@@ -10,13 +10,29 @@ describe('assert', (): void => {
|
|||||||
|
|
||||||
it('should throw an error when test is not true', (): void => {
|
it('should throw an error when test is not true', (): void => {
|
||||||
expect(
|
expect(
|
||||||
(): void => assert(false, 'error thrown')
|
() => assert(false, 'error thrown')
|
||||||
).toThrow(/error thrown/);
|
).toThrow(/error thrown/);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw an error when message: () => string', (): void => {
|
it('should throw an error when message: () => string', (): void => {
|
||||||
expect(
|
expect(
|
||||||
(): void => assert(false, (): string => 'message from function')
|
() => assert(false, (): string => 'message from function')
|
||||||
).toThrow(/message from function/);
|
).toThrow(/message from function/);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('assertReturn', (): void => {
|
||||||
|
it('should not throw an error when result is true', (): void => {
|
||||||
|
expect(assertReturn(true, 'nothing should be thrown')).toEqual(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should not throw an error when result is false', (): void => {
|
||||||
|
expect(assertReturn(false, 'nothing should be thrown')).toEqual(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw an error when result is undefined', (): void => {
|
||||||
|
expect(
|
||||||
|
() => assertReturn(undefined, 'something thrown')
|
||||||
|
).toThrow(/something thrown/);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user