ECSignature: fixes for canonical signatures

This commit is contained in:
Daniel Cousens 2014-06-20 15:25:23 +10:00
parent db5a6d08d1
commit 53595784e1
3 changed files with 79 additions and 13 deletions

View file

@ -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
}
}