mirror of https://github.com/zcash/orchard.git
mul::incomplete: Refactor incomplete::Config.
This is only used in chip::mul::Config. In a subsequent commit, this will be configured from mul::Config instead of from ecc::chip::Config. This commit does not result in circuit changes.
This commit is contained in:
parent
0ede6b2301
commit
22f57005a9
|
@ -145,9 +145,9 @@ pub struct EccConfig {
|
|||
add: add::Config,
|
||||
|
||||
/// Variable-base scalar multiplication (hi half)
|
||||
pub q_mul_hi: (Selector, Selector, Selector),
|
||||
mul_hi: mul::incomplete::Config<{ mul::INCOMPLETE_HI_LEN }>,
|
||||
/// Variable-base scalar multiplication (lo half)
|
||||
pub q_mul_lo: (Selector, Selector, Selector),
|
||||
mul_lo: mul::incomplete::Config<{ mul::INCOMPLETE_LO_LEN }>,
|
||||
/// Selector used to enforce boolean decomposition in variable-base scalar mul
|
||||
pub q_mul_decompose_var: Selector,
|
||||
/// Selector used to enforce switching logic on LSB in variable-base scalar mul
|
||||
|
@ -253,14 +253,23 @@ impl EccChip {
|
|||
advices[6], advices[7], advices[8],
|
||||
);
|
||||
|
||||
// Components of mul::Config
|
||||
// TODO: Move this into mul::Config.
|
||||
let mul_hi = mul::incomplete::Config::configure(
|
||||
meta, advices[9], advices[3], advices[0], advices[1], advices[4], advices[5],
|
||||
);
|
||||
let mul_lo = mul::incomplete::Config::configure(
|
||||
meta, advices[6], advices[7], advices[0], advices[1], advices[8], advices[2],
|
||||
);
|
||||
|
||||
let config = EccConfig {
|
||||
advices,
|
||||
lagrange_coeffs,
|
||||
fixed_z: meta.fixed_column(),
|
||||
add_incomplete,
|
||||
add,
|
||||
q_mul_hi: (meta.selector(), meta.selector(), meta.selector()),
|
||||
q_mul_lo: (meta.selector(), meta.selector(), meta.selector()),
|
||||
mul_hi,
|
||||
mul_lo,
|
||||
q_mul_decompose_var: meta.selector(),
|
||||
q_mul_overflow: meta.selector(),
|
||||
q_mul_lsb: meta.selector(),
|
||||
|
|
|
@ -17,7 +17,8 @@ use halo2::{
|
|||
use pasta_curves::pallas;
|
||||
|
||||
mod complete;
|
||||
mod incomplete;
|
||||
// TODO: Undo this pub(crate).
|
||||
pub(crate) mod incomplete;
|
||||
mod overflow;
|
||||
|
||||
/// Number of bits for which complete addition needs to be used in variable-base
|
||||
|
@ -33,10 +34,12 @@ const INCOMPLETE_RANGE: Range<usize> = 0..INCOMPLETE_LEN;
|
|||
// (It is a coincidence that k_{130} matches the boundary of the
|
||||
// overflow check described in [the book](https://zcash.github.io/halo2/design/gadgets/ecc/var-base-scalar-mul.html#overflow-check).)
|
||||
const INCOMPLETE_HI_RANGE: Range<usize> = 0..(INCOMPLETE_LEN / 2);
|
||||
pub const INCOMPLETE_HI_LEN: usize = INCOMPLETE_LEN / 2;
|
||||
|
||||
// Bits k_{254} to k_{4} inclusive are used in incomplete addition.
|
||||
// The `lo` half is k_{129} to k_{4} inclusive (length 126 bits).
|
||||
const INCOMPLETE_LO_RANGE: Range<usize> = (INCOMPLETE_LEN / 2)..INCOMPLETE_LEN;
|
||||
pub const INCOMPLETE_LO_LEN: usize = (INCOMPLETE_LEN / 2) + 1;
|
||||
|
||||
// Bits k_{3} to k_{1} inclusive are used in complete addition.
|
||||
// Bit k_{0} is handled separately.
|
||||
|
@ -48,9 +51,9 @@ pub struct Config {
|
|||
// Configuration used in complete addition
|
||||
add_config: add::Config,
|
||||
// Configuration used for `hi` bits of the scalar
|
||||
hi_config: incomplete::HiConfig,
|
||||
hi_config: incomplete::Config<INCOMPLETE_HI_LEN>,
|
||||
// Configuration used for `lo` bits of the scalar
|
||||
lo_config: incomplete::LoConfig,
|
||||
lo_config: incomplete::Config<INCOMPLETE_LO_LEN>,
|
||||
// Configuration used for complete addition part of double-and-add algorithm
|
||||
complete_config: complete::Config,
|
||||
// Configuration used to check for overflow
|
||||
|
@ -62,8 +65,8 @@ impl From<&EccConfig> for Config {
|
|||
let config = Self {
|
||||
q_mul_lsb: ecc_config.q_mul_lsb,
|
||||
add_config: ecc_config.add,
|
||||
hi_config: ecc_config.into(),
|
||||
lo_config: ecc_config.into(),
|
||||
hi_config: ecc_config.mul_hi,
|
||||
lo_config: ecc_config.mul_lo,
|
||||
complete_config: ecc_config.into(),
|
||||
overflow_config: ecc_config.into(),
|
||||
};
|
||||
|
@ -81,13 +84,23 @@ impl From<&EccConfig> for Config {
|
|||
// z and lambda1 are assigned on the same row as the add_config output.
|
||||
// Therefore, z and lambda1 must not overlap with add_config.x_qr, add_config.y_qr.
|
||||
let add_config_outputs = config.add_config.output_columns();
|
||||
for config in [&(*config.hi_config), &(*config.lo_config)].iter() {
|
||||
{
|
||||
assert!(
|
||||
!add_config_outputs.contains(&config.z),
|
||||
!add_config_outputs.contains(&config.hi_config.z),
|
||||
"incomplete config z cannot overlap with complete addition columns."
|
||||
);
|
||||
assert!(
|
||||
!add_config_outputs.contains(&config.lambda1),
|
||||
!add_config_outputs.contains(&config.hi_config.lambda1),
|
||||
"incomplete config lambda1 cannot overlap with complete addition columns."
|
||||
);
|
||||
}
|
||||
{
|
||||
assert!(
|
||||
!add_config_outputs.contains(&config.lo_config.z),
|
||||
"incomplete config z cannot overlap with complete addition columns."
|
||||
);
|
||||
assert!(
|
||||
!add_config_outputs.contains(&config.lo_config.lambda1),
|
||||
"incomplete config lambda1 cannot overlap with complete addition columns."
|
||||
);
|
||||
}
|
||||
|
@ -98,8 +111,6 @@ impl From<&EccConfig> for Config {
|
|||
|
||||
impl Config {
|
||||
pub(super) fn create_gate(&self, meta: &mut ConstraintSystem<pallas::Base>) {
|
||||
self.hi_config.create_gate(meta);
|
||||
self.lo_config.create_gate(meta);
|
||||
self.complete_config.create_gate(meta);
|
||||
self.overflow_config.create_gate(meta);
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
use std::ops::Deref;
|
||||
|
||||
use super::super::{copy, CellValue, EccConfig, NonIdentityEccPoint, Var};
|
||||
use super::{INCOMPLETE_HI_RANGE, INCOMPLETE_LO_RANGE, X, Y, Z};
|
||||
use super::super::{copy, CellValue, NonIdentityEccPoint, Var};
|
||||
use super::{X, Y, Z};
|
||||
use crate::circuit::gadget::utilities::bool_check;
|
||||
use ff::Field;
|
||||
use halo2::{
|
||||
|
@ -12,10 +10,8 @@ use halo2::{
|
|||
|
||||
use pasta_curves::{arithmetic::FieldExt, pallas};
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
pub(super) struct Config {
|
||||
// Number of bits covered by this incomplete range.
|
||||
num_bits: usize,
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub(crate) struct Config<const NUM_BITS: usize> {
|
||||
// Selectors used to constrain the cells used in incomplete addition.
|
||||
pub(super) q_mul: (Selector, Selector, Selector),
|
||||
// Cumulative sum used to decompose the scalar.
|
||||
|
@ -32,61 +28,37 @@ pub(super) struct Config {
|
|||
pub(super) lambda2: Column<Advice>,
|
||||
}
|
||||
|
||||
// Columns used in processing the `hi` bits of the scalar.
|
||||
// `x_p, y_p` are shared across the `hi` and `lo` halves.
|
||||
pub(super) struct HiConfig(Config);
|
||||
impl From<&EccConfig> for HiConfig {
|
||||
fn from(ecc_config: &EccConfig) -> Self {
|
||||
let config = Config {
|
||||
num_bits: INCOMPLETE_HI_RANGE.len(),
|
||||
q_mul: ecc_config.q_mul_hi,
|
||||
x_p: ecc_config.advices[0],
|
||||
y_p: ecc_config.advices[1],
|
||||
z: ecc_config.advices[9],
|
||||
x_a: ecc_config.advices[3],
|
||||
lambda1: ecc_config.advices[4],
|
||||
lambda2: ecc_config.advices[5],
|
||||
impl<const NUM_BITS: usize> Config<NUM_BITS> {
|
||||
// TODO: Make this pub(super).
|
||||
pub(crate) fn configure(
|
||||
meta: &mut ConstraintSystem<pallas::Base>,
|
||||
z: Column<Advice>,
|
||||
x_a: Column<Advice>,
|
||||
x_p: Column<Advice>,
|
||||
y_p: Column<Advice>,
|
||||
lambda1: Column<Advice>,
|
||||
lambda2: Column<Advice>,
|
||||
) -> Self {
|
||||
meta.enable_equality(z.into());
|
||||
meta.enable_equality(lambda1.into());
|
||||
|
||||
let config = Self {
|
||||
q_mul: (meta.selector(), meta.selector(), meta.selector()),
|
||||
z,
|
||||
x_a,
|
||||
x_p,
|
||||
y_p,
|
||||
lambda1,
|
||||
lambda2,
|
||||
};
|
||||
Self(config)
|
||||
}
|
||||
}
|
||||
impl Deref for HiConfig {
|
||||
type Target = Config;
|
||||
|
||||
fn deref(&self) -> &Config {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
config.create_gate(meta);
|
||||
|
||||
// Columns used in processing the `lo` bits of the scalar.
|
||||
// `x_p, y_p` are shared across the `hi` and `lo` halves.
|
||||
pub(super) struct LoConfig(Config);
|
||||
impl From<&EccConfig> for LoConfig {
|
||||
fn from(ecc_config: &EccConfig) -> Self {
|
||||
let config = Config {
|
||||
num_bits: INCOMPLETE_LO_RANGE.len(),
|
||||
q_mul: ecc_config.q_mul_lo,
|
||||
x_p: ecc_config.advices[0],
|
||||
y_p: ecc_config.advices[1],
|
||||
z: ecc_config.advices[6],
|
||||
x_a: ecc_config.advices[7],
|
||||
lambda1: ecc_config.advices[8],
|
||||
lambda2: ecc_config.advices[2],
|
||||
};
|
||||
Self(config)
|
||||
config
|
||||
}
|
||||
}
|
||||
impl Deref for LoConfig {
|
||||
type Target = Config;
|
||||
|
||||
fn deref(&self) -> &Config {
|
||||
&self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
// Gate for incomplete addition part of variable-base scalar multiplication.
|
||||
pub(super) fn create_gate(&self, meta: &mut ConstraintSystem<pallas::Base>) {
|
||||
fn create_gate(&self, meta: &mut ConstraintSystem<pallas::Base>) {
|
||||
// Closure to compute x_{R,i} = λ_{1,i}^2 - x_{A,i} - x_{P,i}
|
||||
let x_r = |meta: &mut VirtualCells<pallas::Base>, rotation: Rotation| {
|
||||
let x_a = meta.query_advice(self.x_a, rotation);
|
||||
|
@ -216,7 +188,7 @@ impl Config {
|
|||
acc: (X<pallas::Base>, Y<pallas::Base>, Z<pallas::Base>),
|
||||
) -> Result<(X<pallas::Base>, Y<pallas::Base>, Vec<Z<pallas::Base>>), Error> {
|
||||
// Check that we have the correct number of bits for this double-and-add.
|
||||
assert_eq!(bits.len(), self.num_bits);
|
||||
assert_eq!(bits.len(), NUM_BITS);
|
||||
|
||||
// Handle exceptional cases
|
||||
let (x_p, y_p) = (base.x.value(), base.y.value());
|
||||
|
@ -241,12 +213,12 @@ impl Config {
|
|||
|
||||
let offset = offset + 1;
|
||||
// q_mul_2 = 1 on all rows after offset 0, excluding the last row.
|
||||
for idx in 0..(self.num_bits - 1) {
|
||||
for idx in 0..(NUM_BITS - 1) {
|
||||
self.q_mul.1.enable(region, offset + idx)?;
|
||||
}
|
||||
|
||||
// q_mul_3 = 1 on the last row.
|
||||
self.q_mul.2.enable(region, offset + self.num_bits - 1)?;
|
||||
self.q_mul.2.enable(region, offset + NUM_BITS - 1)?;
|
||||
}
|
||||
|
||||
// Initialise double-and-add
|
||||
|
@ -361,7 +333,7 @@ impl Config {
|
|||
let cell = region.assign_advice(
|
||||
|| "y_a",
|
||||
self.lambda1,
|
||||
offset + self.num_bits,
|
||||
offset + NUM_BITS,
|
||||
|| y_a.ok_or(Error::Synthesis),
|
||||
)?;
|
||||
CellValue::new(cell, y_a)
|
||||
|
|
Loading…
Reference in New Issue