expose signature internal functions
"sign" and "genk" ... and add some signature tests
This commit is contained in:
parent
2c136d4dcc
commit
57a55d0863
@ -117,27 +117,6 @@ Key.prototype.regenerateSync = function() {
|
|||||||
Key.prototype.signSync = function(hash) {
|
Key.prototype.signSync = function(hash) {
|
||||||
var ec = elliptic.curves.secp256k1;
|
var ec = elliptic.curves.secp256k1;
|
||||||
|
|
||||||
var genk = function() {
|
|
||||||
//TODO: account for when >= n
|
|
||||||
return new bignum(SecureRandom.getRandomBuffer(8));
|
|
||||||
};
|
|
||||||
|
|
||||||
var sign = function(hash, priv) {
|
|
||||||
var d = priv;
|
|
||||||
var n = Point.getN();
|
|
||||||
var e = new bignum(hash);
|
|
||||||
|
|
||||||
do {
|
|
||||||
var k = genk();
|
|
||||||
var G = Point.getG();
|
|
||||||
var Q = Point.multiply(G, k);
|
|
||||||
var r = Q.x.mod(n);
|
|
||||||
var s = k.invm(n).mul(e.add(d.mul(r))).mod(n);
|
|
||||||
} while (r.cmp(new bignum(0)) <= 0 || s.cmp(new bignum(0)) <= 0);
|
|
||||||
|
|
||||||
return {r: r, s: s};
|
|
||||||
};
|
|
||||||
|
|
||||||
if (!this.private) {
|
if (!this.private) {
|
||||||
throw new Error('Key does not have a private key set');
|
throw new Error('Key does not have a private key set');
|
||||||
}
|
}
|
||||||
@ -146,7 +125,7 @@ Key.prototype.signSync = function(hash) {
|
|||||||
throw new Error('Arg should be a 32 bytes hash buffer');
|
throw new Error('Arg should be a 32 bytes hash buffer');
|
||||||
}
|
}
|
||||||
var privnum = new bignum(this.private);
|
var privnum = new bignum(this.private);
|
||||||
var sigrs = sign(hash, privnum);
|
var sigrs = Key.sign(hash, privnum);
|
||||||
var der = Key.rs2DER(sigrs.r, sigrs.s);
|
var der = Key.rs2DER(sigrs.r, sigrs.s);
|
||||||
|
|
||||||
return der;
|
return der;
|
||||||
|
|||||||
@ -80,4 +80,25 @@ Key.rs2DER = function(r, s) {
|
|||||||
return der;
|
return der;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Key.sign = function(hash, priv, k) {
|
||||||
|
var d = priv;
|
||||||
|
var n = Point.getN();
|
||||||
|
var e = new bignum(hash);
|
||||||
|
|
||||||
|
do {
|
||||||
|
var k = k || Key.genk();
|
||||||
|
var G = Point.getG();
|
||||||
|
var Q = Point.multiply(G, k);
|
||||||
|
var r = Q.x.mod(n);
|
||||||
|
var s = k.invm(n).mul(e.add(d.mul(r))).mod(n);
|
||||||
|
} while (r.cmp(new bignum(0)) <= 0 || s.cmp(new bignum(0)) <= 0);
|
||||||
|
|
||||||
|
return {r: r, s: s};
|
||||||
|
};
|
||||||
|
|
||||||
|
Key.genk = function() {
|
||||||
|
//TODO: account for when >= n
|
||||||
|
return new bignum(SecureRandom.getRandomBuffer(8));
|
||||||
|
};
|
||||||
|
|
||||||
module.exports = Key;
|
module.exports = Key;
|
||||||
|
|||||||
@ -148,6 +148,38 @@ describe('Key (ECKey)', function() {
|
|||||||
parsed.sbuf.toString('hex').should.equal('0993a6ec81755b9111762fc2cf8e3ede73047515622792110867d12654275e72');
|
parsed.sbuf.toString('hex').should.equal('0993a6ec81755b9111762fc2cf8e3ede73047515622792110867d12654275e72');
|
||||||
parsed.s.toString().should.equal('4331694221846364448463828256391194279133231453999942381442030409253074198130');
|
parsed.s.toString().should.equal('4331694221846364448463828256391194279133231453999942381442030409253074198130');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should parse this 69 byte signature', function() {
|
||||||
|
var sighex = '3043021f59e4705959cc78acbfcf8bd0114e9cc1b389a4287fb33152b73a38c319b50302202f7428a27284c757e409bf41506183e9e49dfb54d5063796dfa0d403a4deccfa';
|
||||||
|
var sig = new Buffer(sighex, 'hex');
|
||||||
|
var parsed = Key.parseDERsig(sig);
|
||||||
|
parsed.header.should.equal(0x30)
|
||||||
|
parsed.length.should.equal(67)
|
||||||
|
parsed.rlength.should.equal(31);
|
||||||
|
parsed.rneg.should.equal(false);
|
||||||
|
parsed.rbuf.toString('hex').should.equal('59e4705959cc78acbfcf8bd0114e9cc1b389a4287fb33152b73a38c319b503');
|
||||||
|
parsed.r.toString().should.equal('158826015856106182499128681792325160381907915189052224498209222621383996675');
|
||||||
|
parsed.slength.should.equal(32);
|
||||||
|
parsed.sneg.should.equal(false);
|
||||||
|
parsed.sbuf.toString('hex').should.equal('2f7428a27284c757e409bf41506183e9e49dfb54d5063796dfa0d403a4deccfa');
|
||||||
|
parsed.s.toString().should.equal('21463938592353267769710297084836796652964571266930856168996063301532842380538');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should parse this 68 byte signature', function() {
|
||||||
|
var sighex = '3042021e17cfe77536c3fb0526bd1a72d7a8e0973f463add210be14063c8a9c37632022061bfa677f825ded82ba0863fb0c46ca1388dd3e647f6a93c038168b59d131a51';
|
||||||
|
var sig = new Buffer(sighex, 'hex');
|
||||||
|
var parsed = Key.parseDERsig(sig);
|
||||||
|
parsed.header.should.equal(0x30)
|
||||||
|
parsed.length.should.equal(66)
|
||||||
|
parsed.rlength.should.equal(30);
|
||||||
|
parsed.rneg.should.equal(false);
|
||||||
|
parsed.rbuf.toString('hex').should.equal('17cfe77536c3fb0526bd1a72d7a8e0973f463add210be14063c8a9c37632');
|
||||||
|
parsed.r.toString().should.equal('164345250294671732127776123343329699648286106708464198588053542748255794');
|
||||||
|
parsed.slength.should.equal(32);
|
||||||
|
parsed.sneg.should.equal(false);
|
||||||
|
parsed.sbuf.toString('hex').should.equal('61bfa677f825ded82ba0863fb0c46ca1388dd3e647f6a93c038168b59d131a51');
|
||||||
|
parsed.s.toString().should.equal('44212963026209759051804639008236126356702363229859210154760104982946304432721');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('#rs2DER', function() {
|
describe('#rs2DER', function() {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user