diff --git a/ff/src/fields/field_hashers/mod.rs b/ff/src/fields/field_hashers/mod.rs index 82454f231..bfd44f231 100644 --- a/ff/src/fields/field_hashers/mod.rs +++ b/ff/src/fields/field_hashers/mod.rs @@ -81,7 +81,7 @@ impl HashToFie ); base_prime_field_elems.push(val); } - let f = F::from_base_prime_field_elems(&base_prime_field_elems).unwrap(); + let f = F::from_base_prime_field_elems(base_prime_field_elems.drain(..)).unwrap(); output.push(f); } diff --git a/ff/src/fields/mod.rs b/ff/src/fields/mod.rs index 2f85643d4..340ccc2fe 100644 --- a/ff/src/fields/mod.rs +++ b/ff/src/fields/mod.rs @@ -8,6 +8,7 @@ use ark_serialize::{ use ark_std::{ fmt::{Debug, Display}, hash::Hash, + iter::IntoIterator, ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}, vec::Vec, }; @@ -224,7 +225,9 @@ pub trait Field: /// Convert a slice of base prime field elements into a field element. /// If the slice length != Self::extension_degree(), must return None. - fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option; + fn from_base_prime_field_elems( + elems: impl IntoIterator, + ) -> Option; /// Constructs a field element from a single base prime field elements. /// ``` diff --git a/ff/src/fields/models/cubic_extension.rs b/ff/src/fields/models/cubic_extension.rs index 8369706be..6771911f8 100644 --- a/ff/src/fields/models/cubic_extension.rs +++ b/ff/src/fields/models/cubic_extension.rs @@ -6,7 +6,7 @@ use ark_std::{ cmp::{Ord, Ordering, PartialOrd}, fmt, io::{Read, Write}, - iter::Chain, + iter::{Chain, IntoIterator}, ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}, vec::Vec, }; @@ -216,17 +216,22 @@ impl Field for CubicExtField

{ ) } - fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option { - if elems.len() != (Self::extension_degree() as usize) { - return None; - } + fn from_base_prime_field_elems( + elems: impl IntoIterator, + ) -> Option { + let mut elems = elems.into_iter(); + let elems = elems.by_ref(); let base_ext_deg = P::BaseField::extension_degree() as usize; - Some(Self::new( - P::BaseField::from_base_prime_field_elems(&elems[0..base_ext_deg]).unwrap(), - P::BaseField::from_base_prime_field_elems(&elems[base_ext_deg..2 * base_ext_deg]) - .unwrap(), - P::BaseField::from_base_prime_field_elems(&elems[2 * base_ext_deg..]).unwrap(), - )) + let element = Some(Self::new( + P::BaseField::from_base_prime_field_elems(elems.take(base_ext_deg))?, + P::BaseField::from_base_prime_field_elems(elems.take(base_ext_deg))?, + P::BaseField::from_base_prime_field_elems(elems.take(base_ext_deg))?, + )); + if elems.next().is_some() { + None + } else { + element + } } #[inline] @@ -734,7 +739,7 @@ mod cube_ext_tests { for _ in 0..d { random_coeffs.push(Fq::rand(&mut test_rng())); } - let res = Fq6::from_base_prime_field_elems(&random_coeffs); + let res = Fq6::from_base_prime_field_elems(random_coeffs); assert_eq!(res, None); } // Test on slice lengths that are equal to the extension degree @@ -745,12 +750,13 @@ mod cube_ext_tests { for _ in 0..ext_degree { random_coeffs.push(Fq::rand(&mut test_rng())); } - let actual = Fq6::from_base_prime_field_elems(&random_coeffs).unwrap(); let expected_0 = Fq2::new(random_coeffs[0], random_coeffs[1]); let expected_1 = Fq2::new(random_coeffs[2], random_coeffs[3]); let expected_2 = Fq2::new(random_coeffs[3], random_coeffs[4]); let expected = Fq6::new(expected_0, expected_1, expected_2); + + let actual = Fq6::from_base_prime_field_elems(random_coeffs).unwrap(); assert_eq!(actual, expected); } } @@ -766,7 +772,7 @@ mod cube_ext_tests { random_coeffs[0] = random_coeff; assert_eq!( res, - Fq6::from_base_prime_field_elems(&random_coeffs).unwrap() + Fq6::from_base_prime_field_elems(random_coeffs).unwrap() ); } } diff --git a/ff/src/fields/models/fp/mod.rs b/ff/src/fields/models/fp/mod.rs index 1113c1222..48ee18a5d 100644 --- a/ff/src/fields/models/fp/mod.rs +++ b/ff/src/fields/models/fp/mod.rs @@ -232,11 +232,15 @@ impl, const N: usize> Field for Fp { iter::once(*self) } - fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option { - if elems.len() != (Self::extension_degree() as usize) { + fn from_base_prime_field_elems( + elems: impl IntoIterator, + ) -> Option { + let mut elems = elems.into_iter(); + let elem = elems.next()?; + if elems.next().is_some() { return None; } - Some(elems[0]) + Some(elem) } #[inline] diff --git a/ff/src/fields/models/quadratic_extension.rs b/ff/src/fields/models/quadratic_extension.rs index 5d7f6de96..f80f9f1b0 100644 --- a/ff/src/fields/models/quadratic_extension.rs +++ b/ff/src/fields/models/quadratic_extension.rs @@ -6,7 +6,7 @@ use ark_std::{ cmp::{Ord, Ordering, PartialOrd}, fmt, io::{Read, Write}, - iter::Chain, + iter::{Chain, IntoIterator}, ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Sub, SubAssign}, vec::Vec, }; @@ -242,15 +242,21 @@ impl Field for QuadExtField

{ .chain(self.c1.to_base_prime_field_elements()) } - fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option { - if elems.len() != (Self::extension_degree() as usize) { - return None; - } + fn from_base_prime_field_elems( + elems: impl IntoIterator, + ) -> Option { + let mut elems = elems.into_iter(); + let elems = elems.by_ref(); let base_ext_deg = P::BaseField::extension_degree() as usize; - Some(Self::new( - P::BaseField::from_base_prime_field_elems(&elems[0..base_ext_deg]).unwrap(), - P::BaseField::from_base_prime_field_elems(&elems[base_ext_deg..]).unwrap(), - )) + let element = Some(Self::new( + P::BaseField::from_base_prime_field_elems(elems.take(base_ext_deg))?, + P::BaseField::from_base_prime_field_elems(elems.take(base_ext_deg))?, + )); + if elems.next().is_some() { + None + } else { + element + } } fn square(&self) -> Self { @@ -794,7 +800,7 @@ mod quad_ext_tests { for _ in 0..d { random_coeffs.push(Fq::rand(&mut test_rng())); } - let res = Fq2::from_base_prime_field_elems(&random_coeffs); + let res = Fq2::from_base_prime_field_elems(random_coeffs); assert_eq!(res, None); } // Test on slice lengths that are equal to the extension degree @@ -805,8 +811,8 @@ mod quad_ext_tests { for _ in 0..ext_degree { random_coeffs.push(Fq::rand(&mut test_rng())); } - let actual = Fq2::from_base_prime_field_elems(&random_coeffs).unwrap(); let expected = Fq2::new(random_coeffs[0], random_coeffs[1]); + let actual = Fq2::from_base_prime_field_elems(random_coeffs).unwrap(); assert_eq!(actual, expected); } } @@ -822,7 +828,7 @@ mod quad_ext_tests { random_coeffs[0] = random_coeff; assert_eq!( res, - Fq2::from_base_prime_field_elems(&random_coeffs).unwrap() + Fq2::from_base_prime_field_elems(random_coeffs).unwrap() ); } } diff --git a/test-templates/src/h2c/mod.rs b/test-templates/src/h2c/mod.rs index c65391d23..4cd52eb35 100644 --- a/test-templates/src/h2c/mod.rs +++ b/test-templates/src/h2c/mod.rs @@ -63,8 +63,8 @@ macro_rules! test_h2c { let y = read_fq_vec(&v.p.y); let got = g1_mapper.hash(&v.msg.as_bytes()).unwrap(); let want = Affine::<$group>::new_unchecked( - <$field>::from_base_prime_field_elems(&x[..]).unwrap(), - <$field>::from_base_prime_field_elems(&y[..]).unwrap(), + <$field>::from_base_prime_field_elems(x).unwrap(), + <$field>::from_base_prime_field_elems(y).unwrap(), ); assert!(got.is_on_curve()); assert!(want.is_on_curve());