Add ed25519 keypair, sign & verify (#71)
This commit is contained in:
Vendored
+40
-2
@@ -1,8 +1,46 @@
|
||||
// @flow
|
||||
|
||||
declare module 'tweetnacl' {
|
||||
declare type Tweetnacl$KeypairType = {
|
||||
publicKey: Uint8Array,
|
||||
secretKey: Uint8Array
|
||||
};
|
||||
|
||||
declare type Tweetnacl$Hash = {
|
||||
(message: Uint8Array): Uint8Array,
|
||||
|
||||
hashLength: number
|
||||
};
|
||||
|
||||
declare type Tweetnacl$Sign$Detached = {
|
||||
(message: Uint8Array, secretKey: Uint8Array): Uint8Array,
|
||||
|
||||
verify: (message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array) => boolean
|
||||
};
|
||||
|
||||
declare type Tweetnacl$Sign$Keypair = {
|
||||
(): Tweetnacl$KeypairType,
|
||||
|
||||
fromSecretKey: (secretKey: Uint8Array) => Tweetnacl$KeypairType,
|
||||
fromSeed: (seed: Uint8Array) => Tweetnacl$KeypairType,
|
||||
};
|
||||
|
||||
declare type Tweetnacl$Sign = {
|
||||
(message: Uint8Array, secretKey: Uint8Array): Uint8Array,
|
||||
detached: Tweetnacl$Sign$Detached,
|
||||
|
||||
open: (signedMsg: Uint8Array, publicKey: Uint8Array) => Uint8Array,
|
||||
keyPair: Tweetnacl$Sign$Keypair,
|
||||
|
||||
publicKeyLength: number,
|
||||
secretKeyLength: number,
|
||||
seedLength: number,
|
||||
signatureLength: number,
|
||||
};
|
||||
|
||||
declare module.exports: {
|
||||
hash: (data: Uint8Array) => Uint8Array,
|
||||
randomBytes: (length: number) => Uint8Array
|
||||
randomBytes: (length: number) => Uint8Array,
|
||||
hash: Tweetnacl$Hash,
|
||||
sign: Tweetnacl$Sign
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,3 +1,94 @@
|
||||
# nacl
|
||||
|
||||
Implements [NaCl](http://nacl.cr.yp.to/) secret-key authenticated encryption, public-key authenticated encryption, hashing, and public-key signatures
|
||||
|
||||
- [naclKeypair](#naclkeypair) Creates a new public/secret keypair.
|
||||
- [naclKeypairFromSecret](#naclkeypairfromsecret) Creates a new public/secret keypair from a secret.
|
||||
- [naclKeypairFromSeed](#naclkeypairfromseed) Creates a new public/secret keypair from a seed.
|
||||
- [naclSign](#naclsign) Signs a message using the supplied secretKey
|
||||
- [naclSign](#naclsign) Verifies the signature on the supplied message.
|
||||
|
||||
## naclKeypair
|
||||
|
||||
Creates a new public/secret keypair.
|
||||
|
||||
```js
|
||||
naclKeypair (): { secretKey: Uint8Array, publicKey: Uint8Array }
|
||||
```
|
||||
|
||||
|
||||
Returns a new generate object containing a `publicKey` & `secretKey`.
|
||||
|
||||
```js
|
||||
import { naclKeypair } from '@polkadot/util-crypto';
|
||||
|
||||
naclKeypair() // => { secretKey: [...], publicKey: [...] }
|
||||
```
|
||||
|
||||
## naclKeypairFromSecret
|
||||
|
||||
Creates a new public/secret keypair from a secret.
|
||||
|
||||
```js
|
||||
naclKeypairFromSecret (secretKey: Uint8Array): { secretKey: Uint8Array, publicKey: Uint8Array }
|
||||
```
|
||||
|
||||
|
||||
Returns a object containing a `publicKey` & `secretKey` generated from the supplied secret.
|
||||
|
||||
```js
|
||||
import { naclKeypairFromSecret } from '@polkadot/util-crypto';
|
||||
|
||||
naclKeypairFromSecret(...) // => { secretKey: [...], publicKey: [...] }
|
||||
```
|
||||
|
||||
## naclKeypairFromSeed
|
||||
|
||||
Creates a new public/secret keypair from a seed.
|
||||
|
||||
```js
|
||||
naclKeypairFromSeed (seed: Uint8Array): { secretKey: Uint8Array, publicKey: Uint8Array }
|
||||
```
|
||||
|
||||
|
||||
Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed.
|
||||
|
||||
```js
|
||||
import { naclKeypairFromSeed } from '@polkadot/util-crypto';
|
||||
|
||||
naclKeypairFromSeed(...) // => { secretKey: [...], publicKey: [...] }
|
||||
```
|
||||
|
||||
## naclSign
|
||||
|
||||
Signs a message using the supplied secretKey
|
||||
|
||||
```js
|
||||
naclSign (message: Uint8Array, secretKey: Uint8Array): Uint8Array
|
||||
```
|
||||
|
||||
|
||||
Returns message signature of `message`, using the `secretKey`.
|
||||
|
||||
```js
|
||||
import { naclSign } from '@polkadot/util-crypto';
|
||||
|
||||
naclSign([...], [...]) // => [...]
|
||||
```
|
||||
|
||||
## naclSign
|
||||
|
||||
Verifies the signature on the supplied message.
|
||||
|
||||
```js
|
||||
naclVerify (message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean
|
||||
```
|
||||
|
||||
|
||||
Verifies the `signature` on `message` with the supplied `plublicKey`. Returns `true` on sucess, `false` otherwise.
|
||||
|
||||
```js
|
||||
import { naclVerify } from '@polkadot/util-crypto';
|
||||
|
||||
naclVerify([...], [...], [...]) // => true/false
|
||||
```
|
||||
@@ -3,8 +3,19 @@
|
||||
// of the ISC license. See the LICENSE file for details.
|
||||
// @flow
|
||||
|
||||
const naclKeypair = require('./keypair');
|
||||
const naclKeypairFromSecret = require('./keypairFromSecret');
|
||||
const naclKeypairFromSeed = require('./keypairFromSeed');
|
||||
const naclSign = require('./sign');
|
||||
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 = {
|
||||
naclKeypair,
|
||||
naclKeypairFromSecret,
|
||||
naclKeypairFromSeed,
|
||||
naclSign,
|
||||
naclVerify
|
||||
};
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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 nacl = require('tweetnacl');
|
||||
|
||||
/**
|
||||
@name naclKeypair
|
||||
@signature naclKeypair (): { secretKey: Uint8Array, publicKey: Uint8Array }
|
||||
@summary Creates a new public/secret keypair.
|
||||
@description
|
||||
Returns a new generate object containing a `publicKey` & `secretKey`.
|
||||
@example
|
||||
import { naclKeypair } from '@polkadot/util-crypto';
|
||||
|
||||
naclKeypair() // => { secretKey: [...], publicKey: [...] }
|
||||
*/
|
||||
module.exports = function naclKeypair (): KeypairType {
|
||||
return nacl.sign.keyPair();
|
||||
};
|
||||
@@ -0,0 +1,25 @@
|
||||
// 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 { naclKeypair } = require('./index');
|
||||
|
||||
describe('naclKeypair', () => {
|
||||
let keypair;
|
||||
|
||||
beforeEach(() => {
|
||||
keypair = naclKeypair();
|
||||
});
|
||||
|
||||
it('generates a valid publicKey', () => {
|
||||
expect(
|
||||
keypair.publicKey
|
||||
).toHaveLength(32);
|
||||
});
|
||||
|
||||
it('generates a valid secretKey', () => {
|
||||
expect(
|
||||
keypair.secretKey
|
||||
).toHaveLength(64);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,23 @@
|
||||
// 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 nacl = require('tweetnacl');
|
||||
|
||||
/**
|
||||
@name naclKeypairFromSecret
|
||||
@signature naclKeypairFromSecret (secretKey: Uint8Array): { secretKey: Uint8Array, publicKey: Uint8Array }
|
||||
@summary Creates a new public/secret keypair from a secret.
|
||||
@description
|
||||
Returns a object containing a `publicKey` & `secretKey` generated from the supplied secret.
|
||||
@example
|
||||
import { naclKeypairFromSecret } from '@polkadot/util-crypto';
|
||||
|
||||
naclKeypairFromSecret(...) // => { secretKey: [...], publicKey: [...] }
|
||||
*/
|
||||
module.exports = function naclKeypairFromSecret (secretKey: Uint8Array): KeypairType {
|
||||
return nacl.sign.keyPair.fromSecretKey(secretKey);
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
// 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 { naclKeypairFromSecret } = require('./index');
|
||||
|
||||
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,23 @@
|
||||
// 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 nacl = require('tweetnacl');
|
||||
|
||||
/**
|
||||
@name naclKeypairFromSeed
|
||||
@signature naclKeypairFromSeed (seed: Uint8Array): { secretKey: Uint8Array, publicKey: Uint8Array }
|
||||
@summary Creates a new public/secret keypair from a seed.
|
||||
@description
|
||||
Returns a object containing a `publicKey` & `secretKey` generated from the supplied seed.
|
||||
@example
|
||||
import { naclKeypairFromSeed } from '@polkadot/util-crypto';
|
||||
|
||||
naclKeypairFromSeed(...) // => { secretKey: [...], publicKey: [...] }
|
||||
*/
|
||||
module.exports = function naclKeypairFromSeed (seed: Uint8Array): KeypairType {
|
||||
return nacl.sign.keyPair.fromSeed(seed);
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
// 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 { naclKeypairFromSeed } = require('./index');
|
||||
|
||||
describe('naclKeypairFromSeed', () => {
|
||||
it('generates a valid publicKey/secretKey pair', () => {
|
||||
expect(
|
||||
naclKeypairFromSeed(
|
||||
new Uint8Array([
|
||||
0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
|
||||
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
|
||||
0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
|
||||
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12
|
||||
])
|
||||
)
|
||||
).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: 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
|
||||
])
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
// 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 naclSign
|
||||
@signature naclSign (message: Uint8Array, secretKey: Uint8Array): Uint8Array
|
||||
@summary Signs a message using the supplied secretKey
|
||||
@description
|
||||
Returns message signature of `message`, using the `secretKey`.
|
||||
@example
|
||||
import { naclSign } from '@polkadot/util-crypto';
|
||||
|
||||
naclSign([...], [...]) // => [...]
|
||||
*/
|
||||
module.exports = function naclSign (message: Uint8Array, secretKey: Uint8Array): Uint8Array {
|
||||
// NOTE: Original message appended to the signature, slice result only
|
||||
return nacl.sign(message, secretKey).subarray(0, 64);
|
||||
};
|
||||
@@ -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 { naclSign, naclKeypairFromSeed } = require('./index');
|
||||
|
||||
describe('naclSign', () => {
|
||||
let secretKey;
|
||||
|
||||
beforeEach(() => {
|
||||
secretKey = naclKeypairFromSeed(
|
||||
new Uint8Array([
|
||||
0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
|
||||
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
|
||||
0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
|
||||
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12
|
||||
])
|
||||
).secretKey;
|
||||
});
|
||||
|
||||
it('returns a valid signature for the message', () => {
|
||||
expect(
|
||||
naclSign(
|
||||
new Uint8Array([0x61, 0x62, 0x63, 0x64]),
|
||||
secretKey
|
||||
)
|
||||
).toEqual(
|
||||
new Uint8Array([
|
||||
209, 234, 164, 44, 182, 218, 103, 16, 205, 238, 97, 222, 123, 112, 2, 240, 24, 192, 26, 134, 11, 170, 167, 153, 141, 108, 187, 171, 241, 125, 226, 179, 244, 232, 131, 61, 44, 68, 87, 41, 141, 131, 88, 36, 175, 173, 57, 29, 12, 112, 26, 200, 247, 89, 14, 64, 224, 188, 211, 198, 233, 119, 158, 6
|
||||
])
|
||||
);
|
||||
});
|
||||
});
|
||||
@@ -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 naclSign
|
||||
@signature naclVerify (message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean
|
||||
@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
|
||||
import { naclVerify } from '@polkadot/util-crypto';
|
||||
|
||||
naclVerify([...], [...], [...]) // => true/false
|
||||
*/
|
||||
module.exports = function naclVerify (message: Uint8Array, signature: Uint8Array, publicKey: Uint8Array): boolean {
|
||||
return nacl.sign.detached.verify(message, signature, publicKey);
|
||||
};
|
||||
@@ -0,0 +1,63 @@
|
||||
// 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 { naclVerify, naclKeypairFromSeed } = require('./index');
|
||||
|
||||
describe('naclSign', () => {
|
||||
let publicKey;
|
||||
let signature;
|
||||
|
||||
beforeEach(() => {
|
||||
publicKey = naclKeypairFromSeed(
|
||||
new Uint8Array([
|
||||
0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
|
||||
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12,
|
||||
0x12, 0x34, 0x56, 0x78, 0x90, 0x12, 0x34, 0x56,
|
||||
0x78, 0x90, 0x12, 0x34, 0x56, 0x78, 0x90, 0x12
|
||||
])
|
||||
).publicKey;
|
||||
signature = new Uint8Array([
|
||||
209, 234, 164, 44, 182, 218, 103, 16,
|
||||
205, 238, 97, 222, 123, 112, 2, 240,
|
||||
24, 192, 26, 134, 11, 170, 167, 153,
|
||||
141, 108, 187, 171, 241, 125, 226, 179,
|
||||
244, 232, 131, 61, 44, 68, 87, 41,
|
||||
141, 131, 88, 36, 175, 173, 57, 29,
|
||||
12, 112, 26, 200, 247, 89, 14, 64,
|
||||
224, 188, 211, 198, 233, 119, 158, 6
|
||||
]);
|
||||
});
|
||||
|
||||
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,8 @@
|
||||
// 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 { Tweetnacl$KeypairType } from 'tweetnacl';
|
||||
|
||||
export type KeypairType = Tweetnacl$KeypairType;
|
||||
Reference in New Issue
Block a user