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 5a31333a..b7fecff1 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 @@ -4,7 +4,7 @@ use crate::{ circuit::gadget::utilities::{ bitrange_subset, copy, lookup_range_check::LookupRangeCheckConfig, CellValue, Var, }, - constants::{self, util::decompose_scalar_fixed, NUM_WINDOWS, T_P}, + constants::{self, util::decompose_scalar_fixed, T_P}, primitives::sinsemilla, }; use halo2::{ @@ -29,7 +29,7 @@ impl From<&EccConfig> for Config { let config = Self { base_field_fixed_mul: config.base_field_fixed_mul, base_field_fixed_canon: config.base_field_fixed_canon, - canon_advices: [config.advices[7], config.advices[8], config.advices[9]], + canon_advices: [config.advices[6], config.advices[7], config.advices[8]], lookup_config: config.lookup_config.clone(), super_config: config.into(), }; @@ -205,8 +205,8 @@ impl Config { scalar: CellValue, base: OrchardFixedBasesFull, ) -> Result { - let (result, scalar) = layouter.assign_region( - || "Base-field elem fixed-base mul", + let (scalar, acc, mul_b) = layouter.assign_region( + || "Base-field elem fixed-base mul (incomplete addition)", |mut region| { let offset = 0; @@ -221,40 +221,38 @@ impl Config { self.base_field_fixed_mul, )?; - // Increase offset by 1 because the running sum decomposition takes - // up 86 rows (1 more than the number of windows.) - let offset = offset + 1; - - // 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, - )?; - - #[cfg(test)] - // Check that the correct multiple is obtained. - { - use group::Curve; - - 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(); - - if let (Some(real_mul), Some(result)) = (real_mul, result) { - assert_eq!(real_mul.to_affine(), result); - } - } - - Ok((result, scalar)) + Ok((scalar, acc, mul_b)) }, )?; + // Add to the accumulator and return the final result as `[scalar]B`. + let result = layouter.assign_region( + || "Base-field elem fixed-base mul (complete addition)", + |mut region| { + self.super_config + .add_config + .assign_region(&mul_b, &acc, 0, &mut region) + }, + )?; + + #[cfg(test)] + // Check that the correct multiple is obtained. + { + use group::Curve; + + 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(); + + if let (Some(real_mul), Some(result)) = (real_mul, result) { + assert_eq!(real_mul.to_affine(), result); + } + } + // We want to enforce canonicity of a 255-bit base field element, α. // That is, we want to check that 0 ≤ α < p, where p is Pallas base // field modulus p = 2^254 + t_p 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 b9003311..821a4e4c 100644 --- a/src/circuit/gadget/ecc/chip/mul_fixed/full_width.rs +++ b/src/circuit/gadget/ecc/chip/mul_fixed/full_width.rs @@ -18,47 +18,49 @@ impl Config { scalar: &EccScalarFixed, base: OrchardFixedBasesFull, ) -> Result { - layouter.assign_region( - || "Full-width fixed-base mul", + let (acc, mul_b) = layouter.assign_region( + || "Full-width fixed-base mul (incomplete addition)", |mut region| { let offset = 0; // Copy the scalar decomposition self.0.copy_scalar(&mut region, offset, &scalar.into())?; - let (acc, mul_b) = self.0.assign_region_inner( + self.0.assign_region_inner( &mut region, offset, &scalar.into(), base.into(), self.0.q_mul_fixed, - )?; - - // 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, - )?; - - #[cfg(test)] - // Check that the correct multiple is obtained. - { - use group::Curve; - - let base: super::OrchardFixedBases = base.into(); - let real_mul = scalar.value.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) + ) }, - ) + )?; + + // Add to the accumulator and return the final result as `[scalar]B`. + let result = layouter.assign_region( + || "Full-width fixed-base mul (last window, complete addition)", + |mut region| { + self.0 + .add_config + .assign_region(&mul_b, &acc, 0, &mut region) + }, + )?; + + #[cfg(test)] + // Check that the correct multiple is obtained. + { + use group::Curve; + + let base: super::OrchardFixedBases = base.into(); + let real_mul = scalar.value.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) } } diff --git a/src/circuit/gadget/ecc/chip/mul_fixed/short.rs b/src/circuit/gadget/ecc/chip/mul_fixed/short.rs index 697d765b..91f43f27 100644 --- a/src/circuit/gadget/ecc/chip/mul_fixed/short.rs +++ b/src/circuit/gadget/ecc/chip/mul_fixed/short.rs @@ -57,8 +57,8 @@ impl Config { scalar: &EccScalarFixedShort, base: &ValueCommitV, ) -> Result { - layouter.assign_region( - || "Short fixed-base mul", + let (acc, mul_b) = layouter.assign_region( + || "Short fixed-base mul (incomplete addition)", |mut region| { let offset = 0; @@ -66,19 +66,25 @@ impl Config { self.super_config .copy_scalar(&mut region, offset, &scalar.into())?; - let (acc, mul_b) = self.super_config.assign_region_inner( + self.super_config.assign_region_inner( &mut region, offset, &scalar.into(), base.clone().into(), self.super_config.q_mul_fixed, - )?; + ) + }, + )?; + let result = layouter.assign_region( + || "Short fixed-base mul (most significant word)", + |mut region| { + let offset = 0; // 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, + offset, &mut region, )?; @@ -90,7 +96,7 @@ impl Config { &mut region, || "sign", self.super_config.window, - offset + NUM_WINDOWS, + offset, &scalar.sign, &self.super_config.perm, )?; @@ -107,54 +113,52 @@ impl Config { }; // Enable mul_fixed_short selector on final row - self.q_mul_fixed_short - .enable(&mut region, offset + NUM_WINDOWS)?; + self.q_mul_fixed_short.enable(&mut region, offset)?; // 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, + offset, || y_val.ok_or(Error::SynthesisError), )?; - let result = EccPoint { + Ok(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) + }) }, - ) + )?; + + #[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) } }