Skip to content

Commit

Permalink
halo2: Improve abstractions documenting (#1654)
Browse files Browse the repository at this point in the history
* fix: Fix cargo clippy warnings

* ci: Increase no_output_timeout for test_storage_proofs_core job

* ci: Fix tarpaulin coverage job

* doc(fil-halo2-gadgets): Add documentation for AssignedBits abstraction

* doc(fil-halo2-gadgets): Add documentation for AdviceIter abstraction

* doc(fil-halo2-gadgets): Make code examples compilable
  • Loading branch information
storojs72 authored Jan 10, 2023
1 parent bf072fe commit 2fccc4b
Show file tree
Hide file tree
Showing 6 changed files with 193 additions and 3 deletions.
5 changes: 3 additions & 2 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ jobs:
- run:
name: Test (<< parameters.crate >>)
command: cargo +$(cat rust-toolchain) test --verbose --package << parameters.crate >>
no_output_timeout: 30m
no_output_timeout: 45m

test_release:
executor: default
Expand Down Expand Up @@ -401,7 +401,7 @@ jobs:
docker run
--security-opt seccomp=unconfined
-v "${PWD}:/volume"
-v "${FIL_PROOFS_PARAMETER_CACHE}:/var/tmp/filecoin-proof-parameters/"
-v "${FIL_PROOFS_PARAMETER_CACHE}:/tmp/filecoin-proof-parameters/"
xd009642/tarpaulin
sh -c "apt update && apt install -y libssl-dev ocl-icd-opencl-dev libhwloc-dev && cargo tarpaulin --timeout 1800 --release -v"
no_output_timeout: 30m
Expand Down Expand Up @@ -666,4 +666,5 @@ workflows:

- coverage-with-tarpaulin:
requires:
- cargo_fetch
- ensure_parameters_and_keys_linux
1 change: 1 addition & 0 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions fil-halo2-gadgets/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sha2 = "0.9.2"
[dev-dependencies]
rand = "0.8"
rand_xorshift = "0.3.0"
pasta_curves = "0.4.0"

[features]
all-chips = []
150 changes: 150 additions & 0 deletions fil-halo2-gadgets/src/boolean.rs
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,12 @@ impl From<u32> for Bits<32> {
}
}

/// Utility for convenient assigning bits (`Bit`) into Halo2 circuit
///
/// It's implementation is motivated by SHA-256 chip (and its optimizations),
/// which operates with 32-bit words. Halo2 circuit stores information as field elements,
/// so regardless of number of bits assigned 1 or 64, they both will occupy single field element.
///
#[derive(Clone, Debug)]
pub struct AssignedBits<F: FieldExt, const LEN: usize>(pub(crate) AssignedCell<Bits<LEN>, F>);

Expand All @@ -207,6 +213,54 @@ impl<F: FieldExt, const LEN: usize> std::ops::Deref for AssignedBits<F, LEN> {
}

