Merge pull request #423 from bitcoinjs/bip66adherance
adhere more closely to BIP66
This commit is contained in:
commit
a8f36ba515
3 changed files with 36 additions and 26 deletions
|
@ -32,39 +32,37 @@ ECSignature.parseCompact = function (buffer) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Strict DER - https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
|
||||||
|
// NOTE: SIGHASH byte ignored
|
||||||
ECSignature.fromDER = function (buffer) {
|
ECSignature.fromDER = function (buffer) {
|
||||||
assert.equal(buffer.readUInt8(0), 0x30, 'Not a DER sequence')
|
// Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
|
||||||
assert.equal(buffer.readUInt8(1), buffer.length - 2, 'Invalid sequence length')
|
if (buffer.length < 8) throw new Error('DER sequence too short')
|
||||||
assert.equal(buffer.readUInt8(2), 0x02, 'Expected a DER integer')
|
if (buffer.length > 72) throw new Error('DER sequence too long')
|
||||||
|
if (buffer[0] !== 0x30) throw new Error('Not a DER sequence')
|
||||||
|
if (buffer[1] !== buffer.length - 2) throw new Error('Invalid sequence length')
|
||||||
|
if (buffer[2] !== 0x02) throw new Error('Expected a DER integer')
|
||||||
|
|
||||||
var rLen = buffer.readUInt8(3)
|
var lenR = buffer.readUInt8(3)
|
||||||
assert(rLen > 0, 'R length is zero')
|
if (lenR === 0) throw new Error('R length is zero')
|
||||||
|
if (5 + lenR >= buffer.length) throw new Error('Invalid DER encoding')
|
||||||
|
if (buffer[4 + lenR] !== 0x02) throw new Error('Expected a DER integer (2)')
|
||||||
|
|
||||||
var offset = 4 + rLen
|
var lenS = buffer[5 + lenR]
|
||||||
assert.equal(buffer.readUInt8(offset), 0x02, 'Expected a DER integer (2)')
|
if (lenS === 0) throw new Error('S length is zero')
|
||||||
|
if ((lenR + lenS + 6) !== buffer.length) throw new Error('Invalid DER encoding (2)')
|
||||||
|
|
||||||
var sLen = buffer.readUInt8(offset + 1)
|
if (buffer[4] & 0x80) throw new Error('R value is negative')
|
||||||
assert(sLen > 0, 'S length is zero')
|
if (lenR > 1 && (buffer[4] === 0x00) && !(buffer[5] & 0x80)) throw new Error('R value excessively padded')
|
||||||
|
|
||||||
var rB = buffer.slice(4, offset)
|
if (buffer[lenR + 6] & 0x80) throw new Error('S value is negative')
|
||||||
var sB = buffer.slice(offset + 2)
|
if (lenS > 1 && (buffer[lenR + 6] === 0x00) && !(buffer[lenR + 7] & 0x80)) throw new Error('S value excessively padded')
|
||||||
offset += 2 + sLen
|
|
||||||
|
|
||||||
if (rLen > 1 && rB.readUInt8(0) === 0x00) {
|
// non-BIP66 - extract R, S values
|
||||||
assert(rB.readUInt8(1) & 0x80, 'R value excessively padded')
|
var rB = buffer.slice(4, 4 + lenR)
|
||||||
}
|
var sB = buffer.slice(lenR + 6)
|
||||||
|
|
||||||
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 r = BigInteger.fromDERInteger(rB)
|
||||||
var s = BigInteger.fromDERInteger(sB)
|
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)
|
return new ECSignature(r, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,7 +66,7 @@ describe('ECSignature', function () {
|
||||||
})
|
})
|
||||||
|
|
||||||
fixtures.invalid.DER.forEach(function (f) {
|
fixtures.invalid.DER.forEach(function (f) {
|
||||||
it('throws on ' + f.hex, function () {
|
it('throws "' + f.exception + '" for ' + f.hex, function () {
|
||||||
var buffer = new Buffer(f.hex, 'hex')
|
var buffer = new Buffer(f.hex, 'hex')
|
||||||
|
|
||||||
assert.throws(function () {
|
assert.throws(function () {
|
||||||
|
|
14
test/fixtures/ecsignature.json
vendored
14
test/fixtures/ecsignature.json
vendored
|
@ -129,6 +129,14 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"DER": [
|
"DER": [
|
||||||
|
{
|
||||||
|
"exception": "DER sequence too short",
|
||||||
|
"hex": "ffffffffffffff"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "DER sequence too long",
|
||||||
|
"hex": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"exception": "Invalid sequence length",
|
"exception": "Invalid sequence length",
|
||||||
"hex": "30ff020400ffffff020400ffffff"
|
"hex": "30ff020400ffffff020400ffffff"
|
||||||
|
@ -147,7 +155,11 @@
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"exception": "Invalid DER encoding",
|
"exception": "Invalid DER encoding",
|
||||||
"hex": "300c020400ffffff020200ffffff"
|
"hex": "300c0204ddffffff020200ffffff"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"exception": "Invalid DER encoding \\(2\\)",
|
||||||
|
"hex": "300c020400ffffff02dd00ffffff"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"exception": "R length is zero",
|
"exception": "R length is zero",
|
||||||
|
|
Loading…
Add table
Reference in a new issue