|
|
@ -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]); |
|
|
|