Skip to content
Closed
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
45 changes: 18 additions & 27 deletions ff/src/fields/models/fp/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@
};
use allocative::Allocative;
use ark_serialize::{
buffer_byte_size, CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
CanonicalSerializeWithFlags, Compress, EmptyFlags, Flags, SerializationError, Valid, Validate,
buffer_byte_size,
};
use ark_std::{
cmp::*,
Expand Down Expand Up @@ -98,6 +99,11 @@
/// this range.
fn from_bigint(other: BigInt<N>) -> Option<Fp<Self, N>>;

/// Construct a field element from an integer in the range
/// `0..(Self::MODULUS - 1)`. Returns `None` if the integer is outside
/// this range (but do not do any Reductions)
fn from_bigint_unchecked(other: BigInt<N>) -> Option<Fp<Self, N>>;

/// Convert a field element to an integer in the range `0..(Self::MODULUS -
/// 1)`.
fn into_bigint(other: Fp<Self, N>) -> BigInt<N>;
Expand Down Expand Up @@ -371,6 +377,11 @@
P::into_bigint(self)
}

#[inline]
fn from_bigint_unchecked(r: BigInt<N>) -> Option<Self> {
P::from_bigint_unchecked(r)
}

#[inline]
fn from_u64<const NPLUS1: usize>(r: u64) -> Option<Self> {
P::from_u64::<NPLUS1>(r)
Expand Down Expand Up @@ -433,11 +444,7 @@
impl<P: FpConfig<N>, const N: usize> From<i128> for Fp<P, N> {
fn from(other: i128) -> Self {
let abs = Self::from(other.unsigned_abs());
if other.is_positive() {
abs
} else {
-abs
}
if other.is_positive() { abs } else { -abs }
}
}

Expand All @@ -464,11 +471,7 @@
impl<P: FpConfig<N>, const N: usize> From<i64> for Fp<P, N> {
fn from(other: i64) -> Self {
let abs = Self::from(other.unsigned_abs());
if other.is_positive() {
abs
} else {
-abs
}
if other.is_positive() { abs } else { -abs }
}
}

Expand All @@ -485,11 +488,7 @@
impl<P: FpConfig<N>, const N: usize> From<i32> for Fp<P, N> {
fn from(other: i32) -> Self {
let abs = Self::from(other.unsigned_abs());
if other.is_positive() {
abs
} else {
-abs
}
if other.is_positive() { abs } else { -abs }
}
}

Expand All @@ -506,11 +505,7 @@
impl<P: FpConfig<N>, const N: usize> From<i16> for Fp<P, N> {
fn from(other: i16) -> Self {
let abs = Self::from(other.unsigned_abs());
if other.is_positive() {
abs
} else {
-abs
}
if other.is_positive() { abs } else { -abs }
}
}

Expand All @@ -527,11 +522,7 @@
impl<P: FpConfig<N>, const N: usize> From<i8> for Fp<P, N> {
fn from(other: i8) -> Self {
let abs = Self::from(other.unsigned_abs());
if other.is_positive() {
abs
} else {
-abs
}
if other.is_positive() { abs } else { -abs }
}
}

Expand All @@ -554,7 +545,7 @@
u64::MAX >> shave_bits
};

