diff --git a/Cargo.lock b/Cargo.lock index ff6675ce4..9b6afc650 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2552,7 +2552,7 @@ dependencies = [ [[package]] name = "zcash_note_encryption" version = "0.4.0" -source = "git+https://github.com/QED-it/zcash_note_encryption?branch=zsa1#b8bd2a186fc04ec4f55b2db44df7374f03ab5725" +source = "git+https://github.com/QED-it/zcash_note_encryption?branch=zsa1#58384553aab76b2ee6d6eb328cf2187fa824ec9a" dependencies = [ "chacha20", "chacha20poly1305", diff --git a/Cargo.toml b/Cargo.toml index 53da31cb3..7b0389cdd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,7 @@ rustdoc-args = ["--cfg", "docsrs", "--html-in-header", "katex-header.html"] [dependencies] aes = "0.8" bitvec = "1" -blake2b_simd = "=1.0.1" # Last version required rust 1.66 +blake2b_simd = "1" half = "=2.2.1" # Last version requires Rust 1.70 ff = "0.13" fpe = "0.6" diff --git a/src/note_encryption/compact_action.rs b/src/note_encryption/compact_action.rs index 77fc768b8..d7494d1c8 100644 --- a/src/note_encryption/compact_action.rs +++ b/src/note_encryption/compact_action.rs @@ -2,7 +2,7 @@ use std::fmt; -use zcash_note_encryption_zsa::{EphemeralKeyBytes, ShieldedOutput}; +use zcash_note_encryption_zsa::{note_bytes::NoteBytes, EphemeralKeyBytes, ShieldedOutput}; use crate::{ action::Action, @@ -25,7 +25,10 @@ impl ShieldedOutput> for Action D::CompactNoteCiphertextBytes { - self.encrypted_note().enc_ciphertext.as_ref()[..D::COMPACT_NOTE_SIZE].into() + D::CompactNoteCiphertextBytes::from_slice( + &self.encrypted_note().enc_ciphertext.as_ref()[..D::COMPACT_NOTE_SIZE], + ) + .unwrap() } } @@ -71,7 +74,7 @@ impl ShieldedOutput> for CompactAction< } fn enc_ciphertext_compact(&self) -> D::CompactNoteCiphertextBytes { - self.enc_ciphertext + D::CompactNoteCiphertextBytes::from_slice(self.enc_ciphertext.as_ref()).unwrap() } } @@ -112,7 +115,7 @@ impl CompactAction { pub mod testing { use rand::RngCore; - use zcash_note_encryption_zsa::{Domain, NoteEncryption}; + use zcash_note_encryption_zsa::{note_bytes::NoteBytes, Domain, NoteEncryption, MEMO_SIZE}; use crate::{ address::Address, @@ -145,7 +148,7 @@ pub mod testing { } }; let note = Note::from_parts(recipient, value, AssetBase::native(), rho, rseed).unwrap(); - let encryptor = NoteEncryption::>::new(ovk, note, [0u8; 512]); + let encryptor = NoteEncryption::>::new(ovk, note, [0u8; MEMO_SIZE]); let cmx = ExtractedNoteCommitment::from(note.commitment()); let ephemeral_key = OrchardDomain::::epk_bytes(encryptor.epk()); let enc_ciphertext = encryptor.encrypt_note_plaintext(); @@ -155,7 +158,10 @@ pub mod testing { nullifier: nf_old, cmx, ephemeral_key, - enc_ciphertext: enc_ciphertext.as_ref()[..52].try_into().unwrap(), + enc_ciphertext: D::CompactNoteCiphertextBytes::from_slice( + &enc_ciphertext.as_ref()[..D::COMPACT_NOTE_SIZE], + ) + .unwrap(), }, note, ) diff --git a/src/note_encryption/domain.rs b/src/note_encryption/domain.rs index c91ad81b4..ec6dc8ad3 100644 --- a/src/note_encryption/domain.rs +++ b/src/note_encryption/domain.rs @@ -7,8 +7,8 @@ use group::ff::PrimeField; use blake2b_simd::Params; use zcash_note_encryption_zsa::{ - BatchDomain, Domain, EphemeralKeyBytes, OutPlaintextBytes, OutgoingCipherKey, MEMO_SIZE, - OUT_PLAINTEXT_SIZE, + note_bytes::NoteBytes, BatchDomain, Domain, EphemeralKeyBytes, OutPlaintextBytes, + OutgoingCipherKey, MEMO_SIZE, OUT_PLAINTEXT_SIZE, }; use crate::{ @@ -255,12 +255,15 @@ impl Domain for OrchardDomain { parse_note_plaintext_without_memo::(self.rho, plaintext, |_| Some(*pk_d)) } - fn extract_memo( + fn split_plaintext_at_memo( &self, plaintext: &D::NotePlaintextBytes, - ) -> (Self::CompactNotePlaintextBytes, Self::Memo) { + ) -> Option<(Self::CompactNotePlaintextBytes, Self::Memo)> { let (compact, memo) = plaintext.as_ref().split_at(D::COMPACT_NOTE_SIZE); - (compact.into(), memo.try_into().unwrap()) + Some(( + Self::CompactNotePlaintextBytes::from_slice(compact)?, + memo.try_into().ok()?, + )) } fn extract_pk_d(out_plaintext: &OutPlaintextBytes) -> Option { diff --git a/src/note_encryption/orchard_domain.rs b/src/note_encryption/orchard_domain.rs index aa70fded6..7ee11530a 100644 --- a/src/note_encryption/orchard_domain.rs +++ b/src/note_encryption/orchard_domain.rs @@ -3,7 +3,7 @@ use core::fmt; -use zcash_note_encryption_zsa::{AEAD_TAG_SIZE, MEMO_SIZE}; +use zcash_note_encryption_zsa::{note_bytes::NoteBytes, AEAD_TAG_SIZE, MEMO_SIZE}; use crate::{ action::Action, @@ -13,48 +13,6 @@ use crate::{ use super::{compact_action::CompactAction, domain::Memo}; -/// Represents a fixed-size array of bytes for note components. -#[derive(Clone, Copy, Debug)] -pub struct NoteBytesData(pub [u8; N]); - -impl AsRef<[u8]> for NoteBytesData { - fn as_ref(&self) -> &[u8] { - &self.0 - } -} - -impl AsMut<[u8]> for NoteBytesData { - fn as_mut(&mut self) -> &mut [u8] { - &mut self.0 - } -} - -impl From<&[u8]> for NoteBytesData { - fn from(s: &[u8]) -> Self { - Self(s.try_into().unwrap()) - } -} - -impl From<(&[u8], &[u8])> for NoteBytesData { - fn from(s: (&[u8], &[u8])) -> Self { - Self([s.0, s.1].concat().try_into().unwrap()) - } -} - -/// Provides a unified interface for handling fixed-size byte arrays used in Orchard note encryption. -pub trait NoteBytes: - AsRef<[u8]> - + AsMut<[u8]> - + for<'a> From<&'a [u8]> - + for<'a> From<(&'a [u8], &'a [u8])> - + Clone - + Copy - + Send -{ -} - -impl NoteBytes for NoteBytesData {} - /// Represents the Orchard protocol domain specifics required for note encryption and decryption. pub trait OrchardDomainCommon: fmt::Debug + Clone { /// The size of a compact note, specific to the Orchard protocol. diff --git a/src/note_encryption/orchard_domain_vanilla.rs b/src/note_encryption/orchard_domain_vanilla.rs index d49c361da..187e12289 100644 --- a/src/note_encryption/orchard_domain_vanilla.rs +++ b/src/note_encryption/orchard_domain_vanilla.rs @@ -1,5 +1,7 @@ //! This module implements the note encryption logic specific for the `OrchardVanilla` flavor. +use zcash_note_encryption_zsa::note_bytes::NoteBytesData; + use crate::{ note::{AssetBase, Note}, orchard_flavor::OrchardVanilla, @@ -9,7 +11,7 @@ use super::{ domain::{ build_base_note_plaintext_bytes, Memo, COMPACT_NOTE_SIZE_VANILLA, NOTE_VERSION_BYTE_V2, }, - orchard_domain::{NoteBytesData, OrchardDomainCommon}, + orchard_domain::OrchardDomainCommon, }; impl OrchardDomainCommon for OrchardVanilla { @@ -40,8 +42,8 @@ mod tests { use rand::rngs::OsRng; use zcash_note_encryption_zsa::{ - try_compact_note_decryption, try_note_decryption, try_output_recovery_with_ovk, Domain, - EphemeralKeyBytes, + note_bytes::NoteBytesData, try_compact_note_decryption, try_note_decryption, + try_output_recovery_with_ovk, Domain, EphemeralKeyBytes, }; use crate::{ @@ -63,7 +65,7 @@ mod tests { use super::super::{ compact_action::CompactAction, domain::{parse_note_plaintext_without_memo, parse_note_version, prf_ock_orchard}, - orchard_domain::{NoteBytesData, OrchardDomain}, + orchard_domain::OrchardDomain, }; type OrchardDomainVanilla = OrchardDomain; @@ -85,7 +87,7 @@ mod tests { // Decode. let domain = OrchardDomainVanilla::for_rho(rho); - let (compact, parsed_memo) = domain.extract_memo(&plaintext); + let (compact, parsed_memo) = domain.split_plaintext_at_memo(&plaintext).unwrap(); assert!(parse_note_version(compact.as_ref()).is_some()); diff --git a/src/note_encryption/orchard_domain_zsa.rs b/src/note_encryption/orchard_domain_zsa.rs index 4979e8c91..52a23bbe1 100644 --- a/src/note_encryption/orchard_domain_zsa.rs +++ b/src/note_encryption/orchard_domain_zsa.rs @@ -1,5 +1,7 @@ //! This module implements the note encryption logic specific for the `OrchardZSA` flavor. +use zcash_note_encryption_zsa::note_bytes::NoteBytesData; + use crate::{ note::{AssetBase, Note}, orchard_flavor::OrchardZSA, @@ -10,7 +12,7 @@ use super::{ build_base_note_plaintext_bytes, Memo, COMPACT_NOTE_SIZE_VANILLA, COMPACT_NOTE_SIZE_ZSA, NOTE_VERSION_BYTE_V3, }, - orchard_domain::{NoteBytesData, OrchardDomainCommon}, + orchard_domain::OrchardDomainCommon, }; impl OrchardDomainCommon for OrchardZSA { @@ -47,8 +49,8 @@ mod tests { use rand::rngs::OsRng; use zcash_note_encryption_zsa::{ - try_compact_note_decryption, try_note_decryption, try_output_recovery_with_ovk, Domain, - EphemeralKeyBytes, + note_bytes::NoteBytesData, try_compact_note_decryption, try_note_decryption, + try_output_recovery_with_ovk, Domain, EphemeralKeyBytes, }; use crate::{ @@ -70,7 +72,7 @@ mod tests { use super::super::{ compact_action::CompactAction, domain::{parse_note_plaintext_without_memo, parse_note_version, prf_ock_orchard}, - orchard_domain::{NoteBytesData, OrchardDomain}, + orchard_domain::OrchardDomain, }; type OrchardDomainZSA = OrchardDomain; @@ -92,7 +94,7 @@ mod tests { // Decode. let domain = OrchardDomainZSA::for_rho(rho); - let (compact, parsed_memo) = domain.extract_memo(&plaintext); + let (compact, parsed_memo) = domain.split_plaintext_at_memo(&plaintext).unwrap(); assert!(parse_note_version(compact.as_ref()).is_some());