Skip to content

Commit

Permalink
initial modification
Browse files Browse the repository at this point in the history
  • Loading branch information
YaoGalteland committed Apr 29, 2024
1 parent 5f436dc commit 58a6ff1
Show file tree
Hide file tree
Showing 18 changed files with 623 additions and 1,911 deletions.
79 changes: 14 additions & 65 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::{AssignedCell, Chip, Layouter, Value},
circuit::{Chip, Layouter, Value},
plonk::Error,
};

Expand Down Expand Up @@ -60,15 +60,6 @@ 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 @@ -120,15 +111,6 @@ 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 @@ -249,7 +231,7 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> ScalarFixed<C, EccChip> {
#[derive(Debug)]
pub struct ScalarFixedShort<C: CurveAffine, EccChip: EccInstructions<C>> {
chip: EccChip,
inner: EccChip::ScalarFixedShort,
pub(crate) inner: EccChip::ScalarFixedShort,
}

impl<C: CurveAffine, EccChip: EccInstructions<C>> ScalarFixedShort<C, EccChip> {
Expand Down Expand Up @@ -393,8 +375,8 @@ impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone + Debug + Eq>
/// A point on a specific elliptic curve.
#[derive(Copy, Clone, Debug)]
pub struct Point<C: CurveAffine, EccChip: EccInstructions<C> + Clone + Debug + Eq> {
chip: EccChip,
inner: EccChip::Point,
pub(crate) chip: EccChip,
pub(crate) inner: EccChip::Point,
}

impl<C: CurveAffine, EccChip: EccInstructions<C> + Clone + Debug + Eq> Point<C, EccChip> {
Expand All @@ -408,16 +390,6 @@ 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 @@ -460,21 +432,6 @@ 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 @@ -638,7 +595,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 Expand Up @@ -772,7 +729,10 @@ pub(crate) mod tests {

#[allow(non_snake_case)]
impl Circuit<pallas::Base> for MyCircuit {
type Config = EccConfig<TestFixedBases>;
type Config = EccConfig<
TestFixedBases,
LookupRangeCheckConfig<pallas::Base, { crate::sinsemilla::primitives::K }>,
>;
type FloorPlanner = SimpleFloorPlanner;

fn without_witnesses(&self) -> Self {
Expand All @@ -793,7 +753,6 @@ pub(crate) mod tests {
meta.advice_column(),
];
let lookup_table = meta.lookup_table_column();
let table_range_check_tag = meta.lookup_table_column();
let lagrange_coeffs = [
meta.fixed_column(),
meta.fixed_column(),
Expand All @@ -808,13 +767,11 @@ pub(crate) mod tests {
let constants = meta.fixed_column();
meta.enable_constant(constants);

let range_check = LookupRangeCheckConfig::configure(
meta,
advices[9],
lookup_table,
table_range_check_tag,
);
EccChip::<TestFixedBases>::configure(meta, advices, lagrange_coeffs, range_check)
let range_check = LookupRangeCheckConfig::configure(meta, advices[9], lookup_table);
EccChip::<
TestFixedBases,
LookupRangeCheckConfig<pallas::Base, { crate::sinsemilla::primitives::K }>,
>::configure(meta, advices, lagrange_coeffs, range_check)
}

fn synthesize(
Expand Down Expand Up @@ -914,14 +871,6 @@ pub(crate) mod tests {
)?;
}

// Test variable-base sign-scalar multiplication
{
super::chip::mul_fixed::short::tests::test_mul_sign(
chip.clone(),
layouter.namespace(|| "variable-base sign-scalar mul"),
)?;
}

// Test full-width fixed-base scalar multiplication
{
super::chip::mul_fixed::full_width::tests::test_mul_fixed(
Expand Down
107 changes: 42 additions & 65 deletions halo2_gadgets/src/ecc/chip.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
//! Chip implementations for the ECC gadgets.
use super::{BaseFitsInScalarInstructions, EccInstructions, FixedPoints};
use crate::{
sinsemilla::primitives as sinsemilla,
utilities::{lookup_range_check::LookupRangeCheckConfig, UtilitiesInstructions},
};
use crate::utilities::{lookup_range_check::DefaultLookupRangeCheck, UtilitiesInstructions};
use arrayvec::ArrayVec;

use ff::PrimeField;
Expand All @@ -17,12 +14,12 @@ use pasta_curves::{arithmetic::CurveAffine, pallas};

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::*;

Expand All @@ -37,11 +34,11 @@ pub struct EccPoint {
/// x-coordinate
///
/// Stored as an `Assigned<F>` to enable batching inversions.
x: AssignedCell<Assigned<pallas::Base>, pallas::Base>,
pub(crate) x: AssignedCell<Assigned<pallas::Base>, pallas::Base>,
/// y-coordinate
///
/// Stored as an `Assigned<F>` to enable batching inversions.
y: AssignedCell<Assigned<pallas::Base>, pallas::Base>,
pub(crate) y: AssignedCell<Assigned<pallas::Base>, pallas::Base>,
}

impl EccPoint {
Expand Down Expand Up @@ -137,7 +134,10 @@ impl From<NonIdentityEccPoint> for EccPoint {
/// Configuration for [`EccChip`].
#[derive(Clone, Debug, Eq, PartialEq)]
#[allow(non_snake_case)]
pub struct EccConfig<FixedPoints: super::FixedPoints<pallas::Affine>> {
pub struct EccConfig<
FixedPoints: super::FixedPoints<pallas::Affine>,
Lookup: DefaultLookupRangeCheck,
> {
/// Advice columns needed by instructions in the ECC chip.
pub advices: [Column<Advice>; 10],

Expand All @@ -148,20 +148,20 @@ pub struct EccConfig<FixedPoints: super::FixedPoints<pallas::Affine>> {
add: add::Config,

/// Variable-base scalar multiplication
mul: mul::Config,
mul: mul::Config<Lookup>,

/// Fixed-base full-width scalar multiplication
mul_fixed_full: mul_fixed::full_width::Config<FixedPoints>,
/// Fixed-base signed short scalar multiplication
mul_fixed_short: mul_fixed::short::Config<FixedPoints>,
pub(crate) mul_fixed_short: mul_fixed::short::Config<FixedPoints>,
/// Fixed-base mul using a base field element as a scalar
mul_fixed_base_field: mul_fixed::base_field_elem::Config<FixedPoints>,
mul_fixed_base_field: mul_fixed::base_field_elem::Config<FixedPoints, Lookup>,

/// Witness point
witness_point: witness_point::Config,
pub(crate) witness_point: witness_point::Config,

/// Lookup range check using 10-bit lookup table
pub lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
pub lookup_config: Lookup,
}

/// A trait representing the kind of scalar used with a particular `FixedPoint`.
Expand Down Expand Up @@ -227,12 +227,15 @@ pub trait FixedPoint<C: CurveAffine>: std::fmt::Debug + Eq + Clone {

/// An [`EccInstructions`] chip that uses 10 advice columns.
#[derive(Clone, Debug, Eq, PartialEq)]
pub struct EccChip<FixedPoints: super::FixedPoints<pallas::Affine>> {
config: EccConfig<FixedPoints>,
pub struct EccChip<FixedPoints: super::FixedPoints<pallas::Affine>, Lookup: DefaultLookupRangeCheck>
{
config: EccConfig<FixedPoints, Lookup>,
}

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

fn config(&self) -> &Self::Config {
Expand All @@ -244,13 +247,15 @@ impl<FixedPoints: super::FixedPoints<pallas::Affine>> Chip<pallas::Base> for Ecc
}
}

impl<Fixed: super::FixedPoints<pallas::Affine>> UtilitiesInstructions<pallas::Base>
for EccChip<Fixed>
impl<Fixed: super::FixedPoints<pallas::Affine>, Lookup: DefaultLookupRangeCheck>
UtilitiesInstructions<pallas::Base> for EccChip<Fixed, Lookup>
{
type Var = AssignedCell<pallas::Base, pallas::Base>;
}

impl<FixedPoints: super::FixedPoints<pallas::Affine>> EccChip<FixedPoints> {
impl<FixedPoints: super::FixedPoints<pallas::Affine>, Lookup: DefaultLookupRangeCheck>
EccChip<FixedPoints, Lookup>
{
/// Reconstructs this chip from the given config.
pub fn construct(config: <Self as Chip<pallas::Base>>::Config) -> Self {
Self { config }
Expand All @@ -264,7 +269,7 @@ impl<FixedPoints: super::FixedPoints<pallas::Affine>> EccChip<FixedPoints> {
meta: &mut ConstraintSystem<pallas::Base>,
advices: [Column<Advice>; 10],
lagrange_coeffs: [Column<Fixed>; 8],
range_check: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
range_check: Lookup,
) -> <Self as Chip<pallas::Base>>::Config {
// Create witness point gate
let witness_point = witness_point::Config::configure(meta, advices[0], advices[1]);
Expand Down Expand Up @@ -301,12 +306,13 @@ impl<FixedPoints: super::FixedPoints<pallas::Affine>> EccChip<FixedPoints> {
mul_fixed::short::Config::<FixedPoints>::configure(meta, mul_fixed.clone());

// Create gate that is only used in fixed-base mul using a base field element.
let mul_fixed_base_field = mul_fixed::base_field_elem::Config::<FixedPoints>::configure(
meta,
advices[6..9].try_into().unwrap(),
range_check,
mul_fixed,
);
let mul_fixed_base_field =
mul_fixed::base_field_elem::Config::<FixedPoints, Lookup>::configure(
meta,
advices[6..9].try_into().unwrap(),
range_check,
mul_fixed,
);

EccConfig {
advices,
Expand Down Expand Up @@ -339,7 +345,7 @@ pub struct EccScalarFixed {
type MagnitudeCell = AssignedCell<pallas::Base, pallas::Base>;
// TODO: Make V an enum Sign { Positive, Negative }
type SignCell = AssignedCell<pallas::Base, pallas::Base>;
type MagnitudeSign = (MagnitudeCell, SignCell);
pub(crate) type MagnitudeSign = (MagnitudeCell, SignCell);

/// A signed short scalar used for fixed-base scalar multiplication.
/// A short scalar must have magnitude in the range [0..2^64), with
Expand Down Expand Up @@ -407,7 +413,8 @@ pub enum ScalarVar {
FullWidth,
}

impl<Fixed: FixedPoints<pallas::Affine>> EccInstructions<pallas::Affine> for EccChip<Fixed>
impl<Fixed: FixedPoints<pallas::Affine>, Lookup: DefaultLookupRangeCheck>
EccInstructions<pallas::Affine> for EccChip<Fixed, Lookup>
where
<Fixed as FixedPoints<pallas::Affine>>::Base:
FixedPoint<pallas::Affine, FixedScalarKind = BaseFieldElem>,
Expand Down Expand Up @@ -453,18 +460,6 @@ 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 Expand Up @@ -544,24 +539,6 @@ where
)
}

/// 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 Expand Up @@ -624,8 +601,8 @@ where
}
}

impl<Fixed: FixedPoints<pallas::Affine>> BaseFitsInScalarInstructions<pallas::Affine>
for EccChip<Fixed>
impl<Fixed: FixedPoints<pallas::Affine>, Lookup: DefaultLookupRangeCheck>
BaseFitsInScalarInstructions<pallas::Affine> for EccChip<Fixed, Lookup>
where
<Fixed as FixedPoints<pallas::Affine>>::Base:
FixedPoint<pallas::Affine, FixedScalarKind = BaseFieldElem>,
Expand Down
Loading

0 comments on commit 58a6ff1

Please sign in to comment.