-
Notifications
You must be signed in to change notification settings - Fork 251
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This isn't a real role per se; it's instead a way for accessing the parsed protocol-specific bundles for individual access and verification.
- Loading branch information
Showing
10 changed files
with
260 additions
and
71 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
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
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
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
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
use crate::Pczt; | ||
|
||
#[cfg(feature = "orchard")] | ||
mod orchard; | ||
#[cfg(feature = "orchard")] | ||
pub use orchard::OrchardError; | ||
|
||
#[cfg(feature = "sapling")] | ||
mod sapling; | ||
#[cfg(feature = "sapling")] | ||
pub use sapling::SaplingError; | ||
|
||
#[cfg(feature = "transparent")] | ||
mod transparent; | ||
#[cfg(feature = "transparent")] | ||
pub use transparent::TransparentError; | ||
|
||
pub struct Verifier { | ||
pczt: Pczt, | ||
} | ||
|
||
impl Verifier { | ||
/// Instantiates the Verifier role with the given PCZT. | ||
pub fn new(pczt: Pczt) -> Self { | ||
Self { pczt } | ||
} | ||
|
||
/// Finishes the Verifier role, returning the updated PCZT. | ||
pub fn finish(self) -> Pczt { | ||
self.pczt | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use crate::Pczt; | ||
|
||
impl super::Verifier { | ||
/// Parses the Orchard bundle and then verifies it in the given closure. | ||
pub fn with_orchard<E, F>(self, f: F) -> Result<Self, OrchardError<E>> | ||
where | ||
F: FnOnce(&orchard::pczt::Bundle) -> Result<(), OrchardError<E>>, | ||
{ | ||
let Pczt { | ||
global, | ||
transparent, | ||
sapling, | ||
orchard, | ||
} = self.pczt; | ||
|
||
let bundle = orchard.into_parsed().map_err(OrchardError::Parse)?; | ||
|
||
f(&bundle)?; | ||
|
||
Ok(Self { | ||
pczt: Pczt { | ||
global, | ||
transparent, | ||
sapling, | ||
orchard: crate::orchard::Bundle::serialize_from(bundle), | ||
}, | ||
}) | ||
} | ||
} | ||
|
||
/// Errors that can occur while verifying the Orchard bundle of a PCZT. | ||
#[derive(Debug)] | ||
pub enum OrchardError<E> { | ||
Parse(orchard::pczt::ParseError), | ||
Verify(orchard::pczt::VerifyError), | ||
Custom(E), | ||
} | ||
|
||
impl<E> From<orchard::pczt::VerifyError> for OrchardError<E> { | ||
fn from(e: orchard::pczt::VerifyError) -> Self { | ||
OrchardError::Verify(e) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
use crate::Pczt; | ||
|
||
impl super::Verifier { | ||
/// Parses the Sapling bundle and then verifies it in the given closure. | ||
pub fn with_sapling<E, F>(self, f: F) -> Result<Self, SaplingError<E>> | ||
where | ||
F: FnOnce(&sapling::pczt::Bundle) -> Result<(), SaplingError<E>>, | ||
{ | ||
let Pczt { | ||
global, | ||
transparent, | ||
sapling, | ||
orchard, | ||
} = self.pczt; | ||
|
||
let bundle = sapling.into_parsed().map_err(SaplingError::Parser)?; | ||
|
||
f(&bundle)?; | ||
|
||
Ok(Self { | ||
pczt: Pczt { | ||
global, | ||
transparent, | ||
sapling: crate::sapling::Bundle::serialize_from(bundle), | ||
orchard, | ||
}, | ||
}) | ||
} | ||
} | ||
|
||
/// Errors that can occur while verifying the Sapling bundle of a PCZT. | ||
#[derive(Debug)] | ||
pub enum SaplingError<E> { | ||
Parser(sapling::pczt::ParseError), | ||
Verifier(sapling::pczt::VerifyError), | ||
Custom(E), | ||
} | ||
|
||
impl<E> From<sapling::pczt::VerifyError> for SaplingError<E> { | ||
fn from(e: sapling::pczt::VerifyError) -> Self { | ||
SaplingError::Verifier(e) | ||
} | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
use zcash_primitives::transaction::components::transparent; | ||
|
||
use crate::Pczt; | ||
|
||
impl super::Verifier { | ||
/// Parses the Transparent bundle and then verifies it in the given closure. | ||
pub fn with_transparent<E, F>(self, f: F) -> Result<Self, TransparentError<E>> | ||
where | ||
F: FnOnce(&transparent::pczt::Bundle) -> Result<(), TransparentError<E>>, | ||
{ | ||
let Pczt { | ||
global, | ||
transparent, | ||
sapling, | ||
orchard, | ||
} = self.pczt; | ||
|
||
let bundle = transparent | ||
.into_parsed() | ||
.map_err(TransparentError::Parser)?; | ||
|
||
f(&bundle)?; | ||
|
||
Ok(Self { | ||
pczt: Pczt { | ||
global, | ||
transparent: crate::transparent::Bundle::serialize_from(bundle), | ||
sapling, | ||
orchard, | ||
}, | ||
}) | ||
} | ||
} | ||
|
||
/// Errors that can occur while verifying the Transparent bundle of a PCZT. | ||
#[derive(Debug)] | ||
pub enum TransparentError<E> { | ||
Parser(transparent::pczt::ParseError), | ||
Verifier(transparent::pczt::VerifyError), | ||
Custom(E), | ||
} | ||
|
||
impl<E> From<transparent::pczt::VerifyError> for TransparentError<E> { | ||
fn from(e: transparent::pczt::VerifyError) -> Self { | ||
TransparentError::Verifier(e) | ||
} | ||
} |
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
65 changes: 65 additions & 0 deletions
65
zcash_primitives/src/transaction/components/transparent/pczt/verify.rs
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
use ripemd::Ripemd160; | ||
use sha2::{Digest, Sha256}; | ||
|
||
use crate::legacy::TransparentAddress; | ||
|
||
impl super::Input { | ||
/// Verifies the consistency of this transparent input. | ||
/// | ||
/// If the `redeem_script` field is set, its validity will be checked. | ||
pub fn verify(&self) -> Result<(), VerifyError> { | ||
match self.script_pubkey().address() { | ||
Some(TransparentAddress::PublicKeyHash(_)) => { | ||
if self.redeem_script().is_some() { | ||
return Err(VerifyError::NotP2sh); | ||
} | ||
} | ||
Some(TransparentAddress::ScriptHash(hash)) => { | ||
if let Some(redeem_script) = self.redeem_script() { | ||
if hash[..] != Ripemd160::digest(Sha256::digest(&redeem_script.0))[..] { | ||
return Err(VerifyError::WrongRedeemScript); | ||
} | ||
} | ||
} | ||
None => return Err(VerifyError::UnsupportedScriptPubkey), | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
impl super::Output { | ||
/// Verifies the consistency of this transparent output. | ||
/// | ||
/// If the `redeem_script` field is set, its validity will be checked. | ||
pub fn verify(&self) -> Result<(), VerifyError> { | ||
match self.script_pubkey().address() { | ||
Some(TransparentAddress::PublicKeyHash(_)) => { | ||
if self.redeem_script().is_some() { | ||
return Err(VerifyError::NotP2sh); | ||
} | ||
} | ||
Some(TransparentAddress::ScriptHash(hash)) => { | ||
if let Some(redeem_script) = self.redeem_script() { | ||
if hash[..] != Ripemd160::digest(Sha256::digest(&redeem_script.0))[..] { | ||
return Err(VerifyError::WrongRedeemScript); | ||
} | ||
} | ||
} | ||
None => return Err(VerifyError::UnsupportedScriptPubkey), | ||
} | ||
|
||
Ok(()) | ||
} | ||
} | ||
|
||
/// Errors that can occur while verifying a PCZT bundle. | ||
#[derive(Debug)] | ||
pub enum VerifyError { | ||
/// A `redeem_script` can only be set on a P2SH coin. | ||
NotP2sh, | ||
/// The `script_pubkey` kind is unsupported. | ||
UnsupportedScriptPubkey, | ||
/// The provided `redeem_script` does not match the input's `script_pubkey`. | ||
WrongRedeemScript, | ||
} |