diff --git a/halo2_gadgets/src/ecc/chip/mul.rs b/halo2_gadgets/src/ecc/chip/mul.rs index 8e857ae442..5939c3822f 100644 --- a/halo2_gadgets/src/ecc/chip/mul.rs +++ b/halo2_gadgets/src/ecc/chip/mul.rs @@ -10,7 +10,7 @@ use std::{ use ff::{Field, PrimeField}; use halo2_proofs::{ - circuit::{AssignedCell, Layouter, Region, Value}, + circuit::{AssignedCell, FieldValue, Layouter, Region, Value}, plonk::{Advice, Assigned, Column, ConstraintSystem, Constraints, Error, Selector}, poly::Rotation, }; @@ -358,7 +358,7 @@ impl Config { if !lsb { base.x.value().cloned() } else { - Value::known(Assigned::Zero) + FieldValue::ZERO } }); @@ -366,7 +366,7 @@ impl Config { if !lsb { -base.y.value() } else { - Value::known(Assigned::Zero) + FieldValue::ZERO } }); diff --git a/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs b/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs index bfdc735f70..9c985aef1f 100644 --- a/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs +++ b/halo2_gadgets/src/ecc/chip/mul_fixed/short.rs @@ -248,7 +248,7 @@ pub mod tests { use group::{ff::PrimeField, Curve}; use halo2_proofs::{ arithmetic::CurveAffine, - circuit::{AssignedCell, Chip, Layouter, Value}, + circuit::{AssignedCell, Chip, FieldValue, Layouter, Value}, plonk::{Any, Error}, }; use pasta_curves::pallas; @@ -519,31 +519,31 @@ pub mod tests { // 2^64 MyCircuit { magnitude: Value::known(pallas::Base::from_u128(1 << 64)), - sign: Value::known(pallas::Base::one()), + sign: FieldValue::ONE, magnitude_error: Value::known(pallas::Base::from(1 << 1)), }, // -2^64 MyCircuit { magnitude: Value::known(pallas::Base::from_u128(1 << 64)), - sign: Value::known(-pallas::Base::one()), + sign: -Value::::ONE, magnitude_error: Value::known(pallas::Base::from(1 << 1)), }, // 2^66 MyCircuit { magnitude: Value::known(pallas::Base::from_u128(1 << 66)), - sign: Value::known(pallas::Base::one()), + sign: FieldValue::ONE, magnitude_error: Value::known(pallas::Base::from(1 << 3)), }, // -2^66 MyCircuit { magnitude: Value::known(pallas::Base::from_u128(1 << 66)), - sign: Value::known(-pallas::Base::one()), + sign: -Value::::ONE, magnitude_error: Value::known(pallas::Base::from(1 << 3)), }, // 2^254 MyCircuit { magnitude: Value::known(pallas::Base::from_u128(1 << 127).square()), - sign: Value::known(pallas::Base::one()), + sign: FieldValue::ONE, magnitude_error: Value::known( pallas::Base::from_u128(1 << 95).square() * pallas::Base::from(2), ), @@ -551,7 +551,7 @@ pub mod tests { // -2^254 MyCircuit { magnitude: Value::known(pallas::Base::from_u128(1 << 127).square()), - sign: Value::known(-pallas::Base::one()), + sign: -Value::::ONE, magnitude_error: Value::known( pallas::Base::from_u128(1 << 95).square() * pallas::Base::from(2), ), @@ -605,7 +605,7 @@ pub mod tests { let magnitude_u64 = rand::random::(); let circuit = MyCircuit { magnitude: Value::known(pallas::Base::from(magnitude_u64)), - sign: Value::known(pallas::Base::zero()), + sign: FieldValue::ZERO, magnitude_error: Value::unknown(), }; diff --git a/halo2_gadgets/src/poseidon/pow5.rs b/halo2_gadgets/src/poseidon/pow5.rs index a8e6711235..b0c951831f 100644 --- a/halo2_gadgets/src/poseidon/pow5.rs +++ b/halo2_gadgets/src/poseidon/pow5.rs @@ -3,7 +3,7 @@ use std::iter; use group::ff::Field; use halo2_proofs::{ - circuit::{AssignedCell, Cell, Chip, Layouter, Region, Value}, + circuit::{AssignedCell, Cell, Chip, FieldValue, Layouter, Region, Value}, plonk::{ Advice, Any, Column, ConstraintSystem, Constraints, Error, Expression, Fixed, Selector, }, @@ -370,7 +370,7 @@ impl< .get(i) .map(|word| word.0.value().cloned()) // The capacity element is never altered by the input. - .unwrap_or_else(|| Value::known(F::ZERO)); + .unwrap_or_else(|| FieldValue::ZERO); region .assign_advice( || format!("load output_{}", i), diff --git a/halo2_gadgets/src/sha256/table16/compression.rs b/halo2_gadgets/src/sha256/table16/compression.rs index 528b1d9a98..ff78a52737 100644 --- a/halo2_gadgets/src/sha256/table16/compression.rs +++ b/halo2_gadgets/src/sha256/table16/compression.rs @@ -4,7 +4,7 @@ use super::{ AssignedBits, BlockWord, SpreadInputs, SpreadVar, Table16Assignment, ROUNDS, STATE, }; use halo2_proofs::{ - circuit::{Layouter, Value}, + circuit::{IntegerValue, Layouter, Value}, pasta::pallas, plonk::{Advice, Column, ConstraintSystem, Error, Selector}, poly::Rotation, @@ -922,7 +922,7 @@ impl CompressionConfig { layouter: &mut impl Layouter, state: State, ) -> Result<[BlockWord; DIGEST_SIZE], Error> { - let mut digest = [BlockWord(Value::known(0)); DIGEST_SIZE]; + let mut digest = [BlockWord(IntegerValue::ZERO); DIGEST_SIZE]; layouter.assign_region( || "digest", |mut region| { diff --git a/halo2_gadgets/src/sinsemilla.rs b/halo2_gadgets/src/sinsemilla.rs index 3f06315a77..21091f7fdc 100644 --- a/halo2_gadgets/src/sinsemilla.rs +++ b/halo2_gadgets/src/sinsemilla.rs @@ -3,11 +3,11 @@ //! [Sinsemilla]: https://zips.z.cash/protocol/protocol.pdf#concretesinsemillahash use crate::{ ecc::{self, EccInstructions, FixedPoints}, - utilities::{FieldValue, RangeConstrained, Var}, + utilities::{FieldValue as _, RangeConstrained, Var}, }; use group::ff::{Field, PrimeField}; use halo2_proofs::{ - circuit::{Layouter, Value}, + circuit::{FieldValue, Layouter, Value}, plonk::Error, }; use pasta_curves::arithmetic::CurveAffine; @@ -243,17 +243,17 @@ where layouter: impl Layouter, subpieces: impl IntoIterator>>, ) -> Result { - let (field_elem, total_bits) = subpieces.into_iter().fold( - (Value::known(C::Base::ZERO), 0), - |(acc, bits), subpiece| { - assert!(bits < 64); - let subpiece_shifted = subpiece - .inner() - .value() - .map(|v| C::Base::from(1 << bits) * v); - (acc + subpiece_shifted, bits + subpiece.num_bits()) - }, - ); + let (field_elem, total_bits) = + subpieces + .into_iter() + .fold((FieldValue::ZERO, 0), |(acc, bits), subpiece| { + assert!(bits < 64); + let subpiece_shifted = subpiece + .inner() + .value() + .map(|v| C::Base::from(1 << bits) * v); + (acc + subpiece_shifted, bits + subpiece.num_bits()) + }); // Message must be composed of `K`-bit words. assert_eq!(total_bits % K, 0); diff --git a/halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs b/halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs index 44beaa4259..ddfbb4013f 100644 --- a/halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs +++ b/halo2_gadgets/src/sinsemilla/chip/hash_to_point.rs @@ -6,6 +6,7 @@ use crate::{ }; use ff::Field; +use halo2_proofs::circuit::FieldValue; use halo2_proofs::{ circuit::{AssignedCell, Chip, Region, Value}, plonk::{Assigned, Error}, @@ -108,13 +109,13 @@ where || "dummy lambda2", config.double_and_add.lambda_2, offset, - || Value::known(pallas::Base::zero()), + || Value::::ZERO, )?; region.assign_advice( || "dummy x_p", config.double_and_add.x_p, offset, - || Value::known(pallas::Base::zero()), + || Value::::ZERO, )?; } @@ -211,7 +212,7 @@ where || "q_s2 = 1", config.q_sinsemilla2, offset + row, - || Value::known(pallas::Base::one()), + || Value::::ONE, )?; } diff --git a/halo2_gadgets/src/utilities/lookup_range_check.rs b/halo2_gadgets/src/utilities/lookup_range_check.rs index b26a89a884..e680eada1d 100644 --- a/halo2_gadgets/src/utilities/lookup_range_check.rs +++ b/halo2_gadgets/src/utilities/lookup_range_check.rs @@ -391,7 +391,7 @@ mod tests { use ff::{Field, PrimeFieldBits}; use halo2_proofs::{ - circuit::{Layouter, SimpleFloorPlanner, Value}, + circuit::{FieldValue, Layouter, SimpleFloorPlanner, Value}, dev::{FailureLocation, MockProver, VerifyFailure}, plonk::{Circuit, ConstraintSystem, Error}, }; @@ -545,7 +545,7 @@ mod tests { // Edge case: zero bits { let circuit: MyCircuit = MyCircuit { - element: Value::known(pallas::Base::ZERO), + element: FieldValue::ZERO, num_bits: 0, }; let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); diff --git a/halo2_proofs/CHANGELOG.md b/halo2_proofs/CHANGELOG.md index 597838a5b2..95be4e42ae 100644 --- a/halo2_proofs/CHANGELOG.md +++ b/halo2_proofs/CHANGELOG.md @@ -16,6 +16,9 @@ and this project adheres to Rust's notion of - `metadata::Region` - `halo2_proofs::poly::Rotation` - `halo2_proofs::arithmetic::FftGroup` +- `halo2_proofs::circuit`: + - `FieldValue` and `IntegerValue` helper traits, to provide common constants + equivalent to using `Value::known(_)`. - `halo2_proofs::circuit::layouter`: - `RegionLayouter::instance_value` method added to provide access to instance values within a region. diff --git a/halo2_proofs/benches/plonk.rs b/halo2_proofs/benches/plonk.rs index 7a57be8a32..730e57ef64 100644 --- a/halo2_proofs/benches/plonk.rs +++ b/halo2_proofs/benches/plonk.rs @@ -2,7 +2,7 @@ extern crate criterion; use group::ff::Field; -use halo2_proofs::circuit::{Cell, Layouter, SimpleFloorPlanner, Value}; +use halo2_proofs::circuit::{Cell, FieldValue, Layouter, SimpleFloorPlanner, Value}; use halo2_proofs::pasta::{EqAffine, Fp}; use halo2_proofs::plonk::*; use halo2_proofs::poly::{commitment::Params, Rotation}; @@ -103,10 +103,10 @@ fn criterion_benchmark(c: &mut Criterion) { || value.unwrap().map(|v| v.2), )?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ZERO))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ZERO))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::::ZERO)?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::::ZERO)?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::::ONE)?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::::ONE)?; Ok((lhs.cell(), rhs.cell(), out.cell())) }, ) @@ -145,15 +145,10 @@ fn criterion_benchmark(c: &mut Criterion) { || value.unwrap().map(|v| v.2), )?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; - region.assign_fixed( - || "a * b", - self.config.sm, - 0, - || Value::known(FF::ZERO), - )?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::::ONE)?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::::ONE)?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::::ONE)?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::::ZERO)?; Ok((lhs.cell(), rhs.cell(), out.cell())) }, ) diff --git a/halo2_proofs/examples/circuit-layout.rs b/halo2_proofs/examples/circuit-layout.rs index 71e22ddc5a..3c28993e26 100644 --- a/halo2_proofs/examples/circuit-layout.rs +++ b/halo2_proofs/examples/circuit-layout.rs @@ -1,6 +1,6 @@ use ff::Field; use halo2_proofs::{ - circuit::{Cell, Layouter, Region, SimpleFloorPlanner, Value}, + circuit::{Cell, FieldValue, Layouter, Region, SimpleFloorPlanner, Value}, pasta::Fp, plonk::{Advice, Assigned, Circuit, Column, ConstraintSystem, Error, Fixed, TableColumn}, poly::Rotation, @@ -93,10 +93,10 @@ impl StandardCs for StandardPlonk { let out = region.assign_advice(|| "out", self.config.c, 0, || value.unwrap().map(|v| v.2))?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ZERO))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ZERO))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::::ZERO)?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::::ZERO)?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::::ONE)?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::::ONE)?; Ok((lhs.cell(), rhs.cell(), out.cell())) } fn raw_add(&self, region: &mut Region, mut f: F) -> Result<(Cell, Cell, Cell), Error> @@ -130,10 +130,10 @@ impl StandardCs for StandardPlonk { let out = region.assign_advice(|| "out", self.config.c, 0, || value.unwrap().map(|v| v.2))?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::ZERO))?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::::ONE)?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::::ONE)?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::::ONE)?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::::ZERO)?; Ok((lhs.cell(), rhs.cell(), out.cell())) } fn copy(&self, region: &mut Region, left: Cell, right: Cell) -> Result<(), Error> { diff --git a/halo2_proofs/src/circuit.rs b/halo2_proofs/src/circuit.rs index 7f16651670..174514f0fe 100644 --- a/halo2_proofs/src/circuit.rs +++ b/halo2_proofs/src/circuit.rs @@ -7,7 +7,7 @@ use ff::Field; use crate::plonk::{Advice, Any, Assigned, Column, Error, Fixed, Instance, Selector, TableColumn}; mod value; -pub use value::Value; +pub use value::{FieldValue, IntegerValue, Value}; pub mod floor_planner; pub use floor_planner::single_pass::SimpleFloorPlanner; diff --git a/halo2_proofs/src/circuit/value.rs b/halo2_proofs/src/circuit/value.rs index 50b30c2676..f22512c1da 100644 --- a/halo2_proofs/src/circuit/value.rs +++ b/halo2_proofs/src/circuit/value.rs @@ -5,6 +5,11 @@ use group::ff::Field; use crate::plonk::{Assigned, Error}; +mod private { + pub trait SealedInteger {} + pub trait SealedField {} +} + /// A value that might exist within a circuit. /// /// This behaves like `Option` but differs in two key ways: @@ -17,6 +22,74 @@ pub struct Value { inner: Option, } +// +// Constants and constructors +// + +/// Helper trait providing common `Value` constants for integer types. +/// +/// # Examples +/// +/// ``` +/// use halo2_proofs::circuit::{IntegerValue, Value}; +/// +/// let a = Value::known(1u64); +/// let b = IntegerValue::ONE; +/// a.zip(b).assert_if_known(|(a, b)| a == b); +/// ``` +pub trait IntegerValue: private::SealedInteger { + /// Equivalent to `Value::known(0)`. + const ZERO: Self; + /// Equivalent to `Value::known(1)`. + const ONE: Self; +} + +macro_rules! integer_value { + ($($type:ty),+) => { + $( + impl private::SealedInteger for Value<$type> {} + impl IntegerValue for Value<$type> { + const ZERO: Value<$type> = Value::known(0); + const ONE: Value<$type> = Value::known(1); + } + )+ + }; +} + +integer_value!(i8, i16, i32, i64, i128, isize); +integer_value!(u8, u16, u32, u64, u128, usize); + +/// Helper trait providing common `Value` constants. +/// +/// # Examples +/// +/// ``` +/// use group::ff::Field; +/// use halo2_proofs::circuit::{FieldValue, Value}; +/// +/// fn my_code() { +/// let a = Value::known(F::ONE); +/// let b = FieldValue::ONE; +/// a.zip(b).assert_if_known(|(a, b)| a == b); +/// } +/// ``` +pub trait FieldValue: private::SealedField { + /// The zero element of the field, the additive identity. + /// + /// Equivalent to `Value::known(F::ZERO)` for `F: Field`. + const ZERO: Self; + /// The one element of the field, the multiplicative identity. + /// + /// Equivalent to `Value::known(F::ONE)` for `F: Field`. + const ONE: Self; +} + +impl private::SealedField for Value {} +impl FieldValue for Value { + const ZERO: Value = Value::known(F::ZERO); + const ONE: Value = Value::known(F::ONE); +} + impl Default for Value { fn default() -> Self { Self::unknown() @@ -496,6 +569,12 @@ where // Assigned // +impl private::SealedField for Value> {} +impl FieldValue for Value> { + const ZERO: Value> = Value::known(Assigned::Zero); + const ONE: Value> = Value::known(Assigned::Trivial(F::ONE)); +} + impl From> for Value> { fn from(value: Value) -> Self { Self { diff --git a/halo2_proofs/src/dev.rs b/halo2_proofs/src/dev.rs index 41e6d92fdd..69f0d622b1 100644 --- a/halo2_proofs/src/dev.rs +++ b/halo2_proofs/src/dev.rs @@ -917,12 +917,11 @@ impl MockProver { #[cfg(test)] mod tests { - use group::ff::Field; use pasta_curves::Fp; use super::{FailureLocation, MockProver, VerifyFailure}; use crate::{ - circuit::{Layouter, SimpleFloorPlanner, Value}, + circuit::{FieldValue, Layouter, SimpleFloorPlanner, Value}, plonk::{ Advice, Any, Circuit, Column, ConstraintSystem, Error, Expression, Selector, TableColumn, @@ -979,7 +978,7 @@ mod tests { config.q.enable(&mut region, 1)?; // Assign a = 0. - region.assign_advice(|| "a", config.a, 0, || Value::known(Fp::ZERO))?; + region.assign_advice(|| "a", config.a, 0, || Value::::ZERO)?; // BUG: Forget to assign b = 0! This could go unnoticed during // development, because cell values default to zero, which in this diff --git a/halo2_proofs/src/plonk/circuit.rs b/halo2_proofs/src/plonk/circuit.rs index d16f3b7e8f..4dcc7b529f 100644 --- a/halo2_proofs/src/plonk/circuit.rs +++ b/halo2_proofs/src/plonk/circuit.rs @@ -230,7 +230,7 @@ impl TryFrom> for Column { /// ``` /// use group::ff::Field; /// use halo2_proofs::{ -/// circuit::{Chip, Layouter, Value}, +/// circuit::{Chip, FieldValue, Layouter}, /// plonk::{Advice, Column, Error, Selector}, /// }; /// # use halo2_proofs::plonk::Fixed; @@ -245,8 +245,8 @@ impl TryFrom> for Column { /// let config = chip.config(); /// # let config: Config = todo!(); /// layouter.assign_region(|| "bar", |mut region| { -/// region.assign_advice(|| "a", config.a, 0, || Value::known(F::ONE))?; -/// region.assign_advice(|| "a", config.b, 1, || Value::known(F::ONE))?; +/// region.assign_advice(|| "a", config.a, 0, || FieldValue::ONE)?; +/// region.assign_advice(|| "a", config.b, 1, || FieldValue::ONE)?; /// config.s.enable(&mut region, 1) /// })?; /// Ok(()) diff --git a/halo2_proofs/tests/plonk_api.rs b/halo2_proofs/tests/plonk_api.rs index 72d59bb9c2..5581c44f91 100644 --- a/halo2_proofs/tests/plonk_api.rs +++ b/halo2_proofs/tests/plonk_api.rs @@ -4,7 +4,7 @@ use assert_matches::assert_matches; use group::ff::{Field, WithSmallOrderMulGroup}; use halo2_proofs::arithmetic::CurveAffine; -use halo2_proofs::circuit::{Cell, Layouter, SimpleFloorPlanner, Value}; +use halo2_proofs::circuit::{Cell, FieldValue, Layouter, SimpleFloorPlanner, Value}; use halo2_proofs::dev::MockProver; use halo2_proofs::pasta::{Eq, EqAffine, Fp}; use halo2_proofs::plonk::{ @@ -138,10 +138,10 @@ fn plonk_api() { || value.unwrap().map(|v| v.2), )?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ZERO))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ZERO))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::known(FF::ONE))?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::::ZERO)?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::::ZERO)?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::::ONE)?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::::ONE)?; Ok((lhs.cell(), rhs.cell(), out.cell())) }, ) @@ -192,15 +192,10 @@ fn plonk_api() { || value.unwrap().map(|v| v.2), )?; - region.assign_fixed(|| "a", self.config.sa, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "b", self.config.sb, 0, || Value::known(FF::ONE))?; - region.assign_fixed(|| "c", self.config.sc, 0, || Value::known(FF::ONE))?; - region.assign_fixed( - || "a * b", - self.config.sm, - 0, - || Value::known(FF::ZERO), - )?; + region.assign_fixed(|| "a", self.config.sa, 0, || Value::::ONE)?; + region.assign_fixed(|| "b", self.config.sb, 0, || Value::::ONE)?; + region.assign_fixed(|| "c", self.config.sc, 0, || Value::::ONE)?; + region.assign_fixed(|| "a * b", self.config.sm, 0, || Value::::ZERO)?; Ok((lhs.cell(), rhs.cell(), out.cell())) }, ) @@ -227,12 +222,7 @@ fn plonk_api() { || "public_input", |mut region| { let value = region.assign_advice(|| "value", self.config.a, 0, &mut f)?; - region.assign_fixed( - || "public", - self.config.sp, - 0, - || Value::known(FF::ONE), - )?; + region.assign_fixed(|| "public", self.config.sp, 0, || Value::::ONE)?; Ok(value.cell()) },