From 69b98623a10ff0c437b67b9769ff1918b2f9932e Mon Sep 17 00:00:00 2001 From: Daniel Lubarov Date: Tue, 30 Mar 2021 11:46:36 -0700 Subject: [PATCH] Batch inverse (ported from plonky1) --- src/field/batch_inverse.rs | 30 ++++++++++++++++++++++++++++++ src/field/mod.rs | 1 + 2 files changed, 31 insertions(+) create mode 100644 src/field/batch_inverse.rs diff --git a/src/field/batch_inverse.rs b/src/field/batch_inverse.rs new file mode 100644 index 00000000..0e86f5f5 --- /dev/null +++ b/src/field/batch_inverse.rs @@ -0,0 +1,30 @@ +use crate::field::field::Field; + +fn batch_multiplicative_inverse(x: &[F]) -> Vec { + // This is Montgomery's trick. At a high level, we invert the product of the given field + // elements, then derive the individual inverses from that via multiplication. + + let n = x.len(); + if n == 0 { + return Vec::new(); + } + + let mut a = Vec::with_capacity(n); + a.push(x[0]); + for i in 1..n { + a.push(a[i - 1] * x[i]); + } + + let mut a_inv = vec![F::ZERO; n]; + a_inv[n - 1] = a[n - 1].try_inverse().expect("No inverse"); + for i in (0..n - 1).rev() { + a_inv[i] = x[i + 1] * a_inv[i + 1]; + } + + let mut x_inv = Vec::with_capacity(n); + x_inv.push(a_inv[0]); + for i in 1..n { + x_inv.push(a[i - 1] * a_inv[i]); + } + x_inv +} diff --git a/src/field/mod.rs b/src/field/mod.rs index 027dd742..234fa73a 100644 --- a/src/field/mod.rs +++ b/src/field/mod.rs @@ -1,3 +1,4 @@ +pub(crate) mod batch_inverse; pub(crate) mod crandall_field; pub(crate) mod field; pub(crate) mod field_search;