Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
30 changes: 30 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,36 @@ and this project adheres to Rust's notion of
- `orchard::primitives::redpallas::testing::arb_valid_spendauth_keypair`
(under the `test-dependencies` feature): a uniformly-distributed valid
`(rsk, rk)` key pair with non-identity `rk`.
- `orchard::{L_ORCHARD_BASE, L_ORCHARD_SCALAR, L_VALUE}`, the bit-length
parameters of the Orchard base field, scalar field, and value encoding
as defined in the Zcash protocol specification.
- `orchard::value::NoteValue::zero`, equivalent to `NoteValue::from_raw(0)`.
- The following modules and APIs are available behind the
`unstable-voting-circuits` feature flag to support downstream
voting-circuit development. These temporary APIs are not covered by the
crate's semver stability guarantees and may change in any future release:
- Modules: `orchard::{constants, spec}`,
`orchard::circuit::{commit_ivk, commit_ivk::gadgets, note_commit,
note_commit::gadgets, gadget::add_chip}`,
`orchard::note::{commitment, nullifier}`.
- Address and circuit helpers: `Address::{g_d, pk_d}`,
`circuit::gadget::{AddInstruction, assign_free_advice, derive_nullifier,
commit_ivk, note_commit}`,
`circuit::gadget::add_chip::{AddConfig, AddChip}` and
`AddChip::{configure, construct}`,
`CommitIvkChip::{configure, construct}`,
`NoteCommitChip::{configure, construct}`.
- Key, note, tree, and value APIs: `SpendingKey::random`,
`SpendAuthorizingKey::derive_inner`, `NullifierDerivingKey` and
`CommitIvkRandomness` and their `inner` methods,
`FullViewingKey::{nk, rivk}`,
`DiversifiedTransmissionKey::{inner, to_bytes}`,
`orchard::note::NoteCommitTrapdoor` and `NoteCommitTrapdoor::inner`,
`Rho::{from_nf_old, into_inner}`, `RandomSeed::{psi, rcm}`,
`Note::{new, dummy}`, `NoteCommitment::inner`,
`ExtractedNoteCommitment::inner`, `Nullifier::{from_inner, inner}`,
`NonIdentityPallasPoint` and `NonIdentityPallasPoint::from_bytes`,
`MerklePath::dummy`, and `MerkleHashOrchard::inner`.

### Changed
- MSRV is now 1.85.1
Expand Down
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ default = ["circuit", "multicore", "std"]
std = ["corez/std", "group/wnaf-memuse", "reddsa/std"]
circuit = ["dep:halo2_gadgets", "dep:halo2_proofs", "std"]
unstable-frost = []
unstable-voting-circuits = []
multicore = ["halo2_proofs?/multicore"]
dev-graph = ["halo2_proofs?/dev-graph", "image", "plotters"]
test-dependencies = ["proptest", "rand/std"]
Expand Down
4 changes: 4 additions & 0 deletions src/address.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,14 @@ impl Address {
self.d
}

/// Returns the diversified base point for this address.
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
Comment thread
daira marked this conversation as resolved.
pub(crate) fn g_d(&self) -> NonIdentityPallasPoint {
diversify_hash(self.d.as_array())
}

/// Returns the diversified transmission key for this address.
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(crate) fn pk_d(&self) -> &DiversifiedTransmissionKey {
&self.pk_d
}
Expand Down
8 changes: 7 additions & 1 deletion src/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,9 +58,15 @@ use halo2_gadgets::{
utilities::lookup_range_check::{LookupRangeCheck, LookupRangeCheckConfig},
};

#[cfg(not(feature = "unstable-voting-circuits"))]
mod commit_ivk;
#[cfg(feature = "unstable-voting-circuits")]
pub mod commit_ivk;
pub mod gadget;
#[cfg(not(feature = "unstable-voting-circuits"))]
mod note_commit;
#[cfg(feature = "unstable-voting-circuits")]
pub mod note_commit;
Comment thread
ebfull marked this conversation as resolved.

pub use crate::Proof;

