Update mul_fixed_* APIs to take Layouter instead of Region.

These APIs are not called internally.
This commit is contained in:
therealyingtong 2021-07-07 11:26:32 +08:00
parent d550e156d9
commit 2d343af068
4 changed files with 187 additions and 163 deletions

View File

@ -449,9 +449,10 @@ impl EccInstructions<pallas::Affine> for EccChip {
) -> Result<Self::Point, Error> {
let config: mul_fixed::full_width::Config<{ constants::NUM_WINDOWS }> =
self.config().into();
layouter.assign_region(
|| format!("fixed-base mul of {:?}", base),
|mut region| config.assign_region(scalar, *base, 0, &mut region),
config.assign(
layouter.namespace(|| format!("fixed-base mul of {:?}", base)),
scalar,
*base,
)
}
@ -463,9 +464,10 @@ impl EccInstructions<pallas::Affine> for EccChip {
) -> Result<Self::Point, Error> {
let config: mul_fixed::short::Config<{ constants::NUM_WINDOWS_SHORT }> =
self.config().into();
layouter.assign_region(
|| format!("short fixed-base mul of {:?}", base),
|mut region| config.assign_region(scalar, base, 0, &mut region),
config.assign(
layouter.namespace(|| format!("short fixed-base mul of {:?}", base)),
scalar,
base,
)
}
@ -476,9 +478,10 @@ impl EccInstructions<pallas::Affine> for EccChip {
base: &Self::FixedPoints,
) -> Result<Self::Point, Error> {
let config: mul_fixed::base_field_elem::Config = self.config().into();
layouter.assign_region(
|| format!("base field elem fixed-base mul of {:?}", base),
|mut region| config.assign_region(base_field_elem, *base, 0, &mut region),
config.assign(
layouter.namespace(|| format!("base-field elem fixed-base mul of {:?}", base)),
base_field_elem,
*base,
)
}
}

View File

@ -5,7 +5,7 @@ use crate::{
constants::{self, util::decompose_scalar_fixed, NUM_WINDOWS},
};
use halo2::{
circuit::Region,
circuit::{Layouter, Region},
plonk::{Column, ConstraintSystem, Error, Expression, Fixed},
poly::Rotation,
};
@ -99,55 +99,61 @@ impl Config {
});
}
pub fn assign_region(
pub fn assign(
&self,
mut layouter: impl Layouter<pallas::Base>,
scalar: CellValue<pallas::Base>,
base: OrchardFixedBasesFull,
offset: usize,
region: &mut Region<'_, pallas::Base>,
) -> Result<EccPoint, Error> {
// Decompose scalar
let scalar = self.decompose_base_field_elem(scalar, offset, region)?;
layouter.assign_region(
|| "Base-field elem fixed-base mul",
|mut region| {
let offset = 0;
let (acc, mul_b) = self.super_config.assign_region_inner(
region,
offset,
&(&scalar).into(),
base.into(),
self.base_field_fixed,
)?;
// Decompose scalar
let scalar = self.decompose_base_field_elem(scalar, offset, &mut region)?;
// Increase offset by 1 because the running sum decomposition takes
// up 86 rows (1 more than the number of windows.)
let offset = offset + 1;
let (acc, mul_b) = self.super_config.assign_region_inner(
&mut region,
offset,
&(&scalar).into(),
base.into(),
self.base_field_fixed,
)?;
// 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,
region,
)?;
// Increase offset by 1 because the running sum decomposition takes
// up 86 rows (1 more than the number of windows.)
let offset = offset + 1;
#[cfg(test)]
// Check that the correct multiple is obtained.
{
use group::Curve;
// 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 base: super::OrchardFixedBases = base.into();
let scalar = &scalar
.base_field_elem()
.value()
.map(|scalar| pallas::Scalar::from_bytes(&scalar.to_bytes()).unwrap());
let real_mul = scalar.map(|scalar| base.generator() * scalar);
let result = result.point();
#[cfg(test)]
// Check that the correct multiple is obtained.
{
use group::Curve;
if let (Some(real_mul), Some(result)) = (real_mul, result) {
assert_eq!(real_mul.to_affine(), result);
}
}
let base: super::OrchardFixedBases = base.into();
let scalar = &scalar
.base_field_elem()
.value()
.map(|scalar| pallas::Scalar::from_bytes(&scalar.to_bytes()).unwrap());
let real_mul = scalar.map(|scalar| base.generator() * scalar);
let result = result.point();
Ok(result)
if let (Some(real_mul), Some(result)) = (real_mul, result) {
assert_eq!(real_mul.to_affine(), result);
}
}
Ok(result)
},
)
}
fn decompose_base_field_elem(

View File

@ -1,6 +1,6 @@
use super::super::{EccConfig, EccPoint, EccScalarFixed, OrchardFixedBasesFull};
use halo2::{circuit::Region, plonk::Error};
use halo2::{circuit::Layouter, plonk::Error};
use pasta_curves::pallas;
pub struct Config<const NUM_WINDOWS: usize>(super::Config<NUM_WINDOWS>);
@ -12,45 +12,53 @@ impl<const NUM_WINDOWS: usize> From<&EccConfig> for Config<NUM_WINDOWS> {
}
impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
pub fn assign_region(
pub fn assign(
&self,
mut layouter: impl Layouter<pallas::Base>,
scalar: &EccScalarFixed,
base: OrchardFixedBasesFull,
offset: usize,
region: &mut Region<'_, pallas::Base>,
) -> Result<EccPoint, Error> {
// Copy the scalar decomposition
self.0.copy_scalar(region, offset, &scalar.into())?;
layouter.assign_region(
|| "Full-width fixed-base mul",
|mut region| {
let offset = 0;
let (acc, mul_b) = self.0.assign_region_inner(
region,
offset,
&scalar.into(),
base.into(),
self.0.mul_fixed,
)?;
// Copy the scalar decomposition
self.0.copy_scalar(&mut region, offset, &scalar.into())?;
// 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, region)?;
let (acc, mul_b) = self.0.assign_region_inner(
&mut region,
offset,
&scalar.into(),
base.into(),
self.0.mul_fixed,
)?;
#[cfg(test)]
// Check that the correct multiple is obtained.
{
use group::Curve;
// 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 base: super::OrchardFixedBases = base.into();
let real_mul = scalar.value.map(|scalar| base.generator() * scalar);
let result = result.point();
#[cfg(test)]
// Check that the correct multiple is obtained.
{
use group::Curve;
if let (Some(real_mul), Some(result)) = (real_mul, result) {
assert_eq!(real_mul.to_affine(), result);
}
}
let base: super::OrchardFixedBases = base.into();
let real_mul = scalar.value.map(|scalar| base.generator() * scalar);
let result = result.point();
Ok(result)
if let (Some(real_mul), Some(result)) = (real_mul, result) {
assert_eq!(real_mul.to_affine(), result);
}
}
Ok(result)
},
)
}
}

View File

@ -4,7 +4,7 @@ use super::super::{copy, CellValue, EccConfig, EccPoint, EccScalarFixedShort, Va
use crate::constants::ValueCommitV;
use halo2::{
circuit::Region,
circuit::Layouter,
plonk::{ConstraintSystem, Error, Selector},
poly::Rotation,
};
@ -51,103 +51,110 @@ impl<const NUM_WINDOWS: usize> Config<NUM_WINDOWS> {
});
}
pub fn assign_region(
pub fn assign(
&self,
mut layouter: impl Layouter<pallas::Base>,
scalar: &EccScalarFixedShort,
base: &ValueCommitV,
offset: usize,
region: &mut Region<'_, pallas::Base>,
) -> Result<EccPoint, Error> {
// Copy the scalar decomposition
self.super_config
.copy_scalar(region, offset, &scalar.into())?;
layouter.assign_region(
|| "Short fixed-base mul",
|mut region| {
let offset = 0;
let (acc, mul_b) = self.super_config.assign_region_inner(
region,
offset,
&scalar.into(),
base.clone().into(),
self.super_config.mul_fixed,
)?;
// Copy the scalar decomposition
self.super_config
.copy_scalar(&mut region, offset, &scalar.into())?;
// 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,
region,
)?;
let (acc, mul_b) = self.super_config.assign_region_inner(
&mut region,
offset,
&scalar.into(),
base.clone().into(),
self.super_config.mul_fixed,
)?;
// Increase offset by 1 after complete addition
let offset = offset + 1;
// 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,
&mut region,
)?;
// Assign sign to `window` column
let sign = copy(
region,
|| "sign",
self.super_config.window,
offset + NUM_WINDOWS,
&scalar.sign,
&self.super_config.perm,
)?;
// Increase offset by 1 after complete addition
let offset = offset + 1;
// Conditionally negate `y`-coordinate
let y_val = if let Some(sign) = sign.value() {
if sign == -pallas::Base::one() {
magnitude_mul.y.value().map(|y: pallas::Base| -y)
} else {
magnitude_mul.y.value()
}
} else {
None
};
// Assign sign to `window` column
let sign = copy(
&mut region,
|| "sign",
self.super_config.window,
offset + NUM_WINDOWS,
&scalar.sign,
&self.super_config.perm,
)?;
// Enable mul_fixed_short selector on final row
self.q_mul_fixed_short
.enable(region, offset + NUM_WINDOWS)?;
// 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,
|| y_val.ok_or(Error::SynthesisError),
)?;
let result = EccPoint {
x: magnitude_mul.x,
y: CellValue::new(y_var, y_val),
};
#[cfg(test)]
// Check that the correct multiple is obtained.
{
use group::Curve;
let base: super::OrchardFixedBases = base.clone().into();
let scalar = scalar
.magnitude
.zip(scalar.sign.value())
.map(|(magnitude, sign)| {
let sign = if sign == pallas::Base::one() {
pallas::Scalar::one()
} else if sign == -pallas::Base::one() {
-pallas::Scalar::one()
// Conditionally negate `y`-coordinate
let y_val = if let Some(sign) = sign.value() {
if sign == -pallas::Base::one() {
magnitude_mul.y.value().map(|y: pallas::Base| -y)
} else {
panic!("Sign should be 1 or -1.")
};
magnitude * sign
});
let real_mul = scalar.map(|scalar| base.generator() * scalar);
let result = result.point();
magnitude_mul.y.value()
}
} else {
None
};
if let (Some(real_mul), Some(result)) = (real_mul, result) {
assert_eq!(real_mul.to_affine(), result);
}
}
// Enable mul_fixed_short selector on final row
self.q_mul_fixed_short
.enable(&mut region, offset + NUM_WINDOWS)?;
Ok(result)
// 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,
|| y_val.ok_or(Error::SynthesisError),
)?;
let result = EccPoint {
x: magnitude_mul.x,
y: CellValue::new(y_var, y_val),
};
#[cfg(test)]
// Check that the correct multiple is obtained.
{
use group::Curve;
let base: super::OrchardFixedBases = base.clone().into();
let scalar =
scalar
.magnitude
.zip(scalar.sign.value())
.map(|(magnitude, sign)| {
let sign = if sign == pallas::Base::one() {
pallas::Scalar::one()
} else if sign == -pallas::Base::one() {
-pallas::Scalar::one()
} else {
panic!("Sign should be 1 or -1.")
};
magnitude * sign
});
let real_mul = scalar.map(|scalar| base.generator() * scalar);
let result = result.point();
if let (Some(real_mul), Some(result)) = (real_mul, result) {
assert_eq!(real_mul.to_affine(), result);
}
}
Ok(result)
},
)
}
}