zcash_transparent/pczt/
verify.rs

1use ripemd::Ripemd160;
2use sha2::{Digest, Sha256};
3
4use crate::address::TransparentAddress;
5
6impl super::Input {
7    /// Verifies the consistency of this transparent input.
8    ///
9    /// If the `redeem_script` field is set, its validity will be checked.
10    pub fn verify(&self) -> Result<(), VerifyError> {
11        match self.script_pubkey().address() {
12            Some(TransparentAddress::PublicKeyHash(_)) => {
13                if self.redeem_script().is_some() {
14                    return Err(VerifyError::NotP2sh);
15                }
16            }
17            Some(TransparentAddress::ScriptHash(hash)) => {
18                if let Some(redeem_script) = self.redeem_script() {
19                    if hash[..] != Ripemd160::digest(Sha256::digest(&redeem_script.0))[..] {
20                        return Err(VerifyError::WrongRedeemScript);
21                    }
22                }
23            }
24            None => return Err(VerifyError::UnsupportedScriptPubkey),
25        }
26
27        Ok(())
28    }
29}
30
31impl super::Output {
32    /// Verifies the consistency of this transparent output.
33    ///
34    /// If the `redeem_script` field is set, its validity will be checked.
35    pub fn verify(&self) -> Result<(), VerifyError> {
36        match self.script_pubkey().address() {
37            Some(TransparentAddress::PublicKeyHash(_)) => {
38                if self.redeem_script().is_some() {
39                    return Err(VerifyError::NotP2sh);
40                }
41            }
42            Some(TransparentAddress::ScriptHash(hash)) => {
43                if let Some(redeem_script) = self.redeem_script() {
44                    if hash[..] != Ripemd160::digest(Sha256::digest(&redeem_script.0))[..] {
45                        return Err(VerifyError::WrongRedeemScript);
46                    }
47                }
48            }
49            None => return Err(VerifyError::UnsupportedScriptPubkey),
50        }
51
52        Ok(())
53    }
54}
55
56/// Errors that can occur while verifying a PCZT bundle.
57#[derive(Debug)]
58pub enum VerifyError {
59    /// A `redeem_script` can only be set on a P2SH coin.
60    NotP2sh,
61    /// The `script_pubkey` kind is unsupported.
62    UnsupportedScriptPubkey,
63    /// The provided `redeem_script` does not match the input's `script_pubkey`.
64    WrongRedeemScript,
65}