Browse Source

Merge pull request #459 from bitcoinjs/nocompact

Remove explicit DER/Compact decoding
addLowRGrinding
Daniel Cousens 7 years ago
committed by GitHub
parent
commit
087b49ea23
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      package.json
  2. 6
      src/ecdsa.js
  3. 97
      src/ecsignature.js
  4. 1
      src/index.js
  5. 1
      src/script.js
  6. 60
      src/script_signature.js
  7. 7
      src/transaction_builder.js
  8. 9
      test/bitcoin.core.js
  9. 31
      test/ecdsa.js
  10. 122
      test/ecsignature.js
  11. 61
      test/fixtures/ecdsa.json
  12. 214
      test/fixtures/ecsignature.json
  13. 140
      test/fixtures/signature.json
  14. 11
      test/integration/cltv.js
  15. 2
      test/integration/crypto.js
  16. 2
      test/integration/transactions.js
  17. 66
      test/script_signature.js

2
package.json

@ -41,7 +41,7 @@
"merkle-lib": "^2.0.10", "merkle-lib": "^2.0.10",
"pushdata-bitcoin": "^1.0.1", "pushdata-bitcoin": "^1.0.1",
"randombytes": "^2.0.1", "randombytes": "^2.0.1",
"safe-buffer": "^5.0.1", "safe-buffer": "^5.1.1",
"typeforce": "^1.11.3", "typeforce": "^1.11.3",
"varuint-bitcoin": "^1.0.4", "varuint-bitcoin": "^1.0.4",
"wif": "^2.0.1" "wif": "^2.0.1"

6
src/ecdsa.js

