Skip to content

Commit

Permalink
Use correct h2c string
Browse files Browse the repository at this point in the history
  • Loading branch information
davxy committed Jun 6, 2024
1 parent 47cfccf commit 91101ed
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 46 deletions.
2 changes: 1 addition & 1 deletion src/arkworks/elligator2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -248,7 +248,7 @@ mod tests {
}

#[test]
fn hash_arbitary_string_to_curve_elligator2() {
fn elligator2_works() {
let hasher = MapToCurveBasedHasher::<
Projective<TestElligator2MapToCurveConfig>,
DefaultFieldHasher<Sha256, 128>,
Expand Down
76 changes: 35 additions & 41 deletions src/suites/bandersnatch.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
//! `ECVRF-BANDERSNATCH-BLAKE2-TAI` suite.
//! `ECVRF-BANDERSNATCH-SHA512-ELL2` suite.
//!
//! Configuration:
//!
Expand Down Expand Up @@ -41,7 +41,7 @@
//! [RFC6234](https://www.rfc-editor.org/rfc/rfc6234), with hLen = 64.
//!
//! * The ECVRF_encode_to_curve function is as specified in
//! Section 5.4.1.2, with `h2c_suite_ID_string` = `"BANDERSNATCH_XMD:BLAKE2b_ELL2_RO_"`.
//! Section 5.4.1.2, with `h2c_suite_ID_string` = `"Bandersnatch_XMD:SHA-512_ELL2_RO_"`.
//! The suite is defined in Section 8.5 of [RFC9380](https://datatracker.ietf.org/doc/rfc9380/).
//!
//! * The prime subgroup generator is generated following Zcash's fashion:
Expand All @@ -60,19 +60,19 @@ pub mod weierstrass {
use super::*;

#[derive(Debug, Copy, Clone)]
pub struct BandersnatchSha512;
pub struct BandersnatchSha512Tai;

suite_types!(BandersnatchSha512);
suite_types!(BandersnatchSha512Tai);

impl Suite for BandersnatchSha512 {
impl Suite for BandersnatchSha512Tai {
const SUITE_ID: &'static [u8] = b"bandersnatch-sha512-tai-sw";
const CHALLENGE_LEN: usize = 32;

type Affine = ark_ed_on_bls12_381_bandersnatch::SWAffine;
type Hasher = sha2::Sha512;
}

impl PedersenSuite for BandersnatchSha512 {
impl PedersenSuite for BandersnatchSha512Tai {
const BLINDING_BASE: AffinePoint = {
const X: BaseField = MontFp!(
"4956610287995045830459834427365747411162584416641336688940534788579455781570"
Expand All @@ -89,13 +89,13 @@ pub mod weierstrass {
use super::*;
use crate::ring as ring_suite;

pub type RingContext = ring_suite::RingContext<BandersnatchSha512>;
pub type VerifierKey = ring_suite::VerifierKey<BandersnatchSha512>;
pub type RingProver = ring_suite::RingProver<BandersnatchSha512>;
pub type RingVerifier = ring_suite::RingVerifier<BandersnatchSha512>;
pub type Proof = ring_suite::Proof<BandersnatchSha512>;
pub type RingContext = ring_suite::RingContext<BandersnatchSha512Tai>;
pub type VerifierKey = ring_suite::VerifierKey<BandersnatchSha512Tai>;
pub type RingProver = ring_suite::RingProver<BandersnatchSha512Tai>;
pub type RingVerifier = ring_suite::RingVerifier<BandersnatchSha512Tai>;
pub type Proof = ring_suite::Proof<BandersnatchSha512Tai>;

impl ring_suite::RingSuite for BandersnatchSha512 {
impl ring_suite::RingSuite for BandersnatchSha512Tai {
type Pairing = ark_bls12_381::Bls12_381;

/// A point on the curve not belonging to the prime order subgroup.
Expand All @@ -114,26 +114,34 @@ pub mod weierstrass {
pub use ring_defs::*;

#[cfg(test)]
suite_tests!(BandersnatchSha512, true);
suite_tests!(BandersnatchSha512Tai, true);
}

pub mod edwards {
use super::*;

#[derive(Debug, Copy, Clone)]
pub struct BandersnatchSha512Edwards;
pub struct BandersnatchSha512Ell2;

suite_types!(BandersnatchSha512Edwards);
suite_types!(BandersnatchSha512Ell2);

impl Suite for BandersnatchSha512Edwards {
const SUITE_ID: &'static [u8] = b"bandersnatch-sha512-tai-te";
impl Suite for BandersnatchSha512Ell2 {
const SUITE_ID: &'static [u8] = b"bandersnatch-sha512-ell2-ed";
const CHALLENGE_LEN: usize = 32;

type Affine = ark_ed_on_bls12_381_bandersnatch::EdwardsAffine;
type Hasher = sha2::Sha512;

/// Hash data to a curve point using Elligator2 method described by RFC 9380.
fn data_to_point(data: &[u8]) -> Option<AffinePoint> {
// "XMD" for expand_message_xmd (Section 5.3.1).
// "RO" for random oracle (Section 3 - hash_to_curve method)
let h2c_suite_id = b"bandersnatch_XMD:SHA-512_ELL2_RO_";
utils::hash_to_curve_ell2_rfc_9380::<Self>(data, h2c_suite_id)
}
}

impl PedersenSuite for BandersnatchSha512Edwards {
impl PedersenSuite for BandersnatchSha512Ell2 {
/// Found mapping the `BLINDING_BASE` of `weierstrass` module using the `utils::map_sw_to_te`
const BLINDING_BASE: AffinePoint = {
const X: BaseField = MontFp!(
Expand Down Expand Up @@ -167,13 +175,13 @@ pub mod edwards {
use super::*;
use crate::ring as ring_suite;

pub type RingContext = ring_suite::RingContext<BandersnatchSha512Edwards>;
pub type VerifierKey = ring_suite::VerifierKey<BandersnatchSha512Edwards>;
pub type RingProver = ring_suite::RingProver<BandersnatchSha512Edwards>;
pub type RingVerifier = ring_suite::RingVerifier<BandersnatchSha512Edwards>;
pub type Proof = ring_suite::Proof<BandersnatchSha512Edwards>;
pub type RingContext = ring_suite::RingContext<BandersnatchSha512Ell2>;
pub type VerifierKey = ring_suite::VerifierKey<BandersnatchSha512Ell2>;
pub type RingProver = ring_suite::RingProver<BandersnatchSha512Ell2>;
pub type RingVerifier = ring_suite::RingVerifier<BandersnatchSha512Ell2>;
pub type Proof = ring_suite::Proof<BandersnatchSha512Ell2>;

impl ring_suite::RingSuite for BandersnatchSha512Edwards {
impl ring_suite::RingSuite for BandersnatchSha512Ell2 {
type Pairing = ark_bls12_381::Bls12_381;

/// A point on the curve not belonging to the prime order subgroup.
Expand All @@ -194,27 +202,13 @@ pub mod edwards {
pub use ring_defs::*;

#[cfg(test)]
suite_tests!(BandersnatchSha512Edwards, true);
suite_tests!(BandersnatchSha512Ell2, true);

#[test]
fn test_elligator2_hash_to_curve() {
let point =
utils::hash_to_curve_ell2_rfc_9380::<BandersnatchSha512Edwards>(b"foo").unwrap();
fn elligator2_hash_to_curve() {
let point = BandersnatchSha512Ell2::data_to_point(b"foo").unwrap();
assert!(point.is_on_curve());
assert!(point.is_in_correct_subgroup_assuming_on_curve());

{
use ietf::{Prover, Verifier};

let secret = Secret::from_seed(b"asd");
let public = secret.public();
let input = Input::from(point);
let output = secret.output(input);

let proof = secret.prove(input, output, b"foo");
let result = public.verify(input, output, b"foo", &proof);
assert!(result.is_ok());
}
}
}

Expand Down
26 changes: 22 additions & 4 deletions src/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub(crate) fn hmac<H: Digest + digest::core_api::BlockSizeUser>(sk: &[u8], data:
.to_vec()
}

/// Try-And-Increment (TAI) method as defined by RFC9381 section 5.4.1.1.
/// Try-And-Increment (TAI) method as defined by RFC 9381 section 5.4.1.1.
///
/// Implements ECVRF_encode_to_curve in a simple and generic way that works
/// for any elliptic curve.
Expand All @@ -62,7 +62,7 @@ pub(crate) fn hmac<H: Digest + digest::core_api::BlockSizeUser>(sk: &[u8], data:
/// ciphersuites specified in Section 5.5, this algorithm is expected to
/// find a valid curve point after approximately two attempts on average.
///
/// The input `data` is defined to be `salt || alpha` according to the spec.
/// The input `data` is defined to be `salt || alpha` according to the RFC 9281.
pub fn hash_to_curve_tai_rfc_9381<S: Suite>(
data: &[u8],
point_be_encoding: bool,
Expand Down Expand Up @@ -103,7 +103,17 @@ pub fn hash_to_curve_tai_rfc_9381<S: Suite>(
None
}

pub fn hash_to_curve_ell2_rfc_9380<S: Suite>(data: &[u8]) -> Option<AffinePoint<S>>
/// Elligator2 method as defined by RFC 9380 and further refined in RFC 9381 section 5.4.1.2.
///
/// Implements ECVRF_encode_to_curve using one of the several hash-to-curve options defined
/// in [RFC9380]. The specific choice of the hash-to-curve option (called the Suite ID in [RFC9380])
/// is given by the h2c_suite_ID_string parameter.
///
/// The input `data` is defined to be `salt || alpha` according to the RFC 9281.
pub fn hash_to_curve_ell2_rfc_9380<S: Suite>(
data: &[u8],
h2c_suite_id: &[u8],
) -> Option<AffinePoint<S>>
where
<S as Suite>::Hasher: Default + Clone + FixedOutputReset + 'static,
crate::CurveConfig<S>: ark_ec::twisted_edwards::TECurveConfig,
Expand All @@ -114,11 +124,19 @@ where
use ark_ec::hashing::HashToCurve;
const SEC_PARAM: usize = 128;

// Domain Separation Tag := "ECVRF_" || h2c_suite_ID_string || suite_string
let dst: Vec<_> = b"ECVRF_"
.iter()
.chain(h2c_suite_id.iter())
.chain(S::SUITE_ID)
.cloned()
.collect();

let hasher = ark_ec::hashing::map_to_curve_hasher::MapToCurveBasedHasher::<
<AffinePoint<S> as AffineRepr>::Group,
ark_ff::field_hashers::DefaultFieldHasher<<S as Suite>::Hasher, SEC_PARAM>,
crate::arkworks::elligator2::Elligator2Map<crate::CurveConfig<S>>,
>::new(b"")
>::new(&dst)
.ok()?;

let res = hasher.hash(data).ok()?;
Expand Down

0 comments on commit 91101ed

Please sign in to comment.