From 98f7eec7e735554a54030c6b21edc533df73ef3f Mon Sep 17 00:00:00 2001 From: Erik Nilsson Date: Sun, 24 Mar 2019 02:02:32 +0100 Subject: [PATCH] eccrypto.generatePrivate() (#38) * eccrypto.generatePrivate() * Fix comment indentation --- README.md | 12 +++++------- browser.js | 14 ++++++++++++++ index.js | 13 +++++++++++++ test.js | 17 ++++++++++++++--- 4 files changed, 46 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 8cc3b4f..2b5477c 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,7 @@ var crypto = require("crypto"); var eccrypto = require("eccrypto"); // A new random 32-byte private key. -var privateKey = crypto.randomBytes(32); +var privateKey = eccrypto.generatePrivate(); // Corresponding uncompressed (65-byte) public key. var publicKey = eccrypto.getPublic(privateKey); @@ -64,12 +64,11 @@ eccrypto.sign(privateKey, msg).then(function(sig) { ### ECDH ```js -var crypto = require("crypto"); var eccrypto = require("eccrypto"); -var privateKeyA = crypto.randomBytes(32); +var privateKeyA = eccrypto.generatePrivate(); var publicKeyA = eccrypto.getPublic(privateKeyA); -var privateKeyB = crypto.randomBytes(32); +var privateKeyB = eccrypto.generatePrivate(); var publicKeyB = eccrypto.getPublic(privateKeyB); eccrypto.derive(privateKeyA, publicKeyB).then(function(sharedKey1) { @@ -82,12 +81,11 @@ eccrypto.derive(privateKeyA, publicKeyB).then(function(sharedKey1) { ### ECIES ```js -var crypto = require("crypto"); var eccrypto = require("eccrypto"); -var privateKeyA = crypto.randomBytes(32); +var privateKeyA = eccrypto.generatePrivate(); var publicKeyA = eccrypto.getPublic(privateKeyA); -var privateKeyB = crypto.randomBytes(32); +var privateKeyB = eccrypto.generatePrivate(); var publicKeyB = eccrypto.getPublic(privateKeyB); // Encrypting the message for B. diff --git a/browser.js b/browser.js index 1ee25c7..a143a70 100644 --- a/browser.js +++ b/browser.js @@ -112,6 +112,20 @@ function hmacSha256Verify(key, msg, sig) { }); } +/** + * Generate a new valid private key. Will use the window.crypto or window.msCrypto as source + * depending on your browser. + * @return {Buffer} A 32-byte private key. + * @function + */ +exports.generatePrivate = function () { + var privateKey = randomBytes(32); + while (!isValidPrivateKey(privateKey)) { + privateKey = randomBytes(32); + } + return privateKey; +}; + var getPublic = exports.getPublic = function(privateKey) { // This function has sync API so we throw an error immediately. assert(privateKey.length === 32, "Bad private key"); diff --git a/index.js b/index.js index facc6f7..3721050 100644 --- a/index.js +++ b/index.js @@ -91,6 +91,19 @@ function pad32(msg){ } } +/** + * Generate a new valid private key. Will use crypto.randomBytes as source. + * @return {Buffer} A 32-byte private key. + * @function + */ +exports.generatePrivate = function() { + var privateKey = crypto.randomBytes(32); + while (!isValidPrivateKey(privateKey)) { + privateKey = crypto.randomBytes(32); + } + return privateKey; +}; + /** * Compute the public key for a given private key. * @param {Buffer} privateKey - A 32-byte private key diff --git a/test.js b/test.js index 498d466..cd40f31 100644 --- a/test.js +++ b/test.js @@ -28,7 +28,7 @@ describe("Key conversion", function() { expect(Buffer.isBuffer(publicKey)).to.be.true; expect(publicKey.toString("hex")).to.equal("041b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f70beaf8f588b541507fed6a642c5ab42dfdf8120a7f639de5122d47a69a8e8d1"); }); - + it("shouwld allow to convert private key to compressed public", function() { expect(Buffer.isBuffer(publicKeyCompressed)).to.be.true; expect(publicKeyCompressed.toString("hex")).to.equal("031b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f"); @@ -56,7 +56,7 @@ describe("ECDSA", function() { return eccrypto.verify(publicKeyCompressed, msg, sig); }); }); - + it("shouldn't verify incorrect signature", function(done) { eccrypto.sign(privateKey, msg).then(function(sig) { expect(Buffer.isBuffer(sig)).to.be.true; @@ -160,7 +160,7 @@ describe("ECDH", function() { }); }); }); - + it("should reject promise on bad keys", function(done) { eccrypto.derive(Buffer.from("test"), publicKeyB).catch(function() { eccrypto.derive(publicKeyB, publicKeyB).catch(function() { @@ -235,6 +235,17 @@ describe("ECIES", function() { }); }); + it("should encrypt and decrypt with generated private and public key", function () { + var privateKey = eccrypto.generatePrivate(); + var publicKey = eccrypto.getPublic(privateKey); + return eccrypto.encrypt(publicKey, Buffer.from("generated private key")) + .then(function(enc) { return eccrypto.decrypt(privateKey, enc); }) + .then(function(msg) { + expect(msg.toString()).to.equal("generated private key"); + }); + }); + + it("should reject promise on bad private key when decrypting", function(done) { eccrypto.encrypt(publicKeyA, Buffer.from("test")).then(function(enc) { eccrypto.decrypt(privateKeyB, enc).catch(function() {