Skip to content

Commit

Permalink
Field::from_base_prime_field_elems takes Iterator, not slice. (#677)
Browse files Browse the repository at this point in the history
  • Loading branch information
burdges authored Sep 8, 2023
1 parent 9ea43e9 commit 2369347
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 33 deletions.
2 changes: 1 addition & 1 deletion ff/src/fields/field_hashers/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ impl<F: Field, H: Default + DynDigest + Clone, const SEC_PARAM: usize> 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);
}

Expand Down
5 changes: 4 additions & 1 deletion ff/src/fields/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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<Self>;
fn from_base_prime_field_elems(
elems: impl IntoIterator<Item = Self::BasePrimeField>,
) -> Option<Self>;

/// Constructs a field element from a single base prime field elements.
/// ```
Expand Down
34 changes: 20 additions & 14 deletions ff/src/fields/models/cubic_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -216,17 +216,22 @@ impl<P: CubicExtConfig> Field for CubicExtField<P> {
)
}

fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option<Self> {
if elems.len() != (Self::extension_degree() as usize) {
return None;
}
fn from_base_prime_field_elems(
elems: impl IntoIterator<Item = Self::BasePrimeField>,
) -> Option<Self> {
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]
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}
Expand All @@ -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()
);
}
}
Expand Down
10 changes: 7 additions & 3 deletions ff/src/fields/models/fp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -232,11 +232,15 @@ impl<P: FpConfig<N>, const N: usize> Field for Fp<P, N> {
iter::once(*self)
}

fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option<Self> {
if elems.len() != (Self::extension_degree() as usize) {
fn from_base_prime_field_elems(
elems: impl IntoIterator<Item = Self::BasePrimeField>,
) -> Option<Self> {
let mut elems = elems.into_iter();
let elem = elems.next()?;
if elems.next().is_some() {
return None;
}
Some(elems[0])
Some(elem)
}

#[inline]
Expand Down
30 changes: 18 additions & 12 deletions ff/src/fields/models/quadratic_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down Expand Up @@ -242,15 +242,21 @@ impl<P: QuadExtConfig> Field for QuadExtField<P> {
.chain(self.c1.to_base_prime_field_elements())
}

fn from_base_prime_field_elems(elems: &[Self::BasePrimeField]) -> Option<Self> {
if elems.len() != (Self::extension_degree() as usize) {
return None;
}
fn from_base_prime_field_elems(
elems: impl IntoIterator<Item = Self::BasePrimeField>,
) -> Option<Self> {
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 {
Expand Down Expand Up @@ -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
Expand All @@ -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);
}
}
Expand All @@ -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()
);
}
}
Expand Down
4 changes: 2 additions & 2 deletions test-templates/src/h2c/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
Expand Down

0 comments on commit 2369347

Please sign in to comment.