mirror of https://github.com/zcash/halo2.git
ecc::chip: Introduce ScalarVar enum.
This commit is contained in:
parent
6f2fc57b3c
commit
1c877f3caf
|
@ -16,17 +16,7 @@ pub mod chip;
|
||||||
pub trait EccInstructions<C: CurveAffine>:
|
pub trait EccInstructions<C: CurveAffine>:
|
||||||
Chip<C::Base> + UtilitiesInstructions<C::Base> + Clone + Debug + Eq
|
Chip<C::Base> + UtilitiesInstructions<C::Base> + Clone + Debug + Eq
|
||||||
{
|
{
|
||||||
/// Variable representing an element of the elliptic curve's base field, that
|
/// Variable representing a scalar used in variable-base scalar mul.
|
||||||
/// is used as a scalar in variable-base scalar mul.
|
|
||||||
///
|
|
||||||
/// It is not true in general that a scalar field element fits in a curve's
|
|
||||||
/// base field, and in particular it is untrue for the Pallas curve, whose
|
|
||||||
/// scalar field `Fq` is larger than its base field `Fp`.
|
|
||||||
///
|
|
||||||
/// However, the only use of variable-base scalar mul in the Orchard protocol
|
|
||||||
/// is in deriving diversified addresses `[ivk] g_d`, and `ivk` is guaranteed
|
|
||||||
/// to be in the base field of the curve. (See non-normative notes in
|
|
||||||
/// https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents.)
|
|
||||||
type ScalarVar: Clone + Debug;
|
type ScalarVar: Clone + Debug;
|
||||||
/// Variable representing a full-width element of the elliptic curve's
|
/// Variable representing a full-width element of the elliptic curve's
|
||||||
/// scalar field, to be used for fixed-base scalar mul.
|
/// scalar field, to be used for fixed-base scalar mul.
|
||||||
|
|
|
@ -377,6 +377,26 @@ impl EccBaseFieldElemFixed {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An enumeration of the possible types of scalars used in variable-base
|
||||||
|
/// multiplication.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub enum ScalarVar {
|
||||||
|
/// An element of the elliptic curve's base field, that is used as a scalar
|
||||||
|
/// in variable-base scalar mul.
|
||||||
|
///
|
||||||
|
/// It is not true in general that a scalar field element fits in a curve's
|
||||||
|
/// base field, and in particular it is untrue for the Pallas curve, whose
|
||||||
|
/// scalar field `Fq` is larger than its base field `Fp`.
|
||||||
|
///
|
||||||
|
/// However, the only use of variable-base scalar mul in the Orchard protocol
|
||||||
|
/// is in deriving diversified addresses `[ivk] g_d`, and `ivk` is guaranteed
|
||||||
|
/// to be in the base field of the curve. (See non-normative notes in
|
||||||
|
/// https://zips.z.cash/protocol/nu5.pdf#orchardkeycomponents.)
|
||||||
|
BaseFieldElem(AssignedCell<pallas::Base, pallas::Base>),
|
||||||
|
/// A full-width scalar. This is unimplemented for halo2_gadgets v0.1.0.
|
||||||
|
FullWidth,
|
||||||
|
}
|
||||||
|
|
||||||
impl<Fixed: FixedPoints<pallas::Affine>> EccInstructions<pallas::Affine> for EccChip<Fixed>
|
impl<Fixed: FixedPoints<pallas::Affine>> EccInstructions<pallas::Affine> for EccChip<Fixed>
|
||||||
where
|
where
|
||||||
<Fixed as FixedPoints<pallas::Affine>>::Base:
|
<Fixed as FixedPoints<pallas::Affine>>::Base:
|
||||||
|
@ -388,7 +408,7 @@ where
|
||||||
{
|
{
|
||||||
type ScalarFixed = EccScalarFixed;
|
type ScalarFixed = EccScalarFixed;
|
||||||
type ScalarFixedShort = EccScalarFixedShort;
|
type ScalarFixedShort = EccScalarFixedShort;
|
||||||
type ScalarVar = AssignedCell<pallas::Base, pallas::Base>;
|
type ScalarVar = ScalarVar;
|
||||||
type Point = EccPoint;
|
type Point = EccPoint;
|
||||||
type NonIdentityPoint = NonIdentityEccPoint;
|
type NonIdentityPoint = NonIdentityEccPoint;
|
||||||
type X = AssignedCell<pallas::Base, pallas::Base>;
|
type X = AssignedCell<pallas::Base, pallas::Base>;
|
||||||
|
@ -484,11 +504,16 @@ where
|
||||||
base: &Self::NonIdentityPoint,
|
base: &Self::NonIdentityPoint,
|
||||||
) -> Result<(Self::Point, Self::ScalarVar), Error> {
|
) -> Result<(Self::Point, Self::ScalarVar), Error> {
|
||||||
let config = self.config().mul;
|
let config = self.config().mul;
|
||||||
config.assign(
|
match scalar {
|
||||||
layouter.namespace(|| "variable-base scalar mul"),
|
ScalarVar::BaseFieldElem(scalar) => config.assign(
|
||||||
scalar.clone(),
|
layouter.namespace(|| "variable-base scalar mul"),
|
||||||
base,
|
scalar.clone(),
|
||||||
)
|
base,
|
||||||
|
),
|
||||||
|
ScalarVar::FullWidth => {
|
||||||
|
todo!()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mul_fixed(
|
fn mul_fixed(
|
||||||
|
@ -549,6 +574,6 @@ where
|
||||||
_layouter: &mut impl Layouter<pallas::Base>,
|
_layouter: &mut impl Layouter<pallas::Base>,
|
||||||
base: &Self::Var,
|
base: &Self::Var,
|
||||||
) -> Result<Self::ScalarVar, Error> {
|
) -> Result<Self::ScalarVar, Error> {
|
||||||
Ok(base.clone())
|
Ok(ScalarVar::BaseFieldElem(base.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use super::{add, EccPoint, NonIdentityEccPoint, T_Q};
|
use super::{add, EccPoint, NonIdentityEccPoint, ScalarVar, T_Q};
|
||||||
use crate::{
|
use crate::{
|
||||||
primitives::sinsemilla,
|
primitives::sinsemilla,
|
||||||
utilities::{bool_check, lookup_range_check::LookupRangeCheckConfig, ternary},
|
utilities::{bool_check, lookup_range_check::LookupRangeCheckConfig, ternary},
|
||||||
|
@ -167,7 +167,7 @@ impl Config {
|
||||||
mut layouter: impl Layouter<pallas::Base>,
|
mut layouter: impl Layouter<pallas::Base>,
|
||||||
alpha: AssignedCell<pallas::Base, pallas::Base>,
|
alpha: AssignedCell<pallas::Base, pallas::Base>,
|
||||||
base: &NonIdentityEccPoint,
|
base: &NonIdentityEccPoint,
|
||||||
) -> Result<(EccPoint, AssignedCell<pallas::Base, pallas::Base>), Error> {
|
) -> Result<(EccPoint, ScalarVar), Error> {
|
||||||
let (result, zs): (EccPoint, Vec<Z<pallas::Base>>) = layouter.assign_region(
|
let (result, zs): (EccPoint, Vec<Z<pallas::Base>>) = layouter.assign_region(
|
||||||
|| "variable-base scalar mul",
|
|| "variable-base scalar mul",
|
||||||
|mut region| {
|
|mut region| {
|
||||||
|
@ -293,7 +293,7 @@ impl Config {
|
||||||
&zs,
|
&zs,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
Ok((result, alpha))
|
Ok((result, ScalarVar::BaseFieldElem(alpha)))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Processes the final scalar bit `k_0`.
|
/// Processes the final scalar bit `k_0`.
|
||||||
|
@ -483,7 +483,7 @@ pub mod tests {
|
||||||
ecc::{
|
ecc::{
|
||||||
chip::{EccChip, EccPoint},
|
chip::{EccChip, EccPoint},
|
||||||
tests::TestFixedBases,
|
tests::TestFixedBases,
|
||||||
EccInstructions, NonIdentityPoint, Point,
|
BaseFitsInScalarInstructions, EccInstructions, NonIdentityPoint, Point,
|
||||||
},
|
},
|
||||||
utilities::UtilitiesInstructions,
|
utilities::UtilitiesInstructions,
|
||||||
};
|
};
|
||||||
|
@ -525,6 +525,7 @@ pub mod tests {
|
||||||
column,
|
column,
|
||||||
Some(scalar_val),
|
Some(scalar_val),
|
||||||
)?;
|
)?;
|
||||||
|
let scalar = chip.scalar_var_from_base(&mut layouter, &scalar)?;
|
||||||
p.mul(layouter.namespace(|| "random [a]B"), &scalar)?
|
p.mul(layouter.namespace(|| "random [a]B"), &scalar)?
|
||||||
};
|
};
|
||||||
constrain_equal_non_id(
|
constrain_equal_non_id(
|
||||||
|
@ -543,6 +544,7 @@ pub mod tests {
|
||||||
let (result, _) = {
|
let (result, _) = {
|
||||||
let scalar =
|
let scalar =
|
||||||
chip.load_private(layouter.namespace(|| "zero"), column, Some(scalar_val))?;
|
chip.load_private(layouter.namespace(|| "zero"), column, Some(scalar_val))?;
|
||||||
|
let scalar = chip.scalar_var_from_base(&mut layouter, &scalar)?;
|
||||||
p.mul(layouter.namespace(|| "[0]B"), &scalar)?
|
p.mul(layouter.namespace(|| "[0]B"), &scalar)?
|
||||||
};
|
};
|
||||||
if let Some(is_identity) = result.inner().is_identity() {
|
if let Some(is_identity) = result.inner().is_identity() {
|
||||||
|
@ -556,6 +558,7 @@ pub mod tests {
|
||||||
let (result, _) = {
|
let (result, _) = {
|
||||||
let scalar =
|
let scalar =
|
||||||
chip.load_private(layouter.namespace(|| "-1"), column, Some(scalar_val))?;
|
chip.load_private(layouter.namespace(|| "-1"), column, Some(scalar_val))?;
|
||||||
|
let scalar = chip.scalar_var_from_base(&mut layouter, &scalar)?;
|
||||||
p.mul(layouter.namespace(|| "[-1]B"), &scalar)?
|
p.mul(layouter.namespace(|| "[-1]B"), &scalar)?
|
||||||
};
|
};
|
||||||
constrain_equal_non_id(
|
constrain_equal_non_id(
|
||||||
|
|
Loading…
Reference in New Issue