Browser ECDSA with the help of elliptic
This commit is contained in:
parent
e103615f49
commit
b39277ba24
36
browser.js
36
browser.js
|
@ -0,0 +1,36 @@
|
||||||
|
/**
|
||||||
|
* Browser eccrypto implementation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
require("es6-promise").polyfill();
|
||||||
|
var EC = require("elliptic").ec;
|
||||||
|
|
||||||
|
var ec = new EC("secp256k1");
|
||||||
|
|
||||||
|
exports.getPublic = function(privateKey) {
|
||||||
|
// XXX(Kagami): `elliptic.utils.encode` returns array for every
|
||||||
|
// encoding except `hex`.
|
||||||
|
return new Buffer(ec.keyPair(privateKey).getPublic("arr"));
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.sign = function(privateKey, msg) {
|
||||||
|
var key = ec.keyPair(privateKey);
|
||||||
|
var sig;
|
||||||
|
try {
|
||||||
|
sig = new Buffer(key.sign(msg).toDER());
|
||||||
|
return Promise.resolve(sig);
|
||||||
|
} catch(e) {
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.verify = function(publicKey, msg, sig) {
|
||||||
|
var key = ec.keyPair(null, publicKey);
|
||||||
|
if (key.verify(msg, sig)) {
|
||||||
|
return Promise.resolve();
|
||||||
|
} else {
|
||||||
|
return Promise.reject();
|
||||||
|
}
|
||||||
|
};
|
21
index.js
21
index.js
|
@ -21,11 +21,8 @@ exports.getPublic = function(privateKey) {
|
||||||
* Create an ECDSA signature.
|
* Create an ECDSA signature.
|
||||||
* @param {Buffer} privateKey A 32-byte private key
|
* @param {Buffer} privateKey A 32-byte private key
|
||||||
* @param {Buffer} msg The message being signed
|
* @param {Buffer} msg The message being signed
|
||||||
* @return {Promise.<Buffer,number>} A promise that resolves with the
|
* @return {Promise.<Buffer,undefined>} A promise that resolves with the
|
||||||
* signature or rejects with error code:
|
* signature or rejects on bad private key/message.
|
||||||
*
|
|
||||||
* - 0: invalid nonce
|
|
||||||
* - -1: invalid private key or message
|
|
||||||
*/
|
*/
|
||||||
// FIXME(Kagami): What to do in case of invalid nonce?
|
// FIXME(Kagami): What to do in case of invalid nonce?
|
||||||
exports.sign = function(privateKey, msg) {
|
exports.sign = function(privateKey, msg) {
|
||||||
|
@ -35,11 +32,11 @@ exports.sign = function(privateKey, msg) {
|
||||||
if (code === 1) {
|
if (code === 1) {
|
||||||
resolve(sig);
|
resolve(sig);
|
||||||
} else {
|
} else {
|
||||||
reject(code);
|
reject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch(e) {
|
} catch(e) {
|
||||||
reject(-1);
|
reject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -49,12 +46,8 @@ exports.sign = function(privateKey, msg) {
|
||||||
* @param {Buffer} publicKey The public key
|
* @param {Buffer} publicKey The public key
|
||||||
* @param {Buffer} msg The message being verified
|
* @param {Buffer} msg The message being verified
|
||||||
* @param {Buffer} sig The signature
|
* @param {Buffer} sig The signature
|
||||||
* @return {Promise.<null,number>} A promise that resolves on correct
|
* @return {Promise} A promise that resolves on correct signature and
|
||||||
* signature and rejects on bad signature with error code:
|
* rejects on bad signature/public key.
|
||||||
*
|
|
||||||
* - 0: incorrect signature
|
|
||||||
* - -1: invalid public key
|
|
||||||
* - -2: invalid signature
|
|
||||||
*/
|
*/
|
||||||
exports.verify = function(publicKey, msg, sig) {
|
exports.verify = function(publicKey, msg, sig) {
|
||||||
return new Promise(function(resolve, reject) {
|
return new Promise(function(resolve, reject) {
|
||||||
|
@ -62,7 +55,7 @@ exports.verify = function(publicKey, msg, sig) {
|
||||||
if (code === 1) {
|
if (code === 1) {
|
||||||
resolve();
|
resolve();
|
||||||
} else {
|
} else {
|
||||||
reject(code);
|
reject();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"browser": "browser.js",
|
"browser": "browser.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"test": "mocha && jshint .",
|
"test": "mocha && xvfb-run -a karma start && jshint .",
|
||||||
"m": "mocha",
|
"m": "mocha",
|
||||||
"k": "xvfb-run -a karma start",
|
"k": "xvfb-run -a karma start",
|
||||||
"kc": "xvfb-run -a karma start --browsers Chromium",
|
"kc": "xvfb-run -a karma start --browsers Chromium",
|
||||||
|
@ -46,6 +46,7 @@
|
||||||
"mocha": "*"
|
"mocha": "*"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"elliptic": "^0.15.15",
|
||||||
"es6-promise": "^2.0.1",
|
"es6-promise": "^2.0.1",
|
||||||
"secp256k1": "~0.0.13"
|
"secp256k1": "~0.0.13"
|
||||||
}
|
}
|
||||||
|
|
17
test.js
17
test.js
|
@ -8,6 +8,7 @@ var msg = Buffer("test");
|
||||||
|
|
||||||
describe("Key", function() {
|
describe("Key", function() {
|
||||||
it("should allow to convert private key to public", function() {
|
it("should allow to convert private key to public", function() {
|
||||||
|
expect(Buffer.isBuffer(publicKey)).to.be.true;
|
||||||
expect(publicKey.toString("hex")).to.equal("041b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f70beaf8f588b541507fed6a642c5ab42dfdf8120a7f639de5122d47a69a8e8d1");
|
expect(publicKey.toString("hex")).to.equal("041b84c5567b126440995d3ed5aaba0565d71e1834604819ff9c17f5e9d5dd078f70beaf8f588b541507fed6a642c5ab42dfdf8120a7f639de5122d47a69a8e8d1");
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -16,6 +17,7 @@ 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;
|
||||||
return eccrypto.verify(publicKey, msg, sig);
|
return eccrypto.verify(publicKey, msg, sig);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -23,16 +25,15 @@ 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;
|
||||||
return eccrypto.verify(publicKey, Buffer("other msg"), sig);
|
return eccrypto.verify(publicKey, Buffer("other msg"), sig);
|
||||||
}).catch(function(code) {
|
}).catch(function() {
|
||||||
expect(code).to.equal(0);
|
|
||||||
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(code) {
|
eccrypto.sign(Buffer("test"), msg).catch(function() {
|
||||||
expect(code).to.equal(-1);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -40,9 +41,9 @@ 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;
|
||||||
return eccrypto.verify(Buffer("test"), msg, sig);
|
return eccrypto.verify(Buffer("test"), msg, sig);
|
||||||
}).catch(function(code) {
|
}).catch(function() {
|
||||||
expect(code).to.equal(-1);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -50,10 +51,10 @@ describe("ECDSA", function() {
|
||||||
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;
|
||||||
sig[0] ^= 1;
|
sig[0] ^= 1;
|
||||||
return eccrypto.verify(publicKey, msg, sig);
|
return eccrypto.verify(publicKey, msg, sig);
|
||||||
}).catch(function(code) {
|
}).catch(function() {
|
||||||
expect(code).to.equal(-2);
|
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user