Migrate to `halo2_gadgets` crate in subdir

- The crate module structure from `orchard` has been flattened.
- The book pages we want to include in `halo2` have been moved to their
  target location, to avoid any conflicts during the merge.
- Common files that already exist in zcash/halo2 have been removed.
This commit is contained in:
Jack Grigg 2022-01-27 21:53:10 +00:00
parent c4ef177e07
commit a2367abcaf
71 changed files with 105 additions and 399 deletions

View File

@ -1,35 +0,0 @@
name: Benchmarks
on:
push:
branches:
- main
permissions:
contents: write
deployments: write
jobs:
benchmark:
name: Performance regression check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.51.0
override: true
- name: Run benchmark
run: cargo bench -- --output-format bencher | tee output.txt
- name: Store benchmark result
uses: benchmark-action/github-action-benchmark@v1
with:
name: Orchard Benchmarks
tool: 'cargo'
output-file-path: output.txt
github-token: ${{ secrets.GITHUB_TOKEN }}
auto-push: true
# Show alert with commit comment on detecting possible performance regression
alert-threshold: '200%'
comment-on-alert: true
fail-on-alert: true
alert-comment-cc-users: '@str4d'

View File

@ -1,32 +0,0 @@
name: Orchard book
on:
push:
branches:
- main
jobs:
deploy:
runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v2
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
with:
mdbook-version: '0.4.5'
- name: Install mdbook-katex
uses: actions-rs/cargo@v1
with:
command: install
args: mdbook-katex
- name: Build Orchard book
run: mdbook build book/
- name: Deploy to GitHub Pages
uses: peaceiris/actions-gh-pages@v3
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./book/book

View File

@ -1,121 +0,0 @@
name: CI checks
on: [push, pull_request]
jobs:
test:
name: Test on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macOS-latest]
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.51.0
override: true
- name: Run tests
uses: actions-rs/cargo@v1
with:
command: test
args: --verbose
bitrot:
name: Bitrot check
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.51.0
override: true
# Build benchmarks to prevent bitrot
- name: Build benchmarks
uses: actions-rs/cargo@v1
with:
command: build
args: --benches
book:
name: Book tests
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.51.0
override: true
- name: Setup mdBook
uses: peaceiris/actions-mdbook@v1
with:
mdbook-version: '0.4.5'
- name: Test Orchard book
run: mdbook test book/
codecov:
name: Code coverage
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
# Use stable for this to ensure that cargo-tarpaulin can be built.
- uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true
- name: Install cargo-tarpaulin
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-tarpaulin
- name: Generate coverage report
uses: actions-rs/cargo@v1
with:
command: tarpaulin
args: --all-features --timeout 600 --out Xml
- name: Upload coverage to Codecov
uses: codecov/codecov-action@v1
with:
token: ${{secrets.CODECOV_TOKEN}}
doc-links:
name: Intra-doc links
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.51.0
override: true
- name: cargo fetch
uses: actions-rs/cargo@v1
with:
command: fetch
# Ensure intra-documentation links all resolve correctly
# Requires #![deny(intra_doc_link_resolution_failure)] in crates.
- name: Check intra-doc links
uses: actions-rs/cargo@v1
with:
command: doc
args: --document-private-items
fmt:
name: Rustfmt
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.51.0
override: true
- run: rustup component add rustfmt
- uses: actions-rs/cargo@v1
with:
command: fmt
args: -- --check

View File

@ -1,27 +0,0 @@
name: Nightly lints
# These lints are only informative, so we only run them directly on branches
# and not trial-merges of PRs, to reduce noise.
on: push
jobs:
clippy-nightly:
name: Clippy (nightly)
timeout-minutes: 30
runs-on: ubuntu-latest
continue-on-error: true
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: nightly
components: clippy
override: true
- name: Run Clippy (nightly)
uses: actions-rs/clippy-check@v1
continue-on-error: true
with:
name: Clippy (nightly)
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features --all-targets

View File

