Skip to content
Merged
3 changes: 1 addition & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -102,3 +102,6 @@ harness = false
[[bench]]
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" }
2 changes: 1 addition & 1 deletion src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ impl PreparedOutputInfo {
cv,
cmu,
epk.to_bytes(),
enc_ciphertext,
enc_ciphertext.0,
out_ciphertext,
zkproof,
)
Expand Down
13 changes: 9 additions & 4 deletions src/bundle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use memuse::DynamicUsage;
use redjubjub::{Binding, SpendAuth};

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

use crate::{
Expand Down Expand Up @@ -404,7 +405,7 @@ impl<Proof: DynamicUsage> DynamicUsage for OutputDescription<Proof> {
}
}

impl<A> ShieldedOutput<SaplingDomain, ENC_CIPHERTEXT_SIZE> for OutputDescription<A> {
impl<A> ShieldedOutput<SaplingDomain> for OutputDescription<A> {
fn ephemeral_key(&self) -> EphemeralKeyBytes {
self.ephemeral_key.clone()
}
Expand All @@ -413,8 +414,12 @@ impl<A> ShieldedOutput<SaplingDomain, ENC_CIPHERTEXT_SIZE> for OutputDescription
self.cmu.to_bytes()
}

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

fn enc_ciphertext_compact(&self) -> <SaplingDomain as Domain>::CompactNoteCiphertextBytes {
unimplemented!("This function is not required for sapling")
}
}

Expand Down
51 changes: 32 additions & 19 deletions src/note_encryption.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,11 @@ use memuse::DynamicUsage;
use rand_core::RngCore;

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,
NotePlaintextBytes, OutPlaintextBytes, OutgoingCipherKey, ShieldedOutput, COMPACT_NOTE_SIZE,
ENC_CIPHERTEXT_SIZE, NOTE_PLAINTEXT_SIZE, OUT_PLAINTEXT_SIZE,
OutPlaintextBytes, OutgoingCipherKey, ShieldedOutput, COMPACT_NOTE_SIZE, ENC_CIPHERTEXT_SIZE,
NOTE_PLAINTEXT_SIZE, OUT_PLAINTEXT_SIZE,
};

