Merge pull request from bitcoinjs/bip66

Extract BIP66 module
This commit is contained in:
Daniel Cousens 2015-08-25 14:17:44 +10:00
commit ec1195bcee
6 changed files with 66 additions and 88 deletions

View file

@ -1,3 +1,4 @@
var bip66 = require('bip66')
var typeforce = require('typeforce')
var types = require('./types')
@ -29,36 +30,10 @@ ECSignature.parseCompact = function (buffer) {
}
}
// Strict DER - https://github.com/bitcoin/bips/blob/master/bip-0066.mediawiki
// NOTE: SIGHASH byte ignored
ECSignature.fromDER = function (buffer) {
// Format: 0x30 [total-length] 0x02 [R-length] [R] 0x02 [S-length] [S]
if (buffer.length < 8) throw new Error('DER sequence too short')
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 lenR = buffer[3]
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 lenS = buffer[5 + lenR]
if (lenS === 0) throw new Error('S length is zero')
if ((lenR + lenS + 6) !== buffer.length) throw new Error('Invalid DER encoding (2)')
if (buffer[4] & 0x80) throw new Error('R value is negative')
if (lenR > 1 && (buffer[4] === 0x00) && !(buffer[5] & 0x80)) throw new Error('R value excessively padded')
if (buffer[lenR + 6] & 0x80) throw new Error('S value is negative')
if (lenS > 1 && (buffer[lenR + 6] === 0x00) && !(buffer[lenR + 7] & 0x80)) throw new Error('S value excessively padded')
// non-BIP66 - extract R, S values
var rB = buffer.slice(4, 4 + lenR)
var sB = buffer.slice(lenR + 6)
var r = BigInteger.fromDERInteger(rB)
var s = BigInteger.fromDERInteger(sB)
var decode = bip66.decode(buffer)
var r = BigInteger.fromDERInteger(decode.r)
var s = BigInteger.fromDERInteger(decode.s)
return new ECSignature(r, s)
}
@ -93,23 +68,10 @@ ECSignature.prototype.toCompact = function (i, compressed) {
}
ECSignature.prototype.toDER = function () {
var rBa = this.r.toDERInteger()
var sBa = this.s.toDERInteger()
var r = new Buffer(this.r.toDERInteger())
var s = new Buffer(this.s.toDERInteger())
var sequence = []
// INTEGER
sequence.push(0x02, rBa.length)
sequence = sequence.concat(rBa)
// INTEGER
sequence.push(0x02, sBa.length)
sequence = sequence.concat(sBa)
// SEQUENCE
sequence.unshift(0x30, sequence.length)
return new Buffer(sequence)
return bip66.encode(r, s)
}
ECSignature.prototype.toScriptSignature = function (hashType) {

View file

@ -1,11 +1,8 @@
var bip66 = require('bip66')
var bufferutils = require('./bufferutils')
var typeforce = require('typeforce')
var types = require('./types')
var ECSignature = require('./ecsignature')
var ecurve = require('ecurve')
var curve = ecurve.getCurveByName('secp256k1')
var OPS = require('./opcodes')
var REVERSE_OPS = []
for (var op in OPS) {
@ -118,34 +115,31 @@ function decompile (buffer) {
function isCanonicalPubKey (buffer) {
if (!Buffer.isBuffer(buffer)) return false
if (buffer.length < 33) return false
try {
ecurve.Point.decodeFrom(curve, buffer)
} catch (e) {
if (!(e.message.match(/Invalid sequence (length|tag)/))) {
throw e
}
return false
switch (buffer[0]) {
case 0x02:
case 0x03:
return buffer.length === 33
case 0x04:
return buffer.length === 65
}
return true
return false
}
function isCanonicalSignature (buffer) {
if (!Buffer.isBuffer(buffer)) return false
if (!isDefinedHashType(buffer[buffer.length - 1])) return false
try {
ECSignature.parseScriptSignature(buffer)
} catch (e) {
if (!(e.message.match(/Not a DER sequence|Invalid sequence length|Expected a DER integer|R length is zero|S length is zero|R value excessively padded|S value excessively padded|R value is negative|S value is negative|Invalid hashType/))) {
throw e
}
return bip66.check(buffer.slice(0, -1))
}
return false
}
function isDefinedHashType (hashType) {
var hashTypeMod = hashType & ~0x80
return true
// return hashTypeMod > SIGHASH_ALL && hashTypeMod < SIGHASH_SINGLE
return hashTypeMod > 0x00 && hashTypeMod < 0x04
}
function isPubKeyHashInput (script) {
@ -379,6 +373,7 @@ module.exports = {
isCanonicalPubKey: isCanonicalPubKey,
isCanonicalSignature: isCanonicalSignature,
isDefinedHashType: isDefinedHashType,
isPubKeyHashInput: isPubKeyHashInput,
isPubKeyHashOutput: isPubKeyHashOutput,
isPubKeyInput: isPubKeyInput,