From 4d8ae89aa9331c3f0d24e183951b725bf03ab4b0 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Thu, 3 Jun 2021 09:41:03 +0800 Subject: [PATCH] Add Utilities chip --- src/circuit/gadget.rs | 1 + src/circuit/gadget/utilities.rs | 78 +++++++++++++++++++++++++++++++++ 2 files changed, 79 insertions(+) create mode 100644 src/circuit/gadget/utilities.rs diff --git a/src/circuit/gadget.rs b/src/circuit/gadget.rs index 7d6426a7..20572cd7 100644 --- a/src/circuit/gadget.rs +++ b/src/circuit/gadget.rs @@ -1,2 +1,3 @@ pub(crate) mod ecc; pub(crate) mod poseidon; +pub(crate) mod utilities; diff --git a/src/circuit/gadget/utilities.rs b/src/circuit/gadget/utilities.rs new file mode 100644 index 00000000..fe8d6925 --- /dev/null +++ b/src/circuit/gadget/utilities.rs @@ -0,0 +1,78 @@ +use halo2::{ + circuit::{Cell, Chip, Layouter, Region}, + plonk::{Advice, Column, Error, Permutation}, +}; +use pasta_curves::arithmetic::FieldExt; + +/// A variable representing a number. +#[derive(Copy, Clone, Debug)] +pub struct CellValue { + cell: Cell, + value: Option, +} + +pub trait Var { + 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: Chip { + 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)) + }, + ) + } +} + +/// Assign a cell the same value as another cell and set up a copy constraint between them. +pub fn copy( + region: &mut Region<'_, F>, + annotation: A, + column: Column, + row: usize, + copy: &CellValue, + perm: &Permutation, +) -> Result, Error> +where + A: Fn() -> AR, + AR: Into, +{ + let cell = region.assign_advice(annotation, column, row, || { + copy.value.ok_or(Error::SynthesisError) + })?; + + region.constrain_equal(perm, cell, copy.cell)?; + + Ok(CellValue::new(cell, copy.value)) +}