From 475f54daa4a15adb3920f5231d3d4a00c0ca7b45 Mon Sep 17 00:00:00 2001 From: Constance Beguier Date: Fri, 23 Jun 2023 10:31:10 +0200 Subject: [PATCH] Add Point::new_from_constant method (#17) It is now possible to create a Point from a constant. This functionality is required to evaluate the old nullifier. - for non split_notes, nf_old = Extract_P([PRF^{nfOrchard}_{nk}(rho_old) + psi_nf) mod q_P] NullifierK + cm_old) - for split notes, nf_old = Extract_P([PRF^{nfOrchard}_{nk}(rho_old) + psi_nf) mod q_P] NullifierK + cm_old + NullifierL) --- halo2_gadgets/src/ecc.rs | 19 +++++++++++ halo2_gadgets/src/ecc/chip.rs | 12 +++++++ halo2_gadgets/src/ecc/chip/witness_point.rs | 37 +++++++++++++++++++++ 3 files changed, 68 insertions(+) diff --git a/halo2_gadgets/src/ecc.rs b/halo2_gadgets/src/ecc.rs index 4bf58d3e..2e6e5091 100644 --- a/halo2_gadgets/src/ecc.rs +++ b/halo2_gadgets/src/ecc.rs @@ -60,6 +60,15 @@ pub trait EccInstructions: value: Value, ) -> Result; + /// Witnesses the given constant point as a private input to the circuit. + /// This allows the point to be the identity, mapped to (0, 0) in + /// affine coordinates. + fn witness_point_from_constant( + &self, + layouter: &mut impl Layouter, + value: C, + ) -> Result; + /// Witnesses the given point as a private input to the circuit. /// This returns an error if the point is the identity. fn witness_point_non_id( @@ -399,6 +408,16 @@ impl + Clone + Debug + Eq> Point, + value: C, + ) -> Result { + let point = chip.witness_point_from_constant(&mut layouter, value); + point.map(|inner| Point { chip, inner }) + } + /// Constrains this point to be equal in value to another point. pub fn constrain_equal> + Clone>( &self, diff --git a/halo2_gadgets/src/ecc/chip.rs b/halo2_gadgets/src/ecc/chip.rs index 0b6fa0d4..119b1670 100644 --- a/halo2_gadgets/src/ecc/chip.rs +++ b/halo2_gadgets/src/ecc/chip.rs @@ -453,6 +453,18 @@ where ) } + fn witness_point_from_constant( + &self, + layouter: &mut impl Layouter, + value: pallas::Affine, + ) -> Result { + let config = self.config().witness_point; + layouter.assign_region( + || "witness point (constant)", + |mut region| config.constant_point(value, 0, &mut region), + ) + } + fn witness_point_non_id( &self, layouter: &mut impl Layouter, diff --git a/halo2_gadgets/src/ecc/chip/witness_point.rs b/halo2_gadgets/src/ecc/chip/witness_point.rs index 7cba8d6f..28e8aaf4 100644 --- a/halo2_gadgets/src/ecc/chip/witness_point.rs +++ b/halo2_gadgets/src/ecc/chip/witness_point.rs @@ -102,6 +102,21 @@ impl Config { Ok((x_var, y_var)) } + fn assign_xy_constant( + &self, + value: (Assigned, Assigned), + offset: usize, + region: &mut Region<'_, pallas::Base>, + ) -> Result { + // Assign `x` value + let x_var = region.assign_advice_from_constant(|| "x", self.x, offset, value.0)?; + + // Assign `y` value + let y_var = region.assign_advice_from_constant(|| "y", self.y, offset, value.1)?; + + Ok((x_var, y_var)) + } + /// Assigns a point that can be the identity. pub(super) fn point( &self, @@ -126,6 +141,28 @@ impl Config { .map(|(x, y)| EccPoint::from_coordinates_unchecked(x, y)) } + /// Assigns a constant point that can be the identity. + pub(super) fn constant_point( + &self, + value: pallas::Affine, + offset: usize, + region: &mut Region<'_, pallas::Base>, + ) -> Result { + // Enable `q_point` selector + self.q_point.enable(region, offset)?; + + let value = if value == pallas::Affine::identity() { + // Map the identity to (0, 0). + (Assigned::Zero, Assigned::Zero) + } else { + let value = value.coordinates().unwrap(); + (value.x().into(), value.y().into()) + }; + + self.assign_xy_constant(value, offset, region) + .map(|(x, y)| EccPoint::from_coordinates_unchecked(x, y)) + } + /// Assigns a non-identity point. pub(super) fn point_non_id( &self,