mirror of https://github.com/zcash/orchard.git
chip::mul: Refactor mul::Config.
This commit does not introduce additional circuit changes.
This commit is contained in:
parent
440cd14dbb
commit
a7dad1d611
|
@ -16,8 +16,6 @@ use halo2::{
|
|||
};
|
||||
use pasta_curves::{arithmetic::CurveAffine, pallas};
|
||||
|
||||
use std::convert::TryInto;
|
||||
|
||||
pub(super) mod add;
|
||||
pub(super) mod add_incomplete;
|
||||
pub(super) mod mul;
|
||||
|
@ -146,16 +144,8 @@ pub struct EccConfig {
|
|||
/// Complete addition
|
||||
add: add::Config,
|
||||
|
||||
/// Variable-base scalar multiplication (hi half)
|
||||
mul_hi: mul::incomplete::Config<{ mul::INCOMPLETE_HI_LEN }>,
|
||||
/// Variable-base scalar multiplication (lo half)
|
||||
mul_lo: mul::incomplete::Config<{ mul::INCOMPLETE_LO_LEN }>,
|
||||
/// Selector used to enforce boolean decomposition in variable-base scalar mul
|
||||
pub mul_complete: mul::complete::Config,
|
||||
/// Selector used to enforce switching logic on LSB in variable-base scalar mul
|
||||
pub q_mul_lsb: Selector,
|
||||
/// Variable-base scalar multiplication (overflow check)
|
||||
pub mul_overflow: mul::overflow::Config,
|
||||
/// Variable-base scalar multiplication
|
||||
mul: mul::Config,
|
||||
|
||||
/// Fixed-base full-width scalar multiplication
|
||||
pub q_mul_fixed_full: Selector,
|
||||
|
@ -223,10 +213,6 @@ impl EccChip {
|
|||
// mul_fixed::base_field_element::Config:
|
||||
// - [advices[6], advices[7], advices[8]]: canon_advices
|
||||
//
|
||||
// mul::incomplete::Config
|
||||
// - advices[4]: lambda1
|
||||
// - advices[9]: z
|
||||
//
|
||||
// TODO: Refactor away from `impl From<EccConfig> for _` so that sub-configs can
|
||||
// equality-enable the columns they need to.
|
||||
for column in &advices {
|
||||
|
@ -249,17 +235,8 @@ 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 mul_complete = mul::complete::Config::configure(meta, advices[9], add);
|
||||
let mul_overflow =
|
||||
mul::overflow::Config::configure(meta, range_check, advices[6..9].try_into().unwrap());
|
||||
// Create variable-base scalar mul gates
|
||||
let mul = mul::Config::configure(meta, add, range_check, advices);
|
||||
|
||||
let config = EccConfig {
|
||||
advices,
|
||||
|
@ -267,11 +244,7 @@ impl EccChip {
|
|||
fixed_z: meta.fixed_column(),
|
||||
add_incomplete,
|
||||
add,
|
||||
mul_hi,
|
||||
mul_lo,
|
||||
mul_complete,
|
||||
mul_overflow,
|
||||
q_mul_lsb: meta.selector(),
|
||||
mul,
|
||||
q_mul_fixed_full: meta.selector(),
|
||||
q_mul_fixed_short: meta.selector(),
|
||||
q_mul_fixed_base_field: meta.selector(),
|
||||
|
@ -281,12 +254,6 @@ impl EccChip {
|
|||
running_sum_config,
|
||||
};
|
||||
|
||||
// Create variable-base scalar mul gates
|
||||
{
|
||||
let mul_config: mul::Config = (&config).into();
|
||||
mul_config.create_gate(meta);
|
||||
}
|
||||
|
||||
// Create gate that is used both in fixed-base mul using a short signed exponent,
|
||||
// and fixed-base mul using a base field element.
|
||||
{
|
||||
|
@ -459,7 +426,7 @@ impl EccInstructions<pallas::Affine> for EccChip {
|
|||
scalar: &Self::Var,
|
||||
base: &Self::NonIdentityPoint,
|
||||
) -> Result<(Self::Point, Self::ScalarVar), Error> {
|
||||
let config: mul::Config = self.config().into();
|
||||
let config = self.config().mul;
|
||||
config.assign(
|
||||
layouter.namespace(|| "variable-base scalar mul"),
|
||||
*scalar,
|
||||
|
|
|
@ -1,27 +1,30 @@
|
|||
use super::{add, CellValue, EccConfig, EccPoint, NonIdentityEccPoint, Var};
|
||||
use super::{add, CellValue, EccPoint, NonIdentityEccPoint, Var};
|
||||
use crate::{
|
||||
circuit::gadget::utilities::{bool_check, copy, ternary},
|
||||
circuit::gadget::utilities::{
|
||||
bool_check, copy, lookup_range_check::LookupRangeCheckConfig, ternary,
|
||||
},
|
||||
constants::T_Q,
|
||||
primitives::sinsemilla,
|
||||
};
|
||||
use std::{
|
||||
convert::TryInto,
|
||||
ops::{Deref, Range},
|
||||
};
|
||||
use std::ops::{Deref, Range};
|
||||
|
||||
use bigint::U256;
|
||||
use ff::PrimeField;
|
||||
use halo2::{
|
||||
arithmetic::FieldExt,
|
||||
circuit::{Layouter, Region},
|
||||
plonk::{ConstraintSystem, Error, Selector},
|
||||
plonk::{Advice, Column, ConstraintSystem, Error, Selector},
|
||||
poly::Rotation,
|
||||
};
|
||||
|
||||
use pasta_curves::pallas;
|
||||
|
||||
// TODO: Undo this pub(crate).
|
||||
pub(crate) mod complete;
|
||||
// TODO: Undo this pub(crate).
|
||||
pub(crate) mod incomplete;
|
||||
// TODO: Undo this pub(crate).
|
||||
pub(crate) mod overflow;
|
||||
mod complete;
|
||||
mod incomplete;
|
||||
mod overflow;
|
||||
|
||||
/// Number of bits for which complete addition needs to be used in variable-base
|
||||
/// scalar multiplication
|
||||
|
@ -36,17 +39,18 @@ 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;
|
||||
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;
|
||||
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.
|
||||
const COMPLETE_RANGE: Range<usize> = INCOMPLETE_LEN..(INCOMPLETE_LEN + NUM_COMPLETE_BITS);
|
||||
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub struct Config {
|
||||
// Selector used to check switching logic on LSB
|
||||
q_mul_lsb: Selector,
|
||||
|
@ -62,17 +66,34 @@ pub struct Config {
|
|||
overflow_config: overflow::Config,
|
||||
}
|
||||
|
||||
impl From<&EccConfig> for Config {
|
||||
fn from(ecc_config: &EccConfig) -> Self {
|
||||
impl Config {
|
||||
pub(super) fn configure(
|
||||
meta: &mut ConstraintSystem<pallas::Base>,
|
||||
add_config: add::Config,
|
||||
lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
|
||||
advices: [Column<Advice>; 10],
|
||||
) -> Self {
|
||||
let hi_config = incomplete::Config::configure(
|
||||
meta, advices[9], advices[3], advices[0], advices[1], advices[4], advices[5],
|
||||
);
|
||||
let lo_config = incomplete::Config::configure(
|
||||
meta, advices[6], advices[7], advices[0], advices[1], advices[8], advices[2],
|
||||
);
|
||||
let complete_config = complete::Config::configure(meta, advices[9], add_config);
|
||||
let overflow_config =
|
||||
overflow::Config::configure(meta, lookup_config, advices[6..9].try_into().unwrap());
|
||||
|
||||
let config = Self {
|
||||
q_mul_lsb: ecc_config.q_mul_lsb,
|
||||
add_config: ecc_config.add,
|
||||
hi_config: ecc_config.mul_hi,
|
||||
lo_config: ecc_config.mul_lo,
|
||||
complete_config: ecc_config.mul_complete,
|
||||
overflow_config: ecc_config.mul_overflow,
|
||||
q_mul_lsb: meta.selector(),
|
||||
add_config,
|
||||
hi_config,
|
||||
lo_config,
|
||||
complete_config,
|
||||
overflow_config,
|
||||
};
|
||||
|
||||
config.create_gate(meta);
|
||||
|
||||
assert_eq!(
|
||||
config.hi_config.x_p, config.lo_config.x_p,
|
||||
"x_p is shared across hi and lo halves."
|
||||
|
@ -109,10 +130,8 @@ impl From<&EccConfig> for Config {
|
|||
|
||||
config
|
||||
}
|
||||
}
|
||||
|
||||
impl Config {
|
||||
pub(super) fn create_gate(&self, meta: &mut ConstraintSystem<pallas::Base>) {
|
||||
fn create_gate(&self, meta: &mut ConstraintSystem<pallas::Base>) {
|
||||
// If `lsb` is 0, (x, y) = (x_p, -y_p). If `lsb` is 1, (x, y) = (0,0).
|
||||
meta.create_gate("LSB check", |meta| {
|
||||
let q_mul_lsb = meta.query_selector(self.q_mul_lsb);
|
||||
|
|
|
@ -21,8 +21,7 @@ pub struct Config {
|
|||
}
|
||||
|
||||
impl Config {
|
||||
/// TODO: Make this pub(super).
|
||||
pub(crate) fn configure(
|
||||
pub(super) fn configure(
|
||||
meta: &mut ConstraintSystem<pallas::Base>,
|
||||
z_complete: Column<Advice>,
|
||||
add_config: add::Config,
|
||||
|
|
|
@ -29,8 +29,7 @@ pub(crate) struct Config<const NUM_BITS: usize> {
|
|||
}
|
||||
|
||||
impl<const NUM_BITS: usize> Config<NUM_BITS> {
|
||||
// TODO: Make this pub(super).
|
||||
pub(crate) fn configure(
|
||||
pub(super) fn configure(
|
||||
meta: &mut ConstraintSystem<pallas::Base>,
|
||||
z: Column<Advice>,
|
||||
x_a: Column<Advice>,
|
||||
|
|
|
@ -26,8 +26,7 @@ pub struct Config {
|
|||
}
|
||||
|
||||
impl Config {
|
||||
// TODO: Make this pub(super).
|
||||
pub(crate) fn configure(
|
||||
pub(super) fn configure(
|
||||
meta: &mut ConstraintSystem<pallas::Base>,
|
||||
lookup_config: LookupRangeCheckConfig<pallas::Base, { sinsemilla::K }>,
|
||||
advices: [Column<Advice>; 3],
|
||||
|
|
Loading…
Reference in New Issue