From 3840f280d7b59ca985a25564f93f55b479db0003 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Thu, 24 Jun 2021 18:23:01 +0800 Subject: [PATCH 1/3] lookup_range_check.rs: Add short range check lookup. Also introduce a "strict" mode for the full-length lookup, where "true" requires the field element to be within num_words * K bits, whereas "false" does not. --- .../gadget/utilities/lookup_range_check.rs | 528 ++++++++++++++---- 1 file changed, 420 insertions(+), 108 deletions(-) diff --git a/src/circuit/gadget/utilities/lookup_range_check.rs b/src/circuit/gadget/utilities/lookup_range_check.rs index 65ad500b..e0aae7d7 100644 --- a/src/circuit/gadget/utilities/lookup_range_check.rs +++ b/src/circuit/gadget/utilities/lookup_range_check.rs @@ -3,8 +3,8 @@ use crate::spec::lebs2ip; use halo2::{ - circuit::Region, - plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation}, + circuit::{Layouter, Region}, + plonk::{Advice, Column, ConstraintSystem, Error, Fixed, Permutation, Selector}, poly::Rotation, }; use std::{convert::TryInto, marker::PhantomData}; @@ -13,19 +13,19 @@ use ff::PrimeFieldBits; use super::*; -#[derive(Debug, Clone)] +#[derive(Eq, PartialEq, Debug, Clone)] pub struct LookupRangeCheckConfig { - q_lookup: Column, - running_sum: Column, + pub q_lookup: Selector, + pub q_lookup_short: Selector, + pub short_lookup_bitshift: Column, + pub running_sum: Column, + constants: Column, table_idx: Column, perm: Permutation, _marker: PhantomData, } impl LookupRangeCheckConfig { - /// The `q_lookup` column toggles the lookup on or off. It MUST be assigned - /// outside of this helper at the appropriate offsets. - /// /// The `running_sum` advice column breaks the field element into `K`-bit /// words. It is used to construct the input expression to the lookup /// argument. @@ -35,21 +35,28 @@ impl LookupRangeCheckConfig /// can be loaded outside this helper. pub fn configure( meta: &mut ConstraintSystem, - q_lookup: Column, running_sum: Column, + constants: Column, table_idx: Column, perm: Permutation, ) -> Self { + let q_lookup = meta.selector(); + let q_lookup_short = meta.selector(); + let short_lookup_bitshift = meta.fixed_column(); let config = LookupRangeCheckConfig { q_lookup, + q_lookup_short, + short_lookup_bitshift, running_sum, + constants, table_idx, perm, _marker: PhantomData, }; + // Lookup for range checks K bits and above. meta.lookup(|meta| { - let q_lookup = meta.query_fixed(config.q_lookup, Rotation::cur()); + let q_lookup = meta.query_selector(config.q_lookup); let z_cur = meta.query_advice(config.running_sum, Rotation::cur()); let z_next = meta.query_advice(config.running_sum, Rotation::next()); // z_i = 2^{K}⋅z_{i + 1} + a_i @@ -60,6 +67,28 @@ impl LookupRangeCheckConfig vec![(q_lookup * word, table)] }); + // Lookup for range checks up to S bits, where S < K. + meta.lookup(|meta| { + let q_lookup_short = meta.query_selector(config.q_lookup_short); + let word = meta.query_advice(config.running_sum, Rotation::cur()); + let table = meta.query_fixed(config.table_idx, Rotation::cur()); + + vec![(q_lookup_short * word, table)] + }); + + // For short lookups, check that the word has been shifted by the correct number of bits. + meta.create_gate("Short lookup bitshift", |meta| { + let inv_two_pow_s = meta.query_fixed(config.short_lookup_bitshift, Rotation::cur()); + let word = meta.query_advice(config.running_sum, Rotation::prev()); + let shifted_word = meta.query_advice(config.running_sum, Rotation::cur()); + + let two_pow_k = F::from_u64(1 << K); + + // shifted_word = word * 2^{K-s} + // = word * 2^K * inv_two_pow_s + vec![inv_two_pow_s.clone() * (word * two_pow_k * inv_two_pow_s - shifted_word)] + }); + config } @@ -67,7 +96,7 @@ impl LookupRangeCheckConfig // Loads the values [0..2^K) into `table_idx`. This is only used in testing // for now, since the Sinsemilla chip provides a pre-loaded table in the // Orchard context. - fn load(&self, layouter: &mut impl Layouter) -> Result<(), Error> { + pub fn load(&self, layouter: &mut impl Layouter) -> Result<(), Error> { layouter.assign_region( || "table_idx", |mut gate| { @@ -85,19 +114,73 @@ impl LookupRangeCheckConfig ) } - /// Only the lower `num_words * K` bits of the field element are constrained - /// by this function. If the field element does not fit into this range, then - /// the final cumulative sum `z_{num_words}` will be nonzero. - // - /// It is up to the caller to constrain `z_{num_words}` == 0` outside this - /// helper, or otherwise constrain upper bits not covered within the - /// `num_words * K` range. - pub fn lookup_range_check( + /// Range check on an existing cell that is copied into this helper. + pub fn copy_check( &self, - region: &mut Region<'_, F>, - offset: usize, + mut layouter: impl Layouter, element: CellValue, num_words: usize, + strict: bool, + ) -> Result>, Error> { + layouter.assign_region( + || format!("{:?} words range check", num_words), + |mut region| { + // Copy `element` and initialize running sum `z_0 = element` to decompose it. + let z_0 = copy( + &mut region, + || "z_0", + self.running_sum, + 0, + &element, + &self.perm, + )?; + + self.range_check(&mut region, z_0, num_words, strict) + }, + ) + } + + /// Range check on a value that is witnessed in this helper. + pub fn witness_check( + &self, + mut layouter: impl Layouter, + value: Option, + num_words: usize, + strict: bool, + ) -> Result<(CellValue, Vec>), Error> { + layouter.assign_region( + || "Witness element", + |mut region| { + let z_0 = { + let cell = region.assign_advice( + || "Witness element", + self.running_sum, + 0, + || value.ok_or(Error::SynthesisError), + )?; + CellValue::new(cell, value) + }; + + let zs = self.range_check(&mut region, z_0, num_words, strict)?; + + Ok((z_0, zs)) + }, + ) + } + + /// If `strict` is set to "true", the field element must fit into + /// `num_words * K` bits. In other words, the the final cumulative sum `z_{num_words}` + /// must be zero. + /// + /// If `strict` is set to "false", the final `z_{num_words}` is not constrained. + /// + /// `element` must have been assigned to `self.running_sum` at offset 0. + fn range_check( + &self, + region: &mut Region<'_, F>, + element: CellValue, + num_words: usize, + strict: bool, ) -> Result>, Error> { // `num_words` must fit into a single field element. assert!(num_words * K <= F::CAPACITY as usize); @@ -126,17 +209,7 @@ impl LookupRangeCheckConfig } }; - // Copy `element` and initialize running sum `z_0 = element` to decompose it. - let z_0 = copy( - region, - || "z_0", - self.running_sum, - offset, - &element, - &self.perm, - )?; - - let mut zs = vec![z_0]; + let mut zs = vec![element]; // Assign cumulative sum such that // z_i = 2^{K}⋅z_{i + 1} + a_i @@ -144,21 +217,24 @@ impl LookupRangeCheckConfig // // For `element` = a_0 + 2^10 a_1 + ... + 2^{120} a_{12}}, initialize z_0 = `element`. // If `element` fits in 130 bits, we end up with z_{13} = 0. - let mut z = z_0; + let mut z = element; let inv_two_pow_k = F::from_u64(1u64 << K).invert().unwrap(); - for (idx, word) in words.into_iter().enumerate() { + for (idx, word) in words.iter().enumerate() { + // Enable lookup on this row + self.q_lookup.enable(region, idx)?; + // z_next = (z_cur - m_cur) / 2^K z = { let z_val = z .value() - .zip(word) + .zip(*word) .map(|(z, word)| (z - word) * inv_two_pow_k); // Assign z_next let z_cell = region.assign_advice( || format!("z_{:?}", idx + 1), self.running_sum, - offset + idx + 1, + idx + 1, || z_val.ok_or(Error::SynthesisError), )?; @@ -167,21 +243,136 @@ impl LookupRangeCheckConfig zs.push(z); } + if strict { + // Constrain the final `z` to be zero. + let cell = + region.assign_fixed(|| "zero", self.constants, words.len(), || Ok(F::zero()))?; + region.constrain_equal(&self.perm, z.cell(), cell)?; + } + Ok(zs) } + + /// Short range check on an existing cell that is copied into this helper. + /// + /// # Panics + /// + /// Panics if NUM_BITS is equal to or larger than K. + pub fn copy_short_check( + &self, + mut layouter: impl Layouter, + element: CellValue, + num_bits: usize, + ) -> Result<(), Error> { + assert!(num_bits < K); + layouter.assign_region( + || format!("Range check {:?} bits", num_bits), + |mut region| { + // Copy `element` to use in the k-bit lookup. + let element = copy( + &mut region, + || "element", + self.running_sum, + 0, + &element, + &self.perm, + )?; + + self.short_range_check(&mut region, element, num_bits) + }, + ) + } + + /// Short range check on value that is witnessed in this helper. + /// + /// # Panics + /// + /// Panics if num_bits is larger than K. + pub fn witness_short_check( + &self, + mut layouter: impl Layouter, + element: Option, + num_bits: usize, + ) -> Result, Error> { + assert!(num_bits <= K); + layouter.assign_region( + || format!("Range check {:?} bits", num_bits), + |mut region| { + // Witness `element` to use in the k-bit lookup. + let element = { + let cell = region.assign_advice( + || "Witness element", + self.running_sum, + 0, + || element.ok_or(Error::SynthesisError), + )?; + CellValue::new(cell, element) + }; + + self.short_range_check(&mut region, element, num_bits)?; + + Ok(element) + }, + ) + } + + /// Constrain `x` to be a NUM_BITS word. + /// + /// `element` must have been assigned to `self.running_sum` at offset 0. + fn short_range_check( + &self, + region: &mut Region<'_, F>, + element: CellValue, + num_bits: usize, + ) -> Result<(), Error> { + // Enable lookup for `element`, to constrain it to 10 bits. + self.q_lookup_short.enable(region, 0)?; + + // Assign 2^{-num_bits} in a fixed column. + { + // 2^{-num_bits} + let inv_two_pow_s = F::from_u64(1 << num_bits).invert().unwrap(); + region.assign_fixed( + || format!("2^(-{})", num_bits), + self.short_lookup_bitshift, + 1, + || Ok(inv_two_pow_s), + )?; + } + + // Assign shifted `element * 2^{K - num_bits}` + let shifted = element.value().map(|element| { + let shift = F::from_u64(1 << (K - num_bits)); + element * shift + }); + print!("element: {:?}", element.value()); + print!("shifted: {:?}", shifted); + + region.assign_advice( + || format!("element * 2^({}-{})", K, num_bits), + self.running_sum, + 1, + || shifted.ok_or(Error::SynthesisError), + )?; + + // Enable lookup for shifted element, to constrain it to 10 bits. + self.q_lookup_short.enable(region, 1)?; + + Ok(()) + } } #[cfg(test)] mod tests { - use super::super::{CellValue, UtilitiesInstructions, Var}; + use super::super::Var; use super::LookupRangeCheckConfig; use crate::primitives::sinsemilla::{INV_TWO_POW_K, K}; use crate::spec::lebs2ip; - use ff::PrimeFieldBits; + use ff::{Field, PrimeFieldBits}; use halo2::{ circuit::{layouter::SingleChipLayouter, Layouter}, - dev::MockProver, + dev::{MockProver, VerifyFailure}, plonk::{Assignment, Circuit, ConstraintSystem, Error}, }; use pasta_curves::{arithmetic::FieldExt, pallas}; @@ -191,27 +382,23 @@ mod tests { #[test] fn lookup_range_check() { struct MyCircuit { + num_words: usize, _marker: PhantomData, } - impl UtilitiesInstructions for MyCircuit { - type Var = CellValue; - } - impl Circuit for MyCircuit { type Config = LookupRangeCheckConfig; fn configure(meta: &mut ConstraintSystem) -> Self::Config { let running_sum = meta.advice_column(); + let constants = meta.fixed_column(); let table_idx = meta.fixed_column(); - let q_lookup = meta.fixed_column(); - - let perm = meta.permutation(&[running_sum.into()]); + let perm = meta.permutation(&[running_sum.into(), constants.into()]); LookupRangeCheckConfig::::configure( meta, - q_lookup, running_sum, + constants, table_idx, perm, ) @@ -227,45 +414,51 @@ mod tests { // Load table_idx config.load(&mut layouter)?; - let num_words = 6; + // Lookup constraining element to be no longer than num_words * K bits. let elements_and_expected_final_zs = [ - (F::from_u64((1 << (num_words * K)) - 1), F::zero()), // a word that is within num_words * K bits long - (F::from_u64(1 << (num_words * K)), F::one()), // a word that is just over num_words * K bits long + ( + F::from_u64((1 << (self.num_words * K)) - 1), + F::zero(), + true, + ), // a word that is within self.num_words * K bits long + (F::from_u64(1 << (self.num_words * K)), F::one(), false), // a word that is just over self.num_words * K bits long ]; - for (element, expected_final_z) in elements_and_expected_final_zs.iter() { - let expected_zs = expected_zs::(*element, num_words); + fn expected_zs( + element: F, + num_words: usize, + ) -> Vec { + let chunks = { + element + .to_le_bits() + .iter() + .by_val() + .take(num_words * K) + .collect::>() + .chunks_exact(K) + .map(|chunk| F::from_u64(lebs2ip::(chunk.try_into().unwrap()))) + .collect::>() + }; + let expected_zs = { + let inv_two_pow_k = F::from_bytes(&INV_TWO_POW_K).unwrap(); + chunks.iter().fold(vec![element], |mut zs, a_i| { + // z_{i + 1} = (z_i - a_i) / 2^{K} + let z = (zs[zs.len() - 1] - a_i) * inv_two_pow_k; + zs.push(z); + zs + }) + }; + expected_zs + } - // Load the value to be decomposed into the circuit. - let element = self.load_private( - layouter.namespace(|| "element"), - config.running_sum, + for (element, expected_final_z, strict) in elements_and_expected_final_zs.iter() { + let expected_zs = expected_zs::(*element, self.num_words); + + let (_, zs) = config.witness_check( + layouter.namespace(|| format!("Lookup {:?}", self.num_words)), Some(*element), - )?; - - // Although this fixed column assignment can be done - // within the `lookup_range_check` method, in practice - // the information needed to toggle the lookup depends - // on some external business logic (e.g. whether the - // top bit of `element` is set). - // - // Leaving the toggle assignment to the caller gives - // them the freedom to define this business logic. - let zs = layouter.assign_region( - || "word within range", - |mut region| { - for idx in 0..num_words { - // Assign fixed column to activate lookup. - region.assign_fixed( - || format!("lookup on row {}", idx), - config.q_lookup, - idx, - || Ok(F::one()), - )?; - } - - config.lookup_range_check(&mut region, 0, element, num_words) - }, + self.num_words, + *strict, )?; assert_eq!(*expected_zs.last().unwrap(), *expected_final_z); @@ -276,13 +469,13 @@ mod tests { } } } - Ok(()) } } { let circuit: MyCircuit = MyCircuit { + num_words: 6, _marker: PhantomData, }; let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); @@ -290,31 +483,150 @@ mod tests { } } - #[cfg(test)] - fn expected_zs( - element: F, - num_words: usize, - ) -> Vec { - let chunks = { - element - .to_le_bits() - .iter() - .by_val() - .take(num_words * K) - .collect::>() - .chunks_exact(K) - .map(|chunk| F::from_u64(lebs2ip::(chunk.try_into().unwrap()))) - .collect::>() - }; - let expected_zs = { - let inv_two_pow_k = F::from_bytes(&INV_TWO_POW_K).unwrap(); - chunks.iter().fold(vec![element], |mut zs, a_i| { - // z_{i + 1} = (z_i - a_i) / 2^{K} - let z = (zs[zs.len() - 1] - a_i) * inv_two_pow_k; - zs.push(z); - zs - }) - }; - expected_zs + #[test] + fn short_range_check() { + struct MyCircuit { + element: Option, + num_bits: usize, + _marker: PhantomData, + } + + impl Circuit for MyCircuit { + type Config = LookupRangeCheckConfig; + + fn configure(meta: &mut ConstraintSystem) -> Self::Config { + let running_sum = meta.advice_column(); + let constants = meta.fixed_column(); + let table_idx = meta.fixed_column(); + let perm = meta.permutation(&[running_sum.into()]); + + LookupRangeCheckConfig::::configure( + meta, + running_sum, + constants, + table_idx, + perm, + ) + } + + fn synthesize( + &self, + cs: &mut impl Assignment, + config: Self::Config, + ) -> Result<(), Error> { + let mut layouter = SingleChipLayouter::new(cs)?; + + // Load table_idx + config.load(&mut layouter)?; + + // Lookup constraining element to be no longer than num_bits. + config.witness_short_check( + layouter.namespace(|| format!("Lookup {:?} bits", self.num_bits)), + self.element, + self.num_bits, + )?; + + Ok(()) + } + } + + // Edge case: zero bits + { + let circuit: MyCircuit = MyCircuit { + element: Some(pallas::Base::zero()), + num_bits: 0, + _marker: PhantomData, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + + // Edge case: K bits + { + let circuit: MyCircuit = MyCircuit { + element: Some(pallas::Base::from_u64((1 << K) - 1)), + num_bits: K, + _marker: PhantomData, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + + // Element within `num_bits` + { + let circuit: MyCircuit = MyCircuit { + element: Some(pallas::Base::from_u64((1 << 6) - 1)), + num_bits: 6, + _marker: PhantomData, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!(prover.verify(), Ok(())); + } + + // Element larger than `num_bits` but within K bits + { + let circuit: MyCircuit = MyCircuit { + element: Some(pallas::Base::from_u64(1 << 6)), + num_bits: 6, + _marker: PhantomData, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!( + prover.verify(), + Err(vec![VerifyFailure::Lookup { + lookup_index: 1, + row: 1 + }]) + ); + } + + // Element larger than K bits + { + let circuit: MyCircuit = MyCircuit { + element: Some(pallas::Base::from_u64(1 << K)), + num_bits: 6, + _marker: PhantomData, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!( + prover.verify(), + Err(vec![ + VerifyFailure::Lookup { + lookup_index: 1, + row: 0 + }, + VerifyFailure::Lookup { + lookup_index: 1, + row: 1 + }, + ]) + ); + } + + // Element which is not within `num_bits`, but which has a shifted value within + // num_bits + { + let num_bits = 6; + let shifted = pallas::Base::from_u64((1 << num_bits) - 1); + // Recall that shifted = element * 2^{K-s} + // => element = shifted * 2^{s-K} + let element = shifted + * pallas::Base::from_u64(1 << (K as u64 - num_bits)) + .invert() + .unwrap(); + let circuit: MyCircuit = MyCircuit { + element: Some(element), + num_bits: num_bits as usize, + _marker: PhantomData, + }; + let prover = MockProver::::run(11, &circuit, vec![]).unwrap(); + assert_eq!( + prover.verify(), + Err(vec![VerifyFailure::Lookup { + lookup_index: 1, + row: 0 + }]) + ); + } } } From c43c91b7965920f3f84c13a7c843b8e8953bf172 Mon Sep 17 00:00:00 2001 From: therealyingtong Date: Mon, 21 Jun 2021 23:16:56 +0800 Subject: [PATCH 2/3] gadget::utilities: Adjustments to utilities gadgets and helpers. --- src/circuit/gadget/utilities.rs | 12 ++++----- src/circuit/gadget/utilities/cond_swap.rs | 30 ++++++++++++++++------- 2 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/circuit/gadget/utilities.rs b/src/circuit/gadget/utilities.rs index d7d05a43..ce01eb22 100644 --- a/src/circuit/gadget/utilities.rs +++ b/src/circuit/gadget/utilities.rs @@ -4,19 +4,19 @@ use halo2::{ }; use pasta_curves::arithmetic::FieldExt; -mod cond_swap; -mod enable_flag; -mod lookup_range_check; -mod plonk; +pub(crate) mod cond_swap; +pub(crate) mod enable_flag; +pub(crate) mod lookup_range_check; +pub(crate) mod plonk; -/// A variable representing a number. +/// A variable representing a field element. #[derive(Copy, Clone, Debug)] pub struct CellValue { cell: Cell, value: Option, } -pub trait Var { +pub trait Var: Copy + Clone + std::fmt::Debug { fn new(cell: Cell, value: Option) -> Self; fn cell(&self) -> Cell; fn value(&self) -> Option; diff --git a/src/circuit/gadget/utilities/cond_swap.rs b/src/circuit/gadget/utilities/cond_swap.rs index 8c3e2f90..c8be9e2d 100644 --- a/src/circuit/gadget/utilities/cond_swap.rs +++ b/src/circuit/gadget/utilities/cond_swap.rs @@ -1,4 +1,4 @@ -use super::{copy, CellValue, UtilitiesInstructions}; +use super::{copy, CellValue, UtilitiesInstructions, Var}; use halo2::{ circuit::{Chip, Layouter}, plonk::{Advice, Column, ConstraintSystem, Error, Expression, Permutation, Selector}, @@ -11,10 +11,14 @@ pub trait CondSwapInstructions: UtilitiesInstructions { #[allow(clippy::type_complexity)] /// Given an input pair (a,b) and a `swap` boolean flag, returns /// (b,a) if `swap` is set, else (a,b) if `swap` is not set. + /// + /// + /// The second element of the pair is required to be a witnessed + /// value, not a variable that already exists in the circuit. fn swap( &self, layouter: impl Layouter, - pair: (Self::Var, Self::Var), + pair: (Self::Var, Option), swap: Option, ) -> Result<(Self::Var, Self::Var), Error>; } @@ -59,7 +63,7 @@ impl CondSwapInstructions for CondSwapChip { fn swap( &self, mut layouter: impl Layouter, - pair: (Self::Var, Self::Var), + pair: (Self::Var, Option), swap: Option, ) -> Result<(Self::Var, Self::Var), Error> { let config = self.config(); @@ -73,8 +77,16 @@ impl CondSwapInstructions for CondSwapChip { // Copy in `a` value let a = copy(&mut region, || "copy a", config.a, 0, &pair.0, &config.perm)?; - // Copy in `b` value - let b = copy(&mut region, || "copy b", config.b, 0, &pair.1, &config.perm)?; + // Witness `b` value + let b = { + let cell = region.assign_advice( + || "witness b", + config.b, + 0, + || pair.1.ok_or(Error::SynthesisError), + )?; + CellValue::new(cell, pair.1) + }; // Witness `swap` value let swap_val = swap.map(|swap| F::from_u64(swap as u64)); @@ -245,19 +257,19 @@ mod tests { // Load the pair and the swap flag into the circuit. let a = chip.load_private(layouter.namespace(|| "a"), config.a, self.a)?; - let b = chip.load_private(layouter.namespace(|| "b"), config.b, self.b)?; // Return the swapped pair. - let swapped_pair = chip.swap(layouter.namespace(|| "swap"), (a, b), self.swap)?; + let swapped_pair = + chip.swap(layouter.namespace(|| "swap"), (a, self.b), self.swap)?; if let Some(swap) = self.swap { if swap { // Check that `a` and `b` have been swapped - assert_eq!(swapped_pair.0.value.unwrap(), b.value.unwrap()); + assert_eq!(swapped_pair.0.value.unwrap(), self.b.unwrap()); assert_eq!(swapped_pair.1.value.unwrap(), a.value.unwrap()); } else { // Check that `a` and `b` have not been swapped assert_eq!(swapped_pair.0.value.unwrap(), a.value.unwrap()); - assert_eq!(swapped_pair.1.value.unwrap(), b.value.unwrap()); + assert_eq!(swapped_pair.1.value.unwrap(), self.b.unwrap()); } } From 209e6a1132f3aafed813c43c8f2ca60354333b40 Mon Sep 17 00:00:00 2001 From: ying tong Date: Tue, 29 Jun 2021 09:51:02 +0800 Subject: [PATCH 3/3] Docfixes. Co-authored-by: Daira Hopwood Co-authored-by: str4d --- src/circuit/gadget/utilities/cond_swap.rs | 1 - src/circuit/gadget/utilities/lookup_range_check.rs | 4 +--- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/src/circuit/gadget/utilities/cond_swap.rs b/src/circuit/gadget/utilities/cond_swap.rs index c8be9e2d..b8947a71 100644 --- a/src/circuit/gadget/utilities/cond_swap.rs +++ b/src/circuit/gadget/utilities/cond_swap.rs @@ -12,7 +12,6 @@ pub trait CondSwapInstructions: UtilitiesInstructions { /// Given an input pair (a,b) and a `swap` boolean flag, returns /// (b,a) if `swap` is set, else (a,b) if `swap` is not set. /// - /// /// The second element of the pair is required to be a witnessed /// value, not a variable that already exists in the circuit. fn swap( diff --git a/src/circuit/gadget/utilities/lookup_range_check.rs b/src/circuit/gadget/utilities/lookup_range_check.rs index e0aae7d7..6298e49a 100644 --- a/src/circuit/gadget/utilities/lookup_range_check.rs +++ b/src/circuit/gadget/utilities/lookup_range_check.rs @@ -67,7 +67,7 @@ impl LookupRangeCheckConfig vec![(q_lookup * word, table)] }); - // Lookup for range checks up to S bits, where S < K. + // Lookup used in range checks up to S bits, where S < K. meta.lookup(|meta| { let q_lookup_short = meta.query_selector(config.q_lookup_short); let word = meta.query_advice(config.running_sum, Rotation::cur()); @@ -345,8 +345,6 @@ impl LookupRangeCheckConfig let shift = F::from_u64(1 << (K - num_bits)); element * shift }); - print!("element: {:?}", element.value()); - print!("shifted: {:?}", shifted); region.assign_advice( || format!("element * 2^({}-{})", K, num_bits),