Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve backward compatability draft1 #28

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion halo2_gadgets/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pprof = { version = "0.8", features = ["criterion", "flamegraph"] } # MSRV 1.56
bench = false

[features]
# default = ["test-dev-graph"]
test-dev-graph = [
"halo2_proofs/dev-graph",
"plotters",
Expand Down Expand Up @@ -82,4 +83,4 @@ harness = false
[[bench]]
name = "sha256"
harness = false
required-features = ["unstable-sha256-gadget"]
required-features = ["unstable-sha256-gadget"]
47 changes: 45 additions & 2 deletions halo2_gadgets/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use std::fmt::Debug;

use halo2_proofs::{
arithmetic::CurveAffine,
circuit::{Chip, Layouter, Value},
circuit::{AssignedCell, Chip, Layouter, Value},
plonk::Error,
};

Expand Down 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 @@ -111,6 +120,15 @@ pub trait EccInstructions<C: CurveAffine>:
b: &B,
) -> Result<Self::Point, Error>;

/// Performs variable-base sign-scalar multiplication, returning `[sign] point`
/// `sign` must be in {-1, 1}.
fn mul_sign(
&self,
layouter: &mut impl Layouter<C::Base>,
sign: &AssignedCell<C::Base, C::Base>,
point: &Self::Point,
) -> Result<Self::Point, Error>;

/// Performs variable-base scalar multiplication, returning `[scalar] base`.
fn mul(
&self,
Expand Down Expand Up @@ -390,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 Expand Up @@ -432,6 +460,21 @@ impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone + Debug + Eq> Point<C,
inner,
})
}

/// Returns `[sign] self`.
/// `sign` must be in {-1, 1}.
pub fn mul_sign(
&self,
mut layouter: impl Layouter<C::Base>,
sign: &AssignedCell<C::Base, C::Base>,
) -> Result<Point<C, EccChip>, Error> {
self.chip
.mul_sign(&mut layouter, sign, &self.inner)
.map(|point| Point {
chip: self.chip.clone(),
inner: point,
})
}
}

/// The affine short Weierstrass x-coordinate of a point on a specific elliptic curve.
Expand Down Expand Up @@ -595,7 +638,7 @@ pub(crate) mod tests {
},
FixedPoints,
};
use crate::utilities::lookup_range_check::LookupRangeCheckConfig;
use crate::utilities::lookup_range_check::{LookupRangeCheck, LookupRangeCheckConfig};

#[derive(Debug, Eq, PartialEq, Clone)]
pub(crate) struct TestFixedBases;
Expand Down
87 changes: 66 additions & 21 deletions halo2_gadgets/src/ecc/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
};
use arrayvec::ArrayVec;

use ff::PrimeField;
use ff::{PrimeField, PrimeFieldBits};

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

unused import: `PrimeFieldBits`

warning: unused import: `PrimeFieldBits` --> halo2_gadgets/src/ecc/chip.rs:10:22 | 10 | use ff::{PrimeField, PrimeFieldBits}; | ^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

unused import: `PrimeFieldBits`

warning: unused import: `PrimeFieldBits` --> halo2_gadgets/src/ecc/chip.rs:10:22 | 10 | use ff::{PrimeField, PrimeFieldBits}; | ^^^^^^^^^^^^^^ | = note: `#[warn(unused_imports)]` on by default

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Bitrot check

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Bitrot check

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Book tests

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Book tests

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Build target wasm32-wasi

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Build target wasm32-wasi

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Build target wasm32-unknown-unknown

unused import: `PrimeFieldBits`

Check failure on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Clippy (MSRV)

unused import: `PrimeFieldBits`

error: unused import: `PrimeFieldBits` --> halo2_gadgets/src/ecc/chip.rs:10:22 | 10 | use ff::{PrimeField, PrimeFieldBits}; | ^^^^^^^^^^^^^^ | = note: `-D unused-imports` implied by `-D warnings`

Check failure on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Clippy (MSRV)

unused import: `PrimeFieldBits`

error: unused import: `PrimeFieldBits` --> halo2_gadgets/src/ecc/chip.rs:10:22 | 10 | use ff::{PrimeField, PrimeFieldBits}; | ^^^^^^^^^^^^^^ | = note: `-D unused-imports` implied by `-D warnings`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest with nightly features

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest with beta features

