diff --git a/src/circuit/gadget/ecc/chip.rs b/src/circuit/gadget/ecc/chip.rs index 07d4769d..7d9f082b 100644 --- a/src/circuit/gadget/ecc/chip.rs +++ b/src/circuit/gadget/ecc/chip.rs @@ -449,9 +449,10 @@ impl EccInstructions for EccChip { ) -> Result { let config: mul_fixed::full_width::Config<{ constants::NUM_WINDOWS }> = self.config().into(); - layouter.assign_region( - || format!("fixed-base mul of {:?}", base), - |mut region| config.assign_region(scalar, *base, 0, &mut region), + config.assign( + layouter.namespace(|| format!("fixed-base mul of {:?}", base)), + scalar, + *base, ) } @@ -463,9 +464,10 @@ impl EccInstructions for EccChip { ) -> Result { let config: mul_fixed::short::Config<{ constants::NUM_WINDOWS_SHORT }> = self.config().into(); - layouter.assign_region( - || format!("short fixed-base mul of {:?}", base), - |mut region| config.assign_region(scalar, base, 0, &mut region), + config.assign( + layouter.namespace(|| format!("short fixed-base mul of {:?}", base)), + scalar, + base, ) } @@ -476,9 +478,10 @@ impl EccInstructions for EccChip { base: &Self::FixedPoints, ) -> Result { let config: mul_fixed::base_field_elem::Config = self.config().into(); - layouter.assign_region( - || format!("base field elem fixed-base mul of {:?}", base), - |mut region| config.assign_region(base_field_elem, *base, 0, &mut region), + config.assign( + layouter.namespace(|| format!("base-field elem fixed-base mul of {:?}", base)), + base_field_elem, + *base, ) } } diff --git a/src/circuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs b/src/circuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs index de643a05..219a2be1 100644 --- a/src/circuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs +++ b/src/circuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs @@ -5,7 +5,7 @@ use crate::{ constants::{self, util::decompose_scalar_fixed, NUM_WINDOWS}, }; use halo2::{ - circuit::Region, + circuit::{Layouter, Region}, plonk::{Column, ConstraintSystem, Error, Expression, Fixed}, poly::Rotation, }; @@ -99,55 +99,61 @@ impl Config { }); } - pub fn assign_region( + pub fn assign( &self, + mut layouter: impl Layouter, scalar: CellValue, base: OrchardFixedBasesFull, - offset: usize, - region: &mut Region<'_, pallas::Base>, ) -> Result { - // Decompose scalar - let scalar = self.decompose_base_field_elem(scalar, offset, region)?; + layouter.assign_region( + || "Base-field elem fixed-base mul", + |mut region| { + let offset = 0; - let (acc, mul_b) = self.super_config.assign_region_inner( - region, - offset, - &(&scalar).into(), - base.into(), - self.base_field_fixed, - )?; + // Decompose scalar + let scalar = self.decompose_base_field_elem(scalar, offset, &mut region)?; - // Increase offset by 1 because the running sum decomposition takes - // up 86 rows (1 more than the number of windows.) - let offset = offset + 1; + let (acc, mul_b) = self.super_config.assign_region_inner( + &mut region, + offset, + &(&scalar).into(), + base.into(), + self.base_field_fixed, + )?; - // Add to the accumulator and return the final result as `[scalar]B`. - let result = self.super_config.add_config.assign_region( - &mul_b, - &acc, - offset + NUM_WINDOWS, - region, - )?; + // Increase offset by 1 because the running sum decomposition takes + // up 86 rows (1 more than the number of windows.) + let offset = offset + 1; - #[cfg(test)] - // Check that the correct multiple is obtained. - { - use group::Curve; + // Add to the accumulator and return the final result as `[scalar]B`. + let result = self.super_config.add_config.assign_region( + &mul_b, + &acc, + offset + NUM_WINDOWS, + &mut region, + )?; - let base: super::OrchardFixedBases = base.into(); - let scalar = &scalar - .base_field_elem() - .value() - .map(|scalar| pallas::Scalar::from_bytes(&scalar.to_bytes()).unwrap()); - let real_mul = scalar.map(|scalar| base.generator() * scalar); - let result = result.point(); + #[cfg(test)] + // Check that the correct multiple is obtained. + { + use group::Curve; - if let (Some(real_mul), Some(result)) = (real_mul, result) { - assert_eq!(real_mul.to_affine(), result); - } - } + let base: super::OrchardFixedBases = base.into(); + let scalar = &scalar + .base_field_elem() + .value() + .map(|scalar| pallas::Scalar::from_bytes(&scalar.to_bytes()).unwrap()); + let real_mul = scalar.map(|scalar| base.generator() * scalar); + let result = result.point(); - Ok(result) + if let (Some(real_mul), Some(result)) = (real_mul, result) { + assert_eq!(real_mul.to_affine(), result); + } + } + + Ok(result) + }, + ) } fn decompose_base_field_elem( diff --git a/src/circuit/gadget/ecc/chip/mul_fixed/full_width.rs b/src/circuit/gadget/ecc/chip/mul_fixed/full_width.rs index 87bdb493..ef68ae9f 100644 --- a/src/circuit/gadget/ecc/chip/mul_fixed/full_width.rs +++ b/src/circuit/gadget/ecc/chip/mul_fixed/full_width.rs @@ -1,6 +1,6 @@ use super::super::{EccConfig, EccPoint, EccScalarFixed, OrchardFixedBasesFull}; -use halo2::{circuit::Region, plonk::Error}; +use halo2::{circuit::Layouter, plonk::Error}; use pasta_curves::pallas; pub struct Config(super::Config); @@ -12,45 +12,53 @@ impl From<&EccConfig> for Config { } impl Config { - pub fn assign_region( + pub fn assign( &self, + mut layouter: impl Layouter, scalar: &EccScalarFixed, base: OrchardFixedBasesFull, - offset: usize, - region: &mut Region<'_, pallas::Base>, ) -> Result { - // Copy the scalar decomposition - self.0.copy_scalar(region, offset, &scalar.into())?; + layouter.assign_region( + || "Full-width fixed-base mul", + |mut region| { + let offset = 0; - let (acc, mul_b) = self.0.assign_region_inner( - region, - offset, - &scalar.into(), - base.into(), - self.0.mul_fixed, - )?; + // Copy the scalar decomposition + self.0.copy_scalar(&mut region, offset, &scalar.into())?; - // Add to the accumulator and return the final result as `[scalar]B`. - let result = self - .0 - .add_config - .assign_region(&mul_b, &acc, offset + NUM_WINDOWS, region)?; + let (acc, mul_b) = self.0.assign_region_inner( + &mut region, + offset, + &scalar.into(), + base.into(), + self.0.mul_fixed, + )?; - #[cfg(test)] - // Check that the correct multiple is obtained. - { - use group::Curve; + // Add to the accumulator and return the final result as `[scalar]B`. + let result = self.0.add_config.assign_region( + &mul_b, + &acc, + offset + NUM_WINDOWS, + &mut region, + )?; - let base: super::OrchardFixedBases = base.into(); - let real_mul = scalar.value.map(|scalar| base.generator() * scalar); - let result = result.point(); + #[cfg(test)] + // Check that the correct multiple is obtained. + { + use group::Curve; - if let (Some(real_mul), Some(result)) = (real_mul, result) { - assert_eq!(real_mul.to_affine(), result); - } - } + let base: super::OrchardFixedBases = base.into(); + let real_mul = scalar.value.map(|scalar| base.generator() * scalar); + let result = result.point(); - Ok(result) + if let (Some(real_mul), Some(result)) = (real_mul, result) { + assert_eq!(real_mul.to_affine(), result); + } + } + + Ok(result) + }, + ) } } diff --git a/src/circuit/gadget/ecc/chip/mul_fixed/short.rs b/src/circuit/gadget/ecc/chip/mul_fixed/short.rs index bb244851..cc2f2d91 100644 --- a/src/circuit/gadget/ecc/chip/mul_fixed/short.rs +++ b/src/circuit/gadget/ecc/chip/mul_fixed/short.rs @@ -4,7 +4,7 @@ use super::super::{copy, CellValue, EccConfig, EccPoint, EccScalarFixedShort, Va use crate::constants::ValueCommitV; use halo2::{ - circuit::Region, + circuit::Layouter, plonk::{ConstraintSystem, Error, Selector}, poly::Rotation, }; @@ -51,103 +51,110 @@ impl Config { }); } - pub fn assign_region( + pub fn assign( &self, + mut layouter: impl Layouter, scalar: &EccScalarFixedShort, base: &ValueCommitV, - offset: usize, - region: &mut Region<'_, pallas::Base>, ) -> Result { - // Copy the scalar decomposition - self.super_config - .copy_scalar(region, offset, &scalar.into())?; + layouter.assign_region( + || "Short fixed-base mul", + |mut region| { + let offset = 0; - let (acc, mul_b) = self.super_config.assign_region_inner( - region, - offset, - &scalar.into(), - base.clone().into(), - self.super_config.mul_fixed, - )?; + // Copy the scalar decomposition + self.super_config + .copy_scalar(&mut region, offset, &scalar.into())?; - // Add to the cumulative sum to get `[magnitude]B`. - let magnitude_mul = self.super_config.add_config.assign_region( - &mul_b, - &acc, - offset + NUM_WINDOWS, - region, - )?; + let (acc, mul_b) = self.super_config.assign_region_inner( + &mut region, + offset, + &scalar.into(), + base.clone().into(), + self.super_config.mul_fixed, + )?; - // Increase offset by 1 after complete addition - let offset = offset + 1; + // Add to the cumulative sum to get `[magnitude]B`. + let magnitude_mul = self.super_config.add_config.assign_region( + &mul_b, + &acc, + offset + NUM_WINDOWS, + &mut region, + )?; - // Assign sign to `window` column - let sign = copy( - region, - || "sign", - self.super_config.window, - offset + NUM_WINDOWS, - &scalar.sign, - &self.super_config.perm, - )?; + // Increase offset by 1 after complete addition + let offset = offset + 1; - // Conditionally negate `y`-coordinate - let y_val = if let Some(sign) = sign.value() { - if sign == -pallas::Base::one() { - magnitude_mul.y.value().map(|y: pallas::Base| -y) - } else { - magnitude_mul.y.value() - } - } else { - None - }; + // Assign sign to `window` column + let sign = copy( + &mut region, + || "sign", + self.super_config.window, + offset + NUM_WINDOWS, + &scalar.sign, + &self.super_config.perm, + )?; - // Enable mul_fixed_short selector on final row - self.q_mul_fixed_short - .enable(region, offset + NUM_WINDOWS)?; - - // Assign final `y` to `y_p` column and return final point - let y_var = region.assign_advice( - || "y_var", - self.super_config.y_p, - offset + NUM_WINDOWS, - || y_val.ok_or(Error::SynthesisError), - )?; - - let result = EccPoint { - x: magnitude_mul.x, - y: CellValue::new(y_var, y_val), - }; - - #[cfg(test)] - // Check that the correct multiple is obtained. - { - use group::Curve; - - let base: super::OrchardFixedBases = base.clone().into(); - - let scalar = scalar - .magnitude - .zip(scalar.sign.value()) - .map(|(magnitude, sign)| { - let sign = if sign == pallas::Base::one() { - pallas::Scalar::one() - } else if sign == -pallas::Base::one() { - -pallas::Scalar::one() + // Conditionally negate `y`-coordinate + let y_val = if let Some(sign) = sign.value() { + if sign == -pallas::Base::one() { + magnitude_mul.y.value().map(|y: pallas::Base| -y) } else { - panic!("Sign should be 1 or -1.") - }; - magnitude * sign - }); - let real_mul = scalar.map(|scalar| base.generator() * scalar); - let result = result.point(); + magnitude_mul.y.value() + } + } else { + None + }; - if let (Some(real_mul), Some(result)) = (real_mul, result) { - assert_eq!(real_mul.to_affine(), result); - } - } + // Enable mul_fixed_short selector on final row + self.q_mul_fixed_short + .enable(&mut region, offset + NUM_WINDOWS)?; - Ok(result) + // Assign final `y` to `y_p` column and return final point + let y_var = region.assign_advice( + || "y_var", + self.super_config.y_p, + offset + NUM_WINDOWS, + || y_val.ok_or(Error::SynthesisError), + )?; + + let result = EccPoint { + x: magnitude_mul.x, + y: CellValue::new(y_var, y_val), + }; + + #[cfg(test)] + // Check that the correct multiple is obtained. + { + use group::Curve; + + let base: super::OrchardFixedBases = base.clone().into(); + + let scalar = + scalar + .magnitude + .zip(scalar.sign.value()) + .map(|(magnitude, sign)| { + let sign = if sign == pallas::Base::one() { + pallas::Scalar::one() + } else if sign == -pallas::Base::one() { + -pallas::Scalar::one() + } else { + panic!("Sign should be 1 or -1.") + }; + magnitude * sign + }); + let real_mul = scalar.map(|scalar| base.generator() * scalar); + let result = result.point(); + + if let (Some(real_mul), Some(result)) = (real_mul, result) { + assert_eq!(real_mul.to_affine(), result); + } + } + + Ok(result) + }, + ) } }