mirror of
https://github.com/saymrwulf/pasta_curves-source.git
synced 2026-09-04 20:03:39 +00:00
Introduce DeferredField trait with eager implementations
Add the `deferred` module with a `DeferredField` trait that enables accumulating multiple unreduced products before performing a single reduction. The trait uses an accumulation-based API: callers feed factor pairs into an `Accumulator` via `mul_accumulate` / `square_accumulate`, then call `reduce` once at the end. For now, both Fp and Fq implement the trait with `Accumulator = Self`, performing eager reduction on each accumulation. A later commit will swap in a wide accumulator that defers reduction for real. The module is feature-gated behind the `deferred` feature flag.
This commit is contained in:
parent
03d9e212b5
commit
c1ec4b7830
5 changed files with 77 additions and 0 deletions
|
|
@ -71,4 +71,5 @@ gpu = ["alloc", "ec-gpu"]
|
|||
sqrt-table = ["alloc", "lazy_static"]
|
||||
repr-c = []
|
||||
uninline-portable = []
|
||||
deferred = []
|
||||
serde = ["hex", "serde_crate"]
|
||||
|
|
|
|||
29
src/deferred.rs
Normal file
29
src/deferred.rs
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
//! Deferred normalization for field arithmetic.
|
||||
//!
|
||||
//! This module provides the [`DeferredField`] trait, which enables accumulating
|
||||
//! multiple unreduced products before performing a single expensive reduction.
|
||||
//! This is useful for operations like inner products where many multiplications
|
||||
//! feed into a sum.
|
||||
|
||||
use core::fmt::Debug;
|
||||
|
||||
/// A trait for fields that support deferred reduction of products.
|
||||
///
|
||||
/// Instead of reducing each multiplication result immediately, callers
|
||||
/// accumulate products into an [`Accumulator`](Self::Accumulator) via
|
||||
/// [`mul_accumulate`](Self::mul_accumulate) and
|
||||
/// [`square_accumulate`](Self::square_accumulate), then perform a single
|
||||
/// reduction at the end with [`reduce`](Self::reduce).
|
||||
pub trait DeferredField: ff::Field {
|
||||
/// A wide accumulator for unreduced products.
|
||||
type Accumulator: Copy + Clone + Debug + Default;
|
||||
|
||||
/// Multiplies `a` by `b` and adds the result into `acc`.
|
||||
fn mul_accumulate(acc: &mut Self::Accumulator, a: &Self, b: &Self);
|
||||
|
||||
/// Squares `a` and adds the result into `acc`.
|
||||
fn square_accumulate(acc: &mut Self::Accumulator, a: &Self);
|
||||
|
||||
/// Reduces the accumulator to a canonical field element.
|
||||
fn reduce(acc: Self::Accumulator) -> Self;
|
||||
}
|
||||
|
|
@ -12,6 +12,8 @@ use lazy_static::lazy_static;
|
|||
use ff::{FieldBits, PrimeFieldBits};
|
||||
|
||||
use crate::arithmetic::{adc, mac, sbb, SqrtTableHelpers};
|
||||
#[cfg(feature = "deferred")]
|
||||
use crate::deferred::DeferredField;
|
||||
|
||||
#[cfg(feature = "sqrt-table")]
|
||||
use crate::arithmetic::SqrtTables;
|
||||
|
|
@ -477,6 +479,26 @@ impl Fp {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "deferred")]
|
||||
impl DeferredField for Fp {
|
||||
type Accumulator = Fp;
|
||||
|
||||
#[inline]
|
||||
fn mul_accumulate(acc: &mut Fp, a: &Fp, b: &Fp) {
|
||||
*acc += *a * *b;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn square_accumulate(acc: &mut Fp, a: &Fp) {
|
||||
*acc += a.square();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reduce(acc: Fp) -> Fp {
|
||||
acc
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Fp> for [u8; 32] {
|
||||
fn from(value: Fp) -> [u8; 32] {
|
||||
value.to_repr()
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ use lazy_static::lazy_static;
|
|||
use ff::{FieldBits, PrimeFieldBits};
|
||||
|
||||
use crate::arithmetic::{adc, mac, sbb, SqrtTableHelpers};
|
||||
#[cfg(feature = "deferred")]
|
||||
use crate::deferred::DeferredField;
|
||||
|
||||
#[cfg(feature = "sqrt-table")]
|
||||
use crate::arithmetic::SqrtTables;
|
||||
|
|
@ -477,6 +479,26 @@ impl Fq {
|
|||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "deferred")]
|
||||
impl DeferredField for Fq {
|
||||
type Accumulator = Fq;
|
||||
|
||||
#[inline]
|
||||
fn mul_accumulate(acc: &mut Fq, a: &Fq, b: &Fq) {
|
||||
*acc += *a * *b;
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn square_accumulate(acc: &mut Fq, a: &Fq) {
|
||||
*acc += a.square();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn reduce(acc: Fq) -> Fq {
|
||||
acc
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Fq> for [u8; 32] {
|
||||
fn from(value: Fq) -> [u8; 32] {
|
||||
value.to_repr()
|
||||
|
|
|
|||
|
|
@ -22,6 +22,9 @@ mod curves;
|
|||
mod fields;
|
||||
|
||||
pub mod arithmetic;
|
||||
#[cfg(feature = "deferred")]
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "deferred")))]
|
||||
pub mod deferred;
|
||||
pub mod pallas;
|
||||
pub mod vesta;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue