Skip to main content

SparseDenseProductSumcheckProver

Struct SparseDenseProductSumcheckProver 

Source
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>

Source

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 repeatable
  • dense - the dense multilinear, whose length fixes the number of variables
  • sum - 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>

Source§

fn n_vars(&self) -> usize

The number of variables in the remaining multivariate polynomial. Read more
Source§

fn execute(&mut self) -> Vec<RoundCoeffs<F>>

Computes the prover messages for this round as a univariate polynomial. Read more
Source§

fn fold(&mut self, challenge: F)

Folds the sumcheck multilinears with a new verifier challenge.
Source§

fn finish(self) -> Vec<F>

Finishes the sumcheck proving protocol and returns the evaluations of all multilinears at the challenge point.

Auto Trait Implementations§

§

impl<P, Data> Freeze for SparseDenseProductSumcheckProver<P, Data>
where <P as FieldOps>::Scalar: Freeze,

§

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>
where <P as FieldOps>::Scalar: Unpin, Data: Unpin,

§

impl<P, Data> UnsafeUnpin for SparseDenseProductSumcheckProver<P, Data>
where <P as FieldOps>::Scalar: UnsafeUnpin,

§

impl<P, Data> UnwindSafe for SparseDenseProductSumcheckProver<P, Data>
where <P as FieldOps>::Scalar: UnwindSafe, Data: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more