From f637f673153f17b8c6aa9f60325abccce3bddfaa Mon Sep 17 00:00:00 2001 From: skaunov Date: Mon, 2 Oct 2023 13:31:03 +0300 Subject: [PATCH] Malfunctioning example Some reference code to be saved at this point. It has two properties which are have to be dropped. * I struggled to preserve `CurveGroup::Affine` output, but seems there's no safe and generic way to do it. * Also tried to add `const fn` to switch to arrays, but I'm just not there yet. --- .../examples/reference_hash_to_curve.rs | 60 +++++++++++++++++++ rust-arkworks/src/hash_to_curve.rs | 21 +------ 2 files changed, 62 insertions(+), 19 deletions(-) create mode 100644 rust-arkworks/examples/reference_hash_to_curve.rs diff --git a/rust-arkworks/examples/reference_hash_to_curve.rs b/rust-arkworks/examples/reference_hash_to_curve.rs new file mode 100644 index 0000000..5e6e115 --- /dev/null +++ b/rust-arkworks/examples/reference_hash_to_curve.rs @@ -0,0 +1,60 @@ +// use ark_ec::{AffineCurve, ProjectiveCurve}; +use ark_ec::{AffineRepr, CurveGroup, CurveConfig, short_weierstrass::SWCurveConfig}; +use tiny_keccak::{Hasher, Shake, Xof}; +use elliptic_curve::hash2curve::{ExpandMsgXmd, GroupDigest}; +use k256::AffinePoint; +use k256::sha2::Sha256; +use elliptic_curve::sec1::ToEncodedPoint; +// use ark_ec::short_weierstrass_jacobian::GroupAffine; +use k256::{ProjectivePoint, Secp256k1}; +use ark_ff::{BigInteger, BigInt, fields::{Field, PrimeField}}; + +const fn digest_len(modulus_bit_size: u32) -> usize {(modulus_bit_size/8 + if modulus_bit_size % 8 != 0 {1} else {0}) as usize} +const fn bigint_len(bytearray_size: usize) -> usize {bytearray_size/8 + if bytearray_size % 8 != 0 {1} else {0}} + +/// Kobi's hash_to_curve function, here for reference only +struct NaiveBytes(Vec); +impl Default for NaiveBytes {fn default() -> Self {Self(vec![0])}} +impl NaiveBytes {fn incement(&mut self) { + // TODO would be nice to make field private so that `unwrap` had no chance to panic + if self.0.iter().last().unwrap() == &u8::MAX {self.0.push(0);} + else { + self.0[self.0.len() - 1] += 1; + } +}} + +pub fn _try_and_increment(msg: &[u8]) -> C::Affine { +// pub fn _try_and_increment(msg: &[u8]) -> Affine { +// `SWCurveConfig` chosen here just as a most general curve description, which can be tuned further with more appropriate to the task modules + let nonce = NaiveBytes::default(); + loop { + let mut h = Shake::v128(); + h.update(&nonce.0); + h.update(msg.as_ref()); + // let width_bits = C::Affine::MODULUS_BIT_SIZE /* + 1 */; + // let output_size = width_bits / 8 + if width_bits % 8 != 0 {1} else {0}; + + // as this one isn't intended to work with greater than 256 bits groups, checks for digest being long enough are omitted here + assert!(<::BaseField as Field>::BasePrimeField::MODULUS_BIT_SIZE <= 256u32); // just to be sure + + let mut output_u8 = [0u8; digest_len(<::BaseField as Field>::BasePrimeField::MODULUS_BIT_SIZE)]; + h.squeeze(&mut output_u8); + + // `from_bytes_be(sign: Sign, bytes: &[u8])` + // `assert_eq!(BigInt::from_bytes_be(Sign::Plus, b"A"), + // BigInt::parse_bytes(b"65", 10).unwrap());` + + let output_u64 = output_u8.into_iter().chunk(8).map(|(i, chunk)| {chunk as u64}); + // TODO check that `BigInt::new` is actually BE + if BigInt::new(output_u64).into() < <::BaseField as Field>::BasePrimeField::MODULUS { + if let Some( + result + ) = ark_ec::short_weierstrass::Affine::get_point_from_x_unchecked( + // ) = ark_ec::models::short_weierstrass::Affine::get_point_from_x_unchecked( + <::BaseField as Field>::BasePrimeField::from_be_bytes_mod_order(&output_u8), + nonce.0.iter().last().unwrap() % 2 == 1 + ) {return result.into_group().into_affine();} + } + // else {dbg!(nonce.0)} + } +} diff --git a/rust-arkworks/src/hash_to_curve.rs b/rust-arkworks/src/hash_to_curve.rs index 9a0a499..a498dcd 100644 --- a/rust-arkworks/src/hash_to_curve.rs +++ b/rust-arkworks/src/hash_to_curve.rs @@ -11,6 +11,8 @@ use k256::{ProjectivePoint, Secp256k1}; use ark_ff::FromBytes; use secp256k1::Sec1EncodePoint; +// for reference see <../examples/> + pub fn hash_to_curve< Fp: ark_ff::PrimeField, // P: ark_ec::SWModelParameters, @@ -69,22 +71,3 @@ pub fn k256_affine_to_arkworks_secp256k1_affine< GroupAffine::

::new(g_x, g_y, false) } - -/// Kobi's hash_to_curve function, here for reference only -pub fn _try_and_increment(msg: &[u8]) -> Result { - for nonce in 0u8..=255 { - let mut h = Shake::v128(); - h.update(&[nonce]); - h.update(msg.as_ref()); - let output_size = C::zero().serialized_size(ark_serialize::Compress::Yes); - // TODO try to replace with an array sized with a generic number - let mut output = vec![0u8; output_size]; - h.squeeze(&mut output); - - if let Some(p) = C::Affine::from_random_bytes(&output) { - return Ok(p); - } - } - - Err(EcError::CannotHashToCurve) -}