use halo2::{ circuit::{Cell, Layouter, Region}, plonk::{Advice, Column, Error, Permutation}, }; use pasta_curves::arithmetic::FieldExt; pub(crate) mod cond_swap; pub(crate) mod enable_flag; pub(crate) mod lookup_range_check; pub(crate) mod plonk; /// A variable representing a field element. #[derive(Copy, Clone, Debug)] pub struct CellValue { cell: Cell, value: Option, } pub trait Var: Copy + Clone + std::fmt::Debug { fn new(cell: Cell, value: Option) -> Self; fn cell(&self) -> Cell; fn value(&self) -> Option; } impl Var for CellValue { fn new(cell: Cell, value: Option) -> Self { Self { cell, value } } fn cell(&self) -> Cell { self.cell } fn value(&self) -> Option { self.value } } pub trait UtilitiesInstructions { type Var: Var; fn load_private( &self, mut layouter: impl Layouter, column: Column, value: Option, ) -> Result { layouter.assign_region( || "load private", |mut region| { let cell = region.assign_advice( || "load private", column, 0, || value.ok_or(Error::SynthesisError), )?; Ok(Var::new(cell, value)) }, ) } } /// Assigns a cell at a specific offset within the given region, constraining it /// to the same value as another cell (which may be in any region). /// /// Returns an error if either `column` or `copy` is not within `perm`. pub fn copy( region: &mut Region<'_, F>, annotation: A, column: Column, offset: usize, copy: &CellValue, perm: &Permutation, ) -> Result, Error> where A: Fn() -> AR, AR: Into, { let cell = region.assign_advice(annotation, column, offset, || { copy.value.ok_or(Error::SynthesisError) })?; region.constrain_equal(perm, cell, copy.cell)?; Ok(CellValue::new(cell, copy.value)) }