Skip to content

Commit

Permalink
Add Point::new_from_constant method (#17)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
ConstanceBeguier committed Nov 23, 2023
1 parent 3600a0a commit 99d9d4c
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
19 changes: 19 additions & 0 deletions halo2_gadgets/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,15 @@ pub trait EccInstructions<C: CurveAffine>:
value: Value<C>,
) -> Result<Self::Point, Error>;

/// 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<C::Base>,
value: C,
) -> Result<Self::Point, Error>;

/// 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(
Expand Down Expand Up @@ -399,6 +408,16 @@ impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone + Debug + Eq> Point<C,
point.map(|inner| Point { chip, inner })
}

/// Constructs a new point with the given fixed value.
pub fn new_from_constant(
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: C,
) -> Result<Self, Error> {
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<Other: Into<Point<C, EccChip>> + Clone>(
&self,
Expand Down
12 changes: 12 additions & 0 deletions halo2_gadgets/src/ecc/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,18 @@ where
)
}

fn witness_point_from_constant(
&self,
layouter: &mut impl Layouter<pallas::Base>,
value: pallas::Affine,
) -> Result<Self::Point, Error> {
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<pallas::Base>,
Expand Down
37 changes: 37 additions & 0 deletions halo2_gadgets/src/ecc/chip/witness_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,21 @@ impl Config {
Ok((x_var, y_var))
}

fn assign_xy_constant(
&self,
value: (Assigned<pallas::Base>, Assigned<pallas::Base>),
offset: usize,
region: &mut Region<'_, pallas::Base>,
) -> Result<Coordinates, Error> {
// 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,
Expand All @@ -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<EccPoint, Error> {
// 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,
Expand Down

0 comments on commit 99d9d4c

Please sign in to comment.