Skip to content

Commit

Permalink
Merge pull request #5 from zcash/recipient_output_decruption
Browse files Browse the repository at this point in the history
Add `zcash_note_encryption::try_output_recovery_with_pkd_esk`
  • Loading branch information
nuttycom authored Dec 7, 2024
2 parents 7db1c6f + ede44ea commit 7ea9f44
Show file tree
Hide file tree
Showing 5 changed files with 29 additions and 6 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this library adheres to Rust's notion of

## [Unreleased]

## [0.4.1] - 2024-12-06
### Added
- `zcash_note_encryption::try_output_recovery_with_pkd_esk`

## [0.4.0] - 2023-06-06
### Changed
- The `esk` and `ephemeral_key` arguments have been removed from
Expand Down
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "zcash_note_encryption"
description = "Note encryption for Zcash transactions"
version = "0.4.0"
version = "0.4.1"
authors = [
"Jack Grigg <[email protected]>",
"Kris Nuttycombe <[email protected]>"
Expand Down
3 changes: 1 addition & 2 deletions src/batch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,11 @@ where
key_chunk
.iter()
.zip(ivks.iter().enumerate())
.filter_map(|(key, (i, ivk))| {
.find_map(|(key, (i, ivk))| {
key.as_ref()
.and_then(|key| decrypt_inner(domain, ivk, ephemeral_key, output, key))
.map(|out| (out, i))
})
.next()
})
.collect::<Vec<Option<_>>>()
}
24 changes: 22 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -636,8 +636,6 @@ pub fn try_output_recovery_with_ock<D: Domain, Output: ShieldedOutput<D, ENC_CIP
output: &Output,
out_ciphertext: &[u8; OUT_CIPHERTEXT_SIZE],
) -> Option<(D::Note, D::Recipient, D::Memo)> {
let enc_ciphertext = output.enc_ciphertext();

let mut op = OutPlaintextBytes([0; OUT_PLAINTEXT_SIZE]);
op.0.copy_from_slice(&out_ciphertext[..OUT_PLAINTEXT_SIZE]);

Expand All @@ -653,13 +651,35 @@ pub fn try_output_recovery_with_ock<D: Domain, Output: ShieldedOutput<D, ENC_CIP
let pk_d = D::extract_pk_d(&op)?;
let esk = D::extract_esk(&op)?;

try_output_recovery_with_pkd_esk(domain, pk_d, esk, output)
}

/// Recovery of the full note plaintext by the sender.
///
/// Attempts to decrypt and validate the given shielded output using the given `pk_d` and `esk`. If
/// successful, the corresponding note and memo are returned, along with the address to which the
/// note was sent.
///
/// Implements part of section 4.19.3 of the
/// [Zcash Protocol Specification](https://zips.z.cash/protocol/nu5.pdf#decryptovk).
/// For decryption using a Full Viewing Key see [`try_output_recovery_with_ovk`].
pub fn try_output_recovery_with_pkd_esk<
D: Domain,
Output: ShieldedOutput<D, ENC_CIPHERTEXT_SIZE>,
>(
domain: &D,
pk_d: D::DiversifiedTransmissionKey,
esk: D::EphemeralSecretKey,
output: &Output,
) -> Option<(D::Note, D::Recipient, D::Memo)> {
let ephemeral_key = output.ephemeral_key();
let shared_secret = D::ka_agree_enc(&esk, &pk_d);
// The small-order point check at the point of output parsing rejects
// non-canonical encodings, so reencoding here for the KDF should
// be okay.
let key = D::kdf(shared_secret, &ephemeral_key);

let enc_ciphertext = output.enc_ciphertext();
let mut plaintext = NotePlaintextBytes([0; NOTE_PLAINTEXT_SIZE]);
plaintext
.0
Expand Down

0 comments on commit 7ea9f44

Please sign in to comment.