Skip to content

Commit

Permalink
init doc
Browse files Browse the repository at this point in the history
  • Loading branch information
YaoGalteland committed May 16, 2024
1 parent 8922ed6 commit 221e17b
Show file tree
Hide file tree
Showing 15 changed files with 1,462 additions and 80 deletions.
56 changes: 28 additions & 28 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -125,33 +125,33 @@ jobs:
- name: Test halo2 book
run: mdbook test -L target/debug/deps book/

codecov:
name: Code coverage
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
# Use stable for this to ensure that cargo-tarpaulin can be built.
- id: prepare
uses: ./.github/actions/prepare
with:
toolchain: stable
nightly-features: true
- name: Install cargo-tarpaulin
uses: actions-rs/cargo@v1
with:
command: install
args: cargo-tarpaulin
- name: Generate coverage report
uses: actions-rs/cargo@v1
with:
command: tarpaulin
args: >
${{ steps.prepare.outputs.feature-flags }}
--timeout 600
--out Xml
- name: Upload coverage to Codecov
uses: codecov/[email protected]
# codecov:
# name: Code coverage
# runs-on: ubuntu-latest
#
# steps:
# - uses: actions/checkout@v3
# # Use stable for this to ensure that cargo-tarpaulin can be built.
# - id: prepare
# uses: ./.github/actions/prepare
# with:
# toolchain: stable
# nightly-features: true
# - name: Install cargo-tarpaulin
# uses: actions-rs/cargo@v1
# with:
# command: install
# args: cargo-tarpaulin
# - name: Generate coverage report
# uses: actions-rs/cargo@v1
# with:
# command: tarpaulin
# args: >
# ${{ steps.prepare.outputs.feature-flags }}
# --timeout 600
# --out Xml
# - name: Upload coverage to Codecov
# uses: codecov/[email protected]

doc-links:
name: Intra-doc links
Expand Down Expand Up @@ -184,4 +184,4 @@ jobs:
- uses: actions-rs/cargo@v1
with:
command: fmt
args: --all -- --check
args: --all -- --check
49 changes: 49 additions & 0 deletions halo2_gadgets/src/ecc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use halo2_proofs::{
circuit::{Chip, Layouter, Value},
plonk::Error,
};
use halo2_proofs::circuit::AssignedCell;

use crate::utilities::UtilitiesInstructions;

Expand Down Expand Up @@ -575,6 +576,54 @@ impl<C: CurveAffine, EccChip: EccInstructions<C>> FixedPointShort<C, EccChip> {
}
}


/// The set of circuit instructions required to use the ECC gadgets.
pub trait EccInstructionsOptimized<C: CurveAffine>: EccInstructions<C> {
/// 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>;

/// 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>;
}

impl<C: CurveAffine, EccChip: EccInstructionsOptimized<C> + Clone + Debug + Eq> Point<C, EccChip> {
/// 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 })
}

/// 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,
})
}
}
#[cfg(test)]
pub(crate) mod tests {
use ff::PrimeField;
Expand Down
44 changes: 43 additions & 1 deletion halo2_gadgets/src/ecc/chip.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Chip implementations for the ECC gadgets.

use super::{BaseFitsInScalarInstructions, EccInstructions, FixedPoints};
use super::{BaseFitsInScalarInstructions, EccInstructions, EccInstructionsOptimized, FixedPoints};
use crate::utilities::{lookup_range_check::PallasLookup, UtilitiesInstructions};
use arrayvec::ArrayVec;

Expand Down Expand Up @@ -615,3 +615,45 @@ where
Ok(ScalarVar::BaseFieldElem(base.clone()))
}
}


impl<Fixed: FixedPoints<pallas::Affine>, Lookup: PallasLookup>
EccInstructionsOptimized<pallas::Affine> for EccChip<Fixed, Lookup>
where
<Fixed as FixedPoints<pallas::Affine>>::Base:
FixedPoint<pallas::Affine, FixedScalarKind = BaseFieldElem>,
<Fixed as FixedPoints<pallas::Affine>>::FullScalar:
FixedPoint<pallas::Affine, FixedScalarKind = FullScalar>,
<Fixed as FixedPoints<pallas::Affine>>::ShortScalar:
FixedPoint<pallas::Affine, FixedScalarKind = ShortScalar>,
{
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),
)
}

/// 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,
)
}
}
66 changes: 66 additions & 0 deletions halo2_gadgets/src/ecc/chip/mul_fixed/short.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use halo2_proofs::{
poly::Rotation,
};
use pasta_curves::pallas;
use halo2_proofs::circuit::AssignedCell;

#[derive(Clone, Debug, Eq, PartialEq)]
pub struct Config<Fixed: FixedPoints<pallas::Affine>> {
Expand Down Expand Up @@ -243,6 +244,71 @@ impl<Fixed: FixedPoints<pallas::Affine>> Config<Fixed> {
}
}


impl<Fixed: FixedPoints<pallas::Affine>> Config<Fixed> {
/// 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)]
pub mod tests {
use group::{ff::PrimeField, Curve};
Expand Down
39 changes: 39 additions & 0 deletions halo2_gadgets/src/ecc/chip/witness_point.rs
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,45 @@ impl Config {
}
}


impl Config {
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 constant point that can be the identity.
pub(crate) 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))
}
}
#[cfg(test)]
pub mod tests {
use halo2_proofs::circuit::Layouter;
Expand Down
Loading

0 comments on commit 221e17b

Please sign in to comment.