mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-08 20:40:31 +00:00
Introduce Curve::hasher abstraction.
This commit is contained in:
parent
68a7a19d3b
commit
83e2656c3e
4 changed files with 64 additions and 18 deletions
|
|
@ -79,6 +79,12 @@ pub trait Curve:
|
||||||
/// Return the Jacobian coordinates of this point.
|
/// Return the Jacobian coordinates of this point.
|
||||||
fn jacobian_coordinates(&self) -> (Self::Base, Self::Base, Self::Base);
|
fn jacobian_coordinates(&self) -> (Self::Base, Self::Base, Self::Base);
|
||||||
|
|
||||||
|
/// Requests a hasher that accepts messages and returns near-uniformly
|
||||||
|
/// distributed elements in the group, given domain prefix `hasher`.
|
||||||
|
///
|
||||||
|
/// This method is suitable for use as a random oracle.
|
||||||
|
fn hasher(domain_prefix: &str) -> Box<dyn Fn(&[u8]) -> Self + 'static>;
|
||||||
|
|
||||||
/// Returns whether or not this element is on the curve; should
|
/// Returns whether or not this element is on the curve; should
|
||||||
/// always be true unless an "unchecked" API was used.
|
/// always be true unless an "unchecked" API was used.
|
||||||
fn is_on_curve(&self) -> Choice;
|
fn is_on_curve(&self) -> Choice;
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use super::{Fp, Fq};
|
||||||
use crate::arithmetic::{Curve, CurveAffine, FieldExt, Group};
|
use crate::arithmetic::{Curve, CurveAffine, FieldExt, Group};
|
||||||
|
|
||||||
macro_rules! new_curve_impl {
|
macro_rules! new_curve_impl {
|
||||||
($name:ident, $name_affine:ident, $base:ident, $scalar:ident, $blake2b_personalization:literal,
|
($name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, $scalar:ident, $blake2b_personalization:literal,
|
||||||
$curve_id:literal, $a_raw:expr, $b_raw:expr, $curve_type:ident) => {
|
$curve_id:literal, $a_raw:expr, $b_raw:expr, $curve_type:ident) => {
|
||||||
/// Represents a point in the projective coordinate space.
|
/// Represents a point in the projective coordinate space.
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug)]
|
||||||
|
|
@ -56,7 +56,7 @@ macro_rules! new_curve_impl {
|
||||||
type Scalar = $scalar;
|
type Scalar = $scalar;
|
||||||
type Base = $base;
|
type Base = $base;
|
||||||
|
|
||||||
impl_projective_curve_specific!($name, $base, $curve_type);
|
impl_projective_curve_specific!($name, $name_affine, $iso_affine, $base, $curve_type);
|
||||||
|
|
||||||
fn zero() -> Self {
|
fn zero() -> Self {
|
||||||
Self {
|
Self {
|
||||||
|
|
@ -685,7 +685,38 @@ macro_rules! new_curve_impl {
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! impl_projective_curve_specific {
|
macro_rules! impl_projective_curve_specific {
|
||||||
($name:ident, $base:ident, special_a0_b5) => {
|
($name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, special_a0_b5) => {
|
||||||
|
fn hasher(domain_prefix: &str) -> Box<dyn Fn(&[u8]) -> Self + 'static> {
|
||||||
|
use super::hashtocurve::SimplifiedSWUWithDegree3Isogeny;
|
||||||
|
|
||||||
|
let swu: SimplifiedSWUWithDegree3Isogeny<$base, $name_affine, $iso_affine> =
|
||||||
|
SimplifiedSWUWithDegree3Isogeny::new(
|
||||||
|
$name::Z,
|
||||||
|
$name::ISOGENY_CONSTANTS,
|
||||||
|
$name::MINUS_B_OVER_A,
|
||||||
|
$name::B_OVER_ZA,
|
||||||
|
$name::THETA,
|
||||||
|
);
|
||||||
|
|
||||||
|
let domain_separation_tag: String = format!(
|
||||||
|
"{}-{}_{}_{}_RO_",
|
||||||
|
domain_prefix,
|
||||||
|
$name_affine::CURVE_ID,
|
||||||
|
"XOF:SHAKE128",
|
||||||
|
"SSWU"
|
||||||
|
);
|
||||||
|
|
||||||
|
Box::new(move |message| {
|
||||||
|
let mut us = [Field::zero(); 2];
|
||||||
|
SimplifiedSWUWithDegree3Isogeny::<$base, $name_affine, $iso_affine>::hash_to_field(
|
||||||
|
message,
|
||||||
|
domain_separation_tag.as_bytes(),
|
||||||
|
&mut us,
|
||||||
|
);
|
||||||
|
swu.field_elements_to_curve(&us[0], &us[1])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
// NOTE: This is specific to b = 5
|
// NOTE: This is specific to b = 5
|
||||||
|
|
||||||
|
|
@ -740,7 +771,12 @@ macro_rules! impl_projective_curve_specific {
|
||||||
$name::conditional_select(&tmp, &$name::zero(), self.is_zero())
|
$name::conditional_select(&tmp, &$name::zero(), self.is_zero())
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
($name:ident, $base:ident, general) => {
|
($name:ident, $name_affine:ident, $iso_affine:ident, $base:ident, general) => {
|
||||||
|
/// Unimplemented: hashing to this curve is not supported
|
||||||
|
fn hasher(_domain_prefix: &str) -> Box<dyn Fn(&[u8]) -> Self + 'static> {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
/// Unimplemented: there is no standard generator for this curve.
|
/// Unimplemented: there is no standard generator for this curve.
|
||||||
fn one() -> Self {
|
fn one() -> Self {
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
|
|
@ -807,6 +843,7 @@ macro_rules! impl_affine_curve_specific {
|
||||||
new_curve_impl!(
|
new_curve_impl!(
|
||||||
Ep,
|
Ep,
|
||||||
EpAffine,
|
EpAffine,
|
||||||
|
IsoEpAffine,
|
||||||
Fp,
|
Fp,
|
||||||
Fq,
|
Fq,
|
||||||
b"halo2_____pallas",
|
b"halo2_____pallas",
|
||||||
|
|
@ -818,6 +855,7 @@ new_curve_impl!(
|
||||||
new_curve_impl!(
|
new_curve_impl!(
|
||||||
Eq,
|
Eq,
|
||||||
EqAffine,
|
EqAffine,
|
||||||
|
IsoEqAffine,
|
||||||
Fq,
|
Fq,
|
||||||
Fp,
|
Fp,
|
||||||
b"halo2______vesta",
|
b"halo2______vesta",
|
||||||
|
|
@ -829,6 +867,7 @@ new_curve_impl!(
|
||||||
new_curve_impl!(
|
new_curve_impl!(
|
||||||
IsoEp,
|
IsoEp,
|
||||||
IsoEpAffine,
|
IsoEpAffine,
|
||||||
|
EpAffine,
|
||||||
Fp,
|
Fp,
|
||||||
Fq,
|
Fq,
|
||||||
b"halo2_iso_pallas",
|
b"halo2_iso_pallas",
|
||||||
|
|
@ -845,6 +884,7 @@ new_curve_impl!(
|
||||||
new_curve_impl!(
|
new_curve_impl!(
|
||||||
IsoEq,
|
IsoEq,
|
||||||
IsoEqAffine,
|
IsoEqAffine,
|
||||||
|
EqAffine,
|
||||||
Fq,
|
Fq,
|
||||||
Fp,
|
Fp,
|
||||||
b"halo2__iso_vesta",
|
b"halo2__iso_vesta",
|
||||||
|
|
@ -859,7 +899,7 @@ new_curve_impl!(
|
||||||
general
|
general
|
||||||
);
|
);
|
||||||
|
|
||||||
impl IsoEpAffine {
|
impl Ep {
|
||||||
/// Constants used for computing the isogeny from IsoEp to Ep.
|
/// Constants used for computing the isogeny from IsoEp to Ep.
|
||||||
pub const ISOGENY_CONSTANTS: [Fp; 13] = [
|
pub const ISOGENY_CONSTANTS: [Fp; 13] = [
|
||||||
Fp::from_raw([
|
Fp::from_raw([
|
||||||
|
|
@ -977,7 +1017,7 @@ impl IsoEpAffine {
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IsoEqAffine {
|
impl Eq {
|
||||||
/// Constants used for computing the isogeny from IsoEq to Eq.
|
/// Constants used for computing the isogeny from IsoEq to Eq.
|
||||||
pub const ISOGENY_CONSTANTS: [Fq; 13] = [
|
pub const ISOGENY_CONSTANTS: [Fq; 13] = [
|
||||||
Fq::from_raw([
|
Fq::from_raw([
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ lazy_static! {
|
||||||
/// The iso-Pallas -> Pallas degree 3 isogeny map.
|
/// The iso-Pallas -> Pallas degree 3 isogeny map.
|
||||||
pub static ref MAP: SimplifiedSWUWithDegree3Isogeny<Base, Affine, IsoAffine> = {
|
pub static ref MAP: SimplifiedSWUWithDegree3Isogeny<Base, Affine, IsoAffine> = {
|
||||||
SimplifiedSWUWithDegree3Isogeny::new(
|
SimplifiedSWUWithDegree3Isogeny::new(
|
||||||
IsoAffine::Z,
|
Point::Z,
|
||||||
IsoAffine::ISOGENY_CONSTANTS,
|
Point::ISOGENY_CONSTANTS,
|
||||||
IsoAffine::MINUS_B_OVER_A,
|
Point::MINUS_B_OVER_A,
|
||||||
IsoAffine::B_OVER_ZA,
|
Point::B_OVER_ZA,
|
||||||
IsoAffine::THETA
|
Point::THETA
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -90,7 +90,7 @@ fn test_map_to_curve_pallas() {
|
||||||
.collect();
|
.collect();
|
||||||
assert!(set.len() == 10000);
|
assert!(set.len() == 10000);
|
||||||
|
|
||||||
let hash = MAP.hash_to_curve("z.cash:test");
|
let hash = Point::hasher("z.cash:test");
|
||||||
let p: Point = hash(b"hello");
|
let p: Point = hash(b"hello");
|
||||||
let (x, y, z) = p.jacobian_coordinates();
|
let (x, y, z) = p.jacobian_coordinates();
|
||||||
println!("{:?}", p);
|
println!("{:?}", p);
|
||||||
|
|
|
||||||
|
|
@ -27,11 +27,11 @@ lazy_static! {
|
||||||
/// The iso-Vesta -> Vesta degree 3 isogeny map.
|
/// The iso-Vesta -> Vesta degree 3 isogeny map.
|
||||||
pub static ref MAP: SimplifiedSWUWithDegree3Isogeny<Base, Affine, IsoAffine> = {
|
pub static ref MAP: SimplifiedSWUWithDegree3Isogeny<Base, Affine, IsoAffine> = {
|
||||||
SimplifiedSWUWithDegree3Isogeny::new(
|
SimplifiedSWUWithDegree3Isogeny::new(
|
||||||
IsoAffine::Z,
|
Point::Z,
|
||||||
IsoAffine::ISOGENY_CONSTANTS,
|
Point::ISOGENY_CONSTANTS,
|
||||||
IsoAffine::MINUS_B_OVER_A,
|
Point::MINUS_B_OVER_A,
|
||||||
IsoAffine::B_OVER_ZA,
|
Point::B_OVER_ZA,
|
||||||
IsoAffine::THETA
|
Point::THETA
|
||||||
)
|
)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
@ -50,7 +50,7 @@ fn test_map_to_curve_vesta() {
|
||||||
.collect();
|
.collect();
|
||||||
assert!(set.len() == 10000);
|
assert!(set.len() == 10000);
|
||||||
|
|
||||||
let hash = MAP.hash_to_curve("z.cash:test");
|
let hash = Point::hasher("z.cash:test");
|
||||||
let p: Point = hash(b"hello");
|
let p: Point = hash(b"hello");
|
||||||
let (x, y, z) = p.jacobian_coordinates();
|
let (x, y, z) = p.jacobian_coordinates();
|
||||||
println!("{:?}", p);
|
println!("{:?}", p);
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue