mirror of https://github.com/zcash/halo2.git
chip::witness_point.rs: Allow witnessing the identity.
This commit is contained in:
parent
36d7888c1c
commit
433791fcb0
|
@ -68,6 +68,7 @@ pub trait EccInstructions<C: CurveAffine>: Chip<C::Base> {
|
||||||
) -> Result<Self::ScalarFixedShort, Error>;
|
) -> Result<Self::ScalarFixedShort, Error>;
|
||||||
|
|
||||||
/// Witnesses the given point as a private input to the circuit.
|
/// Witnesses the given point as a private input to the circuit.
|
||||||
|
/// This maps the identity to (0, 0) in affine coordinates.
|
||||||
fn witness_point(
|
fn witness_point(
|
||||||
&self,
|
&self,
|
||||||
layouter: &mut impl Layouter<C::Base>,
|
layouter: &mut impl Layouter<C::Base>,
|
||||||
|
@ -447,7 +448,13 @@ mod tests {
|
||||||
assert_ne!(p_val, q_val);
|
assert_ne!(p_val, q_val);
|
||||||
|
|
||||||
// Generate a (0,0) point to be used in other tests.
|
// Generate a (0,0) point to be used in other tests.
|
||||||
let zero = p.add(layouter.namespace(|| "P + (-P)"), &p_neg)?;
|
let zero = {
|
||||||
|
super::Point::new(
|
||||||
|
chip.clone(),
|
||||||
|
layouter.namespace(|| "identity"),
|
||||||
|
Some(C::identity()),
|
||||||
|
)?
|
||||||
|
};
|
||||||
|
|
||||||
// Test complete addition
|
// Test complete addition
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use super::{CellValue, EccConfig, EccPoint, Var};
|
use super::{CellValue, EccConfig, EccPoint, Var};
|
||||||
|
|
||||||
|
use ff::Field;
|
||||||
use halo2::{
|
use halo2::{
|
||||||
arithmetic::CurveAffine,
|
arithmetic::CurveAffine,
|
||||||
circuit::Region,
|
circuit::Region,
|
||||||
|
@ -33,14 +34,22 @@ impl<C: CurveAffine> From<&EccConfig<C>> for Config<C> {
|
||||||
impl<C: CurveAffine> Config<C> {
|
impl<C: CurveAffine> Config<C> {
|
||||||
pub(super) fn create_gate(&self, meta: &mut ConstraintSystem<C::Base>) {
|
pub(super) fn create_gate(&self, meta: &mut ConstraintSystem<C::Base>) {
|
||||||
meta.create_gate("witness point", |meta| {
|
meta.create_gate("witness point", |meta| {
|
||||||
|
// Check that either the point being witness is either:
|
||||||
|
// - the identity, which is mapped to (0, 0) in affine coordinates; or
|
||||||
|
// - a valid curve point y^2 = x^3 + b, where b = 5 in the Pallas equation
|
||||||
|
|
||||||
let q_point = meta.query_selector(self.q_point);
|
let q_point = meta.query_selector(self.q_point);
|
||||||
let x = meta.query_advice(self.x, Rotation::cur());
|
let x = meta.query_advice(self.x, Rotation::cur());
|
||||||
let y = meta.query_advice(self.y, Rotation::cur());
|
let y = meta.query_advice(self.y, Rotation::cur());
|
||||||
|
|
||||||
// Check that y^2 = x^3 + b, where b = 5 in the Pallas equation
|
// y^2 = x^3 + b
|
||||||
|
let curve_eqn = y.clone() * y.clone()
|
||||||
|
- (x.clone() * x.clone() * x.clone())
|
||||||
|
- Expression::Constant(C::b());
|
||||||
|
|
||||||
vec![
|
vec![
|
||||||
q_point
|
q_point.clone() * x * curve_eqn.clone(),
|
||||||
* (y.clone() * y - (x.clone() * x.clone() * x) - Expression::Constant(C::b())),
|
q_point * y * curve_eqn,
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -54,10 +63,18 @@ impl<C: CurveAffine> Config<C> {
|
||||||
// Enable `q_point` selector
|
// Enable `q_point` selector
|
||||||
self.q_point.enable(region, offset)?;
|
self.q_point.enable(region, offset)?;
|
||||||
|
|
||||||
let value = value.map(|value| value.coordinates().unwrap());
|
let value = value.map(|value| {
|
||||||
|
// Map the identity to (0, 0).
|
||||||
|
if value == C::identity() {
|
||||||
|
(C::Base::zero(), C::Base::zero())
|
||||||
|
} else {
|
||||||
|
let value = value.coordinates().unwrap();
|
||||||
|
(*value.x(), *value.y())
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// Assign `x` value
|
// Assign `x` value
|
||||||
let x_val = value.map(|value| *value.x());
|
let x_val = value.map(|value| value.0);
|
||||||
let x_var = region.assign_advice(
|
let x_var = region.assign_advice(
|
||||||
|| "x",
|
|| "x",
|
||||||
self.x,
|
self.x,
|
||||||
|
@ -66,7 +83,7 @@ impl<C: CurveAffine> Config<C> {
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// Assign `y` value
|
// Assign `y` value
|
||||||
let y_val = value.map(|value| *value.y());
|
let y_val = value.map(|value| value.1);
|
||||||
let y_var = region.assign_advice(
|
let y_var = region.assign_advice(
|
||||||
|| "y",
|
|| "y",
|
||||||
self.y,
|
self.y,
|
||||||
|
|
Loading…
Reference in New Issue