Skip to content

Commit

Permalink
Add implementations of From<iXXX> for prime fields as well
Browse files Browse the repository at this point in the history
  • Loading branch information
huitseeker committed Apr 16, 2021
1 parent fc60ad5 commit 0845db3
Show file tree
Hide file tree
Showing 5 changed files with 60 additions and 18 deletions.
1 change: 1 addition & 0 deletions ff/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ ark-std = { version = "0.2.0", default-features = false }
ark-serialize = { version = "^0.2.0", path = "../serialize", default-features = false }
derivative = { version = "2", features = ["use_core"] }
num-traits = { version = "0.2", default-features = false }
paste = "1.0"
rayon = { version = "1", optional = true }
zeroize = { version = "1", default-features = false, features = ["zeroize_derive"] }

Expand Down
45 changes: 41 additions & 4 deletions ff/src/fields/arithmetic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ macro_rules! impl_prime_field_standard_sample {
}

macro_rules! impl_prime_field_from_int {
($field: ident, u128, $params: ident, $limbs:expr) => {
($field: ident, 128, $params: ident, $limbs:expr) => {
impl<P: $params> From<u128> for $field<P> {
fn from(other: u128) -> Self {
let mut default_int = P::BigInt::default();
Expand All @@ -242,10 +242,22 @@ macro_rules! impl_prime_field_from_int {
Self::from_repr(default_int).unwrap()
}
}

impl <P: $params> From<i128> for $field<P> {
fn from(other: i128) -> Self {
let positive = other.is_positive();
let abs = Self::from(other.unsigned_abs());
if positive {
abs
} else {
-abs
}
}
}
};
($field: ident, $int: ident, $params: ident, $limbs:expr) => {
impl<P: $params> From<$int> for $field<P> {
fn from(other: $int) -> Self {
($field: ident, bool, $params: ident, $limbs:expr) => {
impl<P: $params> From<bool> for $field<P> {
fn from(other: bool) -> Self {
if $limbs == 1 {
Self::from_repr(P::BigInt::from(u64::from(other) % P::MODULUS.0[0])).unwrap()
} else {
Expand All @@ -254,6 +266,31 @@ macro_rules! impl_prime_field_from_int {
}
}
};
($field: ident, $int: expr, $params: ident, $limbs:expr) => {
paste::paste!{
impl<P: $params> From<[<u $int>]> for $field<P> {
fn from(other: [<u $int>]) -> Self {
if $limbs == 1 {
Self::from_repr(P::BigInt::from(u64::from(other) % P::MODULUS.0[0])).unwrap()
} else {
Self::from_repr(P::BigInt::from(u64::from(other))).unwrap()
}
}
}

impl<P: $params> From<[<i $int>]> for $field<P> {
fn from(other: [<i $int>]) -> Self {
let positive = other.is_positive();
let abs = Self::from(other.unsigned_abs());
if positive {
abs
} else {
-abs
}
}
}
}
};
}

macro_rules! sqrt_impl {
Expand Down
10 changes: 5 additions & 5 deletions ff/src/fields/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -515,11 +515,11 @@ macro_rules! impl_Fp {
}
}

impl_prime_field_from_int!($Fp, u128, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, u64, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, u32, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, u16, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, u8, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, 128, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, 64, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, 32, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, 16, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, 8, $FpParameters, $limbs);
impl_prime_field_from_int!($Fp, bool, $FpParameters, $limbs);

impl_prime_field_standard_sample!($Fp, $FpParameters);
Expand Down
3 changes: 2 additions & 1 deletion ff/src/fields/models/cubic_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@ impl<P: CubicExtParameters> CubicExtField<P> {
self.c2.mul_assign(value);
}

/// Calculate the norm of an element with respect to the base field `P::BaseField`.
/// Calculate the norm of an element with respect to the base field
/// `P::BaseField`.
pub fn norm(&self) -> P::BaseField {
let mut self_to_p = *self;
self_to_p.frobenius_map(1);
Expand Down
19 changes: 11 additions & 8 deletions ff/src/fields/models/quadratic_extension.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ use crate::{

/// Defines a Quadratic extension field from a quadratic non-residue.
pub trait QuadExtParameters: 'static + Send + Sync + Sized {
/// The prime field that this quadratic extension is eventually an extension of.
/// The prime field that this quadratic extension is eventually an extension
/// of.
type BasePrimeField: PrimeField;
/// The base field that this field is a quadratic extension of.
type BaseField: Field<BasePrimeField = Self::BasePrimeField>;
Expand Down Expand Up @@ -63,8 +64,8 @@ pub trait QuadExtParameters: 'static + Send + Sync + Sized {
*x + Self::mul_base_field_by_nonresidue(y)
}

/// A specializable method for computing x + mul_base_field_by_nonresidue(y) + y
/// This allows for optimizations when the non-residue is not -1.
/// A specializable method for computing x + mul_base_field_by_nonresidue(y)
/// + y This allows for optimizations when the non-residue is not -1.
#[inline(always)]
fn add_and_mul_base_field_by_nonresidue_plus_one(
x: &Self::BaseField,
Expand Down Expand Up @@ -148,12 +149,14 @@ impl<P: QuadExtParameters> QuadExtField<P> {
}
}

/// This is only to be used when the element is *known* to be in the cyclotomic subgroup.
/// This is only to be used when the element is *known* to be in the
/// cyclotomic subgroup.
pub fn conjugate(&mut self) {
self.c1 = -self.c1;
}

/// This is only to be used when the element is *known* to be in the cyclotomic subgroup.
/// This is only to be used when the element is *known* to be in the
/// cyclotomic subgroup.
pub fn cyclotomic_exp(&self, exponent: impl AsRef<[u64]>) -> Self {
P::cyclotomic_exp(self, exponent)
}
Expand Down Expand Up @@ -291,9 +294,9 @@ impl<P: QuadExtParameters> Field for QuadExtField<P> {
// result.c1 = 2 * c0 * c1
self.c1 = v2.double();
// result.c0 = (v0) + ((beta + 1) * v2)
// result.c0 = (c0^2 - beta * c0 * c1 - c0 * c1 + beta * c1^2) + ((beta + 1) c0 * c1)
// result.c0 = (c0^2 - beta * c0 * c1 + beta * c1^2) + (beta * c0 * c1)
// result.c0 = c0^2 + beta * c1^2
// result.c0 = (c0^2 - beta * c0 * c1 - c0 * c1 + beta * c1^2) + ((beta + 1) c0
// * c1) result.c0 = (c0^2 - beta * c0 * c1 + beta * c1^2) + (beta *
// c0 * c1) result.c0 = c0^2 + beta * c1^2
self.c0 = P::add_and_mul_base_field_by_nonresidue_plus_one(&v0, &v2);

self
Expand Down

0 comments on commit 0845db3

Please sign in to comment.