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

ZSA integration (step 4): Refactor Orchard structures to generics and add Orchard ZSA support for Transaction V6 #17

Open
wants to merge 23 commits into
base: zsa-integration-txv6
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
23e318c
Add support for Orchard ZSA and updated generic structures for Tx V6 …
dmidem Sep 16, 2024
e98bb67
Fix compilation errors for unit tests
dmidem Sep 18, 2024
dd741e9
Add missed files
dmidem Sep 18, 2024
c218fc5
Fix ciphertexts.rs tests compilation error
dmidem Sep 18, 2024
4807dd6
Simplify the previous fix for ciphertexts.rs test
dmidem Sep 18, 2024
cccadcd
Merge branch 'switch-to-zsa-crates-nu6-txv6-gen' of https://github.co…
dmidem Sep 18, 2024
0f9c164
Fix tests compilation errors for nullifiers
dmidem Sep 18, 2024
20810ee
Merge branch 'switch-to-zsa-crates-nu6-txv6' into switch-to-zsa-crate…
dmidem Sep 22, 2024
986339e
Merge branch 'switch-to-zsa-crates-nu6-txv6' into switch-to-zsa-crate…
dmidem Sep 22, 2024
4d8cdef
Add several FIXME comments
dmidem Sep 24, 2024
1adadb1
Remove (comment out) zcash_unstable=nu6 Rust flag and sync Cargo.lock…
dmidem Sep 24, 2024
e9b0d46
Merge remote-tracking branch 'origin/main' into switch-to-zsa-crates-…
dmidem Sep 24, 2024
e2e160c
Attempt to make the code compilable when tx-v6 feature is disabled
dmidem Sep 30, 2024
5eade11
Merge branch 'main' of https://github.com/QED-it/zebra into switch-to…
dmidem Oct 2, 2024
763cded
Use tx-v6 feature across all crates
dmidem Oct 2, 2024
083171f
Merge branch 'switch-to-zsa-crates-nu6-txv6-gen-txv6-disabled' into s…
dmidem Oct 2, 2024
d2917fb
Merge branch 'switch-to-zsa-crates-nu6-txv6' into switch-to-zsa-crate…
dmidem Oct 2, 2024
c979861
Patch path for zcash_keys in Cargo.toml to avoid crate duplication in…
dmidem Oct 2, 2024
018203e
Merge branch 'zsa-integration-txv6' into zsa-integration-generics
dmidem Oct 17, 2024
d2313fb
Fix Orchard ZSA issuance serialization (use to_vec for notes and asse…
dmidem Oct 17, 2024
6b22fba
Merge branch 'zsa-integration-txv6' into zsa-integration-generics
dmidem Oct 29, 2024
ab9a2b5
Add support for processing ZSA orchard_shielded_data in zebra_state
dmidem Oct 30, 2024
c7cd215
Merge branch 'zsa-integration-txv6' into zsa-integration-generics
dmidem Oct 30, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/ci-basic.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,10 @@ jobs:
ROCKSDB_LIB_DIR: /usr/lib
# Use system-installed Snappy library for compression in RocksDB
SNAPPY_LIB_DIR: /usr/lib/x86_64-linux-gnu
# FIXME: remove the following commented lines
# Enable the `nu6` feature in `zcash_protocol`
RUSTFLAGS: '--cfg zcash_unstable="nu6"'
RUSTDOCFLAGS: '--cfg zcash_unstable="nu6"'
#RUSTFLAGS: '--cfg zcash_unstable="nu6"'
#RUSTDOCFLAGS: '--cfg zcash_unstable="nu6"'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why comment out?


steps:
- uses: actions/checkout@v4
Expand Down
31 changes: 3 additions & 28 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5854,7 +5854,7 @@ dependencies = [
"which",
"zcash_address",
"zcash_encoding",
"zcash_keys 0.2.0 (git+https://github.com/QED-it/librustzcash?branch=zsa1)",
"zcash_keys",
"zcash_note_encryption",
"zcash_primitives",
"zcash_protocol",
Expand All @@ -5881,32 +5881,6 @@ dependencies = [
"primitive-types",
]

[[package]]
name = "zcash_keys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "663489ffb4e51bc4436ff8796832612a9ff3c6516f1c620b5a840cb5dcd7b866"
dependencies = [
"bech32",
"blake2b_simd",
"bls12_381",
"bs58",
"document-features",
"group",
"memuse",
"nonempty",
"rand_core 0.6.4",
"sapling-crypto",
"secrecy",
"subtle",
"tracing",
"zcash_address",
"zcash_encoding",
"zcash_primitives",
"zcash_protocol",
"zip32",
]

[[package]]
name = "zcash_keys"
version = "0.2.0"
Expand Down Expand Up @@ -6060,6 +6034,7 @@ dependencies = [
"itertools 0.13.0",
"jubjub",
"lazy_static",
"nonempty",
"num-integer",
"orchard",
"primitive-types",
Expand Down Expand Up @@ -6293,7 +6268,7 @@ dependencies = [
"tracing-subscriber",
"zcash_address",
"zcash_client_backend",
"zcash_keys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"zcash_keys",
"zcash_note_encryption",
"zcash_primitives",
"zebra-chain",
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -115,3 +115,4 @@ zcash_address = { version = "0.3.2", git = "https://github.com/QED-it/librustzca
zcash_encoding = { version = "0.2.0", git = "https://github.com/QED-it/librustzcash", branch = "zsa1" }
zcash_history = { version = "0.4.0", git = "https://github.com/QED-it/librustzcash", branch = "zsa1" }
zcash_client_backend = { version = "0.12.1", git = "https://github.com/QED-it/librustzcash", branch = "zsa1" }
zcash_keys = { version = "0.2.0", git = "https://github.com/QED-it/librustzcash", branch = "zsa1" }
13 changes: 11 additions & 2 deletions zebra-chain/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ categories = ["asynchronous", "cryptography::cryptocurrencies", "encoding"]

[features]
default = []
#default = ["tx-v6"]

# Production features that activate extra functionality

Expand Down Expand Up @@ -60,6 +61,11 @@ proptest-impl = [

bench = ["zebra-test"]

# Support for transaction version 6
tx-v6 = [
"nonempty"
]

[dependencies]

# Cryptography
Expand Down Expand Up @@ -104,6 +110,9 @@ sapling-crypto.workspace = true
zcash_protocol.workspace = true
zcash_address.workspace = true

# Used for orchard serialization
nonempty = { version = "0.7", optional = true }

# Time
chrono = { version = "0.4.38", default-features = false, features = ["clock", "std", "serde"] }
humantime = "2.1.0"
Expand Down Expand Up @@ -180,5 +189,5 @@ name = "redpallas"
harness = false

# FIXME: remove this and all zcash_unstable usage in the code after updating librustzcash
[lints.rust]
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(zcash_unstable, values("nu6"))'] }
#[lints.rust]
#unexpected_cfgs = { level = "warn", check-cfg = ['cfg(zcash_unstable, values("nu6"))'] }
3 changes: 3 additions & 0 deletions zebra-chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ pub mod transparent;
pub mod value_balance;
pub mod work;

#[cfg(feature = "tx-v6")]
pub mod orchard_zsa;

#[cfg(any(test, feature = "proptest-impl"))]
pub use block::LedgerState;

Expand Down
10 changes: 10 additions & 0 deletions zebra-chain/src/orchard.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ mod action;
mod address;
mod commitment;
mod note;
mod orchard_flavor_ext;
mod sinsemilla;

#[cfg(any(test, feature = "proptest-impl"))]
Expand All @@ -22,4 +23,13 @@ pub use address::Address;
pub use commitment::{CommitmentRandomness, NoteCommitment, ValueCommitment};
pub use keys::Diversifier;
pub use note::{EncryptedNote, Note, Nullifier, WrappedNoteKey};
pub use orchard_flavor_ext::{OrchardFlavorExt, OrchardVanilla};
pub use shielded_data::{AuthorizedAction, Flags, ShieldedData};

pub(crate) use shielded_data::ActionCommon;

#[cfg(feature = "tx-v6")]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not #[cfg(zcash_unstable = "nu6")]
we don't need them both, need to decide on one.

Copy link
Collaborator

@arya2 arya2 Nov 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like tx-v6 better because I think we just need the feature to ensure that v6 transactions can't be (de)serialized by versions of Zebra that aren't ready to deploy NU7, but either seems fine.

pub use orchard_flavor_ext::OrchardZSA;

#[cfg(feature = "tx-v6")]
pub(crate) use crate::orchard_zsa::issuance::IssueData;
12 changes: 7 additions & 5 deletions zebra-chain/src/orchard/action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use super::{
commitment::{self, ValueCommitment},
keys,
note::{self, Nullifier},
OrchardFlavorExt,
};

/// An Action description, as described in the [Zcash specification §7.3][actiondesc].
Expand All @@ -21,7 +22,7 @@ use super::{
///
/// [actiondesc]: https://zips.z.cash/protocol/nu5.pdf#actiondesc
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Action {
pub struct Action<V: OrchardFlavorExt> {
/// A value commitment to net value of the input note minus the output note
pub cv: commitment::ValueCommitment,
/// The nullifier of the input note being spent.
Expand All @@ -35,14 +36,14 @@ pub struct Action {
/// encrypted private key in `out_ciphertext`.
pub ephemeral_key: keys::EphemeralPublicKey,
/// A ciphertext component for the encrypted output note.
pub enc_ciphertext: note::EncryptedNote,
pub enc_ciphertext: V::EncryptedNote,
/// A ciphertext component that allows the holder of a full viewing key to
/// recover the recipient diversified transmission key and the ephemeral
/// private key (and therefore the entire note plaintext).
pub out_ciphertext: note::WrappedNoteKey,
}

impl ZcashSerialize for Action {
impl<V: OrchardFlavorExt> ZcashSerialize for Action<V> {
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
self.cv.zcash_serialize(&mut writer)?;
writer.write_all(&<[u8; 32]>::from(self.nullifier)[..])?;
Expand All @@ -55,7 +56,7 @@ impl ZcashSerialize for Action {
}
}

impl ZcashDeserialize for Action {
impl<V: OrchardFlavorExt> ZcashDeserialize for Action<V> {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
// # Consensus
//
Expand Down Expand Up @@ -93,7 +94,8 @@ impl ZcashDeserialize for Action {
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
// 580 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
// See [`note::EncryptedNote::zcash_deserialize`].
enc_ciphertext: note::EncryptedNote::zcash_deserialize(&mut reader)?,
// FIXME: don't mention about 580 here as this should work for OrchardZSA too?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

right, can remove comment.

enc_ciphertext: V::EncryptedNote::zcash_deserialize(&mut reader)?,
// Type is `Sym.C`, i.e. `𝔹^Y^{\[N\]}`, i.e. arbitrary-sized byte arrays
// https://zips.z.cash/protocol/protocol.pdf#concretesym but fixed to
// 80 bytes in https://zips.z.cash/protocol/protocol.pdf#outputencodingandconsensus
Expand Down
11 changes: 6 additions & 5 deletions zebra-chain/src/orchard/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,18 @@ use reddsa::{orchard::SpendAuth, Signature, SigningKey, VerificationKey, Verific
use proptest::{array, collection::vec, prelude::*};

use super::{
keys::*, note, tree, Action, AuthorizedAction, Flags, NoteCommitment, ValueCommitment,
keys::*, note, tree, Action, AuthorizedAction, Flags, NoteCommitment, OrchardFlavorExt,
OrchardVanilla, ValueCommitment,
};

impl Arbitrary for Action {
impl Arbitrary for Action<OrchardVanilla> {
type Parameters = ();

fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(
any::<note::Nullifier>(),
any::<SpendAuthVerificationKeyBytes>(),
any::<note::EncryptedNote>(),
any::<note::EncryptedNote<{ OrchardVanilla::ENCRYPTED_NOTE_SIZE }>>(),
any::<note::WrappedNoteKey>(),
)
.prop_map(|(nullifier, rk, enc_ciphertext, out_ciphertext)| Self {
Expand Down Expand Up @@ -54,11 +55,11 @@ impl Arbitrary for note::Nullifier {
type Strategy = BoxedStrategy<Self>;
}

impl Arbitrary for AuthorizedAction {
impl Arbitrary for AuthorizedAction<OrchardVanilla> {
type Parameters = ();

fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(any::<Action>(), any::<SpendAuthSignature>())
(any::<Action<OrchardVanilla>>(), any::<SpendAuthSignature>())
.prop_map(|(action, spend_auth_sig)| Self {
action,
spend_auth_sig: spend_auth_sig.0,
Expand Down
6 changes: 3 additions & 3 deletions zebra-chain/src/orchard/note/arbitrary.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ use proptest::{collection::vec, prelude::*};

use super::*;

impl Arbitrary for EncryptedNote {
impl<const N: usize> Arbitrary for EncryptedNote<N> {
type Parameters = ();

fn arbitrary_with(_args: Self::Parameters) -> Self::Strategy {
(vec(any::<u8>(), 580))
(vec(any::<u8>(), N))
.prop_map(|v| {
let mut bytes = [0; 580];
let mut bytes = [0; N];
bytes.copy_from_slice(v.as_slice());
Self(bytes)
})
Expand Down
33 changes: 17 additions & 16 deletions zebra-chain/src/orchard/note/ciphertexts.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! Encrypted parts of Orchard notes.

// FIXME: make it a generic and add support for OrchardZSA (encrypted tote size ofr it is not 580!)

use std::{fmt, io};

use serde_big_array::BigArray;
Expand All @@ -12,57 +10,57 @@ use crate::serialization::{SerializationError, ZcashDeserialize, ZcashSerialize}
///
/// Corresponds to the Orchard 'encCiphertext's
#[derive(Deserialize, Serialize)]
pub struct EncryptedNote(#[serde(with = "BigArray")] pub(crate) [u8; 580]);
pub struct EncryptedNote<const N: usize>(#[serde(with = "BigArray")] pub(crate) [u8; N]);

// These impls all only exist because of array length restrictions.
// TODO: use const generics https://github.com/ZcashFoundation/zebra/issues/2042

impl Copy for EncryptedNote {}
impl<const N: usize> Copy for EncryptedNote<N> {}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Optional: The Copy, Clone, and Debug traits here can be derived now.


impl Clone for EncryptedNote {
impl<const N: usize> Clone for EncryptedNote<N> {
fn clone(&self) -> Self {
*self
}
}

impl fmt::Debug for EncryptedNote {
impl<const N: usize> fmt::Debug for EncryptedNote<N> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_tuple("EncryptedNote")
.field(&hex::encode(&self.0[..]))
.finish()
}
}

impl Eq for EncryptedNote {}
impl<const N: usize> Eq for EncryptedNote<N> {}

impl From<[u8; 580]> for EncryptedNote {
fn from(bytes: [u8; 580]) -> Self {
impl<const N: usize> From<[u8; N]> for EncryptedNote<N> {
fn from(bytes: [u8; N]) -> Self {
EncryptedNote(bytes)
}
}

impl From<EncryptedNote> for [u8; 580] {
fn from(enc_ciphertext: EncryptedNote) -> Self {
impl<const N: usize> From<EncryptedNote<N>> for [u8; N] {
fn from(enc_ciphertext: EncryptedNote<N>) -> Self {
enc_ciphertext.0
}
}

impl PartialEq for EncryptedNote {
impl<const N: usize> PartialEq for EncryptedNote<N> {
fn eq(&self, other: &Self) -> bool {
self.0[..] == other.0[..]
}
}

impl ZcashSerialize for EncryptedNote {
impl<const N: usize> ZcashSerialize for EncryptedNote<N> {
fn zcash_serialize<W: io::Write>(&self, mut writer: W) -> Result<(), io::Error> {
writer.write_all(&self.0[..])?;
Ok(())
}
}

impl ZcashDeserialize for EncryptedNote {
impl<const N: usize> ZcashDeserialize for EncryptedNote<N> {
fn zcash_deserialize<R: io::Read>(mut reader: R) -> Result<Self, SerializationError> {
let mut bytes = [0; 580];
let mut bytes = [0; N];
reader.read_exact(&mut bytes[..])?;
Ok(Self(bytes))
}
Expand Down Expand Up @@ -127,13 +125,16 @@ impl ZcashDeserialize for WrappedNoteKey {
}
}

#[cfg(test)]
use crate::orchard::OrchardFlavorExt;

#[cfg(test)]
use proptest::prelude::*;
#[cfg(test)]
proptest! {

#[test]
fn encrypted_ciphertext_roundtrip(ec in any::<EncryptedNote>()) {
fn encrypted_ciphertext_roundtrip(ec in any::<EncryptedNote::<{ crate::orchard::OrchardVanilla::ENCRYPTED_NOTE_SIZE }>>()) {
let _init_guard = zebra_test::init();

let mut data = Vec::new();
Expand Down
Loading