mirror of https://github.com/zcash/orchard.git
mul_fixed::*: Use a separate region for complete addition assignment.
The mul_fixed regions use complete addition on the last window, and incomplete addition on all other windows. However, the complete addition does not depend on any offsets in the incomplete addition region, and can be separated into a disjoint region. Since incomplete addition uses only four advice columns, while complete addition uses nine, separating the regions would allow the layouter to optimise their placement. Co-authored-by: Jack Grigg <jack@electriccoin.co>
This commit is contained in:
parent
d0e34cd204
commit
96863c9f73
|
@ -4,7 +4,7 @@ use crate::{
|
|||
circuit::gadget::utilities::{
|
||||
bitrange_subset, copy, lookup_range_check::LookupRangeCheckConfig, CellValue, Var,
|
||||
},
|
||||
constants::{self, util::decompose_scalar_fixed, NUM_WINDOWS, T_P},
|
||||
constants::{self, util::decompose_scalar_fixed, T_P},
|
||||
primitives::sinsemilla,
|
||||
};
|
||||
use halo2::{
|
||||
|
@ -29,7 +29,7 @@ impl From<&EccConfig> for Config {
|
|||
let config = Self {
|
||||
base_field_fixed_mul: config.base_field_fixed_mul,
|
||||
base_field_fixed_canon: config.base_field_fixed_canon,
|
||||
canon_advices: [config.advices[7], config.advices[8], config.advices[9]],
|
||||
canon_advices: [config.advices[6], config.advices[7], config.advices[8]],
|
||||
lookup_config: config.lookup_config.clone(),
|
||||
super_config: config.into(),
|
||||
};
|
||||
|
@ -205,8 +205,8 @@ impl Config {
|
|||
scalar: CellValue<pallas::Base>,
|
||||
base: OrchardFixedBasesFull,
|
||||
) -> Result<EccPoint, Error> {
|
||||
let (result, scalar) = layouter.assign_region(
|
||||
|| "Base-field elem fixed-base mul",
|
||||
let (scalar, acc, mul_b) = layouter.assign_region(
|
||||
|| "Base-field elem fixed-base mul (incomplete addition)",
|
||||
|mut region| {
|
||||
let offset = 0;
|
||||
|
||||
|
@ -221,16 +221,18 @@ impl Config {
|
|||
self.base_field_fixed_mul,
|
||||
)?;
|
||||
|
||||
// Increase offset by 1 because the running sum decomposition takes
|
||||
// up 86 rows (1 more than the number of windows.)
|
||||
let offset = offset + 1;
|
||||
Ok((scalar, acc, mul_b))
|
||||
},
|
||||
)?;
|
||||
|
||||
// Add to the accumulator and return the final result as `[scalar]B`.
|
||||
let result = self.super_config.add_config.assign_region(
|
||||
&mul_b,
|
||||
&acc,
|
||||
offset + NUM_WINDOWS,
|
||||
&mut region,
|
||||
let result = layouter.assign_region(
|
||||
|| "Base-field elem fixed-base mul (complete addition)",
|
||||
|mut region| {
|
||||
self.super_config
|
||||
.add_config
|
||||
.assign_region(&mul_b, &acc, 0, &mut region)
|
||||
},
|
||||
)?;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -251,10 +253,6 @@ impl Config {
|
|||
}
|
||||
}
|
||||
|
||||
Ok((result, scalar))
|
||||
},
|
||||
)?;
|
||||
|
||||
// We want to enforce canonicity of a 255-bit base field element, α.
|
||||
// That is, we want to check that 0 ≤ α < p, where p is Pallas base
|
||||
// field modulus p = 2^254 + t_p
|
||||
|
|
|
@ -18,28 +18,32 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
|
|||
scalar: &EccScalarFixed,
|
||||
base: OrchardFixedBasesFull,
|
||||
) -> Result<EccPoint, Error> {
|
||||
layouter.assign_region(
|
||||
|| "Full-width fixed-base mul",
|
||||
let (acc, mul_b) = layouter.assign_region(
|
||||
|| "Full-width fixed-base mul (incomplete addition)",
|
||||
|mut region| {
|
||||
let offset = 0;
|
||||
|
||||
// Copy the scalar decomposition
|
||||
self.0.copy_scalar(&mut region, offset, &scalar.into())?;
|
||||
|
||||
let (acc, mul_b) = self.0.assign_region_inner(
|
||||
self.0.assign_region_inner(
|
||||
&mut region,
|
||||
offset,
|
||||
&scalar.into(),
|
||||
base.into(),
|
||||
self.0.q_mul_fixed,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
// Add to the accumulator and return the final result as `[scalar]B`.
|
||||
let result = self.0.add_config.assign_region(
|
||||
&mul_b,
|
||||
&acc,
|
||||
offset + NUM_WINDOWS,
|
||||
&mut region,
|
||||
let result = layouter.assign_region(
|
||||
|| "Full-width fixed-base mul (last window, complete addition)",
|
||||
|mut region| {
|
||||
self.0
|
||||
.add_config
|
||||
.assign_region(&mul_b, &acc, 0, &mut region)
|
||||
},
|
||||
)?;
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -57,8 +61,6 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
|
|||
}
|
||||
|
||||
Ok(result)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -57,8 +57,8 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
|
|||
scalar: &EccScalarFixedShort,
|
||||
base: &ValueCommitV,
|
||||
) -> Result<EccPoint, Error> {
|
||||
layouter.assign_region(
|
||||
|| "Short fixed-base mul",
|
||||
let (acc, mul_b) = layouter.assign_region(
|
||||
|| "Short fixed-base mul (incomplete addition)",
|
||||
|mut region| {
|
||||
let offset = 0;
|
||||
|
||||
|
@ -66,19 +66,25 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
|
|||
self.super_config
|
||||
.copy_scalar(&mut region, offset, &scalar.into())?;
|
||||
|
||||
let (acc, mul_b) = self.super_config.assign_region_inner(
|
||||
self.super_config.assign_region_inner(
|
||||
&mut region,
|
||||
offset,
|
||||
&scalar.into(),
|
||||
base.clone().into(),
|
||||
self.super_config.q_mul_fixed,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
let result = layouter.assign_region(
|
||||
|| "Short fixed-base mul (most significant word)",
|
||||
|mut region| {
|
||||
let offset = 0;
|
||||
// Add to the cumulative sum to get `[magnitude]B`.
|
||||
let magnitude_mul = self.super_config.add_config.assign_region(
|
||||
&mul_b,
|
||||
&acc,
|
||||
offset + NUM_WINDOWS,
|
||||
offset,
|
||||
&mut region,
|
||||
)?;
|
||||
|
||||
|
@ -90,7 +96,7 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
|
|||
&mut region,
|
||||
|| "sign",
|
||||
self.super_config.window,
|
||||
offset + NUM_WINDOWS,
|
||||
offset,
|
||||
&scalar.sign,
|
||||
&self.super_config.perm,
|
||||
)?;
|
||||
|
@ -107,21 +113,22 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
|
|||
};
|
||||
|
||||
// Enable mul_fixed_short selector on final row
|
||||
self.q_mul_fixed_short
|
||||
.enable(&mut region, offset + NUM_WINDOWS)?;
|
||||
self.q_mul_fixed_short.enable(&mut region, offset)?;
|
||||
|
||||
// Assign final `y` to `y_p` column and return final point
|
||||
let y_var = region.assign_advice(
|
||||
|| "y_var",
|
||||
self.super_config.y_p,
|
||||
offset + NUM_WINDOWS,
|
||||
offset,
|
||||
|| y_val.ok_or(Error::SynthesisError),
|
||||
)?;
|
||||
|
||||
let result = EccPoint {
|
||||
Ok(EccPoint {
|
||||
x: magnitude_mul.x,
|
||||
y: CellValue::new(y_var, y_val),
|
||||
};
|
||||
})
|
||||
},
|
||||
)?;
|
||||
|
||||
#[cfg(test)]
|
||||
// Check that the correct multiple is obtained.
|
||||
|
@ -130,8 +137,7 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
|
|||
|
||||
let base: super::OrchardFixedBases = base.clone().into();
|
||||
|
||||
let scalar =
|
||||
scalar
|
||||
let scalar = scalar
|
||||
.magnitude
|
||||
.zip(scalar.sign.value())
|
||||
.map(|(magnitude, sign)| {
|
||||
|
@ -153,8 +159,6 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
|
|||
}
|
||||
|
||||
Ok(result)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue