Skip to content

Commit

Permalink
halo2_gadgets: Replace Option<V> with Value<V>
Browse files Browse the repository at this point in the history
  • Loading branch information
str4d committed Jun 8, 2022
1 parent 47f25ad commit 5ed3d25
Show file tree
Hide file tree
Showing 40 changed files with 971 additions and 1,101 deletions.
42 changes: 42 additions & 0 deletions halo2_gadgets/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,48 @@ and this project adheres to Rust's notion of
[Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]
### Added
- `halo2_gadgets::utilities::RangeConstrained<F, Value<F>>::bitrange_of`

### Changed
All APIs that represented witnessed values as `Option<V>` now represent them as
`halo2_proofs::circuit::Value<V>`. The core API changes are listed below.

- The following APIs now take `Value<_>` instead of `Option<_>`:
- `halo2_gadgets::ecc`:
- `EccInstructions::{witness_point, witness_point_non_id}`
- `EccInstructions::{witness_scalar_var, witness_scalar_fixed}`
- `ScalarVar::new`
- `ScalarFixed::new`
- `NonIdentityPoint::new`
- `Point::new`
- `halo2_gadgets::sinsemilla`:
- `SinsemillaInstructions::witness_message_piece`
- `MessagePiece::{from_field_elem, from_subpieces}`
- `halo2_gadgets::sinsemilla::merkle`:
- `MerklePath::construct`
- `halo2_gadgets::utilities`:
- `UtilitiesInstructions::load_private`
- `RangeConstrained::witness_short`
- `halo2_gadgets::utilities::cond_swap`:
- `CondSwapInstructions::swap`
- `halo2_gadgets::utilities::decompose_running_sum`:
- `RunningSumConfig::witness_decompose`
- `halo2_gadgets::utilities::lookup_range_check`:
- `LookupRangeCheckConfig::{witness_check, witness_short_check}`
- The following APIs now return `Value<_>` instead of `Option<_>`:
- `halo2_gadgets::ecc::chip`:
- `EccPoint::{point, is_identity}`
- `NonIdentityEccPoint::point`
- `halo2_gadgets::utilities`:
- `FieldValue::value`
- `Var::value`
- `RangeConstrained::value`
- `halo2_gadgets::sha256::BlockWord` is now a newtype wrapper around
`Value<u32>` instead of `Option<u32>`.

### Removed
- `halo2_gadgets::utilities::RangeConstrained<F, Option<F>>::bitrange_of`

## [0.1.0] - 2022-05-10
### Added
Expand Down
28 changes: 12 additions & 16 deletions halo2_gadgets/benches/poseidon.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use ff::Field;
use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner},
circuit::{Layouter, SimpleFloorPlanner, Value},
pasta::Fp,
plonk::{
create_proof, keygen_pk, keygen_vk, verify_proof, Advice, Circuit, Column,
Expand All @@ -26,10 +26,10 @@ struct HashCircuit<S, const WIDTH: usize, const RATE: usize, const L: usize>
where
S: Spec<Fp, WIDTH, RATE> + Clone + Copy,
{
message: Option<[Fp; L]>,
message: Value<[Fp; L]>,
// For the purpose of this test, witness the result.
// TODO: Move this into an instance column.
output: Option<Fp>,
output: Value<Fp>,
_spec: PhantomData<S>,
}

Expand All @@ -49,8 +49,8 @@ where

fn without_witnesses(&self) -> Self {
Self {
message: None,
output: None,
message: Value::unknown(),
output: Value::unknown(),
_spec: PhantomData,
}
}
Expand Down Expand Up @@ -92,7 +92,7 @@ where
|| format!("load message_{}", i),
config.input[i],
0,
|| value.ok_or(Error::Synthesis),
|| value,
)
};

