Skip to content

Commit

Permalink
Merge pull request #445 from zcash/circuitless
Browse files Browse the repository at this point in the history
Move circuit and its dependencies behind a feature flag
  • Loading branch information
str4d authored Dec 16, 2024
2 parents ccc9003 + a5f27e0 commit 4fc9b5e
Show file tree
Hide file tree
Showing 15 changed files with 142 additions and 67 deletions.
31 changes: 29 additions & 2 deletions Cargo.lock

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

15 changes: 10 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@ blake2b_simd = "1"
ff = "0.13"
fpe = "0.6"
group = { version = "0.13", features = ["wnaf-memuse"] }
halo2_gadgets = "0.3"
halo2_proofs = { version = "0.3", default-features = false, features = ["batch", "floor-planner-v1-legacy-pdqsort"] }
hex = "0.4"
lazy_static = "1"
memuse = { version = "0.2.1", features = ["nonempty"] }
Expand All @@ -39,14 +37,20 @@ proptest = { version = "1.0.0", optional = true }
rand = "0.8"
reddsa = "0.5"
nonempty = "0.7"
poseidon = { package = "halo2_poseidon", version = "0.1" }
serde = { version = "1.0", features = ["derive"] }
sinsemilla = "0.1"
subtle = "2.3"
zcash_note_encryption = "0.4"
incrementalmerkletree = "0.7"
zcash_spec = "0.1"
zip32 = "0.1"
visibility = "0.1.1"

# Circuit
halo2_gadgets = { version = "0.3", optional = true }
halo2_proofs = { version = "0.3", optional = true, default-features = false, features = ["batch", "floor-planner-v1-legacy-pdqsort"] }

# Boilerplate
getset = "0.1"

Expand Down Expand Up @@ -74,10 +78,11 @@ pprof = { version = "0.11", features = ["criterion", "flamegraph"] }
bench = false

[features]
default = ["multicore"]
default = ["circuit", "multicore"]
circuit = ["dep:halo2_gadgets", "dep:halo2_proofs"]
unstable-frost = []
multicore = ["halo2_proofs/multicore"]
dev-graph = ["halo2_proofs/dev-graph", "image", "plotters"]
multicore = ["halo2_proofs?/multicore"]
dev-graph = ["halo2_proofs?/dev-graph", "image", "plotters"]
test-dependencies = ["proptest"]

[[bench]]
Expand Down
23 changes: 20 additions & 3 deletions src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ use std::collections::BTreeMap;
use std::fmt::Display;

use ff::Field;
use nonempty::NonEmpty;
use pasta_curves::pallas;
use rand::{prelude::SliceRandom, CryptoRng, RngCore};

use crate::{
action::Action,
address::Address,
bundle::{Authorization, Authorized, Bundle, Flags},
circuit::{Circuit, Instance, Proof, ProvingKey},
keys::{
FullViewingKey, OutgoingViewingKey, Scope, SpendAuthorizingKey, SpendValidatingKey,
SpendingKey,
Expand All @@ -24,6 +21,16 @@ use crate::{
primitives::redpallas::{self, Binding, SpendAuth},
tree::{Anchor, MerklePath},
value::{self, NoteValue, OverflowError, ValueCommitTrapdoor, ValueCommitment, ValueSum},
Proof,
};

#[cfg(feature = "circuit")]
use {
crate::{
action::Action,
circuit::{Circuit, Instance, ProvingKey},
},
nonempty::NonEmpty,
};

const MIN_ACTIONS: usize = 2;
Expand Down Expand Up @@ -120,6 +127,7 @@ pub enum BuildError {
/// A bundle could not be built because required signatures were missing.
MissingSignatures,
/// An error occurred in the process of producing a proof for a bundle.
#[cfg(feature = "circuit")]
Proof(halo2_proofs::plonk::Error),
/// An overflow error occurred while attempting to construct the value
/// for a bundle.
Expand All @@ -138,6 +146,7 @@ impl Display for BuildError {
use BuildError::*;
match self {
MissingSignatures => f.write_str("Required signatures were missing during build"),
#[cfg(feature = "circuit")]
Proof(e) => f.write_str(&format!("Could not create proof: {}", e)),
ValueSum(_) => f.write_str("Overflow occurred during value construction"),
InvalidExternalSignature => f.write_str("External signature was invalid"),
Expand All @@ -156,6 +165,7 @@ impl Display for BuildError {

impl std::error::Error for BuildError {}

#[cfg(feature = "circuit")]
impl From<halo2_proofs::plonk::Error> for BuildError {
fn from(e: halo2_proofs::plonk::Error) -> Self {
BuildError::Proof(e)
Expand Down Expand Up @@ -423,6 +433,7 @@ impl ActionInfo {
/// Defined in [Zcash Protocol Spec § 4.7.3: Sending Notes (Orchard)][orchardsend].
///
/// [orchardsend]: https://zips.z.cash/protocol/nu5.pdf#orchardsend
#[cfg(feature = "circuit")]
fn build(self, mut rng: impl RngCore) -> (Action<SigningMetadata>, Circuit) {
let v_net = self.value_sum();
let cv_net = ValueCommitment::derive(v_net, self.rcv.clone());
Expand Down Expand Up @@ -465,6 +476,7 @@ impl ActionInfo {
/// Type alias for an in-progress bundle that has no proofs or signatures.
///
/// This is returned by [`Builder::build`].
#[cfg(feature = "circuit")]
pub type UnauthorizedBundle<V> = Bundle<InProgress<Unproven, Unauthorized>, V>;

/// Metadata about a bundle created by [`bundle`] or [`Builder::build`] that is not
Expand Down Expand Up @@ -633,6 +645,7 @@ impl Builder {
///
/// The returned bundle will have no proof or signatures; these can be applied with
/// [`Bundle::create_proof`] and [`Bundle::apply_signatures`] respectively.
#[cfg(feature = "circuit")]
pub fn build<V: TryFrom<i64>>(
self,
rng: impl RngCore,
Expand Down Expand Up @@ -685,6 +698,7 @@ impl Builder {
///
/// The returned bundle will have no proof or signatures; these can be applied with
/// [`Bundle::create_proof`] and [`Bundle::apply_signatures`] respectively.
#[cfg(feature = "circuit")]
pub fn bundle<V: TryFrom<i64>>(
rng: impl RngCore,
anchor: Anchor,
Expand Down Expand Up @@ -847,11 +861,13 @@ impl<P: fmt::Debug, S: InProgressSignatures> Authorization for InProgress<P, S>
/// Marker for a bundle without a proof.
///
/// This struct contains the private data needed to create a [`Proof`] for a [`Bundle`].
#[cfg(feature = "circuit")]
#[derive(Clone, Debug)]
pub struct Unproven {
circuits: Vec<Circuit>,
}

#[cfg(feature = "circuit")]
impl<S: InProgressSignatures> InProgress<Unproven, S> {
/// Creates the proof for this bundle.
pub fn create_proof(
Expand All @@ -864,6 +880,7 @@ impl<S: InProgressSignatures> InProgress<Unproven, S> {
}
}

#[cfg(feature = "circuit")]
impl<S: InProgressSignatures, V> Bundle<InProgress<Unproven, S>, V> {
/// Creates the proof for this bundle.
pub fn create_proof(
Expand Down
12 changes: 10 additions & 2 deletions src/bundle.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
//! Structs related to bundles of Orchard actions.
mod batch;
pub mod commitments;

#[cfg(feature = "circuit")]
mod batch;
#[cfg(feature = "circuit")]
pub use batch::BatchValidator;

use core::fmt;
Expand All @@ -16,15 +18,19 @@ use crate::{
action::Action,
address::Address,
bundle::commitments::{hash_bundle_auth_data, hash_bundle_txid_data},
circuit::{Instance, Proof, VerifyingKey},
keys::{IncomingViewingKey, OutgoingViewingKey, PreparedIncomingViewingKey},
note::Note,
note_encryption::OrchardDomain,
primitives::redpallas::{self, Binding, SpendAuth},
tree::Anchor,
value::{ValueCommitTrapdoor, ValueCommitment, ValueSum},
Proof,
};

#[cfg(feature = "circuit")]
use crate::circuit::{Instance, VerifyingKey};

#[cfg(feature = "circuit")]
impl<T> Action<T> {
/// Prepares the public instance for this action, for creating and verifying the
/// bundle proof.
Expand Down Expand Up @@ -288,6 +294,7 @@ impl<T: Authorization, V> Bundle<T, V> {
})
}

#[cfg(feature = "circuit")]
pub(crate) fn to_instances(&self) -> Vec<Instance> {
self.actions
.iter()
Expand Down Expand Up @@ -457,6 +464,7 @@ impl<V> Bundle<Authorized, V> {
}

/// Verifies the proof for this bundle.
#[cfg(feature = "circuit")]
pub fn verify_proof(&self, vk: &VerifyingKey) -> Result<(), halo2_proofs::plonk::Error> {
self.authorization()
.proof()
Expand Down
45 changes: 2 additions & 43 deletions src/circuit.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
//! The Orchard Action circuit implementation.
use core::fmt;

use group::{Curve, GroupEncoding};
use halo2_proofs::{
circuit::{floor_planner, Layouter, Value},
Expand All @@ -12,7 +10,6 @@ use halo2_proofs::{
poly::Rotation,
transcript::{Blake2bRead, Blake2bWrite},
};
use memuse::DynamicUsage;
use pasta_curves::{arithmetic::CurveAffine, pallas, vesta};
use rand::RngCore;

Expand Down Expand Up @@ -63,6 +60,8 @@ mod commit_ivk;
pub mod gadget;
mod note_commit;

pub use crate::Proof;

/// Size of the Orchard circuit.
const K: u32 = 11;

Expand Down Expand Up @@ -856,41 +855,6 @@ impl Instance {
}
}

/// A proof of the validity of an Orchard [`Bundle`].
///
/// [`Bundle`]: crate::bundle::Bundle
#[derive(Clone)]
pub struct Proof(Vec<u8>);

impl fmt::Debug for Proof {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
if f.alternate() {
f.debug_tuple("Proof").field(&self.0).finish()
} else {
// By default, only show the proof length, not its contents.
f.debug_tuple("Proof")
.field(&format_args!("{} bytes", self.0.len()))
.finish()
}
}
}

impl AsRef<[u8]> for Proof {
fn as_ref(&self) -> &[u8] {
&self.0
}
}

impl DynamicUsage for Proof {
fn dynamic_usage(&self) -> usize {
self.0.dynamic_usage()
}

fn dynamic_usage_bounds(&self) -> (usize, Option<usize>) {
self.0.dynamic_usage_bounds()
}
}

impl Proof {
/// Creates a proof for the given circuits and instances.
pub fn create(
Expand Down Expand Up @@ -951,11 +915,6 @@ impl Proof {

batch.add_proof(instances, self.0.clone());
}

/// Constructs a new Proof value.
pub fn new(bytes: Vec<u8>) -> Self {
Proof(bytes)
}
}

#[cfg(test)]
Expand Down
2 changes: 1 addition & 1 deletion src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ pub mod fixed_bases;
pub mod sinsemilla;
pub mod util;

pub use self::sinsemilla::{OrchardCommitDomains, OrchardHashDomains};
pub use fixed_bases::{NullifierK, OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV};
pub use sinsemilla::{OrchardCommitDomains, OrchardHashDomains};

/// $\mathsf{MerkleDepth^{Orchard}}$
pub const MERKLE_DEPTH_ORCHARD: usize = 32;
Expand Down
Loading

0 comments on commit 4fc9b5e

Please sign in to comment.