| 1925 | } |
| 1926 | |
| 1927 | static bool VerifyWitnessProgram(const CScriptWitness& witness, int witversion, const std::vector<unsigned char>& program, script_verify_flags flags, const BaseSignatureChecker& checker, ScriptError* serror, bool is_p2sh) |
| 1928 | { |
| 1929 | CScript exec_script; //!< Actually executed script (last stack item in P2WSH; implied P2PKH script in P2WPKH; leaf script in P2TR) |
| 1930 | std::span stack{witness.stack}; |
| 1931 | ScriptExecutionData execdata; |
| 1932 | |
| 1933 | if (witversion == 0) { |
| 1934 | if (program.size() == WITNESS_V0_SCRIPTHASH_SIZE) { |
| 1935 | // BIP141 P2WSH: 32-byte witness v0 program (which encodes SHA256(script)) |
| 1936 | if (stack.size() == 0) { |
| 1937 | return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY); |
| 1938 | } |
| 1939 | const valtype& script_bytes = SpanPopBack(stack); |
| 1940 | exec_script = CScript(script_bytes.begin(), script_bytes.end()); |
| 1941 | uint256 hash_exec_script; |
| 1942 | CSHA256().Write(exec_script.data(), exec_script.size()).Finalize(hash_exec_script.begin()); |
| 1943 | if (memcmp(hash_exec_script.begin(), program.data(), 32)) { |
| 1944 | return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); |
| 1945 | } |
| 1946 | return ExecuteWitnessScript(stack, exec_script, flags, SigVersion::WITNESS_V0, checker, execdata, serror); |
| 1947 | } else if (program.size() == WITNESS_V0_KEYHASH_SIZE) { |
| 1948 | // BIP141 P2WPKH: 20-byte witness v0 program (which encodes Hash160(pubkey)) |
| 1949 | if (stack.size() != 2) { |
| 1950 | return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_MISMATCH); // 2 items in witness |
| 1951 | } |
| 1952 | exec_script << OP_DUP << OP_HASH160 << program << OP_EQUALVERIFY << OP_CHECKSIG; |
| 1953 | return ExecuteWitnessScript(stack, exec_script, flags, SigVersion::WITNESS_V0, checker, execdata, serror); |
| 1954 | } else { |
| 1955 | return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WRONG_LENGTH); |
| 1956 | } |
| 1957 | } else if (witversion == 1 && program.size() == WITNESS_V1_TAPROOT_SIZE && !is_p2sh) { |
| 1958 | // BIP341 Taproot: 32-byte non-P2SH witness v1 program (which encodes a P2C-tweaked pubkey) |
| 1959 | if (!(flags & SCRIPT_VERIFY_TAPROOT)) return set_success(serror); |
| 1960 | if (stack.size() == 0) return set_error(serror, SCRIPT_ERR_WITNESS_PROGRAM_WITNESS_EMPTY); |
| 1961 | if (stack.size() >= 2 && !stack.back().empty() && stack.back()[0] == ANNEX_TAG) { |
| 1962 | // Drop annex (this is non-standard; see IsWitnessStandard) |
| 1963 | const valtype& annex = SpanPopBack(stack); |
| 1964 | execdata.m_annex_hash = (HashWriter{} << annex).GetSHA256(); |
| 1965 | execdata.m_annex_present = true; |
| 1966 | } else { |
| 1967 | execdata.m_annex_present = false; |
| 1968 | } |
| 1969 | execdata.m_annex_init = true; |
| 1970 | if (stack.size() == 1) { |
| 1971 | // Key path spending (stack size is 1 after removing optional annex) |
| 1972 | if (!checker.CheckSchnorrSignature(stack.front(), program, SigVersion::TAPROOT, execdata, serror)) { |
| 1973 | return false; // serror is set |
| 1974 | } |
| 1975 | return set_success(serror); |
| 1976 | } else { |
| 1977 | // Script path spending (stack size is >1 after removing optional annex) |
| 1978 | const valtype& control = SpanPopBack(stack); |
| 1979 | const valtype& script = SpanPopBack(stack); |
| 1980 | if (control.size() < TAPROOT_CONTROL_BASE_SIZE || control.size() > TAPROOT_CONTROL_MAX_SIZE || ((control.size() - TAPROOT_CONTROL_BASE_SIZE) % TAPROOT_CONTROL_NODE_SIZE) != 0) { |
| 1981 | return set_error(serror, SCRIPT_ERR_TAPROOT_WRONG_CONTROL_SIZE); |
| 1982 | } |
| 1983 | execdata.m_tapleaf_hash = ComputeTapleafHash(control[0] & TAPROOT_LEAF_MASK, script); |
| 1984 | if (!VerifyTaprootCommitment(control, program, execdata.m_tapleaf_hash)) { |
no test coverage detected