impl<F: FieldExt, const LEN: usize> AssignedBits<F, LEN> {
/// Assigns up to 64 bits represented as [bool; LEN] into assigned region of Halo2 circuit
/// at a given `offset` using either advice or fixed column.
///
/// ***Panics*** if bits are assigned to instance column
///
/// ```
/// # use pasta_curves::Fp;
/// # use halo2_proofs::plonk::{ConstraintSystem, Circuit, Error, Column, Advice};
/// # use halo2_proofs::circuit::{Value, SimpleFloorPlanner, Layouter};
/// # use fil_halo2_gadgets::boolean::AssignedBits;
///
/// # struct TestCircuit;
/// # impl Circuit<Fp> for TestCircuit {
/// # type Config = Column<Advice>;
/// # type FloorPlanner = SimpleFloorPlanner;
/// # fn without_witnesses(&self) -> Self {
/// # todo!()
/// # }
/// # fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
/// # todo!()
/// # }
/// # fn synthesize(
/// # &self,
/// # config: Self::Config,
/// # mut layouter: impl Layouter<Fp>,
/// # ) -> Result<(), Error> {
/// # let column = config;
///
/// const LEN: usize = 32;
/// let offset = 0;
/// let value = Value::known([false; 32]);
///
/// layouter.assign_region(
/// || "test assignment",
/// |mut region| {
/// AssignedBits::<Fp, LEN>::assign_bits(
/// &mut region,
/// || "assign 32 zero bits",
/// column,
/// offset,
/// value,
/// )
/// },
/// )?;
/// # Ok(())
/// # }
/// # }
/// ```
pub fn assign_bits<A, AR, T: TryInto<[bool; LEN]> + std::fmt::Debug + Clone>(
region: &mut Region<'_, F>,
annotation: A,
Expand Down Expand Up @@ -245,6 +299,54 @@ impl<F: FieldExt> AssignedBits<F, 16> {
self.value().map(|v| v.into())
}

/// Assigns 16 bits represented as `u16` into assigned region of Halo2 circuit
/// at a given `offset` using either advice or fixed column.
///
/// ***Panics*** if bits are assigned to the instance column
///
/// ```
/// # use pasta_curves::Fp;
/// # use halo2_proofs::plonk::{ConstraintSystem, Circuit, Error, Column, Advice};
/// # use halo2_proofs::circuit::{Value, SimpleFloorPlanner, Layouter};
/// # use fil_halo2_gadgets::boolean::AssignedBits;
///
/// # struct TestCircuit;
/// # impl Circuit<Fp> for TestCircuit {
/// # type Config = Column<Advice>;
/// # type FloorPlanner = SimpleFloorPlanner;
/// # fn without_witnesses(&self) -> Self {
/// # todo!()
/// # }
/// # fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
/// # todo!()
/// # }
/// # fn synthesize(
/// # &self,
/// # config: Self::Config,
/// # mut layouter: impl Layouter<Fp>,
/// # ) -> Result<(), Error> {
/// # let column = config;
///
/// const LEN: usize = 16;
/// let offset = 0;
/// let value = Value::known(0u16);
///
/// layouter.assign_region(
/// || "test assignment",
/// |mut region| {
/// AssignedBits::<Fp, LEN>::assign(
/// &mut region,
/// || "assign 16-bits word",
/// column,
/// offset,
/// value,
/// )
/// },
/// )?;
/// # Ok(())
/// # }
/// # }
/// ```
pub fn assign<A, AR>(
region: &mut Region<'_, F>,
annotation: A,
Expand Down Expand Up @@ -280,6 +382,54 @@ impl<F: FieldExt> AssignedBits<F, 32> {
self.value().map(|v| v.into())
}

/// Assigns 32 bits represented as `u32` into assigned region of Halo2 circuit
/// at a given `offset` using either advice or fixed column.
///
/// ***Panics*** if bits are assigned to instance column
///
/// ```
/// # use pasta_curves::Fp;
/// # use halo2_proofs::plonk::{ConstraintSystem, Circuit, Error, Column, Advice};
/// # use halo2_proofs::circuit::{Value, SimpleFloorPlanner, Layouter};
/// # use fil_halo2_gadgets::boolean::AssignedBits;
///
/// # struct TestCircuit;
/// # impl Circuit<Fp> for TestCircuit {
/// # type Config = Column<Advice>;
/// # type FloorPlanner = SimpleFloorPlanner;
/// # fn without_witnesses(&self) -> Self {
/// # todo!()
/// # }
/// # fn configure(meta: &mut ConstraintSystem<Fp>) -> Self::Config {
/// # todo!()
/// # }
/// # fn synthesize(
/// # &self,
/// # config: Self::Config,
/// # mut layouter: impl Layouter<Fp>,
/// # ) -> Result<(), Error> {
/// # let column = config;
///
/// const LEN: usize = 32;
/// let offset = 0;
/// let value = Value::known(0u32);
///
/// layouter.assign_region(
/// || "test assignment",
/// |mut region| {
/// AssignedBits::<Fp, LEN>::assign(
/// &mut region,
/// || "assign 32-bits word",
/// column,
/// offset,
/// value,
/// )
/// },
/// )?;
/// # Ok(())
/// # }
/// # }
/// ```
pub fn assign<A, AR>(
region: &mut Region<'_, F>,
annotation: A,
Expand Down
37 changes: 37 additions & 0 deletions fil-halo2-gadgets/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,15 @@ impl<T, F: FieldExt> From<MaybeAssigned<T, F>> for AssignedCell<T, F> {
}
}

/// Iterator for `Vec<Column<Advice>>` used for convenient manipulations over columns.
///
/// Assigning data into constraints system optimally in Halo2 often causes confusions which particular column
/// to use and with what offset. `AdviceIter` "automatically" rotates supplied columns while data assignment,
/// and when all columns have been already in use, increments `offset`, so next block of assignment can be performed
/// from a "starting" column.
///
/// Note, as `offset` can increase infinitely, the cost of proving (proof size, proving / verification time) also increases.
///
pub struct AdviceIter {
offset: usize,
advice: Vec<Column<Advice>>,
Expand All @@ -163,6 +172,34 @@ impl AdviceIter {
}
}

/// Returns next `(offset, column)` tuple, considering previous data assignment.
///
/// ```
/// use pasta_curves::Fp;
/// use halo2_proofs::plonk::{ ConstraintSystem, Column, Advice };
/// use fil_halo2_gadgets::AdviceIter;
///
/// let mut cs = ConstraintSystem::<Fp>::default();
///
/// let advice_columns = (0..8).into_iter().map(|_| cs.advice_column()).collect::<Vec<Column<Advice>>>();
///
/// let mut advice_iter = AdviceIter::from(advice_columns);
///
/// for index in 0..8 {
/// let (offset, col) = advice_iter.next();
/// assert_eq!(offset, 0);
/// }
///
/// for index in 8..16 {
/// let (offset, col) = advice_iter.next();
/// assert_eq!(offset, 1);
/// }
///
/// for index in 16..24 {
/// let (offset, col) = advice_iter.next();
/// assert_eq!(offset, 2);
/// }
/// ```
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> (usize, Column<Advice>) {
if self.col_index == self.num_cols {
Expand Down
2 changes: 1 addition & 1 deletion fil-proofs-tooling/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ impl GitMetadata {
let repo = Repository::discover(&repo_path)?;
let head = repo.head()?;
let commit = head.peel_to_commit()?;
let date = Utc.timestamp(commit.time().seconds(), 0);
let date = Utc.timestamp_opt(commit.time().seconds(), 0).unwrap();

Ok(GitMetadata {
hash: commit.id().to_string(),
Expand Down

0 comments on commit 2fccc4b

Please sign in to comment.