unused import: `PrimeFieldBits`

Check warning on line 10 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest with nightly features

unused import: `PrimeFieldBits`
use group::prime::PrimeCurveAffine;
use halo2_proofs::{
circuit::{AssignedCell, Chip, Layouter, Value},
Expand All @@ -17,17 +17,18 @@

use std::convert::TryInto;

pub(super) mod add;
pub(super) mod add_incomplete;
pub(crate) mod add;
pub(crate) mod add_incomplete;
pub mod constants;
pub(super) mod mul;
pub(super) mod mul_fixed;
pub(super) mod witness_point;
pub(crate) mod mul;
pub(crate) mod mul_fixed;
pub(crate) mod witness_point;

pub use constants::*;

// Exposed for Sinsemilla.
pub(crate) use mul::incomplete::DoubleAndAdd;
use crate::utilities::lookup_range_check::LookupRangeCheck;

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

warning: unused import: `crate::utilities::lookup_range_check::LookupRangeCheck` --> halo2_gadgets/src/ecc/chip.rs:31:5 | 31 | use crate::utilities::lookup_range_check::LookupRangeCheck; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Clippy (beta)

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

warning: unused import: `crate::utilities::lookup_range_check::LookupRangeCheck` --> halo2_gadgets/src/ecc/chip.rs:31:5 | 31 | use crate::utilities::lookup_range_check::LookupRangeCheck; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Bitrot check

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Bitrot check

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Book tests

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Book tests

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Build target wasm32-wasi

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Build target wasm32-wasi

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Build target wasm32-unknown-unknown

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check failure on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Clippy (MSRV)

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

error: unused import: `crate::utilities::lookup_range_check::LookupRangeCheck` --> halo2_gadgets/src/ecc/chip.rs:31:5 | 31 | use crate::utilities::lookup_range_check::LookupRangeCheck; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check failure on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Clippy (MSRV)

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

error: unused import: `crate::utilities::lookup_range_check::LookupRangeCheck` --> halo2_gadgets/src/ecc/chip.rs:31:5 | 31 | use crate::utilities::lookup_range_check::LookupRangeCheck; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest with nightly features

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest with beta features

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

Check warning on line 31 in halo2_gadgets/src/ecc/chip.rs

View workflow job for this annotation

GitHub Actions / Test on ubuntu-latest with nightly features

unused import: `crate::utilities::lookup_range_check::LookupRangeCheck`

/// A curve point represented in affine (x, y) coordinates, or the
/// identity represented as (0, 0).
Expand Down Expand Up @@ -230,25 +231,39 @@
pub struct EccChip<FixedPoints: super::FixedPoints<pallas::Affine>> {
config: EccConfig<FixedPoints>,
}
#[macro_export]
/// Implement `Chip` for `chip_type` and `config_type`
macro_rules! impl_trait_Chip_fixedpoints_for {
($chip_type:ty, $config_type:ty) => {
impl<FixedPoints: super::FixedPoints<pallas::Affine>> Chip<pallas::Base> for $chip_type {
type Config = $config_type;
type Loaded = ();

fn config(&self) -> &Self::Config {
&self.config
}

impl<FixedPoints: super::FixedPoints<pallas::Affine>> Chip<pallas::Base> for EccChip<FixedPoints> {
type Config = EccConfig<FixedPoints>;
type Loaded = ();

fn config(&self) -> &Self::Config {
&self.config
}

fn loaded(&self) -> &Self::Loaded {
&()
}
fn loaded(&self) -> &Self::Loaded {
&()
}
}
};
}

impl<Fixed: super::FixedPoints<pallas::Affine>> UtilitiesInstructions<pallas::Base>
for EccChip<Fixed>
{
type Var = AssignedCell<pallas::Base, pallas::Base>;
impl_trait_Chip_fixedpoints_for!(EccChip<FixedPoints>,EccConfig<FixedPoints>);
#[macro_export]
/// Implement `UtilitiesInstructions` for `chip_type`
macro_rules! impl_trait_UtilitiesInstructions_FixedPoints_for {
($chip_type:ty) => {
impl<Fixed: super::FixedPoints<pallas::Affine>> UtilitiesInstructions<pallas::Base>
for $chip_type
{
type Var = AssignedCell<pallas::Base, pallas::Base>;
}
};
}
impl_trait_UtilitiesInstructions_FixedPoints_for!(EccChip<Fixed>);


impl<FixedPoints: super::FixedPoints<pallas::Affine>> EccChip<FixedPoints> {
/// Reconstructs this chip from the given config.
Expand Down Expand Up @@ -453,6 +468,18 @@
)
}

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 Expand Up @@ -532,6 +559,24 @@
)
}

