From 0fcdbd4e09b21d10c90447e2347ea775a1edc613 Mon Sep 17 00:00:00 2001 From: Alex Ostrovski Date: Mon, 2 Oct 2017 00:50:19 +0300 Subject: [PATCH] Rename `randomKey()` to `secret()` ...and add `secret.fromSeed()` for testing purposes. --- src/crypto.js | 40 ++++++++++++++++++++++++++++++++++++---- test/crypto.js | 29 ++++++++++++++++++++++++++++- test/message.js | 4 ++-- 3 files changed, 66 insertions(+), 7 deletions(-) diff --git a/src/crypto.js b/src/crypto.js index 5cbb676..689ae75 100644 --- a/src/crypto.js +++ b/src/crypto.js @@ -46,10 +46,42 @@ export function verify (message, signature, pubkey) { return nacl.sign.detached.verify(message, rawOrSelf(signature), rawOrSelf(pubkey)) } -export function randomKey () { - const secretKey = nacl.sign.keyPair().secretKey - secretKey.pub = function () { return PublicKey.from(fromSecretKey(this)) } - secretKey.rawPub = function () { return fromSecretKey(this) } +/** + * Randomly generates a key pair for signing/verification purposes. + * + * @returns {Uint8Array} + * Secret key with the following additional methods: + * - `pub(): PublicKey` returns Exonum-typed public key + * - `rawPub(): Uint8Array` returns 32-byte raw public key buffer + */ +export function secret () { + const { secretKey, publicKey } = nacl.sign.keyPair() + const exonumPub = PublicKey.from(publicKey) + + secretKey.pub = function () { return exonumPub } + secretKey.rawPub = function () { return publicKey.slice(0) } + + return secretKey +} + +/** + * Generates a key pair for signing/verification purposes from a given 32-byte seed. + * You should not use this method unless for testing purposes; use `secret()` instead. + * + * @param {Uint8Array} seed + * 32-byte seed to generate the key from + * @returns {Uint8Array} + * Secret key with the following additional methods: + * - `pub(): PublicKey` returns Exonum-typed public key + * - `rawPub(): Uint8Array` returns 32-byte raw public key buffer + */ +secret.fromSeed = function (seed) { + const { secretKey, publicKey } = nacl.sign.keyPair.fromSeed(seed) + const exonumPub = PublicKey.from(publicKey) + + secretKey.pub = function () { return exonumPub } + secretKey.rawPub = function () { return publicKey.slice(0) } + return secretKey } diff --git a/test/crypto.js b/test/crypto.js index fbda304..f4a537c 100644 --- a/test/crypto.js +++ b/test/crypto.js @@ -7,7 +7,8 @@ import nacl from 'tweetnacl' import fixedBuffer from '../src/lowlevel/fixedBuffer' import std from '../src/std' -import { hash, sign, verify } from '../src/crypto' +import { hash, sign, verify, secret } from '../src/crypto' +import { isExonumObject } from '../src/lowlevel/common' const expect = chai .use(chaiBytes) @@ -117,3 +118,29 @@ describe('verify', () => { expect(verify(exMessage, Signature.from(signature), PublicKey.from(pk))).to.be.true() }) }) + +describe('secret', () => { + it('should generate a keypair', () => { + const key = secret() + expect(key).to.be.a('uint8array') + expect(key.pub()).to.satisfy(isExonumObject) + expect(key.rawPub()).to.be.a('uint8array') + }) + + it('should generate a new key each time', () => { + const [keyA, keyB] = [secret(), secret()] + expect(keyA).to.not.equalBytes(keyB) + expect(keyA.pub().equals(keyB.pub())).to.be.false() + }) +}) + +describe('secret.fromSeed', () => { + it('should work for 32-byte seeds', () => { + const h = hash(std.Str.from('correct horse battery staple')) + const key = secret.fromSeed(h) + expect(key).to.be.a('uint8array') + expect(key.pub()).to.satisfy(isExonumObject) + expect(key.rawPub()).to.be.a('uint8array') + expect(key.subarray(0, 32)).to.equalBytes(h) + }) +}) diff --git a/test/message.js b/test/message.js index 38e0824..0b71562 100644 --- a/test/message.js +++ b/test/message.js @@ -69,8 +69,8 @@ describe('Message', () => { } }) - const aliceKey = crypto.randomKey() - const bobKey = crypto.randomKey() + const aliceKey = crypto.secret() + const bobKey = crypto.secret() describe('constructor', () => { it('should construct a message', () => {