Skip to content

Commit

Permalink
Return ref from enc ciphertext (#3)
Browse files Browse the repository at this point in the history
* Update ShieldedOutput/OutputDescription to return reference for enc_ciphertext

These changes were discussed and suggested in PR zcash_note_encryption#2

* Fix path zcash_note_encryption in Cargo.toml

* Move COMPACT_NOTE_SIZE, NOTE_PLAINTEXT_SIZE, and ENC_CIPHERTEXT_SIZE constant definitions from zcash_note_encryption to here

* Trigger CI

* Fix CI cargo test errors

* Use NoteBytesData<{...}> instead of <SaplingDomain as Domain>::...

* Add MEMO_SIZE constant and use it instead of the hardcoded 512 for the memo array size

* Fix code example in comment to use MEMO_SIZE

* Make MEMO_SIZE const pub to use it in the comment code example

---------

Co-authored-by: Dmitry Demin <[email protected]>
  • Loading branch information
dmidem and dmidem authored Aug 19, 2024
1 parent e19f4d9 commit 99ad0a5
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 43 deletions.
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
Expand Up @@ -104,4 +104,4 @@ name = "pedersen_hash"
harness = false

[patch.crates-io]
zcash_note_encryption = { version = "0.4", git = "https://github.com/QED-it/zcash_note_encryption", branch = "zsa1" }
zcash_note_encryption = { version = "0.4", git = "https://github.com/QED-it/zcash_note_encryption", branch = "zsa1" }
12 changes: 6 additions & 6 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
},
circuit,
keys::{OutgoingViewingKey, SpendAuthorizingKey, SpendValidatingKey},
note_encryption::{sapling_note_encryption, Zip212Enforcement},
note_encryption::{sapling_note_encryption, Zip212Enforcement, MEMO_SIZE},
prover::{OutputProver, SpendProver},
util::generate_random_rseed_internal,
value::{
Expand Down Expand Up @@ -281,7 +281,7 @@ pub struct OutputInfo {
ovk: Option<OutgoingViewingKey>,
to: PaymentAddress,
value: NoteValue,
memo: [u8; 512],
memo: [u8; MEMO_SIZE],
}

impl OutputInfo {
Expand All @@ -290,14 +290,14 @@ impl OutputInfo {
ovk: Option<OutgoingViewingKey>,
to: PaymentAddress,
value: NoteValue,
memo: Option<[u8; 512]>,
memo: Option<[u8; MEMO_SIZE]>,
) -> Self {
Self {
ovk,
to,
value,
memo: memo.unwrap_or_else(|| {
let mut memo = [0; 512];
let mut memo = [0; MEMO_SIZE];
memo[0] = 0xf6;
memo
}),
Expand Down Expand Up @@ -353,7 +353,7 @@ struct PreparedOutputInfo {
/// `None` represents the `ovk = ⊥` case.
ovk: Option<OutgoingViewingKey>,
note: Note,
memo: [u8; 512],
memo: [u8; MEMO_SIZE],
rcv: ValueCommitTrapdoor,
}

Expand Down Expand Up @@ -523,7 +523,7 @@ impl Builder {
ovk: Option<OutgoingViewingKey>,
to: PaymentAddress,
value: NoteValue,
memo: Option<[u8; 512]>,
memo: Option<[u8; MEMO_SIZE]>,
) -> Result<(), Error> {
let output = OutputInfo::new(ovk, to, value, memo);

Expand Down
31 changes: 17 additions & 14 deletions src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,15 @@ use memuse::DynamicUsage;
use redjubjub::{Binding, SpendAuth};

use zcash_note_encryption::{
note_bytes::NoteBytesData, Domain, EphemeralKeyBytes, ShieldedOutput, COMPACT_NOTE_SIZE,
ENC_CIPHERTEXT_SIZE, OUT_CIPHERTEXT_SIZE,
note_bytes::NoteBytesData, EphemeralKeyBytes, ShieldedOutput, OUT_CIPHERTEXT_SIZE,
};

use crate::{
circuit::GROTH_PROOF_SIZE,
note::ExtractedNoteCommitment,
note_encryption::{CompactOutputDescription, SaplingDomain},
note_encryption::{
CompactOutputDescription, SaplingDomain, COMPACT_NOTE_SIZE, ENC_CIPHERTEXT_SIZE,
},
value::ValueCommitment,
Nullifier,
};
Expand Down Expand Up @@ -321,7 +322,7 @@ pub struct OutputDescription<Proof> {
cv: ValueCommitment,
cmu: ExtractedNoteCommitment,
ephemeral_key: EphemeralKeyBytes,
enc_ciphertext: [u8; ENC_CIPHERTEXT_SIZE],
enc_ciphertext: NoteBytesData<{ ENC_CIPHERTEXT_SIZE }>,
out_ciphertext: [u8; OUT_CIPHERTEXT_SIZE],
zkproof: Proof,
}
Expand All @@ -342,7 +343,7 @@ impl<Proof> OutputDescription<Proof> {
}

/// Returns the encrypted note ciphertext.
pub fn enc_ciphertext(&self) -> &[u8; ENC_CIPHERTEXT_SIZE] {
pub fn enc_ciphertext(&self) -> &NoteBytesData<{ ENC_CIPHERTEXT_SIZE }> {
&self.enc_ciphertext
}

Expand All @@ -369,7 +370,7 @@ impl<Proof> OutputDescription<Proof> {
cv,
cmu,
ephemeral_key,
enc_ciphertext,
enc_ciphertext: NoteBytesData(enc_ciphertext),
out_ciphertext,
zkproof,
}
Expand All @@ -388,7 +389,7 @@ impl<Proof> OutputDescription<Proof> {
&mut self.ephemeral_key
}
pub(crate) fn enc_ciphertext_mut(&mut self) -> &mut [u8; ENC_CIPHERTEXT_SIZE] {
&mut self.enc_ciphertext
&mut self.enc_ciphertext.0
}
pub(crate) fn out_ciphertext_mut(&mut self) -> &mut [u8; OUT_CIPHERTEXT_SIZE] {
&mut self.out_ciphertext
Expand All @@ -414,11 +415,11 @@ impl<A> ShieldedOutput<SaplingDomain> for OutputDescription<A> {
self.cmu.to_bytes()
}

fn enc_ciphertext(&self) -> Option<<SaplingDomain as Domain>::NoteCiphertextBytes> {
Some(NoteBytesData(self.enc_ciphertext))
fn enc_ciphertext(&self) -> Option<&NoteBytesData<{ ENC_CIPHERTEXT_SIZE }>> {
Some(&self.enc_ciphertext)
}

fn enc_ciphertext_compact(&self) -> <SaplingDomain as Domain>::CompactNoteCiphertextBytes {
fn enc_ciphertext_compact(&self) -> NoteBytesData<{ COMPACT_NOTE_SIZE }> {
unimplemented!("This function is not required for sapling")
}
}
Expand Down Expand Up @@ -470,7 +471,7 @@ impl OutputDescriptionV5 {
cv: self.cv,
cmu: self.cmu,
ephemeral_key: self.ephemeral_key,
enc_ciphertext: self.enc_ciphertext,
enc_ciphertext: NoteBytesData(self.enc_ciphertext),
out_ciphertext: self.out_ciphertext,
zkproof,
}
Expand All @@ -482,7 +483,9 @@ impl<A> From<OutputDescription<A>> for CompactOutputDescription {
CompactOutputDescription {
ephemeral_key: out.ephemeral_key,
cmu: out.cmu,
enc_ciphertext: out.enc_ciphertext[..COMPACT_NOTE_SIZE].try_into().unwrap(),
enc_ciphertext: out.enc_ciphertext.as_ref()[..COMPACT_NOTE_SIZE]
.try_into()
.unwrap(),
}
}
}
Expand All @@ -509,7 +512,7 @@ pub mod testing {
};

use super::{
Authorized, Bundle, GrothProofBytes, OutputDescription, SpendDescription,
Authorized, Bundle, GrothProofBytes, NoteBytesData, OutputDescription, SpendDescription,
ENC_CIPHERTEXT_SIZE, OUT_CIPHERTEXT_SIZE,
};

Expand Down Expand Up @@ -572,7 +575,7 @@ pub mod testing {
cv,
cmu,
ephemeral_key: epk.to_bytes().into(),
enc_ciphertext,
enc_ciphertext: NoteBytesData(enc_ciphertext),
out_ciphertext,
zkproof,
}
Expand Down
56 changes: 35 additions & 21 deletions src/note_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,24 @@ use zcash_note_encryption::{
note_bytes::{NoteBytes, NoteBytesData},
try_compact_note_decryption, try_note_decryption, try_output_recovery_with_ock,
try_output_recovery_with_ovk, BatchDomain, Domain, EphemeralKeyBytes, NoteEncryption,
OutPlaintextBytes, OutgoingCipherKey, ShieldedOutput, COMPACT_NOTE_SIZE, ENC_CIPHERTEXT_SIZE,
NOTE_PLAINTEXT_SIZE, OUT_PLAINTEXT_SIZE,
OutPlaintextBytes, OutgoingCipherKey, ShieldedOutput, AEAD_TAG_SIZE, OUT_PLAINTEXT_SIZE,
};

/// The size of the memo.
pub const MEMO_SIZE: usize = 512;

/// The size of a compact note.
pub const COMPACT_NOTE_SIZE: usize = 1 + // version
11 + // diversifier
8 + // value
32; // rseed (or rcm prior to ZIP 212)

/// The size of [`Domain::NotePlaintextBytes`].
pub const NOTE_PLAINTEXT_SIZE: usize = COMPACT_NOTE_SIZE + MEMO_SIZE;

/// The size of an encrypted note plaintext.
pub const ENC_CIPHERTEXT_SIZE: usize = NOTE_PLAINTEXT_SIZE + AEAD_TAG_SIZE;

use crate::{
bundle::{GrothProofBytes, OutputDescription},
keys::{
Expand Down Expand Up @@ -143,7 +157,7 @@ impl Domain for SaplingDomain {
type ValueCommitment = ValueCommitment;
type ExtractedCommitment = ExtractedNoteCommitment;
type ExtractedCommitmentBytes = [u8; 32];
type Memo = [u8; 512];
type Memo = [u8; MEMO_SIZE];

type NotePlaintextBytes = NoteBytesData<{ NOTE_PLAINTEXT_SIZE }>;
type NoteCiphertextBytes = NoteBytesData<{ ENC_CIPHERTEXT_SIZE }>;
Expand Down Expand Up @@ -263,7 +277,7 @@ impl Domain for SaplingDomain {
pk_d: &Self::DiversifiedTransmissionKey,
plaintext: &Self::CompactNotePlaintextBytes,
) -> Option<(Self::Note, Self::Recipient)> {
sapling_parse_note_plaintext_without_memo(self, &plaintext.0, |diversifier| {
sapling_parse_note_plaintext_without_memo(self, plaintext.as_ref(), |diversifier| {
diversifier.g_d().map(|_| *pk_d)
})
}
Expand Down Expand Up @@ -351,11 +365,11 @@ impl ShieldedOutput<SaplingDomain> for CompactOutputDescription {
self.cmu.to_bytes()
}

fn enc_ciphertext(&self) -> Option<<SaplingDomain as Domain>::NoteCiphertextBytes> {
fn enc_ciphertext(&self) -> Option<&NoteBytesData<{ ENC_CIPHERTEXT_SIZE }>> {
None
}

fn enc_ciphertext_compact(&self) -> <SaplingDomain as Domain>::CompactNoteCiphertextBytes {
fn enc_ciphertext_compact(&self) -> NoteBytesData<{ COMPACT_NOTE_SIZE }> {
NoteBytesData::from_slice(self.enc_ciphertext.as_ref()).unwrap()
}
}
Expand All @@ -374,7 +388,7 @@ impl ShieldedOutput<SaplingDomain> for CompactOutputDescription {
/// use rand_core::OsRng;
/// use sapling_crypto::{
/// keys::OutgoingViewingKey,
/// note_encryption::{sapling_note_encryption, Zip212Enforcement},
/// note_encryption::{sapling_note_encryption, Zip212Enforcement, MEMO_SIZE},
/// util::generate_random_rseed,
/// value::{NoteValue, ValueCommitTrapdoor, ValueCommitment},
/// Diversifier, PaymentAddress, Rseed, SaplingIvk,
Expand All @@ -397,14 +411,14 @@ impl ShieldedOutput<SaplingDomain> for CompactOutputDescription {
/// let note = to.create_note(value, rseed);
/// let cmu = note.cmu();
///
/// let mut enc = sapling_note_encryption(ovk, note, [0x37; 512], &mut rng);
/// let mut enc = sapling_note_encryption(ovk, note, [0x37; MEMO_SIZE], &mut rng);
/// let encCiphertext = enc.encrypt_note_plaintext();
/// let outCiphertext = enc.encrypt_outgoing_plaintext(&cv, &cmu, &mut rng);
/// ```
pub fn sapling_note_encryption<R: RngCore>(
ovk: Option<OutgoingViewingKey>,
note: Note,
memo: [u8; 512],
memo: [u8; MEMO_SIZE],
rng: &mut R,
) -> NoteEncryption<SaplingDomain> {
let esk = note.generate_or_derive_esk_internal(rng);
Expand All @@ -425,7 +439,7 @@ pub fn try_sapling_note_decryption<Output: ShieldedOutput<SaplingDomain>>(
ivk: &PreparedIncomingViewingKey,
output: &Output,
zip212_enforcement: Zip212Enforcement,
) -> Option<(Note, PaymentAddress, [u8; 512])> {
) -> Option<(Note, PaymentAddress, [u8; MEMO_SIZE])> {
let domain = SaplingDomain::new(zip212_enforcement);
try_note_decryption(&domain, ivk, output)
}
Expand All @@ -451,7 +465,7 @@ pub fn try_sapling_output_recovery_with_ock(
ock: &OutgoingCipherKey,
output: &OutputDescription<GrothProofBytes>,
zip212_enforcement: Zip212Enforcement,
) -> Option<(Note, PaymentAddress, [u8; 512])> {
) -> Option<(Note, PaymentAddress, [u8; MEMO_SIZE])> {
let domain = SaplingDomain::new(zip212_enforcement);
try_output_recovery_with_ock(&domain, ock, output, output.out_ciphertext())
}
Expand All @@ -468,7 +482,7 @@ pub fn try_sapling_output_recovery(
ovk: &OutgoingViewingKey,
output: &OutputDescription<GrothProofBytes>,
zip212_enforcement: Zip212Enforcement,
) -> Option<(Note, PaymentAddress, [u8; 512])> {
) -> Option<(Note, PaymentAddress, [u8; MEMO_SIZE])> {
let domain = SaplingDomain::new(zip212_enforcement);
try_output_recovery_with_ovk(&domain, ovk, output, output.cv(), output.out_ciphertext())
}
Expand All @@ -486,23 +500,23 @@ mod tests {
use rand_core::{CryptoRng, RngCore};

use zcash_note_encryption::{
batch, EphemeralKeyBytes, NoteEncryption, OutgoingCipherKey, ENC_CIPHERTEXT_SIZE,
NOTE_PLAINTEXT_SIZE, OUT_CIPHERTEXT_SIZE, OUT_PLAINTEXT_SIZE,
batch, EphemeralKeyBytes, NoteEncryption, OutgoingCipherKey, OUT_CIPHERTEXT_SIZE,
OUT_PLAINTEXT_SIZE,
};

use super::{
prf_ock, sapling_note_encryption, try_sapling_compact_note_decryption,
try_sapling_note_decryption, try_sapling_output_recovery,
try_sapling_output_recovery_with_ock, CompactOutputDescription, SaplingDomain,
Zip212Enforcement,
try_sapling_output_recovery_with_ock, CompactOutputDescription, NoteBytesData,
SaplingDomain, Zip212Enforcement, MEMO_SIZE,
};

use crate::{
bundle::{GrothProofBytes, OutputDescription},
circuit::GROTH_PROOF_SIZE,
keys::{DiversifiedTransmissionKey, EphemeralSecretKey, OutgoingViewingKey},
note::ExtractedNoteCommitment,
note_encryption::PreparedIncomingViewingKey,
note_encryption::{PreparedIncomingViewingKey, ENC_CIPHERTEXT_SIZE, NOTE_PLAINTEXT_SIZE},
util::generate_random_rseed,
value::{NoteValue, ValueCommitTrapdoor, ValueCommitment},
Diversifier, PaymentAddress, Rseed, SaplingIvk,
Expand Down Expand Up @@ -564,7 +578,7 @@ mod tests {
let cmu = note.cmu();

let ovk = OutgoingViewingKey([0; 32]);
let ne = sapling_note_encryption(Some(ovk), note, [0x37; 512], &mut rng);
let ne = sapling_note_encryption(Some(ovk), note, [0x37; MEMO_SIZE], &mut rng);
let epk = ne.epk();
let ock = prf_ock(&ovk, &cv, &cmu.to_bytes(), &epk.to_bytes());

Expand Down Expand Up @@ -620,7 +634,7 @@ mod tests {
cv: &ValueCommitment,
cmu: &ExtractedNoteCommitment,
ephemeral_key: &EphemeralKeyBytes,
enc_ciphertext: &[u8; ENC_CIPHERTEXT_SIZE],
enc_ciphertext: &NoteBytesData<{ ENC_CIPHERTEXT_SIZE }>,
out_ciphertext: &[u8; OUT_CIPHERTEXT_SIZE],
modify_plaintext: impl Fn(&mut [u8; NOTE_PLAINTEXT_SIZE]),
) -> [u8; ENC_CIPHERTEXT_SIZE] {
Expand All @@ -646,14 +660,14 @@ mod tests {
let key = shared_secret.kdf_sapling(ephemeral_key);

let mut plaintext = [0; NOTE_PLAINTEXT_SIZE];
plaintext.copy_from_slice(&enc_ciphertext[..NOTE_PLAINTEXT_SIZE]);
plaintext.copy_from_slice(&enc_ciphertext.as_ref()[..NOTE_PLAINTEXT_SIZE]);

ChaCha20Poly1305::new(key.as_bytes().into())
.decrypt_in_place_detached(
[0u8; 12][..].into(),
&[],
&mut plaintext,
enc_ciphertext[NOTE_PLAINTEXT_SIZE..].into(),
enc_ciphertext.as_ref()[NOTE_PLAINTEXT_SIZE..].into(),
)
.unwrap();

Expand Down

0 comments on commit 99ad0a5

Please sign in to comment.