@ -1,23 +0,0 @@
name: Stable lints
# We only run these lints on trial-merges of PRs to reduce noise.
on: pull_request
jobs:
clippy:
name: Clippy (1.51.0)
timeout-minutes: 30
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions-rs/toolchain@v1
with:
toolchain: 1.51.0
components: clippy
override: true
- name: Run Clippy
uses: actions-rs/clippy-check@v1
with:
name: Clippy (1.51.0)
token: ${{ secrets.GITHUB_TOKEN }}
args: --all-features --all-targets -- -D warnings

4
.gitignore vendored
View File

@ -1,4 +0,0 @@
/target
**/*.rs.bk
Cargo.lock
.vscode

View File

@ -1,9 +0,0 @@
[book]
authors = ["Jack Grigg"]
language = "en"
multilingual = false
src = "src"
title = "The Orchard Book"
[preprocessor.katex]
macros = "macros.txt"

View File

@ -1 +0,0 @@
{{#include ../../README.md}}

View File

@ -1,13 +0,0 @@
# The Orchard Book
[Orchard](README.md)
- [Design](design.md)
- [Circuit](design/circuit.md)
- [Gadgets](design/circuit/gadgets.md)
- [Elliptic curve cryptography](design/circuit/gadgets/ecc.md)
- [Incomplete and complete addition](design/circuit/gadgets/ecc/addition.md)
- [Fixed-base scalar multiplication](design/circuit/gadgets/ecc/fixed-base-scalar-mul.md)
- [Variable-base scalar multiplication](design/circuit/gadgets/ecc/var-base-scalar-mul.md)
- [Sinsemilla](design/circuit/gadgets/sinsemilla.md)
- [MerkleCRH](design/circuit/gadgets/sinsemilla/merkle-crh.md)
- [Decomposition](design/circuit/gadgets/decomposition.md)

View File

@ -1,38 +0,0 @@
# Design
## General design notes
### Requirements
- Keep the design close to Sapling, while eliminating aspects we don't like.
### Non-requirements
- Delegated proving with privacy from the prover.
- We know how to do this, but it would require a discrete log equality proof, and the
most efficient way to do this would be to do RedDSA and this at the same time, which
means more work for e.g. hardware wallets.
### Open issues
- Should we have one memo per output, or one memo per transaction, or 0..n memos?
- Variable, or (1 or n), is a potential privacy leak.
- Need to consider the privacy issue related to light clients requesting individual
memos vs being able to fetch all memos.
### Note structure
- TODO: UDAs: arbitrary vs whitelisted
### Typed variables vs byte encodings
For Sapling, we have encountered multiple places where the specification uses typed
variables to define the consensus rules, but the C++ implementation in zcashd relied on
byte encodings to implement them. This resulted in subtly-different consensus rules being
deployed than were intended, for example where a particular type was not round-trip
encodable.
In Orchard, we avoid this by defining the consensus rules in terms of the byte encodings
of all variables, and being explicit about any types that are not round-trip encodable.
This makes consensus compatibility between strongly-typed implementations (such as this
crate) and byte-oriented implementations easier to achieve.

View File

@ -1,3 +0,0 @@
# Circuit

View File

@ -1 +0,0 @@
# Gadgets

View File

@ -1,6 +1,6 @@
[package]
name = "orchard"
version = "0.1.0-beta.1"
name = "halo2_gadgets"
version = "0.0.0"
authors = [
"Sean Bowe <sean@electriccoin.co>",
"Jack Grigg <jack@electriccoin.co>",
@ -9,12 +9,11 @@ authors = [
"Kris Nuttycombe <kris@electriccoin.co>",
]
edition = "2018"
description = "[BETA] The Orchard shielded transaction protocol"
description = "[BETA] Reusable gadgets and chip implementations for Halo 2"
license-file = "LICENSE-BOSL"
repository = "https://github.com/zcash/orchard"
documentation = "https://docs.rs/orchard"
repository = "https://github.com/zcash/halo2"
readme = "README.md"
categories = ["cryptography::cryptocurrencies"]
categories = ["cryptography"]
keywords = ["zcash"]
[package.metadata.docs.rs]

View File

@ -11,8 +11,8 @@ use halo2::{
};
use pasta_curves::{pallas, vesta};
use orchard::{
circuit::gadget::poseidon::{Hash, Pow5Chip, Pow5Config},
use halo2_gadgets::{
poseidon::{Hash, Pow5Chip, Pow5Config},
primitives::poseidon::{self, ConstantLength, Spec},
};
use std::convert::TryInto;

View File

@ -2,7 +2,7 @@ use std::array;
use criterion::{criterion_group, criterion_main, BenchmarkId, Criterion};
use ff::Field;
use orchard::primitives::{
use halo2_gadgets::primitives::{
poseidon::{self, ConstantLength, P128Pow5T3},
sinsemilla,
};

View File

@ -8,7 +8,7 @@ use halo2::{
plonk::Error,
};
use crate::circuit::gadget::utilities::UtilitiesInstructions;
use crate::utilities::UtilitiesInstructions;
pub mod chip;
@ -133,8 +133,11 @@ pub trait EccInstructions<C: CurveAffine>:
/// Defines the fixed points for a given instantiation of the ECC chip.
pub trait FixedPoints<C: CurveAffine>: Debug + Eq + Clone {
/// Fixed points that can be used with full-width scalar multiplication.
type FullScalar: Debug + Eq + Clone;
/// Fixed points that can be used with short scalar multiplication.
type ShortScalar: Debug + Eq + Clone;
/// Fixed points that can be multiplied by base field elements.
type Base: Debug + Eq + Clone;
}
@ -505,7 +508,7 @@ pub(crate) mod tests {
},
FixedPoints,
};
use crate::circuit::gadget::utilities::lookup_range_check::LookupRangeCheckConfig;
use crate::utilities::lookup_range_check::LookupRangeCheckConfig;
#[derive(Debug, Eq, PartialEq, Clone)]
pub(crate) struct TestFixedBases;

View File

@ -1,9 +1,9 @@
//! Chip implementations for the ECC gadgets.
use super::{EccInstructions, FixedPoints};
use crate::{
circuit::gadget::utilities::{
lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions,
},
primitives::sinsemilla,
utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
};
use arrayvec::ArrayVec;
@ -42,7 +42,7 @@ impl EccPoint {
///
/// This is an internal API that we only use where we know we have a valid curve point
/// (specifically inside Sinsemilla).
pub(in crate::circuit::gadget) fn from_coordinates_unchecked(
pub(crate) fn from_coordinates_unchecked(
x: AssignedCell<pallas::Base, pallas::Base>,
y: AssignedCell<pallas::Base, pallas::Base>,
) -> Self {
@ -94,7 +94,7 @@ impl NonIdentityEccPoint {
///
/// This is an internal API that we only use where we know we have a valid non-identity
/// curve point (specifically inside Sinsemilla).
pub(in crate::circuit::gadget) fn from_coordinates_unchecked(
pub(crate) fn from_coordinates_unchecked(
x: AssignedCell<pallas::Base, pallas::Base>,
y: AssignedCell<pallas::Base, pallas::Base>,
) -> Self {
@ -164,11 +164,13 @@ pub struct EccConfig<FixedPoints: super::FixedPoints<pallas::Affine>> {
///
/// This trait exists because of limitations around const generics.
pub trait ScalarKind {
/// The number of windows that this scalar kind requires.
const NUM_WINDOWS: usize;
}
/// Type marker representing a full-width scalar for use in fixed-base scalar
/// multiplication.
#[derive(Debug)]
pub enum FullScalar {}
impl ScalarKind for FullScalar {
const NUM_WINDOWS: usize = NUM_WINDOWS;
@ -176,6 +178,7 @@ impl ScalarKind for FullScalar {
/// Type marker representing a signed 64-bit scalar for use in fixed-base scalar
/// multiplication.
#[derive(Debug)]
pub enum ShortScalar {}
impl ScalarKind for ShortScalar {
const NUM_WINDOWS: usize = NUM_WINDOWS_SHORT;
@ -183,23 +186,36 @@ impl ScalarKind for ShortScalar {
/// Type marker representing a base field element being used as a scalar in fixed-base
/// scalar multiplication.
#[derive(Debug)]
pub enum BaseFieldElem {}
impl ScalarKind for BaseFieldElem {
const NUM_WINDOWS: usize = NUM_WINDOWS;
}
/// Returns information about a fixed point.
/// Returns information about a fixed point that is required by [`EccChip`].
///
/// For each window required by `Self::ScalarKind`, $z$ is a field element such that for
/// each point $(x, y)$ in the window:
/// - $z + y = u^2$ (some square in the field); and
/// - $z - y$ is not a square.
///
/// TODO: When associated consts can be used as const generics, introduce a
/// `const NUM_WINDOWS: usize` associated const, and return `NUM_WINDOWS`-sized
/// arrays instead of `Vec`s.
pub trait FixedPoint<C: CurveAffine>: std::fmt::Debug + Eq + Clone {
/// The kind of scalar that this fixed point can be multiplied by.
type ScalarKind: ScalarKind;
/// Returns the generator for this fixed point.
fn generator(&self) -> C;
/// Returns the $u$ values for this fixed point.
fn u(&self) -> Vec<[[u8; 32]; H]>;
/// Returns the $z$ value for this fixed point.
fn z(&self) -> Vec<u64>;
/// Returns the Lagrange coefficients for this fixed point.
fn lagrange_coeffs(&self) -> Vec<[C::Base; H]> {
compute_lagrange_coeffs(self.generator(), Self::ScalarKind::NUM_WINDOWS)
}
@ -231,6 +247,7 @@ impl<Fixed: super::FixedPoints<pallas::Affine>> UtilitiesInstructions<pallas::Ba
}
impl<FixedPoints: super::FixedPoints<pallas::Affine>> EccChip<FixedPoints> {
/// Reconstructs this chip from the given config.
pub fn construct(config: <Self as Chip<pallas::Base>>::Config) -> Self {
Self { config }
}

View File

@ -394,7 +394,7 @@ pub mod tests {
use halo2::{circuit::Layouter, plonk::Error};
use pasta_curves::{arithmetic::CurveExt, pallas};
use crate::circuit::gadget::ecc::{chip::EccPoint, EccInstructions, NonIdentityPoint};
use crate::ecc::{chip::EccPoint, EccInstructions, NonIdentityPoint};
#[allow(clippy::too_many_arguments)]
pub fn test_add<

View File

@ -163,7 +163,7 @@ pub mod tests {
use halo2::{circuit::Layouter, plonk::Error};
use pasta_curves::pallas;
use crate::circuit::gadget::ecc::{EccInstructions, NonIdentityPoint};
use crate::ecc::{EccInstructions, NonIdentityPoint};
#[allow(clippy::too_many_arguments)]
pub fn test_add_incomplete<

View File

@ -1,3 +1,5 @@
//! Constants required for the ECC chip.
use arrayvec::ArrayVec;
use group::{
ff::{Field, PrimeField},
@ -148,10 +150,10 @@ pub fn find_zs_and_us<C: CurveAffine>(
.collect()
}
// Test that the z-values and u-values satisfy the conditions:
// 1. z + y = u^2,
// 2. z - y is not a square
// for the y-coordinate of each fixed-base multiple in each window.
/// Test that the z-values and u-values satisfy the conditions:
/// 1. z + y = u^2,
/// 2. z - y is not a square
/// for the y-coordinate of each fixed-base multiple in each window.
pub fn test_zs_and_us<C: CurveAffine>(base: C, z: &[u64], u: &[[[u8; 32]; H]], num_windows: usize) {
let window_table = compute_window_table(base, num_windows);
@ -165,8 +167,8 @@ pub fn test_zs_and_us<C: CurveAffine>(base: C, z: &[u64], u: &[[[u8; 32]; H]], n
}
}
// Test that Lagrange interpolation coefficients reproduce the correct x-coordinate
// for each fixed-base multiple in each window.
/// Test that Lagrange interpolation coefficients reproduce the correct x-coordinate
/// for each fixed-base multiple in each window.
pub fn test_lagrange_coeffs<C: CurveAffine>(base: C, num_windows: usize) {
/// Evaluate y = f(x) given the coefficients of f(x)
fn evaluate<C: CurveAffine>(x: u8, coeffs: &[C::Base]) -> C::Base {

View File

@ -1,7 +1,7 @@
use super::{add, EccPoint, NonIdentityEccPoint, T_Q};
use crate::{
circuit::gadget::utilities::{bool_check, lookup_range_check::LookupRangeCheckConfig, ternary},
primitives::sinsemilla,
utilities::{bool_check, lookup_range_check::LookupRangeCheckConfig, ternary},
};
use std::{
convert::TryInto,
@ -473,7 +473,7 @@ pub mod tests {
use pasta_curves::pallas;
use rand::rngs::OsRng;
use crate::circuit::gadget::{
use crate::{
ecc::{
chip::{EccChip, EccPoint},
tests::TestFixedBases,

View File

@ -1,6 +1,6 @@
use super::super::{add, EccPoint};
use super::{COMPLETE_RANGE, X, Y, Z};
use crate::circuit::gadget::utilities::{bool_check, ternary};
use crate::utilities::{bool_check, ternary};
use halo2::{
circuit::Region,

View File

@ -1,6 +1,6 @@
use super::super::NonIdentityEccPoint;
use super::{X, Y, Z};
use crate::circuit::gadget::utilities::bool_check;
use crate::utilities::bool_check;
use ff::Field;
use halo2::{
circuit::Region,

View File

@ -1,7 +1,5 @@
use super::{T_Q, Z};
use crate::{
circuit::gadget::utilities::lookup_range_check::LookupRangeCheckConfig, primitives::sinsemilla,
};
use crate::{primitives::sinsemilla, utilities::lookup_range_check::LookupRangeCheckConfig};
use halo2::circuit::AssignedCell;
use halo2::{
circuit::Layouter,

View File

@ -2,7 +2,7 @@ use super::{
add, add_incomplete, EccBaseFieldElemFixed, EccScalarFixed, EccScalarFixedShort, FixedPoint,
NonIdentityEccPoint, FIXED_BASE_WINDOW_SIZE, H,
};
use crate::circuit::gadget::utilities::decompose_running_sum::RunningSumConfig;
use crate::utilities::decompose_running_sum::RunningSumConfig;
use std::marker::PhantomData;

View File

@ -2,10 +2,8 @@ use super::super::{EccBaseFieldElemFixed, EccPoint, FixedPoints, NUM_WINDOWS, T_
use super::H_BASE;
use crate::{
circuit::gadget::utilities::{
bitrange_subset, lookup_range_check::LookupRangeCheckConfig, range_check,
},
primitives::sinsemilla,
utilities::{bitrange_subset, lookup_range_check::LookupRangeCheckConfig, range_check},
};
use group::ff::PrimeField;
@ -386,7 +384,7 @@ pub mod tests {
use pasta_curves::pallas;
use rand::rngs::OsRng;
use crate::circuit::gadget::{
use crate::{
ecc::{
chip::{EccChip, FixedPoint, H},
tests::{BaseField, TestFixedBases},

View File

@ -1,6 +1,6 @@
use super::super::{EccPoint, EccScalarFixed, FixedPoints, FIXED_BASE_WINDOW_SIZE, H, NUM_WINDOWS};
use crate::circuit::gadget::utilities::{decompose_word, range_check};
use crate::utilities::{decompose_word, range_check};
use arrayvec::ArrayVec;
use ff::PrimeField;
use halo2::{
@ -181,7 +181,7 @@ pub mod tests {
use pasta_curves::pallas;
use rand::rngs::OsRng;
use crate::circuit::gadget::ecc::{
use crate::ecc::{
chip::{EccChip, FixedPoint as _, H},
tests::{FullWidth, TestFixedBases},
FixedPoint, NonIdentityPoint, Point,

View File

@ -1,7 +1,7 @@
use std::{array, convert::TryInto};
use super::super::{EccPoint, EccScalarFixedShort, FixedPoints, L_SCALAR_SHORT, NUM_WINDOWS_SHORT};
use crate::circuit::gadget::{ecc::chip::MagnitudeSign, utilities::bool_check};
use crate::{ecc::chip::MagnitudeSign, utilities::bool_check};
use halo2::{
circuit::{Layouter, Region},
@ -237,7 +237,7 @@ pub mod tests {
};
use pasta_curves::{arithmetic::FieldExt, pallas};
use crate::circuit::gadget::{
use crate::{
ecc::{
chip::{EccChip, FixedPoint, MagnitudeSign},
tests::{Short, TestFixedBases},
@ -371,7 +371,7 @@ pub mod tests {
#[test]
fn invalid_magnitude_sign() {
use crate::circuit::gadget::{
use crate::{
ecc::chip::{EccConfig, FixedPoint},
utilities::UtilitiesInstructions,
};

View File

@ -152,7 +152,7 @@ pub mod tests {
use pasta_curves::pallas;
use super::*;
use crate::circuit::gadget::ecc::{EccInstructions, NonIdentityPoint};
use crate::ecc::{EccInstructions, NonIdentityPoint};
pub fn test_witness_non_id<
EccChip: EccInstructions<pallas::Affine> + Clone + Eq + std::fmt::Debug,

View File

@ -16,5 +16,9 @@
#![deny(missing_docs)]
#![deny(unsafe_code)]
pub mod circuit;
pub mod ecc;
pub mod poseidon;
pub mod sinsemilla;
pub mod utilities;
pub mod primitives;

View File

@ -11,14 +11,14 @@ use halo2::{
use super::{PaddedWord, PoseidonInstructions, PoseidonSpongeInstructions};
use crate::primitives::poseidon::{Domain, Mds, Spec, State};
use crate::{
circuit::gadget::utilities::Var,
primitives::poseidon::{Absorbing, Squeezing},
utilities::Var,
};
/// Configuration for a [`Pow5Chip`].
#[derive(Clone, Debug)]
pub struct Pow5Config<F: FieldExt, const WIDTH: usize, const RATE: usize> {
pub(in crate::circuit) state: [Column<Advice>; WIDTH],
pub(crate) state: [Column<Advice>; WIDTH],
partial_sbox: Column<Advice>,
rc_a: [Column<Fixed>; WIDTH],
rc_b: [Column<Fixed>; WIDTH],
@ -607,7 +607,7 @@ mod tests {
use super::{PoseidonInstructions, Pow5Chip, Pow5Config, StateWord};
use crate::{
circuit::gadget::poseidon::Hash,
poseidon::Hash,
primitives::poseidon::{self, ConstantLength, P128Pow5T3 as OrchardNullifier, Spec},
};
use std::convert::TryInto;

View File

@ -1,5 +1,5 @@
//! Gadget and chips for the Sinsemilla hash function.
use crate::circuit::gadget::{
//! Gadgets for the Sinsemilla hash function.
use crate::{
ecc::{self, EccInstructions, FixedPoints},
utilities::Var,
};
@ -153,6 +153,7 @@ where
}
}
/// A message piece with a bitlength of some multiple of `K`.
#[derive(Copy, Clone, Debug)]
pub struct MessagePiece<C: CurveAffine, SinsemillaChip, const K: usize, const MAX_WORDS: usize>
where
@ -224,6 +225,7 @@ where
/// A domain in which $\mathsf{SinsemillaHashToPoint}$ and $\mathsf{SinsemillaHash}$ can
/// be used.
#[derive(Debug)]
#[allow(non_snake_case)]
pub struct HashDomain<
C: CurveAffine,
@ -317,9 +319,13 @@ pub trait CommitDomains<C: CurveAffine, F: FixedPoints<C>, H: HashDomains<C>>:
/// Trait allowing circuit's Sinsemilla HashDomains to be enumerated.
#[allow(non_snake_case)]
pub trait HashDomains<C: CurveAffine>: Clone + Debug {
/// Returns the `Q` constant for this domain.
fn Q(&self) -> C;
}
/// Gadget representing a domain in which $\mathsf{SinsemillaCommit}$ and
/// $\mathsf{SinsemillaShortCommit}$ can be used.
#[derive(Debug)]
#[allow(non_snake_case)]
pub struct CommitDomain<
C: CurveAffine,
@ -420,7 +426,8 @@ pub(crate) mod tests {
};
use crate::{
circuit::gadget::{
primitives::sinsemilla::{self, K},
{
ecc::{
chip::{find_zs_and_us, EccChip, EccConfig, H, NUM_WINDOWS},
tests::{FullWidth, TestFixedBases},
@ -428,7 +435,6 @@ pub(crate) mod tests {
},
utilities::lookup_range_check::LookupRangeCheckConfig,
},
primitives::sinsemilla::{self, K},
};
use group::{ff::Field, Curve};

View File

@ -1,13 +1,15 @@
//! Chip implementations for the Sinsemilla gadgets.
use super::{
message::{Message, MessagePiece},
CommitDomains, HashDomains, SinsemillaInstructions,
};
use crate::{
circuit::gadget::{
primitives::sinsemilla,
{
ecc::{chip::NonIdentityEccPoint, FixedPoints},
utilities::lookup_range_check::LookupRangeCheckConfig,
},
primitives::sinsemilla,
};
use std::marker::PhantomData;
@ -88,6 +90,7 @@ where
}
}
/// A chip that implements 10-bit Sinsemilla using a lookup table and 5 advice columns.
#[derive(Eq, PartialEq, Clone, Debug)]
pub struct SinsemillaChip<Hash, Commit, Fixed>
where
@ -122,10 +125,12 @@ where
F: FixedPoints<pallas::Affine>,
Commit: CommitDomains<pallas::Affine, F, Hash>,
{
/// Reconstructs this chip from the given config.
pub fn construct(config: <Self as Chip<pallas::Base>>::Config) -> Self {
Self { config }
}
/// Loads the lookup table required by this chip into the circuit.
pub fn load(
config: SinsemillaConfig<Hash, Commit, F>,
layouter: &mut impl Layouter<pallas::Base>,

View File

@ -1,7 +1,7 @@
use super::super::{CommitDomains, HashDomains, SinsemillaInstructions};
use super::{NonIdentityEccPoint, SinsemillaChip};
use crate::circuit::gadget::ecc::FixedPoints;
use crate::ecc::FixedPoints;
use crate::primitives::sinsemilla::{self, lebs2ip_k, INV_TWO_POW_K, SINSEMILLA_S};
use halo2::circuit::AssignedCell;
use halo2::{
@ -120,8 +120,8 @@ where
#[allow(non_snake_case)]
// Check equivalence to result from primitives::sinsemilla::hash_to_point
{
use crate::circuit::gadget::sinsemilla::message::MessagePiece;
use crate::primitives::sinsemilla::{K, S_PERSONALIZATION};
use crate::sinsemilla::message::MessagePiece;
use group::{prime::PrimeCurveAffine, Curve};
use pasta_curves::arithmetic::CurveExt;

View File

@ -1,3 +1,5 @@
//! Gadgets for implementing a Merkle tree with Sinsemilla.
use halo2::{
circuit::{Chip, Layouter},
plonk::Error,
@ -6,12 +8,12 @@ use pasta_curves::arithmetic::CurveAffine;
use super::{HashDomains, SinsemillaInstructions};
use crate::circuit::gadget::utilities::{
use crate::utilities::{
cond_swap::CondSwapInstructions, i2lebsp, transpose_option_array, UtilitiesInstructions,
};
use std::iter;
pub(in crate::circuit) mod chip;
pub(crate) mod chip;
/// SWU hash-to-curve personalization for the Merkle CRH generator
pub const MERKLE_CRH_PERSONALIZATION: &str = "z.cash:Orchard-MerkleCRH";
@ -44,6 +46,8 @@ pub trait MerkleInstructions<
) -> Result<Self::Var, Error>;
}
/// Gadget representing a Merkle path that proves a leaf exists in a Merkle tree at a
/// specific position.
#[derive(Clone, Debug)]
pub struct MerklePath<
C: CurveAffine,
@ -54,12 +58,12 @@ pub struct MerklePath<
> where
MerkleChip: MerkleInstructions<C, PATH_LENGTH, K, MAX_WORDS> + Clone,
{
pub(in crate::circuit) chip_1: MerkleChip,
pub(in crate::circuit) chip_2: MerkleChip,
pub(in crate::circuit) domain: MerkleChip::HashDomains,
pub(in crate::circuit) leaf_pos: Option<u32>,
pub(crate) chip_1: MerkleChip,
pub(crate) chip_2: MerkleChip,
pub(crate) domain: MerkleChip::HashDomains,
pub(crate) leaf_pos: Option<u32>,
// The Merkle path is ordered from leaves to root.
pub(in crate::circuit) path: Option<[C::Base; PATH_LENGTH]>,
pub(crate) path: Option<[C::Base; PATH_LENGTH]>,
}
#[allow(non_snake_case)]
@ -74,7 +78,7 @@ where
MerkleChip: MerkleInstructions<C, PATH_LENGTH, K, MAX_WORDS> + Clone,
{
/// Calculates the root of the tree containing the given leaf at this Merkle path.
pub(in crate::circuit) fn calculate_root(
pub(crate) fn calculate_root(
&self,
mut layouter: impl Layouter<C::Base>,
leaf: MerkleChip::Var,
@ -136,7 +140,7 @@ pub mod tests {
MerklePath,
};
use crate::circuit::gadget::{
use crate::{
ecc::tests::TestFixedBases,
sinsemilla::{
chip::SinsemillaChip,

View File

@ -8,7 +8,8 @@ use pasta_curves::{arithmetic::FieldExt, pallas};
use super::MerkleInstructions;
use crate::{
circuit::gadget::{
primitives::sinsemilla,
{
ecc::FixedPoints,
sinsemilla::{
chip::{SinsemillaChip, SinsemillaConfig},
@ -20,7 +21,6 @@ use crate::{
UtilitiesInstructions,
},
},
primitives::sinsemilla,
};
use group::ff::PrimeField;
use std::array;
@ -345,7 +345,7 @@ where
// Check layer hash output against Sinsemilla primitives hash
#[cfg(test)]
{
use crate::{circuit::gadget::utilities::i2lebsp, primitives::sinsemilla::HashDomain};
use crate::{primitives::sinsemilla::HashDomain, utilities::i2lebsp};
use group::ff::PrimeFieldBits;
if let (Some(left), Some(right)) = (left.value(), right.value()) {

View File

@ -225,7 +225,7 @@ mod tests {
use pasta_curves::{arithmetic::FieldExt, pallas};
use rand::rngs::OsRng;
use crate::circuit::gadget::ecc::chip::{
use crate::ecc::chip::{
FIXED_BASE_WINDOW_SIZE, L_SCALAR_SHORT as L_SHORT, NUM_WINDOWS, NUM_WINDOWS_SHORT,
};

View File

@ -13,6 +13,7 @@ use ff::PrimeFieldBits;
use super::*;
/// The running sum $[z_0, ..., z_W]$. If created in strict mode, $z_W = 0$.
#[derive(Debug)]
pub struct RunningSum<F: FieldExt + PrimeFieldBits>(Vec<AssignedCell<F, F>>);
impl<F: FieldExt + PrimeFieldBits> std::ops::Deref for RunningSum<F> {
type Target = Vec<AssignedCell<F, F>>;

View File

@ -1,15 +0,0 @@
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/katex.min.css" integrity="sha384-9eLZqc9ds8eNjO3TmqPeYcDj8n+Qfa4nuSiGYa6DjLNcv9BtN69ZIulL9+8CqC9Y" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/katex.min.js" integrity="sha384-K3vbOmF2BtaVai+Qk37uypf7VrgBubhQreNQe9aGsz9lB63dIFiQVlJbr92dw2Lx" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/katex@0.10.0/dist/contrib/auto-render.min.js" integrity="sha384-kmZOZB5ObwgQnS/DuDg6TScgOiWWBiVt0plIRkZCmE6rDZGrEOQeHM5PcHi+nyqe" crossorigin="anonymous"></script>
<script>
document.addEventListener("DOMContentLoaded", function() {
renderMathInElement(document.body, {
delimiters: [
{left: "$$", right: "$$", display: true},
{left: "\\(", right: "\\)", display: false},
{left: "$", right: "$", display: false},
{left: "\\[", right: "\\]", display: true}
]
});
});
</script>

View File

@ -1,3 +0,0 @@
//! The Orchard Action circuit implementation.
pub mod gadget;

View File

@ -1,6 +0,0 @@
//! Gadgets used in the Orchard circuit.
pub(crate) mod ecc;
pub mod poseidon;
pub(crate) mod sinsemilla;
pub mod utilities;