Initial pair encryption (xsalsa20-poly1305) (#107)

* Allow keypair generation from input string

* Add keyfile encryption/decryption

* Pass secret through n rounds

* Split definition types

* Additional cleanups

* Pass salt as blake2b input

* Move kdf hashing to util-cypto

* Dangling comma

* Pull through secret as string | Uint8Array

* Update documentation
This commit is contained in:
Jaco Greeff
2018-03-13 17:04:44 +01:00
committed by GitHub
parent 827012783f
commit 995dfecf61
32 changed files with 527 additions and 32 deletions
+1
View File
@@ -3,6 +3,7 @@
Utility methods for this package are split into groups
- [blake2](blake2.md) Create blake2b values with specified bitlengths
- [kdf](kdf.md) Create Keys for use in encryption (rounds & salt) based on inputs
- [keccak](keccak.md) Create Keccak256 values as hex & Uint8Array output
- [nacl](nacl.md) Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption, hashing, and public-key signatures
- [random](random.md) Returns a sequence of secure random bytes in a variety of formats
+22
View File
@@ -0,0 +1,22 @@
# kdf
Create Keys for use in encryption (rounds & salt) based on inputs
- [kdfAsU8a](#kdfasu8a) Create Uint8Array key based on inputs
## kdfAsU8a
Create Uint8Array key based on inputs
```js
kdfAsU8a (secret: Uint8Array | string, rounds?: number, salt?: Uint8Array): { key: Uint8Array, rounds: number, salt: Uint8Array }
```
From either a `string` or a `Uint8Array` input, create a key with an optional (or random) salt based on the number of rounds with Blake2. Return return the result key as a `Uint8Array` in addition to the salt used and rounds employed.
```js
import { kdfAsU8a } from '@polkadot/util-crypto';
kdfAsU8a('123') // => { key: Uint8Array, rounds: number, salt: Uint8Array }
```
+36
View File
@@ -2,9 +2,45 @@
Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption, hashing, and public-key signatures
- [naclDecrypt](#nacldecrypt) Decrypts a message using the supplied secretKey and nonce
- [naclEncrypt](#naclencrypt) Encrypts a message using the supplied secretKey and nonce
- [naclSign](#naclsign) Signs a message using the supplied secretKey
- [naclSign](#naclsign) Verifies the signature on the supplied message.
## naclDecrypt
Decrypts a message using the supplied secretKey and nonce
```js
naclDecrypt (message: Uint8Array, secretKey: Uint8Array, nonce: Uint8Array): Uint8Array
```
Returns an decrypted message, using the `secretKey` and `nonce`.
```js
import { naclDecrypt } from '@polkadot/util-crypto';
naclDecrypt([...], [...], [...]) // => [...]
```
## naclEncrypt
Encrypts a message using the supplied secretKey and nonce
```js
naclEncrypt (message: Uint8Array, secretKey: Uint8Array, nonce?: Uint8Array): { encrypted: Uint8Array, nonce: Uint8Array }
```
Returns an encrypted message, using the `secretKey` and `nonce`. If the `nonce` was not supplied, a random value is generated.
```js
import { naclEncrypt } from '@polkadot/util-crypto';
naclSign([...], [...]) // => [...]
```
## naclSign
Signs a message using the supplied secretKey
+2 -2
View File
@@ -16,6 +16,6 @@ const blake2bAsU8a = require('./blake2b/asU8a');
blake2AsU8a('abc') // => [0xba, 0x80, 0xa53, 0xf98, 0x1c, 0x4d, 0x0d]
*/
module.exports = function blake2AsU8a (data: Uint8Array, bitLength: number = 256): Uint8Array {
return blake2bAsU8a(data, bitLength);
module.exports = function blake2AsU8a (data: Uint8Array, bitLength: number = 256, key?: Uint8Array): Uint8Array {
return blake2bAsU8a(data, bitLength, key);
};
+2 -2
View File
@@ -16,6 +16,6 @@ const blake2AsU8a = require('./asU8a');
blake2AsU8a256('abc') // => 0x44bc2cf5ad770999
*/
module.exports = function blake2AsU8a256 (data: Uint8Array): Uint8Array {
return blake2AsU8a(data, 256);
module.exports = function blake2AsU8a256 (data: Uint8Array, key?: Uint8Array): Uint8Array {
return blake2AsU8a(data, 256, key);
};
@@ -17,6 +17,6 @@ const blakejs = require('blakejs');
blake2bAsU8a('abc') // => Uint8Array('508c5e8c327c14e2e1a72ba34eeb452f37458b209ed63a294d999b4c86675982')
*/
module.exports = function blake2bAsU8a (data: Uint8Array, bitLength: number = 512): Uint8Array {
return blakejs.blake2b(data, null, bitLength / 8);
module.exports = function blake2bAsU8a (data: Uint8Array, bitLength: number = 512, key: ?Uint8Array = null): Uint8Array {
return blakejs.blake2b(data, key, bitLength / 8);
};
+2 -1
View File
@@ -4,6 +4,7 @@
// @flow
const blake2 = require('./blake2');
const kdf = require('./kdf');
const keccak = require('./keccak');
const nacl = require('./nacl');
const random = require('./random');
@@ -14,5 +15,5 @@ const xxhash = require('./xxhash');
@summary Utility methods for this package are split into groups
*/
module.exports = Object.assign(
{}, blake2, keccak, nacl, random, sha512, xxhash
{}, blake2, kdf, keccak, nacl, random, sha512, xxhash
);
+46
View File
@@ -0,0 +1,46 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
type KdfU8a = {
key: Uint8Array,
rounds: number,
salt: Uint8Array
};
const isU8a = require('@polkadot/util/is/u8a');
const u8aFromUtf8 = require('@polkadot/util/u8a/fromUtf8');
const blake2AsU8a256 = require('../blake2/asU8a256');
const randomAsU8a = require('../random/asU8a');
/**
@name kdfAsU8a
@signature kdfAsU8a (secret: Uint8Array | string, rounds?: number, salt?: Uint8Array): { key: Uint8Array, rounds: number, salt: Uint8Array }
@summary Create Uint8Array key based on inputs
@description
From either a `string` or a `Uint8Array` input, create a key with an optional (or random) salt based on the number of rounds with Blake2. Return return the result key as a `Uint8Array` in addition to the salt used and rounds employed.
@example
import { kdfAsU8a } from '@polkadot/util-crypto';
kdfAsU8a('123') // => { key: Uint8Array, rounds: number, salt: Uint8Array }
*/
module.exports = function kdfAsU8a (secret: Uint8Array | string, _rounds: number = 16, salt: Uint8Array = randomAsU8a(32)): KdfU8a {
const rounds = Math.max(1, _rounds);
let key: Uint8Array = isU8a(secret)
// flowlint-next-line unclear-type:off
? ((secret: any): Uint8Array)
// flowlint-next-line unclear-type:off
: u8aFromUtf8(((secret: any): string));
for (let count = 0; count < rounds; count++) {
key = blake2AsU8a256(key, salt);
}
return {
key,
rounds,
salt
};
};
@@ -0,0 +1,33 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
const { kdfAsU8a } = require('./index');
describe('kdfAsU8a', () => {
it('generates known via specified salt & rounds', () => {
const kdf = kdfAsU8a('test', 4, new Uint8Array(32));
expect(
kdf
).toEqual({
key: new Uint8Array([103, 101, 136, 180, 146, 65, 105, 190, 91, 158, 187, 202, 45, 7, 115, 229, 215, 76, 8, 12, 185, 45, 25, 148, 98, 156, 53, 167, 51, 15, 26, 150]),
rounds: 4,
salt: new Uint8Array(32)
});
});
it('defaults with rounds & random salt', () => {
const kdf = kdfAsU8a(new Uint8Array(1, 2, 3, 4));
expect(kdf.key).toHaveLength(32);
expect(kdf.rounds).toEqual(16);
expect(kdf.salt).not.toEqual(new Uint8Array(32));
});
it('does at least 1 round', () => {
const kdf = kdfAsU8a(new Uint8Array(1, 2, 3, 4), -10);
expect(kdf.rounds).toEqual(1);
});
});
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
const kdfAsU8a = require('./asU8a');
/**
@summary Create Keys for use in encryption (rounds & salt) based on inputs
*/
module.exports = {
kdfAsU8a
};
+21
View File
@@ -0,0 +1,21 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
const nacl = require('tweetnacl');
/**
@name naclDecrypt
@signature naclDecrypt (message: Uint8Array, secretKey: Uint8Array, nonce: Uint8Array): Uint8Array
@summary Decrypts a message using the supplied secretKey and nonce
@description
Returns an decrypted message, using the `secretKey` and `nonce`.
@example
import { naclDecrypt } from '@polkadot/util-crypto';
naclDecrypt([...], [...], [...]) // => [...]
*/
module.exports = function naclDecrypt (message: Uint8Array, secret: Uint8Array, nonce: Uint8Array): ?Uint8Array {
return nacl.secretbox.open(message, nonce, secret);
};
@@ -0,0 +1,19 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
const { naclDecrypt, naclEncrypt } = require('./index');
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, secret, nonce)
).toEqual(
message
);
});
});
+33
View File
@@ -0,0 +1,33 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
type Encrypted = {
encrypted: Uint8Array,
nonce: Uint8Array
};
const nacl = require('tweetnacl');
const randomAsU8a = require('../random/asU8a');
/**
@name naclEncrypt
@signature naclEncrypt (message: Uint8Array, secretKey: Uint8Array, nonce?: Uint8Array): { encrypted: Uint8Array, nonce: Uint8Array }
@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
import { naclEncrypt } from '@polkadot/util-crypto';
naclSign([...], [...]) // => [...]
*/
module.exports = function naclEncrypt (message: Uint8Array, secret: Uint8Array, nonce: Uint8Array = randomAsU8a(24)): Encrypted {
const encrypted = nacl.secretbox(message, nonce, secret);
return {
encrypted,
nonce
};
};
@@ -0,0 +1,19 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
const { naclEncrypt } = require('./index');
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)
});
});
});
+6
View File
@@ -3,9 +3,12 @@
// of the ISC license. See the LICENSE file for details.
// @flow
const naclDecrypt = require('./decrypt');
const naclEncrypt = require('./encrypt');
const naclKeypairFromRandom = require('./keypair/fromRandom');
const naclKeypairFromSecret = require('./keypair/fromSecret');
const naclKeypairFromSeed = require('./keypair/fromSeed');
const naclKeypairFromString = require('./keypair/fromString');
const naclSign = require('./sign');
const naclVerify = require('./verify');
@@ -13,9 +16,12 @@ const naclVerify = require('./verify');
@summary Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption, hashing, and public-key signatures
*/
module.exports = {
naclDecrypt,
naclEncrypt,
naclKeypairFromRandom,
naclKeypairFromSecret,
naclKeypairFromSeed,
naclKeypairFromString,
naclSign,
naclVerify
};
@@ -0,0 +1,30 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { KeypairType } from '../../types';
const u8aFromUtf8 = require('@polkadot/util/u8a/fromUtf8');
const blake2AsU8a256 = require('../../blake2/asU8a256');
const fromSeed = require('./fromSeed');
/**
@name naclKeypairFromString
@signature naclKeypairFromString (value: string): { secretKey: Uint8Array, publicKey: Uint8Array }
@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
import { naclKeypairFromString } from '@polkadot/util-crypto';
naclKeypairFromString('test') // => { secretKey: [...], publicKey: [...] }
*/
module.exports = function naclKeypairFromString (value: string): KeypairType {
return fromSeed(
blake2AsU8a256(
u8aFromUtf8(value)
)
);
};
@@ -0,0 +1,16 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
const { naclKeypairFromString } = require('../index');
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])
});
});
});
+1
View File
@@ -2,5 +2,6 @@
- [pair](pair.md)
# Available methods
+3
View File
@@ -0,0 +1,3 @@
# pair
+19
View File
@@ -0,0 +1,19 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { KeyringPairEncrypted, KeyringPair } from './types';
const createPair = require('./pair');
module.exports = function decrypt (box: KeyringPairEncrypted, secret: Uint8Array | string): KeyringPair {
const pair = createPair({
publicKey: box.publicKey,
secretKey: new Uint8Array([])
});
pair.decryptSelf(box, secret);
return pair;
};
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
const index = require('./index');
describe('decrypt', () => {
const publicKey = new Uint8Array([47, 140, 97, 41, 216, 22, 207, 81, 195, 116, 188, 127, 8, 195, 230, 62, 209, 86, 207, 120, 174, 251, 74, 101, 80, 217, 123, 135, 153, 121, 119, 238]);
const seedOne = '12345678901234567890123456789012';
let keypair;
let encrypted;
beforeEach(() => {
keypair = index();
keypair.addFromSeed(seedOne);
encrypted = keypair.encrypt(publicKey, 'test');
keypair = index();
});
it('decrypts a previously encrypted', () => {
expect(
keypair.decrypt(encrypted, 'test')
).toMatchObject({
publicKey
});
});
});
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { KeyringPairEncrypted, KeyringPair } from './types';
module.exports = function encrypt (pair: ?KeyringPair, secret: Uint8Array | string): ?KeyringPairEncrypted {
if (!pair) {
return null;
}
return pair.encryptSelf(secret);
};
+29
View File
@@ -0,0 +1,29 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
const index = require('./index');
describe('encrypt', () => {
const publicKey = new Uint8Array([47, 140, 97, 41, 216, 22, 207, 81, 195, 116, 188, 127, 8, 195, 230, 62, 209, 86, 207, 120, 174, 251, 74, 101, 80, 217, 123, 135, 153, 121, 119, 238]);
const seedOne = '12345678901234567890123456789012';
let keypair;
beforeEach(() => {
keypair = index();
keypair.addFromSeed(seedOne);
});
it('encrypts the key', () => {
expect(
keypair.encrypt(publicKey, 'test').publicKey
).toEqual(publicKey);
});
it('returns null for non-existing', () => {
expect(
keypair.encrypt(new Uint8Array([]), 'test')
).toEqual(null);
});
});
+14 -19
View File
@@ -3,34 +3,29 @@
// of the ISC license. See the LICENSE file for details.
// @flow
import type { KeyringInstance, KeyringPair } from './types';
type KeyringPairMap = {
[Uint8Array]: KeyringPair
};
import type { KeyringPairEncrypted, KeyringInstance, KeyringPair } from './types';
const naclKeypairFromSeed = require('@polkadot/util-crypto/nacl/keypair/fromSeed');
const decrypt = require('./decrypt');
const encrypt = require('./encrypt');
const createPair = require('./pair');
const createPairs = require('./pairs');
module.exports = function keyring (): KeyringInstance {
const pairs: KeyringPairMap = {};
const getPairs = (): Array<KeyringPair> =>
// flowlint-next-line unclear-type:off
((Object.values(pairs): any): Array<KeyringPair>);
const pairs = createPairs();
return {
addFromSeed: (seed: Uint8Array | string): KeyringPair => {
const pair = createPair(naclKeypairFromSeed(seed));
pairs[pair.publicKey] = pair;
return pair;
},
addFromSeed: (seed: Uint8Array | string): KeyringPair =>
pairs.add(createPair(naclKeypairFromSeed(seed))),
decrypt: (encrypted: KeyringPairEncrypted, secret: Uint8Array | string): KeyringPair =>
pairs.add(decrypt(encrypted, secret)),
encrypt: (publicKey: Uint8Array, secret: Uint8Array | string): ?KeyringPairEncrypted =>
encrypt(pairs.get(publicKey), secret),
getPair: (publicKey: Uint8Array): ?KeyringPair =>
pairs[publicKey],
getPairs,
pairs.get(publicKey),
getPairs: pairs.all,
getPublicKeys: (): Array<Uint8Array> =>
getPairs().map(({ publicKey }) => publicKey)
pairs.all().map(({ publicKey }) => publicKey)
};
};
+20
View File
@@ -0,0 +1,20 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { KeyringPairEncrypted } from '../types';
const kdf = require('@polkadot/util-crypto/kdf/asU8a');
const naclDecrypt = require('@polkadot/util-crypto/nacl/decrypt');
const assert = require('@polkadot/util/assert');
module.exports = function decrypt ({ crypto: { params: { nonce }, kdf: { rounds, salt }, text } }: KeyringPairEncrypted, secret: Uint8Array | string): Uint8Array {
const { key } = kdf(secret, rounds, salt);
const secretKey = naclDecrypt(text, key, nonce);
assert(secretKey, 'Unable to decrypt pair using secret');
// $FlowFixMe checking for type just above
return ((secretKey: any): Uint8Array);
};
+28
View File
@@ -0,0 +1,28 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { KeyringPairEncrypted } from '../types';
const kdf = require('@polkadot/util-crypto/kdf/asU8a');
const naclEncrypt = require('@polkadot/util-crypto/nacl/encrypt');
module.exports = function encrypt (message: Uint8Array, secret: Uint8Array | string, publicKey: Uint8Array): KeyringPairEncrypted {
const { key, rounds, salt } = kdf(secret);
const { encrypted, nonce } = naclEncrypt(message, key);
return {
crypto: {
params: {
nonce
},
kdf: {
rounds,
salt
},
text: encrypted
},
publicKey
};
};
@@ -4,14 +4,22 @@
// @flow
import type { KeypairType } from '@polkadot/util-crypto/types';
import type { KeyringPair } from './types';
import type { KeyringPairEncrypted, KeyringPair } from '../types';
const naclSign = require('@polkadot/util-crypto/nacl/sign');
const naclVerify = require('@polkadot/util-crypto/nacl/verify');
const decrypt = require('./decrypt');
const encrypt = require('./encrypt');
module.exports = function pair ({ publicKey, secretKey }: KeypairType): KeyringPair {
return {
publicKey,
decryptSelf: (encrypted: KeyringPairEncrypted, secret: Uint8Array | string): void => {
secretKey = decrypt(encrypted, secret);
},
encryptSelf: (secret: Uint8Array | string): KeyringPairEncrypted =>
encrypt(secretKey, secret, publicKey),
sign: (message: Uint8Array): Uint8Array =>
naclSign(message, secretKey),
verify: (message: Uint8Array, signature: Uint8Array): boolean =>
@@ -2,7 +2,7 @@
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
const keyring = require('./testing')();
const keyring = require('../testing')();
// aligned with @polkadot/util-crypto tests
describe('pair', () => {
+27
View File
@@ -0,0 +1,27 @@
// Copyright 2017-2018 Jaco Greeff
// This software may be modified and distributed under the terms
// of the ISC license. See the LICENSE file for details.
// @flow
import type { KeyringPairs, KeyringPair } from './types';
type KeyringPairMap = {
[Uint8Array]: KeyringPair
};
module.exports = function pairs (): KeyringPairs {
const self: KeyringPairMap = {};
return {
add: (pair: KeyringPair): KeyringPair => {
self[pair.publicKey] = pair;
return pair;
},
all: (): Array<KeyringPair> =>
// flowlint-next-line unclear-type:off
((Object.values(self): any): Array<KeyringPair>),
get: (publicKey: Uint8Array): ?KeyringPair =>
self[publicKey]
};
};
+26
View File
@@ -3,15 +3,41 @@
// of the ISC license. See the LICENSE file for details.
// @flow
export type KeyringPairEncrypted$Cipher = 'xsalsa20-poly1305';
export type KeyringPairEncrypted = {
crypto: {
params: {
nonce: Uint8Array
},
kdf: {
rounds: number,
salt: Uint8Array
},
text: Uint8Array
},
publicKey: Uint8Array
};
export type KeyringPair = {
publicKey: Uint8Array,
decryptSelf: (box: KeyringPairEncrypted, secret: Uint8Array | string) => void,
encryptSelf: (secret: Uint8Array | string) => KeyringPairEncrypted,
sign (message: Uint8Array): Uint8Array,
verify (message: Uint8Array, signature: Uint8Array): boolean
};
export type KeyringPairs = {
add: (pair: KeyringPair) => KeyringPair,
all: () => Array<KeyringPair>,
get: (publicKey: Uint8Array) => ?KeyringPair
};
export type KeyringInstance = {
addFromSeed (seed: Uint8Array | string): KeyringPair,
decrypt (encrypted: KeyringPairEncrypted, secret: Uint8Array | string): KeyringPair,
encrypt (publicKey: Uint8Array, secret: Uint8Array | string): ?KeyringPairEncrypted,
getPair (publicKey: Uint8Array): ?KeyringPair,
getPairs (): Array<KeyringPair>,
getPublicKeys (): Array<Uint8Array>