Compare commits

...
37 Commits
Author SHA1 Message Date
Github Actions 99ffcc52ec [CI Skip] release/stable 3.1.1
skip-checks: true
2020-08-10 04:51:43 +00:00
Jaco Greeff 64510af8d3 3.1 (#655) 2020-08-10 06:47:53 +02:00
Github Actions 52b14db475 [CI Skip] release/beta 3.1.0-beta.8
skip-checks: true
2020-08-09 12:45:13 +00:00
Jaco Greeff c5fe5cd8d4 Bump @polkadot/wasm (#654) 2020-08-09 14:41:40 +02:00
Github Actions bdfc614ad5 [CI Skip] release/beta 3.1.0-beta.7
skip-checks: true
2020-08-09 12:29:56 +00:00
Jaco Greeff 0d03eac307 Add deriveAddress (#653) 2020-08-09 14:26:37 +02:00
Github Actions 6c84edcb9d [CI Skip] release/beta 3.1.0-beta.6
skip-checks: true
2020-08-09 11:31:44 +00:00
Jaco Greeff 9d145e72b8 Base32 encoding/decoding (#652)
* Base32 encoding/decoding

* Attribution

* LOOKUP

* Share base32/58 alphabet validation

* Apply suggestions from code review
2020-08-09 13:27:47 +02:00
Github Actions 4529bc37b5 [CI Skip] release/beta 3.1.0-beta.5
skip-checks: true
2020-08-08 07:07:37 +00:00
Jaco Greeff 038ef42fe5 Bump deps (#651) 2020-08-08 09:03:58 +02:00
Github Actions 1871d36a97 [CI Skip] release/beta 3.1.0-beta.4
skip-checks: true
2020-08-06 12:19:34 +00:00
Jaco Greeff 45c2afae07 Bump berry (#650)
* Bump berry

* Rewrite
2020-08-06 14:15:37 +02:00
Github Actions 51edae2f67 [CI Skip] release/beta 3.1.0-beta.3
skip-checks: true
2020-08-05 14:32:25 +00:00
Jaco Greeff 437314e5ea Bump wasm-crypto (#649)
* Bump wasm-crypto

* Rewrite yarn.lock
2020-08-05 16:28:22 +02:00
Jaco Greeff ce6f9d8bc8 Scrypt via wasm-crypto (#647)
* Scrypt via wasm-crypto

* Bump wasm-crypto
2020-08-05 16:07:38 +02:00
Github Actions 0cf65e1671 [CI Skip] release/beta 3.1.0-beta.2
skip-checks: true
2020-07-31 13:52:39 +00:00
Brad Larson a0251ff650 [FIX] Adjust error message (#646)
I ran into a case where the secret value provided had trailing
whitespace, and when the code ran, it logged that secret value as part
of the stack trace.

This change will make it harder for users to accidentally leak key
material.
2020-07-31 15:48:31 +02:00
Github Actions 9696badcd1 [CI Skip] release/beta 3.1.0-beta.1
skip-checks: true
2020-07-31 08:07:03 +00:00
Jaco Greeff 08817d199d Bump deps (#645) 2020-07-31 10:02:57 +02:00
Github Actions df69a02e6f [CI Skip] release/beta 3.1.0-beta.0
skip-checks: true
2020-07-30 14:02:55 +00:00
Jaco Greeff e845132d89 Bump deps (#644) 2020-07-30 15:58:17 +02:00
Github Actions 21e9b9a033 [CI Skip] release/stable 3.0.1
skip-checks: true
2020-07-27 06:21:35 +00:00
Jaco Greeff db61ea3077 3.0 release (#643) 2020-07-27 08:17:28 +02:00
Github Actions d4a3d2392e [CI Skip] release/beta 3.0.0-beta.4
skip-checks: true
2020-07-27 06:09:08 +00:00
Jaco Greeff 88ecda706d 3.0 (#642)
* 3.0

* Bump dev
2020-07-27 08:05:04 +02:00
Github Actions 184fb1f12e [CI Skip] release/beta 3.0.0-beta.3
skip-checks: true
2020-07-22 15:45:42 +00:00
Reto Trinkler 91340577df Adding 4 as address type of ss58 for Katal Chain (#639) 2020-07-22 17:41:49 +02:00
Github Actions 36729678e2 [CI Skip] release/beta 3.0.0-beta.2
skip-checks: true
2020-07-21 07:06:23 +00:00
Jaco Greeff 1c6b4bfc34 Dev bump 2020-07-21 09:02:25 +02:00
Github Actions bbfd175579 [CI Skip] release/beta 3.0.0-beta.1
skip-checks: true
2020-07-21 06:21:56 +00:00
Jaco Greeff 0a6bd41444 Keyring JSON with kdf (#637)
* Keyring JSON with pbkdf2

* pbkdf2 from wasm

* Encode/decode defaults adjusted

* v2 decoding test

* Recode refreshes defaults

* Use scrypt for kdf

* test conversions

* Fix params

* Cleanup decoding pass

* Swap encoding to base64

* Update for base64 encoding

* 3.0.0
2020-07-21 08:17:46 +02:00
Github Actions ab21274c36 [CI Skip] release/beta 2.19.0-beta.2
skip-checks: true
2020-07-17 12:30:08 +00:00
Jaco Greeff d4e6ad5553 Bump dev 2020-07-17 14:26:11 +02:00
Github Actions 49dbd757df [CI Skip] release/beta 2.19.0-beta.1
skip-checks: true
2020-07-17 12:07:35 +00:00
Jaco Greeff 20e82cc45b Dev bump 2020-07-17 14:03:36 +02:00
Github Actions 6a7fa80c55 [CI Skip] release/beta 2.19.0-beta.0
skip-checks: true
2020-07-17 06:39:13 +00:00
Jaco Greeff 12e34cd3e8 Bump deps (#635) 2020-07-17 08:35:10 +02:00
50 changed files with 3496 additions and 2812 deletions
Vendored Executable
+86
View File
File diff suppressed because one or more lines are too long
-56
View File
File diff suppressed because one or more lines are too long
+1 -1
View File
@@ -8,4 +8,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.js
spec: "@yarnpkg/plugin-interactive-tools"
yarnPath: .yarn/releases/yarn-rc.js
yarnPath: .yarn/releases/yarn-2.1.1.js
+13
View File
@@ -1,5 +1,18 @@
# CHANGELOG
## 3.1.1 Aug 10, 2020
- Add `deriveAddress(<address>, '/<soft>/<soft-b>')` via sr25519 soft
- Use `scrypt` from WASM as available (JS fallback in place)
- Add `base32{Encode, Decode}` utilities (IPFS-compatible alphabet)
- Support IPFS compatibility flag in base58 encoding/decoding
- Update to `@polkadot/wasm-crypto` 1.3.1
## 3.0.1 Jul 27, 2020
- Add Katal ss58Format (Thanks to https://github.com/retotrinkler)
- Adjust JSON pair output with scrypt kdf (version 3 output)
## 2.18.1 Jul 13, 2020
- Add `base64{Decode, Encode, Validate}` as crypto utils
+1 -1
View File
@@ -9,5 +9,5 @@
"packages": [
"packages/*"
],
"version": "2.18.1"
"version": "3.1.1"
}
+5 -5
View File
@@ -21,10 +21,10 @@
"test:one": "polkadot-dev-run-test"
},
"devDependencies": {
"@babel/core": "^7.10.4",
"@polkadot/dev": "^0.55.21",
"@polkadot/ts": "^0.3.27",
"@types/jest": "^26.0.4"
"@babel/core": "^7.11.1",
"@polkadot/dev": "^0.55.36",
"@polkadot/ts": "^0.3.36",
"@types/jest": "^26.0.9"
},
"version": "2.18.1"
"version": "3.1.1"
}
+4 -4
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/keyring",
"version": "2.18.1",
"version": "3.1.1",
"description": "Keyring management",
"main": "index.js",
"publishConfig": {
@@ -27,8 +27,8 @@
},
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/keyring#readme",
"dependencies": {
"@babel/runtime": "^7.10.4",
"@polkadot/util": "2.18.1",
"@polkadot/util-crypto": "2.18.1"
"@babel/runtime": "^7.11.2",
"@polkadot/util": "3.1.1",
"@polkadot/util-crypto": "3.1.1"
}
}
+69
View File
@@ -232,4 +232,73 @@ describe('keypair', (): void => {
).toEqual('5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY');
});
});
describe('version 2 JSON', (): void => {
const PAIR = '{"address":"5CczAE5AmGrZ93MeVhha3Ywam7j9dKB7cArnH7gtrXcMFJvu","encoded":"0xee8f236e2ac3217ce689692a4afc612220dc77fddaed0482f8f95136a7c3e034cccfbc495410a6e9b2439904974ed1d207abeca536ff6985ceb78edeeb3dc343e561c184c488101af8811d1331430b4ccf0e96ef507132e5132964e8564232e7100d973c5bee7b231dd0c8ad5273f3501515a422c8d7ed9d20a73c0ed17c98ee4588e54844bb73052dcad81f7a1094613d63c162fec7446c88b1fae70e","encoding":{"content":["pkcs8","sr25519"],"type":"xsalsa20-poly1305","version":"2"},"meta":{"genesisHash":"0xe143f23803ac50e8f6f8e62695d1ce9e4e1d68aa36c1cd2cfd15340213f3423e","name":"json v2","tags":[],"whenCreated":1595243159596}}';
const PASS2 = 'versionTwo';
const PASS3 = 'versionThree';
let keyring: Keyring;
beforeEach((): void => {
keyring = new Keyring({ ss58Format: 42 });
});
it('can decode from a version 2 JSON file', (): void => {
const pair = keyring.addFromJson(JSON.parse(PAIR));
pair.decodePkcs8(PASS2);
const json = pair.toJson(PASS3);
expect(pair.isLocked).toBe(false);
expect(pair.address).toBe('5CczAE5AmGrZ93MeVhha3Ywam7j9dKB7cArnH7gtrXcMFJvu');
expect(json.encoding).toEqual({
content: ['pkcs8', 'sr25519'],
type: ['scrypt', 'xsalsa20-poly1305'],
version: '3'
});
pair.decodePkcs8(PASS3);
expect(pair.address).toEqual('5CczAE5AmGrZ93MeVhha3Ywam7j9dKB7cArnH7gtrXcMFJvu');
});
});
describe('version 3 JSON (hex)', (): void => {
const PAIR = '{"address":"FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH","encoded":"0xcd238963070cc4d6806053ee1ac500c7add9c28732bb5d434a332f84a91d9be0008000000100000008000000cf630a1113941b350ddd06697e50399183162e5e9a0e893eafc7f5f4893a223dca5055706b9925b56fdb4304192143843da718e11717daf89cf4f4781f94fb443f61432f782d54280af9eec90bd3069c3cc2d957a42b7c18dc2e9497f623735518e0e49b58f8e4db2c09da3a45dbb935659d015fc94b946cba75b606a6ff7f4e823f6b049e2e6892026b49de02d6dbbd64646fe0933f537d9ea53a70be","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"genesisHash":"0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe","name":"version3","tags":[],"whenCreated":1595277797639}}';
const PASS3 = 'version3';
let keyring: Keyring;
beforeEach((): void => {
keyring = new Keyring({ ss58Format: 2 });
});
it('can decode from a version 3 JSON file', (): void => {
const pair = keyring.addFromJson(JSON.parse(PAIR));
pair.decodePkcs8(PASS3);
expect(pair.isLocked).toBe(false);
expect(pair.address).toBe('FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH');
});
});
describe('version 3 JSON (base64)', (): void => {
const PAIR = '{"address":"FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH","encoded":"ILjSgYaGvq1zaCz/kx+aqfLaHBjLXz0Qsmr6RnkOVU4AgAAAAQAAAAgAAAB5R2hm5kgXyc0NQYFxvMU4zCdjB+ugs/ibEooqCvuudbaeKn3Ee47NkCqU1ecOJV+eeaVn4W4dRvIpj5kGmQOGsewR+MiQ/B0G9NFh7JXV0qcPlk2QMNW1/mbJrTO4miqL448BSkP7ZOhUV6HFUpMt3B9HwjiRLN8RORcFp0ID/Azs4Jl/xOpXNzbgQGIffWgCIKTxN9N1ku6tdlG4","encoding":{"content":["pkcs8","sr25519"],"type":["scrypt","xsalsa20-poly1305"],"version":"3"},"meta":{"genesisHash":"0xb0a8d493285c2df73290dfb7e61f870f17b41801197a149ca93654499ea3dafe","name":"version3","tags":[],"whenCreated":1595277797639,"whenEdited":1595278378596}}';
const PASS3 = 'version3';
let keyring: Keyring;
beforeEach((): void => {
keyring = new Keyring({ ss58Format: 2 });
});
it('can decode from a version 3 JSON file', (): void => {
const pair = keyring.addFromJson(JSON.parse(PAIR));
pair.decodePkcs8(PASS3);
expect(pair.isLocked).toBe(false);
expect(pair.address).toBe('FLiSDPCcJ6auZUGXALLj6jpahcP6adVFDBUQznPXUQ7yoqH');
});
});
});
+10 -7
View File
@@ -3,10 +3,10 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { KeypairType, Keypair } from '@polkadot/util-crypto/types';
import { KeyringInstance, KeyringPair, KeyringPair$Json, KeyringPair$Meta, KeyringOptions } from './types';
import { KeyringInstance, KeyringPair, KeyringPair$Json, KeyringPair$JsonEncodingTypes, KeyringPair$Meta, KeyringOptions } from './types';
import { assert, hexToU8a, isHex, isUndefined, stringToU8a } from '@polkadot/util';
import { decodeAddress, encodeAddress, keyExtractSuri, keyFromPath, naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, secp256k1KeypairFromSeed as secp256k1FromSeed, mnemonicToMiniSecret } from '@polkadot/util-crypto';
import { base64Decode, decodeAddress, encodeAddress, keyExtractSuri, keyFromPath, naclKeypairFromSeed as naclFromSeed, schnorrkelKeypairFromSeed as schnorrkelFromSeed, secp256k1KeypairFromSeed as secp256k1FromSeed, mnemonicToMiniSecret } from '@polkadot/util-crypto';
import { DEV_PHRASE } from './defaults';
import createPair from './pair';
@@ -84,10 +84,10 @@ export default class Keyring implements KeyringInstance {
* of an account backup), and then generates a keyring pair from them that it passes to
* `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value.
*/
public addFromAddress (address: string | Uint8Array, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, type: KeypairType = this.type, ignoreChecksum?: boolean): KeyringPair {
public addFromAddress (address: string | Uint8Array, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, type: KeypairType = this.type, ignoreChecksum?: boolean, encType?: KeyringPair$JsonEncodingTypes[]): KeyringPair {
const publicKey = this.decodeAddress(address, ignoreChecksum);
return this.addPair(createPair({ toSS58: this.encodeAddress, type }, { publicKey, secretKey: new Uint8Array() }, meta, encoded));
return this.addPair(createPair({ toSS58: this.encodeAddress, type }, { publicKey, secretKey: new Uint8Array() }, meta, encoded, encType));
}
/**
@@ -97,12 +97,15 @@ export default class Keyring implements KeyringInstance {
* of an account backup), and then generates a keyring pair from it that it passes to
* `addPair` to stores in a keyring pair dictionary the public key of the generated pair as a key and the pair as the associated value.
*/
public addFromJson ({ address, encoded, encoding: { content, version }, meta }: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair {
const type = version === '0' || !Array.isArray(content)
public addFromJson ({ address, encoded, encoding: { content, type, version }, meta }: KeyringPair$Json, ignoreChecksum?: boolean): KeyringPair {
const cryptoType = version === '0' || !Array.isArray(content)
? this.type
: content[1];
const encType = !Array.isArray(type)
? [type]
: type;
return this.addFromAddress(address, meta, hexToU8a(encoded), type, ignoreChecksum);
return this.addFromAddress(address, meta, isHex(encoded) ? hexToU8a(encoded) : base64Decode(encoded), cryptoType, ignoreChecksum, encType);
}
/**
+26 -10
View File
@@ -2,11 +2,13 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { assert, stringToU8a, u8aFixLength } from '@polkadot/util';
import { naclDecrypt } from '@polkadot/util-crypto';
import { KeyringPair$JsonEncodingTypes } from '../types';
import { PairInfo } from './types';
import { NONCE_LENGTH, PKCS8_DIVIDER, PKCS8_HEADER, PUB_LENGTH, SEC_LENGTH, SEED_LENGTH } from './defaults';
import { assert, stringToU8a, u8aFixLength } from '@polkadot/util';
import { naclDecrypt, scryptEncode, scryptFromU8a } from '@polkadot/util-crypto';
import { NONCE_LENGTH, PKCS8_DIVIDER, PKCS8_HEADER, PUB_LENGTH, SEC_LENGTH, SEED_LENGTH, SCRYPT_LENGTH } from './defaults';
const SEED_OFFSET = PKCS8_HEADER.length;
@@ -41,18 +43,32 @@ function decodePkcs8 (encoded: Uint8Array): DecodeResult {
};
}
export default function decode (passphrase?: string, encrypted?: Uint8Array | null): DecodeResult {
export default function decode (passphrase?: string, encrypted?: Uint8Array | null, encType: KeyringPair$JsonEncodingTypes[] = ['scrypt', 'xsalsa20-poly1305']): DecodeResult {
assert(encrypted, 'No encrypted data available to decode');
assert(passphrase || !encType.includes('xsalsa20-poly1305'), 'Password required to decode encypted data');
const encoded = passphrase
? naclDecrypt(
let encoded: Uint8Array | null = encrypted;
if (passphrase) {
let password: Uint8Array;
if (encType.includes('scrypt')) {
const { params, salt } = scryptFromU8a(encrypted);
password = scryptEncode(passphrase, salt, params).password;
encrypted = encrypted.subarray(SCRYPT_LENGTH);
} else {
password = stringToU8a(passphrase);
}
encoded = naclDecrypt(
encrypted.subarray(NONCE_LENGTH),
encrypted.subarray(0, NONCE_LENGTH),
u8aFixLength(stringToU8a(passphrase), 256, true)
)
: encrypted;
u8aFixLength(password, 256, true)
);
}
assert(encoded, 'Unable to unencrypt using the supplied passphrase');
assert(encoded, 'Unable to decode using the supplied passphrase');
return decodePkcs8(encoded);
}
+5 -1
View File
@@ -6,14 +6,18 @@ const NONCE_LENGTH = 24;
const PKCS8_DIVIDER = new Uint8Array([161, 35, 3, 33, 0]);
const PKCS8_HEADER = new Uint8Array([48, 83, 2, 1, 1, 48, 5, 6, 3, 43, 101, 112, 4, 34, 4, 32]);
const PUB_LENGTH = 32;
const SALT_LENGTH = 32;
const SEC_LENGTH = 64;
const SEED_LENGTH = 32;
const SCRYPT_LENGTH = SALT_LENGTH + (3 * 4);
export {
NONCE_LENGTH,
PKCS8_DIVIDER,
PKCS8_HEADER,
PUB_LENGTH,
SALT_LENGTH,
SEC_LENGTH,
SEED_LENGTH
SEED_LENGTH,
SCRYPT_LENGTH
};
+2 -2
View File
@@ -3,10 +3,10 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import testingPairs from '../testingPairs';
import { PKCS8_DIVIDER, PKCS8_HEADER, PUB_LENGTH, SEC_LENGTH } from './defaults';
import { PKCS8_DIVIDER, PKCS8_HEADER, NONCE_LENGTH, PUB_LENGTH, SCRYPT_LENGTH, SEC_LENGTH } from './defaults';
const PKCS8_LENGTH = PKCS8_DIVIDER.length + PKCS8_HEADER.length + PUB_LENGTH + SEC_LENGTH;
const ENCODED_LENGTH = 157;
const ENCODED_LENGTH = 16 + PKCS8_LENGTH + NONCE_LENGTH + SCRYPT_LENGTH;
const keyring = testingPairs({ type: 'ed25519' }, false);
+5 -4
View File
@@ -4,8 +4,8 @@
import { PairInfo } from './types';
import { stringToU8a, u8aConcat, u8aFixLength, assert } from '@polkadot/util';
import { naclEncrypt } from '@polkadot/util-crypto';
import { u8aConcat, assert } from '@polkadot/util';
import { naclEncrypt, scryptEncode, scryptToU8a } from '@polkadot/util-crypto';
import { PKCS8_DIVIDER, PKCS8_HEADER } from './defaults';
@@ -23,7 +23,8 @@ export default function encode ({ publicKey, secretKey }: PairInfo, passphrase?:
return encoded;
}
const { encrypted, nonce } = naclEncrypt(encoded, u8aFixLength(stringToU8a(passphrase), 256, true));
const { params, password, salt } = scryptEncode(passphrase);
const { encrypted, nonce } = naclEncrypt(encoded, password.subarray(0, 32));
return u8aConcat(nonce, encrypted);
return u8aConcat(scryptToU8a(salt, params), nonce, encrypted);
}
+13 -6
View File
@@ -3,7 +3,7 @@
// of the Apache-2.0 license. See the LICENSE file for details.
import { Keypair, KeypairType } from '@polkadot/util-crypto/types';
import { KeyringPair, KeyringPair$Json, KeyringPair$Meta, SignOptions } from '../types';
import { KeyringPair, KeyringPair$Json, KeyringPair$JsonEncodingTypes, KeyringPair$Meta, SignOptions } from '../types';
import { PairInfo } from './types';
import { assert, u8aConcat } from '@polkadot/util';
@@ -112,7 +112,14 @@ function isLocked (secretKey?: Uint8Array): secretKey is undefined {
* an `encoded` property that is assigned with the encoded public key in hex format, and an `encoding`
* property that indicates whether the public key value of the `encoded` property is encoded or not.
*/
export default function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: PairInfo, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null): KeyringPair {
export default function createPair ({ toSS58, type }: Setup, { publicKey, secretKey }: PairInfo, meta: KeyringPair$Meta = {}, encoded: Uint8Array | null = null, encTypes?: KeyringPair$JsonEncodingTypes[]): KeyringPair {
const recode = (passphrase?: string): Uint8Array => {
encoded = encode({ publicKey, secretKey }, passphrase); // re-encode, latest version
encTypes = undefined; // swap to defaults, latest version follows
return encoded;
};
return {
get address (): string {
return toSS58(getAddress(type, publicKey));
@@ -130,8 +137,8 @@ export default function createPair ({ toSS58, type }: Setup, { publicKey, secret
return type;
},
// eslint-disable-next-line sort-keys
decodePkcs8: (passphrase?: string, _encoded?: Uint8Array | null): void => {
const decoded = decode(passphrase, _encoded || encoded);
decodePkcs8: (passphrase?: string, userEncoded?: Uint8Array | null): void => {
const decoded = decode(passphrase, userEncoded || encoded, encTypes);
if (decoded.secretKey.length === 64) {
publicKey = decoded.publicKey;
@@ -152,7 +159,7 @@ export default function createPair ({ toSS58, type }: Setup, { publicKey, secret
return createPair({ toSS58, type }, derived, meta, null);
},
encodePkcs8: (passphrase?: string): Uint8Array =>
encode({ publicKey, secretKey }, passphrase),
recode(passphrase),
lock: (): void => {
secretKey = new Uint8Array(0);
},
@@ -165,7 +172,7 @@ export default function createPair ({ toSS58, type }: Setup, { publicKey, secret
return sign(type, message, { publicKey, secretKey }, options);
},
toJson: (passphrase?: string): KeyringPair$Json =>
toJson(type, { address: toSS58(getAddress(type, publicKey)), meta }, encode({ publicKey, secretKey }, passphrase), !!passphrase),
toJson(type, { address: toSS58(getAddress(type, publicKey)), meta }, recode(passphrase), !!passphrase),
verify: (message: Uint8Array, signature: Uint8Array): boolean =>
verify(type, message, signature, publicKey)
};
+6 -6
View File
@@ -12,11 +12,11 @@ describe('toJson', (): void => {
keyring.alice.toJson()
).toMatchObject({
address: '5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua',
encoded: '0x3053020101300506032b657004220420416c696365202020202020202020202020202020202020202020202020202020d172a74cda4c865912c32ba0a80a57ae69abae410e5ccb59dee84e2f4432db4fa123032100d172a74cda4c865912c32ba0a80a57ae69abae410e5ccb59dee84e2f4432db4f',
encoded: 'MFMCAQEwBQYDK2VwBCIEIEFsaWNlICAgICAgICAgICAgICAgICAgICAgICAgICAg0XKnTNpMhlkSwyugqApXrmmrrkEOXMtZ3uhOL0Qy20+hIwMhANFyp0zaTIZZEsMroKgKV65pq65BDlzLWd7oTi9EMttP',
encoding: {
content: ['pkcs8', 'ed25519'],
type: 'none',
version: '2'
type: ['none'],
version: '3'
},
meta: {
isTesting: true,
@@ -28,13 +28,13 @@ describe('toJson', (): void => {
it('creates an encoded output with passphrase', (): void => {
const json = keyring.alice.toJson('testing');
expect(json.encoded).toHaveLength(316);
expect(json.encoded).toHaveLength(268);
expect(json).toMatchObject({
address: '5GoKvZWG5ZPYL1WUovuHW3zJBWBP5eT8CbqjdRY4Q6iMaQua',
encoding: {
content: ['pkcs8', 'ed25519'],
type: 'xsalsa20-poly1305',
version: '2'
type: ['scrypt', 'xsalsa20-poly1305'],
version: '3'
}
});
});
+8 -5
View File
@@ -5,23 +5,26 @@
import { KeypairType } from '@polkadot/util-crypto/types';
import { KeyringPair$Json, KeyringPair$Meta } from '../types';
import { u8aToHex } from '@polkadot/util';
import { base64Encode } from '@polkadot/util-crypto';
interface PairStateJson {
address: string;
meta: KeyringPair$Meta;
}
// version 2 - nonce, encoded (previous)
// version 3 - salt, nonce, encoded
export default function toJson (type: KeypairType, { address, meta }: PairStateJson, encoded: Uint8Array, isEncrypted: boolean): KeyringPair$Json {
return {
address,
encoded: u8aToHex(encoded),
encoded: base64Encode(encoded),
encoding: {
content: ['pkcs8', type],
type: isEncrypted
? 'xsalsa20-poly1305'
: 'none',
version: '2'
? ['scrypt', 'xsalsa20-poly1305']
: ['none'],
version: '3'
},
meta
};
+4 -2
View File
@@ -12,11 +12,13 @@ export interface KeyringOptions {
export type KeyringPair$Meta = Record<string, unknown>;
export type KeyringPair$JsonVersion = '0' | '1' | '2';
export type KeyringPair$JsonVersion = '0' | '1' | '2' | '3';
export type KeyringPair$JsonEncodingTypes = 'none' | 'scrypt' | 'xsalsa20-poly1305';
export interface KeyringPair$JsonEncoding {
content: ['pkcs8', KeypairType];
type: 'xsalsa20-poly1305' | 'none';
type: KeyringPair$JsonEncodingTypes | KeyringPair$JsonEncodingTypes[];
version: KeyringPair$JsonVersion;
}
+7 -5
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/util-crypto",
"version": "2.18.1",
"version": "3.1.1",
"description": "A collection of useful crypto utilities for @polkadot",
"main": "index.js",
"keywords": [
@@ -25,9 +25,9 @@
},
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
"dependencies": {
"@babel/runtime": "^7.10.4",
"@polkadot/util": "2.18.1",
"@polkadot/wasm-crypto": "^1.2.1",
"@babel/runtime": "^7.11.2",
"@polkadot/util": "3.1.1",
"@polkadot/wasm-crypto": "^1.3.1",
"base-x": "^3.0.8",
"bip39": "^3.0.2",
"blakejs": "^1.1.0",
@@ -35,13 +35,15 @@
"elliptic": "^6.5.3",
"js-sha3": "^0.8.0",
"pbkdf2": "^3.1.1",
"scryptsy": "^2.1.0",
"tweetnacl": "^1.0.3",
"xxhashjs": "^0.2.2"
},
"devDependencies": {
"@types/bn.js": "^4.11.6",
"@types/elliptic": "^6.4.12",
"@types/pbkdf2": "^3.0.0",
"@types/pbkdf2": "^3.1.0",
"@types/scryptsy": "^2.0.0",
"@types/xxhashjs": "^0.2.2"
}
}
@@ -7,7 +7,7 @@ import { stringToU8a, u8aToHex } from '@polkadot/util';
import testingPairs, { TestKeyringMap } from '../../../keyring/src/testingPairs';
import decode from './decode';
describe('decode', (): void => {
describe('decodeAddress', (): void => {
let keyring: TestKeyringMap;
beforeAll((): void => {
@@ -0,0 +1,25 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { waitReady } from '@polkadot/wasm-crypto';
import derive from './derive';
describe('deriveAddress', (): void => {
beforeEach(async (): Promise<void> => {
await waitReady();
});
it('derives a known path', (): void => {
expect(
derive('5CZtJLXtVzrBJq1fMWfywDa6XuRwXekGdShPR4b8i9GWSbzB', '/joe/polkadot/0')
).toEqual('5GZ4srnepXvdsuNVoxCGyVZd8ScDm4gkGLTKuaGARy9akjTa');
});
it('fails on hard paths', (): void => {
expect(
() => derive('5CZtJLXtVzrBJq1fMWfywDa6XuRwXekGdShPR4b8i9GWSbzB', '//bob')
).toThrow(/Expected suri to contain a combination of non-hard paths/);
});
});
@@ -0,0 +1,29 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Prefix } from './types';
import { assert } from '@polkadot/util';
import DeriveJunction from '../key/DeriveJunction';
import { keyExtractPath } from '../key';
import { schnorrkelDerivePublic } from '../schnorrkel';
import decode from './decode';
import encode from './encode';
/**
* @name deriveAddress
* @summary Creates a sr25519 derived address from the supplied and path.
* @description
* Creates a sr25519 derived address based on the input address/publicKey and the uri supplied.
*/
export default function deriveAddress (who: Uint8Array | string, suri: string, ss58Format?: Prefix): string {
const { path } = keyExtractPath(suri);
assert(path.length && !path.some((path) => path.isHard), 'Expected suri to contain a combination of non-hard paths');
return encode(path.reduce((publicKey: Uint8Array, path: DeriveJunction): Uint8Array => {
return schnorrkelDerivePublic(publicKey, path.chainCode);
}, decode(who)), ss58Format);
}
@@ -12,7 +12,7 @@ import keyDerived from './keyDerived';
/**
* @name encodeDerivedAddress
* @summary Creates a derived address.
* @summary Creates a derived address as used in Substrate utility.
* @description
* Creates a Substrate derived address based on the input address/publicKey and the index supplied.
*/
@@ -7,6 +7,7 @@ import checkAddressChecksum from './checkChecksum';
import createKeyMulti from './keyMulti';
import createKeyDerived from './keyDerived';
import decodeAddress from './decode';
import deriveAddress from './derive';
import encodeAddress from './encode';
import encodeDerivedAddress from './encodeDerived';
import encodeMultiAddress from './encodeMulti';
@@ -21,6 +22,7 @@ export {
createKeyDerived,
createKeyMulti,
decodeAddress,
deriveAddress,
encodeAddress,
encodeDerivedAddress,
encodeMultiAddress,
+2
View File
@@ -7,6 +7,8 @@ export const allowedSS58 = [
0, 1,
// Kusama
2, 3,
// Katal Chain
4,
// Kulupu
16, 17,
// Dothereum
+12
View File
@@ -0,0 +1,12 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// https://github.com/multiformats/js-multibase/blob/master/src/constants.js
const BASE32_ALPHABET = 'abcdefghijklmnopqrstuvwxyz234567';
const BITS_PER_CHAR = 5;
export {
BASE32_ALPHABET,
BITS_PER_CHAR
};
@@ -0,0 +1,25 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { u8aToString } from '@polkadot/util';
import { base32Decode } from './';
describe('base32Decode', (): void => {
it('decodes a base32', (): void => {
expect(
u8aToString(
base32Decode('irswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb')
)
).toEqual('Decentralize everything!!');
});
it('decodes a base32 (ipfsCompat)', (): void => {
expect(
u8aToString(
base32Decode('birswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb', true)
)
).toEqual('Decentralize everything!!');
});
});
+54
View File
@@ -0,0 +1,54 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// 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 validate from './validate';
// Build the character lookup table:
const LOOKUP = BASE32_ALPHABET
.split('')
.reduce((lookup: Record<string, number>, char: string, index: number): Record<string, number> => {
lookup[char] = index;
return lookup;
}, {});
/**
* @name base32Decode
* @summary Delookup a base32 value.
* @description
* From the provided input, decode the base32 and return the result as an `Uint8Array`.
*/
export default function base32Decode (value: string, ipfsCompat = false): Uint8Array {
if (ipfsCompat) {
assert(value[0] === 'b', "Expected IPFS base32 identifier 'b' at string start");
value = value.substr(1);
}
validate(value);
const out = new Uint8Array((value.length * BITS_PER_CHAR / 8) | 0);
let bits = 0;
let buffer = 0;
let written = 0;
for (let i = 0; i < value.length; ++i) {
buffer = (buffer << BITS_PER_CHAR) | LOOKUP[value[i]];
bits += BITS_PER_CHAR;
if (bits >= 8) {
bits -= 8;
out[written++] = 0xff & (buffer >> bits);
}
}
assert(!(bits >= BITS_PER_CHAR || 0xff & (buffer << (8 - bits))), 'Unexpected end of data');
return out;
}
@@ -0,0 +1,23 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { base58Decode } from '../base58';
import { base32Encode } from './';
describe('base32Encode', (): void => {
it('encodes to a base32', (): void => {
expect(
base32Encode('Decentralize everything!!')
).toEqual('irswgzloorzgc3djpjssazlwmvzhs5dinfxgoijb');
});
it('encodes a base58 to a base32', (): void => {
expect(
base32Encode(
base58Decode('zb2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV', true),
true
)
).toEqual('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy');
});
});
+42
View File
@@ -0,0 +1,42 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
// adapted from https://github.com/multiformats/js-multibase/blob/424709195b46ffb1d6f2f69a7707598ebe751e5e/src/rfc4648.js
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 default function base32Encode (value: Uint8Array | string | Buffer | number[], 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;
}
+11
View File
@@ -0,0 +1,11 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
/**
* @summary Encode and decode base32 values
*/
export { default as base32Decode } from './decode';
export { default as base32Encode } from './encode';
export { default as base32Validate } from './validate';
@@ -0,0 +1,16 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { validateChars } from '../base58/validate';
import { BASE32_ALPHABET } from './bs32';
/**
* @name base32Validate
* @summary Validates a base32 value.
* @description
* Validates the the supplied value is valid base32
*/
export default function base32Validate (value: string): true {
return validateChars('base32', BASE32_ALPHABET, value);
}
+8 -2
View File
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { bufferToU8a } from '@polkadot/util';
import { assert, bufferToU8a } from '@polkadot/util';
import { bs58 } from './bs58';
import validate from './validate';
@@ -13,7 +13,13 @@ import validate from './validate';
* @description
* From the provided input, decode the base58 and return the result as an `Uint8Array`.
*/
export default function base58Decode (value: string): Uint8Array {
export default function base58Decode (value: string, ipfsCompat = false): Uint8Array {
if (ipfsCompat) {
assert(value[0] === 'z', "Expected IPFS base32 identifier 'z' at string start");
value = value.substr(1);
}
validate(value);
return bufferToU8a(bs58.decode(value));
@@ -0,0 +1,17 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { base32Decode } from '../base32';
import { base58Encode } from './';
describe('base58Encode', (): void => {
it('encodes a base32 to a base38', (): void => {
expect(
base58Encode(
base32Decode('bafkreigh2akiscaildcqabsyg3dfr6chu3fgpregiymsck7e7aqa4s52zy', true),
true
)
).toEqual('zb2rhk6GMPQF3hfzwXTaNYFLKomMeC6UXdUt6jZKPpeVirLtV');
});
});
+6 -2
View File
@@ -12,8 +12,12 @@ import { bs58 } from './bs58';
* @description
* From the provided input, create the base58 and return the result as a string.
*/
export default function base58Encode (value: Uint8Array | string | Buffer | number[]): string {
return bs58.encode(
export default function base58Encode (value: Uint8Array | string | Buffer | number[], ipfsCompat = false): string {
const out = bs58.encode(
u8aToBuffer(u8aToU8a(value))
);
return ipfsCompat
? `z${out}`
: out;
}
+11 -7
View File
@@ -4,6 +4,16 @@
import { BASE58_ALPHABET } from './bs58';
export function validateChars (type: string, alphabet: string, value: string): true {
for (let i = 0; i < value.length; i++) {
if (!alphabet.includes(value[i])) {
throw new TypeError(`Invalid ${type} character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
}
}
return true;
}
/**
* @name base58Validate
* @summary Validates a base58 value.
@@ -11,11 +21,5 @@ import { BASE58_ALPHABET } from './bs58';
* Validates the the supplied value is valid base58
*/
export default function base58Validate (value: string): true {
for (let i = 0; i < value.length; i++) {
if (!BASE58_ALPHABET.includes(value[i])) {
throw new TypeError(`Invalid base58 character "${value[i]}" (0x${value.charCodeAt(i).toString(16)}) at index ${i}`);
}
}
return true;
return validateChars('base58', BASE58_ALPHABET, value);
}
+2
View File
@@ -17,8 +17,10 @@ export * from './keccak';
export * from './key';
export * from './mnemonic';
export * from './nacl';
export * from './pbkdf2';
export * from './random';
export * from './schnorrkel';
export * from './scrypt';
export * from './secp256k1';
export * from './sha512';
export * from './signature';
@@ -8,7 +8,7 @@ describe('keyExtractSuri', (): void => {
it('does not extract from invalid suri', (): void => {
expect(
(): ExtractResult => keyExtractSuri('//2')
).toThrow(/to a secret URI/);
).toThrow('Unable to match provided value to a secret URI');
});
it('derives on "hello world"', (): void => {
+1 -1
View File
@@ -22,7 +22,7 @@ export default function keyExtract (suri: string): ExtractResult {
// eslint-disable-next-line @typescript-eslint/prefer-regexp-exec
const matches = suri.match(RE_CAPTURE);
assert(!isNull(matches), `Unable to match '${suri}' to a secret URI`);
assert(!isNull(matches), 'Unable to match provided value to a secret URI');
const [, phrase, , derivePath, , , password] = matches as string[];
const { path } = keyExtractPath(derivePath);
+24
View File
@@ -0,0 +1,24 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { pbkdf2Sync } from 'pbkdf2';
import { bufferToU8a, u8aToBuffer, u8aToU8a } from '@polkadot/util';
import { isReady, pbkdf2 } from '@polkadot/wasm-crypto';
import randomAsU8a from '../random/asU8a';
interface Result {
password: Uint8Array;
rounds: number;
salt: Uint8Array;
}
export default function pbkdf2Encode (passphrase?: Uint8Array | string, salt = randomAsU8a(), rounds = 2048): Result {
const u8a = u8aToU8a(passphrase);
const password = isReady()
? pbkdf2(u8a, salt, rounds)
: bufferToU8a(pbkdf2Sync(u8aToBuffer(u8a), u8aToBuffer(salt), rounds, 64));
return { password, rounds, salt };
}
+5
View File
@@ -0,0 +1,5 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export { default as pbkdf2Encode } from './encode';
@@ -0,0 +1,11 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import '../polyfill';
import { sr25519DerivePublicSoft } from '@polkadot/wasm-crypto';
export default function deriveSoft (publicKey: Uint8Array, chainCode: Uint8Array): Uint8Array {
return sr25519DerivePublicSoft(publicKey, chainCode);
}
@@ -5,6 +5,7 @@
import '../polyfill';
export { default as schnorrkelDeriveHard } from './deriveHard';
export { default as schnorrkelDerivePublic } from './derivePublic';
export { default as schnorrkelDeriveSoft } from './deriveSoft';
export { default as schnorrkelKeypairFromSeed } from './keypair/fromSeed';
export { default as schnorrkelSign } from './sign';
@@ -0,0 +1,11 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
const DEFAULT_PARAMS = {
N: 1 << 15,
p: 1,
r: 8
};
export { DEFAULT_PARAMS };
+28
View File
@@ -0,0 +1,28 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Params } from './types';
import scryptsy from 'scryptsy';
import { bufferToU8a, u8aToBuffer, u8aToU8a } from '@polkadot/util';
import { isReady, scrypt } from '@polkadot/wasm-crypto';
import randomAsU8a from '../random/asU8a';
import { DEFAULT_PARAMS } from './defaults';
interface Result {
params: Params,
password: Uint8Array;
salt: Uint8Array;
}
export default function scryptEncode (passphrase?: Uint8Array | string, salt = randomAsU8a(), params = DEFAULT_PARAMS): Result {
const password = isReady()
? scrypt(u8aToU8a(passphrase), salt, Math.log2(params.N), params.r, params.p)
: bufferToU8a(
scryptsy(u8aToBuffer(u8aToU8a(passphrase)), u8aToBuffer(salt), params.N, params.r, params.p, 64)
);
return { params, password, salt };
}
@@ -0,0 +1,29 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Params } from './types';
import { u8aToBn, assert } from '@polkadot/util';
import { DEFAULT_PARAMS } from './defaults';
interface Result {
params: Params,
salt: Uint8Array;
}
export default function scryptFromU8a (data: Uint8Array): Result {
const salt = data.subarray(0, 32);
const N = u8aToBn(data.subarray(32 + 0, 32 + 4), { isLe: true }).toNumber();
const p = u8aToBn(data.subarray(32 + 4, 32 + 8), { isLe: true }).toNumber();
const r = u8aToBn(data.subarray(32 + 8, 32 + 12), { isLe: true }).toNumber();
// 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
// eat up CPU since these are user inputs. So we need to get very clever here, but atm we only allow the defaults
// and if no match, bail out
assert(N === DEFAULT_PARAMS.N && p === DEFAULT_PARAMS.p && r === DEFAULT_PARAMS.r, 'Invalid injected scrypt params found');
return { params: { N, p, r }, salt };
}
+7
View File
@@ -0,0 +1,7 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export { default as scryptEncode } from './encode';
export { default as scryptFromU8a } from './fromU8a';
export { default as scryptToU8a } from './toU8a';
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
import { Params } from './types';
import { bnToU8a, u8aConcat } from '@polkadot/util';
export default function scryptToU8a (salt: Uint8Array, { N, p, r }: Params): Uint8Array {
return u8aConcat(
salt,
bnToU8a(N, { bitLength: 32, isLe: true }),
bnToU8a(p, { bitLength: 32, isLe: true }),
bnToU8a(r, { bitLength: 32, isLe: true })
);
}
+9
View File
@@ -0,0 +1,9 @@
// Copyright 2017-2020 @polkadot/util-crypto authors & contributors
// This software may be modified and distributed under the terms
// of the Apache-2.0 license. See the LICENSE file for details.
export interface Params {
N: number;
p: number;
r: number;
}
+2 -2
View File
@@ -1,6 +1,6 @@
{
"name": "@polkadot/util",
"version": "2.18.1",
"version": "3.1.1",
"description": "A collection of useful utilities for @polkadot",
"main": "index.js",
"keywords": [
@@ -25,7 +25,7 @@
},
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util#readme",
"dependencies": {
"@babel/runtime": "^7.10.4",
"@babel/runtime": "^7.11.2",
"@types/bn.js": "^4.11.6",
"bn.js": "^5.1.2",
"camelcase": "^5.3.1",
+2799 -2680
View File
File diff suppressed because it is too large Load Diff