Skip to main content

BinaryChallenger

Struct BinaryChallenger 

Source
pub struct BinaryChallenger<F, Inner> { /* private fields */ }
Expand description

A challenger for a binary tower field, driven by a challenger over bytes.

A tower level is a whole number of bytes wide, and every bit pattern is an element.

A transcript over the field is therefore a transcript over its bytes. Nothing is encoded, decoded or rejection-sampled in either direction.

Observing: absorbs the little-endian bytes of the element into the inner challenger.

Sampling: reads the little-endian bytes of the element from the inner challenger. Since the field has exactly 2^(8·NUM_BYTES) elements, uniform bytes give a uniform field element.

Proof of work: unlike the field and bit sampling above, which work at every level, grinding is only viable in the wider ones. GrindingChallenger::grind enumerates candidates with a 64-bit counter and demands GRIND_MARGIN_BITS of headroom below that space, which puts a ceiling of min(F::bits(), 64) − GRIND_MARGIN_BITS on the width of a single request:

witness fieldlargest supported bits
BinaryField2, BinaryField4, BinaryField8none: every nonzero request panics
BinaryField168
BinaryField3224
BinaryField6456
BinaryField12856, bounded by the counter rather than the field

So the levels below GF(2^32) implement GrindingChallenger without being usable proof-of-work witness types, and a 128-bit witness buys no more width than a 64-bit one.

Implementations§

Source§

impl<F, Inner> BinaryChallenger<F, Inner>

Source

pub const fn new(inner: Inner) -> Self

Wrap a challenger over bytes.

Source§

impl<F, H> BinaryChallenger<F, HashChallenger<u8, H, 32>>
where H: CryptographicHasher<u8, [u8; 32]>,

Source

pub const fn from_hasher(initial_state: Vec<u8>, hasher: H) -> Self

Wrap a fresh HashChallenger over the given hasher and initial transcript.

Trait Implementations§

Source§

impl<F, G, const N: usize, Inner: CanObserve<u8>> CanObserve<&MerkleCap<G, [u8; N]>> for BinaryChallenger<F, Inner>

Source§

fn observe(&mut self, cap: &MerkleCap<G, [u8; N]>)

Absorb a single value into the transcript.
Source§

fn observe_slice(&mut self, values: &[T])
where T: Clone,

Absorb a slice of values into the transcript.
Source§

impl<F, G, const N: usize, Inner: CanObserve<u8>> CanObserve<&MerkleCap<G, [u64; N]>> for BinaryChallenger<F, Inner>

Source§

fn observe(&mut self, cap: &MerkleCap<G, [u64; N]>)

Absorb a single value into the transcript.
Source§

fn observe_slice(&mut self, values: &[T])
where T: Clone,

Absorb a slice of values into the transcript.
Source§

impl<F: TowerLevel, Inner: CanObserve<u8>> CanObserve<F> for BinaryChallenger<F, Inner>

Source§

fn observe(&mut self, value: F)

Absorb a single value into the transcript.
Source§

fn observe_slice(&mut self, values: &[T])
where T: Clone,

Absorb a slice of values into the transcript.
Source§

impl<F, G, const N: usize, Inner: CanObserve<u8>> CanObserve<Hash<G, u8, N>> for BinaryChallenger<F, Inner>

Source§

fn observe(&mut self, values: Hash<G, u8, N>)

Absorb a single value into the transcript.
Source§

fn observe_slice(&mut self, values: &[T])
where T: Clone,

Absorb a slice of values into the transcript.
Source§

impl<F, G, const N: usize, Inner: CanObserve<u8>> CanObserve<Hash<G, u64, N>> for BinaryChallenger<F, Inner>

Word digests are absorbed as the little-endian bytes of each word, in order.

The digest’s own field is free of this challenger’s, as it is for a byte digest. A commitment over one level can then be bound into a transcript over another.

Source§

fn observe(&mut self, values: Hash<G, u64, N>)

Absorb a single value into the transcript.
Source§

fn observe_slice(&mut self, values: &[T])
where T: Clone,

Absorb a slice of values into the transcript.
Source§

impl<F, G, const N: usize, Inner: CanObserve<u8>> CanObserve<MerkleCap<G, [u8; N]>> for BinaryChallenger<F, Inner>

Source§

fn observe(&mut self, cap: MerkleCap<G, [u8; N]>)

Absorb a single value into the transcript.
Source§

fn observe_slice(&mut self, values: &[T])
where T: Clone,

Absorb a slice of values into the transcript.
Source§

impl<F, G, const N: usize, Inner: CanObserve<u8>> CanObserve<MerkleCap<G, [u64; N]>> for BinaryChallenger<F, Inner>

Source§

fn observe(&mut self, cap: MerkleCap<G, [u64; N]>)

Absorb a single value into the transcript.
Source§

fn observe_slice(&mut self, values: &[T])
where T: Clone,

Absorb a slice of values into the transcript.
Source§

