pub struct MergeProverChannel<'a, P, A, C>{ /* private fields */ }Expand description
A prover channel decorator that merges one round’s oracles into one combined oracle.
§Overview
An interaction round is the run of oracles sent between two challenge samples.
Committing each oracle separately costs one commitment per oracle. One Merkle tree per oracle, for example.
This decorator buffers a round’s oracles instead. It commits them together as one larger oracle. That cuts the cost to one commitment per round.
A round’s oracles are sorted from largest to smallest, then laid out end to end. That ordering makes every oracle’s position exact.
Every earlier oracle is at least as large as the current one. So their combined space is a whole multiple of the current oracle’s size.
A round of a single oracle needs no combining. It is forwarded unchanged, at zero cost.
A round is masked as a whole, never partly.
So a round carrying any witness data is masked in full by the underlying channel. The verifier-side decorator is where that choice is made.
§Timing
A round’s oracles are committed the moment its last oracle arrives.
The OracleSchedule says where each round ends, so no challenge sample is needed to find
the boundary.
A real Fiat-Shamir transcript can therefore absorb the commitment before the next challenge.
The combined buffer is finalized on the underlying channel right after it is committed. So finalizing a constituent oracle here just drops the buffer handed back.
§Opening
A verifier only ever holds a formula for a transparent polynomial.
This side holds the actual coefficients instead. A constituent’s own transparent polynomial becomes one for the combined oracle. It is the constituent’s values at the constituent’s own block, and zero everywhere else. This side forwards it to the underlying channel as a zero-padded structure, never writing the zeros.
That placement is the same polynomial a verifier reaches by formula. One side holds the block as explicit values. The other evaluates it on demand.
Implementations§
Source§impl<'a, P, A, C> MergeProverChannel<'a, P, A, C>
impl<'a, P, A, C> MergeProverChannel<'a, P, A, C>
Sourcepub fn new(inner: C, schedule: &'a OracleSchedule, alloc: A) -> Self
pub fn new(inner: C, schedule: &'a OracleSchedule, alloc: A) -> Self
Creates a new merging prover channel over an underlying channel.
§Arguments
inner— the channel every combined oracle is committed to, already configured withschedule.merged_specs().schedule— every oracle this channel’s caller will pass through, grouped into rounds.alloc— where this channel draws its combined buffers from.
§Panics
Panics if inner is not configured with schedule.merged_specs().
Sourcepub fn into_inner(self) -> C
pub fn into_inner(self) -> C
Trait Implementations§
Source§impl<'a, F, P, A, C> IOPProverChannel<P, A> for MergeProverChannel<'a, P, A, C>
impl<'a, F, P, A, C> IOPProverChannel<P, A> for MergeProverChannel<'a, P, A, C>
type Oracle = MergeOracle
Source§fn remaining_oracle_specs(&self) -> &[OracleSpec]
fn remaining_oracle_specs(&self) -> &[OracleSpec]
Source§fn send_oracle(&mut self, buffer: FieldSlice<'_, P>) -> Self::Oracle
fn send_oracle(&mut self, buffer: FieldSlice<'_, P>) -> Self::Oracle
Source§fn prove_oracle_relation(
&mut self,
oracle: Self::Oracle,
transparent: StructuredBuffer<P, A::Vec<P>>,
claim: P::Scalar,
)
fn prove_oracle_relation( &mut self, oracle: Self::Oracle, transparent: StructuredBuffer<P, A::Vec<P>>, claim: P::Scalar, )
Source§impl<F, P, A, C> IPProverChannel<F> for MergeProverChannel<'_, P, A, C>
impl<F, P, A, C> IPProverChannel<F> for MergeProverChannel<'_, P, A, C>
Source§fn observe_one(&mut self, val: F)
fn observe_one(&mut self, val: F)
Source§fn observe_many(&mut self, vals: &[F])
fn observe_many(&mut self, vals: &[F])
Source§fn send_public_claim(&mut self, elem: F)
fn send_public_claim(&mut self, elem: F)
Source§fn sample_many(&mut self, n: usize) -> Vec<F>
fn sample_many(&mut self, n: usize) -> Vec<F>
n random challenges.Source§fn sample_array<const N: usize>(&mut self) -> [F; N]
fn sample_array<const N: usize>(&mut self) -> [F; N]
Source§impl<F, P, A, C> WordIPProverChannel<F> for MergeProverChannel<'_, P, A, C>where
F: Field,
P: PackedField<Scalar = F>,
A: Allocator,
C: IOPProverChannel<P, A> + WordIPProverChannel<F>,
impl<F, P, A, C> WordIPProverChannel<F> for MergeProverChannel<'_, P, A, C>where
F: Field,
P: PackedField<Scalar = F>,
A: Allocator,
C: IOPProverChannel<P, A> + WordIPProverChannel<F>,
Source§fn observe_words(&mut self, words: &[Self::Word])
fn observe_words(&mut self, words: &[Self::Word])
Auto Trait Implementations§
impl<'a, P, A, C> Freeze for MergeProverChannel<'a, P, A, C>
impl<'a, P, A, C> RefUnwindSafe for MergeProverChannel<'a, P, A, C>where
C: RefUnwindSafe,
A: RefUnwindSafe,
<A as Allocator>::Vec<P>: RefUnwindSafe,
<C as IOPProverChannel<P, A>>::Oracle: RefUnwindSafe,
impl<'a, P, A, C> Send for MergeProverChannel<'a, P, A, C>
impl<'a, P, A, C> Sync for MergeProverChannel<'a, P, A, C>
impl<'a, P, A, C> Unpin for MergeProverChannel<'a, P, A, C>
impl<'a, P, A, C> UnsafeUnpin for MergeProverChannel<'a, P, A, C>
impl<'a, P, A, C> UnwindSafe for MergeProverChannel<'a, P, A, C>where
C: UnwindSafe,
A: UnwindSafe,
<A as Allocator>::Vec<P>: UnwindSafe,
<C as IOPProverChannel<P, A>>::Oracle: UnwindSafe,
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