Skip to content

Commit

Permalink
Merge pull request #848 from zcash/note-encryption-avoid-redundant-ch…
Browse files Browse the repository at this point in the history
…ecks

Avoid redundant checks during note decryption
  • Loading branch information
nuttycom authored May 26, 2023
2 parents d56c662 + 2ae4d87 commit 3ae9002
Show file tree
Hide file tree
Showing 3 changed files with 20 additions and 12 deletions.
2 changes: 0 additions & 2 deletions components/zcash_note_encryption/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,6 @@ pub trait Domain {
/// which may be passed via `self`).
/// - The note plaintext contains valid encodings of its various fields.
/// - Any domain-specific requirements are satisfied.
/// - `ephemeral_key` can be derived from `esk` and the diversifier within the note
/// plaintext.
///
/// `&self` is passed here to enable the implementation to enforce contextual checks,
/// such as rules like [ZIP 212] that become active at a specific block height.
Expand Down
11 changes: 11 additions & 0 deletions zcash_primitives/src/sapling/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,17 @@ impl PaymentAddress {
// Check that the diversifier is valid
diversifier.g_d()?;

Self::from_parts_unchecked(diversifier, pk_d)
}

/// Constructs a PaymentAddress from a diversifier and a Jubjub point.
///
/// Returns None if `pk_d` is the identity. The caller must check that `diversifier`
/// is valid for Sapling.
pub(crate) fn from_parts_unchecked(
diversifier: Diversifier,
pk_d: DiversifiedTransmissionKey,
) -> Option<Self> {
if pk_d.is_identity() {
None
} else {
Expand Down
19 changes: 9 additions & 10 deletions zcash_primitives/src/sapling/note_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ pub fn prf_ock(
)
}

/// `get_pk_d` must check that the diversifier contained within the note plaintext is a
/// valid Sapling diversifier.
fn sapling_parse_note_plaintext_without_memo<F, P: consensus::Parameters>(
domain: &SaplingDomain<P>,
plaintext: &[u8],
get_validated_pk_d: F,
get_pk_d: F,
) -> Option<(Note, PaymentAddress)>
where
F: FnOnce(&Diversifier) -> Option<DiversifiedTransmissionKey>,
Expand All @@ -91,9 +93,10 @@ where
Rseed::AfterZip212(r)
};

let pk_d = get_validated_pk_d(&diversifier)?;
let pk_d = get_pk_d(&diversifier)?;

let to = PaymentAddress::from_parts(diversifier, pk_d)?;
// `diversifier` was checked by `get_pk_d`.
let to = PaymentAddress::from_parts_unchecked(diversifier, pk_d)?;
let note = to.create_note(value.into(), rseed);
Some((note, to))
}
Expand Down Expand Up @@ -254,16 +257,12 @@ impl<P: consensus::Parameters> Domain for SaplingDomain<P> {
fn parse_note_plaintext_without_memo_ovk(
&self,
pk_d: &Self::DiversifiedTransmissionKey,
esk: &Self::EphemeralSecretKey,
ephemeral_key: &EphemeralKeyBytes,
_esk: &Self::EphemeralSecretKey,
_ephemeral_key: &EphemeralKeyBytes,
plaintext: &NotePlaintextBytes,
) -> Option<(Self::Note, Self::Recipient)> {
sapling_parse_note_plaintext_without_memo(self, &plaintext.0, |diversifier| {
if esk.derive_public(diversifier.g_d()?.into()).to_bytes().0 == ephemeral_key.0 {
Some(*pk_d)
} else {
None
}
diversifier.g_d().map(|_| *pk_d)
})
}

Expand Down

0 comments on commit 3ae9002

Please sign in to comment.