init
This commit is contained in:
@@ -0,0 +1,201 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
@@ -0,0 +1,21 @@
|
||||
# @polkadot/util-crypto
|
||||
|
||||
Various useful cyrpto utility functions that are used across all projects in the [@polkadot](https://polkadot.js.org) namespace. It provides utility functions with additional safety checks, allowing not only for consistent coding, but also reducing the general boilerplate.
|
||||
|
||||
## Usage
|
||||
|
||||
Installation -
|
||||
|
||||
```
|
||||
yarn add @polkadot/util-crypto
|
||||
```
|
||||
|
||||
Functions can be imported as follows:
|
||||
|
||||
```js
|
||||
import { mnemonicGenerate } from '@polkadot/util-crypto';
|
||||
```
|
||||
|
||||
## Utilities
|
||||
|
||||
[Utilities](SUMMARY.md)
|
||||
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "@plugnet/util-crypto",
|
||||
"version": "0.76.1",
|
||||
"description": "A collection of useful crypto utilities for @plugnet",
|
||||
"main": "index.js",
|
||||
"keywords": [
|
||||
"Plugnet"
|
||||
],
|
||||
"author": "Jaco Greeff <jacogr@gmail.com>",
|
||||
"maintainers": [
|
||||
"Jaco Greeff <jacogr@gmail.com>"
|
||||
],
|
||||
"contributors": [],
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=6.4"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public",
|
||||
"registry": "https://registry.npmjs.org"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/polkadot-js/common.git"
|
||||
},
|
||||
"bugs": {
|
||||
"url": "https://github.com/polkadot-js/common/issues"
|
||||
},
|
||||
"homepage": "https://github.com/polkadot-js/common/tree/master/packages/util-crypto#readme",
|
||||
"dependencies": {
|
||||
"@babel/runtime": "^7.4.3",
|
||||
"@plugnet/util": "^0.76.1",
|
||||
"@polkadot/wasm-crypto": "^0.8.1",
|
||||
"@types/bip39": "^2.4.2",
|
||||
"@types/pbkdf2": "^3.0.0",
|
||||
"@types/secp256k1": "^3.5.0",
|
||||
"@types/webassembly-js-api": "^0.0.2",
|
||||
"@types/xxhashjs": "^0.2.1",
|
||||
"bip39": "^2.5.0",
|
||||
"blakejs": "^1.1.0",
|
||||
"js-sha3": "^0.8.0",
|
||||
"secp256k1": "^3.6.2",
|
||||
"tweetnacl": "^1.0.1",
|
||||
"xxhashjs": "^0.2.2"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2017-2019 @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 { hexToU8a } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import { blake2AsHex } from '.';
|
||||
|
||||
describe('blake2AsHex', () => {
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
it('returns a 64-bit value (specified)', () => {
|
||||
expect(
|
||||
blake2AsHex('abc', 64)
|
||||
).toEqual('0xd8bb14d833d59559');
|
||||
});
|
||||
|
||||
it('returns a 128-bit value (as specified)', () => {
|
||||
expect(
|
||||
blake2AsHex('abc', 128)
|
||||
).toEqual('0xcf4ab791c62b8d2b2109c90275287816');
|
||||
});
|
||||
|
||||
it('returns a 256-bit value (default)', () => {
|
||||
expect(
|
||||
blake2AsHex('abc')
|
||||
).toEqual('0xbddd813c634239723171ef3fee98579b94964e3bb1cb3e427262c8c068d52319');
|
||||
});
|
||||
|
||||
it('returns a 512-bit value (as specified)', () => {
|
||||
expect(
|
||||
blake2AsHex('abc', 512)
|
||||
).toEqual('0xba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923');
|
||||
});
|
||||
|
||||
it('matches with the Rust implementation', () => {
|
||||
expect(
|
||||
blake2AsHex(
|
||||
hexToU8a('0x454545454545454545454545454545454545454545454545454545454545454501000000000000002481853da20b9f4322f34650fea5f240dcbfb266d02db94bfa0153c31f4a29dbdbf025dd4a69a6f4ee6e1577b251b655097e298b692cb34c18d3182cac3de0dc00000000'), 256
|
||||
)
|
||||
).toEqual('0x1025e5db74fdaf4d2818822dccf0e1604ae9ccc62f26cecfde23448ff0248abf');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @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 { u8aToHex } from '@plugnet/util';
|
||||
|
||||
import blake2AsU8a from './asU8a';
|
||||
|
||||
/**
|
||||
* @name blake2AsHex
|
||||
* @summary Creates a blake2b hex from the input.
|
||||
* @description
|
||||
* From a `Uint8Array` input, create the blake2b and return the result as a hex string with the specified `bitLength`.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { blake2AsHex } from '@plugnet/util-crypto';
|
||||
*
|
||||
* blake2AsHex('abc'); // => 0xba80a53f981c4d0d
|
||||
* ```
|
||||
*/
|
||||
export default function blake2AsHex (data: Uint8Array | string, bitLength: number = 256): string {
|
||||
return u8aToHex(
|
||||
blake2AsU8a(data, bitLength)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
// Copyright 2017-2019 @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 { hexToU8a } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import { blake2AsU8a } from '.';
|
||||
|
||||
describe('blake2AsU8a', () => {
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
it('returns a 64-bit value by default', () => {
|
||||
expect(
|
||||
blake2AsU8a('abc')
|
||||
).toEqual(
|
||||
new Uint8Array([189, 221, 129, 60, 99, 66, 57, 114, 49, 113, 239, 63, 238, 152, 87, 155, 148, 150, 78, 59, 177, 203, 62, 66, 114, 98, 200, 192, 104, 213, 35, 25])
|
||||
);
|
||||
});
|
||||
|
||||
it('returns a 128-bit value (as specified)', () => {
|
||||
expect(
|
||||
blake2AsU8a('abc', 128)
|
||||
).toEqual(
|
||||
new Uint8Array([207, 74, 183, 145, 198, 43, 141, 43, 33, 9, 201, 2, 117, 40, 120, 22])
|
||||
);
|
||||
});
|
||||
|
||||
it('returns a 256-bit value (as specified)', () => {
|
||||
expect(
|
||||
blake2AsU8a('abc', 256)
|
||||
).toEqual(
|
||||
new Uint8Array([189, 221, 129, 60, 99, 66, 57, 114, 49, 113, 239, 63, 238, 152, 87, 155, 148, 150, 78, 59, 177, 203, 62, 66, 114, 98, 200, 192, 104, 213, 35, 25])
|
||||
);
|
||||
});
|
||||
|
||||
it('returns a 512-bit value (as specified)', () => {
|
||||
expect(
|
||||
blake2AsU8a('abc', 512)
|
||||
).toEqual(
|
||||
hexToU8a('0xba80a53f981c4d0d6a2797b69f12f6e94c212f14685ac4b74b12bb6fdbffa2d17d87c5392aab792dc252d5de4533cc9518d38aa8dbf1925ab92386edd4009923')
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2017-2019 @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 blakejs from 'blakejs';
|
||||
import { u8aToU8a } from '@plugnet/util';
|
||||
import { blake2b, isReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name blake2AsU8a
|
||||
* @summary Creates a blake2b u8a from the input.
|
||||
* @description
|
||||
* From a `Uint8Array` input, create the blake2b and return the result as a u8a with the specified `bitLength`.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { blake2AsU8a } from '@plugnet/util-crypto';
|
||||
*
|
||||
* blake2AsU8a('abc'); // => [0xba, 0x80, 0xa53, 0xf98, 0x1c, 0x4d, 0x0d]
|
||||
* ```
|
||||
*/
|
||||
export default function blake2AsU8a (data: Uint8Array | string, bitLength: number = 256, key: Uint8Array | null = null): Uint8Array {
|
||||
const byteLength = Math.ceil(bitLength / 8);
|
||||
|
||||
return isReady()
|
||||
? blake2b(u8aToU8a(data), u8aToU8a(key), byteLength)
|
||||
: blakejs.blake2b(data, key, byteLength);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017-2019 @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 Create blake2b values with specified bitlengths
|
||||
*/
|
||||
|
||||
export { default as blake2AsHex } from './asHex';
|
||||
export { default as blake2AsU8a } from './asU8a';
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2017-2019 @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 wasmCrypto from '@plugnet/wasm-crypto';
|
||||
|
||||
export * from './blake2';
|
||||
export * from './keccak';
|
||||
export * from './key';
|
||||
export * from './mnemonic';
|
||||
export * from './nacl';
|
||||
export * from './random';
|
||||
export * from './schnorrkel';
|
||||
export * from './secp256k1';
|
||||
export * from './sha512';
|
||||
export * from './xxhash';
|
||||
|
||||
export function cryptoWaitReady (): Promise<boolean> {
|
||||
return wasmCrypto
|
||||
.waitReady()
|
||||
.then(() => true)
|
||||
.catch((error) => {
|
||||
console.error('Unable to initialize @polkadot/util-crypto', error);
|
||||
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
// start init process immediately
|
||||
cryptoWaitReady().catch(() => {
|
||||
// shouldn't happen, logged above
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
// Copyright 2017-2019 @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 '@plugnet/wasm-crypto';
|
||||
|
||||
import { keccakAsHex } from '.';
|
||||
|
||||
const value = 'test value';
|
||||
const result = '2d07364b5c231c56ce63d49430e085ea3033c750688ba532b24029124c26ca5e';
|
||||
|
||||
describe('keccakAsHex', () => {
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
it('returns a prefixed hex representation', () => {
|
||||
expect(
|
||||
keccakAsHex(value)
|
||||
).toEqual(`0x${result}`);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @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 { u8aToHex } from '@plugnet/util';
|
||||
|
||||
import keccakAsU8a from './asU8a';
|
||||
|
||||
/**
|
||||
* @name keccakAsHex
|
||||
* @summary Creates a keccak hex string from the input.
|
||||
* @description
|
||||
* From either a `string` or a `Buffer` input, create the keccak and return the result as a `0x` prefixed hex string.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { keccakAsHex } from '@plugnet/util-crypto';
|
||||
*
|
||||
* keccakAsHex('123'); // => 0x...
|
||||
* ```
|
||||
*/
|
||||
export default function keccakAsHex (value: Buffer | Uint8Array | string): string {
|
||||
return u8aToHex(
|
||||
keccakAsU8a(value)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
// Copyright 2017-2019 @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 { hexToU8a, stringToU8a } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import { keccakAsU8a } from '.';
|
||||
|
||||
describe('keccakAsU8a', () => {
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
const input = 'test value';
|
||||
const output = hexToU8a(
|
||||
'0x2d07364b5c231c56ce63d49430e085ea3033c750688ba532b24029124c26ca5e'
|
||||
);
|
||||
|
||||
it('returns an hex representation (string)', () => {
|
||||
expect(
|
||||
keccakAsU8a(input)
|
||||
).toEqual(output);
|
||||
});
|
||||
|
||||
it('returns an hex representation (Buffer)', () => {
|
||||
expect(
|
||||
keccakAsU8a(
|
||||
Buffer.from(input)
|
||||
)
|
||||
).toEqual(output);
|
||||
});
|
||||
|
||||
it('returns an hex representation (Uint8Array)', () => {
|
||||
expect(
|
||||
keccakAsU8a(
|
||||
stringToU8a(input)
|
||||
)
|
||||
).toEqual(output);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,29 @@
|
||||
// Copyright 2017-2019 @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 jssha3 from 'js-sha3';
|
||||
import { u8aToU8a } from '@plugnet/util';
|
||||
import { isReady, keccak256 } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name keccakAsU8a
|
||||
* @summary Creates a keccak Uint8Array from the input.
|
||||
* @description
|
||||
* From either a `string` or a `Buffer` input, create the keccak and return the result as a `Uint8Array`.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { keccakAsU8a } from '@plugnet/util-crypto';
|
||||
*
|
||||
* keccakAsU8a('123'); // => Uint8Array
|
||||
* ```
|
||||
*/
|
||||
export default function keccakAsU8a (value: Buffer | Uint8Array | string): Uint8Array {
|
||||
return isReady()
|
||||
? keccak256(u8aToU8a(value))
|
||||
: new Uint8Array(
|
||||
jssha3.keccak256.update(value).arrayBuffer()
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017-2019 @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 Create Keccak256 values as hex & Uint8Array output
|
||||
*/
|
||||
|
||||
export { default as keccakAsHex } from './asHex';
|
||||
export { default as keccakAsU8a } from './asU8a';
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright 2017-2019 @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 BN from 'bn.js';
|
||||
import { bnToHex, compactAddLength, hexToU8a, isBn, isHex, isNumber, isString, stringToU8a } from '@plugnet/util';
|
||||
|
||||
import blake2AsU8a from '../blake2/asU8a';
|
||||
|
||||
const RE_NUMBER = /^\d+$/;
|
||||
|
||||
const JUNCTION_ID_LEN: number = 32;
|
||||
const BN_OPTIONS = {
|
||||
bitLength: 256,
|
||||
isLe: true
|
||||
};
|
||||
|
||||
export default class DeriveJunction {
|
||||
private _chainCode: Uint8Array = new Uint8Array(32);
|
||||
private _isHard: boolean = false;
|
||||
|
||||
static from (value: string): DeriveJunction {
|
||||
const [code, isHard] = value[0] === '/'
|
||||
? [value.substr(1), true]
|
||||
: [value, false];
|
||||
const result = new DeriveJunction();
|
||||
|
||||
result.soft(
|
||||
RE_NUMBER.test(code)
|
||||
? parseInt(code, 10)
|
||||
: code
|
||||
);
|
||||
|
||||
return isHard
|
||||
? result.harden()
|
||||
: result;
|
||||
}
|
||||
|
||||
get chainCode (): Uint8Array {
|
||||
return this._chainCode;
|
||||
}
|
||||
|
||||
get isHard (): boolean {
|
||||
return this._isHard;
|
||||
}
|
||||
|
||||
get isSoft (): boolean {
|
||||
return !this._isHard;
|
||||
}
|
||||
|
||||
hard (value: number | BN | string | Uint8Array): DeriveJunction {
|
||||
return this.soft(value).harden();
|
||||
}
|
||||
|
||||
harden (): DeriveJunction {
|
||||
this._isHard = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
soft (value: number | BN | string | Uint8Array): DeriveJunction {
|
||||
if (isNumber(value) || isBn(value)) {
|
||||
return this.soft(bnToHex(value, BN_OPTIONS));
|
||||
} else if (isString(value)) {
|
||||
return isHex(value)
|
||||
? this.soft(hexToU8a(value))
|
||||
: this.soft(compactAddLength(stringToU8a(value)));
|
||||
}
|
||||
|
||||
if (value.length > JUNCTION_ID_LEN) {
|
||||
return this.soft(blake2AsU8a(value));
|
||||
}
|
||||
|
||||
this._chainCode.fill(0);
|
||||
this._chainCode.set(value, 0);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
soften (): DeriveJunction {
|
||||
this._isHard = false;
|
||||
|
||||
return this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
// Copyright 2017-2019 @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 keyExtractPath from './extractPath';
|
||||
|
||||
describe('keyExtractPath', () => {
|
||||
it('extracts properly from soft', () => {
|
||||
expect(
|
||||
keyExtractPath('/1')
|
||||
).toEqual({
|
||||
parts: ['/1'],
|
||||
path: [
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('extracts properly from hard', () => {
|
||||
expect(
|
||||
keyExtractPath('//1')
|
||||
).toEqual({
|
||||
parts: ['//1'],
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('extracts properly from hard/soft', () => {
|
||||
expect(
|
||||
keyExtractPath('//1/2')
|
||||
).toEqual({
|
||||
parts: ['//1', '/2'],
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
]
|
||||
});
|
||||
});
|
||||
|
||||
it('does not extract from invalid paths', () => {
|
||||
expect(
|
||||
() => keyExtractPath('1/2')
|
||||
).toThrow(/does not match input/);
|
||||
});
|
||||
|
||||
it('does not extract from invalid paths', () => {
|
||||
expect(
|
||||
() => keyExtractPath('hello')
|
||||
).toThrow(/does not match input/);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2017-2019 @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 DeriveJunction from './DeriveJunction';
|
||||
import { assert } from '@plugnet/util';
|
||||
|
||||
const RE_JUNCTION = /\/(\/?)([^\/]+)/g;
|
||||
|
||||
type ExtractResult = {
|
||||
parts: null | Array<string>,
|
||||
path: Array<DeriveJunction>
|
||||
};
|
||||
|
||||
/**
|
||||
* @description Extract derivation juntions from the supplied path
|
||||
*/
|
||||
export default function keyExtractPath (derivePath: string): ExtractResult {
|
||||
const parts = derivePath.match(RE_JUNCTION);
|
||||
const path: Array<DeriveJunction> = [];
|
||||
let constructed = '';
|
||||
|
||||
if (parts) {
|
||||
constructed = parts.join('');
|
||||
|
||||
parts.forEach((value: string) => {
|
||||
path.push(DeriveJunction.from(value.substr(1)));
|
||||
});
|
||||
}
|
||||
|
||||
assert(constructed === derivePath, `Re-constructed path "${constructed}" does not match input`);
|
||||
|
||||
return {
|
||||
parts,
|
||||
path
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,137 @@
|
||||
// Copyright 2017-2019 @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 keyExtractSuri from './extractSuri';
|
||||
|
||||
describe('keyExtractSuri', () => {
|
||||
it('does not extract from invalid suri', () => {
|
||||
expect(
|
||||
() => keyExtractSuri('//2')
|
||||
).toThrow(/to a secret URI/);
|
||||
});
|
||||
|
||||
it('derives on "hello world"', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world')
|
||||
).toEqual({
|
||||
path: [],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world/1', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world/1')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world/DOT', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world/DOT')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//1', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world//1')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//DOT', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world//DOT')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//1/DOT', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world//1/DOT')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//DOT/1', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world//DOT/1')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world///password"', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world///password')
|
||||
).toEqual({
|
||||
password: 'password',
|
||||
path: [],
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world//1/DOT///password"', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world//1/DOT///password')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
password: 'password',
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on "hello world/1//DOT///password"', () => {
|
||||
expect(
|
||||
keyExtractSuri('hello world/1//DOT///password')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: false, _chainCode: Uint8Array.from([1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) },
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([12, 68, 79, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
password: 'password',
|
||||
phrase: 'hello world'
|
||||
});
|
||||
});
|
||||
|
||||
it('derives on actual Alice', () => {
|
||||
expect(
|
||||
keyExtractSuri('bottom drive obey lake curtain smoke basket hold race lonely fit walk//Alice')
|
||||
).toEqual({
|
||||
path: [
|
||||
{ _isHard: true, _chainCode: Uint8Array.from([20, 65, 108, 105, 99, 101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) }
|
||||
],
|
||||
phrase: 'bottom drive obey lake curtain smoke basket hold race lonely fit walk'
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright 2017-2019 @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 { assert, isNull } from '@plugnet/util';
|
||||
|
||||
import DeriveJunction from './DeriveJunction';
|
||||
import keyExtractPath from './extractPath';
|
||||
|
||||
type ExtractResult = {
|
||||
password?: string,
|
||||
path: Array<DeriveJunction>,
|
||||
phrase: string
|
||||
};
|
||||
|
||||
const RE_CAPTURE = /^(\w+( \w+)*)((\/\/?[^\/]+)*)(\/\/\/(.*))?$/;
|
||||
|
||||
/**
|
||||
* @description Extracts the phrase, path and password from a SURI format for specifying secret keys `<secret>/<soft-key>//<hard-key>///<password>` (the `///password` may be omitted, and `/<soft-key>` and `//<hard-key>` maybe repeated and mixed).
|
||||
*/
|
||||
export default function keyExtract (suri: string): ExtractResult {
|
||||
const matches = suri.match(RE_CAPTURE);
|
||||
|
||||
assert(!isNull(matches), `Unable to match '${suri}' to a secret URI`);
|
||||
|
||||
const [, phrase, , derivePath, , , password] = matches as Array<string>;
|
||||
const { path } = keyExtractPath(derivePath);
|
||||
|
||||
return {
|
||||
password,
|
||||
path,
|
||||
phrase
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2017-2019 @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 { KeypairType, Keypair } from '../types';
|
||||
|
||||
import DeriveJunction from './DeriveJunction';
|
||||
import keyHdkdEd15519 from './hdkdEd25519';
|
||||
import keyHdkdSr15519 from './hdkdSr25519';
|
||||
|
||||
export default function keyFromPath (pair: Keypair, path: Array<DeriveJunction>, type: KeypairType): Keypair {
|
||||
const isEd25519 = type === 'ed25519';
|
||||
|
||||
return path.reduce((pair, junction) => {
|
||||
return isEd25519
|
||||
? keyHdkdEd15519(pair, junction)
|
||||
: keyHdkdSr15519(pair, junction);
|
||||
}, pair);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../types';
|
||||
|
||||
import { assert } from '@plugnet/util';
|
||||
|
||||
import naclDeriveHard from '../nacl/deriveHard';
|
||||
import naclKeypairFromSeed from '../nacl/keypair/fromSeed';
|
||||
import DeriveJunction from './DeriveJunction';
|
||||
|
||||
export default function keyHdkdEd25519 (keypair: Keypair, { chainCode, isHard }: DeriveJunction): Keypair {
|
||||
assert(isHard, 'A soft key was found in the path (and is unsupported)');
|
||||
|
||||
return naclKeypairFromSeed(
|
||||
naclDeriveHard(keypair.secretKey.subarray(0, 32), chainCode)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../types';
|
||||
|
||||
import schnorrkelDeriveHard from '../schnorrkel/deriveHard';
|
||||
import schnorrkelDeriveSoft from '../schnorrkel/deriveSoft';
|
||||
import DeriveJunction from './DeriveJunction';
|
||||
|
||||
export default function keyHdkdSr25519 (keypair: Keypair, { chainCode, isSoft }: DeriveJunction): Keypair {
|
||||
return isSoft
|
||||
? schnorrkelDeriveSoft(keypair, chainCode)
|
||||
: schnorrkelDeriveHard(keypair, chainCode);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
// Copyright 2017-2019 @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 Create keys from paths, seeds and password
|
||||
*/
|
||||
export { default as keyExtractPath } from './extractPath';
|
||||
export { default as keyExtractSuri } from './extractSuri';
|
||||
export { default as keyFromPath } from './fromPath';
|
||||
export { default as keyHdkdEd25519 } from './hdkdEd25519';
|
||||
export { default as keyHdkdSr25519 } from './hdkdEd25519';
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2017-2019 @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 generate from './generate';
|
||||
import validate from './validate';
|
||||
import { cryptoWaitReady } from '..';
|
||||
|
||||
describe('mnemonicGenerate', () => {
|
||||
beforeEach(async () => {
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
|
||||
it('generates a valid mnemonic (default strength)', () => {
|
||||
const mnemonic = generate();
|
||||
|
||||
console.error(mnemonic);
|
||||
|
||||
expect(
|
||||
validate(mnemonic)
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
[12, 15, 18, 21, 24].forEach((num) => {
|
||||
it(`generates a valid mnemonic (${num} words)`, () => {
|
||||
const mnemonic = generate(num as any);
|
||||
const isValid = validate(mnemonic);
|
||||
|
||||
console.error(mnemonic);
|
||||
|
||||
expect(mnemonic.split(' ')).toHaveLength(num);
|
||||
expect(isValid).toEqual(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2017-2019 @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 { generateMnemonic } from 'bip39';
|
||||
import { bip39Generate, isReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
type WordCount = 12 | 15 | 18 | 21 | 24;
|
||||
|
||||
// mapping of words to the actual strength (as expected)
|
||||
const STRENGTH_MAP = {
|
||||
12: 16 * 8,
|
||||
15: 20 * 8,
|
||||
18: 24 * 8,
|
||||
21: 28 * 8,
|
||||
24: 32 * 8
|
||||
};
|
||||
|
||||
/**
|
||||
* @name mnemonicGenerate
|
||||
* @summary Creates a valid mnemonic string using using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { mnemonicGenerate } from '@plugnet/util-crypto';
|
||||
*
|
||||
* const mnemonic = mnemonicGenerate(); // => string
|
||||
* ```
|
||||
*/
|
||||
export default function mnemonicGenerate (numWords: WordCount = 12): string {
|
||||
return isReady()
|
||||
? bip39Generate(numWords)
|
||||
: generateMnemonic(STRENGTH_MAP[numWords]);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2019 @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';
|
||||
|
||||
/**
|
||||
* @summary Create valid mnemonic strings, validate them using BIP39, and convert them to valid seeds
|
||||
*/
|
||||
|
||||
export { default as mnemonicGenerate } from './generate';
|
||||
export { default as mnemonicToEntropy } from './toEntropy';
|
||||
export { default as mnemonicToMiniSecret } from './toMiniSecret';
|
||||
export { default as mnemonicToSeed } from './toSeed';
|
||||
export { default as mnemonicValidate } from './validate';
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright 2017-2019 @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 { u8aToHex } from '@plugnet/util';
|
||||
|
||||
import toEntropy from './toEntropy';
|
||||
import tests from '../schnorrkel/keypair/testing';
|
||||
import { cryptoWaitReady } from '..';
|
||||
|
||||
describe('mnemonicToEntropy', () => {
|
||||
beforeEach(async () => {
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
|
||||
tests.forEach(([mnemonic, entropy], index) => {
|
||||
it(`Created correct entropy for ${index}`, () => {
|
||||
expect(u8aToHex(toEntropy(mnemonic))).toEqual(entropy);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2017-2019 @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 { mnemonicToEntropy } from 'bip39';
|
||||
import { hexAddPrefix, hexToU8a } from '@plugnet/util';
|
||||
import { bip39ToEntropy, isReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
export default function toEntropy (mnemonic: string): Uint8Array {
|
||||
return isReady()
|
||||
? bip39ToEntropy(mnemonic)
|
||||
: hexToU8a(
|
||||
hexAddPrefix(
|
||||
mnemonicToEntropy(mnemonic)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2017-2019 @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 { u8aToHex } from '@plugnet/util';
|
||||
|
||||
import mnemonicToMiniSecret from './toMiniSecret';
|
||||
import tests from '../schnorrkel/keypair/testing';
|
||||
import { cryptoWaitReady } from '..';
|
||||
|
||||
describe('mnemonicToMiniSecret', () => {
|
||||
beforeEach(async () => {
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
|
||||
it('generates a valid seed', () => {
|
||||
expect(
|
||||
u8aToHex(mnemonicToMiniSecret('seed sock milk update focus rotate barely fade car face mechanic mercy'))
|
||||
).toEqual('0x4d1ab2a57929edfd018aaa974e62ed557e3f54b4104acabedf73c8f5a1dbb029');
|
||||
});
|
||||
|
||||
tests.forEach(([mnemonic, , seed], index) => {
|
||||
it(`Created correct seed for ${index}`, () => {
|
||||
expect(
|
||||
u8aToHex(mnemonicToMiniSecret(mnemonic, 'Substrate'))
|
||||
).toEqual(
|
||||
// mini returned here, only check first 32-bytes (64 hex + 2 prefix)
|
||||
seed.substr(0, 66)
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017-2019 @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 { pbkdf2Sync } from 'pbkdf2';
|
||||
import { bufferToU8a, stringToU8a, u8aToBuffer } from '@plugnet/util';
|
||||
import { bip39ToMiniSecret, isReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import toEntropy from './toEntropy';
|
||||
|
||||
export default function toMiniSecret (mnemonic: string, password: string = ''): Uint8Array {
|
||||
if (isReady()) {
|
||||
return bip39ToMiniSecret(mnemonic, password);
|
||||
}
|
||||
|
||||
const entropy = u8aToBuffer(toEntropy(mnemonic));
|
||||
const salt = u8aToBuffer(stringToU8a(`mnemonic${password}`));
|
||||
|
||||
// return the first 32 bytes as the seed
|
||||
return bufferToU8a(
|
||||
pbkdf2Sync(entropy, salt, 2048, 64, 'sha512')
|
||||
).slice(0, 32);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2019 @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 { u8aToHex } from '@plugnet/util';
|
||||
|
||||
import toSeed from './toSeed';
|
||||
|
||||
describe('mnemonicToSeed', () => {
|
||||
it('generates a valid seed', () => {
|
||||
expect(
|
||||
u8aToHex(toSeed('seed sock milk update focus rotate barely fade car face mechanic mercy'))
|
||||
).toEqual('0x3c121e20de068083b49c2315697fb59a2d9e8643c24e5ea7628132c58969a027');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2019 @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 { mnemonicToSeed } from 'bip39';
|
||||
import { bufferToU8a } from '@plugnet/util';
|
||||
import { bip39ToSeed, isReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name toSeed
|
||||
* @summary Creates a valid seed from a mnemonic input
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { mnemonicGenerate, mnemonicToSeed, mnemonicValidate } from '@plugnet/util-crypto';
|
||||
*
|
||||
* const mnemonic = mnemonicGenerate(); // => string
|
||||
* const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean
|
||||
*
|
||||
* if (isValidMnemonic) {
|
||||
* console.log(`Seed generated from mnemonic: ${mnemonicToSeed(mnemonic)}`); => u8a
|
||||
* }
|
||||
* ```
|
||||
*/
|
||||
export default function toSeed (mnemonic: string, password: string = ''): Uint8Array {
|
||||
return isReady()
|
||||
? bip39ToSeed(mnemonic, password)
|
||||
: bufferToU8a(mnemonicToSeed(mnemonic, password)).subarray(0, 32);
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
// Copyright 2017-2019 @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 validate from './validate';
|
||||
import { cryptoWaitReady } from '..';
|
||||
|
||||
describe('mnemonicValidate', () => {
|
||||
beforeEach(async () => {
|
||||
await cryptoWaitReady();
|
||||
});
|
||||
|
||||
it('returns true on valid', () => {
|
||||
expect(
|
||||
validate('seed sock milk update focus rotate barely fade car face mechanic mercy')
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('returns false on invalid', () => {
|
||||
expect(
|
||||
validate('wine photo extra cushion basket dwarf humor cloud truck job boat submit')
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @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 { validateMnemonic } from 'bip39';
|
||||
import { bip39Validate, isReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name mnemonicValidate
|
||||
* @summary Validates a mnemonic input using [BIP39](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki).
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { mnemonicGenerate, mnemonicValidate } from '@plugnet/util-crypto';
|
||||
*
|
||||
* const mnemonic = mnemonicGenerate(); // => string
|
||||
* const isValidMnemonic = mnemonicValidate(mnemonic); // => boolean
|
||||
* ```
|
||||
*/
|
||||
export default function mnemonicValidate (mnemonic: string): boolean {
|
||||
return isReady()
|
||||
? bip39Validate(mnemonic)
|
||||
: validateMnemonic(mnemonic);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017-2019 @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 { naclDecrypt, naclEncrypt } from '.';
|
||||
|
||||
describe('naclDecrypt', () => {
|
||||
it('decrypts a encrypted message', () => {
|
||||
const secret = new Uint8Array(32);
|
||||
const message = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
|
||||
const { encrypted, nonce } = naclEncrypt(message, secret);
|
||||
|
||||
expect(
|
||||
naclDecrypt(encrypted, nonce, secret)
|
||||
).toEqual(
|
||||
message
|
||||
);
|
||||
});
|
||||
|
||||
it('returns null on invalid', () => {
|
||||
expect(
|
||||
naclDecrypt(new Uint8Array(), new Uint8Array(24), new Uint8Array(32))
|
||||
).toEqual(null);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright 2017-2019 @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 nacl from 'tweetnacl';
|
||||
|
||||
/**
|
||||
* @name naclDecrypt
|
||||
* @summary Decrypts a message using the supplied secretKey and nonce
|
||||
* @description
|
||||
* Returns an decrypted message, using the `secret` and `nonce`.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { naclDecrypt } from '@plugnet/util-crypto';
|
||||
*
|
||||
* naclDecrypt([...], [...], [...]); // => [...]
|
||||
* ```
|
||||
*/
|
||||
export default function naclDecrypt (encrypted: Uint8Array, nonce: Uint8Array, secret: Uint8Array): Uint8Array | null {
|
||||
return nacl.secretbox.open(encrypted, nonce, secret) || null;
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2019 @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 { compactAddLength, stringToU8a, u8aConcat } from '@plugnet/util';
|
||||
|
||||
import blake2AsU8a from '../blake2/asU8a';
|
||||
|
||||
const HDKD = compactAddLength(stringToU8a('Ed25519HDKD'));
|
||||
|
||||
export default function deriveHard (seed: Uint8Array, chainCode: Uint8Array): Uint8Array {
|
||||
return blake2AsU8a(
|
||||
u8aConcat(HDKD, seed, chainCode)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
// Copyright 2017-2019 @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 { naclEncrypt } from '.';
|
||||
|
||||
describe('naclEncrypt', () => {
|
||||
it('encrypts a message', () => {
|
||||
const secret = new Uint8Array(32);
|
||||
const message = new Uint8Array([1, 2, 3, 4, 5, 4, 3, 2, 1]);
|
||||
|
||||
expect(
|
||||
naclEncrypt(message, secret, new Uint8Array(24))
|
||||
).toEqual({
|
||||
encrypted: new Uint8Array([94, 21, 20, 69, 68, 221, 140, 245, 200, 67, 77, 188, 129, 85, 227, 141, 199, 60, 184, 251, 251, 129, 205, 46, 234]),
|
||||
nonce: new Uint8Array(24)
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2017-2019 @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 nacl from 'tweetnacl';
|
||||
|
||||
import randomAsU8a from '../random/asU8a';
|
||||
|
||||
type Encrypted = {
|
||||
encrypted: Uint8Array,
|
||||
nonce: Uint8Array
|
||||
};
|
||||
|
||||
/**
|
||||
* @name naclEncrypt
|
||||
* @summary Encrypts a message using the supplied secretKey and nonce
|
||||
* @description
|
||||
* Returns an encrypted message, using the `secretKey` and `nonce`. If the `nonce` was not supplied, a random value is generated.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { naclEncrypt } from '@plugnet/util-crypto';
|
||||
*
|
||||
* naclEncrypt([...], [...]); // => [...]
|
||||
* ```
|
||||
*/
|
||||
export default function naclEncrypt (message: Uint8Array, secret: Uint8Array, nonce: Uint8Array = randomAsU8a(24)): Encrypted {
|
||||
return {
|
||||
encrypted: nacl.secretbox(message, nonce, secret),
|
||||
nonce
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2017-2019 @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 Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption, hashing, and public-key signatures
|
||||
*/
|
||||
export { default as naclDecrypt } from './decrypt';
|
||||
export { default as deriveHard } from './deriveHard';
|
||||
export { default as naclEncrypt } from './encrypt';
|
||||
export { default as naclKeypairFromRandom } from './keypair/fromRandom';
|
||||
export { default as naclKeypairFromSecret } from './keypair/fromSecret';
|
||||
export { default as naclKeypairFromSeed } from './keypair/fromSeed';
|
||||
export { default as naclKeypairFromString } from './keypair/fromString';
|
||||
export { default as naclSign } from './sign';
|
||||
export { default as naclVerify } from './verify';
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../../types';
|
||||
|
||||
import { naclKeypairFromRandom } from '..';
|
||||
|
||||
describe('naclKeypairFromRandom', () => {
|
||||
let keypair: Keypair;
|
||||
|
||||
beforeEach(() => {
|
||||
keypair = naclKeypairFromRandom();
|
||||
});
|
||||
|
||||
it('generates a valid publicKey', () => {
|
||||
expect(
|
||||
keypair.publicKey
|
||||
).toHaveLength(32);
|
||||
});
|
||||
|
||||
it('generates a valid secretKey', () => {
|
||||
expect(
|
||||
keypair.secretKey
|
||||
).toHaveLength(64);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../../types';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
|
||||
/**
|
||||
* @name naclKeypairFromRandom
|
||||
* @summary Creates a new public/secret keypair.
|
||||
* @description
|
||||
* Returns a new generate object containing a `publicKey` & `secretKey`.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { naclKeypairFromRandom } from '@plugnet/util-crypto';
|
||||
*
|
||||
* naclKeypairFromRandom(); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export default function naclKeypairFromRandom (): Keypair {
|
||||
return nacl.sign.keyPair();
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2017-2019 @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 { naclKeypairFromSecret } from '..';
|
||||
|
||||
describe('naclKeypairFromSecret', () => {
|
||||
const secretKey = new Uint8Array([
|
||||
18, 52, 86, 120, 144, 18, 52, 86,
|
||||
120, 144, 18, 52, 86, 120, 144, 18,
|
||||
18, 52, 86, 120, 144, 18, 52, 86,
|
||||
120, 144, 18, 52, 86, 120, 144, 18,
|
||||
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
|
||||
]);
|
||||
|
||||
it('generates a valid publicKey/secretKey pair', () => {
|
||||
expect(
|
||||
naclKeypairFromSecret(secretKey)
|
||||
).toEqual({
|
||||
publicKey: 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
|
||||
]),
|
||||
secretKey
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../../types';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
|
||||
/**
|
||||
* @name naclKeypairFromSecret
|
||||
* @summary Creates a new public/secret keypair from a secret.
|
||||
* @description
|
||||
* Returns a object containing a `publicKey` & `secretKey` generated from the supplied secret.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { naclKeypairFromSecret } from '@plugnet/util-crypto';
|
||||
*
|
||||
* naclKeypairFromSecret(...); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export default function naclKeypairFromSecret (secret: Uint8Array): Keypair {
|
||||
return nacl.sign.keyPair.fromSecretKey(secret);
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2017-2019 @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 { stringToU8a } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import { naclKeypairFromSeed } from '..';
|
||||
|
||||
describe('naclKeypairFromSeed', () => {
|
||||
// NOTE: Aligned with Rust test, b"12345678901234567890123456789012"
|
||||
const TEST = stringToU8a('12345678901234567890123456789012');
|
||||
const RESULT = {
|
||||
publicKey: new Uint8Array([
|
||||
0x2f, 0x8c, 0x61, 0x29, 0xd8, 0x16, 0xcf, 0x51,
|
||||
0xc3, 0x74, 0xbc, 0x7f, 0x08, 0xc3, 0xe6, 0x3e,
|
||||
0xd1, 0x56, 0xcf, 0x78, 0xae, 0xfb, 0x4a, 0x65,
|
||||
0x50, 0xd9, 0x7b, 0x87, 0x99, 0x79, 0x77, 0xee
|
||||
]),
|
||||
secretKey: new Uint8Array([
|
||||
49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50,
|
||||
// public part
|
||||
0x2f, 0x8c, 0x61, 0x29, 0xd8, 0x16, 0xcf, 0x51,
|
||||
0xc3, 0x74, 0xbc, 0x7f, 0x08, 0xc3, 0xe6, 0x3e,
|
||||
0xd1, 0x56, 0xcf, 0x78, 0xae, 0xfb, 0x4a, 0x65,
|
||||
0x50, 0xd9, 0x7b, 0x87, 0x99, 0x79, 0x77, 0xee
|
||||
])
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
it('generates a valid publicKey/secretKey pair (u8a)', () => {
|
||||
expect(
|
||||
naclKeypairFromSeed(TEST)
|
||||
).toEqual(RESULT);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../../types';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
import { isReady, ed25519KeypairFromSeed } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name naclKeypairFromSeed
|
||||
* @summary Creates a new public/secret keypair from a seed.
|
||||
* @description
|
||||
* Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { naclKeypairFromSeed } from '@plugnet/util-crypto';
|
||||
*
|
||||
* naclKeypairFromSeed(...); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export default function naclKeypairFromSeed (seed: Uint8Array): Keypair {
|
||||
if (isReady()) {
|
||||
const full = ed25519KeypairFromSeed(seed);
|
||||
|
||||
return {
|
||||
publicKey: full.slice(32),
|
||||
secretKey: full.slice(0, 64)
|
||||
};
|
||||
}
|
||||
|
||||
return nacl.sign.keyPair.fromSeed(seed);
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2017-2019 @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 { naclKeypairFromString } from '..';
|
||||
|
||||
describe('naclKeypairFromSeed', () => {
|
||||
it('generates a valid publicKey/secretKey pair', () => {
|
||||
expect(
|
||||
naclKeypairFromString('test')
|
||||
).toEqual({
|
||||
publicKey: new Uint8Array([188, 108, 179, 142, 36, 142, 76, 87, 77, 193, 147, 139, 254, 110, 196, 217, 117, 233, 167, 165, 250, 150, 247, 237, 198, 68, 129, 4, 211, 209, 136, 48]),
|
||||
secretKey: new Uint8Array([146, 139, 32, 54, 105, 67, 226, 175, 209, 30, 188, 14, 174, 46, 83, 169, 59, 241, 119, 164, 252, 243, 91, 204, 100, 213, 3, 112, 78, 101, 226, 2, 188, 108, 179, 142, 36, 142, 76, 87, 77, 193, 147, 139, 254, 110, 196, 217, 117, 233, 167, 165, 250, 150, 247, 237, 198, 68, 129, 4, 211, 209, 136, 48])
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../../types';
|
||||
|
||||
import { stringToU8a } from '@plugnet/util';
|
||||
|
||||
import blake2AsU8a from '../../blake2/asU8a';
|
||||
import fromSeed from './fromSeed';
|
||||
|
||||
/**
|
||||
* @name naclKeypairFromString
|
||||
* @summary Creates a new public/secret keypair from a string.
|
||||
* @description
|
||||
* Returns a object containing a `publicKey` & `secretKey` generated from the supplied string. The string is hashed and the value used as the input seed.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { naclKeypairFromString } from '@plugnet/util-crypto';
|
||||
*
|
||||
* naclKeypairFromString('test'); // => { secretKey: [...], publicKey: [...] }
|
||||
* ```
|
||||
*/
|
||||
export default function naclKeypairFromString (value: string): Keypair {
|
||||
return fromSeed(
|
||||
blake2AsU8a(
|
||||
stringToU8a(value),
|
||||
256
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @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 { stringToU8a } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import { naclSign, naclKeypairFromSeed } from '.';
|
||||
|
||||
describe('naclSign', () => {
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
it('returns a valid signature for the message', () => {
|
||||
expect(
|
||||
naclSign(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
||||
naclKeypairFromSeed(
|
||||
stringToU8a('12345678901234567890123456789012')
|
||||
)
|
||||
)
|
||||
).toEqual(
|
||||
new Uint8Array([28, 58, 206, 239, 249, 70, 59, 191, 166, 40, 219, 218, 235, 170, 25, 79, 10, 94, 9, 197, 34, 126, 1, 150, 246, 68, 28, 238, 36, 26, 172, 163, 168, 90, 202, 211, 126, 246, 57, 212, 43, 24, 88, 197, 240, 113, 118, 76, 37, 81, 91, 110, 236, 50, 144, 134, 100, 223, 220, 238, 34, 185, 211, 7])
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../types';
|
||||
|
||||
import nacl from 'tweetnacl';
|
||||
import { assert } from '@plugnet/util';
|
||||
import { isReady, ed25519Sign } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name naclSign
|
||||
* @summary Signs a message using the supplied secretKey
|
||||
* @description
|
||||
* Returns message signature of `message`, using the `secretKey`.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { naclSign } from '@plugnet/util-crypto';
|
||||
*
|
||||
* naclSign([...], [...]); // => [...]
|
||||
* ```
|
||||
*/
|
||||
export default function naclSign (message: Uint8Array, { publicKey, secretKey }: Partial<Keypair>): Uint8Array {
|
||||
assert(secretKey, 'Expected valid secretKey');
|
||||
|
||||
return isReady()
|
||||
? ed25519Sign(publicKey as Uint8Array, (secretKey as Uint8Array).subarray(0, 32), message)
|
||||
: nacl.sign.detached(message, secretKey as Uint8Array);
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
// Copyright 2017-2019 @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 { stringToU8a } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import { naclVerify, naclKeypairFromSeed } from '.';
|
||||
|
||||
describe('naclSign', () => {
|
||||
let publicKey: Uint8Array;
|
||||
let signature: Uint8Array;
|
||||
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
|
||||
publicKey = naclKeypairFromSeed(
|
||||
stringToU8a('12345678901234567890123456789012')
|
||||
).publicKey;
|
||||
signature = new Uint8Array([28, 58, 206, 239, 249, 70, 59, 191, 166, 40, 219, 218, 235, 170, 25, 79, 10, 94, 9, 197, 34, 126, 1, 150, 246, 68, 28, 238, 36, 26, 172, 163, 168, 90, 202, 211, 126, 246, 57, 212, 43, 24, 88, 197, 240, 113, 118, 76, 37, 81, 91, 110, 236, 50, 144, 134, 100, 223, 220, 238, 34, 185, 211, 7]);
|
||||
});
|
||||
|
||||
it('validates a correctly signed message', () => {
|
||||
expect(
|
||||
naclVerify(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
||||
signature,
|
||||
publicKey
|
||||
)
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('fails a correctly signed message (message changed)', () => {
|
||||
expect(
|
||||
naclVerify(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64, 0x65]),
|
||||
signature,
|
||||
publicKey
|
||||
)
|
||||
).toEqual(false);
|
||||
});
|
||||
|
||||
it('fails a correctly signed message (signature changed)', () => {
|
||||
signature[0] = 0xff;
|
||||
|
||||
expect(
|
||||
naclVerify(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
||||
signature,
|
||||
publicKey
|
||||
)
|
||||
).toEqual(false);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017-2019 @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 nacl from 'tweetnacl';
|
||||
import { isReady, ed25519Verify } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name naclSign
|
||||
* @summary Verifies the signature on the supplied message.
|
||||
* @description
|
||||
* Verifies the `signature` on `message` with the supplied `plublicKey`. Returns `true` on sucess, `false` otherwise.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { naclVerify } from '@plugnet/util-crypto';
|
||||
*
|
||||
* naclVerify([...], [...], [...]); // => true/false
|
||||
* ```
|
||||
*/
|
||||
export default function naclVerify (message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean {
|
||||
return isReady()
|
||||
? ed25519Verify(signature, message, publicKey)
|
||||
: nacl.sign.detached.verify(message, signature, publicKey);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2017-2019 @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 '@polkadot/wasm-crypto/crypto-polyfill';
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2017-2019 @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 { isHex } from '@plugnet/util';
|
||||
|
||||
import { randomAsHex } from '.';
|
||||
|
||||
describe('randomAsBuffer', () => {
|
||||
it('generated results does not match', () => {
|
||||
expect(
|
||||
randomAsHex()
|
||||
).not.toEqual(
|
||||
randomAsHex()
|
||||
);
|
||||
});
|
||||
|
||||
it('is a valid hex number', () => {
|
||||
expect(
|
||||
isHex(
|
||||
randomAsHex()
|
||||
)
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('generates 32 bytes by default', () => {
|
||||
expect(
|
||||
randomAsHex()
|
||||
).toHaveLength(32 * 2 + 2);
|
||||
});
|
||||
|
||||
it('generates with the supplied length', () => {
|
||||
expect(
|
||||
randomAsHex(66)
|
||||
).toHaveLength(66 * 2 + 2);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @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 { u8aToHex } from '@plugnet/util';
|
||||
|
||||
import randomAsU8a from './asU8a';
|
||||
|
||||
/**
|
||||
* @name randomAsHex
|
||||
* @summary Creates a hex string filled with random bytes.
|
||||
* @description
|
||||
* Returns a hex string with the specified (optional) length filled with random bytes.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { randomAsHex } from '@plugnet/util-crypto';
|
||||
*
|
||||
* randomAsHex(); // => 0x...
|
||||
* ```
|
||||
*/
|
||||
export default function randomAsHex (length: number = 32): string {
|
||||
return u8aToHex(
|
||||
randomAsU8a(length)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2019 @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 { randomAsNumber } from '.';
|
||||
|
||||
describe('randomAsNumber', () => {
|
||||
it('generates subsequent non-matching numbers', () => {
|
||||
expect(
|
||||
randomAsNumber()
|
||||
).not.toEqual(
|
||||
randomAsNumber()
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
// Copyright 2017-2019 @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 BN from 'bn.js';
|
||||
import { hexToBn } from '@plugnet/util';
|
||||
|
||||
import randomAsHex from './asHex';
|
||||
|
||||
const BN_53 = new BN(0b11111111111111111111111111111111111111111111111111111);
|
||||
|
||||
/**
|
||||
* @name randomAsNumber
|
||||
* @summary Creates a random number from random bytes.
|
||||
* @description
|
||||
* Returns a random number generated from the secure bytes.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { randomAsNumber } from '@plugnet/util-crypto';
|
||||
*
|
||||
* randomAsNumber(); // => <random number>
|
||||
* ```
|
||||
*/
|
||||
export default function randomAsNumber (): number {
|
||||
return hexToBn(
|
||||
randomAsHex(8)
|
||||
).and(BN_53).toNumber();
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
// Copyright 2017-2019 @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 { isU8a } from '@plugnet/util';
|
||||
|
||||
import { randomAsU8a } from '.';
|
||||
|
||||
describe('randomAsU8a', () => {
|
||||
it('generates a Uint8Array', () => {
|
||||
expect(
|
||||
isU8a(randomAsU8a())
|
||||
).toEqual(true);
|
||||
});
|
||||
|
||||
it('generated results does not match', () => {
|
||||
expect(
|
||||
randomAsU8a()
|
||||
).not.toEqual(
|
||||
randomAsU8a()
|
||||
);
|
||||
});
|
||||
|
||||
it('generates 32 bytes by default', () => {
|
||||
expect(
|
||||
randomAsU8a()
|
||||
).toHaveLength(32);
|
||||
});
|
||||
|
||||
it('generates with the suuplied length', () => {
|
||||
expect(
|
||||
randomAsU8a(66)
|
||||
).toHaveLength(66);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright 2017-2019 @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 nacl from 'tweetnacl';
|
||||
|
||||
/**
|
||||
* @name randomAsU8a
|
||||
* @summary Creates a Uint8Array filled with random bytes.
|
||||
* @description
|
||||
* Returns a `Uint8Array` with the specified (optional) length filled with random bytes.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { randomAsU8a } from '@plugnet/util-crypto';
|
||||
*
|
||||
* randomAsU8a(); // => Uint8Array([...])
|
||||
* ```
|
||||
*/
|
||||
export default function randomAsU8a (length: number = 32): Uint8Array {
|
||||
return nacl.randomBytes(length);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017-2019 @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 Returns a sequence of secure random bytes in a variety of formats
|
||||
*/
|
||||
|
||||
export { default as randomAsHex } from './asHex';
|
||||
export { default as randomAsNumber } from './asNumber';
|
||||
export { default as randomAsU8a } from './asU8a';
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../types';
|
||||
|
||||
import '../polyfill';
|
||||
|
||||
import { sr25519DeriveKeypairHard } from '@plugnet/wasm-crypto';
|
||||
|
||||
import keypairFromU8a from './keypair/fromU8a';
|
||||
import keypairToU8a from './keypair/toU8a';
|
||||
|
||||
export default function deriveHard (keypair: Keypair, chainCode: Uint8Array): Keypair {
|
||||
return keypairFromU8a(
|
||||
sr25519DeriveKeypairHard(keypairToU8a(keypair), chainCode)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../types';
|
||||
|
||||
import '../polyfill';
|
||||
|
||||
import { sr25519DeriveKeypairSoft } from '@plugnet/wasm-crypto';
|
||||
|
||||
import keypairFromU8a from './keypair/fromU8a';
|
||||
import keypairToU8a from './keypair/toU8a';
|
||||
|
||||
export default function deriveSoft (keypair: Keypair, chainCode: Uint8Array): Keypair {
|
||||
return keypairFromU8a(
|
||||
sr25519DeriveKeypairSoft(keypairToU8a(keypair), chainCode)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017-2019 @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';
|
||||
|
||||
export { default as schnorrkelDeriveHard } from './deriveHard';
|
||||
export { default as schnorrkelDeriveSoft } from './deriveSoft';
|
||||
export { default as schnorrkelKeypairFromSeed } from './keypair/fromSeed';
|
||||
export { default as schnorrkelSign } from './sign';
|
||||
export { default as schnorrkelVerify } from './verify';
|
||||
@@ -0,0 +1,39 @@
|
||||
// Copyright 2017-2019 @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 { stringToU8a, u8aToHex } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import { mnemonicToMiniSecret } from '../../mnemonic';
|
||||
import { schnorrkelKeypairFromSeed } from '..';
|
||||
import tests from './testing';
|
||||
|
||||
describe('schnorrkelKeypairFromSeed', () => {
|
||||
const TEST = stringToU8a('12345678901234567890123456789012');
|
||||
const RESULT = {
|
||||
publicKey: new Uint8Array([116, 28, 8, 160, 111, 65, 197, 150, 96, 143, 103, 116, 37, 155, 217, 4, 51, 4, 173, 250, 93, 62, 234, 98, 118, 11, 217, 190, 151, 99, 77, 99]),
|
||||
secretKey: new Uint8Array([240, 16, 102, 96, 195, 221, 162, 63, 22, 218, 169, 172, 91, 129, 27, 150, 48, 119, 245, 188, 10, 248, 159, 133, 128, 79, 13, 232, 228, 36, 240, 80, 249, 141, 102, 243, 148, 66, 80, 111, 249, 71, 253, 145, 31, 24, 199, 167, 165, 218, 99, 154, 99, 232, 211, 180, 226, 51, 247, 65, 67, 217, 81, 193])
|
||||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
return waitReady();
|
||||
});
|
||||
|
||||
it('generates a valid publicKey/secretKey pair (u8a)', () => {
|
||||
expect(
|
||||
schnorrkelKeypairFromSeed(TEST)
|
||||
).toEqual(RESULT);
|
||||
});
|
||||
|
||||
tests.forEach(([mnemonic, , , secret], index) => {
|
||||
it(`creates valid against known (${index})`, () => {
|
||||
const seed = mnemonicToMiniSecret(mnemonic, 'Substrate');
|
||||
const pair = schnorrkelKeypairFromSeed(seed);
|
||||
|
||||
expect(
|
||||
u8aToHex(pair.secretKey)
|
||||
).toEqual(secret);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../../types';
|
||||
|
||||
import '../../polyfill';
|
||||
|
||||
import { sr25519KeypairFromSeed } from '@plugnet/wasm-crypto';
|
||||
|
||||
import keypairFromU8a from './fromU8a';
|
||||
|
||||
/**
|
||||
* @name schnorrkelKeypairFromSeed
|
||||
* @description Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed.
|
||||
*/
|
||||
export default function schnorrkelKeypairFromSeed (seed: Uint8Array): Keypair {
|
||||
return keypairFromU8a(
|
||||
sr25519KeypairFromSeed(seed)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../../types';
|
||||
|
||||
const SEC_LEN = 64;
|
||||
const PUB_LEN = 32;
|
||||
|
||||
export default function schnorrkelKeypairFromU8a (full: Uint8Array): Keypair {
|
||||
return {
|
||||
publicKey: full.slice(SEC_LEN, SEC_LEN + PUB_LEN),
|
||||
secretKey: full.slice(0, SEC_LEN)
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
// Copyright 2017-2019 @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.
|
||||
|
||||
// mnemonic, entropy, seed, secret (expanded)
|
||||
type Test = [string, string, string, string];
|
||||
|
||||
const tests: Array<Test> = [
|
||||
[
|
||||
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about',
|
||||
'0x00000000000000000000000000000000',
|
||||
'0x44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453',
|
||||
'0xb0b3174fe43c15938bb0d0cc5b6f7ac7295f557ee1e6fdeb24fb73f4e0cb2b6ec40ffb9da4af6d411eae8e292750fd105ff70fe93f337b5b590f5a9d9030c750'
|
||||
],
|
||||
[
|
||||
'legal winner thank year wave sausage worth useful legal winner thank yellow',
|
||||
'0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f',
|
||||
'0x4313249608fe8ac10fd5886c92c4579007272cb77c21551ee5b8d60b780416850f1e26c1f4b8d88ece681cb058ab66d6182bc2ce5a03181f7b74c27576b5c8bf',
|
||||
'0x20666c9dd63c5b04a6a14377579af14aba60707752d134726304d0804992e26f9092c47fbb9e14c02fd53c702c8a3cfca4735638599da5c4362e0d0560dceb58'
|
||||
],
|
||||
[
|
||||
'letter advice cage absurd amount doctor acoustic avoid letter advice cage above',
|
||||
'0x80808080808080808080808080808080',
|
||||
'0x27f3eb595928c60d5bc91a4d747da40ed236328183046892ed6cd5aa9ae38122acd1183adf09a89839acb1e6eaa7fb563cc958a3f9161248d5a036e0d0af533d',
|
||||
'0x709e8254d0a9543c6b35b145dd23349e6369d487a1d10b0cfe09c05ff521f4691ad8bb8221339af38fc48510ec2dfc3104bb94d38f1fa241ceb252943df7b6b5'
|
||||
],
|
||||
[
|
||||
'zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong',
|
||||
'0xffffffffffffffffffffffffffffffff',
|
||||
'0x227d6256fd4f9ccaf06c45eaa4b2345969640462bbb00c5f51f43cb43418c7a753265f9b1e0c0822c155a9cabc769413ecc14553e135fe140fc50b6722c6b9df',
|
||||
'0x88206f4b4102ad30ee40b4b5943c5259db77fd576d95d79eeea00160197e406308821814dea9442675a5d3fa375b3bd65ffe92be43e07dbf6bb4ab84e9d4449d'
|
||||
],
|
||||
[
|
||||
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon agent',
|
||||
'0x000000000000000000000000000000000000000000000000',
|
||||
'0x44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453',
|
||||
'0xb0b3174fe43c15938bb0d0cc5b6f7ac7295f557ee1e6fdeb24fb73f4e0cb2b6ec40ffb9da4af6d411eae8e292750fd105ff70fe93f337b5b590f5a9d9030c750'
|
||||
],
|
||||
[
|
||||
'legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal will',
|
||||
'0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f',
|
||||
'0xcb1d50e14101024a88905a098feb1553d4306d072d7460e167a60ccb3439a6817a0afc59060f45d999ddebc05308714733c9e1e84f30feccddd4ad6f95c8a445',
|
||||
'0x50dcb74f223740d6a256000a2f1ccdb60044b39ce3aad71a3bd7761848d5f55d5a34f96e0b96ecb45d7a142e07ddfde734f9525f9f88310ab50e347da5789d3e'
|
||||
],
|
||||
[
|
||||
'letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter always',
|
||||
'0x808080808080808080808080808080808080808080808080',
|
||||
'0x9ddecf32ce6bee77f867f3c4bb842d1f0151826a145cb4489598fe71ac29e3551b724f01052d1bc3f6d9514d6df6aa6d0291cfdf997a5afdb7b6a614c88ab36a',
|
||||
'0x88112947a30e864b511838b6daf6e1e13801ae003d6d9b73eb5892c355f7e37ab3bb71200092d004467b06fe67bc153ee4e2bb7af2f544815b0dde276d2dae75'
|
||||
],
|
||||
[
|
||||
'zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo when',
|
||||
'0xffffffffffffffffffffffffffffffffffffffffffffffff',
|
||||
'0x8971cb290e7117c64b63379c97ed3b5c6da488841bd9f95cdc2a5651ac89571e2c64d391d46e2475e8b043911885457cd23e99a28b5a18535fe53294dc8e1693',
|
||||
'0x4859cdeda3f957b7ffcd2d59257c30e43996796f38e1be5c6136c9bf3744e047ce9a52c11793c98d0dc8caee927576ce46ef2e5f4b3f1d5e4b1344b2c31ebe8e'
|
||||
],
|
||||
[
|
||||
'abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon art',
|
||||
'0x0000000000000000000000000000000000000000000000000000000000000000',
|
||||
'0x44e9d125f037ac1d51f0a7d3649689d422c2af8b1ec8e00d71db4d7bf6d127e33f50c3d5c84fa3e5399c72d6cbbbbc4a49bf76f76d952f479d74655a2ef2d453',
|
||||
'0xb0b3174fe43c15938bb0d0cc5b6f7ac7295f557ee1e6fdeb24fb73f4e0cb2b6ec40ffb9da4af6d411eae8e292750fd105ff70fe93f337b5b590f5a9d9030c750'
|
||||
],
|
||||
[
|
||||
'legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth useful legal winner thank year wave sausage worth title',
|
||||
'0x7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f7f',
|
||||
'0x3037276a5d05fcd7edf51869eb841bdde27c574dae01ac8cfb1ea476f6bea6ef57ab9afe14aea1df8a48f97ae25b37d7c8326e49289efb25af92ba5a25d09ed3',
|
||||
'0xe8962ace15478f69fa42ddd004aad2c285c9f5a02e0712860e83fbec041f89489046aa57b21db2314d93aeb4a2d7cbdab21d4856e8e151894abd17fb04ae65e1'
|
||||
],
|
||||
[
|
||||
'letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic avoid letter advice cage absurd amount doctor acoustic bless',
|
||||
'0x8080808080808080808080808080808080808080808080808080808080808080',
|
||||
'0x2c9c6144a06ae5a855453d98c3dea470e2a8ffb78179c2e9eb15208ccca7d831c97ddafe844ab933131e6eb895f675ede2f4e39837bb5769d4e2bc11df58ac42',
|
||||
'0x78667314bf1e52e38d29792cdf294efcaddadc4fa9ce48c5f2bef4daad7ed95d1db960d6f6f895c1a9d2a3ddcc0398ba6578580ea1f03f65ea9a68e97cf3f840'
|
||||
],
|
||||
[
|
||||
'zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo vote',
|
||||
'0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff',
|
||||
'0x047e89ef7739cbfe30da0ad32eb1720d8f62441dd4f139b981b8e2d0bd412ed4eb14b89b5098c49db2301d4e7df4e89c21e53f345138e56a5e7d63fae21c5939',
|
||||
'0xe09f4ae0d4e22f6c9bbc4251c880e73d93d10fdf7f152c393ce36e4e942b3155a6f4b48e6c6ebce902a10d4ab46ef59cd154c15aeb8f7fcd4e1e26342d40806d'
|
||||
],
|
||||
[
|
||||
'ozone drill grab fiber curtain grace pudding thank cruise elder eight picnic',
|
||||
'0x9e885d952ad362caeb4efe34a8e91bd2',
|
||||
'0xf4956be6960bc145cdab782e649a5056598fd07cd3f32ceb73421c3da27833241324dc2c8b0a4d847eee457e6d4c5429f5e625ece22abaa6a976e82f1ec5531d',
|
||||
'0xb0eb046f48eacb7ad6c4da3ff92bfc29c9ad471bae3e554d5d63e58827160c70c7e5165598761f96b5659ab28c474f50e89ee13c67e30bca40fdcf4335835649'
|
||||
],
|
||||
[
|
||||
'gravity machine north sort system female filter attitude volume fold club stay feature office ecology stable narrow fog',
|
||||
'0x6610b25967cdcca9d59875f5cb50b0ea75433311869e930b',
|
||||
'0xfbcc5229ade0c0ff018cb7a329c5459f91876e4dde2a97ddf03c832eab7f26124366a543f1485479c31a9db0d421bda82d7e1fe562e57f3533cb1733b001d84d',
|
||||
'0xd8da734285a13967647dd906288e1ac871e1945d0c6b72fa259de4051a9b75431be0c4eb40b1ca38c780f445e3e2809282b9efef4dcc3538355e68094f1e79fa'
|
||||
],
|
||||
[
|
||||
'hamster diagram private dutch cause delay private meat slide toddler razor book happy fancy gospel tennis maple dilemma loan word shrug inflict delay length',
|
||||
'0x68a79eaca2324873eacc50cb9c6eca8cc68ea5d936f98787c60c7ebc74e6ce7c',
|
||||
'0x7c60c555126c297deddddd59f8cdcdc9e3608944455824dd604897984b5cc369cad749803bb36eb8b786b570c9cdc8db275dbe841486676a6adf389f3be3f076',
|
||||
'0x883b72fa7fb06b6abd0fc2cdb0018b3578e086e93074256bbbb8c68e53c04a56391bc0d19d7b2fa22a8148ccbe191d969c4323faca1935a576cc1b24301f203a'
|
||||
],
|
||||
[
|
||||
'scheme spot photo card baby mountain device kick cradle pact join borrow',
|
||||
'0xc0ba5a8e914111210f2bd131f3d5e08d',
|
||||
'0xc12157bf2506526c4bd1b79a056453b071361538e9e2c19c28ba2cfa39b5f23034b974e0164a1e8acd30f5b4c4de7d424fdb52c0116bfc6a965ba8205e6cc121',
|
||||
'0x7039a64150089f8d43188af964c7b8e2b8c9ba20aede085baca5672e978a47576c7193c3e557f37cdeeee5e5131b854e4309efc55259b050474e1f0884a7a621'
|
||||
],
|
||||
[
|
||||
'horn tenant knee talent sponsor spell gate clip pulse soap slush warm silver nephew swap uncle crack brave',
|
||||
'0x6d9be1ee6ebd27a258115aad99b7317b9c8d28b6d76431c3',
|
||||
'0x23766723e970e6b79dec4d5e4fdd627fd27d1ee026eb898feb9f653af01ad22080c6f306d1061656d01c4fe9a14c05f991d2c7d8af8730780de4f94cd99bd819',
|
||||
'0xe07a1f3073edad5b63585cdf1d5e6f8e50e3145de550fc8eb1fb430cce62d76d251904272c5d25fd634615d413bb31a2bc7b5d6eeb2f6ddc68a2b95ac6bd49bc'
|
||||
],
|
||||
[
|
||||
'panda eyebrow bullet gorilla call smoke muffin taste mesh discover soft ostrich alcohol speed nation flash devote level hobby quick inner drive ghost inside',
|
||||
'0x9f6a2878b2520799a44ef18bc7df394e7061a224d2c33cd015b157d746869863',
|
||||
'0xf4c83c86617cb014d35cd87d38b5ef1c5d5c3d58a73ab779114438a7b358f457e0462c92bddab5a406fe0e6b97c71905cf19f925f356bc673ceb0e49792f4340',
|
||||
'0x607f8595266ac0d4aa91bf4fddbd2a868889317f40099979be9743c46c418976e6ff3717bd11b94b418f91c8b88eae142cecb19104820997ddf5a379dd9da5ae'
|
||||
],
|
||||
[
|
||||
'cat swing flag economy stadium alone churn speed unique patch report train',
|
||||
'0x23db8160a31d3e0dca3688ed941adbf3',
|
||||
'0x719d4d4de0638a1705bf5237262458983da76933e718b2d64eb592c470f3c5d222e345cc795337bb3da393b94375ff4a56cfcd68d5ea25b577ee9384d35f4246',
|
||||
'0xd078b66bb357f1f06e897a6fdfa2f3dfb0da05836ded1fd0793373068b7e854e783a548a6d194f142e1ba78bf42a49fa58e3673b363ba6f6494efffa28f168df'
|
||||
],
|
||||
[
|
||||
'light rule cinnamon wrap drastic word pride squirrel upgrade then income fatal apart sustain crack supply proud access',
|
||||
'0x8197a4a47f0425faeaa69deebc05ca29c0a5b5cc76ceacc0',
|
||||
'0x7ae1291db32d16457c248567f2b101e62c5549d2a64cd2b7605d503ec876d58707a8d663641e99663bc4f6cc9746f4852e75e7e54de5bc1bd3c299c9a113409e',
|
||||
'0x5095fe4d0144b06e82aa4753d595fd10de9bba3733eba8ce0784417182317e725fac31b2fb53f4856a5e38866501425b485f4d2eaf2666a9f20ae68f4331ed2c'
|
||||
],
|
||||
[
|
||||
'all hour make first leader extend hole alien behind guard gospel lava path output census museum junior mass reopen famous sing advance salt reform',
|
||||
'0x066dca1a2bb7e8a1db2832148ce9933eea0f3ac9548d793112d9a95c9407efad',
|
||||
'0xa911a5f4db0940b17ecb79c4dcf9392bf47dd18acaebdd4ef48799909ebb49672947cc15f4ef7e8ef47103a1a91a6732b821bda2c667e5b1d491c54788c69391',
|
||||
'0x8844cb50f3ba8030ab61afee623534836d4ea3677d42bae470fc5e251ea0ca7ec9ea65c8c40be191c7c8683165848279ced81f3a121c9450078a496b6c59f610'
|
||||
],
|
||||
[
|
||||
'vessel ladder alter error federal sibling chat ability sun glass valve picture',
|
||||
'0xf30f8c1da665478f49b001d94c5fc452',
|
||||
'0x4e2314ca7d9eebac6fe5a05a5a8d3546bc891785414d82207ac987926380411e559c885190d641ff7e686ace8c57db6f6e4333c1081e3d88d7141a74cf339c8f',
|
||||
'0x18917f0c7480c95cd4d98bdc7df773c366d33590252707da1358eb58b43a7b765e3c513878541bfbfb466bb4206f581edf9bf601409c72afac130bcc8b5661b5'
|
||||
],
|
||||
[
|
||||
'scissors invite lock maple supreme raw rapid void congress muscle digital elegant little brisk hair mango congress clump',
|
||||
'0xc10ec20dc3cd9f652c7fac2f1230f7a3c828389a14392f05',
|
||||
'0x7a83851102849edc5d2a3ca9d8044d0d4f00e5c4a292753ed3952e40808593251b0af1dd3c9ed9932d46e8608eb0b928216a6160bd4fc775a6e6fbd493d7c6b2',
|
||||
'0xb0bf86b0955413fc95144bab124e82042d0cce9c292c1bfd0874ae5a95412977e7bc109aeef33c7c90be952a83f3fe528419776520de721ef6ec9e814749c3fc'
|
||||
],
|
||||
[
|
||||
'void come effort suffer camp survey warrior heavy shoot primary clutch crush open amazing screen patrol group space point ten exist slush involve unfold',
|
||||
'0xf585c11aec520db57dd353c69554b21a89b20fb0650966fa0a9d6f74fd989d8f',
|
||||
'0x938ba18c3f521f19bd4a399c8425b02c716844325b1a65106b9d1593fbafe5e0b85448f523f91c48e331995ff24ae406757cff47d11f240847352b348ff436ed',
|
||||
'0xc07ba4a979657576f4f7446e3bd2672c87131fa0f472a8bc1f2e9b28c11fb04c66da12cd280662196a5888d8a77178dab8034ed42b11d1654a31db6e1ff4d4c5'
|
||||
]
|
||||
];
|
||||
|
||||
export default tests;
|
||||
@@ -0,0 +1,11 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../../types';
|
||||
|
||||
import { u8aConcat } from '@plugnet/util';
|
||||
|
||||
export default function schnorrkelKeypairToU8a ({ publicKey, secretKey }: Keypair): Uint8Array {
|
||||
return u8aConcat(secretKey, publicKey).slice();
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
// Copyright 2017-2019 @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 { Keypair } from '../types';
|
||||
|
||||
import '../polyfill';
|
||||
|
||||
import { assert } from '@plugnet/util';
|
||||
import { sr25519Sign } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name schnorrkelSign
|
||||
* @description Returns message signature of `message`, using the supplied pair
|
||||
*/
|
||||
export default function schnorrkelSign (message: Uint8Array, { publicKey, secretKey }: Partial<Keypair>): Uint8Array {
|
||||
assert(publicKey && publicKey.length === 32, 'Expected valid publicKey, 32-bytes');
|
||||
assert(secretKey && secretKey.length === 64, 'Expected valid secretKey, 64-bytes');
|
||||
|
||||
return sr25519Sign(publicKey as Uint8Array, secretKey as Uint8Array, message);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
// Copyright 2017-2019 @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 { stringToU8a } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import randomAsU8a from '../random/asU8a';
|
||||
import pairFromSeed from './keypair/fromSeed';
|
||||
import sign from './sign';
|
||||
import verify from './verify';
|
||||
|
||||
const MESSAGE = stringToU8a('this is a message');
|
||||
|
||||
describe('sign and verify', () => {
|
||||
beforeEach(async () => {
|
||||
return waitReady();
|
||||
});
|
||||
|
||||
it('has 64-byte signatures', () => {
|
||||
const pair = pairFromSeed(randomAsU8a());
|
||||
|
||||
expect(sign(MESSAGE, pair)).toHaveLength(64);
|
||||
});
|
||||
|
||||
it('can sign and verify a message', () => {
|
||||
const pair = pairFromSeed(randomAsU8a());
|
||||
const signature = sign(MESSAGE, pair);
|
||||
|
||||
expect(verify(MESSAGE, signature, pair.publicKey)).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2019 @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 { sr25519Verify } from '@plugnet/wasm-crypto';
|
||||
|
||||
/**
|
||||
* @name schnorrkelVerify
|
||||
* @description Verifies the signature of `message`, using the supplied pair
|
||||
*/
|
||||
export default function schnorrkelVerify (message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean {
|
||||
return sr25519Verify(signature, message, publicKey);
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
// Copyright 2017-2019 @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 secp256k1Recover } from './recover';
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2017-2019 @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 secp256k1 from 'secp256k1';
|
||||
import { u8aToBuffer, u8aToU8a } from '@plugnet/util';
|
||||
|
||||
/**
|
||||
* @name secp256k1Recover
|
||||
* @description Recovers a publicKey from the supplied signature
|
||||
*/
|
||||
export default function secp256k1Recover (message: Uint8Array, signature: Uint8Array, recovery: number): Uint8Array {
|
||||
return u8aToU8a(
|
||||
secp256k1.recover(u8aToBuffer(message), u8aToBuffer(signature), recovery)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017-2019 @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 '@plugnet/wasm-crypto';
|
||||
|
||||
import { sha512AsU8a } from '.';
|
||||
|
||||
describe('sha512AsU8a', () => {
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
it('creates a sha-512 hash', () => {
|
||||
expect(
|
||||
sha512AsU8a(
|
||||
Uint8Array.from([0x61, 0x62, 0x63, 0x64])
|
||||
)
|
||||
).toEqual(
|
||||
Uint8Array.from([
|
||||
216, 2, 47, 32, 96, 173, 110, 253, 41, 122, 183, 61, 204, 83, 85, 201, 178, 20, 5, 75, 13, 23, 118, 161, 54, 166, 105, 210, 106, 125, 59, 20, 247, 58, 160, 208, 235, 255, 25, 238, 51, 51, 104, 240, 22, 75, 100, 25, 169, 109, 164, 158, 62, 72, 23, 83, 231, 233, 107, 113, 107, 220, 203, 111
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,26 @@
|
||||
// Copyright 2017-2019 @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 nacl from 'tweetnacl';
|
||||
import { isReady, sha512 } from '@plugnet/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 '@plugnet/util-crypto';
|
||||
*
|
||||
* sha512AsU8a(Uint8Array.from([...])); // => Uint8Array([...])
|
||||
* ```
|
||||
*/
|
||||
export default function sha512AsU8a (data: Uint8Array): Uint8Array {
|
||||
return isReady()
|
||||
? sha512(data)
|
||||
: nacl.hash(data);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// Copyright 2017-2019 @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 Implements Sha-512 hashing functions for a variety of input and outputs
|
||||
*/
|
||||
|
||||
export { default as sha512AsU8a } from './asU8a';
|
||||
@@ -0,0 +1,15 @@
|
||||
// Copyright 2017-2019 @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 type Keypair = {
|
||||
publicKey: Uint8Array;
|
||||
secretKey: Uint8Array;
|
||||
};
|
||||
|
||||
export type Seedpair = {
|
||||
publicKey: Uint8Array;
|
||||
seed: Uint8Array;
|
||||
};
|
||||
|
||||
export type KeypairType = 'ed25519' | 'sr25519';
|
||||
@@ -0,0 +1,31 @@
|
||||
// Copyright 2017-2019 @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 '@plugnet/wasm-crypto';
|
||||
|
||||
import { xxhashAsHex } from '.';
|
||||
|
||||
describe('xxhashAsHex', () => {
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
it('returns a 64-bit value by default', () => {
|
||||
expect(
|
||||
xxhashAsHex('abc')
|
||||
).toEqual('0x990977adf52cbc44');
|
||||
});
|
||||
|
||||
it('returns a 128-bit value (as specified)', () => {
|
||||
expect(
|
||||
xxhashAsHex('abc', 128)
|
||||
).toEqual('0x990977adf52cbc440889329981caa9be');
|
||||
});
|
||||
|
||||
it('returns a 256-bit value (as specified)', () => {
|
||||
expect(
|
||||
xxhashAsHex('abc', 256)
|
||||
).toEqual('0x990977adf52cbc440889329981caa9bef7da5770b2b8a05303b75d95360dd62b');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @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 { u8aToHex } from '@plugnet/util';
|
||||
|
||||
import xxhashAsU8a from './asU8a';
|
||||
|
||||
/**
|
||||
* @name xxhashAsHex
|
||||
* @summary Creates a xxhash64 hex from the input.
|
||||
* @description
|
||||
* From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash64 and return the result as a hex string with the specified `bitLength`.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { xxhashAsHex } from '@plugnet/util-crypto';
|
||||
*
|
||||
* xxhashAsHex('abc'); // => 0x44bc2cf5ad770999
|
||||
* ```
|
||||
*/
|
||||
export default function xxhashAsHex (data: Buffer | Uint8Array | string, bitLength: number = 64): string {
|
||||
return u8aToHex(
|
||||
xxhashAsU8a(data, bitLength)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2017-2019 @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 { hexToU8a } from '@plugnet/util';
|
||||
import { waitReady } from '@plugnet/wasm-crypto';
|
||||
|
||||
import { xxhashAsU8a } from '.';
|
||||
|
||||
describe('xxhashAsU8a', () => {
|
||||
beforeEach(async () => {
|
||||
await waitReady();
|
||||
});
|
||||
|
||||
it('returns a 64-bit value by default', () => {
|
||||
expect(
|
||||
xxhashAsU8a('abc')
|
||||
).toEqual(
|
||||
hexToU8a('0x990977adf52cbc44')
|
||||
);
|
||||
});
|
||||
|
||||
it('returns a 128-bit value (as specified)', () => {
|
||||
expect(
|
||||
xxhashAsU8a('abc', 128)
|
||||
).toEqual(
|
||||
hexToU8a('0x990977adf52cbc440889329981caa9be')
|
||||
);
|
||||
});
|
||||
|
||||
it('returns a 256-bit value (as specified)', () => {
|
||||
expect(
|
||||
xxhashAsU8a('abc', 256)
|
||||
).toEqual(
|
||||
hexToU8a('0x990977adf52cbc440889329981caa9bef7da5770b2b8a05303b75d95360dd62b')
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,38 @@
|
||||
// Copyright 2017-2019 @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 { u8aToU8a } from '@plugnet/util';
|
||||
import { isReady, twox } from '@plugnet/wasm-crypto';
|
||||
|
||||
import xxhash64AsBn from './xxhash64/asBn';
|
||||
|
||||
/**
|
||||
* @name xxhashAsU8a
|
||||
* @summary Creates a xxhash64 u8a from the input.
|
||||
* @description
|
||||
* From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash64 and return the result as a `Uint8Array` with the specified `bitLength`.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { xxhashAsU8a } from '@plugnet/util-crypto';
|
||||
*
|
||||
* xxhashAsU8a('abc'); // => 0x44bc2cf5ad770999
|
||||
* ```
|
||||
*/
|
||||
export default function xxhashAsU8a (data: Buffer | Uint8Array | string, bitLength: number = 64): Uint8Array {
|
||||
const iterations = Math.ceil(bitLength / 64);
|
||||
|
||||
if (isReady()) {
|
||||
return twox(u8aToU8a(data), iterations);
|
||||
}
|
||||
|
||||
const u8a = new Uint8Array(Math.ceil(bitLength / 8));
|
||||
|
||||
for (let seed = 0; seed < iterations; seed++) {
|
||||
u8a.set(xxhash64AsBn(data, seed).toArray('le', 8), seed * 8);
|
||||
}
|
||||
|
||||
return u8a;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// Copyright 2017-2019 @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 Create xxhash64 values with specified bitlengths
|
||||
*/
|
||||
|
||||
export { default as xxhashAsHex } from './asHex';
|
||||
export { default as xxhashAsU8a } from './asU8a';
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017-2019 @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 { xxhash64AsBn } from '.';
|
||||
|
||||
describe('xxhash64AsBn', () => {
|
||||
it('creates the correct BN output', () => {
|
||||
expect(
|
||||
xxhash64AsBn('abcd', 0xabcd).toString(16)
|
||||
).toEqual('e29f70f8b8c96df7');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,28 @@
|
||||
// Copyright 2017-2019 @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 BN from 'bn.js';
|
||||
|
||||
import xxhash64AsRaw from './asRaw';
|
||||
|
||||
/**
|
||||
* @name xxhash64AsBn
|
||||
* @summary Creates a xxhash BN from the input.
|
||||
* @description
|
||||
* From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash and return the result as a BN.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { xxhash64AsNumber } from '@plugnet/util-crypto';
|
||||
*
|
||||
* xxhash64AsBn('abcd', 0xabcd)); // => new BN(0xe29f70f8b8c96df7)
|
||||
* ```
|
||||
*/
|
||||
export default function xxhash64AsBn (data: Buffer | Uint8Array | string, seed: number): BN {
|
||||
return new BN(
|
||||
xxhash64AsRaw(data, seed),
|
||||
16
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017-2019 @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 { xxhash64AsHex } from '.';
|
||||
|
||||
describe('xxhash64AsHex', () => {
|
||||
it('creates the correct hex output', () => {
|
||||
expect(
|
||||
xxhash64AsHex('abcd', 0xabcd)
|
||||
).toEqual('0xe29f70f8b8c96df7');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,27 @@
|
||||
// Copyright 2017-2019 @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 { hexAddPrefix } from '@plugnet/util';
|
||||
|
||||
import xxhash64AsRaw from './asRaw';
|
||||
|
||||
/**
|
||||
* @name xxhash64AsHex
|
||||
* @summary Creates a xxhash hex from the input.
|
||||
* @description
|
||||
* From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash and return the result as a hex string.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { xxhash64AsHex } from '@plugnet/util-crypto';
|
||||
*
|
||||
* xxhash64AsHex('abcd', 0xabcd)); // => 0xe29f70f8b8c96df7
|
||||
* ```
|
||||
*/
|
||||
export default function xxhash64AsHex (data: Buffer | Uint8Array | string, seed: number): string {
|
||||
return hexAddPrefix(
|
||||
xxhash64AsRaw(data, seed)
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
// Copyright 2017-2019 @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 { xxhash64AsRaw } from '.';
|
||||
|
||||
describe('xxhash64AsRaw', () => {
|
||||
it('creates the correct non-prefixed hex output', () => {
|
||||
expect(
|
||||
xxhash64AsRaw('abcd', 0xabcd)
|
||||
).toEqual('e29f70f8b8c96df7');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
// Copyright 2017-2019 @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 xxhash64AsValue from './asValue';
|
||||
|
||||
/**
|
||||
* @name xxhash64AsRaw
|
||||
* @summary Creates a xxhash non-prefixed hex from the input.
|
||||
* @description
|
||||
* From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash and return the result as a non-prefixed hex string.
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { xxhash64AsRaw } from '@plugnet/util-crypto';
|
||||
*
|
||||
* xxhash64AsRaw('abcd', 0xabcd)); // => e29f70f8b8c96df7
|
||||
* ```
|
||||
*/
|
||||
export default function xxhash64AsRaw (data: Buffer | Uint8Array | string, seed: number): string {
|
||||
return xxhash64AsValue(data, seed).toString(16);
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
// Copyright 2017-2019 @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 xxhash64AsValue from './asValue';
|
||||
|
||||
describe('xxhash64AsValue', () => {
|
||||
it('creates the correct output (string input)', () => {
|
||||
expect(
|
||||
xxhash64AsValue('abcd', 0xabcd).toString(16)
|
||||
).toEqual('e29f70f8b8c96df7');
|
||||
});
|
||||
|
||||
it('creates the correct output (Buffer input)', () => {
|
||||
expect(
|
||||
xxhash64AsValue(Buffer.from([0x61, 0x62, 0x63, 0x64]), 0xabcd).toString(16)
|
||||
).toEqual('e29f70f8b8c96df7');
|
||||
});
|
||||
|
||||
it('creates the correct output (Uint8Array input)', () => {
|
||||
expect(
|
||||
xxhash64AsValue(new Uint8Array([0x61, 0x62, 0x63, 0x64]), 0xabcd).toString(16)
|
||||
).toEqual('e29f70f8b8c96df7');
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright 2017-2019 @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 xxhashjs from 'xxhashjs';
|
||||
import { isBuffer, isString, u8aToBuffer } from '@plugnet/util';
|
||||
|
||||
/**
|
||||
* @name xxhash64AsValue
|
||||
* @summary Creates a hex number from the input.
|
||||
* @description
|
||||
* From either a `string`, `Uint8Array` or a `Buffer` input, create the xxhash and return the result as a hex number
|
||||
* @example
|
||||
* <BR>
|
||||
*
|
||||
* ```javascript
|
||||
* import { xxhash64AsValue } from '@plugnet/util-crypto';
|
||||
*
|
||||
* xxhash64AsValue('abcd', 0xabcd)); // => e29f70f8b8c96df7
|
||||
* ```
|
||||
*/
|
||||
export default function xxhash64AsValue (data: Buffer | Uint8Array | string, seed: number): number {
|
||||
if (isBuffer(data) || isString(data)) {
|
||||
// @ts-ignore Buffer is ArrayBuffer underlying
|
||||
return xxhashjs.h64(data, seed);
|
||||
}
|
||||
|
||||
// @ts-ignore conversion works, yields correct result
|
||||
return xxhashjs.h64(
|
||||
u8aToBuffer(data),
|
||||
seed
|
||||
) as any;
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
// Copyright 2017-2019 @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 xxhash64AsBn from './asBn';
|
||||
import xxhash64AsHex from './asHex';
|
||||
import xxhash64AsRaw from './asRaw';
|
||||
|
||||
/**
|
||||
* @summary Create [XXHash](http://cyan4973.github.io/xxHash/) values as BN, hex & number output
|
||||
*/
|
||||
export {
|
||||
xxhash64AsBn,
|
||||
xxhash64AsHex,
|
||||
xxhash64AsRaw
|
||||
};
|
||||
Reference in New Issue
Block a user