sign/verify with uncompressed pubkeys
This commit is contained in:
parent
a80d512570
commit
bc94a5cb59
|
@ -97,6 +97,7 @@ ECDSA.prototype.sig2pubkey = function() {
|
|||
var Q = R.mul(s).add(G.mul(eNeg)).mul(rInv);
|
||||
|
||||
var pubkey = new Pubkey(Q);
|
||||
pubkey.compressed = this.sig.compressed;
|
||||
pubkey.validate();
|
||||
|
||||
return pubkey;
|
||||
|
@ -156,7 +157,7 @@ ECDSA.prototype.sign = function() {
|
|||
var s = k.invm(N).mul(e.add(d.mul(r))).mod(N);
|
||||
} while (r.cmp(0) <= 0 || s.cmp(0) <= 0);
|
||||
|
||||
this.sig = new Signature(r, s);
|
||||
this.sig = new Signature(r, s, undefined, this.key.pubkey.compressed);
|
||||
return this.sig;
|
||||
};
|
||||
|
||||
|
|
|
@ -65,7 +65,7 @@ Message.prototype.verify = function() {
|
|||
return this;
|
||||
}
|
||||
|
||||
var address = Address().fromPubkey(ecdsa.key.pubkey);
|
||||
var address = Address().fromPubkey(ecdsa.key.pubkey, undefined, this.sig.compressed);
|
||||
//TODO: what if livenet/testnet mismatch?
|
||||
if (address.hashbuf.toString('hex') === this.address.hashbuf.toString('hex'))
|
||||
this.verified = true;
|
||||
|
|
|
@ -2,17 +2,25 @@ var BN = require('./bn');
|
|||
var Point = require('./point');
|
||||
var Pubkey = require('./pubkey');
|
||||
|
||||
var Signature = function Signature(r, s, i) {
|
||||
var Signature = function Signature(r, s, i, compressed) {
|
||||
if (!(this instanceof Signature))
|
||||
return new Signature(r, s, i);
|
||||
return new Signature(r, s, i, compressed);
|
||||
|
||||
this.r = r;
|
||||
this.s = s;
|
||||
this.i = i; //public key recovery parameter in range [0, 3]
|
||||
this.compressed = compressed;
|
||||
};
|
||||
|
||||
Signature.prototype.fromCompact = function(buf) {
|
||||
var compressed = true;
|
||||
if (i < 0) {
|
||||
var compressed = false;
|
||||
i = i + 4;
|
||||
}
|
||||
|
||||
var i = buf.slice(0, 1)[0] - 27 - 4; //TODO: handle uncompressed pubkeys
|
||||
|
||||
var b2 = buf.slice(1, 33);
|
||||
var b3 = buf.slice(33, 65);
|
||||
|
||||
|
@ -23,6 +31,7 @@ Signature.prototype.fromCompact = function(buf) {
|
|||
if (b3.length !== 32)
|
||||
throw new Error('s must be 32 bytes');
|
||||
|
||||
this.compressed = compressed;
|
||||
this.i = i;
|
||||
this.r = BN().fromBuffer(b2);
|
||||
this.s = BN().fromBuffer(b3);
|
||||
|
@ -102,12 +111,17 @@ Signature.parseDER = function(buf) {
|
|||
return obj;
|
||||
};
|
||||
|
||||
Signature.prototype.toCompact = function(i) {
|
||||
Signature.prototype.toCompact = function(i, compressed) {
|
||||
i = typeof i === 'number' ? i : this.i;
|
||||
compressed = typeof compressed === 'boolean' ? compressed : this.compressed;
|
||||
|
||||
if (!(i === 0 || i === 1 || i === 2 || i === 3))
|
||||
throw new Error('i must be equal to 0, 1, 2, or 3');
|
||||
|
||||
var b1 = new Buffer([i + 27 + 4]); //TODO: handle uncompressed pubkeys
|
||||
var val = i + 27 + 4;
|
||||
if (compressed === false)
|
||||
val = val - 4;
|
||||
var b1 = new Buffer([val]);
|
||||
var b2 = this.r.toBuffer({size: 32});
|
||||
var b3 = this.s.toBuffer({size: 32});
|
||||
return Buffer.concat([b1, b2, b3]);
|
||||
|
|
|
@ -56,6 +56,24 @@ describe('Message', function() {
|
|||
sigbuf.length.should.equal(1 + 32 + 32);
|
||||
});
|
||||
|
||||
it('should sign with a compressed pubkey', function() {
|
||||
var key = Key().fromRandom();
|
||||
key.pubkey.compressed = true;
|
||||
var sigstr = Message.sign(messagebuf, key);
|
||||
var sigbuf = new Buffer(sigstr, 'base64');
|
||||
sigbuf[0].should.be.above(27 + 4 - 1);
|
||||
sigbuf[0].should.be.below(27 + 4 + 4 - 1);
|
||||
});
|
||||
|
||||
it('should sign with an uncompressed pubkey', function() {
|
||||
var key = Key().fromRandom();
|
||||
key.pubkey.compressed = false;
|
||||
var sigstr = Message.sign(messagebuf, key);
|
||||
var sigbuf = new Buffer(sigstr, 'base64');
|
||||
sigbuf[0].should.be.above(27 - 1);
|
||||
sigbuf[0].should.be.below(27 + 4 - 1);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
describe('@verify', function() {
|
||||
|
|
Loading…
Reference in New Issue