Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Field::from_base_prime_field_elems takes Iterator, not slice. #677

Merged
merged 2 commits into from
Sep 8, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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