Skip to content

Commit

Permalink
[WIP] Configure Sinsemilla chip
Browse files Browse the repository at this point in the history
  • Loading branch information
therealyingtong committed Apr 1, 2021
1 parent cf400c9 commit bcec210
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 45 deletions.
88 changes: 44 additions & 44 deletions src/circuit/gadget/ecc/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,49 +47,49 @@ impl<F: FieldExt> CellValue<F> {
#[derive(Clone, Debug)]
#[allow(non_snake_case)]
pub struct EccConfig {
// Advice column for scalar decomposition into bits
bits: Column<Advice>,
// Witness u = (y + z).sqrt(), used in fixed-base scalar multiplication
u: Column<Advice>,
// Holds a point (x_a, y_a) that is usually the result of an addition
A: (Column<Advice>, Column<Advice>),
// Holds a point (x_p, y_p)
P: (Column<Advice>, Column<Advice>),
// A pair (lambda1, lambda2) representing gradients
lambda: (Column<Advice>, Column<Advice>),
// [A, B, C, D] boolean flags used in complete addition
add_complete_bool: [Column<Advice>; 4],
// [alpha, beta, gamma, delta] inverses used in complete addition
add_complete_inv: [Column<Advice>; 4],
// Coefficients of interpolation polynomials for x-coordinates (used in fixed-base scalar multiplication)
lagrange_coeffs: [Column<Fixed>; constants::H],
// Fixed z such that y + z = u^2 some square, and -y + z is a non-square. (Used in fixed-base scalar multiplication)
fixed_z: Column<Fixed>,

// Incomplete addition
q_add: Selector,
// Complete addition
q_add_complete: Selector,
// Point doubling
q_double: Selector,
// Variable-base scalar multiplication
q_mul: Selector,
// Fixed-base full-width scalar multiplication
q_mul_fixed: Selector,
// Fixed-base signed short scalar multiplication
q_mul_fixed_short: Selector,
// Witness point
q_point: Selector,
// Witness scalar for variable-base scalar mul
q_scalar_var: Selector,
// Witness full-width scalar for fixed-base scalar mul
q_scalar_fixed: Selector,
// Witness signed short scalar for full-width fixed-base scalar mul
q_scalar_fixed_short: Selector,
// Copy bits of decomposed scalars
perm_scalar: Permutation,
// Copy between (x_p, y_p) and (x_a, y_a)
perm_sum: Permutation,
/// Advice column for scalar decomposition into bits
pub bits: Column<Advice>,
/// Witness u = (y + z).sqrt(), used in fixed-base scalar multiplication
pub u: Column<Advice>,
/// Holds a point (x_a, y_a) that is usually the result of an addition
pub A: (Column<Advice>, Column<Advice>),
/// Holds a point (x_p, y_p)
pub P: (Column<Advice>, Column<Advice>),
/// A pair (lambda1, lambda2) representing gradients
pub lambda: (Column<Advice>, Column<Advice>),
/// [A, B, C, D] boolean flags used in complete addition
pub add_complete_bool: [Column<Advice>; 4],
/// [alpha, beta, gamma, delta] inverses used in complete addition
pub add_complete_inv: [Column<Advice>; 4],
/// Coefficients of interpolation polynomials for x-coordinates (used in fixed-base scalar multiplication)
pub lagrange_coeffs: [Column<Fixed>; constants::H],
/// Fixed z such that y + z = u^2 some square, and -y + z is a non-square. (Used in fixed-base scalar multiplication)
pub fixed_z: Column<Fixed>,

/// Incomplete addition
pub q_add: Selector,
/// Complete addition
pub q_add_complete: Selector,
/// Point doubling
pub q_double: Selector,
/// Variable-base scalar multiplication
pub q_mul: Selector,
/// Fixed-base full-width scalar multiplication
pub q_mul_fixed: Selector,
/// Fixed-base signed short scalar multiplication
pub q_mul_fixed_short: Selector,
/// Witness point
pub q_point: Selector,
/// Witness scalar for variable-base scalar mul
pub q_scalar_var: Selector,
/// Witness full-width scalar for fixed-base scalar mul
pub q_scalar_fixed: Selector,
/// Witness signed short scalar for full-width fixed-base scalar mul
pub q_scalar_fixed_short: Selector,
/// Copy bits of decomposed scalars
pub perm_scalar: Permutation,
/// Copy between (x_p, y_p) and (x_a, y_a)
pub perm_sum: Permutation,
}

/// A chip implementing EccInstructions
Expand All @@ -100,7 +100,7 @@ pub struct EccChip<C: CurveAffine> {

#[allow(non_snake_case)]
impl<C: CurveAffine> EccChip<C> {
fn configure(
pub fn configure(
meta: &mut ConstraintSystem<C::Base>,
bits: Column<Advice>,
u: Column<Advice>,
Expand Down
83 changes: 82 additions & 1 deletion src/circuit/gadget/sinsemilla/chip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,15 @@ use super::super::ecc::chip::{EccChip, EccConfig};
use super::{CommitDomains, HashDomains, SinsemillaInstructions};

use crate::constants::OrchardFixedBases;
use crate::primitives::sinsemilla::K;

use ff::Field;
use group::Curve;
use halo2::{
arithmetic::{CurveAffine, FieldExt},
circuit::{Cell, Layouter},
plonk::{Error, Selector},
plonk::{Advice, Column, ConstraintSystem, Error, Expression, Selector},
poly::Rotation,
};

mod generator_table;
Expand Down Expand Up @@ -92,6 +97,82 @@ impl<C: CurveAffine> CommitDomains<C, OrchardFixedBases<C>, OrchardHashDomains<C
}
}

/// Configuration for the ECC chip
#[derive(Clone, Debug)]
#[allow(non_snake_case)]
pub struct SinsemillaConfig {
ecc_config: EccConfig,
generator_table: GeneratorTable,
q_sinsemilla: Selector,
}

#[allow(non_snake_case)]
impl<C: CurveAffine> EccChip<C> {
fn configure_sinsemilla(
meta: &mut ConstraintSystem<C::Base>,
q_sinsemilla: Selector,
bits: Column<Advice>,
u: Column<Advice>,
A: (Column<Advice>, Column<Advice>),
P: (Column<Advice>, Column<Advice>),
lambda: (Column<Advice>, Column<Advice>),
add_complete_bool: [Column<Advice>; 4],
add_complete_inv: [Column<Advice>; 4],
) -> SinsemillaConfig {
let ecc_config = EccChip::<C>::configure(
meta,
bits,
u,
A,
P,
lambda,
add_complete_bool,
add_complete_inv,
);

// Fixed column for Sinsemilla selector
let sinsemilla_cur = meta.query_selector(q_sinsemilla, Rotation::cur());

// m_i = z_{i + 1} - (z_i * 2^k)
let z_cur = meta.query_advice(ecc_config.bits, Rotation::cur());
let z_next = meta.query_advice(ecc_config.bits, Rotation::next());
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(ecc_config.lambda.0, Rotation::cur());
let lambda2_cur = meta.query_advice(ecc_config.lambda.1, Rotation::cur());
let x_a_cur = meta.query_advice(ecc_config.A.0, Rotation::cur());
let x_p_cur = meta.query_advice(ecc_config.P.0, Rotation::cur());
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()))
* 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::<C>(0).to_affine().get_xy().unwrap();

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

// TODO: create gates

SinsemillaConfig {
ecc_config,
generator_table,
q_sinsemilla,
}
}
}

impl<C: CurveAffine> SinsemillaInstructions<C> for EccChip<C> {
type Message = Message<C::Base>;
type CommitDomains = OrchardCommitDomains<C>;
Expand Down

0 comments on commit bcec210

Please sign in to comment.