pub struct SparseDenseProductSumcheckProver<P: PackedField, Data: BufferData<P> = Vec<P>> { /* private fields */ }Expand description
Proves the hypercube sum of the product of a sparse and a dense multilinear.
The sparse multilinear $A$ is given as a list of (index, value) entries, defined as
$$ A(v) = \sum_{(i, c) \in \text{entries}, i = v} c $$
so entries at a repeated index add up and need not be deduplicated. The dense multilinear $B$ is a full buffer over the same $n$ variables. The prover argues the claim
$$ s = \sum_{v \in B_n} A(v) B(v) $$
which is the plain, non-eq-weighted sumcheck of a degree-2 composition. Its rounds cost one pass over the entry list plus two dense lookups per entry, so the work per round is set by the number of entries rather than by the size of the hypercube.
Variables bind from the highest index down, as in the dense provers of this module. Round $j$
therefore splits the index space at half, the bit the round binds: an entry below it lies in
the half where the bound variable is 0, one at or above it in the half where it is 1.
§Round polynomial
With $A_0, A_1$ the two halves of $A$ on the bound variable (likewise $B$), the round polynomial is sampled at 1 and at infinity, and its value at 0 recovered from the round claim:
$$ R(1) = \sum_v A_1(v) B_1(v) \qquad R(\infty) = \sum_v (A_0 + A_1)(v) (B_0 + B_1)(v) $$
Both are linear in $A$, so each entry contributes to them on its own: pairing an entry with the one facing it across the split is never needed. An entry $(i, c)$ with $v = i \bmod \text{half}$ adds $c B(i)$ to $R(1)$ when it lies in the upper half, and $c (B_0 + B_1)(v)$ to $R(\infty)$ wherever it lies.
§Folding
Folding is linear in $A$ for the same reason: an entry keeps its identity across the fold,
scaled by the challenge weight of the half it sits in and moved down into the lower half.
Entries thus stay a flat list of the same length for the whole protocol, and collapse to the
evaluation of $A$ at the challenge point only in SumcheckProver::finish, which emits the
sparse multilinear’s evaluation before the dense one’s.
Implementations§
Source§impl<P: PackedField, Data: BufferData<P>> SparseDenseProductSumcheckProver<P, Data>
impl<P: PackedField, Data: BufferData<P>> SparseDenseProductSumcheckProver<P, Data>
Sourcepub fn new(
sparse: Vec<SparseEntry<P::Scalar>>,
dense: FactoredMultilinear<P, Data>,
sum: P::Scalar,
) -> Self
pub fn new( sparse: Vec<SparseEntry<P::Scalar>>, dense: FactoredMultilinear<P, Data>, sum: P::Scalar, ) -> Self
Creates a prover for the claim that the sparse-dense product sums to sum.
§Arguments
sparse- the entries of the sparse multilinear, in any order, indices repeatabledense- the dense multilinear, whose length fixes the number of variablessum- the claimed sum of the product over the hypercube
§Panics
Panics if any entry index is out of range for dense.
Trait Implementations§
Source§impl<F: Field, P: PackedField<Scalar = F>, Data: BufferData<P> + Sync> SumcheckProver<F> for SparseDenseProductSumcheckProver<P, Data>
impl<F: Field, P: PackedField<Scalar = F>, Data: BufferData<P> + Sync> SumcheckProver<F> for SparseDenseProductSumcheckProver<P, Data>
Source§fn n_vars(&self) -> usize
fn n_vars(&self) -> usize
Source§fn execute(&mut self) -> Vec<RoundCoeffs<F>>
fn execute(&mut self) -> Vec<RoundCoeffs<F>>
Auto Trait Implementations§
impl<P, Data> Freeze for SparseDenseProductSumcheckProver<P, Data>
impl<P, Data> RefUnwindSafe for SparseDenseProductSumcheckProver<P, Data>
impl<P, Data> Send for SparseDenseProductSumcheckProver<P, Data>where
Data: Send,
impl<P, Data> Sync for SparseDenseProductSumcheckProver<P, Data>where
Data: Sync,
impl<P, Data> Unpin for SparseDenseProductSumcheckProver<P, Data>
impl<P, Data> UnsafeUnpin for SparseDenseProductSumcheckProver<P, Data>
impl<P, Data> UnwindSafe for SparseDenseProductSumcheckProver<P, Data>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more