use crate::{
Expand Down Expand Up @@ -144,6 +145,11 @@ impl Domain for SaplingDomain {
type ExtractedCommitmentBytes = [u8; 32];
type Memo = [u8; 512];

type NotePlaintextBytes = NoteBytesData<{ NOTE_PLAINTEXT_SIZE }>;
type NoteCiphertextBytes = NoteBytesData<{ ENC_CIPHERTEXT_SIZE }>;
type CompactNotePlaintextBytes = NoteBytesData<{ COMPACT_NOTE_SIZE }>;
type CompactNoteCiphertextBytes = NoteBytesData<{ COMPACT_NOTE_SIZE }>;

fn derive_esk(note: &Self::Note) -> Option<Self::EphemeralSecretKey> {
note.derive_esk()
}
Expand Down Expand Up @@ -184,7 +190,7 @@ impl Domain for SaplingDomain {
dhsecret.kdf_sapling(epk)
}

fn note_plaintext_bytes(note: &Self::Note, memo: &Self::Memo) -> NotePlaintextBytes {
fn note_plaintext_bytes(note: &Self::Note, memo: &Self::Memo) -> Self::NotePlaintextBytes {
// Note plaintext encoding is defined in section 5.5 of the Zcash Protocol
// Specification.
let mut input = [0; NOTE_PLAINTEXT_SIZE];
Expand All @@ -208,7 +214,7 @@ impl Domain for SaplingDomain {

input[COMPACT_NOTE_SIZE..NOTE_PLAINTEXT_SIZE].copy_from_slice(&memo[..]);

NotePlaintextBytes(input)
Self::NotePlaintextBytes::from_slice(input.as_ref()).unwrap()
}

fn derive_ock(
Expand Down Expand Up @@ -245,17 +251,17 @@ impl Domain for SaplingDomain {
fn parse_note_plaintext_without_memo_ivk(
&self,
ivk: &Self::IncomingViewingKey,
plaintext: &[u8],
plaintext: &Self::CompactNotePlaintextBytes,
) -> Option<(Self::Note, Self::Recipient)> {
sapling_parse_note_plaintext_without_memo(self, plaintext, |diversifier| {
sapling_parse_note_plaintext_without_memo(self, plaintext.as_ref(), |diversifier| {
DiversifiedTransmissionKey::derive(ivk, diversifier)
})
}

fn parse_note_plaintext_without_memo_ovk(
&self,
pk_d: &Self::DiversifiedTransmissionKey,
plaintext: &NotePlaintextBytes,
plaintext: &Self::CompactNotePlaintextBytes,
) -> Option<(Self::Note, Self::Recipient)> {
sapling_parse_note_plaintext_without_memo(self, &plaintext.0, |diversifier| {
diversifier.g_d().map(|_| *pk_d)
Expand All @@ -282,10 +288,15 @@ impl Domain for SaplingDomain {
.into()
}

fn extract_memo(&self, plaintext: &NotePlaintextBytes) -> Self::Memo {
plaintext.0[COMPACT_NOTE_SIZE..NOTE_PLAINTEXT_SIZE]
.try_into()
.expect("correct length")
fn split_plaintext_at_memo(
&self,
plaintext: &Self::NotePlaintextBytes,
) -> Option<(Self::CompactNotePlaintextBytes, Self::Memo)> {
let (compact, memo) = plaintext.0.split_at(COMPACT_NOTE_SIZE);
Some((
Self::parse_compact_note_plaintext_bytes(compact)?,
memo.try_into().ok()?,
))
}
}

Expand Down Expand Up @@ -331,7 +342,7 @@ pub struct CompactOutputDescription {

memuse::impl_no_dynamic_usage!(CompactOutputDescription);

impl ShieldedOutput<SaplingDomain, COMPACT_NOTE_SIZE> for CompactOutputDescription {
impl ShieldedOutput<SaplingDomain> for CompactOutputDescription {
fn ephemeral_key(&self) -> EphemeralKeyBytes {
self.ephemeral_key.clone()
}
Expand All @@ -340,8 +351,12 @@ impl ShieldedOutput<SaplingDomain, COMPACT_NOTE_SIZE> for CompactOutputDescripti
self.cmu.to_bytes()
}

fn enc_ciphertext(&self) -> &[u8; COMPACT_NOTE_SIZE] {
&self.enc_ciphertext
fn enc_ciphertext(&self) -> Option<<SaplingDomain as Domain>::NoteCiphertextBytes> {
None
}

fn enc_ciphertext_compact(&self) -> <SaplingDomain as Domain>::CompactNoteCiphertextBytes {
NoteBytesData::from_slice(self.enc_ciphertext.as_ref()).unwrap()
}
}

Expand Down Expand Up @@ -406,7 +421,7 @@ pub fn plaintext_version_is_valid(zip212_enforcement: Zip212Enforcement, leadbyt
}
}

pub fn try_sapling_note_decryption<Output: ShieldedOutput<SaplingDomain, ENC_CIPHERTEXT_SIZE>>(
pub fn try_sapling_note_decryption<Output: ShieldedOutput<SaplingDomain>>(
ivk: &PreparedIncomingViewingKey,
output: &Output,
zip212_enforcement: Zip212Enforcement,
Expand All @@ -415,9 +430,7 @@ pub fn try_sapling_note_decryption<Output: ShieldedOutput<SaplingDomain, ENC_CIP
try_note_decryption(&domain, ivk, output)
}

pub fn try_sapling_compact_note_decryption<
Output: ShieldedOutput<SaplingDomain, COMPACT_NOTE_SIZE>,
>(
pub fn try_sapling_compact_note_decryption<Output: ShieldedOutput<SaplingDomain>>(
ivk: &PreparedIncomingViewingKey,
output: &Output,
zip212_enforcement: Zip212Enforcement,
Expand Down Expand Up @@ -560,7 +573,7 @@ mod tests {
cv,
cmu,
epk.to_bytes(),
ne.encrypt_note_plaintext(),
ne.encrypt_note_plaintext().0,
out_ciphertext,
[0u8; GROTH_PROOF_SIZE],
);
Expand Down