Skip to content

Commit

Permalink
Further type cleanups
Browse files Browse the repository at this point in the history
  • Loading branch information
therealyingtong committed Feb 23, 2021
1 parent d3519ee commit 04e95cc
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 43 deletions.
15 changes: 6 additions & 9 deletions src/gadget/sinsemilla.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ pub trait SinsemillaInstructions<F: FieldExt>: Chip<Field = F> {

#[test]
fn test_sinsemilla() {
use crate::arithmetic::{CurveAffine, FieldExt};
use crate::arithmetic::CurveAffine;
use crate::circuit::layouter::SingleChip;
use crate::pasta::{EpAffine, EqAffine};
use crate::plonk::*;
Expand All @@ -64,10 +64,7 @@ fn test_sinsemilla() {
}

impl<'a, C: Chip, CS: Assignment<C::Field>> SingleChip<'a, C, CS> {
fn load_new<Cu: CurveAffine<Base = C::Field>>(
cs: &'a mut CS,
config: C::Config,
) -> Result<Self, Error> {
fn load_new(cs: &'a mut CS, config: C::Config) -> Result<Self, Error> {
let mut res = SingleChip::new(cs, config);

C::load(&mut res)?;
Expand All @@ -76,10 +73,10 @@ fn test_sinsemilla() {
}
}

impl<F: FieldExt, C: CurveAffine<Base = F>> Circuit<F> for MyCircuit<C> {
impl<C: CurveAffine> Circuit<C::Base> for MyCircuit<C> {
type Config = SinsemillaConfig;

fn configure(meta: &mut ConstraintSystem<F>) -> Self::Config {
fn configure(meta: &mut ConstraintSystem<C::Base>) -> Self::Config {
let columns = SinsemillaColumns::new(
meta.fixed_column(),
meta.advice_column(),
Expand All @@ -94,10 +91,10 @@ fn test_sinsemilla() {

fn synthesize(
&self,
cs: &mut impl Assignment<F>,
cs: &mut impl Assignment<C::Base>,
config: Self::Config,
) -> Result<(), Error> {
let mut layouter = SingleChip::load_new::<C>(cs, config)?;
let mut layouter = SingleChip::load_new(cs, config)?;

SinsemillaChip::<C>::hash(&mut layouter, self.message.clone())?;

Expand Down
43 changes: 22 additions & 21 deletions src/gadget/sinsemilla/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use crate::{
poly::Rotation,
};

use ff::Field;
use group::Curve;

mod generator_table;
Expand Down Expand Up @@ -62,10 +63,10 @@ pub struct SinsemillaChip<C: CurveAffine> {
_marker_c: PhantomData<C>,
}

impl<F: FieldExt, C: CurveAffine<Base = F>> SinsemillaChip<C> {
impl<C: CurveAffine> SinsemillaChip<C> {
/// Configures this chip for use in a circuit.
pub fn configure(
meta: &mut ConstraintSystem<F>,
meta: &mut ConstraintSystem<C::Base>,
k: usize,
rounds: usize,
columns: SinsemillaColumns,
Expand All @@ -77,7 +78,7 @@ impl<F: FieldExt, C: CurveAffine<Base = F>> SinsemillaChip<C> {
// m_i = z_{i + 1} - (z_i * 2^k)
let z_cur = meta.query_advice(columns.z, Rotation::cur());
let z_next = meta.query_advice(columns.z, Rotation::next());
let m = z_next - z_cur * F::from_u64((1 << k) as u64);
let m = z_next - z_cur * C::Base::from_u64((1 << k) as u64);

// y_a = (1/2) ⋅ (lambda1 + lambda2) ⋅ (x_a - (lambda1^2 - x_a - x_p))
let lambda1_cur = meta.query_advice(columns.lambda1, Rotation::cur());
Expand All @@ -87,22 +88,22 @@ impl<F: FieldExt, C: CurveAffine<Base = F>> SinsemillaChip<C> {
let y_a_cur = (lambda1_cur.clone() + lambda2_cur.clone())
* (x_a_cur.clone()
- (lambda1_cur.clone() * lambda1_cur.clone() - x_a_cur.clone() - x_p_cur.clone()))
* F::TWO_INV;
* C::Base::TWO_INV;

// y_p = y_a - lambda1 ⋅ (x_a - x_p)
let y_p = y_a_cur.clone() - lambda1_cur.clone() * (x_a_cur.clone() - x_p_cur.clone());

let (x_p_init, y_p_init) = get_s_by_idx::<F, C>(0).to_affine().get_xy().unwrap();
let (x_p_init, y_p_init) = get_s_by_idx::<C>(0).to_affine().get_xy().unwrap();

let lookup_table = GeneratorTable::configure::<F, C>(
let lookup_table = GeneratorTable::configure::<C>(
meta,
k,
sinsemilla_cur.clone() * m
+ (Expression::Constant(F::one()) - sinsemilla_cur.clone()) * F::zero(),
+ (Expression::Constant(C::Base::one()) - sinsemilla_cur.clone()) * C::Base::zero(),
sinsemilla_cur.clone() * x_p_cur.clone()
+ (Expression::Constant(F::one()) - sinsemilla_cur.clone()) * x_p_init,
+ (Expression::Constant(C::Base::one()) - sinsemilla_cur.clone()) * x_p_init,
sinsemilla_cur.clone() * y_p
+ (Expression::Constant(F::one()) - sinsemilla_cur.clone()) * y_p_init,
+ (Expression::Constant(C::Base::one()) - sinsemilla_cur.clone()) * y_p_init,
);

let lambda1_next = meta.query_advice(columns.lambda1, Rotation::next());
Expand All @@ -112,7 +113,7 @@ impl<F: FieldExt, C: CurveAffine<Base = F>> SinsemillaChip<C> {
let y_a_next = (lambda1_next.clone() + lambda2_next)
* (x_a_next.clone()
- (lambda1_next.clone() * lambda1_next - x_a_next.clone() - x_p_next))
* F::TWO_INV;
* C::Base::TWO_INV;

// Sinsemilla expr1 gate
meta.create_gate("Sinsemilla expr1", |_| {
Expand Down Expand Up @@ -152,11 +153,11 @@ impl<C: CurveAffine> Chip for SinsemillaChip<C> {
}
}

impl<F: FieldExt, C: CurveAffine<Base = F>> SinsemillaInstructions<F> for SinsemillaChip<C> {
impl<C: CurveAffine> SinsemillaInstructions<C::Base> for SinsemillaChip<C> {
type Message = Vec<bool>;
type HashOutput = C;

fn q() -> (F, F) {
fn q() -> (C::Base, C::Base) {
let hash = C::CurveExt::hash_to_curve(Q_DOMAIN_PREFIX);
let q = hash(&Q_PERSONALIZATION).to_affine();
q.get_xy().unwrap()
Expand Down Expand Up @@ -195,13 +196,12 @@ impl<F: FieldExt, C: CurveAffine<Base = F>> SinsemillaInstructions<F> for Sinsem
let words = words;

// Get (x_p, y_p) for each word. We precompute this here so that we can use `batch_normalize()`.
let generators_projective: Vec<_> = words
.iter()
.map(|word| get_s_by_idx::<F, C>(*word))
.collect();
let generators_projective: Vec<_> =
words.iter().map(|word| get_s_by_idx::<C>(*word)).collect();
let mut generators = vec![C::default(); generators_projective.len()];
C::Curve::batch_normalize(&generators_projective, &mut generators);
let generators: Vec<(F, F)> = generators.iter().map(|gen| gen.get_xy().unwrap()).collect();
let generators: Vec<(C::Base, C::Base)> =
generators.iter().map(|gen| gen.get_xy().unwrap()).collect();

// Initialize `(x_a, y_a)` to be `(x_q, y_q)`
let (mut x_a, mut y_a) = Self::q();
Expand All @@ -222,12 +222,12 @@ impl<F: FieldExt, C: CurveAffine<Base = F>> SinsemillaInstructions<F> for Sinsem
|| "Sinsemilla expr1",
config.columns.sinsemilla,
row,
|| Ok(F::one()),
|| Ok(C::Base::one()),
)?;
}

// Assign initialized values
region.assign_advice(|| "z_0", config.columns.z, 0, || Ok(F::from_u64(z)))?;
region.assign_advice(|| "z_0", config.columns.z, 0, || Ok(C::Base::from_u64(z)))?;
region.assign_advice(|| "x_q", config.columns.x_a, 0, || Ok(x_a))?;

for row in 0..config.rounds {
Expand All @@ -245,13 +245,14 @@ impl<F: FieldExt, C: CurveAffine<Base = F>> SinsemillaInstructions<F> for Sinsem
|| "z",
config.columns.z,
row + 1,
|| Ok(F::from_u64(z)),
|| Ok(C::Base::from_u64(z)),
)?;

// Compute and assign `lambda1, lambda2`
let lambda1 = (y_a - y_p) * (x_a - x_p).invert().unwrap();
let x_r = lambda1 * lambda1 - x_a - x_p;
let lambda2 = F::from_u64(2) * y_a * (x_a - x_r).invert().unwrap() - lambda1;
let lambda2 =
C::Base::from_u64(2) * y_a * (x_a - x_r).invert().unwrap() - lambda1;
region.assign_advice(
|| "lambda1",
config.columns.lambda1,
Expand Down
27 changes: 14 additions & 13 deletions src/gadget/sinsemilla/chip/generator_table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::{
poly::Rotation,
};

use ff::Field;
use group::Curve;

/// Table containing independent generators P[0..2^k]
Expand All @@ -19,12 +20,12 @@ pub(super) struct GeneratorTable {
}

impl GeneratorTable {
pub(super) fn configure<F: FieldExt, C: CurveAffine<Base = F>>(
meta: &mut ConstraintSystem<F>,
pub(super) fn configure<C: CurveAffine>(
meta: &mut ConstraintSystem<C::Base>,
k: usize,
m: Expression<F>,
x_p: Expression<F>,
y_p: Expression<F>,
m: Expression<C::Base>,
x_p: Expression<C::Base>,
y_p: Expression<C::Base>,
) -> Self {
let table_idx = meta.fixed_column();
let table_idx_cur = meta.query_fixed(table_idx, Rotation::cur());
Expand All @@ -46,17 +47,17 @@ impl GeneratorTable {
// Generates P[0..2^k] as 2^k independent, verifiably random generators of the group.
// Loads these generators into a lookup table along with their indices.
// Uses SWU hash-to-curve.
fn generate<F: FieldExt, C: CurveAffine<Base = F>>(&self) -> impl Iterator<Item = (F, F, F)> {
let (init_x, init_y) = get_s_by_idx::<F, C>(0).to_affine().get_xy().unwrap();
fn generate<C: CurveAffine>(&self) -> impl Iterator<Item = (C::Base, C::Base, C::Base)> {
let (init_x, init_y) = get_s_by_idx::<C>(0).to_affine().get_xy().unwrap();

(1..=(1 << self.k)).scan((F::zero(), init_x, init_y), move |(idx, x, y), i| {
(1..=(1 << self.k)).scan((C::Base::zero(), init_x, init_y), move |(idx, x, y), i| {
// We computed this table row in the previous iteration.
let res = (*idx, *x, *y);

// i holds the zero-indexed row number for the next table row.
*idx = F::from_u64(i as u64);
*idx = C::Base::from_u64(i as u64);

let (new_x, new_y) = get_s_by_idx::<F, C>(i).to_affine().get_xy().unwrap();
let (new_x, new_y) = get_s_by_idx::<C>(i).to_affine().get_xy().unwrap();

*x = new_x;
*y = new_y;
Expand All @@ -65,15 +66,15 @@ impl GeneratorTable {
})
}

pub(super) fn load<F: FieldExt, C: CurveAffine<Base = F>>(
pub(super) fn load<C: CurveAffine>(
&self,
layouter: &mut impl Layouter<SinsemillaChip<C>>,
) -> Result<(), Error> {
layouter.assign_region(
|| "generator_table",
|mut gate| {
// We generate the row values lazily (we only need them during keygen).
let mut rows = self.generate::<F, C>();
let mut rows = self.generate::<C>();

for index in 0..(1 << self.k) {
let mut row = None;
Expand Down Expand Up @@ -106,7 +107,7 @@ impl GeneratorTable {
}

/// Get generator S by index
pub fn get_s_by_idx<F: FieldExt, C: CurveAffine<Base = F>>(idx: u64) -> C::Curve {
pub fn get_s_by_idx<C: CurveAffine>(idx: u64) -> C::Curve {
let hash = C::CurveExt::hash_to_curve(S_DOMAIN_PREFIX);
hash(&idx.to_le_bytes())
}

0 comments on commit 04e95cc

Please sign in to comment.