Expand All @@ -110,12 +110,8 @@ where
layouter.assign_region(
|| "constrain output",
|mut region| {
let expected_var = region.assign_advice(
|| "load output",
config.input[0],
0,
|| self.output.ok_or(Error::Synthesis),
)?;
let expected_var =
region.assign_advice(|| "load output", config.input[0], 0, || self.output)?;
region.constrain_equal(output.cell(), expected_var.cell())
},
)
Expand Down Expand Up @@ -191,8 +187,8 @@ fn bench_poseidon<S, const WIDTH: usize, const RATE: usize, const L: usize>(
let params: Params<vesta::Affine> = Params::new(K);

let empty_circuit = HashCircuit::<S, WIDTH, RATE, L> {
message: None,
output: None,
message: Value::unknown(),
output: Value::unknown(),
_spec: PhantomData,
};

Expand All @@ -212,8 +208,8 @@ fn bench_poseidon<S, const WIDTH: usize, const RATE: usize, const L: usize>(
let output = poseidon::Hash::<_, S, ConstantLength<L>, WIDTH, RATE>::init().hash(message);

let circuit = HashCircuit::<S, WIDTH, RATE, L> {
message: Some(message),
output: Some(output),
message: Value::known(message),
output: Value::known(output),
_spec: PhantomData,
};

Expand Down
34 changes: 17 additions & 17 deletions halo2_gadgets/benches/sha256.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner},
circuit::{Layouter, SimpleFloorPlanner, Value},
pasta::{pallas, EqAffine},
plonk::{
create_proof, keygen_pk, keygen_vk, verify_proof, Circuit, ConstraintSystem, Error,
Expand Down Expand Up @@ -47,22 +47,22 @@ fn bench(name: &str, k: u32, c: &mut Criterion) {

// Test vector: "abc"
let test_input = [
BlockWord(Some(0b01100001011000100110001110000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000000000)),
BlockWord(Some(0b00000000000000000000000000011000)),
BlockWord(Value::known(0b01100001011000100110001110000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000000000)),
BlockWord(Value::known(0b00000000000000000000000000011000)),
];

// Create a message of length 31 blocks
Expand Down
30 changes: 15 additions & 15 deletions halo2_gadgets/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::fmt::Debug;

use halo2_proofs::{
arithmetic::CurveAffine,
circuit::{Chip, Layouter},
circuit::{Chip, Layouter, Value},
plonk::Error,
};

Expand Down Expand Up @@ -57,29 +57,29 @@ pub trait EccInstructions<C: CurveAffine>:
fn witness_point(
&self,
layouter: &mut impl Layouter<C::Base>,
value: Option<C>,
value: Value<C>,
) -> Result<Self::Point, Error>;

/// Witnesses the given point as a private input to the circuit.
/// This returns an error if the point is the identity.
fn witness_point_non_id(
&self,
layouter: &mut impl Layouter<C::Base>,
value: Option<C>,
value: Value<C>,
) -> Result<Self::NonIdentityPoint, Error>;

/// Witnesses a full-width scalar to be used in variable-base multiplication.
fn witness_scalar_var(
&self,
layouter: &mut impl Layouter<C::Base>,
value: Option<C::Scalar>,
value: Value<C::Scalar>,
) -> Result<Self::ScalarVar, Error>;

/// Witnesses a full-width scalar to be used in fixed-base multiplication.
fn witness_scalar_fixed(
&self,
layouter: &mut impl Layouter<C::Base>,
value: Option<C::Scalar>,
value: Value<C::Scalar>,
) -> Result<Self::ScalarFixed, Error>;

/// Converts a magnitude and sign that exists as variables in the circuit into a
Expand Down Expand Up @@ -184,7 +184,7 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> ScalarVar<C, EccChip> {
pub fn new(
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: Option<C::Scalar>,
value: Value<C::Scalar>,
) -> Result<Self, Error> {
let scalar = chip.witness_scalar_var(&mut layouter, value);
scalar.map(|inner| ScalarVar { chip, inner })
Expand Down Expand Up @@ -219,7 +219,7 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> ScalarFixed<C, EccChip> {
pub fn new(
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: Option<C::Scalar>,
value: Value<C::Scalar>,
) -> Result<Self, Error> {
let scalar = chip.witness_scalar_fixed(&mut layouter, value);
scalar.map(|inner| ScalarFixed { chip, inner })
Expand Down Expand Up @@ -266,7 +266,7 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> NonIdentityPoint<C, EccChip> {
pub fn new(
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: Option<C>,
value: Value<C>,
) -> Result<Self, Error> {
let point = chip.witness_point_non_id(&mut layouter, value);
point.map(|inner| NonIdentityPoint { chip, inner })
Expand Down Expand Up @@ -384,7 +384,7 @@ impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone + Debug + Eq> Point<C,
pub fn new(
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: Option<C>,
value: Value<C>,
) -> Result<Self, Error> {
let point = chip.witness_point(&mut layouter, value);
point.map(|inner| Point { chip, inner })
Expand Down Expand Up @@ -581,7 +581,7 @@ pub(crate) mod tests {
use group::{prime::PrimeCurveAffine, Curve, Group};

use halo2_proofs::{
circuit::{Layouter, SimpleFloorPlanner},
circuit::{Layouter, SimpleFloorPlanner, Value},
dev::MockProver,
plonk::{Circuit, ConstraintSystem, Error},
};
Expand Down Expand Up @@ -784,21 +784,21 @@ pub(crate) mod tests {
let p = super::NonIdentityPoint::new(
chip.clone(),
layouter.namespace(|| "P"),
Some(p_val),
Value::known(p_val),
)?;
let p_neg = -p_val;
let p_neg = super::NonIdentityPoint::new(
chip.clone(),
layouter.namespace(|| "-P"),
Some(p_neg),
Value::known(p_neg),
)?;

// Generate a random non-identity point Q
let q_val = pallas::Point::random(rand::rngs::OsRng).to_affine(); // Q
let q = super::NonIdentityPoint::new(
chip.clone(),
layouter.namespace(|| "Q"),
Some(q_val),
Value::known(q_val),
)?;

// Make sure P and Q are not the same point.
Expand All @@ -809,13 +809,13 @@ pub(crate) mod tests {
let _ = super::Point::new(
chip.clone(),
layouter.namespace(|| "identity"),
Some(pallas::Affine::identity()),
Value::known(pallas::Affine::identity()),
)?;

super::NonIdentityPoint::new(
chip.clone(),
layouter.namespace(|| "identity"),
Some(pallas::Affine::identity()),
Value::known(pallas::Affine::identity()),
)
.expect_err("Trying to witness the identity should return an error");
}
Expand Down
Loading

0 comments on commit 5ed3d25

Please sign in to comment.