87 lines
2.2 KiB
JavaScript
87 lines
2.2 KiB
JavaScript
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) {
|
|
if (buffer.length !== 65) throw new Error('Invalid signature length')
|
|
|
|
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 r = BigInteger.fromBuffer(buffer.slice(1, 33))
|
|
var s = BigInteger.fromBuffer(buffer.slice(33))
|
|
|
|
return {
|
|
compressed: compressed,
|
|
i: recoveryParam,
|
|
signature: 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 = 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 r = new Buffer(this.r.toDERInteger())
|
|
var s = new Buffer(this.s.toDERInteger())
|
|
|
|
return bip66.encode(r, s)
|
|
}
|
|
|
|
ECSignature.prototype.toScriptSignature = function (hashType) {
|
|
var hashTypeMod = hashType & ~0x80
|
|
if (hashTypeMod <= 0 || hashTypeMod >= 4) throw new Error('Invalid hashType ' + hashType)
|
|
|
|
var hashTypeBuffer = new Buffer(1)
|
|
hashTypeBuffer.writeUInt8(hashType, 0)
|
|
|
|
return Buffer.concat([this.toDER(), hashTypeBuffer])
|
|
}
|
|
|
|
module.exports = ECSignature
|