diff --git a/src/ring.rs b/src/ring.rs index b280144..900d29f 100644 --- a/src/ring.rs +++ b/src/ring.rs @@ -368,10 +368,11 @@ pub(crate) mod testing { pub fn accumulator_base_check() where BaseField: ark_ff::PrimeField, - AffinePoint: ring_proof::AffineCondAdd, + AffinePoint: ring_proof::AffineCondAdd + utils::common::FindAccumulatorBase, { + use utils::common::FindAccumulatorBase; const ACCUMULATOR_BASE_SEED: &[u8] = b"w3f/ring-proof/accumulator"; - let p = S::data_to_point(ACCUMULATOR_BASE_SEED).unwrap(); + let p = AffinePoint::::find_accumulator_base(ACCUMULATOR_BASE_SEED).unwrap(); assert_eq!(S::ACCUMULATOR_BASE, p); } diff --git a/src/suites/bandersnatch.rs b/src/suites/bandersnatch.rs index ded9d5f..9db572f 100644 --- a/src/suites/bandersnatch.rs +++ b/src/suites/bandersnatch.rs @@ -98,10 +98,10 @@ pub mod weierstrass { const ACCUMULATOR_BASE: AffinePoint = { const X: BaseField = MontFp!( - "35802491285899595673230581729646824849514038723976226341205595068750227004007" + "15150996146563882842769969038633761710782764651218288537939960956638818073022" ); const Y: BaseField = MontFp!( - "17572023958760623860499337087020156281410269069550950996534533909010878422310" + "16757608954684538402264076732157050129188667760550924730618160766485829703559" ); AffinePoint::new_unchecked(X, Y) }; diff --git a/src/utils/common.rs b/src/utils/common.rs index 5cdd69d..274a7bb 100644 --- a/src/utils/common.rs +++ b/src/utils/common.rs @@ -1,6 +1,10 @@ use crate::*; -use ark_ec::AffineRepr; +use ark_ec::{ + short_weierstrass::{self, SWCurveConfig}, + twisted_edwards::{self, TECurveConfig}, + AffineRepr, +}; use ark_ff::PrimeField; use digest::{Digest, FixedOutputReset}; @@ -92,9 +96,9 @@ pub fn hash_to_curve_ell2_rfc_9380( ) -> Option> where ::Hasher: Default + Clone + FixedOutputReset + 'static, - crate::CurveConfig: ark_ec::twisted_edwards::TECurveConfig, - crate::CurveConfig: crate::utils::elligator2::Elligator2Config, - crate::utils::elligator2::Elligator2Map>: + CurveConfig: ark_ec::twisted_edwards::TECurveConfig, + CurveConfig: utils::elligator2::Elligator2Config, + utils::elligator2::Elligator2Map>: ark_ec::hashing::map_to_curve_hasher::MapToCurve< as AffineRepr>::Group>, { use ark_ec::hashing::HashToCurve; @@ -111,7 +115,7 @@ where let hasher = ark_ec::hashing::map_to_curve_hasher::MapToCurveBasedHasher::< as AffineRepr>::Group, ark_ff::field_hashers::DefaultFieldHasher<::Hasher, SEC_PARAM>, - crate::utils::elligator2::Elligator2Map>, + utils::elligator2::Elligator2Map>, >::new(&dst) .ok()?; @@ -208,10 +212,71 @@ where S::Codec::scalar_decode(&v) } +pub trait FindComplementPoint: Sized { + fn try_from(r: C::BaseField) -> Option; + + fn find_complement_point() -> Self { + use ark_ff::{One, Zero}; + assert!(!C::cofactor_is_one()); + let mut r = C::BaseField::zero(); + loop { + if let Some(p) = Self::try_from(r) { + return p; + } + r += C::BaseField::one(); + } + } +} + +impl FindComplementPoint for short_weierstrass::Affine { + fn try_from(r: C::BaseField) -> Option { + Self::get_point_from_x_unchecked(r, false) + .filter(|p| !p.is_in_correct_subgroup_assuming_on_curve()) + } +} + +impl FindComplementPoint for twisted_edwards::Affine { + fn try_from(r: C::BaseField) -> Option { + Self::get_point_from_y_unchecked(r, false) + .filter(|p| !p.is_in_correct_subgroup_assuming_on_curve()) + } +} + +pub trait FindAccumulatorBase: Sized { + #[allow(dead_code)] + fn find_accumulator_base(data: &[u8]) -> Option; +} + +impl FindAccumulatorBase for short_weierstrass::Affine +where + C: SWCurveConfig, + S: Suite, +{ + fn find_accumulator_base(data: &[u8]) -> Option { + let p = S::data_to_point(data)?; + let c = Self::find_complement_point(); + let res = (p + c).into_affine(); + debug_assert!(!res.is_in_correct_subgroup_assuming_on_curve()); + Some(res) + } +} + +impl FindAccumulatorBase for twisted_edwards::Affine +where + C: TECurveConfig, + S: Suite, +{ + fn find_accumulator_base(data: &[u8]) -> Option { + let res = S::data_to_point(data)?; + debug_assert!(res.is_in_correct_subgroup_assuming_on_curve()); + Some(res) + } +} + #[cfg(test)] mod tests { use super::*; - use crate::suites::testing::TestSuite; + use suites::testing::TestSuite; #[test] fn hash_to_curve_tai_works() {