ecdsa: moved all signature encoding to ECSignature

This commit is contained in:
Daniel Cousens 2014-06-15 16:44:52 +10:00
parent c5252fc509
commit eb3d9a25f7
9 changed files with 350 additions and 297 deletions

View file

@ -2,6 +2,7 @@ var assert = require('assert')
var crypto = require('./crypto')
var BigInteger = require('bigi')
var ECSignature = require('./ecsignature')
var Point = require('ecurve').Point
function deterministicGenerateK(curve, hash, d) {
@ -51,7 +52,7 @@ function sign(curve, hash, d) {
s = n.subtract(s)
}
return {r: r, s: s}
return new ECSignature(r, s)
}
function verify(curve, hash, signature, Q) {
@ -81,102 +82,6 @@ function verifyRaw(curve, e, signature, Q) {
return v.equals(r)
}
/**
* Serialize a signature into DER format.
*
* Takes two BigIntegers representing r and s and returns a byte array.
*/
function serializeSig(signature) {
var rBa = signature.r.toDERInteger()
var sBa = signature.s.toDERInteger()
var sequence = []
sequence.push(0x02) // INTEGER
sequence.push(rBa.length)
sequence = sequence.concat(rBa)
sequence.push(0x02) // INTEGER
sequence.push(sBa.length)
sequence = sequence.concat(sBa)
sequence.unshift(sequence.length)
sequence.unshift(0x30) // SEQUENCE
return new Buffer(sequence)
}
/**
* Parses a buffer containing a DER-encoded signature.
*
* This function will return an object of the form:
*
* {
* r: BigInteger,
* s: BigInteger
* }
*/
function parseSig(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)
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)
offset += 2 + sLen
assert.equal(offset, buffer.length, 'Invalid DER encoding')
return {
r: BigInteger.fromDERInteger(rB),
s: BigInteger.fromDERInteger(sB)
}
}
function serializeSigCompact(signature, i, compressed) {
if (compressed) {
i += 4
}
i += 27
var buffer = new Buffer(65)
buffer.writeUInt8(i, 0)
signature.r.toBuffer(32).copy(buffer, 1)
signature.s.toBuffer(32).copy(buffer, 33)
return buffer
}
function parseSigCompact(buffer) {
assert.equal(buffer.length, 65, 'Invalid signature length')
var i = buffer.readUInt8(0) - 27
// At most 3 bits
assert.equal(i, i & 7, 'Invalid signature parameter')
var compressed = !!(i & 4)
// Recovery param only
i = i & 3
var r = BigInteger.fromBuffer(buffer.slice(1, 33))
var s = BigInteger.fromBuffer(buffer.slice(33))
return {
signature: {
r: r,
s: s
},
i: i,
compressed: compressed
}
}
/**
* Recover a public key from a signature.
*
@ -269,9 +174,5 @@ module.exports = {
recoverPubKey: recoverPubKey,
sign: sign,
verify: verify,
verifyRaw: verifyRaw,
serializeSig: serializeSig,
parseSig: parseSig,
serializeSigCompact: serializeSigCompact,
parseSigCompact: parseSigCompact
verifyRaw: verifyRaw
}

102
src/ecsignature.js Normal file
View file

@ -0,0 +1,102 @@
var assert = require('assert')
var BigInteger = require('bigi')
function ECSignature(r, s) {
assert(r instanceof BigInteger, 'Expected BigInteger, got ' + r)
assert(s instanceof BigInteger, 'Expected BigInteger, got ' + s)
this.r = r
this.s = s
}
// Import operations
ECSignature.fromCompact = function(buffer) {
assert.equal(buffer.length, 65, 'Invalid signature length')
var i = buffer.readUInt8(0) - 27
// At most 3 bits
assert.equal(i, i & 7, 'Invalid signature parameter')
var compressed = !!(i & 4)
// Recovery param only
i = i & 3
var r = BigInteger.fromBuffer(buffer.slice(1, 33))
var s = BigInteger.fromBuffer(buffer.slice(33))
return {
compressed: compressed,
i: i,
signature: new ECSignature(r, s)
}
}
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)
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)
offset += 2 + sLen
assert.equal(offset, buffer.length, 'Invalid DER encoding')
var r = BigInteger.fromDERInteger(rB)
var s = BigInteger.fromDERInteger(sB)
return new ECSignature(r, s)
}
ECSignature.fromScriptSignature = function(buffer) {
return {
signature: ECSignature.fromDER(buffer.slice(0, -1)),
hashType: buffer.readUInt8(buffer.length - 1)
}
}
// Export operations
ECSignature.prototype.toCompact = function(i, compressed) {
if (compressed) i += 4
i += 27
var buffer = new Buffer(65)
buffer.writeUInt8(i, 0)
this.r.toBuffer(32).copy(buffer, 1)
this.s.toBuffer(32).copy(buffer, 33)
return buffer
}
ECSignature.prototype.toDER = function() {
var rBa = this.r.toDERInteger()
var sBa = this.s.toDERInteger()
var sequence = []
sequence.push(0x02) // INTEGER
sequence.push(rBa.length)
sequence = sequence.concat(rBa)
sequence.push(0x02) // INTEGER
sequence.push(sBa.length)
sequence = sequence.concat(sBa)
sequence.unshift(sequence.length)
sequence.unshift(0x30) // SEQUENCE
return new Buffer(sequence)
}
ECSignature.prototype.toScriptSignature = function(hashType) {
var hashTypeBuffer = new Buffer(1)
hashTypeBuffer.writeUInt8(hashType, 0)
return Buffer.concat([this.toDER(), hashTypeBuffer])
}
module.exports = ECSignature

View file

@ -8,6 +8,7 @@ module.exports = {
ecdsa: require('./ecdsa'),
ECKey: require('./eckey'),
ECPubKey: require('./ecpubkey'),
ECSignature: require('./ecsignature'),
Message: require('./message'),
opcodes: require('./opcodes'),
HDNode: require('./hdnode'),

View file

@ -8,6 +8,7 @@ var networks = require('./networks')
var Address = require('./address')
var ECPubKey = require('./ecpubkey')
var ECSignature = require('./ecsignature')
var ecurve = require('ecurve')
var ecparams = ecurve.getCurveByName('secp256k1')
@ -18,32 +19,30 @@ function magicHash(message, network) {
var lengthBuffer = new Buffer(bufferutils.varIntSize(messageBuffer.length))
bufferutils.writeVarInt(lengthBuffer, messageBuffer.length, 0)
var buffer = Buffer.concat([
magicPrefix, lengthBuffer, messageBuffer
])
var buffer = Buffer.concat([magicPrefix, lengthBuffer, messageBuffer])
return crypto.hash256(buffer)
}
function sign(key, message, network) {
function sign(privKey, message, network) {
network = network || networks.bitcoin
var hash = magicHash(message, network)
var signature = key.sign(hash)
var signature = privKey.sign(hash)
var e = BigInteger.fromBuffer(hash)
var i = ecdsa.calcPubKeyRecoveryParam(ecparams, e, signature, key.pub.Q)
var i = ecdsa.calcPubKeyRecoveryParam(ecparams, e, signature, privKey.pub.Q)
return ecdsa.serializeSigCompact(signature, i, key.pub.compressed)
return signature.toCompact(i, privKey.pub.compressed)
}
// TODO: network could be implied from address
function verify(address, compactSig, message, network) {
function verify(address, signatureBuffer, message, network) {
if (address instanceof Address) {
address = address.toString()
}
network = network || networks.bitcoin
var hash = magicHash(message, network)
var parsed = ecdsa.parseSigCompact(compactSig)
var parsed = ECSignature.fromCompact(signatureBuffer)
var e = BigInteger.fromBuffer(hash)
var Q = ecdsa.recoverPubKey(ecparams, e, parsed.signature, parsed.i)

View file

@ -1,12 +1,12 @@
var assert = require('assert')
var bufferutils = require('./bufferutils')
var crypto = require('./crypto')
var ecdsa = require('./ecdsa')
var opcodes = require('./opcodes')
var scripts = require('./scripts')
var Address = require('./address')
var ECKey = require('./eckey')
var ECSignature = require('./ecsignature')
var Script = require('./script')
var DEFAULT_SEQUENCE = 0xffffffff
@ -301,16 +301,11 @@ Transaction.prototype.sign = function(index, privKey, hashType) {
Transaction.prototype.signInput = function(index, prevOutScript, privKey, hashType) {
hashType = hashType || SIGHASH_ALL
assert(privKey instanceof ECKey, 'Expected ECKey, got ' + privKey)
var hash = this.hashForSignature(prevOutScript, index, hashType)
var signature = privKey.sign(hash)
var DERencoded = ecdsa.serializeSig(signature)
return Buffer.concat([
new Buffer(DERencoded),
new Buffer([hashType])
])
return signature.toScriptSignature(hashType)
}
Transaction.prototype.setInputScript = function(index, script) {
@ -318,14 +313,11 @@ Transaction.prototype.setInputScript = function(index, script) {
}
// FIXME: could be validateInput(index, prevTxOut, pub)
Transaction.prototype.validateInput = function(index, prevOutScript, pubKey, DERsig) {
var type = DERsig.readUInt8(DERsig.length - 1)
DERsig = DERsig.slice(0, -1)
Transaction.prototype.validateInput = function(index, prevOutScript, pubKey, buffer) {
var parsed = ECSignature.fromScriptSignature(buffer)
var hash = this.hashForSignature(prevOutScript, index, parsed.hashType)
var hash = this.hashForSignature(prevOutScript, index, type)
var signature = ecdsa.parseSig(DERsig)
return pubKey.verify(hash, signature)
return pubKey.verify(hash, parsed.signature)
}
module.exports = Transaction

View file

@ -5,6 +5,7 @@ var message = require('../src/message')
var networks = require('../src/networks')
var BigInteger = require('bigi')
var ECSignature = require('../src/ecsignature')
var ecurve = require('ecurve')
var curve = ecurve.getCurveByName('secp256k1')
@ -35,7 +36,7 @@ describe('ecdsa', function() {
}
var h1 = crypto.sha256(f.message)
var e = BigInteger.fromBuffer(h1)
var Qprime = ecdsa.recoverPubKey(curve, e, signature, f.compact.i)
var Qprime = ecdsa.recoverPubKey(curve, e, signature, f.i)
assert(Qprime.equals(Q))
})
@ -45,8 +46,8 @@ describe('ecdsa', function() {
var hash = message.magicHash('1111', networks.bitcoin)
var e = BigInteger.fromBuffer(hash)
var signature = new Buffer('INcvXVVEFyIfHLbDX+xoxlKFn3Wzj9g0UbhObXdMq+YMKC252o5RHFr0/cKdQe1WsBLUBi4morhgZ77obDJVuV0=', 'base64')
var parsed = ecdsa.parseSigCompact(signature)
var signatureBuffer = new Buffer('INcvXVVEFyIfHLbDX+xoxlKFn3Wzj9g0UbhObXdMq+YMKC252o5RHFr0/cKdQe1WsBLUBi4morhgZ77obDJVuV0=', 'base64')
var signature = ECSignature.fromCompact(signatureBuffer).signature
var points = [
'03e3a8c44a8bf712f1fbacee274fb19c0239b1a9e877eff0075ea335f2be8ff380',
'0279be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798',
@ -56,7 +57,7 @@ describe('ecdsa', function() {
points.forEach(function(expectedHex, i) {
it('recovers an expected point for i of ' + i, function() {
var Qprime = ecdsa.recoverPubKey(curve, e, parsed.signature, i)
var Qprime = ecdsa.recoverPubKey(curve, e, signature, i)
var QprimeHex = Qprime.getEncoded().toString('hex')
assert.equal(QprimeHex, expectedHex)
@ -67,10 +68,7 @@ describe('ecdsa', function() {
fixtures.invalid.recoverPubKey.forEach(function(f) {
it('throws on ' + f.description, function() {
var e = BigInteger.fromHex(f.e)
var signature = {
r: new BigInteger(f.signature.r),
s: new BigInteger(f.signature.s)
}
var signature = new ECSignature(new BigInteger(f.signature.r), new BigInteger(f.signature.s))
assert.throws(function() {
ecdsa.recoverPubKey(curve, e, signature, f.i)
@ -105,13 +103,12 @@ describe('ecdsa', function() {
fixtures.valid.forEach(function(f) {
it('verifies a valid signature for \"' + f.message + '\"', function() {
var d = BigInteger.fromHex(f.d)
var Q = curve.params.G.multiply(d)
var signature = {
r: new BigInteger(f.signature.r),
s: new BigInteger(f.signature.s)
}
var e = BigInteger.fromBuffer(crypto.sha256(f.message))
var signature = new ECSignature(
new BigInteger(f.signature.r),
new BigInteger(f.signature.s)
)
var Q = curve.params.G.multiply(d)
assert(ecdsa.verifyRaw(curve, e, signature, Q))
})
@ -121,90 +118,14 @@ describe('ecdsa', function() {
it('fails to verify with ' + f.description, function() {
var d = BigInteger.fromHex(f.d)
var e = BigInteger.fromHex(f.e)
var signature = {
r: new BigInteger(f.signature.r),
s: new BigInteger(f.signature.s)
}
var signature = new ECSignature(
new BigInteger(f.signature.r),
new BigInteger(f.signature.s)
)
var Q = curve.params.G.multiply(d)
assert.equal(ecdsa.verifyRaw(curve, e, signature, Q), false)
})
})
})
describe('serializeSig', function() {
it('encodes a DER signature', function() {
fixtures.valid.forEach(function(f) {
var signature = {
r: new BigInteger(f.signature.r),
s: new BigInteger(f.signature.s)
}
var signature = new Buffer(ecdsa.serializeSig(signature))
assert.equal(signature.toString('hex'), f.DER)
})
})
})
describe('parseSig', function() {
it('decodes the correct signature', function() {
fixtures.valid.forEach(function(f) {
var buffer = new Buffer(f.DER, 'hex')
var signature = ecdsa.parseSig(buffer)
assert.equal(signature.r.toString(), f.signature.r)
assert.equal(signature.s.toString(), f.signature.s)
})
})
fixtures.invalid.DER.forEach(function(f) {
it('throws on ' + f.hex, function() {
var buffer = new Buffer(f.hex, 'hex')
assert.throws(function() {
ecdsa.parseSig(buffer)
}, new RegExp(f.exception))
})
})
})
describe('serializeSigCompact', function() {
fixtures.valid.forEach(function(f) {
it('encodes ' + f.compact.hex + ' correctly', function() {
var signature = {
r: new BigInteger(f.signature.r),
s: new BigInteger(f.signature.s)
}
var i = f.compact.i
var compressed = f.compact.compressed
var signature = ecdsa.serializeSigCompact(signature, i, compressed)
assert.equal(signature.toString('hex'), f.compact.hex)
})
})
})
describe('parseSigCompact', function() {
fixtures.valid.forEach(function(f) {
it('decodes ' + f.compact.hex + ' correctly', function() {
var buffer = new Buffer(f.compact.hex, 'hex')
var parsed = ecdsa.parseSigCompact(buffer)
assert.equal(parsed.signature.r.toString(), f.signature.r)
assert.equal(parsed.signature.s.toString(), f.signature.s)
assert.equal(parsed.i, f.compact.i)
assert.equal(parsed.compressed, f.compact.compressed)
})
})
fixtures.invalid.compact.forEach(function(f) {
it('throws on ' + f.hex, function() {
var buffer = new Buffer(f.hex, 'hex')
assert.throws(function() {
ecdsa.parseSigCompact(buffer)
}, new RegExp(f.exception))
})
})
})
})

82
test/ecsignature.js Normal file
View file

@ -0,0 +1,82 @@
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('encodes ' + 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.equal(buffer.toString('hex'), f.compact.hex)
})
})
})
describe('fromCompact', function() {
fixtures.valid.forEach(function(f) {
it('decodes ' + f.compact.hex + ' correctly', function() {
var buffer = new Buffer(f.compact.hex, 'hex')
var parsed = ECSignature.fromCompact(buffer)
assert.equal(parsed.compressed, f.compact.compressed)
assert.equal(parsed.i, f.compact.i)
assert.equal(parsed.signature.r.toString(), f.signature.r)
assert.equal(parsed.signature.s.toString(), f.signature.s)
})
})
fixtures.invalid.compact.forEach(function(f) {
it('throws on ' + f.hex, function() {
var buffer = new Buffer(f.hex, 'hex')
assert.throws(function() {
ECSignature.fromCompact(buffer)
}, new RegExp(f.exception))
})
})
})
describe('toDER', function() {
it('encodes a DER signature', function() {
fixtures.valid.forEach(function(f) {
var signature = new ECSignature(
new BigInteger(f.signature.r),
new BigInteger(f.signature.s)
)
var DER = signature.toDER()
assert.equal(DER.toString('hex'), f.DER)
})
})
})
describe('fromDER', function() {
it('decodes the correct signature', function() {
fixtures.valid.forEach(function(f) {
var buffer = new Buffer(f.DER, 'hex')
var signature = ECSignature.fromDER(buffer)
assert.equal(signature.r.toString(), f.signature.r)
assert.equal(signature.s.toString(), f.signature.s)
})
})
fixtures.invalid.DER.forEach(function(f) {
it('throws on ' + f.hex, function() {
var buffer = new Buffer(f.hex, 'hex')
assert.throws(function() {
ECSignature.fromDER(buffer)
}, new RegExp(f.exception))
})
})
})
})

View file

@ -4,12 +4,7 @@
"d": "01",
"k": "ec633bd56a5774a0940cb97e27a9e4e51dc94af737596a0c5cbb3d30332d92a5",
"message": "Everything should be made as simple as possible, but not simpler.",
"compact": {
"hex": "1f33a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c96f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262",
"compressed": true,
"i": 0
},
"DER": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262",
"i": 0,
"signature": {
"r": "23362334225185207751494092901091441011938859014081160902781146257181456271561",
"s": "50433721247292933944369538617440297985091596895097604618403996029256432099938"
@ -19,12 +14,7 @@
"d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
"k": "9dc74cbfd383980fb4ae5d2680acddac9dac956dca65a28c80ac9c847c2374e4",
"message": "Equations are more important to me, because politics is for the present, but an equation is something for eternity.",
"compact": {
"hex": "1b54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5",
"compressed": false,
"i": 0
},
"DER": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5",
"i": 0,
"signature": {
"r": "38341707918488238920692284707283974715538935465589664377561695343399725051885",
"s": "3180566392414476763164587487324397066658063772201694230600609996154610926757"
@ -34,12 +24,7 @@
"d": "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364140",
"k": "fd27071f01648ebbdd3e1cfbae48facc9fa97edc43bbbc9a7fdc28eae13296f5",
"message": "Not only is the Universe stranger than we think, it is stranger than we can think.",
"compact": {
"hex": "1fff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd06fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283",
"compressed": true,
"i": 0
},
"DER": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283",
"i": 0,
"signature": {
"r": "115464191557905790016094131873849783294273568009648050793030031933291767741904",
"s": "50562520307781850052192542766631199590053690478900449960232079510155113443971"
@ -49,12 +34,7 @@
"d": "0000000000000000000000000000000000000000000000000000000000000001",
"k": "f0cd2ba5fc7c183de589f6416220a36775a146740798756d8d949f7166dcc87f",
"message": "How wonderful that we have met with a paradox. Now we have some hope of making progress.",
"compact": {
"hex": "1cc0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d375afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3",
"compressed": false,
"i": 1
},
"DER": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3",
"i": 1,
"signature": {
"r": "87230998027579607140680851455601772643840468630989315269459846730712163783123",
"s": "53231320085894623106179381504478252331065330583563809963303318469380290929875"
@ -64,12 +44,7 @@
"d": "69ec59eaa1f4f2e36b639716b7c30ca86d9a5375c7b38d8918bd9c0ebc80ba64",
"k": "6bb4a594ad57c1aa22dbe991a9d8501daf4688bf50a4892ef21bd7c711afda97",
"message": "Computer science is no more about computers than astronomy is about telescopes.",
"compact": {
"hex": "1f7186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d0de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6",
"compressed": true,
"i": 0
},
"DER": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6",
"i": 0,
"signature": {
"r": "51348483531757779992459563033975330355971795607481991320287437101831125115997",
"s": "6277080015686056199074771961940657638578000617958603212944619747099038735862"
@ -79,12 +54,7 @@
"d": "00000000000000000000000000007246174ab1e92e9149c6e446fe194d072637",
"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",
"compact": {
"hex": "1cfbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda4870e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37",
"compressed": false,
"i": 1
},
"DER": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37",
"i": 1,
"signature": {
"r": "113979859486826658566290715281614250298918272782414232881639314569529560769671",
"s": "6517071009538626957379450615706485096874328019806177698938278220732027419959"
@ -94,12 +64,7 @@
"d": "000000000000000000000000000000000000000000056916d0f9b31dc9b637f3",
"k": "19355c36c8cbcdfb2382e23b194b79f8c97bf650040fc7728dfbf6b39a97c25b",
"message": "The question of whether computers can think is like the question of whether submarines can swim.",
"compact": {
"hex": "20cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf906ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef",
"compressed": true,
"i": 1
},
"DER": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef",
"i": 1,
"signature": {
"r": "93122007060065279508564838030979550535085999589142852106617159184757394422777",
"s": "3078539468410661027472930027406594684630312677495124015420811882501887769839"
@ -107,42 +72,6 @@
}
],
"invalid": {
"compact": [
{
"exception": "Invalid signature parameter",
"hex": "23987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e93791d7629795b62"
},
{
"exception": "Invalid signature length",
"hex": "1c987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e93791d7629795b62000000"
},
{
"exception": "Invalid signature length",
"hex": "1c987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e9379"
}
],
"DER": [
{
"exception": "Invalid sequence length",
"hex": "30ff0204ffffffff0204ffffffff"
},
{
"exception": "Invalid sequence length",
"hex": "300c0304ffffffff0304ffffffff0000"
},
{
"exception": "Expected a DER integer",
"hex": "300cff04ffffffff0204ffffffff"
},
{
"exception": "Expected a DER integer \\(2\\)",
"hex": "300c0202ffffffff0204ffffffff"
},
{
"exception": "Invalid DER encoding",
"hex": "300c0204ffffffff0202ffffffff"
}
],
"recoverPubKey": [
{
"description": "Invalid r value (== 0)",

126
test/fixtures/ecsignature.json vendored Normal file
View file

@ -0,0 +1,126 @@
{
"valid": [
{
"compact": {
"hex": "1f33a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c96f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262",
"compressed": true,
"i": 0
},
"DER": "3044022033a69cd2065432a30f3d1ce4eb0d59b8ab58c74f27c41a7fdb5696ad4e6108c902206f807982866f785d3f6418d24163ddae117b7db4d5fdf0071de069fa54342262",
"signature": {
"r": "23362334225185207751494092901091441011938859014081160902781146257181456271561",
"s": "50433721247292933944369538617440297985091596895097604618403996029256432099938"
}
},
{
"compact": {
"hex": "1b54c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed07082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5",
"compressed": false,
"i": 0
},
"DER": "3044022054c4a33c6423d689378f160a7ff8b61330444abb58fb470f96ea16d99d4a2fed022007082304410efa6b2943111b6a4e0aaa7b7db55a07e9861d1fb3cb1f421044a5",
"signature": {
"r": "38341707918488238920692284707283974715538935465589664377561695343399725051885",
"s": "3180566392414476763164587487324397066658063772201694230600609996154610926757"
}
},
{
"compact": {
"hex": "1fff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd06fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283",
"compressed": true,
"i": 0
},
"DER": "3045022100ff466a9f1b7b273e2f4c3ffe032eb2e814121ed18ef84665d0f515360dab3dd002206fc95f5132e5ecfdc8e5e6e616cc77151455d46ed48f5589b7db7771a332b283",
"signature": {
"r": "115464191557905790016094131873849783294273568009648050793030031933291767741904",
"s": "50562520307781850052192542766631199590053690478900449960232079510155113443971"
}
},
{
"compact": {
"hex": "1cc0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d375afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3",
"compressed": false,
"i": 1
},
"DER": "3045022100c0dafec8251f1d5010289d210232220b03202cba34ec11fec58b3e93a85b91d3022075afdc06b7d6322a590955bf264e7aaa155847f614d80078a90292fe205064d3",
"signature": {
"r": "87230998027579607140680851455601772643840468630989315269459846730712163783123",
"s": "53231320085894623106179381504478252331065330583563809963303318469380290929875"
}
},
{
"compact": {
"hex": "1f7186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d0de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6",
"compressed": true,
"i": 0
},
"DER": "304402207186363571d65e084e7f02b0b77c3ec44fb1b257dee26274c38c928986fea45d02200de0b38e06807e46bda1f1e293f4f6323e854c86d58abdd00c46c16441085df6",
"signature": {
"r": "51348483531757779992459563033975330355971795607481991320287437101831125115997",
"s": "6277080015686056199074771961940657638578000617958603212944619747099038735862"
}
},
{
"compact": {
"hex": "1cfbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda4870e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37",
"compressed": false,
"i": 1
},
"DER": "3045022100fbfe5076a15860ba8ed00e75e9bd22e05d230f02a936b653eb55b61c99dda48702200e68880ebb0050fe4312b1b1eb0899e1b82da89baa5b895f612619edf34cbd37",
"signature": {
"r": "113979859486826658566290715281614250298918272782414232881639314569529560769671",
"s": "6517071009538626957379450615706485096874328019806177698938278220732027419959"
}
},
{
"compact": {
"hex": "20cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf906ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef",
"compressed": true,
"i": 1
},
"DER": "3045022100cde1302d83f8dd835d89aef803c74a119f561fbaef3eb9129e45f30de86abbf9022006ce643f5049ee1f27890467b77a6a8e11ec4661cc38cd8badf90115fbd03cef",
"signature": {
"r": "93122007060065279508564838030979550535085999589142852106617159184757394422777",
"s": "3078539468410661027472930027406594684630312677495124015420811882501887769839"
}
}
],
"invalid": {
"compact": [
{
"exception": "Invalid signature parameter",
"hex": "23987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e93791d7629795b62"
},
{
"exception": "Invalid signature length",
"hex": "1c987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e93791d7629795b62000000"
},
{
"exception": "Invalid signature length",
"hex": "1c987ceade6a304fc5823ab38f99fc3c5f772a2d3e89ea05931e2726105fc53b9e601fc3231f35962c714fcbce5c95b427496edc7ae8b3d12e9379"
}
],
"DER": [
{
"exception": "Invalid sequence length",
"hex": "30ff0204ffffffff0204ffffffff"
},
{
"exception": "Invalid sequence length",
"hex": "300c0304ffffffff0304ffffffff0000"
},
{
"exception": "Expected a DER integer",
"hex": "300cff04ffffffff0204ffffffff"
},
{
"exception": "Expected a DER integer \\(2\\)",
"hex": "300c0202ffffffff0204ffffffff"
},
{
"exception": "Invalid DER encoding",
"hex": "300c0204ffffffff0202ffffffff"
}
]
}
}