Skip to content

Commit df0643e

Browse files
committed
Merge remote-tracking branch 'ari/feat/fewer-reductions' into feat/snark-composition
2 parents d691e95 + fee4ab2 commit df0643e

File tree

3 files changed

+52
-33
lines changed

3 files changed

+52
-33
lines changed

ff/src/fields/models/fp/mod.rs

Lines changed: 18 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@ use crate::{
44
};
55
use allocative::Allocative;
66
use ark_serialize::{
7-
buffer_byte_size, CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
7+
CanonicalDeserialize, CanonicalDeserializeWithFlags, CanonicalSerialize,
88
CanonicalSerializeWithFlags, Compress, EmptyFlags, Flags, SerializationError, Valid, Validate,
9+
buffer_byte_size,
910
};
1011
use ark_std::{
1112
cmp::*,
@@ -98,6 +99,11 @@ pub trait FpConfig<const N: usize>: Send + Sync + 'static + Sized {
9899
/// this range.
99100
fn from_bigint(other: BigInt<N>) -> Option<Fp<Self, N>>;
100101

102+
/// Construct a field element from an integer in the range
103+
/// `0..(Self::MODULUS - 1)`. Returns `None` if the integer is outside
104+
/// this range (but do not do any Reductions)
105+
fn from_bigint_unchecked(other: BigInt<N>) -> Option<Fp<Self, N>>;
106+
101107
/// Convert a field element to an integer in the range `0..(Self::MODULUS -
102108
/// 1)`.
103109
fn into_bigint(other: Fp<Self, N>) -> BigInt<N>;
@@ -371,6 +377,11 @@ impl<P: FpConfig<N>, const N: usize> PrimeField for Fp<P, N> {
371377
P::into_bigint(self)
372378
}
373379

380+
#[inline]
381+
fn from_bigint_unchecked(r: BigInt<N>) -> Option<Self> {
382+
P::from_bigint_unchecked(r)
383+
}
384+
374385
#[inline]
375386
fn from_u64<const NPLUS1: usize>(r: u64) -> Option<Self> {
376387
P::from_u64::<NPLUS1>(r)
@@ -433,11 +444,7 @@ impl<P: FpConfig<N>, const N: usize> From<u128> for Fp<P, N> {
433444
impl<P: FpConfig<N>, const N: usize> From<i128> for Fp<P, N> {
434445
fn from(other: i128) -> Self {
435446
let abs = Self::from(other.unsigned_abs());
436-
if other.is_positive() {
437-
abs
438-
} else {
439-
-abs
440-
}
447+
if other.is_positive() { abs } else { -abs }
441448
}
442449
}
443450

@@ -464,11 +471,7 @@ impl<P: FpConfig<N>, const N: usize> From<u64> for Fp<P, N> {
464471
impl<P: FpConfig<N>, const N: usize> From<i64> for Fp<P, N> {
465472
fn from(other: i64) -> Self {
466473
let abs = Self::from(other.unsigned_abs());
467-
if other.is_positive() {
468-
abs
469-
} else {
470-
-abs
471-
}
474+
if other.is_positive() { abs } else { -abs }
472475
}
473476
}
474477

@@ -485,11 +488,7 @@ impl<P: FpConfig<N>, const N: usize> From<u32> for Fp<P, N> {
485488
impl<P: FpConfig<N>, const N: usize> From<i32> for Fp<P, N> {
486489
fn from(other: i32) -> Self {
487490
let abs = Self::from(other.unsigned_abs());
488-
if other.is_positive() {
489-
abs
490-
} else {
491-
-abs
492-
}
491+
if other.is_positive() { abs } else { -abs }
493492
}
494493
}
495494

@@ -506,11 +505,7 @@ impl<P: FpConfig<N>, const N: usize> From<u16> for Fp<P, N> {
506505
impl<P: FpConfig<N>, const N: usize> From<i16> for Fp<P, N> {
507506
fn from(other: i16) -> Self {
508507
let abs = Self::from(other.unsigned_abs());
509-
if other.is_positive() {
510-
abs
511-
} else {
512-
-abs
513-
}
508+
if other.is_positive() { abs } else { -abs }
514509
}
515510
}
516511

@@ -527,11 +522,7 @@ impl<P: FpConfig<N>, const N: usize> From<u8> for Fp<P, N> {
527522
impl<P: FpConfig<N>, const N: usize> From<i8> for Fp<P, N> {
528523
fn from(other: i8) -> Self {
529524
let abs = Self::from(other.unsigned_abs());
530-
if other.is_positive() {
531-
abs
532-
} else {
533-
-abs
534-
}
525+
if other.is_positive() { abs } else { -abs }
535526
}
536527
}
537528

@@ -554,7 +545,7 @@ impl<P: FpConfig<N>, const N: usize> ark_std::rand::distributions::Distribution<
554545
u64::MAX >> shave_bits
555546
};
556547

557-
if let Some(val) = tmp.0 .0.last_mut() {
548+
if let Some(val) = tmp.0.0.last_mut() {
558549
*val &= mask
559550
}
560551

ff/src/fields/models/fp/montgomery_backend.rs

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -462,6 +462,10 @@ pub trait MontConfig<const N: usize>: 'static + Sync + Send + Sized {
462462
}
463463
}
464464

465+
fn from_bigint_unchecked(r: BigInt<N>) -> Option<Fp<MontBackend<Self, N>, N>> {
466+
Some(Fp::new_unchecked(r))
467+
}
468+
465469
fn from_bigint(r: BigInt<N>) -> Option<Fp<MontBackend<Self, N>, N>> {
466470
let mut r = Fp::new_unchecked(r);
467471
if r.is_zero() {
@@ -493,7 +497,11 @@ pub trait MontConfig<const N: usize>: 'static + Sync + Send + Sized {
493497
// return Fp::zero();
494498
// }
495499
let fe = Self::from_bigint_mixed::<M>(x.magnitude);
496-
if x.is_positive { fe } else { -fe }
500+
if x.is_positive {
501+
fe
502+
} else {
503+
-fe
504+
}
497505
}
498506

499507
/// Construct from a signed big integer with high 32-bit tail and K low 64-bit limbs.
@@ -503,13 +511,20 @@ pub trait MontConfig<const N: usize>: 'static + Sync + Send + Sized {
503511
fn from_signed_bigint_hi32<const K: usize, const KPLUS1: usize>(
504512
x: crate::biginteger::SignedBigIntHi32<K>,
505513
) -> Fp<MontBackend<Self, N>, N> {
506-
debug_assert!(KPLUS1 == K + 1, "from_signed_bigint_hi32 requires KPLUS1 = K + 1");
514+
debug_assert!(
515+
KPLUS1 == K + 1,
516+
"from_signed_bigint_hi32 requires KPLUS1 = K + 1"
517+
);
507518
// if x.is_zero() {
508519
// return Fp::zero();
509520
// }
510521
let mag = x.magnitude_as_bigint_nplus1::<KPLUS1>();
511522
let fe = Self::from_bigint_mixed::<KPLUS1>(mag);
512-
if x.is_positive() { fe } else { -fe }
523+
if x.is_positive() {
524+
fe
525+
} else {
526+
-fe
527+
}
513528
}
514529

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

852+
fn from_bigint_unchecked(r: BigInt<N>) -> Option<Fp<Self, N>> {
853+
T::from_bigint_unchecked(r)
854+
}
855+
837856
#[inline]
838857
#[allow(clippy::modulo_one)]
839858
fn into_bigint(a: Fp<Self, N>) -> BigInt<N> {
@@ -882,9 +901,7 @@ impl<T: MontConfig<N>, const N: usize> Fp<MontBackend<T, N>, N> {
882901
/// Implementation folds from high to low using the existing N+1 Barrett kernel.
883902
/// Precondition: L >= N. For performance, prefer small L close to N..N+3 when possible.
884903
#[inline(always)]
885-
pub fn from_barrett_reduce<const L: usize, const NPLUS1: usize>(
886-
unreduced: BigInt<L>,
887-
) -> Self {
904+
pub fn from_barrett_reduce<const L: usize, const NPLUS1: usize>(unreduced: BigInt<L>) -> Self {
888905
debug_assert!(NPLUS1 == N + 1);
889906
debug_assert!(L >= N);
890907

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

1114+
/// Returns self * rhs_high_limbs, where RHS is zero in low N-2 limbs and has its top two
1115+
/// limbs provided by `hi` (low 64 -> limb N-2, high 64 -> limb N-1). Equivalent to K=2.
1116+
/// At the cost 2 extra words of storage uses no bit shift instructions to extract higher limbs
1117+
/// as in mul_hi_u128
1118+
#[inline]
1119+
pub const fn mul_hi_bigint_u128(self, big_int_repre: [u64; 4]) -> Self {
1120+
self.const_cios_mul_rhs_hi2(big_int_repre[2], big_int_repre[3])
1121+
}
10971122
/// Returns self * rhs_high_limbs, where RHS is zero in low N-2 limbs and has its top two
10981123
/// limbs provided by `hi` (low 64 -> limb N-2, high 64 -> limb N-1). Equivalent to K=2.
10991124
#[inline]

ff/src/fields/prime.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ pub trait PrimeField:
5757
/// Converts an element of the prime field into an integer in the range 0..(p - 1).
5858
fn into_bigint(self) -> Self::BigInt;
5959

60+
/// Construct a prime field element from an integer in the range 0..(p - 1) (no reductions)
61+
fn from_bigint_unchecked(repr: Self::BigInt) -> Option<Self>;
62+
6063
/// Creates a field element from a `u64`.
6164
/// Returns `None` if the `u64` is larger than or equal to the modulus.
6265
fn from_u64<const NPLUS1: usize>(val: u64) -> Option<Self>;

0 commit comments

Comments
 (0)