|
|
@ -1,5 +1,4 @@ |
|
|
|
var assert = require('assert') |
|
|
|
|
|
|
|
var BigInteger = require('bigi') |
|
|
|
|
|
|
|
function ECSignature(r, s) { |
|
|
@ -34,28 +33,50 @@ ECSignature.parseCompact = function(buffer) { |
|
|
|
ECSignature.fromDER = function(buffer) { |
|
|
|
assert.equal(buffer.readUInt8(0), 0x30, 'Not a DER sequence') |
|
|
|
assert.equal(buffer.readUInt8(1), buffer.length - 2, 'Invalid sequence length') |
|
|
|
|
|
|
|
assert.equal(buffer.readUInt8(2), 0x02, 'Expected a DER integer') |
|
|
|
|
|
|
|
var rLen = buffer.readUInt8(3) |
|
|
|
var rB = buffer.slice(4, 4 + rLen) |
|
|
|
assert(rLen > 0, 'R length is zero') |
|
|
|
|
|
|
|
var offset = 4 + rLen |
|
|
|
assert.equal(buffer.readUInt8(offset), 0x02, 'Expected a DER integer (2)') |
|
|
|
var sLen = buffer.readUInt8(1 + offset) |
|
|
|
var sB = buffer.slice(2 + offset) |
|
|
|
|
|
|
|
var sLen = buffer.readUInt8(offset + 1) |
|
|
|
assert(sLen > 0, 'R length is zero') |
|
|
|
|
|
|
|
var rB = buffer.slice(4, offset) |
|
|
|
var sB = buffer.slice(offset + 2) |
|
|
|
offset += 2 + sLen |
|
|
|
|
|
|
|
if (rLen > 1 && rB.readUInt8(0) === 0x00) { |
|
|
|
assert(rB.readUInt8(1) & 0x80, 'R value excessively padded') |
|
|
|
} |
|
|
|
|
|
|
|
if (sLen > 1 && sB.readUInt8(0) === 0x00) { |
|
|
|
assert(sB.readUInt8(1) & 0x80, 'S value excessively padded') |
|
|
|
} |
|
|
|
|
|
|
|
assert.equal(offset, buffer.length, 'Invalid DER encoding') |
|
|
|
var r = BigInteger.fromDERInteger(rB) |
|
|
|
var s = BigInteger.fromDERInteger(sB) |
|
|
|
|
|
|
|
assert(r.signum() >= 0, 'R value is negative') |
|
|
|
assert(s.signum() >= 0, 'S value is negative') |
|
|
|
|
|
|
|
return new ECSignature(r, s) |
|
|
|
} |
|
|
|
|
|
|
|
// FIXME: 0x00, 0x04, 0x80 are SIGHASH_* boundary constants, importing Transaction causes a circular dependency
|
|
|
|
ECSignature.parseScriptSignature = function(buffer) { |
|
|
|
var hashType = buffer.readUInt8(buffer.length - 1) |
|
|
|
var hashTypeMod = hashType & ~0x80 |
|
|
|
|
|
|
|
assert(hashTypeMod > 0x00, 'Invalid hashType') |
|
|
|
assert(hashTypeMod < 0x04, 'Invalid hashType') |
|
|
|
|
|
|
|
return { |
|
|
|
signature: ECSignature.fromDER(buffer.slice(0, -1)), |
|
|
|
hashType: buffer.readUInt8(buffer.length - 1) |
|
|
|
hashType: hashType |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|