/// Performs variable-base sign-scalar multiplication, returning `[sign] point`
/// `sign` must be in {-1, 1}.
fn mul_sign(
&self,
layouter: &mut impl Layouter<pallas::Base>,
sign: &AssignedCell<pallas::Base, pallas::Base>,
point: &Self::Point,
) -> Result<Self::Point, Error> {
// Multiply point by sign, using the same gate as mul_fixed::short.
// This also constrains sign to be in {-1, 1}.
let config_short = self.config().mul_fixed_short.clone();
config_short.assign_scalar_sign(
layouter.namespace(|| "variable-base sign-scalar mul"),
sign,
point,
)
}

fn mul(
&self,
layouter: &mut impl Layouter<pallas::Base>,
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/ecc/chip/mul/overflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use halo2_proofs::{
};
use pasta_curves::pallas;

use crate::utilities::lookup_range_check::LookupRangeCheck;
use std::iter;

#[derive(Copy, Clone, Debug, Eq, PartialEq)]
Expand Down
1 change: 1 addition & 0 deletions halo2_gadgets/src/ecc/chip/mul_fixed/base_field_elem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ use halo2_proofs::{
};
use pasta_curves::pallas;

use crate::utilities::lookup_range_check::LookupRangeCheck;
use std::convert::TryInto;

#[derive(Clone, Debug, Eq, PartialEq)]
Expand Down
63 changes: 63 additions & 0 deletions halo2_gadgets/src/ecc/chip/mul_fixed/short.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use std::convert::TryInto;
use super::super::{EccPoint, EccScalarFixedShort, FixedPoints, L_SCALAR_SHORT, NUM_WINDOWS_SHORT};
use crate::{ecc::chip::MagnitudeSign, utilities::bool_check};

use halo2_proofs::circuit::AssignedCell;
use halo2_proofs::{
circuit::{Layouter, Region},
plonk::{ConstraintSystem, Constraints, Error, Expression, Selector},
Expand Down Expand Up @@ -241,6 +242,68 @@ impl<Fixed: FixedPoints<pallas::Affine>> Config<Fixed> {

Ok((result, scalar))
}

/// Multiply the point by sign, using the q_mul_fixed_short gate.
/// Constraints `sign` in {-1, 1}
pub fn assign_scalar_sign(
&self,
mut layouter: impl Layouter<pallas::Base>,
sign: &AssignedCell<pallas::Base, pallas::Base>,
point: &EccPoint,
) -> Result<EccPoint, Error> {
let signed_point = layouter.assign_region(
|| "Signed point",
|mut region| {
let offset = 0;

// Enable mul_fixed_short selector to check the sign logic.
self.q_mul_fixed_short.enable(&mut region, offset)?;

// Set "last window" to 0 (this field is irrelevant here).
region.assign_advice_from_constant(
|| "u=0",
self.super_config.u,
offset,
pallas::Base::zero(),
)?;

// Copy sign to `window` column
sign.copy_advice(|| "sign", &mut region, self.super_config.window, offset)?;

// Assign the input y-coordinate.
point.y.copy_advice(
|| "unsigned y",
&mut region,
self.super_config.add_config.y_qr,
offset,
)?;

// Conditionally negate y-coordinate according to the value of sign
let signed_y_val = sign.value().and_then(|sign| {
if sign == &-pallas::Base::one() {
-point.y.value()
} else {
point.y.value().cloned()
}
});

// Assign the output signed y-coordinate.
let signed_y = region.assign_advice(
|| "signed y",
self.super_config.add_config.y_p,
offset,
|| signed_y_val,
)?;

Ok(EccPoint {
x: point.x.clone(),
y: signed_y,
})
},
)?;

Ok(signed_point)
}
}

#[cfg(test)]
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_from_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_from_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
Loading
Loading