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

Return ref from enc ciphertext #3

Merged
merged 9 commits into from
Aug 19, 2024
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