mirror of https://github.com/zcash/halo2.git
Define hash-to-curve over Curve, not CurveAffine
This removes an unnecessary layer of indirection from the type system, and ensures that these APIs depend on the halo2-specific trait with the extensions we require.
This commit is contained in:
parent
082d66d6e7
commit
55fb581f17
|
@ -84,9 +84,12 @@ pub trait Curve:
|
|||
/// # Example
|
||||
///
|
||||
/// ```
|
||||
/// use halo2::arithmetic::{Curve, CurveAffine};
|
||||
/// fn pedersen_commitment<C: CurveAffine>(x: C::Scalar, r: C::Scalar) -> C {
|
||||
/// let hasher = C::Curve::hash_to_curve("z.cash:example_pedersen_commitment");
|
||||
/// use halo2::arithmetic::Curve;
|
||||
/// fn pedersen_commitment<C: Curve>(
|
||||
/// x: <C as Curve>::Scalar,
|
||||
/// r: <C as Curve>::Scalar,
|
||||
/// ) -> C::Affine {
|
||||
/// let hasher = C::hash_to_curve("z.cash:example_pedersen_commitment");
|
||||
/// let g = hasher(b"g");
|
||||
/// let h = hasher(b"h");
|
||||
/// (g * x + &(h * r)).to_affine()
|
||||
|
|
|
@ -11,7 +11,7 @@ use super::{Fp, Fq};
|
|||
use crate::arithmetic::{Curve, CurveAffine, FieldExt, Group};
|
||||
|
||||
macro_rules! new_curve_impl {
|
||||
(($($privacy:tt)*), $name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, $scalar:ident, $blake2b_personalization:literal,
|
||||
(($($privacy:tt)*), $name:ident, $name_affine:ident, $iso:ident, $base:ident, $scalar:ident, $blake2b_personalization:literal,
|
||||
$curve_id:literal, $a_raw:expr, $b_raw:expr, $curve_type:ident) => {
|
||||
/// Represents a point in the projective coordinate space.
|
||||
#[derive(Copy, Clone, Debug)]
|
||||
|
@ -85,7 +85,7 @@ macro_rules! new_curve_impl {
|
|||
$name_affine::conditional_select(&tmp, &$name_affine::identity(), zinv.ct_is_zero())
|
||||
}
|
||||
|
||||
impl_projective_curve_ext!($name, $name_affine, $iso_affine, $base, $curve_type);
|
||||
impl_projective_curve_ext!($name, $name_affine, $iso, $base, $curve_type);
|
||||
|
||||
fn a() -> Self::Base {
|
||||
$name::curve_constant_a()
|
||||
|
@ -759,29 +759,26 @@ 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) => {
|
||||
($name:ident, $name_affine:ident, $iso: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>(
|
||||
let q0 = hashtocurve::map_to_curve_simple_swu::<$base, $name, $iso>(
|
||||
&us[0],
|
||||
$name::THETA,
|
||||
$name::Z,
|
||||
);
|
||||
let q1 = hashtocurve::map_to_curve_simple_swu::<$base, $name_affine, $iso_affine>(
|
||||
let q1 = hashtocurve::map_to_curve_simple_swu::<$base, $name, $iso>(
|
||||
&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,
|
||||
)
|
||||
hashtocurve::iso_map::<$base, $name, $iso>(&r, &$name::ISOGENY_CONSTANTS)
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -795,7 +792,7 @@ macro_rules! impl_projective_curve_ext {
|
|||
}
|
||||
}
|
||||
};
|
||||
($name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, general) => {
|
||||
($name:ident, $name_affine:ident, $iso: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!()
|
||||
|
@ -835,7 +832,7 @@ new_curve_impl!(
|
|||
(pub),
|
||||
Ep,
|
||||
EpAffine,
|
||||
IsoEpAffine,
|
||||
IsoEp,
|
||||
Fp,
|
||||
Fq,
|
||||
b"halo2_____pallas",
|
||||
|
@ -848,7 +845,7 @@ new_curve_impl!(
|
|||
(pub),
|
||||
Eq,
|
||||
EqAffine,
|
||||
IsoEqAffine,
|
||||
IsoEq,
|
||||
Fq,
|
||||
Fp,
|
||||
b"halo2______vesta",
|
||||
|
@ -861,7 +858,7 @@ new_curve_impl!(
|
|||
(pub(crate)),
|
||||
IsoEp,
|
||||
IsoEpAffine,
|
||||
EpAffine,
|
||||
Ep,
|
||||
Fp,
|
||||
Fq,
|
||||
b"halo2_iso_pallas",
|
||||
|
@ -879,7 +876,7 @@ new_curve_impl!(
|
|||
(pub(crate)),
|
||||
IsoEq,
|
||||
IsoEqAffine,
|
||||
EqAffine,
|
||||
Eq,
|
||||
Fq,
|
||||
Fp,
|
||||
b"halo2__iso_vesta",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
use subtle::ConstantTimeEq;
|
||||
|
||||
use crate::arithmetic::{Curve, CurveAffine, FieldExt};
|
||||
use crate::arithmetic::{Curve, FieldExt};
|
||||
|
||||
/// Hashes over a message and writes the output to all of `buf`.
|
||||
pub fn hash_to_field<F: FieldExt>(
|
||||
|
@ -72,10 +72,10 @@ pub fn hash_to_field<F: FieldExt>(
|
|||
}
|
||||
|
||||
/// Implements a degree 3 isogeny map.
|
||||
pub fn iso_map<F: FieldExt, C: CurveAffine<Base = F>, I: CurveAffine<Base = F>>(
|
||||
p: &I::Curve,
|
||||
pub fn iso_map<F: FieldExt, C: Curve<Base = F>, I: Curve<Base = F>>(
|
||||
p: &I,
|
||||
iso: &[C::Base; 13],
|
||||
) -> C::Curve {
|
||||
) -> C {
|
||||
// The input and output are in Jacobian coordinates, using the method
|
||||
// in "Avoiding inversions" [WB2019, section 4.3].
|
||||
|
||||
|
@ -96,14 +96,14 @@ pub fn iso_map<F: FieldExt, C: CurveAffine<Base = F>, I: CurveAffine<Base = F>>(
|
|||
let xo = num_x * div_y * zo;
|
||||
let yo = num_y * div_x * zo.square();
|
||||
|
||||
C::Curve::new_jacobian(xo, yo, zo).unwrap()
|
||||
C::new_jacobian(xo, yo, zo).unwrap()
|
||||
}
|
||||
|
||||
pub fn map_to_curve_simple_swu<F: FieldExt, C: CurveAffine<Base = F>, I: CurveAffine<Base = F>>(
|
||||
pub fn map_to_curve_simple_swu<F: FieldExt, C: Curve<Base = F>, I: Curve<Base = F>>(
|
||||
u: &F,
|
||||
theta: F,
|
||||
z: F,
|
||||
) -> I::Curve {
|
||||
) -> I {
|
||||
// 1. tv1 = inv0(Z^2 * u^4 + Z * u^2)
|
||||
// 2. x1 = (-B / A) * (1 + tv1)
|
||||
// 3. If tv1 == 0, set x1 = B / (Z * A)
|
||||
|
@ -171,5 +171,5 @@ pub fn map_to_curve_simple_swu<F: FieldExt, C: CurveAffine<Base = F>, I: CurveAf
|
|||
(u.get_lower_32() % 2).ct_eq(&(y.get_lower_32() % 2)),
|
||||
);
|
||||
|
||||
I::Curve::new_jacobian(num_x * div, y * div3, div).unwrap()
|
||||
I::new_jacobian(num_x * div, y * div3, div).unwrap()
|
||||
}
|
||||
|
|
|
@ -42,8 +42,7 @@ fn test_iso_map() {
|
|||
]),
|
||||
)
|
||||
.unwrap();
|
||||
let p =
|
||||
super::hashtocurve::iso_map::<_, Affine, super::IsoEpAffine>(&r, &Ep::ISOGENY_CONSTANTS);
|
||||
let p = super::hashtocurve::iso_map::<_, Point, super::IsoEp>(&r, &Ep::ISOGENY_CONSTANTS);
|
||||
let (x, y, z) = p.jacobian_coordinates();
|
||||
assert!(
|
||||
format!("{:?}", x) == "0x318cc15f281662b3f26d0175cab97b924870c837879cac647e877be51a85e898"
|
||||
|
@ -58,8 +57,7 @@ fn test_iso_map() {
|
|||
// check that iso_map([2] r) = [2] iso_map(r)
|
||||
let r2 = r.double();
|
||||
assert!(bool::from(r2.is_on_curve()));
|
||||
let p2 =
|
||||
super::hashtocurve::iso_map::<_, Affine, super::IsoEpAffine>(&r2, &Ep::ISOGENY_CONSTANTS);
|
||||
let p2 = super::hashtocurve::iso_map::<_, Point, super::IsoEp>(&r2, &Ep::ISOGENY_CONSTANTS);
|
||||
assert!(bool::from(p2.is_on_curve()));
|
||||
assert!(p2 == p.double());
|
||||
}
|
||||
|
@ -92,8 +90,7 @@ fn test_iso_map_identity() {
|
|||
let r = (r * -Fq::one()) + r;
|
||||
assert!(bool::from(r.is_on_curve()));
|
||||
assert!(bool::from(r.is_identity()));
|
||||
let p =
|
||||
super::hashtocurve::iso_map::<_, Affine, super::IsoEpAffine>(&r, &Ep::ISOGENY_CONSTANTS);
|
||||
let p = super::hashtocurve::iso_map::<_, Point, super::IsoEp>(&r, &Ep::ISOGENY_CONSTANTS);
|
||||
assert!(bool::from(p.is_on_curve()));
|
||||
assert!(bool::from(p.is_identity()));
|
||||
}
|
||||
|
@ -101,12 +98,11 @@ fn test_iso_map_identity() {
|
|||
#[test]
|
||||
fn test_map_to_curve_simple_swu() {
|
||||
use crate::arithmetic::Curve;
|
||||
use crate::pasta::curves::{IsoEp, IsoEpAffine};
|
||||
use crate::pasta::curves::IsoEp;
|
||||
use crate::pasta::hashtocurve::map_to_curve_simple_swu;
|
||||
|
||||
// The zero input is a special case.
|
||||
let p: IsoEp =
|
||||
map_to_curve_simple_swu::<Fp, EpAffine, IsoEpAffine>(&Fp::zero(), Ep::THETA, Ep::Z);
|
||||
let p: IsoEp = map_to_curve_simple_swu::<Fp, Ep, IsoEp>(&Fp::zero(), Ep::THETA, Ep::Z);
|
||||
let (x, y, z) = p.jacobian_coordinates();
|
||||
println!("{:?}", p);
|
||||
assert!(
|
||||
|
@ -119,8 +115,7 @@ fn test_map_to_curve_simple_swu() {
|
|||
format!("{:?}", z) == "0x054b3ba10416dc104157b1318534a19d5d115472da7d746f8a5f250cd8cdef36"
|
||||
);
|
||||
|
||||
let p: IsoEp =
|
||||
map_to_curve_simple_swu::<Fp, EpAffine, IsoEpAffine>(&Fp::one(), Ep::THETA, Ep::Z);
|
||||
let p: IsoEp = map_to_curve_simple_swu::<Fp, Ep, IsoEp>(&Fp::one(), Ep::THETA, Ep::Z);
|
||||
let (x, y, z) = p.jacobian_coordinates();
|
||||
println!("{:?}", p);
|
||||
assert!(
|
||||
|
|
|
@ -17,12 +17,11 @@ pub type Affine = EqAffine;
|
|||
#[test]
|
||||
fn test_map_to_curve_simple_swu() {
|
||||
use crate::arithmetic::Curve;
|
||||
use crate::pasta::curves::{IsoEq, IsoEqAffine};
|
||||
use crate::pasta::curves::IsoEq;
|
||||
use crate::pasta::hashtocurve::map_to_curve_simple_swu;
|
||||
|
||||
// The zero input is a special case.
|
||||
let p: IsoEq =
|
||||
map_to_curve_simple_swu::<Fq, EqAffine, IsoEqAffine>(&Fq::zero(), Eq::THETA, Eq::Z);
|
||||
let p: IsoEq = map_to_curve_simple_swu::<Fq, Eq, IsoEq>(&Fq::zero(), Eq::THETA, Eq::Z);
|
||||
let (x, y, z) = p.jacobian_coordinates();
|
||||
println!("{:?}", p);
|
||||
assert!(
|
||||
|
@ -35,8 +34,7 @@ fn test_map_to_curve_simple_swu() {
|
|||
format!("{:?}", z) == "0x0b851e9e579403a76df1100f556e1f226e5656bdf38f3bf8601d8a3a9a15890b"
|
||||
);
|
||||
|
||||
let p: IsoEq =
|
||||
map_to_curve_simple_swu::<Fq, EqAffine, IsoEqAffine>(&Fq::one(), Eq::THETA, Eq::Z);
|
||||
let p: IsoEq = map_to_curve_simple_swu::<Fq, Eq, IsoEq>(&Fq::one(), Eq::THETA, Eq::Z);
|
||||
let (x, y, z) = p.jacobian_coordinates();
|
||||
println!("{:?}", p);
|
||||
assert!(
|
||||
|
|
Loading…
Reference in New Issue