pasta: Split halo2-specific curve-specific logic into a separate macro

This commit is contained in:
Jack Grigg 2021-02-22 18:33:53 +00:00
parent 627d729836
commit 81a7936d99

View file

@ -55,7 +55,7 @@ macro_rules! new_curve_impl {
type Scalar = $scalar;
type Base = $base;
impl_projective_curve_specific!($name, $name_affine, $iso_affine, $base, $curve_type);
impl_projective_curve_specific!($name, $base, $curve_type);
fn zero() -> Self {
Self {
@ -85,6 +85,8 @@ macro_rules! new_curve_impl {
$name_affine::conditional_select(&tmp, &$name_affine::zero(), zinv.ct_is_zero())
}
impl_projective_curve_ext!($name, $name_affine, $iso_affine, $base, $curve_type);
fn a() -> Self::Base {
$name::curve_constant_a()
}
@ -676,32 +678,7 @@ macro_rules! new_curve_impl {
}
macro_rules! impl_projective_curve_specific {
($name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, special_a0_b5) => {
fn hash_to_curve<'a>(domain_prefix: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a> {
use super::hashtocurve;
Box::new(move |message| {
let mut us = [Field::zero(); 2];
hashtocurve::hash_to_field($name_affine::CURVE_ID, domain_prefix, message, &mut us);
let q0 = hashtocurve::map_to_curve_simple_swu::<$base, $name_affine, $iso_affine>(
&us[0],
$name::THETA,
$name::Z,
);
let q1 = hashtocurve::map_to_curve_simple_swu::<$base, $name_affine, $iso_affine>(
&us[1],
$name::THETA,
$name::Z,
);
let r = q0 + &q1;
debug_assert!(bool::from(r.is_on_curve()));
hashtocurve::iso_map::<$base, $name_affine, $iso_affine>(
&r,
&$name::ISOGENY_CONSTANTS,
)
})
}
($name:ident, $base:ident, special_a0_b5) => {
fn one() -> Self {
// NOTE: This is specific to b = 5
@ -715,16 +692,6 @@ macro_rules! impl_projective_curve_specific {
}
}
/// Apply the curve endomorphism by multiplying the x-coordinate
/// by an element of multiplicative order 3.
fn endo(&self) -> Self {
$name {
x: self.x * $base::ZETA,
y: self.y,
z: self.z,
}
}
fn double(&self) -> Self {
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian-0.html#doubling-dbl-2009-l
//
@ -756,22 +723,12 @@ macro_rules! impl_projective_curve_specific {
$name::conditional_select(&tmp, &$name::zero(), self.is_zero())
}
};
($name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, general) => {
/// Unimplemented: hashing to this curve is not supported
fn hash_to_curve<'a>(_domain_prefix: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a> {
unimplemented!()
}
($name:ident, $base:ident, general) => {
/// Unimplemented: there is no standard generator for this curve.
fn one() -> Self {
unimplemented!()
}
/// Unimplemented: no endomorphism is supported for this curve.
fn endo(&self) -> Self {
unimplemented!()
}
fn double(&self) -> Self {
// http://www.hyperelliptic.org/EFD/g1p/auto-shortw-jacobian.html#doubling-dbl-2007-bl
//
@ -801,6 +758,56 @@ macro_rules! impl_projective_curve_specific {
};
}
macro_rules! impl_projective_curve_ext {
($name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, special_a0_b5) => {
fn hash_to_curve<'a>(domain_prefix: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a> {
use super::hashtocurve;
Box::new(move |message| {
let mut us = [Field::zero(); 2];
hashtocurve::hash_to_field($name_affine::CURVE_ID, domain_prefix, message, &mut us);
let q0 = hashtocurve::map_to_curve_simple_swu::<$base, $name_affine, $iso_affine>(
&us[0],
$name::THETA,
$name::Z,
);
let q1 = hashtocurve::map_to_curve_simple_swu::<$base, $name_affine, $iso_affine>(
&us[1],
$name::THETA,
$name::Z,
);
let r = q0 + &q1;
debug_assert!(bool::from(r.is_on_curve()));
hashtocurve::iso_map::<$base, $name_affine, $iso_affine>(
&r,
&$name::ISOGENY_CONSTANTS,
)
})
}
/// Apply the curve endomorphism by multiplying the x-coordinate
/// by an element of multiplicative order 3.
fn endo(&self) -> Self {
$name {
x: self.x * $base::ZETA,
y: self.y,
z: self.z,
}
}
};
($name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, general) => {
/// Unimplemented: hashing to this curve is not supported
fn hash_to_curve<'a>(_domain_prefix: &'a str) -> Box<dyn Fn(&[u8]) -> Self + 'a> {
unimplemented!()
}
/// Unimplemented: no endomorphism is supported for this curve.
fn endo(&self) -> Self {
unimplemented!()
}
};
}
macro_rules! impl_affine_curve_specific {
($name:ident, $base:ident, special_a0_b5) => {
fn one() -> Self {