@ -4,7 +4,6 @@ var typeforce = require('typeforce')
var types = require('./types') var types = require('./types')
var BigInteger = require('bigi') var BigInteger = require('bigi')
var ECSignature = require('./ecsignature')
var ZERO = Buffer.alloc(1, 0) var ZERO = Buffer.alloc(1, 0)
var ONE = Buffer.alloc(1, 1) var ONE = Buffer.alloc(1, 1)
@ -102,7 +101,10 @@ function sign (hash, d) {
s = n.subtract(s) s = n.subtract(s)
} }
return new ECSignature(r, s) return {
r: r,
s: s
}
} }
function verify (hash, signature, Q) { function verify (hash, signature, Q) {

97
src/ecsignature.js

@ -1,97 +0,0 @@
var bip66 = require('bip66')
var typeforce = require('typeforce')
var types = require('./types')
var BigInteger = require('bigi')
function ECSignature (r, s) {
typeforce(types.tuple(types.BigInt, types.BigInt), arguments)
this.r = r
this.s = s
}
ECSignature.parseCompact = function (buffer) {
typeforce(types.BufferN(65), buffer)
var flagByte = buffer.readUInt8(0) - 27
if (flagByte !== (flagByte & 7)) throw new Error('Invalid signature parameter')
var compressed = !!(flagByte & 4)
var recoveryParam = flagByte & 3
var signature = ECSignature.fromRSBuffer(buffer.slice(1))
return {
compressed: compressed,
i: recoveryParam,
signature: signature
}
}
ECSignature.fromRSBuffer = function (buffer) {
typeforce(types.BufferN(64), buffer)
var r = BigInteger.fromBuffer(buffer.slice(0, 32))
var s = BigInteger.fromBuffer(buffer.slice(32, 64))
return new ECSignature(r, s)
}
ECSignature.fromDER = function (buffer) {
var decode = bip66.decode(buffer)
var r = BigInteger.fromDERInteger(decode.r)
var s = BigInteger.fromDERInteger(decode.s)
return new ECSignature(r, s)
}
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
ECSignature.parseScriptSignature = function (buffer) {
var hashType = buffer.readUInt8(buffer.length - 1)
var hashTypeMod = hashType & ~0x80
if (hashTypeMod <= 0x00 || hashTypeMod >= 0x04) throw new Error('Invalid hashType ' + hashType)
return {
signature: ECSignature.fromDER(buffer.slice(0, -1)),
hashType: hashType
}
}
ECSignature.prototype.toCompact = function (i, compressed) {
if (compressed) {
i += 4
}
i += 27
var buffer = Buffer.alloc(65)
buffer.writeUInt8(i, 0)
this.toRSBuffer(buffer, 1)
return buffer
}
ECSignature.prototype.toDER = function () {
var r = Buffer.from(this.r.toDERInteger())
var s = Buffer.from(this.s.toDERInteger())
return bip66.encode(r, s)
}
ECSignature.prototype.toRSBuffer = function (buffer, offset) {
buffer = buffer || Buffer.alloc(64)
this.r.toBuffer(32).copy(buffer, offset)
this.s.toBuffer(32).copy(buffer, offset + 32)
return buffer
}
ECSignature.prototype.toScriptSignature = function (hashType) {
var hashTypeMod = hashType & ~0x80
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
var hashTypeBuffer = Buffer.alloc(1)
hashTypeBuffer.writeUInt8(hashType, 0)
return Buffer.concat([this.toDER(), hashTypeBuffer])
}
module.exports = ECSignature

1
src/index.js

@ -8,7 +8,6 @@ for (var key in templates) {
module.exports = { module.exports = {
Block: require('./block'), Block: require('./block'),
ECPair: require('./ecpair'), ECPair: require('./ecpair'),
ECSignature: require('./ecsignature'),
HDNode: require('./hdnode'), HDNode: require('./hdnode'),
Transaction: require('./transaction'), Transaction: require('./transaction'),
TransactionBuilder: require('./transaction_builder'), TransactionBuilder: require('./transaction_builder'),

1
src/script.js

@ -206,6 +206,7 @@ module.exports = {
toStack: toStack, toStack: toStack,
number: require('./script_number'), number: require('./script_number'),
signature: require('./script_signature'),
isCanonicalPubKey: isCanonicalPubKey, isCanonicalPubKey: isCanonicalPubKey,
isCanonicalSignature: isCanonicalSignature, isCanonicalSignature: isCanonicalSignature,

60
src/script_signature.js

@ -0,0 +1,60 @@
var bip66 = require('bip66')
var BigInteger = require('bigi')
var Buffer = require('safe-buffer').Buffer
var typeforce = require('typeforce')
var types = require('./types')
// BIP62: 1 byte hashType flag (only 0x01, 0x02, 0x03, 0x81, 0x82 and 0x83 are allowed)
function decode (buffer) {
var hashType = buffer.readUInt8(buffer.length - 1)
var hashTypeMod = hashType & ~0x80
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
var decode = bip66.decode(buffer.slice(0, -1))
return {
signature: {
r: BigInteger.fromDERInteger(decode.r),
s: BigInteger.fromDERInteger(decode.s)
},
hashType: hashType
}
}
function toRSBuffer (signature, buffer, offset) {
buffer = buffer || Buffer.alloc(64)
signature.r.toBuffer(32).copy(buffer, offset)
signature.s.toBuffer(32).copy(buffer, offset + 32)
return buffer
}
function fromRSBuffer (buffer) {
typeforce(types.BufferN(64), buffer)
var r = BigInteger.fromBuffer(buffer.slice(0, 32))
var s = BigInteger.fromBuffer(buffer.slice(32, 64))
return { r: r, s: s }
}
function encode (signature, hashType) {
var hashTypeMod = hashType & ~0x80
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
var hashTypeBuffer = Buffer.allocUnsafe(1)
hashTypeBuffer.writeUInt8(hashType, 0)
var r = Buffer.from(signature.r.toDERInteger())
var s = Buffer.from(signature.s.toDERInteger())
return Buffer.concat([
bip66.encode(r, s),
hashTypeBuffer
])
}
module.exports = {
fromRSBuffer: fromRSBuffer,
toRSBuffer: toRSBuffer,
decode: decode,
encode: encode
}

7
src/transaction_builder.js

@ -12,7 +12,6 @@ var SIGNABLE = [btemplates.types.P2PKH, btemplates.types.P2PK, btemplates.types.
var P2SH = SIGNABLE.concat([btemplates.types.P2WPKH, btemplates.types.P2WSH]) var P2SH = SIGNABLE.concat([btemplates.types.P2WPKH, btemplates.types.P2WSH])
var ECPair = require('./ecpair') var ECPair = require('./ecpair')
var ECSignature = require('./ecsignature')
var Transaction = require('./transaction') var Transaction = require('./transaction')
function supportedType (type) { function supportedType (type) {
@ -190,7 +189,7 @@ function fixMultisigOrder (input, transaction, vin) {
if (!signature) return false if (!signature) return false
// TODO: avoid O(n) hashForSignature // TODO: avoid O(n) hashForSignature
var parsed = ECSignature.parseScriptSignature(signature) var parsed = bscript.signature.decode(signature)
var hash = transaction.hashForSignature(vin, input.redeemScript, parsed.hashType) var hash = transaction.hashForSignature(vin, input.redeemScript, parsed.hashType)
// skip if signature does not match pubKey // skip if signature does not match pubKey
@ -717,9 +716,9 @@ TransactionBuilder.prototype.sign = function (vin, keyPair, redeemScript, hashTy
)) throw new Error('BIP143 rejects uncompressed public keys in P2WPKH or P2WSH') )) throw new Error('BIP143 rejects uncompressed public keys in P2WPKH or P2WSH')
var signature = keyPair.sign(signatureHash) var signature = keyPair.sign(signatureHash)
if (Buffer.isBuffer(signature)) signature = ECSignature.fromRSBuffer(signature) if (Buffer.isBuffer(signature)) signature = bscript.signature.fromRSBuffer(signature)
input.signatures[i] = signature.toScriptSignature(hashType) input.signatures[i] = bscript.signature.encode(signature, hashType)
return true return true
}) })

9
test/bitcoin.core.js

@ -198,13 +198,14 @@ describe('Bitcoin-core', function () {
}) })
}) })
describe('ECSignature.parseScriptSignature', function () { describe('script.signature.decode', function () {
sigCanonical.forEach(function (hex) { sigCanonical.forEach(function (hex) {
var buffer = Buffer.from(hex, 'hex') var buffer = Buffer.from(hex, 'hex')
it('can parse ' + hex, function () { it('can parse ' + hex, function () {
var parsed = bitcoin.ECSignature.parseScriptSignature(buffer) var parsed = bitcoin.script.signature.decode(buffer)
var actual = parsed.signature.toScriptSignature(parsed.hashType) var actual = bitcoin.script.signature.encode(parsed.signature, parsed.hashType)
assert.strictEqual(actual.toString('hex'), hex) assert.strictEqual(actual.toString('hex'), hex)
}) })
}) })
@ -218,7 +219,7 @@ describe('Bitcoin-core', function () {
it('throws on ' + description, function () { it('throws on ' + description, function () {
assert.throws(function () { assert.throws(function () {
bitcoin.ECSignature.parseScriptSignature(buffer) bitcoin.script.signature.decode(buffer)
}, /Expected DER (integer|sequence)|(R|S) value (excessively padded|is negative)|(R|S|DER sequence) length is (zero|too short|too long|invalid)|Invalid hashType/) }, /Expected DER (integer|sequence)|(R|S) value (excessively padded|is negative)|(R|S|DER sequence) length is (zero|too short|too long|invalid)|Invalid hashType/)
}) })
}) })

31
test/ecdsa.js

@ -2,17 +2,31 @@
var assert = require('assert') var assert = require('assert')
var bcrypto = require('../src/crypto') var bcrypto = require('../src/crypto')
var bscript = require('../src/script')
var ecdsa = require('../src/ecdsa') var ecdsa = require('../src/ecdsa')
var hoodwink = require('hoodwink') var hoodwink = require('hoodwink')
var BigInteger = require('bigi') var BigInteger = require('bigi')
var ECSignature = require('../src/ecsignature')
var curve = ecdsa.__curve var curve = ecdsa.__curve
var fixtures = require('./fixtures/ecdsa.json') var fixtures = require('./fixtures/ecdsa.json')
describe('ecdsa', function () { describe('ecdsa', function () {
function fromRaw (signature) {
return {
r: new BigInteger(signature.r, 16),
s: new BigInteger(signature.s, 16)
}
}
function toRaw (signature) {
return {
r: signature.r.toHex(),
s: signature.s.toHex()
}
}
describe('deterministicGenerateK', function () { describe('deterministicGenerateK', function () {
function checkSig () { function checkSig () {
return true return true
@ -80,9 +94,9 @@ describe('ecdsa', function () {
it('produces a deterministic signature for "' + f.message + '"', function () { it('produces a deterministic signature for "' + f.message + '"', function () {
var d = BigInteger.fromHex(f.d) var d = BigInteger.fromHex(f.d)
var hash = bcrypto.sha256(f.message) var hash = bcrypto.sha256(f.message)
var signature = ecdsa.sign(hash, d).toDER() var signature = ecdsa.sign(hash, d)
assert.strictEqual(signature.toString('hex'), f.signature) assert.deepEqual(toRaw(signature), f.signature)
}) })
}) })
@ -101,7 +115,7 @@ describe('ecdsa', function () {
it('verifies a valid signature for "' + f.message + '"', function () { it('verifies a valid signature for "' + f.message + '"', function () {
var d = BigInteger.fromHex(f.d) var d = BigInteger.fromHex(f.d)
var H = bcrypto.sha256(f.message) var H = bcrypto.sha256(f.message)
var signature = ECSignature.fromDER(Buffer.from(f.signature, 'hex')) var signature = fromRaw(f.signature)
var Q = curve.G.multiply(d) var Q = curve.G.multiply(d)
assert(ecdsa.verify(H, signature, Q)) assert(ecdsa.verify(H, signature, Q))
@ -112,14 +126,7 @@ describe('ecdsa', function () {
it('fails to verify with ' + f.description, function () { it('fails to verify with ' + f.description, function () {
var H = bcrypto.sha256(f.message) var H = bcrypto.sha256(f.message)
var d = BigInteger.fromHex(f.d) var d = BigInteger.fromHex(f.d)
var signature = fromRaw(f.signature)
var signature
if (f.signature) {
signature = ECSignature.fromDER(Buffer.from(f.signature, 'hex'))
} else if (f.signatureRaw) {
signature = new ECSignature(new BigInteger(f.signatureRaw.r, 16), new BigInteger(f.signatureRaw.s, 16))
}
var Q = curve.G.multiply(d) var Q = curve.G.multiply(d)
assert.strictEqual(ecdsa.verify(H, signature, Q), false) assert.strictEqual(ecdsa.verify(H, signature, Q), false)

122
test/ecsignature.js

@ -1,122 +0,0 @@
/* global describe, it */
var assert = require('assert')
var BigInteger = require('bigi')
var ECSignature = require('../src/ecsignature')
var fixtures = require('./fixtures/ecsignature.json')
describe('ECSignature', function () {
describe('toCompact', function () {
fixtures.valid.forEach(function (f) {
it('exports ' + f.compact.hex + ' correctly', function () {
var signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s))
var buffer = signature.toCompact(f.compact.i, f.compact.compressed)
assert.strictEqual(buffer.toString('hex'), f.compact.hex)
})
})
})
describe('parseCompact', function () {
fixtures.valid.forEach(function (f) {
it('imports ' + f.compact.hex + ' correctly', function () {
var buffer = Buffer.from(f.compact.hex, 'hex')
var parsed = ECSignature.parseCompact(buffer)
assert.strictEqual(parsed.compressed, f.compact.compressed)
assert.strictEqual(parsed.i, f.compact.i)
assert.strictEqual(parsed.signature.r.toString(), f.signature.r)
assert.strictEqual(parsed.signature.s.toString(), f.signature.s)
})
})
fixtures.invalid.compact.forEach(function (f) {
it('throws on ' + f.hex, function () {
var buffer = Buffer.from(f.hex, 'hex')
assert.throws(function () {
ECSignature.parseCompact(buffer)
}, new RegExp(f.exception))
})
})
})
describe('toDER', function () {
fixtures.valid.forEach(function (f) {
it('exports ' + f.DER + ' correctly', function () {
var signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s))
var DER = signature.toDER()
assert.strictEqual(DER.toString('hex'), f.DER)
})
})
})
describe('fromDER', function () {
fixtures.valid.forEach(function (f) {
it('imports ' + f.DER + ' correctly', function () {
var buffer = Buffer.from(f.DER, 'hex')
var signature = ECSignature.fromDER(buffer)
assert.strictEqual(signature.r.toString(), f.signature.r)
assert.strictEqual(signature.s.toString(), f.signature.s)
})
})
fixtures.invalid.DER.forEach(function (f) {
it('throws "' + f.exception + '" for ' + f.hex, function () {
var buffer = Buffer.from(f.hex, 'hex')
assert.throws(function () {
ECSignature.fromDER(buffer)
}, new RegExp(f.exception))
})
})
})
describe('toScriptSignature', function () {
fixtures.valid.forEach(function (f) {
it('exports ' + f.scriptSignature.hex + ' correctly', function () {
var signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s))
var scriptSignature = signature.toScriptSignature(f.scriptSignature.hashType)
assert.strictEqual(scriptSignature.toString('hex'), f.scriptSignature.hex)
})
})
fixtures.invalid.scriptSignature.forEach(function (f) {
it('throws ' + f.exception, function () {
var signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s))
assert.throws(function () {
signature.toScriptSignature(f.hashType)
}, new RegExp(f.exception))
})
})
})
describe('parseScriptSignature', function () {
fixtures.valid.forEach(function (f) {
it('imports ' + f.scriptSignature.hex + ' correctly', function () {
var buffer = Buffer.from(f.scriptSignature.hex, 'hex')
var parsed = ECSignature.parseScriptSignature(buffer)
assert.strictEqual(parsed.signature.r.toString(), f.signature.r)
assert.strictEqual(parsed.signature.s.toString(), f.signature.s)
assert.strictEqual(parsed.hashType, f.scriptSignature.hashType)
})
})
fixtures.invalid.scriptSignature.forEach(function (f) {
it('throws on ' + f.hex, function () {
var buffer = Buffer.from(f.hex, 'hex')
assert.throws(function () {
ECSignature.parseScriptSignature(buffer)
}, new RegExp(f.exception))
})
})
})
})

61
test/fixtures/ecdsa.json

@ -5,50 +5,64 @@
"d": "01", "d": "01",
"k": "ec633bd56a5774a0940cb97e27a9e4e51dc94af737596a0c5cbb3d30332d92a5", "k": "ec633bd56a5774a0940cb97e27a9e4e51dc94af737596a0c5cbb3d30332d92a5",
"message": "Everything should be made as simple as possible, but not simpler.", "message": "Everything should be made as simple as possible, but not simpler.",
"i": 0, "signature": {
"signature": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262" "r": "33a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c9",
"s": "6f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262"
}
}, },
{ {
"d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
"k": "9dc74cbfd383980fb4ae5d2680acddac9dac956dca65a28c80ac9c847c2374e4", "k": "9dc74cbfd383980fb4ae5d2680acddac9dac956dca65a28c80ac9c847c2374e4",
"message": "Equations are more important to me, because politics is for the present, but an equation is something for eternity.", "message": "Equations are more important to me, because politics is for the present, but an equation is something for eternity.",
"i": 0, "signature": {
"signature": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5" "r": "54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed",
"s": "07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5"
}
}, },
{ {
"d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140", "d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
"k": "fd27071f01648ebbdd3e1cfbae48facc9fa97edc43bbbc9a7fdc28eae13296f5", "k": "fd27071f01648ebbdd3e1cfbae48facc9fa97edc43bbbc9a7fdc28eae13296f5",
"message": "Not only is the Universe stranger than we think, it is stranger than we can think.", "message": "Not only is the Universe stranger than we think, it is stranger than we can think.",
"i": 0, "signature": {
"signature": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283" "r": "ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd0",
"s": "6fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283"
}
}, },
{ {
"d": "0000000000000000000000000000000000000000000000000000000000000001", "d": "0000000000000000000000000000000000000000000000000000000000000001",
"k": "f0cd2ba5fc7c183de589f6416220a36775a146740798756d8d949f7166dcc87f", "k": "f0cd2ba5fc7c183de589f6416220a36775a146740798756d8d949f7166dcc87f",
"message": "How wonderful that we have met with a paradox. Now we have some hope of making progress.", "message": "How wonderful that we have met with a paradox. Now we have some hope of making progress.",
"i": 1, "signature": {
"signature": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3" "r": "c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3",
"s": "75afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3"
}
}, },
{ {
"d": "69ec59eaa1f4f2e36b639716b7c30ca86d9a5375c7b38d8918bd9c0ebc80ba64", "d": "69ec59eaa1f4f2e36b639716b7c30ca86d9a5375c7b38d8918bd9c0ebc80ba64",
"k": "6bb4a594ad57c1aa22dbe991a9d8501daf4688bf50a4892ef21bd7c711afda97", "k": "6bb4a594ad57c1aa22dbe991a9d8501daf4688bf50a4892ef21bd7c711afda97",
"message": "Computer science is no more about computers than astronomy is about telescopes.", "message": "Computer science is no more about computers than astronomy is about telescopes.",
"i": 0, "signature": {
"signature": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6" "r": "7186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d",
"s": "0de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6"
}
}, },
{ {
"d": "00000000000000000000000000007246174ab1e92e9149c6e446fe194d072637", "d": "00000000000000000000000000007246174ab1e92e9149c6e446fe194d072637",
"k": "097b5c8ee22c3ea78a4d3635e0ff6fe85a1eb92ce317ded90b9e71aab2b861cb", "k": "097b5c8ee22c3ea78a4d3635e0ff6fe85a1eb92ce317ded90b9e71aab2b861cb",
"message": "...if you aren't, at any given time, scandalized by code you wrote five or even three years ago, you're not learning anywhere near enough", "message": "...if you aren't, at any given time, scandalized by code you wrote five or even three years ago, you're not learning anywhere near enough",
"i": 1, "signature": {
"signature": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37" "r": "fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda487",
"s": "0e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37"
}
}, },
{ {
"d": "000000000000000000000000000000000000000000056916d0f9b31dc9b637f3", "d": "000000000000000000000000000000000000000000056916d0f9b31dc9b637f3",
"k": "19355c36c8cbcdfb2382e23b194b79f8c97bf650040fc7728dfbf6b39a97c25b", "k": "19355c36c8cbcdfb2382e23b194b79f8c97bf650040fc7728dfbf6b39a97c25b",
"message": "The question of whether computers can think is like the question of whether submarines can swim.", "message": "The question of whether computers can think is like the question of whether submarines can swim.",
"i": 1, "signature": {
"signature": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef" "r": "cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9",
"s": "06ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef"
}
} }
], ],
"rfc6979": [ "rfc6979": [
@ -130,13 +144,16 @@
"description": "The wrong signature", "description": "The wrong signature",
"d": "01", "d": "01",
"message": "foo", "message": "foo",
"signature": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5" "signature": {
"r": "54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed",
"s": "07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5"
}
}, },
{ {
"description": "Invalid r value (< 0)", "description": "Invalid r value (< 0)",
"d": "01", "d": "01",
"message": "foo", "message": "foo",
"signatureRaw": { "signature": {
"r": "-01", "r": "-01",
"s": "02" "s": "02"
} }
@ -145,7 +162,7 @@
"description": "Invalid r value (== 0)", "description": "Invalid r value (== 0)",
"d": "01", "d": "01",
"message": "foo", "message": "foo",
"signatureRaw": { "signature": {
"r": "00", "r": "00",
"s": "02" "s": "02"
} }
@ -154,7 +171,7 @@
"description": "Invalid r value (>= n)", "description": "Invalid r value (>= n)",
"d": "01", "d": "01",
"message": "foo", "message": "foo",
"signatureRaw": { "signature": {
"r": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", "r": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
"s": "02" "s": "02"
} }
@ -163,7 +180,7 @@
"description": "Invalid s value (< 0)", "description": "Invalid s value (< 0)",
"d": "01", "d": "01",
"message": "foo", "message": "foo",
"signatureRaw": { "signature": {
"r": "02", "r": "02",
"s": "-01" "s": "-01"
} }
@ -172,7 +189,7 @@
"description": "Invalid s value (== 0)", "description": "Invalid s value (== 0)",
"d": "01", "d": "01",
"message": "foo", "message": "foo",
"signatureRaw": { "signature": {
"r": "02", "r": "02",
"s": "00" "s": "00"
} }
@ -181,7 +198,7 @@
"description": "Invalid s value (>= n)", "description": "Invalid s value (>= n)",
"d": "01", "d": "01",
"message": "foo", "message": "foo",
"signatureRaw": { "signature": {
"r": "02", "r": "02",
"s": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" "s": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"
} }
@ -190,7 +207,7 @@
"description": "Invalid r, s values (r = s = -n)", "description": "Invalid r, s values (r = s = -n)",
"d": "01", "d": "01",
"message": "foo", "message": "foo",
"signatureRaw": { "signature": {
"r": "-fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141", "r": "-fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
"s": "-fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141" "s": "-fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"
} }

214
test/fixtures/ecsignature.json

@ -1,214 +0,0 @@
{
"valid": [
{
"compact": {
"hex": "1f33a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c96f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262",
"compressed": true,
"i": 0
},
"scriptSignature": {
"hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa5434226201",
"hashType": 1
},
"DER": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262",
"signature": {
"r": "23362334225185207751494092901091441011938859014081160902781146257181456271561",
"s": "50433721247292933944369538617440297985091596895097604618403996029256432099938"
}
},
{
"compact": {
"hex": "1b54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5",
"compressed": false,
"i": 0
},
"DER": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5",
"scriptSignature": {
"hex": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a502",
"hashType": 2
},
"signature": {
"r": "38341707918488238920692284707283974715538935465589664377561695343399725051885",
"s": "3180566392414476763164587487324397066658063772201694230600609996154610926757"
}
},
{
"compact": {
"hex": "1fff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd06fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283",
"compressed": true,
"i": 0
},
"scriptSignature": {
"hex": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b28303",
"hashType": 3
},
"DER": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283",
"signature": {
"r": "115464191557905790016094131873849783294273568009648050793030031933291767741904",
"s": "50562520307781850052192542766631199590053690478900449960232079510155113443971"
}
},
{
"compact": {
"hex": "1cc0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d375afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3",
"compressed": false,
"i": 1
},
"scriptSignature": {
"hex": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d381",
"hashType": 129
},
"DER": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3",
"signature": {
"r": "87230998027579607140680851455601772643840468630989315269459846730712163783123",
"s": "53231320085894623106179381504478252331065330583563809963303318469380290929875"
}
},
{
"compact": {
"hex": "1f7186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d0de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6",
"compressed": true,
"i": 0
},
"scriptSignature": {
"hex": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df682",
"hashType": 130
},
"DER": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6",
"signature": {
"r": "51348483531757779992459563033975330355971795607481991320287437101831125115997",
"s": "6277080015686056199074771961940657638578000617958603212944619747099038735862"
}
},
{
"compact": {
"hex": "1cfbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda4870e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37",
"compressed": false,
"i": 1
},
"scriptSignature": {
"hex": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd3783",
"hashType": 131
},
"DER": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37",
"signature": {
"r": "113979859486826658566290715281614250298918272782414232881639314569529560769671",
"s": "6517071009538626957379450615706485096874328019806177698938278220732027419959"
}
},
{
"compact": {
"hex": "20cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf906ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef",
"compressed": true,
"i": 1
},
"scriptSignature": {
"hex": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef81",
"hashType": 129
},
"DER": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef",
"signature": {
"r": "93122007060065279508564838030979550535085999589142852106617159184757394422777",
"s": "3078539468410661027472930027406594684630312677495124015420811882501887769839"
}
}
],
"invalid": {
"compact": [
{
"exception": "Invalid signature parameter",
"hex": "23987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e93791d7629795b62"
},
{
"exception": "Expected Buffer\\(Length: 65\\), got Buffer\\(Length: 68\\)",
"hex": "1c987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e93791d7629795b62000000"
},
{
"exception": "Expected Buffer\\(Length: 65\\), got Buffer\\(Length: 59\\)",
"hex": "1c987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e9379"
}
],
"DER": [
{
"exception": "DER sequence length is too short",
"hex": "ffffffffffffff"
},
{
"exception": "DER sequence length is too long",
"hex": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
},
{
"exception": "Expected DER sequence",
"hex": "00ffff0400ffffff020400ffffff"
},
{
"exception": "DER sequence length is invalid",
"hex": "30ff020400ffffff020400ffffff"
},
{
"exception": "DER sequence length is invalid",
"hex": "300c030400ffffff030400ffffff0000"
},
{
"exception": "Expected DER integer",
"hex": "300cff0400ffffff020400ffffff"
},
{
"exception": "Expected DER integer \\(2\\)",
"hex": "300c020200ffffff020400ffffff"
},
{
"exception": "R length is zero",
"hex": "30080200020400ffffff"
},
{
"exception": "S length is zero",
"hex": "3008020400ffffff0200"
},
{
"exception": "R length is too long",
"hex": "300c02dd00ffffff020400ffffff"
},
{
"exception": "S length is invalid",
"hex": "300c020400ffffff02dd00ffffff"
},
{
"exception": "R value is negative",
"hex": "300c020480000000020400ffffff"
},
{
"exception": "S value is negative",
"hex": "300c020400ffffff020480000000"
},
{
"exception": "R value excessively padded",
"hex": "300c02040000ffff020400ffffff"
},
{
"exception": "S value excessively padded",
"hex": "300c020400ffffff02040000ffff"
}
],
"scriptSignature": [
{
"exception": "Invalid hashType 7",
"hashType": 7,
"hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa5434226207",
"signature": {
"r": "23362334225185207751494092901091441011938859014081160902781146257181456271561",
"s": "50433721247292933944369538617440297985091596895097604618403996029256432099938"
}
},
{
"exception": "Invalid hashType 140",
"hashType": 140,
"hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa543422628c",
"signature": {
"r": "23362334225185207751494092901091441011938859014081160902781146257181456271561",
"s": "50433721247292933944369538617440297985091596895097604618403996029256432099938"
}
}
]
}
}

140
test/fixtures/signature.json

@ -0,0 +1,140 @@
{
"valid": [
{
"hashType": 1,
"hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa5434226201",
"raw": {
"r": "23362334225185207751494092901091441011938859014081160902781146257181456271561",
"s": "50433721247292933944369538617440297985091596895097604618403996029256432099938"
}
},
{
"hashType": 2,
"hex": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a502",
"raw": {
"r": "38341707918488238920692284707283974715538935465589664377561695343399725051885",
"s": "3180566392414476763164587487324397066658063772201694230600609996154610926757"
}
},
{
"hashType": 3,
"hex": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b28303",
"raw": {
"r": "115464191557905790016094131873849783294273568009648050793030031933291767741904",
"s": "50562520307781850052192542766631199590053690478900449960232079510155113443971"
}
},
{
"hashType": 129,
"hex": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d381",
"raw": {
"r": "87230998027579607140680851455601772643840468630989315269459846730712163783123",
"s": "53231320085894623106179381504478252331065330583563809963303318469380290929875"
}
},
{
"hashType": 130,
"hex": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df682",
"raw": {
"r": "51348483531757779992459563033975330355971795607481991320287437101831125115997",
"s": "6277080015686056199074771961940657638578000617958603212944619747099038735862"
}
},
{
"hashType": 131,
"hex": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd3783",
"raw": {
"r": "113979859486826658566290715281614250298918272782414232881639314569529560769671",
"s": "6517071009538626957379450615706485096874328019806177698938278220732027419959"
}
},
{
"hashType": 129,
"hex": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef81",
"raw": {
"r": "93122007060065279508564838030979550535085999589142852106617159184757394422777",
"s": "3078539468410661027472930027406594684630312677495124015420811882501887769839"
}
}
],
"invalid": [
{
"exception": "DER sequence length is too short",
"hex": "ffffffffffffff01"
},
{
"exception": "DER sequence length is too long",
"hex": "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff01"
},
{
"exception": "Expected DER sequence",
"hex": "00ffff0400ffffff020400ffffff01"
},
{
"exception": "DER sequence length is invalid",
"hex": "30ff020400ffffff020400ffffff01"
},
{
"exception": "DER sequence length is invalid",
"hex": "300c030400ffffff030400ffffff000001"
},
{
"exception": "Expected DER integer",
"hex": "300cff0400ffffff020400ffffff01"
},
{
"exception": "Expected DER integer \\(2\\)",
"hex": "300c020200ffffff020400ffffff01"
},
{
"exception": "R length is zero",
"hex": "30080200020400ffffff01"
},
{
"exception": "S length is zero",
"hex": "3008020400ffffff020001"
},
{
"exception": "R length is too long",
"hex": "300c02dd00ffffff020400ffffff01"
},
{
"exception": "S length is invalid",
"hex": "300c020400ffffff02dd00ffffff01"
},
{
"exception": "R value is negative",
"hex": "300c020480000000020400ffffff01"
},
{
"exception": "S value is negative",
"hex": "300c020400ffffff02048000000001"
},
{
"exception": "R value excessively padded",
"hex": "300c02040000ffff020400ffffff01"
},
{
"exception": "S value excessively padded",
"hex": "300c020400ffffff02040000ffff01"
},
{
"exception": "Invalid hashType 7",
"hashType": 7,
"hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa5434226207",
"raw": {
"r": "23362334225185207751494092901091441011938859014081160902781146257181456271561",
"s": "50433721247292933944369538617440297985091596895097604618403996029256432099938"
}
},
{
"exception": "Invalid hashType 140",
"hashType": 140,
"hex": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa543422628c",
"raw": {
"r": "23362334225185207751494092901091441011938859014081160902781146257181456271561",
"s": "50433721247292933944369538617440297985091596895097604618403996029256432099938"
}
}
]
}

11
test/integration/cltv.js

@ -56,7 +56,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
var tx = txb.buildIncomplete() var tx = txb.buildIncomplete()
var signatureHash = tx.hashForSignature(0, redeemScript, hashType) var signatureHash = tx.hashForSignature(0, redeemScript, hashType)
var redeemScriptSig = bitcoin.script.scriptHash.input.encode([ var redeemScriptSig = bitcoin.script.scriptHash.input.encode([
alice.sign(signatureHash).toScriptSignature(hashType), bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.opcodes.OP_TRUE bitcoin.opcodes.OP_TRUE
], redeemScript) ], redeemScript)
tx.setInputScript(0, redeemScriptSig) tx.setInputScript(0, redeemScriptSig)
@ -100,7 +100,7 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
var tx = txb.buildIncomplete() var tx = txb.buildIncomplete()
var signatureHash = tx.hashForSignature(0, redeemScript, hashType) var signatureHash = tx.hashForSignature(0, redeemScript, hashType)
var redeemScriptSig = bitcoin.script.scriptHash.input.encode([ var redeemScriptSig = bitcoin.script.scriptHash.input.encode([
alice.sign(signatureHash).toScriptSignature(hashType), bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.opcodes.OP_TRUE bitcoin.opcodes.OP_TRUE
], redeemScript) ], redeemScript)
tx.setInputScript(0, redeemScriptSig) tx.setInputScript(0, redeemScriptSig)
@ -154,8 +154,8 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
var tx = txb.buildIncomplete() var tx = txb.buildIncomplete()
var signatureHash = tx.hashForSignature(0, redeemScript, hashType) var signatureHash = tx.hashForSignature(0, redeemScript, hashType)
var redeemScriptSig = bitcoin.script.scriptHash.input.encode([ var redeemScriptSig = bitcoin.script.scriptHash.input.encode([
alice.sign(signatureHash).toScriptSignature(hashType), bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bob.sign(signatureHash).toScriptSignature(hashType), bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
bitcoin.opcodes.OP_FALSE bitcoin.opcodes.OP_FALSE
], redeemScript) ], redeemScript)
tx.setInputScript(0, redeemScriptSig) tx.setInputScript(0, redeemScriptSig)
@ -196,7 +196,8 @@ describe('bitcoinjs-lib (transactions w/ CLTV)', function () {
var tx = txb.buildIncomplete() var tx = txb.buildIncomplete()
var signatureHash = tx.hashForSignature(0, redeemScript, hashType) var signatureHash = tx.hashForSignature(0, redeemScript, hashType)
var redeemScriptSig = bitcoin.script.scriptHash.input.encode([ var redeemScriptSig = bitcoin.script.scriptHash.input.encode([
alice.sign(signatureHash).toScriptSignature(hashType), bitcoin.script.signature.encode(alice.sign(signatureHash), hashType),
bitcoin.script.signature.encode(bob.sign(signatureHash), hashType),
bitcoin.opcodes.OP_TRUE bitcoin.opcodes.OP_TRUE
], redeemScript) ], redeemScript)
tx.setInputScript(0, redeemScriptSig) tx.setInputScript(0, redeemScriptSig)

2
test/integration/crypto.js

@ -21,7 +21,7 @@ describe('bitcoinjs-lib (crypto)', function () {
assert(bitcoin.script.pubKeyHash.input.check(scriptChunks), 'Expected pubKeyHash script') assert(bitcoin.script.pubKeyHash.input.check(scriptChunks), 'Expected pubKeyHash script')
var prevOutScript = bitcoin.address.toOutputScript('1ArJ9vRaQcoQ29mTWZH768AmRwzb6Zif1z') var prevOutScript = bitcoin.address.toOutputScript('1ArJ9vRaQcoQ29mTWZH768AmRwzb6Zif1z')
var scriptSignature = bitcoin.ECSignature.parseScriptSignature(scriptChunks[0]) var scriptSignature = bitcoin.script.signature.decode(scriptChunks[0])
var publicKey = bitcoin.ECPair.fromPublicKeyBuffer(scriptChunks[1]) var publicKey = bitcoin.ECPair.fromPublicKeyBuffer(scriptChunks[1])
var m = tx.hashForSignature(vin, prevOutScript, scriptSignature.hashType) var m = tx.hashForSignature(vin, prevOutScript, scriptSignature.hashType)

2
test/integration/transactions.js

@ -230,7 +230,7 @@ describe('bitcoinjs-lib (transactions)', function () {
var keyPair = keyPairs[i] var keyPair = keyPairs[i]
var prevOutScript = bitcoin.address.toOutputScript(keyPair.getAddress()) var prevOutScript = bitcoin.address.toOutputScript(keyPair.getAddress())
var scriptSig = bitcoin.script.pubKeyHash.input.decode(input.script) var scriptSig = bitcoin.script.pubKeyHash.input.decode(input.script)
var ss = bitcoin.ECSignature.parseScriptSignature(scriptSig.signature) var ss = bitcoin.script.signature.decode(scriptSig.signature)
var hash = tx.hashForSignature(i, prevOutScript, ss.hashType) var hash = tx.hashForSignature(i, prevOutScript, ss.hashType)
assert.strictEqual(scriptSig.pubKey.toString('hex'), keyPair.getPublicKeyBuffer().toString('hex')) assert.strictEqual(scriptSig.pubKey.toString('hex'), keyPair.getPublicKeyBuffer().toString('hex'))

66
test/script_signature.js

@ -0,0 +1,66 @@
/* global describe, it */
var assert = require('assert')
var bscriptSig = require('../src/script').signature
var BigInteger = require('bigi')
var Buffer = require('safe-buffer').Buffer
var fixtures = require('./fixtures/signature.json')
describe('Script Signatures', function () {
function fromRaw (signature) {
return {
r: new BigInteger(signature.r),
s: new BigInteger(signature.s)
}
}
function toRaw (signature) {
return {
r: signature.r.toString(),
s: signature.s.toString()
}
}
describe('encode', function () {
fixtures.valid.forEach(function (f) {
it('encodes ' + f.hex, function () {
var buffer = bscriptSig.encode(fromRaw(f.raw), f.hashType)
assert.strictEqual(buffer.toString('hex'), f.hex)
})
})
fixtures.invalid.forEach(function (f) {
if (!f.raw) return
it('throws ' + f.exception, function () {
var signature = fromRaw(f.raw)
assert.throws(function () {
bscriptSig.encode(signature, f.hashType)
}, new RegExp(f.exception))
})
})
})
describe('decode', function () {
fixtures.valid.forEach(function (f) {
it('decodes ' + f.hex, function () {
var decode = bscriptSig.decode(Buffer.from(f.hex, 'hex'))
assert.deepEqual(toRaw(decode.signature), f.raw)
assert.strictEqual(decode.hashType, f.hashType)
})
})
fixtures.invalid.forEach(function (f) {
it('throws on ' + f.hex, function () {
var buffer = Buffer.from(f.hex, 'hex')
assert.throws(function () {
bscriptSig.decode(buffer)
}, new RegExp(f.exception))
})
})
})
})
Loading…
Cancel
Save