mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-03 06:13:07 +00:00
Faster squaring in extension fields (#318)
* Faster squaring for extension fields; use in cube(). * Add squaring to arithmetic benchmark. * Rename variable to remove warning; adjust comment. * Inline always (improves latency measurements a lot).
This commit is contained in:
parent
001c979599
commit
c406f464b8
@ -34,6 +34,32 @@ pub(crate) fn bench_field<F: Field>(c: &mut Criterion) {
|
||||
)
|
||||
});
|
||||
|
||||
c.bench_function(&format!("sqr-throughput<{}>", type_name::<F>()), |b| {
|
||||
b.iter_batched(
|
||||
|| (F::rand(), F::rand(), F::rand(), F::rand()),
|
||||
|(mut x, mut y, mut z, mut w)| {
|
||||
for _ in 0..25 {
|
||||
(x, y, z, w) = (x.square(), y.square(), z.square(), w.square());
|
||||
}
|
||||
(x, y, z, w)
|
||||
},
|
||||
BatchSize::SmallInput,
|
||||
)
|
||||
});
|
||||
|
||||
c.bench_function(&format!("sqr-latency<{}>", type_name::<F>()), |b| {
|
||||
b.iter_batched(
|
||||
|| F::rand(),
|
||||
|mut x| {
|
||||
for _ in 0..100 {
|
||||
x = x.square();
|
||||
}
|
||||
x
|
||||
},
|
||||
BatchSize::SmallInput,
|
||||
)
|
||||
});
|
||||
|
||||
c.bench_function(&format!("add-throughput<{}>", type_name::<F>()), |b| {
|
||||
b.iter_batched(
|
||||
|| {
|
||||
|
||||
@ -70,6 +70,19 @@ impl<F: Extendable<2>> Field for QuadraticExtension<F> {
|
||||
F::order() * F::order()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn square(&self) -> Self {
|
||||
// Specialising mul reduces the computation of c1 from 2 muls
|
||||
// and one add to one mul and a shift
|
||||
|
||||
let Self([a0, a1]) = *self;
|
||||
|
||||
let c0 = a0.square() + <Self as OEF<2>>::W * a1.square();
|
||||
let c1 = a0 * a1.double();
|
||||
|
||||
Self([c0, c1])
|
||||
}
|
||||
|
||||
// Algorithm 11.3.4 in Handbook of Elliptic and Hyperelliptic Curve Cryptography.
|
||||
fn try_inverse(&self) -> Option<Self> {
|
||||
if self.is_zero() {
|
||||
|
||||
@ -72,6 +72,19 @@ impl<F: Extendable<4>> Field for QuarticExtension<F> {
|
||||
F::order().pow(4u32)
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
fn square(&self) -> Self {
|
||||
let Self([a0, a1, a2, a3]) = *self;
|
||||
let w = <Self as OEF<4>>::W;
|
||||
|
||||
let c0 = a0.square() + w * (a1 * a3.double() + a2.square());
|
||||
let c1 = (a0 * a1 + w * a2 * a3).double();
|
||||
let c2 = a0 * a2.double() + a1.square() + w * a3.square();
|
||||
let c3 = (a0 * a3 + a1 * a2).double();
|
||||
|
||||
Self([c0, c1, c2, c3])
|
||||
}
|
||||
|
||||
// Algorithm 11.3.4 in Handbook of Elliptic and Hyperelliptic Curve Cryptography.
|
||||
fn try_inverse(&self) -> Option<Self> {
|
||||
if self.is_zero() {
|
||||
|
||||
@ -74,12 +74,16 @@ pub trait Field:
|
||||
*self == Self::ONE
|
||||
}
|
||||
|
||||
fn double(&self) -> Self {
|
||||
*self + *self
|
||||
}
|
||||
|
||||
fn square(&self) -> Self {
|
||||
*self * *self
|
||||
}
|
||||
|
||||
fn cube(&self) -> Self {
|
||||
*self * *self * *self
|
||||
self.square() * *self
|
||||
}
|
||||
|
||||
/// Compute the multiplicative inverse of this field element.
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user