Last active
February 24, 2024 05:26
-
-
Save reardencode/9dbc60a6d6e1591905d25bf4d123dfdd to your computer and use it in GitHub Desktop.
Test Scripts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { ECPairFactory } = require('ecpair'); | |
const btc = require('./src'); | |
const ecc = require('tiny-secp256k1'); | |
const { secp256k1, schnorr } = require('@noble/curves/secp256k1'); | |
const psbtutils = require('./src/psbt/psbtutils'); | |
const { reverseBuffer } = require('./src/bufferutils'); | |
const { REVERSE_OPS: rOps } = require('./src/ops'); | |
btc.initEccLib(ecc); | |
const ECPair = ECPairFactory(ecc); | |
const data = { | |
small: Buffer.from('checksigfromstack', 'ascii'), | |
valid: Buffer.from( | |
'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', | |
'hex', | |
), | |
invalid: Buffer.from( | |
'feadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', | |
'hex', | |
), | |
}; | |
const { address } = btc.payments.p2tr({ | |
internalPubkey: Buffer.from( | |
schnorr.getPublicKey(secp256k1.utils.randomPrivateKey()), | |
), | |
network: btc.networks.regtest, | |
}); | |
const sk = secp256k1.utils.randomPrivateKey(); | |
const pubkeys = { | |
schnorr: schnorr.getPublicKey(sk), | |
ecdsa: secp256k1.getPublicKey(sk), | |
}; | |
const sigs = { | |
small: schnorr.sign(data.small, sk), | |
schnorr: schnorr.sign(data.valid, sk), | |
ecdsa: secp256k1.sign(data.valid, sk, { lowS: true }).toDERRawBytes(), | |
zero: Buffer.of(), | |
}; | |
const mkScript = (type, dataType, pkType) => { | |
const pk = pubkeys[pkType]; | |
const m = data[dataType]; | |
const baseScript = Buffer.concat([ | |
Buffer.of(m.length), | |
m, | |
Buffer.of(pk.length), | |
pk, | |
]); | |
switch (type) { | |
case 'verify': | |
return Buffer.concat([ | |
baseScript, | |
Buffer.of(0xb4), | |
Buffer.of(btc.opcodes.OP_2DROP), | |
]); | |
case 'plain': | |
return Buffer.concat([baseScript, Buffer.of(0xcc)]); | |
case 'zero-success': | |
return Buffer.concat([ | |
baseScript, | |
Buffer.of(0xcc), | |
Buffer.of(btc.opcodes.OP_0), | |
Buffer.of(btc.opcodes.OP_EQUAL), | |
]); | |
default: | |
throw new Error('Invalid script type'); | |
} | |
}; | |
const nums = Buffer.from( | |
'50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0', | |
'hex', | |
); | |
const inputs = { | |
valid: 'e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5', | |
invalid: 'a2522fa96033c5736f3142ff616426cd03a3d0f077f609e22c5a33a96e04e597', | |
}; | |
const mkPsbt = (type, script, inputType, sigType) => { | |
let opts = { network: btc.networks.regtest }; | |
switch (type) { | |
case 'p2sh': | |
case 'p2wsh': | |
opts = { ...opts, redeem: { output: script } }; | |
break; | |
case 'p2tr': | |
opts = { | |
...opts, | |
internalPubkey: nums, | |
scriptTree: { output: script }, | |
redeem: { output: script }, | |
}; | |
break; | |
default: | |
throw new Error('Invalid payment type'); | |
} | |
const p = btc.payments[type](opts); | |
const psbt = new btc.Psbt({ network: btc.networks.regtest }); | |
psbt.addInput({ | |
hash: inputs[inputType], | |
index: 0, | |
witnessUtxo: { value: 155000, script: p.output }, | |
}); | |
psbt.addOutput({ value: 150000, address }); | |
const sig = sigs[sigType]; | |
switch (type) { | |
case 'p2sh': | |
psbt.updateInput(0, { redeemScript: p.redeem.output }); | |
psbt.finalizeInput(0, (inputIndex, input, _) => ({ | |
finalScriptSig: btc.script.compile([ | |
Buffer.from(sig), | |
input.redeemScript, | |
]), | |
})); | |
break; | |
case 'p2wsh': | |
psbt.updateInput(0, { witnessScript: p.redeem.output }); | |
psbt.finalizeInput(0, (inputIndex, input, _) => ({ | |
finalScriptWitness: psbtutils.witnessStackToScriptWitness([ | |
sig, | |
input.witnessScript, | |
]), | |
})); | |
break; | |
case 'p2tr': | |
psbt.updateInput(0, { | |
tapLeafScript: [ | |
{ | |
leafVersion: 0xc0, | |
script: p.redeem.output, | |
controlBlock: p.witness[p.witness.length - 1], | |
}, | |
], | |
}); | |
psbt.finalizeInput(0, (inputIndex, input, _) => ({ | |
finalScriptWitness: psbtutils.witnessStackToScriptWitness([ | |
sig, | |
input.tapLeafScript[0].script, | |
input.tapLeafScript[0].controlBlock, | |
]), | |
})); | |
break; | |
default: | |
throw new Error('Invalid payment type'); | |
} | |
return psbt; | |
}; | |
const printTest = ({ name, psbt, flags }) => { | |
const prevOut = psbt.txInputs[0]; | |
const asm = btc.script.decompile(psbt.data.inputs[0].witnessUtxo.script); | |
let spk = asm | |
.map(it => | |
Buffer.isBuffer(it) | |
? `0x${it.length.toString(16)} 0x${it.toString('hex')}` | |
: it === btc.opcodes.OP_0 | |
? '0' | |
: it === btc.opcodes.OP_1 | |
? '1' | |
: `${rOps[it]}`, | |
) | |
.join(' '); | |
console.log(` ["${name}"],`); | |
console.log(` [[["${reverseBuffer(prevOut.hash).toString('hex')}",`); | |
console.log(` ${prevOut.index},`); | |
console.log(` "${spk}",`); | |
console.log(` ${psbt.data.inputs[0].witnessUtxo.value}]],`); | |
console.log(`"${psbt.extractTransaction().toHex()}",`); | |
console.log(` "${flags}"],`); | |
}; | |
const validTests = [ | |
() => { | |
const script = mkScript('plain', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'schnorr'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('plain', 'valid', 'ecdsa'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'schnorr'); | |
const asm = btc.script.decompile(psbt.data.inputs[0].witnessUtxo.script); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK succeeds with unknown key type', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK,DISCOURAGE_UPGRADABLE_PUBKEYTYPE', | |
}; | |
}, | |
() => { | |
const script = mkScript('zero-success', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'zero'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK yields 0 for 0-sig', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('plain', 'small', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'small'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK, shorter message', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'schnorr'); | |
return { | |
name: 'Test Taproot OP_CHECKSIGFROMSTACKVERIFY', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'valid', 'ecdsa'); | |
const psbt = mkPsbt('p2wsh', script, 'valid', 'ecdsa'); | |
return { | |
name: 'Test P2WSH OP_CHECKSIGFROMSTACKVERIFY ECDSA', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2wsh', script, 'valid', 'schnorr'); | |
return { | |
name: 'Test P2WSH OP_CHECKSIGFROMSTACKVERIFY BIP340', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'small', 'schnorr'); | |
const psbt = mkPsbt('p2wsh', script, 'valid', 'small'); | |
return { | |
name: 'Test P2WSH OP_CHECKSIGFROMSTACKVERIFY BIP340 shorter message', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2sh', script, 'valid', 'schnorr'); | |
return { | |
name: 'Test P2SH OP_CHECKSIGFROMSTACKVERIFY BIP340', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
]; | |
//validTests.forEach(test => printTest(test())); | |
const invalidTests = [ | |
() => { | |
const script = mkScript('zero-success', 'invalid', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'invalid', 'schnorr'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK, fails immediately with sig for wrong data', | |
psbt, | |
flags: 'P2SH,WITNESS,TAPROOT,CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'small', 'ecdsa'); | |
const psbt = mkPsbt('p2wsh', script, 'invalid', 'ecdsa'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACKVERIFY ECDSA, fails for small data', | |
psbt, | |
flags: 'P2SH,TAPROOT,CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'invalid', 'schnorr'); | |
const psbt = mkPsbt('p2wsh', script, 'invalid', 'schnorr'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACKVERIFY fails with sig for wrong data', | |
psbt, | |
flags: 'P2SH,WITNESS,CHECKSIGFROMSTACK', | |
}; | |
}, | |
]; | |
invalidTests.forEach(test => printTest(test())); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const btc = require('./src'); | |
const ecc = require('tiny-secp256k1'); | |
const psbtutils = require('./src/psbt/psbtutils'); | |
btc.initEccLib(ecc); | |
const { address } = btc.payments.p2tr({ | |
internalPubkey: Buffer.from( | |
'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', | |
'hex', | |
), | |
network: btc.networks.regtest, | |
}); | |
const leafScript = Buffer.from( | |
'cb2050929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac087', | |
'hex', | |
); | |
const nums = Buffer.from( | |
'50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0', | |
'hex', | |
); | |
const p = btc.payments.p2tr({ | |
internalPubkey: nums, | |
scriptTree: { output: leafScript }, | |
redeem: { output: leafScript }, | |
network: btc.networks.regtest, | |
}); | |
const psbt = new btc.Psbt({ network: btc.networks.regtest }); | |
psbt.addInput({ | |
hash: 'e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5', | |
index: 0, | |
witnessUtxo: { value: 155000, script: p.output }, | |
}); | |
psbt.updateInput(0, { | |
tapLeafScript: [ | |
{ | |
leafVersion: 0xc0, | |
script: p.redeem.output, | |
controlBlock: p.witness[p.witness.length - 1], | |
}, | |
], | |
}); | |
psbt.addOutput({ value: 150000, address }); | |
psbt.finalizeInput(0, (inputIndex, input, _) => ({ | |
finalScriptWitness: psbtutils.witnessStackToScriptWitness([ | |
input.tapLeafScript[0].script, | |
input.tapLeafScript[0].controlBlock, | |
]), | |
})); | |
console.log({ | |
pubkey: p.pubkey.toString('hex'), | |
tx: psbt.extractTransaction().toHex(), | |
leafScript: p.scriptTree.output.toString('hex'), | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const { ECPairFactory } = require('ecpair'); | |
const btc = require('./src'); | |
const ecc = require('tiny-secp256k1'); | |
const { secp256k1, schnorr } = require('@noble/curves/secp256k1'); | |
const psbtutils = require('./src/psbt/psbtutils'); | |
const { reverseBuffer } = require('./src/bufferutils'); | |
const { REVERSE_OPS: rOps } = require('./src/ops'); | |
btc.initEccLib(ecc); | |
const ECPair = ECPairFactory(ecc); | |
const data = { | |
small: Buffer.from('checksigfromstack', 'ascii'), | |
valid: Buffer.from( | |
'deadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', | |
'hex', | |
), | |
invalid: Buffer.from( | |
'feadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeefdeadbeef', | |
'hex', | |
), | |
}; | |
const { address } = btc.payments.p2tr({ | |
internalPubkey: Buffer.from( | |
schnorr.getPublicKey(secp256k1.utils.randomPrivateKey()), | |
), | |
network: btc.networks.regtest, | |
}); | |
const sk = secp256k1.utils.randomPrivateKey(); | |
const pubkeys = { | |
schnorr: schnorr.getPublicKey(sk), | |
ecdsa: secp256k1.getPublicKey(sk), | |
}; | |
const sigs = { | |
small: schnorr.sign(data.small, sk), | |
schnorr: schnorr.sign(data.valid, sk), | |
ecdsa: secp256k1.sign(data.valid, sk, { lowS: true }).toDERRawBytes(), | |
zero: Buffer.of(), | |
}; | |
const mkScript = (type, dataType, pkType) => { | |
const pk = pubkeys[pkType]; | |
const m = data[dataType]; | |
const baseScript = Buffer.concat([ | |
Buffer.of(m.length), | |
m, | |
Buffer.of(pk.length), | |
pk, | |
]); | |
switch (type) { | |
case 'verify': | |
return Buffer.concat([ | |
baseScript, | |
Buffer.of(0xb4), | |
Buffer.of(btc.opcodes.OP_2DROP), | |
]); | |
case 'plain': | |
return Buffer.concat([baseScript, Buffer.of(0xcc)]); | |
case 'zero-success': | |
return Buffer.concat([ | |
baseScript, | |
Buffer.of(0xcc), | |
Buffer.of(btc.opcodes.OP_0), | |
Buffer.of(btc.opcodes.OP_EQUAL), | |
]); | |
default: | |
throw new Error('Invalid script type'); | |
} | |
}; | |
const nums = Buffer.from( | |
'50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0', | |
'hex', | |
); | |
const inputs = { | |
valid: 'e2f2baee9c59389b34e39742ce05debf64aaa7a00fbdab88614f4d3c133186d5', | |
invalid: 'a2522fa96033c5736f3142ff616426cd03a3d0f077f609e22c5a33a96e04e597', | |
}; | |
const mkPsbt = (type, script, inputType, sigType) => { | |
let opts = { network: btc.networks.regtest }; | |
switch (type) { | |
case 'p2sh': | |
case 'p2wsh': | |
opts = { ...opts, redeem: { output: script } }; | |
break; | |
case 'p2tr': | |
opts = { | |
...opts, | |
internalPubkey: nums, | |
scriptTree: { output: script }, | |
redeem: { output: script }, | |
}; | |
break; | |
default: | |
throw new Error('Invalid payment type'); | |
} | |
const p = btc.payments[type](opts); | |
const psbt = new btc.Psbt({ network: btc.networks.regtest }); | |
psbt.addInput({ | |
hash: inputs[inputType], | |
index: 0, | |
witnessUtxo: { value: 155000, script: p.output }, | |
}); | |
psbt.addOutput({ value: 150000, address }); | |
const sig = sigs[sigType]; | |
switch (type) { | |
case 'p2sh': | |
psbt.updateInput(0, { redeemScript: p.redeem.output }); | |
psbt.finalizeInput(0, (inputIndex, input, _) => ({ | |
finalScriptSig: btc.script.compile([ | |
Buffer.from(sig), | |
input.redeemScript, | |
]), | |
})); | |
break; | |
case 'p2wsh': | |
psbt.updateInput(0, { witnessScript: p.redeem.output }); | |
psbt.finalizeInput(0, (inputIndex, input, _) => ({ | |
finalScriptWitness: psbtutils.witnessStackToScriptWitness([ | |
sig, | |
input.witnessScript, | |
]), | |
})); | |
break; | |
case 'p2tr': | |
psbt.updateInput(0, { | |
tapLeafScript: [ | |
{ | |
leafVersion: 0xc0, | |
script: p.redeem.output, | |
controlBlock: p.witness[p.witness.length - 1], | |
}, | |
], | |
}); | |
psbt.finalizeInput(0, (inputIndex, input, _) => ({ | |
finalScriptWitness: psbtutils.witnessStackToScriptWitness([ | |
sig, | |
input.tapLeafScript[0].script, | |
input.tapLeafScript[0].controlBlock, | |
]), | |
})); | |
break; | |
default: | |
throw new Error('Invalid payment type'); | |
} | |
return psbt; | |
}; | |
const printTest = ({ name, psbt, flags }) => { | |
const prevOut = psbt.txInputs[0]; | |
const asm = btc.script.decompile(psbt.data.inputs[0].witnessUtxo.script); | |
let spk = asm | |
.map(it => | |
Buffer.isBuffer(it) | |
? `0x${it.length.toString(16)} 0x${it.toString('hex')}` | |
: it === btc.opcodes.OP_0 | |
? '0' | |
: it === btc.opcodes.OP_1 | |
? '1' | |
: `${rOps[it]}`, | |
) | |
.join(' '); | |
console.log(` ["${name}"],`); | |
console.log(` [[["${reverseBuffer(prevOut.hash).toString('hex')}",`); | |
console.log(` ${prevOut.index},`); | |
console.log(` "${spk}",`); | |
console.log(` ${psbt.data.inputs[0].witnessUtxo.value}]],`); | |
console.log(`"${psbt.extractTransaction().toHex()}",`); | |
console.log(` "${flags}"],`); | |
}; | |
const validTests = [ | |
() => { | |
const script = mkScript('plain', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'schnorr'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('plain', 'valid', 'ecdsa'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'schnorr'); | |
const asm = btc.script.decompile(psbt.data.inputs[0].witnessUtxo.script); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK succeeds with unknown key type', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK,DISCOURAGE_UPGRADABLE_PUBKEYTYPE', | |
}; | |
}, | |
() => { | |
const script = mkScript('zero-success', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'zero'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK yields 0 for 0-sig', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('plain', 'small', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'small'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK, shorter message', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'valid', 'schnorr'); | |
return { | |
name: 'Test Taproot OP_CHECKSIGFROMSTACKVERIFY', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'valid', 'ecdsa'); | |
const psbt = mkPsbt('p2wsh', script, 'valid', 'ecdsa'); | |
return { | |
name: 'Test P2WSH OP_CHECKSIGFROMSTACKVERIFY ECDSA', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2wsh', script, 'valid', 'schnorr'); | |
return { | |
name: 'Test P2WSH OP_CHECKSIGFROMSTACKVERIFY BIP340', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'small', 'schnorr'); | |
const psbt = mkPsbt('p2wsh', script, 'valid', 'small'); | |
return { | |
name: 'Test P2WSH OP_CHECKSIGFROMSTACKVERIFY BIP340 shorter message', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'valid', 'schnorr'); | |
const psbt = mkPsbt('p2sh', script, 'valid', 'schnorr'); | |
return { | |
name: 'Test P2SH OP_CHECKSIGFROMSTACKVERIFY BIP340', | |
psbt, | |
flags: 'DISCOURAGE_CHECKSIGFROMSTACK', | |
}; | |
}, | |
]; | |
//validTests.forEach(test => printTest(test())); | |
const invalidTests = [ | |
() => { | |
const script = mkScript('zero-success', 'invalid', 'schnorr'); | |
const psbt = mkPsbt('p2tr', script, 'invalid', 'schnorr'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACK, fails immediately with sig for wrong data', | |
psbt, | |
flags: 'P2SH,WITNESS,TAPROOT,CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'small', 'ecdsa'); | |
const psbt = mkPsbt('p2wsh', script, 'invalid', 'ecdsa'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACKVERIFY ECDSA, fails for small data', | |
psbt, | |
flags: 'P2SH,TAPROOT,CHECKSIGFROMSTACK', | |
}; | |
}, | |
() => { | |
const script = mkScript('verify', 'invalid', 'schnorr'); | |
const psbt = mkPsbt('p2wsh', script, 'invalid', 'schnorr'); | |
return { | |
name: 'Test OP_CHECKSIGFROMSTACKVERIFY fails with sig for wrong data', | |
psbt, | |
flags: 'P2SH,WITNESS,CHECKSIGFROMSTACK', | |
}; | |
}, | |
]; | |
invalidTests.forEach(test => printTest(test())); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment