zebra_chain/primitives/
zcash_note_encryption.rs

1//! Contains code that interfaces with the zcash_note_encryption crate from
2//! librustzcash.
3
4use crate::{
5    block::Height,
6    parameters::{Network, NetworkUpgrade},
7    transaction::Transaction,
8};
9
10/// Returns true if all Sapling or Orchard outputs, if any, decrypt successfully with
11/// an all-zeroes outgoing viewing key.
12pub fn decrypts_successfully(tx: &Transaction, network: &Network, height: Height) -> bool {
13    let nu = NetworkUpgrade::current(network, height);
14
15    let Ok(tx) = tx.to_librustzcash(nu) else {
16        return false;
17    };
18
19    let null_sapling_ovk = sapling_crypto::keys::OutgoingViewingKey([0u8; 32]);
20
21    // Note that, since this function is used to validate coinbase transactions, we can ignore
22    // the "grace period" mentioned in ZIP-212.
23    let zip_212_enforcement = if nu >= NetworkUpgrade::Canopy {
24        sapling_crypto::note_encryption::Zip212Enforcement::On
25    } else {
26        sapling_crypto::note_encryption::Zip212Enforcement::Off
27    };
28
29    if let Some(bundle) = tx.sapling_bundle() {
30        for output in bundle.shielded_outputs().iter() {
31            let recovery = sapling_crypto::note_encryption::try_sapling_output_recovery(
32                &null_sapling_ovk,
33                output,
34                zip_212_enforcement,
35            );
36            if recovery.is_none() {
37                return false;
38            }
39        }
40    }
41
42    if let Some(bundle) = tx.orchard_bundle() {
43        for act in bundle.actions() {
44            if zcash_note_encryption::try_output_recovery_with_ovk(
45                &orchard::note_encryption::OrchardDomain::for_action(act),
46                &orchard::keys::OutgoingViewingKey::from([0u8; 32]),
47                act,
48                act.cv_net(),
49                &act.encrypted_note().out_ciphertext,
50            )
51            .is_none()
52            {
53                return false;
54            }
55        }
56    }
57
58    true
59}