Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Remove redundant checks during note encryption #394

Merged
merged 1 commit into from
May 26, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 7 additions & 19 deletions src/note_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@ use crate::{
OutgoingViewingKey, PreparedEphemeralPublicKey, PreparedIncomingViewingKey, SharedSecret,
},
note::{ExtractedNoteCommitment, Nullifier, RandomSeed},
spec::diversify_hash,
value::{NoteValue, ValueCommitment},
Address, Note,
};
Expand Down Expand Up @@ -52,10 +51,10 @@ pub(crate) fn prf_ock_orchard(
fn orchard_parse_note_plaintext_without_memo<F>(
domain: &OrchardDomain,
plaintext: &[u8],
get_validated_pk_d: F,
get_pk_d: F,
) -> Option<(Note, Address)>
where
F: FnOnce(&Diversifier) -> Option<DiversifiedTransmissionKey>,
F: FnOnce(&Diversifier) -> DiversifiedTransmissionKey,
{
assert!(plaintext.len() >= COMPACT_NOTE_SIZE);

Expand All @@ -72,7 +71,7 @@ where
&domain.rho,
))?;

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

let recipient = Address::from_parts(diversifier, pk_d);
let note = Option::from(Note::from_parts(recipient, value, domain.rho, rseed))?;
Expand Down Expand Up @@ -209,29 +208,18 @@ impl Domain for OrchardDomain {
plaintext: &[u8],
) -> Option<(Self::Note, Self::Recipient)> {
orchard_parse_note_plaintext_without_memo(self, plaintext, |diversifier| {
Some(DiversifiedTransmissionKey::derive(ivk, diversifier))
DiversifiedTransmissionKey::derive(ivk, diversifier)
})
}

fn parse_note_plaintext_without_memo_ovk(
&self,
pk_d: &Self::DiversifiedTransmissionKey,
esk: &Self::EphemeralSecretKey,
ephemeral_key: &EphemeralKeyBytes,
_esk: &Self::EphemeralSecretKey,
_ephemeral_key: &EphemeralKeyBytes,
Comment on lines +218 to +219
Copy link
Contributor

@daira daira May 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
_esk: &Self::EphemeralSecretKey,
_ephemeral_key: &EphemeralKeyBytes,

See https://github.com/zcash/librustzcash/pull/848/files#r1199198303

It may seem as though this is making life more difficult because removing these arguments is a breaking change, but strictly speaking the change to the guarantee of the method is a breaking API change anyway, even if not one that would otherwise be detected by the Rust compiler.

That is, it would be incorrect to mix a version of orchard from after this PR with a version of zcash_note_encryption from before zcash/librustzcash#848 — not (as it happens) because it would be insecure per se, but because that usage hasn't been reviewed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mixing in the way you describe cannot happen, because the traits would not be version-compatible. Rust code is never dynamically linked internally.

plaintext: &NotePlaintextBytes,
) -> Option<(Self::Note, Self::Recipient)> {
orchard_parse_note_plaintext_without_memo(self, &plaintext.0, |diversifier| {
if esk
.derive_public(diversify_hash(diversifier.as_array()))
.to_bytes()
.0
== ephemeral_key.0
{
Some(*pk_d)
} else {
None
}
})
orchard_parse_note_plaintext_without_memo(self, &plaintext.0, |_| *pk_d)
}

fn extract_memo(&self, plaintext: &NotePlaintextBytes) -> Self::Memo {
Expand Down