Skip to content

Commit

Permalink
Add a few simplifications around Mont inverse (arkworks-rs#788)
Browse files Browse the repository at this point in the history
* Add a few simplifications around Mont inverse

* Update ff/src/biginteger/mod.rs

Co-authored-by: Pratyush Mishra <pratyush795@gmail.com>

---------

Co-authored-by: Pratyush Mishra <pratyush795@gmail.com>
  • Loading branch information
tcoratger and Pratyush authored Feb 27, 2024
1 parent 80e7b5a commit 2a8f518
Show file tree
Hide file tree
Showing 2 changed files with 46 additions and 48 deletions.
3 changes: 1 addition & 2 deletions ff/src/biginteger/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,7 @@ impl<const N: usize> BigInteger for BigInt<N> {
#[inline]
fn div2(&mut self) {
let mut t = 0;
for i in 0..N {
let a = &mut self.0[N - i - 1];
for a in self.0.iter_mut().rev() {
let t2 = *a << 63;
*a >>= 1;
*a |= t;
Expand Down
91 changes: 45 additions & 46 deletions ff/src/fields/models/fp/montgomery_backend.rs
Original file line number Diff line number Diff line change
Expand Up @@ -295,64 +295,63 @@ pub trait MontConfig<const N: usize>: 'static + Sync + Send + Sized {

fn inverse(a: &Fp<MontBackend<Self, N>, N>) -> Option<Fp<MontBackend<Self, N>, N>> {
if a.is_zero() {
None
} else {
// Guajardo Kumar Paar Pelzl
// Efficient Software-Implementation of Finite Fields with Applications to
// Cryptography
// Algorithm 16 (BEA for Inversion in Fp)

let one = BigInt::from(1u64);

let mut u = a.0;
let mut v = Self::MODULUS;
let mut b = Fp::new_unchecked(Self::R2); // Avoids unnecessary reduction step.
let mut c = Fp::zero();

while u != one && v != one {
while u.is_even() {
u.div2();

if b.0.is_even() {
b.0.div2();
} else {
let carry = b.0.add_with_carry(&Self::MODULUS);
b.0.div2();
if !Self::MODULUS_HAS_SPARE_BIT && carry {
(b.0).0[N - 1] |= 1 << 63;
}
}
}
return None;
}
// Guajardo Kumar Paar Pelzl
// Efficient Software-Implementation of Finite Fields with Applications to
// Cryptography
// Algorithm 16 (BEA for Inversion in Fp)

while v.is_even() {
v.div2();
let one = BigInt::from(1u64);

if c.0.is_even() {
c.0.div2();
} else {
let carry = c.0.add_with_carry(&Self::MODULUS);
c.0.div2();
if !Self::MODULUS_HAS_SPARE_BIT && carry {
(c.0).0[N - 1] |= 1 << 63;
}
let mut u = a.0;
let mut v = Self::MODULUS;
let mut b = Fp::new_unchecked(Self::R2); // Avoids unnecessary reduction step.
let mut c = Fp::zero();

while u != one && v != one {
while u.is_even() {
u.div2();

if b.0.is_even() {
b.0.div2();
} else {
let carry = b.0.add_with_carry(&Self::MODULUS);
b.0.div2();
if !Self::MODULUS_HAS_SPARE_BIT && carry {
(b.0).0[N - 1] |= 1 << 63;
}
}
}

while v.is_even() {
v.div2();

if v < u {
u.sub_with_borrow(&v);
b -= &c;
if c.0.is_even() {
c.0.div2();
} else {
v.sub_with_borrow(&u);
c -= &b;
let carry = c.0.add_with_carry(&Self::MODULUS);
c.0.div2();
if !Self::MODULUS_HAS_SPARE_BIT && carry {
(c.0).0[N - 1] |= 1 << 63;
}
}
}

if u == one {
Some(b)
if v < u {
u.sub_with_borrow(&v);
b -= &c;
} else {
Some(c)
v.sub_with_borrow(&u);
c -= &b;
}
}

if u == one {
Some(b)
} else {
Some(c)
}
}

fn from_bigint(r: BigInt<N>) -> Option<Fp<MontBackend<Self, N>, N>> {
Expand Down

0 comments on commit 2a8f518

Please sign in to comment.