Expand Down Expand Up @@ -890,7 +896,7 @@ impl Instance {
instance[ANCHOR] = self.anchor.inner();
instance[CV_NET_X] = self.cv_net.x();
instance[CV_NET_Y] = self.cv_net.y();
instance[NF_OLD] = self.nf_old.0;
instance[NF_OLD] = self.nf_old.inner();

let rk = pallas::Point::from_bytes(&self.rk.clone().into())
.expect("the cached byte encoding of a VerificationKey<_> is canonical")
Expand Down
16 changes: 16 additions & 0 deletions src/circuit/commit_ivk.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
//! Sub-circuit implementing the `CommitIvk` gadget.
//!
//! `CommitIvk` is the Sinsemilla-based commitment that binds an incoming
//! viewing key `ivk` to the full viewing key `(ak, nk)` and the randomness
//! `rivk`. This module provides the Halo 2 chip that enforces that
//! commitment inside the Orchard Action circuit.

use core::iter;

use group::ff::{Field, PrimeField};
Expand All @@ -15,18 +22,22 @@ use halo2_gadgets::{
utilities::{bool_check, RangeConstrained},
};

/// Configuration for the [`CommitIvkChip`], including its selector and advice columns.
#[derive(Clone, Debug)]
pub struct CommitIvkConfig {
q_commit_ivk: Selector,
advices: [Column<Advice>; 10],
}

/// A Halo 2 chip that proves correct evaluation of the `CommitIvk` gadget.
#[derive(Clone, Debug)]
pub struct CommitIvkChip {
config: CommitIvkConfig,
}

impl CommitIvkChip {
/// Configures the chip's gate and column assignments.
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn configure(
meta: &mut ConstraintSystem<pallas::Base>,
advices: [Column<Advice>; 10],
Expand Down Expand Up @@ -222,11 +233,15 @@ impl CommitIvkChip {
config
}

/// Constructs the chip from a [`CommitIvkConfig`].
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn construct(config: CommitIvkConfig) -> Self {
Self { config }
}
}

/// Gadget functions for `CommitIvk` operations.
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) mod gadgets {
use halo2_gadgets::utilities::{
lookup_range_check::{LookupRangeCheck, LookupRangeCheckConfig},
Expand All @@ -241,6 +256,7 @@ pub(in crate::circuit) mod gadgets {
/// [Section 5.4.8.4 Sinsemilla commitments]: https://zips.z.cash/protocol/protocol.pdf#concretesinsemillacommit
#[allow(non_snake_case)]
#[allow(clippy::type_complexity)]
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn commit_ivk(
sinsemilla_chip: SinsemillaChip<
OrchardHashDomains,
Expand Down
9 changes: 9 additions & 0 deletions src/circuit/gadget.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,11 @@ use halo2_proofs::{
plonk::{self, Advice, Assigned, Column},
};

#[cfg(not(feature = "unstable-voting-circuits"))]
pub(in crate::circuit) mod add_chip;
/// Addition chip for constraining `a + b = c` in-circuit.
#[cfg(feature = "unstable-voting-circuits")]
pub mod add_chip;
Comment thread
nuttycom marked this conversation as resolved.

impl super::Config {
pub(super) fn add_chip(&self) -> add_chip::AddChip {
Expand Down Expand Up @@ -77,6 +81,7 @@ impl super::Config {
}

/// An instruction set for adding two circuit words (field elements).
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) trait AddInstruction<F: Field>: Chip<F> {
/// Constraints `a + b` and returns the sum.
fn add(
Expand All @@ -92,6 +97,7 @@ pub(in crate::circuit) trait AddInstruction<F: Field>: Chip<F> {
/// Usages of this helper are technically superfluous, as the single-cell region is only
/// ever used in equality constraints. We could eliminate them with a
/// [write-on-copy abstraction](https://github.com/zcash/halo2/issues/334).
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn assign_free_advice<F: Field, V: Copy>(
mut layouter: impl Layouter<F>,
column: Column<Advice>,
Expand Down Expand Up @@ -145,6 +151,7 @@ pub(in crate::circuit) fn value_commit_orchard<
///
/// [Section 4.16: Note Commitments and Nullifiers]: https://zips.z.cash/protocol/protocol.pdf#commitmentsandnullifiers
#[allow(clippy::too_many_arguments)]
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn derive_nullifier<
PoseidonChip: PoseidonSpongeInstructions<pallas::Base, poseidon::P128Pow5T3, ConstantLength<2>, 3, 2>,
AddChip: AddInstruction<pallas::Base>,
Expand Down Expand Up @@ -199,5 +206,7 @@ pub(in crate::circuit) fn derive_nullifier<
.map(|res| res.extract_p())
}

#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) use crate::circuit::commit_ivk::gadgets::commit_ivk;
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) use crate::circuit::note_commit::gadgets::note_commit;
8 changes: 8 additions & 0 deletions src/circuit/gadget/add_chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@ use pasta_curves::pallas;

use super::AddInstruction;

/// Configuration for the addition chip.
#[derive(Clone, Debug)]
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) struct AddConfig {
a: Column<Advice>,
b: Column<Advice>,
Expand All @@ -16,6 +18,8 @@ pub(in crate::circuit) struct AddConfig {
}

/// A chip implementing a single addition constraint `c = a + b` on a single row.
#[derive(Debug)]
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) struct AddChip {
config: AddConfig,
}
Expand All @@ -34,6 +38,8 @@ impl Chip<pallas::Base> for AddChip {
}

impl AddChip {
/// Configures the addition chip with the given advice columns.
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn configure(
meta: &mut ConstraintSystem<pallas::Base>,
a: Column<Advice>,
Expand All @@ -53,6 +59,8 @@ impl AddChip {
AddConfig { a, b, c, q_add }
}

/// Constructs an addition chip from the given config.
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn construct(config: AddConfig) -> Self {
Self { config }
}
Expand Down
20 changes: 20 additions & 0 deletions src/circuit/note_commit.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
//! Sub-circuit implementing the `NoteCommit` gadget.
//!
//! `NoteCommit` is the Sinsemilla-based commitment that binds the note's
//! diversified transmission key `(g_d, pk_d)`, value `v`, ρ, and ψ, with
//! canonicity checks on each component field element. This module provides
//! the Halo 2 chip that enforces that commitment inside the Orchard Action
//! circuit.

use core::iter;

use group::ff::PrimeField;
Expand Down Expand Up @@ -1412,6 +1420,9 @@ impl YCanonicity {
}
}

/// Configuration for the [`NoteCommitChip`], aggregating the per-field
/// decomposition and canonicity sub-configurations and the underlying
/// Sinsemilla configuration.
#[allow(non_snake_case)]
#[derive(Clone, Debug)]
pub struct NoteCommitConfig {
Expand All @@ -1431,14 +1442,17 @@ pub struct NoteCommitConfig {
SinsemillaConfig<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
}

/// A Halo 2 chip that proves correct evaluation of the `NoteCommit` gadget.
#[derive(Clone, Debug)]
pub struct NoteCommitChip {
config: NoteCommitConfig,
}

impl NoteCommitChip {
/// Configures the chip's gates, Sinsemilla instances, and canonicity checks.
#[allow(non_snake_case)]
#[allow(clippy::many_single_char_names)]
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn configure(
meta: &mut ConstraintSystem<pallas::Base>,
advices: [Column<Advice>; 10],
Expand Down Expand Up @@ -1558,19 +1572,25 @@ impl NoteCommitChip {
}
}

/// Constructs the chip from a [`NoteCommitConfig`].
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn construct(config: NoteCommitConfig) -> Self {
Self { config }
}
}

/// Gadget functions for `NoteCommit` operations.
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) mod gadgets {
use halo2_proofs::circuit::{Chip, Value};

use super::*;

/// Computes the note commitment in-circuit.
#[allow(clippy::many_single_char_names)]
#[allow(clippy::type_complexity)]
#[allow(clippy::too_many_arguments)]
#[cfg_attr(feature = "unstable-voting-circuits", visibility::make(pub))]
pub(in crate::circuit) fn note_commit(
mut layouter: impl Layouter<pallas::Base>,
chip: SinsemillaChip<OrchardHashDomains, OrchardCommitDomains, OrchardFixedBases>,
Expand Down
6 changes: 3 additions & 3 deletions src/constants.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ pub(crate) const T_Q: u128 = 45560315531506369815346746415080538113;
pub(crate) const T_P: u128 = 45560315531419706090280762371685220353;

/// $\ell^\mathsf{Orchard}_\mathsf{base}$
pub(crate) const L_ORCHARD_BASE: usize = 255;
pub const L_ORCHARD_BASE: usize = 255;

/// $\ell^\mathsf{Orchard}_\mathsf{scalar}$
pub(crate) const L_ORCHARD_SCALAR: usize = 255;
pub const L_ORCHARD_SCALAR: usize = 255;

/// $\ell_\mathsf{value}$
pub(crate) const L_VALUE: usize = 64;
pub const L_VALUE: usize = 64;

/// SWU hash-to-curve personalization for the group hash for key diversification
pub const KEY_DIVERSIFICATION_PERSONALIZATION: &str = "z.cash:Orchard-gd";
Expand Down
20 changes: 18 additions & 2 deletions src/constants/fixed_bases.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,17 @@ use halo2_gadgets::ecc::{
#[cfg(feature = "circuit")]
use pasta_curves::pallas;

/// Precomputed table for the `CommitIvk` commitment randomness base.
pub mod commit_ivk_r;
/// Precomputed table for the `NoteCommit` commitment randomness base.
pub mod note_commit_r;
/// Precomputed table for the nullifier base `K^Orchard`.
pub mod nullifier_k;
/// Precomputed table for the spend authorization base `G^Orchard`.
pub mod spend_auth_g;
/// Precomputed table for the value commitment randomness base.
pub mod value_commit_r;
/// Precomputed table for the value commitment value base.
pub mod value_commit_v;

/// SWU hash-to-curve personalization for the spending key base point and
Expand Down Expand Up @@ -52,12 +58,18 @@ pub const NUM_WINDOWS: usize = L_ORCHARD_SCALAR.div_ceil(FIXED_BASE_WINDOW_SIZE)
/// Number of windows for a short signed scalar
pub const NUM_WINDOWS_SHORT: usize = L_VALUE.div_ceil(FIXED_BASE_WINDOW_SIZE);

/// Enumeration of every fixed base used in the Orchard circuit.
///
/// This enables the shared fixed-base scalar multiplication machinery in
/// `halo2_gadgets` to dispatch across full-width, base-field, and short-signed
/// bases using a single type.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
// A sum type for both full-width and short bases. This enables us to use the
// shared functionality of full-width and short fixed-base scalar multiplication.
pub enum OrchardFixedBases {
/// A full-width scalar multiplication base.
Full(OrchardFixedBasesFull),
/// The nullifier base `K^Orchard`, used with a base-field scalar.
NullifierK,
/// The value commitment value base, used with a short signed scalar.
ValueCommitV,
}

Expand All @@ -82,9 +94,13 @@ impl From<NullifierK> for OrchardFixedBases {
/// The Orchard fixed bases used in scalar mul with full-width scalars.
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
pub enum OrchardFixedBasesFull {
/// Randomness base for the `CommitIvk` commitment.
CommitIvkR,
/// Randomness base for the `NoteCommit` commitment.
NoteCommitR,
/// Randomness base for value commitments.
ValueCommitR,
/// Spend authorization base `G^Orchard`.
SpendAuthG,
}

Expand Down
1 change: 1 addition & 0 deletions src/constants/fixed_bases/commit_ivk_r.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2920,6 +2920,7 @@ pub static U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
],
];

/// Returns the affine generator point for this fixed base.
pub fn generator() -> pallas::Affine {
pallas::Affine::from_xy(
pallas::Base::from_repr(GENERATOR.0).unwrap(),
Expand Down
1 change: 1 addition & 0 deletions src/constants/fixed_bases/note_commit_r.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2920,6 +2920,7 @@ pub static U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
],
];

/// Returns the affine generator point for this fixed base.
pub fn generator() -> pallas::Affine {
pallas::Affine::from_xy(
pallas::Base::from_repr(GENERATOR.0).unwrap(),
Expand Down
1 change: 1 addition & 0 deletions src/constants/fixed_bases/nullifier_k.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2920,6 +2920,7 @@ pub static U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
],
];

/// Returns the affine generator point for this fixed base.
pub fn generator() -> pallas::Affine {
pallas::Affine::from_xy(
pallas::Base::from_repr(GENERATOR.0).unwrap(),
Expand Down
1 change: 1 addition & 0 deletions src/constants/fixed_bases/spend_auth_g.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2920,6 +2920,7 @@ pub static U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
],
];

/// Returns the affine generator point for this fixed base.
pub fn generator() -> pallas::Affine {
pallas::Affine::from_xy(
pallas::Base::from_repr(GENERATOR.0).unwrap(),
Expand Down
1 change: 1 addition & 0 deletions src/constants/fixed_bases/value_commit_r.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2921,6 +2921,7 @@ pub static U: [[[u8; 32]; super::H]; super::NUM_WINDOWS] = [
],
];

/// Returns the affine generator point for this fixed base.
pub fn generator() -> pallas::Affine {
pallas::Affine::from_xy(
pallas::Base::from_repr(GENERATOR.0).unwrap(),
Expand Down
Loading
Loading