mirror of
https://github.com/privacy-scaling-explorations/halo2wrong.git
synced 2026-05-05 03:00:34 -04:00
feature: sketch ecc add
This commit is contained in:
@@ -13,6 +13,7 @@ num-bigint = { version = "0.4", features = ["rand"] }
|
||||
num-integer = "0.1"
|
||||
num-traits = "0.2"
|
||||
rand = "0.8"
|
||||
group = "0.11"
|
||||
|
||||
|
||||
[dev-dependencies]
|
||||
|
||||
@@ -1,40 +1,315 @@
|
||||
use crate::rns::Integer;
|
||||
use crate::circuit::main_gate::{MainGateConfig};
|
||||
|
||||
use super::{integer::IntegerConfig, AssignedInteger};
|
||||
use halo2::arithmetic::CurveAffine;
|
||||
use halo2::circuit::Region;
|
||||
use super::{AssignedCondition, AssignedInteger};
|
||||
use super::main_gate::{MainGate, MainGateInstructions};
|
||||
use super::integer::{IntegerConfig, IntegerChip, IntegerInstructions};
|
||||
use halo2::arithmetic::{FieldExt, CurveAffine};
|
||||
use halo2::circuit::{Region, Layouter};
|
||||
use halo2::plonk::Error;
|
||||
use std::marker::PhantomData;
|
||||
use crate::NUMBER_OF_LIMBS;
|
||||
|
||||
mod base_field_ecc;
|
||||
mod external_ecc;
|
||||
|
||||
pub struct Point<C: CurveAffine> {
|
||||
x: Integer<C::ScalarExt>,
|
||||
y: Integer<C::ScalarExt>,
|
||||
// Ecc operation mods
|
||||
mod add;
|
||||
|
||||
/* Emulate CurveAffine point undert field F */
|
||||
#[derive(Default, Clone, Debug)]
|
||||
pub struct Point<C: CurveAffine, F:FieldExt> {
|
||||
x: Integer<F>,
|
||||
y: Integer<F>,
|
||||
_marker: PhantomData<C::Base>
|
||||
}
|
||||
|
||||
impl<C: CurveAffine> Point<C> {
|
||||
fn new(x: Integer<C::ScalarExt>, y: Integer<C::ScalarExt>) -> Self {
|
||||
Point { x, y }
|
||||
impl<C: CurveAffine, F:FieldExt> Point<C, F> {
|
||||
fn new(x: Integer<F>, y: Integer<F>) -> Self {
|
||||
Point { x, y, _marker:PhantomData }
|
||||
}
|
||||
}
|
||||
|
||||
pub struct AssignedPoint<C: CurveAffine> {
|
||||
x: AssignedInteger<C::ScalarExt>,
|
||||
y: AssignedInteger<C::ScalarExt>,
|
||||
pub struct AssignedPoint<C: CurveAffine, F:FieldExt > {
|
||||
x: AssignedInteger<F>,
|
||||
y: AssignedInteger<F>,
|
||||
// indicate whether the poinit is the identity point of curve or not
|
||||
z: AssignedCondition<F>,
|
||||
_marker: PhantomData<C::Base>
|
||||
}
|
||||
|
||||
impl<C: CurveAffine, F:FieldExt> AssignedPoint<C, F> {
|
||||
pub fn new(
|
||||
x:AssignedInteger<F>,
|
||||
y:AssignedInteger<F>,
|
||||
z:AssignedCondition<F>
|
||||
) -> AssignedPoint<C,F> {
|
||||
AssignedPoint{ x, y, z, _marker:PhantomData }
|
||||
}
|
||||
pub fn is_identity(&self) -> AssignedCondition<F> {
|
||||
self.z.clone()
|
||||
}
|
||||
}
|
||||
|
||||
/// Linear combination term
|
||||
pub enum Term<C: CurveAffine> {
|
||||
Assigned(AssignedPoint<C>, C::ScalarExt),
|
||||
Unassigned(Option<Point<C>>, C::ScalarExt),
|
||||
pub enum Term<C: CurveAffine, F:FieldExt> {
|
||||
Assigned(AssignedPoint<C, F>, F),
|
||||
Unassigned(Option<Point<C, F>>, F),
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct EccConfig {
|
||||
integer_chip_config: IntegerConfig,
|
||||
integer_gate_config: MainGateConfig,
|
||||
}
|
||||
|
||||
pub struct EccChip {
|
||||
config: IntegerConfig,
|
||||
// we need template arg C to extract curve constants including a and b
|
||||
pub struct EccChip<C: CurveAffine, F: FieldExt> {
|
||||
config: EccConfig,
|
||||
integer_chip: IntegerChip<C::Base, F>,
|
||||
// We need to assign following integers based on constants of curve C
|
||||
a: AssignedInteger<F>,
|
||||
b: AssignedInteger<F>,
|
||||
}
|
||||
|
||||
/* Now moved to external_ecc
|
||||
impl<C: CurveAffine, F:FieldExt> EccInstruction<C, F> for EccChip<C, F> {
|
||||
fn assign_point(&self, region: &mut Region<'_, F>, point: Point<C,F>, offset: &mut usize) -> Result<AssignedPoint<C,F>, Error> {
|
||||
let x = self.integer_chip.assign_integer(region, Some(point.x.clone()), offset)?.clone();
|
||||
let y = self.integer_chip.assign_integer(region, Some(point.y.clone()), offset)?.clone();
|
||||
let z = self.integer_gate().assign_bit(region, Some(F::zero()), offset)?.clone();
|
||||
Ok(AssignedPoint::new(x,y,z))
|
||||
}
|
||||
|
||||
fn assert_is_on_curve(&self, region: &mut Region<'_, F>, point: AssignedPoint<C,F>, offset: &mut usize) -> Result<(), Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn assert_equal(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
p0: &AssignedPoint<C,F>,
|
||||
p1: &AssignedPoint<C,F>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedPoint<C,F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn add(&self, region: &mut Region<'_, F>, p0: &AssignedPoint<C,F>, p1: &AssignedPoint<C,F>, offset: &mut usize) -> Result<AssignedPoint<C,F>, Error> {
|
||||
self._add(region, p0, p1, offset)
|
||||
}
|
||||
|
||||
fn double(&self, region: &mut Region<'_, F>, p: AssignedPoint<C,F>, offset: &mut usize) -> Result<AssignedPoint<C,F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn mul_var(&self, region: &mut Region<'_, F>, p: AssignedPoint<C,F>, e: F, offset: &mut usize) -> Result<AssignedPoint<C,F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn mul_fix(&self, region: &mut Region<'_, F>, p: C, e: F, offset: &mut usize) -> Result<AssignedPoint<C,F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn multi_exp(&self, region: &mut Region<'_, F>, terms: Vec<Term<C, F>>, offset: &mut usize) -> Result<AssignedPoint<C,F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn combine(&self, region: &mut Region<'_, F>, terms: Vec<Term<C, F>>, u: F, offset: &mut usize) -> Result<AssignedPoint<C,F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
impl<C: CurveAffine, F: FieldExt> EccChip<C, F> {
|
||||
fn new(
|
||||
layouter: &mut impl Layouter<F>,
|
||||
config: EccConfig,
|
||||
integer_chip: IntegerChip<C::Base, F>
|
||||
) -> Result<Self, Error> {
|
||||
let ca = Integer::<F>::from_bytes_le(
|
||||
&C::a().to_bytes(),
|
||||
NUMBER_OF_LIMBS,
|
||||
integer_chip.rns.bit_len_limb
|
||||
);
|
||||
let cb = Integer::<F>::from_bytes_le(
|
||||
&C::b().to_bytes(),
|
||||
NUMBER_OF_LIMBS,
|
||||
integer_chip.rns.bit_len_limb
|
||||
);
|
||||
|
||||
let (a, b) = {
|
||||
let mut a: Option<AssignedInteger<F>> = None;
|
||||
let mut b: Option<AssignedInteger<F>> = None;
|
||||
layouter.assign_region(
|
||||
|| "region 0",
|
||||
|mut region| {
|
||||
let offset = &mut 0;
|
||||
a = Some (integer_chip.assign_integer(&mut region, Some(ca.clone()), offset)?);
|
||||
b = Some (integer_chip.assign_integer(&mut region, Some(cb.clone()), offset)?);
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
(a.unwrap(), b.unwrap())
|
||||
};
|
||||
Ok(EccChip {config, integer_chip, a, b})
|
||||
}
|
||||
}
|
||||
|
||||
impl<C: CurveAffine, F:FieldExt> EccChip<C, F> {
|
||||
fn integer_gate(&self) -> MainGate<F> {
|
||||
let main_gate_config = self.config.integer_gate_config.clone();
|
||||
MainGate::<F>::new(main_gate_config)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use halo2::arithmetic::{CurveAffine, FieldExt, Field};
|
||||
use super::{IntegerChip, IntegerConfig, IntegerInstructions};
|
||||
use crate::circuit::AssignedValue;
|
||||
use crate::circuit::main_gate::{MainGate, MainGateConfig, MainGateInstructions};
|
||||
use crate::circuit::range::{RangeChip, RangeInstructions, RangeConfig};
|
||||
use crate::circuit::ecc::{Point, EccChip, EccInstruction, EccConfig};
|
||||
use crate::rns::{Integer, Limb, Rns};
|
||||
use halo2::circuit::{Layouter, SimpleFloorPlanner};
|
||||
use halo2::dev::MockProver;
|
||||
use halo2::plonk::{Circuit, ConstraintSystem, Error};
|
||||
use group::{Curve, prime::PrimeCurveAffine};
|
||||
use crate::NUMBER_OF_LIMBS;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
struct TestCircuitConfig {
|
||||
integer_gate_config: MainGateConfig,
|
||||
integer_chip_config: IntegerConfig,
|
||||
ecc_chip_config: EccConfig,
|
||||
range_config: RangeConfig,
|
||||
}
|
||||
|
||||
impl TestCircuitConfig {
|
||||
fn overflow_bit_lengths() -> Vec<usize> {
|
||||
vec![2, 3]
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Debug)]
|
||||
struct TestEcc<C: CurveAffine, N: FieldExt> {
|
||||
x: Point<C, N>,
|
||||
y: Point<C, N>,
|
||||
z: Point<C, N>,
|
||||
rns: Rns<C::Base, N>,
|
||||
}
|
||||
|
||||
impl<C: CurveAffine, N: FieldExt> Circuit<N> for TestEcc<C, N> {
|
||||
type Config = TestCircuitConfig;
|
||||
type FloorPlanner = SimpleFloorPlanner;
|
||||
|
||||
fn without_witnesses(&self) -> Self {
|
||||
Self::default()
|
||||
}
|
||||
|
||||
fn configure(meta: &mut ConstraintSystem<N>) -> Self::Config {
|
||||
let integer_gate_config = MainGate::<N>::configure(meta);
|
||||
let overflow_bit_lengths = TestCircuitConfig::overflow_bit_lengths();
|
||||
let range_config = RangeChip::<N>::configure(meta, &integer_gate_config, overflow_bit_lengths);
|
||||
let integer_chip_config = IntegerChip::<C::Base, N>::configure(meta, &range_config, &integer_gate_config);
|
||||
let ecc_chip_config = EccConfig {
|
||||
integer_gate_config: integer_gate_config.clone(),
|
||||
integer_chip_config: integer_chip_config.clone()
|
||||
};
|
||||
TestCircuitConfig {
|
||||
range_config,
|
||||
integer_chip_config,
|
||||
integer_gate_config,
|
||||
ecc_chip_config,
|
||||
}
|
||||
}
|
||||
|
||||
fn synthesize(&self, config: Self::Config, mut layouter: impl Layouter<N>) -> Result<(), Error> {
|
||||
let integer_chip = IntegerChip::<C::Base, N>::new(config.integer_chip_config.clone(), self.rns.clone());
|
||||
|
||||
let ecc_chip = EccChip::<C, N>::new(&mut layouter, config.ecc_chip_config, integer_chip)?;
|
||||
let offset = &mut 0;
|
||||
layouter.assign_region(
|
||||
|| "region 0",
|
||||
|mut region| {
|
||||
let px = ecc_chip.assign_point(&mut region, self.x.clone(), offset)?;
|
||||
let py = ecc_chip.assign_point(&mut region, self.y.clone(), offset)?;
|
||||
let pz = ecc_chip.assign_point(&mut region, self.z.clone(), offset)?;
|
||||
let r = ecc_chip.add(&mut region, &px, &py, offset)?;
|
||||
ecc_chip.assert_equal(&mut region, &r, &pz, offset)?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
|
||||
let range_chip = RangeChip::<N>::new(config.range_config, self.rns.bit_len_lookup);
|
||||
#[cfg(not(feature = "no_lookup"))]
|
||||
range_chip.load_limb_range_table(&mut layouter)?;
|
||||
#[cfg(not(feature = "no_lookup"))]
|
||||
range_chip.load_overflow_range_tables(&mut layouter)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ecc_add_circuit() {
|
||||
use halo2::pasta::EpAffine as C;
|
||||
use halo2::pasta::Fq as Native;
|
||||
let bit_len_limb = 64;
|
||||
|
||||
let rns_base = Rns::<<C as CurveAffine>::Base, Native>::construct(bit_len_limb);
|
||||
let rns_scalar = Rns::<<C as CurveAffine>::ScalarExt, Native>::construct(bit_len_limb);
|
||||
|
||||
#[cfg(not(feature = "no_lookup"))]
|
||||
let k: u32 = (rns_base.bit_len_lookup + 1) as u32;
|
||||
#[cfg(feature = "no_lookup")]
|
||||
let k: u32 = 8;
|
||||
|
||||
let sk = <C as CurveAffine>::ScalarExt::rand();
|
||||
let generator = <C as PrimeCurveAffine> :: generator();
|
||||
let pk = generator * sk;
|
||||
|
||||
let pbase = //<C as PrimeCurveAffine> :: generator()
|
||||
pk
|
||||
.to_affine()
|
||||
.coordinates()
|
||||
.unwrap();
|
||||
let x = {
|
||||
let x = Integer::<<C as CurveAffine>::ScalarExt>::from_bytes_le(
|
||||
&pbase.x().to_bytes(), NUMBER_OF_LIMBS, bit_len_limb);
|
||||
let y = Integer::<<C as CurveAffine>::ScalarExt>::from_bytes_le(
|
||||
&pbase.y().to_bytes(), NUMBER_OF_LIMBS, bit_len_limb);
|
||||
Point::new(x, y)
|
||||
};
|
||||
let y = {
|
||||
let x = Integer::<<C as CurveAffine>::ScalarExt>::from_bytes_le(
|
||||
&pbase.x().to_bytes(), NUMBER_OF_LIMBS, bit_len_limb);
|
||||
let y = Integer::<<C as CurveAffine>::ScalarExt>::from_bytes_le(
|
||||
&pbase.y().to_bytes(), NUMBER_OF_LIMBS, bit_len_limb);
|
||||
Point::new(x, y)
|
||||
};
|
||||
let z = {
|
||||
let x = Integer::<<C as CurveAffine>::ScalarExt>::from_bytes_le(
|
||||
&pbase.x().to_bytes(), NUMBER_OF_LIMBS, bit_len_limb);
|
||||
let y = Integer::<<C as CurveAffine>::ScalarExt>::from_bytes_le(
|
||||
&pbase.y().to_bytes(), NUMBER_OF_LIMBS, bit_len_limb);
|
||||
Point::new(x, y)
|
||||
};
|
||||
|
||||
let circuit = TestEcc::<C, Native> {
|
||||
x: x,
|
||||
y: y,
|
||||
z: z,
|
||||
rns: rns_base.clone(),
|
||||
};
|
||||
|
||||
let prover = match MockProver::run(k, &circuit, vec![]) {
|
||||
Ok(prover) => prover,
|
||||
Err(e) => panic!("{:#?}", e),
|
||||
};
|
||||
|
||||
assert_eq!(prover.verify(), Ok(()));
|
||||
}
|
||||
}
|
||||
|
||||
136
src/circuit/ecc/add.rs
Normal file
136
src/circuit/ecc/add.rs
Normal file
@@ -0,0 +1,136 @@
|
||||
use super::EccChip;
|
||||
use super::{AssignedPoint};
|
||||
use super::super::integer::{IntegerConfig, IntegerChip, IntegerInstructions};
|
||||
use crate::circuit::main_gate::{MainGateConfig, MainGateInstructions};
|
||||
use crate::circuit::{AssignedInteger, AssignedLimb, AssignedCondition};
|
||||
use halo2::arithmetic::{CurveAffine, FieldExt};
|
||||
use halo2::circuit::Region;
|
||||
use halo2::plonk::Error;
|
||||
|
||||
|
||||
impl<C: CurveAffine, F: FieldExt> EccChip<C, F> {
|
||||
fn curvature(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
a: &AssignedPoint<C,F>,
|
||||
offset: &mut usize
|
||||
) -> Result <AssignedInteger<F>, Error> {
|
||||
// (3 * a.x^2 + self.a) / 2 * a.y
|
||||
let cst3 = {
|
||||
let rns3 = self.integer_chip.rns.new_from_big(3u32.into());
|
||||
&self.integer_chip.assign_integer(region, Some(rns3), offset)?
|
||||
};
|
||||
let cst2 = {
|
||||
let rns2 = self.integer_chip.rns.new_from_big(2u32.into());
|
||||
&self.integer_chip.assign_integer(region, Some(rns2), offset)?
|
||||
};
|
||||
|
||||
let xsqm = {
|
||||
let xsq = self.integer_chip.mul(region, &a.x, &a.x, offset)?;
|
||||
self.integer_chip.mul(region, &xsq, cst3, offset)?
|
||||
};
|
||||
let curvature = {
|
||||
let numerator = self.integer_chip.add(region, &xsqm, &self.a, offset)?;
|
||||
let denominator = self.integer_chip.mul(region, &a.y, cst2, offset)?;
|
||||
let (lambda, _) = self.integer_chip.div(region,
|
||||
&numerator,
|
||||
&denominator,
|
||||
offset
|
||||
)?;
|
||||
lambda
|
||||
};
|
||||
Ok(curvature)
|
||||
}
|
||||
|
||||
fn lambda(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
a: &AssignedPoint<C,F>,
|
||||
b: &AssignedPoint<C,F>,
|
||||
offset: &mut usize
|
||||
) -> Result<(AssignedInteger<F>, AssignedCondition<F>), Error> {
|
||||
let integer_gate = self.integer_gate();
|
||||
|
||||
let numerator = self.integer_chip.sub(region, &a.y, &b.y, offset)?;
|
||||
let (_, eqy_cond) = self.integer_chip.invert(region, &numerator, offset)?;
|
||||
|
||||
let (lambda_neq, eqx_cond) = {
|
||||
let denominator = self.integer_chip.sub(region, &a.x, &b.x, offset)?;
|
||||
self.integer_chip.div(region, &numerator, &denominator, offset)?
|
||||
};
|
||||
|
||||
// When eqx_cond == 1, we calculated the tangent curvature
|
||||
let lambda_eq = self.curvature(region, a, offset)?;
|
||||
let lambda = self.integer_chip.cond_select(region, &lambda_neq, &lambda_eq, &eqx_cond, offset)?;
|
||||
|
||||
// eqx_cond == 1 and eqy_cond == 0 means tangent is infinity
|
||||
let not_eqy_cond = integer_gate.cond_not(region, &eqy_cond, offset)?;
|
||||
let zero_cond = integer_gate.cond_and(region,
|
||||
¬_eqy_cond,
|
||||
&eqx_cond,
|
||||
offset,
|
||||
)?;
|
||||
Ok((lambda, zero_cond))
|
||||
}
|
||||
|
||||
/* We use affine coordinates since invert cost almost the same as mul in
|
||||
* halo circuts gates while projective coordinates involves more multiplication
|
||||
* than affine coordinates.
|
||||
* Thus coordinate z in point is used as an indicator of whether the point is
|
||||
* identity(infinity) or not.
|
||||
*/
|
||||
pub(crate) fn _add(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
a: &AssignedPoint<C,F>,
|
||||
b: &AssignedPoint<C,F>,
|
||||
offset: &mut usize
|
||||
) -> Result<AssignedPoint<C,F>, Error> {
|
||||
let integer_gate = self.integer_gate();
|
||||
|
||||
let (lambda, zero_cond) = self.lambda(region, a, b, offset)?;
|
||||
let lambda_square = self.integer_chip._square(region, &lambda, offset)?;
|
||||
|
||||
// cx = λ^2 - a.x - b.x
|
||||
let sqsub = self.integer_chip._sub(region, &lambda_square, &a.x, offset)?;
|
||||
let cx = self.integer_chip._sub(
|
||||
region,
|
||||
&sqsub,
|
||||
&b.x,
|
||||
offset
|
||||
)?;
|
||||
|
||||
// cy = λ(a.x - c.x) - a.y
|
||||
let xsub = self.integer_chip._sub(region, &a.x, &cx, offset)?;
|
||||
let yi = self.integer_chip._mul(
|
||||
region,
|
||||
&lambda,
|
||||
&xsub,
|
||||
offset,
|
||||
)?;
|
||||
let cy = self.integer_chip._sub(region, &yi, &a.y, offset)?;
|
||||
let cx_sel = self.integer_chip.cond_select(region,
|
||||
&b.x,
|
||||
&cx,
|
||||
&a.is_identity(),
|
||||
offset
|
||||
)?;
|
||||
let p = AssignedPoint::new(cx, cy, zero_cond);
|
||||
|
||||
/* Now combine the calculation using the following cond table
|
||||
* a.is_identity() -> b
|
||||
* b.is_identity() -> a
|
||||
* zero_cond -> self.identity()
|
||||
* otherwise -> p
|
||||
*/
|
||||
|
||||
let id_sel = integer_gate.cond_or(
|
||||
region,
|
||||
&a.is_identity(),
|
||||
&b.is_identity(),
|
||||
offset
|
||||
)?;
|
||||
|
||||
Ok(p)
|
||||
}
|
||||
}
|
||||
@@ -1,60 +1,63 @@
|
||||
use crate::circuit::AssignedInteger;
|
||||
use halo2::arithmetic::CurveAffine;
|
||||
use halo2::arithmetic::{FieldExt, CurveAffine};
|
||||
use halo2::circuit::Region;
|
||||
use halo2::plonk::Error;
|
||||
|
||||
use super::{AssignedPoint, EccChip, Point};
|
||||
|
||||
pub trait ExternalEccInstruction<Native: CurveAffine, External: CurveAffine> {
|
||||
fn assign_point(&self, region: &mut Region<'_, Native::ScalarExt>, point: Point<External>, offset: &mut usize) -> Result<AssignedPoint<External>, Error>;
|
||||
pub trait ExternalEccInstruction<External: CurveAffine, Native: FieldExt> {
|
||||
fn assign_point(&self, region: &mut Region<'_, Native>, point: Point<External>, offset: &mut usize) -> Result<AssignedPoint<External>, Error>;
|
||||
|
||||
fn assert_is_on_curve(&self, region: &mut Region<'_, Native::ScalarExt>, point: AssignedPoint<External>, offset: &mut usize) -> Result<(), Error>;
|
||||
fn assert_is_on_curve(&self, region: &mut Region<'_, Native>, point: AssignedPoint<External>, offset: &mut usize) -> Result<(), Error>;
|
||||
|
||||
fn assert_equal(
|
||||
&self,
|
||||
region: &mut Region<'_, Native::ScalarExt>,
|
||||
p0: AssignedPoint<External>,
|
||||
p1: AssignedPoint<External>,
|
||||
region: &mut Region<'_, Native>,
|
||||
p0: AssignedPoint<External, Native>,
|
||||
p1: AssignedPoint<External, Native>,
|
||||
offset: &mut usize,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
fn add(
|
||||
&self,
|
||||
region: &mut Region<'_, Native::ScalarExt>,
|
||||
region: &mut Region<'_, Native>,
|
||||
p0: AssignedPoint<External>,
|
||||
p1: AssignedPoint<External>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedPoint<External>, Error>;
|
||||
fn double(&self, region: &mut Region<'_, Native::ScalarExt>, p: AssignedPoint<External>, offset: &mut usize) -> Result<AssignedPoint<External>, Error>;
|
||||
fn double(&self, region: &mut Region<'_, Native>, p: AssignedPoint<External>, offset: &mut usize) -> Result<AssignedPoint<External>, Error>;
|
||||
|
||||
fn mul_var(
|
||||
&self,
|
||||
region: &mut Region<'_, Native::ScalarExt>,
|
||||
region: &mut Region<'_, Native>,
|
||||
p: AssignedPoint<External>,
|
||||
e: AssignedInteger<External::ScalarExt>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedPoint<External>, Error>;
|
||||
fn mul_fix(
|
||||
&self,
|
||||
region: &mut Region<'_, Native::ScalarExt>,
|
||||
region: &mut Region<'_, Native>,
|
||||
p: Point<External>,
|
||||
e: AssignedInteger<External::ScalarExt>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedPoint<External>, Error>;
|
||||
}
|
||||
|
||||
impl<Native: CurveAffine, External: CurveAffine> ExternalEccInstruction<Native, External> for EccChip {
|
||||
fn assign_point(&self, region: &mut Region<'_, Native::ScalarExt>, point: Point<External>, offset: &mut usize) -> Result<AssignedPoint<External>, Error> {
|
||||
unimplemented!();
|
||||
impl<External: CurveAffine, Native: FieldExt> ExternalEccInstruction<External, Native> for EccChip {
|
||||
fn assign_point(&self, region: &mut Region<'_, Native>, point: Point<External>, offset: &mut usize) -> Result<AssignedPoint<External>, Error> {
|
||||
let x = self.integer_chip.assign_integer(region, Some(point.x.clone()), offset)?.clone();
|
||||
let y = self.integer_chip.assign_integer(region, Some(point.y.clone()), offset)?.clone();
|
||||
let z = self.integer_gate().assign_bit(region, Some(F::zero()), offset)?.clone();
|
||||
Ok(AssignedPoint::new(x,y,z))
|
||||
}
|
||||
|
||||
fn assert_is_on_curve(&self, region: &mut Region<'_, Native::ScalarExt>, point: AssignedPoint<External>, offset: &mut usize) -> Result<(), Error> {
|
||||
fn assert_is_on_curve(&self, region: &mut Region<'_, Native>, point: AssignedPoint<External>, offset: &mut usize) -> Result<(), Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn assert_equal(
|
||||
&self,
|
||||
region: &mut Region<'_, Native::ScalarExt>,
|
||||
region: &mut Region<'_, Native>,
|
||||
p0: AssignedPoint<External>,
|
||||
p1: AssignedPoint<External>,
|
||||
offset: &mut usize,
|
||||
@@ -64,7 +67,7 @@ impl<Native: CurveAffine, External: CurveAffine> ExternalEccInstruction<Native,
|
||||
|
||||
fn add(
|
||||
&self,
|
||||
region: &mut Region<'_, Native::ScalarExt>,
|
||||
region: &mut Region<'_, Native>,
|
||||
p0: AssignedPoint<External>,
|
||||
p1: AssignedPoint<External>,
|
||||
offset: &mut usize,
|
||||
@@ -72,13 +75,13 @@ impl<Native: CurveAffine, External: CurveAffine> ExternalEccInstruction<Native,
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn double(&self, region: &mut Region<'_, Native::ScalarExt>, p: AssignedPoint<External>, offset: &mut usize) -> Result<AssignedPoint<External>, Error> {
|
||||
fn double(&self, region: &mut Region<'_, Native>, p: AssignedPoint<External>, offset: &mut usize) -> Result<AssignedPoint<External>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn mul_var(
|
||||
&self,
|
||||
region: &mut Region<'_, Native::ScalarExt>,
|
||||
region: &mut Region<'_, Native>,
|
||||
p: AssignedPoint<External>,
|
||||
e: AssignedInteger<External::ScalarExt>,
|
||||
offset: &mut usize,
|
||||
@@ -88,7 +91,7 @@ impl<Native: CurveAffine, External: CurveAffine> ExternalEccInstruction<Native,
|
||||
|
||||
fn mul_fix(
|
||||
&self,
|
||||
region: &mut Region<'_, Native::ScalarExt>,
|
||||
region: &mut Region<'_, Native>,
|
||||
p: Point<External>,
|
||||
e: AssignedInteger<External::ScalarExt>,
|
||||
offset: &mut usize,
|
||||
@@ -96,3 +99,5 @@ impl<Native: CurveAffine, External: CurveAffine> ExternalEccInstruction<Native,
|
||||
unimplemented!();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -29,10 +29,10 @@ pub struct IntegerConfig {
|
||||
|
||||
pub struct IntegerChip<Wrong: FieldExt, Native: FieldExt> {
|
||||
config: IntegerConfig,
|
||||
rns: Rns<Wrong, Native>,
|
||||
pub rns: Rns<Wrong, Native>,
|
||||
}
|
||||
|
||||
trait IntegerInstructions<N: FieldExt> {
|
||||
pub trait IntegerInstructions<N: FieldExt> {
|
||||
fn assign_integer(&self, region: &mut Region<'_, N>, integer: Option<Integer<N>>, offset: &mut usize) -> Result<AssignedInteger<N>, Error>;
|
||||
fn range_assign_integer(
|
||||
&self,
|
||||
|
||||
@@ -111,6 +111,29 @@ pub trait MainGateInstructions<F: FieldExt> {
|
||||
|
||||
fn one_or_one(&self, region: &mut Region<'_, F>, a: impl Assigned<F>, b: impl Assigned<F>, offset: &mut usize) -> Result<(), Error>;
|
||||
|
||||
fn cond_or(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
c1: &AssignedCondition<F>,
|
||||
c2: &AssignedCondition<F>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedCondition<F>, Error>;
|
||||
|
||||
fn cond_and(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
c1: &AssignedCondition<F>,
|
||||
c2: &AssignedCondition<F>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedCondition<F>, Error>;
|
||||
|
||||
fn cond_not(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
c: &AssignedCondition<F>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedCondition<F>, Error>;
|
||||
|
||||
fn cond_select(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
@@ -522,6 +545,38 @@ impl<F: FieldExt> MainGateInstructions<F> for MainGate<F> {
|
||||
Ok(is_zero)
|
||||
}
|
||||
|
||||
fn cond_or(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
c1: &AssignedCondition<F>,
|
||||
c2: &AssignedCondition<F>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedCondition<F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn cond_and(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
c1: &AssignedCondition<F>,
|
||||
c2: &AssignedCondition<F>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedCondition<F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
fn cond_not(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
c: &AssignedCondition<F>,
|
||||
offset: &mut usize,
|
||||
) -> Result<AssignedCondition<F>, Error> {
|
||||
unimplemented!();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
fn cond_select(
|
||||
&self,
|
||||
region: &mut Region<'_, F>,
|
||||
|
||||
@@ -490,6 +490,12 @@ impl<F: FieldExt> Integer<F> {
|
||||
Self { limbs }
|
||||
}
|
||||
|
||||
pub fn from_bytes_le(e: &[u8], number_of_limbs: usize, bit_len: usize) -> Self {
|
||||
let x = num_bigint::BigUint::from_bytes_le(e);
|
||||
Self::from_big(x, number_of_limbs, bit_len)
|
||||
}
|
||||
|
||||
|
||||
pub fn limbs(&self) -> Vec<F> {
|
||||
self.limbs.iter().map(|limb| limb.fe()).collect()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user