MCPcopy Create free account
hub / github.com/ElementsProject/elements / VerifyWitnessProgram

Function VerifyWitnessProgram

src/script/interpreter.cpp:3287–3380  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3285}
3286
3287static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector<unsigned char>& program, unsigned int flags, const BaseSignatureChecker& checker, ScriptError* serror, bool is_p2sh)
3288{
3289 CScript exec_script; //!< Actually executed script (last stack item in P2WSH; implied P2PKH script in P2WPKH; leaf script in P2TR)
3290 Span stack{witness.stack};
3291 ScriptExecutionData execdata;
3292
3293 if (witversion == 0) {
3294 if (program.size() == WITNESS_V0_SCRIPTHASH_SIZE) {
3295 // BIP141 P2WSH: 32-byte witness v0 program (which encodes SHA256(script))
3296 if (stack.size() == 0) {
3297 return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY);
3298 }
3299 const valtype& script_bytes = SpanPopBack(stack);
3300 exec_script = CScript(script_bytes.begin(), script_bytes.end());
3301 uint256 hash_exec_script;
3302 CSHA256().Write(exec_script.data(), exec_script.size()).Finalize(hash_exec_script.begin());
3303 if (memcmp(hash_exec_script.begin(), program.data(), 32)) {
3304 return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH);
3305 }
3306 return ExecuteWitnessScript(stack, exec_script, flags, SigVersion::WITNESS_V0, checker, execdata, serror);
3307 } else if (program.size() == WITNESS_V0_KEYHASH_SIZE) {
3308 // BIP141 P2WPKH: 20-byte witness v0 program (which encodes Hash160(pubkey))
3309 if (stack.size() != 2) {
3310 return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); // 2 items in witness
3311 }
3312 exec_script << OP_DUP << OP_HASH160 << program << OP_EQUALVERIFY << OP_CHECKSIG;
3313 return ExecuteWitnessScript(stack, exec_script, flags, SigVersion::WITNESS_V0, checker, execdata, serror);
3314 } else {
3315 return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH);
3316 }
3317 } else if (witversion == 1 && program.size() == WITNESS_V1_TAPROOT_SIZE && !is_p2sh) {
3318 // BIP341 Taproot: 32-byte non-P2SH witness v1 program (which encodes a P2C-tweaked pubkey)
3319 if (!(flags & SCRIPT_VERIFY_TAPROOT)) return set_success(serror);
3320 if (stack.size() == 0) return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY);
3321 if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) {
3322 // Drop annex (this is non-standard; see IsWitnessStandard)
3323 const valtype& annex = SpanPopBack(stack);
3324 execdata.m_annex_hash = (CHashWriter(SER_GETHASH, 0) << annex).GetSHA256();
3325 execdata.m_annex_present = true;
3326 } else {
3327 execdata.m_annex_present = false;
3328 }
3329 execdata.m_annex_init = true;
3330 if (stack.size() == 1) {
3331 // Key path spending (stack size is 1 after removing optional annex)
3332 if (!checker.CheckSchnorrSignature(stack.front(), program, SigVersion::TAPROOT, execdata, serror)) {
3333 return false; // serror is set
3334 }
3335 return set_success(serror);
3336 } else {
3337 // Script path spending (stack size is >1 after removing optional annex)
3338 const valtype& control = SpanPopBack(stack);
3339 const valtype& script_bytes = SpanPopBack(stack);
3340 exec_script = CScript(script_bytes.begin(), script_bytes.end());
3341 if (control.size() < TAPROOT_CONTROL_BASE_SIZE || control.size() > TAPROOT_CONTROL_MAX_SIZE || ((control.size() - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE) != 0) {
3342 return set_error(serror, SCRIPT_ERR_TAPROOT_WRONG_CONTROL_SIZE);
3343 }
3344 execdata.m_tapleaf_hash = ComputeTapleafHash(control[0] & TAPROOT_LEAF_MASK, exec_script);

Callers 1

VerifyScriptFunction · 0.85

Calls 15

CSHA256Class · 0.85
ExecuteWitnessScriptFunction · 0.85
set_successFunction · 0.85
CHashWriterClass · 0.85
ComputeTapleafHashFunction · 0.85
VerifyTaprootCommitmentFunction · 0.85
GetSerializeSizeFunction · 0.85
GetSHA256Method · 0.80
set_errorFunction · 0.70
CScriptClass · 0.70
sizeMethod · 0.45
beginMethod · 0.45

Tested by

no test coverage detected