if let Some(val) = tmp.0 .0.last_mut() {
if let Some(val) = tmp.0.0.last_mut() {
*val &= mask
}

Expand Down Expand Up @@ -696,7 +687,7 @@
impl<P: FpConfig<N>, const N: usize> Neg for Fp<P, N> {
type Output = Self;
#[inline]
#[must_use]

Check failure on line 690 in ff/src/fields/models/fp/mod.rs

View workflow job for this annotation

GitHub Actions / Test (stable)

`#[must_use]` has no effect when applied to a provided trait method

Check failure on line 690 in ff/src/fields/models/fp/mod.rs

View workflow job for this annotation

GitHub Actions / Test (nightly)

`#[must_use]` attribute cannot be used on trait methods in impl blocks

Check warning on line 690 in ff/src/fields/models/fp/mod.rs

View workflow job for this annotation

GitHub Actions / Test assembly

`#[must_use]` attribute cannot be used on trait methods in impl blocks
fn neg(mut self) -> Self {
P::neg_in_place(&mut self);
self
Expand Down
37 changes: 31 additions & 6 deletions ff/src/fields/models/fp/montgomery_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -462,6 +462,10 @@ pub trait MontConfig<const N: usize>: 'static + Sync + Send + Sized {
}
}

fn from_bigint_unchecked(r: BigInt<N>) -> Option<Fp<MontBackend<Self, N>, N>> {
Some(Fp::new_unchecked(r))
}

fn from_bigint(r: BigInt<N>) -> Option<Fp<MontBackend<Self, N>, N>> {
let mut r = Fp::new_unchecked(r);
if r.is_zero() {
Expand Down Expand Up @@ -493,7 +497,11 @@ pub trait MontConfig<const N: usize>: 'static + Sync + Send + Sized {
// return Fp::zero();
// }
let fe = Self::from_bigint_mixed::<M>(x.magnitude);
if x.is_positive { fe } else { -fe }
if x.is_positive {
fe
} else {
-fe
}
}

/// Construct from a signed big integer with high 32-bit tail and K low 64-bit limbs.
Expand All @@ -503,13 +511,20 @@ pub trait MontConfig<const N: usize>: 'static + Sync + Send + Sized {
fn from_signed_bigint_hi32<const K: usize, const KPLUS1: usize>(
x: crate::biginteger::SignedBigIntHi32<K>,
) -> Fp<MontBackend<Self, N>, N> {
debug_assert!(KPLUS1 == K + 1, "from_signed_bigint_hi32 requires KPLUS1 = K + 1");
debug_assert!(
KPLUS1 == K + 1,
"from_signed_bigint_hi32 requires KPLUS1 = K + 1"
);
// if x.is_zero() {
// return Fp::zero();
// }
let mag = x.magnitude_as_bigint_nplus1::<KPLUS1>();
let fe = Self::from_bigint_mixed::<KPLUS1>(mag);
if x.is_positive() { fe } else { -fe }
if x.is_positive() {
fe
} else {
-fe
}
}

#[inline]
Expand Down Expand Up @@ -834,6 +849,10 @@ impl<T: MontConfig<N>, const N: usize> FpConfig<N> for MontBackend<T, N> {
T::from_bigint(r)
}

fn from_bigint_unchecked(r: BigInt<N>) -> Option<Fp<Self, N>> {
T::from_bigint_unchecked(r)
}

#[inline]
#[allow(clippy::modulo_one)]
fn into_bigint(a: Fp<Self, N>) -> BigInt<N> {
Expand Down Expand Up @@ -882,9 +901,7 @@ impl<T: MontConfig<N>, const N: usize> Fp<MontBackend<T, N>, N> {
/// Implementation folds from high to low using the existing N+1 Barrett kernel.
/// Precondition: L >= N. For performance, prefer small L close to N..N+3 when possible.
#[inline(always)]
pub fn from_barrett_reduce<const L: usize, const NPLUS1: usize>(
unreduced: BigInt<L>,
) -> Self {
pub fn from_barrett_reduce<const L: usize, const NPLUS1: usize>(unreduced: BigInt<L>) -> Self {
debug_assert!(NPLUS1 == N + 1);
debug_assert!(L >= N);

Expand Down Expand Up @@ -1094,6 +1111,14 @@ impl<T: MontConfig<N>, const N: usize> Fp<MontBackend<T, N>, N> {
*self = self.const_cios_mul_rhs_hi2(hi as u64, (hi >> 64) as u64);
}

/// Returns self * rhs_high_limbs, where RHS is zero in low N-2 limbs and has its top two
/// limbs provided by `hi` (low 64 -> limb N-2, high 64 -> limb N-1). Equivalent to K=2.
/// At the cost 2 extra words of storage uses no bit shift instructions to extract higher limbs
/// as in mul_hi_u128
#[inline]
pub const fn mul_hi_bigint_u128(self, big_int_repre: [u64; 4]) -> Self {
self.const_cios_mul_rhs_hi2(big_int_repre[2], big_int_repre[3])
}
/// Returns self * rhs_high_limbs, where RHS is zero in low N-2 limbs and has its top two
/// limbs provided by `hi` (low 64 -> limb N-2, high 64 -> limb N-1). Equivalent to K=2.
#[inline]
Expand Down
3 changes: 3 additions & 0 deletions ff/src/fields/prime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ pub trait PrimeField:
/// Converts an element of the prime field into an integer in the range 0..(p - 1).
fn into_bigint(self) -> Self::BigInt;

/// Construct a prime field element from an integer in the range 0..(p - 1) (no reductions)
fn from_bigint_unchecked(repr: Self::BigInt) -> Option<Self>;

/// Creates a field element from a `u64`.
/// Returns `None` if the `u64` is larger than or equal to the modulus.
fn from_u64<const NPLUS1: usize>(val: u64) -> Option<Self>;
Expand Down
Loading