Skip to content

Commit

Permalink
Merge pull request #66 from zcash/ecc-chip-config
Browse files Browse the repository at this point in the history
[WIP] Fix ECC implementation to work with new Chip trait
  • Loading branch information
therealyingtong committed Apr 23, 2021
2 parents faa88c6 + 334c190 commit 6c5624d
Show file tree
Hide file tree
Showing 15 changed files with 800 additions and 640 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ subtle = "2.3"

[dependencies.halo2]
git = "https://github.com/zcash/halo2.git"
rev = "6acacf1aca12f34fc311aa59056e40adc0e6d8bd"
branch = "chip-config"

[dependencies.pasta_curves]
git = "https://github.com/zcash/pasta_curves.git"
Expand Down
112 changes: 73 additions & 39 deletions src/circuit/gadget/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,13 @@ use halo2::{
plonk::Error,
};

mod chip;
pub mod chip;

/// Trait allowing circuit's fixed points to be enumerated.
pub trait FixedPoints<C: CurveAffine>: Clone + fmt::Debug {}
pub trait FixedPoints<C: CurveAffine> {}

/// The set of circuit instructions required to use the ECC gadgets.
pub trait EccInstructions<C: CurveAffine>: Chip<Field = C::Base> {
pub trait EccInstructions<C: CurveAffine>: Chip<C::Base> {
/// Variable representing an element of the elliptic curve's scalar field, to be used for variable-base scalar mul.
type ScalarVar: Clone + fmt::Debug;
/// Variable representing a full-width element of the elliptic curve's scalar field, to be used for fixed-base scalar mul.
Expand All @@ -32,71 +32,81 @@ pub trait EccInstructions<C: CurveAffine>: Chip<Field = C::Base> {

/// Witnesses the given scalar as a private input to the circuit for variable-based scalar mul.
fn witness_scalar_var(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
value: Option<C::Scalar>,
) -> Result<Self::ScalarVar, Error>;

/// Witnesses the given full-width scalar as a private input to the circuit for fixed-based scalar mul.
fn witness_scalar_fixed(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
value: Option<C::Scalar>,
) -> Result<Self::ScalarFixed, Error>;

/// Witnesses the given signed short scalar as a private input to the circuit for fixed-based scalar mul.
fn witness_scalar_fixed_short(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
value: Option<C::Scalar>,
) -> Result<Self::ScalarFixedShort, Error>;

/// Witnesses the given point as a private input to the circuit.
fn witness_point(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
value: Option<C>,
) -> Result<Self::Point, Error>;

/// Extracts the x-coordinate of a point.
fn extract_p(point: &Self::Point) -> &Self::X;

/// Gets a fixed point into the circuit.
fn get_fixed(
layouter: &mut impl Layouter<Self>,
fixed_points: Self::FixedPoints,
) -> Result<Self::FixedPoint, Error>;
fn get_fixed(&self, fixed_points: Self::FixedPoints) -> Result<Self::FixedPoint, Error>;

/// Performs point addition, returning `a + b`.
fn add(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
a: &Self::Point,
b: &Self::Point,
) -> Result<Self::Point, Error>;

/// Performs complete point addition, returning `a + b`.
fn add_complete(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
a: &Self::Point,
b: &Self::Point,
) -> Result<Self::Point, Error>;

/// Performs point doubling, returning `[2] a`.
fn double(layouter: &mut impl Layouter<Self>, a: &Self::Point) -> Result<Self::Point, Error>;
fn double(
&self,
layouter: &mut impl Layouter<C::Base>,
a: &Self::Point,
) -> Result<Self::Point, Error>;

/// Performs variable-base scalar multiplication, returning `[scalar] base`.
fn mul(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
scalar: &Self::ScalarVar,
base: &Self::Point,
) -> Result<Self::Point, Error>;

/// Performs fixed-base scalar multiplication using a full-width scalar, returning `[scalar] base`.
fn mul_fixed(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
scalar: &Self::ScalarFixed,
base: &Self::FixedPoint,
) -> Result<Self::Point, Error>;

/// Performs fixed-base scalar multiplication using a short signed scalar, returning `[scalar] base`.
fn mul_fixed_short(
layouter: &mut impl Layouter<Self>,
&self,
layouter: &mut impl Layouter<C::Base>,
scalar: &Self::ScalarFixedShort,
base: &Self::FixedPoint,
) -> Result<Self::Point, Error>;
Expand All @@ -111,10 +121,12 @@ pub struct ScalarVar<C: CurveAffine, EccChip: EccInstructions<C>> {
impl<C: CurveAffine, EccChip: EccInstructions<C>> ScalarVar<C, EccChip> {
/// Constructs a new ScalarVar with the given value.
pub fn new(
mut layouter: impl Layouter<EccChip>,
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: Option<C::Scalar>,
) -> Result<Self, Error> {
EccChip::witness_scalar_var(&mut layouter, value).map(|inner| ScalarVar { inner })
chip.witness_scalar_var(&mut layouter, value)
.map(|inner| ScalarVar { inner })
}
}

Expand All @@ -127,10 +139,12 @@ pub struct ScalarFixed<C: CurveAffine, EccChip: EccInstructions<C>> {
impl<C: CurveAffine, EccChip: EccInstructions<C>> ScalarFixed<C, EccChip> {
/// Constructs a new ScalarFixed with the given value.
pub fn new(
mut layouter: impl Layouter<EccChip>,
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: Option<C::Scalar>,
) -> Result<Self, Error> {
EccChip::witness_scalar_fixed(&mut layouter, value).map(|inner| ScalarFixed { inner })
chip.witness_scalar_fixed(&mut layouter, value)
.map(|inner| ScalarFixed { inner })
}
}

Expand All @@ -143,10 +157,11 @@ pub struct ScalarFixedShort<C: CurveAffine, EccChip: EccInstructions<C>> {
impl<C: CurveAffine, EccChip: EccInstructions<C>> ScalarFixedShort<C, EccChip> {
/// Constructs a new ScalarFixedShort with the given value.
pub fn new(
mut layouter: impl Layouter<EccChip>,
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: Option<C::Scalar>,
) -> Result<Self, Error> {
EccChip::witness_scalar_fixed_short(&mut layouter, value)
chip.witness_scalar_fixed_short(&mut layouter, value)
.map(|inner| ScalarFixedShort { inner })
}
}
Expand All @@ -159,8 +174,13 @@ pub struct Point<C: CurveAffine, EccChip: EccInstructions<C>> {

impl<C: CurveAffine, EccChip: EccInstructions<C>> Point<C, EccChip> {
/// Constructs a new point with the given value.
pub fn new(mut layouter: impl Layouter<EccChip>, value: Option<C>) -> Result<Self, Error> {
EccChip::witness_point(&mut layouter, value).map(|inner| Point { inner })
pub fn new(
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
value: Option<C>,
) -> Result<Self, Error> {
chip.witness_point(&mut layouter, value)
.map(|inner| Point { inner })
}

/// Extracts the x-coordinate of a point.
Expand All @@ -174,22 +194,35 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> Point<C, EccChip> {
}

/// Returns `self + other`.
pub fn add(&self, mut layouter: impl Layouter<EccChip>, other: &Self) -> Result<Self, Error> {
EccChip::add(&mut layouter, &self.inner, &other.inner).map(|inner| Point { inner })
pub fn add(
&self,
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
other: &Self,
) -> Result<Self, Error> {
chip.add(&mut layouter, &self.inner, &other.inner)
.map(|inner| Point { inner })
}

/// Returns `[2] self`.
pub fn double(&self, mut layouter: impl Layouter<EccChip>) -> Result<Self, Error> {
EccChip::double(&mut layouter, &self.inner).map(|inner| Point { inner })
pub fn double(
&self,
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
) -> Result<Self, Error> {
chip.double(&mut layouter, &self.inner)
.map(|inner| Point { inner })
}

/// Returns `[by] self`.
pub fn mul(
&self,
mut layouter: impl Layouter<EccChip>,
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
by: &ScalarVar<C, EccChip>,
) -> Result<Self, Error> {
EccChip::mul(&mut layouter, &by.inner, &self.inner).map(|inner| Point { inner })
chip.mul(&mut layouter, &by.inner, &self.inner)
.map(|inner| Point { inner })
}
}

Expand All @@ -208,26 +241,27 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> X<C, EccChip> {

/// A constant elliptic curve point over the given curve, for which scalar multiplication
/// is more efficient.
#[derive(Debug)]
#[derive(Clone, Debug)]
pub struct FixedPoint<C: CurveAffine, EccChip: EccInstructions<C>> {
inner: EccChip::FixedPoint,
}

impl<C: CurveAffine, EccChip: EccInstructions<C>> FixedPoints<C> for FixedPoint<C, EccChip> {}

impl<C: CurveAffine, EccChip: EccInstructions<C>> FixedPoint<C, EccChip> {
/// Gets a reference to the specified fixed point in the circuit.
pub fn get(
mut layouter: impl Layouter<EccChip>,
point: EccChip::FixedPoints,
) -> Result<Self, Error> {
EccChip::get_fixed(&mut layouter, point).map(|inner| FixedPoint { inner })
pub fn get(chip: EccChip, point: EccChip::FixedPoints) -> Result<Self, Error> {
chip.get_fixed(point).map(|inner| FixedPoint { inner })
}

/// Returns `[by] self`.
pub fn mul(
&self,
mut layouter: impl Layouter<EccChip>,
chip: EccChip,
mut layouter: impl Layouter<C::Base>,
by: &ScalarFixed<C, EccChip>,
) -> Result<Point<C, EccChip>, Error> {
EccChip::mul_fixed(&mut layouter, &by.inner, &self.inner).map(|inner| Point { inner })
chip.mul_fixed(&mut layouter, &by.inner, &self.inner)
.map(|inner| Point { inner })
}
}
Loading

0 comments on commit 6c5624d

Please sign in to comment.