Variable-size note encryption support#177
Conversation
#2) * Use updated backward compatible zcash_note_encryption (WIP) * Move constants from zcash_note_encryption * Use NoteBytes from zcash_note_encryption * Add new line * Use NoteBytesData * Synchronize with updates from zcash_note_encryption for PR #2 issues resolve * Revert toolchain Rust version back to 1.65.0 * Change zcash_note_encryption reference in Cargo.toml to point to the zsa1 branch * Remove FIXME comments and other minor changes * Move implementations of parse_... Domain trait methods to zcash_note_encryption crate --------- Co-authored-by: alexeykoren <2365507+alexeykoren@users.noreply.github.com> Co-authored-by: Dmitry Demin <dmitry@qed-it.com>
* 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 <dmitry@qed-it.com>
Update zsa1 to ustream
# Conflicts: # .github/workflows/ci.yml # src/builder.rs # src/pczt.rs
Merge upstream 20260309
- Use `rev` instead of a branch in the patch section of `Cargo.toml` (to match our other repositories) - Remove `Option` from `memo`
| Some(&self.enc_ciphertext) | ||
| } | ||
|
|
||
| fn enc_ciphertext_compact(&self) -> NoteBytesData<{ COMPACT_NOTE_SIZE }> { |
There was a problem hiding this comment.
Using the same type for enc ciphertexts and compact enc ciphertexts seems like a type error: they don't only differ in length, but also in semantics (compact enc ciphertexts don't have a memo and don't use authenticated encryption as of NU6.1). I don't think there are cases where we'd want to use them polymorphically.
Consider splitting/renaming NoteBytesData into two types: EncCiphertext and CompactEncCiphertext. These can even be type aliases to NoteBytesData with particular lengths if you want to make the minimal change.
| 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] |
There was a problem hiding this comment.
This is not the enc ciphertext, so the field is misnamed. I realize it was misnamed before. Consider renaming it to enc_ciphertext_compact if that isn't too disruptive. Or that can be a separate PR. (It might need to be done for Orchard as well.)
There was a problem hiding this comment.
Out of scope for this PR, as discussed.
| } | ||
|
|
||
| fn enc_ciphertext_compact(&self) -> NoteBytesData<{ COMPACT_NOTE_SIZE }> { | ||
| unimplemented!("This function is not required for sapling") |
There was a problem hiding this comment.
Why can't the truncation be implemented here rather than manually truncating in several other places? It seems as though those places could call enc_ciphertext_compact instead.
There was a problem hiding this comment.
Done (implemented enc_ciphertext_compact)
| type Memo = [u8; MEMO_SIZE]; | ||
|
|
||
| type NotePlaintextBytes = NoteBytesData<{ NOTE_PLAINTEXT_SIZE }>; | ||
| type NoteCiphertextBytes = NoteBytesData<{ ENC_CIPHERTEXT_SIZE }>; |
There was a problem hiding this comment.
This would become type EncCiphertextBytes = EncCiphertextBytes;, etc.
There was a problem hiding this comment.
Out of scope for this PR, as discussed.
|
|
||
| fn enc_ciphertext(&self) -> &[u8; COMPACT_NOTE_SIZE] { | ||
| &self.enc_ciphertext | ||
| fn enc_ciphertext(&self) -> Option<&NoteBytesData<{ ENC_CIPHERTEXT_SIZE }>> { |
There was a problem hiding this comment.
Hmm. The previous API was terrible (enc_ciphertext() returning something that is not an enc ciphertext) but this also seems error-prone. Are we sure that CompactOutputDescription should impl ShieldedOutput<SaplingDomain> given that the latter has an enc_ciphertext method? Perhaps it shouldn't, and enc_ciphertext should be on a separate trait impl'd by OutputDescription.
There was a problem hiding this comment.
Out of scope for this PR, as discussed.
daira
left a comment
There was a problem hiding this comment.
Abstracting over MEMO_SIZE isn't sufficient for memo bundles (the chunks are not in the enc ciphertext, an encryption key is); nor is it necessary for ZSAs (they don't change the memo size or type). So I wonder why this is necessary.
In any case, utACK to unblock further progress, even though I think this is definitely going to need to be refactored again.
|
As discussed in the meeting, we will fix the issues that require no significant changes to other crates and revisit. Update: fixed, please see last commits and comments |
Merge upstream 20260428
Adapts
sapling-cryptoto work with the updatedzcash_note_encryptioncrate that supports variable-size note plaintexts, a prerequisite for the OrchardZSA protocol and related changes in librustzcash.Motivation
The upstream
zcash_note_encryptioncrate has been refactored to make note sizes generic via const generics and associated types, replacing the previous fixed-size arrays. This PR updatessapling-cryptoto conform to that new interface while keeping Sapling's own note sizes unchanged.Key changes
COMPACT_NOTE_SIZE,NOTE_PLAINTEXT_SIZE,ENC_CIPHERTEXT_SIZE,MEMO_SIZE) are now defined locally insapling-cryptorather than imported fromzcash_note_encryption, since each protocol defines its own sizes.Domainassociated typesNotePlaintextBytes,NoteCiphertextBytes,CompactNotePlaintextBytes, andCompactNoteCiphertextBytesare implemented using the genericNoteBytesData<N>wrapper from the encryption crate.enc_ciphertextfields changed from fixed-size[u8; ENC_CIPHERTEXT_SIZE]arrays toNoteBytesData<{ ENC_CIPHERTEXT_SIZE }>.ShieldedOutputtrait no longer carries a const generic size parameter - implementations now provide bothenc_ciphertext()andenc_ciphertext_compact()methods.extract_memoreplaced bysplit_plaintext_at_memo, which splits the plaintext into compact note bytes and memo.parse_note_plaintext_without_memo_ivk/ovknow takes typedCompactNotePlaintextBytesinstead of raw&[u8]/&NotePlaintextBytes.[u8; 512]memo references replaced with[u8; MEMO_SIZE]throughout.