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

[WIP] Recursive verifier API #666

Draft
wants to merge 24 commits into
base: endoscale
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
c2a524b
Add RunningSumConfig::window_expr() method.
therealyingtong Jun 1, 2022
9e2ed52
Add WINDOW_NUM_BITS const generic to RunningSum struct
therealyingtong Jun 1, 2022
96c7c5b
Add RunningSum::windows() method.
therealyingtong Jun 1, 2022
8c1c9f5
decompose_running_sum::RunningSum: Add num_bits, strict fields.
therealyingtong Jun 9, 2022
c8c745c
decompose_running_sum: Move range_check gate outside the helper.
therealyingtong Jun 10, 2022
a193258
Make EccPoint and NonIdentityEccPoint generic over the curve.
therealyingtong Jun 7, 2022
48d75ea
Make add_incomplete helper generic over the curve.
therealyingtong Jun 7, 2022
e259ae4
Introduce incomplete point doubling helper.
therealyingtong Jun 7, 2022
38aae08
Fix expected test output in mul_fixed::short.
therealyingtong Jun 7, 2022
274635a
halo2_gadgets::utilities: Add double_and_add helper.
therealyingtong Jul 5, 2022
789eeef
[book] Add double-and-add description.
therealyingtong Jul 5, 2022
99e7872
Utilities for endoscaling.
therealyingtong Dec 8, 2021
a816b74
recursion::endoscale: Add EndoscaleInstructions.
therealyingtong Dec 17, 2021
6b0fb68
endoscale::chip: Add skeleton EndoscaleConfig configuration.
therealyingtong Feb 28, 2022
211de0f
endoscale::chip: Implement witness_bitstring instruction.
therealyingtong Jun 8, 2022
32c2655
endoscale::chip::alg_1: Implement endoscale_fixed_base, endoscale_var…
therealyingtong Feb 28, 2022
92d8ae5
endoscale::chip::alg_2: Implement compute_endoscalar
therealyingtong Feb 28, 2022
a9bd1c0
compute_endoscalar: Implement support for partial chunks.
therealyingtong Mar 19, 2022
f3cb22a
endoscale::chip::alg_2: constrain_bitstring
therealyingtong Jul 3, 2022
1075246
Test endoscale chip.
therealyingtong Feb 9, 2022
6a2ba5e
Add description of endoscaling and public input handling (#599)
daira Jul 7, 2022
ddf48b3
utilities::bitstring: Introduce BitstringInstructions
therealyingtong Sep 27, 2022
f66d77c
[WIP] recursive_verifier::transcript: Introduce Transcript gadget
therealyingtong Sep 27, 2022
0124fdd
recursive_verifier: Introduce Verifier gadget
therealyingtong Sep 27, 2022
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
Prev Previous commit
Next Next commit
endoscale::chip: Add skeleton EndoscaleConfig configuration.
  • Loading branch information
therealyingtong committed Oct 24, 2022
commit 6b0fb68d452fd48221e84c5eb7ea7972317d3d18
4 changes: 2 additions & 2 deletions halo2_gadgets/src/ecc/chip.rs
Original file line number Diff line number Diff line change
@@ -17,9 +17,9 @@ use pasta_curves::{arithmetic::CurveAffine, pallas};
use std::convert::TryInto;

pub(super) mod add;
pub(super) mod add_incomplete;
pub(crate) mod add_incomplete;
pub mod constants;
pub(super) mod double;
pub(crate) mod double;
pub(super) mod mul;
pub(super) mod mul_fixed;
pub(super) mod witness_point;
4 changes: 2 additions & 2 deletions halo2_gadgets/src/ecc/chip/add_incomplete.rs
Original file line number Diff line number Diff line change
@@ -23,7 +23,7 @@ pub struct Config<C: CurveAffine> {
}

impl<C: CurveAffine> Config<C> {
pub(super) fn configure(
pub(crate) fn configure(
meta: &mut ConstraintSystem<C::Base>,
x_p: Column<Advice>,
y_p: Column<Advice>,
@@ -81,7 +81,7 @@ impl<C: CurveAffine> Config<C> {
});
}

pub(super) fn assign_region(
pub(crate) fn assign_region(
&self,
p: &NonIdentityEccPoint<C>,
q: &NonIdentityEccPoint<C>,
4 changes: 2 additions & 2 deletions halo2_gadgets/src/ecc/chip/double.rs
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ pub struct Config<C: CurveAffine> {
}

impl<C: CurveAffine> Config<C> {
pub(super) fn configure(
pub(crate) fn configure(
meta: &mut ConstraintSystem<C::Base>,
x_p: Column<Advice>,
y_p: Column<Advice>,
@@ -75,7 +75,7 @@ impl<C: CurveAffine> Config<C> {
});
}

pub(super) fn assign_region(
pub(crate) fn assign_region(
&self,
p: &NonIdentityEccPoint<C>,
offset: usize,
1 change: 1 addition & 0 deletions halo2_gadgets/src/endoscale.rs
Original file line number Diff line number Diff line change
@@ -7,6 +7,7 @@ use halo2_proofs::{
use pasta_curves::arithmetic::CurveAffine;
use std::fmt::Debug;

pub(crate) mod chip;
pub mod util;

/// Instructions to map bitstrings to and from endoscalars.
162 changes: 162 additions & 0 deletions halo2_gadgets/src/endoscale/chip.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
use crate::{ecc::chip::NonIdentityEccPoint, utilities::decompose_running_sum::RunningSumConfig};

use super::EndoscaleInstructions;
use ff::PrimeFieldBits;
use halo2_proofs::{
arithmetic::{CurveAffine, FieldExt},
circuit::{AssignedCell, Layouter, Value},
plonk::{Advice, Assigned, Column, ConstraintSystem, Error, Instance},
};

mod alg_1;
mod alg_2;

use alg_1::Alg1Config;
use alg_2::Alg2Config;

/// Bitstring used in endoscaling.
#[derive(Clone, Debug)]
#[allow(clippy::type_complexity)]
pub enum Bitstring<F: FieldExt + PrimeFieldBits, const K: usize> {
Pair(alg_1::Bitstring<F, 2>),
KBit(alg_2::Bitstring<F, K>),
}

/// Config used in processing endoscalars.
#[derive(Clone, Debug)]
pub struct EndoscaleConfig<C: CurveAffine, const K: usize, const MAX_BITSTRING_LENGTH: usize>
where
C::Base: PrimeFieldBits,
{
alg_1: Alg1Config<C>,
alg_2: Alg2Config<C, K, MAX_BITSTRING_LENGTH>,
}

impl<C: CurveAffine, const K: usize, const MAX_BITSTRING_LENGTH: usize>
EndoscaleConfig<C, K, MAX_BITSTRING_LENGTH>
where
C::Base: PrimeFieldBits,
{
#[allow(dead_code)]
#[allow(clippy::too_many_arguments)]
pub(crate) fn configure(
meta: &mut ConstraintSystem<C::Base>,
// Advice columns not shared across alg_1 and alg_2
advices: [Column<Advice>; 8],
// Running sum column shared across alg_1 and alg_2
running_sum: Column<Advice>,
endoscalars: Column<Instance>,
) -> Self {
let running_sum_pairs = {
let q_pairs = meta.selector();
RunningSumConfig::configure(meta, q_pairs, running_sum)
};

let alg_1 = Alg1Config::configure(
meta,
(advices[0], advices[1]),
(advices[2], advices[3]),
(advices[4], advices[5], advices[6], advices[7]),
running_sum_pairs,
);

let running_sum_chunks = {
let q_chunks = meta.complex_selector();
RunningSumConfig::configure(meta, q_chunks, running_sum)
};

let alg_2 = Alg2Config::configure(
meta,
endoscalars,
advices[0],
advices[1],
running_sum_chunks,
);

Self { alg_1, alg_2 }
}
}

impl<C: CurveAffine, const K: usize, const N: usize> EndoscaleInstructions<C>
for EndoscaleConfig<C, K, N>
where
C::Base: PrimeFieldBits,
{
type NonIdentityPoint = NonIdentityEccPoint<C>;
type Bitstring = Bitstring<C::Base, K>;
type FixedBases = C;
const MAX_BITSTRING_LENGTH: usize = 248;
const NUM_FIXED_BASES: usize = N;

fn witness_bitstring(
&self,
_layouter: &mut impl Layouter<C::Base>,
_bits: &[Value<bool>],
_for_base: bool,
) -> Result<Vec<Self::Bitstring>, Error> {
todo!()
}

#[allow(clippy::type_complexity)]
fn endoscale_fixed_base(
&self,
layouter: &mut impl Layouter<C::Base>,
bitstring: Vec<Self::Bitstring>,
bases: Vec<Self::FixedBases>,
) -> Result<Vec<Self::NonIdentityPoint>, Error> {
let mut points = Vec::new();
for (bitstring, base) in bitstring.iter().zip(bases.iter()) {
match bitstring {
Bitstring::Pair(bitstring) => {
points.push(self.alg_1.endoscale_fixed_base(layouter, bitstring, base)?)
}
_ => unreachable!(),
}
}
Ok(points)
}

fn endoscale_var_base(
&self,
layouter: &mut impl Layouter<C::Base>,
bitstring: Vec<Self::Bitstring>,
bases: Vec<Self::NonIdentityPoint>,
) -> Result<Vec<Self::NonIdentityPoint>, Error> {
let mut points = Vec::new();
for (bitstring, base) in bitstring.iter().zip(bases.iter()) {
match bitstring {
Bitstring::Pair(bitstring) => {
points.push(self.alg_1.endoscale_var_base(layouter, bitstring, base)?)
}
_ => unreachable!(),
}
}
Ok(points)
}

fn compute_endoscalar(
&self,
layouter: &mut impl Layouter<C::Base>,
bitstring: &Self::Bitstring,
) -> Result<AssignedCell<Assigned<C::Base>, C::Base>, Error> {
match bitstring {
Bitstring::KBit(bitstring) => self.alg_2.compute_endoscalar(layouter, bitstring),
_ => unreachable!(),
}
}

fn constrain_bitstring(
&self,
layouter: &mut impl Layouter<C::Base>,
bitstring: &Self::Bitstring,
pub_input_rows: Vec<usize>,
) -> Result<(), Error> {
match bitstring {
Bitstring::KBit(bitstring) => {
self.alg_2
.constrain_bitstring(layouter, bitstring, pub_input_rows)
}
_ => unreachable!(),
}
}
}
142 changes: 142 additions & 0 deletions halo2_gadgets/src/endoscale/chip/alg_1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
use ff::PrimeFieldBits;
use halo2_proofs::{
arithmetic::CurveAffine,
circuit::Layouter,
plonk::{Advice, Column, ConstraintSystem, Error, Selector},
};

use crate::{
ecc::chip::{add_incomplete, double, NonIdentityEccPoint},
utilities::{
decompose_running_sum::{RunningSum, RunningSumConfig},
double_and_add::DoubleAndAdd,
},
};

pub(super) type Bitstring<F, const K: usize> = RunningSum<F, K>;

/// Config used in Algorithm 1 (endoscaling with a base).
#[derive(Clone, Debug)]
pub(super) struct Alg1Config<C: CurveAffine>
where
C::Base: PrimeFieldBits,
{
// Selector for endoscaling checks.
q_endoscale_base: Selector,
// Selector for the initial check in double-and-add.
q_double_and_add_init: Selector,
// Selector for stead-state double-and-add.
q_double_and_add: Selector,
// Selector for the final check in double-and-add.
q_double_and_add_final: Selector,
// Configuration used for steady-state double-and-add.
double_and_add: DoubleAndAdd<C>,
// Incomplete point doubling config
double: double::Config<C>,
// Incomplete point addition config
add_incomplete: add_incomplete::Config<C>,
// Bases used in endoscaling.
base: (Column<Advice>, Column<Advice>),
// Bits used in endoscaling. These are in (b_0, b_1) pairs.
pair: (Column<Advice>, Column<Advice>),
// Configuration for running sum decomposition into pairs of bits.
running_sum_pairs: RunningSumConfig<C::Base, 2>,
}

impl<C: CurveAffine> Alg1Config<C>
where
C::Base: PrimeFieldBits,
{
pub(super) fn configure(
meta: &mut ConstraintSystem<C::Base>,
pair: (Column<Advice>, Column<Advice>),
base: (Column<Advice>, Column<Advice>),
(x_a, x_p, lambda_1, lambda_2): (
Column<Advice>,
Column<Advice>,
Column<Advice>,
Column<Advice>,
),
running_sum_pairs: RunningSumConfig<C::Base, 2>,
) -> Self {
meta.enable_equality(base.0);
meta.enable_equality(base.1);

let q_endoscale_base = meta.selector();

// Initial double-and-add gate
let q_double_and_add_init = meta.selector();
// Steady-state double-and-add gate
let q_double_and_add = meta.complex_selector();
// Final double-and-add gate
let q_double_and_add_final = meta.complex_selector();

let double_and_add = DoubleAndAdd::configure(
meta,
x_a,
x_p,
lambda_1,
lambda_2,
&|meta| {
let q_double_and_add = meta.query_selector(q_double_and_add);
let q_double_and_add_final = meta.query_selector(q_double_and_add_final);
q_double_and_add + q_double_and_add_final
},
&|meta| meta.query_selector(q_double_and_add),
);

let advices = double_and_add.advices();
let add_incomplete =
add_incomplete::Config::configure(meta, advices[2], advices[3], advices[0], advices[1]);
let double =
double::Config::configure(meta, advices[0], advices[1], advices[2], advices[3]);

meta.enable_equality(add_incomplete.x_p);
meta.enable_equality(add_incomplete.y_p);

meta.create_gate("init double-and-add", |meta| {
// TODO
let selector = meta.query_selector(q_double_and_add_init);

vec![selector]
});

meta.create_gate("final double-and-add", |meta| {
// TODO
let selector = meta.query_selector(q_double_and_add_final);

vec![selector]
});

Self {
q_endoscale_base,
q_double_and_add_init,
q_double_and_add,
q_double_and_add_final,
double_and_add,
double,
add_incomplete,
base,
pair,
running_sum_pairs,
}
}

pub(super) fn endoscale_fixed_base(
&self,
mut _layouter: &mut impl Layouter<C::Base>,
_bitstring: &RunningSum<C::Base, 2>,
_bases: &C,
) -> Result<NonIdentityEccPoint<C>, Error> {
todo!()
}

pub(super) fn endoscale_var_base(
&self,
mut _layouter: &mut impl Layouter<C::Base>,
_bitstring: &RunningSum<C::Base, 2>,
_bases: &NonIdentityEccPoint<C>,
) -> Result<NonIdentityEccPoint<C>, Error> {
todo!()
}
}
Loading