ECDH (Browser)
This commit is contained in:
parent
e723993d1c
commit
9a9555a797
15
browser.js
15
browser.js
|
@ -21,6 +21,8 @@ function assert(condition, message) {
|
||||||
}
|
}
|
||||||
|
|
||||||
exports.getPublic = function(privateKey) {
|
exports.getPublic = function(privateKey) {
|
||||||
|
// This function has sync API so we throw an error immediately.
|
||||||
|
// (`elliptic` doesn't do this).
|
||||||
assert(privateKey.length === 32, "Bad private key");
|
assert(privateKey.length === 32, "Bad private key");
|
||||||
// XXX(Kagami): `elliptic.utils.encode` returns array for every
|
// XXX(Kagami): `elliptic.utils.encode` returns array for every
|
||||||
// encoding except `hex`.
|
// encoding except `hex`.
|
||||||
|
@ -28,15 +30,24 @@ exports.getPublic = function(privateKey) {
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.sign = function(privateKey, msg) {
|
exports.sign = function(privateKey, msg) {
|
||||||
var key = ec.keyPair(privateKey);
|
|
||||||
return new Promise(function(resolve) {
|
return new Promise(function(resolve) {
|
||||||
|
var key = ec.keyPair(privateKey);
|
||||||
resolve(new Buffer(key.sign(msg).toDER()));
|
resolve(new Buffer(key.sign(msg).toDER()));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.verify = function(key, msg, sig) {
|
exports.verify = function(key, msg, sig) {
|
||||||
key = ec.keyPair(key);
|
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
key = ec.keyPair(key);
|
||||||
return key.verify(msg, sig) ? resolve() : reject();
|
return key.verify(msg, sig) ? resolve() : reject();
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
exports.derive = function(privateKeyA, publicKeyB) {
|
||||||
|
return new Promise(function(resolve) {
|
||||||
|
var keyA = ec.keyPair(privateKeyA);
|
||||||
|
var keyB = ec.keyPair(publicKeyB);
|
||||||
|
var Px = keyA.derive(keyB.getPublic()); // BN instance
|
||||||
|
resolve(new Buffer(Px.toString(16), "hex"));
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
54
test.js
54
test.js
|
@ -2,11 +2,20 @@ var expect = require("chai").expect;
|
||||||
var crypto = require("crypto");
|
var crypto = require("crypto");
|
||||||
var eccrypto = require("./");
|
var eccrypto = require("./");
|
||||||
|
|
||||||
|
var msg = crypto.createHash("sha256").update("test").digest();
|
||||||
|
var otherMsg = crypto.createHash("sha256").update("test2").digest();
|
||||||
|
|
||||||
var privateKey = Buffer(32);
|
var privateKey = Buffer(32);
|
||||||
privateKey.fill(1);
|
privateKey.fill(1);
|
||||||
var publicKey = eccrypto.getPublic(privateKey);
|
var publicKey = eccrypto.getPublic(privateKey);
|
||||||
var msg = crypto.createHash("sha256").update("test").digest();
|
|
||||||
var otherMsg = crypto.createHash("sha256").update("test2").digest();
|
var privateKeyA = Buffer(32);
|
||||||
|
privateKeyA.fill(2);
|
||||||
|
var publicKeyA = eccrypto.getPublic(privateKeyA);
|
||||||
|
|
||||||
|
var privateKeyB = Buffer(32);
|
||||||
|
privateKeyB.fill(3);
|
||||||
|
var publicKeyB = eccrypto.getPublic(privateKeyB);
|
||||||
|
|
||||||
describe("Key convertion", function() {
|
describe("Key convertion", function() {
|
||||||
it("should allow to convert private key to public", function() {
|
it("should allow to convert private key to public", function() {
|
||||||
|
@ -22,8 +31,7 @@ describe("Key convertion", function() {
|
||||||
|
|
||||||
describe("ECDSA", function() {
|
describe("ECDSA", function() {
|
||||||
it("should allow to sign and verify message", function() {
|
it("should allow to sign and verify message", function() {
|
||||||
return eccrypto.sign(privateKey, msg)
|
return eccrypto.sign(privateKey, msg).then(function(sig) {
|
||||||
.then(function(sig) {
|
|
||||||
expect(Buffer.isBuffer(sig)).to.be.true;
|
expect(Buffer.isBuffer(sig)).to.be.true;
|
||||||
expect(sig.toString("hex")).to.equal("3044022078c15897a34de6566a0d396fdef660698c59fef56d34ee36bef14ad89ee0f6f8022016e02e8b7285d93feafafbe745702f142973a77d5c2fa6293596357e17b3b47c");
|
expect(sig.toString("hex")).to.equal("3044022078c15897a34de6566a0d396fdef660698c59fef56d34ee36bef14ad89ee0f6f8022016e02e8b7285d93feafafbe745702f142973a77d5c2fa6293596357e17b3b47c");
|
||||||
return eccrypto.verify(publicKey, msg, sig);
|
return eccrypto.verify(publicKey, msg, sig);
|
||||||
|
@ -39,14 +47,13 @@ describe("ECDSA", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("shouldn't verify incorrect signature", function(done) {
|
it("shouldn't verify incorrect signature", function(done) {
|
||||||
eccrypto.sign(privateKey, msg)
|
eccrypto.sign(privateKey, msg).then(function(sig) {
|
||||||
.then(function(sig) {
|
|
||||||
expect(Buffer.isBuffer(sig)).to.be.true;
|
expect(Buffer.isBuffer(sig)).to.be.true;
|
||||||
return eccrypto.verify(publicKey, otherMsg, sig);
|
eccrypto.verify(publicKey, otherMsg, sig).catch(function() {
|
||||||
}).catch(function() {
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("should reject promise on invalid key when signing", function(done) {
|
it("should reject promise on invalid key when signing", function(done) {
|
||||||
eccrypto.sign(Buffer("test"), msg).catch(function() {
|
eccrypto.sign(Buffer("test"), msg).catch(function() {
|
||||||
|
@ -55,23 +62,38 @@ describe("ECDSA", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
it("should reject promise on invalid key when verifying", function(done) {
|
it("should reject promise on invalid key when verifying", function(done) {
|
||||||
eccrypto.sign(privateKey, msg)
|
eccrypto.sign(privateKey, msg).then(function(sig) {
|
||||||
.then(function(sig) {
|
|
||||||
expect(Buffer.isBuffer(sig)).to.be.true;
|
expect(Buffer.isBuffer(sig)).to.be.true;
|
||||||
return eccrypto.verify(Buffer("test"), msg, sig);
|
eccrypto.verify(Buffer("test"), msg, sig).catch(function() {
|
||||||
}).catch(function() {
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
it("should reject promise on invalid sig when verifying", function(done) {
|
it("should reject promise on invalid sig when verifying", function(done) {
|
||||||
eccrypto.sign(privateKey, msg)
|
eccrypto.sign(privateKey, msg).then(function(sig) {
|
||||||
.then(function(sig) {
|
|
||||||
expect(Buffer.isBuffer(sig)).to.be.true;
|
expect(Buffer.isBuffer(sig)).to.be.true;
|
||||||
sig[0] ^= 1;
|
sig[0] ^= 1;
|
||||||
return eccrypto.verify(publicKey, msg, sig);
|
eccrypto.verify(publicKey, msg, sig).catch(function() {
|
||||||
}).catch(function() {
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
describe("ECDH", function() {
|
||||||
|
it("should derive shared secret from privkey A and pubkey B", function() {
|
||||||
|
return eccrypto.derive(privateKeyA, publicKeyB).then(function(Px) {
|
||||||
|
expect(Buffer.isBuffer(Px)).to.be.true;
|
||||||
|
expect(Px.length).to.equal(32);
|
||||||
|
expect(Px.toString("hex")).to.equal("aca78f27d5f23b2e7254a0bb8df128e7c0f922d47ccac72814501e07b7291886");
|
||||||
|
return eccrypto.derive(privateKeyB, publicKeyA).then(function(Px2) {
|
||||||
|
expect(Buffer.isBuffer(Px2)).to.be.true;
|
||||||
|
expect(Px2.length).to.equal(32);
|
||||||
|
expect(Px.toString("hex")).to.equal(Px2.toString("hex"));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user