From 45a6a30b2126ef1e6efc964b5ebef7b423a6ee35 Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Mon, 14 Mar 2022 17:30:37 -0600 Subject: [PATCH 1/2] Add convenience methods on `Bundle` to decrypt actions with OVKs. This renames `decrypt_outputs_for_keys` to `decrypt_outputs_with_keys` for consistency with `decrypt_output_with_key` and tne newly added `recover_output*_with_ovk*` methods. --- src/bundle.rs | 55 ++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 50 insertions(+), 5 deletions(-) diff --git a/src/bundle.rs b/src/bundle.rs index 57f91f09..2cc7d508 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -9,13 +9,13 @@ use std::io; use blake2b_simd::Hash as Blake2bHash; use memuse::DynamicUsage; use nonempty::NonEmpty; -use zcash_note_encryption::try_note_decryption; +use zcash_note_encryption::{try_note_decryption, try_output_recovery_with_ovk}; use crate::{ address::Address, bundle::commitments::{hash_bundle_auth_data, hash_bundle_txid_data}, circuit::{Instance, Proof, VerifyingKey}, - keys::IncomingViewingKey, + keys::{IncomingViewingKey, OutgoingViewingKey}, note::{ExtractedNoteCommitment, Note, Nullifier, TransmittedNoteCiphertext}, note_encryption::OrchardDomain, primitives::redpallas::{self, Binding, SpendAuth}, @@ -364,10 +364,10 @@ impl Bundle { .collect() } - /// Perform trial decryption of each action in the bundle with each of the + /// Performs trial decryption of each action in the bundle with each of the /// specified incoming viewing keys, and return the decrypted note contents /// along with the index of the action from which it was derived. - pub fn decrypt_outputs_for_keys( + pub fn decrypt_outputs_with_keys( &self, keys: &[IncomingViewingKey], ) -> Vec<(usize, IncomingViewingKey, Note, Address, [u8; 512])> { @@ -384,7 +384,7 @@ impl Bundle { .collect() } - /// Perform trial decryption of each action at `action_idx` in the bundle with the + /// Performs trial decryption of the action at `action_idx` in the bundle with the /// specified incoming viewing key, and return the decrypted note contents. pub fn decrypt_output_with_key( &self, @@ -396,6 +396,51 @@ impl Bundle { try_note_decryption(&domain, key, action) }) } + + /// Performs trial decryption of each action in the bundle with each of the + /// specified outgoing viewing keys, and return the decrypted note contents + /// along with the index of the action from which it was derived. + pub fn recover_outputs_with_ovks( + &self, + keys: &[OutgoingViewingKey], + ) -> Vec<(usize, OutgoingViewingKey, Note, Address, [u8; 512])> { + self.actions + .iter() + .enumerate() + .filter_map(|(idx, action)| { + let domain = OrchardDomain::for_action(action); + keys.iter().find_map(move |key| { + try_output_recovery_with_ovk( + &domain, + key, + action, + action.cv_net(), + &action.encrypted_note().out_ciphertext, + ) + .map(|(n, a, m)| (idx, key.clone(), n, a, m)) + }) + }) + .collect() + } + + /// Attempts to decrypt the action at the specified index with the specified + /// outgoing viewing key, and return the decrypted note contents. + pub fn recover_output_with_ovk( + &self, + action_idx: usize, + key: &OutgoingViewingKey, + ) -> Option<(Note, Address, [u8; 512])> { + self.actions.get(action_idx).and_then(move |action| { + let domain = OrchardDomain::for_action(action); + try_output_recovery_with_ovk( + &domain, + key, + action, + action.cv_net(), + &action.encrypted_note().out_ciphertext, + ) + }) + } } impl> Bundle { From 40efd57757fce12c5059959621e78dd8d06e90bb Mon Sep 17 00:00:00 2001 From: Kris Nuttycombe Date: Tue, 15 Mar 2022 07:47:21 -0600 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Daira Hopwood --- src/bundle.rs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/bundle.rs b/src/bundle.rs index 2cc7d508..e6004f45 100644 --- a/src/bundle.rs +++ b/src/bundle.rs @@ -365,8 +365,9 @@ impl Bundle { } /// Performs trial decryption of each action in the bundle with each of the - /// specified incoming viewing keys, and return the decrypted note contents - /// along with the index of the action from which it was derived. + /// specified incoming viewing keys, and returns a vector of each decrypted + /// note plaintext contents along with the index of the action from which it + /// was derived. pub fn decrypt_outputs_with_keys( &self, keys: &[IncomingViewingKey], @@ -385,7 +386,8 @@ impl Bundle { } /// Performs trial decryption of the action at `action_idx` in the bundle with the - /// specified incoming viewing key, and return the decrypted note contents. + /// specified incoming viewing key, and returns the decrypted note plaintext + /// contents if successful. pub fn decrypt_output_with_key( &self, action_idx: usize, @@ -398,8 +400,9 @@ impl Bundle { } /// Performs trial decryption of each action in the bundle with each of the - /// specified outgoing viewing keys, and return the decrypted note contents - /// along with the index of the action from which it was derived. + /// specified outgoing viewing keys, and returns a vector of each decrypted + /// note plaintext contents along with the index of the action from which it + /// was derived. pub fn recover_outputs_with_ovks( &self, keys: &[OutgoingViewingKey], @@ -424,7 +427,8 @@ impl Bundle { } /// Attempts to decrypt the action at the specified index with the specified - /// outgoing viewing key, and return the decrypted note contents. + /// outgoing viewing key, and returns the decrypted note plaintext contents + /// if successful. pub fn recover_output_with_ovk( &self, action_idx: usize,