impl<F, EF, Inner> CanSample<EF> for BinaryChallenger<F, Inner>
where F: TowerLevel, EF: BasedVectorSpace<F>, Inner: CanSample<u8>,

Source§

fn sample(&mut self) -> EF

Sample a single challenge value from the transcript.
Source§

fn sample_into_slice(&mut self, values: &mut [T])

Fill an existing buffer with consecutive samples.
Source§

fn sample_array<const N: usize>(&mut self) -> [T; N]

Sample an array of N challenge values from the transcript.
Source§

fn sample_vec(&mut self, n: usize) -> Vec<T>

Sample a Vec of n challenge values from the transcript.
Source§

impl<F, Inner> CanSampleBits<usize> for BinaryChallenger<F, Inner>
where F: TowerLevel, Inner: CanSample<u8>,

Source§

fn sample_bits(&mut self, bits: usize) -> usize

Sample a bitstring by masking bytes taken from the inner stream.

A challenger that bit-decomposes a sampled field element can only extract as many bits as that element carries, and so has to bound the request by the field order. This one instead reads its entropy straight off the inner byte stream, so how many bits are available per call does not depend on F’s width at all: a challenger over a narrow level can still draw a query index far wider than one of its own elements.

The one real bound is that the result must fit in a usize, which also keeps it within the u64 the bytes are read into.

Source§

impl<F, Inner> CanSampleUniformBits<F> for BinaryChallenger<F, Inner>
where F: TowerLevel, Inner: CanSample<u8>,

Source§

fn sample_uniform_bits<const RESAMPLE: bool>( &mut self, bits: usize, ) -> Result<usize, ResamplingError>

Sample uniform bits by masking bytes from the inner stream.

§Overview

The inner stream emits cryptographic-hash bytes uniform on [0, 2^8).

Reading 8 bytes as a 64-bit integer and masking the low bits is exactly uniform on [0, 2^bits).

No field-element decomposition occurs, so no rejection band exists. The const generic is therefore inert: this function never errors and never resamples.

Source§

impl<F: Clone, Inner: Clone> Clone for BinaryChallenger<F, Inner>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<F: Debug, Inner: Debug> Debug for BinaryChallenger<F, Inner>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<F, Inner> FieldChallenger<F> for BinaryChallenger<F, Inner>
where F: TowerLevel, Inner: CanSample<u8> + CanObserve<u8> + Clone + Send + Sync,

Source§

fn observe_algebra_element<A>(&mut self, alg_elem: A)
where A: BasedVectorSpace<F>,

Absorb an element from a vector space over the base field. Read more
Source§

fn observe_algebra_slice<A>(&mut self, alg_elems: &[A])
where A: BasedVectorSpace<F> + Clone,

Absorb a slice of elements from a vector space over the base field. Read more
Source§

fn sample_algebra_element<A>(&mut self) -> A
where A: BasedVectorSpace<F>,

Sample an element of a vector space over the base field. Read more
Source§

fn observe_base_as_algebra_element<EF>(&mut self, val: F)
where EF: Algebra<F> + BasedVectorSpace<F>,

Observe base field elements as extension field elements for recursion-friendly transcripts. Read more
Source§

impl<F, Inner> GrindingChallenger for BinaryChallenger<F, Inner>
where F: TowerLevel, Inner: CanSample<u8> + CanObserve<u8> + Clone + Send + Sync,

Source§

fn grind(&mut self, bits: usize) -> Self::Witness

§Panics

Panics unless bits + GRIND_MARGIN_BITS <= min(F::bits(), 64). See the per-level ceiling tabulated on BinaryChallenger.

Source§

type Witness = F

The underlying field element type used as the witness.
Source§

fn check_witness(&mut self, bits: usize, witness: Self::Witness) -> bool

Check whether a given witness satisfies the PoW condition. Read more

Auto Trait Implementations§

§

impl<F, Inner> Freeze for BinaryChallenger<F, Inner>
where Inner: Freeze, PhantomData<F>: Freeze,

§

impl<F, Inner> RefUnwindSafe for BinaryChallenger<F, Inner>

§

impl<F, Inner> Send for BinaryChallenger<F, Inner>
where Inner: Send, PhantomData<F>: Send,

§

impl<F, Inner> Sync for BinaryChallenger<F, Inner>
where Inner: Sync, PhantomData<F>: Sync,

§

impl<F, Inner> Unpin for BinaryChallenger<F, Inner>
where Inner: Unpin, PhantomData<F>: Unpin,

§

impl<F, Inner> UnsafeUnpin for BinaryChallenger<F, Inner>

§

impl<F, Inner> UnwindSafe for BinaryChallenger<F, Inner>
where Inner: UnwindSafe, PhantomData<F>: 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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T> Instrument for T

Source§

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

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

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

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = !

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

fn try_from(value: U) -> Result<T, !>

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

impl<T> WithSubscriber for T

Source§

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

fn with_current_subscriber(self) -> WithDispatch<Self>

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