diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/docs/.lock b/docs/.lock new file mode 100644 index 000000000..e69de29bb diff --git a/docs/arecibo/all.html b/docs/arecibo/all.html new file mode 100644 index 000000000..3c26af02f --- /dev/null +++ b/docs/arecibo/all.html @@ -0,0 +1 @@ +List of all items in this crate

List of all items

Structs

Enums

Traits

Macros

Functions

Type Definitions

Constants

\ No newline at end of file diff --git a/docs/arecibo/constants/constant.NUM_HASH_BITS.html b/docs/arecibo/constants/constant.NUM_HASH_BITS.html new file mode 100644 index 000000000..a3f8b5021 --- /dev/null +++ b/docs/arecibo/constants/constant.NUM_HASH_BITS.html @@ -0,0 +1,2 @@ +NUM_HASH_BITS in arecibo::constants - Rust
pub const NUM_HASH_BITS: usize = 250;
Expand description

Bit size of Nova field element hashes

+
\ No newline at end of file diff --git a/docs/arecibo/constants/index.html b/docs/arecibo/constants/index.html new file mode 100644 index 000000000..c8170d70b --- /dev/null +++ b/docs/arecibo/constants/index.html @@ -0,0 +1,2 @@ +arecibo::constants - Rust

Module arecibo::constants

source ·
Expand description

Global Nova constants

+

Constants

\ No newline at end of file diff --git a/docs/arecibo/constants/sidebar-items.js b/docs/arecibo/constants/sidebar-items.js new file mode 100644 index 000000000..ab4150cfa --- /dev/null +++ b/docs/arecibo/constants/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"constant":["NUM_HASH_BITS"]}; \ No newline at end of file diff --git a/docs/arecibo/errors/enum.NovaError.html b/docs/arecibo/errors/enum.NovaError.html new file mode 100644 index 000000000..75299f85b --- /dev/null +++ b/docs/arecibo/errors/enum.NovaError.html @@ -0,0 +1,144 @@ +NovaError in arecibo::errors - Rust
#[non_exhaustive]
pub enum NovaError { +
Show 21 variants InvalidIndex, + OddInputLength, + InvalidInputLength, + InvalidWitnessLength, + UnSat, + UnSatIndex(usize), + DecompressionError, + ProofVerifyError, + InvalidCommitmentKeyLength, + InvalidNumSteps, + PCSError(PCSError), + InvalidSumcheckProof, + InvalidInitialInputLength, + InvalidStepOutputLength, + InternalTranscriptError, + InvalidMultisetProof, + InvalidProductProof, + IncorrectWitness, + SynthesisError(String), + DigestError, + InternalError, +
}
Expand description

Errors returned by Nova

+

Variants (Non-exhaustive)§

This enum is marked as non-exhaustive
Non-exhaustive enums could have additional variants added in future. Therefore, when matching against variants of non-exhaustive enums, an extra wildcard arm must be added to account for any future variants.
§

InvalidIndex

returned if the supplied row or col in (row,col,val) tuple is out of range

+
§

OddInputLength

returned if the supplied input is not even-sized

+
§

InvalidInputLength

returned if the supplied input is not of the right length

+
§

InvalidWitnessLength

returned if the supplied witness is not of the right length

+
§

UnSat

returned if the supplied witness is not a satisfying witness to a given shape and instance

+
§

UnSatIndex(usize)

returned if the supplied witness is not a satisfying witness to a given shape and instance, with error constraint index

+
§

DecompressionError

returned when the supplied compressed commitment cannot be decompressed

+
§

ProofVerifyError

returned if proof verification fails

+
§

InvalidCommitmentKeyLength

returned if the provided commitment key is not of sufficient length

+
§

InvalidNumSteps

returned if the provided number of steps is zero

+
§

PCSError(PCSError)

returned if there is an error in the proof/verification of a PCS

+
§

InvalidSumcheckProof

returned when an invalid sum-check proof is provided

+
§

InvalidInitialInputLength

returned when the initial input to an incremental computation differs from a previously declared arity

+
§

InvalidStepOutputLength

returned when the step execution produces an output whose length differs from a previously declared arity

+
§

InternalTranscriptError

returned when the transcript engine encounters an overflow of the round number

+
§

InvalidMultisetProof

returned when the multiset check fails

+
§

InvalidProductProof

returned when the product proof check fails

+
§

IncorrectWitness

returned when the consistency with public IO and assignment used fails

+
§

SynthesisError(String)

return when error during synthesis

+
§

DigestError

returned when there is an error creating a digest

+
§

InternalError

returned when the prover cannot prove the provided statement due to completeness error

+

Trait Implementations§

source§

impl Clone for NovaError

source§

fn clone(&self) -> NovaError

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for NovaError

source§

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

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

impl Display for NovaError

source§

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

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

impl Error for NovaError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<NovaError> for SuperNovaError

source§

fn from(source: NovaError) -> Self

Converts to this type from the input type.
source§

impl From<PCSError> for NovaError

source§

fn from(source: PCSError) -> Self

Converts to this type from the input type.
source§

impl From<SynthesisError> for NovaError

source§

fn from(err: SynthesisError) -> Self

Converts to this type from the input type.
source§

impl PartialEq<NovaError> for NovaError

source§

fn eq(&self, other: &NovaError) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for NovaError

source§

impl StructuralEq for NovaError

source§

impl StructuralPartialEq for NovaError

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/errors/enum.PCSError.html b/docs/arecibo/errors/enum.PCSError.html new file mode 100644 index 000000000..25d3f9a9d --- /dev/null +++ b/docs/arecibo/errors/enum.PCSError.html @@ -0,0 +1,108 @@ +PCSError in arecibo::errors - Rust

Enum arecibo::errors::PCSError

source ·
pub enum PCSError {
+    InvalidIPA,
+    ZMError,
+    LengthError,
+}
Expand description

Errors specific to the Polynomial commitment scheme

+

Variants§

§

InvalidIPA

returned when an invalid inner product argument is provided

+
§

ZMError

returned when there is a Zeromorph error

+
§

LengthError

returned when a length check fails in a PCS

+

Trait Implementations§

source§

impl Clone for PCSError

source§

fn clone(&self) -> PCSError

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for PCSError

source§

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

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

impl Display for PCSError

source§

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

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

impl Error for PCSError

1.30.0 · source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<PCSError> for NovaError

source§

fn from(source: PCSError) -> Self

Converts to this type from the input type.
source§

impl PartialEq<PCSError> for PCSError

source§

fn eq(&self, other: &PCSError) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for PCSError

source§

impl StructuralEq for PCSError

source§

impl StructuralPartialEq for PCSError

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/errors/index.html b/docs/arecibo/errors/index.html new file mode 100644 index 000000000..9a4f33e46 --- /dev/null +++ b/docs/arecibo/errors/index.html @@ -0,0 +1,2 @@ +arecibo::errors - Rust

Module arecibo::errors

source ·
Expand description

This module defines errors returned by the library.

+

Enums

  • Errors returned by Nova
  • Errors specific to the Polynomial commitment scheme
\ No newline at end of file diff --git a/docs/arecibo/errors/sidebar-items.js b/docs/arecibo/errors/sidebar-items.js new file mode 100644 index 000000000..84e4d76e3 --- /dev/null +++ b/docs/arecibo/errors/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["NovaError","PCSError"]}; \ No newline at end of file diff --git a/docs/arecibo/fn.circuit_digest.html b/docs/arecibo/fn.circuit_digest.html new file mode 100644 index 000000000..f9ba9ed1f --- /dev/null +++ b/docs/arecibo/fn.circuit_digest.html @@ -0,0 +1,6 @@ +circuit_digest in arecibo - Rust

Function arecibo::circuit_digest

source ·
pub fn circuit_digest<E1: Engine<Base = <E2 as Engine>::Scalar>, E2: Engine<Base = <E1 as Engine>::Scalar>, C: StepCircuit<E1::Scalar>>(
+    circuit: &C
+) -> E1::Scalar
Expand description

Compute the circuit digest of a StepCircuit.

+

Note for callers: This function should be called with its performance characteristics in mind. +It will synthesize and digest the full circuit given.

+
\ No newline at end of file diff --git a/docs/arecibo/gadgets/ecc/index.html b/docs/arecibo/gadgets/ecc/index.html new file mode 100644 index 000000000..9da447640 --- /dev/null +++ b/docs/arecibo/gadgets/ecc/index.html @@ -0,0 +1,2 @@ +arecibo::gadgets::ecc - Rust

Module arecibo::gadgets::ecc

source ·
Expand description

This module implements various elliptic curve gadgets

+

Structs

\ No newline at end of file diff --git a/docs/arecibo/gadgets/ecc/sidebar-items.js b/docs/arecibo/gadgets/ecc/sidebar-items.js new file mode 100644 index 000000000..5f89ae848 --- /dev/null +++ b/docs/arecibo/gadgets/ecc/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["AllocatedPoint","AllocatedPointNonInfinity"]}; \ No newline at end of file diff --git a/docs/arecibo/gadgets/ecc/struct.AllocatedPoint.html b/docs/arecibo/gadgets/ecc/struct.AllocatedPoint.html new file mode 100644 index 000000000..7459de43c --- /dev/null +++ b/docs/arecibo/gadgets/ecc/struct.AllocatedPoint.html @@ -0,0 +1,154 @@ +AllocatedPoint in arecibo::gadgets::ecc - Rust
pub struct AllocatedPoint<E: Engine> { /* private fields */ }
Expand description

AllocatedPoint provides an elliptic curve abstraction inside a circuit.

+

Implementations§

source§

impl<E> AllocatedPoint<E>where + E: Engine,

source

pub fn alloc<CS: ConstraintSystem<E::Base>>( + cs: CS, + coords: Option<(E::Base, E::Base, bool)> +) -> Result<Self, SynthesisError>

Allocates a new point on the curve using coordinates provided by coords. +If coords = None, it allocates the default infinity point

+
source

pub fn check_on_curve<CS>(&self, cs: CS) -> Result<(), SynthesisError>where + CS: ConstraintSystem<E::Base>,

checks if self is on the curve or if it is infinity

+
source

pub fn default<CS: ConstraintSystem<E::Base>>( + cs: CS +) -> Result<Self, SynthesisError>

Allocates a default point on the curve, set to the identity point.

+
source

pub const fn get_coordinates( + &self +) -> (&AllocatedNum<E::Base>, &AllocatedNum<E::Base>, &AllocatedNum<E::Base>)

Returns coordinates associated with the point.

+
source

pub fn negate<CS: ConstraintSystem<E::Base>>( + &self, + cs: CS +) -> Result<Self, SynthesisError>

Negates the provided point

+
source

pub fn add<CS: ConstraintSystem<E::Base>>( + &self, + cs: CS, + other: &Self +) -> Result<Self, SynthesisError>

Add two points (may be equal)

+
source

pub fn add_internal<CS: ConstraintSystem<E::Base>>( + &self, + cs: CS, + other: &Self, + equal_x: &AllocatedBit +) -> Result<Self, SynthesisError>

Adds other point to this point and returns the result. Assumes that the two points are +different and that both other.is_infinity and this.is_infinty are bits

+
source

pub fn double<CS: ConstraintSystem<E::Base>>( + &self, + cs: CS +) -> Result<Self, SynthesisError>

Doubles the supplied point.

+
source

pub fn scalar_mul<CS: ConstraintSystem<E::Base>>( + &self, + cs: CS, + scalar_bits: &[AllocatedBit] +) -> Result<Self, SynthesisError>

A gadget for scalar multiplication, optimized to use incomplete addition law. +The optimization here is analogous to https://github.com/arkworks-rs/r1cs-std/blob/6d64f379a27011b3629cf4c9cb38b7b7b695d5a0/src/groups/curves/short_weierstrass/mod.rs#L295, +except we use complete addition law over affine coordinates instead of projective coordinates for the tail bits

+
source

pub fn conditionally_select<CS: ConstraintSystem<E::Base>>( + cs: CS, + a: &Self, + b: &Self, + condition: &Boolean +) -> Result<Self, SynthesisError>

If condition outputs a otherwise outputs b

+
source

pub fn select_point_or_infinity<CS: ConstraintSystem<E::Base>>( + cs: CS, + a: &Self, + condition: &Boolean +) -> Result<Self, SynthesisError>

If condition outputs a otherwise infinity

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for AllocatedPoint<E>where + E::Base: Clone,

source§

fn clone(&self) -> AllocatedPoint<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for AllocatedPoint<E>where + <E as Engine>::Base: RefUnwindSafe,

§

impl<E> Send for AllocatedPoint<E>

§

impl<E> Sync for AllocatedPoint<E>

§

impl<E> Unpin for AllocatedPoint<E>where + <E as Engine>::Base: Unpin,

§

impl<E> UnwindSafe for AllocatedPoint<E>where + <E as Engine>::Base: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/gadgets/ecc/struct.AllocatedPointNonInfinity.html b/docs/arecibo/gadgets/ecc/struct.AllocatedPointNonInfinity.html new file mode 100644 index 000000000..fbd00bb44 --- /dev/null +++ b/docs/arecibo/gadgets/ecc/struct.AllocatedPointNonInfinity.html @@ -0,0 +1,132 @@ +AllocatedPointNonInfinity in arecibo::gadgets::ecc - Rust
pub struct AllocatedPointNonInfinity<E: Engine> { /* private fields */ }
Expand description

AllocatedPoint but one that is guaranteed to be not infinity

+

Implementations§

source§

impl<E> AllocatedPointNonInfinity<E>where + E: Engine,

source

pub const fn new(x: AllocatedNum<E::Base>, y: AllocatedNum<E::Base>) -> Self

Creates a new AllocatedPointNonInfinity from the specified coordinates

+
source

pub fn alloc<CS: ConstraintSystem<E::Base>>( + cs: CS, + coords: Option<(E::Base, E::Base)> +) -> Result<Self, SynthesisError>

Allocates a new point on the curve using coordinates provided by coords.

+
source

pub fn from_allocated_point(p: &AllocatedPoint<E>) -> Self

Turns an AllocatedPoint into an AllocatedPointNonInfinity (assumes it is not infinity)

+
source

pub fn to_allocated_point( + &self, + is_infinity: &AllocatedNum<E::Base> +) -> Result<AllocatedPoint<E>, SynthesisError>

Returns an AllocatedPoint from an AllocatedPointNonInfinity

+
source

pub const fn get_coordinates( + &self +) -> (&AllocatedNum<E::Base>, &AllocatedNum<E::Base>)

Returns coordinates associated with the point.

+
source

pub fn add_incomplete<CS>( + &self, + cs: CS, + other: &Self +) -> Result<Self, SynthesisError>where + CS: ConstraintSystem<E::Base>,

Add two points assuming self != +/- other

+
source

pub fn double_incomplete<CS: ConstraintSystem<E::Base>>( + &self, + cs: CS +) -> Result<Self, SynthesisError>

doubles the point; since this is called with a point not at infinity, it is guaranteed to be not infinity

+
source

pub fn conditionally_select<CS: ConstraintSystem<E::Base>>( + cs: CS, + a: &Self, + b: &Self, + condition: &Boolean +) -> Result<Self, SynthesisError>

If condition outputs a otherwise outputs b

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for AllocatedPointNonInfinity<E>where + E::Base: Clone,

source§

fn clone(&self) -> AllocatedPointNonInfinity<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/gadgets/index.html b/docs/arecibo/gadgets/index.html new file mode 100644 index 000000000..efc7bc91b --- /dev/null +++ b/docs/arecibo/gadgets/index.html @@ -0,0 +1,2 @@ +arecibo::gadgets - Rust

Module arecibo::gadgets

source ·
Expand description

This module implements various gadgets necessary for Nova and applications built with Nova.

+

Modules

  • This module implements various elliptic curve gadgets
\ No newline at end of file diff --git a/docs/arecibo/gadgets/sidebar-items.js b/docs/arecibo/gadgets/sidebar-items.js new file mode 100644 index 000000000..c20d9aa94 --- /dev/null +++ b/docs/arecibo/gadgets/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["ecc"]}; \ No newline at end of file diff --git a/docs/arecibo/index.html b/docs/arecibo/index.html new file mode 100644 index 000000000..442ce4341 --- /dev/null +++ b/docs/arecibo/index.html @@ -0,0 +1,7 @@ +arecibo - Rust

Crate arecibo

source ·
Expand description

This library implements Nova, a high-speed recursive SNARK.

+

Modules

  • Global Nova constants
  • This module defines errors returned by the library.
  • This module implements various gadgets necessary for Nova and applications built with Nova.
  • This module implements Nova’s traits using the following several different combinations
  • This module defines R1CS related types and a folding scheme for Relaxed R1CS
  • This module implements RelaxedR1CSSNARKTrait using Spartan that is generic +over the polynomial commitment and evaluation argument (i.e., a PCS) +We provide two implementations, one in snark.rs (which does not use any preprocessing) +and another in ppsnark.rs (which uses preprocessing to keep the verifier’s state small if the PCS provides a succinct verifier) +We also provide direct.rs that allows proving a step circuit directly with either of the two SNARKs.
  • SuperNova Description
  • This module defines various traits required by the users of the library to implement.

Macros

  • This implementation behaves in ways specific to the halo2curves suite of curves in:
  • Macros to give syntactic sugar for zipWith pattern and variants.
  • Like zip_with but use for_each instead of map.

Structs

  • A SNARK that proves the knowledge of a valid RecursiveSNARK
  • A type that holds the prover key for CompressedSNARK
  • A type that holds public parameters of Nova
  • A type that holds parameters for the primary and secondary circuits of Nova and SuperNova
  • A SNARK that proves the correct execution of an incremental computation
  • A resource buffer for RecursiveSNARK for storing scratch values that are computed by prove_step, +which allows the reuse of memory allocations and avoids unnecessary new allocations in the critical section.
  • A type that holds the verifier key for CompressedSNARK

Functions

\ No newline at end of file diff --git a/docs/arecibo/macro.impl_traits!.html b/docs/arecibo/macro.impl_traits!.html new file mode 100644 index 000000000..68f98b909 --- /dev/null +++ b/docs/arecibo/macro.impl_traits!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.impl_traits.html...

+ + + \ No newline at end of file diff --git a/docs/arecibo/macro.impl_traits.html b/docs/arecibo/macro.impl_traits.html new file mode 100644 index 000000000..5d752edb0 --- /dev/null +++ b/docs/arecibo/macro.impl_traits.html @@ -0,0 +1,14 @@ +impl_traits in arecibo - Rust

Macro arecibo::impl_traits

source ·
macro_rules! impl_traits {
+    (
+    $name:ident,
+    $order_str:literal,
+    $base_str:literal
+  ) => { ... };
+    (
+    $name:ident,
+    $order_str:literal,
+    $base_str:literal,
+    $large_msm_method: ident
+  ) => { ... };
+}
Expand description

This implementation behaves in ways specific to the halo2curves suite of curves in:

+
\ No newline at end of file diff --git a/docs/arecibo/macro.zip_with!.html b/docs/arecibo/macro.zip_with!.html new file mode 100644 index 000000000..91bc6f2c3 --- /dev/null +++ b/docs/arecibo/macro.zip_with!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.zip_with.html...

+ + + \ No newline at end of file diff --git a/docs/arecibo/macro.zip_with.html b/docs/arecibo/macro.zip_with.html new file mode 100644 index 000000000..c8603dd2b --- /dev/null +++ b/docs/arecibo/macro.zip_with.html @@ -0,0 +1,18 @@ +zip_with in arecibo - Rust

Macro arecibo::zip_with

source ·
macro_rules! zip_with {
+    ($($f:ident,)? ($e:expr $(, $rest:expr)*), $($move:ident)? |$($i:ident),+ $(,)?| $($work:tt)*) => { ... };
+    ($($f:ident,)? ($e:expr $(, $rest:expr)*), $worker:ident, $($move:ident,)? |$($i:ident),+ $(,)?|  $($work:tt)*) => { ... };
+}
Expand description

Macros to give syntactic sugar for zipWith pattern and variants.

+ +
use crate::spartan::zip_with;
+use itertools::Itertools as _; // we use zip_eq to zip!
+let v = vec![0, 1, 2];
+let w = vec![2, 3, 4];
+let y = vec![4, 5, 6];
+
+// Using the `zip_with!` macro to zip three iterators together and apply a closure
+// that sums the elements of each iterator.
+let res = zip_with!((v.iter(), w.iter(), y.iter()), |a, b, c| a + b + c)
+    .collect::<Vec<_>>();
+
+println!("{:?}", res); // Output: [6, 9, 12]
+
\ No newline at end of file diff --git a/docs/arecibo/macro.zip_with_for_each!.html b/docs/arecibo/macro.zip_with_for_each!.html new file mode 100644 index 000000000..60fb64c87 --- /dev/null +++ b/docs/arecibo/macro.zip_with_for_each!.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to macro.zip_with_for_each.html...

+ + + \ No newline at end of file diff --git a/docs/arecibo/macro.zip_with_for_each.html b/docs/arecibo/macro.zip_with_for_each.html new file mode 100644 index 000000000..915fc2f8d --- /dev/null +++ b/docs/arecibo/macro.zip_with_for_each.html @@ -0,0 +1,4 @@ +zip_with_for_each in arecibo - Rust
macro_rules! zip_with_for_each {
+    ($($f:ident,)? ($e:expr $(, $rest:expr)*), $($move:ident)? |$($i:ident),+ $(,)?| $($work:tt)*) => { ... };
+}
Expand description

Like zip_with but use for_each instead of map.

+
\ No newline at end of file diff --git a/docs/arecibo/provider/index.html b/docs/arecibo/provider/index.html new file mode 100644 index 000000000..be09ee1f1 --- /dev/null +++ b/docs/arecibo/provider/index.html @@ -0,0 +1,2 @@ +arecibo::provider - Rust

Module arecibo::provider

source ·
Expand description

This module implements Nova’s traits using the following several different combinations

+

Modules

  • This module implements EvaluationEngine using an IPA-based polynomial commitment scheme
  • This module implements Nova’s evaluation engine using multilinear KZG
  • Non-hiding Zeromorph scheme for Multilinear Polynomials.

Structs

  • An implementation of the Nova Engine trait with BN254 curve and Pedersen commitment scheme
  • An implementation of Nova traits with multilinear KZG over the BN256 curve
  • An implementation of the Nova Engine trait with BN254 curve and Zeromorph commitment scheme
  • An implementation of the Nova Engine trait with Grumpkin curve and Pedersen commitment scheme
  • An implementation of the Nova Engine trait with Pallas curve and Pedersen commitment scheme
  • An implementation of the Nova Engine trait with Secp256k1 curve and Pedersen commitment scheme
  • An implementation of the Nova Engine trait with Secp256k1 curve and Pedersen commitment scheme
  • An implementation of the Nova Engine trait with Vesta curve and Pedersen commitment scheme
\ No newline at end of file diff --git a/docs/arecibo/provider/ipa_pc/index.html b/docs/arecibo/provider/ipa_pc/index.html new file mode 100644 index 000000000..11e0d385d --- /dev/null +++ b/docs/arecibo/provider/ipa_pc/index.html @@ -0,0 +1,2 @@ +arecibo::provider::ipa_pc - Rust

Module arecibo::provider::ipa_pc

source ·
Expand description

This module implements EvaluationEngine using an IPA-based polynomial commitment scheme

+

Structs

\ No newline at end of file diff --git a/docs/arecibo/provider/ipa_pc/sidebar-items.js b/docs/arecibo/provider/ipa_pc/sidebar-items.js new file mode 100644 index 000000000..07cf9c7f2 --- /dev/null +++ b/docs/arecibo/provider/ipa_pc/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["EvaluationEngine","InnerProductArgument","ProverKey","VerifierKey"]}; \ No newline at end of file diff --git a/docs/arecibo/provider/ipa_pc/struct.EvaluationEngine.html b/docs/arecibo/provider/ipa_pc/struct.EvaluationEngine.html new file mode 100644 index 000000000..dea6f82ba --- /dev/null +++ b/docs/arecibo/provider/ipa_pc/struct.EvaluationEngine.html @@ -0,0 +1,127 @@ +EvaluationEngine in arecibo::provider::ipa_pc - Rust
pub struct EvaluationEngine<E> { /* private fields */ }
Expand description

Provides an implementation of a polynomial evaluation engine using IPA

+

Trait Implementations§

source§

impl<E: Clone> Clone for EvaluationEngine<E>

source§

fn clone(&self) -> EvaluationEngine<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug> Debug for EvaluationEngine<E>

source§

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

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

impl<'de, E> Deserialize<'de> for EvaluationEngine<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E> EvaluationEngineTrait<E> for EvaluationEngine<E>where + E: Engine, + E::GE: DlogGroup, + <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: CommitmentKeyExtTrait<E>,

source§

fn verify( + vk: &Self::VerifierKey, + transcript: &mut E::TE, + comm: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, + point: &[E::Scalar], + eval: &E::Scalar, + arg: &Self::EvaluationArgument +) -> Result<(), NovaError>

A method to verify purported evaluations of a batch of polynomials

+
§

type ProverKey = ProverKey<E>

A type that holds the prover key
§

type VerifierKey = VerifierKey<E>

A type that holds the verifier key
§

type EvaluationArgument = InnerProductArgument<E>

A type that holds the evaluation argument
source§

fn setup( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey +) -> (Self::ProverKey, Self::VerifierKey)

A method to perform any additional setup needed to produce proofs of evaluations
source§

fn prove( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + pk: &Self::ProverKey, + transcript: &mut E::TE, + comm: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, + poly: &[E::Scalar], + point: &[E::Scalar], + eval: &E::Scalar +) -> Result<Self::EvaluationArgument, NovaError>

A method to prove the evaluation of a multilinear polynomial
source§

impl<E> Serialize for EvaluationEngine<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for EvaluationEngine<E>where + E: RefUnwindSafe,

§

impl<E> Send for EvaluationEngine<E>where + E: Send,

§

impl<E> Sync for EvaluationEngine<E>where + E: Sync,

§

impl<E> Unpin for EvaluationEngine<E>where + E: Unpin,

§

impl<E> UnwindSafe for EvaluationEngine<E>where + E: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/ipa_pc/struct.InnerProductArgument.html b/docs/arecibo/provider/ipa_pc/struct.InnerProductArgument.html new file mode 100644 index 000000000..255a3cdc1 --- /dev/null +++ b/docs/arecibo/provider/ipa_pc/struct.InnerProductArgument.html @@ -0,0 +1,109 @@ +InnerProductArgument in arecibo::provider::ipa_pc - Rust
pub struct InnerProductArgument<E: Engine> { /* private fields */ }
Expand description

An inner product argument

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for InnerProductArgument<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> InnerProductArgument<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for InnerProductArgument<E>where + E::Scalar: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for InnerProductArgument<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine> Serialize for InnerProductArgument<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/ipa_pc/struct.ProverKey.html b/docs/arecibo/provider/ipa_pc/struct.ProverKey.html new file mode 100644 index 000000000..e53604caa --- /dev/null +++ b/docs/arecibo/provider/ipa_pc/struct.ProverKey.html @@ -0,0 +1,107 @@ +ProverKey in arecibo::provider::ipa_pc - Rust
pub struct ProverKey<E: Engine> { /* private fields */ }
Expand description

Provides an implementation of the prover key

+

Trait Implementations§

source§

impl<E: Engine> Abomonation for ProverKey<E>

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine> Clone for ProverKey<E>

source§

fn clone(&self) -> ProverKey<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for ProverKey<E>

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for ProverKey<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine> Serialize for ProverKey<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for ProverKey<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: RefUnwindSafe,

§

impl<E> Send for ProverKey<E>

§

impl<E> Sync for ProverKey<E>

§

impl<E> Unpin for ProverKey<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: Unpin,

§

impl<E> UnwindSafe for ProverKey<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/ipa_pc/struct.VerifierKey.html b/docs/arecibo/provider/ipa_pc/struct.VerifierKey.html new file mode 100644 index 000000000..3e6116151 --- /dev/null +++ b/docs/arecibo/provider/ipa_pc/struct.VerifierKey.html @@ -0,0 +1,107 @@ +VerifierKey in arecibo::provider::ipa_pc - Rust
pub struct VerifierKey<E: Engine> { /* private fields */ }
Expand description

Provides an implementation of the verifier key

+

Trait Implementations§

source§

impl<E: Engine> Abomonation for VerifierKey<E>

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine> Clone for VerifierKey<E>

source§

fn clone(&self) -> VerifierKey<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for VerifierKey<E>

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for VerifierKey<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine> Serialize for VerifierKey<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for VerifierKey<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: RefUnwindSafe,

§

impl<E> Send for VerifierKey<E>

§

impl<E> Sync for VerifierKey<E>

§

impl<E> Unpin for VerifierKey<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: Unpin,

§

impl<E> UnwindSafe for VerifierKey<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/mlkzg/index.html b/docs/arecibo/provider/mlkzg/index.html new file mode 100644 index 000000000..2562322c0 --- /dev/null +++ b/docs/arecibo/provider/mlkzg/index.html @@ -0,0 +1,2 @@ +arecibo::provider::mlkzg - Rust

Module arecibo::provider::mlkzg

source ·
Expand description

This module implements Nova’s evaluation engine using multilinear KZG

+

Structs

\ No newline at end of file diff --git a/docs/arecibo/provider/mlkzg/sidebar-items.js b/docs/arecibo/provider/mlkzg/sidebar-items.js new file mode 100644 index 000000000..9f1f41787 --- /dev/null +++ b/docs/arecibo/provider/mlkzg/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["EvaluationArgument","EvaluationEngine"]}; \ No newline at end of file diff --git a/docs/arecibo/provider/mlkzg/struct.EvaluationArgument.html b/docs/arecibo/provider/mlkzg/struct.EvaluationArgument.html new file mode 100644 index 000000000..4ca0ae1bd --- /dev/null +++ b/docs/arecibo/provider/mlkzg/struct.EvaluationArgument.html @@ -0,0 +1,115 @@ +EvaluationArgument in arecibo::provider::mlkzg - Rust
pub struct EvaluationArgument<E: Engine> { /* private fields */ }
Expand description

Provides an implementation of a polynomial evaluation argument

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for EvaluationArgument<E>where + E::G1Affine: Clone, + E::Fr: Clone,

source§

fn clone(&self) -> EvaluationArgument<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for EvaluationArgument<E>where + E::G1Affine: Debug, + E::Fr: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for EvaluationArgument<E>where + E::G1Affine: Deserialize<'de>, + E::Fr: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine> Serialize for EvaluationArgument<E>where + E::G1Affine: Serialize, + E::Fr: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for EvaluationArgument<E>where + <E as Engine>::Fr: RefUnwindSafe, + <E as Engine>::G1Affine: RefUnwindSafe,

§

impl<E> Send for EvaluationArgument<E>

§

impl<E> Sync for EvaluationArgument<E>

§

impl<E> Unpin for EvaluationArgument<E>where + <E as Engine>::Fr: Unpin, + <E as Engine>::G1Affine: Unpin,

§

impl<E> UnwindSafe for EvaluationArgument<E>where + <E as Engine>::Fr: UnwindSafe, + <E as Engine>::G1Affine: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/mlkzg/struct.EvaluationEngine.html b/docs/arecibo/provider/mlkzg/struct.EvaluationEngine.html new file mode 100644 index 000000000..ec6318d85 --- /dev/null +++ b/docs/arecibo/provider/mlkzg/struct.EvaluationEngine.html @@ -0,0 +1,134 @@ +EvaluationEngine in arecibo::provider::mlkzg - Rust
pub struct EvaluationEngine<E, NE> { /* private fields */ }
Expand description

Provides an implementation of a polynomial evaluation engine using KZG

+

Trait Implementations§

source§

impl<E: Clone, NE: Clone> Clone for EvaluationEngine<E, NE>

source§

fn clone(&self) -> EvaluationEngine<E, NE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug, NE: Debug> Debug for EvaluationEngine<E, NE>

source§

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

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

impl<'de, E, NE> Deserialize<'de> for EvaluationEngine<E, NE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E, NE> EvaluationEngineTrait<NE> for EvaluationEngine<E, NE>where + E: MultiMillerLoop, + NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>, + E::Fr: Serialize + DeserializeOwned + PrimeFieldBits + TranscriptReprTrait<E::G1>, + E::G1Affine: Serialize + DeserializeOwned + TranscriptReprTrait<E::G1>, + E::G2Affine: Serialize + DeserializeOwned, + E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>, + <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>,

source§

fn verify( + vk: &Self::VerifierKey, + transcript: &mut <NE as NovaEngine>::TE, + C: &Commitment<NE>, + point: &[E::Fr], + P_of_x: &E::Fr, + pi: &Self::EvaluationArgument +) -> Result<(), NovaError>

A method to verify purported evaluations of a batch of polynomials

+
§

type EvaluationArgument = EvaluationArgument<E>

A type that holds the evaluation argument
§

type ProverKey = KZGProverKey<E>

A type that holds the prover key
§

type VerifierKey = KZGVerifierKey<E>

A type that holds the verifier key
source§

fn setup(ck: &UniversalKZGParam<E>) -> (Self::ProverKey, Self::VerifierKey)

A method to perform any additional setup needed to produce proofs of evaluations
source§

fn prove( + ck: &UniversalKZGParam<E>, + _pk: &Self::ProverKey, + transcript: &mut <NE as NovaEngine>::TE, + _C: &Commitment<NE>, + hat_P: &[E::Fr], + point: &[E::Fr], + _eval: &E::Fr +) -> Result<Self::EvaluationArgument, NovaError>

A method to prove the evaluation of a multilinear polynomial
source§

impl<E, NE> Serialize for EvaluationEngine<E, NE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, NE> RefUnwindSafe for EvaluationEngine<E, NE>where + E: RefUnwindSafe, + NE: RefUnwindSafe,

§

impl<E, NE> Send for EvaluationEngine<E, NE>where + E: Send, + NE: Send,

§

impl<E, NE> Sync for EvaluationEngine<E, NE>where + E: Sync, + NE: Sync,

§

impl<E, NE> Unpin for EvaluationEngine<E, NE>where + E: Unpin, + NE: Unpin,

§

impl<E, NE> UnwindSafe for EvaluationEngine<E, NE>where + E: UnwindSafe, + NE: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/non_hiding_zeromorph/index.html b/docs/arecibo/provider/non_hiding_zeromorph/index.html new file mode 100644 index 000000000..b0ee13c30 --- /dev/null +++ b/docs/arecibo/provider/non_hiding_zeromorph/index.html @@ -0,0 +1,5 @@ +arecibo::provider::non_hiding_zeromorph - Rust
Expand description

Non-hiding Zeromorph scheme for Multilinear Polynomials.

+

Structs

  • Commitments
  • Polynomial Evaluation
  • Zeromorph Polynomial Commitment Scheme on multilinear polynomials. +Note: this is non-hiding, which is why we will implement the EvaluationEngineTrait on this token struct, +as we will have several impls for the trait pegged on the same instance of a pairing::Engine.
  • Proofs
  • ZMProverKey is used to generate a proof
  • ZMVerifierKey is used to check evaluation proofs for a given +commitment.
\ No newline at end of file diff --git a/docs/arecibo/provider/non_hiding_zeromorph/sidebar-items.js b/docs/arecibo/provider/non_hiding_zeromorph/sidebar-items.js new file mode 100644 index 000000000..c2e73489f --- /dev/null +++ b/docs/arecibo/provider/non_hiding_zeromorph/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["ZMCommitment","ZMEvaluation","ZMPCS","ZMProof","ZMProverKey","ZMVerifierKey"]}; \ No newline at end of file diff --git a/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMCommitment.html b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMCommitment.html new file mode 100644 index 000000000..4e0c8b76b --- /dev/null +++ b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMCommitment.html @@ -0,0 +1,113 @@ +ZMCommitment in arecibo::provider::non_hiding_zeromorph - Rust
pub struct ZMCommitment<E: Engine>(_);
Expand description

Commitments

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for ZMCommitment<E>where + E::G1Affine: Clone,

source§

fn clone(&self) -> ZMCommitment<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for ZMCommitment<E>where + E::G1Affine: Debug,

source§

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

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

impl<E: Default + Engine> Default for ZMCommitment<E>where + E::G1Affine: Default,

source§

fn default() -> ZMCommitment<E>

Returns the “default value” for a type. Read more
source§

impl<'de, E: Engine> Deserialize<'de> for ZMCommitment<E>where + E::G1Affine: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<ZMCommitment<E>> for ZMCommitment<E>where + E::G1Affine: PartialEq,

source§

fn eq(&self, other: &ZMCommitment<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for ZMCommitment<E>where + E::G1Affine: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for ZMCommitment<E>where + E::G1Affine: Eq,

source§

impl<E: Engine> StructuralEq for ZMCommitment<E>

source§

impl<E: Engine> StructuralPartialEq for ZMCommitment<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for ZMCommitment<E>where + <E as Engine>::G1Affine: RefUnwindSafe,

§

impl<E> Send for ZMCommitment<E>

§

impl<E> Sync for ZMCommitment<E>

§

impl<E> Unpin for ZMCommitment<E>where + <E as Engine>::G1Affine: Unpin,

§

impl<E> UnwindSafe for ZMCommitment<E>where + <E as Engine>::G1Affine: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMEvaluation.html b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMEvaluation.html new file mode 100644 index 000000000..7788ea7e6 --- /dev/null +++ b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMEvaluation.html @@ -0,0 +1,108 @@ +ZMEvaluation in arecibo::provider::non_hiding_zeromorph - Rust
pub struct ZMEvaluation<E: Engine>(_);
Expand description

Polynomial Evaluation

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for ZMEvaluation<E>where + E::Fr: Clone,

source§

fn clone(&self) -> ZMEvaluation<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for ZMEvaluation<E>where + E::Fr: Debug,

source§

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

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

impl<E: Default + Engine> Default for ZMEvaluation<E>where + E::Fr: Default,

source§

fn default() -> ZMEvaluation<E>

Returns the “default value” for a type. Read more
source§

impl<E: PartialEq + Engine> PartialEq<ZMEvaluation<E>> for ZMEvaluation<E>where + E::Fr: PartialEq,

source§

fn eq(&self, other: &ZMEvaluation<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Eq + Engine> Eq for ZMEvaluation<E>where + E::Fr: Eq,

source§

impl<E: Engine> StructuralEq for ZMEvaluation<E>

source§

impl<E: Engine> StructuralPartialEq for ZMEvaluation<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for ZMEvaluation<E>where + <E as Engine>::Fr: RefUnwindSafe,

§

impl<E> Send for ZMEvaluation<E>

§

impl<E> Sync for ZMEvaluation<E>

§

impl<E> Unpin for ZMEvaluation<E>where + <E as Engine>::Fr: Unpin,

§

impl<E> UnwindSafe for ZMEvaluation<E>where + <E as Engine>::Fr: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMPCS.html b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMPCS.html new file mode 100644 index 000000000..ca3be6545 --- /dev/null +++ b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMPCS.html @@ -0,0 +1,132 @@ +ZMPCS in arecibo::provider::non_hiding_zeromorph - Rust
pub struct ZMPCS<E, NE> { /* private fields */ }
Expand description

Zeromorph Polynomial Commitment Scheme on multilinear polynomials. +Note: this is non-hiding, which is why we will implement the EvaluationEngineTrait on this token struct, +as we will have several impls for the trait pegged on the same instance of a pairing::Engine.

+

Trait Implementations§

source§

impl<E: Clone, NE: Clone> Clone for ZMPCS<E, NE>

source§

fn clone(&self) -> ZMPCS<E, NE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug, NE: Debug> Debug for ZMPCS<E, NE>

source§

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

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

impl<E: Default, NE: Default> Default for ZMPCS<E, NE>

source§

fn default() -> ZMPCS<E, NE>

Returns the “default value” for a type. Read more
source§

impl<E: MultiMillerLoop, NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>> EvaluationEngineTrait<NE> for ZMPCS<E, NE>where + E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>, + E::G1Affine: Serialize + for<'de> Deserialize<'de>, + E::G2Affine: Serialize + for<'de> Deserialize<'de>, + <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>, + E::Fr: PrimeFieldBits,

§

type ProverKey = ZMProverKey<E>

A type that holds the prover key
§

type VerifierKey = ZMVerifierKey<E>

A type that holds the verifier key
§

type EvaluationArgument = ZMProof<E>

A type that holds the evaluation argument
source§

fn setup(ck: &UniversalKZGParam<E>) -> (Self::ProverKey, Self::VerifierKey)

A method to perform any additional setup needed to produce proofs of evaluations
source§

fn prove( + _ck: &UniversalKZGParam<E>, + pk: &Self::ProverKey, + transcript: &mut NE::TE, + comm: &<<NE as Engine>::CE as CommitmentEngineTrait<NE>>::Commitment, + poly: &[NE::Scalar], + point: &[NE::Scalar], + eval: &NE::Scalar +) -> Result<Self::EvaluationArgument, NovaError>

A method to prove the evaluation of a multilinear polynomial
source§

fn verify( + vk: &Self::VerifierKey, + transcript: &mut NE::TE, + comm: &<<NE as Engine>::CE as CommitmentEngineTrait<NE>>::Commitment, + point: &[NE::Scalar], + eval: &NE::Scalar, + arg: &Self::EvaluationArgument +) -> Result<(), NovaError>

A method to verify the purported evaluation of a multilinear polynomials
source§

impl<E: PartialEq, NE: PartialEq> PartialEq<ZMPCS<E, NE>> for ZMPCS<E, NE>

source§

fn eq(&self, other: &ZMPCS<E, NE>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Eq, NE: Eq> Eq for ZMPCS<E, NE>

source§

impl<E, NE> StructuralEq for ZMPCS<E, NE>

source§

impl<E, NE> StructuralPartialEq for ZMPCS<E, NE>

Auto Trait Implementations§

§

impl<E, NE> RefUnwindSafe for ZMPCS<E, NE>where + E: RefUnwindSafe, + NE: RefUnwindSafe,

§

impl<E, NE> Send for ZMPCS<E, NE>where + E: Send, + NE: Send,

§

impl<E, NE> Sync for ZMPCS<E, NE>where + E: Sync, + NE: Sync,

§

impl<E, NE> Unpin for ZMPCS<E, NE>where + E: Unpin, + NE: Unpin,

§

impl<E, NE> UnwindSafe for ZMPCS<E, NE>where + E: UnwindSafe, + NE: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMProof.html b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMProof.html new file mode 100644 index 000000000..7dcaff28a --- /dev/null +++ b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMProof.html @@ -0,0 +1,113 @@ +ZMProof in arecibo::provider::non_hiding_zeromorph - Rust
pub struct ZMProof<E: Engine> { /* private fields */ }
Expand description

Proofs

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for ZMProof<E>where + E::G1Affine: Clone,

source§

fn clone(&self) -> ZMProof<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for ZMProof<E>where + E::G1Affine: Debug,

source§

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

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

impl<E: Default + Engine> Default for ZMProof<E>where + E::G1Affine: Default,

source§

fn default() -> ZMProof<E>

Returns the “default value” for a type. Read more
source§

impl<'de, E: Engine> Deserialize<'de> for ZMProof<E>where + E::G1Affine: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<ZMProof<E>> for ZMProof<E>where + E::G1Affine: PartialEq,

source§

fn eq(&self, other: &ZMProof<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for ZMProof<E>where + E::G1Affine: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for ZMProof<E>where + E::G1Affine: Eq,

source§

impl<E: Engine> StructuralEq for ZMProof<E>

source§

impl<E: Engine> StructuralPartialEq for ZMProof<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for ZMProof<E>where + <E as Engine>::G1Affine: RefUnwindSafe,

§

impl<E> Send for ZMProof<E>

§

impl<E> Sync for ZMProof<E>

§

impl<E> Unpin for ZMProof<E>where + <E as Engine>::G1Affine: Unpin,

§

impl<E> UnwindSafe for ZMProof<E>where + <E as Engine>::G1Affine: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMProverKey.html b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMProverKey.html new file mode 100644 index 000000000..7144b44f4 --- /dev/null +++ b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMProverKey.html @@ -0,0 +1,111 @@ +ZMProverKey in arecibo::provider::non_hiding_zeromorph - Rust
pub struct ZMProverKey<E: Engine> { /* private fields */ }
Expand description

ZMProverKey is used to generate a proof

+

Trait Implementations§

source§

impl<E: Engine> Abomonation for ZMProverKey<E>

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine> Clone for ZMProverKey<E>

source§

fn clone(&self) -> ZMProverKey<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for ZMProverKey<E>

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for ZMProverKey<E>where + E::G1Affine: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<ZMProverKey<E>> for ZMProverKey<E>

source§

fn eq(&self, other: &ZMProverKey<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for ZMProverKey<E>where + E::G1Affine: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for ZMProverKey<E>

source§

impl<E: Engine> StructuralEq for ZMProverKey<E>

source§

impl<E: Engine> StructuralPartialEq for ZMProverKey<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for ZMProverKey<E>where + <E as Engine>::G1Affine: RefUnwindSafe,

§

impl<E> Send for ZMProverKey<E>

§

impl<E> Sync for ZMProverKey<E>

§

impl<E> Unpin for ZMProverKey<E>where + <E as Engine>::G1Affine: Unpin,

§

impl<E> UnwindSafe for ZMProverKey<E>where + <E as Engine>::G1Affine: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMVerifierKey.html b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMVerifierKey.html new file mode 100644 index 000000000..a5e87d428 --- /dev/null +++ b/docs/arecibo/provider/non_hiding_zeromorph/struct.ZMVerifierKey.html @@ -0,0 +1,121 @@ +ZMVerifierKey in arecibo::provider::non_hiding_zeromorph - Rust
pub struct ZMVerifierKey<E: Engine> { /* private fields */ }
Expand description

ZMVerifierKey is used to check evaluation proofs for a given +commitment.

+

Trait Implementations§

source§

impl<E: Engine> Abomonation for ZMVerifierKey<E>

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine> Clone for ZMVerifierKey<E>where + E::G2Affine: Clone,

source§

fn clone(&self) -> ZMVerifierKey<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for ZMVerifierKey<E>where + E::G2Affine: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for ZMVerifierKey<E>where + E::G1Affine: Deserialize<'de>, + E::G2Affine: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<ZMVerifierKey<E>> for ZMVerifierKey<E>where + E::G2Affine: PartialEq,

source§

fn eq(&self, other: &ZMVerifierKey<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for ZMVerifierKey<E>where + E::G1Affine: Serialize, + E::G2Affine: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for ZMVerifierKey<E>where + E::G2Affine: Eq,

source§

impl<E: Engine> StructuralEq for ZMVerifierKey<E>

source§

impl<E: Engine> StructuralPartialEq for ZMVerifierKey<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for ZMVerifierKey<E>where + <E as Engine>::G1Affine: RefUnwindSafe, + <E as Engine>::G2Affine: RefUnwindSafe,

§

impl<E> Send for ZMVerifierKey<E>

§

impl<E> Sync for ZMVerifierKey<E>

§

impl<E> Unpin for ZMVerifierKey<E>where + <E as Engine>::G1Affine: Unpin, + <E as Engine>::G2Affine: Unpin,

§

impl<E> UnwindSafe for ZMVerifierKey<E>where + <E as Engine>::G1Affine: UnwindSafe, + <E as Engine>::G2Affine: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/provider/sidebar-items.js b/docs/arecibo/provider/sidebar-items.js new file mode 100644 index 000000000..6a861daa1 --- /dev/null +++ b/docs/arecibo/provider/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["ipa_pc","mlkzg","non_hiding_zeromorph"],"struct":["Bn256Engine","Bn256EngineKZG","Bn256EngineZM","GrumpkinEngine","PallasEngine","Secp256k1Engine","Secq256k1Engine","VestaEngine"]}; \ No newline at end of file diff --git a/docs/arecibo/provider/struct.Bn256Engine.html b/docs/arecibo/provider/struct.Bn256Engine.html new file mode 100644 index 000000000..239badce6 --- /dev/null +++ b/docs/arecibo/provider/struct.Bn256Engine.html @@ -0,0 +1,101 @@ +Bn256Engine in arecibo::provider - Rust
pub struct Bn256Engine;
Expand description

An implementation of the Nova Engine trait with BN254 curve and Pedersen commitment scheme

+

Trait Implementations§

source§

impl Clone for Bn256Engine

source§

fn clone(&self) -> Bn256Engine

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for Bn256Engine

source§

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

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

impl Engine for Bn256Engine

§

type Base = Fq

A type representing an element of the base field of the group
§

type Scalar = Fr

A type representing an element of the scalar field of the group
§

type GE = G1

A type that represents an element of the group
§

type RO = PoseidonRO<<Bn256Engine as Engine>::Base, <Bn256Engine as Engine>::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field
§

type ROCircuit = PoseidonROCircuit<<Bn256Engine as Engine>::Base>

An alternate implementation of Self::RO in the circuit model
§

type TE = Keccak256Transcript<Bn256Engine>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
§

type CE = CommitmentEngine<Bn256Engine>

A type that defines a commitment engine over scalars in the group
source§

impl PartialEq<Bn256Engine> for Bn256Engine

source§

fn eq(&self, other: &Bn256Engine) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Bn256Engine

source§

impl Eq for Bn256Engine

source§

impl StructuralEq for Bn256Engine

source§

impl StructuralPartialEq for Bn256Engine

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/struct.Bn256EngineKZG.html b/docs/arecibo/provider/struct.Bn256EngineKZG.html new file mode 100644 index 000000000..bce2195c2 --- /dev/null +++ b/docs/arecibo/provider/struct.Bn256EngineKZG.html @@ -0,0 +1,101 @@ +Bn256EngineKZG in arecibo::provider - Rust
pub struct Bn256EngineKZG;
Expand description

An implementation of Nova traits with multilinear KZG over the BN256 curve

+

Trait Implementations§

source§

impl Clone for Bn256EngineKZG

source§

fn clone(&self) -> Bn256EngineKZG

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for Bn256EngineKZG

source§

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

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

impl Engine for Bn256EngineKZG

§

type Base = Fq

A type representing an element of the base field of the group
§

type Scalar = Fr

A type representing an element of the scalar field of the group
§

type GE = G1

A type that represents an element of the group
§

type RO = PoseidonRO<<Bn256EngineKZG as Engine>::Base, <Bn256EngineKZG as Engine>::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field
§

type ROCircuit = PoseidonROCircuit<<Bn256EngineKZG as Engine>::Base>

An alternate implementation of Self::RO in the circuit model
§

type TE = Keccak256Transcript<Bn256EngineKZG>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
§

type CE = KZGCommitmentEngine<Bn256>

A type that defines a commitment engine over scalars in the group
source§

impl PartialEq<Bn256EngineKZG> for Bn256EngineKZG

source§

fn eq(&self, other: &Bn256EngineKZG) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Bn256EngineKZG

source§

impl Eq for Bn256EngineKZG

source§

impl StructuralEq for Bn256EngineKZG

source§

impl StructuralPartialEq for Bn256EngineKZG

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/struct.Bn256EngineZM.html b/docs/arecibo/provider/struct.Bn256EngineZM.html new file mode 100644 index 000000000..2540b13d4 --- /dev/null +++ b/docs/arecibo/provider/struct.Bn256EngineZM.html @@ -0,0 +1,101 @@ +Bn256EngineZM in arecibo::provider - Rust
pub struct Bn256EngineZM;
Expand description

An implementation of the Nova Engine trait with BN254 curve and Zeromorph commitment scheme

+

Trait Implementations§

source§

impl Clone for Bn256EngineZM

source§

fn clone(&self) -> Bn256EngineZM

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for Bn256EngineZM

source§

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

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

impl Engine for Bn256EngineZM

§

type Base = Fq

A type representing an element of the base field of the group
§

type Scalar = Fr

A type representing an element of the scalar field of the group
§

type GE = G1

A type that represents an element of the group
§

type RO = PoseidonRO<<Bn256EngineZM as Engine>::Base, <Bn256EngineZM as Engine>::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field
§

type ROCircuit = PoseidonROCircuit<<Bn256EngineZM as Engine>::Base>

An alternate implementation of Self::RO in the circuit model
§

type TE = Keccak256Transcript<Bn256EngineZM>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
§

type CE = KZGCommitmentEngine<Bn256>

A type that defines a commitment engine over scalars in the group
source§

impl PartialEq<Bn256EngineZM> for Bn256EngineZM

source§

fn eq(&self, other: &Bn256EngineZM) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Bn256EngineZM

source§

impl Eq for Bn256EngineZM

source§

impl StructuralEq for Bn256EngineZM

source§

impl StructuralPartialEq for Bn256EngineZM

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/struct.GrumpkinEngine.html b/docs/arecibo/provider/struct.GrumpkinEngine.html new file mode 100644 index 000000000..b87a532ea --- /dev/null +++ b/docs/arecibo/provider/struct.GrumpkinEngine.html @@ -0,0 +1,101 @@ +GrumpkinEngine in arecibo::provider - Rust
pub struct GrumpkinEngine;
Expand description

An implementation of the Nova Engine trait with Grumpkin curve and Pedersen commitment scheme

+

Trait Implementations§

source§

impl Clone for GrumpkinEngine

source§

fn clone(&self) -> GrumpkinEngine

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for GrumpkinEngine

source§

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

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

impl Engine for GrumpkinEngine

§

type Base = Fr

A type representing an element of the base field of the group
§

type Scalar = Fq

A type representing an element of the scalar field of the group
§

type GE = G1

A type that represents an element of the group
§

type RO = PoseidonRO<<GrumpkinEngine as Engine>::Base, <GrumpkinEngine as Engine>::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field
§

type ROCircuit = PoseidonROCircuit<<GrumpkinEngine as Engine>::Base>

An alternate implementation of Self::RO in the circuit model
§

type TE = Keccak256Transcript<GrumpkinEngine>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
§

type CE = CommitmentEngine<GrumpkinEngine>

A type that defines a commitment engine over scalars in the group
source§

impl PartialEq<GrumpkinEngine> for GrumpkinEngine

source§

fn eq(&self, other: &GrumpkinEngine) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for GrumpkinEngine

source§

impl Eq for GrumpkinEngine

source§

impl StructuralEq for GrumpkinEngine

source§

impl StructuralPartialEq for GrumpkinEngine

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/struct.PallasEngine.html b/docs/arecibo/provider/struct.PallasEngine.html new file mode 100644 index 000000000..14e59db37 --- /dev/null +++ b/docs/arecibo/provider/struct.PallasEngine.html @@ -0,0 +1,101 @@ +PallasEngine in arecibo::provider - Rust
pub struct PallasEngine;
Expand description

An implementation of the Nova Engine trait with Pallas curve and Pedersen commitment scheme

+

Trait Implementations§

source§

impl Clone for PallasEngine

source§

fn clone(&self) -> PallasEngine

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for PallasEngine

source§

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

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

impl Engine for PallasEngine

§

type Base = Fp

A type representing an element of the base field of the group
§

type Scalar = Fq

A type representing an element of the scalar field of the group
§

type GE = Ep

A type that represents an element of the group
§

type RO = PoseidonRO<<PallasEngine as Engine>::Base, <PallasEngine as Engine>::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field
§

type ROCircuit = PoseidonROCircuit<<PallasEngine as Engine>::Base>

An alternate implementation of Self::RO in the circuit model
§

type TE = Keccak256Transcript<PallasEngine>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
§

type CE = CommitmentEngine<PallasEngine>

A type that defines a commitment engine over scalars in the group
source§

impl PartialEq<PallasEngine> for PallasEngine

source§

fn eq(&self, other: &PallasEngine) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for PallasEngine

source§

impl Eq for PallasEngine

source§

impl StructuralEq for PallasEngine

source§

impl StructuralPartialEq for PallasEngine

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/struct.Secp256k1Engine.html b/docs/arecibo/provider/struct.Secp256k1Engine.html new file mode 100644 index 000000000..dbda32783 --- /dev/null +++ b/docs/arecibo/provider/struct.Secp256k1Engine.html @@ -0,0 +1,101 @@ +Secp256k1Engine in arecibo::provider - Rust
pub struct Secp256k1Engine;
Expand description

An implementation of the Nova Engine trait with Secp256k1 curve and Pedersen commitment scheme

+

Trait Implementations§

source§

impl Clone for Secp256k1Engine

source§

fn clone(&self) -> Secp256k1Engine

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for Secp256k1Engine

source§

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

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

impl Engine for Secp256k1Engine

§

type Base = Fp

A type representing an element of the base field of the group
§

type Scalar = Fq

A type representing an element of the scalar field of the group
§

type GE = Secp256k1

A type that represents an element of the group
§

type RO = PoseidonRO<<Secp256k1Engine as Engine>::Base, <Secp256k1Engine as Engine>::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field
§

type ROCircuit = PoseidonROCircuit<<Secp256k1Engine as Engine>::Base>

An alternate implementation of Self::RO in the circuit model
§

type TE = Keccak256Transcript<Secp256k1Engine>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
§

type CE = CommitmentEngine<Secp256k1Engine>

A type that defines a commitment engine over scalars in the group
source§

impl PartialEq<Secp256k1Engine> for Secp256k1Engine

source§

fn eq(&self, other: &Secp256k1Engine) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Secp256k1Engine

source§

impl Eq for Secp256k1Engine

source§

impl StructuralEq for Secp256k1Engine

source§

impl StructuralPartialEq for Secp256k1Engine

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/struct.Secq256k1Engine.html b/docs/arecibo/provider/struct.Secq256k1Engine.html new file mode 100644 index 000000000..791f1a651 --- /dev/null +++ b/docs/arecibo/provider/struct.Secq256k1Engine.html @@ -0,0 +1,101 @@ +Secq256k1Engine in arecibo::provider - Rust
pub struct Secq256k1Engine;
Expand description

An implementation of the Nova Engine trait with Secp256k1 curve and Pedersen commitment scheme

+

Trait Implementations§

source§

impl Clone for Secq256k1Engine

source§

fn clone(&self) -> Secq256k1Engine

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for Secq256k1Engine

source§

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

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

impl Engine for Secq256k1Engine

§

type Base = Fq

A type representing an element of the base field of the group
§

type Scalar = Fp

A type representing an element of the scalar field of the group
§

type GE = Secq256k1

A type that represents an element of the group
§

type RO = PoseidonRO<<Secq256k1Engine as Engine>::Base, <Secq256k1Engine as Engine>::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field
§

type ROCircuit = PoseidonROCircuit<<Secq256k1Engine as Engine>::Base>

An alternate implementation of Self::RO in the circuit model
§

type TE = Keccak256Transcript<Secq256k1Engine>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
§

type CE = CommitmentEngine<Secq256k1Engine>

A type that defines a commitment engine over scalars in the group
source§

impl PartialEq<Secq256k1Engine> for Secq256k1Engine

source§

fn eq(&self, other: &Secq256k1Engine) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for Secq256k1Engine

source§

impl Eq for Secq256k1Engine

source§

impl StructuralEq for Secq256k1Engine

source§

impl StructuralPartialEq for Secq256k1Engine

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/provider/struct.VestaEngine.html b/docs/arecibo/provider/struct.VestaEngine.html new file mode 100644 index 000000000..f82d06c60 --- /dev/null +++ b/docs/arecibo/provider/struct.VestaEngine.html @@ -0,0 +1,101 @@ +VestaEngine in arecibo::provider - Rust
pub struct VestaEngine;
Expand description

An implementation of the Nova Engine trait with Vesta curve and Pedersen commitment scheme

+

Trait Implementations§

source§

impl Clone for VestaEngine

source§

fn clone(&self) -> VestaEngine

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for VestaEngine

source§

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

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

impl Engine for VestaEngine

§

type Base = Fq

A type representing an element of the base field of the group
§

type Scalar = Fp

A type representing an element of the scalar field of the group
§

type GE = Eq

A type that represents an element of the group
§

type RO = PoseidonRO<<VestaEngine as Engine>::Base, <VestaEngine as Engine>::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field
§

type ROCircuit = PoseidonROCircuit<<VestaEngine as Engine>::Base>

An alternate implementation of Self::RO in the circuit model
§

type TE = Keccak256Transcript<VestaEngine>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
§

type CE = CommitmentEngine<VestaEngine>

A type that defines a commitment engine over scalars in the group
source§

impl PartialEq<VestaEngine> for VestaEngine

source§

fn eq(&self, other: &VestaEngine) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Copy for VestaEngine

source§

impl Eq for VestaEngine

source§

impl StructuralEq for VestaEngine

source§

impl StructuralPartialEq for VestaEngine

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/r1cs/fn.commitment_key.html b/docs/arecibo/r1cs/fn.commitment_key.html new file mode 100644 index 000000000..94e25e7f6 --- /dev/null +++ b/docs/arecibo/r1cs/fn.commitment_key.html @@ -0,0 +1,13 @@ +commitment_key in arecibo::r1cs - Rust

Function arecibo::r1cs::commitment_key

source ·
pub fn commitment_key<E: Engine>(
+    S: &R1CSShape<E>,
+    ck_floor: &CommitmentKeyHint<E>
+) -> <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey
Expand description

Generates public parameters for a Rank-1 Constraint System (R1CS).

+

This function takes into consideration the shape of the R1CS matrices and a hint function +for the number of generators. It returns a CommitmentKey.

+

Arguments

+
    +
  • S: The shape of the R1CS matrices.
  • +
  • ck_floor: A function that provides a floor for the number of generators. A good function to +provide is the commitment_key_floor field in the trait RelaxedR1CSSNARKTrait.
  • +
+
\ No newline at end of file diff --git a/docs/arecibo/r1cs/fn.commitment_key_size.html b/docs/arecibo/r1cs/fn.commitment_key_size.html new file mode 100644 index 000000000..85a75015d --- /dev/null +++ b/docs/arecibo/r1cs/fn.commitment_key_size.html @@ -0,0 +1,5 @@ +commitment_key_size in arecibo::r1cs - Rust
pub fn commitment_key_size<E: Engine>(
+    S: &R1CSShape<E>,
+    ck_floor: &CommitmentKeyHint<E>
+) -> usize
Expand description

Computes the number of generators required for the commitment key corresponding to shape S.

+
\ No newline at end of file diff --git a/docs/arecibo/r1cs/fn.default_T.html b/docs/arecibo/r1cs/fn.default_T.html new file mode 100644 index 000000000..88d3c4571 --- /dev/null +++ b/docs/arecibo/r1cs/fn.default_T.html @@ -0,0 +1,2 @@ +default_T in arecibo::r1cs - Rust

Function arecibo::r1cs::default_T

source ·
pub fn default_T<E: Engine>(num_cons: usize) -> Vec<E::Scalar>
Expand description

Empty buffer for commit_T_into

+
\ No newline at end of file diff --git a/docs/arecibo/r1cs/index.html b/docs/arecibo/r1cs/index.html new file mode 100644 index 000000000..4c39ddc57 --- /dev/null +++ b/docs/arecibo/r1cs/index.html @@ -0,0 +1,2 @@ +arecibo::r1cs - Rust

Module arecibo::r1cs

source ·
Expand description

This module defines R1CS related types and a folding scheme for Relaxed R1CS

+

Structs

Functions

  • Generates public parameters for a Rank-1 Constraint System (R1CS).
  • Computes the number of generators required for the commitment key corresponding to shape S.
  • Empty buffer for commit_T_into

Type Definitions

  • A type for functions that hints commitment key sizing by returning the floor of the number of required generators.
\ No newline at end of file diff --git a/docs/arecibo/r1cs/sidebar-items.js b/docs/arecibo/r1cs/sidebar-items.js new file mode 100644 index 000000000..cc243fb1d --- /dev/null +++ b/docs/arecibo/r1cs/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["commitment_key","commitment_key_size","default_T"],"struct":["R1CSInstance","R1CSResult","R1CSShape","R1CSWitness","RelaxedR1CSInstance","RelaxedR1CSWitness"],"type":["CommitmentKeyHint"]}; \ No newline at end of file diff --git a/docs/arecibo/r1cs/struct.R1CSInstance.html b/docs/arecibo/r1cs/struct.R1CSInstance.html new file mode 100644 index 000000000..b69a89daa --- /dev/null +++ b/docs/arecibo/r1cs/struct.R1CSInstance.html @@ -0,0 +1,118 @@ +R1CSInstance in arecibo::r1cs - Rust

Struct arecibo::r1cs::R1CSInstance

source ·
pub struct R1CSInstance<E: Engine> { /* private fields */ }
Expand description

A type that holds an R1CS instance

+

Implementations§

source§

impl<E: Engine> R1CSInstance<E>

source

pub fn new( + S: &R1CSShape<E>, + comm_W: <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, + X: Vec<E::Scalar> +) -> Result<Self, NovaError>

A method to create an instance object using constituent elements

+

Trait Implementations§

source§

impl<E: Engine> AbsorbInROTrait<E> for R1CSInstance<E>

source§

fn absorb_in_ro(&self, ro: &mut E::RO)

Absorbs the value in the provided RO
source§

impl<E: Clone + Engine> Clone for R1CSInstance<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> R1CSInstance<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for R1CSInstance<E>where + E::Scalar: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for R1CSInstance<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<R1CSInstance<E>> for R1CSInstance<E>where + E::Scalar: PartialEq,

source§

fn eq(&self, other: &R1CSInstance<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for R1CSInstance<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for R1CSInstance<E>where + E::Scalar: Eq,

source§

impl<E: Engine> StructuralEq for R1CSInstance<E>

source§

impl<E: Engine> StructuralPartialEq for R1CSInstance<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for R1CSInstance<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe, + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E> Send for R1CSInstance<E>

§

impl<E> Sync for R1CSInstance<E>

§

impl<E> Unpin for R1CSInstance<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin, + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for R1CSInstance<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/r1cs/struct.R1CSResult.html b/docs/arecibo/r1cs/struct.R1CSResult.html new file mode 100644 index 000000000..8a41e57cd --- /dev/null +++ b/docs/arecibo/r1cs/struct.R1CSResult.html @@ -0,0 +1,111 @@ +R1CSResult in arecibo::r1cs - Rust

Struct arecibo::r1cs::R1CSResult

source ·
pub struct R1CSResult<E: Engine> { /* private fields */ }
Expand description

A type that holds the result of a R1CS multiplication

+

Implementations§

source§

impl<E: Engine> R1CSResult<E>

source

pub fn default(num_cons: usize) -> Self

Produces a default R1CSResult given an R1CSShape

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for R1CSResult<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> R1CSResult<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for R1CSResult<E>where + E::Scalar: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for R1CSResult<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<R1CSResult<E>> for R1CSResult<E>where + E::Scalar: PartialEq,

source§

fn eq(&self, other: &R1CSResult<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for R1CSResult<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for R1CSResult<E>where + E::Scalar: Eq,

source§

impl<E: Engine> StructuralEq for R1CSResult<E>

source§

impl<E: Engine> StructuralPartialEq for R1CSResult<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for R1CSResult<E>where + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E> Send for R1CSResult<E>

§

impl<E> Sync for R1CSResult<E>

§

impl<E> Unpin for R1CSResult<E>where + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for R1CSResult<E>where + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/r1cs/struct.R1CSShape.html b/docs/arecibo/r1cs/struct.R1CSShape.html new file mode 100644 index 000000000..1e0ad7596 --- /dev/null +++ b/docs/arecibo/r1cs/struct.R1CSShape.html @@ -0,0 +1,171 @@ +R1CSShape in arecibo::r1cs - Rust

Struct arecibo::r1cs::R1CSShape

source ·
pub struct R1CSShape<E: Engine> { /* private fields */ }
Expand description

A type that holds the shape of the R1CS matrices

+

Implementations§

source§

impl<E: Engine> R1CSShape<E>

source

pub fn new( + num_cons: usize, + num_vars: usize, + num_io: usize, + A: SparseMatrix<E::Scalar>, + B: SparseMatrix<E::Scalar>, + C: SparseMatrix<E::Scalar> +) -> Result<Self, NovaError>

Create an object of type R1CSShape from the explicitly specified R1CS matrices

+
source

pub fn random<R: RngCore + CryptoRng>( + num_cons: usize, + num_vars: usize, + num_io: usize, + num_entries: usize, + rng: &mut R +) -> Self

Generate a random R1CSShape with the specified number of constraints, variables, and public inputs/outputs.

+
source

pub fn random_witness_instance<R: RngCore + CryptoRng>( + &self, + commitment_key: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + rng: &mut R +) -> (RelaxedR1CSWitness<E>, RelaxedR1CSInstance<E>)

Generate a satisfying RelaxedR1CSWitness and RelaxedR1CSInstance for this R1CSShape.

+
source

pub fn digest(&self) -> E::Scalar

returned the digest of the R1CSShape

+
source

pub fn is_sat_relaxed( + &self, + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + U: &RelaxedR1CSInstance<E>, + W: &RelaxedR1CSWitness<E> +) -> Result<(), NovaError>

Checks if the Relaxed R1CS instance is satisfiable given a witness and its shape

+
source

pub fn is_sat( + &self, + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + U: &R1CSInstance<E>, + W: &R1CSWitness<E> +) -> Result<(), NovaError>

Checks if the R1CS instance is satisfiable given a witness and its shape

+
source

pub fn commit_T( + &self, + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + U1: &RelaxedR1CSInstance<E>, + W1: &RelaxedR1CSWitness<E>, + U2: &R1CSInstance<E>, + W2: &R1CSWitness<E> +) -> Result<(Vec<E::Scalar>, <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment), NovaError>

A method to compute a commitment to the cross-term T given a +Relaxed R1CS instance-witness pair and an R1CS instance-witness pair

+
source

pub fn commit_T_into( + &self, + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + U1: &RelaxedR1CSInstance<E>, + W1: &RelaxedR1CSWitness<E>, + U2: &R1CSInstance<E>, + W2: &R1CSWitness<E>, + T: &mut Vec<E::Scalar>, + ABC_Z_1: &mut R1CSResult<E>, + ABC_Z_2: &mut R1CSResult<E> +) -> Result<<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, NovaError>

A method to compute a commitment to the cross-term T given a +Relaxed R1CS instance-witness pair and an R1CS instance-witness pair

+

This is R1CSShape::commit_T but into a buffer.

+
source

pub fn pad(&self) -> Self

Pads the R1CSShape so that the number of variables is a power of two +Renumbers variables to accommodate padded variables

+

Trait Implementations§

source§

impl<E: Engine> Abomonation for R1CSShape<E>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine> Clone for R1CSShape<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> R1CSShape<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for R1CSShape<E>where + E::Scalar: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for R1CSShape<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<R1CSShape<E>> for R1CSShape<E>where + E::Scalar: PartialEq,

source§

fn eq(&self, other: &R1CSShape<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for R1CSShape<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for R1CSShape<E>where + E::Scalar: Eq,

source§

impl<E: Engine> StructuralEq for R1CSShape<E>

source§

impl<E: Engine> StructuralPartialEq for R1CSShape<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for R1CSShape<E>where + <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe,

§

impl<E> Send for R1CSShape<E>

§

impl<E> Sync for R1CSShape<E>

§

impl<E> Unpin for R1CSShape<E>where + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for R1CSShape<E>where + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/r1cs/struct.R1CSWitness.html b/docs/arecibo/r1cs/struct.R1CSWitness.html new file mode 100644 index 000000000..5f20a7e24 --- /dev/null +++ b/docs/arecibo/r1cs/struct.R1CSWitness.html @@ -0,0 +1,115 @@ +R1CSWitness in arecibo::r1cs - Rust

Struct arecibo::r1cs::R1CSWitness

source ·
pub struct R1CSWitness<E: Engine> { /* private fields */ }
Expand description

A type that holds a witness for a given R1CS instance

+

Implementations§

source§

impl<E: Engine> R1CSWitness<E>

source

pub fn new(S: &R1CSShape<E>, W: Vec<E::Scalar>) -> Result<Self, NovaError>

A method to create a witness object using a vector of scalars

+
source

pub fn commit( + &self, + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey +) -> <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment

Commits to the witness using the supplied generators

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for R1CSWitness<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> R1CSWitness<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for R1CSWitness<E>where + E::Scalar: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for R1CSWitness<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<R1CSWitness<E>> for R1CSWitness<E>where + E::Scalar: PartialEq,

source§

fn eq(&self, other: &R1CSWitness<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for R1CSWitness<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for R1CSWitness<E>where + E::Scalar: Eq,

source§

impl<E: Engine> StructuralEq for R1CSWitness<E>

source§

impl<E: Engine> StructuralPartialEq for R1CSWitness<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for R1CSWitness<E>where + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E> Send for R1CSWitness<E>

§

impl<E> Sync for R1CSWitness<E>

§

impl<E> Unpin for R1CSWitness<E>where + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for R1CSWitness<E>where + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/r1cs/struct.RelaxedR1CSInstance.html b/docs/arecibo/r1cs/struct.RelaxedR1CSInstance.html new file mode 100644 index 000000000..b6dad11a5 --- /dev/null +++ b/docs/arecibo/r1cs/struct.RelaxedR1CSInstance.html @@ -0,0 +1,138 @@ +RelaxedR1CSInstance in arecibo::r1cs - Rust
pub struct RelaxedR1CSInstance<E: Engine> { /* private fields */ }
Expand description

A type that holds a Relaxed R1CS instance

+

Implementations§

source§

impl<E: Engine> RelaxedR1CSInstance<E>

source

pub fn default( + _ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + S: &R1CSShape<E> +) -> Self

Produces a default RelaxedR1CSInstance given R1CSGens and R1CSShape

+
source

pub fn from_r1cs_instance( + _ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + S: &R1CSShape<E>, + instance: R1CSInstance<E> +) -> Self

Initializes a new RelaxedR1CSInstance from an R1CSInstance

+
source

pub fn from_r1cs_instance_unchecked( + comm_W: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, + X: &[E::Scalar] +) -> Self

Initializes a new RelaxedR1CSInstance from an R1CSInstance

+
source

pub fn fold( + &self, + U2: &R1CSInstance<E>, + comm_T: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, + r: &E::Scalar +) -> Self

Folds an incoming RelaxedR1CSInstance into the current one

+
source

pub fn fold_mut( + &mut self, + U2: &R1CSInstance<E>, + comm_T: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, + r: &E::Scalar +)

Mutably folds an incoming RelaxedR1CSInstance into the current one

+

Trait Implementations§

source§

impl<E: Engine> AbsorbInROTrait<E> for RelaxedR1CSInstance<E>

source§

fn absorb_in_ro(&self, ro: &mut E::RO)

Absorbs the value in the provided RO
source§

impl<E: Clone + Engine> Clone for RelaxedR1CSInstance<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> RelaxedR1CSInstance<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for RelaxedR1CSInstance<E>where + E::Scalar: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for RelaxedR1CSInstance<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<RelaxedR1CSInstance<E>> for RelaxedR1CSInstance<E>where + E::Scalar: PartialEq,

source§

fn eq(&self, other: &RelaxedR1CSInstance<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for RelaxedR1CSInstance<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Engine> TranscriptReprTrait<<E as Engine>::GE> for RelaxedR1CSInstance<E>

source§

fn to_transcript_bytes(&self) -> Vec<u8>

returns a byte representation of self to be added to the transcript
source§

impl<E: Eq + Engine> Eq for RelaxedR1CSInstance<E>where + E::Scalar: Eq,

source§

impl<E: Engine> StructuralEq for RelaxedR1CSInstance<E>

source§

impl<E: Engine> StructuralPartialEq for RelaxedR1CSInstance<E>

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/r1cs/struct.RelaxedR1CSWitness.html b/docs/arecibo/r1cs/struct.RelaxedR1CSWitness.html new file mode 100644 index 000000000..9edef98bb --- /dev/null +++ b/docs/arecibo/r1cs/struct.RelaxedR1CSWitness.html @@ -0,0 +1,129 @@ +RelaxedR1CSWitness in arecibo::r1cs - Rust
pub struct RelaxedR1CSWitness<E: Engine> { /* private fields */ }
Expand description

A type that holds a witness for a given Relaxed R1CS instance

+

Implementations§

source§

impl<E: Engine> RelaxedR1CSWitness<E>

source

pub fn default(S: &R1CSShape<E>) -> Self

Produces a default RelaxedR1CSWitness given an R1CSShape

+
source

pub fn from_r1cs_witness(S: &R1CSShape<E>, witness: R1CSWitness<E>) -> Self

Initializes a new RelaxedR1CSWitness from an R1CSWitness

+
source

pub fn commit( + &self, + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey +) -> (<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment)

Commits to the witness using the supplied generators

+
source

pub fn fold( + &self, + W2: &R1CSWitness<E>, + T: &[E::Scalar], + r: &E::Scalar +) -> Result<Self, NovaError>

Folds an incoming R1CSWitness into the current one

+
source

pub fn fold_mut( + &mut self, + W2: &R1CSWitness<E>, + T: &[E::Scalar], + r: &E::Scalar +) -> Result<(), NovaError>

Mutably folds an incoming R1CSWitness into the current one

+
source

pub fn pad(&self, S: &R1CSShape<E>) -> Self

Pads the provided witness to the correct length

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for RelaxedR1CSWitness<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> RelaxedR1CSWitness<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for RelaxedR1CSWitness<E>where + E::Scalar: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for RelaxedR1CSWitness<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<RelaxedR1CSWitness<E>> for RelaxedR1CSWitness<E>where + E::Scalar: PartialEq,

source§

fn eq(&self, other: &RelaxedR1CSWitness<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for RelaxedR1CSWitness<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for RelaxedR1CSWitness<E>where + E::Scalar: Eq,

source§

impl<E: Engine> StructuralEq for RelaxedR1CSWitness<E>

source§

impl<E: Engine> StructuralPartialEq for RelaxedR1CSWitness<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for RelaxedR1CSWitness<E>where + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E> Send for RelaxedR1CSWitness<E>

§

impl<E> Sync for RelaxedR1CSWitness<E>

§

impl<E> Unpin for RelaxedR1CSWitness<E>where + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for RelaxedR1CSWitness<E>where + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/r1cs/type.CommitmentKeyHint.html b/docs/arecibo/r1cs/type.CommitmentKeyHint.html new file mode 100644 index 000000000..113de3380 --- /dev/null +++ b/docs/arecibo/r1cs/type.CommitmentKeyHint.html @@ -0,0 +1,2 @@ +CommitmentKeyHint in arecibo::r1cs - Rust

Type Definition arecibo::r1cs::CommitmentKeyHint

source ·
pub type CommitmentKeyHint<E> = dyn Fn(&R1CSShape<E>) -> usize;
Expand description

A type for functions that hints commitment key sizing by returning the floor of the number of required generators.

+
\ No newline at end of file diff --git a/docs/arecibo/sidebar-items.js b/docs/arecibo/sidebar-items.js new file mode 100644 index 000000000..5dbf68559 --- /dev/null +++ b/docs/arecibo/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["circuit_digest"],"macro":["impl_traits","zip_with","zip_with_for_each"],"mod":["constants","errors","gadgets","provider","r1cs","spartan","supernova","traits"],"struct":["CompressedSNARK","ProverKey","PublicParams","R1CSWithArity","RecursiveSNARK","ResourceBuffer","VerifierKey"]}; \ No newline at end of file diff --git a/docs/arecibo/spartan/batched/index.html b/docs/arecibo/spartan/batched/index.html new file mode 100644 index 000000000..b8f5bb2a0 --- /dev/null +++ b/docs/arecibo/spartan/batched/index.html @@ -0,0 +1,7 @@ +arecibo::spartan::batched - Rust

Module arecibo::spartan::batched

source ·
Expand description

This module implements BatchedRelaxedR1CSSNARKTrait using Spartan that is generic over the polynomial commitment +and evaluation argument (i.e., a PCS) This version of Spartan does not use preprocessing so the verifier keeps the +entire description of R1CS matrices. This is essentially optimal for the verifier when using an IPA-based polynomial +commitment scheme. This batched implementation batches the outer and inner sumchecks of the Spartan SNARK.

+

Structs

  • A succinct proof of knowledge of a witness to a batch of relaxed R1CS instances +The proof is produced using Spartan’s combination of the sum-check and +the commitment to a vector viewed as a polynomial commitment
  • A type that represents the prover’s key
  • A type that represents the verifier’s key
\ No newline at end of file diff --git a/docs/arecibo/spartan/batched/sidebar-items.js b/docs/arecibo/spartan/batched/sidebar-items.js new file mode 100644 index 000000000..0f61de1bb --- /dev/null +++ b/docs/arecibo/spartan/batched/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["BatchedRelaxedR1CSSNARK","ProverKey","VerifierKey"]}; \ No newline at end of file diff --git a/docs/arecibo/spartan/batched/struct.BatchedRelaxedR1CSSNARK.html b/docs/arecibo/spartan/batched/struct.BatchedRelaxedR1CSSNARK.html new file mode 100644 index 000000000..ae15860b0 --- /dev/null +++ b/docs/arecibo/spartan/batched/struct.BatchedRelaxedR1CSSNARK.html @@ -0,0 +1,130 @@ +BatchedRelaxedR1CSSNARK in arecibo::spartan::batched - Rust
pub struct BatchedRelaxedR1CSSNARK<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A succinct proof of knowledge of a witness to a batch of relaxed R1CS instances +The proof is produced using Spartan’s combination of the sum-check and +the commitment to a vector viewed as a polynomial commitment

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> BatchedRelaxedR1CSSNARKTrait<E> for BatchedRelaxedR1CSSNARK<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

§

type ProverKey = ProverKey<E, EE>

A type that represents the prover’s key
§

type VerifierKey = VerifierKey<E, EE>

A type that represents the verifier’s key
source§

fn setup( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + S: Vec<&R1CSShape<E>> +) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>

Produces the keys for the prover and the verifier
source§

fn prove( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + pk: &Self::ProverKey, + S: Vec<&R1CSShape<E>>, + U: &[RelaxedR1CSInstance<E>], + W: &[RelaxedR1CSWitness<E>] +) -> Result<Self, NovaError>

Produces a new SNARK for a batch of relaxed R1CS
source§

fn verify( + &self, + vk: &Self::VerifierKey, + U: &[RelaxedR1CSInstance<E>] +) -> Result<(), NovaError>

Verifies a SNARK for a batch of relaxed R1CS
source§

fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize>

This associated function (not a method) provides a hint that offers +a minimum sizing cue for the commitment key used by this SNARK +implementation. The commitment key passed in setup should then +be at least as large as this hint.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for BatchedRelaxedR1CSSNARK<E, EE>where + E::Scalar: Clone, + EE::EvaluationArgument: Clone,

source§

fn clone(&self) -> BatchedRelaxedR1CSSNARK<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine, EE: Debug + EvaluationEngineTrait<E>> Debug for BatchedRelaxedR1CSSNARK<E, EE>where + E::Scalar: Debug, + EE::EvaluationArgument: Debug,

source§

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

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

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for BatchedRelaxedR1CSSNARK<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for BatchedRelaxedR1CSSNARK<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/batched/struct.ProverKey.html b/docs/arecibo/spartan/batched/struct.ProverKey.html new file mode 100644 index 000000000..4a314e673 --- /dev/null +++ b/docs/arecibo/spartan/batched/struct.ProverKey.html @@ -0,0 +1,113 @@ +ProverKey in arecibo::spartan::batched - Rust
pub struct ProverKey<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A type that represents the prover’s key

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for ProverKey<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for ProverKey<E, EE>where + EE::ProverKey: Clone, + E::Scalar: Clone,

source§

fn clone(&self) -> ProverKey<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for ProverKey<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for ProverKey<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for ProverKey<E, EE>where + <EE as EvaluationEngineTrait<E>>::ProverKey: RefUnwindSafe, + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E, EE> Send for ProverKey<E, EE>

§

impl<E, EE> Sync for ProverKey<E, EE>

§

impl<E, EE> Unpin for ProverKey<E, EE>where + <EE as EvaluationEngineTrait<E>>::ProverKey: Unpin, + <E as Engine>::Scalar: Unpin,

§

impl<E, EE> UnwindSafe for ProverKey<E, EE>where + <EE as EvaluationEngineTrait<E>>::ProverKey: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/batched/struct.VerifierKey.html b/docs/arecibo/spartan/batched/struct.VerifierKey.html new file mode 100644 index 000000000..741005ed0 --- /dev/null +++ b/docs/arecibo/spartan/batched/struct.VerifierKey.html @@ -0,0 +1,114 @@ +VerifierKey in arecibo::spartan::batched - Rust
pub struct VerifierKey<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A type that represents the verifier’s key

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for VerifierKey<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for VerifierKey<E, EE>where + EE::VerifierKey: Clone, + E::Scalar: Clone,

source§

fn clone(&self) -> VerifierKey<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for VerifierKey<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for VerifierKey<E, EE>

source§

fn digest(&self) -> E::Scalar

Returns the digest of the verifier’s key.

+
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for VerifierKey<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for VerifierKey<E, EE>where + <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe, + <EE as EvaluationEngineTrait<E>>::VerifierKey: RefUnwindSafe,

§

impl<E, EE> Send for VerifierKey<E, EE>

§

impl<E, EE> Sync for VerifierKey<E, EE>

§

impl<E, EE> Unpin for VerifierKey<E, EE>where + <E as Engine>::Scalar: Unpin, + <EE as EvaluationEngineTrait<E>>::VerifierKey: Unpin,

§

impl<E, EE> UnwindSafe for VerifierKey<E, EE>where + <E as Engine>::Scalar: UnwindSafe, + <EE as EvaluationEngineTrait<E>>::VerifierKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/batched_ppsnark/index.html b/docs/arecibo/spartan/batched_ppsnark/index.html new file mode 100644 index 000000000..533cb9814 --- /dev/null +++ b/docs/arecibo/spartan/batched_ppsnark/index.html @@ -0,0 +1,4 @@ +arecibo::spartan::batched_ppsnark - Rust
Expand description

batched pp snark

+

Structs

  • A succinct proof of knowledge of a witness to a relaxed R1CS instance +The proof is produced using Spartan’s combination of the sum-check and +the commitment to a vector viewed as a polynomial commitment
  • A type that represents the prover’s key
  • A type that represents the verifier’s key
\ No newline at end of file diff --git a/docs/arecibo/spartan/batched_ppsnark/sidebar-items.js b/docs/arecibo/spartan/batched_ppsnark/sidebar-items.js new file mode 100644 index 000000000..0f61de1bb --- /dev/null +++ b/docs/arecibo/spartan/batched_ppsnark/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["BatchedRelaxedR1CSSNARK","ProverKey","VerifierKey"]}; \ No newline at end of file diff --git a/docs/arecibo/spartan/batched_ppsnark/struct.BatchedRelaxedR1CSSNARK.html b/docs/arecibo/spartan/batched_ppsnark/struct.BatchedRelaxedR1CSSNARK.html new file mode 100644 index 000000000..59b4744d7 --- /dev/null +++ b/docs/arecibo/spartan/batched_ppsnark/struct.BatchedRelaxedR1CSSNARK.html @@ -0,0 +1,133 @@ +BatchedRelaxedR1CSSNARK in arecibo::spartan::batched_ppsnark - Rust
pub struct BatchedRelaxedR1CSSNARK<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A succinct proof of knowledge of a witness to a relaxed R1CS instance +The proof is produced using Spartan’s combination of the sum-check and +the commitment to a vector viewed as a polynomial commitment

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> BatchedRelaxedR1CSSNARKTrait<E> for BatchedRelaxedR1CSSNARK<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

§

type ProverKey = ProverKey<E, EE>

A type that represents the prover’s key
§

type VerifierKey = VerifierKey<E, EE>

A type that represents the verifier’s key
source§

fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize>

This associated function (not a method) provides a hint that offers +a minimum sizing cue for the commitment key used by this SNARK +implementation. The commitment key passed in setup should then +be at least as large as this hint.
source§

fn setup( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + S: Vec<&R1CSShape<E>> +) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>

Produces the keys for the prover and the verifier
source§

fn prove( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + pk: &Self::ProverKey, + S: Vec<&R1CSShape<E>>, + U: &[RelaxedR1CSInstance<E>], + W: &[RelaxedR1CSWitness<E>] +) -> Result<Self, NovaError>

Produces a new SNARK for a batch of relaxed R1CS
source§

fn verify( + &self, + vk: &Self::VerifierKey, + U: &[RelaxedR1CSInstance<E>] +) -> Result<(), NovaError>

Verifies a SNARK for a batch of relaxed R1CS
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for BatchedRelaxedR1CSSNARK<E, EE>where + E::Scalar: Clone, + EE::EvaluationArgument: Clone,

source§

fn clone(&self) -> BatchedRelaxedR1CSSNARK<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine, EE: Debug + EvaluationEngineTrait<E>> Debug for BatchedRelaxedR1CSSNARK<E, EE>where + E::Scalar: Debug, + EE::EvaluationArgument: Debug,

source§

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

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

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for BatchedRelaxedR1CSSNARK<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for BatchedRelaxedR1CSSNARK<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/batched_ppsnark/struct.ProverKey.html b/docs/arecibo/spartan/batched_ppsnark/struct.ProverKey.html new file mode 100644 index 000000000..f346dcbd6 --- /dev/null +++ b/docs/arecibo/spartan/batched_ppsnark/struct.ProverKey.html @@ -0,0 +1,116 @@ +ProverKey in arecibo::spartan::batched_ppsnark - Rust
pub struct ProverKey<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A type that represents the prover’s key

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for ProverKey<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for ProverKey<E, EE>where + EE::ProverKey: Clone, + E::Scalar: Clone,

source§

fn clone(&self) -> ProverKey<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for ProverKey<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for ProverKey<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for ProverKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe, + <EE as EvaluationEngineTrait<E>>::ProverKey: RefUnwindSafe, + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E, EE> Send for ProverKey<E, EE>

§

impl<E, EE> Sync for ProverKey<E, EE>

§

impl<E, EE> Unpin for ProverKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin, + <EE as EvaluationEngineTrait<E>>::ProverKey: Unpin, + <E as Engine>::Scalar: Unpin,

§

impl<E, EE> UnwindSafe for ProverKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe, + <EE as EvaluationEngineTrait<E>>::ProverKey: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/batched_ppsnark/struct.VerifierKey.html b/docs/arecibo/spartan/batched_ppsnark/struct.VerifierKey.html new file mode 100644 index 000000000..b36355dee --- /dev/null +++ b/docs/arecibo/spartan/batched_ppsnark/struct.VerifierKey.html @@ -0,0 +1,117 @@ +VerifierKey in arecibo::spartan::batched_ppsnark - Rust
pub struct VerifierKey<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A type that represents the verifier’s key

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for VerifierKey<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for VerifierKey<E, EE>where + EE::VerifierKey: Clone, + E::Scalar: Clone,

source§

fn clone(&self) -> VerifierKey<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for VerifierKey<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for VerifierKey<E, EE>

source§

fn digest(&self) -> E::Scalar

Returns the digest of the verifier’s key

+
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for VerifierKey<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for VerifierKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe, + <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe, + <EE as EvaluationEngineTrait<E>>::VerifierKey: RefUnwindSafe,

§

impl<E, EE> Send for VerifierKey<E, EE>

§

impl<E, EE> Sync for VerifierKey<E, EE>

§

impl<E, EE> Unpin for VerifierKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin, + <E as Engine>::Scalar: Unpin, + <EE as EvaluationEngineTrait<E>>::VerifierKey: Unpin,

§

impl<E, EE> UnwindSafe for VerifierKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe, + <EE as EvaluationEngineTrait<E>>::VerifierKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/index.html b/docs/arecibo/spartan/index.html new file mode 100644 index 000000000..1404194e0 --- /dev/null +++ b/docs/arecibo/spartan/index.html @@ -0,0 +1,18 @@ +arecibo::spartan - Rust

Module arecibo::spartan

source ·
Expand description

This module implements RelaxedR1CSSNARKTrait using Spartan that is generic +over the polynomial commitment and evaluation argument (i.e., a PCS) +We provide two implementations, one in snark.rs (which does not use any preprocessing) +and another in ppsnark.rs (which uses preprocessing to keep the verifier’s state small if the PCS provides a succinct verifier) +We also provide direct.rs that allows proving a step circuit directly with either of the two SNARKs.

+

In polynomial.rs we also provide foundational types and functions for manipulating multilinear polynomials.

+

Modules

  • This module implements BatchedRelaxedR1CSSNARKTrait using Spartan that is generic over the polynomial commitment +and evaluation argument (i.e., a PCS) This version of Spartan does not use preprocessing so the verifier keeps the +entire description of R1CS matrices. This is essentially optimal for the verifier when using an IPA-based polynomial +commitment scheme. This batched implementation batches the outer and inner sumchecks of the Spartan SNARK.
  • batched pp snark
  • This module contains the definitions of polynomial types used in the Spartan SNARK.
  • This module implements RelaxedR1CSSNARK traits using a spark-based approach to prove evaluations of +sparse multilinear polynomials involved in Spartan’s sum-check protocol, thereby providing a preprocessing SNARK +The verifier in this preprocessing SNARK maintains a commitment to R1CS matrices. This is beneficial when using a +polynomial commitment scheme in which the verifier’s costs is succinct. +This code includes experimental optimizations to reduce runtimes and proof sizes.
  • This module implements RelaxedR1CSSNARKTrait using Spartan that is generic +over the polynomial commitment and evaluation argument (i.e., a PCS) +This version of Spartan does not use preprocessing so the verifier keeps the entire +description of R1CS matrices. This is essentially optimal for the verifier when using +an IPA-based polynomial commitment scheme.
\ No newline at end of file diff --git a/docs/arecibo/spartan/polys/index.html b/docs/arecibo/spartan/polys/index.html new file mode 100644 index 000000000..940074ebd --- /dev/null +++ b/docs/arecibo/spartan/polys/index.html @@ -0,0 +1,2 @@ +arecibo::spartan::polys - Rust

Module arecibo::spartan::polys

source ·
Expand description

This module contains the definitions of polynomial types used in the Spartan SNARK.

+

Modules

\ No newline at end of file diff --git a/docs/arecibo/spartan/polys/multilinear/index.html b/docs/arecibo/spartan/polys/multilinear/index.html new file mode 100644 index 000000000..4da80a993 --- /dev/null +++ b/docs/arecibo/spartan/polys/multilinear/index.html @@ -0,0 +1,7 @@ +arecibo::spartan::polys::multilinear - Rust
Expand description

Main components:

+
    +
  • MultilinearPolynomial: Dense representation of multilinear polynomials, represented by evaluations over all possible binary inputs.
  • +
  • SparsePolynomial: Efficient representation of sparse multilinear polynomials, storing only non-zero evaluations.
  • +
+

Structs

  • A multilinear extension of a polynomial $Z(\cdot)$, denote it as $\tilde{Z}(x_1, …, x_m)$ +where the degree of each variable is at most one.
\ No newline at end of file diff --git a/docs/arecibo/spartan/polys/multilinear/sidebar-items.js b/docs/arecibo/spartan/polys/multilinear/sidebar-items.js new file mode 100644 index 000000000..1d4155e79 --- /dev/null +++ b/docs/arecibo/spartan/polys/multilinear/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["MultilinearPolynomial"]}; \ No newline at end of file diff --git a/docs/arecibo/spartan/polys/multilinear/struct.MultilinearPolynomial.html b/docs/arecibo/spartan/polys/multilinear/struct.MultilinearPolynomial.html new file mode 100644 index 000000000..18ac95b72 --- /dev/null +++ b/docs/arecibo/spartan/polys/multilinear/struct.MultilinearPolynomial.html @@ -0,0 +1,137 @@ +MultilinearPolynomial in arecibo::spartan::polys::multilinear - Rust
pub struct MultilinearPolynomial<Scalar> { /* private fields */ }
Expand description

A multilinear extension of a polynomial $Z(\cdot)$, denote it as $\tilde{Z}(x_1, …, x_m)$ +where the degree of each variable is at most one.

+

This is the dense representation of a multilinear poynomial. +Let it be $\mathbb{G}(\cdot): \mathbb{F}^m \rightarrow \mathbb{F}$, it can be represented uniquely by the list of +evaluations of $\mathbb{G}(\cdot)$ over the Boolean hypercube ${0, 1}^m$.

+

For example, a 3 variables multilinear polynomial can be represented by evaluation +at points $[0, 2^3-1]$.

+

The implementation follows +$$ +\tilde{Z}(x_1, …, x_m) = \sum_{e\in {0,1}^m}Z(e) \cdot \prod_{i=1}^m(x_i \cdot e_i + (1-x_i) \cdot (1-e_i)) +$$

+

Vector $Z$ indicates $Z(e)$ where $e$ ranges from $0$ to $2^m-1$.

+

Implementations§

source§

impl<Scalar: PrimeField> MultilinearPolynomial<Scalar>

source

pub fn new(Z: Vec<Scalar>) -> Self

Creates a new MultilinearPolynomial from the given evaluations.

+
Panics
+

The number of evaluations must be a power of two.

+
source

pub fn evaluations(&self) -> &[Scalar]

evaluations of the polynomial in all the 2^num_vars Boolean inputs

+
source

pub const fn get_num_vars(&self) -> usize

Returns the number of variables in the multilinear polynomial

+
source

pub fn len(&self) -> usize

Returns the total number of evaluations.

+
source

pub fn is_empty(&self) -> bool

Returns true if no evaluations.

+
source

pub fn random<R: RngCore + CryptoRng>(num_vars: usize, rng: &mut R) -> Self

Returns a random polynomial

+
source

pub fn bind_poly_var_top(&mut self, r: &Scalar)

Binds the polynomial’s top variable using the given scalar.

+

This operation modifies the polynomial in-place.

+
source

pub fn evaluate(&self, r: &[Scalar]) -> Scalar

Evaluates the polynomial at the given point. +Returns Z(r) in O(n) time.

+

The point must have a value for each variable.

+
source

pub fn evaluate_with(Z: &[Scalar], r: &[Scalar]) -> Scalar

Evaluates the polynomial with the given evaluations and point.

+

Trait Implementations§

source§

impl<Scalar: PrimeField> Add<MultilinearPolynomial<Scalar>> for MultilinearPolynomial<Scalar>

Adds another multilinear polynomial to self. +Assumes the two polynomials have the same number of variables.

+
§

type Output = Result<MultilinearPolynomial<Scalar>, &'static str>

The resulting type after applying the + operator.
source§

fn add(self, other: Self) -> Self::Output

Performs the + operation. Read more
source§

impl<Scalar: Clone> Clone for MultilinearPolynomial<Scalar>

source§

fn clone(&self) -> MultilinearPolynomial<Scalar>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<Scalar: Debug> Debug for MultilinearPolynomial<Scalar>

source§

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

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

impl<'de, Scalar> Deserialize<'de> for MultilinearPolynomial<Scalar>where + Scalar: Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<Scalar: PrimeField> Index<usize> for MultilinearPolynomial<Scalar>

§

type Output = Scalar

The returned type after indexing.
source§

fn index(&self, _index: usize) -> &Scalar

Performs the indexing (container[index]) operation. Read more
source§

impl<Scalar: PartialEq> PartialEq<MultilinearPolynomial<Scalar>> for MultilinearPolynomial<Scalar>

source§

fn eq(&self, other: &MultilinearPolynomial<Scalar>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<Scalar> Serialize for MultilinearPolynomial<Scalar>where + Scalar: Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<Scalar: Eq> Eq for MultilinearPolynomial<Scalar>

source§

impl<Scalar> StructuralEq for MultilinearPolynomial<Scalar>

source§

impl<Scalar> StructuralPartialEq for MultilinearPolynomial<Scalar>

Auto Trait Implementations§

§

impl<Scalar> RefUnwindSafe for MultilinearPolynomial<Scalar>where + Scalar: RefUnwindSafe,

§

impl<Scalar> Send for MultilinearPolynomial<Scalar>where + Scalar: Send,

§

impl<Scalar> Sync for MultilinearPolynomial<Scalar>where + Scalar: Sync,

§

impl<Scalar> Unpin for MultilinearPolynomial<Scalar>where + Scalar: Unpin,

§

impl<Scalar> UnwindSafe for MultilinearPolynomial<Scalar>where + Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/polys/sidebar-items.js b/docs/arecibo/spartan/polys/sidebar-items.js new file mode 100644 index 000000000..b7e0e497d --- /dev/null +++ b/docs/arecibo/spartan/polys/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["multilinear"]}; \ No newline at end of file diff --git a/docs/arecibo/spartan/ppsnark/index.html b/docs/arecibo/spartan/ppsnark/index.html new file mode 100644 index 000000000..d594c15a1 --- /dev/null +++ b/docs/arecibo/spartan/ppsnark/index.html @@ -0,0 +1,8 @@ +arecibo::spartan::ppsnark - Rust

Module arecibo::spartan::ppsnark

source ·
Expand description

This module implements RelaxedR1CSSNARK traits using a spark-based approach to prove evaluations of +sparse multilinear polynomials involved in Spartan’s sum-check protocol, thereby providing a preprocessing SNARK +The verifier in this preprocessing SNARK maintains a commitment to R1CS matrices. This is beneficial when using a +polynomial commitment scheme in which the verifier’s costs is succinct. +This code includes experimental optimizations to reduce runtimes and proof sizes.

+

Structs

  • A type that represents the prover’s key
  • A type that holds a commitment to a sparse polynomial
  • A type that holds R1CSShape in a form amenable to memory checking
  • A succinct proof of knowledge of a witness to a relaxed R1CS instance +The proof is produced using Spartan’s combination of the sum-check and +the commitment to a vector viewed as a polynomial commitment
  • A type that represents the verifier’s key
\ No newline at end of file diff --git a/docs/arecibo/spartan/ppsnark/sidebar-items.js b/docs/arecibo/spartan/ppsnark/sidebar-items.js new file mode 100644 index 000000000..df236dfd5 --- /dev/null +++ b/docs/arecibo/spartan/ppsnark/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["ProverKey","R1CSShapeSparkCommitment","R1CSShapeSparkRepr","RelaxedR1CSSNARK","VerifierKey"]}; \ No newline at end of file diff --git a/docs/arecibo/spartan/ppsnark/struct.ProverKey.html b/docs/arecibo/spartan/ppsnark/struct.ProverKey.html new file mode 100644 index 000000000..a2d9a73f1 --- /dev/null +++ b/docs/arecibo/spartan/ppsnark/struct.ProverKey.html @@ -0,0 +1,116 @@ +ProverKey in arecibo::spartan::ppsnark - Rust
pub struct ProverKey<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A type that represents the prover’s key

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for ProverKey<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for ProverKey<E, EE>where + EE::ProverKey: Clone, + E::Scalar: Clone,

source§

fn clone(&self) -> ProverKey<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for ProverKey<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for ProverKey<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for ProverKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe, + <EE as EvaluationEngineTrait<E>>::ProverKey: RefUnwindSafe, + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E, EE> Send for ProverKey<E, EE>

§

impl<E, EE> Sync for ProverKey<E, EE>

§

impl<E, EE> Unpin for ProverKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin, + <EE as EvaluationEngineTrait<E>>::ProverKey: Unpin, + <E as Engine>::Scalar: Unpin,

§

impl<E, EE> UnwindSafe for ProverKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe, + <EE as EvaluationEngineTrait<E>>::ProverKey: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/ppsnark/struct.R1CSShapeSparkCommitment.html b/docs/arecibo/spartan/ppsnark/struct.R1CSShapeSparkCommitment.html new file mode 100644 index 000000000..520de0857 --- /dev/null +++ b/docs/arecibo/spartan/ppsnark/struct.R1CSShapeSparkCommitment.html @@ -0,0 +1,108 @@ +R1CSShapeSparkCommitment in arecibo::spartan::ppsnark - Rust
pub struct R1CSShapeSparkCommitment<E: Engine> { /* private fields */ }
Expand description

A type that holds a commitment to a sparse polynomial

+

Trait Implementations§

source§

impl<E: Engine> Abomonation for R1CSShapeSparkCommitment<E>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine> Clone for R1CSShapeSparkCommitment<E>

source§

fn clone(&self) -> R1CSShapeSparkCommitment<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine> Deserialize<'de> for R1CSShapeSparkCommitment<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine> Serialize for R1CSShapeSparkCommitment<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Engine> TranscriptReprTrait<<E as Engine>::GE> for R1CSShapeSparkCommitment<E>

source§

fn to_transcript_bytes(&self) -> Vec<u8>

returns a byte representation of self to be added to the transcript

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/ppsnark/struct.R1CSShapeSparkRepr.html b/docs/arecibo/spartan/ppsnark/struct.R1CSShapeSparkRepr.html new file mode 100644 index 000000000..76b0c734d --- /dev/null +++ b/docs/arecibo/spartan/ppsnark/struct.R1CSShapeSparkRepr.html @@ -0,0 +1,110 @@ +R1CSShapeSparkRepr in arecibo::spartan::ppsnark - Rust
pub struct R1CSShapeSparkRepr<E: Engine> { /* private fields */ }
Expand description

A type that holds R1CSShape in a form amenable to memory checking

+

Implementations§

source§

impl<E: Engine> R1CSShapeSparkRepr<E>

source

pub fn new(S: &R1CSShape<E>) -> Self

represents R1CSShape in a Spark-friendly format amenable to memory checking

+

Trait Implementations§

source§

impl<E: Engine> Abomonation for R1CSShapeSparkRepr<E>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine> Clone for R1CSShapeSparkRepr<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> R1CSShapeSparkRepr<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine> Deserialize<'de> for R1CSShapeSparkRepr<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine> Serialize for R1CSShapeSparkRepr<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for R1CSShapeSparkRepr<E>where + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E> Send for R1CSShapeSparkRepr<E>

§

impl<E> Sync for R1CSShapeSparkRepr<E>

§

impl<E> Unpin for R1CSShapeSparkRepr<E>where + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for R1CSShapeSparkRepr<E>where + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/ppsnark/struct.RelaxedR1CSSNARK.html b/docs/arecibo/spartan/ppsnark/struct.RelaxedR1CSSNARK.html new file mode 100644 index 000000000..00125827d --- /dev/null +++ b/docs/arecibo/spartan/ppsnark/struct.RelaxedR1CSSNARK.html @@ -0,0 +1,135 @@ +RelaxedR1CSSNARK in arecibo::spartan::ppsnark - Rust
pub struct RelaxedR1CSSNARK<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A succinct proof of knowledge of a witness to a relaxed R1CS instance +The proof is produced using Spartan’s combination of the sum-check and +the commitment to a vector viewed as a polynomial commitment

+

Trait Implementations§

source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for RelaxedR1CSSNARK<E, EE>where + E::Scalar: Clone, + EE::EvaluationArgument: Clone,

source§

fn clone(&self) -> RelaxedR1CSSNARK<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine, EE: Debug + EvaluationEngineTrait<E>> Debug for RelaxedR1CSSNARK<E, EE>where + E::Scalar: Debug, + EE::EvaluationArgument: Debug,

source§

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

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

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for RelaxedR1CSSNARK<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> RelaxedR1CSSNARKTrait<E> for RelaxedR1CSSNARK<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

fn prove( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + pk: &Self::ProverKey, + S: &R1CSShape<E>, + U: &RelaxedR1CSInstance<E>, + W: &RelaxedR1CSWitness<E> +) -> Result<Self, NovaError>

produces a succinct proof of satisfiability of a RelaxedR1CS instance

+
source§

fn verify( + &self, + vk: &Self::VerifierKey, + U: &RelaxedR1CSInstance<E> +) -> Result<(), NovaError>

verifies a proof of satisfiability of a RelaxedR1CS instance

+
§

type ProverKey = ProverKey<E, EE>

A type that represents the prover’s key
§

type VerifierKey = VerifierKey<E, EE>

A type that represents the verifier’s key
source§

fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize>

This associated function (not a method) provides a hint that offers +a minimum sizing cue for the commitment key used by this SNARK +implementation. The commitment key passed in setup should then +be at least as large as this hint.
source§

fn setup( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + S: &R1CSShape<E> +) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>

Produces the keys for the prover and the verifier
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for RelaxedR1CSSNARK<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/ppsnark/struct.VerifierKey.html b/docs/arecibo/spartan/ppsnark/struct.VerifierKey.html new file mode 100644 index 000000000..f1af50f23 --- /dev/null +++ b/docs/arecibo/spartan/ppsnark/struct.VerifierKey.html @@ -0,0 +1,117 @@ +VerifierKey in arecibo::spartan::ppsnark - Rust
pub struct VerifierKey<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A type that represents the verifier’s key

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for VerifierKey<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for VerifierKey<E, EE>where + EE::VerifierKey: Clone, + E::Scalar: Clone,

source§

fn clone(&self) -> VerifierKey<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for VerifierKey<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for VerifierKey<E, EE>

source§

fn digest(&self) -> E::Scalar

Returns the digest of the verifier’s key

+
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for VerifierKey<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for VerifierKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe, + <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe, + <EE as EvaluationEngineTrait<E>>::VerifierKey: RefUnwindSafe,

§

impl<E, EE> Send for VerifierKey<E, EE>

§

impl<E, EE> Sync for VerifierKey<E, EE>

§

impl<E, EE> Unpin for VerifierKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin, + <E as Engine>::Scalar: Unpin, + <EE as EvaluationEngineTrait<E>>::VerifierKey: Unpin,

§

impl<E, EE> UnwindSafe for VerifierKey<E, EE>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe, + <EE as EvaluationEngineTrait<E>>::VerifierKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/sidebar-items.js b/docs/arecibo/spartan/sidebar-items.js new file mode 100644 index 000000000..231dd8aa5 --- /dev/null +++ b/docs/arecibo/spartan/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["batched","batched_ppsnark","polys","ppsnark","snark"]}; \ No newline at end of file diff --git a/docs/arecibo/spartan/snark/index.html b/docs/arecibo/spartan/snark/index.html new file mode 100644 index 000000000..29157a2bd --- /dev/null +++ b/docs/arecibo/spartan/snark/index.html @@ -0,0 +1,8 @@ +arecibo::spartan::snark - Rust

Module arecibo::spartan::snark

source ·
Expand description

This module implements RelaxedR1CSSNARKTrait using Spartan that is generic +over the polynomial commitment and evaluation argument (i.e., a PCS) +This version of Spartan does not use preprocessing so the verifier keeps the entire +description of R1CS matrices. This is essentially optimal for the verifier when using +an IPA-based polynomial commitment scheme.

+

Structs

  • A type that represents the prover’s key
  • A succinct proof of knowledge of a witness to a relaxed R1CS instance +The proof is produced using Spartan’s combination of the sum-check and +the commitment to a vector viewed as a polynomial commitment
  • A type that represents the verifier’s key
\ No newline at end of file diff --git a/docs/arecibo/spartan/snark/sidebar-items.js b/docs/arecibo/spartan/snark/sidebar-items.js new file mode 100644 index 000000000..c501def86 --- /dev/null +++ b/docs/arecibo/spartan/snark/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["ProverKey","RelaxedR1CSSNARK","VerifierKey"]}; \ No newline at end of file diff --git a/docs/arecibo/spartan/snark/struct.ProverKey.html b/docs/arecibo/spartan/snark/struct.ProverKey.html new file mode 100644 index 000000000..25f85e3b6 --- /dev/null +++ b/docs/arecibo/spartan/snark/struct.ProverKey.html @@ -0,0 +1,113 @@ +ProverKey in arecibo::spartan::snark - Rust
pub struct ProverKey<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A type that represents the prover’s key

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for ProverKey<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for ProverKey<E, EE>where + EE::ProverKey: Clone, + E::Scalar: Clone,

source§

fn clone(&self) -> ProverKey<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for ProverKey<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for ProverKey<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for ProverKey<E, EE>where + <EE as EvaluationEngineTrait<E>>::ProverKey: RefUnwindSafe, + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E, EE> Send for ProverKey<E, EE>

§

impl<E, EE> Sync for ProverKey<E, EE>

§

impl<E, EE> Unpin for ProverKey<E, EE>where + <EE as EvaluationEngineTrait<E>>::ProverKey: Unpin, + <E as Engine>::Scalar: Unpin,

§

impl<E, EE> UnwindSafe for ProverKey<E, EE>where + <EE as EvaluationEngineTrait<E>>::ProverKey: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/snark/struct.RelaxedR1CSSNARK.html b/docs/arecibo/spartan/snark/struct.RelaxedR1CSSNARK.html new file mode 100644 index 000000000..90cad1c10 --- /dev/null +++ b/docs/arecibo/spartan/snark/struct.RelaxedR1CSSNARK.html @@ -0,0 +1,132 @@ +RelaxedR1CSSNARK in arecibo::spartan::snark - Rust
pub struct RelaxedR1CSSNARK<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A succinct proof of knowledge of a witness to a relaxed R1CS instance +The proof is produced using Spartan’s combination of the sum-check and +the commitment to a vector viewed as a polynomial commitment

+

Trait Implementations§

source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for RelaxedR1CSSNARK<E, EE>where + E::Scalar: Clone, + EE::EvaluationArgument: Clone,

source§

fn clone(&self) -> RelaxedR1CSSNARK<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine, EE: Debug + EvaluationEngineTrait<E>> Debug for RelaxedR1CSSNARK<E, EE>where + E::Scalar: Debug, + EE::EvaluationArgument: Debug,

source§

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

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

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for RelaxedR1CSSNARK<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> RelaxedR1CSSNARKTrait<E> for RelaxedR1CSSNARK<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

fn prove( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + pk: &Self::ProverKey, + S: &R1CSShape<E>, + U: &RelaxedR1CSInstance<E>, + W: &RelaxedR1CSWitness<E> +) -> Result<Self, NovaError>

produces a succinct proof of satisfiability of a RelaxedR1CS instance

+
source§

fn verify( + &self, + vk: &Self::VerifierKey, + U: &RelaxedR1CSInstance<E> +) -> Result<(), NovaError>

verifies a proof of satisfiability of a RelaxedR1CS instance

+
§

type ProverKey = ProverKey<E, EE>

A type that represents the prover’s key
§

type VerifierKey = VerifierKey<E, EE>

A type that represents the verifier’s key
source§

fn setup( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + S: &R1CSShape<E> +) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>

Produces the keys for the prover and the verifier
source§

fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize>

This associated function (not a method) provides a hint that offers +a minimum sizing cue for the commitment key used by this SNARK +implementation. The commitment key passed in setup should then +be at least as large as this hint.
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for RelaxedR1CSSNARK<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for RelaxedR1CSSNARK<E, EE>where + <EE as EvaluationEngineTrait<E>>::EvaluationArgument: RefUnwindSafe, + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E, EE> Send for RelaxedR1CSSNARK<E, EE>

§

impl<E, EE> Sync for RelaxedR1CSSNARK<E, EE>

§

impl<E, EE> Unpin for RelaxedR1CSSNARK<E, EE>where + <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Unpin, + <E as Engine>::Scalar: Unpin,

§

impl<E, EE> UnwindSafe for RelaxedR1CSSNARK<E, EE>where + <EE as EvaluationEngineTrait<E>>::EvaluationArgument: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/spartan/snark/struct.VerifierKey.html b/docs/arecibo/spartan/snark/struct.VerifierKey.html new file mode 100644 index 000000000..acfb8fe01 --- /dev/null +++ b/docs/arecibo/spartan/snark/struct.VerifierKey.html @@ -0,0 +1,114 @@ +VerifierKey in arecibo::spartan::snark - Rust
pub struct VerifierKey<E: Engine, EE: EvaluationEngineTrait<E>> { /* private fields */ }
Expand description

A type that represents the verifier’s key

+

Trait Implementations§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for VerifierKey<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for VerifierKey<E, EE>where + EE::VerifierKey: Clone, + E::Scalar: Clone,

source§

fn clone(&self) -> VerifierKey<E, EE>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for VerifierKey<E, EE>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for VerifierKey<E, EE>

source§

fn digest(&self) -> E::Scalar

Returns the digest of the verifier’s key.

+
source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for VerifierKey<E, EE>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E, EE> RefUnwindSafe for VerifierKey<E, EE>where + <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe, + <EE as EvaluationEngineTrait<E>>::VerifierKey: RefUnwindSafe,

§

impl<E, EE> Send for VerifierKey<E, EE>

§

impl<E, EE> Sync for VerifierKey<E, EE>

§

impl<E, EE> Unpin for VerifierKey<E, EE>where + <E as Engine>::Scalar: Unpin, + <EE as EvaluationEngineTrait<E>>::VerifierKey: Unpin,

§

impl<E, EE> UnwindSafe for VerifierKey<E, EE>where + <E as Engine>::Scalar: UnwindSafe, + <EE as EvaluationEngineTrait<E>>::VerifierKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/struct.CompressedSNARK.html b/docs/arecibo/struct.CompressedSNARK.html new file mode 100644 index 000000000..61d7ee176 --- /dev/null +++ b/docs/arecibo/struct.CompressedSNARK.html @@ -0,0 +1,175 @@ +CompressedSNARK in arecibo - Rust
pub struct CompressedSNARK<E1, E2, C1, C2, S1, S2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: RelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,{ /* private fields */ }
Expand description

A SNARK that proves the knowledge of a valid RecursiveSNARK

+

Implementations§

source§

impl<E1, E2, C1, C2, S1, S2> CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source

pub fn setup( + pp: &PublicParams<E1, E2, C1, C2> +) -> Result<(ProverKey<E1, E2, C1, C2, S1, S2>, VerifierKey<E1, E2, C1, C2, S1, S2>), NovaError>

Creates prover and verifier keys for CompressedSNARK

+
source

pub fn prove( + pp: &PublicParams<E1, E2, C1, C2>, + pk: &ProverKey<E1, E2, C1, C2, S1, S2>, + recursive_snark: &RecursiveSNARK<E1, E2, C1, C2> +) -> Result<Self, NovaError>

Create a new CompressedSNARK

+
source

pub fn verify( + &self, + vk: &VerifierKey<E1, E2, C1, C2, S1, S2>, + num_steps: usize, + z0_primary: &[E1::Scalar], + z0_secondary: &[E2::Scalar] +) -> Result<(Vec<E1::Scalar>, Vec<E2::Scalar>), NovaError>

Verify the correctness of the CompressedSNARK

+

Trait Implementations§

source§

impl<E1, E2, C1, C2, S1, S2> Clone for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + S1: RelaxedR1CSSNARKTrait<E1> + Clone, + S2: RelaxedR1CSSNARKTrait<E2> + Clone, + E1::Scalar: Clone, + E2::Scalar: Clone,

source§

fn clone(&self) -> CompressedSNARK<E1, E2, C1, C2, S1, S2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2, S1, S2> Serialize for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + S1: RefUnwindSafe, + S2: RefUnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: RefUnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: RefUnwindSafe, + <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: RefUnwindSafe, + <E1 as Engine>::Scalar: RefUnwindSafe, + <E2 as Engine>::Scalar: RefUnwindSafe,

§

impl<E1, E2, C1, C2, S1, S2> Send for CompressedSNARK<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Sync for CompressedSNARK<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Unpin for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + C1: Unpin, + C2: Unpin, + S1: Unpin, + S2: Unpin, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Unpin, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Unpin, + <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: Unpin, + <E1 as Engine>::Scalar: Unpin, + <E2 as Engine>::Scalar: Unpin,

§

impl<E1, E2, C1, C2, S1, S2> UnwindSafe for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + C1: UnwindSafe, + C2: UnwindSafe, + S1: UnwindSafe, + S2: UnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: UnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: UnwindSafe, + <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: UnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/struct.ProverKey.html b/docs/arecibo/struct.ProverKey.html new file mode 100644 index 000000000..c9eeae8c8 --- /dev/null +++ b/docs/arecibo/struct.ProverKey.html @@ -0,0 +1,156 @@ +ProverKey in arecibo - Rust

Struct arecibo::ProverKey

source ·
pub struct ProverKey<E1, E2, C1, C2, S1, S2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: RelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,{ /* private fields */ }
Expand description

A type that holds the prover key for CompressedSNARK

+

Trait Implementations§

source§

impl<E1, E2, C1, C2, S1, S2> Abomonation for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E1, E2, C1, C2, S1, S2> Clone for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + S1: RelaxedR1CSSNARKTrait<E1> + Clone, + S2: RelaxedR1CSSNARKTrait<E2> + Clone, + S1::ProverKey: Clone, + S2::ProverKey: Clone,

source§

fn clone(&self) -> ProverKey<E1, E2, C1, C2, S1, S2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E1, E2, C1, C2, S1, S2> Debug for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Debug, + E2: Engine<Base = <E1 as Engine>::Scalar> + Debug, + C1: StepCircuit<E1::Scalar> + Debug, + C2: StepCircuit<E2::Scalar> + Debug, + S1: RelaxedR1CSSNARKTrait<E1> + Debug, + S2: RelaxedR1CSSNARKTrait<E2> + Debug, + S1::ProverKey: Debug, + S2::ProverKey: Debug,

source§

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

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

impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2, S1, S2> Serialize for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for ProverKey<E1, E2, C1, C2, S1, S2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + <S1 as RelaxedR1CSSNARKTrait<E1>>::ProverKey: RefUnwindSafe, + <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: RefUnwindSafe,

§

impl<E1, E2, C1, C2, S1, S2> Send for ProverKey<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Sync for ProverKey<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Unpin for ProverKey<E1, E2, C1, C2, S1, S2>where + C1: Unpin, + C2: Unpin, + <S1 as RelaxedR1CSSNARKTrait<E1>>::ProverKey: Unpin, + <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: Unpin,

§

impl<E1, E2, C1, C2, S1, S2> UnwindSafe for ProverKey<E1, E2, C1, C2, S1, S2>where + C1: UnwindSafe, + C2: UnwindSafe, + <S1 as RelaxedR1CSSNARKTrait<E1>>::ProverKey: UnwindSafe, + <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/struct.PublicParams.html b/docs/arecibo/struct.PublicParams.html new file mode 100644 index 000000000..ed09ee01f --- /dev/null +++ b/docs/arecibo/struct.PublicParams.html @@ -0,0 +1,211 @@ +PublicParams in arecibo - Rust

Struct arecibo::PublicParams

source ·
pub struct PublicParams<E1, E2, C1, C2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,{ /* private fields */ }
Expand description

A type that holds public parameters of Nova

+

Implementations§

source§

impl<E1, E2, C1, C2> PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source

pub fn setup( + c_primary: &C1, + c_secondary: &C2, + ck_hint1: &CommitmentKeyHint<E1>, + ck_hint2: &CommitmentKeyHint<E2> +) -> Self

Set up builder to create PublicParams for a pair of circuits C1 and C2.

+
Note
+

Public parameters set up a number of bases for the homomorphic commitment scheme of Nova.

+

Some final compressing SNARKs, like variants of Spartan, use computation commitments that require +larger sizes for these parameters. These SNARKs provide a hint for these values by +implementing RelaxedR1CSSNARKTrait::ck_floor(), which can be passed to this function.

+

If you’re not using such a SNARK, pass arecibo::traits::snark::default_ck_hint() instead.

+
Arguments
+
    +
  • c_primary: The primary circuit of type C1.
  • +
  • c_secondary: The secondary circuit of type C2.
  • +
  • ck_hint1: A CommitmentKeyHint for G1, which is a function that provides a hint +for the number of generators required in the commitment scheme for the primary circuit.
  • +
  • ck_hint2: A CommitmentKeyHint for G2, similar to ck_hint1, but for the secondary circuit.
  • +
+
Example
+
use arecibo::PublicParams;
+
+type E1 = PallasEngine;
+type E2 = VestaEngine;
+type EE<E> = EvaluationEngine<E>;
+type SPrime<E> = RelaxedR1CSSNARK<E, EE<E>>;
+
+let circuit1 = TrivialCircuit::<<E1 as Engine>::Scalar>::default();
+let circuit2 = TrivialCircuit::<<E2 as Engine>::Scalar>::default();
+// Only relevant for a SNARK using computation commitmnets, pass &(|_| 0)
+// or &*nova_snark::traits::snark::default_ck_hint() otherwise.
+let ck_hint1 = &*SPrime::<E1>::ck_floor();
+let ck_hint2 = &*SPrime::<E2>::ck_floor();
+
+let pp = PublicParams::setup(&circuit1, &circuit2, ck_hint1, ck_hint2);
+
source

pub fn digest(&self) -> E1::Scalar

Retrieve the digest of the public parameters.

+
source

pub const fn num_constraints(&self) -> (usize, usize)

Returns the number of constraints in the primary and secondary circuits

+
source

pub const fn num_variables(&self) -> (usize, usize)

Returns the number of variables in the primary and secondary circuits

+

Trait Implementations§

source§

impl<E1, E2, C1, C2> Abomonation for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + <E1::Scalar as PrimeField>::Repr: Abomonation, + <E2::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E1, E2, C1, C2> Clone for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + E1::Scalar: Clone,

source§

fn clone(&self) -> PublicParams<E1, E2, C1, C2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E1, E2, C1, C2> Deserialize<'de> for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2> PartialEq<PublicParams<E1, E2, C1, C2>> for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + PartialEq, + E2: Engine<Base = <E1 as Engine>::Scalar> + PartialEq, + C1: StepCircuit<E1::Scalar> + PartialEq, + C2: StepCircuit<E2::Scalar> + PartialEq, + E1::Scalar: PartialEq,

source§

fn eq(&self, other: &PublicParams<E1, E2, C1, C2>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E1, E2, C1, C2> Serialize for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E1, E2, C1, C2> StructuralPartialEq for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

Auto Trait Implementations§

§

impl<E1, E2, C1, C2> RefUnwindSafe for PublicParams<E1, E2, C1, C2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: RefUnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: RefUnwindSafe, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe + RefUnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe + RefUnwindSafe,

§

impl<E1, E2, C1, C2> Send for PublicParams<E1, E2, C1, C2>

§

impl<E1, E2, C1, C2> Sync for PublicParams<E1, E2, C1, C2>

§

impl<E1, E2, C1, C2> Unpin for PublicParams<E1, E2, C1, C2>where + C1: Unpin, + C2: Unpin, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: Unpin, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: Unpin, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Unpin, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Unpin, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: Unpin, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: Unpin, + <E1 as Engine>::Scalar: Unpin, + <E2 as Engine>::Scalar: Unpin,

§

impl<E1, E2, C1, C2> UnwindSafe for PublicParams<E1, E2, C1, C2>where + C1: UnwindSafe, + C2: UnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: UnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: UnwindSafe, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: UnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/struct.R1CSWithArity.html b/docs/arecibo/struct.R1CSWithArity.html new file mode 100644 index 000000000..bb6dc7cb4 --- /dev/null +++ b/docs/arecibo/struct.R1CSWithArity.html @@ -0,0 +1,112 @@ +R1CSWithArity in arecibo - Rust

Struct arecibo::R1CSWithArity

source ·
pub struct R1CSWithArity<E: Engine> { /* private fields */ }
Expand description

A type that holds parameters for the primary and secondary circuits of Nova and SuperNova

+

Implementations§

source§

impl<E: Engine> R1CSWithArity<E>

source

pub fn new(r1cs_shape: R1CSShape<E>, F_arity: usize) -> Self

Create a new R1CSWithArity

+
source

pub fn digest(&self) -> E::Scalar

Return the R1CSWithArity’ digest.

+

Trait Implementations§

source§

impl<E: Engine> Abomonation for R1CSWithArity<E>where + <E::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E: Clone + Engine> Clone for R1CSWithArity<E>

source§

fn clone(&self) -> R1CSWithArity<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E: Engine> Deserialize<'de> for R1CSWithArity<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<R1CSWithArity<E>> for R1CSWithArity<E>

source§

fn eq(&self, other: &R1CSWithArity<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for R1CSWithArity<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for R1CSWithArity<E>

source§

impl<E: Engine> StructuralEq for R1CSWithArity<E>

source§

impl<E: Engine> StructuralPartialEq for R1CSWithArity<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for R1CSWithArity<E>where + <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe,

§

impl<E> Send for R1CSWithArity<E>

§

impl<E> Sync for R1CSWithArity<E>

§

impl<E> Unpin for R1CSWithArity<E>where + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for R1CSWithArity<E>where + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/struct.RecursiveSNARK.html b/docs/arecibo/struct.RecursiveSNARK.html new file mode 100644 index 000000000..a2621fcb4 --- /dev/null +++ b/docs/arecibo/struct.RecursiveSNARK.html @@ -0,0 +1,170 @@ +RecursiveSNARK in arecibo - Rust

Struct arecibo::RecursiveSNARK

source ·
pub struct RecursiveSNARK<E1, E2, C1, C2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,{ /* private fields */ }
Expand description

A SNARK that proves the correct execution of an incremental computation

+

Implementations§

source§

impl<E1, E2, C1, C2> RecursiveSNARK<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source

pub fn new( + pp: &PublicParams<E1, E2, C1, C2>, + c_primary: &C1, + c_secondary: &C2, + z0_primary: &[E1::Scalar], + z0_secondary: &[E2::Scalar] +) -> Result<Self, NovaError>

Create new instance of recursive SNARK

+
source

pub fn prove_step( + &mut self, + pp: &PublicParams<E1, E2, C1, C2>, + c_primary: &C1, + c_secondary: &C2 +) -> Result<(), NovaError>

Create a new RecursiveSNARK (or updates the provided RecursiveSNARK) +by executing a step of the incremental computation

+
source

pub fn verify( + &self, + pp: &PublicParams<E1, E2, C1, C2>, + num_steps: usize, + z0_primary: &[E1::Scalar], + z0_secondary: &[E2::Scalar] +) -> Result<(Vec<E1::Scalar>, Vec<E2::Scalar>), NovaError>

Verify the correctness of the RecursiveSNARK

+
source

pub fn outputs(&self) -> (&[E1::Scalar], &[E2::Scalar])

Get the outputs after the last step of computation.

+
source

pub fn num_steps(&self) -> usize

The number of steps which have been executed thus far.

+

Trait Implementations§

source§

impl<E1, E2, C1, C2> Clone for RecursiveSNARK<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + E1::Scalar: Clone, + E2::Scalar: Clone,

source§

fn clone(&self) -> RecursiveSNARK<E1, E2, C1, C2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E1, E2, C1, C2> Debug for RecursiveSNARK<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Debug, + E2: Engine<Base = <E1 as Engine>::Scalar> + Debug, + C1: StepCircuit<E1::Scalar> + Debug, + C2: StepCircuit<E2::Scalar> + Debug, + E1::Scalar: Debug, + E2::Scalar: Debug,

source§

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

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

impl<'de, E1, E2, C1, C2> Deserialize<'de> for RecursiveSNARK<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2> Serialize for RecursiveSNARK<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2, C1, C2> RefUnwindSafe for RecursiveSNARK<E1, E2, C1, C2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: RefUnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: RefUnwindSafe, + <E1 as Engine>::Scalar: RefUnwindSafe, + <E2 as Engine>::Scalar: RefUnwindSafe,

§

impl<E1, E2, C1, C2> Send for RecursiveSNARK<E1, E2, C1, C2>

§

impl<E1, E2, C1, C2> Sync for RecursiveSNARK<E1, E2, C1, C2>

§

impl<E1, E2, C1, C2> Unpin for RecursiveSNARK<E1, E2, C1, C2>where + C1: Unpin, + C2: Unpin, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Unpin, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Unpin, + <E1 as Engine>::Scalar: Unpin, + <E2 as Engine>::Scalar: Unpin,

§

impl<E1, E2, C1, C2> UnwindSafe for RecursiveSNARK<E1, E2, C1, C2>where + C1: UnwindSafe, + C2: UnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: UnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: UnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/struct.ResourceBuffer.html b/docs/arecibo/struct.ResourceBuffer.html new file mode 100644 index 000000000..de9fee6dc --- /dev/null +++ b/docs/arecibo/struct.ResourceBuffer.html @@ -0,0 +1,110 @@ +ResourceBuffer in arecibo - Rust

Struct arecibo::ResourceBuffer

source ·
pub struct ResourceBuffer<E: Engine> { /* private fields */ }
Expand description

A resource buffer for RecursiveSNARK for storing scratch values that are computed by prove_step, +which allows the reuse of memory allocations and avoids unnecessary new allocations in the critical section.

+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for ResourceBuffer<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> ResourceBuffer<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Debug + Engine> Debug for ResourceBuffer<E>where + E::Scalar: Debug,

source§

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

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

impl<'de, E: Engine> Deserialize<'de> for ResourceBuffer<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: Engine> Serialize for ResourceBuffer<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for ResourceBuffer<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe, + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E> Send for ResourceBuffer<E>

§

impl<E> Sync for ResourceBuffer<E>

§

impl<E> Unpin for ResourceBuffer<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin, + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for ResourceBuffer<E>where + <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe, + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/struct.VerifierKey.html b/docs/arecibo/struct.VerifierKey.html new file mode 100644 index 000000000..0202ca7b6 --- /dev/null +++ b/docs/arecibo/struct.VerifierKey.html @@ -0,0 +1,159 @@ +VerifierKey in arecibo - Rust

Struct arecibo::VerifierKey

source ·
pub struct VerifierKey<E1, E2, C1, C2, S1, S2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: RelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,{ /* private fields */ }
Expand description

A type that holds the verifier key for CompressedSNARK

+

Trait Implementations§

source§

impl<E1, E2, C1, C2, S1, S2> Abomonation for VerifierKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>, + <E1::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E1, E2, C1, C2, S1, S2> Clone for VerifierKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + S1: RelaxedR1CSSNARKTrait<E1> + Clone, + S2: RelaxedR1CSSNARKTrait<E2> + Clone, + E1::Scalar: Clone, + S1::VerifierKey: Clone, + S2::VerifierKey: Clone,

source§

fn clone(&self) -> VerifierKey<E1, E2, C1, C2, S1, S2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for VerifierKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2, S1, S2> Serialize for VerifierKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: RelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for VerifierKey<E1, E2, C1, C2, S1, S2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <E1 as Engine>::Scalar: RefUnwindSafe, + <S1 as RelaxedR1CSSNARKTrait<E1>>::VerifierKey: RefUnwindSafe, + <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: RefUnwindSafe,

§

impl<E1, E2, C1, C2, S1, S2> Send for VerifierKey<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Sync for VerifierKey<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Unpin for VerifierKey<E1, E2, C1, C2, S1, S2>where + C1: Unpin, + C2: Unpin, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Unpin, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Unpin, + <E1 as Engine>::Scalar: Unpin, + <S1 as RelaxedR1CSSNARKTrait<E1>>::VerifierKey: Unpin, + <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: Unpin,

§

impl<E1, E2, C1, C2, S1, S2> UnwindSafe for VerifierKey<E1, E2, C1, C2, S1, S2>where + C1: UnwindSafe, + C2: UnwindSafe, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: UnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe, + <S1 as RelaxedR1CSSNARKTrait<E1>>::VerifierKey: UnwindSafe, + <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/supernova/circuit/struct.TrivialSecondaryCircuit.html b/docs/arecibo/supernova/circuit/struct.TrivialSecondaryCircuit.html new file mode 100644 index 000000000..a8fe0a18f --- /dev/null +++ b/docs/arecibo/supernova/circuit/struct.TrivialSecondaryCircuit.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../arecibo/supernova/struct.TrivialSecondaryCircuit.html...

+ + + \ No newline at end of file diff --git a/docs/arecibo/supernova/circuit/struct.TrivialTestCircuit.html b/docs/arecibo/supernova/circuit/struct.TrivialTestCircuit.html new file mode 100644 index 000000000..330768d35 --- /dev/null +++ b/docs/arecibo/supernova/circuit/struct.TrivialTestCircuit.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../arecibo/supernova/struct.TrivialTestCircuit.html...

+ + + \ No newline at end of file diff --git a/docs/arecibo/supernova/circuit/trait.StepCircuit.html b/docs/arecibo/supernova/circuit/trait.StepCircuit.html new file mode 100644 index 000000000..f46ab0e6c --- /dev/null +++ b/docs/arecibo/supernova/circuit/trait.StepCircuit.html @@ -0,0 +1,11 @@ + + + + + Redirection + + +

Redirecting to ../../../arecibo/supernova/trait.StepCircuit.html...

+ + + \ No newline at end of file diff --git a/docs/arecibo/supernova/error/enum.SuperNovaError.html b/docs/arecibo/supernova/error/enum.SuperNovaError.html new file mode 100644 index 000000000..1b07d0778 --- /dev/null +++ b/docs/arecibo/supernova/error/enum.SuperNovaError.html @@ -0,0 +1,108 @@ +SuperNovaError in arecibo::supernova::error - Rust
pub enum SuperNovaError {
+    NovaError(NovaError),
+    MissingCK,
+    UnSatIndex(&'static str, usize),
+}
Expand description

Errors returned by Nova

+

Variants§

§

NovaError(NovaError)

Nova error

+
§

MissingCK

missing commitment key

+
§

UnSatIndex(&'static str, usize)

Extended error for supernova

+

Trait Implementations§

source§

impl Clone for SuperNovaError

source§

fn clone(&self) -> SuperNovaError

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl Debug for SuperNovaError

source§

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

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

impl Display for SuperNovaError

source§

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

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

impl Error for SuperNovaError

source§

fn source(&self) -> Option<&(dyn Error + 'static)>

The lower-level source of this error, if any. Read more
1.0.0 · source§

fn description(&self) -> &str

👎Deprecated since 1.42.0: use the Display impl or to_string()
1.0.0 · source§

fn cause(&self) -> Option<&dyn Error>

👎Deprecated since 1.33.0: replaced by Error::source, which can support downcasting
source§

fn provide<'a>(&'a self, request: &mut Request<'a>)

🔬This is a nightly-only experimental API. (error_generic_member_access)
Provides type based access to context intended for error reports. Read more
source§

impl From<NovaError> for SuperNovaError

source§

fn from(source: NovaError) -> Self

Converts to this type from the input type.
source§

impl PartialEq<SuperNovaError> for SuperNovaError

source§

fn eq(&self, other: &SuperNovaError) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl Eq for SuperNovaError

source§

impl StructuralEq for SuperNovaError

source§

impl StructuralPartialEq for SuperNovaError

Auto Trait Implementations§

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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> ToString for Twhere + T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/supernova/error/index.html b/docs/arecibo/supernova/error/index.html new file mode 100644 index 000000000..f938ff485 --- /dev/null +++ b/docs/arecibo/supernova/error/index.html @@ -0,0 +1,2 @@ +arecibo::supernova::error - Rust

Module arecibo::supernova::error

source ·
Expand description

This module defines errors returned by the library.

+

Enums

\ No newline at end of file diff --git a/docs/arecibo/supernova/error/sidebar-items.js b/docs/arecibo/supernova/error/sidebar-items.js new file mode 100644 index 000000000..9fafea7f0 --- /dev/null +++ b/docs/arecibo/supernova/error/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"enum":["SuperNovaError"]}; \ No newline at end of file diff --git a/docs/arecibo/supernova/fn.circuit_digest.html b/docs/arecibo/supernova/fn.circuit_digest.html new file mode 100644 index 000000000..70bc33063 --- /dev/null +++ b/docs/arecibo/supernova/fn.circuit_digest.html @@ -0,0 +1,7 @@ +circuit_digest in arecibo::supernova - Rust
pub fn circuit_digest<E1: Engine<Base = <E2 as Engine>::Scalar>, E2: Engine<Base = <E1 as Engine>::Scalar>, C: StepCircuit<E1::Scalar>>(
+    circuit: &C,
+    num_augmented_circuits: usize
+) -> E1::Scalar
Expand description

Compute the circuit digest of a supernova StepCircuit.

+

Note for callers: This function should be called with its performance characteristics in mind. +It will synthesize and digest the full circuit given.

+
\ No newline at end of file diff --git a/docs/arecibo/supernova/index.html b/docs/arecibo/supernova/index.html new file mode 100644 index 000000000..fcfec1d1d --- /dev/null +++ b/docs/arecibo/supernova/index.html @@ -0,0 +1,346 @@ +arecibo::supernova - Rust

Module arecibo::supernova

source ·
Expand description

SuperNova Description

+

This document explains from a high-level how the SuperNova protocol was implemented in Arecibo. +We aim to provide a mathematical description of the protocol, as it is implemented, and highlight the differences with the original paper.

+

Terminology and Concept Clarifications

+

Before delving into the specifics of the implementation, it’s crucial to define and clarify some key terms and concepts used throughout this document:

+
    +
  • Recursive SNARK: A Recursive SNARK is a type of succinct non-interactive argument of knowledge for a circuit $F$ which can be composed with itself as $z_{i+1} \gets F(z_i)$. +Each iteration proves the verification of a proof for $z_i$ and the correctness of $z_{i+1}$, ensuring the proving of each step remains constant.
  • +
  • Augmentation Circuit: In the context of the SuperNova protocol, an augmentation circuit refers to a circuit $F’$ composing $F$ with a circuit which partially verifies the validity of the previous output $z_i$ before running $F(z_i)$.
  • +
  • NIFS Folding Verifier: A non-interactive folding scheme is a protocol for efficiently updating a proof $\pi_i$ about an iterated function $z_{i+1} \gets F(z_i)$ into a new proof $\pi_{i+1}$, through a process referred to as “folding”. +By splitting the proof into an instance/witness pair $(u,w) = \pi$, the folding verifier describes an algorithm for verifying that the $u$ component was properly updated.
  • +
+

SuperNova vs. Nova

+

The main improvement of SuperNova, is to allow each iteration to apply one of several functions to the previous output, whereas Nova only supported the iteration of a single function.

+

Let $F_0, \ldots, F_{\ell-1}$ be folding circuits with the same arity $a$. +In the context of SuperNova, this means that each $F_j$ takes $a$ inputs from the previous iteration, and returns $a$ outputs. +These circuits implement the circuit_supernova::StepCircuit trait, where the main differences with the existing StepCircuit trait are

+
    +
  • The circuit $F_j$ provides its circuit_index $j$
  • +
  • The synthesize function upon input $z_i$ returns the next program_counter $\mathsf{pc}_{i+1}$ alongside the output $z_{i+1}$. It also accepts the (optional) input program counter $\mathsf{pc}_i$, which can be None when $\ell=1$. During circuit synthesis, a constraint enforces $\mathsf{pc}_i \equiv j$. In contrast to the paper, the predicate function $\varphi$ is built into the circuit itself. In other words, we have the signature $(\mathsf{pc}_{i+1}, z_{i+1}) \gets F_{j}(\mathsf{pc}_{i}, z_{i})$.
  • +
+

The goal is to efficiently prove the following computation:

+ +
pc_i = pc_0
+z_i = z_0
+for i in 0..num_steps
+	(pc_i, z_i) = F_{pc_i}(z_i)
+return z_i
+

Cycles of Curves

+

“Cycles of Curves” describes a technique for more efficiently verifying the output $z_i$ of the previous circuit iteration, by running the verification on a curve whose base/scalar fields are inverted. +The result is that the elliptic curve scalar multiplications in the algorithm can be computed in the “native field” of the circuit, minimizing the need for expensive non-native field arithmetic.

+

While the original Nova implementation allows computation to be done on both curves, the SuperNova implementation only uses the cycle curve to verify the computation performed on the primary curve.

+

Prover state

+

The prover needs to store data about the previous function iteration. It is defined by the supernova::RecursiveSNARK struct. It contains:

+
    +
  • $i$: the number of iterations performed. +Note that the new constructor actually performs the first iteration, and the first call to prove_step simply sets the counter to 1.
  • +
  • Primary curve: +
      +
    • $(\mathsf{pc}_i, z_0, z_i)$: current program counter and inputs for the primary circuit
    • +
    • $U[\ ],W[\ ]$: List of relaxed instance/witness pairs for all the circuits on the primary curve. +These can be None when the circuit for that pair has not yet been executed. +The last updated entry is the result of having folded a proof for the correctness of $z_i$.
    • +
    +
  • +
  • Secondary curve +
      +
    • $(z_0’, z_i’)$: Inputs for the single circuit on the secondary curve.
    • +
    • $u’,w’$: Proof for the correctness of the circuit that produced $z_i’$
    • +
    • $U’, W’$: Relaxed instance/witness pair into which $(u’, w’)$ will be folded into in the next iteration.
    • +
    +
  • +
+

Due to the particularities of the cycles of curves implementation, the outputs of the circuits producing $(z_i, z_i’)$ are encoded in public outputs of the proof $u’$.

+

Prove Step

+

At each step, the prover needs to:

+
    +
  • Create a proof $T’$ for folding $u’$ into $U’$, producing $U’_{next}$.
  • +
  • Create a proof $(u,w)$ on the primary curve for the statements: +
      +
    • $(\mathsf{pc}_{i+1}, z_{i+1}) \gets F_\mathsf{pc_i}(z_i)$
    • +
    • Verifying the folding of $u’$ into $U’$ with $T’$
    • +
    +
  • +
  • Create a proof $T$ for folding $u$ into $U[\mathsf{pc}_i]$, producing $U_{next}$
  • +
  • Create a proof $(u’_{next}, w’_{next})$ for the verification on the secondary curve +
      +
    • Verifying the folding of $u$ into $U[\mathsf{pc}_i]$ with $T$
    • +
    +
  • +
  • Update the state of the claims +
      +
    • $U’ = U’_{next}$, $W’ = W’_{next}$
    • +
    • $U[\mathsf{pc}_i] = U_{next}$, $W[\mathsf{pc}_i] = W_{next}$
    • +
    • $(u’,w’) = (u’_{next}, w’_{next})$
    • +
    +
  • +
  • Save $z_{i+1},z’_{i+1}, \mathsf{pc}_{i+1}$ as inputs for the next iteration.
  • +
+

In pseudocode, prove_step looks something like:

+
if i = 0 {
+	U[] = [ø;l]
+
+	// Create a proof for the first iteration of F on the primary curve
+	(pc_1, z_1), (u_1, w_1) <- Prove(F_{pc0},
+		i=0,
+		pc_0,
+		z_0,
+		_,   // z_i : z_0 is the input used
+		_,   // U' : Existing accumulator is empty
+		_,   // u' : No proof of the secondary curve to verify
+		_,   // T' : Nothing to fold
+		0,   // index of u' in U'
+	)
+	// The circuit output is [ vk, i=1, pc_1, z_0, z_1, U'=ø ]
+	// Update state to catch up with verifier
+	z_i    = z_1
+	pc_i   = pc_1
+	U'     = ø
+	W'     = ø
+
+	// Create proof on secondary curve
+	// verifying the validity of the first proof
+	z'_1, (u'_1, w'_1) <- Prove(F',
+		i,
+		0,      // pc is always 0 on secondary curve
+		z'_0,
+		_,      // z'_i : z'_0 is the input used
+		_,      // U[]: all accumulators on primary curve are empty
+		u_0,    // proof for z1
+		_,      // T: u_0 is directly included into U[pc0]
+		pc_1,   // index of u_0 in U[]
+	)
+	// The circuit outputs [ vk, i=1, z'_0, z'_1, U_next[] ]
+	// Update state to catch up with verifier
+	z_i'    = z_1'
+	U[pc_1] = u_1
+	W[pc_1] = w_1
+
+	// Save the proof of F' to be folded into U' in the next iteration
+	u'     = u'_1
+	w'     = w'_1
+} else {
+	// Create folding proof for u' into U', producing U'_next
+	(U'_next, W'_next), T' <- NIFS.Prove(U', W', u', w')
+
+	// Create a proof for the next iteration of F on the primary curve
+	(pc_next, z_next), (u_new, w_new) <- Prove(F_{pc_i},
+		i,
+		pc_i,
+		z_0,
+		z_i,
+		[U'],
+		u',
+		T',
+		0,     // index of u' in [U'] is always 0
+	)
+	// The circuit outputs [ vk, i+1, pc_next, z_0, z_next, U'_next ]
+	// Update state to catch up with verifier
+	z_i  = z_next
+	pc_i = pc_next
+	U'   = U'_next
+	W'   = W'_next
+
+	// Create folding proof for u_new into U[pci], producing U_next
+	(U_next, W_next), T <- NIFS.Prove(U[pci], W[pci], u_new, w_new)
+
+	// Create proof on secondary curve
+	// verifying the folding of u_next into
+	z'_next, (u'_next, w'_next) <- Prove(F',
+		i,
+		0,     // pc is always 0 on secondary curve
+		z_0',
+		z_i',
+		U[],
+		u_new,
+		T,
+		pc_i,  // Index of u_new in U[]
+	)
+	// The circuit outputs [ vk, i+1, z'_0, z'_next, U_next[] ]
+	// Update state to catch up with verifier
+	z_i'       = z'_next
+	U[pc_next] = U_next
+	W[pc_next] = W_next
+
+	// Save the proof of F' to be folded into U' in the next iteration
+	u'         = u'_next
+	w'         = w'_next
+}
+
+

Each iteration stops when the prover has produced a valid R1CS instance $(u’,w’)$ for the secondary circuit, just before folding it back into its accumulator $(U’,W’)$ in the next iteration. +This allows us to access the public outputs of the secondary circuit in the next iteration, or when verifying the IVC chain.

+

Augmented Circuit

+

During each proof iteration, the circuits evaluated and proved by the prover need to be augmented to include additional constraints which verify that the previous iteration was correctly accumulated.

+

To minimize code duplication, there is only a single version of the recursive verification circuit. The circuit is customized depending on whether it is synthesized on the primary/secondary curve.

+

Input Allocation

+

The inputs of provided to the augmented step circuit $F’_j$ are:

+

Inputs for step circuit

+
    +
  • $\mathsf{vk}$: a digest of the verification key for the final compressing SNARK (which includes all public parameters of all circuits)
  • +
  • $i \in \mathbb{Z}_{\geq 0}$: the number of iteration of the functions before running $F$
  • +
  • $\mathsf{pc}_i \in [\ell]$: index of the current function being executed +
      +
    • Primary: The program counter $\mathsf{pc}_i$ must always be Some, and through the EnforcingStepCircuit trait, we enforce $\mathsf{pc}_i \equiv j$.
    • +
    • Secondary: Always None, and interpreted as $\mathsf{pc}_i \equiv 0$, since there is only a single circuit.
    • +
    +
  • +
  • $z_0 \in \mathbb{F}^a$: inputs for the first iteration of $F$
  • +
  • $z_i \in \mathbb{F}^a$: inputs for the current iteration of $F$ +
      +
    • Base case: Set to None, in which case it is allocated as $[0]$, and $z_0$ is used as $z_i$.
    • +
    +
  • +
  • $U_i[\ ] \in \mathbb{R}’^\ell$: list of relaxed R1CS instances on the other curve +
      +
    • Primary: Since there is only a single circuit on the secondary curve, we have $\ell = 0$ and therefore $U_i[\ ]$ only contains a single RelaxedR1CSInstance.
    • +
    • Secondary: The list of input relaxed instances $U_i[\ ]$ is initialized by passing a slice [Option<RelaxedR1CSInstance<G>>], one for each circuit on the primary curve. +Since some of these instances do not exist yet (i.e. for circuits which have not been executed yet), the None entries are allocated as a default instance.
    • +
    +
  • +
+

To minimize the cost related to handling public inputs/outputs of the circuit, these values are hashed as $H(\mathsf{vk}, i, \mathsf{pc}_i, z_0, z_i, U_i[\ ])$. +In the first iteration though, the hash comparison is skipped, and the optional values are conditionally replaced with constrained default values.

+

Auxiliary inputs for recursive verification of other the curve’s circuit

+
    +
  • $u \in \mathbb{R}’$: fresh R1CS instance for the previous iteration on the other curve +
      +
    • Contains the public outputs of the 2 previous circuits on the different curves.
    • +
    • Base case – Primary: Set to None, since there is no proof of the secondary curve to fold
    • +
    +
  • +
  • $T \in \mathbb{G}‘$: Proof for folding $u$ into $U[\mathsf{pc}’]$. +
      +
    • Base case – Primary: Set to None, since there is no proof of the secondary curve to fold
    • +
    +
  • +
  • $\mathsf{pc}’ \in [\ell]$: index of the previously executed function on the other curve. +
      +
    • Primary: Always 0 since the program counter on the secondary curve is always 0
    • +
    • Secondary: Equal to the program counter of the last function proved on the primary curve.
    • +
    +
  • +
+

These non-deterministic inputs are used to compute the circuit’s outputs. +When they are empty, we allocate checked default values instead. +We also check that the computed hash of the inputs matches the hash of the output of the previous iteration contained in $u$.

+

Outputs

+
    +
  • $\mathsf{vk}$: passed along as-is
  • +
  • $i+1 \in \mathbb{Z}_{\geq 0}$: the incremented number of iterations
  • +
  • $\mathsf{pc}_{i+1} \in [\ell]$: index of next function to execute
  • +
  • $z_0 \in \mathbb{F}^a$: passed along as-is
  • +
  • $z_{i+1} \in \mathbb{F}^a$: output of the execution $F_{\mathsf{pc}_i}$
  • +
  • $U_{i+1}[\ ] \in \mathbb{R}‘^\ell$: Updated list of Relaxed R1CS instances, reflecting the folding of $u$ into $U_i[\mathsf{pc}’]$ +
      +
    • Primary: Since no input proof was provided, we set $U_1$ to the default initial instance.
    • +
    +
  • +
+

All these values should be computed deterministically from the inputs described above (even if just passed along as-is). +The actual public output is the hash of these values, to be consistent with the encoding of the inputs.

+

Constraints

+

The circuit has a branching depending on whether it is verifying the first iteration of the IVC chain. Each branch computes the next list of instances $U_{i+1}[\ ]$.

+
Branch: i>0 synthesize_non_base_case
+

The verification circuit first checks that the public output $u.X_0$ is equal to the hash of all outputs of the previous circuit iteration. +Note that this value is defined as a public output of the proof $u$ on the other curve. +It was simply passed along unverified by the cycle circuit to link the two circuits from the same curve. +Since the base case does not have any previous input, we only check the hash if $i>0$. +The circuit produces a bit corresponding to:

+

$$b_{X_0} \gets X_0 \stackrel{?}{=} H(\mathsf{vk}, i, \mathsf{pc}_i, z_0, z_i, U_i[\ ])$$

+

This bit is checked later on.

+

The circuit extracts $U_i[\mathsf{pc}‘]$ by using conditional selection on $U_i[\ ]$. +This is done by computing a selector vector $s \in {0,1}^\ell$ such that $s_{\mathsf{pc}’}=1$ and all other entries are 0.

+

The instance new folding instance $U_{i+1}[\mathsf{pc}’]$ is produced by running the NIFS folding verifier:

+

$$ +U_{i+1}[\mathsf{pc}‘] \gets \mathsf{NIFS}.\mathsf{Verify}(\mathsf{vk}, u, U[\mathsf{pc}’], T) +$$

+

A new list of accumulators $U_{i+1}[\ ]$ is then obtained using conditional selection. +This branch returns $U_{i+1}[\ ]$, $b_{X_0}$ as well as the selector $s$.

+
Branch: i=0 (synthesize_base_case)
+

If $i \equiv 0$, then the verification circuit must instantiate the inputs as their defaults. +Namely, it initializes a list $U_0[\ ]$ (different from the input list which is given to the previous branch) with “empty instances” (all group elements are set to the identity).

+

The output list of instances $U_1[\ ]$ is

+
    +
  • Primary curve: the incoming proof $u$ is trivial, so the result of folding two trivial instances is defined as the trivial relaxed instance.
  • +
  • Secondary curve: the instance $U_0[\mathsf{pc}’]$ is simply replaced with the relaxation of $u$ using conditional selection.
  • +
+

This branch returns $U_1[\ ]$.

+
Remaining constraints
+

Having run both branches, the circuit has computed

+
    +
  • +

    $U_{i+1}[\ ], b_{X_0}, s$ from the first branch

    +
  • +
  • +

    $U_1[\ ]$ from the second branch

    +
  • +
  • +

    Using the bit $b_{i=0} \gets i \stackrel{?}{=} 0$, it needs to conditionally select which list of instance to return.

    +
      +
    • $U_{i+1} \gets b_{i=0} \ \ ?\ \ U_{1}[\ ] \ \ :\ \ U_{i+1}[\ ]$
    • +
    +
  • +
  • +

    Check that $(i\neq 0) \implies b_{X_0}$, enforcing that the hash is correct when not handling the base case

    +
      +
    • $b_{i=0} \lor b_{X_0}$
    • +
    +
  • +
  • +

    Select

    +
      +
    • $z_i \gets b_{i=0} \ \ ?\ \ z_0 \ \ :\ \ z_i$
    • +
    +
  • +
  • +

    Enforce circuit selection

    +
      +
    • $\mathsf{pc}_{i} \equiv j$
    • +
    +
  • +
  • +

    Compute next output

    +
      +
    • $(\mathsf{pc}_{i+1}, z_{i+1}) \gets F_j(z_i)$
    • +
    +
  • +
+

Public Outputs

+

The output at this point would be

+

$$ +\Big (i+1, \mathsf{pc}_{i+1}, z_0, z_{i+1}, U_{i+1}\Big) +$$

+

To keep the number of public outputs small, the outputs of the circuit are hashed into a single field element. We create this hash as $H_{out} = H\big (\mathsf{vk}, i+1, \mathsf{pc}_{i+1}, z_0, z_{i+1}, U_{next}\big)$.

+

We also return the hash resulting from the output on the other curve, $u.X_1$. It will be unpacked at the start of the next iteration of the circuit on the cycle curve, so we swap it and place it first. The actual public output is then.

+

$$ +[u.X_1, H_{out}] +$$

+

We can view output as the shared state between the circuits on the two curve. The list of two elements is a queue, where the last inserted element is popped out to be consumed by the verification circuit, and the resulting output is added to the end of the queue.

+

Verification

+

After any number of iterations of prove_step, we can check that the current prover state is correct. In particular, we want to ensure that $(z_i, z’_i)$ are the correct outputs after having run $i$ iterations of the folding prover.

+

To verify that $(z_i, z’_i)$ are correct, the verifier needs to recompute the public outputs of the latest proof $u’$. Since this is the output on the secondary curve, the first entry $u’.X_0$ will be the output of the primary curve circuit producing $(\mathsf{pc}_i, z_i)$ and the accumulator $U’$ in which we will fold $u’$. The second entry $u’.X_1$ is the output of the last circuit on the secondary curve, which will have folded the proof for $(\mathsf{pc}_i, z_i)$ into $U[\ ]$.

+
    +
  • $u’.X_0 \stackrel{?}{=} H(\mathsf{vk}, i, \mathsf{pc}_i, z_0, z_i, U’)$
  • +
  • $u’.X_1 \stackrel{?}{=} H’(\mathsf{vk}, i, z’_0, z’_i, U[\ ])$
  • +
+

We then verify that $(u’,w’)$ is a satisfying circuit, which proves that all relaxed instances $U[\ ], U’$ were correctly updated through by folding proof.

+

We then need to verify that all accumulators $(U[\ ], W[\ ])$ and $(U’, W’)$ are correct by checking the circuit satisfiability.

+

Comparison of Nova and SuperNova

+ + + + + + + + +
NovaSuperNova
RecursiveSNARKlib.rssupernova/mod.rs
CompressedSNARKlib.rssupernova/snark.rs
StepCircuittraits/circuit.rstraits/circuit_supernova.rs
Augmented Circuitcircuit.rssupernova/circuit.rs
(Batched)RelaxedR1CSSNARKTraittraits/snark.rstraits/snark.rs
Direct Spartanspartan/snark.rsspartan/batched.rs
Spartan with Spark preprocessingspartan/ppsnark.rsspartan/batched_ppsnark.rs
(batched) Sumcheck primitivesspartan/sumcheck.rsspartan/sumcheck.rs
+

Modules

  • This module defines errors returned by the library.
  • This module defines a final compressing SNARK for supernova proofs

Structs

  • Auxiliary PublicParams information about the commitment keys and +secondary circuit. This is used as a helper struct when reconstructing +PublicParams downstream in lurk.
  • A struct that manages all the digests of the primary circuits of a SuperNova instance
  • A vector of R1CSWithArity adjoined to a set of PublicParams
  • A SNARK that proves the correct execution of an non-uniform incremental computation
  • A trivial step circuit that simply returns the input, for use on the secondary circuit when implementing NIVC. +NOTE: This should not be needed. The secondary circuit doesn’t need the program counter at all. +Ideally, the need this fills could be met by traits::circuit::TrivialTestCircuit (or equivalent).
  • A trivial step circuit that simply returns the input

Traits

  • SuperNova helper trait, for implementors that provide sets of sub-circuits to be proved via NIVC. C1 must be a +type (likely an Enum) for which a potentially-distinct instance can be supplied for each index below +self.num_circuits().
  • A helper trait for a step of the incremental computation for SuperNova (i.e., circuit for F) – to be implemented by +applications.

Functions

\ No newline at end of file diff --git a/docs/arecibo/supernova/sidebar-items.js b/docs/arecibo/supernova/sidebar-items.js new file mode 100644 index 000000000..1e44cf920 --- /dev/null +++ b/docs/arecibo/supernova/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["circuit_digest"],"mod":["error","snark"],"struct":["AuxParams","CircuitDigests","PublicParams","RecursiveSNARK","TrivialSecondaryCircuit","TrivialTestCircuit"],"trait":["NonUniformCircuit","StepCircuit"]}; \ No newline at end of file diff --git a/docs/arecibo/supernova/snark/index.html b/docs/arecibo/supernova/snark/index.html new file mode 100644 index 000000000..9bc01256a --- /dev/null +++ b/docs/arecibo/supernova/snark/index.html @@ -0,0 +1,2 @@ +arecibo::supernova::snark - Rust

Module arecibo::supernova::snark

source ·
Expand description

This module defines a final compressing SNARK for supernova proofs

+

Structs

  • A SNARK that proves the knowledge of a valid RecursiveSNARK
  • A type that holds the prover key for CompressedSNARK
  • A type that holds the verifier key for CompressedSNARK
\ No newline at end of file diff --git a/docs/arecibo/supernova/snark/sidebar-items.js b/docs/arecibo/supernova/snark/sidebar-items.js new file mode 100644 index 000000000..c2a3d0ef8 --- /dev/null +++ b/docs/arecibo/supernova/snark/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["CompressedSNARK","ProverKey","VerifierKey"]}; \ No newline at end of file diff --git a/docs/arecibo/supernova/snark/struct.CompressedSNARK.html b/docs/arecibo/supernova/snark/struct.CompressedSNARK.html new file mode 100644 index 000000000..5cd615489 --- /dev/null +++ b/docs/arecibo/supernova/snark/struct.CompressedSNARK.html @@ -0,0 +1,189 @@ +CompressedSNARK in arecibo::supernova::snark - Rust
pub struct CompressedSNARK<E1, E2, C1, C2, S1, S2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,{ /* private fields */ }
Expand description

A SNARK that proves the knowledge of a valid RecursiveSNARK

+

Implementations§

source§

impl<E1, E2, C1, C2, S1, S2> CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source

pub fn setup( + pp: &PublicParams<E1, E2, C1, C2> +) -> Result<(ProverKey<E1, E2, C1, C2, S1, S2>, VerifierKey<E1, E2, C1, C2, S1, S2>), SuperNovaError>

Creates prover and verifier keys for CompressedSNARK

+
source

pub fn prove( + pp: &PublicParams<E1, E2, C1, C2>, + pk: &ProverKey<E1, E2, C1, C2, S1, S2>, + recursive_snark: &RecursiveSNARK<E1, E2> +) -> Result<Self, SuperNovaError>

Create a new CompressedSNARK

+
source

pub fn verify( + &self, + pp: &PublicParams<E1, E2, C1, C2>, + vk: &VerifierKey<E1, E2, C1, C2, S1, S2>, + z0_primary: &[E1::Scalar], + z0_secondary: &[E2::Scalar] +) -> Result<(Vec<E1::Scalar>, Vec<E2::Scalar>), SuperNovaError>

Verify the correctness of the CompressedSNARK

+

Trait Implementations§

source§

impl<E1, E2, C1, C2, S1, S2> Clone for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + S1: BatchedRelaxedR1CSSNARKTrait<E1> + Clone, + S2: RelaxedR1CSSNARKTrait<E2> + Clone, + E1::Scalar: Clone, + E2::Scalar: Clone,

source§

fn clone(&self) -> CompressedSNARK<E1, E2, C1, C2, S1, S2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E1, E2, C1, C2, S1, S2> Debug for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Debug, + E2: Engine<Base = <E1 as Engine>::Scalar> + Debug, + C1: StepCircuit<E1::Scalar> + Debug, + C2: StepCircuit<E2::Scalar> + Debug, + S1: BatchedRelaxedR1CSSNARKTrait<E1> + Debug, + S2: RelaxedR1CSSNARKTrait<E2> + Debug, + E1::Scalar: Debug, + E2::Scalar: Debug,

source§

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

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

impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2, S1, S2> Serialize for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + E1: RefUnwindSafe, + E2: RefUnwindSafe, + S1: RefUnwindSafe, + S2: RefUnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: RefUnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: RefUnwindSafe, + <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: RefUnwindSafe, + <E1 as Engine>::Scalar: RefUnwindSafe, + <E2 as Engine>::Scalar: RefUnwindSafe,

§

impl<E1, E2, C1, C2, S1, S2> Send for CompressedSNARK<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Sync for CompressedSNARK<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Unpin for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + C1: Unpin, + C2: Unpin, + E1: Unpin, + E2: Unpin, + S1: Unpin, + S2: Unpin, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Unpin, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Unpin, + <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: Unpin, + <E1 as Engine>::Scalar: Unpin, + <E2 as Engine>::Scalar: Unpin,

§

impl<E1, E2, C1, C2, S1, S2> UnwindSafe for CompressedSNARK<E1, E2, C1, C2, S1, S2>where + C1: UnwindSafe, + C2: UnwindSafe, + E1: UnwindSafe, + E2: UnwindSafe, + S1: UnwindSafe, + S2: UnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: UnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: UnwindSafe, + <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: UnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/supernova/snark/struct.ProverKey.html b/docs/arecibo/supernova/snark/struct.ProverKey.html new file mode 100644 index 000000000..6e143a9ef --- /dev/null +++ b/docs/arecibo/supernova/snark/struct.ProverKey.html @@ -0,0 +1,149 @@ +ProverKey in arecibo::supernova::snark - Rust
pub struct ProverKey<E1, E2, C1, C2, S1, S2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,{ /* private fields */ }
Expand description

A type that holds the prover key for CompressedSNARK

+

Trait Implementations§

source§

impl<E1, E2, C1, C2, S1, S2> Abomonation for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>, + <E1::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E1, E2, C1, C2, S1, S2> Clone for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + S1: BatchedRelaxedR1CSSNARKTrait<E1> + Clone, + S2: RelaxedR1CSSNARKTrait<E2> + Clone, + S1::ProverKey: Clone, + S2::ProverKey: Clone,

source§

fn clone(&self) -> ProverKey<E1, E2, C1, C2, S1, S2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2, S1, S2> Serialize for ProverKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for ProverKey<E1, E2, C1, C2, S1, S2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::ProverKey: RefUnwindSafe, + <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: RefUnwindSafe,

§

impl<E1, E2, C1, C2, S1, S2> Send for ProverKey<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Sync for ProverKey<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Unpin for ProverKey<E1, E2, C1, C2, S1, S2>where + C1: Unpin, + C2: Unpin, + <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::ProverKey: Unpin, + <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: Unpin,

§

impl<E1, E2, C1, C2, S1, S2> UnwindSafe for ProverKey<E1, E2, C1, C2, S1, S2>where + C1: UnwindSafe, + C2: UnwindSafe, + <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::ProverKey: UnwindSafe, + <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/supernova/snark/struct.VerifierKey.html b/docs/arecibo/supernova/snark/struct.VerifierKey.html new file mode 100644 index 000000000..2ac23f043 --- /dev/null +++ b/docs/arecibo/supernova/snark/struct.VerifierKey.html @@ -0,0 +1,149 @@ +VerifierKey in arecibo::supernova::snark - Rust
pub struct VerifierKey<E1, E2, C1, C2, S1, S2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,{ /* private fields */ }
Expand description

A type that holds the verifier key for CompressedSNARK

+

Trait Implementations§

source§

impl<E1, E2, C1, C2, S1, S2> Abomonation for VerifierKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>, + <E1::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E1, E2, C1, C2, S1, S2> Clone for VerifierKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + S1: BatchedRelaxedR1CSSNARKTrait<E1> + Clone, + S2: RelaxedR1CSSNARKTrait<E2> + Clone, + S1::VerifierKey: Clone, + S2::VerifierKey: Clone,

source§

fn clone(&self) -> VerifierKey<E1, E2, C1, C2, S1, S2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for VerifierKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2, S1, S2> Serialize for VerifierKey<E1, E2, C1, C2, S1, S2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>, + S1: BatchedRelaxedR1CSSNARKTrait<E1>, + S2: RelaxedR1CSSNARKTrait<E2>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for VerifierKey<E1, E2, C1, C2, S1, S2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::VerifierKey: RefUnwindSafe, + <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: RefUnwindSafe,

§

impl<E1, E2, C1, C2, S1, S2> Send for VerifierKey<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Sync for VerifierKey<E1, E2, C1, C2, S1, S2>

§

impl<E1, E2, C1, C2, S1, S2> Unpin for VerifierKey<E1, E2, C1, C2, S1, S2>where + C1: Unpin, + C2: Unpin, + <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::VerifierKey: Unpin, + <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: Unpin,

§

impl<E1, E2, C1, C2, S1, S2> UnwindSafe for VerifierKey<E1, E2, C1, C2, S1, S2>where + C1: UnwindSafe, + C2: UnwindSafe, + <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::VerifierKey: UnwindSafe, + <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/supernova/struct.AuxParams.html b/docs/arecibo/supernova/struct.AuxParams.html new file mode 100644 index 000000000..48b57562c --- /dev/null +++ b/docs/arecibo/supernova/struct.AuxParams.html @@ -0,0 +1,150 @@ +AuxParams in arecibo::supernova - Rust
pub struct AuxParams<E1, E2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,{ /* private fields */ }
Expand description

Auxiliary PublicParams information about the commitment keys and +secondary circuit. This is used as a helper struct when reconstructing +PublicParams downstream in lurk.

+

Trait Implementations§

source§

impl<E1, E2> Abomonation for AuxParams<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + <E1::Scalar as PrimeField>::Repr: Abomonation, + <E2::Scalar as PrimeField>::Repr: Abomonation,

source§

unsafe fn entomb<W: Write>(&self, bytes: &mut W) -> Result<()>

Write any additional information about &self beyond its binary representation. Read more
source§

unsafe fn exhume<'a, 'b>( + &'a mut self, + bytes: &'b mut [u8] +) -> Option<&'b mut [u8]>

Recover any information for &mut self not evident from its binary representation. Read more
source§

fn extent(&self) -> usize

Reports the number of further bytes required to entomb self.
source§

impl<E1, E2> Clone for AuxParams<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + E1::Scalar: Clone,

source§

fn clone(&self) -> AuxParams<E1, E2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E1, E2> Deserialize<'de> for AuxParams<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2> PartialEq<AuxParams<E1, E2>> for AuxParams<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + PartialEq, + E2: Engine<Base = <E1 as Engine>::Scalar> + PartialEq, + E1::Scalar: PartialEq,

source§

fn eq(&self, other: &AuxParams<E1, E2>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E1, E2> Serialize for AuxParams<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E1, E2> StructuralPartialEq for AuxParams<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>,

Auto Trait Implementations§

§

impl<E1, E2> RefUnwindSafe for AuxParams<E1, E2>where + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: RefUnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: RefUnwindSafe, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <E1 as Engine>::Scalar: RefUnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe + RefUnwindSafe,

§

impl<E1, E2> Send for AuxParams<E1, E2>

§

impl<E1, E2> Sync for AuxParams<E1, E2>

§

impl<E1, E2> Unpin for AuxParams<E1, E2>where + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: Unpin, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: Unpin, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Unpin, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Unpin, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: Unpin, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: Unpin, + <E1 as Engine>::Scalar: Unpin, + <E2 as Engine>::Scalar: Unpin,

§

impl<E1, E2> UnwindSafe for AuxParams<E1, E2>where + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: UnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: UnwindSafe, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: UnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/supernova/struct.CircuitDigests.html b/docs/arecibo/supernova/struct.CircuitDigests.html new file mode 100644 index 000000000..3b94e86bf --- /dev/null +++ b/docs/arecibo/supernova/struct.CircuitDigests.html @@ -0,0 +1,2494 @@ +CircuitDigests in arecibo::supernova - Rust
pub struct CircuitDigests<E: Engine> { /* private fields */ }
Expand description

A struct that manages all the digests of the primary circuits of a SuperNova instance

+

Implementations§

source§

impl<E: Engine> CircuitDigests<E>

source

pub fn new(digests: Vec<E::Scalar>) -> Self

Construct a new CircuitDigests

+
source

pub fn digest(&self) -> E::Scalar

Return the CircuitDigests’ digest.

+

Methods from Deref<Target = Vec<E::Scalar>>§

1.0.0 · source

pub fn capacity(&self) -> usize

Returns the total number of elements the vector can hold without +reallocating.

+
Examples
+
let mut vec: Vec<i32> = Vec::with_capacity(10);
+vec.push(42);
+assert!(vec.capacity() >= 10);
+
1.7.0 · source

pub fn as_slice(&self) -> &[T]

Extracts a slice containing the entire vector.

+

Equivalent to &s[..].

+
Examples
+
use std::io::{self, Write};
+let buffer = vec![1, 2, 3, 5, 8];
+io::sink().write(buffer.as_slice()).unwrap();
+
1.37.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the vector’s buffer, or a dangling raw pointer +valid for zero sized reads if the vector didn’t allocate.

+

The caller must ensure that the vector outlives the pointer this +function returns, or else it will end up pointing to garbage. +Modifying the vector may cause its buffer to be reallocated, +which would also make any pointers to it invalid.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+
Examples
+
let x = vec![1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(*x_ptr.add(i), 1 << i);
+    }
+}
+
source

pub fn allocator(&self) -> &A

🔬This is a nightly-only experimental API. (allocator_api)

Returns a reference to the underlying allocator.

+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the vector, also referred to +as its ‘length’.

+
Examples
+
let a = vec![1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the vector contains no elements.

+
Examples
+
let mut v = Vec::new();
+assert!(v.is_empty());
+
+v.push(1);
+assert!(!v.is_empty());
+

Methods from Deref<Target = [T]>§

source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f32::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f32::NAN, 8.29, f32::INFINITY, -1.0, 0.0, -f32::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f32::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f32::INFINITY, f32::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
1.23.0 · source

pub fn is_ascii(&self) -> bool

Checks if all bytes in this slice are within the ASCII range.

+
source

pub fn as_ascii(&self) -> Option<&[AsciiChar]>

🔬This is a nightly-only experimental API. (ascii_char)

If this slice is_ascii, returns it as a slice of +ASCII characters, otherwise returns None.

+
source

pub unsafe fn as_ascii_unchecked(&self) -> &[AsciiChar]

🔬This is a nightly-only experimental API. (ascii_char)

Converts this slice of bytes into a slice of ASCII characters, +without checking whether they’re valid.

+
Safety
+

Every byte in the slice must be in 0..=127, or else this is UB.

+
1.23.0 · source

pub fn eq_ignore_ascii_case(&self, other: &[u8]) -> bool

Checks that two slices are an ASCII case-insensitive match.

+

Same as to_ascii_lowercase(a) == to_ascii_lowercase(b), +but without allocating and copying temporaries.

+
1.23.0 · source

pub fn make_ascii_uppercase(&mut self)

Converts this slice to its ASCII upper case equivalent in-place.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To return a new uppercased value without modifying the existing one, use +to_ascii_uppercase.

+
1.23.0 · source

pub fn make_ascii_lowercase(&mut self)

Converts this slice to its ASCII lower case equivalent in-place.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To return a new lowercased value without modifying the existing one, use +to_ascii_lowercase.

+
1.60.0 · source

pub fn escape_ascii(&self) -> EscapeAscii<'_>

Returns an iterator that produces an escaped version of this slice, +treating it as an ASCII string.

+
Examples
+

+let s = b"0\t\r\n'\"\\\x9d";
+let escaped = s.escape_ascii().to_string();
+assert_eq!(escaped, "0\\t\\r\\n\\'\\\"\\\\\\x9d");
+
source

pub fn trim_ascii_start(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b" \t hello world\n".trim_ascii_start(), b"hello world\n");
+assert_eq!(b"  ".trim_ascii_start(), b"");
+assert_eq!(b"".trim_ascii_start(), b"");
+
source

pub fn trim_ascii_end(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with trailing ASCII whitespace bytes removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii_end(), b"\r hello world");
+assert_eq!(b"  ".trim_ascii_end(), b"");
+assert_eq!(b"".trim_ascii_end(), b"");
+
source

pub fn trim_ascii(&self) -> &[u8]

🔬This is a nightly-only experimental API. (byte_slice_trim_ascii)

Returns a byte slice with leading and trailing ASCII whitespace bytes +removed.

+

‘Whitespace’ refers to the definition used by +u8::is_ascii_whitespace.

+
Examples
+
#![feature(byte_slice_trim_ascii)]
+
+assert_eq!(b"\r hello world\n ".trim_ascii(), b"hello world");
+assert_eq!(b"  ".trim_ascii(), b"");
+assert_eq!(b"".trim_ascii(), b"");
+
source

pub fn flatten(&self) -> &[T]

🔬This is a nightly-only experimental API. (slice_flatten)

Takes a &[[T; N]], and flattens it to a &[T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+assert_eq!([[1, 2, 3], [4, 5, 6]].flatten(), &[1, 2, 3, 4, 5, 6]);
+
+assert_eq!(
+    [[1, 2, 3], [4, 5, 6]].flatten(),
+    [[1, 2], [3, 4], [5, 6]].flatten(),
+);
+
+let slice_of_empty_arrays: &[[i32; 0]] = &[[], [], [], [], []];
+assert!(slice_of_empty_arrays.flatten().is_empty());
+
+let empty_slice_of_arrays: &[[u32; 10]] = &[];
+assert!(empty_slice_of_arrays.flatten().is_empty());
+
source

pub fn flatten_mut(&mut self) -> &mut [T]

🔬This is a nightly-only experimental API. (slice_flatten)

Takes a &mut [[T; N]], and flattens it to a &mut [T].

+
Panics
+

This panics if the length of the resulting slice would overflow a usize.

+

This is only possible when flattening a slice of arrays of zero-sized +types, and thus tends to be irrelevant in practice. If +size_of::<T>() > 0, this will never panic.

+
Examples
+
#![feature(slice_flatten)]
+
+fn add_5_to_all(slice: &mut [i32]) {
+    for i in slice {
+        *i += 5;
+    }
+}
+
+let mut array = [[1, 2, 3], [4, 5, 6], [7, 8, 9]];
+add_5_to_all(array.flatten_mut());
+assert_eq!(array, [[6, 7, 8], [9, 10, 11], [12, 13, 14]]);
+
source

pub fn sort_floats(&mut self)

🔬This is a nightly-only experimental API. (sort_floats)

Sorts the slice of floats.

+

This sort is in-place (i.e. does not allocate), O(n * log(n)) worst-case, and uses +the ordering defined by f64::total_cmp.

+
Current implementation
+

This uses the same sorting algorithm as sort_unstable_by.

+
Examples
+
#![feature(sort_floats)]
+let mut v = [2.6, -5e-8, f64::NAN, 8.29, f64::INFINITY, -1.0, 0.0, -f64::INFINITY, -0.0];
+
+v.sort_floats();
+let sorted = [-f64::INFINITY, -1.0, -5e-8, -0.0, 0.0, 2.6, 8.29, f64::INFINITY, f64::NAN];
+assert_eq!(&v[..8], &sorted[..8]);
+assert!(v[8].is_nan());
+
source

pub fn as_str(&self) -> &str

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a UTF-8 str.

+
source

pub fn as_bytes(&self) -> &[u8]

🔬This is a nightly-only experimental API. (ascii_char)

Views this slice of ASCII characters as a slice of u8 bytes.

+
1.0.0 · source

pub fn len(&self) -> usize

Returns the number of elements in the slice.

+
Examples
+
let a = [1, 2, 3];
+assert_eq!(a.len(), 3);
+
1.0.0 · source

pub fn is_empty(&self) -> bool

Returns true if the slice has a length of 0.

+
Examples
+
let a = [1, 2, 3];
+assert!(!a.is_empty());
+
1.0.0 · source

pub fn first(&self) -> Option<&T>

Returns the first element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&10), v.first());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.first());
+
1.0.0 · source

pub fn first_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the first element of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_mut() {
+    *first = 5;
+}
+assert_eq!(x, &[5, 1, 2]);
+
1.5.0 · source

pub fn split_first(&self) -> Option<(&T, &[T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first() {
+    assert_eq!(first, &0);
+    assert_eq!(elements, &[1, 2]);
+}
+
1.5.0 · source

pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the first and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_mut() {
+    *first = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
1.5.0 · source

pub fn split_last(&self) -> Option<(&T, &[T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last() {
+    assert_eq!(last, &2);
+    assert_eq!(elements, &[0, 1]);
+}
+
1.5.0 · source

pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])>

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_mut() {
+    *last = 3;
+    elements[0] = 4;
+    elements[1] = 5;
+}
+assert_eq!(x, &[4, 5, 3]);
+
1.0.0 · source

pub fn last(&self) -> Option<&T>

Returns the last element of the slice, or None if it is empty.

+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&30), v.last());
+
+let w: &[i32] = &[];
+assert_eq!(None, w.last());
+
1.0.0 · source

pub fn last_mut(&mut self) -> Option<&mut T>

Returns a mutable pointer to the last item in the slice.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_mut() {
+    *last = 10;
+}
+assert_eq!(x, &[0, 1, 10]);
+
source

pub fn first_chunk<const N: usize>(&self) -> Option<&[T; N]>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the first N elements of the slice, or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[10, 40]), u.first_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.first_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.first_chunk::<0>());
+
source

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

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns a mutable reference to the first N elements of the slice, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(first) = x.first_chunk_mut::<2>() {
+    first[0] = 5;
+    first[1] = 4;
+}
+assert_eq!(x, &[5, 4, 2]);
+
source

pub fn split_first_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk::<2>() {
+    assert_eq!(first, &[0, 1]);
+    assert_eq!(elements, &[2]);
+}
+
source

pub fn split_first_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns a mutable reference to the first N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((first, elements)) = x.split_first_chunk_mut::<2>() {
+    first[0] = 3;
+    first[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[3, 4, 5]);
+
source

pub fn split_last_chunk<const N: usize>(&self) -> Option<(&[T; N], &[T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the last N elements of the slice and the remainder, +or None if it has fewer than N elements.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &[0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk::<2>() {
+    assert_eq!(last, &[1, 2]);
+    assert_eq!(elements, &[0]);
+}
+
source

pub fn split_last_chunk_mut<const N: usize>( + &mut self +) -> Option<(&mut [T; N], &mut [T])>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the last and all the rest of the elements of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some((last, elements)) = x.split_last_chunk_mut::<2>() {
+    last[0] = 3;
+    last[1] = 4;
+    elements[0] = 5;
+}
+assert_eq!(x, &[5, 3, 4]);
+
source

pub fn last_chunk<const N: usize>(&self) -> Option<&[T; N]>

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns the last element of the slice, or None if it is empty.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let u = [10, 40, 30];
+assert_eq!(Some(&[40, 30]), u.last_chunk::<2>());
+
+let v: &[i32] = &[10];
+assert_eq!(None, v.last_chunk::<2>());
+
+let w: &[i32] = &[];
+assert_eq!(Some(&[]), w.last_chunk::<0>());
+
source

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

🔬This is a nightly-only experimental API. (slice_first_last_chunk)

Returns a mutable pointer to the last item in the slice.

+
Examples
+
#![feature(slice_first_last_chunk)]
+
+let x = &mut [0, 1, 2];
+
+if let Some(last) = x.last_chunk_mut::<2>() {
+    last[0] = 10;
+    last[1] = 20;
+}
+assert_eq!(x, &[0, 10, 20]);
+
1.0.0 · source

pub fn get<I>(&self, index: I) -> Option<&<I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a reference to an element or subslice depending on the type of +index.

+
    +
  • If given a position, returns a reference to the element at that +position or None if out of bounds.
  • +
  • If given a range, returns the subslice corresponding to that range, +or None if out of bounds.
  • +
+
Examples
+
let v = [10, 40, 30];
+assert_eq!(Some(&40), v.get(1));
+assert_eq!(Some(&[10, 40][..]), v.get(0..2));
+assert_eq!(None, v.get(3));
+assert_eq!(None, v.get(0..4));
+
1.0.0 · source

pub fn get_mut<I>( + &mut self, + index: I +) -> Option<&mut <I as SliceIndex<[T]>>::Output>where + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice depending on the +type of index (see get) or None if the index is out of bounds.

+
Examples
+
let x = &mut [0, 1, 2];
+
+if let Some(elem) = x.get_mut(1) {
+    *elem = 42;
+}
+assert_eq!(x, &[0, 42, 2]);
+
1.0.0 · source

pub unsafe fn get_unchecked<I>( + &self, + index: I +) -> &<I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a reference to an element or subslice, without doing bounds +checking.

+

For a safe alternative see get.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+
Examples
+
let x = &[1, 2, 4];
+
+unsafe {
+    assert_eq!(x.get_unchecked(1), &2);
+}
+
1.0.0 · source

pub unsafe fn get_unchecked_mut<I>( + &mut self, + index: I +) -> &mut <I as SliceIndex<[T]>>::Outputwhere + I: SliceIndex<[T]>,

Returns a mutable reference to an element or subslice, without doing +bounds checking.

+

For a safe alternative see get_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used.

+
Examples
+
let x = &mut [1, 2, 4];
+
+unsafe {
+    let elem = x.get_unchecked_mut(1);
+    *elem = 13;
+}
+assert_eq!(x, &[1, 13, 4]);
+
1.0.0 · source

pub fn as_ptr(&self) -> *const T

Returns a raw pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

The caller must also ensure that the memory the pointer (non-transitively) points to +is never written to (except inside an UnsafeCell) using this pointer or any pointer +derived from it. If you need to mutate the contents of the slice, use as_mut_ptr.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &[1, 2, 4];
+let x_ptr = x.as_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        assert_eq!(x.get_unchecked(i), &*x_ptr.add(i));
+    }
+}
+
1.0.0 · source

pub fn as_mut_ptr(&mut self) -> *mut T

Returns an unsafe mutable pointer to the slice’s buffer.

+

The caller must ensure that the slice outlives the pointer this +function returns, or else it will end up pointing to garbage.

+

Modifying the container referenced by this slice may cause its buffer +to be reallocated, which would also make any pointers to it invalid.

+
Examples
+
let x = &mut [1, 2, 4];
+let x_ptr = x.as_mut_ptr();
+
+unsafe {
+    for i in 0..x.len() {
+        *x_ptr.add(i) += 2;
+    }
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.48.0 · source

pub fn as_ptr_range(&self) -> Range<*const T>

Returns the two raw pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_ptr for warnings on using these pointers. The end pointer +requires extra caution, as it does not point to a valid element in the +slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+

It can also be useful to check if a pointer to an element refers to an +element of this slice:

+ +
let a = [1, 2, 3];
+let x = &a[1] as *const _;
+let y = &5 as *const _;
+
+assert!(a.as_ptr_range().contains(&x));
+assert!(!a.as_ptr_range().contains(&y));
+
1.48.0 · source

pub fn as_mut_ptr_range(&mut self) -> Range<*mut T>

Returns the two unsafe mutable pointers spanning the slice.

+

The returned range is half-open, which means that the end pointer +points one past the last element of the slice. This way, an empty +slice is represented by two equal pointers, and the difference between +the two pointers represents the size of the slice.

+

See as_mut_ptr for warnings on using these pointers. The end +pointer requires extra caution, as it does not point to a valid element +in the slice.

+

This function is useful for interacting with foreign interfaces which +use two pointers to refer to a range of elements in memory, as is +common in C++.

+
1.0.0 · source

pub fn swap(&mut self, a: usize, b: usize)

Swaps two elements in the slice.

+

If a equals to b, it’s guaranteed that elements won’t change value.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Panics
+

Panics if a or b are out of bounds.

+
Examples
+
let mut v = ["a", "b", "c", "d", "e"];
+v.swap(2, 4);
+assert!(v == ["a", "b", "e", "d", "c"]);
+
source

pub unsafe fn swap_unchecked(&mut self, a: usize, b: usize)

🔬This is a nightly-only experimental API. (slice_swap_unchecked)

Swaps two elements in the slice, without doing bounds checking.

+

For a safe alternative see swap.

+
Arguments
+
    +
  • a - The index of the first element
  • +
  • b - The index of the second element
  • +
+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior. +The caller has to ensure that a < self.len() and b < self.len().

+
Examples
+
#![feature(slice_swap_unchecked)]
+
+let mut v = ["a", "b", "c", "d"];
+// SAFETY: we know that 1 and 3 are both indices of the slice
+unsafe { v.swap_unchecked(1, 3) };
+assert!(v == ["a", "d", "c", "b"]);
+
1.0.0 · source

pub fn reverse(&mut self)

Reverses the order of elements in the slice, in place.

+
Examples
+
let mut v = [1, 2, 3];
+v.reverse();
+assert!(v == [3, 2, 1]);
+
1.0.0 · source

pub fn iter(&self) -> Iter<'_, T>

Returns an iterator over the slice.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &[1, 2, 4];
+let mut iterator = x.iter();
+
+assert_eq!(iterator.next(), Some(&1));
+assert_eq!(iterator.next(), Some(&2));
+assert_eq!(iterator.next(), Some(&4));
+assert_eq!(iterator.next(), None);
+
1.0.0 · source

pub fn iter_mut(&mut self) -> IterMut<'_, T>

Returns an iterator that allows modifying each value.

+

The iterator yields all items from start to end.

+
Examples
+
let x = &mut [1, 2, 4];
+for elem in x.iter_mut() {
+    *elem += 2;
+}
+assert_eq!(x, &[3, 4, 6]);
+
1.0.0 · source

pub fn windows(&self, size: usize) -> Windows<'_, T>

Returns an iterator over all contiguous windows of length +size. The windows overlap. If the slice is shorter than +size, the iterator returns no values.

+
Panics
+

Panics if size is 0.

+
Examples
+
let slice = ['r', 'u', 's', 't'];
+let mut iter = slice.windows(2);
+assert_eq!(iter.next().unwrap(), &['r', 'u']);
+assert_eq!(iter.next().unwrap(), &['u', 's']);
+assert_eq!(iter.next().unwrap(), &['s', 't']);
+assert!(iter.next().is_none());
+

If the slice is shorter than size:

+ +
let slice = ['f', 'o', 'o'];
+let mut iter = slice.windows(4);
+assert!(iter.next().is_none());
+

There’s no windows_mut, as that existing would let safe code violate the +“only one &mut at a time to the same thing” rule. However, you can sometimes +use Cell::as_slice_of_cells in +conjunction with windows to accomplish something similar:

+ +
use std::cell::Cell;
+
+let mut array = ['R', 'u', 's', 't', ' ', '2', '0', '1', '5'];
+let slice = &mut array[..];
+let slice_of_cells: &[Cell<char>] = Cell::from_mut(slice).as_slice_of_cells();
+for w in slice_of_cells.windows(3) {
+    Cell::swap(&w[0], &w[2]);
+}
+assert_eq!(array, ['s', 't', ' ', '2', '0', '1', '5', 'u', 'R']);
+
1.0.0 · source

pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See chunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and rchunks for the same iterator but starting at the end of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert_eq!(iter.next().unwrap(), &['m']);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See chunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and rchunks_mut for the same iterator but starting at +the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 3]);
+
1.31.0 · source

pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks.

+

See chunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and rchunks_exact for the same iterator but starting at the end of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.chunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
1.31.0 · source

pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See chunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and rchunks_exact_mut for the same iterator but starting at the end of +the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.chunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub unsafe fn as_chunks_unchecked<const N: usize>(&self) -> &[[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &[char] = &['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &[[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &[[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked() };
+assert_eq!(chunks, &[['l', 'o', 'r'], ['e', 'm', '!']]);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked() // Zero-length chunks are never allowed
+
source

pub fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (chunks, remainder) = slice.as_chunks();
+assert_eq!(chunks, &[['l', 'o'], ['r', 'e']]);
+assert_eq!(remainder, &['m']);
+

If you expect the slice to be an exact multiple, you can combine +let-else with an empty slice pattern:

+ +
#![feature(slice_as_chunks)]
+let slice = ['R', 'u', 's', 't'];
+let (chunks, []) = slice.as_chunks::<2>() else {
+    panic!("slice didn't have even length")
+};
+assert_eq!(chunks, &[['R', 'u'], ['s', 't']]);
+
source

pub fn as_rchunks<const N: usize>(&self) -> (&[T], &[[T; N]])

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let (remainder, chunks) = slice.as_rchunks();
+assert_eq!(remainder, &['l']);
+assert_eq!(chunks, &[['o', 'r'], ['e', 'm']]);
+
source

pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are array references and do not overlap. If N does not divide the +length of the slice, then the last up to N-1 elements will be omitted and can be +retrieved from the remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.array_chunks();
+assert_eq!(iter.next().unwrap(), &['l', 'o']);
+assert_eq!(iter.next().unwrap(), &['r', 'e']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['m']);
+
source

pub unsafe fn as_chunks_unchecked_mut<const N: usize>( + &mut self +) -> &mut [[T; N]]

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +assuming that there’s no remainder.

+
Safety
+

This may only be called when

+
    +
  • The slice splits exactly into N-element chunks (aka self.len() % N == 0).
  • +
  • N != 0.
  • +
+
Examples
+
#![feature(slice_as_chunks)]
+let slice: &mut [char] = &mut ['l', 'o', 'r', 'e', 'm', '!'];
+let chunks: &mut [[char; 1]] =
+    // SAFETY: 1-element chunks never have remainder
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[0] = ['L'];
+assert_eq!(chunks, &[['L'], ['o'], ['r'], ['e'], ['m'], ['!']]);
+let chunks: &mut [[char; 3]] =
+    // SAFETY: The slice length (6) is a multiple of 3
+    unsafe { slice.as_chunks_unchecked_mut() };
+chunks[1] = ['a', 'x', '?'];
+assert_eq!(slice, &['L', 'o', 'r', 'a', 'x', '?']);
+
+// These would be unsound:
+// let chunks: &[[_; 5]] = slice.as_chunks_unchecked_mut() // The slice length is not a multiple of 5
+// let chunks: &[[_; 0]] = slice.as_chunks_unchecked_mut() // Zero-length chunks are never allowed
+
source

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

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the beginning of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (chunks, remainder) = v.as_chunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 9]);
+
source

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

🔬This is a nightly-only experimental API. (slice_as_chunks)

Splits the slice into a slice of N-element arrays, +starting at the end of the slice, +and a remainder slice with length strictly less than N.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(slice_as_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+let (remainder, chunks) = v.as_rchunks_mut();
+remainder[0] = 9;
+for chunk in chunks {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[9, 1, 1, 2, 2]);
+
source

pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N>

🔬This is a nightly-only experimental API. (array_chunks)

Returns an iterator over N elements of the slice at a time, starting at the +beginning of the slice.

+

The chunks are mutable array references and do not overlap. If N does not divide +the length of the slice, then the last up to N-1 elements will be omitted and +can be retrieved from the into_remainder function of the iterator.

+

This method is the const generic equivalent of chunks_exact_mut.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_chunks)]
+let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.array_chunks_mut() {
+    *chunk = [count; 2];
+    count += 1;
+}
+assert_eq!(v, &[1, 1, 2, 2, 0]);
+
source

pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N>

🔬This is a nightly-only experimental API. (array_windows)

Returns an iterator over overlapping windows of N elements of a slice, +starting at the beginning of the slice.

+

This is the const generic equivalent of windows.

+

If N is greater than the size of the slice, it will return no windows.

+
Panics
+

Panics if N is 0. This check will most probably get changed to a compile time +error before this method gets stabilized.

+
Examples
+
#![feature(array_windows)]
+let slice = [0, 1, 2, 3];
+let mut iter = slice.array_windows();
+assert_eq!(iter.next().unwrap(), &[0, 1]);
+assert_eq!(iter.next().unwrap(), &[1, 2]);
+assert_eq!(iter.next().unwrap(), &[2, 3]);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact for a variant of this iterator that returns chunks of always exactly +chunk_size elements, and chunks for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert_eq!(iter.next().unwrap(), &['l']);
+assert!(iter.next().is_none());
+
1.31.0 · source

pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last chunk will not have length chunk_size.

+

See rchunks_exact_mut for a variant of this iterator that returns chunks of always +exactly chunk_size elements, and chunks_mut for the same iterator but starting at the +beginning of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[3, 2, 2, 1, 1]);
+
1.31.0 · source

pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the +end of the slice.

+

The chunks are slices and do not overlap. If chunk_size does not divide the length of the +slice, then the last up to chunk_size-1 elements will be omitted and can be retrieved +from the remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of rchunks.

+

See rchunks for a variant of this iterator that also returns the remainder as a smaller +chunk, and chunks_exact for the same iterator but starting at the beginning of the +slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let slice = ['l', 'o', 'r', 'e', 'm'];
+let mut iter = slice.rchunks_exact(2);
+assert_eq!(iter.next().unwrap(), &['e', 'm']);
+assert_eq!(iter.next().unwrap(), &['o', 'r']);
+assert!(iter.next().is_none());
+assert_eq!(iter.remainder(), &['l']);
+
1.31.0 · source

pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T>

Returns an iterator over chunk_size elements of the slice at a time, starting at the end +of the slice.

+

The chunks are mutable slices, and do not overlap. If chunk_size does not divide the +length of the slice, then the last up to chunk_size-1 elements will be omitted and can be +retrieved from the into_remainder function of the iterator.

+

Due to each chunk having exactly chunk_size elements, the compiler can often optimize the +resulting code better than in the case of chunks_mut.

+

See rchunks_mut for a variant of this iterator that also returns the remainder as a +smaller chunk, and chunks_exact_mut for the same iterator but starting at the beginning +of the slice.

+
Panics
+

Panics if chunk_size is 0.

+
Examples
+
let v = &mut [0, 0, 0, 0, 0];
+let mut count = 1;
+
+for chunk in v.rchunks_exact_mut(2) {
+    for elem in chunk.iter_mut() {
+        *elem += count;
+    }
+    count += 1;
+}
+assert_eq!(v, &[0, 2, 2, 1, 1]);
+
source

pub fn group_by<F>(&self, pred: F) -> GroupBy<'_, T, F>where + F: FnMut(&T, &T) -> bool,

🔬This is a nightly-only experimental API. (slice_group_by)

Returns an iterator over the slice producing non-overlapping runs +of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&[3, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &[1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&[1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3][..]));
+assert_eq!(iter.next(), Some(&[2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
source

pub fn group_by_mut<F>(&mut self, pred: F) -> GroupByMut<'_, T, F>where + F: FnMut(&T, &T) -> bool,

🔬This is a nightly-only experimental API. (slice_group_by)

Returns an iterator over the slice producing non-overlapping mutable +runs of elements using the predicate to separate them.

+

The predicate is called on two elements following themselves, +it means the predicate is called on slice[0] and slice[1] +then on slice[1] and slice[2] and so on.

+
Examples
+
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 1, 3, 3, 2, 2, 2];
+
+let mut iter = slice.group_by_mut(|a, b| a == b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 1][..]));
+assert_eq!(iter.next(), Some(&mut [3, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 2, 2][..]));
+assert_eq!(iter.next(), None);
+

This method can be used to extract the sorted subslices:

+ +
#![feature(slice_group_by)]
+
+let slice = &mut [1, 1, 2, 3, 2, 3, 2, 3, 4];
+
+let mut iter = slice.group_by_mut(|a, b| a <= b);
+
+assert_eq!(iter.next(), Some(&mut [1, 1, 2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3][..]));
+assert_eq!(iter.next(), Some(&mut [2, 3, 4][..]));
+assert_eq!(iter.next(), None);
+
1.0.0 · source

pub fn split_at(&self, mid: usize) -> (&[T], &[T])

Divides one slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let v = [1, 2, 3, 4, 5, 6];
+
+{
+   let (left, right) = v.split_at(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_at(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
1.0.0 · source

pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T])

Divides one mutable slice into two at an index.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+
Panics
+

Panics if mid > len.

+
Examples
+
let mut v = [1, 0, 3, 0, 5, 6];
+let (left, right) = v.split_at_mut(2);
+assert_eq!(left, [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub unsafe fn split_at_unchecked(&self, mid: usize) -> (&[T], &[T])

🔬This is a nightly-only experimental API. (slice_split_at_unchecked)

Divides one slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let v = [1, 2, 3, 4, 5, 6];
+
+unsafe {
+   let (left, right) = v.split_at_unchecked(0);
+   assert_eq!(left, []);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(2);
+    assert_eq!(left, [1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+unsafe {
+    let (left, right) = v.split_at_unchecked(6);
+    assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

pub unsafe fn split_at_mut_unchecked( + &mut self, + mid: usize +) -> (&mut [T], &mut [T])

🔬This is a nightly-only experimental API. (slice_split_at_unchecked)

Divides one mutable slice into two at an index, without doing bounds checking.

+

The first will contain all indices from [0, mid) (excluding +the index mid itself) and the second will contain all +indices from [mid, len) (excluding the index len itself).

+

For a safe alternative see split_at_mut.

+
Safety
+

Calling this method with an out-of-bounds index is undefined behavior +even if the resulting reference is not used. The caller has to ensure that +0 <= mid <= self.len().

+
Examples
+
#![feature(slice_split_at_unchecked)]
+
+let mut v = [1, 0, 3, 0, 5, 6];
+// scoped to restrict the lifetime of the borrows
+unsafe {
+    let (left, right) = v.split_at_mut_unchecked(2);
+    assert_eq!(left, [1, 0]);
+    assert_eq!(right, [3, 0, 5, 6]);
+    left[1] = 2;
+    right[1] = 4;
+}
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub fn split_array_ref<const N: usize>(&self) -> (&[T; N], &[T])

🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.split_array_ref::<0>();
+   assert_eq!(left, &[]);
+   assert_eq!(right, [1, 2, 3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<2>();
+    assert_eq!(left, &[1, 2]);
+    assert_eq!(right, [3, 4, 5, 6]);
+}
+
+{
+    let (left, right) = v.split_array_ref::<6>();
+    assert_eq!(left, &[1, 2, 3, 4, 5, 6]);
+    assert_eq!(right, []);
+}
+
source

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

🔬This is a nightly-only experimental API. (split_array)

Divides one mutable slice into an array and a remainder slice at an index.

+

The array will contain all indices from [0, N) (excluding +the index N itself) and the slice will contain all +indices from [N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.split_array_mut::<2>();
+assert_eq!(left, &mut [1, 0]);
+assert_eq!(right, [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
source

pub fn rsplit_array_ref<const N: usize>(&self) -> (&[T], &[T; N])

🔬This is a nightly-only experimental API. (split_array)

Divides one slice into an array and a remainder slice at an index from +the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index len - N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let v = &[1, 2, 3, 4, 5, 6][..];
+
+{
+   let (left, right) = v.rsplit_array_ref::<0>();
+   assert_eq!(left, [1, 2, 3, 4, 5, 6]);
+   assert_eq!(right, &[]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<2>();
+    assert_eq!(left, [1, 2, 3, 4]);
+    assert_eq!(right, &[5, 6]);
+}
+
+{
+    let (left, right) = v.rsplit_array_ref::<6>();
+    assert_eq!(left, []);
+    assert_eq!(right, &[1, 2, 3, 4, 5, 6]);
+}
+
source

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

🔬This is a nightly-only experimental API. (split_array)

Divides one mutable slice into an array and a remainder slice at an +index from the end.

+

The slice will contain all indices from [0, len - N) (excluding +the index N itself) and the array will contain all +indices from [len - N, len) (excluding the index len itself).

+
Panics
+

Panics if N > len.

+
Examples
+
#![feature(split_array)]
+
+let mut v = &mut [1, 0, 3, 0, 5, 6][..];
+let (left, right) = v.rsplit_array_mut::<4>();
+assert_eq!(left, [1, 0]);
+assert_eq!(right, &mut [3, 0, 5, 6]);
+left[1] = 2;
+right[1] = 4;
+assert_eq!(v, [1, 2, 3, 4, 5, 6]);
+
1.0.0 · source

pub fn split<F>(&self, pred: F) -> Split<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is not contained in the subslices.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the first element is matched, an empty slice will be the first item +returned by the iterator. Similarly, if the last element in the slice +is matched, an empty slice will be the last item returned by the +iterator:

+ +
let slice = [10, 40, 33];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert!(iter.next().is_none());
+

If two matched elements are directly adjacent, an empty slice will be +present between them:

+ +
let slice = [10, 6, 33, 20];
+let mut iter = slice.split(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10]);
+assert_eq!(iter.next().unwrap(), &[]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+
1.0.0 · source

pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_mut(|num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 1]);
+
1.51.0 · source

pub fn split_inclusive<F>(&self, pred: F) -> SplitInclusive<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred. The matched element is contained in the end of the previous +subslice as a terminator.

+
Examples
+
let slice = [10, 40, 33, 20];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert_eq!(iter.next().unwrap(), &[20]);
+assert!(iter.next().is_none());
+

If the last element of the slice is matched, +that element will be considered the terminator of the preceding slice. +That slice will be the last item returned by the iterator.

+ +
let slice = [3, 10, 40, 33];
+let mut iter = slice.split_inclusive(|num| num % 3 == 0);
+
+assert_eq!(iter.next().unwrap(), &[3]);
+assert_eq!(iter.next().unwrap(), &[10, 40, 33]);
+assert!(iter.next().is_none());
+
1.51.0 · source

pub fn split_inclusive_mut<F>(&mut self, pred: F) -> SplitInclusiveMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred. The matched element is contained in the previous +subslice as a terminator.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.split_inclusive_mut(|num| *num % 3 == 0) {
+    let terminator_idx = group.len()-1;
+    group[terminator_idx] = 1;
+}
+assert_eq!(v, [10, 40, 1, 20, 1, 1]);
+
1.27.0 · source

pub fn rsplit<F>(&self, pred: F) -> RSplit<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, starting at the end of the slice and working backwards. +The matched element is not contained in the subslices.

+
Examples
+
let slice = [11, 22, 33, 0, 44, 55];
+let mut iter = slice.rsplit(|num| *num == 0);
+
+assert_eq!(iter.next().unwrap(), &[44, 55]);
+assert_eq!(iter.next().unwrap(), &[11, 22, 33]);
+assert_eq!(iter.next(), None);
+

As with split(), if the first or last element is matched, an empty +slice will be the first (or last) item returned by the iterator.

+ +
let v = &[0, 1, 1, 2, 3, 5, 8];
+let mut it = v.rsplit(|n| *n % 2 == 0);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next().unwrap(), &[3, 5]);
+assert_eq!(it.next().unwrap(), &[1, 1]);
+assert_eq!(it.next().unwrap(), &[]);
+assert_eq!(it.next(), None);
+
1.27.0 · source

pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that +match pred, starting at the end of the slice and working +backwards. The matched element is not contained in the subslices.

+
Examples
+
let mut v = [100, 400, 300, 200, 600, 500];
+
+let mut count = 0;
+for group in v.rsplit_mut(|num| *num % 3 == 0) {
+    count += 1;
+    group[0] = count;
+}
+assert_eq!(v, [3, 400, 300, 2, 600, 1]);
+
1.0.0 · source

pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once by numbers divisible by 3 (i.e., [10, 40], +[20, 60, 50]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over mutable subslices separated by elements that match +pred, limited to returning at most n items. The matched element is +not contained in the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut v = [10, 40, 30, 20, 60, 50];
+
+for group in v.splitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(v, [1, 40, 30, 1, 60, 50]);
+
1.0.0 · source

pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+

Print the slice split once, starting from the end, by numbers divisible +by 3 (i.e., [50], [10, 40, 30, 20]):

+ +
let v = [10, 40, 30, 20, 60, 50];
+
+for group in v.rsplitn(2, |num| *num % 3 == 0) {
+    println!("{group:?}");
+}
+
1.0.0 · source

pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<'_, T, F>where + F: FnMut(&T) -> bool,

Returns an iterator over subslices separated by elements that match +pred limited to returning at most n items. This starts at the end of +the slice and works backwards. The matched element is not contained in +the subslices.

+

The last element returned, if any, will contain the remainder of the +slice.

+
Examples
+
let mut s = [10, 40, 30, 20, 60, 50];
+
+for group in s.rsplitn_mut(2, |num| *num % 3 == 0) {
+    group[0] = 1;
+}
+assert_eq!(s, [1, 40, 30, 20, 60, 1]);
+
1.0.0 · source

pub fn contains(&self, x: &T) -> boolwhere + T: PartialEq<T>,

Returns true if the slice contains an element with the given value.

+

This operation is O(n).

+

Note that if you have a sorted slice, binary_search may be faster.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.contains(&30));
+assert!(!v.contains(&50));
+

If you do not have a &T, but some other value that you can compare +with one (for example, String implements PartialEq<str>), you can +use iter().any:

+ +
let v = [String::from("hello"), String::from("world")]; // slice of `String`
+assert!(v.iter().any(|e| e == "hello")); // search with `&str`
+assert!(!v.iter().any(|e| e == "hi"));
+
1.0.0 · source

pub fn starts_with(&self, needle: &[T]) -> boolwhere + T: PartialEq<T>,

Returns true if needle is a prefix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.starts_with(&[10]));
+assert!(v.starts_with(&[10, 40]));
+assert!(!v.starts_with(&[50]));
+assert!(!v.starts_with(&[10, 50]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.starts_with(&[]));
+let v: &[u8] = &[];
+assert!(v.starts_with(&[]));
+
1.0.0 · source

pub fn ends_with(&self, needle: &[T]) -> boolwhere + T: PartialEq<T>,

Returns true if needle is a suffix of the slice.

+
Examples
+
let v = [10, 40, 30];
+assert!(v.ends_with(&[30]));
+assert!(v.ends_with(&[40, 30]));
+assert!(!v.ends_with(&[50]));
+assert!(!v.ends_with(&[50, 30]));
+

Always returns true if needle is an empty slice:

+ +
let v = &[10, 40, 30];
+assert!(v.ends_with(&[]));
+let v: &[u8] = &[];
+assert!(v.ends_with(&[]));
+
1.51.0 · source

pub fn strip_prefix<P>(&self, prefix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq<T>,

Returns a subslice with the prefix removed.

+

If the slice starts with prefix, returns the subslice after the prefix, wrapped in Some. +If prefix is empty, simply returns the original slice.

+

If the slice does not start with prefix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_prefix(&[10]), Some(&[40, 30][..]));
+assert_eq!(v.strip_prefix(&[10, 40]), Some(&[30][..]));
+assert_eq!(v.strip_prefix(&[50]), None);
+assert_eq!(v.strip_prefix(&[10, 50]), None);
+
+let prefix : &str = "he";
+assert_eq!(b"hello".strip_prefix(prefix.as_bytes()),
+           Some(b"llo".as_ref()));
+
1.51.0 · source

pub fn strip_suffix<P>(&self, suffix: &P) -> Option<&[T]>where + P: SlicePattern<Item = T> + ?Sized, + T: PartialEq<T>,

Returns a subslice with the suffix removed.

+

If the slice ends with suffix, returns the subslice before the suffix, wrapped in Some. +If suffix is empty, simply returns the original slice.

+

If the slice does not end with suffix, returns None.

+
Examples
+
let v = &[10, 40, 30];
+assert_eq!(v.strip_suffix(&[30]), Some(&[10, 40][..]));
+assert_eq!(v.strip_suffix(&[40, 30]), Some(&[10][..]));
+assert_eq!(v.strip_suffix(&[50]), None);
+assert_eq!(v.strip_suffix(&[50, 30]), None);
+

Binary searches this slice for a given element. +If the slice is not sorted, the returned result is unspecified and +meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search_by, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+assert_eq!(s.binary_search(&13),  Ok(9));
+assert_eq!(s.binary_search(&4),   Err(7));
+assert_eq!(s.binary_search(&100), Err(13));
+let r = s.binary_search(&1);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+

If you want to find that whole range of matching items, rather than +an arbitrary matching one, that can be done using partition_point:

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let low = s.partition_point(|x| x < &1);
+assert_eq!(low, 1);
+let high = s.partition_point(|x| x <= &1);
+assert_eq!(high, 5);
+let r = s.binary_search(&1);
+assert!((low..high).contains(&r.unwrap()));
+
+assert!(s[..low].iter().all(|&x| x < 1));
+assert!(s[low..high].iter().all(|&x| x == 1));
+assert!(s[high..].iter().all(|&x| x > 1));
+
+// For something not found, the "range" of equal items is empty
+assert_eq!(s.partition_point(|x| x < &11), 9);
+assert_eq!(s.partition_point(|x| x <= &11), 9);
+assert_eq!(s.binary_search(&11), Err(9));
+

If you want to insert an item to a sorted vector, while maintaining +sort order, consider using partition_point:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+// The above is equivalent to `let idx = s.binary_search(&num).unwrap_or_else(|x| x);`
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
1.0.0 · source

pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>where + F: FnMut(&'a T) -> Ordering,

Binary searches this slice with a comparator function.

+

The comparator function should return an order code that indicates +whether its argument is Less, Equal or Greater the desired +target. +If the slice is not sorted or if the comparator function does not +implement an order consistent with the sort order of the underlying +slice, the returned result is unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by_key, and partition_point.

+
Examples
+

Looks up a series of four elements. The first is found, with a +uniquely determined position; the second and third are not +found; the fourth could match any position in [1, 4].

+ +
let s = [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+
+let seek = 13;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Ok(9));
+let seek = 4;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(7));
+let seek = 100;
+assert_eq!(s.binary_search_by(|probe| probe.cmp(&seek)), Err(13));
+let seek = 1;
+let r = s.binary_search_by(|probe| probe.cmp(&seek));
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.10.0 · source

pub fn binary_search_by_key<'a, B, F>( + &'a self, + b: &B, + f: F +) -> Result<usize, usize>where + F: FnMut(&'a T) -> B, + B: Ord,

Binary searches this slice with a key extraction function.

+

Assumes that the slice is sorted by the key, for instance with +sort_by_key using the same key extraction function. +If the slice is not sorted by the key, the returned result is +unspecified and meaningless.

+

If the value is found then Result::Ok is returned, containing the +index of the matching element. If there are multiple matches, then any +one of the matches could be returned. The index is chosen +deterministically, but is subject to change in future versions of Rust. +If the value is not found then Result::Err is returned, containing +the index where a matching element could be inserted while maintaining +sorted order.

+

See also binary_search, binary_search_by, and partition_point.

+
Examples
+

Looks up a series of four elements in a slice of pairs sorted by +their second elements. The first is found, with a uniquely +determined position; the second and third are not found; the +fourth could match any position in [1, 4].

+ +
let s = [(0, 0), (2, 1), (4, 1), (5, 1), (3, 1),
+         (1, 2), (2, 3), (4, 5), (5, 8), (3, 13),
+         (1, 21), (2, 34), (4, 55)];
+
+assert_eq!(s.binary_search_by_key(&13, |&(a, b)| b),  Ok(9));
+assert_eq!(s.binary_search_by_key(&4, |&(a, b)| b),   Err(7));
+assert_eq!(s.binary_search_by_key(&100, |&(a, b)| b), Err(13));
+let r = s.binary_search_by_key(&1, |&(a, b)| b);
+assert!(match r { Ok(1..=4) => true, _ => false, });
+
1.20.0 · source

pub fn sort_unstable(&mut self)where + T: Ord,

Sorts the slice, but might not preserve the order of equal elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort_unstable();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.20.0 · source

pub fn sort_unstable_by<F>(&mut self, compare: F)where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_unstable_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

It is typically faster than stable sorting, except in a few special cases, e.g., when the +slice consists of several concatenated sorted sequences.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_unstable_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_unstable_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.20.0 · source

pub fn sort_unstable_by_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function, but might not preserve the order of equal +elements.

+

This sort is unstable (i.e., may reorder equal elements), in-place +(i.e., does not allocate), and O(m * n * log(n)) worst-case, where the key function is +O(m).

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

Due to its key calling strategy, sort_unstable_by_key +is likely to be slower than sort_by_cached_key in +cases where the key function is expensive.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_unstable_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.49.0 · source

pub fn select_nth_unstable( + &mut self, + index: usize +) -> (&mut [T], &mut T, &mut [T])where + T: Ord,

Reorder the slice such that the element at index is at its final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index. Additionally, this reordering is +unstable (i.e. any number of equal elements may end up at position index), in-place +(i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from the reordered slice: +the subslice prior to index, the element at index, and the subslice after index; +accordingly, the values in those two subslices will respectively all be less-than-or-equal-to +and greater-than-or-equal-to the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median
+v.select_nth_unstable(2);
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [-3, -5, 1, 2, 4] ||
+        v == [-5, -3, 1, 2, 4] ||
+        v == [-3, -5, 1, 4, 2] ||
+        v == [-5, -3, 1, 4, 2]);
+
1.49.0 · source

pub fn select_nth_unstable_by<F>( + &mut self, + index: usize, + compare: F +) -> (&mut [T], &mut T, &mut [T])where + F: FnMut(&T, &T) -> Ordering,

Reorder the slice with a comparator function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the comparator function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided comparator function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Find the median as if the slice were sorted in descending order.
+v.select_nth_unstable_by(2, |a, b| b.cmp(a));
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [2, 4, 1, -5, -3] ||
+        v == [2, 4, 1, -3, -5] ||
+        v == [4, 2, 1, -5, -3] ||
+        v == [4, 2, 1, -3, -5]);
+
1.49.0 · source

pub fn select_nth_unstable_by_key<K, F>( + &mut self, + index: usize, + f: F +) -> (&mut [T], &mut T, &mut [T])where + F: FnMut(&T) -> K, + K: Ord,

Reorder the slice with a key extraction function such that the element at index is at its +final sorted position.

+

This reordering has the additional property that any value at position i < index will be +less than or equal to any value at a position j > index using the key extraction function. +Additionally, this reordering is unstable (i.e. any number of equal elements may end up at +position index), in-place (i.e. does not allocate), and runs in O(n) time. +This function is also known as “kth element” in other libraries.

+

It returns a triplet of the following from +the slice reordered according to the provided key extraction function: the subslice prior to +index, the element at index, and the subslice after index; accordingly, the values in +those two subslices will respectively all be less-than-or-equal-to and greater-than-or-equal-to +the value of the element at index.

+
Current implementation
+

The current algorithm is an introselect implementation based on Pattern Defeating Quicksort, which is also +the basis for sort_unstable. The fallback algorithm is Median of Medians using Tukey’s Ninther for +pivot selection, which guarantees linear runtime for all inputs.

+
Panics
+

Panics when index >= len(), meaning it always panics on empty slices.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+// Return the median as if the array were sorted according to absolute value.
+v.select_nth_unstable_by_key(2, |a| a.abs());
+
+// We are only guaranteed the slice will be one of the following, based on the way we sort
+// about the specified index.
+assert!(v == [1, 2, -3, 4, -5] ||
+        v == [1, 2, -3, -5, 4] ||
+        v == [2, 1, -3, 4, -5] ||
+        v == [2, 1, -3, -5, 4]);
+
source

pub fn partition_dedup(&mut self) -> (&mut [T], &mut [T])where + T: PartialEq<T>,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all consecutive repeated elements to the end of the slice according to the +PartialEq trait implementation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [1, 2, 2, 3, 3, 2, 1, 1];
+
+let (dedup, duplicates) = slice.partition_dedup();
+
+assert_eq!(dedup, [1, 2, 3, 2, 1]);
+assert_eq!(duplicates, [2, 3, 1]);
+
source

pub fn partition_dedup_by<F>(&mut self, same_bucket: F) -> (&mut [T], &mut [T])where + F: FnMut(&mut T, &mut T) -> bool,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice satisfying +a given equality relation.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

The same_bucket function is passed references to two elements from the slice and +must determine if the elements compare equal. The elements are passed in opposite order +from their order in the slice, so if same_bucket(a, b) returns true, a is moved +at the end of the slice.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = ["foo", "Foo", "BAZ", "Bar", "bar", "baz", "BAZ"];
+
+let (dedup, duplicates) = slice.partition_dedup_by(|a, b| a.eq_ignore_ascii_case(b));
+
+assert_eq!(dedup, ["foo", "BAZ", "Bar", "baz"]);
+assert_eq!(duplicates, ["bar", "Foo", "BAZ"]);
+
source

pub fn partition_dedup_by_key<K, F>(&mut self, key: F) -> (&mut [T], &mut [T])where + F: FnMut(&mut T) -> K, + K: PartialEq<K>,

🔬This is a nightly-only experimental API. (slice_partition_dedup)

Moves all but the first of consecutive elements to the end of the slice that resolve +to the same key.

+

Returns two slices. The first contains no consecutive repeated elements. +The second contains all the duplicates in no specified order.

+

If the slice is sorted, the first returned slice contains no duplicates.

+
Examples
+
#![feature(slice_partition_dedup)]
+
+let mut slice = [10, 20, 21, 30, 30, 20, 11, 13];
+
+let (dedup, duplicates) = slice.partition_dedup_by_key(|i| *i / 10);
+
+assert_eq!(dedup, [10, 20, 30, 20, 11]);
+assert_eq!(duplicates, [21, 30, 13]);
+
1.26.0 · source

pub fn rotate_left(&mut self, mid: usize)

Rotates the slice in-place such that the first mid elements of the +slice move to the end while the last self.len() - mid elements move to +the front. After calling rotate_left, the element previously at index +mid will become the first element in the slice.

+
Panics
+

This function will panic if mid is greater than the length of the +slice. Note that mid == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_left(2);
+assert_eq!(a, ['c', 'd', 'e', 'f', 'a', 'b']);
+

Rotating a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_left(1);
+assert_eq!(a, ['a', 'c', 'd', 'e', 'b', 'f']);
+
1.26.0 · source

pub fn rotate_right(&mut self, k: usize)

Rotates the slice in-place such that the first self.len() - k +elements of the slice move to the end while the last k elements move +to the front. After calling rotate_right, the element previously at +index self.len() - k will become the first element in the slice.

+
Panics
+

This function will panic if k is greater than the length of the +slice. Note that k == self.len() does not panic and is a no-op +rotation.

+
Complexity
+

Takes linear (in self.len()) time.

+
Examples
+
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a.rotate_right(2);
+assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
+

Rotate a subslice:

+ +
let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
+a[1..5].rotate_right(1);
+assert_eq!(a, ['a', 'e', 'b', 'c', 'd', 'f']);
+
1.50.0 · source

pub fn fill(&mut self, value: T)where + T: Clone,

Fills self with elements by cloning value.

+
Examples
+
let mut buf = vec![0; 10];
+buf.fill(1);
+assert_eq!(buf, vec![1; 10]);
+
1.51.0 · source

pub fn fill_with<F>(&mut self, f: F)where + F: FnMut() -> T,

Fills self with elements returned by calling a closure repeatedly.

+

This method uses a closure to create new values. If you’d rather +Clone a given value, use fill. If you want to use the Default +trait to generate values, you can pass Default::default as the +argument.

+
Examples
+
let mut buf = vec![1; 10];
+buf.fill_with(Default::default);
+assert_eq!(buf, vec![0; 10]);
+
1.7.0 · source

pub fn clone_from_slice(&mut self, src: &[T])where + T: Clone,

Copies the elements from src into self.

+

The length of src must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Cloning two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.clone_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use clone_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].clone_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.clone_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.9.0 · source

pub fn copy_from_slice(&mut self, src: &[T])where + T: Copy,

Copies all elements from src into self, using a memcpy.

+

The length of src must be the same as self.

+

If T does not implement Copy, use clone_from_slice.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Examples
+

Copying two elements from a slice into another:

+ +
let src = [1, 2, 3, 4];
+let mut dst = [0, 0];
+
+// Because the slices have to be the same length,
+// we slice the source slice from four elements
+// to two. It will panic if we don't do this.
+dst.copy_from_slice(&src[2..]);
+
+assert_eq!(src, [1, 2, 3, 4]);
+assert_eq!(dst, [3, 4]);
+

Rust enforces that there can only be one mutable reference with no +immutable references to a particular piece of data in a particular +scope. Because of this, attempting to use copy_from_slice on a +single slice will result in a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+slice[..2].copy_from_slice(&slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.copy_from_slice(&right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 4, 5]);
+
1.37.0 · source

pub fn copy_within<R>(&mut self, src: R, dest: usize)where + R: RangeBounds<usize>, + T: Copy,

Copies elements from one part of the slice to another part of itself, +using a memmove.

+

src is the range within self to copy from. dest is the starting +index of the range within self to copy to, which will have the same +length as src. The two ranges may overlap. The ends of the two ranges +must be less than or equal to self.len().

+
Panics
+

This function will panic if either range exceeds the end of the slice, +or if the end of src is before the start.

+
Examples
+

Copying four bytes within a slice:

+ +
let mut bytes = *b"Hello, World!";
+
+bytes.copy_within(1..5, 8);
+
+assert_eq!(&bytes, b"Hello, Wello!");
+
1.27.0 · source

pub fn swap_with_slice(&mut self, other: &mut [T])

Swaps all elements in self with those in other.

+

The length of other must be the same as self.

+
Panics
+

This function will panic if the two slices have different lengths.

+
Example
+

Swapping two elements across slices:

+ +
let mut slice1 = [0, 0];
+let mut slice2 = [1, 2, 3, 4];
+
+slice1.swap_with_slice(&mut slice2[2..]);
+
+assert_eq!(slice1, [3, 4]);
+assert_eq!(slice2, [1, 2, 0, 0]);
+

Rust enforces that there can only be one mutable reference to a +particular piece of data in a particular scope. Because of this, +attempting to use swap_with_slice on a single slice will result in +a compile failure:

+ +
let mut slice = [1, 2, 3, 4, 5];
+slice[..2].swap_with_slice(&mut slice[3..]); // compile fail!
+

To work around this, we can use split_at_mut to create two distinct +mutable sub-slices from a slice:

+ +
let mut slice = [1, 2, 3, 4, 5];
+
+{
+    let (left, right) = slice.split_at_mut(2);
+    left.swap_with_slice(&mut right[1..]);
+}
+
+assert_eq!(slice, [4, 5, 3, 1, 2]);
+
1.30.0 · source

pub unsafe fn align_to<U>(&self) -> (&[T], &[U], &[T])

Transmute the slice to a slice of another type, ensuring alignment of the types is +maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
1.30.0 · source

pub unsafe fn align_to_mut<U>(&mut self) -> (&mut [T], &mut [U], &mut [T])

Transmute the mutable slice to a mutable slice of another type, ensuring alignment of the +types is maintained.

+

This method splits the slice into three distinct slices: prefix, correctly aligned middle +slice of a new type, and the suffix slice. How exactly the slice is split up is not +specified; the middle part may be smaller than necessary. However, if this fails to return a +maximal middle part, that is because code is running in a context where performance does not +matter, such as a sanitizer attempting to find alignment bugs. Regular code running +in a default (debug or release) execution will return a maximal middle part.

+

This method has no purpose when either input element T or output element U are +zero-sized and will return the original slice without splitting anything.

+
Safety
+

This method is essentially a transmute with respect to the elements in the returned +middle slice, so all the usual caveats pertaining to transmute::<T, U> also apply here.

+
Examples
+

Basic usage:

+ +
unsafe {
+    let mut bytes: [u8; 7] = [1, 2, 3, 4, 5, 6, 7];
+    let (prefix, shorts, suffix) = bytes.align_to_mut::<u16>();
+    // less_efficient_algorithm_for_bytes(prefix);
+    // more_efficient_algorithm_for_aligned_shorts(shorts);
+    // less_efficient_algorithm_for_bytes(suffix);
+}
+
source

pub fn as_simd<const LANES: usize>(&self) -> (&[T], &[Simd<T, LANES>], &[T])where + Simd<T, LANES>: AsRef<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a slice into a prefix, a middle of aligned SIMD types, and a suffix.

+

This is a safe wrapper around slice::align_to, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
Examples
+
#![feature(portable_simd)]
+use core::simd::SimdFloat;
+
+let short = &[1, 2, 3];
+let (prefix, middle, suffix) = short.as_simd::<4>();
+assert_eq!(middle, []); // Not enough elements for anything in the middle
+
+// They might be split in any possible way between prefix and suffix
+let it = prefix.iter().chain(suffix).copied();
+assert_eq!(it.collect::<Vec<_>>(), vec![1, 2, 3]);
+
+fn basic_simd_sum(x: &[f32]) -> f32 {
+    use std::ops::Add;
+    use std::simd::f32x4;
+    let (prefix, middle, suffix) = x.as_simd();
+    let sums = f32x4::from_array([
+        prefix.iter().copied().sum(),
+        0.0,
+        0.0,
+        suffix.iter().copied().sum(),
+    ]);
+    let sums = middle.iter().copied().fold(sums, f32x4::add);
+    sums.reduce_sum()
+}
+
+let numbers: Vec<f32> = (1..101).map(|x| x as _).collect();
+assert_eq!(basic_simd_sum(&numbers[1..99]), 4949.0);
+
source

pub fn as_simd_mut<const LANES: usize>( + &mut self +) -> (&mut [T], &mut [Simd<T, LANES>], &mut [T])where + Simd<T, LANES>: AsMut<[T; LANES]>, + T: SimdElement, + LaneCount<LANES>: SupportedLaneCount,

🔬This is a nightly-only experimental API. (portable_simd)

Split a mutable slice into a mutable prefix, a middle of aligned SIMD types, +and a mutable suffix.

+

This is a safe wrapper around slice::align_to_mut, so has the same weak +postconditions as that method. You’re only assured that +self.len() == prefix.len() + middle.len() * LANES + suffix.len().

+

Notably, all of the following are possible:

+
    +
  • prefix.len() >= LANES.
  • +
  • middle.is_empty() despite self.len() >= 3 * LANES.
  • +
  • suffix.len() >= LANES.
  • +
+

That said, this is a safe method, so if you’re only writing safe code, +then this can at most cause incorrect logic, not unsoundness.

+

This is the mutable version of slice::as_simd; see that for examples.

+
Panics
+

This will panic if the size of the SIMD type is different from +LANES times that of the scalar.

+

At the time of writing, the trait restrictions on Simd<T, LANES> keeps +that from ever happening, as only power-of-two numbers of lanes are +supported. It’s possible that, in the future, those restrictions might +be lifted in a way that would make it possible to see panics from this +method for something like LANES == 3.

+
source

pub fn is_sorted(&self) -> boolwhere + T: PartialOrd<T>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted.

+

That is, for each element a and its following element b, a <= b must hold. If the +slice yields exactly zero or one element, true is returned.

+

Note that if Self::Item is only PartialOrd, but not Ord, the above definition +implies that this function returns false if any two consecutive items are not +comparable.

+
Examples
+
#![feature(is_sorted)]
+let empty: [i32; 0] = [];
+
+assert!([1, 2, 2, 9].is_sorted());
+assert!(![1, 3, 2, 4].is_sorted());
+assert!([0].is_sorted());
+assert!(empty.is_sorted());
+assert!(![0.0, 1.0, f32::NAN].is_sorted());
+
source

pub fn is_sorted_by<'a, F>(&'a self, compare: F) -> boolwhere + F: FnMut(&'a T, &'a T) -> Option<Ordering>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given comparator function.

+

Instead of using PartialOrd::partial_cmp, this function uses the given compare +function to determine the ordering of two elements. Apart from that, it’s equivalent to +is_sorted; see its documentation for more information.

+
source

pub fn is_sorted_by_key<'a, F, K>(&'a self, f: F) -> boolwhere + F: FnMut(&'a T) -> K, + K: PartialOrd<K>,

🔬This is a nightly-only experimental API. (is_sorted)

Checks if the elements of this slice are sorted using the given key extraction function.

+

Instead of comparing the slice’s elements directly, this function compares the keys of the +elements, as determined by f. Apart from that, it’s equivalent to is_sorted; see its +documentation for more information.

+
Examples
+
#![feature(is_sorted)]
+
+assert!(["c", "bb", "aaa"].is_sorted_by_key(|s| s.len()));
+assert!(![-2i32, -1, 0, 3].is_sorted_by_key(|n| n.abs()));
+
1.52.0 · source

pub fn partition_point<P>(&self, pred: P) -> usizewhere + P: FnMut(&T) -> bool,

Returns the index of the partition point according to the given predicate +(the index of the first element of the second partition).

+

The slice is assumed to be partitioned according to the given predicate. +This means that all elements for which the predicate returns true are at the start of the slice +and all elements for which the predicate returns false are at the end. +For example, [7, 15, 3, 5, 4, 12, 6] is partitioned under the predicate x % 2 != 0 +(all odd numbers are at the start, all even at the end).

+

If this slice is not partitioned, the returned result is unspecified and meaningless, +as this method performs a kind of binary search.

+

See also binary_search, binary_search_by, and binary_search_by_key.

+
Examples
+
let v = [1, 2, 3, 3, 5, 6, 7];
+let i = v.partition_point(|&x| x < 5);
+
+assert_eq!(i, 4);
+assert!(v[..i].iter().all(|&x| x < 5));
+assert!(v[i..].iter().all(|&x| !(x < 5)));
+

If all elements of the slice match the predicate, including if the slice +is empty, then the length of the slice will be returned:

+ +
let a = [2, 4, 8];
+assert_eq!(a.partition_point(|x| x < &100), a.len());
+let a: [i32; 0] = [];
+assert_eq!(a.partition_point(|x| x < &100), 0);
+

If you want to insert an item to a sorted vector, while maintaining +sort order:

+ +
let mut s = vec![0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55];
+let num = 42;
+let idx = s.partition_point(|&x| x < num);
+s.insert(idx, num);
+assert_eq!(s, [0, 1, 1, 1, 1, 2, 3, 5, 8, 13, 21, 34, 42, 55]);
+
source

pub fn take<R, 'a>(self: &mut &'a [T], range: R) -> Option<&'a [T]>where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut first_three = slice.take(..3).unwrap();
+
+assert_eq!(slice, &['d']);
+assert_eq!(first_three, &['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+let mut tail = slice.take(2..).unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(tail, &['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take(5..));
+assert_eq!(None, slice.take(..5));
+assert_eq!(None, slice.take(..=4));
+let expected: &[char] = &['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take(..4));
+
source

pub fn take_mut<R, 'a>(self: &mut &'a mut [T], range: R) -> Option<&'a mut [T]>where + R: OneSidedRange<usize>,

🔬This is a nightly-only experimental API. (slice_take)

Removes the subslice corresponding to the given range +and returns a mutable reference to it.

+

Returns None and does not modify the slice if the given +range is out of bounds.

+

Note that this method only accepts one-sided ranges such as +2.. or ..6, but not 2..6.

+
Examples
+

Taking the first three elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut first_three = slice.take_mut(..3).unwrap();
+
+assert_eq!(slice, &mut ['d']);
+assert_eq!(first_three, &mut ['a', 'b', 'c']);
+

Taking the last two elements of a slice:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+let mut tail = slice.take_mut(2..).unwrap();
+
+assert_eq!(slice, &mut ['a', 'b']);
+assert_eq!(tail, &mut ['c', 'd']);
+

Getting None when range is out of bounds:

+ +
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+
+assert_eq!(None, slice.take_mut(5..));
+assert_eq!(None, slice.take_mut(..5));
+assert_eq!(None, slice.take_mut(..=4));
+let expected: &mut [_] = &mut ['a', 'b', 'c', 'd'];
+assert_eq!(Some(expected), slice.take_mut(..4));
+
source

pub fn take_first<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let first = slice.take_first().unwrap();
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'a');
+
source

pub fn take_first_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the first element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let first = slice.take_first_mut().unwrap();
+*first = 'd';
+
+assert_eq!(slice, &['b', 'c']);
+assert_eq!(first, &'d');
+
source

pub fn take_last<'a>(self: &mut &'a [T]) -> Option<&'a T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a reference +to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &[_] = &['a', 'b', 'c'];
+let last = slice.take_last().unwrap();
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'c');
+
source

pub fn take_last_mut<'a>(self: &mut &'a mut [T]) -> Option<&'a mut T>

🔬This is a nightly-only experimental API. (slice_take)

Removes the last element of the slice and returns a mutable +reference to it.

+

Returns None if the slice is empty.

+
Examples
+
#![feature(slice_take)]
+
+let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
+let last = slice.take_last_mut().unwrap();
+*last = 'd';
+
+assert_eq!(slice, &['a', 'b']);
+assert_eq!(last, &'d');
+
source

pub unsafe fn get_many_unchecked_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> [&mut T; N]

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once, without doing any checks.

+

For a safe alternative see get_many_mut.

+
Safety
+

Calling this method with overlapping or out-of-bounds indices is undefined behavior +even if the resulting references are not used.

+
Examples
+
#![feature(get_many_mut)]
+
+let x = &mut [1, 2, 4];
+
+unsafe {
+    let [a, b] = x.get_many_unchecked_mut([0, 2]);
+    *a *= 10;
+    *b *= 100;
+}
+assert_eq!(x, &[10, 2, 400]);
+
source

pub fn get_many_mut<const N: usize>( + &mut self, + indices: [usize; N] +) -> Result<[&mut T; N], GetManyMutError<N>>

🔬This is a nightly-only experimental API. (get_many_mut)

Returns mutable references to many indices at once.

+

Returns an error if any index is out-of-bounds, or if the same index was +passed more than once.

+
Examples
+
#![feature(get_many_mut)]
+
+let v = &mut [1, 2, 3];
+if let Ok([a, b]) = v.get_many_mut([0, 2]) {
+    *a = 413;
+    *b = 612;
+}
+assert_eq!(v, &[413, 2, 612]);
+
1.23.0 · source

pub fn to_ascii_uppercase(&self) -> Vec<u8, Global>

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII upper case equivalent.

+

ASCII letters ‘a’ to ‘z’ are mapped to ‘A’ to ‘Z’, +but non-ASCII letters are unchanged.

+

To uppercase the value in-place, use make_ascii_uppercase.

+
1.23.0 · source

pub fn to_ascii_lowercase(&self) -> Vec<u8, Global>

Returns a vector containing a copy of this slice where each byte +is mapped to its ASCII lower case equivalent.

+

ASCII letters ‘A’ to ‘Z’ are mapped to ‘a’ to ‘z’, +but non-ASCII letters are unchanged.

+

To lowercase the value in-place, use make_ascii_lowercase.

+
1.0.0 · source

pub fn sort(&mut self)where + T: Ord,

Sorts the slice.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5, 4, 1, -3, 2];
+
+v.sort();
+assert!(v == [-5, -3, 1, 2, 4]);
+
1.0.0 · source

pub fn sort_by<F>(&mut self, compare: F)where + F: FnMut(&T, &T) -> Ordering,

Sorts the slice with a comparator function.

+

This sort is stable (i.e., does not reorder equal elements) and O(n * log(n)) worst-case.

+

The comparator function must define a total ordering for the elements in the slice. If +the ordering is not total, the order of the elements is unspecified. An order is a +total order if it is (for all a, b and c):

+
    +
  • total and antisymmetric: exactly one of a < b, a == b or a > b is true, and
  • +
  • transitive, a < b and b < c implies a < c. The same must hold for both == and >.
  • +
+

For example, while f64 doesn’t implement Ord because NaN != NaN, we can use +partial_cmp as our sort function when we know the slice doesn’t contain a NaN.

+ +
let mut floats = [5f64, 4.0, 1.0, 3.0, 2.0];
+floats.sort_by(|a, b| a.partial_cmp(b).unwrap());
+assert_eq!(floats, [1.0, 2.0, 3.0, 4.0, 5.0]);
+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [5, 4, 1, 3, 2];
+v.sort_by(|a, b| a.cmp(b));
+assert!(v == [1, 2, 3, 4, 5]);
+
+// reverse sorting
+v.sort_by(|a, b| b.cmp(a));
+assert!(v == [5, 4, 3, 2, 1]);
+
1.7.0 · source

pub fn sort_by_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n * log(n)) +worst-case, where the key function is O(m).

+

For expensive key functions (e.g. functions that are not simple property accesses or +basic operations), sort_by_cached_key is likely to be +significantly faster, as it does not recompute element keys.

+

When applicable, unstable sorting is preferred because it is generally faster than stable +sorting and it doesn’t allocate auxiliary memory. +See sort_unstable_by_key.

+
Current implementation
+

The current algorithm is an adaptive, iterative merge sort inspired by +timsort. +It is designed to be very fast in cases where the slice is nearly sorted, or consists of +two or more sorted sequences concatenated one after another.

+

Also, it allocates temporary storage half the size of self, but for short slices a +non-allocating insertion sort is used instead.

+
Examples
+
let mut v = [-5i32, 4, 1, -3, 2];
+
+v.sort_by_key(|k| k.abs());
+assert!(v == [1, 2, -3, 4, -5]);
+
1.34.0 · source

pub fn sort_by_cached_key<K, F>(&mut self, f: F)where + F: FnMut(&T) -> K, + K: Ord,

Sorts the slice with a key extraction function.

+

During sorting, the key function is called at most once per element, by using +temporary storage to remember the results of key evaluation. +The order of calls to the key function is unspecified and may change in future versions +of the standard library.

+

This sort is stable (i.e., does not reorder equal elements) and O(m * n + n * log(n)) +worst-case, where the key function is O(m).

+

For simple key functions (e.g., functions that are property accesses or +basic operations), sort_by_key is likely to be +faster.

+
Current implementation
+

The current algorithm is based on pattern-defeating quicksort by Orson Peters, +which combines the fast average case of randomized quicksort with the fast worst case of +heapsort, while achieving linear time on slices with certain patterns. It uses some +randomization to avoid degenerate cases, but with a fixed seed to always provide +deterministic behavior.

+

In the worst case, the algorithm allocates temporary storage in a Vec<(K, usize)> the +length of the slice.

+
Examples
+
let mut v = [-5i32, 4, 32, -3, 2];
+
+v.sort_by_cached_key(|k| k.to_string());
+assert!(v == [-3, -5, 2, 32, 4]);
+
1.0.0 · source

pub fn to_vec(&self) -> Vec<T, Global>where + T: Clone,

Copies self into a new Vec.

+
Examples
+
let s = [10, 40, 30];
+let x = s.to_vec();
+// Here, `s` and `x` can be modified independently.
+
source

pub fn to_vec_in<A>(&self, alloc: A) -> Vec<T, A>where + A: Allocator, + T: Clone,

🔬This is a nightly-only experimental API. (allocator_api)

Copies self into a new Vec with an allocator.

+
Examples
+
#![feature(allocator_api)]
+
+use std::alloc::System;
+
+let s = [10, 40, 30];
+let x = s.to_vec_in(System);
+// Here, `s` and `x` can be modified independently.
+
1.40.0 · source

pub fn repeat(&self, n: usize) -> Vec<T, Global>where + T: Copy,

Creates a vector by copying a slice n times.

+
Panics
+

This function will panic if the capacity would overflow.

+
Examples
+

Basic usage:

+ +
assert_eq!([1, 2].repeat(3), vec![1, 2, 1, 2, 1, 2]);
+

A panic upon overflow:

+ +
// this will panic at runtime
+b"0123456789abcdef".repeat(usize::MAX);
+
1.0.0 · source

pub fn concat<Item>(&self) -> <[T] as Concat<Item>>::Output where + [T]: Concat<Item>, + Item: ?Sized,

Flattens a slice of T into a single value Self::Output.

+
Examples
+
assert_eq!(["hello", "world"].concat(), "helloworld");
+assert_eq!([[1, 2], [3, 4]].concat(), [1, 2, 3, 4]);
+
1.3.0 · source

pub fn join<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].join(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].join(&0), [1, 2, 0, 3, 4]);
+assert_eq!([[1, 2], [3, 4]].join(&[0, 0][..]), [1, 2, 0, 0, 3, 4]);
+
1.0.0 · source

pub fn connect<Separator>( + &self, + sep: Separator +) -> <[T] as Join<Separator>>::Output where + [T]: Join<Separator>,

👎Deprecated since 1.3.0: renamed to join

Flattens a slice of T into a single value Self::Output, placing a +given separator between each.

+
Examples
+
assert_eq!(["hello", "world"].connect(" "), "hello world");
+assert_eq!([[1, 2], [3, 4]].connect(&0), [1, 2, 0, 3, 4]);
+

Trait Implementations§

source§

impl<E: Clone + Engine> Clone for CircuitDigests<E>where + E::Scalar: Clone,

source§

fn clone(&self) -> CircuitDigests<E>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E: Engine> Deref for CircuitDigests<E>

§

type Target = Vec<<E as Engine>::Scalar, Global>

The resulting type after dereferencing.
source§

fn deref(&self) -> &Self::Target

Dereferences the value.
source§

impl<'de, E: Engine> Deserialize<'de> for CircuitDigests<E>

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E: PartialEq + Engine> PartialEq<CircuitDigests<E>> for CircuitDigests<E>where + E::Scalar: PartialEq,

source§

fn eq(&self, other: &CircuitDigests<E>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<E: Engine> Serialize for CircuitDigests<E>

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<E: Eq + Engine> Eq for CircuitDigests<E>where + E::Scalar: Eq,

source§

impl<E: Engine> StructuralEq for CircuitDigests<E>

source§

impl<E: Engine> StructuralPartialEq for CircuitDigests<E>

Auto Trait Implementations§

§

impl<E> RefUnwindSafe for CircuitDigests<E>where + <E as Engine>::Scalar: RefUnwindSafe,

§

impl<E> Send for CircuitDigests<E>

§

impl<E> Sync for CircuitDigests<E>

§

impl<E> Unpin for CircuitDigests<E>where + <E as Engine>::Scalar: Unpin,

§

impl<E> UnwindSafe for CircuitDigests<E>where + <E as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/supernova/struct.PublicParams.html b/docs/arecibo/supernova/struct.PublicParams.html new file mode 100644 index 000000000..5d1f55c07 --- /dev/null +++ b/docs/arecibo/supernova/struct.PublicParams.html @@ -0,0 +1,186 @@ +PublicParams in arecibo::supernova - Rust
pub struct PublicParams<E1, E2, C1, C2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,{ /* private fields */ }
Expand description

A vector of R1CSWithArity adjoined to a set of PublicParams

+

Implementations§

source§

impl<E1, E2, C1, C2> PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source

pub fn setup<NC: NonUniformCircuit<E1, E2, C1, C2>>( + non_uniform_circuit: &NC, + ck_hint1: &CommitmentKeyHint<E1>, + ck_hint2: &CommitmentKeyHint<E2> +) -> Self

Construct a new PublicParams

+
Note
+

Public parameters set up a number of bases for the homomorphic commitment scheme of Nova.

+

Some final compressing SNARKs, like variants of Spartan, use computation commitments that require +larger sizes for these parameters. These SNARKs provide a hint for these values by +implementing RelaxedR1CSSNARKTrait::commitment_key_floor(), which can be passed to this function.

+

If you’re not using such a SNARK, pass &(|_| 0) instead.

+
Arguments
+
    +
  • non_uniform_circuit: The non-uniform circuit of type NC.
  • +
  • ck_hint1: A CommitmentKeyHint for E1, which is a function that provides a hint +for the number of generators required in the commitment scheme for the primary circuit.
  • +
  • ck_hint2: A CommitmentKeyHint for E2, similar to ck_hint1, but for the secondary circuit.
  • +
+
source

pub fn into_parts(self) -> (Vec<R1CSWithArity<E1>>, AuxParams<E1, E2>)

Breaks down an instance of PublicParams into the circuit params and auxiliary params.

+
source

pub fn from_parts( + circuit_shapes: Vec<R1CSWithArity<E1>>, + aux_params: AuxParams<E1, E2> +) -> Self

Create a PublicParams from a vector of raw R1CSWithArity and auxiliary params.

+
source

pub fn from_parts_unchecked( + circuit_shapes: Vec<R1CSWithArity<E1>>, + aux_params: AuxParams<E1, E2> +) -> Self

Create a PublicParams from a vector of raw R1CSWithArity and auxiliary params. +We don’t check that the aux_params.digest is a valid digest for the created params.

+
source

pub fn digest(&self) -> E1::Scalar

Return the PublicParams’ digest.

+
source

pub fn circuit_param_digests(&self) -> CircuitDigests<E1>

All of the primary circuit digests of this PublicParams

+

Trait Implementations§

source§

impl<E1, E2, C1, C2> Clone for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + C1: StepCircuit<E1::Scalar> + Clone, + C2: StepCircuit<E2::Scalar> + Clone, + E1::Scalar: Clone,

source§

fn clone(&self) -> PublicParams<E1, E2, C1, C2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<'de, E1, E2, C1, C2> Deserialize<'de> for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2, C1, C2> Index<usize> for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

§

type Output = R1CSWithArity<E1>

The returned type after indexing.
source§

fn index(&self, index: usize) -> &Self::Output

Performs the indexing (container[index]) operation. Read more
source§

impl<E1, E2, C1, C2> Serialize for PublicParams<E1, E2, C1, C2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>, + C1: StepCircuit<E1::Scalar>, + C2: StepCircuit<E2::Scalar>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2, C1, C2> RefUnwindSafe for PublicParams<E1, E2, C1, C2>where + C1: RefUnwindSafe, + C2: RefUnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: RefUnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: RefUnwindSafe, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: RefUnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe + RefUnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe + RefUnwindSafe,

§

impl<E1, E2, C1, C2> Send for PublicParams<E1, E2, C1, C2>

§

impl<E1, E2, C1, C2> Sync for PublicParams<E1, E2, C1, C2>

§

impl<E1, E2, C1, C2> Unpin for PublicParams<E1, E2, C1, C2>where + C1: Unpin, + C2: Unpin, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: Unpin, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: Unpin, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Unpin, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Unpin, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: Unpin, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: Unpin, + <E1 as Engine>::Scalar: Unpin, + <E2 as Engine>::Scalar: Unpin,

§

impl<E1, E2, C1, C2> UnwindSafe for PublicParams<E1, E2, C1, C2>where + C1: UnwindSafe, + C2: UnwindSafe, + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: UnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: UnwindSafe, + <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: UnwindSafe, + <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: UnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/supernova/struct.RecursiveSNARK.html b/docs/arecibo/supernova/struct.RecursiveSNARK.html new file mode 100644 index 000000000..cd09ed6fc --- /dev/null +++ b/docs/arecibo/supernova/struct.RecursiveSNARK.html @@ -0,0 +1,149 @@ +RecursiveSNARK in arecibo::supernova - Rust
pub struct RecursiveSNARK<E1, E2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,{ /* private fields */ }
Expand description

A SNARK that proves the correct execution of an non-uniform incremental computation

+

Implementations§

source§

impl<E1, E2> RecursiveSNARK<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>,

source

pub fn new<C0: NonUniformCircuit<E1, E2, C1, C2>, C1: StepCircuit<E1::Scalar>, C2: StepCircuit<E2::Scalar>>( + pp: &PublicParams<E1, E2, C1, C2>, + non_uniform_circuit: &C0, + c_primary: &C1, + c_secondary: &C2, + z0_primary: &[E1::Scalar], + z0_secondary: &[E2::Scalar] +) -> Result<Self, SuperNovaError>

iterate base step to get new instance of recursive SNARK

+
source

pub fn prove_step<C1: StepCircuit<E1::Scalar>, C2: StepCircuit<E2::Scalar>>( + &mut self, + pp: &PublicParams<E1, E2, C1, C2>, + c_primary: &C1, + c_secondary: &C2 +) -> Result<(), SuperNovaError>

executing a step of the incremental computation

+
source

pub fn verify<C1: StepCircuit<E1::Scalar>, C2: StepCircuit<E2::Scalar>>( + &self, + pp: &PublicParams<E1, E2, C1, C2>, + z0_primary: &[E1::Scalar], + z0_secondary: &[E2::Scalar] +) -> Result<(Vec<E1::Scalar>, Vec<E2::Scalar>), SuperNovaError>

verify recursive snark

+

Trait Implementations§

source§

impl<E1, E2> Clone for RecursiveSNARK<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Clone, + E2: Engine<Base = <E1 as Engine>::Scalar> + Clone, + E1::Scalar: Clone, + E2::Scalar: Clone,

source§

fn clone(&self) -> RecursiveSNARK<E1, E2>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<E1, E2> Debug for RecursiveSNARK<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar> + Debug, + E2: Engine<Base = <E1 as Engine>::Scalar> + Debug, + E1::Scalar: Debug, + E2::Scalar: Debug,

source§

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

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

impl<'de, E1, E2> Deserialize<'de> for RecursiveSNARK<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where + __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<E1, E2> Serialize for RecursiveSNARK<E1, E2>where + E1: Engine<Base = <E2 as Engine>::Scalar>, + E2: Engine<Base = <E1 as Engine>::Scalar>,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>where + __S: Serializer,

Serialize this value into the given Serde serializer. Read more

Auto Trait Implementations§

§

impl<E1, E2> RefUnwindSafe for RecursiveSNARK<E1, E2>where + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: RefUnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: RefUnwindSafe, + <E1 as Engine>::Scalar: RefUnwindSafe, + <E2 as Engine>::Scalar: RefUnwindSafe,

§

impl<E1, E2> Send for RecursiveSNARK<E1, E2>

§

impl<E1, E2> Sync for RecursiveSNARK<E1, E2>

§

impl<E1, E2> Unpin for RecursiveSNARK<E1, E2>where + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Unpin, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Unpin, + <E1 as Engine>::Scalar: Unpin, + <E2 as Engine>::Scalar: Unpin,

§

impl<E1, E2> UnwindSafe for RecursiveSNARK<E1, E2>where + <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: UnwindSafe, + <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: UnwindSafe, + <E1 as Engine>::Scalar: UnwindSafe, + <E2 as Engine>::Scalar: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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

impl<T> DeserializeOwned for Twhere + T: for<'de> Deserialize<'de>,

\ No newline at end of file diff --git a/docs/arecibo/supernova/struct.TrivialSecondaryCircuit.html b/docs/arecibo/supernova/struct.TrivialSecondaryCircuit.html new file mode 100644 index 000000000..7e5dafba1 --- /dev/null +++ b/docs/arecibo/supernova/struct.TrivialSecondaryCircuit.html @@ -0,0 +1,115 @@ +TrivialSecondaryCircuit in arecibo::supernova - Rust
pub struct TrivialSecondaryCircuit<F> { /* private fields */ }
Expand description

A trivial step circuit that simply returns the input, for use on the secondary circuit when implementing NIVC. +NOTE: This should not be needed. The secondary circuit doesn’t need the program counter at all. +Ideally, the need this fills could be met by traits::circuit::TrivialTestCircuit (or equivalent).

+

Trait Implementations§

source§

impl<F: Clone> Clone for TrivialSecondaryCircuit<F>

source§

fn clone(&self) -> TrivialSecondaryCircuit<F>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<F: Debug> Debug for TrivialSecondaryCircuit<F>

source§

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

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

impl<F: Default> Default for TrivialSecondaryCircuit<F>

source§

fn default() -> TrivialSecondaryCircuit<F>

Returns the “default value” for a type. Read more
source§

impl<F> StepCircuit<F> for TrivialSecondaryCircuit<F>where + F: PrimeField,

source§

fn arity(&self) -> usize

Return the the number of inputs or outputs of each step +(this method is called only at circuit synthesis time) +synthesize and output methods are expected to take as +input a vector of size equal to arity and output a vector of size equal to arity
source§

fn circuit_index(&self) -> usize

Return this StepCircuit’s assigned index, for use when enforcing the program counter.
source§

fn synthesize<CS: ConstraintSystem<F>>( + &self, + _cs: &mut CS, + program_counter: Option<&AllocatedNum<F>>, + z: &[AllocatedNum<F>] +) -> Result<(Option<AllocatedNum<F>>, Vec<AllocatedNum<F>>), SynthesisError>

Synthesize the circuit for a computation step and return variable +that corresponds to the output of the step pc_{i+1} and z_{i+1}

Auto Trait Implementations§

§

impl<F> RefUnwindSafe for TrivialSecondaryCircuit<F>where + F: RefUnwindSafe,

§

impl<F> Send for TrivialSecondaryCircuit<F>where + F: Send,

§

impl<F> Sync for TrivialSecondaryCircuit<F>where + F: Sync,

§

impl<F> Unpin for TrivialSecondaryCircuit<F>where + F: Unpin,

§

impl<F> UnwindSafe for TrivialSecondaryCircuit<F>where + F: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/supernova/struct.TrivialTestCircuit.html b/docs/arecibo/supernova/struct.TrivialTestCircuit.html new file mode 100644 index 000000000..244c3af69 --- /dev/null +++ b/docs/arecibo/supernova/struct.TrivialTestCircuit.html @@ -0,0 +1,113 @@ +TrivialTestCircuit in arecibo::supernova - Rust
pub struct TrivialTestCircuit<F> { /* private fields */ }
Expand description

A trivial step circuit that simply returns the input

+

Trait Implementations§

source§

impl<F: Clone> Clone for TrivialTestCircuit<F>

source§

fn clone(&self) -> TrivialTestCircuit<F>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<F: Debug> Debug for TrivialTestCircuit<F>

source§

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

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

impl<F: Default> Default for TrivialTestCircuit<F>

source§

fn default() -> TrivialTestCircuit<F>

Returns the “default value” for a type. Read more
source§

impl<F> StepCircuit<F> for TrivialTestCircuit<F>where + F: PrimeField,

source§

fn arity(&self) -> usize

Return the the number of inputs or outputs of each step +(this method is called only at circuit synthesis time) +synthesize and output methods are expected to take as +input a vector of size equal to arity and output a vector of size equal to arity
source§

fn circuit_index(&self) -> usize

Return this StepCircuit’s assigned index, for use when enforcing the program counter.
source§

fn synthesize<CS: ConstraintSystem<F>>( + &self, + _cs: &mut CS, + program_counter: Option<&AllocatedNum<F>>, + z: &[AllocatedNum<F>] +) -> Result<(Option<AllocatedNum<F>>, Vec<AllocatedNum<F>>), SynthesisError>

Synthesize the circuit for a computation step and return variable +that corresponds to the output of the step pc_{i+1} and z_{i+1}

Auto Trait Implementations§

§

impl<F> RefUnwindSafe for TrivialTestCircuit<F>where + F: RefUnwindSafe,

§

impl<F> Send for TrivialTestCircuit<F>where + F: Send,

§

impl<F> Sync for TrivialTestCircuit<F>where + F: Sync,

§

impl<F> Unpin for TrivialTestCircuit<F>where + F: Unpin,

§

impl<F> UnwindSafe for TrivialTestCircuit<F>where + F: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/supernova/trait.NonUniformCircuit.html b/docs/arecibo/supernova/trait.NonUniformCircuit.html new file mode 100644 index 000000000..c5dafe69e --- /dev/null +++ b/docs/arecibo/supernova/trait.NonUniformCircuit.html @@ -0,0 +1,20 @@ +NonUniformCircuit in arecibo::supernova - Rust
pub trait NonUniformCircuit<E1, E2, C1, C2>where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,{
+    // Required methods
+    fn num_circuits(&self) -> usize;
+    fn primary_circuit(&self, circuit_index: usize) -> C1;
+    fn secondary_circuit(&self) -> C2;
+
+    // Provided method
+    fn initial_circuit_index(&self) -> usize { ... }
+}
Expand description

SuperNova helper trait, for implementors that provide sets of sub-circuits to be proved via NIVC. C1 must be a +type (likely an Enum) for which a potentially-distinct instance can be supplied for each index below +self.num_circuits().

+

Required Methods§

source

fn num_circuits(&self) -> usize

How many circuits are provided?

+
source

fn primary_circuit(&self, circuit_index: usize) -> C1

Return a new instance of the primary circuit at index.

+
source

fn secondary_circuit(&self) -> C2

Return a new instance of the secondary circuit.

+

Provided Methods§

source

fn initial_circuit_index(&self) -> usize

Initial circuit index, defaults to zero.

+

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/supernova/trait.StepCircuit.html b/docs/arecibo/supernova/trait.StepCircuit.html new file mode 100644 index 000000000..9b4d6c0c8 --- /dev/null +++ b/docs/arecibo/supernova/trait.StepCircuit.html @@ -0,0 +1,27 @@ +StepCircuit in arecibo::supernova - Rust
pub trait StepCircuit<F: PrimeField>: Send + Sync + Clone {
+    // Required methods
+    fn arity(&self) -> usize;
+    fn circuit_index(&self) -> usize;
+    fn synthesize<CS: ConstraintSystem<F>>(
+        &self,
+        cs: &mut CS,
+        pc: Option<&AllocatedNum<F>>,
+        z: &[AllocatedNum<F>]
+    ) -> Result<(Option<AllocatedNum<F>>, Vec<AllocatedNum<F>>), SynthesisError>;
+}
Expand description

A helper trait for a step of the incremental computation for SuperNova (i.e., circuit for F) – to be implemented by +applications.

+

Required Methods§

source

fn arity(&self) -> usize

Return the the number of inputs or outputs of each step +(this method is called only at circuit synthesis time) +synthesize and output methods are expected to take as +input a vector of size equal to arity and output a vector of size equal to arity

+
source

fn circuit_index(&self) -> usize

Return this StepCircuit’s assigned index, for use when enforcing the program counter.

+
source

fn synthesize<CS: ConstraintSystem<F>>( + &self, + cs: &mut CS, + pc: Option<&AllocatedNum<F>>, + z: &[AllocatedNum<F>] +) -> Result<(Option<AllocatedNum<F>>, Vec<AllocatedNum<F>>), SynthesisError>

Synthesize the circuit for a computation step and return variable +that corresponds to the output of the step pc_{i+1} and z_{i+1}

+

Implementors§

source§

impl<F> StepCircuit<F> for TrivialSecondaryCircuit<F>where + F: PrimeField,

source§

impl<F> StepCircuit<F> for TrivialTestCircuit<F>where + F: PrimeField,

\ No newline at end of file diff --git a/docs/arecibo/traits/circuit/index.html b/docs/arecibo/traits/circuit/index.html new file mode 100644 index 000000000..1de1defd0 --- /dev/null +++ b/docs/arecibo/traits/circuit/index.html @@ -0,0 +1,2 @@ +arecibo::traits::circuit - Rust

Module arecibo::traits::circuit

source ·
Expand description

This module defines traits that a step function must implement

+

Structs

Traits

  • A helper trait for a step of the incremental computation (i.e., circuit for F)
\ No newline at end of file diff --git a/docs/arecibo/traits/circuit/sidebar-items.js b/docs/arecibo/traits/circuit/sidebar-items.js new file mode 100644 index 000000000..f5a11f28f --- /dev/null +++ b/docs/arecibo/traits/circuit/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"struct":["TrivialCircuit"],"trait":["StepCircuit"]}; \ No newline at end of file diff --git a/docs/arecibo/traits/circuit/struct.TrivialCircuit.html b/docs/arecibo/traits/circuit/struct.TrivialCircuit.html new file mode 100644 index 000000000..9c6d49fc2 --- /dev/null +++ b/docs/arecibo/traits/circuit/struct.TrivialCircuit.html @@ -0,0 +1,113 @@ +TrivialCircuit in arecibo::traits::circuit - Rust
pub struct TrivialCircuit<F> { /* private fields */ }
Expand description

A trivial step circuit that simply returns the input

+

Trait Implementations§

source§

impl<F: Clone> Clone for TrivialCircuit<F>

source§

fn clone(&self) -> TrivialCircuit<F>

Returns a copy of the value. Read more
1.0.0 · source§

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

Performs copy-assignment from source. Read more
source§

impl<F: Debug> Debug for TrivialCircuit<F>

source§

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

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

impl<F: Default> Default for TrivialCircuit<F>

source§

fn default() -> TrivialCircuit<F>

Returns the “default value” for a type. Read more
source§

impl<F: PartialEq> PartialEq<TrivialCircuit<F>> for TrivialCircuit<F>

source§

fn eq(&self, other: &TrivialCircuit<F>) -> bool

This method tests for self and other values to be equal, and is used +by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always +sufficient, and should not be overridden without very good reason.
source§

impl<F: PrimeField> StepCircuit<F> for TrivialCircuit<F>

source§

fn arity(&self) -> usize

Return the number of inputs or outputs of each step +(this method is called only at circuit synthesis time) +synthesize and output methods are expected to take as +input a vector of size equal to arity and output a vector of size equal to arity
source§

fn synthesize<CS: ConstraintSystem<F>>( + &self, + _cs: &mut CS, + z: &[AllocatedNum<F>] +) -> Result<Vec<AllocatedNum<F>>, SynthesisError>

Sythesize the circuit for a computation step and return variable +that corresponds to the output of the step z_{i+1}
source§

impl<F: Eq> Eq for TrivialCircuit<F>

source§

impl<F> StructuralEq for TrivialCircuit<F>

source§

impl<F> StructuralPartialEq for TrivialCircuit<F>

Auto Trait Implementations§

§

impl<F> RefUnwindSafe for TrivialCircuit<F>where + F: RefUnwindSafe,

§

impl<F> Send for TrivialCircuit<F>where + F: Send,

§

impl<F> Sync for TrivialCircuit<F>where + F: Sync,

§

impl<F> Unpin for TrivialCircuit<F>where + F: Unpin,

§

impl<F> UnwindSafe for TrivialCircuit<F>where + F: UnwindSafe,

Blanket Implementations§

source§

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

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for Twhere + T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for Twhere + T: ?Sized,

source§

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

Mutably borrows from an owned value. Read more
§

impl<T> Conv for T

§

fn conv<T>(self) -> Twhere + Self: Into<T>,

Converts self into T using Into<T>. Read more
§

impl<T> FmtForward for T

§

fn fmt_binary(self) -> FmtBinary<Self>where + Self: Binary,

Causes self to use its Binary implementation when Debug-formatted.
§

fn fmt_display(self) -> FmtDisplay<Self>where + Self: Display,

Causes self to use its Display implementation when +Debug-formatted.
§

fn fmt_lower_exp(self) -> FmtLowerExp<Self>where + Self: LowerExp,

Causes self to use its LowerExp implementation when +Debug-formatted.
§

fn fmt_lower_hex(self) -> FmtLowerHex<Self>where + Self: LowerHex,

Causes self to use its LowerHex implementation when +Debug-formatted.
§

fn fmt_octal(self) -> FmtOctal<Self>where + Self: Octal,

Causes self to use its Octal implementation when Debug-formatted.
§

fn fmt_pointer(self) -> FmtPointer<Self>where + Self: Pointer,

Causes self to use its Pointer implementation when +Debug-formatted.
§

fn fmt_upper_exp(self) -> FmtUpperExp<Self>where + Self: UpperExp,

Causes self to use its UpperExp implementation when +Debug-formatted.
§

fn fmt_upper_hex(self) -> FmtUpperHex<Self>where + Self: UpperHex,

Causes self to use its UpperHex implementation when +Debug-formatted.
§

fn fmt_list(self) -> FmtList<Self>where + &'a Self: for<'a> IntoIterator,

Formats each item in a sequence. 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 Twhere + 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.

+
§

impl<T> Pipe for Twhere + T: ?Sized,

§

fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere + Self: Sized,

Pipes by value. This is generally the method you want to use. Read more
§

fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere + R: 'a,

Borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere + R: 'a,

Mutably borrows self and passes that borrow into the pipe function. Read more
§

fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> Rwhere + Self: Borrow<B>, + B: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.borrow() into the pipe function. Read more
§

fn pipe_borrow_mut<'a, B, R>( + &'a mut self, + func: impl FnOnce(&'a mut B) -> R +) -> Rwhere + Self: BorrowMut<B>, + B: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.borrow_mut() into the pipe +function. Read more
§

fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> Rwhere + Self: AsRef<U>, + U: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.as_ref() into the pipe function.
§

fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> Rwhere + Self: AsMut<U>, + U: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.as_mut() into the pipe +function.
§

fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> Rwhere + Self: Deref<Target = T>, + T: 'a + ?Sized, + R: 'a,

Borrows self, then passes self.deref() into the pipe function.
§

fn pipe_deref_mut<'a, T, R>( + &'a mut self, + func: impl FnOnce(&'a mut T) -> R +) -> Rwhere + Self: DerefMut<Target = T> + Deref, + T: 'a + ?Sized, + R: 'a,

Mutably borrows self, then passes self.deref_mut() into the pipe +function.
§

impl<T> Pointable for T

§

const ALIGN: usize = mem::align_of::<T>()

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<T> for T

§

type Output = T

Should always be Self
§

impl<T> Tap for T

§

fn tap(self, func: impl FnOnce(&Self)) -> Self

Immutable access to a value. Read more
§

fn tap_mut(self, func: impl FnOnce(&mut Self)) -> Self

Mutable access to a value. Read more
§

fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Immutable access to the Borrow<B> of a value. Read more
§

fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Mutable access to the BorrowMut<B> of a value. Read more
§

fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Immutable access to the AsRef<R> view of a value. Read more
§

fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Mutable access to the AsMut<R> view of a value. Read more
§

fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Immutable access to the Deref::Target of a value. Read more
§

fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Mutable access to the Deref::Target of a value. Read more
§

fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self

Calls .tap() only in debug builds, and is erased in release builds.
§

fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self

Calls .tap_mut() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Selfwhere + Self: Borrow<B>, + B: ?Sized,

Calls .tap_borrow() only in debug builds, and is erased in release +builds.
§

fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Selfwhere + Self: BorrowMut<B>, + B: ?Sized,

Calls .tap_borrow_mut() only in debug builds, and is erased in release +builds.
§

fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Selfwhere + Self: AsRef<R>, + R: ?Sized,

Calls .tap_ref() only in debug builds, and is erased in release +builds.
§

fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Selfwhere + Self: AsMut<R>, + R: ?Sized,

Calls .tap_ref_mut() only in debug builds, and is erased in release +builds.
§

fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Selfwhere + Self: Deref<Target = T>, + T: ?Sized,

Calls .tap_deref() only in debug builds, and is erased in release +builds.
§

fn tap_deref_mut_dbg<T>(self, func: impl FnOnce(&mut T)) -> Selfwhere + Self: DerefMut<Target = T> + Deref, + T: ?Sized,

Calls .tap_deref_mut() only in debug builds, and is erased in release +builds.
source§

impl<T> ToOwned for Twhere + T: Clone,

§

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
§

impl<T> TryConv for T

§

fn try_conv<T>(self) -> Result<T, Self::Error>where + Self: TryInto<T>,

Attempts to convert self into T using TryInto<T>. Read more
source§

impl<T, U> TryFrom<U> for Twhere + U: Into<T>,

§

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 Twhere + U: TryFrom<T>,

§

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<V, T> VZip<V> for Twhere + V: MultiLane<T>,

§

fn vzip(self) -> V

§

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
\ No newline at end of file diff --git a/docs/arecibo/traits/circuit/trait.StepCircuit.html b/docs/arecibo/traits/circuit/trait.StepCircuit.html new file mode 100644 index 000000000..cd046c906 --- /dev/null +++ b/docs/arecibo/traits/circuit/trait.StepCircuit.html @@ -0,0 +1,20 @@ +StepCircuit in arecibo::traits::circuit - Rust
pub trait StepCircuit<F: PrimeField>: Send + Sync + Clone {
+    // Required methods
+    fn arity(&self) -> usize;
+    fn synthesize<CS: ConstraintSystem<F>>(
+        &self,
+        cs: &mut CS,
+        z: &[AllocatedNum<F>]
+    ) -> Result<Vec<AllocatedNum<F>>, SynthesisError>;
+}
Expand description

A helper trait for a step of the incremental computation (i.e., circuit for F)

+

Required Methods§

source

fn arity(&self) -> usize

Return the number of inputs or outputs of each step +(this method is called only at circuit synthesis time) +synthesize and output methods are expected to take as +input a vector of size equal to arity and output a vector of size equal to arity

+
source

fn synthesize<CS: ConstraintSystem<F>>( + &self, + cs: &mut CS, + z: &[AllocatedNum<F>] +) -> Result<Vec<AllocatedNum<F>>, SynthesisError>

Sythesize the circuit for a computation step and return variable +that corresponds to the output of the step z_{i+1}

+

Implementors§

source§

impl<F: PrimeField> StepCircuit<F> for TrivialCircuit<F>

\ No newline at end of file diff --git a/docs/arecibo/traits/commitment/index.html b/docs/arecibo/traits/commitment/index.html new file mode 100644 index 000000000..c2656d0a3 --- /dev/null +++ b/docs/arecibo/traits/commitment/index.html @@ -0,0 +1,4 @@ +arecibo::traits::commitment - Rust

Module arecibo::traits::commitment

source ·
Expand description

This module defines a collection of traits that define the behavior of a commitment engine +We require the commitment engine to provide a commitment to vectors with a single group element

+

Traits

  • A trait that ties different pieces of the commitment generation together
  • This trait defines the behavior of the commitment
  • A trait that helps determine the lenght of a structure. +Note this does not impose any memory representation contraints on the structure.
  • A helper trait for types implementing scalar multiplication.
\ No newline at end of file diff --git a/docs/arecibo/traits/commitment/sidebar-items.js b/docs/arecibo/traits/commitment/sidebar-items.js new file mode 100644 index 000000000..6fba3e249 --- /dev/null +++ b/docs/arecibo/traits/commitment/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"trait":["CommitmentEngineTrait","CommitmentTrait","Len","ScalarMul"]}; \ No newline at end of file diff --git a/docs/arecibo/traits/commitment/trait.CommitmentEngineTrait.html b/docs/arecibo/traits/commitment/trait.CommitmentEngineTrait.html new file mode 100644 index 000000000..ab6fd7ed5 --- /dev/null +++ b/docs/arecibo/traits/commitment/trait.CommitmentEngineTrait.html @@ -0,0 +1,14 @@ +CommitmentEngineTrait in arecibo::traits::commitment - Rust
pub trait CommitmentEngineTrait<E: Engine>: Clone + Send + Sync {
+    type CommitmentKey: Len + Clone + PartialEq + Debug + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+    type Commitment: CommitmentTrait<E>;
+
+    // Required methods
+    fn setup(label: &'static [u8], n: usize) -> Self::CommitmentKey;
+    fn commit(ck: &Self::CommitmentKey, v: &[E::Scalar]) -> Self::Commitment;
+}
Expand description

A trait that ties different pieces of the commitment generation together

+

Required Associated Types§

source

type CommitmentKey: Len + Clone + PartialEq + Debug + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation

Holds the type of the commitment key +The key should quantify its length in terms of group generators.

+
source

type Commitment: CommitmentTrait<E>

Holds the type of the commitment

+

Required Methods§

source

fn setup(label: &'static [u8], n: usize) -> Self::CommitmentKey

Samples a new commitment key of a specified size

+
source

fn commit(ck: &Self::CommitmentKey, v: &[E::Scalar]) -> Self::Commitment

Commits to the provided vector using the provided generators

+

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/commitment/trait.CommitmentTrait.html b/docs/arecibo/traits/commitment/trait.CommitmentTrait.html new file mode 100644 index 000000000..79e4b84b6 --- /dev/null +++ b/docs/arecibo/traits/commitment/trait.CommitmentTrait.html @@ -0,0 +1,13 @@ +CommitmentTrait in arecibo::traits::commitment - Rust
pub trait CommitmentTrait<E: Engine>: Clone + Copy + Debug + Default + PartialEq + Eq + Send + Sync + TranscriptReprTrait<E::GE> + Serialize + for<'de> Deserialize<'de> + Abomonation + AbsorbInROTrait<E> + Add<Self, Output = Self> + ScalarMul<E::Scalar> {
+    type CompressedCommitment: Clone + Debug + PartialEq + Eq + Send + Sync + TranscriptReprTrait<E::GE> + Serialize + for<'de> Deserialize<'de>;
+
+    // Required methods
+    fn compress(&self) -> Self::CompressedCommitment;
+    fn to_coordinates(&self) -> (E::Base, E::Base, bool);
+    fn decompress(c: &Self::CompressedCommitment) -> Result<Self, NovaError>;
+}
Expand description

This trait defines the behavior of the commitment

+

Required Associated Types§

source

type CompressedCommitment: Clone + Debug + PartialEq + Eq + Send + Sync + TranscriptReprTrait<E::GE> + Serialize + for<'de> Deserialize<'de>

Holds the type of the compressed commitment

+

Required Methods§

source

fn compress(&self) -> Self::CompressedCommitment

Compresses self into a compressed commitment

+
source

fn to_coordinates(&self) -> (E::Base, E::Base, bool)

Returns the coordinate representation of the commitment

+
source

fn decompress(c: &Self::CompressedCommitment) -> Result<Self, NovaError>

Decompresses a compressed commitment into a commitment

+

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/commitment/trait.Len.html b/docs/arecibo/traits/commitment/trait.Len.html new file mode 100644 index 000000000..42cc0b2f2 --- /dev/null +++ b/docs/arecibo/traits/commitment/trait.Len.html @@ -0,0 +1,7 @@ +Len in arecibo::traits::commitment - Rust
pub trait Len {
+    // Required method
+    fn length(&self) -> usize;
+}
Expand description

A trait that helps determine the lenght of a structure. +Note this does not impose any memory representation contraints on the structure.

+

Required Methods§

source

fn length(&self) -> usize

Returns the length of the structure.

+

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/commitment/trait.ScalarMul.html b/docs/arecibo/traits/commitment/trait.ScalarMul.html new file mode 100644 index 000000000..adc49edd0 --- /dev/null +++ b/docs/arecibo/traits/commitment/trait.ScalarMul.html @@ -0,0 +1,3 @@ +ScalarMul in arecibo::traits::commitment - Rust
pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> { }
Expand description

A helper trait for types implementing scalar multiplication.

+

Implementors§

source§

impl<T, Rhs, Output> ScalarMul<Rhs, Output> for Twhere + T: Mul<Rhs, Output = Output> + MulAssign<Rhs>,

\ No newline at end of file diff --git a/docs/arecibo/traits/evaluation/index.html b/docs/arecibo/traits/evaluation/index.html new file mode 100644 index 000000000..e9efd1650 --- /dev/null +++ b/docs/arecibo/traits/evaluation/index.html @@ -0,0 +1,4 @@ +arecibo::traits::evaluation - Rust

Module arecibo::traits::evaluation

source ·
Expand description

This module defines a collection of traits that define the behavior of a polynomial evaluation engine +A vector of size N is treated as a multilinear polynomial in \log{N} variables, +and a commitment provided by the commitment engine is treated as a multilinear polynomial commitment

+

Traits

\ No newline at end of file diff --git a/docs/arecibo/traits/evaluation/sidebar-items.js b/docs/arecibo/traits/evaluation/sidebar-items.js new file mode 100644 index 000000000..e6ee74686 --- /dev/null +++ b/docs/arecibo/traits/evaluation/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"trait":["EvaluationEngineTrait"]}; \ No newline at end of file diff --git a/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html b/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html new file mode 100644 index 000000000..93ea50f04 --- /dev/null +++ b/docs/arecibo/traits/evaluation/trait.EvaluationEngineTrait.html @@ -0,0 +1,66 @@ +EvaluationEngineTrait in arecibo::traits::evaluation - Rust
pub trait EvaluationEngineTrait<E: Engine>: Clone + Send + Sync {
+    type ProverKey: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+    type VerifierKey: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+    type EvaluationArgument: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de>;
+
+    // Required methods
+    fn setup(
+        ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey
+    ) -> (Self::ProverKey, Self::VerifierKey);
+    fn prove(
+        ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+        pk: &Self::ProverKey,
+        transcript: &mut E::TE,
+        comm: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment,
+        poly: &[E::Scalar],
+        point: &[E::Scalar],
+        eval: &E::Scalar
+    ) -> Result<Self::EvaluationArgument, NovaError>;
+    fn verify(
+        vk: &Self::VerifierKey,
+        transcript: &mut E::TE,
+        comm: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment,
+        point: &[E::Scalar],
+        eval: &E::Scalar,
+        arg: &Self::EvaluationArgument
+    ) -> Result<(), NovaError>;
+}
Expand description

A trait that ties different pieces of the commitment evaluation together

+

Required Associated Types§

source

type ProverKey: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation

A type that holds the prover key

+
source

type VerifierKey: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation

A type that holds the verifier key

+
source

type EvaluationArgument: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de>

A type that holds the evaluation argument

+

Required Methods§

source

fn setup( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey +) -> (Self::ProverKey, Self::VerifierKey)

A method to perform any additional setup needed to produce proofs of evaluations

+
source

fn prove( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + pk: &Self::ProverKey, + transcript: &mut E::TE, + comm: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, + poly: &[E::Scalar], + point: &[E::Scalar], + eval: &E::Scalar +) -> Result<Self::EvaluationArgument, NovaError>

A method to prove the evaluation of a multilinear polynomial

+
source

fn verify( + vk: &Self::VerifierKey, + transcript: &mut E::TE, + comm: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment, + point: &[E::Scalar], + eval: &E::Scalar, + arg: &Self::EvaluationArgument +) -> Result<(), NovaError>

A method to verify the purported evaluation of a multilinear polynomials

+

Implementors§

source§

impl<E> EvaluationEngineTrait<E> for arecibo::provider::ipa_pc::EvaluationEngine<E>where + E: Engine, + E::GE: DlogGroup, + <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: CommitmentKeyExtTrait<E>,

source§

impl<E, NE> EvaluationEngineTrait<NE> for arecibo::provider::mlkzg::EvaluationEngine<E, NE>where + E: MultiMillerLoop, + NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>, + E::Fr: Serialize + DeserializeOwned + PrimeFieldBits + TranscriptReprTrait<E::G1>, + E::G1Affine: Serialize + DeserializeOwned + TranscriptReprTrait<E::G1>, + E::G2Affine: Serialize + DeserializeOwned, + E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>, + <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>,

§

type EvaluationArgument = EvaluationArgument<E>

§

type ProverKey = KZGProverKey<E>

§

type VerifierKey = KZGVerifierKey<E>

source§

impl<E: MultiMillerLoop, NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>> EvaluationEngineTrait<NE> for ZMPCS<E, NE>where + E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>, + E::G1Affine: Serialize + for<'de> Deserialize<'de>, + E::G2Affine: Serialize + for<'de> Deserialize<'de>, + <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>, + E::Fr: PrimeFieldBits,

\ No newline at end of file diff --git a/docs/arecibo/traits/index.html b/docs/arecibo/traits/index.html new file mode 100644 index 000000000..a6b0ae667 --- /dev/null +++ b/docs/arecibo/traits/index.html @@ -0,0 +1,6 @@ +arecibo::traits - Rust

Module arecibo::traits

source ·
Expand description

This module defines various traits required by the users of the library to implement.

+

Modules

  • This module defines traits that a step function must implement
  • This module defines a collection of traits that define the behavior of a commitment engine +We require the commitment engine to provide a commitment to vectors with a single group element
  • This module defines a collection of traits that define the behavior of a polynomial evaluation engine +A vector of size N is treated as a multilinear polynomial in \log{N} variables, +and a commitment provided by the commitment engine is treated as a multilinear polynomial commitment
  • This module defines a collection of traits that define the behavior of a zkSNARK for RelaxedR1CS

Traits

  • A helper trait to absorb different objects in RO
  • A collection of engines that are required by the library
  • Represents an element of a group +This is currently tailored for an elliptic curve group
  • Defines additional methods on PrimeField objects
  • A helper trait that defines the behavior of a hash function that we use as an RO in the circuit model
  • A helper trait that defines the behavior of a hash function that we use as an RO
  • This trait defines the behavior of a transcript engine compatible with Spartan
  • This trait allows types to implement how they want to be added to TranscriptEngine

Type Definitions

\ No newline at end of file diff --git a/docs/arecibo/traits/sidebar-items.js b/docs/arecibo/traits/sidebar-items.js new file mode 100644 index 000000000..cfff8e279 --- /dev/null +++ b/docs/arecibo/traits/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"mod":["circuit","commitment","evaluation","snark"],"trait":["AbsorbInROTrait","Engine","Group","PrimeFieldExt","ROCircuitTrait","ROTrait","TranscriptEngineTrait","TranscriptReprTrait"],"type":["ROConstants","ROConstantsCircuit"]}; \ No newline at end of file diff --git a/docs/arecibo/traits/snark/fn.default_ck_hint.html b/docs/arecibo/traits/snark/fn.default_ck_hint.html new file mode 100644 index 000000000..3ff462be0 --- /dev/null +++ b/docs/arecibo/traits/snark/fn.default_ck_hint.html @@ -0,0 +1,6 @@ +default_ck_hint in arecibo::traits::snark - Rust
pub fn default_ck_hint<E: Engine>(
+) -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize>
Expand description

Public parameter creation takes a size hint. This size hint carries the particular requirements of +the final compressing SNARK the user expected to use with these public parameters, and the below +is a sensible default, which is to not require any more bases then the usual (maximum of the number of +variables and constraints of the involved R1CS circuit).

+
\ No newline at end of file diff --git a/docs/arecibo/traits/snark/index.html b/docs/arecibo/traits/snark/index.html new file mode 100644 index 000000000..643e3e2ee --- /dev/null +++ b/docs/arecibo/traits/snark/index.html @@ -0,0 +1,5 @@ +arecibo::traits::snark - Rust

Module arecibo::traits::snark

source ·
Expand description

This module defines a collection of traits that define the behavior of a zkSNARK for RelaxedR1CS

+

Traits

Functions

  • Public parameter creation takes a size hint. This size hint carries the particular requirements of +the final compressing SNARK the user expected to use with these public parameters, and the below +is a sensible default, which is to not require any more bases then the usual (maximum of the number of +variables and constraints of the involved R1CS circuit).
\ No newline at end of file diff --git a/docs/arecibo/traits/snark/sidebar-items.js b/docs/arecibo/traits/snark/sidebar-items.js new file mode 100644 index 000000000..68a77bb9c --- /dev/null +++ b/docs/arecibo/traits/snark/sidebar-items.js @@ -0,0 +1 @@ +window.SIDEBAR_ITEMS = {"fn":["default_ck_hint"],"trait":["BatchedRelaxedR1CSSNARKTrait","DigestHelperTrait","RelaxedR1CSSNARKTrait"]}; \ No newline at end of file diff --git a/docs/arecibo/traits/snark/trait.BatchedRelaxedR1CSSNARKTrait.html b/docs/arecibo/traits/snark/trait.BatchedRelaxedR1CSSNARKTrait.html new file mode 100644 index 000000000..d0a6a1568 --- /dev/null +++ b/docs/arecibo/traits/snark/trait.BatchedRelaxedR1CSSNARKTrait.html @@ -0,0 +1,50 @@ +BatchedRelaxedR1CSSNARKTrait in arecibo::traits::snark - Rust
pub trait BatchedRelaxedR1CSSNARKTrait<E: Engine>: Send + Sync + Serialize + for<'de> Deserialize<'de> {
+    type ProverKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+    type VerifierKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + DigestHelperTrait<E> + Abomonation;
+
+    // Required methods
+    fn setup(
+        ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+        S: Vec<&R1CSShape<E>>
+    ) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>;
+    fn prove(
+        ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+        pk: &Self::ProverKey,
+        S: Vec<&R1CSShape<E>>,
+        U: &[RelaxedR1CSInstance<E>],
+        W: &[RelaxedR1CSWitness<E>]
+    ) -> Result<Self, NovaError>;
+    fn verify(
+        &self,
+        vk: &Self::VerifierKey,
+        U: &[RelaxedR1CSInstance<E>]
+    ) -> Result<(), NovaError>;
+
+    // Provided method
+    fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize> { ... }
+}
Expand description

A trait that defines the behavior of a zkSNARK to prove knowledge of satisfying witness to batches of relaxed R1CS instances.

+

Required Associated Types§

source

type ProverKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation

A type that represents the prover’s key

+
source

type VerifierKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + DigestHelperTrait<E> + Abomonation

A type that represents the verifier’s key

+

Required Methods§

source

fn setup( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + S: Vec<&R1CSShape<E>> +) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>

Produces the keys for the prover and the verifier

+
source

fn prove( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + pk: &Self::ProverKey, + S: Vec<&R1CSShape<E>>, + U: &[RelaxedR1CSInstance<E>], + W: &[RelaxedR1CSWitness<E>] +) -> Result<Self, NovaError>

Produces a new SNARK for a batch of relaxed R1CS

+
source

fn verify( + &self, + vk: &Self::VerifierKey, + U: &[RelaxedR1CSInstance<E>] +) -> Result<(), NovaError>

Verifies a SNARK for a batch of relaxed R1CS

+

Provided Methods§

source

fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize>

This associated function (not a method) provides a hint that offers +a minimum sizing cue for the commitment key used by this SNARK +implementation. The commitment key passed in setup should then +be at least as large as this hint.

+

Implementors§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> BatchedRelaxedR1CSSNARKTrait<E> for arecibo::spartan::batched::BatchedRelaxedR1CSSNARK<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

§

type ProverKey = ProverKey<E, EE>

§

type VerifierKey = VerifierKey<E, EE>

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> BatchedRelaxedR1CSSNARKTrait<E> for arecibo::spartan::batched_ppsnark::BatchedRelaxedR1CSSNARK<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

§

type ProverKey = ProverKey<E, EE>

§

type VerifierKey = VerifierKey<E, EE>

\ No newline at end of file diff --git a/docs/arecibo/traits/snark/trait.DigestHelperTrait.html b/docs/arecibo/traits/snark/trait.DigestHelperTrait.html new file mode 100644 index 000000000..f64b62171 --- /dev/null +++ b/docs/arecibo/traits/snark/trait.DigestHelperTrait.html @@ -0,0 +1,6 @@ +DigestHelperTrait in arecibo::traits::snark - Rust
pub trait DigestHelperTrait<E: Engine> {
+    // Required method
+    fn digest(&self) -> E::Scalar;
+}
Expand description

A helper trait that defines the behavior of a verifier key of zkSNARK

+

Required Methods§

source

fn digest(&self) -> E::Scalar

Returns the digest of the verifier’s key

+

Implementors§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for arecibo::spartan::batched::VerifierKey<E, EE>

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for arecibo::spartan::batched_ppsnark::VerifierKey<E, EE>

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for arecibo::spartan::ppsnark::VerifierKey<E, EE>

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for arecibo::spartan::snark::VerifierKey<E, EE>

\ No newline at end of file diff --git a/docs/arecibo/traits/snark/trait.RelaxedR1CSSNARKTrait.html b/docs/arecibo/traits/snark/trait.RelaxedR1CSSNARKTrait.html new file mode 100644 index 000000000..908e1bb93 --- /dev/null +++ b/docs/arecibo/traits/snark/trait.RelaxedR1CSSNARKTrait.html @@ -0,0 +1,50 @@ +RelaxedR1CSSNARKTrait in arecibo::traits::snark - Rust
pub trait RelaxedR1CSSNARKTrait<E: Engine>: Send + Sync + Serialize + for<'de> Deserialize<'de> {
+    type ProverKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+    type VerifierKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + DigestHelperTrait<E> + Abomonation;
+
+    // Required methods
+    fn setup(
+        ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+        S: &R1CSShape<E>
+    ) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>;
+    fn prove(
+        ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+        pk: &Self::ProverKey,
+        S: &R1CSShape<E>,
+        U: &RelaxedR1CSInstance<E>,
+        W: &RelaxedR1CSWitness<E>
+    ) -> Result<Self, NovaError>;
+    fn verify(
+        &self,
+        vk: &Self::VerifierKey,
+        U: &RelaxedR1CSInstance<E>
+    ) -> Result<(), NovaError>;
+
+    // Provided method
+    fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize> { ... }
+}
Expand description

A trait that defines the behavior of a zkSNARK

+

Required Associated Types§

source

type ProverKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation

A type that represents the prover’s key

+
source

type VerifierKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + DigestHelperTrait<E> + Abomonation

A type that represents the verifier’s key

+

Required Methods§

source

fn setup( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + S: &R1CSShape<E> +) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>

Produces the keys for the prover and the verifier

+
source

fn prove( + ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey, + pk: &Self::ProverKey, + S: &R1CSShape<E>, + U: &RelaxedR1CSInstance<E>, + W: &RelaxedR1CSWitness<E> +) -> Result<Self, NovaError>

Produces a new SNARK for a relaxed R1CS

+
source

fn verify( + &self, + vk: &Self::VerifierKey, + U: &RelaxedR1CSInstance<E> +) -> Result<(), NovaError>

Verifies a SNARK for a relaxed R1CS

+

Provided Methods§

source

fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize>

This associated function (not a method) provides a hint that offers +a minimum sizing cue for the commitment key used by this SNARK +implementation. The commitment key passed in setup should then +be at least as large as this hint.

+

Implementors§

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> RelaxedR1CSSNARKTrait<E> for arecibo::spartan::ppsnark::RelaxedR1CSSNARK<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

§

type ProverKey = ProverKey<E, EE>

§

type VerifierKey = VerifierKey<E, EE>

source§

impl<E: Engine, EE: EvaluationEngineTrait<E>> RelaxedR1CSSNARKTrait<E> for arecibo::spartan::snark::RelaxedR1CSSNARK<E, EE>where + <E::Scalar as PrimeField>::Repr: Abomonation,

§

type ProverKey = ProverKey<E, EE>

§

type VerifierKey = VerifierKey<E, EE>

\ No newline at end of file diff --git a/docs/arecibo/traits/trait.AbsorbInROTrait.html b/docs/arecibo/traits/trait.AbsorbInROTrait.html new file mode 100644 index 000000000..b5ea51e77 --- /dev/null +++ b/docs/arecibo/traits/trait.AbsorbInROTrait.html @@ -0,0 +1,6 @@ +AbsorbInROTrait in arecibo::traits - Rust
pub trait AbsorbInROTrait<E: Engine> {
+    // Required method
+    fn absorb_in_ro(&self, ro: &mut E::RO);
+}
Expand description

A helper trait to absorb different objects in RO

+

Required Methods§

source

fn absorb_in_ro(&self, ro: &mut E::RO)

Absorbs the value in the provided RO

+

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/trait.Engine.html b/docs/arecibo/traits/trait.Engine.html new file mode 100644 index 000000000..287a4b529 --- /dev/null +++ b/docs/arecibo/traits/trait.Engine.html @@ -0,0 +1,18 @@ +Engine in arecibo::traits - Rust

Trait arecibo::traits::Engine

source ·
pub trait Engine: Clone + Copy + Debug + Send + Sync + Sized + Eq + PartialEq {
+    type Base: PrimeFieldBits + TranscriptReprTrait<Self::GE> + Serialize + for<'de> Deserialize<'de>;
+    type Scalar: PrimeFieldBits + PrimeFieldExt + Send + Sync + TranscriptReprTrait<Self::GE> + Serialize + for<'de> Deserialize<'de>;
+    type GE: Group<Base = Self::Base, Scalar = Self::Scalar> + Serialize + for<'de> Deserialize<'de>;
+    type RO: ROTrait<Self::Base, Self::Scalar>;
+    type ROCircuit: ROCircuitTrait<Self::Base>;
+    type TE: TranscriptEngineTrait<Self>;
+    type CE: CommitmentEngineTrait<Self>;
+}
Expand description

A collection of engines that are required by the library

+

Required Associated Types§

source

type Base: PrimeFieldBits + TranscriptReprTrait<Self::GE> + Serialize + for<'de> Deserialize<'de>

A type representing an element of the base field of the group

+
source

type Scalar: PrimeFieldBits + PrimeFieldExt + Send + Sync + TranscriptReprTrait<Self::GE> + Serialize + for<'de> Deserialize<'de>

A type representing an element of the scalar field of the group

+
source

type GE: Group<Base = Self::Base, Scalar = Self::Scalar> + Serialize + for<'de> Deserialize<'de>

A type that represents an element of the group

+
source

type RO: ROTrait<Self::Base, Self::Scalar>

A type that represents a circuit-friendly sponge that consumes elements +from the base field and squeezes out elements of the scalar field

+
source

type ROCircuit: ROCircuitTrait<Self::Base>

An alternate implementation of Self::RO in the circuit model

+
source

type TE: TranscriptEngineTrait<Self>

A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs

+
source

type CE: CommitmentEngineTrait<Self>

A type that defines a commitment engine over scalars in the group

+

Implementors§

source§

impl Engine for Bn256Engine

§

type Base = Fq

§

type Scalar = Fr

§

type GE = G1

§

type RO = PoseidonRO<<Bn256Engine as Engine>::Base, <Bn256Engine as Engine>::Scalar>

§

type ROCircuit = PoseidonROCircuit<<Bn256Engine as Engine>::Base>

§

type TE = Keccak256Transcript<Bn256Engine>

§

type CE = CommitmentEngine<Bn256Engine>

source§

impl Engine for Bn256EngineKZG

§

type Base = Fq

§

type Scalar = Fr

§

type GE = G1

§

type RO = PoseidonRO<<Bn256EngineKZG as Engine>::Base, <Bn256EngineKZG as Engine>::Scalar>

§

type ROCircuit = PoseidonROCircuit<<Bn256EngineKZG as Engine>::Base>

§

type TE = Keccak256Transcript<Bn256EngineKZG>

§

type CE = KZGCommitmentEngine<Bn256>

source§

impl Engine for Bn256EngineZM

§

type Base = Fq

§

type Scalar = Fr

§

type GE = G1

§

type RO = PoseidonRO<<Bn256EngineZM as Engine>::Base, <Bn256EngineZM as Engine>::Scalar>

§

type ROCircuit = PoseidonROCircuit<<Bn256EngineZM as Engine>::Base>

§

type TE = Keccak256Transcript<Bn256EngineZM>

§

type CE = KZGCommitmentEngine<Bn256>

source§

impl Engine for GrumpkinEngine

§

type Base = Fr

§

type Scalar = Fq

§

type GE = G1

§

type RO = PoseidonRO<<GrumpkinEngine as Engine>::Base, <GrumpkinEngine as Engine>::Scalar>

§

type ROCircuit = PoseidonROCircuit<<GrumpkinEngine as Engine>::Base>

§

type TE = Keccak256Transcript<GrumpkinEngine>

§

type CE = CommitmentEngine<GrumpkinEngine>

source§

impl Engine for PallasEngine

§

type Base = Fp

§

type Scalar = Fq

§

type GE = Ep

§

type RO = PoseidonRO<<PallasEngine as Engine>::Base, <PallasEngine as Engine>::Scalar>

§

type ROCircuit = PoseidonROCircuit<<PallasEngine as Engine>::Base>

§

type TE = Keccak256Transcript<PallasEngine>

§

type CE = CommitmentEngine<PallasEngine>

source§

impl Engine for Secp256k1Engine

§

type Base = Fp

§

type Scalar = Fq

§

type GE = Secp256k1

§

type RO = PoseidonRO<<Secp256k1Engine as Engine>::Base, <Secp256k1Engine as Engine>::Scalar>

§

type ROCircuit = PoseidonROCircuit<<Secp256k1Engine as Engine>::Base>

§

type TE = Keccak256Transcript<Secp256k1Engine>

§

type CE = CommitmentEngine<Secp256k1Engine>

source§

impl Engine for Secq256k1Engine

§

type Base = Fq

§

type Scalar = Fp

§

type GE = Secq256k1

§

type RO = PoseidonRO<<Secq256k1Engine as Engine>::Base, <Secq256k1Engine as Engine>::Scalar>

§

type ROCircuit = PoseidonROCircuit<<Secq256k1Engine as Engine>::Base>

§

type TE = Keccak256Transcript<Secq256k1Engine>

§

type CE = CommitmentEngine<Secq256k1Engine>

source§

impl Engine for VestaEngine

§

type Base = Fq

§

type Scalar = Fp

§

type GE = Eq

§

type RO = PoseidonRO<<VestaEngine as Engine>::Base, <VestaEngine as Engine>::Scalar>

§

type ROCircuit = PoseidonROCircuit<<VestaEngine as Engine>::Base>

§

type TE = Keccak256Transcript<VestaEngine>

§

type CE = CommitmentEngine<VestaEngine>

\ No newline at end of file diff --git a/docs/arecibo/traits/trait.Group.html b/docs/arecibo/traits/trait.Group.html new file mode 100644 index 000000000..b5bec9064 --- /dev/null +++ b/docs/arecibo/traits/trait.Group.html @@ -0,0 +1,12 @@ +Group in arecibo::traits - Rust

Trait arecibo::traits::Group

source ·
pub trait Group: Clone + Copy + Debug + Send + Sync + Sized + Eq + PartialEq {
+    type Base: PrimeFieldBits + Serialize + for<'de> Deserialize<'de>;
+    type Scalar: PrimeFieldBits + PrimeFieldExt + Send + Sync + Serialize + for<'de> Deserialize<'de>;
+
+    // Required method
+    fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt);
+}
Expand description

Represents an element of a group +This is currently tailored for an elliptic curve group

+

Required Associated Types§

source

type Base: PrimeFieldBits + Serialize + for<'de> Deserialize<'de>

A type representing an element of the base field of the group

+
source

type Scalar: PrimeFieldBits + PrimeFieldExt + Send + Sync + Serialize + for<'de> Deserialize<'de>

A type representing an element of the scalar field of the group

+

Required Methods§

source

fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt)

Returns A, B, the order of the group, the size of the base field as big integers

+

Implementations on Foreign Types§

source§

impl Group for Point

§

type Base = Fp

§

type Scalar = Fq

source§

fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt)

source§

impl Group for Point

§

type Base = Fq

§

type Scalar = Fr

source§

fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt)

source§

impl Group for Point

§

type Base = Fq

§

type Scalar = Fp

source§

fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt)

source§

impl Group for Point

§

type Base = Fq

§

type Scalar = Fp

source§

fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt)

source§

impl Group for Point

§

type Base = Fr

§

type Scalar = Fq

source§

fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt)

source§

impl Group for Point

§

type Base = Fp

§

type Scalar = Fq

source§

fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt)

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/trait.PrimeFieldExt.html b/docs/arecibo/traits/trait.PrimeFieldExt.html new file mode 100644 index 000000000..4b30ee39b --- /dev/null +++ b/docs/arecibo/traits/trait.PrimeFieldExt.html @@ -0,0 +1,6 @@ +PrimeFieldExt in arecibo::traits - Rust
pub trait PrimeFieldExt: PrimeField {
+    // Required method
+    fn from_uniform(bytes: &[u8]) -> Self;
+}
Expand description

Defines additional methods on PrimeField objects

+

Required Methods§

source

fn from_uniform(bytes: &[u8]) -> Self

Returns a scalar representing the bytes

+

Implementations on Foreign Types§

source§

impl PrimeFieldExt for Scalar

source§

fn from_uniform(bytes: &[u8]) -> Self

source§

impl PrimeFieldExt for Scalar

source§

fn from_uniform(bytes: &[u8]) -> Self

source§

impl PrimeFieldExt for Scalar

source§

fn from_uniform(bytes: &[u8]) -> Self

source§

impl PrimeFieldExt for Scalar

source§

fn from_uniform(bytes: &[u8]) -> Self

source§

impl PrimeFieldExt for Scalar

source§

fn from_uniform(bytes: &[u8]) -> Self

source§

impl PrimeFieldExt for Scalar

source§

fn from_uniform(bytes: &[u8]) -> Self

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/trait.ROCircuitTrait.html b/docs/arecibo/traits/trait.ROCircuitTrait.html new file mode 100644 index 000000000..2ccf4c506 --- /dev/null +++ b/docs/arecibo/traits/trait.ROCircuitTrait.html @@ -0,0 +1,23 @@ +ROCircuitTrait in arecibo::traits - Rust
pub trait ROCircuitTrait<Base: PrimeField> {
+    type NativeRO<T: PrimeField>: ROTrait<Base, T, Constants = Self::Constants>;
+    type Constants: Default + Clone + PartialEq + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+
+    // Required methods
+    fn new(constants: Self::Constants, num_absorbs: usize) -> Self;
+    fn absorb(&mut self, e: &AllocatedNum<Base>);
+    fn squeeze<CS: ConstraintSystem<Base>>(
+        &mut self,
+        cs: CS,
+        num_bits: usize
+    ) -> Result<Vec<AllocatedBit>, SynthesisError>;
+}
Expand description

A helper trait that defines the behavior of a hash function that we use as an RO in the circuit model

+

Required Associated Types§

source

type NativeRO<T: PrimeField>: ROTrait<Base, T, Constants = Self::Constants>

the vanilla alter ego of this trait - this constrains it to use the same constants

+
source

type Constants: Default + Clone + PartialEq + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation

A type representing constants/parameters associated with the hash function on this Base field

+

Required Methods§

source

fn new(constants: Self::Constants, num_absorbs: usize) -> Self

Initializes the hash function

+
source

fn absorb(&mut self, e: &AllocatedNum<Base>)

Adds a scalar to the internal state

+
source

fn squeeze<CS: ConstraintSystem<Base>>( + &mut self, + cs: CS, + num_bits: usize +) -> Result<Vec<AllocatedBit>, SynthesisError>

Returns a challenge of num_bits by hashing the internal state

+

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/trait.ROTrait.html b/docs/arecibo/traits/trait.ROTrait.html new file mode 100644 index 000000000..63ea723a5 --- /dev/null +++ b/docs/arecibo/traits/trait.ROTrait.html @@ -0,0 +1,15 @@ +ROTrait in arecibo::traits - Rust

Trait arecibo::traits::ROTrait

source ·
pub trait ROTrait<Base: PrimeField, Scalar> {
+    type CircuitRO: ROCircuitTrait<Base, Constants = Self::Constants>;
+    type Constants: Default + Clone + PartialEq + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+
+    // Required methods
+    fn new(constants: Self::Constants, num_absorbs: usize) -> Self;
+    fn absorb(&mut self, e: Base);
+    fn squeeze(&mut self, num_bits: usize) -> Scalar;
+}
Expand description

A helper trait that defines the behavior of a hash function that we use as an RO

+

Required Associated Types§

source

type CircuitRO: ROCircuitTrait<Base, Constants = Self::Constants>

The circuit alter ego of this trait impl - this constrains it to use the same constants

+
source

type Constants: Default + Clone + PartialEq + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation

A type representing constants/parameters associated with the hash function

+

Required Methods§

source

fn new(constants: Self::Constants, num_absorbs: usize) -> Self

Initializes the hash function

+
source

fn absorb(&mut self, e: Base)

Adds a scalar to the internal state

+
source

fn squeeze(&mut self, num_bits: usize) -> Scalar

Returns a challenge of num_bits by hashing the internal state

+

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/trait.TranscriptEngineTrait.html b/docs/arecibo/traits/trait.TranscriptEngineTrait.html new file mode 100644 index 000000000..5ed3f97fd --- /dev/null +++ b/docs/arecibo/traits/trait.TranscriptEngineTrait.html @@ -0,0 +1,16 @@ +TranscriptEngineTrait in arecibo::traits - Rust
pub trait TranscriptEngineTrait<E: Engine>: Send + Sync {
+    // Required methods
+    fn new(label: &'static [u8]) -> Self;
+    fn squeeze(&mut self, label: &'static [u8]) -> Result<E::Scalar, NovaError>;
+    fn absorb<T: TranscriptReprTrait<E::GE>>(
+        &mut self,
+        label: &'static [u8],
+        o: &T
+    );
+    fn dom_sep(&mut self, bytes: &'static [u8]);
+}
Expand description

This trait defines the behavior of a transcript engine compatible with Spartan

+

Required Methods§

source

fn new(label: &'static [u8]) -> Self

initializes the transcript

+
source

fn squeeze(&mut self, label: &'static [u8]) -> Result<E::Scalar, NovaError>

returns a scalar element of the group as a challenge

+
source

fn absorb<T: TranscriptReprTrait<E::GE>>(&mut self, label: &'static [u8], o: &T)

absorbs any type that implements TranscriptReprTrait under a label

+
source

fn dom_sep(&mut self, bytes: &'static [u8])

adds a domain separator

+

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/trait.TranscriptReprTrait.html b/docs/arecibo/traits/trait.TranscriptReprTrait.html new file mode 100644 index 000000000..300b0d0fc --- /dev/null +++ b/docs/arecibo/traits/trait.TranscriptReprTrait.html @@ -0,0 +1,6 @@ +TranscriptReprTrait in arecibo::traits - Rust
pub trait TranscriptReprTrait<G: Group>: Send + Sync {
+    // Required method
+    fn to_transcript_bytes(&self) -> Vec<u8> ;
+}
Expand description

This trait allows types to implement how they want to be added to TranscriptEngine

+

Required Methods§

source

fn to_transcript_bytes(&self) -> Vec<u8>

returns a byte representation of self to be added to the transcript

+

Implementations on Foreign Types§

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Affine

source§

impl<G: Group> TranscriptReprTrait<G> for Scalar

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Affine

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Compressed

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Affine

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Affine

source§

impl<G: Group> TranscriptReprTrait<G> for Scalar

source§

impl<G: Group, T: TranscriptReprTrait<G>> TranscriptReprTrait<G> for &[T]

source§

impl<G: Group> TranscriptReprTrait<G> for Scalar

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Affine

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Compressed

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Compressed

source§

impl<G: Group> TranscriptReprTrait<G> for Scalar

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Affine

source§

impl<G: Group> TranscriptReprTrait<G> for Scalar

source§

impl<G: Group> TranscriptReprTrait<G> for Scalar

source§

impl<G: DlogGroup> TranscriptReprTrait<G> for Compressed

Implementors§

\ No newline at end of file diff --git a/docs/arecibo/traits/type.ROConstants.html b/docs/arecibo/traits/type.ROConstants.html new file mode 100644 index 000000000..2c53407d0 --- /dev/null +++ b/docs/arecibo/traits/type.ROConstants.html @@ -0,0 +1,2 @@ +ROConstants in arecibo::traits - Rust

Type Definition arecibo::traits::ROConstants

source ·
pub type ROConstants<E> = <<E as Engine>::RO as ROTrait<<E as Engine>::Base, <E as Engine>::Scalar>>::Constants;
Expand description

An alias for constants associated with E::RO

+
\ No newline at end of file diff --git a/docs/arecibo/traits/type.ROConstantsCircuit.html b/docs/arecibo/traits/type.ROConstantsCircuit.html new file mode 100644 index 000000000..2746cfc59 --- /dev/null +++ b/docs/arecibo/traits/type.ROConstantsCircuit.html @@ -0,0 +1,2 @@ +ROConstantsCircuit in arecibo::traits - Rust

Type Definition arecibo::traits::ROConstantsCircuit

source ·
pub type ROConstantsCircuit<E> = <<E as Engine>::ROCircuit as ROCircuitTrait<<E as Engine>::Base>>::Constants;
Expand description

An alias for constants associated with E::ROCircuit

+
\ No newline at end of file diff --git a/docs/crates.js b/docs/crates.js new file mode 100644 index 000000000..4b6f654cb --- /dev/null +++ b/docs/crates.js @@ -0,0 +1 @@ +window.ALL_CRATES = ["arecibo"]; \ No newline at end of file diff --git a/docs/help.html b/docs/help.html new file mode 100644 index 000000000..9a1d81dc8 --- /dev/null +++ b/docs/help.html @@ -0,0 +1 @@ +Rustdoc help

Rustdoc help

Back
\ No newline at end of file diff --git a/docs/implementors/abomonation/trait.Abomonation.js b/docs/implementors/abomonation/trait.Abomonation.js new file mode 100644 index 000000000..585b6e717 --- /dev/null +++ b/docs/implementors/abomonation/trait.Abomonation.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<E: Engine> Abomonation for ProverKey<E>"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for VerifierKey<E, EE>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for ProverKey<E, EE>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E1, E2, C1, C2> Abomonation for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n <E1::Scalar as PrimeField>::Repr: Abomonation,\n <E2::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine> Abomonation for ZMProverKey<E>"],["impl<E: Engine> Abomonation for ZMVerifierKey<E>"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for VerifierKey<E, EE>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E1, E2> Abomonation for AuxParams<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n <E1::Scalar as PrimeField>::Repr: Abomonation,\n <E2::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E1, E2, C1, C2, S1, S2> Abomonation for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: BatchedRelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,\n <E1::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine> Abomonation for R1CSWithArity<E>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine> Abomonation for R1CSShapeSparkCommitment<E>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine> Abomonation for VerifierKey<E>"],["impl<E1, E2, C1, C2, S1, S2> Abomonation for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: RelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for ProverKey<E, EE>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E1, E2, C1, C2, S1, S2> Abomonation for VerifierKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: BatchedRelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,\n <E1::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for ProverKey<E, EE>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for VerifierKey<E, EE>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine> Abomonation for R1CSShape<E>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E1, E2, C1, C2, S1, S2> Abomonation for VerifierKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: RelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,\n <E1::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for ProverKey<E, EE>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine> Abomonation for R1CSShapeSparkRepr<E>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Abomonation for VerifierKey<E, EE>where\n <E::Scalar as PrimeField>::Repr: Abomonation,"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/supernova/circuit/trait.StepCircuit.js b/docs/implementors/arecibo/supernova/circuit/trait.StepCircuit.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/supernova/circuit/trait.StepCircuit.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/circuit/trait.StepCircuit.js b/docs/implementors/arecibo/traits/circuit/trait.StepCircuit.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/circuit/trait.StepCircuit.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/commitment/trait.ScalarMul.js b/docs/implementors/arecibo/traits/commitment/trait.ScalarMul.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/commitment/trait.ScalarMul.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/evaluation/trait.EvaluationEngineTrait.js b/docs/implementors/arecibo/traits/evaluation/trait.EvaluationEngineTrait.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/evaluation/trait.EvaluationEngineTrait.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/snark/trait.BatchedRelaxedR1CSSNARKTrait.js b/docs/implementors/arecibo/traits/snark/trait.BatchedRelaxedR1CSSNARKTrait.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/snark/trait.BatchedRelaxedR1CSSNARKTrait.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/snark/trait.DigestHelperTrait.js b/docs/implementors/arecibo/traits/snark/trait.DigestHelperTrait.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/snark/trait.DigestHelperTrait.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/snark/trait.RelaxedR1CSSNARKTrait.js b/docs/implementors/arecibo/traits/snark/trait.RelaxedR1CSSNARKTrait.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/snark/trait.RelaxedR1CSSNARKTrait.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/trait.AbsorbInROTrait.js b/docs/implementors/arecibo/traits/trait.AbsorbInROTrait.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/trait.AbsorbInROTrait.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/trait.Engine.js b/docs/implementors/arecibo/traits/trait.Engine.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/trait.Engine.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/trait.Group.js b/docs/implementors/arecibo/traits/trait.Group.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/trait.Group.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/trait.PrimeFieldExt.js b/docs/implementors/arecibo/traits/trait.PrimeFieldExt.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/trait.PrimeFieldExt.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/arecibo/traits/trait.TranscriptReprTrait.js b/docs/implementors/arecibo/traits/trait.TranscriptReprTrait.js new file mode 100644 index 000000000..4fa8c4669 --- /dev/null +++ b/docs/implementors/arecibo/traits/trait.TranscriptReprTrait.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/clone/trait.Clone.js b/docs/implementors/core/clone/trait.Clone.js new file mode 100644 index 000000000..d52ecdde8 --- /dev/null +++ b/docs/implementors/core/clone/trait.Clone.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl Clone for Bn256EngineZM"],["impl<Scalar: Clone> Clone for MultilinearPolynomial<Scalar>"],["impl<E: Clone + Engine> Clone for CircuitDigests<E>where\n E::Scalar: Clone,"],["impl<E: Clone + Engine> Clone for AllocatedPoint<E>where\n E::Base: Clone,"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for BatchedRelaxedR1CSSNARK<E, EE>where\n E::Scalar: Clone,\n EE::EvaluationArgument: Clone,"],["impl<E: Clone + Engine> Clone for R1CSWithArity<E>"],["impl<E: Clone + Engine> Clone for R1CSWitness<E>where\n E::Scalar: Clone,"],["impl Clone for Bn256Engine"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for ProverKey<E, EE>where\n EE::ProverKey: Clone,\n E::Scalar: Clone,"],["impl Clone for Secp256k1Engine"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for VerifierKey<E, EE>where\n EE::VerifierKey: Clone,\n E::Scalar: Clone,"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for VerifierKey<E, EE>where\n EE::VerifierKey: Clone,\n E::Scalar: Clone,"],["impl Clone for PCSError"],["impl<E1, E2> Clone for RecursiveSNARK<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n E1::Scalar: Clone,\n E2::Scalar: Clone,"],["impl<E: Clone + Engine> Clone for RelaxedR1CSInstance<E>where\n E::Scalar: Clone,"],["impl<E: Clone, NE: Clone> Clone for EvaluationEngine<E, NE>"],["impl Clone for PallasEngine"],["impl<E: Clone + Engine> Clone for ProverKey<E>"],["impl<E: Clone + Engine> Clone for ZMEvaluation<E>where\n E::Fr: Clone,"],["impl<E: Clone + Engine> Clone for RelaxedR1CSWitness<E>where\n E::Scalar: Clone,"],["impl<E1, E2> Clone for AuxParams<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n E1::Scalar: Clone,"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for VerifierKey<E, EE>where\n EE::VerifierKey: Clone,\n E::Scalar: Clone,"],["impl<E: Clone + Engine> Clone for R1CSInstance<E>where\n E::Scalar: Clone,"],["impl<E: Clone> Clone for EvaluationEngine<E>"],["impl Clone for Secq256k1Engine"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for VerifierKey<E, EE>where\n EE::VerifierKey: Clone,\n E::Scalar: Clone,"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for RelaxedR1CSSNARK<E, EE>where\n E::Scalar: Clone,\n EE::EvaluationArgument: Clone,"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for ProverKey<E, EE>where\n EE::ProverKey: Clone,\n E::Scalar: Clone,"],["impl<E1, E2, C1, C2, S1, S2> Clone for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n S1: RelaxedR1CSSNARKTrait<E1> + Clone,\n S2: RelaxedR1CSSNARKTrait<E2> + Clone,\n S1::ProverKey: Clone,\n S2::ProverKey: Clone,"],["impl<F: Clone> Clone for TrivialSecondaryCircuit<F>"],["impl<E: Clone + Engine> Clone for EvaluationArgument<E>where\n E::G1Affine: Clone,\n E::Fr: Clone,"],["impl<E: Clone + Engine> Clone for R1CSShape<E>where\n E::Scalar: Clone,"],["impl<E: Clone + Engine> Clone for ZMVerifierKey<E>where\n E::G2Affine: Clone,"],["impl<F: Clone> Clone for TrivialTestCircuit<F>"],["impl<E: Clone + Engine> Clone for ZMCommitment<E>where\n E::G1Affine: Clone,"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for ProverKey<E, EE>where\n EE::ProverKey: Clone,\n E::Scalar: Clone,"],["impl<E: Clone + Engine> Clone for VerifierKey<E>"],["impl<F: Clone> Clone for TrivialCircuit<F>"],["impl Clone for SuperNovaError"],["impl<E1, E2, C1, C2> Clone for RecursiveSNARK<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n E1::Scalar: Clone,\n E2::Scalar: Clone,"],["impl<E: Clone + Engine> Clone for R1CSResult<E>where\n E::Scalar: Clone,"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for BatchedRelaxedR1CSSNARK<E, EE>where\n E::Scalar: Clone,\n EE::EvaluationArgument: Clone,"],["impl<E1, E2, C1, C2, S1, S2> Clone for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n S1: RelaxedR1CSSNARKTrait<E1> + Clone,\n S2: RelaxedR1CSSNARKTrait<E2> + Clone,\n E1::Scalar: Clone,\n E2::Scalar: Clone,"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for RelaxedR1CSSNARK<E, EE>where\n E::Scalar: Clone,\n EE::EvaluationArgument: Clone,"],["impl<E: Clone + Engine> Clone for ZMProverKey<E>"],["impl<E: Clone + Engine, EE: Clone + EvaluationEngineTrait<E>> Clone for ProverKey<E, EE>where\n EE::ProverKey: Clone,\n E::Scalar: Clone,"],["impl<E: Clone + Engine> Clone for AllocatedPointNonInfinity<E>where\n E::Base: Clone,"],["impl<E: Clone + Engine> Clone for ResourceBuffer<E>where\n E::Scalar: Clone,"],["impl Clone for GrumpkinEngine"],["impl<E: Clone + Engine> Clone for ZMProof<E>where\n E::G1Affine: Clone,"],["impl<E: Clone, NE: Clone> Clone for ZMPCS<E, NE>"],["impl<E: Clone + Engine> Clone for R1CSShapeSparkRepr<E>where\n E::Scalar: Clone,"],["impl<E1, E2, C1, C2, S1, S2> Clone for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n S1: BatchedRelaxedR1CSSNARKTrait<E1> + Clone,\n S2: RelaxedR1CSSNARKTrait<E2> + Clone,\n E1::Scalar: Clone,\n E2::Scalar: Clone,"],["impl<E1, E2, C1, C2, S1, S2> Clone for VerifierKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n S1: RelaxedR1CSSNARKTrait<E1> + Clone,\n S2: RelaxedR1CSSNARKTrait<E2> + Clone,\n E1::Scalar: Clone,\n S1::VerifierKey: Clone,\n S2::VerifierKey: Clone,"],["impl<E1, E2, C1, C2> Clone for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n E1::Scalar: Clone,"],["impl Clone for Bn256EngineKZG"],["impl<E1, E2, C1, C2, S1, S2> Clone for VerifierKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n S1: BatchedRelaxedR1CSSNARKTrait<E1> + Clone,\n S2: RelaxedR1CSSNARKTrait<E2> + Clone,\n S1::VerifierKey: Clone,\n S2::VerifierKey: Clone,"],["impl<E1, E2, C1, C2> Clone for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n E1::Scalar: Clone,"],["impl Clone for VestaEngine"],["impl<E1, E2, C1, C2, S1, S2> Clone for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Clone,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Clone,\n C1: StepCircuit<E1::Scalar> + Clone,\n C2: StepCircuit<E2::Scalar> + Clone,\n S1: BatchedRelaxedR1CSSNARKTrait<E1> + Clone,\n S2: RelaxedR1CSSNARKTrait<E2> + Clone,\n S1::ProverKey: Clone,\n S2::ProverKey: Clone,"],["impl<E: Clone + Engine> Clone for InnerProductArgument<E>where\n E::Scalar: Clone,"],["impl Clone for NovaError"],["impl<E: Clone + Engine> Clone for R1CSShapeSparkCommitment<E>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/cmp/trait.Eq.js b/docs/implementors/core/cmp/trait.Eq.js new file mode 100644 index 000000000..810e1b02d --- /dev/null +++ b/docs/implementors/core/cmp/trait.Eq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<E: Eq + Engine> Eq for ZMProof<E>where\n E::G1Affine: Eq,"],["impl Eq for Bn256EngineKZG"],["impl<E: Eq + Engine> Eq for ZMEvaluation<E>where\n E::Fr: Eq,"],["impl<E: Eq + Engine> Eq for RelaxedR1CSInstance<E>where\n E::Scalar: Eq,"],["impl Eq for Secp256k1Engine"],["impl<Scalar: Eq> Eq for MultilinearPolynomial<Scalar>"],["impl<E: Eq, NE: Eq> Eq for ZMPCS<E, NE>"],["impl<E: Eq + Engine> Eq for R1CSInstance<E>where\n E::Scalar: Eq,"],["impl Eq for Bn256EngineZM"],["impl<E: Eq + Engine> Eq for R1CSWithArity<E>"],["impl<E: Eq + Engine> Eq for ZMCommitment<E>where\n E::G1Affine: Eq,"],["impl Eq for Secq256k1Engine"],["impl<E: Eq + Engine> Eq for R1CSShape<E>where\n E::Scalar: Eq,"],["impl Eq for PCSError"],["impl Eq for Bn256Engine"],["impl<E: Eq + Engine> Eq for ZMProverKey<E>"],["impl<E: Eq + Engine> Eq for RelaxedR1CSWitness<E>where\n E::Scalar: Eq,"],["impl Eq for GrumpkinEngine"],["impl<E: Eq + Engine> Eq for R1CSWitness<E>where\n E::Scalar: Eq,"],["impl Eq for NovaError"],["impl Eq for PallasEngine"],["impl Eq for SuperNovaError"],["impl<E: Eq + Engine> Eq for ZMVerifierKey<E>where\n E::G2Affine: Eq,"],["impl<E: Eq + Engine> Eq for CircuitDigests<E>where\n E::Scalar: Eq,"],["impl<F: Eq> Eq for TrivialCircuit<F>"],["impl Eq for VestaEngine"],["impl<E: Eq + Engine> Eq for R1CSResult<E>where\n E::Scalar: Eq,"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/cmp/trait.PartialEq.js b/docs/implementors/core/cmp/trait.PartialEq.js new file mode 100644 index 000000000..952adf7c1 --- /dev/null +++ b/docs/implementors/core/cmp/trait.PartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl PartialEq<Bn256EngineZM> for Bn256EngineZM"],["impl PartialEq<GrumpkinEngine> for GrumpkinEngine"],["impl<F: PartialEq> PartialEq<TrivialCircuit<F>> for TrivialCircuit<F>"],["impl<E1, E2, C1, C2> PartialEq<PublicParams<E1, E2, C1, C2>> for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + PartialEq,\n E2: Engine<Base = <E1 as Engine>::Scalar> + PartialEq,\n C1: StepCircuit<E1::Scalar> + PartialEq,\n C2: StepCircuit<E2::Scalar> + PartialEq,\n E1::Scalar: PartialEq,"],["impl<Scalar: PartialEq> PartialEq<MultilinearPolynomial<Scalar>> for MultilinearPolynomial<Scalar>"],["impl<E: PartialEq + Engine> PartialEq<ZMVerifierKey<E>> for ZMVerifierKey<E>where\n E::G2Affine: PartialEq,"],["impl<E: PartialEq + Engine> PartialEq<R1CSInstance<E>> for R1CSInstance<E>where\n E::Scalar: PartialEq,"],["impl<E: PartialEq + Engine> PartialEq<RelaxedR1CSWitness<E>> for RelaxedR1CSWitness<E>where\n E::Scalar: PartialEq,"],["impl PartialEq<PCSError> for PCSError"],["impl PartialEq<PallasEngine> for PallasEngine"],["impl<E: PartialEq + Engine> PartialEq<CircuitDigests<E>> for CircuitDigests<E>where\n E::Scalar: PartialEq,"],["impl<E1, E2> PartialEq<AuxParams<E1, E2>> for AuxParams<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + PartialEq,\n E2: Engine<Base = <E1 as Engine>::Scalar> + PartialEq,\n E1::Scalar: PartialEq,"],["impl<E: PartialEq + Engine> PartialEq<ZMCommitment<E>> for ZMCommitment<E>where\n E::G1Affine: PartialEq,"],["impl<E: PartialEq + Engine> PartialEq<R1CSShape<E>> for R1CSShape<E>where\n E::Scalar: PartialEq,"],["impl<E: PartialEq + Engine> PartialEq<R1CSWithArity<E>> for R1CSWithArity<E>"],["impl<E: PartialEq + Engine> PartialEq<ZMEvaluation<E>> for ZMEvaluation<E>where\n E::Fr: PartialEq,"],["impl PartialEq<SuperNovaError> for SuperNovaError"],["impl PartialEq<Secq256k1Engine> for Secq256k1Engine"],["impl<E: PartialEq + Engine> PartialEq<RelaxedR1CSInstance<E>> for RelaxedR1CSInstance<E>where\n E::Scalar: PartialEq,"],["impl<E: PartialEq + Engine> PartialEq<R1CSWitness<E>> for R1CSWitness<E>where\n E::Scalar: PartialEq,"],["impl PartialEq<Bn256EngineKZG> for Bn256EngineKZG"],["impl PartialEq<NovaError> for NovaError"],["impl<E: PartialEq + Engine> PartialEq<ZMProverKey<E>> for ZMProverKey<E>"],["impl<E: PartialEq, NE: PartialEq> PartialEq<ZMPCS<E, NE>> for ZMPCS<E, NE>"],["impl<E: PartialEq + Engine> PartialEq<R1CSResult<E>> for R1CSResult<E>where\n E::Scalar: PartialEq,"],["impl PartialEq<VestaEngine> for VestaEngine"],["impl PartialEq<Secp256k1Engine> for Secp256k1Engine"],["impl<E: PartialEq + Engine> PartialEq<ZMProof<E>> for ZMProof<E>where\n E::G1Affine: PartialEq,"],["impl PartialEq<Bn256Engine> for Bn256Engine"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/convert/trait.From.js b/docs/implementors/core/convert/trait.From.js new file mode 100644 index 000000000..0351f6bdf --- /dev/null +++ b/docs/implementors/core/convert/trait.From.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl From<PCSError> for NovaError"],["impl From<SynthesisError> for NovaError"],["impl From<NovaError> for SuperNovaError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/default/trait.Default.js b/docs/implementors/core/default/trait.Default.js new file mode 100644 index 000000000..50c0c1a6b --- /dev/null +++ b/docs/implementors/core/default/trait.Default.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<E: Default + Engine> Default for ZMProof<E>where\n E::G1Affine: Default,"],["impl<F: Default> Default for TrivialCircuit<F>"],["impl<F: Default> Default for TrivialSecondaryCircuit<F>"],["impl<E: Default, NE: Default> Default for ZMPCS<E, NE>"],["impl<E: Default + Engine> Default for ZMCommitment<E>where\n E::G1Affine: Default,"],["impl<F: Default> Default for TrivialTestCircuit<F>"],["impl<E: Default + Engine> Default for ZMEvaluation<E>where\n E::Fr: Default,"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/error/trait.Error.js b/docs/implementors/core/error/trait.Error.js new file mode 100644 index 000000000..353488cca --- /dev/null +++ b/docs/implementors/core/error/trait.Error.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl Error for NovaError"],["impl Error for SuperNovaError"],["impl Error for PCSError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/fmt/trait.Debug.js b/docs/implementors/core/fmt/trait.Debug.js new file mode 100644 index 000000000..21b931567 --- /dev/null +++ b/docs/implementors/core/fmt/trait.Debug.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<E: Debug + Engine> Debug for ProverKey<E>"],["impl Debug for VestaEngine"],["impl<E1, E2, C1, C2, S1, S2> Debug for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Debug,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Debug,\n C1: StepCircuit<E1::Scalar> + Debug,\n C2: StepCircuit<E2::Scalar> + Debug,\n S1: BatchedRelaxedR1CSSNARKTrait<E1> + Debug,\n S2: RelaxedR1CSSNARKTrait<E2> + Debug,\n E1::Scalar: Debug,\n E2::Scalar: Debug,"],["impl<E: Debug> Debug for EvaluationEngine<E>"],["impl<E: Debug + Engine> Debug for R1CSWitness<E>where\n E::Scalar: Debug,"],["impl<E: Debug, NE: Debug> Debug for EvaluationEngine<E, NE>"],["impl<E1, E2> Debug for RecursiveSNARK<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Debug,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Debug,\n E1::Scalar: Debug,\n E2::Scalar: Debug,"],["impl<E: Debug + Engine> Debug for ResourceBuffer<E>where\n E::Scalar: Debug,"],["impl<E: Debug, NE: Debug> Debug for ZMPCS<E, NE>"],["impl Debug for Bn256EngineKZG"],["impl<E: Debug + Engine> Debug for RelaxedR1CSInstance<E>where\n E::Scalar: Debug,"],["impl Debug for NovaError"],["impl<E: Debug + Engine> Debug for ZMCommitment<E>where\n E::G1Affine: Debug,"],["impl<E: Debug + Engine> Debug for ZMProof<E>where\n E::G1Affine: Debug,"],["impl Debug for SuperNovaError"],["impl<E: Debug + Engine, EE: Debug + EvaluationEngineTrait<E>> Debug for RelaxedR1CSSNARK<E, EE>where\n E::Scalar: Debug,\n EE::EvaluationArgument: Debug,"],["impl Debug for Secq256k1Engine"],["impl<E: Debug + Engine, EE: Debug + EvaluationEngineTrait<E>> Debug for RelaxedR1CSSNARK<E, EE>where\n E::Scalar: Debug,\n EE::EvaluationArgument: Debug,"],["impl<E1, E2, C1, C2, S1, S2> Debug for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Debug,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Debug,\n C1: StepCircuit<E1::Scalar> + Debug,\n C2: StepCircuit<E2::Scalar> + Debug,\n S1: RelaxedR1CSSNARKTrait<E1> + Debug,\n S2: RelaxedR1CSSNARKTrait<E2> + Debug,\n S1::ProverKey: Debug,\n S2::ProverKey: Debug,"],["impl Debug for Bn256Engine"],["impl<E: Debug + Engine> Debug for VerifierKey<E>"],["impl<E: Debug + Engine> Debug for ZMProverKey<E>"],["impl<F: Debug> Debug for TrivialCircuit<F>"],["impl Debug for Bn256EngineZM"],["impl<E: Debug + Engine> Debug for EvaluationArgument<E>where\n E::G1Affine: Debug,\n E::Fr: Debug,"],["impl<Scalar: Debug> Debug for MultilinearPolynomial<Scalar>"],["impl<E: Debug + Engine> Debug for InnerProductArgument<E>where\n E::Scalar: Debug,"],["impl<F: Debug> Debug for TrivialTestCircuit<F>"],["impl Debug for GrumpkinEngine"],["impl<E: Debug + Engine, EE: Debug + EvaluationEngineTrait<E>> Debug for BatchedRelaxedR1CSSNARK<E, EE>where\n E::Scalar: Debug,\n EE::EvaluationArgument: Debug,"],["impl<E: Debug + Engine> Debug for R1CSInstance<E>where\n E::Scalar: Debug,"],["impl<E: Debug + Engine> Debug for ZMVerifierKey<E>where\n E::G2Affine: Debug,"],["impl<E: Debug + Engine> Debug for R1CSResult<E>where\n E::Scalar: Debug,"],["impl<E: Debug + Engine> Debug for RelaxedR1CSWitness<E>where\n E::Scalar: Debug,"],["impl<F: Debug> Debug for TrivialSecondaryCircuit<F>"],["impl Debug for Secp256k1Engine"],["impl<E: Debug + Engine, EE: Debug + EvaluationEngineTrait<E>> Debug for BatchedRelaxedR1CSSNARK<E, EE>where\n E::Scalar: Debug,\n EE::EvaluationArgument: Debug,"],["impl<E: Debug + Engine> Debug for ZMEvaluation<E>where\n E::Fr: Debug,"],["impl<E1, E2, C1, C2> Debug for RecursiveSNARK<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar> + Debug,\n E2: Engine<Base = <E1 as Engine>::Scalar> + Debug,\n C1: StepCircuit<E1::Scalar> + Debug,\n C2: StepCircuit<E2::Scalar> + Debug,\n E1::Scalar: Debug,\n E2::Scalar: Debug,"],["impl<E: Debug + Engine> Debug for R1CSShape<E>where\n E::Scalar: Debug,"],["impl Debug for PallasEngine"],["impl Debug for PCSError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/fmt/trait.Display.js b/docs/implementors/core/fmt/trait.Display.js new file mode 100644 index 000000000..2bd3a9d04 --- /dev/null +++ b/docs/implementors/core/fmt/trait.Display.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl Display for PCSError"],["impl Display for NovaError"],["impl Display for SuperNovaError"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/marker/trait.Copy.js b/docs/implementors/core/marker/trait.Copy.js new file mode 100644 index 000000000..cda5225fe --- /dev/null +++ b/docs/implementors/core/marker/trait.Copy.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl Copy for Bn256EngineKZG"],["impl Copy for VestaEngine"],["impl Copy for Secq256k1Engine"],["impl Copy for PallasEngine"],["impl Copy for Bn256EngineZM"],["impl Copy for Bn256Engine"],["impl Copy for GrumpkinEngine"],["impl Copy for Secp256k1Engine"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/marker/trait.Freeze.js b/docs/implementors/core/marker/trait.Freeze.js new file mode 100644 index 000000000..46fef9d08 --- /dev/null +++ b/docs/implementors/core/marker/trait.Freeze.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl Freeze for NovaError",1,["arecibo::errors::NovaError"]],["impl Freeze for PCSError",1,["arecibo::errors::PCSError"]],["impl<E> Freeze for AllocatedPoint<E>where\n <E as Engine>::Base: Freeze,",1,["arecibo::gadgets::ecc::AllocatedPoint"]],["impl<E> Freeze for AllocatedPointNonInfinity<E>where\n <E as Engine>::Base: Freeze,",1,["arecibo::gadgets::ecc::AllocatedPointNonInfinity"]],["impl<E> Freeze for ProverKey<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: Freeze,",1,["arecibo::provider::ipa_pc::ProverKey"]],["impl<E> Freeze for VerifierKey<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: Freeze,",1,["arecibo::provider::ipa_pc::VerifierKey"]],["impl<E> Freeze for EvaluationEngine<E>",1,["arecibo::provider::ipa_pc::EvaluationEngine"]],["impl<E> Freeze for InnerProductArgument<E>where\n <E as Engine>::Scalar: Freeze,",1,["arecibo::provider::ipa_pc::InnerProductArgument"]],["impl<E> Freeze for EvaluationArgument<E>",1,["arecibo::provider::mlkzg::EvaluationArgument"]],["impl<E, NE> Freeze for EvaluationEngine<E, NE>",1,["arecibo::provider::mlkzg::EvaluationEngine"]],["impl<E> Freeze for ZMProverKey<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMProverKey"]],["impl<E> Freeze for ZMVerifierKey<E>where\n <E as Engine>::G1Affine: Freeze,\n <E as Engine>::G2Affine: Freeze,",1,["arecibo::provider::non_hiding_zeromorph::ZMVerifierKey"]],["impl<E> Freeze for ZMCommitment<E>where\n <E as Engine>::G1Affine: Freeze,",1,["arecibo::provider::non_hiding_zeromorph::ZMCommitment"]],["impl<E> Freeze for ZMEvaluation<E>where\n <E as Engine>::Fr: Freeze,",1,["arecibo::provider::non_hiding_zeromorph::ZMEvaluation"]],["impl<E> Freeze for ZMProof<E>where\n <E as Engine>::G1Affine: Freeze,",1,["arecibo::provider::non_hiding_zeromorph::ZMProof"]],["impl<E, NE> Freeze for ZMPCS<E, NE>",1,["arecibo::provider::non_hiding_zeromorph::ZMPCS"]],["impl Freeze for Bn256Engine",1,["arecibo::provider::Bn256Engine"]],["impl Freeze for GrumpkinEngine",1,["arecibo::provider::GrumpkinEngine"]],["impl Freeze for Bn256EngineZM",1,["arecibo::provider::Bn256EngineZM"]],["impl Freeze for Bn256EngineKZG",1,["arecibo::provider::Bn256EngineKZG"]],["impl Freeze for Secp256k1Engine",1,["arecibo::provider::Secp256k1Engine"]],["impl Freeze for Secq256k1Engine",1,["arecibo::provider::Secq256k1Engine"]],["impl Freeze for PallasEngine",1,["arecibo::provider::PallasEngine"]],["impl Freeze for VestaEngine",1,["arecibo::provider::VestaEngine"]],["impl<E> !Freeze for R1CSShape<E>",1,["arecibo::r1cs::R1CSShape"]],["impl<E> Freeze for R1CSResult<E>",1,["arecibo::r1cs::R1CSResult"]],["impl<E> Freeze for R1CSWitness<E>",1,["arecibo::r1cs::R1CSWitness"]],["impl<E> Freeze for R1CSInstance<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Freeze,",1,["arecibo::r1cs::R1CSInstance"]],["impl<E> Freeze for RelaxedR1CSWitness<E>",1,["arecibo::r1cs::RelaxedR1CSWitness"]],["impl<E> Freeze for RelaxedR1CSInstance<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Freeze,\n <E as Engine>::Scalar: Freeze,",1,["arecibo::r1cs::RelaxedR1CSInstance"]],["impl<E, EE> Freeze for BatchedRelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Freeze,",1,["arecibo::spartan::batched::BatchedRelaxedR1CSSNARK"]],["impl<E, EE> Freeze for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: Freeze,\n <E as Engine>::Scalar: Freeze,",1,["arecibo::spartan::batched::ProverKey"]],["impl<E, EE> !Freeze for VerifierKey<E, EE>",1,["arecibo::spartan::batched::VerifierKey"]],["impl<E, EE> Freeze for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: Freeze,\n <E as Engine>::Scalar: Freeze,",1,["arecibo::spartan::batched_ppsnark::ProverKey"]],["impl<E, EE> !Freeze for VerifierKey<E, EE>",1,["arecibo::spartan::batched_ppsnark::VerifierKey"]],["impl<E, EE> Freeze for BatchedRelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Freeze,",1,["arecibo::spartan::batched_ppsnark::BatchedRelaxedR1CSSNARK"]],["impl<Scalar> Freeze for MultilinearPolynomial<Scalar>",1,["arecibo::spartan::polys::multilinear::MultilinearPolynomial"]],["impl<E> Freeze for R1CSShapeSparkRepr<E>",1,["arecibo::spartan::ppsnark::R1CSShapeSparkRepr"]],["impl<E> Freeze for R1CSShapeSparkCommitment<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Freeze,",1,["arecibo::spartan::ppsnark::R1CSShapeSparkCommitment"]],["impl<E, EE> Freeze for ProverKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Freeze,\n <EE as EvaluationEngineTrait<E>>::ProverKey: Freeze,\n <E as Engine>::Scalar: Freeze,",1,["arecibo::spartan::ppsnark::ProverKey"]],["impl<E, EE> !Freeze for VerifierKey<E, EE>",1,["arecibo::spartan::ppsnark::VerifierKey"]],["impl<E, EE> Freeze for RelaxedR1CSSNARK<E, EE>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: Freeze,\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Freeze,\n <E as Engine>::Scalar: Freeze,",1,["arecibo::spartan::ppsnark::RelaxedR1CSSNARK"]],["impl<E, EE> Freeze for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: Freeze,\n <E as Engine>::Scalar: Freeze,",1,["arecibo::spartan::snark::ProverKey"]],["impl<E, EE> !Freeze for VerifierKey<E, EE>",1,["arecibo::spartan::snark::VerifierKey"]],["impl<E, EE> Freeze for RelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Freeze,\n <E as Engine>::Scalar: Freeze,",1,["arecibo::spartan::snark::RelaxedR1CSSNARK"]],["impl<F> Freeze for TrivialCircuit<F>",1,["arecibo::traits::circuit::TrivialCircuit"]],["impl<F> Freeze for TrivialTestCircuit<F>",1,["arecibo::supernova::circuit::TrivialTestCircuit"]],["impl<F> Freeze for TrivialSecondaryCircuit<F>",1,["arecibo::supernova::circuit::TrivialSecondaryCircuit"]],["impl Freeze for SuperNovaError",1,["arecibo::supernova::error::SuperNovaError"]],["impl<E1, E2, C1, C2, S1, S2> Freeze for ProverKey<E1, E2, C1, C2, S1, S2>where\n <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::ProverKey: Freeze,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: Freeze,",1,["arecibo::supernova::snark::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> Freeze for VerifierKey<E1, E2, C1, C2, S1, S2>where\n <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::VerifierKey: Freeze,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: Freeze,",1,["arecibo::supernova::snark::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> Freeze for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n S1: Freeze,\n S2: Freeze,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Freeze,\n <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: Freeze,\n <E1 as Engine>::Scalar: Freeze,\n <E2 as Engine>::Scalar: Freeze,",1,["arecibo::supernova::snark::CompressedSNARK"]],["impl<E> Freeze for CircuitDigests<E>",1,["arecibo::supernova::CircuitDigests"]],["impl<E1, E2, C1, C2> !Freeze for PublicParams<E1, E2, C1, C2>",1,["arecibo::supernova::PublicParams"]],["impl<E1, E2> !Freeze for AuxParams<E1, E2>",1,["arecibo::supernova::AuxParams"]],["impl<E1, E2> Freeze for RecursiveSNARK<E1, E2>where\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Freeze,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Freeze,\n <E1 as Engine>::Scalar: Freeze,\n <E2 as Engine>::Scalar: Freeze,",1,["arecibo::supernova::RecursiveSNARK"]],["impl<E> !Freeze for R1CSWithArity<E>",1,["arecibo::R1CSWithArity"]],["impl<E1, E2, C1, C2> !Freeze for PublicParams<E1, E2, C1, C2>",1,["arecibo::PublicParams"]],["impl<E> Freeze for ResourceBuffer<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Freeze,",1,["arecibo::ResourceBuffer"]],["impl<E1, E2, C1, C2> Freeze for RecursiveSNARK<E1, E2, C1, C2>where\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Freeze,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Freeze,\n <E1 as Engine>::Scalar: Freeze,\n <E2 as Engine>::Scalar: Freeze,",1,["arecibo::RecursiveSNARK"]],["impl<E1, E2, C1, C2, S1, S2> Freeze for ProverKey<E1, E2, C1, C2, S1, S2>where\n <S1 as RelaxedR1CSSNARKTrait<E1>>::ProverKey: Freeze,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: Freeze,",1,["arecibo::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> Freeze for VerifierKey<E1, E2, C1, C2, S1, S2>where\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Freeze,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Freeze,\n <E1 as Engine>::Scalar: Freeze,\n <S1 as RelaxedR1CSSNARKTrait<E1>>::VerifierKey: Freeze,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: Freeze,",1,["arecibo::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> Freeze for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n S1: Freeze,\n S2: Freeze,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Freeze,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Freeze,\n <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: Freeze,\n <E1 as Engine>::Scalar: Freeze,\n <E2 as Engine>::Scalar: Freeze,",1,["arecibo::CompressedSNARK"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/marker/trait.Send.js b/docs/implementors/core/marker/trait.Send.js new file mode 100644 index 000000000..b96a9dc90 --- /dev/null +++ b/docs/implementors/core/marker/trait.Send.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl Send for NovaError",1,["arecibo::errors::NovaError"]],["impl Send for PCSError",1,["arecibo::errors::PCSError"]],["impl<E> Send for AllocatedPoint<E>",1,["arecibo::gadgets::ecc::AllocatedPoint"]],["impl<E> Send for AllocatedPointNonInfinity<E>",1,["arecibo::gadgets::ecc::AllocatedPointNonInfinity"]],["impl<E> Send for ProverKey<E>",1,["arecibo::provider::ipa_pc::ProverKey"]],["impl<E> Send for VerifierKey<E>",1,["arecibo::provider::ipa_pc::VerifierKey"]],["impl<E> Send for EvaluationEngine<E>where\n E: Send,",1,["arecibo::provider::ipa_pc::EvaluationEngine"]],["impl<E> Send for InnerProductArgument<E>",1,["arecibo::provider::ipa_pc::InnerProductArgument"]],["impl<E> Send for EvaluationArgument<E>",1,["arecibo::provider::mlkzg::EvaluationArgument"]],["impl<E, NE> Send for EvaluationEngine<E, NE>where\n E: Send,\n NE: Send,",1,["arecibo::provider::mlkzg::EvaluationEngine"]],["impl<E> Send for ZMProverKey<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMProverKey"]],["impl<E> Send for ZMVerifierKey<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMVerifierKey"]],["impl<E> Send for ZMCommitment<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMCommitment"]],["impl<E> Send for ZMEvaluation<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMEvaluation"]],["impl<E> Send for ZMProof<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMProof"]],["impl<E, NE> Send for ZMPCS<E, NE>where\n E: Send,\n NE: Send,",1,["arecibo::provider::non_hiding_zeromorph::ZMPCS"]],["impl Send for Bn256Engine",1,["arecibo::provider::Bn256Engine"]],["impl Send for GrumpkinEngine",1,["arecibo::provider::GrumpkinEngine"]],["impl Send for Bn256EngineZM",1,["arecibo::provider::Bn256EngineZM"]],["impl Send for Bn256EngineKZG",1,["arecibo::provider::Bn256EngineKZG"]],["impl Send for Secp256k1Engine",1,["arecibo::provider::Secp256k1Engine"]],["impl Send for Secq256k1Engine",1,["arecibo::provider::Secq256k1Engine"]],["impl Send for PallasEngine",1,["arecibo::provider::PallasEngine"]],["impl Send for VestaEngine",1,["arecibo::provider::VestaEngine"]],["impl<E> Send for R1CSShape<E>",1,["arecibo::r1cs::R1CSShape"]],["impl<E> Send for R1CSResult<E>",1,["arecibo::r1cs::R1CSResult"]],["impl<E> Send for R1CSWitness<E>",1,["arecibo::r1cs::R1CSWitness"]],["impl<E> Send for R1CSInstance<E>",1,["arecibo::r1cs::R1CSInstance"]],["impl<E> Send for RelaxedR1CSWitness<E>",1,["arecibo::r1cs::RelaxedR1CSWitness"]],["impl<E> Send for RelaxedR1CSInstance<E>",1,["arecibo::r1cs::RelaxedR1CSInstance"]],["impl<E, EE> Send for BatchedRelaxedR1CSSNARK<E, EE>",1,["arecibo::spartan::batched::BatchedRelaxedR1CSSNARK"]],["impl<E, EE> Send for ProverKey<E, EE>",1,["arecibo::spartan::batched::ProverKey"]],["impl<E, EE> Send for VerifierKey<E, EE>",1,["arecibo::spartan::batched::VerifierKey"]],["impl<E, EE> Send for ProverKey<E, EE>",1,["arecibo::spartan::batched_ppsnark::ProverKey"]],["impl<E, EE> Send for VerifierKey<E, EE>",1,["arecibo::spartan::batched_ppsnark::VerifierKey"]],["impl<E, EE> Send for BatchedRelaxedR1CSSNARK<E, EE>",1,["arecibo::spartan::batched_ppsnark::BatchedRelaxedR1CSSNARK"]],["impl<Scalar> Send for MultilinearPolynomial<Scalar>where\n Scalar: Send,",1,["arecibo::spartan::polys::multilinear::MultilinearPolynomial"]],["impl<E> Send for R1CSShapeSparkRepr<E>",1,["arecibo::spartan::ppsnark::R1CSShapeSparkRepr"]],["impl<E> Send for R1CSShapeSparkCommitment<E>",1,["arecibo::spartan::ppsnark::R1CSShapeSparkCommitment"]],["impl<E, EE> Send for ProverKey<E, EE>",1,["arecibo::spartan::ppsnark::ProverKey"]],["impl<E, EE> Send for VerifierKey<E, EE>",1,["arecibo::spartan::ppsnark::VerifierKey"]],["impl<E, EE> Send for RelaxedR1CSSNARK<E, EE>",1,["arecibo::spartan::ppsnark::RelaxedR1CSSNARK"]],["impl<E, EE> Send for ProverKey<E, EE>",1,["arecibo::spartan::snark::ProverKey"]],["impl<E, EE> Send for VerifierKey<E, EE>",1,["arecibo::spartan::snark::VerifierKey"]],["impl<E, EE> Send for RelaxedR1CSSNARK<E, EE>",1,["arecibo::spartan::snark::RelaxedR1CSSNARK"]],["impl<F> Send for TrivialCircuit<F>where\n F: Send,",1,["arecibo::traits::circuit::TrivialCircuit"]],["impl<F> Send for TrivialTestCircuit<F>where\n F: Send,",1,["arecibo::supernova::circuit::TrivialTestCircuit"]],["impl<F> Send for TrivialSecondaryCircuit<F>where\n F: Send,",1,["arecibo::supernova::circuit::TrivialSecondaryCircuit"]],["impl Send for SuperNovaError",1,["arecibo::supernova::error::SuperNovaError"]],["impl<E1, E2, C1, C2, S1, S2> Send for ProverKey<E1, E2, C1, C2, S1, S2>",1,["arecibo::supernova::snark::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> Send for VerifierKey<E1, E2, C1, C2, S1, S2>",1,["arecibo::supernova::snark::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> Send for CompressedSNARK<E1, E2, C1, C2, S1, S2>",1,["arecibo::supernova::snark::CompressedSNARK"]],["impl<E> Send for CircuitDigests<E>",1,["arecibo::supernova::CircuitDigests"]],["impl<E1, E2, C1, C2> Send for PublicParams<E1, E2, C1, C2>",1,["arecibo::supernova::PublicParams"]],["impl<E1, E2> Send for AuxParams<E1, E2>",1,["arecibo::supernova::AuxParams"]],["impl<E1, E2> Send for RecursiveSNARK<E1, E2>",1,["arecibo::supernova::RecursiveSNARK"]],["impl<E> Send for R1CSWithArity<E>",1,["arecibo::R1CSWithArity"]],["impl<E1, E2, C1, C2> Send for PublicParams<E1, E2, C1, C2>",1,["arecibo::PublicParams"]],["impl<E> Send for ResourceBuffer<E>",1,["arecibo::ResourceBuffer"]],["impl<E1, E2, C1, C2> Send for RecursiveSNARK<E1, E2, C1, C2>",1,["arecibo::RecursiveSNARK"]],["impl<E1, E2, C1, C2, S1, S2> Send for ProverKey<E1, E2, C1, C2, S1, S2>",1,["arecibo::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> Send for VerifierKey<E1, E2, C1, C2, S1, S2>",1,["arecibo::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> Send for CompressedSNARK<E1, E2, C1, C2, S1, S2>",1,["arecibo::CompressedSNARK"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/marker/trait.StructuralEq.js b/docs/implementors/core/marker/trait.StructuralEq.js new file mode 100644 index 000000000..a6944fc26 --- /dev/null +++ b/docs/implementors/core/marker/trait.StructuralEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl StructuralEq for SuperNovaError"],["impl<E: Engine> StructuralEq for R1CSInstance<E>"],["impl StructuralEq for Bn256EngineKZG"],["impl<E: Engine> StructuralEq for ZMVerifierKey<E>"],["impl<E: Engine> StructuralEq for ZMProverKey<E>"],["impl StructuralEq for NovaError"],["impl<E: Engine> StructuralEq for ZMEvaluation<E>"],["impl<E: Engine> StructuralEq for ZMCommitment<E>"],["impl<Scalar> StructuralEq for MultilinearPolynomial<Scalar>"],["impl<E: Engine> StructuralEq for RelaxedR1CSWitness<E>"],["impl<E: Engine> StructuralEq for RelaxedR1CSInstance<E>"],["impl StructuralEq for VestaEngine"],["impl<E, NE> StructuralEq for ZMPCS<E, NE>"],["impl StructuralEq for Secp256k1Engine"],["impl<E: Engine> StructuralEq for R1CSShape<E>"],["impl<F> StructuralEq for TrivialCircuit<F>"],["impl<E: Engine> StructuralEq for ZMProof<E>"],["impl<E: Engine> StructuralEq for CircuitDigests<E>"],["impl StructuralEq for Secq256k1Engine"],["impl<E: Engine> StructuralEq for R1CSResult<E>"],["impl StructuralEq for Bn256Engine"],["impl StructuralEq for PallasEngine"],["impl StructuralEq for GrumpkinEngine"],["impl StructuralEq for PCSError"],["impl StructuralEq for Bn256EngineZM"],["impl<E: Engine> StructuralEq for R1CSWithArity<E>"],["impl<E: Engine> StructuralEq for R1CSWitness<E>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/marker/trait.StructuralPartialEq.js b/docs/implementors/core/marker/trait.StructuralPartialEq.js new file mode 100644 index 000000000..ce987498b --- /dev/null +++ b/docs/implementors/core/marker/trait.StructuralPartialEq.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl StructuralPartialEq for PCSError"],["impl StructuralPartialEq for Bn256EngineKZG"],["impl<F> StructuralPartialEq for TrivialCircuit<F>"],["impl<E: Engine> StructuralPartialEq for R1CSWitness<E>"],["impl<E: Engine> StructuralPartialEq for RelaxedR1CSInstance<E>"],["impl StructuralPartialEq for GrumpkinEngine"],["impl StructuralPartialEq for Secq256k1Engine"],["impl<E1, E2> StructuralPartialEq for AuxParams<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,"],["impl<E: Engine> StructuralPartialEq for CircuitDigests<E>"],["impl<E, NE> StructuralPartialEq for ZMPCS<E, NE>"],["impl<E: Engine> StructuralPartialEq for RelaxedR1CSWitness<E>"],["impl StructuralPartialEq for NovaError"],["impl<E: Engine> StructuralPartialEq for ZMEvaluation<E>"],["impl<E: Engine> StructuralPartialEq for R1CSInstance<E>"],["impl StructuralPartialEq for SuperNovaError"],["impl StructuralPartialEq for PallasEngine"],["impl StructuralPartialEq for Bn256EngineZM"],["impl<E: Engine> StructuralPartialEq for ZMProverKey<E>"],["impl<E: Engine> StructuralPartialEq for R1CSShape<E>"],["impl<E: Engine> StructuralPartialEq for ZMCommitment<E>"],["impl StructuralPartialEq for VestaEngine"],["impl<Scalar> StructuralPartialEq for MultilinearPolynomial<Scalar>"],["impl StructuralPartialEq for Secp256k1Engine"],["impl<E1, E2, C1, C2> StructuralPartialEq for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,"],["impl<E: Engine> StructuralPartialEq for R1CSResult<E>"],["impl StructuralPartialEq for Bn256Engine"],["impl<E: Engine> StructuralPartialEq for ZMVerifierKey<E>"],["impl<E: Engine> StructuralPartialEq for R1CSWithArity<E>"],["impl<E: Engine> StructuralPartialEq for ZMProof<E>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/marker/trait.Sync.js b/docs/implementors/core/marker/trait.Sync.js new file mode 100644 index 000000000..0a75ed6c6 --- /dev/null +++ b/docs/implementors/core/marker/trait.Sync.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl Sync for NovaError",1,["arecibo::errors::NovaError"]],["impl Sync for PCSError",1,["arecibo::errors::PCSError"]],["impl<E> Sync for AllocatedPoint<E>",1,["arecibo::gadgets::ecc::AllocatedPoint"]],["impl<E> Sync for AllocatedPointNonInfinity<E>",1,["arecibo::gadgets::ecc::AllocatedPointNonInfinity"]],["impl<E> Sync for ProverKey<E>",1,["arecibo::provider::ipa_pc::ProverKey"]],["impl<E> Sync for VerifierKey<E>",1,["arecibo::provider::ipa_pc::VerifierKey"]],["impl<E> Sync for EvaluationEngine<E>where\n E: Sync,",1,["arecibo::provider::ipa_pc::EvaluationEngine"]],["impl<E> Sync for InnerProductArgument<E>",1,["arecibo::provider::ipa_pc::InnerProductArgument"]],["impl<E> Sync for EvaluationArgument<E>",1,["arecibo::provider::mlkzg::EvaluationArgument"]],["impl<E, NE> Sync for EvaluationEngine<E, NE>where\n E: Sync,\n NE: Sync,",1,["arecibo::provider::mlkzg::EvaluationEngine"]],["impl<E> Sync for ZMProverKey<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMProverKey"]],["impl<E> Sync for ZMVerifierKey<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMVerifierKey"]],["impl<E> Sync for ZMCommitment<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMCommitment"]],["impl<E> Sync for ZMEvaluation<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMEvaluation"]],["impl<E> Sync for ZMProof<E>",1,["arecibo::provider::non_hiding_zeromorph::ZMProof"]],["impl<E, NE> Sync for ZMPCS<E, NE>where\n E: Sync,\n NE: Sync,",1,["arecibo::provider::non_hiding_zeromorph::ZMPCS"]],["impl Sync for Bn256Engine",1,["arecibo::provider::Bn256Engine"]],["impl Sync for GrumpkinEngine",1,["arecibo::provider::GrumpkinEngine"]],["impl Sync for Bn256EngineZM",1,["arecibo::provider::Bn256EngineZM"]],["impl Sync for Bn256EngineKZG",1,["arecibo::provider::Bn256EngineKZG"]],["impl Sync for Secp256k1Engine",1,["arecibo::provider::Secp256k1Engine"]],["impl Sync for Secq256k1Engine",1,["arecibo::provider::Secq256k1Engine"]],["impl Sync for PallasEngine",1,["arecibo::provider::PallasEngine"]],["impl Sync for VestaEngine",1,["arecibo::provider::VestaEngine"]],["impl<E> Sync for R1CSShape<E>",1,["arecibo::r1cs::R1CSShape"]],["impl<E> Sync for R1CSResult<E>",1,["arecibo::r1cs::R1CSResult"]],["impl<E> Sync for R1CSWitness<E>",1,["arecibo::r1cs::R1CSWitness"]],["impl<E> Sync for R1CSInstance<E>",1,["arecibo::r1cs::R1CSInstance"]],["impl<E> Sync for RelaxedR1CSWitness<E>",1,["arecibo::r1cs::RelaxedR1CSWitness"]],["impl<E> Sync for RelaxedR1CSInstance<E>",1,["arecibo::r1cs::RelaxedR1CSInstance"]],["impl<E, EE> Sync for BatchedRelaxedR1CSSNARK<E, EE>",1,["arecibo::spartan::batched::BatchedRelaxedR1CSSNARK"]],["impl<E, EE> Sync for ProverKey<E, EE>",1,["arecibo::spartan::batched::ProverKey"]],["impl<E, EE> Sync for VerifierKey<E, EE>",1,["arecibo::spartan::batched::VerifierKey"]],["impl<E, EE> Sync for ProverKey<E, EE>",1,["arecibo::spartan::batched_ppsnark::ProverKey"]],["impl<E, EE> Sync for VerifierKey<E, EE>",1,["arecibo::spartan::batched_ppsnark::VerifierKey"]],["impl<E, EE> Sync for BatchedRelaxedR1CSSNARK<E, EE>",1,["arecibo::spartan::batched_ppsnark::BatchedRelaxedR1CSSNARK"]],["impl<Scalar> Sync for MultilinearPolynomial<Scalar>where\n Scalar: Sync,",1,["arecibo::spartan::polys::multilinear::MultilinearPolynomial"]],["impl<E> Sync for R1CSShapeSparkRepr<E>",1,["arecibo::spartan::ppsnark::R1CSShapeSparkRepr"]],["impl<E> Sync for R1CSShapeSparkCommitment<E>",1,["arecibo::spartan::ppsnark::R1CSShapeSparkCommitment"]],["impl<E, EE> Sync for ProverKey<E, EE>",1,["arecibo::spartan::ppsnark::ProverKey"]],["impl<E, EE> Sync for VerifierKey<E, EE>",1,["arecibo::spartan::ppsnark::VerifierKey"]],["impl<E, EE> Sync for RelaxedR1CSSNARK<E, EE>",1,["arecibo::spartan::ppsnark::RelaxedR1CSSNARK"]],["impl<E, EE> Sync for ProverKey<E, EE>",1,["arecibo::spartan::snark::ProverKey"]],["impl<E, EE> Sync for VerifierKey<E, EE>",1,["arecibo::spartan::snark::VerifierKey"]],["impl<E, EE> Sync for RelaxedR1CSSNARK<E, EE>",1,["arecibo::spartan::snark::RelaxedR1CSSNARK"]],["impl<F> Sync for TrivialCircuit<F>where\n F: Sync,",1,["arecibo::traits::circuit::TrivialCircuit"]],["impl<F> Sync for TrivialTestCircuit<F>where\n F: Sync,",1,["arecibo::supernova::circuit::TrivialTestCircuit"]],["impl<F> Sync for TrivialSecondaryCircuit<F>where\n F: Sync,",1,["arecibo::supernova::circuit::TrivialSecondaryCircuit"]],["impl Sync for SuperNovaError",1,["arecibo::supernova::error::SuperNovaError"]],["impl<E1, E2, C1, C2, S1, S2> Sync for ProverKey<E1, E2, C1, C2, S1, S2>",1,["arecibo::supernova::snark::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> Sync for VerifierKey<E1, E2, C1, C2, S1, S2>",1,["arecibo::supernova::snark::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> Sync for CompressedSNARK<E1, E2, C1, C2, S1, S2>",1,["arecibo::supernova::snark::CompressedSNARK"]],["impl<E> Sync for CircuitDigests<E>",1,["arecibo::supernova::CircuitDigests"]],["impl<E1, E2, C1, C2> Sync for PublicParams<E1, E2, C1, C2>",1,["arecibo::supernova::PublicParams"]],["impl<E1, E2> Sync for AuxParams<E1, E2>",1,["arecibo::supernova::AuxParams"]],["impl<E1, E2> Sync for RecursiveSNARK<E1, E2>",1,["arecibo::supernova::RecursiveSNARK"]],["impl<E> Sync for R1CSWithArity<E>",1,["arecibo::R1CSWithArity"]],["impl<E1, E2, C1, C2> Sync for PublicParams<E1, E2, C1, C2>",1,["arecibo::PublicParams"]],["impl<E> Sync for ResourceBuffer<E>",1,["arecibo::ResourceBuffer"]],["impl<E1, E2, C1, C2> Sync for RecursiveSNARK<E1, E2, C1, C2>",1,["arecibo::RecursiveSNARK"]],["impl<E1, E2, C1, C2, S1, S2> Sync for ProverKey<E1, E2, C1, C2, S1, S2>",1,["arecibo::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> Sync for VerifierKey<E1, E2, C1, C2, S1, S2>",1,["arecibo::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> Sync for CompressedSNARK<E1, E2, C1, C2, S1, S2>",1,["arecibo::CompressedSNARK"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/marker/trait.Unpin.js b/docs/implementors/core/marker/trait.Unpin.js new file mode 100644 index 000000000..b27dbf841 --- /dev/null +++ b/docs/implementors/core/marker/trait.Unpin.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl Unpin for NovaError",1,["arecibo::errors::NovaError"]],["impl Unpin for PCSError",1,["arecibo::errors::PCSError"]],["impl<E> Unpin for AllocatedPoint<E>where\n <E as Engine>::Base: Unpin,",1,["arecibo::gadgets::ecc::AllocatedPoint"]],["impl<E> Unpin for AllocatedPointNonInfinity<E>where\n <E as Engine>::Base: Unpin,",1,["arecibo::gadgets::ecc::AllocatedPointNonInfinity"]],["impl<E> Unpin for ProverKey<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: Unpin,",1,["arecibo::provider::ipa_pc::ProverKey"]],["impl<E> Unpin for VerifierKey<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: Unpin,",1,["arecibo::provider::ipa_pc::VerifierKey"]],["impl<E> Unpin for EvaluationEngine<E>where\n E: Unpin,",1,["arecibo::provider::ipa_pc::EvaluationEngine"]],["impl<E> Unpin for InnerProductArgument<E>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::provider::ipa_pc::InnerProductArgument"]],["impl<E> Unpin for EvaluationArgument<E>where\n <E as Engine>::Fr: Unpin,\n <E as Engine>::G1Affine: Unpin,",1,["arecibo::provider::mlkzg::EvaluationArgument"]],["impl<E, NE> Unpin for EvaluationEngine<E, NE>where\n E: Unpin,\n NE: Unpin,",1,["arecibo::provider::mlkzg::EvaluationEngine"]],["impl<E> Unpin for ZMProverKey<E>where\n <E as Engine>::G1Affine: Unpin,",1,["arecibo::provider::non_hiding_zeromorph::ZMProverKey"]],["impl<E> Unpin for ZMVerifierKey<E>where\n <E as Engine>::G1Affine: Unpin,\n <E as Engine>::G2Affine: Unpin,",1,["arecibo::provider::non_hiding_zeromorph::ZMVerifierKey"]],["impl<E> Unpin for ZMCommitment<E>where\n <E as Engine>::G1Affine: Unpin,",1,["arecibo::provider::non_hiding_zeromorph::ZMCommitment"]],["impl<E> Unpin for ZMEvaluation<E>where\n <E as Engine>::Fr: Unpin,",1,["arecibo::provider::non_hiding_zeromorph::ZMEvaluation"]],["impl<E> Unpin for ZMProof<E>where\n <E as Engine>::G1Affine: Unpin,",1,["arecibo::provider::non_hiding_zeromorph::ZMProof"]],["impl<E, NE> Unpin for ZMPCS<E, NE>where\n E: Unpin,\n NE: Unpin,",1,["arecibo::provider::non_hiding_zeromorph::ZMPCS"]],["impl Unpin for Bn256Engine",1,["arecibo::provider::Bn256Engine"]],["impl Unpin for GrumpkinEngine",1,["arecibo::provider::GrumpkinEngine"]],["impl Unpin for Bn256EngineZM",1,["arecibo::provider::Bn256EngineZM"]],["impl Unpin for Bn256EngineKZG",1,["arecibo::provider::Bn256EngineKZG"]],["impl Unpin for Secp256k1Engine",1,["arecibo::provider::Secp256k1Engine"]],["impl Unpin for Secq256k1Engine",1,["arecibo::provider::Secq256k1Engine"]],["impl Unpin for PallasEngine",1,["arecibo::provider::PallasEngine"]],["impl Unpin for VestaEngine",1,["arecibo::provider::VestaEngine"]],["impl<E> Unpin for R1CSShape<E>where\n <E as Engine>::Scalar: Unpin,",1,["arecibo::r1cs::R1CSShape"]],["impl<E> Unpin for R1CSResult<E>where\n <E as Engine>::Scalar: Unpin,",1,["arecibo::r1cs::R1CSResult"]],["impl<E> Unpin for R1CSWitness<E>where\n <E as Engine>::Scalar: Unpin,",1,["arecibo::r1cs::R1CSWitness"]],["impl<E> Unpin for R1CSInstance<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::r1cs::R1CSInstance"]],["impl<E> Unpin for RelaxedR1CSWitness<E>where\n <E as Engine>::Scalar: Unpin,",1,["arecibo::r1cs::RelaxedR1CSWitness"]],["impl<E> Unpin for RelaxedR1CSInstance<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::r1cs::RelaxedR1CSInstance"]],["impl<E, EE> Unpin for BatchedRelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::batched::BatchedRelaxedR1CSSNARK"]],["impl<E, EE> Unpin for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::batched::ProverKey"]],["impl<E, EE> Unpin for VerifierKey<E, EE>where\n <E as Engine>::Scalar: Unpin,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: Unpin,",1,["arecibo::spartan::batched::VerifierKey"]],["impl<E, EE> Unpin for ProverKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin,\n <EE as EvaluationEngineTrait<E>>::ProverKey: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::batched_ppsnark::ProverKey"]],["impl<E, EE> Unpin for VerifierKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin,\n <E as Engine>::Scalar: Unpin,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: Unpin,",1,["arecibo::spartan::batched_ppsnark::VerifierKey"]],["impl<E, EE> Unpin for BatchedRelaxedR1CSSNARK<E, EE>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: Unpin,\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::batched_ppsnark::BatchedRelaxedR1CSSNARK"]],["impl<Scalar> Unpin for MultilinearPolynomial<Scalar>where\n Scalar: Unpin,",1,["arecibo::spartan::polys::multilinear::MultilinearPolynomial"]],["impl<E> Unpin for R1CSShapeSparkRepr<E>where\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::ppsnark::R1CSShapeSparkRepr"]],["impl<E> Unpin for R1CSShapeSparkCommitment<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin,",1,["arecibo::spartan::ppsnark::R1CSShapeSparkCommitment"]],["impl<E, EE> Unpin for ProverKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin,\n <EE as EvaluationEngineTrait<E>>::ProverKey: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::ppsnark::ProverKey"]],["impl<E, EE> Unpin for VerifierKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin,\n <E as Engine>::Scalar: Unpin,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: Unpin,",1,["arecibo::spartan::ppsnark::VerifierKey"]],["impl<E, EE> Unpin for RelaxedR1CSSNARK<E, EE>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: Unpin,\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::ppsnark::RelaxedR1CSSNARK"]],["impl<E, EE> Unpin for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::snark::ProverKey"]],["impl<E, EE> Unpin for VerifierKey<E, EE>where\n <E as Engine>::Scalar: Unpin,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: Unpin,",1,["arecibo::spartan::snark::VerifierKey"]],["impl<E, EE> Unpin for RelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::spartan::snark::RelaxedR1CSSNARK"]],["impl<F> Unpin for TrivialCircuit<F>where\n F: Unpin,",1,["arecibo::traits::circuit::TrivialCircuit"]],["impl<F> Unpin for TrivialTestCircuit<F>where\n F: Unpin,",1,["arecibo::supernova::circuit::TrivialTestCircuit"]],["impl<F> Unpin for TrivialSecondaryCircuit<F>where\n F: Unpin,",1,["arecibo::supernova::circuit::TrivialSecondaryCircuit"]],["impl Unpin for SuperNovaError",1,["arecibo::supernova::error::SuperNovaError"]],["impl<E1, E2, C1, C2, S1, S2> Unpin for ProverKey<E1, E2, C1, C2, S1, S2>where\n C1: Unpin,\n C2: Unpin,\n <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::ProverKey: Unpin,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: Unpin,",1,["arecibo::supernova::snark::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> Unpin for VerifierKey<E1, E2, C1, C2, S1, S2>where\n C1: Unpin,\n C2: Unpin,\n <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::VerifierKey: Unpin,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: Unpin,",1,["arecibo::supernova::snark::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> Unpin for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n C1: Unpin,\n C2: Unpin,\n E1: Unpin,\n E2: Unpin,\n S1: Unpin,\n S2: Unpin,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Unpin,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Unpin,\n <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: Unpin,\n <E1 as Engine>::Scalar: Unpin,\n <E2 as Engine>::Scalar: Unpin,",1,["arecibo::supernova::snark::CompressedSNARK"]],["impl<E> Unpin for CircuitDigests<E>where\n <E as Engine>::Scalar: Unpin,",1,["arecibo::supernova::CircuitDigests"]],["impl<E1, E2, C1, C2> Unpin for PublicParams<E1, E2, C1, C2>where\n C1: Unpin,\n C2: Unpin,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: Unpin,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: Unpin,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Unpin,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Unpin,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: Unpin,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: Unpin,\n <E1 as Engine>::Scalar: Unpin,\n <E2 as Engine>::Scalar: Unpin,",1,["arecibo::supernova::PublicParams"]],["impl<E1, E2> Unpin for AuxParams<E1, E2>where\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: Unpin,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: Unpin,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Unpin,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Unpin,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: Unpin,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: Unpin,\n <E1 as Engine>::Scalar: Unpin,\n <E2 as Engine>::Scalar: Unpin,",1,["arecibo::supernova::AuxParams"]],["impl<E1, E2> Unpin for RecursiveSNARK<E1, E2>where\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Unpin,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Unpin,\n <E1 as Engine>::Scalar: Unpin,\n <E2 as Engine>::Scalar: Unpin,",1,["arecibo::supernova::RecursiveSNARK"]],["impl<E> Unpin for R1CSWithArity<E>where\n <E as Engine>::Scalar: Unpin,",1,["arecibo::R1CSWithArity"]],["impl<E1, E2, C1, C2> Unpin for PublicParams<E1, E2, C1, C2>where\n C1: Unpin,\n C2: Unpin,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: Unpin,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: Unpin,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Unpin,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Unpin,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: Unpin,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: Unpin,\n <E1 as Engine>::Scalar: Unpin,\n <E2 as Engine>::Scalar: Unpin,",1,["arecibo::PublicParams"]],["impl<E> Unpin for ResourceBuffer<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: Unpin,\n <E as Engine>::Scalar: Unpin,",1,["arecibo::ResourceBuffer"]],["impl<E1, E2, C1, C2> Unpin for RecursiveSNARK<E1, E2, C1, C2>where\n C1: Unpin,\n C2: Unpin,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Unpin,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Unpin,\n <E1 as Engine>::Scalar: Unpin,\n <E2 as Engine>::Scalar: Unpin,",1,["arecibo::RecursiveSNARK"]],["impl<E1, E2, C1, C2, S1, S2> Unpin for ProverKey<E1, E2, C1, C2, S1, S2>where\n C1: Unpin,\n C2: Unpin,\n <S1 as RelaxedR1CSSNARKTrait<E1>>::ProverKey: Unpin,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: Unpin,",1,["arecibo::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> Unpin for VerifierKey<E1, E2, C1, C2, S1, S2>where\n C1: Unpin,\n C2: Unpin,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: Unpin,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: Unpin,\n <E1 as Engine>::Scalar: Unpin,\n <S1 as RelaxedR1CSSNARKTrait<E1>>::VerifierKey: Unpin,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: Unpin,",1,["arecibo::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> Unpin for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n C1: Unpin,\n C2: Unpin,\n S1: Unpin,\n S2: Unpin,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: Unpin,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: Unpin,\n <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: Unpin,\n <E1 as Engine>::Scalar: Unpin,\n <E2 as Engine>::Scalar: Unpin,",1,["arecibo::CompressedSNARK"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/ops/arith/trait.Add.js b/docs/implementors/core/ops/arith/trait.Add.js new file mode 100644 index 000000000..018c628fb --- /dev/null +++ b/docs/implementors/core/ops/arith/trait.Add.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<Scalar: PrimeField> Add<MultilinearPolynomial<Scalar>> for MultilinearPolynomial<Scalar>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/ops/deref/trait.Deref.js b/docs/implementors/core/ops/deref/trait.Deref.js new file mode 100644 index 000000000..16d7b2c84 --- /dev/null +++ b/docs/implementors/core/ops/deref/trait.Deref.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<E: Engine> Deref for CircuitDigests<E>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/ops/index/trait.Index.js b/docs/implementors/core/ops/index/trait.Index.js new file mode 100644 index 000000000..5346773f9 --- /dev/null +++ b/docs/implementors/core/ops/index/trait.Index.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<Scalar: PrimeField> Index<usize> for MultilinearPolynomial<Scalar>"],["impl<E1, E2, C1, C2> Index<usize> for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js b/docs/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js new file mode 100644 index 000000000..4281479a7 --- /dev/null +++ b/docs/implementors/core/panic/unwind_safe/trait.RefUnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl RefUnwindSafe for NovaError",1,["arecibo::errors::NovaError"]],["impl RefUnwindSafe for PCSError",1,["arecibo::errors::PCSError"]],["impl<E> RefUnwindSafe for AllocatedPoint<E>where\n <E as Engine>::Base: RefUnwindSafe,",1,["arecibo::gadgets::ecc::AllocatedPoint"]],["impl<E> RefUnwindSafe for AllocatedPointNonInfinity<E>where\n <E as Engine>::Base: RefUnwindSafe,",1,["arecibo::gadgets::ecc::AllocatedPointNonInfinity"]],["impl<E> RefUnwindSafe for ProverKey<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: RefUnwindSafe,",1,["arecibo::provider::ipa_pc::ProverKey"]],["impl<E> RefUnwindSafe for VerifierKey<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: RefUnwindSafe,",1,["arecibo::provider::ipa_pc::VerifierKey"]],["impl<E> RefUnwindSafe for EvaluationEngine<E>where\n E: RefUnwindSafe,",1,["arecibo::provider::ipa_pc::EvaluationEngine"]],["impl<E> RefUnwindSafe for InnerProductArgument<E>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::provider::ipa_pc::InnerProductArgument"]],["impl<E> RefUnwindSafe for EvaluationArgument<E>where\n <E as Engine>::Fr: RefUnwindSafe,\n <E as Engine>::G1Affine: RefUnwindSafe,",1,["arecibo::provider::mlkzg::EvaluationArgument"]],["impl<E, NE> RefUnwindSafe for EvaluationEngine<E, NE>where\n E: RefUnwindSafe,\n NE: RefUnwindSafe,",1,["arecibo::provider::mlkzg::EvaluationEngine"]],["impl<E> RefUnwindSafe for ZMProverKey<E>where\n <E as Engine>::G1Affine: RefUnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMProverKey"]],["impl<E> RefUnwindSafe for ZMVerifierKey<E>where\n <E as Engine>::G1Affine: RefUnwindSafe,\n <E as Engine>::G2Affine: RefUnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMVerifierKey"]],["impl<E> RefUnwindSafe for ZMCommitment<E>where\n <E as Engine>::G1Affine: RefUnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMCommitment"]],["impl<E> RefUnwindSafe for ZMEvaluation<E>where\n <E as Engine>::Fr: RefUnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMEvaluation"]],["impl<E> RefUnwindSafe for ZMProof<E>where\n <E as Engine>::G1Affine: RefUnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMProof"]],["impl<E, NE> RefUnwindSafe for ZMPCS<E, NE>where\n E: RefUnwindSafe,\n NE: RefUnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMPCS"]],["impl RefUnwindSafe for Bn256Engine",1,["arecibo::provider::Bn256Engine"]],["impl RefUnwindSafe for GrumpkinEngine",1,["arecibo::provider::GrumpkinEngine"]],["impl RefUnwindSafe for Bn256EngineZM",1,["arecibo::provider::Bn256EngineZM"]],["impl RefUnwindSafe for Bn256EngineKZG",1,["arecibo::provider::Bn256EngineKZG"]],["impl RefUnwindSafe for Secp256k1Engine",1,["arecibo::provider::Secp256k1Engine"]],["impl RefUnwindSafe for Secq256k1Engine",1,["arecibo::provider::Secq256k1Engine"]],["impl RefUnwindSafe for PallasEngine",1,["arecibo::provider::PallasEngine"]],["impl RefUnwindSafe for VestaEngine",1,["arecibo::provider::VestaEngine"]],["impl<E> RefUnwindSafe for R1CSShape<E>where\n <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe,",1,["arecibo::r1cs::R1CSShape"]],["impl<E> RefUnwindSafe for R1CSResult<E>where\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::r1cs::R1CSResult"]],["impl<E> RefUnwindSafe for R1CSWitness<E>where\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::r1cs::R1CSWitness"]],["impl<E> RefUnwindSafe for R1CSInstance<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::r1cs::R1CSInstance"]],["impl<E> RefUnwindSafe for RelaxedR1CSWitness<E>where\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::r1cs::RelaxedR1CSWitness"]],["impl<E> RefUnwindSafe for RelaxedR1CSInstance<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::r1cs::RelaxedR1CSInstance"]],["impl<E, EE> RefUnwindSafe for BatchedRelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::batched::BatchedRelaxedR1CSSNARK"]],["impl<E, EE> RefUnwindSafe for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::batched::ProverKey"]],["impl<E, EE> RefUnwindSafe for VerifierKey<E, EE>where\n <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: RefUnwindSafe,",1,["arecibo::spartan::batched::VerifierKey"]],["impl<E, EE> RefUnwindSafe for ProverKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe,\n <EE as EvaluationEngineTrait<E>>::ProverKey: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::batched_ppsnark::ProverKey"]],["impl<E, EE> RefUnwindSafe for VerifierKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe,\n <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: RefUnwindSafe,",1,["arecibo::spartan::batched_ppsnark::VerifierKey"]],["impl<E, EE> RefUnwindSafe for BatchedRelaxedR1CSSNARK<E, EE>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: RefUnwindSafe,\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::batched_ppsnark::BatchedRelaxedR1CSSNARK"]],["impl<Scalar> RefUnwindSafe for MultilinearPolynomial<Scalar>where\n Scalar: RefUnwindSafe,",1,["arecibo::spartan::polys::multilinear::MultilinearPolynomial"]],["impl<E> RefUnwindSafe for R1CSShapeSparkRepr<E>where\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::ppsnark::R1CSShapeSparkRepr"]],["impl<E> RefUnwindSafe for R1CSShapeSparkCommitment<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe,",1,["arecibo::spartan::ppsnark::R1CSShapeSparkCommitment"]],["impl<E, EE> RefUnwindSafe for ProverKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe,\n <EE as EvaluationEngineTrait<E>>::ProverKey: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::ppsnark::ProverKey"]],["impl<E, EE> RefUnwindSafe for VerifierKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe,\n <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: RefUnwindSafe,",1,["arecibo::spartan::ppsnark::VerifierKey"]],["impl<E, EE> RefUnwindSafe for RelaxedR1CSSNARK<E, EE>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: RefUnwindSafe,\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::ppsnark::RelaxedR1CSSNARK"]],["impl<E, EE> RefUnwindSafe for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::snark::ProverKey"]],["impl<E, EE> RefUnwindSafe for VerifierKey<E, EE>where\n <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: RefUnwindSafe,",1,["arecibo::spartan::snark::VerifierKey"]],["impl<E, EE> RefUnwindSafe for RelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::spartan::snark::RelaxedR1CSSNARK"]],["impl<F> RefUnwindSafe for TrivialCircuit<F>where\n F: RefUnwindSafe,",1,["arecibo::traits::circuit::TrivialCircuit"]],["impl<F> RefUnwindSafe for TrivialTestCircuit<F>where\n F: RefUnwindSafe,",1,["arecibo::supernova::circuit::TrivialTestCircuit"]],["impl<F> RefUnwindSafe for TrivialSecondaryCircuit<F>where\n F: RefUnwindSafe,",1,["arecibo::supernova::circuit::TrivialSecondaryCircuit"]],["impl RefUnwindSafe for SuperNovaError",1,["arecibo::supernova::error::SuperNovaError"]],["impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for ProverKey<E1, E2, C1, C2, S1, S2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::ProverKey: RefUnwindSafe,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: RefUnwindSafe,",1,["arecibo::supernova::snark::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for VerifierKey<E1, E2, C1, C2, S1, S2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::VerifierKey: RefUnwindSafe,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: RefUnwindSafe,",1,["arecibo::supernova::snark::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n E1: RefUnwindSafe,\n E2: RefUnwindSafe,\n S1: RefUnwindSafe,\n S2: RefUnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: RefUnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: RefUnwindSafe,\n <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: RefUnwindSafe,\n <E1 as Engine>::Scalar: RefUnwindSafe,\n <E2 as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::supernova::snark::CompressedSNARK"]],["impl<E> RefUnwindSafe for CircuitDigests<E>where\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::supernova::CircuitDigests"]],["impl<E1, E2, C1, C2> RefUnwindSafe for PublicParams<E1, E2, C1, C2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: RefUnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: RefUnwindSafe,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe + RefUnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe + RefUnwindSafe,",1,["arecibo::supernova::PublicParams"]],["impl<E1, E2> RefUnwindSafe for AuxParams<E1, E2>where\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: RefUnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: RefUnwindSafe,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <E1 as Engine>::Scalar: RefUnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe + RefUnwindSafe,",1,["arecibo::supernova::AuxParams"]],["impl<E1, E2> RefUnwindSafe for RecursiveSNARK<E1, E2>where\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: RefUnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: RefUnwindSafe,\n <E1 as Engine>::Scalar: RefUnwindSafe,\n <E2 as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::supernova::RecursiveSNARK"]],["impl<E> RefUnwindSafe for R1CSWithArity<E>where\n <E as Engine>::Scalar: UnwindSafe + RefUnwindSafe,",1,["arecibo::R1CSWithArity"]],["impl<E1, E2, C1, C2> RefUnwindSafe for PublicParams<E1, E2, C1, C2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: RefUnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: RefUnwindSafe,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe + RefUnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe + RefUnwindSafe,",1,["arecibo::PublicParams"]],["impl<E> RefUnwindSafe for ResourceBuffer<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: RefUnwindSafe,\n <E as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::ResourceBuffer"]],["impl<E1, E2, C1, C2> RefUnwindSafe for RecursiveSNARK<E1, E2, C1, C2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: RefUnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: RefUnwindSafe,\n <E1 as Engine>::Scalar: RefUnwindSafe,\n <E2 as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::RecursiveSNARK"]],["impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for ProverKey<E1, E2, C1, C2, S1, S2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n <S1 as RelaxedR1CSSNARKTrait<E1>>::ProverKey: RefUnwindSafe,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: RefUnwindSafe,",1,["arecibo::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for VerifierKey<E1, E2, C1, C2, S1, S2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: RefUnwindSafe,\n <E1 as Engine>::Scalar: RefUnwindSafe,\n <S1 as RelaxedR1CSSNARKTrait<E1>>::VerifierKey: RefUnwindSafe,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: RefUnwindSafe,",1,["arecibo::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> RefUnwindSafe for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n C1: RefUnwindSafe,\n C2: RefUnwindSafe,\n S1: RefUnwindSafe,\n S2: RefUnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: RefUnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: RefUnwindSafe,\n <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: RefUnwindSafe,\n <E1 as Engine>::Scalar: RefUnwindSafe,\n <E2 as Engine>::Scalar: RefUnwindSafe,",1,["arecibo::CompressedSNARK"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/core/panic/unwind_safe/trait.UnwindSafe.js b/docs/implementors/core/panic/unwind_safe/trait.UnwindSafe.js new file mode 100644 index 000000000..5fbb0ea8d --- /dev/null +++ b/docs/implementors/core/panic/unwind_safe/trait.UnwindSafe.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl UnwindSafe for NovaError",1,["arecibo::errors::NovaError"]],["impl UnwindSafe for PCSError",1,["arecibo::errors::PCSError"]],["impl<E> UnwindSafe for AllocatedPoint<E>where\n <E as Engine>::Base: UnwindSafe,",1,["arecibo::gadgets::ecc::AllocatedPoint"]],["impl<E> UnwindSafe for AllocatedPointNonInfinity<E>where\n <E as Engine>::Base: UnwindSafe,",1,["arecibo::gadgets::ecc::AllocatedPointNonInfinity"]],["impl<E> UnwindSafe for ProverKey<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: UnwindSafe,",1,["arecibo::provider::ipa_pc::ProverKey"]],["impl<E> UnwindSafe for VerifierKey<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey: UnwindSafe,",1,["arecibo::provider::ipa_pc::VerifierKey"]],["impl<E> UnwindSafe for EvaluationEngine<E>where\n E: UnwindSafe,",1,["arecibo::provider::ipa_pc::EvaluationEngine"]],["impl<E> UnwindSafe for InnerProductArgument<E>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::provider::ipa_pc::InnerProductArgument"]],["impl<E> UnwindSafe for EvaluationArgument<E>where\n <E as Engine>::Fr: UnwindSafe,\n <E as Engine>::G1Affine: UnwindSafe,",1,["arecibo::provider::mlkzg::EvaluationArgument"]],["impl<E, NE> UnwindSafe for EvaluationEngine<E, NE>where\n E: UnwindSafe,\n NE: UnwindSafe,",1,["arecibo::provider::mlkzg::EvaluationEngine"]],["impl<E> UnwindSafe for ZMProverKey<E>where\n <E as Engine>::G1Affine: UnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMProverKey"]],["impl<E> UnwindSafe for ZMVerifierKey<E>where\n <E as Engine>::G1Affine: UnwindSafe,\n <E as Engine>::G2Affine: UnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMVerifierKey"]],["impl<E> UnwindSafe for ZMCommitment<E>where\n <E as Engine>::G1Affine: UnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMCommitment"]],["impl<E> UnwindSafe for ZMEvaluation<E>where\n <E as Engine>::Fr: UnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMEvaluation"]],["impl<E> UnwindSafe for ZMProof<E>where\n <E as Engine>::G1Affine: UnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMProof"]],["impl<E, NE> UnwindSafe for ZMPCS<E, NE>where\n E: UnwindSafe,\n NE: UnwindSafe,",1,["arecibo::provider::non_hiding_zeromorph::ZMPCS"]],["impl UnwindSafe for Bn256Engine",1,["arecibo::provider::Bn256Engine"]],["impl UnwindSafe for GrumpkinEngine",1,["arecibo::provider::GrumpkinEngine"]],["impl UnwindSafe for Bn256EngineZM",1,["arecibo::provider::Bn256EngineZM"]],["impl UnwindSafe for Bn256EngineKZG",1,["arecibo::provider::Bn256EngineKZG"]],["impl UnwindSafe for Secp256k1Engine",1,["arecibo::provider::Secp256k1Engine"]],["impl UnwindSafe for Secq256k1Engine",1,["arecibo::provider::Secq256k1Engine"]],["impl UnwindSafe for PallasEngine",1,["arecibo::provider::PallasEngine"]],["impl UnwindSafe for VestaEngine",1,["arecibo::provider::VestaEngine"]],["impl<E> UnwindSafe for R1CSShape<E>where\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::r1cs::R1CSShape"]],["impl<E> UnwindSafe for R1CSResult<E>where\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::r1cs::R1CSResult"]],["impl<E> UnwindSafe for R1CSWitness<E>where\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::r1cs::R1CSWitness"]],["impl<E> UnwindSafe for R1CSInstance<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::r1cs::R1CSInstance"]],["impl<E> UnwindSafe for RelaxedR1CSWitness<E>where\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::r1cs::RelaxedR1CSWitness"]],["impl<E> UnwindSafe for RelaxedR1CSInstance<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::r1cs::RelaxedR1CSInstance"]],["impl<E, EE> UnwindSafe for BatchedRelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::batched::BatchedRelaxedR1CSSNARK"]],["impl<E, EE> UnwindSafe for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::batched::ProverKey"]],["impl<E, EE> UnwindSafe for VerifierKey<E, EE>where\n <E as Engine>::Scalar: UnwindSafe,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: UnwindSafe,",1,["arecibo::spartan::batched::VerifierKey"]],["impl<E, EE> UnwindSafe for ProverKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe,\n <EE as EvaluationEngineTrait<E>>::ProverKey: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::batched_ppsnark::ProverKey"]],["impl<E, EE> UnwindSafe for VerifierKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: UnwindSafe,",1,["arecibo::spartan::batched_ppsnark::VerifierKey"]],["impl<E, EE> UnwindSafe for BatchedRelaxedR1CSSNARK<E, EE>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: UnwindSafe,\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::batched_ppsnark::BatchedRelaxedR1CSSNARK"]],["impl<Scalar> UnwindSafe for MultilinearPolynomial<Scalar>where\n Scalar: UnwindSafe,",1,["arecibo::spartan::polys::multilinear::MultilinearPolynomial"]],["impl<E> UnwindSafe for R1CSShapeSparkRepr<E>where\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::ppsnark::R1CSShapeSparkRepr"]],["impl<E> UnwindSafe for R1CSShapeSparkCommitment<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe,",1,["arecibo::spartan::ppsnark::R1CSShapeSparkCommitment"]],["impl<E, EE> UnwindSafe for ProverKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe,\n <EE as EvaluationEngineTrait<E>>::ProverKey: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::ppsnark::ProverKey"]],["impl<E, EE> UnwindSafe for VerifierKey<E, EE>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: UnwindSafe,",1,["arecibo::spartan::ppsnark::VerifierKey"]],["impl<E, EE> UnwindSafe for RelaxedR1CSSNARK<E, EE>where\n <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment: UnwindSafe,\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::ppsnark::RelaxedR1CSSNARK"]],["impl<E, EE> UnwindSafe for ProverKey<E, EE>where\n <EE as EvaluationEngineTrait<E>>::ProverKey: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::snark::ProverKey"]],["impl<E, EE> UnwindSafe for VerifierKey<E, EE>where\n <E as Engine>::Scalar: UnwindSafe,\n <EE as EvaluationEngineTrait<E>>::VerifierKey: UnwindSafe,",1,["arecibo::spartan::snark::VerifierKey"]],["impl<E, EE> UnwindSafe for RelaxedR1CSSNARK<E, EE>where\n <EE as EvaluationEngineTrait<E>>::EvaluationArgument: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::spartan::snark::RelaxedR1CSSNARK"]],["impl<F> UnwindSafe for TrivialCircuit<F>where\n F: UnwindSafe,",1,["arecibo::traits::circuit::TrivialCircuit"]],["impl<F> UnwindSafe for TrivialTestCircuit<F>where\n F: UnwindSafe,",1,["arecibo::supernova::circuit::TrivialTestCircuit"]],["impl<F> UnwindSafe for TrivialSecondaryCircuit<F>where\n F: UnwindSafe,",1,["arecibo::supernova::circuit::TrivialSecondaryCircuit"]],["impl UnwindSafe for SuperNovaError",1,["arecibo::supernova::error::SuperNovaError"]],["impl<E1, E2, C1, C2, S1, S2> UnwindSafe for ProverKey<E1, E2, C1, C2, S1, S2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::ProverKey: UnwindSafe,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: UnwindSafe,",1,["arecibo::supernova::snark::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> UnwindSafe for VerifierKey<E1, E2, C1, C2, S1, S2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n <S1 as BatchedRelaxedR1CSSNARKTrait<E1>>::VerifierKey: UnwindSafe,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: UnwindSafe,",1,["arecibo::supernova::snark::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> UnwindSafe for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n E1: UnwindSafe,\n E2: UnwindSafe,\n S1: UnwindSafe,\n S2: UnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: UnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: UnwindSafe,\n <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: UnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe,",1,["arecibo::supernova::snark::CompressedSNARK"]],["impl<E> UnwindSafe for CircuitDigests<E>where\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::supernova::CircuitDigests"]],["impl<E1, E2, C1, C2> UnwindSafe for PublicParams<E1, E2, C1, C2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: UnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: UnwindSafe,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: UnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe,",1,["arecibo::supernova::PublicParams"]],["impl<E1, E2> UnwindSafe for AuxParams<E1, E2>where\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: UnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: UnwindSafe,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: UnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe,",1,["arecibo::supernova::AuxParams"]],["impl<E1, E2> UnwindSafe for RecursiveSNARK<E1, E2>where\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: UnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: UnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe,",1,["arecibo::supernova::RecursiveSNARK"]],["impl<E> UnwindSafe for R1CSWithArity<E>where\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::R1CSWithArity"]],["impl<E1, E2, C1, C2> UnwindSafe for PublicParams<E1, E2, C1, C2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::CommitmentKey: UnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::CommitmentKey: UnwindSafe,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E1 as Engine>::ROCircuit as ROCircuitTrait<<E2 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E2 as Engine>::ROCircuit as ROCircuitTrait<<E1 as Engine>::Scalar>>::Constants: UnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe,",1,["arecibo::PublicParams"]],["impl<E> UnwindSafe for ResourceBuffer<E>where\n <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment: UnwindSafe,\n <E as Engine>::Scalar: UnwindSafe,",1,["arecibo::ResourceBuffer"]],["impl<E1, E2, C1, C2> UnwindSafe for RecursiveSNARK<E1, E2, C1, C2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: UnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: UnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe,",1,["arecibo::RecursiveSNARK"]],["impl<E1, E2, C1, C2, S1, S2> UnwindSafe for ProverKey<E1, E2, C1, C2, S1, S2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n <S1 as RelaxedR1CSSNARKTrait<E1>>::ProverKey: UnwindSafe,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::ProverKey: UnwindSafe,",1,["arecibo::ProverKey"]],["impl<E1, E2, C1, C2, S1, S2> UnwindSafe for VerifierKey<E1, E2, C1, C2, S1, S2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n <<E1 as Engine>::RO as ROTrait<<E2 as Engine>::Scalar, <E1 as Engine>::Scalar>>::Constants: UnwindSafe,\n <<E2 as Engine>::RO as ROTrait<<E1 as Engine>::Scalar, <E2 as Engine>::Scalar>>::Constants: UnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe,\n <S1 as RelaxedR1CSSNARKTrait<E1>>::VerifierKey: UnwindSafe,\n <S2 as RelaxedR1CSSNARKTrait<E2>>::VerifierKey: UnwindSafe,",1,["arecibo::VerifierKey"]],["impl<E1, E2, C1, C2, S1, S2> UnwindSafe for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n C1: UnwindSafe,\n C2: UnwindSafe,\n S1: UnwindSafe,\n S2: UnwindSafe,\n <<E1 as Engine>::CE as CommitmentEngineTrait<E1>>::Commitment: UnwindSafe,\n <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment: UnwindSafe,\n <<<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment as CommitmentTrait<E2>>::CompressedCommitment: UnwindSafe,\n <E1 as Engine>::Scalar: UnwindSafe,\n <E2 as Engine>::Scalar: UnwindSafe,",1,["arecibo::CompressedSNARK"]]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/serde/de/trait.Deserialize.js b/docs/implementors/serde/de/trait.Deserialize.js new file mode 100644 index 000000000..beed7b780 --- /dev/null +++ b/docs/implementors/serde/de/trait.Deserialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for RelaxedR1CSSNARK<E, EE>"],["impl<'de, E: Engine> Deserialize<'de> for R1CSInstance<E>"],["impl<'de, E, NE> Deserialize<'de> for EvaluationEngine<E, NE>"],["impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: RelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<'de, E: Engine> Deserialize<'de> for ResourceBuffer<E>"],["impl<'de, E: Engine> Deserialize<'de> for RelaxedR1CSWitness<E>"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for ProverKey<E, EE>"],["impl<'de, E: Engine> Deserialize<'de> for RelaxedR1CSInstance<E>"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for BatchedRelaxedR1CSSNARK<E, EE>"],["impl<'de, E: Engine> Deserialize<'de> for ProverKey<E>"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for ProverKey<E, EE>"],["impl<'de, E: Engine> Deserialize<'de> for R1CSShapeSparkRepr<E>"],["impl<'de, E1, E2, C1, C2> Deserialize<'de> for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,"],["impl<'de, E: Engine> Deserialize<'de> for CircuitDigests<E>"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for VerifierKey<E, EE>"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for ProverKey<E, EE>"],["impl<'de, E1, E2, C1, C2> Deserialize<'de> for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,"],["impl<'de, E: Engine> Deserialize<'de> for R1CSShape<E>"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for ProverKey<E, EE>"],["impl<'de, E: Engine> Deserialize<'de> for InnerProductArgument<E>"],["impl<'de, E: Engine> Deserialize<'de> for ZMProof<E>where\n E::G1Affine: Deserialize<'de>,"],["impl<'de, E1, E2, C1, C2> Deserialize<'de> for RecursiveSNARK<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,"],["impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for VerifierKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: RelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: BatchedRelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<'de, E: Engine> Deserialize<'de> for EvaluationArgument<E>where\n E::G1Affine: Deserialize<'de>,\n E::Fr: Deserialize<'de>,"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for VerifierKey<E, EE>"],["impl<'de, E: Engine> Deserialize<'de> for ZMProverKey<E>where\n E::G1Affine: Deserialize<'de>,"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for VerifierKey<E, EE>"],["impl<'de, E: Engine> Deserialize<'de> for ZMVerifierKey<E>where\n E::G1Affine: Deserialize<'de>,\n E::G2Affine: Deserialize<'de>,"],["impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for VerifierKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: BatchedRelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<'de, E: Engine> Deserialize<'de> for R1CSShapeSparkCommitment<E>"],["impl<'de, E1, E2> Deserialize<'de> for RecursiveSNARK<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,"],["impl<'de, Scalar> Deserialize<'de> for MultilinearPolynomial<Scalar>where\n Scalar: Deserialize<'de>,"],["impl<'de, E1, E2> Deserialize<'de> for AuxParams<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,"],["impl<'de, E: Engine> Deserialize<'de> for R1CSWitness<E>"],["impl<'de, E: Engine> Deserialize<'de> for R1CSResult<E>"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for BatchedRelaxedR1CSSNARK<E, EE>"],["impl<'de, E> Deserialize<'de> for EvaluationEngine<E>"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for RelaxedR1CSSNARK<E, EE>"],["impl<'de, E: Engine> Deserialize<'de> for R1CSWithArity<E>"],["impl<'de, E: Engine> Deserialize<'de> for VerifierKey<E>"],["impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: RelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<'de, E: Engine> Deserialize<'de> for ZMCommitment<E>where\n E::G1Affine: Deserialize<'de>,"],["impl<'de, E1, E2, C1, C2, S1, S2> Deserialize<'de> for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: BatchedRelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<'de, E: Engine, EE: EvaluationEngineTrait<E>> Deserialize<'de> for VerifierKey<E, EE>"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/implementors/serde/ser/trait.Serialize.js b/docs/implementors/serde/ser/trait.Serialize.js new file mode 100644 index 000000000..1f0028b99 --- /dev/null +++ b/docs/implementors/serde/ser/trait.Serialize.js @@ -0,0 +1,3 @@ +(function() {var implementors = { +"arecibo":[["impl<E: Engine> Serialize for RelaxedR1CSInstance<E>"],["impl<E: Engine> Serialize for CircuitDigests<E>"],["impl<E: Engine> Serialize for ProverKey<E>"],["impl<E1, E2, C1, C2, S1, S2> Serialize for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: BatchedRelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<E: Engine> Serialize for EvaluationArgument<E>where\n E::G1Affine: Serialize,\n E::Fr: Serialize,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for ProverKey<E, EE>"],["impl<E: Engine> Serialize for R1CSWitness<E>"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for ProverKey<E, EE>"],["impl<E: Engine> Serialize for ResourceBuffer<E>"],["impl<Scalar> Serialize for MultilinearPolynomial<Scalar>where\n Scalar: Serialize,"],["impl<E1, E2, C1, C2, S1, S2> Serialize for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: RelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for VerifierKey<E, EE>"],["impl<E1, E2, C1, C2> Serialize for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for ProverKey<E, EE>"],["impl<E: Engine> Serialize for VerifierKey<E>"],["impl<E: Engine> Serialize for ZMCommitment<E>where\n E::G1Affine: Serialize,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for BatchedRelaxedR1CSSNARK<E, EE>"],["impl<E1, E2, C1, C2, S1, S2> Serialize for VerifierKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: BatchedRelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for BatchedRelaxedR1CSSNARK<E, EE>"],["impl<E: Engine> Serialize for R1CSInstance<E>"],["impl<E1, E2, C1, C2, S1, S2> Serialize for ProverKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: RelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for VerifierKey<E, EE>"],["impl<E: Engine> Serialize for RelaxedR1CSWitness<E>"],["impl<E: Engine> Serialize for R1CSShapeSparkCommitment<E>"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for VerifierKey<E, EE>"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for RelaxedR1CSSNARK<E, EE>"],["impl<E1, E2> Serialize for AuxParams<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,"],["impl<E: Engine> Serialize for ZMProverKey<E>where\n E::G1Affine: Serialize,"],["impl<E> Serialize for EvaluationEngine<E>"],["impl<E: Engine> Serialize for ZMProof<E>where\n E::G1Affine: Serialize,"],["impl<E: Engine> Serialize for InnerProductArgument<E>"],["impl<E: Engine> Serialize for R1CSResult<E>"],["impl<E: Engine> Serialize for R1CSShapeSparkRepr<E>"],["impl<E: Engine> Serialize for R1CSShape<E>"],["impl<E: Engine> Serialize for ZMVerifierKey<E>where\n E::G1Affine: Serialize,\n E::G2Affine: Serialize,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for ProverKey<E, EE>"],["impl<E1, E2, C1, C2> Serialize for RecursiveSNARK<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,"],["impl<E: Engine> Serialize for R1CSWithArity<E>"],["impl<E, NE> Serialize for EvaluationEngine<E, NE>"],["impl<E1, E2, C1, C2> Serialize for PublicParams<E1, E2, C1, C2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for RelaxedR1CSSNARK<E, EE>"],["impl<E: Engine, EE: EvaluationEngineTrait<E>> Serialize for VerifierKey<E, EE>"],["impl<E1, E2> Serialize for RecursiveSNARK<E1, E2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,"],["impl<E1, E2, C1, C2, S1, S2> Serialize for CompressedSNARK<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: BatchedRelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"],["impl<E1, E2, C1, C2, S1, S2> Serialize for VerifierKey<E1, E2, C1, C2, S1, S2>where\n E1: Engine<Base = <E2 as Engine>::Scalar>,\n E2: Engine<Base = <E1 as Engine>::Scalar>,\n C1: StepCircuit<E1::Scalar>,\n C2: StepCircuit<E2::Scalar>,\n S1: RelaxedR1CSSNARKTrait<E1>,\n S2: RelaxedR1CSSNARKTrait<E2>,"]] +};if (window.register_implementors) {window.register_implementors(implementors);} else {window.pending_implementors = implementors;}})() \ No newline at end of file diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 000000000..3eed6da45 --- /dev/null +++ b/docs/index.html @@ -0,0 +1 @@ +Index of crates

List of all crates

\ No newline at end of file diff --git a/docs/search-index.js b/docs/search-index.js new file mode 100644 index 000000000..10c294379 --- /dev/null +++ b/docs/search-index.js @@ -0,0 +1,5 @@ +var searchIndex = JSON.parse('{\ +"arecibo":{"doc":"This library implements Nova, a high-speed recursive SNARK.","t":"DDDDDDDLLLLLLLLLLLLLLFLLLLLLLLLLLLLLALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLALLLLLLLLLLLLLLLLLLAOLLLLLLLLLLLLLLLLLLLLLLAALLLLLLLLLAALLLLLLLALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLOORNNNNNNNNNNNNNNNNNENENNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLADDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDDDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLAAALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLGDDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLFFLLLFLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLAAAAADDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLADLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLDDIDDIDDKLLLLLLLLLLLLLLFKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLALLLLLLLLLLLLLLLLLLLLLLLLLLLLLLKKLKLLLLLAKLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLNNENLLLLLLLLLLLLLLLLLLLLLLDDDLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLIQQQQQQIQIQIQQIGGIQQQIIKKKKAAKAKKKKKAKKKKIDKLLLLLLLLLLLLLLLKLLLLLLQIQIQIIKKKKKKQIQQKKKIIQQIQQLLFKKKKKKK","n":["CompressedSNARK","ProverKey","PublicParams","R1CSWithArity","RecursiveSNARK","ResourceBuffer","VerifierKey","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","circuit_digest","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","constants","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","deserialize","deserialize","deserialize","deserialize","digest","digest","drop","drop","drop","drop","drop","drop","drop","entomb","entomb","entomb","entomb","eq","eq","equivalent","errors","exhume","exhume","exhume","exhume","extent","extent","extent","extent","fmt","fmt","fmt","from","from","from","from","from","from","from","gadgets","impl_traits","init","init","init","init","init","init","init","into","into","into","into","into","into","into","new","new","num_constraints","num_steps","num_variables","outputs","prove","prove_step","provider","r1cs","serialize","serialize","serialize","serialize","serialize","serialize","serialize","setup","setup","spartan","supernova","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","traits","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","verify","verify","vzip","vzip","vzip","vzip","vzip","vzip","vzip","zip_with","zip_with_for_each","NUM_HASH_BITS","DecompressionError","DigestError","IncorrectWitness","InternalError","InternalTranscriptError","InvalidCommitmentKeyLength","InvalidIPA","InvalidIndex","InvalidInitialInputLength","InvalidInputLength","InvalidMultisetProof","InvalidNumSteps","InvalidProductProof","InvalidStepOutputLength","InvalidSumcheckProof","InvalidWitnessLength","LengthError","NovaError","OddInputLength","PCSError","PCSError","ProofVerifyError","SynthesisError","UnSat","UnSatIndex","ZMError","borrow","borrow","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","deref","deref","deref_mut","deref_mut","drop","drop","eq","eq","equivalent","equivalent","fmt","fmt","fmt","fmt","from","from","from","from","init","init","into","into","source","to_owned","to_owned","to_string","to_string","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","ecc","AllocatedPoint","AllocatedPointNonInfinity","add","add_incomplete","add_internal","alloc","alloc","borrow","borrow","borrow_mut","borrow_mut","check_on_curve","clone","clone","clone_into","clone_into","conditionally_select","conditionally_select","default","deref","deref","deref_mut","deref_mut","double","double_incomplete","drop","drop","from","from","from_allocated_point","get_coordinates","get_coordinates","init","init","into","into","negate","new","scalar_mul","select_point_or_infinity","to_allocated_point","to_owned","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","vzip","vzip","Bn256Engine","Bn256EngineKZG","Bn256EngineZM","GrumpkinEngine","PallasEngine","Secp256k1Engine","Secq256k1Engine","VestaEngine","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","deref","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","drop","drop","drop","drop","drop","drop","drop","drop","eq","eq","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","fmt","fmt","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","from","from","init","init","init","init","init","init","init","init","into","into","into","into","into","into","into","into","ipa_pc","mlkzg","non_hiding_zeromorph","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","vzip","vzip","EvaluationEngine","InnerProductArgument","ProverKey","VerifierKey","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","deserialize","drop","drop","drop","drop","entomb","entomb","exhume","exhume","extent","extent","fmt","fmt","fmt","fmt","from","from","from","from","init","init","init","init","into","into","into","into","prove","serialize","serialize","serialize","serialize","setup","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","verify","vzip","vzip","vzip","vzip","EvaluationArgument","EvaluationEngine","borrow","borrow","borrow_mut","borrow_mut","clone","clone","clone_into","clone_into","deref","deref","deref_mut","deref_mut","deserialize","deserialize","drop","drop","fmt","fmt","from","from","init","init","into","into","prove","serialize","serialize","setup","to_owned","to_owned","try_from","try_from","try_into","try_into","type_id","type_id","verify","vzip","vzip","ZMCommitment","ZMEvaluation","ZMPCS","ZMProof","ZMProverKey","ZMVerifierKey","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","default","default","default","default","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","deserialize","drop","drop","drop","drop","drop","drop","entomb","entomb","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","exhume","exhume","extent","extent","fmt","fmt","fmt","fmt","fmt","fmt","from","from","from","from","from","from","init","init","init","init","init","init","into","into","into","into","into","into","prove","serialize","serialize","serialize","serialize","setup","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","verify","vzip","vzip","vzip","vzip","vzip","vzip","CommitmentKeyHint","R1CSInstance","R1CSResult","R1CSShape","R1CSWitness","RelaxedR1CSInstance","RelaxedR1CSWitness","absorb_in_ro","absorb_in_ro","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","commit","commit","commit_T","commit_T_into","commitment_key","commitment_key_size","default","default","default","default_T","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","deserialize","deserialize","deserialize","digest","drop","drop","drop","drop","drop","drop","entomb","eq","eq","eq","eq","eq","eq","equivalent","equivalent","equivalent","equivalent","equivalent","equivalent","exhume","extent","fmt","fmt","fmt","fmt","fmt","fmt","fold","fold","fold_mut","fold_mut","from","from","from","from","from","from","from_r1cs_instance","from_r1cs_instance_unchecked","from_r1cs_witness","init","init","init","init","init","init","into","into","into","into","into","into","is_sat","is_sat_relaxed","new","new","new","pad","pad","random","random_witness_instance","serialize","serialize","serialize","serialize","serialize","serialize","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","to_transcript_bytes","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","vzip","vzip","vzip","vzip","vzip","vzip","batched","batched_ppsnark","polys","ppsnark","snark","BatchedRelaxedR1CSSNARK","ProverKey","VerifierKey","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","deref","deref","deref","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","digest","drop","drop","drop","entomb","entomb","exhume","exhume","extent","extent","fmt","from","from","from","init","init","init","into","into","into","prove","serialize","serialize","serialize","setup","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","verify","vzip","vzip","vzip","BatchedRelaxedR1CSSNARK","ProverKey","VerifierKey","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","ck_floor","clone","clone","clone","clone_into","clone_into","clone_into","deref","deref","deref","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","digest","drop","drop","drop","entomb","entomb","exhume","exhume","extent","extent","fmt","from","from","from","init","init","init","into","into","into","prove","serialize","serialize","serialize","setup","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","verify","vzip","vzip","vzip","multilinear","MultilinearPolynomial","add","bind_poly_var_top","borrow","borrow_mut","clone","clone_into","deref","deref_mut","deserialize","drop","eq","equivalent","evaluate","evaluate_with","evaluations","fmt","from","get_num_vars","index","init","into","is_empty","len","new","random","serialize","to_owned","try_from","try_into","type_id","vzip","ProverKey","R1CSShapeSparkCommitment","R1CSShapeSparkRepr","RelaxedR1CSSNARK","VerifierKey","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","ck_floor","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","deserialize","deserialize","digest","drop","drop","drop","drop","drop","entomb","entomb","entomb","entomb","exhume","exhume","exhume","exhume","extent","extent","extent","extent","fmt","from","from","from","from","from","init","init","init","init","init","into","into","into","into","into","new","prove","serialize","serialize","serialize","serialize","serialize","setup","to_owned","to_owned","to_owned","to_owned","to_owned","to_transcript_bytes","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","verify","vzip","vzip","vzip","vzip","vzip","ProverKey","RelaxedR1CSSNARK","VerifierKey","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","deref","deref","deref","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","digest","drop","drop","drop","entomb","entomb","exhume","exhume","extent","extent","fmt","from","from","from","init","init","init","into","into","into","prove","serialize","serialize","serialize","setup","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","verify","vzip","vzip","vzip","AuxParams","CircuitDigests","NonUniformCircuit","PublicParams","RecursiveSNARK","StepCircuit","TrivialSecondaryCircuit","TrivialTestCircuit","arity","arity","arity","borrow","borrow","borrow","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","borrow_mut","circuit_digest","circuit_index","circuit_index","circuit_index","circuit_param_digests","clone","clone","clone","clone","clone","clone","clone_into","clone_into","clone_into","clone_into","clone_into","clone_into","default","default","deref","deref","deref","deref","deref","deref","deref","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","deserialize","digest","digest","drop","drop","drop","drop","drop","drop","entomb","eq","eq","equivalent","error","exhume","extent","fmt","fmt","fmt","from","from","from","from","from","from","from_parts","from_parts_unchecked","index","init","init","init","init","init","init","initial_circuit_index","into","into","into","into","into","into","into_parts","new","new","num_circuits","primary_circuit","prove_step","secondary_circuit","serialize","serialize","serialize","serialize","setup","snark","synthesize","synthesize","synthesize","to_owned","to_owned","to_owned","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_from","try_from","try_from","try_into","try_into","try_into","try_into","try_into","try_into","type_id","type_id","type_id","type_id","type_id","type_id","verify","vzip","vzip","vzip","vzip","vzip","vzip","MissingCK","NovaError","SuperNovaError","UnSatIndex","borrow","borrow_mut","clone","clone_into","deref","deref_mut","drop","eq","equivalent","fmt","fmt","from","from","init","into","source","to_owned","to_string","try_from","try_into","type_id","vzip","CompressedSNARK","ProverKey","VerifierKey","borrow","borrow","borrow","borrow_mut","borrow_mut","borrow_mut","clone","clone","clone","clone_into","clone_into","clone_into","deref","deref","deref","deref_mut","deref_mut","deref_mut","deserialize","deserialize","deserialize","drop","drop","drop","entomb","entomb","exhume","exhume","extent","extent","fmt","from","from","from","init","init","init","into","into","into","prove","serialize","serialize","serialize","setup","to_owned","to_owned","to_owned","try_from","try_from","try_from","try_into","try_into","try_into","type_id","type_id","type_id","verify","vzip","vzip","vzip","AbsorbInROTrait","Base","Base","CE","CircuitRO","Constants","Constants","Engine","GE","Group","NativeRO","PrimeFieldExt","RO","ROCircuit","ROCircuitTrait","ROConstants","ROConstantsCircuit","ROTrait","Scalar","Scalar","TE","TranscriptEngineTrait","TranscriptReprTrait","absorb","absorb","absorb","absorb_in_ro","circuit","commitment","dom_sep","evaluation","from_uniform","group_params","new","new","new","snark","squeeze","squeeze","squeeze","to_transcript_bytes","StepCircuit","TrivialCircuit","arity","arity","borrow","borrow_mut","clone","clone_into","default","deref","deref_mut","drop","eq","equivalent","fmt","from","init","into","synthesize","synthesize","to_owned","try_from","try_into","type_id","vzip","Commitment","CommitmentEngineTrait","CommitmentKey","CommitmentTrait","CompressedCommitment","Len","ScalarMul","commit","compress","decompress","length","setup","to_coordinates","EvaluationArgument","EvaluationEngineTrait","ProverKey","VerifierKey","prove","setup","verify","BatchedRelaxedR1CSSNARKTrait","DigestHelperTrait","ProverKey","ProverKey","RelaxedR1CSSNARKTrait","VerifierKey","VerifierKey","ck_floor","ck_floor","default_ck_hint","digest","prove","prove","setup","setup","verify","verify"],"q":[[0,"arecibo"],[170,"arecibo::constants"],[171,"arecibo::errors"],[240,"arecibo::gadgets"],[241,"arecibo::gadgets::ecc"],[292,"arecibo::provider"],[447,"arecibo::provider::ipa_pc"],[532,"arecibo::provider::mlkzg"],[573,"arecibo::provider::non_hiding_zeromorph"],[708,"arecibo::r1cs"],[868,"arecibo::spartan"],[873,"arecibo::spartan::batched"],[938,"arecibo::spartan::batched_ppsnark"],[1004,"arecibo::spartan::polys"],[1005,"arecibo::spartan::polys::multilinear"],[1037,"arecibo::spartan::ppsnark"],[1147,"arecibo::spartan::snark"],[1212,"arecibo::supernova"],[1358,"arecibo::supernova::error"],[1384,"arecibo::supernova::snark"],[1448,"arecibo::traits"],[1489,"arecibo::traits::circuit"],[1514,"arecibo::traits::commitment"],[1527,"arecibo::traits::evaluation"],[1534,"arecibo::traits::snark"]],"d":["A SNARK that proves the knowledge of a valid RecursiveSNARK","A type that holds the prover key for CompressedSNARK","A type that holds public parameters of Nova","A type that holds parameters for the primary and secondary …","A SNARK that proves the correct execution of an …","A resource buffer for RecursiveSNARK for storing scratch …","A type that holds the verifier key for CompressedSNARK","","","","","","","","","","","","","","","Compute the circuit digest of a StepCircuit.","","","","","","","","","","","","","","","Global Nova constants","","","","","","","","","","","","","","","","","","","","","","Return the R1CSWithArity’ digest.","Retrieve the digest of the public parameters.","","","","","","","","","","","","","","","This module defines errors returned by the library.","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","This module implements various gadgets necessary for Nova …","This implementation behaves in ways specific to the …","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Create a new R1CSWithArity","Create new instance of recursive SNARK","Returns the number of constraints in the primary and …","The number of steps which have been executed thus far.","Returns the number of variables in the primary and …","Get the outputs after the last step of computation.","Create a new CompressedSNARK","Create a new RecursiveSNARK (or updates the provided …","This module implements Nova’s traits using the following …","This module defines R1CS related types and a folding …","","","","","","","","Set up builder to create PublicParams for a pair of …","Creates prover and verifier keys for CompressedSNARK","This module implements RelaxedR1CSSNARKTrait using Spartan …","SuperNova Description","","","","","","","","This module defines various traits required by the users …","","","","","","","","","","","","","","","","","","","","","","Verify the correctness of the RecursiveSNARK","Verify the correctness of the CompressedSNARK","","","","","","","","Macros to give syntactic sugar for zipWith pattern and …","Like zip_with but use for_each instead of map.","Bit size of Nova field element hashes","returned when the supplied compressed commitment cannot be …","returned when there is an error creating a digest","returned when the consistency with public IO and …","returned when the prover cannot prove the provided …","returned when the transcript engine encounters an overflow …","returned if the provided commitment key is not of …","returned when an invalid inner product argument is provided","returned if the supplied row or col in (row,col,val) tuple …","returned when the initial input to an incremental …","returned if the supplied input is not of the right length","returned when the multiset check fails","returned if the provided number of steps is zero","returned when the product proof check fails","returned when the step execution produces an output whose …","returned when an invalid sum-check proof is provided","returned if the supplied witness is not of the right length","returned when a length check fails in a PCS","Errors returned by Nova","returned if the supplied input is not even-sized","Errors specific to the Polynomial commitment scheme","returned if there is an error in the proof/verification of …","returned if proof verification fails","return when error during synthesis","returned if the supplied witness is not a satisfying …","returned if the supplied witness is not a satisfying …","returned when there is a Zeromorph error","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","","Returns the argument unchanged.","","","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","This module implements various elliptic curve gadgets","AllocatedPoint provides an elliptic curve abstraction …","AllocatedPoint but one that is guaranteed to be not …","Add two points (may be equal)","Add two points assuming self != +/- other","Adds other point to this point and returns the result. …","Allocates a new point on the curve using coordinates …","Allocates a new point on the curve using coordinates …","","","","","checks if self is on the curve or if it is infinity","","","","","If condition outputs a otherwise outputs b","If condition outputs a otherwise outputs b","Allocates a default point on the curve, set to the …","","","","","Doubles the supplied point.","doubles the point; since this is called with a point not …","","","Returns the argument unchanged.","Returns the argument unchanged.","Turns an AllocatedPoint into an AllocatedPointNonInfinity …","Returns coordinates associated with the point.","Returns coordinates associated with the point.","","","Calls U::from(self).","Calls U::from(self).","Negates the provided point","Creates a new AllocatedPointNonInfinity from the specified …","A gadget for scalar multiplication, optimized to use …","If condition outputs a otherwise infinity","Returns an AllocatedPoint from an AllocatedPointNonInfinity","","","","","","","","","","","An implementation of the Nova Engine trait with BN254 …","An implementation of Nova traits with multilinear KZG over …","An implementation of the Nova Engine trait with BN254 …","An implementation of the Nova Engine trait with Grumpkin …","An implementation of the Nova Engine trait with Pallas …","An implementation of the Nova Engine trait with Secp256k1 …","An implementation of the Nova Engine trait with Secp256k1 …","An implementation of the Nova Engine trait with Vesta …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","This module implements EvaluationEngine using an IPA-based …","This module implements Nova’s evaluation engine using …","Non-hiding Zeromorph scheme for Multilinear Polynomials.","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Provides an implementation of a polynomial evaluation …","An inner product argument","Provides an implementation of the prover key","Provides an implementation of the verifier key","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","A method to verify purported evaluations of a batch of …","","","","","Provides an implementation of a polynomial evaluation …","Provides an implementation of a polynomial evaluation …","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","","","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","A method to verify purported evaluations of a batch of …","","","Commitments","Polynomial Evaluation","Zeromorph Polynomial Commitment Scheme on multilinear …","Proofs","ZMProverKey is used to generate a proof","ZMVerifierKey is used to check evaluation proofs for a …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","A type for functions that hints commitment key sizing by …","A type that holds an R1CS instance","A type that holds the result of a R1CS multiplication","A type that holds the shape of the R1CS matrices","A type that holds a witness for a given R1CS instance","A type that holds a Relaxed R1CS instance","A type that holds a witness for a given Relaxed R1CS …","","","","","","","","","","","","","","","","","","","","","","","","","","","Commits to the witness using the supplied generators","Commits to the witness using the supplied generators","A method to compute a commitment to the cross-term T given …","A method to compute a commitment to the cross-term T given …","Generates public parameters for a Rank-1 Constraint System …","Computes the number of generators required for the …","Produces a default R1CSResult given an R1CSShape","Produces a default RelaxedR1CSWitness given an R1CSShape","Produces a default RelaxedR1CSInstance given R1CSGens and …","Empty buffer for commit_T_into","","","","","","","","","","","","","","","","","","","returned the digest of the R1CSShape","","","","","","","","","","","","","","","","","","","","","","","","","","","","Folds an incoming R1CSWitness into the current one","Folds an incoming RelaxedR1CSInstance into the current one","Mutably folds an incoming R1CSWitness into the current one","Mutably folds an incoming RelaxedR1CSInstance into the …","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Initializes a new RelaxedR1CSInstance from an R1CSInstance","Initializes a new RelaxedR1CSInstance from an R1CSInstance","Initializes a new RelaxedR1CSWitness from an R1CSWitness","","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Checks if the R1CS instance is satisfiable given a witness …","Checks if the Relaxed R1CS instance is satisfiable given a …","Create an object of type R1CSShape from the explicitly …","A method to create a witness object using a vector of …","A method to create an instance object using constituent …","Pads the R1CSShape so that the number of variables is a …","Pads the provided witness to the correct length","Generate a random R1CSShape with the specified number of …","Generate a satisfying RelaxedR1CSWitness and …","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","This module implements BatchedRelaxedR1CSSNARKTrait using …","batched pp snark","This module contains the definitions of polynomial types …","This module implements RelaxedR1CSSNARK traits using a …","This module implements RelaxedR1CSSNARKTrait using Spartan …","A succinct proof of knowledge of a witness to a batch of …","A type that represents the prover’s key","A type that represents the verifier’s key","","","","","","","","","","","","","","","","","","","","","","Returns the digest of the verifier’s key.","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","A succinct proof of knowledge of a witness to a relaxed …","A type that represents the prover’s key","A type that represents the verifier’s key","","","","","","","","","","","","","","","","","","","","","","","Returns the digest of the verifier’s key","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","","","","","","","","","","","","","","","","","","","","","","Main components:","A multilinear extension of a polynomial $Z(\\\\cdot)$, denote …","","Binds the polynomial’s top variable using the given …","","","","","","","","","","","Evaluates the polynomial at the given point. Returns Z(r) …","Evaluates the polynomial with the given evaluations and …","evaluations of the polynomial in all the 2^num_vars …","","Returns the argument unchanged.","Returns the number of variables in the multilinear …","","","Calls U::from(self).","Returns true if no evaluations.","Returns the total number of evaluations.","Creates a new MultilinearPolynomial from the given …","Returns a random polynomial","","","","","","","A type that represents the prover’s key","A type that holds a commitment to a sparse polynomial","A type that holds R1CSShape in a form amenable to memory …","A succinct proof of knowledge of a witness to a relaxed …","A type that represents the verifier’s key","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the digest of the verifier’s key","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","represents R1CSShape in a Spark-friendly format amenable …","produces a succinct proof of satisfiability of a …","","","","","","","","","","","","","","","","","","","","","","","","","","","","verifies a proof of satisfiability of a RelaxedR1CS …","","","","","","A type that represents the prover’s key","A succinct proof of knowledge of a witness to a relaxed …","A type that represents the verifier’s key","","","","","","","","","","","","","","","","","","","","","","Returns the digest of the verifier’s key.","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","produces a succinct proof of satisfiability of a …","","","","","","","","","","","","","","","","","verifies a proof of satisfiability of a RelaxedR1CS …","","","","Auxiliary PublicParams information about the commitment …","A struct that manages all the digests of the primary …","SuperNova helper trait, for implementors that provide sets …","A vector of R1CSWithArity adjoined to a set of PublicParams","A SNARK that proves the correct execution of an …","A helper trait for a step of the incremental computation …","A trivial step circuit that simply returns the input, for …","A trivial step circuit that simply returns the input","Return the the number of inputs or outputs of each step …","","","","","","","","","","","","","","","Compute the circuit digest of a supernova StepCircuit.","Return this StepCircuit’s assigned index, for use when …","","","All of the primary circuit digests of this PublicParams","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Return the CircuitDigests’ digest.","Return the PublicParams’ digest.","","","","","","","","","","","This module defines errors returned by the library.","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","Create a PublicParams from a vector of raw R1CSWithArity …","Create a PublicParams from a vector of raw R1CSWithArity …","","","","","","","","Initial circuit index, defaults to zero.","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Breaks down an instance of PublicParams into the circuit …","Construct a new CircuitDigests","iterate base step to get new instance of recursive SNARK","How many circuits are provided?","Return a new instance of the primary circuit at index.","executing a step of the incremental computation","Return a new instance of the secondary circuit.","","","","","Construct a new PublicParams","This module defines a final compressing SNARK for …","Synthesize the circuit for a computation step and return …","","","","","","","","","","","","","","","","","","","","","","","","","","","verify recursive snark","","","","","","","missing commitment key","Nova error","Errors returned by Nova","Extended error for supernova","","","","","","","","","","","","","Returns the argument unchanged.","","Calls U::from(self).","","","","","","","","A SNARK that proves the knowledge of a valid RecursiveSNARK","A type that holds the prover key for CompressedSNARK","A type that holds the verifier key for CompressedSNARK","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","","Returns the argument unchanged.","Returns the argument unchanged.","Returns the argument unchanged.","","","","Calls U::from(self).","Calls U::from(self).","Calls U::from(self).","Create a new CompressedSNARK","","","","Creates prover and verifier keys for CompressedSNARK","","","","","","","","","","","","","Verify the correctness of the CompressedSNARK","","","","A helper trait to absorb different objects in RO","A type representing an element of the base field of the …","A type representing an element of the base field of the …","A type that defines a commitment engine over scalars in …","The circuit alter ego of this trait impl - this constrains …","A type representing constants/parameters associated with …","A type representing constants/parameters associated with …","A collection of engines that are required by the library","A type that represents an element of the group","Represents an element of a group This is currently …","the vanilla alter ego of this trait - this constrains it …","Defines additional methods on PrimeField objects","A type that represents a circuit-friendly sponge that …","An alternate implementation of Self::RO in the circuit …","A helper trait that defines the behavior of a hash …","An alias for constants associated with E::RO","An alias for constants associated with E::ROCircuit","A helper trait that defines the behavior of a hash …","A type representing an element of the scalar field of the …","A type representing an element of the scalar field of the …","A type that provides a generic Fiat-Shamir transcript to …","This trait defines the behavior of a transcript engine …","This trait allows types to implement how they want to be …","Adds a scalar to the internal state","Adds a scalar to the internal state","absorbs any type that implements TranscriptReprTrait under …","Absorbs the value in the provided RO","This module defines traits that a step function must …","This module defines a collection of traits that define the …","adds a domain separator","This module defines a collection of traits that define the …","Returns a scalar representing the bytes","Returns A, B, the order of the group, the size of the base …","Initializes the hash function","Initializes the hash function","initializes the transcript","This module defines a collection of traits that define the …","Returns a challenge of num_bits by hashing the internal …","Returns a challenge of num_bits by hashing the internal …","returns a scalar element of the group as a challenge","returns a byte representation of self to be added to the …","A helper trait for a step of the incremental computation …","A trivial step circuit that simply returns the input","Return the number of inputs or outputs of each step (this …","","","","","","","","","","","","","Returns the argument unchanged.","","Calls U::from(self).","Sythesize the circuit for a computation step and return …","","","","","","","Holds the type of the commitment","A trait that ties different pieces of the commitment …","Holds the type of the commitment key The key should …","This trait defines the behavior of the commitment","Holds the type of the compressed commitment","A trait that helps determine the lenght of a structure. …","A helper trait for types implementing scalar …","Commits to the provided vector using the provided …","Compresses self into a compressed commitment","Decompresses a compressed commitment into a commitment","Returns the length of the structure.","Samples a new commitment key of a specified size","Returns the coordinate representation of the commitment","A type that holds the evaluation argument","A trait that ties different pieces of the commitment …","A type that holds the prover key","A type that holds the verifier key","A method to prove the evaluation of a multilinear …","A method to perform any additional setup needed to produce …","A method to verify the purported evaluation of a …","A trait that defines the behavior of a zkSNARK to prove …","A helper trait that defines the behavior of a verifier key …","A type that represents the prover’s key","A type that represents the prover’s key","A trait that defines the behavior of a zkSNARK","A type that represents the verifier’s key","A type that represents the verifier’s key","This associated function (not a method) provides a hint …","This associated function (not a method) provides a hint …","Public parameter creation takes a size hint. This size …","Returns the digest of the verifier’s key","Produces a new SNARK for a relaxed R1CS","Produces a new SNARK for a batch of relaxed R1CS","Produces the keys for the prover and the verifier","Produces the keys for the prover and the verifier","Verifies a SNARK for a relaxed R1CS","Verifies a SNARK for a batch of relaxed R1CS"],"i":[0,0,0,0,0,0,0,4,5,6,7,9,10,11,4,5,6,7,9,10,11,0,4,5,6,7,9,10,11,4,5,6,7,9,10,11,0,4,5,6,7,9,10,11,4,5,6,7,9,10,11,4,5,6,7,9,10,11,4,5,4,5,6,7,9,10,11,4,5,9,10,4,5,4,0,4,5,9,10,4,5,9,10,6,7,9,4,5,6,7,9,10,11,0,0,4,5,6,7,9,10,11,4,5,6,7,9,10,11,4,7,5,7,5,7,11,7,0,0,4,5,6,7,9,10,11,5,11,0,0,4,5,6,7,9,10,11,0,4,5,6,7,9,10,11,4,5,6,7,9,10,11,4,5,6,7,9,10,11,7,11,4,5,6,7,9,10,11,0,0,0,26,26,26,26,26,26,30,26,26,26,26,26,26,26,26,26,30,0,26,0,26,26,26,26,26,30,26,30,26,30,26,30,26,30,26,30,26,30,26,30,26,30,26,30,26,26,30,30,26,26,26,30,26,30,26,30,26,26,30,26,30,26,30,26,30,26,30,26,30,0,0,0,34,36,34,34,36,34,36,34,36,34,34,36,34,36,34,36,34,34,36,34,36,34,36,34,36,34,36,36,34,36,34,36,34,36,34,36,34,34,36,34,36,34,36,34,36,34,36,34,36,0,0,0,0,0,0,0,0,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,0,0,0,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,40,41,42,43,44,45,46,47,0,0,0,0,48,49,50,51,48,49,50,51,48,49,50,51,48,49,50,51,48,49,50,51,48,49,50,51,48,49,50,51,48,49,50,51,48,49,48,49,48,49,48,49,50,51,48,49,50,51,48,49,50,51,48,49,50,51,50,48,49,50,51,50,48,49,50,51,48,49,50,51,48,49,50,51,48,49,50,51,50,48,49,50,51,0,0,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,53,54,54,53,54,54,53,54,53,54,53,54,53,54,54,53,54,0,0,0,0,0,0,56,57,58,59,60,61,56,57,58,59,60,61,56,57,58,59,60,61,56,57,58,59,60,61,58,59,60,61,56,57,58,59,60,61,56,57,58,59,60,61,56,57,58,60,56,57,58,59,60,61,56,57,56,57,58,59,60,61,56,57,58,59,60,61,56,57,56,57,56,57,58,59,60,61,56,57,58,59,60,61,56,57,58,59,60,61,56,57,58,59,60,61,61,56,57,58,60,61,56,57,58,59,60,61,56,57,58,59,60,61,56,57,58,59,60,61,56,57,58,59,60,61,61,56,57,58,59,60,61,0,0,0,0,0,0,0,63,64,25,65,66,63,67,64,25,65,66,63,67,64,25,65,66,63,67,64,25,65,66,63,67,64,66,67,25,25,0,0,65,67,64,0,25,65,66,63,67,64,25,65,66,63,67,64,25,65,66,63,67,64,25,25,65,66,63,67,64,25,25,65,66,63,67,64,25,65,66,63,67,64,25,25,25,65,66,63,67,64,67,64,67,64,25,65,66,63,67,64,64,64,67,25,65,66,63,67,64,25,65,66,63,67,64,25,25,25,66,63,25,67,25,25,25,65,66,63,67,64,25,65,66,63,67,64,64,25,65,66,63,67,64,25,65,66,63,67,64,25,65,66,63,67,64,25,65,66,63,67,64,0,0,0,0,0,0,0,0,72,73,74,72,73,74,72,73,74,72,73,74,72,73,74,72,73,74,72,73,74,74,72,73,74,73,74,73,74,73,74,72,72,73,74,72,73,74,72,73,74,72,72,73,74,72,72,73,74,72,73,74,72,73,74,72,73,74,72,72,73,74,0,0,0,77,78,79,77,78,79,79,77,78,79,77,78,79,77,78,79,77,78,79,77,78,79,78,77,78,79,77,78,77,78,77,78,79,77,78,79,77,78,79,77,78,79,79,77,78,79,79,77,78,79,77,78,79,77,78,79,77,78,79,79,77,78,79,0,0,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,81,0,0,0,0,0,84,85,86,87,88,84,85,86,87,88,88,84,85,86,87,88,84,85,86,87,88,84,85,86,87,88,84,85,86,87,88,84,85,86,87,88,87,84,85,86,87,88,84,85,86,87,84,85,86,87,84,85,86,87,88,84,85,86,87,88,84,85,86,87,88,84,85,86,87,88,84,88,84,85,86,87,88,88,84,85,86,87,88,85,84,85,86,87,88,84,85,86,87,88,84,85,86,87,88,88,84,85,86,87,88,0,0,0,89,90,91,89,90,91,89,90,91,89,90,91,89,90,91,89,90,91,89,90,91,90,89,90,91,89,90,89,90,89,90,91,89,90,91,89,90,91,89,90,91,91,89,90,91,91,89,90,91,89,90,91,89,90,91,89,90,91,91,89,90,91,0,0,0,0,0,0,0,0,94,92,93,92,93,96,95,97,98,92,93,96,95,97,98,0,94,92,93,95,92,93,96,95,97,98,92,93,96,95,97,98,92,93,92,93,96,96,95,97,98,92,93,96,95,97,98,96,95,97,98,96,95,92,93,96,95,97,98,97,96,97,96,0,97,97,92,93,98,92,93,96,95,97,98,95,95,95,92,93,96,95,97,98,99,92,93,96,95,97,98,95,96,98,99,99,98,99,96,95,97,98,95,0,94,92,93,92,93,96,95,97,98,92,93,96,95,97,98,92,93,96,95,97,98,92,93,96,95,97,98,98,92,93,96,95,97,98,100,100,0,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,0,0,0,102,103,104,102,103,104,102,103,104,102,103,104,102,103,104,102,103,104,102,103,104,102,103,104,102,103,102,103,102,103,104,102,103,104,102,103,104,102,103,104,104,102,103,104,104,102,103,104,102,103,104,102,103,104,102,103,104,104,102,103,104,0,107,3,3,108,108,109,0,3,0,109,0,3,3,0,0,0,0,107,3,3,0,0,108,109,110,111,0,0,110,0,112,107,108,109,110,0,108,109,110,105,0,0,1,106,106,106,106,106,106,106,106,106,106,106,106,106,106,106,1,106,106,106,106,106,106,113,0,113,0,114,0,0,113,114,114,115,113,114,71,0,71,71,71,71,71,0,0,8,101,0,8,101,8,101,0,116,8,101,8,101,8,101],"f":[0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[1],[[[4,[[0,[2,3]]]]],[[4,[[0,[2,3]]]]]],[[[5,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]]]]],[[5,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]]]]]],[[[6,[[0,[2,3]]]]],[[6,[[0,[2,3]]]]]],[[[7,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]]]]],[[7,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]]]]]],[[[9,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]],[0,[[8,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]],[[9,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]],[0,[[8,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]]],[[[10,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]],[0,[[8,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]],[[10,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]],[0,[[8,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]]],[[[11,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]],[0,[[8,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]],[[11,[[0,[3,2]],[0,[3,2]],[0,[1,2]],[0,[1,2]],[0,[[8,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[13,[[14,[[4,[3]]]]]],[13,[[14,[[5,[3,3,1,1]]]]]],[13,[[14,[[6,[3]]]]]],[13,[[14,[[7,[3,3,1,1]]]]]],[13,[[14,[[9,[3,3,1,1,[8,[3]],[8,[3]]]]]]]],[13,[[14,[[10,[3,3,1,1,[8,[3]],[8,[3]]]]]]]],[13,[[14,[[11,[3,3,1,1,[8,[3]],[8,[3]]]]]]]],[[[4,[3]]]],[[[5,[3,3,1,1]]]],[12],[12],[12],[12],[12],[12],[12],[[[4,[3]],15],16],[[[5,[3,3,1,1]],15],16],[[[9,[3,3,1,1,[8,[3]],[8,[3]]]],15],16],[[[10,[3,3,1,1,[8,[3]],[8,[3]]]],15],16],[[[4,[[0,[17,3]]]],[4,[[0,[17,3]]]]],18],[[[5,[[0,[3,17]],[0,[3,17]],[0,[1,17]],[0,[1,17]]]],[5,[[0,[3,17]],[0,[3,17]],[0,[1,17]],[0,[1,17]]]]],18],[[],18],0,[[[4,[3]],[20,[19]]],[[21,[[20,[19]]]]]],[[[5,[3,3,1,1]],[20,[19]]],[[21,[[20,[19]]]]]],[[[9,[3,3,1,1,[8,[3]],[8,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[10,[3,3,1,1,[8,[3]],[8,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[4,[3]]],12],[[[5,[3,3,1,1]]],12],[[[9,[3,3,1,1,[8,[3]],[8,[3]]]]],12],[[[10,[3,3,1,1,[8,[3]],[8,[3]]]]],12],[[[6,[[0,[22,3]]]],23],24],[[[7,[[0,[3,22]],[0,[3,22]],[0,[1,22]],[0,[1,22]]]],23],24],[[[9,[[0,[3,22]],[0,[3,22]],[0,[1,22]],[0,[1,22]],[0,[[8,[[0,[3,22]]]],22]],[0,[[8,[[0,[3,22]]]],22]]]],23],24],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[25,[3]],12],[[4,[3]]]],[[[5,[3,3,1,1]],1,1,20,20],[[14,[[7,[3,3,1,1]],26]]]],[[[5,[3,3,1,1]]]],[[[7,[3,3,1,1]]],12],[[[5,[3,3,1,1]]]],[[[7,[3,3,1,1]]]],[[[5,[3,3,1,1]],[9,[3,3,1,1,[8,[3]],[8,[3]]]],[7,[3,3,1,1]]],[[14,[[11,[3,3,1,1,[8,[3]],[8,[3]]]],26]]]],[[[7,[3,3,1,1]],[5,[3,3,1,1]],1,1],[[14,[26]]]],0,0,[[[4,[3]],27],14],[[[5,[3,3,1,1]],27],14],[[[6,[3]],27],14],[[[7,[3,3,1,1]],27],14],[[[9,[3,3,1,1,[8,[3]],[8,[3]]]],27],14],[[[10,[3,3,1,1,[8,[3]],[8,[3]]]],27],14],[[[11,[3,3,1,1,[8,[3]],[8,[3]]]],27],14],[[1,1,[28,[3]],[28,[3]]],[[5,[3,3,1,1]]]],[[[5,[3,3,1,1]]],[[14,[26]]]],0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[],29],[[],29],[[],29],[[],29],[[[7,[3,3,1,1]],[5,[3,3,1,1]],12,20,20],[[14,[26]]]],[[[11,[3,3,1,1,[8,[3]],[8,[3]]]],[10,[3,3,1,1,[8,[3]],[8,[3]]]],12,20,20],[[14,[26]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[26,26],[30,30],[[]],[[]],[12],[12],[12],[12],[12],[12],[[26,26],18],[[30,30],18],[[],18],[[],18],[[26,23],24],[[26,23],24],[[30,23],24],[[30,23],24],[31,26],[[]],[30,26],[[]],[[],12],[[],12],[[]],[[]],[26,[[21,[32]]]],[[]],[[]],[[],33],[[],33],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[]],[[]],0,0,0,[[[34,[3]],35,[34,[3]]],[[14,[[34,[3]],31]]]],[[[36,[3]],35,[36,[3]]],[[14,[[36,[3]],31]]]],[[[34,[3]],35,[34,[3]],37],[[14,[[34,[3]],31]]]],[[35,21],[[14,[[34,[3]],31]]]],[[35,21],[[14,[[36,[3]],31]]]],[[]],[[]],[[]],[[]],[[[34,[3]],35],[[14,[31]]]],[[[34,[[0,[2,3]]]]],[[34,[[0,[2,3]]]]]],[[[36,[[0,[2,3]]]]],[[36,[[0,[2,3]]]]]],[[]],[[]],[[35,[34,[3]],[34,[3]],38],[[14,[[34,[3]],31]]]],[[35,[36,[3]],[36,[3]],38],[[14,[[36,[3]],31]]]],[35,[[14,[[34,[3]],31]]]],[12],[12],[12],[12],[[[34,[3]],35],[[14,[[34,[3]],31]]]],[[[36,[3]],35],[[14,[[36,[3]],31]]]],[12],[12],[[]],[[]],[[[34,[3]]],[[36,[3]]]],[[[34,[3]]]],[[[36,[3]]]],[[],12],[[],12],[[]],[[]],[[[34,[3]],35],[[14,[[34,[3]],31]]]],[[39,39],[[36,[3]]]],[[[34,[3]],35,[20,[37]]],[[14,[[34,[3]],31]]]],[[35,[34,[3]],38],[[14,[[34,[3]],31]]]],[[[36,[3]],39],[[14,[[34,[3]],31]]]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[]],[[]],0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[40,40],[41,41],[42,42],[43,43],[44,44],[45,45],[46,46],[47,47],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[[40,40],18],[[41,41],18],[[42,42],18],[[43,43],18],[[44,44],18],[[45,45],18],[[46,46],18],[[47,47],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[40,23],24],[[41,23],24],[[42,23],24],[[43,23],24],[[44,23],24],[[45,23],24],[[46,23],24],[[47,23],24],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[],29],[[],29],[[],29],[[],29],[[],29],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[48,[[0,[2,3]]]]],[[48,[[0,[2,3]]]]]],[[[49,[[0,[2,3]]]]],[[49,[[0,[2,3]]]]]],[[[50,[2]]],[[50,[2]]]],[[[51,[[0,[2,3]]]]],[[51,[[0,[2,3]]]]]],[[]],[[]],[[]],[[]],[12],[12],[12],[12],[12],[12],[12],[12],[13,[[14,[[48,[3]]]]]],[13,[[14,[[49,[3]]]]]],[13,[[14,[50]]]],[13,[[14,[[51,[3]]]]]],[12],[12],[12],[12],[[[48,[3]],15],16],[[[49,[3]],15],16],[[[48,[3]],[20,[19]]],[[21,[[20,[19]]]]]],[[[49,[3]],[20,[19]]],[[21,[[20,[19]]]]]],[[[48,[3]]],12],[[[49,[3]]],12],[[[48,[[0,[22,3]]]],23],24],[[[49,[[0,[22,3]]]],23],24],[[[50,[22]],23],24],[[[51,[[0,[22,3]]]],23],24],[[]],[[]],[[]],[[]],[[],12],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[]],[[20,20],[[14,[26]]]],[[[48,[3]],27],14],[[[49,[3]],27],14],[[50,27],14],[[[51,[3]],27],14],[[]],[[]],[[]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[],29],[20,[[14,[26]]]],[[]],[[]],[[]],[[]],0,0,[[]],[[]],[[]],[[]],[[[53,[[0,[2,52]]]]],[[53,[[0,[2,52]]]]]],[[[54,[2,2]]],[[54,[2,2]]]],[[]],[[]],[12],[12],[12],[12],[13,[[14,[[53,[52]]]]]],[13,[[14,[54]]]],[12],[12],[[[53,[[0,[22,52]]]],23],24],[[[54,[22,22]],23],24],[[]],[[]],[[],12],[[],12],[[]],[[]],[[[0,[55]],[0,[3]],20,20],[[14,[26]]]],[[[53,[52]],27],14],[[54,27],14],[[[0,[55]]]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[[0,[3]],20],[[14,[26]]]],[[]],[[]],0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[56,[[0,[2,52]]]]],[[56,[[0,[2,52]]]]]],[[[57,[[0,[2,52]]]]],[[57,[[0,[2,52]]]]]],[[[58,[[0,[2,52]]]]],[[58,[[0,[2,52]]]]]],[[[59,[[0,[2,52]]]]],[[59,[[0,[2,52]]]]]],[[[60,[[0,[2,52]]]]],[[60,[[0,[2,52]]]]]],[[[61,[2,2]]],[[61,[2,2]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[],[[58,[[0,[62,52]]]]]],[[],[[59,[[0,[62,52]]]]]],[[],[[60,[[0,[62,52]]]]]],[[],[[61,[62,62]]]],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[13,[[14,[[56,[52]]]]]],[13,[[14,[[57,[52]]]]]],[13,[[14,[[58,[52]]]]]],[13,[[14,[[60,[52]]]]]],[12],[12],[12],[12],[12],[12],[[[56,[52]],15],16],[[[57,[52]],15],16],[[[56,[[0,[17,52]]]],[56,[[0,[17,52]]]]],18],[[[57,[[0,[17,52]]]],[57,[[0,[17,52]]]]],18],[[[58,[[0,[17,52]]]],[58,[[0,[17,52]]]]],18],[[[59,[[0,[17,52]]]],[59,[[0,[17,52]]]]],18],[[[60,[[0,[17,52]]]],[60,[[0,[17,52]]]]],18],[[[61,[17,17]],[61,[17,17]]],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[[56,[52]],[20,[19]]],[[21,[[20,[19]]]]]],[[[57,[52]],[20,[19]]],[[21,[[20,[19]]]]]],[[[56,[52]]],12],[[[57,[52]]],12],[[[56,[[0,[22,52]]]],23],24],[[[57,[[0,[22,52]]]],23],24],[[[58,[[0,[22,52]]]],23],24],[[[59,[[0,[22,52]]]],23],24],[[[60,[[0,[22,52]]]],23],24],[[[61,[22,22]],23],24],[[]],[[]],[[]],[[]],[[]],[[]],[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[]],[[]],[[]],[[[0,[55]],20,20],[[14,[26]]]],[[[56,[52]],27],14],[[[57,[52]],27],14],[[[58,[52]],27],14],[[[60,[52]],27],14],[[[0,[55]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[],29],[[],29],[[],29],[20,[[14,[26]]]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,[[[63,[3]]]],[[[64,[3]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[[25,[[0,[2,3]]]]],[[25,[[0,[2,3]]]]]],[[[65,[[0,[2,3]]]]],[[65,[[0,[2,3]]]]]],[[[66,[[0,[2,3]]]]],[[66,[[0,[2,3]]]]]],[[[63,[[0,[2,3]]]]],[[63,[[0,[2,3]]]]]],[[[67,[[0,[2,3]]]]],[[67,[[0,[2,3]]]]]],[[[64,[[0,[2,3]]]]],[[64,[[0,[2,3]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[[66,[3]]]],[[[67,[3]]]],[[[25,[3]],[64,[3]],[67,[3]],[63,[3]],[66,[3]]],[[14,[26]]]],[[[25,[3]],[64,[3]],[67,[3]],[63,[3]],[66,[3]],68,[65,[3]],[65,[3]]],[[14,[26]]]],[[[25,[3]],[28,[3]]]],[[[25,[3]],[28,[3]]],12],[12,[[65,[3]]]],[[[25,[3]]],[[67,[3]]]],[[[25,[3]]],[[64,[3]]]],[12,68],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[13,[[14,[[25,[3]]]]]],[13,[[14,[[65,[3]]]]]],[13,[[14,[[66,[3]]]]]],[13,[[14,[[63,[3]]]]]],[13,[[14,[[67,[3]]]]]],[13,[[14,[[64,[3]]]]]],[[[25,[3]]]],[12],[12],[12],[12],[12],[12],[[[25,[3]],15],16],[[[25,[[0,[17,3]]]],[25,[[0,[17,3]]]]],18],[[[65,[[0,[17,3]]]],[65,[[0,[17,3]]]]],18],[[[66,[[0,[17,3]]]],[66,[[0,[17,3]]]]],18],[[[63,[[0,[17,3]]]],[63,[[0,[17,3]]]]],18],[[[67,[[0,[17,3]]]],[67,[[0,[17,3]]]]],18],[[[64,[[0,[17,3]]]],[64,[[0,[17,3]]]]],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[],18],[[[25,[3]],[20,[19]]],[[21,[[20,[19]]]]]],[[[25,[3]]],12],[[[25,[[0,[22,3]]]],23],24],[[[65,[[0,[22,3]]]],23],24],[[[66,[[0,[22,3]]]],23],24],[[[63,[[0,[22,3]]]],23],24],[[[67,[[0,[22,3]]]],23],24],[[[64,[[0,[22,3]]]],23],24],[[[67,[3]],[66,[3]],20],[[14,[[67,[3]],26]]]],[[[64,[3]],[63,[3]]],[[64,[3]]]],[[[67,[3]],[66,[3]],20],[[14,[26]]]],[[[64,[3]],[63,[3]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[[25,[3]],[63,[3]]],[[64,[3]]]],[20,[[64,[3]]]],[[[25,[3]],[66,[3]]],[[67,[3]]]],[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[]],[[]],[[]],[[[25,[3]],[63,[3]],[66,[3]]],[[14,[26]]]],[[[25,[3]],[64,[3]],[67,[3]]],[[14,[26]]]],0,[[[25,[3]],68],[[14,[[66,[3]],26]]]],[[[25,[3]],68],[[14,[[63,[3]],26]]]],[[[25,[3]]],[[25,[3]]]],[[[67,[3]],[25,[3]]],[[67,[3]]]],[[12,12,12,12,[0,[69,70]]],[[25,[3]]]],[[[25,[3]],[0,[69,70]]]],[[[25,[3]],27],14],[[[65,[3]],27],14],[[[66,[3]],27],14],[[[63,[3]],27],14],[[[67,[3]],27],14],[[[64,[3]],27],14],[[]],[[]],[[]],[[]],[[]],[[]],[[[64,[3]]],[[68,[19]]]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[],29],[[],29],[[],29],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[[72,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[72,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[[73,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[73,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[[74,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[74,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[]],[[]],[[]],[12],[12],[12],[12],[12],[12],[13,[[14,[[72,[3,[71,[3]]]]]]]],[13,[[14,[[73,[3,[71,[3]]]]]]]],[13,[[14,[[74,[3,[71,[3]]]]]]]],[[[74,[3,[71,[3]]]]]],[12],[12],[12],[[[73,[3,[71,[3]]]],15],16],[[[74,[3,[71,[3]]]],15],16],[[[73,[3,[71,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[74,[3,[71,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[73,[3,[71,[3]]]]],12],[[[74,[3,[71,[3]]]]],12],[[[72,[[0,[22,3]],[0,[22,[71,[[0,[22,3]]]]]]]],23],24],[[]],[[]],[[]],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[[68,[[25,[3]]]],[20,[[64,[3]]]],[20,[[67,[3]]]]],[[14,[[72,[3,[71,[3]]]],26]]]],[[[72,[3,[71,[3]]]],27],14],[[[73,[3,[71,[3]]]],27],14],[[[74,[3,[71,[3]]]],27],14],[[[68,[[25,[3]]]]],[[14,[26]]]],[[]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[[72,[3,[71,[3]]]],[20,[[64,[3]]]]],[[14,[26]]]],[[]],[[]],[[]],0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[],[[76,[75]]]],[[[77,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[77,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[[78,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[78,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[[79,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[79,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[]],[[]],[[]],[12],[12],[12],[12],[12],[12],[13,[[14,[[77,[3,[71,[3]]]]]]]],[13,[[14,[[78,[3,[71,[3]]]]]]]],[13,[[14,[[79,[3,[71,[3]]]]]]]],[[[78,[3,[71,[3]]]]]],[12],[12],[12],[[[77,[3,[71,[3]]]],15],16],[[[78,[3,[71,[3]]]],15],16],[[[77,[3,[71,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[78,[3,[71,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[77,[3,[71,[3]]]]],12],[[[78,[3,[71,[3]]]]],12],[[[79,[[0,[22,3]],[0,[22,[71,[[0,[22,3]]]]]]]],23],24],[[]],[[]],[[]],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[[68,[[25,[3]]]],[20,[[64,[3]]]],[20,[[67,[3]]]]],[[14,[[79,[3,[71,[3]]]],26]]]],[[[77,[3,[71,[3]]]],27],14],[[[78,[3,[71,[3]]]],27],14],[[[79,[3,[71,[3]]]],27],14],[[[68,[[25,[3]]]]],[[14,[26]]]],[[]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[[79,[3,[71,[3]]]],[20,[[64,[3]]]]],[[14,[26]]]],[[]],[[]],[[]],0,0,[[[81,[80]],[81,[80]]]],[[[81,[80]],80]],[[]],[[]],[[[81,[2]]],[[81,[2]]]],[[]],[12],[12],[13,[[14,[[81,[82]]]]]],[12],[[[81,[17]],[81,[17]]],18],[[],18],[[[81,[80]],[20,[80]]],80],[[[20,[80]],[20,[80]]],80],[[[81,[80]]],[[20,[80]]]],[[[81,[22]],23],24],[[]],[[[81,[80]]],12],[[[81,[80]],12],80],[[],12],[[]],[[[81,[80]]],18],[[[81,[80]]],12],[[[68,[80]]],[[81,[80]]]],[[12,[0,[69,70]]],[[81,[80]]]],[[[81,[83]],27],14],[[]],[[],14],[[],14],[[],29],[[]],0,0,0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[],[[76,[75]]]],[[[84,[[0,[2,3]]]]],[[84,[[0,[2,3]]]]]],[[[85,[[0,[2,3]]]]],[[85,[[0,[2,3]]]]]],[[[86,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[86,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[[87,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[87,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[[88,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[88,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[]],[[]],[[]],[[]],[[]],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[13,[[14,[[84,[3]]]]]],[13,[[14,[[85,[3]]]]]],[13,[[14,[[86,[3,[71,[3]]]]]]]],[13,[[14,[[87,[3,[71,[3]]]]]]]],[13,[[14,[[88,[3,[71,[3]]]]]]]],[[[87,[3,[71,[3]]]]]],[12],[12],[12],[12],[12],[[[84,[3]],15],16],[[[85,[3]],15],16],[[[86,[3,[71,[3]]]],15],16],[[[87,[3,[71,[3]]]],15],16],[[[84,[3]],[20,[19]]],[[21,[[20,[19]]]]]],[[[85,[3]],[20,[19]]],[[21,[[20,[19]]]]]],[[[86,[3,[71,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[87,[3,[71,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[84,[3]]],12],[[[85,[3]]],12],[[[86,[3,[71,[3]]]]],12],[[[87,[3,[71,[3]]]]],12],[[[88,[[0,[22,3]],[0,[22,[71,[[0,[22,3]]]]]]]],23],24],[[]],[[]],[[]],[[]],[[]],[[],12],[[],12],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[]],[[]],[[[25,[3]]],[[84,[3]]]],[[[25,[3]],[64,[3]],[67,[3]]],[[14,[[88,[3,[71,[3]]]],26]]]],[[[84,[3]],27],14],[[[85,[3]],27],14],[[[86,[3,[71,[3]]]],27],14],[[[87,[3,[71,[3]]]],27],14],[[[88,[3,[71,[3]]]],27],14],[[[25,[3]]],[[14,[26]]]],[[]],[[]],[[]],[[]],[[]],[[[85,[3]]],[[68,[19]]]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[],29],[[],29],[[[88,[3,[71,[3]]]],[64,[3]]],[[14,[26]]]],[[]],[[]],[[]],[[]],[[]],0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[[89,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[89,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[[90,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[90,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[[91,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]],[[91,[[0,[2,3]],[0,[2,[71,[[0,[2,3]]]]]]]]]],[[]],[[]],[[]],[12],[12],[12],[12],[12],[12],[13,[[14,[[89,[3,[71,[3]]]]]]]],[13,[[14,[[90,[3,[71,[3]]]]]]]],[13,[[14,[[91,[3,[71,[3]]]]]]]],[[[90,[3,[71,[3]]]]]],[12],[12],[12],[[[89,[3,[71,[3]]]],15],16],[[[90,[3,[71,[3]]]],15],16],[[[89,[3,[71,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[90,[3,[71,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[89,[3,[71,[3]]]]],12],[[[90,[3,[71,[3]]]]],12],[[[91,[[0,[22,3]],[0,[22,[71,[[0,[22,3]]]]]]]],23],24],[[]],[[]],[[]],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[[25,[3]],[64,[3]],[67,[3]]],[[14,[[91,[3,[71,[3]]]],26]]]],[[[89,[3,[71,[3]]]],27],14],[[[90,[3,[71,[3]]]],27],14],[[[91,[3,[71,[3]]]],27],14],[[[25,[3]]],[[14,[26]]]],[[]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[[91,[3,[71,[3]]]],[64,[3]]],[[14,[26]]]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,[[],12],[[[92,[80]]],12],[[[93,[80]]],12],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[]],[[94,12]],[[],12],[[[92,[80]]],12],[[[93,[80]]],12],[[[95,[3,3,94,94]]],[[96,[3]]]],[[[92,[2]]],[[92,[2]]]],[[[93,[2]]],[[93,[2]]]],[[[96,[[0,[2,3]]]]],[[96,[[0,[2,3]]]]]],[[[95,[[0,[3,2]],[0,[3,2]],[0,[94,2]],[0,[94,2]]]]],[[95,[[0,[3,2]],[0,[3,2]],[0,[94,2]],[0,[94,2]]]]]],[[[97,[[0,[3,2]],[0,[3,2]]]]],[[97,[[0,[3,2]],[0,[3,2]]]]]],[[[98,[[0,[3,2]],[0,[3,2]]]]],[[98,[[0,[3,2]],[0,[3,2]]]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[],[[92,[62]]]],[[],[[93,[62]]]],[12],[12],[[[96,[3]]]],[12],[12],[12],[12],[12],[12],[12],[12],[12],[12],[13,[[14,[[96,[3]]]]]],[13,[[14,[[95,[3,3,94,94]]]]]],[13,[[14,[[97,[3,3]]]]]],[13,[[14,[[98,[3,3]]]]]],[[[96,[3]]]],[[[95,[3,3,94,94]]]],[12],[12],[12],[12],[12],[12],[[[97,[3,3]],15],16],[[[96,[[0,[17,3]]]],[96,[[0,[17,3]]]]],18],[[[97,[[0,[3,17]],[0,[3,17]]]],[97,[[0,[3,17]],[0,[3,17]]]]],18],[[],18],0,[[[97,[3,3]],[20,[19]]],[[21,[[20,[19]]]]]],[[[97,[3,3]]],12],[[[92,[22]],23],24],[[[93,[22]],23],24],[[[98,[[0,[3,22]],[0,[3,22]]]],23],24],[[]],[[]],[[]],[[]],[[]],[[]],[[[68,[[4,[3]]]],[97,[3,3]]],[[95,[3,3,94,94]]]],[[[68,[[4,[3]]]],[97,[3,3]]],[[95,[3,3,94,94]]]],[[[95,[3,3,94,94]],12]],[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[]],[[]],[[]],[[[95,[3,3,94,94]]]],[68,[[96,[3]]]],[[[95,[3,3,94,94]],[99,[3,3,94,94]],94,94,20,20],[[14,[[98,[3,3]],100]]]],[[],12],[12],[[[98,[3,3]],[95,[3,3,94,94]],94,94],[[14,[100]]]],[[]],[[[96,[3]],27],14],[[[95,[3,3,94,94]],27],14],[[[97,[3,3]],27],14],[[[98,[3,3]],27],14],[[[99,[3,3,94,94]],[28,[3]],[28,[3]]],[[95,[3,3,94,94]]]],0,[[35,[21,[39]],[20,[39]]],[[14,[31]]]],[[[92,[80]],[35,[80]],[21,[[39,[80]]]],[20,[[39,[80]]]]],[[14,[31]]]],[[[93,[80]],[35,[80]],[21,[[39,[80]]]],[20,[[39,[80]]]]],[[14,[31]]]],[[]],[[]],[[]],[[]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[],29],[[],29],[[],29],[[[98,[3,3]],[95,[3,3,94,94]],20,20],[[14,[100]]]],[[]],[[]],[[]],[[]],[[]],[[]],0,0,0,0,[[]],[[]],[100,100],[[]],[12],[12],[12],[[100,100],18],[[],18],[[100,23],24],[[100,23],24],[26,100],[[]],[[],12],[[]],[100,[[21,[32]]]],[[]],[[],33],[[],14],[[],14],[[],29],[[]],0,0,0,[[]],[[]],[[]],[[]],[[]],[[]],[[[102,[[0,[3,2]],[0,[3,2]],[0,[94,2]],[0,[94,2]],[0,[[101,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]],[[102,[[0,[3,2]],[0,[3,2]],[0,[94,2]],[0,[94,2]],[0,[[101,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]]],[[[103,[[0,[3,2]],[0,[3,2]],[0,[94,2]],[0,[94,2]],[0,[[101,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]],[[103,[[0,[3,2]],[0,[3,2]],[0,[94,2]],[0,[94,2]],[0,[[101,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]]],[[[104,[[0,[3,2]],[0,[3,2]],[0,[94,2]],[0,[94,2]],[0,[[101,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]],[[104,[[0,[3,2]],[0,[3,2]],[0,[94,2]],[0,[94,2]],[0,[[101,[[0,[3,2]]]],2]],[0,[[8,[[0,[3,2]]]],2]]]]]],[[]],[[]],[[]],[12],[12],[12],[12],[12],[12],[13,[[14,[[102,[3,3,94,94,[101,[3]],[8,[3]]]]]]]],[13,[[14,[[103,[3,3,94,94,[101,[3]],[8,[3]]]]]]]],[13,[[14,[[104,[3,3,94,94,[101,[3]],[8,[3]]]]]]]],[12],[12],[12],[[[102,[3,3,94,94,[101,[3]],[8,[3]]]],15],16],[[[103,[3,3,94,94,[101,[3]],[8,[3]]]],15],16],[[[102,[3,3,94,94,[101,[3]],[8,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[103,[3,3,94,94,[101,[3]],[8,[3]]]],[20,[19]]],[[21,[[20,[19]]]]]],[[[102,[3,3,94,94,[101,[3]],[8,[3]]]]],12],[[[103,[3,3,94,94,[101,[3]],[8,[3]]]]],12],[[[104,[[0,[3,22]],[0,[3,22]],[0,[94,22]],[0,[94,22]],[0,[[101,[[0,[3,22]]]],22]],[0,[[8,[[0,[3,22]]]],22]]]],23],24],[[]],[[]],[[]],[[],12],[[],12],[[],12],[[]],[[]],[[]],[[[95,[3,3,94,94]],[102,[3,3,94,94,[101,[3]],[8,[3]]]],[98,[3,3]]],[[14,[[104,[3,3,94,94,[101,[3]],[8,[3]]]],100]]]],[[[102,[3,3,94,94,[101,[3]],[8,[3]]]],27],14],[[[103,[3,3,94,94,[101,[3]],[8,[3]]]],27],14],[[[104,[3,3,94,94,[101,[3]],[8,[3]]]],27],14],[[[95,[3,3,94,94]]],[[14,[100]]]],[[]],[[]],[[]],[[],14],[[],14],[[],14],[[],14],[[],14],[[],14],[[],29],[[],29],[[],29],[[[104,[3,3,94,94,[101,[3]],[8,[3]]]],[95,[3,3,94,94]],[103,[3,3,94,94,[101,[3]],[8,[3]]]],20,20],[[14,[100]]]],[[]],[[]],[[]],0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,[[]],[39],[[[20,[19]],105]],[[]],0,0,[[[20,[19]]]],0,[[[20,[19]]]],[[]],[12],[12],[[[20,[19]]]],0,[12],[[35,12],[[14,[[68,[37]],31]]]],[[[20,[19]]],[[14,[26]]]],[[],[[68,[19]]]],0,0,[[],12],[[[106,[80]]],12],[[]],[[]],[[[106,[2]]],[[106,[2]]]],[[]],[[],[[106,[62]]]],[12],[12],[12],[[[106,[17]],[106,[17]]],18],[[],18],[[[106,[22]],23],24],[[]],[[],12],[[]],[[35,[20,[39]]],[[14,[[68,[39]],31]]]],[[[106,[80]],[35,[80]],[20,[[39,[80]]]]],[[14,[[68,[[39,[80]]]],31]]]],[[]],[[],14],[[],14],[[],29],[[]],0,0,0,0,0,0,0,[20],[[]],[[],[[14,[26]]]],[[],12],[[[20,[19]],12]],[[]],0,0,0,0,[[20,20],[[14,[26]]]],[[]],[20,[[14,[26]]]],0,0,0,0,0,0,0,[[],[[76,[75]]]],[[],[[76,[75]]]],[[],[[76,[75]]]],[[]],[[25,64,67],[[14,[26]]]],[[[68,[25]],[20,[64]],[20,[67]]],[[14,[26]]]],[25,[[14,[26]]]],[[[68,[25]]],[[14,[26]]]],[64,[[14,[26]]]],[[[20,[64]]],[[14,[26]]]]],"c":[],"p":[[8,"StepCircuit"],[8,"Clone"],[8,"Engine"],[3,"R1CSWithArity"],[3,"PublicParams"],[3,"ResourceBuffer"],[3,"RecursiveSNARK"],[8,"RelaxedR1CSSNARKTrait"],[3,"ProverKey"],[3,"VerifierKey"],[3,"CompressedSNARK"],[15,"usize"],[8,"Deserializer"],[4,"Result"],[8,"Write"],[6,"Result"],[8,"PartialEq"],[15,"bool"],[15,"u8"],[15,"slice"],[4,"Option"],[8,"Debug"],[3,"Formatter"],[6,"Result"],[3,"R1CSShape"],[4,"NovaError"],[8,"Serializer"],[6,"CommitmentKeyHint"],[3,"TypeId"],[4,"PCSError"],[4,"SynthesisError"],[8,"Error"],[3,"String"],[3,"AllocatedPoint"],[8,"ConstraintSystem"],[3,"AllocatedPointNonInfinity"],[3,"AllocatedBit"],[4,"Boolean"],[3,"AllocatedNum"],[3,"Bn256Engine"],[3,"GrumpkinEngine"],[3,"Bn256EngineZM"],[3,"Bn256EngineKZG"],[3,"Secp256k1Engine"],[3,"Secq256k1Engine"],[3,"PallasEngine"],[3,"VestaEngine"],[3,"ProverKey"],[3,"VerifierKey"],[3,"EvaluationEngine"],[3,"InnerProductArgument"],[8,"Engine"],[3,"EvaluationArgument"],[3,"EvaluationEngine"],[8,"MultiMillerLoop"],[3,"ZMProverKey"],[3,"ZMVerifierKey"],[3,"ZMCommitment"],[3,"ZMEvaluation"],[3,"ZMProof"],[3,"ZMPCS"],[8,"Default"],[3,"R1CSInstance"],[3,"RelaxedR1CSInstance"],[3,"R1CSResult"],[3,"R1CSWitness"],[3,"RelaxedR1CSWitness"],[3,"Vec"],[8,"RngCore"],[8,"CryptoRng"],[8,"EvaluationEngineTrait"],[3,"BatchedRelaxedR1CSSNARK"],[3,"ProverKey"],[3,"VerifierKey"],[8,"Fn"],[3,"Box"],[3,"ProverKey"],[3,"VerifierKey"],[3,"BatchedRelaxedR1CSSNARK"],[8,"PrimeField"],[3,"MultilinearPolynomial"],[8,"Deserialize"],[8,"Serialize"],[3,"R1CSShapeSparkRepr"],[3,"R1CSShapeSparkCommitment"],[3,"ProverKey"],[3,"VerifierKey"],[3,"RelaxedR1CSSNARK"],[3,"ProverKey"],[3,"VerifierKey"],[3,"RelaxedR1CSSNARK"],[3,"TrivialTestCircuit"],[3,"TrivialSecondaryCircuit"],[8,"StepCircuit"],[3,"PublicParams"],[3,"CircuitDigests"],[3,"AuxParams"],[3,"RecursiveSNARK"],[8,"NonUniformCircuit"],[4,"SuperNovaError"],[8,"BatchedRelaxedR1CSSNARKTrait"],[3,"ProverKey"],[3,"VerifierKey"],[3,"CompressedSNARK"],[8,"TranscriptReprTrait"],[3,"TrivialCircuit"],[8,"Group"],[8,"ROTrait"],[8,"ROCircuitTrait"],[8,"TranscriptEngineTrait"],[8,"AbsorbInROTrait"],[8,"PrimeFieldExt"],[8,"CommitmentEngineTrait"],[8,"CommitmentTrait"],[8,"Len"],[8,"DigestHelperTrait"]]}\ +}'); +if (typeof window !== 'undefined' && window.initSearch) {window.initSearch(searchIndex)}; +if (typeof exports !== 'undefined') {exports.searchIndex = searchIndex}; diff --git a/docs/settings.html b/docs/settings.html new file mode 100644 index 000000000..6fe4aa783 --- /dev/null +++ b/docs/settings.html @@ -0,0 +1 @@ +Rustdoc settings

Rustdoc settings

Back
\ No newline at end of file diff --git a/docs/src-files.js b/docs/src-files.js new file mode 100644 index 000000000..0ead77fab --- /dev/null +++ b/docs/src-files.js @@ -0,0 +1,4 @@ +var srcIndex = JSON.parse('{\ +"arecibo":["",[["bellpepper",[],["mod.rs","r1cs.rs","shape_cs.rs","solver.rs","test_shape_cs.rs"]],["gadgets",[["nonnative",[],["bignat.rs","mod.rs","util.rs"]]],["ecc.rs","mod.rs","r1cs.rs","utils.rs"]],["provider",[["util",[],["fb_msm.rs","mod.rs"]]],["bn256_grumpkin.rs","ipa_pc.rs","keccak.rs","kzg_commitment.rs","mlkzg.rs","mod.rs","non_hiding_kzg.rs","non_hiding_zeromorph.rs","pasta.rs","pedersen.rs","poseidon.rs","secp_secq.rs","traits.rs"]],["r1cs",[],["mod.rs","sparse.rs"]],["spartan",[["polys",[],["eq.rs","identity.rs","masked_eq.rs","mod.rs","multilinear.rs","power.rs","univariate.rs"]],["sumcheck",[],["engine.rs","mod.rs"]]],["batched.rs","batched_ppsnark.rs","macros.rs","math.rs","mod.rs","ppsnark.rs","snark.rs"]],["supernova",[],["circuit.rs","error.rs","mod.rs","snark.rs","utils.rs"]],["traits",[],["circuit.rs","commitment.rs","evaluation.rs","mod.rs","snark.rs"]]],["circuit.rs","constants.rs","digest.rs","errors.rs","lib.rs","nifs.rs"]]\ +}'); +createSrcSidebar(); diff --git a/docs/src/arecibo/bellpepper/mod.rs.html b/docs/src/arecibo/bellpepper/mod.rs.html new file mode 100644 index 000000000..452956ca3 --- /dev/null +++ b/docs/src/arecibo/bellpepper/mod.rs.html @@ -0,0 +1,131 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+
//! Support for generating R1CS from [Bellpepper].
+//!
+//! [Bellpepper]: https://github.com/lurk-lab/bellpepper
+
+pub mod r1cs;
+pub mod shape_cs;
+pub mod solver;
+pub mod test_shape_cs;
+
+#[cfg(test)]
+mod tests {
+  use crate::{
+    bellpepper::{
+      r1cs::{NovaShape, NovaWitness},
+      shape_cs::ShapeCS,
+      solver::SatisfyingAssignment,
+    },
+    provider::{Bn256Engine, PallasEngine, Secp256k1Engine},
+    traits::{snark::default_ck_hint, Engine},
+  };
+  use bellpepper_core::{num::AllocatedNum, ConstraintSystem};
+  use ff::PrimeField;
+
+  fn synthesize_alloc_bit<Fr: PrimeField, CS: ConstraintSystem<Fr>>(cs: &mut CS) {
+    // get two bits as input and check that they are indeed bits
+    let a = AllocatedNum::alloc_infallible(cs.namespace(|| "a"), || Fr::ONE);
+    let _ = a.inputize(cs.namespace(|| "a is input"));
+    cs.enforce(
+      || "check a is 0 or 1",
+      |lc| lc + CS::one() - a.get_variable(),
+      |lc| lc + a.get_variable(),
+      |lc| lc,
+    );
+    let b = AllocatedNum::alloc_infallible(cs.namespace(|| "b"), || Fr::ONE);
+    let _ = b.inputize(cs.namespace(|| "b is input"));
+    cs.enforce(
+      || "check b is 0 or 1",
+      |lc| lc + CS::one() - b.get_variable(),
+      |lc| lc + b.get_variable(),
+      |lc| lc,
+    );
+  }
+
+  fn test_alloc_bit_with<E: Engine>() {
+    // First create the shape
+    let mut cs: ShapeCS<E> = ShapeCS::new();
+    synthesize_alloc_bit(&mut cs);
+    let (shape, ck) = cs.r1cs_shape_and_key(&*default_ck_hint());
+
+    // Now get the assignment
+    let mut cs = SatisfyingAssignment::<E>::new();
+    synthesize_alloc_bit(&mut cs);
+    let (inst, witness) = cs.r1cs_instance_and_witness(&shape, &ck).unwrap();
+
+    // Make sure that this is satisfiable
+    assert!(shape.is_sat(&ck, &inst, &witness).is_ok());
+  }
+
+  #[test]
+  fn test_alloc_bit() {
+    test_alloc_bit_with::<PallasEngine>();
+    test_alloc_bit_with::<Bn256Engine>();
+    test_alloc_bit_with::<Secp256k1Engine>();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/bellpepper/r1cs.rs.html b/docs/src/arecibo/bellpepper/r1cs.rs.html new file mode 100644 index 000000000..96d4179c5 --- /dev/null +++ b/docs/src/arecibo/bellpepper/r1cs.rs.html @@ -0,0 +1,303 @@ +r1cs.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+
//! Support for generating R1CS using bellpepper.
+
+#![allow(non_snake_case)]
+
+use super::{shape_cs::ShapeCS, solver::SatisfyingAssignment, test_shape_cs::TestShapeCS};
+use crate::{
+  errors::NovaError,
+  r1cs::{commitment_key, CommitmentKeyHint, R1CSInstance, R1CSShape, R1CSWitness, SparseMatrix},
+  traits::Engine,
+  CommitmentKey,
+};
+use bellpepper_core::{Index, LinearCombination};
+use ff::PrimeField;
+
+/// `NovaWitness` provide a method for acquiring an `R1CSInstance` and `R1CSWitness` from implementers.
+pub trait NovaWitness<E: Engine> {
+  /// Return an instance and witness, given a shape and ck.
+  fn r1cs_instance_and_witness(
+    self,
+    shape: &R1CSShape<E>,
+    ck: &CommitmentKey<E>,
+  ) -> Result<(R1CSInstance<E>, R1CSWitness<E>), NovaError>;
+}
+
+/// `NovaShape` provides methods for acquiring `R1CSShape` and `CommitmentKey` from implementers.
+pub trait NovaShape<E: Engine> {
+  /// Return an appropriate `R1CSShape` and `CommitmentKey` structs.
+  /// A `CommitmentKeyHint` should be provided to help guide the construction of the `CommitmentKey`.
+  /// This parameter is documented in `r1cs::R1CS::commitment_key`.
+  fn r1cs_shape_and_key(&self, ck_hint: &CommitmentKeyHint<E>) -> (R1CSShape<E>, CommitmentKey<E>) {
+    let S = self.r1cs_shape();
+    let ck = commitment_key(&S, ck_hint);
+
+    (S, ck)
+  }
+  /// Return an appropriate `R1CSShape`.
+  fn r1cs_shape(&self) -> R1CSShape<E>;
+}
+
+impl<E: Engine> NovaWitness<E> for SatisfyingAssignment<E> {
+  fn r1cs_instance_and_witness(
+    self,
+    shape: &R1CSShape<E>,
+    ck: &CommitmentKey<E>,
+  ) -> Result<(R1CSInstance<E>, R1CSWitness<E>), NovaError> {
+    let (input_assignment, aux_assignment) = self.to_assignments();
+    let W = R1CSWitness::<E>::new(shape, aux_assignment)?;
+    let X = input_assignment[1..].to_owned();
+
+    let comm_W = W.commit(ck);
+
+    let instance = R1CSInstance::<E>::new(shape, comm_W, X)?;
+
+    Ok((instance, W))
+  }
+}
+
+macro_rules! impl_nova_shape {
+  ( $name:ident) => {
+    impl<E: Engine> NovaShape<E> for $name<E>
+    where
+      E::Scalar: PrimeField,
+    {
+      fn r1cs_shape(&self) -> R1CSShape<E> {
+        let mut A = SparseMatrix::<E::Scalar>::empty();
+        let mut B = SparseMatrix::<E::Scalar>::empty();
+        let mut C: SparseMatrix<<E as Engine>::Scalar> = SparseMatrix::<E::Scalar>::empty();
+
+        let mut num_cons_added = 0;
+        let mut X = (&mut A, &mut B, &mut C, &mut num_cons_added);
+        let num_inputs = self.num_inputs();
+        let num_constraints = self.num_constraints();
+        let num_vars = self.num_aux();
+
+        for constraint in self.constraints.iter() {
+          add_constraint(
+            &mut X,
+            num_vars,
+            &constraint.0,
+            &constraint.1,
+            &constraint.2,
+          );
+        }
+        assert_eq!(num_cons_added, num_constraints);
+
+        A.cols = num_vars + num_inputs;
+        B.cols = num_vars + num_inputs;
+        C.cols = num_vars + num_inputs;
+
+        // Don't count One as an input for shape's purposes.
+        let res = R1CSShape::new(num_constraints, num_vars, num_inputs - 1, A, B, C);
+        res.unwrap()
+      }
+    }
+  };
+}
+
+impl_nova_shape!(ShapeCS);
+impl_nova_shape!(TestShapeCS);
+
+fn add_constraint<S: PrimeField>(
+  X: &mut (
+    &mut SparseMatrix<S>,
+    &mut SparseMatrix<S>,
+    &mut SparseMatrix<S>,
+    &mut usize,
+  ),
+  num_vars: usize,
+  a_lc: &LinearCombination<S>,
+  b_lc: &LinearCombination<S>,
+  c_lc: &LinearCombination<S>,
+) {
+  let (A, B, C, nn) = X;
+  let n = **nn;
+  assert_eq!(n + 1, A.indptr.len(), "A: invalid shape");
+  assert_eq!(n + 1, B.indptr.len(), "B: invalid shape");
+  assert_eq!(n + 1, C.indptr.len(), "C: invalid shape");
+
+  let add_constraint_component = |index: Index, coeff: &S, M: &mut SparseMatrix<S>| {
+    match index {
+      Index::Input(idx) => {
+        // Inputs come last, with input 0, representing 'one',
+        // at position num_vars within the witness vector.
+        let idx = idx + num_vars;
+        M.data.push(*coeff);
+        M.indices.push(idx);
+      }
+      Index::Aux(idx) => {
+        M.data.push(*coeff);
+        M.indices.push(idx);
+      }
+    }
+  };
+
+  for (index, coeff) in a_lc.iter() {
+    add_constraint_component(index.0, coeff, A);
+  }
+  A.indptr.push(A.indices.len());
+
+  for (index, coeff) in b_lc.iter() {
+    add_constraint_component(index.0, coeff, B)
+  }
+  B.indptr.push(B.indices.len());
+
+  for (index, coeff) in c_lc.iter() {
+    add_constraint_component(index.0, coeff, C)
+  }
+  C.indptr.push(C.indices.len());
+
+  **nn += 1;
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/bellpepper/shape_cs.rs.html b/docs/src/arecibo/bellpepper/shape_cs.rs.html new file mode 100644 index 000000000..5809a6127 --- /dev/null +++ b/docs/src/arecibo/bellpepper/shape_cs.rs.html @@ -0,0 +1,213 @@ +shape_cs.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+
//! Support for generating R1CS shape using bellpepper.
+
+use crate::traits::Engine;
+use bellpepper_core::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};
+use ff::PrimeField;
+
+/// `ShapeCS` is a `ConstraintSystem` for creating `R1CSShape`s for a circuit.
+pub struct ShapeCS<E: Engine>
+where
+  E::Scalar: PrimeField,
+{
+  /// All constraints added to the `ShapeCS`.
+  pub constraints: Vec<(
+    LinearCombination<E::Scalar>,
+    LinearCombination<E::Scalar>,
+    LinearCombination<E::Scalar>,
+  )>,
+  inputs: usize,
+  aux: usize,
+}
+
+impl<E: Engine> ShapeCS<E> {
+  /// Create a new, default `ShapeCS`,
+  pub fn new() -> Self {
+    Self::default()
+  }
+
+  /// Returns the number of constraints defined for this `ShapeCS`.
+  pub fn num_constraints(&self) -> usize {
+    self.constraints.len()
+  }
+
+  /// Returns the number of inputs defined for this `ShapeCS`.
+  pub fn num_inputs(&self) -> usize {
+    self.inputs
+  }
+
+  /// Returns the number of aux inputs defined for this `ShapeCS`.
+  pub fn num_aux(&self) -> usize {
+    self.aux
+  }
+}
+
+impl<E: Engine> Default for ShapeCS<E> {
+  fn default() -> Self {
+    Self {
+      constraints: vec![],
+      inputs: 1,
+      aux: 0,
+    }
+  }
+}
+
+impl<E: Engine> ConstraintSystem<E::Scalar> for ShapeCS<E> {
+  type Root = Self;
+
+  fn alloc<F, A, AR>(&mut self, _annotation: A, _f: F) -> Result<Variable, SynthesisError>
+  where
+    F: FnOnce() -> Result<E::Scalar, SynthesisError>,
+    A: FnOnce() -> AR,
+    AR: Into<String>,
+  {
+    self.aux += 1;
+
+    Ok(Variable::new_unchecked(Index::Aux(self.aux - 1)))
+  }
+
+  fn alloc_input<F, A, AR>(&mut self, _annotation: A, _f: F) -> Result<Variable, SynthesisError>
+  where
+    F: FnOnce() -> Result<E::Scalar, SynthesisError>,
+    A: FnOnce() -> AR,
+    AR: Into<String>,
+  {
+    self.inputs += 1;
+
+    Ok(Variable::new_unchecked(Index::Input(self.inputs - 1)))
+  }
+
+  fn enforce<A, AR, LA, LB, LC>(&mut self, _annotation: A, a: LA, b: LB, c: LC)
+  where
+    A: FnOnce() -> AR,
+    AR: Into<String>,
+    LA: FnOnce(LinearCombination<E::Scalar>) -> LinearCombination<E::Scalar>,
+    LB: FnOnce(LinearCombination<E::Scalar>) -> LinearCombination<E::Scalar>,
+    LC: FnOnce(LinearCombination<E::Scalar>) -> LinearCombination<E::Scalar>,
+  {
+    let a = a(LinearCombination::zero());
+    let b = b(LinearCombination::zero());
+    let c = c(LinearCombination::zero());
+
+    self.constraints.push((a, b, c));
+  }
+
+  fn push_namespace<NR, N>(&mut self, _name_fn: N)
+  where
+    NR: Into<String>,
+    N: FnOnce() -> NR,
+  {
+  }
+
+  fn pop_namespace(&mut self) {}
+
+  fn get_root(&mut self) -> &mut Self::Root {
+    self
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/bellpepper/solver.rs.html b/docs/src/arecibo/bellpepper/solver.rs.html new file mode 100644 index 000000000..2f9a1cb41 --- /dev/null +++ b/docs/src/arecibo/bellpepper/solver.rs.html @@ -0,0 +1,17 @@ +solver.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+
//! Support for generating R1CS witness using bellpepper.
+
+use crate::traits::Engine;
+
+use bellpepper::util_cs::witness_cs::WitnessCS;
+
+/// A `ConstraintSystem` which calculates witness values for a concrete instance of an R1CS circuit.
+pub type SatisfyingAssignment<E> = WitnessCS<<E as Engine>::Scalar>;
+
\ No newline at end of file diff --git a/docs/src/arecibo/bellpepper/test_shape_cs.rs.html b/docs/src/arecibo/bellpepper/test_shape_cs.rs.html new file mode 100644 index 000000000..fafa21082 --- /dev/null +++ b/docs/src/arecibo/bellpepper/test_shape_cs.rs.html @@ -0,0 +1,637 @@ +test_shape_cs.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+
//! Support for generating R1CS shape using bellpepper.
+//! `TestShapeCS` implements a superset of `ShapeCS`, adding non-trivial namespace support for use in testing.
+
+use std::{
+  cmp::Ordering,
+  collections::{BTreeMap, HashMap},
+};
+
+use crate::traits::Engine;
+use bellpepper_core::{ConstraintSystem, Index, LinearCombination, SynthesisError, Variable};
+use core::fmt::Write;
+use ff::{Field, PrimeField};
+
+#[derive(Clone, Copy)]
+struct OrderedVariable(Variable);
+
+#[derive(Debug)]
+enum NamedObject {
+  Constraint(usize),
+  Var(Variable),
+  Namespace,
+}
+
+impl Eq for OrderedVariable {}
+impl PartialEq for OrderedVariable {
+  fn eq(&self, other: &Self) -> bool {
+    match (self.0.get_unchecked(), other.0.get_unchecked()) {
+      (Index::Input(ref a), Index::Input(ref b)) | (Index::Aux(ref a), Index::Aux(ref b)) => a == b,
+      _ => false,
+    }
+  }
+}
+impl PartialOrd for OrderedVariable {
+  fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+    Some(self.cmp(other))
+  }
+}
+impl Ord for OrderedVariable {
+  fn cmp(&self, other: &Self) -> Ordering {
+    match (self.0.get_unchecked(), other.0.get_unchecked()) {
+      (Index::Input(ref a), Index::Input(ref b)) | (Index::Aux(ref a), Index::Aux(ref b)) => {
+        a.cmp(b)
+      }
+      (Index::Input(_), Index::Aux(_)) => Ordering::Less,
+      (Index::Aux(_), Index::Input(_)) => Ordering::Greater,
+    }
+  }
+}
+
+/// `TestShapeCS` is a `ConstraintSystem` for creating `R1CSShape`s for a circuit.
+pub struct TestShapeCS<E: Engine> {
+  named_objects: HashMap<String, NamedObject>,
+  current_namespace: Vec<String>,
+  /// All constraints added to the `TestShapeCS`.
+  pub constraints: Vec<(
+    LinearCombination<E::Scalar>,
+    LinearCombination<E::Scalar>,
+    LinearCombination<E::Scalar>,
+    String,
+  )>,
+  inputs: Vec<String>,
+  aux: Vec<String>,
+}
+
+fn proc_lc<Scalar: PrimeField>(
+  terms: &LinearCombination<Scalar>,
+) -> BTreeMap<OrderedVariable, Scalar> {
+  let mut map = BTreeMap::new();
+  for (var, &coeff) in terms.iter() {
+    map
+      .entry(OrderedVariable(var))
+      .or_insert_with(|| Scalar::ZERO)
+      .add_assign(&coeff);
+  }
+
+  // Remove terms that have a zero coefficient to normalize
+  let mut to_remove = vec![];
+  for (var, coeff) in map.iter() {
+    if coeff.is_zero().into() {
+      to_remove.push(*var)
+    }
+  }
+
+  for var in to_remove {
+    map.remove(&var);
+  }
+
+  map
+}
+
+impl<E: Engine> TestShapeCS<E>
+where
+  E::Scalar: PrimeField,
+{
+  #[allow(unused)]
+  /// Create a new, default `TestShapeCS`,
+  pub fn new() -> Self {
+    Self::default()
+  }
+
+  /// Returns the number of constraints defined for this `TestShapeCS`.
+  pub fn num_constraints(&self) -> usize {
+    self.constraints.len()
+  }
+
+  /// Returns the number of inputs defined for this `TestShapeCS`.
+  pub fn num_inputs(&self) -> usize {
+    self.inputs.len()
+  }
+
+  /// Returns the number of aux inputs defined for this `TestShapeCS`.
+  pub fn num_aux(&self) -> usize {
+    self.aux.len()
+  }
+
+  /// Print all public inputs, aux inputs, and constraint names.
+  #[allow(dead_code)]
+  pub fn pretty_print_list(&self) -> Vec<String> {
+    let mut result = Vec::new();
+
+    for input in &self.inputs {
+      result.push(format!("INPUT {input}"));
+    }
+    for aux in &self.aux {
+      result.push(format!("AUX {aux}"));
+    }
+
+    for (_a, _b, _c, name) in &self.constraints {
+      result.push(name.to_string());
+    }
+
+    result
+  }
+
+  /// Print all iputs and a detailed representation of each constraint.
+  #[allow(dead_code)]
+  pub fn pretty_print(&self) -> String {
+    let mut s = String::new();
+
+    for input in &self.inputs {
+      writeln!(s, "INPUT {}", &input).unwrap()
+    }
+
+    let negone = -<E::Scalar>::ONE;
+
+    let powers_of_two = (0..E::Scalar::NUM_BITS)
+      .map(|i| E::Scalar::from(2u64).pow_vartime([u64::from(i)]))
+      .collect::<Vec<_>>();
+
+    let pp = |s: &mut String, lc: &LinearCombination<E::Scalar>| {
+      s.push('(');
+      let mut is_first = true;
+      for (var, coeff) in proc_lc::<E::Scalar>(lc) {
+        if coeff == negone {
+          s.push_str(" - ")
+        } else if !is_first {
+          s.push_str(" + ")
+        }
+        is_first = false;
+
+        if coeff != <E::Scalar>::ONE && coeff != negone {
+          for (i, x) in powers_of_two.iter().enumerate() {
+            if x == &coeff {
+              write!(s, "2^{i} . ").unwrap();
+              break;
+            }
+          }
+
+          write!(s, "{coeff:?} . ").unwrap()
+        }
+
+        match var.0.get_unchecked() {
+          Index::Input(i) => {
+            write!(s, "`I{}`", &self.inputs[i]).unwrap();
+          }
+          Index::Aux(i) => {
+            write!(s, "`A{}`", &self.aux[i]).unwrap();
+          }
+        }
+      }
+      if is_first {
+        // Nothing was visited, print 0.
+        s.push('0');
+      }
+      s.push(')');
+    };
+
+    for (a, b, c, name) in &self.constraints {
+      s.push('\n');
+
+      write!(s, "{name}: ").unwrap();
+      pp(&mut s, a);
+      write!(s, " * ").unwrap();
+      pp(&mut s, b);
+      s.push_str(" = ");
+      pp(&mut s, c);
+    }
+
+    s.push('\n');
+
+    s
+  }
+
+  /// Associate `NamedObject` with `path`.
+  /// `path` must not already have an associated object.
+  fn set_named_obj(&mut self, path: String, to: NamedObject) {
+    assert!(
+      !self.named_objects.contains_key(&path),
+      "tried to create object at existing path: {path}"
+    );
+
+    self.named_objects.insert(path, to);
+  }
+}
+
+impl<E: Engine> Default for TestShapeCS<E> {
+  fn default() -> Self {
+    let mut map = HashMap::new();
+    map.insert("ONE".into(), NamedObject::Var(Self::one()));
+    Self {
+      named_objects: map,
+      current_namespace: vec![],
+      constraints: vec![],
+      inputs: vec![String::from("ONE")],
+      aux: vec![],
+    }
+  }
+}
+
+impl<E: Engine> ConstraintSystem<E::Scalar> for TestShapeCS<E>
+where
+  E::Scalar: PrimeField,
+{
+  type Root = Self;
+
+  fn alloc<F, A, AR>(&mut self, annotation: A, _f: F) -> Result<Variable, SynthesisError>
+  where
+    F: FnOnce() -> Result<E::Scalar, SynthesisError>,
+    A: FnOnce() -> AR,
+    AR: Into<String>,
+  {
+    let path = compute_path(&self.current_namespace, &annotation().into());
+    self.aux.push(path);
+
+    Ok(Variable::new_unchecked(Index::Aux(self.aux.len() - 1)))
+  }
+
+  fn alloc_input<F, A, AR>(&mut self, annotation: A, _f: F) -> Result<Variable, SynthesisError>
+  where
+    F: FnOnce() -> Result<E::Scalar, SynthesisError>,
+    A: FnOnce() -> AR,
+    AR: Into<String>,
+  {
+    let path = compute_path(&self.current_namespace, &annotation().into());
+    self.inputs.push(path);
+
+    Ok(Variable::new_unchecked(Index::Input(self.inputs.len() - 1)))
+  }
+
+  fn enforce<A, AR, LA, LB, LC>(&mut self, annotation: A, a: LA, b: LB, c: LC)
+  where
+    A: FnOnce() -> AR,
+    AR: Into<String>,
+    LA: FnOnce(LinearCombination<E::Scalar>) -> LinearCombination<E::Scalar>,
+    LB: FnOnce(LinearCombination<E::Scalar>) -> LinearCombination<E::Scalar>,
+    LC: FnOnce(LinearCombination<E::Scalar>) -> LinearCombination<E::Scalar>,
+  {
+    let path = compute_path(&self.current_namespace, &annotation().into());
+    let index = self.constraints.len();
+    self.set_named_obj(path.clone(), NamedObject::Constraint(index));
+
+    let a = a(LinearCombination::zero());
+    let b = b(LinearCombination::zero());
+    let c = c(LinearCombination::zero());
+
+    self.constraints.push((a, b, c, path));
+  }
+
+  fn push_namespace<NR, N>(&mut self, name_fn: N)
+  where
+    NR: Into<String>,
+    N: FnOnce() -> NR,
+  {
+    let name = name_fn().into();
+    let path = compute_path(&self.current_namespace, &name);
+    self.set_named_obj(path, NamedObject::Namespace);
+    self.current_namespace.push(name);
+  }
+
+  fn pop_namespace(&mut self) {
+    assert!(self.current_namespace.pop().is_some());
+  }
+
+  fn get_root(&mut self) -> &mut Self::Root {
+    self
+  }
+}
+
+fn compute_path(ns: &[String], this: &str) -> String {
+  assert!(
+    !this.chars().any(|a| a == '/'),
+    "'/' is not allowed in names"
+  );
+
+  let mut name = String::new();
+
+  let mut needs_separation = false;
+  for ns in ns.iter().chain(Some(this.to_string()).iter()) {
+    if needs_separation {
+      name += "/";
+    }
+
+    name += ns;
+    needs_separation = true;
+  }
+
+  name
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/circuit.rs.html b/docs/src/arecibo/circuit.rs.html new file mode 100644 index 000000000..a1ad70df4 --- /dev/null +++ b/docs/src/arecibo/circuit.rs.html @@ -0,0 +1,1011 @@ +circuit.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+
//! There are two augmented circuits: the primary and the secondary.
+//! Each of them is over a curve in a 2-cycle of elliptic curves.
+//! We have two running instances. Each circuit takes as input 2 hashes: one for each
+//! of the running instances. Each of these hashes is H(params = H(shape, ck), i, z0, zi, U).
+//! Each circuit folds the last invocation of the other into the running instance
+
+use crate::{
+  constants::{NUM_FE_WITHOUT_IO_FOR_CRHF, NUM_HASH_BITS},
+  gadgets::{
+    ecc::AllocatedPoint,
+    r1cs::{AllocatedR1CSInstance, AllocatedRelaxedR1CSInstance},
+    utils::{
+      alloc_num_equals, alloc_scalar_as_base, alloc_zero, conditionally_select_vec, le_bits_to_num,
+    },
+  },
+  r1cs::{R1CSInstance, RelaxedR1CSInstance},
+  traits::{
+    circuit::StepCircuit, commitment::CommitmentTrait, Engine, ROCircuitTrait, ROConstantsCircuit,
+  },
+  Commitment,
+};
+use abomonation_derive::Abomonation;
+use bellpepper::gadgets::Assignment;
+use bellpepper_core::{
+  boolean::{AllocatedBit, Boolean},
+  num::AllocatedNum,
+  ConstraintSystem, SynthesisError,
+};
+use ff::Field;
+use serde::{Deserialize, Serialize};
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
+pub struct NovaAugmentedCircuitParams {
+  limb_width: usize,
+  n_limbs: usize,
+  is_primary_circuit: bool, // A boolean indicating if this is the primary circuit
+}
+
+impl NovaAugmentedCircuitParams {
+  pub const fn new(limb_width: usize, n_limbs: usize, is_primary_circuit: bool) -> Self {
+    Self {
+      limb_width,
+      n_limbs,
+      is_primary_circuit,
+    }
+  }
+}
+
+#[derive(Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct NovaAugmentedCircuitInputs<E: Engine> {
+  params: E::Scalar,
+  i: E::Base,
+  z0: Vec<E::Base>,
+  zi: Option<Vec<E::Base>>,
+  U: Option<RelaxedR1CSInstance<E>>,
+  u: Option<R1CSInstance<E>>,
+  T: Option<Commitment<E>>,
+}
+
+impl<E: Engine> NovaAugmentedCircuitInputs<E> {
+  /// Create new inputs/witness for the verification circuit
+  pub fn new(
+    params: E::Scalar,
+    i: E::Base,
+    z0: Vec<E::Base>,
+    zi: Option<Vec<E::Base>>,
+    U: Option<RelaxedR1CSInstance<E>>,
+    u: Option<R1CSInstance<E>>,
+    T: Option<Commitment<E>>,
+  ) -> Self {
+    Self {
+      params,
+      i,
+      z0,
+      zi,
+      U,
+      u,
+      T,
+    }
+  }
+}
+
+/// The augmented circuit F' in Nova that includes a step circuit F
+/// and the circuit for the verifier in Nova's non-interactive folding scheme
+pub struct NovaAugmentedCircuit<'a, E: Engine, SC: StepCircuit<E::Base>> {
+  params: &'a NovaAugmentedCircuitParams,
+  ro_consts: ROConstantsCircuit<E>,
+  inputs: Option<NovaAugmentedCircuitInputs<E>>,
+  step_circuit: &'a SC, // The function that is applied for each step
+}
+
+impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
+  /// Create a new verification circuit for the input relaxed r1cs instances
+  pub const fn new(
+    params: &'a NovaAugmentedCircuitParams,
+    inputs: Option<NovaAugmentedCircuitInputs<E>>,
+    step_circuit: &'a SC,
+    ro_consts: ROConstantsCircuit<E>,
+  ) -> Self {
+    Self {
+      params,
+      inputs,
+      step_circuit,
+      ro_consts,
+    }
+  }
+
+  /// Allocate all witnesses and return
+  fn alloc_witness<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    mut cs: CS,
+    arity: usize,
+  ) -> Result<
+    (
+      AllocatedNum<E::Base>,
+      AllocatedNum<E::Base>,
+      Vec<AllocatedNum<E::Base>>,
+      Vec<AllocatedNum<E::Base>>,
+      AllocatedRelaxedR1CSInstance<E>,
+      AllocatedR1CSInstance<E>,
+      AllocatedPoint<E>,
+    ),
+    SynthesisError,
+  > {
+    // Allocate the params
+    let params = alloc_scalar_as_base::<E, _>(
+      cs.namespace(|| "params"),
+      self.inputs.as_ref().map(|inputs| inputs.params),
+    )?;
+
+    // Allocate i
+    let i = AllocatedNum::alloc(cs.namespace(|| "i"), || Ok(self.inputs.get()?.i))?;
+
+    // Allocate z0
+    let z_0 = (0..arity)
+      .map(|i| {
+        AllocatedNum::alloc(cs.namespace(|| format!("z0_{i}")), || {
+          Ok(self.inputs.get()?.z0[i])
+        })
+      })
+      .collect::<Result<Vec<AllocatedNum<E::Base>>, _>>()?;
+
+    // Allocate zi. If inputs.zi is not provided (base case) allocate default value 0
+    let zero = vec![E::Base::ZERO; arity];
+    let z_i = (0..arity)
+      .map(|i| {
+        AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || {
+          Ok(self.inputs.get()?.zi.as_ref().unwrap_or(&zero)[i])
+        })
+      })
+      .collect::<Result<Vec<AllocatedNum<E::Base>>, _>>()?;
+
+    // Allocate the running instance
+    let U: AllocatedRelaxedR1CSInstance<E> = AllocatedRelaxedR1CSInstance::alloc(
+      cs.namespace(|| "Allocate U"),
+      self.inputs.as_ref().and_then(|inputs| inputs.U.as_ref()),
+      self.params.limb_width,
+      self.params.n_limbs,
+    )?;
+
+    // Allocate the instance to be folded in
+    let u = AllocatedR1CSInstance::alloc(
+      cs.namespace(|| "allocate instance u to fold"),
+      self.inputs.as_ref().and_then(|inputs| inputs.u.as_ref()),
+    )?;
+
+    // Allocate T
+    let T = AllocatedPoint::alloc(
+      cs.namespace(|| "allocate T"),
+      self
+        .inputs
+        .as_ref()
+        .and_then(|inputs| inputs.T.map(|T| T.to_coordinates())),
+    )?;
+    T.check_on_curve(cs.namespace(|| "check T on curve"))?;
+
+    Ok((params, i, z_0, z_i, U, u, T))
+  }
+
+  /// Synthesizes base case and returns the new relaxed `R1CSInstance`
+  fn synthesize_base_case<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    mut cs: CS,
+    u: AllocatedR1CSInstance<E>,
+  ) -> Result<AllocatedRelaxedR1CSInstance<E>, SynthesisError> {
+    let U_default: AllocatedRelaxedR1CSInstance<E> = if self.params.is_primary_circuit {
+      // The primary circuit just returns the default R1CS instance
+      AllocatedRelaxedR1CSInstance::default(
+        cs.namespace(|| "Allocate U_default"),
+        self.params.limb_width,
+        self.params.n_limbs,
+      )?
+    } else {
+      // The secondary circuit returns the incoming R1CS instance
+      AllocatedRelaxedR1CSInstance::from_r1cs_instance(
+        cs.namespace(|| "Allocate U_default"),
+        u,
+        self.params.limb_width,
+        self.params.n_limbs,
+      )?
+    };
+    Ok(U_default)
+  }
+
+  /// Synthesizes non base case and returns the new relaxed `R1CSInstance`
+  /// And a boolean indicating if all checks pass
+  fn synthesize_non_base_case<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    mut cs: CS,
+    params: &AllocatedNum<E::Base>,
+    i: &AllocatedNum<E::Base>,
+    z_0: &[AllocatedNum<E::Base>],
+    z_i: &[AllocatedNum<E::Base>],
+    U: &AllocatedRelaxedR1CSInstance<E>,
+    u: &AllocatedR1CSInstance<E>,
+    T: &AllocatedPoint<E>,
+    arity: usize,
+  ) -> Result<(AllocatedRelaxedR1CSInstance<E>, AllocatedBit), SynthesisError> {
+    // Check that u.x[0] = Hash(params, U, i, z0, zi)
+    let mut ro = E::ROCircuit::new(
+      self.ro_consts.clone(),
+      NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * arity,
+    );
+    ro.absorb(params);
+    ro.absorb(i);
+    for e in z_0 {
+      ro.absorb(e);
+    }
+    for e in z_i {
+      ro.absorb(e);
+    }
+    U.absorb_in_ro(cs.namespace(|| "absorb U"), &mut ro)?;
+
+    let hash_bits = ro.squeeze(cs.namespace(|| "Input hash"), NUM_HASH_BITS)?;
+    let hash = le_bits_to_num(cs.namespace(|| "bits to hash"), &hash_bits)?;
+    let check_pass = alloc_num_equals(
+      cs.namespace(|| "check consistency of u.X[0] with H(params, U, i, z0, zi)"),
+      &u.X0,
+      &hash,
+    )?;
+
+    // Run NIFS Verifier
+    let U_fold = U.fold_with_r1cs(
+      cs.namespace(|| "compute fold of U and u"),
+      params,
+      u,
+      T,
+      self.ro_consts.clone(),
+      self.params.limb_width,
+      self.params.n_limbs,
+    )?;
+
+    Ok((U_fold, check_pass))
+  }
+}
+
+impl<'a, E: Engine, SC: StepCircuit<E::Base>> NovaAugmentedCircuit<'a, E, SC> {
+  /// synthesize circuit giving constraint system
+  pub fn synthesize<CS: ConstraintSystem<<E as Engine>::Base>>(
+    self,
+    cs: &mut CS,
+  ) -> Result<Vec<AllocatedNum<E::Base>>, SynthesisError> {
+    let arity = self.step_circuit.arity();
+
+    // Allocate all witnesses
+    let (params, i, z_0, z_i, U, u, T) =
+      self.alloc_witness(cs.namespace(|| "allocate the circuit witness"), arity)?;
+
+    // Compute variable indicating if this is the base case
+    let zero = alloc_zero(cs.namespace(|| "zero"));
+    let is_base_case = alloc_num_equals(cs.namespace(|| "Check if base case"), &i.clone(), &zero)?;
+
+    // Synthesize the circuit for the base case and get the new running instance
+    let Unew_base = self.synthesize_base_case(cs.namespace(|| "base case"), u.clone())?;
+
+    // Synthesize the circuit for the non-base case and get the new running
+    // instance along with a boolean indicating if all checks have passed
+    let (Unew_non_base, check_non_base_pass) = self.synthesize_non_base_case(
+      cs.namespace(|| "synthesize non base case"),
+      &params,
+      &i,
+      &z_0,
+      &z_i,
+      &U,
+      &u,
+      &T,
+      arity,
+    )?;
+
+    // Either check_non_base_pass=true or we are in the base case
+    let should_be_false = AllocatedBit::nor(
+      cs.namespace(|| "check_non_base_pass nor base_case"),
+      &check_non_base_pass,
+      &is_base_case,
+    )?;
+    cs.enforce(
+      || "check_non_base_pass nor base_case = false",
+      |lc| lc + should_be_false.get_variable(),
+      |lc| lc + CS::one(),
+      |lc| lc,
+    );
+
+    // Compute the U_new
+    let Unew = Unew_base.conditionally_select(
+      cs.namespace(|| "compute U_new"),
+      &Unew_non_base,
+      &Boolean::from(is_base_case.clone()),
+    )?;
+
+    // Compute i + 1
+    let i_new = AllocatedNum::alloc(cs.namespace(|| "i + 1"), || {
+      Ok(*i.get_value().get()? + E::Base::ONE)
+    })?;
+    cs.enforce(
+      || "check i + 1",
+      |lc| lc,
+      |lc| lc,
+      |lc| lc + i_new.get_variable() - CS::one() - i.get_variable(),
+    );
+
+    // Compute z_{i+1}
+    let z_input = conditionally_select_vec(
+      cs.namespace(|| "select input to F"),
+      &z_0,
+      &z_i,
+      &Boolean::from(is_base_case),
+    )?;
+
+    let z_next = self
+      .step_circuit
+      .synthesize(&mut cs.namespace(|| "F"), &z_input)?;
+
+    if z_next.len() != arity {
+      return Err(SynthesisError::IncompatibleLengthVector(
+        "z_next".to_string(),
+      ));
+    }
+
+    // Compute the new hash H(params, Unew, i+1, z0, z_{i+1})
+    let mut ro = E::ROCircuit::new(self.ro_consts, NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * arity);
+    ro.absorb(&params);
+    ro.absorb(&i_new);
+    for e in &z_0 {
+      ro.absorb(e);
+    }
+    for e in &z_next {
+      ro.absorb(e);
+    }
+    Unew.absorb_in_ro(cs.namespace(|| "absorb U_new"), &mut ro)?;
+    let hash_bits = ro.squeeze(cs.namespace(|| "output hash bits"), NUM_HASH_BITS)?;
+    let hash = le_bits_to_num(cs.namespace(|| "convert hash to num"), &hash_bits)?;
+
+    // Outputs the computed hash and u.X[1] that corresponds to the hash of the other circuit
+    u.X1
+      .inputize(cs.namespace(|| "Output unmodified hash of the other circuit"))?;
+    hash.inputize(cs.namespace(|| "output new hash of this circuit"))?;
+
+    Ok(z_next)
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::{
+    bellpepper::{
+      r1cs::{NovaShape, NovaWitness},
+      solver::SatisfyingAssignment,
+      test_shape_cs::TestShapeCS,
+    },
+    constants::{BN_LIMB_WIDTH, BN_N_LIMBS},
+    gadgets::utils::scalar_as_base,
+    provider::{
+      poseidon::PoseidonConstantsCircuit,
+      {Bn256Engine, GrumpkinEngine}, {PallasEngine, VestaEngine},
+      {Secp256k1Engine, Secq256k1Engine},
+    },
+    traits::{circuit::TrivialCircuit, snark::default_ck_hint},
+  };
+  use expect_test::{expect, Expect};
+
+  // In the following we use 1 to refer to the primary, and 2 to refer to the secondary circuit
+  fn test_recursive_circuit_with<E1, E2>(
+    primary_params: &NovaAugmentedCircuitParams,
+    secondary_params: &NovaAugmentedCircuitParams,
+    ro_consts1: ROConstantsCircuit<E2>,
+    ro_consts2: ROConstantsCircuit<E1>,
+    expected_num_constraints_primary: &Expect,
+    expected_num_constraints_secondary: &Expect,
+  ) where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    let tc1 = TrivialCircuit::default();
+    // Initialize the shape and ck for the primary
+    let circuit1: NovaAugmentedCircuit<'_, E2, TrivialCircuit<<E2 as Engine>::Base>> =
+      NovaAugmentedCircuit::new(primary_params, None, &tc1, ro_consts1.clone());
+    let mut cs: TestShapeCS<E1> = TestShapeCS::new();
+    let _ = circuit1.synthesize(&mut cs);
+    let (shape1, ck1) = cs.r1cs_shape_and_key(&*default_ck_hint());
+
+    expected_num_constraints_primary.assert_eq(&cs.num_constraints().to_string());
+
+    let tc2 = TrivialCircuit::default();
+    // Initialize the shape and ck for the secondary
+    let circuit2: NovaAugmentedCircuit<'_, E1, TrivialCircuit<<E1 as Engine>::Base>> =
+      NovaAugmentedCircuit::new(secondary_params, None, &tc2, ro_consts2.clone());
+    let mut cs: TestShapeCS<E2> = TestShapeCS::new();
+    let _ = circuit2.synthesize(&mut cs);
+    let (shape2, ck2) = cs.r1cs_shape_and_key(&*default_ck_hint());
+
+    expected_num_constraints_secondary.assert_eq(&cs.num_constraints().to_string());
+
+    // Execute the base case for the primary
+    let zero1 = <<E2 as Engine>::Base as Field>::ZERO;
+    let mut cs1 = SatisfyingAssignment::<E1>::new();
+    let inputs1: NovaAugmentedCircuitInputs<E2> = NovaAugmentedCircuitInputs::new(
+      scalar_as_base::<E1>(zero1), // pass zero for testing
+      zero1,
+      vec![zero1],
+      None,
+      None,
+      None,
+      None,
+    );
+    let circuit1: NovaAugmentedCircuit<'_, E2, TrivialCircuit<<E2 as Engine>::Base>> =
+      NovaAugmentedCircuit::new(primary_params, Some(inputs1), &tc1, ro_consts1);
+    let _ = circuit1.synthesize(&mut cs1);
+    let (inst1, witness1) = cs1.r1cs_instance_and_witness(&shape1, &ck1).unwrap();
+    // Make sure that this is satisfiable
+    assert!(shape1.is_sat(&ck1, &inst1, &witness1).is_ok());
+
+    // Execute the base case for the secondary
+    let zero2 = <<E1 as Engine>::Base as Field>::ZERO;
+    let mut cs2 = SatisfyingAssignment::<E2>::new();
+    let inputs2: NovaAugmentedCircuitInputs<E1> = NovaAugmentedCircuitInputs::new(
+      scalar_as_base::<E2>(zero2), // pass zero for testing
+      zero2,
+      vec![zero2],
+      None,
+      None,
+      Some(inst1),
+      None,
+    );
+    let circuit2: NovaAugmentedCircuit<'_, E1, TrivialCircuit<<E1 as Engine>::Base>> =
+      NovaAugmentedCircuit::new(secondary_params, Some(inputs2), &tc2, ro_consts2);
+    let _ = circuit2.synthesize(&mut cs2);
+    let (inst2, witness2) = cs2.r1cs_instance_and_witness(&shape2, &ck2).unwrap();
+    // Make sure that it is satisfiable
+    assert!(shape2.is_sat(&ck2, &inst2, &witness2).is_ok());
+  }
+
+  #[test]
+  fn test_recursive_circuit_pasta() {
+    // this test checks against values that must be replicated in benchmarks if changed here
+    let params1 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+    let params2 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
+    let ro_consts1: ROConstantsCircuit<VestaEngine> = PoseidonConstantsCircuit::default();
+    let ro_consts2: ROConstantsCircuit<PallasEngine> = PoseidonConstantsCircuit::default();
+
+    test_recursive_circuit_with::<PallasEngine, VestaEngine>(
+      &params1,
+      &params2,
+      ro_consts1,
+      ro_consts2,
+      &expect!["9825"],
+      &expect!["10357"],
+    );
+  }
+
+  #[test]
+  fn test_recursive_circuit_grumpkin() {
+    let params1 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+    let params2 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
+    let ro_consts1: ROConstantsCircuit<GrumpkinEngine> = PoseidonConstantsCircuit::default();
+    let ro_consts2: ROConstantsCircuit<Bn256Engine> = PoseidonConstantsCircuit::default();
+
+    test_recursive_circuit_with::<Bn256Engine, GrumpkinEngine>(
+      &params1,
+      &params2,
+      ro_consts1,
+      ro_consts2,
+      &expect!["9993"],
+      &expect!["10546"],
+    );
+  }
+
+  #[test]
+  fn test_recursive_circuit_secp() {
+    let params1 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+    let params2 = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
+    let ro_consts1: ROConstantsCircuit<Secq256k1Engine> = PoseidonConstantsCircuit::default();
+    let ro_consts2: ROConstantsCircuit<Secp256k1Engine> = PoseidonConstantsCircuit::default();
+
+    test_recursive_circuit_with::<Secp256k1Engine, Secq256k1Engine>(
+      &params1,
+      &params2,
+      ro_consts1,
+      ro_consts2,
+      &expect!["10272"],
+      &expect!["10969"],
+    );
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/constants.rs.html b/docs/src/arecibo/constants.rs.html new file mode 100644 index 000000000..538caa573 --- /dev/null +++ b/docs/src/arecibo/constants.rs.html @@ -0,0 +1,21 @@ +constants.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+
//! Global Nova constants
+
+pub(crate) const NUM_CHALLENGE_BITS: usize = 128;
+pub(crate) const BN_LIMB_WIDTH: usize = 64;
+pub(crate) const BN_N_LIMBS: usize = 4;
+pub(crate) const NUM_FE_WITHOUT_IO_FOR_CRHF: usize = 17;
+pub(crate) const NUM_FE_FOR_RO: usize = 24;
+
+/// Bit size of Nova field element hashes
+pub const NUM_HASH_BITS: usize = 250;
+
\ No newline at end of file diff --git a/docs/src/arecibo/digest.rs.html b/docs/src/arecibo/digest.rs.html new file mode 100644 index 000000000..035309c6c --- /dev/null +++ b/docs/src/arecibo/digest.rs.html @@ -0,0 +1,321 @@ +digest.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+
use bincode::Options;
+use ff::PrimeField;
+use serde::Serialize;
+use sha3::{Digest, Sha3_256};
+use std::io;
+use std::marker::PhantomData;
+
+use crate::constants::NUM_HASH_BITS;
+
+/// Trait for components with potentially discrete digests to be included in their container's digest.
+pub trait Digestible {
+  /// Write the byte representation of Self in a byte buffer
+  fn write_bytes<W: Sized + io::Write>(&self, byte_sink: &mut W) -> Result<(), io::Error>;
+}
+
+/// Marker trait to be implemented for types that implement `Digestible` and `Serialize`.
+/// Their instances will be serialized to bytes then digested.
+pub trait SimpleDigestible: Serialize {}
+
+impl<T: SimpleDigestible> Digestible for T {
+  fn write_bytes<W: Sized + io::Write>(&self, byte_sink: &mut W) -> Result<(), io::Error> {
+    let config = bincode::DefaultOptions::new()
+      .with_little_endian()
+      .with_fixint_encoding();
+    // Note: bincode recursively length-prefixes every field!
+    config
+      .serialize_into(byte_sink, self)
+      .map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
+  }
+}
+
+pub struct DigestComputer<'a, F, T> {
+  inner: &'a T,
+  _phantom: PhantomData<F>,
+}
+
+impl<'a, F: PrimeField, T: Digestible> DigestComputer<'a, F, T> {
+  fn hasher() -> Sha3_256 {
+    Sha3_256::new()
+  }
+
+  fn map_to_field(digest: &[u8]) -> F {
+    let bv = (0..NUM_HASH_BITS).map(|i| {
+      let (byte_pos, bit_pos) = (i / 8, i % 8);
+      let bit = (digest[byte_pos] >> bit_pos) & 1;
+      bit == 1
+    });
+
+    // turn the bit vector into a scalar
+    let mut digest = F::ZERO;
+    let mut coeff = F::ONE;
+    for bit in bv {
+      if bit {
+        digest += coeff;
+      }
+      coeff += coeff;
+    }
+    digest
+  }
+
+  /// Create a new `DigestComputer`
+  pub fn new(inner: &'a T) -> Self {
+    DigestComputer {
+      inner,
+      _phantom: PhantomData,
+    }
+  }
+
+  /// Compute the digest of a `Digestible` instance.
+  pub fn digest(&self) -> Result<F, io::Error> {
+    let mut hasher = Self::hasher();
+    self.inner.write_bytes(&mut hasher)?;
+    let bytes: [u8; 32] = hasher.finalize().into();
+    Ok(Self::map_to_field(&bytes))
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::{DigestComputer, SimpleDigestible};
+  use crate::{provider::PallasEngine, traits::Engine};
+  use ff::Field;
+  use once_cell::sync::OnceCell;
+  use serde::{Deserialize, Serialize};
+
+  type E = PallasEngine;
+
+  #[derive(Serialize, Deserialize)]
+  struct S<E: Engine> {
+    i: usize,
+    #[serde(skip, default = "OnceCell::new")]
+    digest: OnceCell<E::Scalar>,
+  }
+
+  impl<E: Engine> SimpleDigestible for S<E> {}
+
+  impl<E: Engine> S<E> {
+    fn new(i: usize) -> Self {
+      Self {
+        i,
+        digest: OnceCell::new(),
+      }
+    }
+
+    fn digest(&self) -> E::Scalar {
+      self
+        .digest
+        .get_or_try_init(|| DigestComputer::new(self).digest())
+        .cloned()
+        .unwrap()
+    }
+  }
+
+  #[test]
+  fn test_digest_field_not_ingested_in_computation() {
+    let s1 = S::<E>::new(42);
+
+    // let's set up a struct with a weird digest field to make sure the digest computation does not depend of it
+    let oc = OnceCell::new();
+    oc.set(<E as Engine>::Scalar::ONE).unwrap();
+
+    let s2: S<E> = S { i: 42, digest: oc };
+
+    assert_eq!(
+      DigestComputer::<<E as Engine>::Scalar, _>::new(&s1)
+        .digest()
+        .unwrap(),
+      DigestComputer::<<E as Engine>::Scalar, _>::new(&s2)
+        .digest()
+        .unwrap()
+    );
+
+    // note: because of the semantics of `OnceCell::get_or_try_init`, the above
+    // equality will not result in `s1.digest() == s2.digest`
+    assert_ne!(
+      s2.digest(),
+      DigestComputer::<<E as Engine>::Scalar, _>::new(&s2)
+        .digest()
+        .unwrap()
+    );
+  }
+
+  #[test]
+  fn test_digest_impervious_to_serialization() {
+    let good_s = S::<E>::new(42);
+
+    // let's set up a struct with a weird digest field to confuse deserializers
+    let oc = OnceCell::new();
+    oc.set(<E as Engine>::Scalar::ONE).unwrap();
+
+    let bad_s: S<E> = S { i: 42, digest: oc };
+    // this justifies the adjective "bad"
+    assert_ne!(good_s.digest(), bad_s.digest());
+
+    let naughty_bytes = bincode::serialize(&bad_s).unwrap();
+
+    let retrieved_s: S<E> = bincode::deserialize(&naughty_bytes).unwrap();
+    assert_eq!(good_s.digest(), retrieved_s.digest())
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/errors.rs.html b/docs/src/arecibo/errors.rs.html new file mode 100644 index 000000000..a9349a0b9 --- /dev/null +++ b/docs/src/arecibo/errors.rs.html @@ -0,0 +1,185 @@ +errors.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+
//! This module defines errors returned by the library.
+use core::fmt::Debug;
+use thiserror::Error;
+
+/// Errors returned by Nova
+#[derive(Clone, Debug, Eq, PartialEq, Error)]
+#[non_exhaustive]
+pub enum NovaError {
+  /// returned if the supplied row or col in (row,col,val) tuple is out of range
+  #[error("InvalidIndex")]
+  InvalidIndex,
+  /// returned if the supplied input is not even-sized
+  #[error("OddInputLength")]
+  OddInputLength,
+  /// returned if the supplied input is not of the right length
+  #[error("InvalidInputLength")]
+  InvalidInputLength,
+  /// returned if the supplied witness is not of the right length
+  #[error("InvalidWitnessLength")]
+  InvalidWitnessLength,
+  /// returned if the supplied witness is not a satisfying witness to a given shape and instance
+  #[error("UnSat")]
+  UnSat,
+  /// returned if the supplied witness is not a satisfying witness to a given shape and instance, with error constraint index
+  #[error("UnSatIndex")]
+  UnSatIndex(usize),
+  /// returned when the supplied compressed commitment cannot be decompressed
+  #[error("DecompressionError")]
+  DecompressionError,
+  /// returned if proof verification fails
+  #[error("ProofVerifyError")]
+  ProofVerifyError,
+  /// returned if the provided commitment key is not of sufficient length
+  #[error("InvalidCommitmentKeyLength")]
+  InvalidCommitmentKeyLength,
+  /// returned if the provided number of steps is zero
+  #[error("InvalidNumSteps")]
+  InvalidNumSteps,
+  /// returned if there is an error in the proof/verification of a PCS
+  #[error("PCSError")]
+  PCSError(#[from] PCSError),
+  /// returned when an invalid sum-check proof is provided
+  #[error("InvalidSumcheckProof")]
+  InvalidSumcheckProof,
+  /// returned when the initial input to an incremental computation differs from a previously declared arity
+  #[error("InvalidInitialInputLength")]
+  InvalidInitialInputLength,
+  /// returned when the step execution produces an output whose length differs from a previously declared arity
+  #[error("InvalidStepOutputLength")]
+  InvalidStepOutputLength,
+  /// returned when the transcript engine encounters an overflow of the round number
+  #[error("InternalTranscriptError")]
+  InternalTranscriptError,
+  /// returned when the multiset check fails
+  #[error("InvalidMultisetProof")]
+  InvalidMultisetProof,
+  /// returned when the product proof check fails
+  #[error("InvalidProductProof")]
+  InvalidProductProof,
+  /// returned when the consistency with public IO and assignment used fails
+  #[error("IncorrectWitness")]
+  IncorrectWitness,
+  /// return when error during synthesis
+  #[error("SynthesisError: {0}")]
+  SynthesisError(String),
+  /// returned when there is an error creating a digest
+  #[error("DigestError")]
+  DigestError,
+  /// returned when the prover cannot prove the provided statement due to completeness error
+  #[error("InternalError")]
+  InternalError,
+}
+
+/// Errors specific to the Polynomial commitment scheme
+#[derive(Clone, Debug, Eq, PartialEq, Error)]
+pub enum PCSError {
+  /// returned when an invalid inner product argument is provided
+  #[error("InvalidIPA")]
+  InvalidIPA,
+  /// returned when there is a Zeromorph error
+  #[error("ZMError")]
+  ZMError,
+  /// returned when a length check fails in a PCS
+  #[error("LengthError")]
+  LengthError,
+}
+
+impl From<bellpepper_core::SynthesisError> for NovaError {
+  fn from(err: bellpepper_core::SynthesisError) -> Self {
+    Self::SynthesisError(err.to_string())
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/gadgets/ecc.rs.html b/docs/src/arecibo/gadgets/ecc.rs.html new file mode 100644 index 000000000..4ebb2ebd9 --- /dev/null +++ b/docs/src/arecibo/gadgets/ecc.rs.html @@ -0,0 +1,2379 @@ +ecc.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+
//! This module implements various elliptic curve gadgets
+#![allow(non_snake_case)]
+use crate::{
+  gadgets::utils::{
+    alloc_num_equals, alloc_one, alloc_zero, conditionally_select, conditionally_select2,
+    select_num_or_one, select_num_or_zero, select_num_or_zero2, select_one_or_diff2,
+    select_one_or_num2, select_zero_or_num2,
+  },
+  traits::{Engine, Group},
+};
+use bellpepper::gadgets::Assignment;
+use bellpepper_core::{
+  boolean::{AllocatedBit, Boolean},
+  num::AllocatedNum,
+  ConstraintSystem, SynthesisError,
+};
+use ff::{Field, PrimeField};
+
+/// `AllocatedPoint` provides an elliptic curve abstraction inside a circuit.
+#[derive(Clone)]
+pub struct AllocatedPoint<E: Engine> {
+  pub(crate) x: AllocatedNum<E::Base>,
+  pub(crate) y: AllocatedNum<E::Base>,
+  pub(crate) is_infinity: AllocatedNum<E::Base>,
+}
+
+impl<E> AllocatedPoint<E>
+where
+  E: Engine,
+{
+  /// Allocates a new point on the curve using coordinates provided by `coords`.
+  /// If coords = None, it allocates the default infinity point
+  pub fn alloc<CS: ConstraintSystem<E::Base>>(
+    mut cs: CS,
+    coords: Option<(E::Base, E::Base, bool)>,
+  ) -> Result<Self, SynthesisError> {
+    let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
+      Ok(coords.map_or(E::Base::ZERO, |c| c.0))
+    })?;
+    let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
+      Ok(coords.map_or(E::Base::ZERO, |c| c.1))
+    })?;
+    let is_infinity = AllocatedNum::alloc(cs.namespace(|| "is_infinity"), || {
+      Ok(if coords.map_or(true, |c| c.2) {
+        E::Base::ONE
+      } else {
+        E::Base::ZERO
+      })
+    })?;
+    cs.enforce(
+      || "is_infinity is bit",
+      |lc| lc + is_infinity.get_variable(),
+      |lc| lc + CS::one() - is_infinity.get_variable(),
+      |lc| lc,
+    );
+
+    Ok(Self { x, y, is_infinity })
+  }
+
+  /// checks if `self` is on the curve or if it is infinity
+  pub fn check_on_curve<CS>(&self, mut cs: CS) -> Result<(), SynthesisError>
+  where
+    CS: ConstraintSystem<E::Base>,
+  {
+    // check that (x,y) is on the curve if it is not infinity
+    // we will check that (1- is_infinity) * y^2 = (1-is_infinity) * (x^3 + Ax + B)
+    // note that is_infinity is already restricted to be in the set {0, 1}
+    let y_square = self.y.square(cs.namespace(|| "y_square"))?;
+    let x_square = self.x.square(cs.namespace(|| "x_square"))?;
+    let x_cube = self.x.mul(cs.namespace(|| "x_cube"), &x_square)?;
+
+    let rhs = AllocatedNum::alloc(cs.namespace(|| "rhs"), || {
+      if *self.is_infinity.get_value().get()? == E::Base::ONE {
+        Ok(E::Base::ZERO)
+      } else {
+        Ok(
+          *x_cube.get_value().get()?
+            + *self.x.get_value().get()? * E::GE::group_params().0
+            + E::GE::group_params().1,
+        )
+      }
+    })?;
+
+    cs.enforce(
+      || "rhs = (1-is_infinity) * (x^3 + Ax + B)",
+      |lc| {
+        lc + x_cube.get_variable()
+          + (E::GE::group_params().0, self.x.get_variable())
+          + (E::GE::group_params().1, CS::one())
+      },
+      |lc| lc + CS::one() - self.is_infinity.get_variable(),
+      |lc| lc + rhs.get_variable(),
+    );
+
+    // check that (1-infinity) * y_square = rhs
+    cs.enforce(
+      || "check that y_square * (1 - is_infinity) = rhs",
+      |lc| lc + y_square.get_variable(),
+      |lc| lc + CS::one() - self.is_infinity.get_variable(),
+      |lc| lc + rhs.get_variable(),
+    );
+
+    Ok(())
+  }
+
+  /// Allocates a default point on the curve, set to the identity point.
+  pub fn default<CS: ConstraintSystem<E::Base>>(mut cs: CS) -> Result<Self, SynthesisError> {
+    let zero = alloc_zero(cs.namespace(|| "zero"));
+    let one = alloc_one(cs.namespace(|| "one"));
+
+    Ok(Self {
+      x: zero.clone(),
+      y: zero,
+      is_infinity: one,
+    })
+  }
+
+  /// Returns coordinates associated with the point.
+  pub const fn get_coordinates(
+    &self,
+  ) -> (
+    &AllocatedNum<E::Base>,
+    &AllocatedNum<E::Base>,
+    &AllocatedNum<E::Base>,
+  ) {
+    (&self.x, &self.y, &self.is_infinity)
+  }
+
+  /// Negates the provided point
+  pub fn negate<CS: ConstraintSystem<E::Base>>(&self, mut cs: CS) -> Result<Self, SynthesisError> {
+    let y = AllocatedNum::alloc(cs.namespace(|| "y"), || Ok(-*self.y.get_value().get()?))?;
+
+    cs.enforce(
+      || "check y = - self.y",
+      |lc| lc + self.y.get_variable(),
+      |lc| lc + CS::one(),
+      |lc| lc - y.get_variable(),
+    );
+
+    Ok(Self {
+      x: self.x.clone(),
+      y,
+      is_infinity: self.is_infinity.clone(),
+    })
+  }
+
+  /// Add two points (may be equal)
+  pub fn add<CS: ConstraintSystem<E::Base>>(
+    &self,
+    mut cs: CS,
+    other: &Self,
+  ) -> Result<Self, SynthesisError> {
+    // Compute boolean equal indicating if self = other
+
+    let equal_x = alloc_num_equals(
+      cs.namespace(|| "check self.x == other.x"),
+      &self.x,
+      &other.x,
+    )?;
+
+    let equal_y = alloc_num_equals(
+      cs.namespace(|| "check self.y == other.y"),
+      &self.y,
+      &other.y,
+    )?;
+
+    // Compute the result of the addition and the result of double self
+    let result_from_add = self.add_internal(cs.namespace(|| "add internal"), other, &equal_x)?;
+    let result_from_double = self.double(cs.namespace(|| "double"))?;
+
+    // Output:
+    // If (self == other) {
+    //  return double(self)
+    // }else {
+    //  if (self.x == other.x){
+    //      return infinity [negation]
+    //  } else {
+    //      return add(self, other)
+    //  }
+    // }
+    let result_for_equal_x = Self::select_point_or_infinity(
+      cs.namespace(|| "equal_y ? result_from_double : infinity"),
+      &result_from_double,
+      &Boolean::from(equal_y),
+    )?;
+
+    Self::conditionally_select(
+      cs.namespace(|| "equal ? result_from_double : result_from_add"),
+      &result_for_equal_x,
+      &result_from_add,
+      &Boolean::from(equal_x),
+    )
+  }
+
+  /// Adds other point to this point and returns the result. Assumes that the two points are
+  /// different and that both `other.is_infinity` and `this.is_infinty` are bits
+  pub fn add_internal<CS: ConstraintSystem<E::Base>>(
+    &self,
+    mut cs: CS,
+    other: &Self,
+    equal_x: &AllocatedBit,
+  ) -> Result<Self, SynthesisError> {
+    //************************************************************************/
+    // lambda = (other.y - self.y) * (other.x - self.x).invert().unwrap();
+    //************************************************************************/
+    // First compute (other.x - self.x).inverse()
+    // If either self or other are the infinity point or self.x = other.x  then compute bogus values
+    // Specifically,
+    // x_diff = self != inf && other != inf && self.x == other.x ? (other.x - self.x) : 1
+
+    // Compute self.is_infinity OR other.is_infinity =
+    // NOT(NOT(self.is_ifninity) AND NOT(other.is_infinity))
+    let at_least_one_inf = AllocatedNum::alloc(cs.namespace(|| "at least one inf"), || {
+      Ok(
+        E::Base::ONE
+          - (E::Base::ONE - *self.is_infinity.get_value().get()?)
+            * (E::Base::ONE - *other.is_infinity.get_value().get()?),
+      )
+    })?;
+    cs.enforce(
+      || "1 - at least one inf = (1-self.is_infinity) * (1-other.is_infinity)",
+      |lc| lc + CS::one() - self.is_infinity.get_variable(),
+      |lc| lc + CS::one() - other.is_infinity.get_variable(),
+      |lc| lc + CS::one() - at_least_one_inf.get_variable(),
+    );
+
+    // Now compute x_diff_is_actual = at_least_one_inf OR equal_x
+    let x_diff_is_actual =
+      AllocatedNum::alloc(cs.namespace(|| "allocate x_diff_is_actual"), || {
+        Ok(if *equal_x.get_value().get()? {
+          E::Base::ONE
+        } else {
+          *at_least_one_inf.get_value().get()?
+        })
+      })?;
+    cs.enforce(
+      || "1 - x_diff_is_actual = (1-equal_x) * (1-at_least_one_inf)",
+      |lc| lc + CS::one() - at_least_one_inf.get_variable(),
+      |lc| lc + CS::one() - equal_x.get_variable(),
+      |lc| lc + CS::one() - x_diff_is_actual.get_variable(),
+    );
+
+    // x_diff = 1 if either self.is_infinity or other.is_infinity or self.x = other.x else self.x -
+    // other.x
+    let x_diff = select_one_or_diff2(
+      cs.namespace(|| "Compute x_diff"),
+      &other.x,
+      &self.x,
+      &x_diff_is_actual,
+    )?;
+
+    let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
+      let x_diff_inv = if *x_diff_is_actual.get_value().get()? == E::Base::ONE {
+        // Set to default
+        E::Base::ONE
+      } else {
+        // Set to the actual inverse
+        (*other.x.get_value().get()? - *self.x.get_value().get()?)
+          .invert()
+          .unwrap()
+      };
+
+      Ok((*other.y.get_value().get()? - *self.y.get_value().get()?) * x_diff_inv)
+    })?;
+    cs.enforce(
+      || "Check that lambda is correct",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + x_diff.get_variable(),
+      |lc| lc + other.y.get_variable() - self.y.get_variable(),
+    );
+
+    //************************************************************************/
+    // x = lambda * lambda - self.x - other.x;
+    //************************************************************************/
+    let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
+      Ok(
+        *lambda.get_value().get()? * lambda.get_value().get()?
+          - *self.x.get_value().get()?
+          - *other.x.get_value().get()?,
+      )
+    })?;
+    cs.enforce(
+      || "check that x is correct",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + x.get_variable() + self.x.get_variable() + other.x.get_variable(),
+    );
+
+    //************************************************************************/
+    // y = lambda * (self.x - x) - self.y;
+    //************************************************************************/
+    let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
+      Ok(
+        *lambda.get_value().get()? * (*self.x.get_value().get()? - *x.get_value().get()?)
+          - *self.y.get_value().get()?,
+      )
+    })?;
+
+    cs.enforce(
+      || "Check that y is correct",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + self.x.get_variable() - x.get_variable(),
+      |lc| lc + y.get_variable() + self.y.get_variable(),
+    );
+
+    //************************************************************************/
+    // We only return the computed x, y if neither of the points is infinity and self.x != other.y
+    // if self.is_infinity return other.clone()
+    // elif other.is_infinity return self.clone()
+    // elif self.x == other.x return infinity
+    // Otherwise return the computed points.
+    //************************************************************************/
+    // Now compute the output x
+
+    let x1 = conditionally_select2(
+      cs.namespace(|| "x1 = other.is_infinity ? self.x : x"),
+      &self.x,
+      &x,
+      &other.is_infinity,
+    )?;
+
+    let x = conditionally_select2(
+      cs.namespace(|| "x = self.is_infinity ? other.x : x1"),
+      &other.x,
+      &x1,
+      &self.is_infinity,
+    )?;
+
+    let y1 = conditionally_select2(
+      cs.namespace(|| "y1 = other.is_infinity ? self.y : y"),
+      &self.y,
+      &y,
+      &other.is_infinity,
+    )?;
+
+    let y = conditionally_select2(
+      cs.namespace(|| "y = self.is_infinity ? other.y : y1"),
+      &other.y,
+      &y1,
+      &self.is_infinity,
+    )?;
+
+    let is_infinity1 = select_num_or_zero2(
+      cs.namespace(|| "is_infinity1 = other.is_infinity ? self.is_infinity : 0"),
+      &self.is_infinity,
+      &other.is_infinity,
+    )?;
+
+    let is_infinity = conditionally_select2(
+      cs.namespace(|| "is_infinity = self.is_infinity ? other.is_infinity : is_infinity1"),
+      &other.is_infinity,
+      &is_infinity1,
+      &self.is_infinity,
+    )?;
+
+    Ok(Self { x, y, is_infinity })
+  }
+
+  /// Doubles the supplied point.
+  pub fn double<CS: ConstraintSystem<E::Base>>(&self, mut cs: CS) -> Result<Self, SynthesisError> {
+    //*************************************************************/
+    // lambda = (E::Base::from(3) * self.x * self.x + E::GE::A())
+    //  * (E::Base::from(2)) * self.y).invert().unwrap();
+    /*************************************************************/
+
+    // Compute tmp = (E::Base::ONE + E::Base::ONE)* self.y ? self != inf : 1
+    let tmp_actual = AllocatedNum::alloc(cs.namespace(|| "tmp_actual"), || {
+      Ok(*self.y.get_value().get()? + *self.y.get_value().get()?)
+    })?;
+    cs.enforce(
+      || "check tmp_actual",
+      |lc| lc + CS::one() + CS::one(),
+      |lc| lc + self.y.get_variable(),
+      |lc| lc + tmp_actual.get_variable(),
+    );
+
+    let tmp = select_one_or_num2(cs.namespace(|| "tmp"), &tmp_actual, &self.is_infinity)?;
+
+    // Now compute lambda as (E::Base::from(3) * self.x * self.x + E::GE::A()) * tmp_inv
+
+    let prod_1 = AllocatedNum::alloc(cs.namespace(|| "alloc prod 1"), || {
+      Ok(E::Base::from(3) * self.x.get_value().get()? * self.x.get_value().get()?)
+    })?;
+    cs.enforce(
+      || "Check prod 1",
+      |lc| lc + (E::Base::from(3), self.x.get_variable()),
+      |lc| lc + self.x.get_variable(),
+      |lc| lc + prod_1.get_variable(),
+    );
+
+    let lambda = AllocatedNum::alloc(cs.namespace(|| "alloc lambda"), || {
+      let tmp_inv = if *self.is_infinity.get_value().get()? == E::Base::ONE {
+        // Return default value 1
+        E::Base::ONE
+      } else {
+        // Return the actual inverse
+        (*tmp.get_value().get()?).invert().unwrap()
+      };
+
+      Ok(tmp_inv * (*prod_1.get_value().get()? + E::GE::group_params().0))
+    })?;
+
+    cs.enforce(
+      || "Check lambda",
+      |lc| lc + tmp.get_variable(),
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + prod_1.get_variable() + (E::GE::group_params().0, CS::one()),
+    );
+
+    /*************************************************************/
+    //          x = lambda * lambda - self.x - self.x;
+    /*************************************************************/
+
+    let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
+      Ok(
+        ((*lambda.get_value().get()?) * (*lambda.get_value().get()?))
+          - *self.x.get_value().get()?
+          - self.x.get_value().get()?,
+      )
+    })?;
+    cs.enforce(
+      || "Check x",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + x.get_variable() + self.x.get_variable() + self.x.get_variable(),
+    );
+
+    /*************************************************************/
+    //        y = lambda * (self.x - x) - self.y;
+    /*************************************************************/
+
+    let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
+      Ok(
+        (*lambda.get_value().get()?) * (*self.x.get_value().get()? - x.get_value().get()?)
+          - self.y.get_value().get()?,
+      )
+    })?;
+    cs.enforce(
+      || "Check y",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + self.x.get_variable() - x.get_variable(),
+      |lc| lc + y.get_variable() + self.y.get_variable(),
+    );
+
+    /*************************************************************/
+    // Only return the computed x and y if the point is not infinity
+    /*************************************************************/
+
+    // x
+    let x = select_zero_or_num2(cs.namespace(|| "final x"), &x, &self.is_infinity)?;
+
+    // y
+    let y = select_zero_or_num2(cs.namespace(|| "final y"), &y, &self.is_infinity)?;
+
+    // is_infinity
+    let is_infinity = self.is_infinity.clone();
+
+    Ok(Self { x, y, is_infinity })
+  }
+
+  /// A gadget for scalar multiplication, optimized to use incomplete addition law.
+  /// The optimization here is analogous to <https://github.com/arkworks-rs/r1cs-std/blob/6d64f379a27011b3629cf4c9cb38b7b7b695d5a0/src/groups/curves/short_weierstrass/mod.rs#L295>,
+  /// except we use complete addition law over affine coordinates instead of projective coordinates for the tail bits
+  pub fn scalar_mul<CS: ConstraintSystem<E::Base>>(
+    &self,
+    mut cs: CS,
+    scalar_bits: &[AllocatedBit],
+  ) -> Result<Self, SynthesisError> {
+    let split_len = core::cmp::min(scalar_bits.len(), (E::Base::NUM_BITS - 2) as usize);
+    let (incomplete_bits, complete_bits) = scalar_bits.split_at(split_len);
+
+    // we convert AllocatedPoint into AllocatedPointNonInfinity; we deal with the case where self.is_infinity = 1 below
+    let mut p = AllocatedPointNonInfinity::from_allocated_point(self);
+
+    // we assume the first bit to be 1, so we must initialize acc to self and double it
+    // we remove this assumption below
+    let mut acc = p;
+    p = acc.double_incomplete(cs.namespace(|| "double"))?;
+
+    // perform the double-and-add loop to compute the scalar mul using incomplete addition law
+    for (i, bit) in incomplete_bits.iter().enumerate().skip(1) {
+      let temp = acc.add_incomplete(cs.namespace(|| format!("add {i}")), &p)?;
+      acc = AllocatedPointNonInfinity::conditionally_select(
+        cs.namespace(|| format!("acc_iteration_{i}")),
+        &temp,
+        &acc,
+        &Boolean::from(bit.clone()),
+      )?;
+
+      p = p.double_incomplete(cs.namespace(|| format!("double {i}")))?;
+    }
+
+    // convert back to AllocatedPoint
+    let res = {
+      // we set acc.is_infinity = self.is_infinity
+      let acc = acc.to_allocated_point(&self.is_infinity)?;
+
+      // we remove the initial slack if bits[0] is as not as assumed (i.e., it is not 1)
+      let acc_minus_initial = {
+        let neg = self.negate(cs.namespace(|| "negate"))?;
+        acc.add(cs.namespace(|| "res minus self"), &neg)
+      }?;
+
+      Self::conditionally_select(
+        cs.namespace(|| "remove slack if necessary"),
+        &acc,
+        &acc_minus_initial,
+        &Boolean::from(scalar_bits[0].clone()),
+      )?
+    };
+
+    // when self.is_infinity = 1, return the default point, else return res
+    // we already set res.is_infinity to be self.is_infinity, so we do not need to set it here
+    let default = Self::default(cs.namespace(|| "default"))?;
+    let x = conditionally_select2(
+      cs.namespace(|| "check if self.is_infinity is zero (x)"),
+      &default.x,
+      &res.x,
+      &self.is_infinity,
+    )?;
+
+    let y = conditionally_select2(
+      cs.namespace(|| "check if self.is_infinity is zero (y)"),
+      &default.y,
+      &res.y,
+      &self.is_infinity,
+    )?;
+
+    // we now perform the remaining scalar mul using complete addition law
+    let mut acc = Self {
+      x,
+      y,
+      is_infinity: res.is_infinity,
+    };
+    let mut p_complete = p.to_allocated_point(&self.is_infinity)?;
+
+    for (i, bit) in complete_bits.iter().enumerate() {
+      let temp = acc.add(cs.namespace(|| format!("add_complete {i}")), &p_complete)?;
+      acc = Self::conditionally_select(
+        cs.namespace(|| format!("acc_complete_iteration_{i}")),
+        &temp,
+        &acc,
+        &Boolean::from(bit.clone()),
+      )?;
+
+      p_complete = p_complete.double(cs.namespace(|| format!("double_complete {i}")))?;
+    }
+
+    Ok(acc)
+  }
+
+  /// If condition outputs a otherwise outputs b
+  pub fn conditionally_select<CS: ConstraintSystem<E::Base>>(
+    mut cs: CS,
+    a: &Self,
+    b: &Self,
+    condition: &Boolean,
+  ) -> Result<Self, SynthesisError> {
+    let x = conditionally_select(cs.namespace(|| "select x"), &a.x, &b.x, condition)?;
+
+    let y = conditionally_select(cs.namespace(|| "select y"), &a.y, &b.y, condition)?;
+
+    let is_infinity = conditionally_select(
+      cs.namespace(|| "select is_infinity"),
+      &a.is_infinity,
+      &b.is_infinity,
+      condition,
+    )?;
+
+    Ok(Self { x, y, is_infinity })
+  }
+
+  /// If condition outputs a otherwise infinity
+  pub fn select_point_or_infinity<CS: ConstraintSystem<E::Base>>(
+    mut cs: CS,
+    a: &Self,
+    condition: &Boolean,
+  ) -> Result<Self, SynthesisError> {
+    let x = select_num_or_zero(cs.namespace(|| "select x"), &a.x, condition)?;
+
+    let y = select_num_or_zero(cs.namespace(|| "select y"), &a.y, condition)?;
+
+    let is_infinity = select_num_or_one(
+      cs.namespace(|| "select is_infinity"),
+      &a.is_infinity,
+      condition,
+    )?;
+
+    Ok(Self { x, y, is_infinity })
+  }
+}
+
+#[derive(Clone)]
+/// `AllocatedPoint` but one that is guaranteed to be not infinity
+pub struct AllocatedPointNonInfinity<E: Engine> {
+  x: AllocatedNum<E::Base>,
+  y: AllocatedNum<E::Base>,
+}
+
+impl<E> AllocatedPointNonInfinity<E>
+where
+  E: Engine,
+{
+  /// Creates a new `AllocatedPointNonInfinity` from the specified coordinates
+  pub const fn new(x: AllocatedNum<E::Base>, y: AllocatedNum<E::Base>) -> Self {
+    Self { x, y }
+  }
+
+  /// Allocates a new point on the curve using coordinates provided by `coords`.
+  pub fn alloc<CS: ConstraintSystem<E::Base>>(
+    mut cs: CS,
+    coords: Option<(E::Base, E::Base)>,
+  ) -> Result<Self, SynthesisError> {
+    let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
+      coords.map_or(Err(SynthesisError::AssignmentMissing), |c| Ok(c.0))
+    })?;
+    let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
+      coords.map_or(Err(SynthesisError::AssignmentMissing), |c| Ok(c.1))
+    })?;
+
+    Ok(Self { x, y })
+  }
+
+  /// Turns an `AllocatedPoint` into an `AllocatedPointNonInfinity` (assumes it is not infinity)
+  pub fn from_allocated_point(p: &AllocatedPoint<E>) -> Self {
+    Self {
+      x: p.x.clone(),
+      y: p.y.clone(),
+    }
+  }
+
+  /// Returns an `AllocatedPoint` from an `AllocatedPointNonInfinity`
+  pub fn to_allocated_point(
+    &self,
+    is_infinity: &AllocatedNum<E::Base>,
+  ) -> Result<AllocatedPoint<E>, SynthesisError> {
+    Ok(AllocatedPoint {
+      x: self.x.clone(),
+      y: self.y.clone(),
+      is_infinity: is_infinity.clone(),
+    })
+  }
+
+  /// Returns coordinates associated with the point.
+  pub const fn get_coordinates(&self) -> (&AllocatedNum<E::Base>, &AllocatedNum<E::Base>) {
+    (&self.x, &self.y)
+  }
+
+  /// Add two points assuming self != +/- other
+  pub fn add_incomplete<CS>(&self, mut cs: CS, other: &Self) -> Result<Self, SynthesisError>
+  where
+    CS: ConstraintSystem<E::Base>,
+  {
+    // allocate a free variable that an honest prover sets to lambda = (y2-y1)/(x2-x1)
+    let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
+      if *other.x.get_value().get()? == *self.x.get_value().get()? {
+        Ok(E::Base::ONE)
+      } else {
+        Ok(
+          (*other.y.get_value().get()? - *self.y.get_value().get()?)
+            * (*other.x.get_value().get()? - *self.x.get_value().get()?)
+              .invert()
+              .unwrap(),
+        )
+      }
+    })?;
+    cs.enforce(
+      || "Check that lambda is computed correctly",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + other.x.get_variable() - self.x.get_variable(),
+      |lc| lc + other.y.get_variable() - self.y.get_variable(),
+    );
+
+    //************************************************************************/
+    // x = lambda * lambda - self.x - other.x;
+    //************************************************************************/
+    let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
+      Ok(
+        *lambda.get_value().get()? * lambda.get_value().get()?
+          - *self.x.get_value().get()?
+          - *other.x.get_value().get()?,
+      )
+    })?;
+    cs.enforce(
+      || "check that x is correct",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + x.get_variable() + self.x.get_variable() + other.x.get_variable(),
+    );
+
+    //************************************************************************/
+    // y = lambda * (self.x - x) - self.y;
+    //************************************************************************/
+    let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
+      Ok(
+        *lambda.get_value().get()? * (*self.x.get_value().get()? - *x.get_value().get()?)
+          - *self.y.get_value().get()?,
+      )
+    })?;
+
+    cs.enforce(
+      || "Check that y is correct",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + self.x.get_variable() - x.get_variable(),
+      |lc| lc + y.get_variable() + self.y.get_variable(),
+    );
+
+    Ok(Self { x, y })
+  }
+
+  /// doubles the point; since this is called with a point not at infinity, it is guaranteed to be not infinity
+  pub fn double_incomplete<CS: ConstraintSystem<E::Base>>(
+    &self,
+    mut cs: CS,
+  ) -> Result<Self, SynthesisError> {
+    // lambda = (3 x^2 + a) / 2 * y
+
+    let x_sq = self.x.square(cs.namespace(|| "x_sq"))?;
+
+    let lambda = AllocatedNum::alloc(cs.namespace(|| "lambda"), || {
+      let n = E::Base::from(3) * x_sq.get_value().get()? + E::GE::group_params().0;
+      let d = E::Base::from(2) * *self.y.get_value().get()?;
+      if d == E::Base::ZERO {
+        Ok(E::Base::ONE)
+      } else {
+        Ok(n * d.invert().unwrap())
+      }
+    })?;
+    cs.enforce(
+      || "Check that lambda is computed correctly",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + (E::Base::from(2), self.y.get_variable()),
+      |lc| lc + (E::Base::from(3), x_sq.get_variable()) + (E::GE::group_params().0, CS::one()),
+    );
+
+    let x = AllocatedNum::alloc(cs.namespace(|| "x"), || {
+      Ok(
+        *lambda.get_value().get()? * *lambda.get_value().get()?
+          - *self.x.get_value().get()?
+          - *self.x.get_value().get()?,
+      )
+    })?;
+
+    cs.enforce(
+      || "check that x is correct",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + x.get_variable() + (E::Base::from(2), self.x.get_variable()),
+    );
+
+    let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
+      Ok(
+        *lambda.get_value().get()? * (*self.x.get_value().get()? - *x.get_value().get()?)
+          - *self.y.get_value().get()?,
+      )
+    })?;
+
+    cs.enforce(
+      || "Check that y is correct",
+      |lc| lc + lambda.get_variable(),
+      |lc| lc + self.x.get_variable() - x.get_variable(),
+      |lc| lc + y.get_variable() + self.y.get_variable(),
+    );
+
+    Ok(Self { x, y })
+  }
+
+  /// If condition outputs a otherwise outputs b
+  pub fn conditionally_select<CS: ConstraintSystem<E::Base>>(
+    mut cs: CS,
+    a: &Self,
+    b: &Self,
+    condition: &Boolean,
+  ) -> Result<Self, SynthesisError> {
+    let x = conditionally_select(cs.namespace(|| "select x"), &a.x, &b.x, condition)?;
+    let y = conditionally_select(cs.namespace(|| "select y"), &a.y, &b.y, condition)?;
+
+    Ok(Self { x, y })
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::{
+    bellpepper::{
+      r1cs::{NovaShape, NovaWitness},
+      {solver::SatisfyingAssignment, test_shape_cs::TestShapeCS},
+    },
+    provider::{
+      bn256_grumpkin::{bn256, grumpkin},
+      secp_secq::{secp256k1, secq256k1},
+      Bn256Engine, GrumpkinEngine, Secp256k1Engine, Secq256k1Engine, {PallasEngine, VestaEngine},
+    },
+    traits::snark::default_ck_hint,
+  };
+  use expect_test::{expect, Expect};
+  use ff::{Field, PrimeFieldBits};
+  use pasta_curves::{arithmetic::CurveAffine, group::Curve, pallas, vesta};
+  use rand::rngs::OsRng;
+
+  #[derive(Debug, Clone)]
+  pub struct Point<E: Engine> {
+    x: E::Base,
+    y: E::Base,
+    is_infinity: bool,
+  }
+
+  impl<E: Engine> Point<E> {
+    pub fn new(x: E::Base, y: E::Base, is_infinity: bool) -> Self {
+      Self { x, y, is_infinity }
+    }
+
+    pub fn random_vartime() -> Self {
+      loop {
+        let x = E::Base::random(&mut OsRng);
+        let y = (x.square() * x + E::GE::group_params().1).sqrt();
+        if y.is_some().unwrap_u8() == 1 {
+          return Self {
+            x,
+            y: y.unwrap(),
+            is_infinity: false,
+          };
+        }
+      }
+    }
+
+    /// Add any two points
+    pub fn add(&self, other: &Self) -> Self {
+      if self.x == other.x {
+        // If self == other then call double
+        if self.y == other.y {
+          self.double()
+        } else {
+          // if self.x == other.x and self.y != other.y then return infinity
+          Self {
+            x: E::Base::ZERO,
+            y: E::Base::ZERO,
+            is_infinity: true,
+          }
+        }
+      } else {
+        self.add_internal(other)
+      }
+    }
+
+    /// Add two different points
+    pub fn add_internal(&self, other: &Self) -> Self {
+      if self.is_infinity {
+        return other.clone();
+      }
+
+      if other.is_infinity {
+        return self.clone();
+      }
+
+      let lambda = (other.y - self.y) * (other.x - self.x).invert().unwrap();
+      let x = lambda * lambda - self.x - other.x;
+      let y = lambda * (self.x - x) - self.y;
+      Self {
+        x,
+        y,
+        is_infinity: false,
+      }
+    }
+
+    pub fn double(&self) -> Self {
+      if self.is_infinity {
+        return Self {
+          x: E::Base::ZERO,
+          y: E::Base::ZERO,
+          is_infinity: true,
+        };
+      }
+
+      let lambda = E::Base::from(3)
+        * self.x
+        * self.x
+        * ((E::Base::ONE + E::Base::ONE) * self.y).invert().unwrap();
+      let x = lambda * lambda - self.x - self.x;
+      let y = lambda * (self.x - x) - self.y;
+      Self {
+        x,
+        y,
+        is_infinity: false,
+      }
+    }
+
+    pub fn scalar_mul(&self, scalar: &E::Scalar) -> Self {
+      let mut res = Self {
+        x: E::Base::ZERO,
+        y: E::Base::ZERO,
+        is_infinity: true,
+      };
+
+      let bits = scalar.to_le_bits();
+      for i in (0..bits.len()).rev() {
+        res = res.double();
+        if bits[i] {
+          res = self.add(&res);
+        }
+      }
+      res
+    }
+  }
+
+  // Allocate a random point. Only used for testing
+  pub fn alloc_random_point<E: Engine, CS: ConstraintSystem<E::Base>>(
+    mut cs: CS,
+  ) -> Result<AllocatedPoint<E>, SynthesisError> {
+    // get a random point
+    let p = Point::<E>::random_vartime();
+    AllocatedPoint::alloc(cs.namespace(|| "alloc p"), Some((p.x, p.y, p.is_infinity)))
+  }
+
+  /// Make the point io
+  pub fn inputize_allocted_point<E: Engine, CS: ConstraintSystem<E::Base>>(
+    p: &AllocatedPoint<E>,
+    mut cs: CS,
+  ) {
+    let _ = p.x.inputize(cs.namespace(|| "Input point.x"));
+    let _ = p.y.inputize(cs.namespace(|| "Input point.y"));
+    let _ = p
+      .is_infinity
+      .inputize(cs.namespace(|| "Input point.is_infinity"));
+  }
+
+  #[test]
+  fn test_ecc_ops() {
+    test_ecc_ops_with::<pallas::Affine, PallasEngine>();
+    test_ecc_ops_with::<vesta::Affine, VestaEngine>();
+
+    test_ecc_ops_with::<bn256::Affine, Bn256Engine>();
+    test_ecc_ops_with::<grumpkin::Affine, GrumpkinEngine>();
+
+    test_ecc_ops_with::<secp256k1::Affine, Secp256k1Engine>();
+    test_ecc_ops_with::<secq256k1::Affine, Secq256k1Engine>();
+  }
+
+  fn test_ecc_ops_with<C, E>()
+  where
+    E: Engine,
+    C: CurveAffine<Base = E::Base, ScalarExt = E::Scalar>,
+  {
+    // perform some curve arithmetic
+    let a = Point::<E>::random_vartime();
+    let b = Point::<E>::random_vartime();
+    let c = a.add(&b);
+    let d = a.double();
+    let s = <E as Engine>::Scalar::random(&mut OsRng);
+    let e = a.scalar_mul(&s);
+
+    // perform the same computation by translating to curve types
+    let a_curve = C::from_xy(
+      C::Base::from_repr(a.x.to_repr()).unwrap(),
+      C::Base::from_repr(a.y.to_repr()).unwrap(),
+    )
+    .unwrap();
+    let b_curve = C::from_xy(
+      C::Base::from_repr(b.x.to_repr()).unwrap(),
+      C::Base::from_repr(b.y.to_repr()).unwrap(),
+    )
+    .unwrap();
+    let c_curve = (a_curve + b_curve).to_affine();
+    let d_curve = (a_curve + a_curve).to_affine();
+    let e_curve = a_curve
+      .mul(C::Scalar::from_repr(s.to_repr()).unwrap())
+      .to_affine();
+
+    // transform c, d, and e into curve types
+    let c_curve_2 = C::from_xy(
+      C::Base::from_repr(c.x.to_repr()).unwrap(),
+      C::Base::from_repr(c.y.to_repr()).unwrap(),
+    )
+    .unwrap();
+    let d_curve_2 = C::from_xy(
+      C::Base::from_repr(d.x.to_repr()).unwrap(),
+      C::Base::from_repr(d.y.to_repr()).unwrap(),
+    )
+    .unwrap();
+    let e_curve_2 = C::from_xy(
+      C::Base::from_repr(e.x.to_repr()).unwrap(),
+      C::Base::from_repr(e.y.to_repr()).unwrap(),
+    )
+    .unwrap();
+
+    // check that we have the same outputs
+    assert_eq!(c_curve, c_curve_2);
+    assert_eq!(d_curve, d_curve_2);
+    assert_eq!(e_curve, e_curve_2);
+  }
+
+  fn synthesize_smul<E, CS>(mut cs: CS) -> (AllocatedPoint<E>, AllocatedPoint<E>, E::Scalar)
+  where
+    E: Engine,
+    CS: ConstraintSystem<E::Base>,
+  {
+    let a = alloc_random_point(cs.namespace(|| "a")).unwrap();
+    inputize_allocted_point(&a, cs.namespace(|| "inputize a"));
+
+    let s = E::Scalar::random(&mut OsRng);
+    // Allocate bits for s
+    let bits: Vec<AllocatedBit> = s
+      .to_le_bits()
+      .into_iter()
+      .enumerate()
+      .map(|(i, bit)| AllocatedBit::alloc(cs.namespace(|| format!("bit {i}")), Some(bit)))
+      .collect::<Result<Vec<AllocatedBit>, SynthesisError>>()
+      .unwrap();
+    let e = a.scalar_mul(cs.namespace(|| "Scalar Mul"), &bits).unwrap();
+    inputize_allocted_point(&e, cs.namespace(|| "inputize e"));
+    (a, e, s)
+  }
+
+  #[test]
+  fn test_ecc_circuit_ops() {
+    test_ecc_circuit_ops_with::<PallasEngine, VestaEngine>(&expect!["2704"], &expect!["2692"]);
+    test_ecc_circuit_ops_with::<VestaEngine, PallasEngine>(&expect!["2704"], &expect!["2692"]);
+
+    test_ecc_circuit_ops_with::<Bn256Engine, GrumpkinEngine>(&expect!["2738"], &expect!["2724"]);
+    test_ecc_circuit_ops_with::<GrumpkinEngine, Bn256Engine>(&expect!["2738"], &expect!["2724"]);
+
+    test_ecc_circuit_ops_with::<Secp256k1Engine, Secq256k1Engine>(
+      &expect!["2670"],
+      &expect!["2660"],
+    );
+    test_ecc_circuit_ops_with::<Secq256k1Engine, Secp256k1Engine>(
+      &expect!["2670"],
+      &expect!["2660"],
+    );
+  }
+
+  fn test_ecc_circuit_ops_with<E1, E2>(expected_constraints: &Expect, expected_variables: &Expect)
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    // First create the shape
+    let mut cs: TestShapeCS<E2> = TestShapeCS::new();
+    let _ = synthesize_smul::<E1, _>(cs.namespace(|| "synthesize"));
+    expected_constraints.assert_eq(&cs.num_constraints().to_string());
+    expected_variables.assert_eq(&cs.num_aux().to_string());
+    let (shape, ck) = cs.r1cs_shape_and_key(&*default_ck_hint());
+
+    // Then the satisfying assignment
+    let mut cs = SatisfyingAssignment::<E2>::new();
+    let (a, e, s) = synthesize_smul::<E1, _>(cs.namespace(|| "synthesize"));
+    let (inst, witness) = cs.r1cs_instance_and_witness(&shape, &ck).unwrap();
+
+    let a_p: Point<E1> = Point::new(
+      a.x.get_value().unwrap(),
+      a.y.get_value().unwrap(),
+      a.is_infinity.get_value().unwrap() == <E1 as Engine>::Base::ONE,
+    );
+    let e_p: Point<E1> = Point::new(
+      e.x.get_value().unwrap(),
+      e.y.get_value().unwrap(),
+      e.is_infinity.get_value().unwrap() == <E1 as Engine>::Base::ONE,
+    );
+    let e_new = a_p.scalar_mul(&s);
+    assert!(e_p.x == e_new.x && e_p.y == e_new.y);
+    // Make sure that this is satisfiable
+    assert!(shape.is_sat(&ck, &inst, &witness).is_ok());
+  }
+
+  fn synthesize_add_equal<E, CS>(mut cs: CS) -> (AllocatedPoint<E>, AllocatedPoint<E>)
+  where
+    E: Engine,
+    CS: ConstraintSystem<E::Base>,
+  {
+    let a = alloc_random_point(cs.namespace(|| "a")).unwrap();
+    inputize_allocted_point(&a, cs.namespace(|| "inputize a"));
+    let e = a.add(cs.namespace(|| "add a to a"), &a).unwrap();
+    inputize_allocted_point(&e, cs.namespace(|| "inputize e"));
+    (a, e)
+  }
+
+  #[test]
+  fn test_ecc_circuit_add_equal() {
+    test_ecc_circuit_add_equal_with::<PallasEngine, VestaEngine>();
+    test_ecc_circuit_add_equal_with::<VestaEngine, PallasEngine>();
+
+    test_ecc_circuit_add_equal_with::<Bn256Engine, GrumpkinEngine>();
+    test_ecc_circuit_add_equal_with::<GrumpkinEngine, Bn256Engine>();
+
+    test_ecc_circuit_add_equal_with::<Secp256k1Engine, Secq256k1Engine>();
+    test_ecc_circuit_add_equal_with::<Secq256k1Engine, Secp256k1Engine>();
+  }
+
+  fn test_ecc_circuit_add_equal_with<E1, E2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    // First create the shape
+    let mut cs: TestShapeCS<E2> = TestShapeCS::new();
+    let _ = synthesize_add_equal::<E1, _>(cs.namespace(|| "synthesize add equal"));
+    println!("Number of constraints: {}", cs.num_constraints());
+    let (shape, ck) = cs.r1cs_shape_and_key(&*default_ck_hint());
+
+    // Then the satisfying assignment
+    let mut cs = SatisfyingAssignment::<E2>::new();
+    let (a, e) = synthesize_add_equal::<E1, _>(cs.namespace(|| "synthesize add equal"));
+    let (inst, witness) = cs.r1cs_instance_and_witness(&shape, &ck).unwrap();
+    let a_p: Point<E1> = Point::new(
+      a.x.get_value().unwrap(),
+      a.y.get_value().unwrap(),
+      a.is_infinity.get_value().unwrap() == <E1 as Engine>::Base::ONE,
+    );
+    let e_p: Point<E1> = Point::new(
+      e.x.get_value().unwrap(),
+      e.y.get_value().unwrap(),
+      e.is_infinity.get_value().unwrap() == <E1 as Engine>::Base::ONE,
+    );
+    let e_new = a_p.add(&a_p);
+    assert!(e_p.x == e_new.x && e_p.y == e_new.y);
+    // Make sure that it is satisfiable
+    assert!(shape.is_sat(&ck, &inst, &witness).is_ok());
+  }
+
+  fn synthesize_add_negation<E, CS>(mut cs: CS) -> AllocatedPoint<E>
+  where
+    E: Engine,
+    CS: ConstraintSystem<E::Base>,
+  {
+    let a = alloc_random_point(cs.namespace(|| "a")).unwrap();
+    inputize_allocted_point(&a, cs.namespace(|| "inputize a"));
+    let b = &mut a.clone();
+    b.y = AllocatedNum::alloc(cs.namespace(|| "allocate negation of a"), || {
+      Ok(E::Base::ZERO)
+    })
+    .unwrap();
+    inputize_allocted_point(b, cs.namespace(|| "inputize b"));
+    let e = a.add(cs.namespace(|| "add a to b"), b).unwrap();
+    e
+  }
+
+  #[test]
+  fn test_ecc_circuit_add_negation() {
+    test_ecc_circuit_add_negation_with::<PallasEngine, VestaEngine>(&expect!["39"], &expect!["34"]);
+    test_ecc_circuit_add_negation_with::<VestaEngine, PallasEngine>(&expect!["39"], &expect!["34"]);
+
+    test_ecc_circuit_add_negation_with::<Bn256Engine, GrumpkinEngine>(
+      &expect!["39"],
+      &expect!["34"],
+    );
+    test_ecc_circuit_add_negation_with::<GrumpkinEngine, Bn256Engine>(
+      &expect!["39"],
+      &expect!["34"],
+    );
+
+    test_ecc_circuit_add_negation_with::<Secp256k1Engine, Secq256k1Engine>(
+      &expect!["39"],
+      &expect!["34"],
+    );
+    test_ecc_circuit_add_negation_with::<Secq256k1Engine, Secp256k1Engine>(
+      &expect!["39"],
+      &expect!["34"],
+    );
+  }
+
+  fn test_ecc_circuit_add_negation_with<E1, E2>(
+    expected_constraints: &Expect,
+    expected_variables: &Expect,
+  ) where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    // First create the shape
+    let mut cs: TestShapeCS<E2> = TestShapeCS::new();
+    let _ = synthesize_add_negation::<E1, _>(cs.namespace(|| "synthesize add equal"));
+    expected_constraints.assert_eq(&cs.num_constraints().to_string());
+    expected_variables.assert_eq(&cs.num_aux().to_string());
+    let (shape, ck) = cs.r1cs_shape_and_key(&*default_ck_hint());
+
+    // Then the satisfying assignment
+    let mut cs = SatisfyingAssignment::<E2>::new();
+    let e = synthesize_add_negation::<E1, _>(cs.namespace(|| "synthesize add negation"));
+    let (inst, witness) = cs.r1cs_instance_and_witness(&shape, &ck).unwrap();
+    let e_p: Point<E1> = Point::new(
+      e.x.get_value().unwrap(),
+      e.y.get_value().unwrap(),
+      e.is_infinity.get_value().unwrap() == <E1 as Engine>::Base::ONE,
+    );
+    assert!(e_p.is_infinity);
+    // Make sure that it is satisfiable
+    assert!(shape.is_sat(&ck, &inst, &witness).is_ok());
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/gadgets/mod.rs.html b/docs/src/arecibo/gadgets/mod.rs.html new file mode 100644 index 000000000..f1605c982 --- /dev/null +++ b/docs/src/arecibo/gadgets/mod.rs.html @@ -0,0 +1,11 @@ +mod.rs - source
1
+2
+3
+4
+5
+
//! This module implements various gadgets necessary for Nova and applications built with Nova.
+pub mod ecc;
+pub(crate) mod nonnative;
+pub(crate) mod r1cs;
+pub(crate) mod utils;
+
\ No newline at end of file diff --git a/docs/src/arecibo/gadgets/nonnative/bignat.rs.html b/docs/src/arecibo/gadgets/nonnative/bignat.rs.html new file mode 100644 index 000000000..eab798a20 --- /dev/null +++ b/docs/src/arecibo/gadgets/nonnative/bignat.rs.html @@ -0,0 +1,1799 @@ +bignat.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+
use super::{
+  util::{
+    Bitvector, Num, {f_to_nat, nat_to_f},
+  },
+  OptionExt,
+};
+use bellpepper_core::{ConstraintSystem, LinearCombination, SynthesisError};
+use ff::PrimeField;
+use itertools::Itertools as _;
+use num_bigint::BigInt;
+use num_traits::cast::ToPrimitive;
+use std::borrow::Borrow;
+use std::cmp::{max, min};
+use std::convert::From;
+
+/// Compute the natural number represented by an array of limbs.
+/// The limbs are assumed to be based the `limb_width` power of 2.
+pub fn limbs_to_nat<Scalar: PrimeField, B: Borrow<Scalar>, I: DoubleEndedIterator<Item = B>>(
+  limbs: I,
+  limb_width: usize,
+) -> BigInt {
+  limbs.rev().fold(BigInt::from(0), |mut acc, limb| {
+    acc <<= limb_width as u32;
+    acc += f_to_nat(limb.borrow());
+    acc
+  })
+}
+
+fn int_with_n_ones(n: usize) -> BigInt {
+  let mut m = BigInt::from(1);
+  m <<= n as u32;
+  m -= 1;
+  m
+}
+
+/// Compute the limbs encoding a natural number.
+/// The limbs are assumed to be based the `limb_width` power of 2.
+pub fn nat_to_limbs<Scalar: PrimeField>(
+  nat: &BigInt,
+  limb_width: usize,
+  n_limbs: usize,
+) -> Result<Vec<Scalar>, SynthesisError> {
+  let mask = int_with_n_ones(limb_width);
+  let mut nat = nat.clone();
+  if nat.bits() as usize <= n_limbs * limb_width {
+    Ok(
+      (0..n_limbs)
+        .map(|_| {
+          let r = &nat & &mask;
+          nat >>= limb_width as u32;
+          nat_to_f(&r).unwrap()
+        })
+        .collect(),
+    )
+  } else {
+    eprintln!("nat {nat} does not fit in {n_limbs} limbs of width {limb_width}");
+    Err(SynthesisError::Unsatisfiable)
+  }
+}
+
+#[derive(Clone, PartialEq, Eq)]
+pub struct BigNatParams {
+  pub min_bits: usize,
+  pub max_word: BigInt,
+  pub limb_width: usize,
+  pub n_limbs: usize,
+}
+
+impl BigNatParams {
+  pub fn new(limb_width: usize, n_limbs: usize) -> Self {
+    let mut max_word = BigInt::from(1) << limb_width as u32;
+    max_word -= 1;
+    Self {
+      max_word,
+      n_limbs,
+      limb_width,
+      min_bits: 0,
+    }
+  }
+}
+
+/// A representation of a large natural number (a member of {0, 1, 2, ... })
+#[derive(Clone)]
+pub struct BigNat<Scalar: PrimeField> {
+  /// The linear combinations which constrain the value of each limb of the number
+  pub limbs: Vec<LinearCombination<Scalar>>,
+  /// The witness values for each limb (filled at witness-time)
+  pub limb_values: Option<Vec<Scalar>>,
+  /// The value of the whole number (filled at witness-time)
+  pub value: Option<BigInt>,
+  /// Parameters
+  pub params: BigNatParams,
+}
+
+impl<Scalar: PrimeField> PartialEq for BigNat<Scalar> {
+  fn eq(&self, other: &Self) -> bool {
+    self.value == other.value && self.params == other.params
+  }
+}
+impl<Scalar: PrimeField> Eq for BigNat<Scalar> {}
+
+impl<Scalar: PrimeField> From<BigNat<Scalar>> for Polynomial<Scalar> {
+  fn from(other: BigNat<Scalar>) -> Self {
+    Self {
+      coefficients: other.limbs,
+      values: other.limb_values,
+    }
+  }
+}
+
+impl<Scalar: PrimeField> BigNat<Scalar> {
+  /// Allocates a `BigNat` in the circuit with `n_limbs` limbs of width `limb_width` each.
+  /// If `max_word` is missing, then it is assumed to be `(2 << limb_width) - 1`.
+  /// The value is provided by a closure returning limb values.
+  pub fn alloc_from_limbs<CS, F>(
+    mut cs: CS,
+    f: F,
+    max_word: Option<BigInt>,
+    limb_width: usize,
+    n_limbs: usize,
+  ) -> Result<Self, SynthesisError>
+  where
+    CS: ConstraintSystem<Scalar>,
+    F: FnOnce() -> Result<Vec<Scalar>, SynthesisError>,
+  {
+    let values_cell = f();
+    let mut value = None;
+    let mut limb_values = None;
+    let limbs = (0..n_limbs)
+      .map(|limb_i| {
+        cs.alloc(
+          || format!("limb {limb_i}"),
+          || match values_cell {
+            Ok(ref vs) => {
+              if vs.len() != n_limbs {
+                eprintln!("Values do not match stated limb count");
+                return Err(SynthesisError::Unsatisfiable);
+              }
+              if value.is_none() {
+                value = Some(limbs_to_nat::<Scalar, _, _>(vs.iter(), limb_width));
+              }
+              if limb_values.is_none() {
+                limb_values = Some(vs.clone());
+              }
+              Ok(vs[limb_i])
+            }
+            // Hack b/c SynthesisError and io::Error don't implement Clone
+            Err(ref e) => Err(SynthesisError::from(std::io::Error::new(
+              std::io::ErrorKind::Other,
+              format!("{e}"),
+            ))),
+          },
+        )
+        .map(|v| LinearCombination::zero() + v)
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+    Ok(Self {
+      value,
+      limb_values,
+      limbs,
+      params: BigNatParams {
+        min_bits: 0,
+        n_limbs,
+        max_word: max_word.unwrap_or_else(|| int_with_n_ones(limb_width)),
+        limb_width,
+      },
+    })
+  }
+
+  /// Allocates a `BigNat` in the circuit with `n_limbs` limbs of width `limb_width` each.
+  /// The `max_word` is gauranteed to be `(2 << limb_width) - 1`.
+  /// The value is provided by a closure returning a natural number.
+  pub fn alloc_from_nat<CS, F>(
+    mut cs: CS,
+    f: F,
+    limb_width: usize,
+    n_limbs: usize,
+  ) -> Result<Self, SynthesisError>
+  where
+    CS: ConstraintSystem<Scalar>,
+    F: FnOnce() -> Result<BigInt, SynthesisError>,
+  {
+    let all_values_cell =
+      f().and_then(|v| Ok((nat_to_limbs::<Scalar>(&v, limb_width, n_limbs)?, v)));
+    let mut value = None;
+    let mut limb_values = Vec::new();
+    let limbs = (0..n_limbs)
+      .map(|limb_i| {
+        cs.alloc(
+          || format!("limb {limb_i}"),
+          || match all_values_cell {
+            Ok((ref vs, ref v)) => {
+              if value.is_none() {
+                value = Some(v.clone());
+              }
+              limb_values.push(vs[limb_i]);
+              Ok(vs[limb_i])
+            }
+            // Hack b/c SynthesisError and io::Error don't implement Clone
+            Err(ref e) => Err(SynthesisError::from(std::io::Error::new(
+              std::io::ErrorKind::Other,
+              format!("{e}"),
+            ))),
+          },
+        )
+        .map(|v| LinearCombination::zero() + v)
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+    Ok(Self {
+      value,
+      limb_values: if !limb_values.is_empty() {
+        Some(limb_values)
+      } else {
+        None
+      },
+      limbs,
+      params: BigNatParams::new(limb_width, n_limbs),
+    })
+  }
+
+  /// Allocates a `BigNat` in the circuit with `n_limbs` limbs of width `limb_width` each.
+  /// The `max_word` is gauranteed to be `(2 << limb_width) - 1`.
+  /// The value is provided by an allocated number
+  pub fn from_num<CS: ConstraintSystem<Scalar>>(
+    mut cs: CS,
+    n: &Num<Scalar>,
+    limb_width: usize,
+    n_limbs: usize,
+  ) -> Result<Self, SynthesisError> {
+    let bignat = Self::alloc_from_nat(
+      cs.namespace(|| "bignat"),
+      || {
+        Ok({
+          n.value
+            .as_ref()
+            .map(|n| f_to_nat(n))
+            .ok_or(SynthesisError::AssignmentMissing)?
+        })
+      },
+      limb_width,
+      n_limbs,
+    )?;
+
+    // check if bignat equals n
+    // (1) decompose `bignat` into a bitvector `bv`
+    let bv = bignat.decompose(cs.namespace(|| "bv"))?;
+    // (2) recompose bits and check if it equals n
+    n.is_equal(cs.namespace(|| "n"), &bv);
+
+    Ok(bignat)
+  }
+
+  pub fn as_limbs(&self) -> Vec<Num<Scalar>> {
+    let mut limbs = Vec::new();
+    for (i, lc) in self.limbs.iter().enumerate() {
+      limbs.push(Num::new(
+        self.limb_values.as_ref().map(|vs| vs[i]),
+        lc.clone(),
+      ));
+    }
+    limbs
+  }
+
+  pub fn assert_well_formed<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+  ) -> Result<(), SynthesisError> {
+    // swap the option and iterator
+    let limb_values_split =
+      (0..self.limbs.len()).map(|i| self.limb_values.as_ref().map(|vs| vs[i]));
+    for (i, (limb, limb_value)) in self.limbs.iter().zip_eq(limb_values_split).enumerate() {
+      Num::new(limb_value, limb.clone())
+        .fits_in_bits(cs.namespace(|| format!("{i}")), self.params.limb_width)?;
+    }
+    Ok(())
+  }
+
+  /// Break `self` up into a bit-vector.
+  pub fn decompose<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+  ) -> Result<Bitvector<Scalar>, SynthesisError> {
+    let limb_values_split =
+      (0..self.limbs.len()).map(|i| self.limb_values.as_ref().map(|vs| vs[i]));
+    let bitvectors: Vec<Bitvector<Scalar>> = self
+      .limbs
+      .iter()
+      .zip_eq(limb_values_split)
+      .enumerate()
+      .map(|(i, (limb, limb_value))| {
+        Num::new(limb_value, limb.clone()).decompose(
+          cs.namespace(|| format!("subdecmop {i}")),
+          self.params.limb_width,
+        )
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+    let mut bits = Vec::new();
+    let mut values = Vec::new();
+    let mut allocations = Vec::new();
+    for bv in bitvectors {
+      bits.extend(bv.bits);
+      if let Some(vs) = bv.values {
+        values.extend(vs)
+      };
+      allocations.extend(bv.allocations);
+    }
+    let values = if !values.is_empty() {
+      Some(values)
+    } else {
+      None
+    };
+    Ok(Bitvector {
+      bits,
+      values,
+      allocations,
+    })
+  }
+
+  pub fn enforce_limb_width_agreement(
+    &self,
+    other: &Self,
+    location: &str,
+  ) -> Result<usize, SynthesisError> {
+    if self.params.limb_width == other.params.limb_width {
+      Ok(self.params.limb_width)
+    } else {
+      eprintln!(
+        "Limb widths {}, {}, do not agree at {}",
+        self.params.limb_width, other.params.limb_width, location
+      );
+      Err(SynthesisError::Unsatisfiable)
+    }
+  }
+
+  pub fn from_poly(poly: Polynomial<Scalar>, limb_width: usize, max_word: BigInt) -> Self {
+    Self {
+      params: BigNatParams {
+        min_bits: 0,
+        max_word,
+        n_limbs: poly.coefficients.len(),
+        limb_width,
+      },
+      limbs: poly.coefficients,
+      value: poly
+        .values
+        .as_ref()
+        .map(|limb_values| limbs_to_nat::<Scalar, _, _>(limb_values.iter(), limb_width)),
+      limb_values: poly.values,
+    }
+  }
+
+  /// Constrain `self` to be equal to `other`, after carrying both.
+  pub fn equal_when_carried<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+    other: &Self,
+  ) -> Result<(), SynthesisError> {
+    self.enforce_limb_width_agreement(other, "equal_when_carried")?;
+
+    // We'll propegate carries over the first `n` limbs.
+    let n = min(self.limbs.len(), other.limbs.len());
+    let target_base = BigInt::from(1u8) << self.params.limb_width as u32;
+    let mut accumulated_extra = BigInt::from(0usize);
+    let max_word = max(&self.params.max_word, &other.params.max_word);
+    let carry_bits = (((max_word.to_f64().unwrap() * 2.0).log2() - self.params.limb_width as f64)
+      .ceil()
+      + 0.1) as usize;
+    let mut carry_in = Num::new(Some(Scalar::ZERO), LinearCombination::zero());
+
+    for i in 0..n {
+      let carry = Num::alloc(cs.namespace(|| format!("carry value {i}")), || {
+        Ok(
+          nat_to_f(
+            &((f_to_nat(&self.limb_values.grab()?[i])
+              + f_to_nat(&carry_in.value.unwrap())
+              + max_word
+              - f_to_nat(&other.limb_values.grab()?[i]))
+              / &target_base),
+          )
+          .unwrap(),
+        )
+      })?;
+      accumulated_extra += max_word;
+
+      cs.enforce(
+        || format!("carry {i}"),
+        |lc| lc,
+        |lc| lc,
+        |lc| {
+          lc + &carry_in.num + &self.limbs[i] - &other.limbs[i]
+            + (nat_to_f(max_word).unwrap(), CS::one())
+            - (nat_to_f(&target_base).unwrap(), &carry.num)
+            - (
+              nat_to_f(&(&accumulated_extra % &target_base)).unwrap(),
+              CS::one(),
+            )
+        },
+      );
+
+      accumulated_extra /= &target_base;
+
+      if i < n - 1 {
+        carry.fits_in_bits(cs.namespace(|| format!("carry {i} decomp")), carry_bits)?;
+      } else {
+        cs.enforce(
+          || format!("carry {i} is out"),
+          |lc| lc,
+          |lc| lc,
+          |lc| lc + &carry.num - (nat_to_f(&accumulated_extra).unwrap(), CS::one()),
+        );
+      }
+      carry_in = carry;
+    }
+
+    for (i, zero_limb) in self.limbs.iter().enumerate().skip(n) {
+      cs.enforce(
+        || format!("zero self {i}"),
+        |lc| lc,
+        |lc| lc,
+        |lc| lc + zero_limb,
+      );
+    }
+    for (i, zero_limb) in other.limbs.iter().enumerate().skip(n) {
+      cs.enforce(
+        || format!("zero other {i}"),
+        |lc| lc,
+        |lc| lc,
+        |lc| lc + zero_limb,
+      );
+    }
+    Ok(())
+  }
+
+  /// Constrain `self` to be equal to `other`, after carrying both.
+  /// Uses regrouping internally to take full advantage of the field size and reduce the amount
+  /// of carrying.
+  pub fn equal_when_carried_regroup<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+    other: &Self,
+  ) -> Result<(), SynthesisError> {
+    self.enforce_limb_width_agreement(other, "equal_when_carried_regroup")?;
+    let max_word = max(&self.params.max_word, &other.params.max_word);
+    let carry_bits = (((max_word.to_f64().unwrap() * 2.0).log2() - self.params.limb_width as f64)
+      .ceil()
+      + 0.1) as usize;
+    let limbs_per_group = (Scalar::CAPACITY as usize - carry_bits) / self.params.limb_width;
+    let self_grouped = self.group_limbs(limbs_per_group);
+    let other_grouped = other.group_limbs(limbs_per_group);
+    self_grouped.equal_when_carried(cs.namespace(|| "grouped"), &other_grouped)
+  }
+
+  pub fn add(&self, other: &Self) -> Result<Self, SynthesisError> {
+    self.enforce_limb_width_agreement(other, "add")?;
+    let n_limbs = max(self.params.n_limbs, other.params.n_limbs);
+    let max_word = &self.params.max_word + &other.params.max_word;
+    let limbs: Vec<LinearCombination<Scalar>> = (0..n_limbs)
+      .map(|i| match (self.limbs.get(i), other.limbs.get(i)) {
+        (Some(a), Some(b)) => a.clone() + b,
+        (Some(a), None) => a.clone(),
+        (None, Some(b)) => b.clone(),
+        (None, None) => unreachable!(),
+      })
+      .collect();
+    let limb_values: Option<Vec<Scalar>> = self.limb_values.as_ref().and_then(|x| {
+      other.limb_values.as_ref().map(|y| {
+        (0..n_limbs)
+          .map(|i| match (x.get(i), y.get(i)) {
+            (Some(a), Some(b)) => {
+              let mut t = *a;
+              t.add_assign(b);
+              t
+            }
+            (Some(a), None) | (None, Some(a)) => *a,
+            (None, None) => unreachable!(),
+          })
+          .collect()
+      })
+    });
+    let value = self
+      .value
+      .as_ref()
+      .and_then(|x| other.value.as_ref().map(|y| x + y));
+    Ok(Self {
+      limb_values,
+      value,
+      limbs,
+      params: BigNatParams {
+        min_bits: max(self.params.min_bits, other.params.min_bits),
+        n_limbs,
+        max_word,
+        limb_width: self.params.limb_width,
+      },
+    })
+  }
+
+  /// Compute a `BigNat` contrained to be equal to `self * other % modulus`.
+  pub fn mult_mod<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+    other: &Self,
+    modulus: &Self,
+  ) -> Result<(Self, Self), SynthesisError> {
+    self.enforce_limb_width_agreement(other, "mult_mod")?;
+    let limb_width = self.params.limb_width;
+    let quotient_bits = (self.n_bits() + other.n_bits()).saturating_sub(modulus.params.min_bits);
+    let quotient_limbs = quotient_bits.saturating_sub(1) / limb_width + 1;
+    let quotient = Self::alloc_from_nat(
+      cs.namespace(|| "quotient"),
+      || {
+        Ok({
+          let mut x = self.value.grab()?.clone();
+          x *= other.value.grab()?;
+          x /= modulus.value.grab()?;
+          x
+        })
+      },
+      self.params.limb_width,
+      quotient_limbs,
+    )?;
+    quotient.assert_well_formed(cs.namespace(|| "quotient rangecheck"))?;
+    let remainder = Self::alloc_from_nat(
+      cs.namespace(|| "remainder"),
+      || {
+        Ok({
+          let mut x = self.value.grab()?.clone();
+          x *= other.value.grab()?;
+          x %= modulus.value.grab()?;
+          x
+        })
+      },
+      self.params.limb_width,
+      modulus.limbs.len(),
+    )?;
+    remainder.assert_well_formed(cs.namespace(|| "remainder rangecheck"))?;
+    let a_poly = Polynomial::from(self.clone());
+    let b_poly = Polynomial::from(other.clone());
+    let mod_poly = Polynomial::from(modulus.clone());
+    let q_poly = Polynomial::from(quotient.clone());
+    let r_poly = Polynomial::from(remainder.clone());
+
+    // a * b
+    let left = a_poly.alloc_product(cs.namespace(|| "left"), &b_poly)?;
+    let right_product = q_poly.alloc_product(cs.namespace(|| "right_product"), &mod_poly)?;
+    // q * m + r
+    let right = right_product.sum(&r_poly);
+
+    let left_max_word = {
+      let mut x = BigInt::from(min(self.limbs.len(), other.limbs.len()));
+      x *= &self.params.max_word;
+      x *= &other.params.max_word;
+      x
+    };
+    let right_max_word = {
+      let mut x = BigInt::from(min(quotient.limbs.len(), modulus.limbs.len()));
+      x *= &quotient.params.max_word;
+      x *= &modulus.params.max_word;
+      x += &remainder.params.max_word;
+      x
+    };
+
+    let left_int = Self::from_poly(left, limb_width, left_max_word);
+    let right_int = Self::from_poly(right, limb_width, right_max_word);
+    left_int.equal_when_carried_regroup(cs.namespace(|| "carry"), &right_int)?;
+    Ok((quotient, remainder))
+  }
+
+  /// Compute a `BigNat` contrained to be equal to `self * other % modulus`.
+  pub fn red_mod<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+    modulus: &Self,
+  ) -> Result<Self, SynthesisError> {
+    self.enforce_limb_width_agreement(modulus, "red_mod")?;
+    let limb_width = self.params.limb_width;
+    let quotient_bits = self.n_bits().saturating_sub(modulus.params.min_bits);
+    let quotient_limbs = quotient_bits.saturating_sub(1) / limb_width + 1;
+    let quotient = Self::alloc_from_nat(
+      cs.namespace(|| "quotient"),
+      || Ok(self.value.grab()? / modulus.value.grab()?),
+      self.params.limb_width,
+      quotient_limbs,
+    )?;
+    quotient.assert_well_formed(cs.namespace(|| "quotient rangecheck"))?;
+    let remainder = Self::alloc_from_nat(
+      cs.namespace(|| "remainder"),
+      || Ok(self.value.grab()? % modulus.value.grab()?),
+      self.params.limb_width,
+      modulus.limbs.len(),
+    )?;
+    remainder.assert_well_formed(cs.namespace(|| "remainder rangecheck"))?;
+    let mod_poly = Polynomial::from(modulus.clone());
+    let q_poly = Polynomial::from(quotient.clone());
+    let r_poly = Polynomial::from(remainder.clone());
+
+    // q * m + r
+    let right_product = q_poly.alloc_product(cs.namespace(|| "right_product"), &mod_poly)?;
+    let right = right_product.sum(&r_poly);
+
+    let right_max_word = {
+      let mut x = BigInt::from(min(quotient.limbs.len(), modulus.limbs.len()));
+      x *= &quotient.params.max_word;
+      x *= &modulus.params.max_word;
+      x += &remainder.params.max_word;
+      x
+    };
+
+    let right_int = Self::from_poly(right, limb_width, right_max_word);
+    self.equal_when_carried_regroup(cs.namespace(|| "carry"), &right_int)?;
+    Ok(remainder)
+  }
+
+  /// Combines limbs into groups.
+  pub fn group_limbs(&self, limbs_per_group: usize) -> Self {
+    let n_groups = (self.limbs.len() - 1) / limbs_per_group + 1;
+    let limb_values = self.limb_values.as_ref().map(|vs| {
+      let mut values: Vec<Scalar> = vec![Scalar::ZERO; n_groups];
+      let mut shift = Scalar::ONE;
+      let limb_block = (0..self.params.limb_width).fold(Scalar::ONE, |mut l, _| {
+        l = l.double();
+        l
+      });
+      for (i, v) in vs.iter().enumerate() {
+        if i % limbs_per_group == 0 {
+          shift = Scalar::ONE;
+        }
+        let mut a = shift;
+        a *= v;
+        values[i / limbs_per_group].add_assign(&a);
+        shift.mul_assign(&limb_block);
+      }
+      values
+    });
+    let limbs = {
+      let mut limbs: Vec<LinearCombination<Scalar>> = vec![LinearCombination::zero(); n_groups];
+      let mut shift = Scalar::ONE;
+      let limb_block = (0..self.params.limb_width).fold(Scalar::ONE, |mut l, _| {
+        l = l.double();
+        l
+      });
+      for (i, limb) in self.limbs.iter().enumerate() {
+        if i % limbs_per_group == 0 {
+          shift = Scalar::ONE;
+        }
+        limbs[i / limbs_per_group] =
+          std::mem::replace(&mut limbs[i / limbs_per_group], LinearCombination::zero())
+            + (shift, limb);
+        shift.mul_assign(&limb_block);
+      }
+      limbs
+    };
+    let max_word = (0..limbs_per_group).fold(BigInt::from(0u8), |mut acc, i| {
+      acc.set_bit((i * self.params.limb_width) as u64, true);
+      acc
+    }) * &self.params.max_word;
+    Self {
+      params: BigNatParams {
+        min_bits: self.params.min_bits,
+        limb_width: self.params.limb_width * limbs_per_group,
+        n_limbs: limbs.len(),
+        max_word,
+      },
+      limbs,
+      limb_values,
+      value: self.value.clone(),
+    }
+  }
+
+  pub fn n_bits(&self) -> usize {
+    assert!(self.params.n_limbs > 0);
+    self.params.limb_width * (self.params.n_limbs - 1) + self.params.max_word.bits() as usize
+  }
+}
+
+pub struct Polynomial<Scalar: PrimeField> {
+  pub coefficients: Vec<LinearCombination<Scalar>>,
+  pub values: Option<Vec<Scalar>>,
+}
+
+impl<Scalar: PrimeField> Polynomial<Scalar> {
+  pub fn alloc_product<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+    other: &Self,
+  ) -> Result<Self, SynthesisError> {
+    let n_product_coeffs = self.coefficients.len() + other.coefficients.len() - 1;
+    let values = self.values.as_ref().and_then(|self_vs| {
+      other.values.as_ref().map(|other_vs| {
+        let mut values: Vec<Scalar> = std::iter::repeat_with(|| Scalar::ZERO)
+          .take(n_product_coeffs)
+          .collect();
+        for (self_i, self_v) in self_vs.iter().enumerate() {
+          for (other_i, other_v) in other_vs.iter().enumerate() {
+            let mut v = *self_v;
+            v.mul_assign(other_v);
+            values[self_i + other_i].add_assign(&v);
+          }
+        }
+        values
+      })
+    });
+    let coefficients = (0..n_product_coeffs)
+      .map(|i| {
+        Ok(LinearCombination::zero() + cs.alloc(|| format!("prod {i}"), || Ok(values.grab()?[i]))?)
+      })
+      .collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?;
+    let product = Self {
+      coefficients,
+      values,
+    };
+    let one = Scalar::ONE;
+    let mut x = Scalar::ZERO;
+    for _ in 1..(n_product_coeffs + 1) {
+      x.add_assign(&one);
+      cs.enforce(
+        || format!("pointwise product @ {x:?}"),
+        |lc| {
+          let mut i = Scalar::ONE;
+          self.coefficients.iter().fold(lc, |lc, c| {
+            let r = lc + (i, c);
+            i.mul_assign(&x);
+            r
+          })
+        },
+        |lc| {
+          let mut i = Scalar::ONE;
+          other.coefficients.iter().fold(lc, |lc, c| {
+            let r = lc + (i, c);
+            i.mul_assign(&x);
+            r
+          })
+        },
+        |lc| {
+          let mut i = Scalar::ONE;
+          product.coefficients.iter().fold(lc, |lc, c| {
+            let r = lc + (i, c);
+            i.mul_assign(&x);
+            r
+          })
+        },
+      )
+    }
+    Ok(product)
+  }
+
+  pub fn sum(&self, other: &Self) -> Self {
+    let n_coeffs = max(self.coefficients.len(), other.coefficients.len());
+    let values = self.values.as_ref().and_then(|self_vs| {
+      other.values.as_ref().map(|other_vs| {
+        (0..n_coeffs)
+          .map(|i| {
+            let mut s = Scalar::ZERO;
+            if i < self_vs.len() {
+              s.add_assign(&self_vs[i]);
+            }
+            if i < other_vs.len() {
+              s.add_assign(&other_vs[i]);
+            }
+            s
+          })
+          .collect()
+      })
+    });
+    let coefficients = (0..n_coeffs)
+      .map(|i| {
+        let mut lc = LinearCombination::zero();
+        if i < self.coefficients.len() {
+          lc = lc + &self.coefficients[i];
+        }
+        if i < other.coefficients.len() {
+          lc = lc + &other.coefficients[i];
+        }
+        lc
+      })
+      .collect();
+    Self {
+      coefficients,
+      values,
+    }
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use bellpepper_core::{test_cs::TestConstraintSystem, Circuit};
+  use pasta_curves::pallas::Scalar;
+  #[cfg(not(target_arch = "wasm32"))]
+  use proptest::prelude::*;
+
+  pub struct PolynomialMultiplier<Scalar> {
+    pub a: Vec<Scalar>,
+    pub b: Vec<Scalar>,
+  }
+
+  impl<Scalar: PrimeField> Circuit<Scalar> for PolynomialMultiplier<Scalar> {
+    fn synthesize<CS: ConstraintSystem<Scalar>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
+      let a = Polynomial {
+        coefficients: self
+          .a
+          .iter()
+          .enumerate()
+          .map(|(i, x)| {
+            Ok(LinearCombination::zero() + cs.alloc(|| format!("coeff_a {i}"), || Ok(*x))?)
+          })
+          .collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?,
+        values: Some(self.a),
+      };
+      let b = Polynomial {
+        coefficients: self
+          .b
+          .iter()
+          .enumerate()
+          .map(|(i, x)| {
+            Ok(LinearCombination::zero() + cs.alloc(|| format!("coeff_b {i}"), || Ok(*x))?)
+          })
+          .collect::<Result<Vec<LinearCombination<Scalar>>, SynthesisError>>()?,
+        values: Some(self.b),
+      };
+      let _prod = a.alloc_product(cs.namespace(|| "product"), &b)?;
+      Ok(())
+    }
+  }
+
+  #[test]
+  fn test_polynomial_multiplier_circuit() {
+    let mut cs = TestConstraintSystem::<Scalar>::new();
+
+    let circuit = PolynomialMultiplier {
+      a: [1, 1, 1].iter().map(|i| Scalar::from_u128(*i)).collect(),
+      b: [1, 1].iter().map(|i| Scalar::from_u128(*i)).collect(),
+    };
+
+    circuit.synthesize(&mut cs).expect("synthesis failed");
+
+    if let Some(token) = cs.which_is_unsatisfied() {
+      eprintln!("Error: {} is unsatisfied", token);
+    }
+  }
+
+  #[derive(Debug)]
+  pub struct BigNatBitDecompInputs {
+    pub n: BigInt,
+  }
+
+  pub struct BigNatBitDecompParams {
+    pub limb_width: usize,
+    pub n_limbs: usize,
+  }
+
+  pub struct BigNatBitDecomp {
+    inputs: Option<BigNatBitDecompInputs>,
+    params: BigNatBitDecompParams,
+  }
+
+  impl<Scalar: PrimeField> Circuit<Scalar> for BigNatBitDecomp {
+    fn synthesize<CS: ConstraintSystem<Scalar>>(self, cs: &mut CS) -> Result<(), SynthesisError> {
+      let n = BigNat::alloc_from_nat(
+        cs.namespace(|| "n"),
+        || Ok(self.inputs.grab()?.n.clone()),
+        self.params.limb_width,
+        self.params.n_limbs,
+      )?;
+      n.decompose(cs.namespace(|| "decomp"))?;
+      Ok(())
+    }
+  }
+
+  #[cfg(not(target_arch = "wasm32"))]
+  proptest! {
+    #![proptest_config(ProptestConfig {
+      cases: 10, // this test is costlier as max n gets larger
+      .. ProptestConfig::default()
+    })]
+    #[test]
+    fn test_big_nat_can_decompose(n in any::<u16>(), limb_width in 40u8..200) {
+        let n = n as usize;
+
+        let n_limbs = if n == 0 {
+            1
+        } else {
+            (n - 1) / limb_width as usize + 1
+        };
+
+        let circuit = BigNatBitDecomp {
+           inputs: Some(BigNatBitDecompInputs {
+                n: BigInt::from(n),
+            }),
+            params: BigNatBitDecompParams {
+                limb_width: limb_width as usize,
+                n_limbs,
+            },
+        };
+        let mut cs = TestConstraintSystem::<Scalar>::new();
+        circuit.synthesize(&mut cs).expect("synthesis failed");
+        prop_assert!(cs.is_satisfied());
+    }
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/gadgets/nonnative/mod.rs.html b/docs/src/arecibo/gadgets/nonnative/mod.rs.html new file mode 100644 index 000000000..48b3a9ee7 --- /dev/null +++ b/docs/src/arecibo/gadgets/nonnative/mod.rs.html @@ -0,0 +1,79 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+
//! This module implements various gadgets necessary for doing non-native arithmetic
+//! Code in this module is adapted from [bellman-bignat](https://github.com/alex-ozdemir/bellman-bignat), which is licenced under MIT
+
+use bellpepper_core::SynthesisError;
+use ff::PrimeField;
+
+trait OptionExt<T> {
+  fn grab(&self) -> Result<&T, SynthesisError>;
+  fn grab_mut(&mut self) -> Result<&mut T, SynthesisError>;
+}
+
+impl<T> OptionExt<T> for Option<T> {
+  fn grab(&self) -> Result<&T, SynthesisError> {
+    self.as_ref().ok_or(SynthesisError::AssignmentMissing)
+  }
+  fn grab_mut(&mut self) -> Result<&mut T, SynthesisError> {
+    self.as_mut().ok_or(SynthesisError::AssignmentMissing)
+  }
+}
+
+trait BitAccess {
+  fn get_bit(&self, i: usize) -> Option<bool>;
+}
+
+impl<Scalar: PrimeField> BitAccess for Scalar {
+  fn get_bit(&self, i: usize) -> Option<bool> {
+    if i as u32 >= Scalar::NUM_BITS {
+      return None;
+    }
+
+    let (byte_pos, bit_pos) = (i / 8, i % 8);
+    let byte = self.to_repr().as_ref()[byte_pos];
+    let bit = byte >> bit_pos & 1;
+    Some(bit == 1)
+  }
+}
+
+pub mod bignat;
+pub mod util;
+
\ No newline at end of file diff --git a/docs/src/arecibo/gadgets/nonnative/util.rs.html b/docs/src/arecibo/gadgets/nonnative/util.rs.html new file mode 100644 index 000000000..b5bd88d9d --- /dev/null +++ b/docs/src/arecibo/gadgets/nonnative/util.rs.html @@ -0,0 +1,513 @@ +util.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+
use super::{BitAccess, OptionExt};
+use bellpepper_core::{
+  num::AllocatedNum,
+  {ConstraintSystem, LinearCombination, SynthesisError, Variable},
+};
+use byteorder::WriteBytesExt;
+use ff::PrimeField;
+use num_bigint::{BigInt, Sign};
+use std::convert::From;
+use std::io::{self, Write};
+
+#[derive(Clone)]
+/// A representation of a bit
+pub struct Bit<Scalar: PrimeField> {
+  /// The linear combination which constrain the value of the bit
+  pub bit: LinearCombination<Scalar>,
+  /// The value of the bit (filled at witness-time)
+  pub value: Option<bool>,
+}
+
+#[derive(Clone)]
+/// A representation of a bit-vector
+pub struct Bitvector<Scalar: PrimeField> {
+  /// The linear combination which constrain the values of the bits
+  pub bits: Vec<LinearCombination<Scalar>>,
+  /// The value of the bits (filled at witness-time)
+  pub values: Option<Vec<bool>>,
+  /// Allocated bit variables
+  pub allocations: Vec<Bit<Scalar>>,
+}
+
+impl<Scalar: PrimeField> Bit<Scalar> {
+  /// Allocate a variable in the constraint system which can only be a
+  /// boolean value.
+  pub fn alloc<CS: ConstraintSystem<Scalar>>(
+    mut cs: CS,
+    value: Option<bool>,
+  ) -> Result<Self, SynthesisError> {
+    let var = cs.alloc(
+      || "boolean",
+      || {
+        if *value.grab()? {
+          Ok(Scalar::ONE)
+        } else {
+          Ok(Scalar::ZERO)
+        }
+      },
+    )?;
+
+    // Constrain: (1 - a) * a = 0
+    // This constrains a to be either 0 or 1.
+    cs.enforce(
+      || "boolean constraint",
+      |lc| lc + CS::one() - var,
+      |lc| lc + var,
+      |lc| lc,
+    );
+
+    Ok(Self {
+      bit: LinearCombination::zero() + var,
+      value,
+    })
+  }
+}
+
+pub struct Num<Scalar: PrimeField> {
+  pub num: LinearCombination<Scalar>,
+  pub value: Option<Scalar>,
+}
+
+impl<Scalar: PrimeField> Num<Scalar> {
+  pub const fn new(value: Option<Scalar>, num: LinearCombination<Scalar>) -> Self {
+    Self { value, num }
+  }
+  pub fn alloc<CS, F>(mut cs: CS, value: F) -> Result<Self, SynthesisError>
+  where
+    CS: ConstraintSystem<Scalar>,
+    F: FnOnce() -> Result<Scalar, SynthesisError>,
+  {
+    let mut new_value = None;
+    let var = cs.alloc(
+      || "num",
+      || {
+        let tmp = value()?;
+
+        new_value = Some(tmp);
+
+        Ok(tmp)
+      },
+    )?;
+
+    Ok(Self {
+      value: new_value,
+      num: LinearCombination::zero() + var,
+    })
+  }
+
+  pub fn fits_in_bits<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+    n_bits: usize,
+  ) -> Result<(), SynthesisError> {
+    let v = self.value;
+
+    // Allocate all but the first bit.
+    let bits: Vec<Variable> = (1..n_bits)
+      .map(|i| {
+        cs.alloc(
+          || format!("bit {i}"),
+          || {
+            let r = if *v.grab()?.get_bit(i).grab()? {
+              Scalar::ONE
+            } else {
+              Scalar::ZERO
+            };
+            Ok(r)
+          },
+        )
+      })
+      .collect::<Result<_, _>>()?;
+
+    for (i, v) in bits.iter().enumerate() {
+      cs.enforce(
+        || format!("{i} is bit"),
+        |lc| lc + *v,
+        |lc| lc + CS::one() - *v,
+        |lc| lc,
+      )
+    }
+
+    // Last bit
+    cs.enforce(
+      || "last bit",
+      |mut lc| {
+        let mut f = Scalar::ONE;
+        lc = lc + &self.num;
+        for v in bits.iter() {
+          f = f.double();
+          lc = lc - (f, *v);
+        }
+        lc
+      },
+      |mut lc| {
+        lc = lc + CS::one();
+        let mut f = Scalar::ONE;
+        lc = lc - &self.num;
+        for v in bits.iter() {
+          f = f.double();
+          lc = lc + (f, *v);
+        }
+        lc
+      },
+      |lc| lc,
+    );
+    Ok(())
+  }
+
+  /// Computes the natural number represented by an array of bits.
+  /// Checks if the natural number equals `self`
+  pub fn is_equal<CS: ConstraintSystem<Scalar>>(&self, mut cs: CS, other: &Bitvector<Scalar>) {
+    let allocations = other.allocations.clone();
+    let mut f = Scalar::ONE;
+    let sum = allocations
+      .iter()
+      .fold(LinearCombination::zero(), |lc, bit| {
+        let l = lc + (f, &bit.bit);
+        f = f.double();
+        l
+      });
+    let sum_lc = LinearCombination::zero() + &self.num - &sum;
+    cs.enforce(|| "sum", |lc| lc + &sum_lc, |lc| lc + CS::one(), |lc| lc);
+  }
+
+  /// Compute the natural number represented by an array of limbs.
+  /// The limbs are assumed to be based the `limb_width` power of 2.
+  /// Low-index bits are low-order
+  pub fn decompose<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+    n_bits: usize,
+  ) -> Result<Bitvector<Scalar>, SynthesisError> {
+    let values: Option<Vec<bool>> = self.value.as_ref().map(|v| {
+      let num = *v;
+      (0..n_bits).map(|i| num.get_bit(i).unwrap()).collect()
+    });
+    let allocations: Vec<Bit<Scalar>> = (0..n_bits)
+      .map(|bit_i| {
+        Bit::alloc(
+          cs.namespace(|| format!("bit{bit_i}")),
+          values.as_ref().map(|vs| vs[bit_i]),
+        )
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+    let mut f = Scalar::ONE;
+    let sum = allocations
+      .iter()
+      .fold(LinearCombination::zero(), |lc, bit| {
+        let l = lc + (f, &bit.bit);
+        f = f.double();
+        l
+      });
+    let sum_lc = LinearCombination::zero() + &self.num - &sum;
+    cs.enforce(|| "sum", |lc| lc + &sum_lc, |lc| lc + CS::one(), |lc| lc);
+    let bits: Vec<LinearCombination<Scalar>> = allocations
+      .clone()
+      .into_iter()
+      .map(|a| LinearCombination::zero() + &a.bit)
+      .collect();
+    Ok(Bitvector {
+      allocations,
+      values,
+      bits,
+    })
+  }
+
+  pub fn as_allocated_num<CS: ConstraintSystem<Scalar>>(
+    &self,
+    mut cs: CS,
+  ) -> Result<AllocatedNum<Scalar>, SynthesisError> {
+    let new = AllocatedNum::alloc(cs.namespace(|| "alloc"), || Ok(*self.value.grab()?))?;
+    cs.enforce(
+      || "eq",
+      |lc| lc,
+      |lc| lc,
+      |lc| lc + new.get_variable() - &self.num,
+    );
+    Ok(new)
+  }
+}
+
+impl<Scalar: PrimeField> From<AllocatedNum<Scalar>> for Num<Scalar> {
+  fn from(a: AllocatedNum<Scalar>) -> Self {
+    Self::new(a.get_value(), LinearCombination::zero() + a.get_variable())
+  }
+}
+
+fn write_be<F: PrimeField, W: Write>(f: &F, mut writer: W) -> io::Result<()> {
+  for digit in f.to_repr().as_ref().iter().rev() {
+    writer.write_u8(*digit)?;
+  }
+
+  Ok(())
+}
+
+/// Convert a field element to a natural number
+pub fn f_to_nat<Scalar: PrimeField>(f: &Scalar) -> BigInt {
+  let mut s = Vec::new();
+  write_be(f, &mut s).unwrap(); // f.to_repr().write_be(&mut s).unwrap();
+  BigInt::from_bytes_le(Sign::Plus, f.to_repr().as_ref())
+}
+
+/// Convert a natural number to a field element.
+/// Returns `None` if the number is too big for the field.
+pub fn nat_to_f<Scalar: PrimeField>(n: &BigInt) -> Option<Scalar> {
+  Scalar::from_str_vartime(&format!("{n}"))
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/gadgets/r1cs.rs.html b/docs/src/arecibo/gadgets/r1cs.rs.html new file mode 100644 index 000000000..553e24d01 --- /dev/null +++ b/docs/src/arecibo/gadgets/r1cs.rs.html @@ -0,0 +1,865 @@ +r1cs.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+
//! This module implements various gadgets necessary for folding R1CS types.
+use super::nonnative::{
+  bignat::BigNat,
+  util::{f_to_nat, Num},
+};
+use crate::{
+  constants::{NUM_CHALLENGE_BITS, NUM_FE_FOR_RO},
+  gadgets::{
+    ecc::AllocatedPoint,
+    utils::{
+      alloc_bignat_constant, alloc_one, alloc_scalar_as_base, conditionally_select,
+      conditionally_select_bignat, le_bits_to_num,
+    },
+  },
+  r1cs::{R1CSInstance, RelaxedR1CSInstance},
+  traits::{commitment::CommitmentTrait, Engine, Group, ROCircuitTrait, ROConstantsCircuit},
+};
+use bellpepper::gadgets::{boolean::Boolean, num::AllocatedNum, Assignment};
+use bellpepper_core::{ConstraintSystem, SynthesisError};
+use ff::Field;
+use itertools::Itertools as _;
+
+/// An Allocated R1CS Instance
+#[derive(Clone)]
+pub struct AllocatedR1CSInstance<E: Engine> {
+  pub(crate) W: AllocatedPoint<E>,
+  pub(crate) X0: AllocatedNum<E::Base>,
+  pub(crate) X1: AllocatedNum<E::Base>,
+}
+
+impl<E: Engine> AllocatedR1CSInstance<E> {
+  /// Takes the r1cs instance and creates a new allocated r1cs instance
+  pub fn alloc<CS: ConstraintSystem<<E as Engine>::Base>>(
+    mut cs: CS,
+    u: Option<&R1CSInstance<E>>,
+  ) -> Result<Self, SynthesisError> {
+    let W = AllocatedPoint::alloc(
+      cs.namespace(|| "allocate W"),
+      u.map(|u| u.comm_W.to_coordinates()),
+    )?;
+    W.check_on_curve(cs.namespace(|| "check W on curve"))?;
+
+    let X0 = alloc_scalar_as_base::<E, _>(cs.namespace(|| "allocate X[0]"), u.map(|u| u.X[0]))?;
+    let X1 = alloc_scalar_as_base::<E, _>(cs.namespace(|| "allocate X[1]"), u.map(|u| u.X[1]))?;
+
+    Ok(Self { W, X0, X1 })
+  }
+
+  /// Absorb the provided instance in the RO
+  pub fn absorb_in_ro(&self, ro: &mut E::ROCircuit) {
+    ro.absorb(&self.W.x);
+    ro.absorb(&self.W.y);
+    ro.absorb(&self.W.is_infinity);
+    ro.absorb(&self.X0);
+    ro.absorb(&self.X1);
+  }
+}
+
+/// An Allocated Relaxed R1CS Instance
+#[derive(Clone)]
+pub struct AllocatedRelaxedR1CSInstance<E: Engine> {
+  pub(crate) W: AllocatedPoint<E>,
+  pub(crate) E: AllocatedPoint<E>,
+  pub(crate) u: AllocatedNum<E::Base>,
+  pub(crate) X0: BigNat<E::Base>,
+  pub(crate) X1: BigNat<E::Base>,
+}
+
+impl<E: Engine> AllocatedRelaxedR1CSInstance<E> {
+  /// Allocates the given `RelaxedR1CSInstance` as a witness of the circuit
+  pub fn alloc<CS: ConstraintSystem<<E as Engine>::Base>>(
+    mut cs: CS,
+    inst: Option<&RelaxedR1CSInstance<E>>,
+    limb_width: usize,
+    n_limbs: usize,
+  ) -> Result<Self, SynthesisError> {
+    // We do not need to check that W or E are well-formed (e.g., on the curve) as we do a hash check
+    // in the Nova augmented circuit, which ensures that the relaxed instance
+    // came from a prior iteration of Nova.
+    let W = AllocatedPoint::alloc(
+      cs.namespace(|| "allocate W"),
+      inst.map(|inst| inst.comm_W.to_coordinates()),
+    )?;
+
+    let E = AllocatedPoint::alloc(
+      cs.namespace(|| "allocate E"),
+      inst.map(|inst| inst.comm_E.to_coordinates()),
+    )?;
+
+    // u << |E::Base| despite the fact that u is a scalar.
+    // So we parse all of its bytes as a E::Base element
+    let u = alloc_scalar_as_base::<E, _>(cs.namespace(|| "allocate u"), inst.map(|inst| inst.u))?;
+
+    // Allocate X0 and X1. If the input instance is None, then allocate default values 0.
+    let X0 = BigNat::alloc_from_nat(
+      cs.namespace(|| "allocate X[0]"),
+      || Ok(f_to_nat(&inst.map_or(E::Scalar::ZERO, |inst| inst.X[0]))),
+      limb_width,
+      n_limbs,
+    )?;
+
+    let X1 = BigNat::alloc_from_nat(
+      cs.namespace(|| "allocate X[1]"),
+      || Ok(f_to_nat(&inst.map_or(E::Scalar::ZERO, |inst| inst.X[1]))),
+      limb_width,
+      n_limbs,
+    )?;
+
+    Ok(Self { W, E, u, X0, X1 })
+  }
+
+  /// Allocates the hardcoded default `RelaxedR1CSInstance` in the circuit.
+  /// W = E = 0, u = 0, X0 = X1 = 0
+  pub fn default<CS: ConstraintSystem<<E as Engine>::Base>>(
+    mut cs: CS,
+    limb_width: usize,
+    n_limbs: usize,
+  ) -> Result<Self, SynthesisError> {
+    let W = AllocatedPoint::default(cs.namespace(|| "allocate W"))?;
+    let E = W.clone();
+
+    let u = W.x.clone(); // In the default case, W.x = u = 0
+
+    // X0 and X1 are allocated and in the honest prover case set to zero
+    // If the prover is malicious, it can set to arbitrary values, but the resulting
+    // relaxed R1CS instance with the the checked default values of W, E, and u must still be satisfying
+    let X0 = BigNat::alloc_from_nat(
+      cs.namespace(|| "allocate x_default[0]"),
+      || Ok(f_to_nat(&E::Scalar::ZERO)),
+      limb_width,
+      n_limbs,
+    )?;
+
+    let X1 = BigNat::alloc_from_nat(
+      cs.namespace(|| "allocate x_default[1]"),
+      || Ok(f_to_nat(&E::Scalar::ZERO)),
+      limb_width,
+      n_limbs,
+    )?;
+
+    Ok(Self { W, E, u, X0, X1 })
+  }
+
+  /// Allocates the R1CS Instance as a `RelaxedR1CSInstance` in the circuit.
+  /// E = 0, u = 1
+  pub fn from_r1cs_instance<CS: ConstraintSystem<<E as Engine>::Base>>(
+    mut cs: CS,
+    inst: AllocatedR1CSInstance<E>,
+    limb_width: usize,
+    n_limbs: usize,
+  ) -> Result<Self, SynthesisError> {
+    let E = AllocatedPoint::default(cs.namespace(|| "allocate default E"))?;
+
+    let u = alloc_one(cs.namespace(|| "one"));
+
+    let X0 = BigNat::from_num(
+      cs.namespace(|| "allocate X0 from relaxed r1cs"),
+      &Num::from(inst.X0),
+      limb_width,
+      n_limbs,
+    )?;
+
+    let X1 = BigNat::from_num(
+      cs.namespace(|| "allocate X1 from relaxed r1cs"),
+      &Num::from(inst.X1),
+      limb_width,
+      n_limbs,
+    )?;
+
+    Ok(Self {
+      W: inst.W,
+      E,
+      u,
+      X0,
+      X1,
+    })
+  }
+
+  /// Absorb the provided instance in the RO
+  pub fn absorb_in_ro<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    mut cs: CS,
+    ro: &mut E::ROCircuit,
+  ) -> Result<(), SynthesisError> {
+    ro.absorb(&self.W.x);
+    ro.absorb(&self.W.y);
+    ro.absorb(&self.W.is_infinity);
+    ro.absorb(&self.E.x);
+    ro.absorb(&self.E.y);
+    ro.absorb(&self.E.is_infinity);
+    ro.absorb(&self.u);
+
+    // Analyze X0 as limbs
+    let X0_bn = self
+      .X0
+      .as_limbs()
+      .iter()
+      .enumerate()
+      .map(|(i, limb)| {
+        limb.as_allocated_num(cs.namespace(|| format!("convert limb {i} of X_r[0] to num")))
+      })
+      .collect::<Result<Vec<AllocatedNum<E::Base>>, _>>()?;
+
+    // absorb each of the limbs of X[0]
+    for limb in X0_bn {
+      ro.absorb(&limb);
+    }
+
+    // Analyze X1 as limbs
+    let X1_bn = self
+      .X1
+      .as_limbs()
+      .iter()
+      .enumerate()
+      .map(|(i, limb)| {
+        limb.as_allocated_num(cs.namespace(|| format!("convert limb {i} of X_r[1] to num")))
+      })
+      .collect::<Result<Vec<AllocatedNum<E::Base>>, _>>()?;
+
+    // absorb each of the limbs of X[1]
+    for limb in X1_bn {
+      ro.absorb(&limb);
+    }
+
+    Ok(())
+  }
+
+  /// Folds self with a relaxed r1cs instance and returns the result
+  pub fn fold_with_r1cs<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    mut cs: CS,
+    params: &AllocatedNum<E::Base>, // hash of R1CSShape of F'
+    u: &AllocatedR1CSInstance<E>,
+    T: &AllocatedPoint<E>,
+    ro_consts: ROConstantsCircuit<E>,
+    limb_width: usize,
+    n_limbs: usize,
+  ) -> Result<Self, SynthesisError> {
+    // Compute r:
+    let mut ro = E::ROCircuit::new(ro_consts, NUM_FE_FOR_RO);
+    ro.absorb(params);
+    self.absorb_in_ro(cs.namespace(|| "absorb running instance"), &mut ro)?;
+    u.absorb_in_ro(&mut ro);
+    ro.absorb(&T.x);
+    ro.absorb(&T.y);
+    ro.absorb(&T.is_infinity);
+    let r_bits = ro.squeeze(cs.namespace(|| "r bits"), NUM_CHALLENGE_BITS)?;
+    let r = le_bits_to_num(cs.namespace(|| "r"), &r_bits)?;
+
+    // W_fold = self.W + r * u.W
+    let rW = u.W.scalar_mul(cs.namespace(|| "r * u.W"), &r_bits)?;
+    let W_fold = self.W.add(cs.namespace(|| "self.W + r * u.W"), &rW)?;
+
+    // E_fold = self.E + r * T
+    let rT = T.scalar_mul(cs.namespace(|| "r * T"), &r_bits)?;
+    let E_fold = self.E.add(cs.namespace(|| "self.E + r * T"), &rT)?;
+
+    // u_fold = u_r + r
+    let u_fold = AllocatedNum::alloc(cs.namespace(|| "u_fold"), || {
+      Ok(*self.u.get_value().get()? + r.get_value().get()?)
+    })?;
+    cs.enforce(
+      || "Check u_fold",
+      |lc| lc,
+      |lc| lc,
+      |lc| lc + u_fold.get_variable() - self.u.get_variable() - r.get_variable(),
+    );
+
+    // Fold the IO:
+    // Analyze r into limbs
+    let r_bn = BigNat::from_num(
+      cs.namespace(|| "allocate r_bn"),
+      &Num::from(r),
+      limb_width,
+      n_limbs,
+    )?;
+
+    // Allocate the order of the non-native field as a constant
+    let m_bn = alloc_bignat_constant(
+      cs.namespace(|| "alloc m"),
+      &E::GE::group_params().2,
+      limb_width,
+      n_limbs,
+    )?;
+
+    // Analyze X0 to bignat
+    let X0_bn = BigNat::from_num(
+      cs.namespace(|| "allocate X0_bn"),
+      &Num::from(u.X0.clone()),
+      limb_width,
+      n_limbs,
+    )?;
+
+    // Fold self.X[0] + r * X[0]
+    let (_, r_0) = X0_bn.mult_mod(cs.namespace(|| "r*X[0]"), &r_bn, &m_bn)?;
+    // add X_r[0]
+    let r_new_0 = self.X0.add(&r_0)?;
+    // Now reduce
+    let X0_fold = r_new_0.red_mod(cs.namespace(|| "reduce folded X[0]"), &m_bn)?;
+
+    // Analyze X1 to bignat
+    let X1_bn = BigNat::from_num(
+      cs.namespace(|| "allocate X1_bn"),
+      &Num::from(u.X1.clone()),
+      limb_width,
+      n_limbs,
+    )?;
+
+    // Fold self.X[1] + r * X[1]
+    let (_, r_1) = X1_bn.mult_mod(cs.namespace(|| "r*X[1]"), &r_bn, &m_bn)?;
+    // add X_r[1]
+    let r_new_1 = self.X1.add(&r_1)?;
+    // Now reduce
+    let X1_fold = r_new_1.red_mod(cs.namespace(|| "reduce folded X[1]"), &m_bn)?;
+
+    Ok(Self {
+      W: W_fold,
+      E: E_fold,
+      u: u_fold,
+      X0: X0_fold,
+      X1: X1_fold,
+    })
+  }
+
+  /// If the condition is true then returns this otherwise it returns the other
+  pub fn conditionally_select<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    cs: CS,
+    other: &Self,
+    condition: &Boolean,
+  ) -> Result<Self, SynthesisError> {
+    conditionally_select_alloc_relaxed_r1cs(cs, self, other, condition)
+  }
+}
+
+/// c = cond ? a: b, where a, b: `AllocatedRelaxedR1CSInstance`
+pub fn conditionally_select_alloc_relaxed_r1cs<
+  E: Engine,
+  CS: ConstraintSystem<<E as Engine>::Base>,
+>(
+  mut cs: CS,
+  a: &AllocatedRelaxedR1CSInstance<E>,
+  b: &AllocatedRelaxedR1CSInstance<E>,
+  condition: &Boolean,
+) -> Result<AllocatedRelaxedR1CSInstance<E>, SynthesisError> {
+  let c = AllocatedRelaxedR1CSInstance {
+    W: conditionally_select_point(
+      cs.namespace(|| "W = cond ? a.W : b.W"),
+      &a.W,
+      &b.W,
+      condition,
+    )?,
+    E: conditionally_select_point(
+      cs.namespace(|| "E = cond ? a.E : b.E"),
+      &a.E,
+      &b.E,
+      condition,
+    )?,
+    u: conditionally_select(
+      cs.namespace(|| "u = cond ? a.u : b.u"),
+      &a.u,
+      &b.u,
+      condition,
+    )?,
+    X0: conditionally_select_bignat(
+      cs.namespace(|| "X[0] = cond ? a.X[0] : b.X[0]"),
+      &a.X0,
+      &b.X0,
+      condition,
+    )?,
+    X1: conditionally_select_bignat(
+      cs.namespace(|| "X[1] = cond ? a.X[1] : b.X[1]"),
+      &a.X1,
+      &b.X1,
+      condition,
+    )?,
+  };
+  Ok(c)
+}
+
+/// c = cond ? a: b, where a, b: `Vec<AllocatedRelaxedR1CSInstance>`
+pub fn conditionally_select_vec_allocated_relaxed_r1cs_instance<
+  E: Engine,
+  CS: ConstraintSystem<<E as Engine>::Base>,
+>(
+  mut cs: CS,
+  a: &[AllocatedRelaxedR1CSInstance<E>],
+  b: &[AllocatedRelaxedR1CSInstance<E>],
+  condition: &Boolean,
+) -> Result<Vec<AllocatedRelaxedR1CSInstance<E>>, SynthesisError> {
+  a.iter()
+    .enumerate()
+    .zip_eq(b.iter())
+    .map(|((i, a), b)| {
+      a.conditionally_select(
+        cs.namespace(|| format!("cond ? a[{}]: b[{}]", i, i)),
+        b,
+        condition,
+      )
+    })
+    .collect::<Result<Vec<AllocatedRelaxedR1CSInstance<E>>, _>>()
+}
+
+/// c = cond ? a: b, where a, b: `AllocatedPoint`
+pub fn conditionally_select_point<E: Engine, CS: ConstraintSystem<<E as Engine>::Base>>(
+  mut cs: CS,
+  a: &AllocatedPoint<E>,
+  b: &AllocatedPoint<E>,
+  condition: &Boolean,
+) -> Result<AllocatedPoint<E>, SynthesisError> {
+  let c = AllocatedPoint {
+    x: conditionally_select(
+      cs.namespace(|| "x = cond ? a.x : b.x"),
+      &a.x,
+      &b.x,
+      condition,
+    )?,
+    y: conditionally_select(
+      cs.namespace(|| "y = cond ? a.y : b.y"),
+      &a.y,
+      &b.y,
+      condition,
+    )?,
+    is_infinity: conditionally_select(
+      cs.namespace(|| "is_infinity = cond ? a.is_infinity : b.is_infinity"),
+      &a.is_infinity,
+      &b.is_infinity,
+      condition,
+    )?,
+  };
+  Ok(c)
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/gadgets/utils.rs.html b/docs/src/arecibo/gadgets/utils.rs.html new file mode 100644 index 000000000..0c36933c7 --- /dev/null +++ b/docs/src/arecibo/gadgets/utils.rs.html @@ -0,0 +1,857 @@ +utils.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+
//! This module implements various low-level gadgets
+use super::nonnative::bignat::{nat_to_limbs, BigNat};
+use crate::traits::Engine;
+use bellpepper::gadgets::Assignment;
+use bellpepper_core::{
+  boolean::{AllocatedBit, Boolean},
+  num::AllocatedNum,
+  ConstraintSystem, LinearCombination, SynthesisError,
+};
+use ff::{Field, PrimeField, PrimeFieldBits};
+use itertools::Itertools as _;
+use num_bigint::BigInt;
+
+/// Gets as input the little indian representation of a number and spits out the number
+pub fn le_bits_to_num<Scalar, CS>(
+  mut cs: CS,
+  bits: &[AllocatedBit],
+) -> Result<AllocatedNum<Scalar>, SynthesisError>
+where
+  Scalar: PrimeField + PrimeFieldBits,
+  CS: ConstraintSystem<Scalar>,
+{
+  // We loop over the input bits and construct the constraint
+  // and the field element that corresponds to the result
+  let mut lc = LinearCombination::zero();
+  let mut coeff = Scalar::ONE;
+  let mut fe = Some(Scalar::ZERO);
+  for bit in bits.iter() {
+    lc = lc + (coeff, bit.get_variable());
+    fe = bit.get_value().map(|val| {
+      if val {
+        fe.unwrap() + coeff
+      } else {
+        fe.unwrap()
+      }
+    });
+    coeff = coeff.double();
+  }
+  let num = AllocatedNum::alloc(cs.namespace(|| "Field element"), || {
+    fe.ok_or(SynthesisError::AssignmentMissing)
+  })?;
+  lc = lc - num.get_variable();
+  cs.enforce(|| "compute number from bits", |lc| lc, |lc| lc, |_| lc);
+  Ok(num)
+}
+
+/// Allocate a variable that is set to zero
+pub fn alloc_zero<F: PrimeField, CS: ConstraintSystem<F>>(mut cs: CS) -> AllocatedNum<F> {
+  let zero = AllocatedNum::alloc_infallible(cs.namespace(|| "alloc"), || F::ZERO);
+  cs.enforce(
+    || "check zero is valid",
+    |lc| lc,
+    |lc| lc,
+    |lc| lc + zero.get_variable(),
+  );
+  zero
+}
+
+/// Allocate a variable that is set to one
+pub fn alloc_one<F: PrimeField, CS: ConstraintSystem<F>>(mut cs: CS) -> AllocatedNum<F> {
+  let one = AllocatedNum::alloc_infallible(cs.namespace(|| "alloc"), || F::ONE);
+  cs.enforce(
+    || "check one is valid",
+    |lc| lc + CS::one(),
+    |lc| lc + CS::one(),
+    |lc| lc + one.get_variable(),
+  );
+
+  one
+}
+
+/// Allocate a scalar as a base. Only to be used is the scalar fits in base!
+pub fn alloc_scalar_as_base<E, CS>(
+  mut cs: CS,
+  input: Option<E::Scalar>,
+) -> Result<AllocatedNum<E::Base>, SynthesisError>
+where
+  E: Engine,
+  <E as Engine>::Scalar: PrimeFieldBits,
+  CS: ConstraintSystem<<E as Engine>::Base>,
+{
+  AllocatedNum::alloc(cs.namespace(|| "allocate scalar as base"), || {
+    let input_bits = input.unwrap_or(E::Scalar::ZERO).clone().to_le_bits();
+    let mut mult = E::Base::ONE;
+    let mut val = E::Base::ZERO;
+    for bit in input_bits {
+      if bit {
+        val += mult;
+      }
+      mult = mult + mult;
+    }
+    Ok(val)
+  })
+}
+
+/// interepret scalar as base
+pub fn scalar_as_base<E: Engine>(input: E::Scalar) -> E::Base {
+  let input_bits = input.to_le_bits();
+  let mut mult = E::Base::ONE;
+  let mut val = E::Base::ZERO;
+  for bit in input_bits {
+    if bit {
+      val += mult;
+    }
+    mult = mult + mult;
+  }
+  val
+}
+
+/// Allocate bignat a constant
+pub fn alloc_bignat_constant<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  val: &BigInt,
+  limb_width: usize,
+  n_limbs: usize,
+) -> Result<BigNat<F>, SynthesisError> {
+  let limbs = nat_to_limbs(val, limb_width, n_limbs).unwrap();
+  let bignat = BigNat::alloc_from_limbs(
+    cs.namespace(|| "alloc bignat"),
+    || Ok(limbs.clone()),
+    None,
+    limb_width,
+    n_limbs,
+  )?;
+  // Now enforce that the limbs are all equal to the constants
+  (0..n_limbs).for_each(|i| {
+    cs.enforce(
+      || format!("check limb {i}"),
+      |lc| lc + &bignat.limbs[i],
+      |lc| lc + CS::one(),
+      |lc| lc + (limbs[i], CS::one()),
+    );
+  });
+  Ok(bignat)
+}
+
+/// Check that two numbers are equal and return a bit
+pub fn alloc_num_equals<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  b: &AllocatedNum<F>,
+) -> Result<AllocatedBit, SynthesisError> {
+  // Allocate and constrain `r`: result boolean bit.
+  // It equals `true` if `a` equals `b`, `false` otherwise
+  let r_value = match (a.get_value(), b.get_value()) {
+    (Some(a), Some(b)) => Some(a == b),
+    _ => None,
+  };
+
+  let r = AllocatedBit::alloc(cs.namespace(|| "r"), r_value)?;
+
+  // Allocate t s.t. t=1 if a == b else 1/(a - b)
+
+  let t = AllocatedNum::alloc(cs.namespace(|| "t"), || {
+    let a_val = *a.get_value().get()?;
+    let b_val = *b.get_value().get()?;
+    Ok(if a_val == b_val {
+      F::ONE
+    } else {
+      (a_val - b_val).invert().unwrap()
+    })
+  })?;
+
+  cs.enforce(
+    || "t*(a - b) = 1 - r",
+    |lc| lc + t.get_variable(),
+    |lc| lc + a.get_variable() - b.get_variable(),
+    |lc| lc + CS::one() - r.get_variable(),
+  );
+
+  cs.enforce(
+    || "r*(a - b) = 0",
+    |lc| lc + r.get_variable(),
+    |lc| lc + a.get_variable() - b.get_variable(),
+    |lc| lc,
+  );
+
+  Ok(r)
+}
+
+/// If condition return a otherwise b
+pub fn conditionally_select<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  b: &AllocatedNum<F>,
+  condition: &Boolean,
+) -> Result<AllocatedNum<F>, SynthesisError> {
+  let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
+    if *condition.get_value().get()? {
+      Ok(*a.get_value().get()?)
+    } else {
+      Ok(*b.get_value().get()?)
+    }
+  })?;
+
+  // a * condition + b*(1-condition) = c ->
+  // a * condition - b*condition = c - b
+  cs.enforce(
+    || "conditional select constraint",
+    |lc| lc + a.get_variable() - b.get_variable(),
+    |_| condition.lc(CS::one(), F::ONE),
+    |lc| lc + c.get_variable() - b.get_variable(),
+  );
+
+  Ok(c)
+}
+
+/// If condition return a otherwise b
+pub fn conditionally_select_vec<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &[AllocatedNum<F>],
+  b: &[AllocatedNum<F>],
+  condition: &Boolean,
+) -> Result<Vec<AllocatedNum<F>>, SynthesisError> {
+  a.iter()
+    .zip_eq(b.iter())
+    .enumerate()
+    .map(|(i, (a, b))| {
+      conditionally_select(cs.namespace(|| format!("select_{i}")), a, b, condition)
+    })
+    .collect::<Result<Vec<AllocatedNum<F>>, SynthesisError>>()
+}
+
+/// If condition return a otherwise b where a and b are `BigNats`
+pub fn conditionally_select_bignat<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &BigNat<F>,
+  b: &BigNat<F>,
+  condition: &Boolean,
+) -> Result<BigNat<F>, SynthesisError> {
+  assert!(a.limbs.len() == b.limbs.len());
+  let c = BigNat::alloc_from_nat(
+    cs.namespace(|| "conditional select result"),
+    || {
+      if *condition.get_value().get()? {
+        Ok(a.value.get()?.clone())
+      } else {
+        Ok(b.value.get()?.clone())
+      }
+    },
+    a.params.limb_width,
+    a.params.n_limbs,
+  )?;
+
+  // a * condition + b*(1-condition) = c ->
+  // a * condition - b*condition = c - b
+  for i in 0..c.limbs.len() {
+    cs.enforce(
+      || format!("conditional select constraint {i}"),
+      |lc| lc + &a.limbs[i] - &b.limbs[i],
+      |_| condition.lc(CS::one(), F::ONE),
+      |lc| lc + &c.limbs[i] - &b.limbs[i],
+    );
+  }
+  Ok(c)
+}
+
+/// Same as the above but Condition is an `AllocatedNum` that needs to be
+/// 0 or 1. 1 => True, 0 => False
+pub fn conditionally_select2<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  b: &AllocatedNum<F>,
+  condition: &AllocatedNum<F>,
+) -> Result<AllocatedNum<F>, SynthesisError> {
+  let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
+    if *condition.get_value().get()? == F::ONE {
+      Ok(*a.get_value().get()?)
+    } else {
+      Ok(*b.get_value().get()?)
+    }
+  })?;
+
+  // a * condition + b*(1-condition) = c ->
+  // a * condition - b*condition = c - b
+  cs.enforce(
+    || "conditional select constraint",
+    |lc| lc + a.get_variable() - b.get_variable(),
+    |lc| lc + condition.get_variable(),
+    |lc| lc + c.get_variable() - b.get_variable(),
+  );
+
+  Ok(c)
+}
+
+/// If condition set to 0 otherwise a. Condition is an allocated num
+pub fn select_zero_or_num2<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  condition: &AllocatedNum<F>,
+) -> Result<AllocatedNum<F>, SynthesisError> {
+  let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
+    if *condition.get_value().get()? == F::ONE {
+      Ok(F::ZERO)
+    } else {
+      Ok(*a.get_value().get()?)
+    }
+  })?;
+
+  // a * (1 - condition) = c
+  cs.enforce(
+    || "conditional select constraint",
+    |lc| lc + a.get_variable(),
+    |lc| lc + CS::one() - condition.get_variable(),
+    |lc| lc + c.get_variable(),
+  );
+
+  Ok(c)
+}
+
+/// If condition set to a otherwise 0. Condition is an allocated num
+pub fn select_num_or_zero2<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  condition: &AllocatedNum<F>,
+) -> Result<AllocatedNum<F>, SynthesisError> {
+  let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
+    if *condition.get_value().get()? == F::ONE {
+      Ok(*a.get_value().get()?)
+    } else {
+      Ok(F::ZERO)
+    }
+  })?;
+
+  cs.enforce(
+    || "conditional select constraint",
+    |lc| lc + a.get_variable(),
+    |lc| lc + condition.get_variable(),
+    |lc| lc + c.get_variable(),
+  );
+
+  Ok(c)
+}
+
+/// If condition set to a otherwise 0
+pub fn select_num_or_zero<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  condition: &Boolean,
+) -> Result<AllocatedNum<F>, SynthesisError> {
+  let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
+    if *condition.get_value().get()? {
+      Ok(*a.get_value().get()?)
+    } else {
+      Ok(F::ZERO)
+    }
+  })?;
+
+  cs.enforce(
+    || "conditional select constraint",
+    |lc| lc + a.get_variable(),
+    |_| condition.lc(CS::one(), F::ONE),
+    |lc| lc + c.get_variable(),
+  );
+
+  Ok(c)
+}
+
+/// If condition set to 1 otherwise a
+pub fn select_one_or_num2<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  condition: &AllocatedNum<F>,
+) -> Result<AllocatedNum<F>, SynthesisError> {
+  let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
+    if *condition.get_value().get()? == F::ONE {
+      Ok(F::ONE)
+    } else {
+      Ok(*a.get_value().get()?)
+    }
+  })?;
+
+  cs.enforce(
+    || "conditional select constraint",
+    |lc| lc + CS::one() - a.get_variable(),
+    |lc| lc + condition.get_variable(),
+    |lc| lc + c.get_variable() - a.get_variable(),
+  );
+  Ok(c)
+}
+
+/// If condition set to 1 otherwise a - b
+pub fn select_one_or_diff2<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  b: &AllocatedNum<F>,
+  condition: &AllocatedNum<F>,
+) -> Result<AllocatedNum<F>, SynthesisError> {
+  let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
+    if *condition.get_value().get()? == F::ONE {
+      Ok(F::ONE)
+    } else {
+      Ok(*a.get_value().get()? - *b.get_value().get()?)
+    }
+  })?;
+
+  cs.enforce(
+    || "conditional select constraint",
+    |lc| lc + CS::one() - a.get_variable() + b.get_variable(),
+    |lc| lc + condition.get_variable(),
+    |lc| lc + c.get_variable() - a.get_variable() + b.get_variable(),
+  );
+  Ok(c)
+}
+
+/// If condition set to a otherwise 1 for boolean conditions
+pub fn select_num_or_one<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  a: &AllocatedNum<F>,
+  condition: &Boolean,
+) -> Result<AllocatedNum<F>, SynthesisError> {
+  let c = AllocatedNum::alloc(cs.namespace(|| "conditional select result"), || {
+    if *condition.get_value().get()? {
+      Ok(*a.get_value().get()?)
+    } else {
+      Ok(F::ONE)
+    }
+  })?;
+
+  cs.enforce(
+    || "conditional select constraint",
+    |lc| lc + a.get_variable() - CS::one(),
+    |_| condition.lc(CS::one(), F::ONE),
+    |lc| lc + c.get_variable() - CS::one(),
+  );
+
+  Ok(c)
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/lib.rs.html b/docs/src/arecibo/lib.rs.html new file mode 100644 index 000000000..e5a7807f8 --- /dev/null +++ b/docs/src/arecibo/lib.rs.html @@ -0,0 +1,3411 @@ +lib.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+1364
+1365
+1366
+1367
+1368
+1369
+1370
+1371
+1372
+1373
+1374
+1375
+1376
+1377
+1378
+1379
+1380
+1381
+1382
+1383
+1384
+1385
+1386
+1387
+1388
+1389
+1390
+1391
+1392
+1393
+1394
+1395
+1396
+1397
+1398
+1399
+1400
+1401
+1402
+1403
+1404
+1405
+1406
+1407
+1408
+1409
+1410
+1411
+1412
+1413
+1414
+1415
+1416
+1417
+1418
+1419
+1420
+1421
+1422
+1423
+1424
+1425
+1426
+1427
+1428
+1429
+1430
+1431
+1432
+1433
+1434
+1435
+1436
+1437
+1438
+1439
+1440
+1441
+1442
+1443
+1444
+1445
+1446
+1447
+1448
+1449
+1450
+1451
+1452
+1453
+1454
+1455
+1456
+1457
+1458
+1459
+1460
+1461
+1462
+1463
+1464
+1465
+1466
+1467
+1468
+1469
+1470
+1471
+1472
+1473
+1474
+1475
+1476
+1477
+1478
+1479
+1480
+1481
+1482
+1483
+1484
+1485
+1486
+1487
+1488
+1489
+1490
+1491
+1492
+1493
+1494
+1495
+1496
+1497
+1498
+1499
+1500
+1501
+1502
+1503
+1504
+1505
+1506
+1507
+1508
+1509
+1510
+1511
+1512
+1513
+1514
+1515
+1516
+1517
+1518
+1519
+1520
+1521
+1522
+1523
+1524
+1525
+1526
+1527
+1528
+1529
+1530
+1531
+1532
+1533
+1534
+1535
+1536
+1537
+1538
+1539
+1540
+1541
+1542
+1543
+1544
+1545
+1546
+1547
+1548
+1549
+1550
+1551
+1552
+1553
+1554
+1555
+1556
+1557
+1558
+1559
+1560
+1561
+1562
+1563
+1564
+1565
+1566
+1567
+1568
+1569
+1570
+1571
+1572
+1573
+1574
+1575
+1576
+1577
+1578
+1579
+1580
+1581
+1582
+1583
+1584
+1585
+1586
+1587
+1588
+1589
+1590
+1591
+1592
+1593
+1594
+1595
+1596
+1597
+1598
+1599
+1600
+1601
+1602
+1603
+1604
+1605
+1606
+1607
+1608
+1609
+1610
+1611
+1612
+1613
+1614
+1615
+1616
+1617
+1618
+1619
+1620
+1621
+1622
+1623
+1624
+1625
+1626
+1627
+1628
+1629
+1630
+1631
+1632
+1633
+1634
+1635
+1636
+1637
+1638
+1639
+1640
+1641
+1642
+1643
+1644
+1645
+1646
+1647
+1648
+1649
+1650
+1651
+1652
+1653
+1654
+1655
+1656
+1657
+1658
+1659
+1660
+1661
+1662
+1663
+1664
+1665
+1666
+1667
+1668
+1669
+1670
+1671
+1672
+1673
+1674
+1675
+1676
+1677
+1678
+1679
+1680
+1681
+1682
+1683
+1684
+1685
+1686
+1687
+1688
+1689
+1690
+1691
+1692
+1693
+1694
+1695
+1696
+1697
+1698
+1699
+1700
+1701
+1702
+1703
+1704
+1705
+
//! This library implements Nova, a high-speed recursive SNARK.
+#![deny(
+  warnings,
+  unused,
+  future_incompatible,
+  nonstandard_style,
+  rust_2018_idioms,
+  missing_docs
+)]
+#![allow(non_snake_case)]
+// #![forbid(unsafe_code)] // Commented for development with `Abomonation`
+
+// private modules
+mod bellpepper;
+mod circuit;
+mod digest;
+mod nifs;
+
+// public modules
+pub mod constants;
+pub mod errors;
+pub mod gadgets;
+pub mod provider;
+pub mod r1cs;
+pub mod spartan;
+pub mod traits;
+
+pub mod supernova;
+
+use once_cell::sync::OnceCell;
+
+use crate::digest::{DigestComputer, SimpleDigestible};
+use crate::{
+  bellpepper::{
+    r1cs::{NovaShape, NovaWitness},
+    shape_cs::ShapeCS,
+    solver::SatisfyingAssignment,
+  },
+  r1cs::R1CSResult,
+};
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use bellpepper_core::{ConstraintSystem, SynthesisError};
+use circuit::{NovaAugmentedCircuit, NovaAugmentedCircuitInputs, NovaAugmentedCircuitParams};
+use constants::{BN_LIMB_WIDTH, BN_N_LIMBS, NUM_FE_WITHOUT_IO_FOR_CRHF, NUM_HASH_BITS};
+use core::marker::PhantomData;
+use errors::NovaError;
+use ff::{Field, PrimeField};
+use gadgets::utils::scalar_as_base;
+use nifs::NIFS;
+use r1cs::{
+  CommitmentKeyHint, R1CSInstance, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness,
+};
+use serde::{Deserialize, Serialize};
+use traits::{
+  circuit::StepCircuit,
+  commitment::{CommitmentEngineTrait, CommitmentTrait},
+  snark::RelaxedR1CSSNARKTrait,
+  AbsorbInROTrait, Engine, ROConstants, ROConstantsCircuit, ROTrait,
+};
+
+/// A type that holds parameters for the primary and secondary circuits of Nova and SuperNova
+#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as PrimeField>::Repr: Abomonation)]
+pub struct R1CSWithArity<E: Engine> {
+  F_arity: usize,
+  r1cs_shape: R1CSShape<E>,
+}
+
+impl<E: Engine> SimpleDigestible for R1CSWithArity<E> {}
+
+impl<E: Engine> R1CSWithArity<E> {
+  /// Create a new `R1CSWithArity`
+  pub fn new(r1cs_shape: R1CSShape<E>, F_arity: usize) -> Self {
+    Self {
+      F_arity,
+      r1cs_shape,
+    }
+  }
+
+  /// Return the [R1CSWithArity]' digest.
+  pub fn digest(&self) -> E::Scalar {
+    let dc: DigestComputer<'_, <E as Engine>::Scalar, Self> = DigestComputer::new(self);
+    dc.digest().expect("Failure in computing digest")
+  }
+}
+
+/// A type that holds public parameters of Nova
+#[derive(Clone, PartialEq, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  <E1::Scalar as PrimeField>::Repr: Abomonation,
+  <E2::Scalar as PrimeField>::Repr: Abomonation,
+)]
+pub struct PublicParams<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  F_arity_primary: usize,
+  F_arity_secondary: usize,
+  ro_consts_primary: ROConstants<E1>,
+  ro_consts_circuit_primary: ROConstantsCircuit<E2>,
+  ck_primary: CommitmentKey<E1>,
+  circuit_shape_primary: R1CSWithArity<E1>,
+  ro_consts_secondary: ROConstants<E2>,
+  ro_consts_circuit_secondary: ROConstantsCircuit<E1>,
+  ck_secondary: CommitmentKey<E2>,
+  circuit_shape_secondary: R1CSWithArity<E2>,
+  augmented_circuit_params_primary: NovaAugmentedCircuitParams,
+  augmented_circuit_params_secondary: NovaAugmentedCircuitParams,
+  #[abomonation_skip]
+  #[serde(skip, default = "OnceCell::new")]
+  digest: OnceCell<E1::Scalar>,
+  _p: PhantomData<(C1, C2)>,
+}
+
+impl<E1, E2, C1, C2> SimpleDigestible for PublicParams<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+}
+
+impl<E1, E2, C1, C2> PublicParams<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  /// Set up builder to create `PublicParams` for a pair of circuits `C1` and `C2`.
+  ///
+  /// # Note
+  ///
+  /// Public parameters set up a number of bases for the homomorphic commitment scheme of Nova.
+  ///
+  /// Some final compressing SNARKs, like variants of Spartan, use computation commitments that require
+  /// larger sizes for these parameters. These SNARKs provide a hint for these values by
+  /// implementing `RelaxedR1CSSNARKTrait::ck_floor()`, which can be passed to this function.
+  ///
+  /// If you're not using such a SNARK, pass `arecibo::traits::snark::default_ck_hint()` instead.
+  ///
+  /// # Arguments
+  ///
+  /// * `c_primary`: The primary circuit of type `C1`.
+  /// * `c_secondary`: The secondary circuit of type `C2`.
+  /// * `ck_hint1`: A `CommitmentKeyHint` for `G1`, which is a function that provides a hint
+  ///   for the number of generators required in the commitment scheme for the primary circuit.
+  /// * `ck_hint2`: A `CommitmentKeyHint` for `G2`, similar to `ck_hint1`, but for the secondary circuit.
+  ///
+  /// # Example
+  ///
+  /// ```rust
+  /// # use arecibo::spartan::ppsnark::RelaxedR1CSSNARK;
+  /// # use arecibo::provider::ipa_pc::EvaluationEngine;
+  /// # use arecibo::provider::{PallasEngine, VestaEngine};
+  /// # use arecibo::traits::{circuit::TrivialCircuit, Engine, snark::RelaxedR1CSSNARKTrait};
+  /// use arecibo::PublicParams;
+  ///
+  /// type E1 = PallasEngine;
+  /// type E2 = VestaEngine;
+  /// type EE<E> = EvaluationEngine<E>;
+  /// type SPrime<E> = RelaxedR1CSSNARK<E, EE<E>>;
+  ///
+  /// let circuit1 = TrivialCircuit::<<E1 as Engine>::Scalar>::default();
+  /// let circuit2 = TrivialCircuit::<<E2 as Engine>::Scalar>::default();
+  /// // Only relevant for a SNARK using computation commitmnets, pass &(|_| 0)
+  /// // or &*nova_snark::traits::snark::default_ck_hint() otherwise.
+  /// let ck_hint1 = &*SPrime::<E1>::ck_floor();
+  /// let ck_hint2 = &*SPrime::<E2>::ck_floor();
+  ///
+  /// let pp = PublicParams::setup(&circuit1, &circuit2, ck_hint1, ck_hint2);
+  /// ```
+  pub fn setup(
+    c_primary: &C1,
+    c_secondary: &C2,
+    ck_hint1: &CommitmentKeyHint<E1>,
+    ck_hint2: &CommitmentKeyHint<E2>,
+  ) -> Self {
+    let augmented_circuit_params_primary =
+      NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+    let augmented_circuit_params_secondary =
+      NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
+
+    let ro_consts_primary: ROConstants<E1> = ROConstants::<E1>::default();
+    let ro_consts_secondary: ROConstants<E2> = ROConstants::<E2>::default();
+
+    let F_arity_primary = c_primary.arity();
+    let F_arity_secondary = c_secondary.arity();
+
+    // ro_consts_circuit_primary are parameterized by E2 because the type alias uses E2::Base = E1::Scalar
+    let ro_consts_circuit_primary: ROConstantsCircuit<E2> = ROConstantsCircuit::<E2>::default();
+    let ro_consts_circuit_secondary: ROConstantsCircuit<E1> = ROConstantsCircuit::<E1>::default();
+
+    // Initialize ck for the primary
+    let circuit_primary: NovaAugmentedCircuit<'_, E2, C1> = NovaAugmentedCircuit::new(
+      &augmented_circuit_params_primary,
+      None,
+      c_primary,
+      ro_consts_circuit_primary.clone(),
+    );
+    let mut cs: ShapeCS<E1> = ShapeCS::new();
+    let _ = circuit_primary.synthesize(&mut cs);
+    let (r1cs_shape_primary, ck_primary) = cs.r1cs_shape_and_key(ck_hint1);
+    let circuit_shape_primary = R1CSWithArity::new(r1cs_shape_primary, F_arity_primary);
+
+    // Initialize ck for the secondary
+    let circuit_secondary: NovaAugmentedCircuit<'_, E1, C2> = NovaAugmentedCircuit::new(
+      &augmented_circuit_params_secondary,
+      None,
+      c_secondary,
+      ro_consts_circuit_secondary.clone(),
+    );
+    let mut cs: ShapeCS<E2> = ShapeCS::new();
+    let _ = circuit_secondary.synthesize(&mut cs);
+    let (r1cs_shape_secondary, ck_secondary) = cs.r1cs_shape_and_key(ck_hint2);
+    let circuit_shape_secondary = R1CSWithArity::new(r1cs_shape_secondary, F_arity_secondary);
+
+    Self {
+      F_arity_primary,
+      F_arity_secondary,
+      ro_consts_primary,
+      ro_consts_circuit_primary,
+      ck_primary,
+      circuit_shape_primary,
+      ro_consts_secondary,
+      ro_consts_circuit_secondary,
+      ck_secondary,
+      circuit_shape_secondary,
+      augmented_circuit_params_primary,
+      augmented_circuit_params_secondary,
+      digest: OnceCell::new(),
+      _p: Default::default(),
+    }
+  }
+
+  /// Retrieve the digest of the public parameters.
+  pub fn digest(&self) -> E1::Scalar {
+    self
+      .digest
+      .get_or_try_init(|| DigestComputer::new(self).digest())
+      .cloned()
+      .expect("Failure in retrieving digest")
+  }
+
+  /// Returns the number of constraints in the primary and secondary circuits
+  pub const fn num_constraints(&self) -> (usize, usize) {
+    (
+      self.circuit_shape_primary.r1cs_shape.num_cons,
+      self.circuit_shape_secondary.r1cs_shape.num_cons,
+    )
+  }
+
+  /// Returns the number of variables in the primary and secondary circuits
+  pub const fn num_variables(&self) -> (usize, usize) {
+    (
+      self.circuit_shape_primary.r1cs_shape.num_vars,
+      self.circuit_shape_secondary.r1cs_shape.num_vars,
+    )
+  }
+}
+
+/// A resource buffer for [`RecursiveSNARK`] for storing scratch values that are computed by `prove_step`,
+/// which allows the reuse of memory allocations and avoids unnecessary new allocations in the critical section.
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct ResourceBuffer<E: Engine> {
+  l_w: Option<R1CSWitness<E>>,
+  l_u: Option<R1CSInstance<E>>,
+
+  ABC_Z_1: R1CSResult<E>,
+  ABC_Z_2: R1CSResult<E>,
+
+  /// buffer for `commit_T`
+  T: Vec<E::Scalar>,
+}
+
+/// A SNARK that proves the correct execution of an incremental computation
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct RecursiveSNARK<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  z0_primary: Vec<E1::Scalar>,
+  z0_secondary: Vec<E2::Scalar>,
+  r_W_primary: RelaxedR1CSWitness<E1>,
+  r_U_primary: RelaxedR1CSInstance<E1>,
+  r_W_secondary: RelaxedR1CSWitness<E2>,
+  r_U_secondary: RelaxedR1CSInstance<E2>,
+  l_w_secondary: R1CSWitness<E2>,
+  l_u_secondary: R1CSInstance<E2>,
+
+  /// Buffer for memory needed by the primary fold-step
+  buffer_primary: ResourceBuffer<E1>,
+  /// Buffer for memory needed by the secondary fold-step
+  buffer_secondary: ResourceBuffer<E2>,
+
+  i: usize,
+  zi_primary: Vec<E1::Scalar>,
+  zi_secondary: Vec<E2::Scalar>,
+  _p: PhantomData<(C1, C2)>,
+}
+
+impl<E1, E2, C1, C2> RecursiveSNARK<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  /// Create new instance of recursive SNARK
+  pub fn new(
+    pp: &PublicParams<E1, E2, C1, C2>,
+    c_primary: &C1,
+    c_secondary: &C2,
+    z0_primary: &[E1::Scalar],
+    z0_secondary: &[E2::Scalar],
+  ) -> Result<Self, NovaError> {
+    if z0_primary.len() != pp.F_arity_primary || z0_secondary.len() != pp.F_arity_secondary {
+      return Err(NovaError::InvalidInitialInputLength);
+    }
+
+    let r1cs_primary = &pp.circuit_shape_primary.r1cs_shape;
+    let r1cs_secondary = &pp.circuit_shape_secondary.r1cs_shape;
+
+    // base case for the primary
+    let mut cs_primary = SatisfyingAssignment::<E1>::new();
+    let inputs_primary: NovaAugmentedCircuitInputs<E2> = NovaAugmentedCircuitInputs::new(
+      scalar_as_base::<E1>(pp.digest()),
+      E1::Scalar::ZERO,
+      z0_primary.to_vec(),
+      None,
+      None,
+      None,
+      None,
+    );
+
+    let circuit_primary: NovaAugmentedCircuit<'_, E2, C1> = NovaAugmentedCircuit::new(
+      &pp.augmented_circuit_params_primary,
+      Some(inputs_primary),
+      c_primary,
+      pp.ro_consts_circuit_primary.clone(),
+    );
+    let zi_primary = circuit_primary.synthesize(&mut cs_primary)?;
+    let (u_primary, w_primary) =
+      cs_primary.r1cs_instance_and_witness(r1cs_primary, &pp.ck_primary)?;
+
+    // base case for the secondary
+    let mut cs_secondary = SatisfyingAssignment::<E2>::new();
+    let inputs_secondary: NovaAugmentedCircuitInputs<E1> = NovaAugmentedCircuitInputs::new(
+      pp.digest(),
+      E2::Scalar::ZERO,
+      z0_secondary.to_vec(),
+      None,
+      None,
+      Some(u_primary.clone()),
+      None,
+    );
+    let circuit_secondary: NovaAugmentedCircuit<'_, E1, C2> = NovaAugmentedCircuit::new(
+      &pp.augmented_circuit_params_secondary,
+      Some(inputs_secondary),
+      c_secondary,
+      pp.ro_consts_circuit_secondary.clone(),
+    );
+    let zi_secondary = circuit_secondary.synthesize(&mut cs_secondary)?;
+    let (u_secondary, w_secondary) = cs_secondary
+      .r1cs_instance_and_witness(&pp.circuit_shape_secondary.r1cs_shape, &pp.ck_secondary)?;
+
+    // IVC proof for the primary circuit
+    let l_w_primary = w_primary;
+    let l_u_primary = u_primary;
+    let r_W_primary = RelaxedR1CSWitness::from_r1cs_witness(r1cs_primary, l_w_primary);
+    let r_U_primary = RelaxedR1CSInstance::from_r1cs_instance(
+      &pp.ck_primary,
+      &pp.circuit_shape_primary.r1cs_shape,
+      l_u_primary,
+    );
+
+    // IVC proof for the secondary circuit
+    let l_w_secondary = w_secondary;
+    let l_u_secondary = u_secondary;
+    let r_W_secondary = RelaxedR1CSWitness::<E2>::default(r1cs_secondary);
+    let r_U_secondary = RelaxedR1CSInstance::<E2>::default(&pp.ck_secondary, r1cs_secondary);
+
+    assert!(
+      !(zi_primary.len() != pp.F_arity_primary || zi_secondary.len() != pp.F_arity_secondary),
+      "Invalid step length"
+    );
+
+    let zi_primary = zi_primary
+      .iter()
+      .map(|v| v.get_value().ok_or(SynthesisError::AssignmentMissing))
+      .collect::<Result<Vec<<E1 as Engine>::Scalar>, _>>()?;
+
+    let zi_secondary = zi_secondary
+      .iter()
+      .map(|v| v.get_value().ok_or(SynthesisError::AssignmentMissing))
+      .collect::<Result<Vec<<E2 as Engine>::Scalar>, _>>()?;
+
+    let buffer_primary = ResourceBuffer {
+      l_w: None,
+      l_u: None,
+      ABC_Z_1: R1CSResult::default(r1cs_primary.num_cons),
+      ABC_Z_2: R1CSResult::default(r1cs_primary.num_cons),
+      T: r1cs::default_T::<E1>(r1cs_primary.num_cons),
+    };
+
+    let buffer_secondary = ResourceBuffer {
+      l_w: None,
+      l_u: None,
+      ABC_Z_1: R1CSResult::default(r1cs_secondary.num_cons),
+      ABC_Z_2: R1CSResult::default(r1cs_secondary.num_cons),
+      T: r1cs::default_T::<E2>(r1cs_secondary.num_cons),
+    };
+
+    Ok(Self {
+      z0_primary: z0_primary.to_vec(),
+      z0_secondary: z0_secondary.to_vec(),
+      r_W_primary,
+      r_U_primary,
+      r_W_secondary,
+      r_U_secondary,
+      l_w_secondary,
+      l_u_secondary,
+
+      buffer_primary,
+      buffer_secondary,
+      i: 0,
+      zi_primary,
+      zi_secondary,
+      _p: Default::default(),
+    })
+  }
+
+  /// Create a new `RecursiveSNARK` (or updates the provided `RecursiveSNARK`)
+  /// by executing a step of the incremental computation
+  #[tracing::instrument(skip_all, name = "nova::RecursiveSNARK::prove_step")]
+  pub fn prove_step(
+    &mut self,
+    pp: &PublicParams<E1, E2, C1, C2>,
+    c_primary: &C1,
+    c_secondary: &C2,
+  ) -> Result<(), NovaError> {
+    // first step was already done in the constructor
+    if self.i == 0 {
+      self.i = 1;
+      return Ok(());
+    }
+
+    // save the inputs before proceeding to the `i+1`th step
+    let r_U_primary_i = self.r_U_primary.clone();
+    let r_U_secondary_i = self.r_U_secondary.clone();
+    let l_u_secondary_i = self.l_u_secondary.clone();
+
+    // fold the secondary circuit's instance
+    let nifs_secondary = NIFS::prove_mut(
+      &pp.ck_secondary,
+      &pp.ro_consts_secondary,
+      &scalar_as_base::<E1>(pp.digest()),
+      &pp.circuit_shape_secondary.r1cs_shape,
+      &mut self.r_U_secondary,
+      &mut self.r_W_secondary,
+      &self.l_u_secondary,
+      &self.l_w_secondary,
+      &mut self.buffer_secondary.T,
+      &mut self.buffer_secondary.ABC_Z_1,
+      &mut self.buffer_secondary.ABC_Z_2,
+    )?;
+
+    let mut cs_primary = SatisfyingAssignment::<E1>::with_capacity(
+      pp.circuit_shape_primary.r1cs_shape.num_io + 1,
+      pp.circuit_shape_primary.r1cs_shape.num_vars,
+    );
+    let inputs_primary: NovaAugmentedCircuitInputs<E2> = NovaAugmentedCircuitInputs::new(
+      scalar_as_base::<E1>(pp.digest()),
+      E1::Scalar::from(self.i as u64),
+      self.z0_primary.to_vec(),
+      Some(self.zi_primary.clone()),
+      Some(r_U_secondary_i),
+      Some(l_u_secondary_i),
+      Some(Commitment::<E2>::decompress(&nifs_secondary.comm_T)?),
+    );
+
+    let circuit_primary: NovaAugmentedCircuit<'_, E2, C1> = NovaAugmentedCircuit::new(
+      &pp.augmented_circuit_params_primary,
+      Some(inputs_primary),
+      c_primary,
+      pp.ro_consts_circuit_primary.clone(),
+    );
+
+    let zi_primary = circuit_primary.synthesize(&mut cs_primary)?;
+
+    let (l_u_primary, l_w_primary) =
+      cs_primary.r1cs_instance_and_witness(&pp.circuit_shape_primary.r1cs_shape, &pp.ck_primary)?;
+
+    // fold the primary circuit's instance
+    let nifs_primary = NIFS::prove_mut(
+      &pp.ck_primary,
+      &pp.ro_consts_primary,
+      &pp.digest(),
+      &pp.circuit_shape_primary.r1cs_shape,
+      &mut self.r_U_primary,
+      &mut self.r_W_primary,
+      &l_u_primary,
+      &l_w_primary,
+      &mut self.buffer_primary.T,
+      &mut self.buffer_primary.ABC_Z_1,
+      &mut self.buffer_primary.ABC_Z_2,
+    )?;
+
+    let mut cs_secondary = SatisfyingAssignment::<E2>::with_capacity(
+      pp.circuit_shape_secondary.r1cs_shape.num_io + 1,
+      pp.circuit_shape_secondary.r1cs_shape.num_vars,
+    );
+    let inputs_secondary: NovaAugmentedCircuitInputs<E1> = NovaAugmentedCircuitInputs::new(
+      pp.digest(),
+      E2::Scalar::from(self.i as u64),
+      self.z0_secondary.to_vec(),
+      Some(self.zi_secondary.clone()),
+      Some(r_U_primary_i),
+      Some(l_u_primary),
+      Some(Commitment::<E1>::decompress(&nifs_primary.comm_T)?),
+    );
+
+    let circuit_secondary: NovaAugmentedCircuit<'_, E1, C2> = NovaAugmentedCircuit::new(
+      &pp.augmented_circuit_params_secondary,
+      Some(inputs_secondary),
+      c_secondary,
+      pp.ro_consts_circuit_secondary.clone(),
+    );
+    let zi_secondary = circuit_secondary.synthesize(&mut cs_secondary)?;
+
+    let (l_u_secondary, l_w_secondary) = cs_secondary
+      .r1cs_instance_and_witness(&pp.circuit_shape_secondary.r1cs_shape, &pp.ck_secondary)
+      .map_err(|_e| NovaError::UnSat)?;
+
+    // update the running instances and witnesses
+    self.zi_primary = zi_primary
+      .iter()
+      .map(|v| v.get_value().ok_or(SynthesisError::AssignmentMissing))
+      .collect::<Result<Vec<<E1 as Engine>::Scalar>, _>>()?;
+    self.zi_secondary = zi_secondary
+      .iter()
+      .map(|v| v.get_value().ok_or(SynthesisError::AssignmentMissing))
+      .collect::<Result<Vec<<E2 as Engine>::Scalar>, _>>()?;
+
+    self.l_u_secondary = l_u_secondary;
+    self.l_w_secondary = l_w_secondary;
+
+    self.i += 1;
+
+    Ok(())
+  }
+
+  /// Verify the correctness of the `RecursiveSNARK`
+  pub fn verify(
+    &self,
+    pp: &PublicParams<E1, E2, C1, C2>,
+    num_steps: usize,
+    z0_primary: &[E1::Scalar],
+    z0_secondary: &[E2::Scalar],
+  ) -> Result<(Vec<E1::Scalar>, Vec<E2::Scalar>), NovaError> {
+    // number of steps cannot be zero
+    let is_num_steps_zero = num_steps == 0;
+
+    // check if the provided proof has executed num_steps
+    let is_num_steps_not_match = self.i != num_steps;
+
+    // check if the initial inputs match
+    let is_inputs_not_match = self.z0_primary != z0_primary || self.z0_secondary != z0_secondary;
+
+    // check if the (relaxed) R1CS instances have two public outputs
+    let is_instance_has_two_outpus = self.l_u_secondary.X.len() != 2
+      || self.r_U_primary.X.len() != 2
+      || self.r_U_secondary.X.len() != 2;
+
+    if is_num_steps_zero
+      || is_num_steps_not_match
+      || is_inputs_not_match
+      || is_instance_has_two_outpus
+    {
+      return Err(NovaError::ProofVerifyError);
+    }
+
+    // check if the output hashes in R1CS instances point to the right running instances
+    let (hash_primary, hash_secondary) = {
+      let mut hasher = <E2 as Engine>::RO::new(
+        pp.ro_consts_secondary.clone(),
+        NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_primary,
+      );
+      hasher.absorb(pp.digest());
+      hasher.absorb(E1::Scalar::from(num_steps as u64));
+      for e in z0_primary {
+        hasher.absorb(*e);
+      }
+      for e in &self.zi_primary {
+        hasher.absorb(*e);
+      }
+      self.r_U_secondary.absorb_in_ro(&mut hasher);
+
+      let mut hasher2 = <E1 as Engine>::RO::new(
+        pp.ro_consts_primary.clone(),
+        NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * pp.F_arity_secondary,
+      );
+      hasher2.absorb(scalar_as_base::<E1>(pp.digest()));
+      hasher2.absorb(E2::Scalar::from(num_steps as u64));
+      for e in z0_secondary {
+        hasher2.absorb(*e);
+      }
+      for e in &self.zi_secondary {
+        hasher2.absorb(*e);
+      }
+      self.r_U_primary.absorb_in_ro(&mut hasher2);
+
+      (
+        hasher.squeeze(NUM_HASH_BITS),
+        hasher2.squeeze(NUM_HASH_BITS),
+      )
+    };
+
+    if hash_primary != self.l_u_secondary.X[0]
+      || hash_secondary != scalar_as_base::<E2>(self.l_u_secondary.X[1])
+    {
+      return Err(NovaError::ProofVerifyError);
+    }
+
+    // check the satisfiability of the provided instances
+    let (res_r_primary, (res_r_secondary, res_l_secondary)) = rayon::join(
+      || {
+        pp.circuit_shape_primary.r1cs_shape.is_sat_relaxed(
+          &pp.ck_primary,
+          &self.r_U_primary,
+          &self.r_W_primary,
+        )
+      },
+      || {
+        rayon::join(
+          || {
+            pp.circuit_shape_secondary.r1cs_shape.is_sat_relaxed(
+              &pp.ck_secondary,
+              &self.r_U_secondary,
+              &self.r_W_secondary,
+            )
+          },
+          || {
+            pp.circuit_shape_secondary.r1cs_shape.is_sat(
+              &pp.ck_secondary,
+              &self.l_u_secondary,
+              &self.l_w_secondary,
+            )
+          },
+        )
+      },
+    );
+
+    // check the returned res objects
+    res_r_primary?;
+    res_r_secondary?;
+    res_l_secondary?;
+
+    Ok((self.zi_primary.clone(), self.zi_secondary.clone()))
+  }
+
+  /// Get the outputs after the last step of computation.
+  pub fn outputs(&self) -> (&[E1::Scalar], &[E2::Scalar]) {
+    (&self.zi_primary, &self.zi_secondary)
+  }
+
+  /// The number of steps which have been executed thus far.
+  pub fn num_steps(&self) -> usize {
+    self.i
+  }
+}
+
+/// A type that holds the prover key for `CompressedSNARK`
+#[derive(Clone, Debug, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_omit_bounds]
+pub struct ProverKey<E1, E2, C1, C2, S1, S2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  S1: RelaxedR1CSSNARKTrait<E1>,
+  S2: RelaxedR1CSSNARKTrait<E2>,
+{
+  pk_primary: S1::ProverKey,
+  pk_secondary: S2::ProverKey,
+  _p: PhantomData<(C1, C2)>,
+}
+
+/// A type that holds the verifier key for `CompressedSNARK`
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: RelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+  )]
+pub struct VerifierKey<E1, E2, C1, C2, S1, S2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  S1: RelaxedR1CSSNARKTrait<E1>,
+  S2: RelaxedR1CSSNARKTrait<E2>,
+{
+  F_arity_primary: usize,
+  F_arity_secondary: usize,
+  ro_consts_primary: ROConstants<E1>,
+  ro_consts_secondary: ROConstants<E2>,
+  #[abomonate_with(<E1::Scalar as PrimeField>::Repr)]
+  pp_digest: E1::Scalar,
+  vk_primary: S1::VerifierKey,
+  vk_secondary: S2::VerifierKey,
+  _p: PhantomData<(C1, C2)>,
+}
+
+/// A SNARK that proves the knowledge of a valid `RecursiveSNARK`
+#[derive(Clone, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct CompressedSNARK<E1, E2, C1, C2, S1, S2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  S1: RelaxedR1CSSNARKTrait<E1>,
+  S2: RelaxedR1CSSNARKTrait<E2>,
+{
+  r_U_primary: RelaxedR1CSInstance<E1>,
+  r_W_snark_primary: S1,
+
+  r_U_secondary: RelaxedR1CSInstance<E2>,
+  l_u_secondary: R1CSInstance<E2>,
+  nifs_secondary: NIFS<E2>,
+  f_W_snark_secondary: S2,
+
+  zn_primary: Vec<E1::Scalar>,
+  zn_secondary: Vec<E2::Scalar>,
+
+  _p: PhantomData<(C1, C2)>,
+}
+
+impl<E1, E2, C1, C2, S1, S2> CompressedSNARK<E1, E2, C1, C2, S1, S2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  S1: RelaxedR1CSSNARKTrait<E1>,
+  S2: RelaxedR1CSSNARKTrait<E2>,
+{
+  /// Creates prover and verifier keys for `CompressedSNARK`
+  pub fn setup(
+    pp: &PublicParams<E1, E2, C1, C2>,
+  ) -> Result<
+    (
+      ProverKey<E1, E2, C1, C2, S1, S2>,
+      VerifierKey<E1, E2, C1, C2, S1, S2>,
+    ),
+    NovaError,
+  > {
+    let (pk_primary, vk_primary) = S1::setup(&pp.ck_primary, &pp.circuit_shape_primary.r1cs_shape)?;
+    let (pk_secondary, vk_secondary) =
+      S2::setup(&pp.ck_secondary, &pp.circuit_shape_secondary.r1cs_shape)?;
+
+    let pk = ProverKey {
+      pk_primary,
+      pk_secondary,
+      _p: Default::default(),
+    };
+
+    let vk = VerifierKey {
+      F_arity_primary: pp.F_arity_primary,
+      F_arity_secondary: pp.F_arity_secondary,
+      ro_consts_primary: pp.ro_consts_primary.clone(),
+      ro_consts_secondary: pp.ro_consts_secondary.clone(),
+      pp_digest: pp.digest(),
+      vk_primary,
+      vk_secondary,
+      _p: Default::default(),
+    };
+
+    Ok((pk, vk))
+  }
+
+  /// Create a new `CompressedSNARK`
+  pub fn prove(
+    pp: &PublicParams<E1, E2, C1, C2>,
+    pk: &ProverKey<E1, E2, C1, C2, S1, S2>,
+    recursive_snark: &RecursiveSNARK<E1, E2, C1, C2>,
+  ) -> Result<Self, NovaError> {
+    // fold the secondary circuit's instance with its running instance
+    let (nifs_secondary, (f_U_secondary, f_W_secondary)) = NIFS::prove(
+      &pp.ck_secondary,
+      &pp.ro_consts_secondary,
+      &scalar_as_base::<E1>(pp.digest()),
+      &pp.circuit_shape_secondary.r1cs_shape,
+      &recursive_snark.r_U_secondary,
+      &recursive_snark.r_W_secondary,
+      &recursive_snark.l_u_secondary,
+      &recursive_snark.l_w_secondary,
+    )?;
+
+    // create SNARKs proving the knowledge of f_W_primary and f_W_secondary
+    let (r_W_snark_primary, f_W_snark_secondary) = rayon::join(
+      || {
+        S1::prove(
+          &pp.ck_primary,
+          &pk.pk_primary,
+          &pp.circuit_shape_primary.r1cs_shape,
+          &recursive_snark.r_U_primary,
+          &recursive_snark.r_W_primary,
+        )
+      },
+      || {
+        S2::prove(
+          &pp.ck_secondary,
+          &pk.pk_secondary,
+          &pp.circuit_shape_secondary.r1cs_shape,
+          &f_U_secondary,
+          &f_W_secondary,
+        )
+      },
+    );
+
+    Ok(Self {
+      r_U_primary: recursive_snark.r_U_primary.clone(),
+      r_W_snark_primary: r_W_snark_primary?,
+
+      r_U_secondary: recursive_snark.r_U_secondary.clone(),
+      l_u_secondary: recursive_snark.l_u_secondary.clone(),
+      nifs_secondary,
+      f_W_snark_secondary: f_W_snark_secondary?,
+
+      zn_primary: recursive_snark.zi_primary.clone(),
+      zn_secondary: recursive_snark.zi_secondary.clone(),
+
+      _p: Default::default(),
+    })
+  }
+
+  /// Verify the correctness of the `CompressedSNARK`
+  pub fn verify(
+    &self,
+    vk: &VerifierKey<E1, E2, C1, C2, S1, S2>,
+    num_steps: usize,
+    z0_primary: &[E1::Scalar],
+    z0_secondary: &[E2::Scalar],
+  ) -> Result<(Vec<E1::Scalar>, Vec<E2::Scalar>), NovaError> {
+    // the number of steps cannot be zero
+    if num_steps == 0 {
+      return Err(NovaError::ProofVerifyError);
+    }
+
+    // check if the (relaxed) R1CS instances have two public outputs
+    if self.l_u_secondary.X.len() != 2
+      || self.r_U_primary.X.len() != 2
+      || self.r_U_secondary.X.len() != 2
+    {
+      return Err(NovaError::ProofVerifyError);
+    }
+
+    // check if the output hashes in R1CS instances point to the right running instances
+    let (hash_primary, hash_secondary) = {
+      let mut hasher = <E2 as Engine>::RO::new(
+        vk.ro_consts_secondary.clone(),
+        NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * vk.F_arity_primary,
+      );
+      hasher.absorb(vk.pp_digest);
+      hasher.absorb(E1::Scalar::from(num_steps as u64));
+      for e in z0_primary {
+        hasher.absorb(*e);
+      }
+      for e in &self.zn_primary {
+        hasher.absorb(*e);
+      }
+      self.r_U_secondary.absorb_in_ro(&mut hasher);
+
+      let mut hasher2 = <E1 as Engine>::RO::new(
+        vk.ro_consts_primary.clone(),
+        NUM_FE_WITHOUT_IO_FOR_CRHF + 2 * vk.F_arity_secondary,
+      );
+      hasher2.absorb(scalar_as_base::<E1>(vk.pp_digest));
+      hasher2.absorb(E2::Scalar::from(num_steps as u64));
+      for e in z0_secondary {
+        hasher2.absorb(*e);
+      }
+      for e in &self.zn_secondary {
+        hasher2.absorb(*e);
+      }
+      self.r_U_primary.absorb_in_ro(&mut hasher2);
+
+      (
+        hasher.squeeze(NUM_HASH_BITS),
+        hasher2.squeeze(NUM_HASH_BITS),
+      )
+    };
+
+    if hash_primary != self.l_u_secondary.X[0]
+      || hash_secondary != scalar_as_base::<E2>(self.l_u_secondary.X[1])
+    {
+      return Err(NovaError::ProofVerifyError);
+    }
+
+    // fold the secondary's running instance with the last instance to get a folded instance
+    let f_U_secondary = self.nifs_secondary.verify(
+      &vk.ro_consts_secondary,
+      &scalar_as_base::<E1>(vk.pp_digest),
+      &self.r_U_secondary,
+      &self.l_u_secondary,
+    )?;
+
+    // check the satisfiability of the folded instances using
+    // SNARKs proving the knowledge of their satisfying witnesses
+    let (res_primary, res_secondary) = rayon::join(
+      || {
+        self
+          .r_W_snark_primary
+          .verify(&vk.vk_primary, &self.r_U_primary)
+      },
+      || {
+        self
+          .f_W_snark_secondary
+          .verify(&vk.vk_secondary, &f_U_secondary)
+      },
+    );
+
+    res_primary?;
+    res_secondary?;
+
+    Ok((self.zn_primary.clone(), self.zn_secondary.clone()))
+  }
+}
+
+/// Compute the circuit digest of a [StepCircuit].
+///
+/// Note for callers: This function should be called with its performance characteristics in mind.
+/// It will synthesize and digest the full `circuit` given.
+pub fn circuit_digest<
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C: StepCircuit<E1::Scalar>,
+>(
+  circuit: &C,
+) -> E1::Scalar {
+  let augmented_circuit_params = NovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+
+  // ro_consts_circuit are parameterized by G2 because the type alias uses G2::Base = G1::Scalar
+  let ro_consts_circuit: ROConstantsCircuit<E2> = ROConstantsCircuit::<E2>::default();
+
+  // Initialize ck for the primary
+  let augmented_circuit: NovaAugmentedCircuit<'_, E2, C> =
+    NovaAugmentedCircuit::new(&augmented_circuit_params, None, circuit, ro_consts_circuit);
+  let mut cs: ShapeCS<E1> = ShapeCS::new();
+  let _ = augmented_circuit.synthesize(&mut cs);
+  cs.r1cs_shape().digest()
+}
+
+type CommitmentKey<E> = <<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey;
+type Commitment<E> = <<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment;
+type CompressedCommitment<E> = <<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment;
+type CE<E> = <E as Engine>::CE;
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::{
+    provider::{
+      non_hiding_zeromorph::ZMPCS, traits::DlogGroup, Bn256Engine, Bn256EngineKZG, Bn256EngineZM,
+      GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine,
+    },
+    traits::{evaluation::EvaluationEngineTrait, snark::default_ck_hint},
+  };
+  use ::bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError};
+  use core::{fmt::Write, marker::PhantomData};
+  use expect_test::{expect, Expect};
+  use ff::PrimeField;
+  use halo2curves::bn256::Bn256;
+  use traits::circuit::TrivialCircuit;
+
+  type EE<E> = provider::ipa_pc::EvaluationEngine<E>;
+  type S<E, EE> = spartan::snark::RelaxedR1CSSNARK<E, EE>;
+  type SPrime<E, EE> = spartan::ppsnark::RelaxedR1CSSNARK<E, EE>;
+
+  #[derive(Clone, Debug, Default)]
+  struct CubicCircuit<F> {
+    _p: PhantomData<F>,
+  }
+
+  impl<F: PrimeField> StepCircuit<F> for CubicCircuit<F> {
+    fn arity(&self) -> usize {
+      1
+    }
+
+    fn synthesize<CS: ConstraintSystem<F>>(
+      &self,
+      cs: &mut CS,
+      z: &[AllocatedNum<F>],
+    ) -> Result<Vec<AllocatedNum<F>>, SynthesisError> {
+      // Consider a cubic equation: `x^3 + x + 5 = y`, where `x` and `y` are respectively the input and output.
+      let x = &z[0];
+      let x_sq = x.square(cs.namespace(|| "x_sq"))?;
+      let x_cu = x_sq.mul(cs.namespace(|| "x_cu"), x)?;
+      let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
+        Ok(x_cu.get_value().unwrap() + x.get_value().unwrap() + F::from(5u64))
+      })?;
+
+      cs.enforce(
+        || "y = x^3 + x + 5",
+        |lc| {
+          lc + x_cu.get_variable()
+            + x.get_variable()
+            + CS::one()
+            + CS::one()
+            + CS::one()
+            + CS::one()
+            + CS::one()
+        },
+        |lc| lc + CS::one(),
+        |lc| lc + y.get_variable(),
+      );
+
+      Ok(vec![y])
+    }
+  }
+
+  impl<F: PrimeField> CubicCircuit<F> {
+    fn output(&self, z: &[F]) -> Vec<F> {
+      vec![z[0] * z[0] * z[0] + z[0] + F::from(5u64)]
+    }
+  }
+
+  fn test_pp_digest_with<E1, E2, T1, T2, EE1, EE2>(circuit1: &T1, circuit2: &T2, expected: &Expect)
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    E1::GE: DlogGroup,
+    E2::GE: DlogGroup,
+    T1: StepCircuit<E1::Scalar>,
+    T2: StepCircuit<E2::Scalar>,
+    EE1: EvaluationEngineTrait<E1>,
+    EE2: EvaluationEngineTrait<E2>,
+    // this is due to the reliance on Abomonation
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+    <E2::Scalar as PrimeField>::Repr: Abomonation,
+  {
+    // this tests public parameters with a size specifically intended for a spark-compressed SNARK
+    let ck_hint1 = &*SPrime::<E1, EE1>::ck_floor();
+    let ck_hint2 = &*SPrime::<E2, EE2>::ck_floor();
+    let pp = PublicParams::<E1, E2, T1, T2>::setup(circuit1, circuit2, ck_hint1, ck_hint2);
+
+    let digest_str = pp
+      .digest()
+      .to_repr()
+      .as_ref()
+      .iter()
+      .fold(String::new(), |mut output, b| {
+        let _ = write!(output, "{b:02x}");
+        output
+      });
+
+    expected.assert_eq(&digest_str);
+  }
+
+  #[test]
+  fn test_pp_digest() {
+    let trivial_circuit1 = TrivialCircuit::<<PallasEngine as Engine>::Scalar>::default();
+    let trivial_circuit2 = TrivialCircuit::<<VestaEngine as Engine>::Scalar>::default();
+    let cubic_circuit1 = CubicCircuit::<<PallasEngine as Engine>::Scalar>::default();
+
+    test_pp_digest_with::<PallasEngine, VestaEngine, _, _, EE<_>, EE<_>>(
+      &trivial_circuit1,
+      &trivial_circuit2,
+      &expect!["f4a04841515b4721519e2671b7ee11e58e2d4a30bb183ded963b71ad2ec80d00"],
+    );
+
+    test_pp_digest_with::<PallasEngine, VestaEngine, _, _, EE<_>, EE<_>>(
+      &cubic_circuit1,
+      &trivial_circuit2,
+      &expect!["dc1b7c40ab50c5c6877ad027769452870cc28f1d13f140de7ca3a00138c58502"],
+    );
+
+    let trivial_circuit1_grumpkin = TrivialCircuit::<<Bn256Engine as Engine>::Scalar>::default();
+    let trivial_circuit2_grumpkin = TrivialCircuit::<<GrumpkinEngine as Engine>::Scalar>::default();
+    let cubic_circuit1_grumpkin = CubicCircuit::<<Bn256Engine as Engine>::Scalar>::default();
+
+    // These tests should not need be different on the "asm" feature for bn256.
+    // See https://github.com/privacy-scaling-explorations/halo2curves/issues/100 for why they are - closing the issue there
+    // should eliminate the discrepancy here.
+    test_pp_digest_with::<Bn256Engine, GrumpkinEngine, _, _, EE<_>, EE<_>>(
+      &trivial_circuit1_grumpkin,
+      &trivial_circuit2_grumpkin,
+      &expect!["2af2a80ea8a0c21cfc4096e9b2d4822344a29174d88cd86239a99a363efe8702"],
+    );
+    test_pp_digest_with::<Bn256Engine, GrumpkinEngine, _, _, EE<_>, EE<_>>(
+      &cubic_circuit1_grumpkin,
+      &trivial_circuit2_grumpkin,
+      &expect!["9273fd39ed6220ea28e60abca8bdb3180f90e37e6aaf3031e6d670d073e8a002"],
+    );
+    test_pp_digest_with::<Bn256EngineZM, GrumpkinEngine, _, _, ZMPCS<Bn256, _>, EE<_>>(
+      &trivial_circuit1_grumpkin,
+      &trivial_circuit2_grumpkin,
+      &expect!["eac63861dcbaa924a1bd9721f01528271385dd6ff182c77bc62e03448adc1902"],
+    );
+    test_pp_digest_with::<Bn256EngineZM, GrumpkinEngine, _, _, ZMPCS<Bn256, _>, EE<_>>(
+      &cubic_circuit1_grumpkin,
+      &trivial_circuit2_grumpkin,
+      &expect!["21bd7e07175b23e3bd2bbc6a0c3b9efd8603815609dbe93f8df9c174e132de03"],
+    );
+
+    let trivial_circuit1_secp = TrivialCircuit::<<Secp256k1Engine as Engine>::Scalar>::default();
+    let trivial_circuit2_secp = TrivialCircuit::<<Secq256k1Engine as Engine>::Scalar>::default();
+    let cubic_circuit1_secp = CubicCircuit::<<Secp256k1Engine as Engine>::Scalar>::default();
+
+    test_pp_digest_with::<Secp256k1Engine, Secq256k1Engine, _, _, EE<_>, EE<_>>(
+      &trivial_circuit1_secp,
+      &trivial_circuit2_secp,
+      &expect!["7652ef8326b01e784eaac7b44bd0bc2f27af3904c96ef2bf7ab1b923b8aae701"],
+    );
+    test_pp_digest_with::<Secp256k1Engine, Secq256k1Engine, _, _, EE<_>, EE<_>>(
+      &cubic_circuit1_secp,
+      &trivial_circuit2_secp,
+      &expect!["da51e6bac881c054c4ed08320ce42d8a0e61a22fbd70bbbbf05384ec4adeb201"],
+    );
+  }
+
+  fn test_ivc_trivial_with<E1, E2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    let test_circuit1 = TrivialCircuit::<<E1 as Engine>::Scalar>::default();
+    let test_circuit2 = TrivialCircuit::<<E2 as Engine>::Scalar>::default();
+
+    // produce public parameters
+    let pp = PublicParams::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      TrivialCircuit<<E2 as Engine>::Scalar>,
+    >::setup(
+      &test_circuit1,
+      &test_circuit2,
+      &*default_ck_hint(),
+      &*default_ck_hint(),
+    );
+    let num_steps = 1;
+
+    // produce a recursive SNARK
+    let mut recursive_snark = RecursiveSNARK::new(
+      &pp,
+      &test_circuit1,
+      &test_circuit2,
+      &[<E1 as Engine>::Scalar::ZERO],
+      &[<E2 as Engine>::Scalar::ZERO],
+    )
+    .unwrap();
+
+    let res = recursive_snark.prove_step(&pp, &test_circuit1, &test_circuit2);
+
+    assert!(res.is_ok());
+
+    // verify the recursive SNARK
+    let res = recursive_snark.verify(
+      &pp,
+      num_steps,
+      &[<E1 as Engine>::Scalar::ZERO],
+      &[<E2 as Engine>::Scalar::ZERO],
+    );
+    assert!(res.is_ok());
+  }
+
+  #[test]
+  fn test_ivc_trivial() {
+    test_ivc_trivial_with::<PallasEngine, VestaEngine>();
+    test_ivc_trivial_with::<Bn256Engine, GrumpkinEngine>();
+    test_ivc_trivial_with::<Secp256k1Engine, Secq256k1Engine>();
+  }
+
+  fn test_ivc_nontrivial_with<E1, E2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    let circuit_primary = TrivialCircuit::default();
+    let circuit_secondary = CubicCircuit::default();
+
+    // produce public parameters
+    let pp = PublicParams::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      CubicCircuit<<E2 as Engine>::Scalar>,
+    >::setup(
+      &circuit_primary,
+      &circuit_secondary,
+      &*default_ck_hint(),
+      &*default_ck_hint(),
+    );
+
+    let num_steps = 3;
+
+    // produce a recursive SNARK
+    let mut recursive_snark = RecursiveSNARK::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      CubicCircuit<<E2 as Engine>::Scalar>,
+    >::new(
+      &pp,
+      &circuit_primary,
+      &circuit_secondary,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    )
+    .unwrap();
+
+    for i in 0..num_steps {
+      let res = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary);
+      assert!(res.is_ok());
+
+      // verify the recursive snark at each step of recursion
+      let res = recursive_snark.verify(
+        &pp,
+        i + 1,
+        &[<E1 as Engine>::Scalar::ONE],
+        &[<E2 as Engine>::Scalar::ZERO],
+      );
+      assert!(res.is_ok());
+    }
+
+    // verify the recursive SNARK
+    let res = recursive_snark.verify(
+      &pp,
+      num_steps,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    );
+    assert!(res.is_ok());
+
+    let (zn_primary, zn_secondary) = res.unwrap();
+
+    // sanity: check the claimed output with a direct computation of the same
+    assert_eq!(zn_primary, vec![<E1 as Engine>::Scalar::ONE]);
+    let mut zn_secondary_direct = vec![<E2 as Engine>::Scalar::ZERO];
+    for _i in 0..num_steps {
+      zn_secondary_direct = circuit_secondary.clone().output(&zn_secondary_direct);
+    }
+    assert_eq!(zn_secondary, zn_secondary_direct);
+    assert_eq!(zn_secondary, vec![<E2 as Engine>::Scalar::from(2460515u64)]);
+  }
+
+  #[test]
+  fn test_ivc_nontrivial() {
+    test_ivc_nontrivial_with::<PallasEngine, VestaEngine>();
+    test_ivc_nontrivial_with::<Bn256Engine, GrumpkinEngine>();
+    test_ivc_nontrivial_with::<Secp256k1Engine, Secq256k1Engine>();
+  }
+
+  fn test_ivc_nontrivial_with_compression_with<E1, E2, EE1, EE2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    EE1: EvaluationEngineTrait<E1>,
+    EE2: EvaluationEngineTrait<E2>,
+    // this is due to the reliance on Abomonation
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+    <E2::Scalar as PrimeField>::Repr: Abomonation,
+  {
+    let circuit_primary = TrivialCircuit::default();
+    let circuit_secondary = CubicCircuit::default();
+
+    // produce public parameters
+    let pp = PublicParams::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      CubicCircuit<<E2 as Engine>::Scalar>,
+    >::setup(
+      &circuit_primary,
+      &circuit_secondary,
+      &*default_ck_hint(),
+      &*default_ck_hint(),
+    );
+
+    let num_steps = 3;
+
+    // produce a recursive SNARK
+    let mut recursive_snark = RecursiveSNARK::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      CubicCircuit<<E2 as Engine>::Scalar>,
+    >::new(
+      &pp,
+      &circuit_primary,
+      &circuit_secondary,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    )
+    .unwrap();
+
+    for _i in 0..num_steps {
+      let res = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary);
+      assert!(res.is_ok());
+    }
+
+    // verify the recursive SNARK
+    let res = recursive_snark.verify(
+      &pp,
+      num_steps,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    );
+    assert!(res.is_ok());
+
+    let (zn_primary, zn_secondary) = res.unwrap();
+
+    // sanity: check the claimed output with a direct computation of the same
+    assert_eq!(zn_primary, vec![<E1 as Engine>::Scalar::ONE]);
+    let mut zn_secondary_direct = vec![<E2 as Engine>::Scalar::ZERO];
+    for _i in 0..num_steps {
+      zn_secondary_direct = circuit_secondary.clone().output(&zn_secondary_direct);
+    }
+    assert_eq!(zn_secondary, zn_secondary_direct);
+    assert_eq!(zn_secondary, vec![<E2 as Engine>::Scalar::from(2460515u64)]);
+
+    // produce the prover and verifier keys for compressed snark
+    let (pk, vk) = CompressedSNARK::<_, _, _, _, S<E1, EE1>, S<E2, EE2>>::setup(&pp).unwrap();
+
+    // produce a compressed SNARK
+    let res =
+      CompressedSNARK::<_, _, _, _, S<E1, EE1>, S<E2, EE2>>::prove(&pp, &pk, &recursive_snark);
+    assert!(res.is_ok());
+    let compressed_snark = res.unwrap();
+
+    // verify the compressed SNARK
+    let res = compressed_snark.verify(
+      &vk,
+      num_steps,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    );
+    assert!(res.is_ok());
+  }
+
+  #[test]
+  fn test_ivc_nontrivial_with_compression() {
+    test_ivc_nontrivial_with_compression_with::<PallasEngine, VestaEngine, EE<_>, EE<_>>();
+    test_ivc_nontrivial_with_compression_with::<Bn256Engine, GrumpkinEngine, EE<_>, EE<_>>();
+    test_ivc_nontrivial_with_compression_with::<Secp256k1Engine, Secq256k1Engine, EE<_>, EE<_>>();
+    test_ivc_nontrivial_with_compression_with::<
+      Bn256EngineZM,
+      GrumpkinEngine,
+      ZMPCS<Bn256, _>,
+      EE<_>,
+    >();
+
+    test_ivc_nontrivial_with_spark_compression_with::<
+      Bn256EngineKZG,
+      GrumpkinEngine,
+      provider::mlkzg::EvaluationEngine<Bn256, _>,
+      EE<_>,
+    >();
+  }
+
+  fn test_ivc_nontrivial_with_spark_compression_with<E1, E2, EE1, EE2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    EE1: EvaluationEngineTrait<E1>,
+    EE2: EvaluationEngineTrait<E2>,
+    // this is due to the reliance on Abomonation
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+    <E2::Scalar as PrimeField>::Repr: Abomonation,
+  {
+    let circuit_primary = TrivialCircuit::default();
+    let circuit_secondary = CubicCircuit::default();
+
+    // produce public parameters, which we'll use with a spark-compressed SNARK
+    let pp = PublicParams::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      CubicCircuit<<E2 as Engine>::Scalar>,
+    >::setup(
+      &circuit_primary,
+      &circuit_secondary,
+      &*SPrime::<E1, EE1>::ck_floor(),
+      &*SPrime::<E2, EE2>::ck_floor(),
+    );
+
+    let num_steps = 3;
+
+    // produce a recursive SNARK
+    let mut recursive_snark = RecursiveSNARK::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      CubicCircuit<<E2 as Engine>::Scalar>,
+    >::new(
+      &pp,
+      &circuit_primary,
+      &circuit_secondary,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    )
+    .unwrap();
+
+    for _i in 0..num_steps {
+      let res = recursive_snark.prove_step(&pp, &circuit_primary, &circuit_secondary);
+      assert!(res.is_ok());
+    }
+
+    // verify the recursive SNARK
+    let res = recursive_snark.verify(
+      &pp,
+      num_steps,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    );
+    assert!(res.is_ok());
+
+    let (zn_primary, zn_secondary) = res.unwrap();
+
+    // sanity: check the claimed output with a direct computation of the same
+    assert_eq!(zn_primary, vec![<E1 as Engine>::Scalar::ONE]);
+    let mut zn_secondary_direct = vec![<E2 as Engine>::Scalar::ZERO];
+    for _i in 0..num_steps {
+      zn_secondary_direct = CubicCircuit::default().output(&zn_secondary_direct);
+    }
+    assert_eq!(zn_secondary, zn_secondary_direct);
+    assert_eq!(zn_secondary, vec![<E2 as Engine>::Scalar::from(2460515u64)]);
+
+    // run the compressed snark with Spark compiler
+    // produce the prover and verifier keys for compressed snark
+    let (pk, vk) =
+      CompressedSNARK::<_, _, _, _, SPrime<E1, EE1>, SPrime<E2, EE2>>::setup(&pp).unwrap();
+
+    // produce a compressed SNARK
+    let res = CompressedSNARK::<_, _, _, _, SPrime<E1, EE1>, SPrime<E2, EE2>>::prove(
+      &pp,
+      &pk,
+      &recursive_snark,
+    );
+    assert!(res.is_ok());
+    let compressed_snark = res.unwrap();
+
+    // verify the compressed SNARK
+    let res = compressed_snark.verify(
+      &vk,
+      num_steps,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    );
+    assert!(res.is_ok());
+  }
+
+  #[test]
+  fn test_ivc_nontrivial_with_spark_compression() {
+    test_ivc_nontrivial_with_spark_compression_with::<PallasEngine, VestaEngine, EE<_>, EE<_>>();
+    test_ivc_nontrivial_with_spark_compression_with::<Bn256Engine, GrumpkinEngine, EE<_>, EE<_>>();
+    test_ivc_nontrivial_with_spark_compression_with::<Secp256k1Engine, Secq256k1Engine, EE<_>, EE<_>>(
+    );
+    test_ivc_nontrivial_with_spark_compression_with::<
+      Bn256EngineZM,
+      GrumpkinEngine,
+      ZMPCS<Bn256, _>,
+      EE<_>,
+    >();
+  }
+
+  fn test_ivc_nondet_with_compression_with<E1, E2, EE1, EE2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    EE1: EvaluationEngineTrait<E1>,
+    EE2: EvaluationEngineTrait<E2>,
+    // this is due to the reliance on Abomonation
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+    <E2::Scalar as PrimeField>::Repr: Abomonation,
+  {
+    // y is a non-deterministic advice representing the fifth root of the input at a step.
+    #[derive(Clone, Debug)]
+    struct FifthRootCheckingCircuit<F> {
+      y: F,
+    }
+
+    impl<F: PrimeField> FifthRootCheckingCircuit<F> {
+      fn new(num_steps: usize) -> (Vec<F>, Vec<Self>) {
+        let mut powers = Vec::new();
+        let rng = &mut rand::rngs::OsRng;
+        let mut seed = F::random(rng);
+        for _i in 0..num_steps + 1 {
+          seed *= seed.clone().square().square();
+
+          powers.push(Self { y: seed });
+        }
+
+        // reverse the powers to get roots
+        let roots = powers.into_iter().rev().collect::<Vec<Self>>();
+        (vec![roots[0].y], roots[1..].to_vec())
+      }
+    }
+
+    impl<F> StepCircuit<F> for FifthRootCheckingCircuit<F>
+    where
+      F: PrimeField,
+    {
+      fn arity(&self) -> usize {
+        1
+      }
+
+      fn synthesize<CS: ConstraintSystem<F>>(
+        &self,
+        cs: &mut CS,
+        z: &[AllocatedNum<F>],
+      ) -> Result<Vec<AllocatedNum<F>>, SynthesisError> {
+        let x = &z[0];
+
+        // we allocate a variable and set it to the provided non-deterministic advice.
+        let y = AllocatedNum::alloc_infallible(cs.namespace(|| "y"), || self.y);
+
+        // We now check if y = x^{1/5} by checking if y^5 = x
+        let y_sq = y.square(cs.namespace(|| "y_sq"))?;
+        let y_quad = y_sq.square(cs.namespace(|| "y_quad"))?;
+        let y_pow_5 = y_quad.mul(cs.namespace(|| "y_fifth"), &y)?;
+
+        cs.enforce(
+          || "y^5 = x",
+          |lc| lc + y_pow_5.get_variable(),
+          |lc| lc + CS::one(),
+          |lc| lc + x.get_variable(),
+        );
+
+        Ok(vec![y])
+      }
+    }
+
+    let circuit_primary = FifthRootCheckingCircuit {
+      y: <E1 as Engine>::Scalar::ZERO,
+    };
+
+    let circuit_secondary = TrivialCircuit::default();
+
+    // produce public parameters
+    let pp = PublicParams::<
+      E1,
+      E2,
+      FifthRootCheckingCircuit<<E1 as Engine>::Scalar>,
+      TrivialCircuit<<E2 as Engine>::Scalar>,
+    >::setup(
+      &circuit_primary,
+      &circuit_secondary,
+      &*default_ck_hint(),
+      &*default_ck_hint(),
+    );
+
+    let num_steps = 3;
+
+    // produce non-deterministic advice
+    let (z0_primary, roots) = FifthRootCheckingCircuit::new(num_steps);
+    let z0_secondary = vec![<E2 as Engine>::Scalar::ZERO];
+
+    // produce a recursive SNARK
+    let mut recursive_snark: RecursiveSNARK<
+      E1,
+      E2,
+      FifthRootCheckingCircuit<<E1 as Engine>::Scalar>,
+      TrivialCircuit<<E2 as Engine>::Scalar>,
+    > = RecursiveSNARK::<
+      E1,
+      E2,
+      FifthRootCheckingCircuit<<E1 as Engine>::Scalar>,
+      TrivialCircuit<<E2 as Engine>::Scalar>,
+    >::new(
+      &pp,
+      &roots[0],
+      &circuit_secondary,
+      &z0_primary,
+      &z0_secondary,
+    )
+    .unwrap();
+
+    for circuit_primary in roots.iter().take(num_steps) {
+      let res = recursive_snark.prove_step(&pp, circuit_primary, &circuit_secondary);
+      assert!(res.is_ok());
+    }
+
+    // verify the recursive SNARK
+    let res = recursive_snark.verify(&pp, num_steps, &z0_primary, &z0_secondary);
+    assert!(res.is_ok());
+
+    // produce the prover and verifier keys for compressed snark
+    let (pk, vk) = CompressedSNARK::<_, _, _, _, S<E1, EE1>, S<E2, EE2>>::setup(&pp).unwrap();
+
+    // produce a compressed SNARK
+    let res =
+      CompressedSNARK::<_, _, _, _, S<E1, EE1>, S<E2, EE2>>::prove(&pp, &pk, &recursive_snark);
+    assert!(res.is_ok());
+    let compressed_snark = res.unwrap();
+
+    // verify the compressed SNARK
+    let res = compressed_snark.verify(&vk, num_steps, &z0_primary, &z0_secondary);
+    assert!(res.is_ok());
+  }
+
+  #[test]
+  fn test_ivc_nondet_with_compression() {
+    test_ivc_nondet_with_compression_with::<PallasEngine, VestaEngine, EE<_>, EE<_>>();
+    test_ivc_nondet_with_compression_with::<Bn256Engine, GrumpkinEngine, EE<_>, EE<_>>();
+    test_ivc_nondet_with_compression_with::<Secp256k1Engine, Secq256k1Engine, EE<_>, EE<_>>();
+    test_ivc_nondet_with_compression_with::<Bn256EngineZM, GrumpkinEngine, ZMPCS<Bn256, _>, EE<_>>(
+    );
+  }
+
+  fn test_ivc_base_with<E1, E2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    let test_circuit1 = TrivialCircuit::<<E1 as Engine>::Scalar>::default();
+    let test_circuit2 = CubicCircuit::<<E2 as Engine>::Scalar>::default();
+
+    // produce public parameters
+    let pp = PublicParams::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      CubicCircuit<<E2 as Engine>::Scalar>,
+    >::setup(
+      &test_circuit1,
+      &test_circuit2,
+      &*default_ck_hint(),
+      &*default_ck_hint(),
+    );
+
+    let num_steps = 1;
+
+    // produce a recursive SNARK
+    let mut recursive_snark = RecursiveSNARK::<
+      E1,
+      E2,
+      TrivialCircuit<<E1 as Engine>::Scalar>,
+      CubicCircuit<<E2 as Engine>::Scalar>,
+    >::new(
+      &pp,
+      &test_circuit1,
+      &test_circuit2,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    )
+    .unwrap();
+
+    // produce a recursive SNARK
+    let res = recursive_snark.prove_step(&pp, &test_circuit1, &test_circuit2);
+
+    assert!(res.is_ok());
+
+    // verify the recursive SNARK
+    let res = recursive_snark.verify(
+      &pp,
+      num_steps,
+      &[<E1 as Engine>::Scalar::ONE],
+      &[<E2 as Engine>::Scalar::ZERO],
+    );
+    assert!(res.is_ok());
+
+    let (zn_primary, zn_secondary) = res.unwrap();
+
+    assert_eq!(zn_primary, vec![<E1 as Engine>::Scalar::ONE]);
+    assert_eq!(zn_secondary, vec![<E2 as Engine>::Scalar::from(5u64)]);
+  }
+
+  #[test]
+  fn test_ivc_base() {
+    test_ivc_base_with::<PallasEngine, VestaEngine>();
+    test_ivc_base_with::<Bn256Engine, GrumpkinEngine>();
+    test_ivc_base_with::<Secp256k1Engine, Secq256k1Engine>();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/nifs.rs.html b/docs/src/arecibo/nifs.rs.html new file mode 100644 index 000000000..dc3f891ae --- /dev/null +++ b/docs/src/arecibo/nifs.rs.html @@ -0,0 +1,889 @@ +nifs.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+
//! This module implements a non-interactive folding scheme
+#![allow(non_snake_case)]
+
+use crate::{
+  constants::{NUM_CHALLENGE_BITS, NUM_FE_FOR_RO},
+  errors::NovaError,
+  r1cs::{
+    R1CSInstance, R1CSResult, R1CSShape, R1CSWitness, RelaxedR1CSInstance, RelaxedR1CSWitness,
+  },
+  scalar_as_base,
+  traits::{commitment::CommitmentTrait, AbsorbInROTrait, Engine, ROTrait},
+  Commitment, CommitmentKey, CompressedCommitment,
+};
+use serde::{Deserialize, Serialize};
+
+/// A SNARK that holds the proof of a step of an incremental computation
+#[allow(clippy::upper_case_acronyms)]
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct NIFS<E: Engine> {
+  pub(crate) comm_T: CompressedCommitment<E>,
+}
+
+type ROConstants<E> =
+  <<E as Engine>::RO as ROTrait<<E as Engine>::Base, <E as Engine>::Scalar>>::Constants;
+
+impl<E: Engine> NIFS<E> {
+  /// Takes as input a Relaxed R1CS instance-witness tuple `(U1, W1)` and
+  /// an R1CS instance-witness tuple `(U2, W2)` with the same structure `shape`
+  /// and defined with respect to the same `ck`, and outputs
+  /// a folded Relaxed R1CS instance-witness tuple `(U, W)` of the same shape `shape`,
+  /// with the guarantee that the folded witness `W` satisfies the folded instance `U`
+  /// if and only if `W1` satisfies `U1` and `W2` satisfies `U2`.
+  #[allow(clippy::too_many_arguments)]
+  #[tracing::instrument(skip_all, level = "trace", name = "NIFS::prove")]
+  pub fn prove(
+    ck: &CommitmentKey<E>,
+    ro_consts: &ROConstants<E>,
+    pp_digest: &E::Scalar,
+    S: &R1CSShape<E>,
+    U1: &RelaxedR1CSInstance<E>,
+    W1: &RelaxedR1CSWitness<E>,
+    U2: &R1CSInstance<E>,
+    W2: &R1CSWitness<E>,
+  ) -> Result<(Self, (RelaxedR1CSInstance<E>, RelaxedR1CSWitness<E>)), NovaError> {
+    // initialize a new RO
+    let mut ro = E::RO::new(ro_consts.clone(), NUM_FE_FOR_RO);
+
+    // append the digest of pp to the transcript
+    ro.absorb(scalar_as_base::<E>(*pp_digest));
+
+    // append U1 and U2 to transcript
+    U1.absorb_in_ro(&mut ro);
+    U2.absorb_in_ro(&mut ro);
+
+    // compute a commitment to the cross-term
+    let (T, comm_T) = S.commit_T(ck, U1, W1, U2, W2)?;
+
+    // append `comm_T` to the transcript and obtain a challenge
+    comm_T.absorb_in_ro(&mut ro);
+
+    // compute a challenge from the RO
+    let r = ro.squeeze(NUM_CHALLENGE_BITS);
+
+    // fold the instance using `r` and `comm_T`
+    let U = U1.fold(U2, &comm_T, &r);
+
+    // fold the witness using `r` and `T`
+    let W = W1.fold(W2, &T, &r)?;
+
+    // return the folded instance and witness
+    Ok((
+      Self {
+        comm_T: comm_T.compress(),
+      },
+      (U, W),
+    ))
+  }
+
+  /// Takes as input a Relaxed R1CS instance-witness tuple `(U1, W1)` and
+  /// an R1CS instance-witness tuple `(U2, W2)` with the same structure `shape`
+  /// and defined with respect to the same `ck`, and updates `(U1, W1)` by folding
+  /// `(U2, W2)` into it with the guarantee that the updated witness `W` satisfies
+  /// the updated instance `U` if and only if `W1` satisfies `U1` and `W2` satisfies `U2`.
+  #[allow(clippy::too_many_arguments)]
+  #[tracing::instrument(skip_all, level = "trace", name = "NIFS::prove_mut")]
+  pub fn prove_mut(
+    ck: &CommitmentKey<E>,
+    ro_consts: &ROConstants<E>,
+    pp_digest: &E::Scalar,
+    S: &R1CSShape<E>,
+    U1: &mut RelaxedR1CSInstance<E>,
+    W1: &mut RelaxedR1CSWitness<E>,
+    U2: &R1CSInstance<E>,
+    W2: &R1CSWitness<E>,
+    T: &mut Vec<E::Scalar>,
+    ABC_Z_1: &mut R1CSResult<E>,
+    ABC_Z_2: &mut R1CSResult<E>,
+  ) -> Result<Self, NovaError> {
+    // initialize a new RO
+    let mut ro = E::RO::new(ro_consts.clone(), NUM_FE_FOR_RO);
+
+    // append the digest of pp to the transcript
+    ro.absorb(scalar_as_base::<E>(*pp_digest));
+
+    // append U1 and U2 to transcript
+    U1.absorb_in_ro(&mut ro);
+    U2.absorb_in_ro(&mut ro);
+
+    // compute a commitment to the cross-term
+    let comm_T = S.commit_T_into(ck, U1, W1, U2, W2, T, ABC_Z_1, ABC_Z_2)?;
+
+    // append `comm_T` to the transcript and obtain a challenge
+    comm_T.absorb_in_ro(&mut ro);
+
+    // compute a challenge from the RO
+    let r = ro.squeeze(NUM_CHALLENGE_BITS);
+
+    // fold the instance using `r` and `comm_T`
+    U1.fold_mut(U2, &comm_T, &r);
+
+    // fold the witness using `r` and `T`
+    W1.fold_mut(W2, T, &r)?;
+
+    // return the commitment
+    Ok(Self {
+      comm_T: comm_T.compress(),
+    })
+  }
+
+  /// Takes as input a relaxed R1CS instance `U1` and R1CS instance `U2`
+  /// with the same shape and defined with respect to the same parameters,
+  /// and outputs a folded instance `U` with the same shape,
+  /// with the guarantee that the folded instance `U`
+  /// if and only if `U1` and `U2` are satisfiable.
+  pub fn verify(
+    &self,
+    ro_consts: &ROConstants<E>,
+    pp_digest: &E::Scalar,
+    U1: &RelaxedR1CSInstance<E>,
+    U2: &R1CSInstance<E>,
+  ) -> Result<RelaxedR1CSInstance<E>, NovaError> {
+    // initialize a new RO
+    let mut ro = E::RO::new(ro_consts.clone(), NUM_FE_FOR_RO);
+
+    // append the digest of pp to the transcript
+    ro.absorb(scalar_as_base::<E>(*pp_digest));
+
+    // append U1 and U2 to transcript
+    U1.absorb_in_ro(&mut ro);
+    U2.absorb_in_ro(&mut ro);
+
+    // append `comm_T` to the transcript and obtain a challenge
+    let comm_T = Commitment::<E>::decompress(&self.comm_T)?;
+    comm_T.absorb_in_ro(&mut ro);
+
+    // compute a challenge from the RO
+    let r = ro.squeeze(NUM_CHALLENGE_BITS);
+
+    // fold the instance using `r` and `comm_T`
+    let U = U1.fold(U2, &comm_T, &r);
+
+    // return the folded instance
+    Ok(U)
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::{
+    bellpepper::{
+      r1cs::{NovaShape, NovaWitness},
+      solver::SatisfyingAssignment,
+      test_shape_cs::TestShapeCS,
+    },
+    provider::{Bn256Engine, PallasEngine, Secp256k1Engine},
+    r1cs::{commitment_key, SparseMatrix},
+    traits::{snark::default_ck_hint, Engine},
+  };
+  use ::bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError};
+  use ff::{Field, PrimeField};
+  use rand::rngs::OsRng;
+
+  fn synthesize_tiny_r1cs_bellpepper<Scalar: PrimeField, CS: ConstraintSystem<Scalar>>(
+    cs: &mut CS,
+    x_val: Option<Scalar>,
+  ) -> Result<(), SynthesisError> {
+    // Consider a cubic equation: `x^3 + x + 5 = y`, where `x` and `y` are respectively the input and output.
+    let x = AllocatedNum::alloc_infallible(cs.namespace(|| "x"), || x_val.unwrap());
+    let _ = x.inputize(cs.namespace(|| "x is input"));
+
+    let x_sq = x.square(cs.namespace(|| "x_sq"))?;
+    let x_cu = x_sq.mul(cs.namespace(|| "x_cu"), &x)?;
+    let y = AllocatedNum::alloc(cs.namespace(|| "y"), || {
+      Ok(x_cu.get_value().unwrap() + x.get_value().unwrap() + Scalar::from(5u64))
+    })?;
+    let _ = y.inputize(cs.namespace(|| "y is output"));
+
+    cs.enforce(
+      || "y = x^3 + x + 5",
+      |lc| {
+        lc + x_cu.get_variable()
+          + x.get_variable()
+          + CS::one()
+          + CS::one()
+          + CS::one()
+          + CS::one()
+          + CS::one()
+      },
+      |lc| lc + CS::one(),
+      |lc| lc + y.get_variable(),
+    );
+
+    Ok(())
+  }
+
+  fn test_tiny_r1cs_bellpepper_with<E: Engine>() {
+    // First create the shape
+    let mut cs: TestShapeCS<E> = TestShapeCS::new();
+    let _ = synthesize_tiny_r1cs_bellpepper(&mut cs, None);
+    let (shape, ck) = cs.r1cs_shape_and_key(&*default_ck_hint());
+    let ro_consts =
+      <<E as Engine>::RO as ROTrait<<E as Engine>::Base, <E as Engine>::Scalar>>::Constants::default();
+
+    // Now get the instance and assignment for one instance
+    let mut cs = SatisfyingAssignment::<E>::new();
+    let _ = synthesize_tiny_r1cs_bellpepper(&mut cs, Some(E::Scalar::from(5)));
+    let (U1, W1) = cs.r1cs_instance_and_witness(&shape, &ck).unwrap();
+
+    // Make sure that the first instance is satisfiable
+    assert!(shape.is_sat(&ck, &U1, &W1).is_ok());
+
+    // Now get the instance and assignment for second instance
+    let mut cs = SatisfyingAssignment::<E>::new();
+    let _ = synthesize_tiny_r1cs_bellpepper(&mut cs, Some(E::Scalar::from(135)));
+    let (U2, W2) = cs.r1cs_instance_and_witness(&shape, &ck).unwrap();
+
+    // Make sure that the second instance is satisfiable
+    assert!(shape.is_sat(&ck, &U2, &W2).is_ok());
+
+    // execute a sequence of folds
+    execute_sequence(
+      &ck,
+      &ro_consts,
+      &<E as Engine>::Scalar::ZERO,
+      &shape,
+      &U1,
+      &W1,
+      &U2,
+      &W2,
+    );
+  }
+
+  #[test]
+  fn test_tiny_r1cs_bellpepper() {
+    test_tiny_r1cs_bellpepper_with::<PallasEngine>();
+    test_tiny_r1cs_bellpepper_with::<Bn256Engine>();
+    test_tiny_r1cs_bellpepper_with::<Secp256k1Engine>();
+  }
+
+  fn execute_sequence<E: Engine>(
+    ck: &CommitmentKey<E>,
+    ro_consts: &<<E as Engine>::RO as ROTrait<<E as Engine>::Base, <E as Engine>::Scalar>>::Constants,
+    pp_digest: &<E as Engine>::Scalar,
+    shape: &R1CSShape<E>,
+    U1: &R1CSInstance<E>,
+    W1: &R1CSWitness<E>,
+    U2: &R1CSInstance<E>,
+    W2: &R1CSWitness<E>,
+  ) {
+    // produce a default running instance
+    let mut r_W = RelaxedR1CSWitness::default(shape);
+    let mut r_U = RelaxedR1CSInstance::default(ck, shape);
+
+    // produce a step SNARK with (W1, U1) as the first incoming witness-instance pair
+    let res = NIFS::prove(ck, ro_consts, pp_digest, shape, &r_U, &r_W, U1, W1);
+    assert!(res.is_ok());
+    let (nifs, (_U, W)) = res.unwrap();
+
+    // verify the step SNARK with U1 as the first incoming instance
+    let res = nifs.verify(ro_consts, pp_digest, &r_U, U1);
+    assert!(res.is_ok());
+    let U = res.unwrap();
+
+    assert_eq!(U, _U);
+
+    // update the running witness and instance
+    r_W = W;
+    r_U = U;
+
+    // produce a step SNARK with (W2, U2) as the second incoming witness-instance pair
+    let res = NIFS::prove(ck, ro_consts, pp_digest, shape, &r_U, &r_W, U2, W2);
+    assert!(res.is_ok());
+    let (nifs, (_U, W)) = res.unwrap();
+
+    // verify the step SNARK with U1 as the first incoming instance
+    let res = nifs.verify(ro_consts, pp_digest, &r_U, U2);
+    assert!(res.is_ok());
+    let U = res.unwrap();
+
+    assert_eq!(U, _U);
+
+    // update the running witness and instance
+    r_W = W;
+    r_U = U;
+
+    // check if the running instance is satisfiable
+    assert!(shape.is_sat_relaxed(ck, &r_U, &r_W).is_ok());
+  }
+
+  fn test_tiny_r1cs_with<E: Engine>() {
+    let one = <E::Scalar as Field>::ONE;
+    let (num_cons, num_vars, num_io, A, B, C) = {
+      let num_cons = 4;
+      let num_vars = 3;
+      let num_io = 2;
+
+      // Consider a cubic equation: `x^3 + x + 5 = y`, where `x` and `y` are respectively the input and output.
+      // The R1CS for this problem consists of the following constraints:
+      // `I0 * I0 - Z0 = 0`
+      // `Z0 * I0 - Z1 = 0`
+      // `(Z1 + I0) * 1 - Z2 = 0`
+      // `(Z2 + 5) * 1 - I1 = 0`
+
+      // Relaxed R1CS is a set of three sparse matrices (A B C), where there is a row for every
+      // constraint and a column for every entry in z = (vars, u, inputs)
+      // An R1CS instance is satisfiable iff:
+      // Az \circ Bz = u \cdot Cz + E, where z = (vars, 1, inputs)
+      let mut A: Vec<(usize, usize, E::Scalar)> = Vec::new();
+      let mut B: Vec<(usize, usize, E::Scalar)> = Vec::new();
+      let mut C: Vec<(usize, usize, E::Scalar)> = Vec::new();
+
+      // constraint 0 entries in (A,B,C)
+      // `I0 * I0 - Z0 = 0`
+      A.push((0, num_vars + 1, one));
+      B.push((0, num_vars + 1, one));
+      C.push((0, 0, one));
+
+      // constraint 1 entries in (A,B,C)
+      // `Z0 * I0 - Z1 = 0`
+      A.push((1, 0, one));
+      B.push((1, num_vars + 1, one));
+      C.push((1, 1, one));
+
+      // constraint 2 entries in (A,B,C)
+      // `(Z1 + I0) * 1 - Z2 = 0`
+      A.push((2, 1, one));
+      A.push((2, num_vars + 1, one));
+      B.push((2, num_vars, one));
+      C.push((2, 2, one));
+
+      // constraint 3 entries in (A,B,C)
+      // `(Z2 + 5) * 1 - I1 = 0`
+      A.push((3, 2, one));
+      A.push((3, num_vars, one + one + one + one + one));
+      B.push((3, num_vars, one));
+      C.push((3, num_vars + 2, one));
+
+      (num_cons, num_vars, num_io, A, B, C)
+    };
+
+    // create a shape object
+    let rows = num_cons;
+    let num_inputs = num_io + 1;
+    let cols = num_vars + num_inputs;
+    let S = {
+      let res = R1CSShape::new(
+        num_cons,
+        num_vars,
+        num_inputs - 1,
+        SparseMatrix::new(&A, rows, cols),
+        SparseMatrix::new(&B, rows, cols),
+        SparseMatrix::new(&C, rows, cols),
+      );
+      assert!(res.is_ok());
+      res.unwrap()
+    };
+
+    // generate generators and ro constants
+    let ck = commitment_key(&S, &*default_ck_hint());
+    let ro_consts =
+      <<E as Engine>::RO as ROTrait<<E as Engine>::Base, <E as Engine>::Scalar>>::Constants::default();
+
+    let rand_inst_witness_generator =
+      |ck: &CommitmentKey<E>, I: &E::Scalar| -> (E::Scalar, R1CSInstance<E>, R1CSWitness<E>) {
+        let i0 = *I;
+
+        // compute a satisfying (vars, X) tuple
+        let (O, vars, X) = {
+          let z0 = i0 * i0; // constraint 0
+          let z1 = i0 * z0; // constraint 1
+          let z2 = z1 + i0; // constraint 2
+          let i1 = z2 + one + one + one + one + one; // constraint 3
+
+          // store the witness and IO for the instance
+          let W = vec![z0, z1, z2];
+          let X = vec![i0, i1];
+          (i1, W, X)
+        };
+
+        let W = {
+          let res = R1CSWitness::new(&S, vars);
+          assert!(res.is_ok());
+          res.unwrap()
+        };
+        let U = {
+          let comm_W = W.commit(ck);
+          let res = R1CSInstance::new(&S, comm_W, X);
+          assert!(res.is_ok());
+          res.unwrap()
+        };
+
+        // check that generated instance is satisfiable
+        assert!(S.is_sat(ck, &U, &W).is_ok());
+
+        (O, U, W)
+      };
+
+    let mut csprng: OsRng = OsRng;
+    let I = E::Scalar::random(&mut csprng); // the first input is picked randomly for the first instance
+    let (O, U1, W1) = rand_inst_witness_generator(&ck, &I);
+    let (_O, U2, W2) = rand_inst_witness_generator(&ck, &O);
+
+    // execute a sequence of folds
+    execute_sequence(
+      &ck,
+      &ro_consts,
+      &<E as Engine>::Scalar::ZERO,
+      &S,
+      &U1,
+      &W1,
+      &U2,
+      &W2,
+    );
+  }
+
+  #[test]
+  fn test_tiny_r1cs() {
+    test_tiny_r1cs_with::<PallasEngine>();
+    test_tiny_r1cs_with::<Bn256Engine>();
+    test_tiny_r1cs_with::<Secp256k1Engine>();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/bn256_grumpkin.rs.html b/docs/src/arecibo/provider/bn256_grumpkin.rs.html new file mode 100644 index 000000000..9b292b03a --- /dev/null +++ b/docs/src/arecibo/provider/bn256_grumpkin.rs.html @@ -0,0 +1,209 @@ +bn256_grumpkin.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+
//! This module implements the Nova traits for `bn256::Point`, `bn256::Scalar`, `grumpkin::Point`, `grumpkin::Scalar`.
+use crate::{
+  impl_traits,
+  provider::{traits::DlogGroup, util::msm::cpu_best_msm},
+  traits::{Group, PrimeFieldExt, TranscriptReprTrait},
+};
+use digest::{ExtendableOutput, Update};
+use ff::{FromUniformBytes, PrimeField};
+use group::{cofactor::CofactorCurveAffine, Curve, Group as AnotherGroup};
+#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
+use grumpkin_msm::{bn256 as bn256_msm, grumpkin as grumpkin_msm};
+// Remove this when https://github.com/zcash/pasta_curves/issues/41 resolves
+use halo2curves::{CurveAffine, CurveExt};
+use num_bigint::BigInt;
+use num_traits::Num;
+use rayon::prelude::*;
+use sha3::Shake256;
+use std::io::Read;
+
+/// Re-exports that give access to the standard aliases used in the code base, for bn256
+pub mod bn256 {
+  pub use halo2curves::bn256::{
+    Fq as Base, Fr as Scalar, G1Affine as Affine, G1Compressed as Compressed, G1 as Point,
+  };
+}
+
+/// Re-exports that give access to the standard aliases used in the code base, for grumpkin
+pub mod grumpkin {
+  pub use halo2curves::grumpkin::{
+    Fq as Base, Fr as Scalar, G1Affine as Affine, G1Compressed as Compressed, G1 as Point,
+  };
+}
+
+#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
+impl_traits!(
+  bn256,
+  "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
+  "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47",
+  bn256_msm
+);
+#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
+impl_traits!(
+  bn256,
+  "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
+  "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
+);
+
+#[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
+impl_traits!(
+  grumpkin,
+  "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47",
+  "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001",
+  grumpkin_msm
+);
+#[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
+impl_traits!(
+  grumpkin,
+  "30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47",
+  "30644e72e131a029b85045b68181585d2833e84879b9709143e1f593f0000001"
+);
+
+#[cfg(test)]
+mod tests {
+  use ff::Field;
+  use rand::thread_rng;
+
+  use crate::provider::{
+    bn256_grumpkin::{bn256, grumpkin},
+    traits::DlogGroup,
+    util::msm::cpu_best_msm,
+  };
+
+  #[test]
+  fn test_bn256_msm_correctness() {
+    let npoints = 1usize << 16;
+    let points = bn256::Point::from_label(b"test", npoints);
+
+    let mut rng = thread_rng();
+    let scalars = (0..npoints)
+      .map(|_| bn256::Scalar::random(&mut rng))
+      .collect::<Vec<_>>();
+
+    let cpu_msm = cpu_best_msm(&points, &scalars);
+    let gpu_msm = bn256::Point::vartime_multiscalar_mul(&scalars, &points);
+
+    assert_eq!(cpu_msm, gpu_msm);
+  }
+
+  #[test]
+  fn test_grumpkin_msm_correctness() {
+    let npoints = 1usize << 16;
+    let points = grumpkin::Point::from_label(b"test", npoints);
+
+    let mut rng = thread_rng();
+    let scalars = (0..npoints)
+      .map(|_| grumpkin::Scalar::random(&mut rng))
+      .collect::<Vec<_>>();
+
+    let cpu_msm = cpu_best_msm(&points, &scalars);
+    let gpu_msm = grumpkin::Point::vartime_multiscalar_mul(&scalars, &points);
+
+    assert_eq!(cpu_msm, gpu_msm);
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/ipa_pc.rs.html b/docs/src/arecibo/provider/ipa_pc.rs.html new file mode 100644 index 000000000..3f3d78e27 --- /dev/null +++ b/docs/src/arecibo/provider/ipa_pc.rs.html @@ -0,0 +1,853 @@ +ipa_pc.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+
//! This module implements `EvaluationEngine` using an IPA-based polynomial commitment scheme
+use crate::{
+  errors::{NovaError, PCSError},
+  provider::{pedersen::CommitmentKeyExtTrait, traits::DlogGroup},
+  spartan::polys::eq::EqPolynomial,
+  traits::{
+    commitment::{CommitmentEngineTrait, CommitmentTrait},
+    evaluation::EvaluationEngineTrait,
+    Engine, TranscriptEngineTrait, TranscriptReprTrait,
+  },
+  Commitment, CommitmentKey, CompressedCommitment, CE,
+};
+use abomonation_derive::Abomonation;
+use core::iter;
+use ff::Field;
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+use std::marker::PhantomData;
+
+/// Provides an implementation of the prover key
+#[derive(Clone, Debug, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_omit_bounds]
+pub struct ProverKey<E: Engine> {
+  ck_s: CommitmentKey<E>,
+}
+
+/// Provides an implementation of the verifier key
+#[derive(Clone, Debug, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_omit_bounds]
+pub struct VerifierKey<E: Engine> {
+  ck_v: CommitmentKey<E>,
+  ck_s: CommitmentKey<E>,
+}
+
+/// Provides an implementation of a polynomial evaluation engine using IPA
+#[derive(Clone, Debug, Serialize, Deserialize)]
+pub struct EvaluationEngine<E> {
+  _p: PhantomData<E>,
+}
+
+impl<E> EvaluationEngineTrait<E> for EvaluationEngine<E>
+where
+  E: Engine,
+  E::GE: DlogGroup,
+  CommitmentKey<E>: CommitmentKeyExtTrait<E>,
+{
+  type ProverKey = ProverKey<E>;
+  type VerifierKey = VerifierKey<E>;
+  type EvaluationArgument = InnerProductArgument<E>;
+
+  fn setup(
+    ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+  ) -> (Self::ProverKey, Self::VerifierKey) {
+    let ck_c = E::CE::setup(b"ipa", 1);
+
+    let pk = ProverKey { ck_s: ck_c.clone() };
+    let vk = VerifierKey {
+      ck_v: ck.clone(),
+      ck_s: ck_c,
+    };
+
+    (pk, vk)
+  }
+
+  fn prove(
+    ck: &CommitmentKey<E>,
+    pk: &Self::ProverKey,
+    transcript: &mut E::TE,
+    comm: &Commitment<E>,
+    poly: &[E::Scalar],
+    point: &[E::Scalar],
+    eval: &E::Scalar,
+  ) -> Result<Self::EvaluationArgument, NovaError> {
+    let u = InnerProductInstance::new(comm, &EqPolynomial::evals_from_points(point), eval);
+    let w = InnerProductWitness::new(poly);
+
+    InnerProductArgument::prove(ck, &pk.ck_s, &u, &w, transcript)
+  }
+
+  /// A method to verify purported evaluations of a batch of polynomials
+  fn verify(
+    vk: &Self::VerifierKey,
+    transcript: &mut E::TE,
+    comm: &Commitment<E>,
+    point: &[E::Scalar],
+    eval: &E::Scalar,
+    arg: &Self::EvaluationArgument,
+  ) -> Result<(), NovaError> {
+    let u = InnerProductInstance::new(comm, &EqPolynomial::evals_from_points(point), eval);
+
+    arg.verify(
+      &vk.ck_v,
+      &vk.ck_s,
+      (2_usize).pow(point.len() as u32),
+      &u,
+      transcript,
+    )?;
+
+    Ok(())
+  }
+}
+
+fn inner_product<T: Field + Send + Sync>(a: &[T], b: &[T]) -> T {
+  assert_eq!(a.len(), b.len());
+  (0..a.len())
+    .into_par_iter()
+    .map(|i| a[i] * b[i])
+    .reduce(|| T::ZERO, |x, y| x + y)
+}
+
+/// An inner product instance consists of a commitment to a vector `a` and another vector `b`
+/// and the claim that c = <a, b>.
+struct InnerProductInstance<E: Engine> {
+  comm_a_vec: Commitment<E>,
+  b_vec: Vec<E::Scalar>,
+  c: E::Scalar,
+}
+
+impl<E> InnerProductInstance<E>
+where
+  E: Engine,
+  E::GE: DlogGroup,
+{
+  fn new(comm_a_vec: &Commitment<E>, b_vec: &[E::Scalar], c: &E::Scalar) -> Self {
+    Self {
+      comm_a_vec: *comm_a_vec,
+      b_vec: b_vec.to_vec(),
+      c: *c,
+    }
+  }
+}
+
+impl<E: Engine> TranscriptReprTrait<E::GE> for InnerProductInstance<E> {
+  fn to_transcript_bytes(&self) -> Vec<u8> {
+    // we do not need to include self.b_vec as in our context it is produced from the transcript
+    [
+      self.comm_a_vec.to_transcript_bytes(),
+      self.c.to_transcript_bytes(),
+    ]
+    .concat()
+  }
+}
+
+struct InnerProductWitness<E: Engine> {
+  a_vec: Vec<E::Scalar>,
+}
+
+impl<E: Engine> InnerProductWitness<E> {
+  fn new(a_vec: &[E::Scalar]) -> Self {
+    Self {
+      a_vec: a_vec.to_vec(),
+    }
+  }
+}
+
+/// An inner product argument
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct InnerProductArgument<E: Engine> {
+  L_vec: Vec<CompressedCommitment<E>>,
+  R_vec: Vec<CompressedCommitment<E>>,
+  a_hat: E::Scalar,
+}
+
+impl<E> InnerProductArgument<E>
+where
+  E: Engine,
+  E::GE: DlogGroup,
+  CommitmentKey<E>: CommitmentKeyExtTrait<E>,
+{
+  const fn protocol_name() -> &'static [u8] {
+    b"IPA"
+  }
+
+  fn prove(
+    ck: &CommitmentKey<E>,
+    ck_c: &CommitmentKey<E>,
+    U: &InnerProductInstance<E>,
+    W: &InnerProductWitness<E>,
+    transcript: &mut E::TE,
+  ) -> Result<Self, NovaError> {
+    transcript.dom_sep(Self::protocol_name());
+
+    let (ck, _) = ck.split_at(U.b_vec.len());
+
+    if U.b_vec.len() != W.a_vec.len() {
+      return Err(NovaError::InvalidInputLength);
+    }
+
+    // absorb the instance in the transcript
+    transcript.absorb(b"U", U);
+
+    // sample a random base for commiting to the inner product
+    let r = transcript.squeeze(b"r")?;
+    let ck_c = ck_c.scale(&r);
+
+    // a closure that executes a step of the recursive inner product argument
+    let prove_inner = |a_vec: &[E::Scalar],
+                       b_vec: &[E::Scalar],
+                       ck: &CommitmentKey<E>,
+                       transcript: &mut E::TE|
+     -> Result<
+      (
+        CompressedCommitment<E>,
+        CompressedCommitment<E>,
+        Vec<E::Scalar>,
+        Vec<E::Scalar>,
+        CommitmentKey<E>,
+      ),
+      NovaError,
+    > {
+      let n = a_vec.len();
+      let (ck_L, ck_R) = ck.split_at(n / 2);
+
+      let c_L = inner_product(&a_vec[0..n / 2], &b_vec[n / 2..n]);
+      let c_R = inner_product(&a_vec[n / 2..n], &b_vec[0..n / 2]);
+
+      let L = CE::<E>::commit(
+        &ck_R.combine(&ck_c),
+        &a_vec[0..n / 2]
+          .iter()
+          .chain(iter::once(&c_L))
+          .copied()
+          .collect::<Vec<E::Scalar>>(),
+      )
+      .compress();
+      let R = CE::<E>::commit(
+        &ck_L.combine(&ck_c),
+        &a_vec[n / 2..n]
+          .iter()
+          .chain(iter::once(&c_R))
+          .copied()
+          .collect::<Vec<E::Scalar>>(),
+      )
+      .compress();
+
+      transcript.absorb(b"L", &L);
+      transcript.absorb(b"R", &R);
+
+      let r = transcript.squeeze(b"r")?;
+      let r_inverse = r.invert().unwrap();
+
+      // fold the left half and the right half
+      let a_vec_folded = a_vec[0..n / 2]
+        .par_iter()
+        .zip_eq(a_vec[n / 2..n].par_iter())
+        .map(|(a_L, a_R)| *a_L * r + r_inverse * *a_R)
+        .collect::<Vec<E::Scalar>>();
+
+      let b_vec_folded = b_vec[0..n / 2]
+        .par_iter()
+        .zip_eq(b_vec[n / 2..n].par_iter())
+        .map(|(b_L, b_R)| *b_L * r_inverse + r * *b_R)
+        .collect::<Vec<E::Scalar>>();
+
+      let ck_folded = ck.fold(&r_inverse, &r);
+
+      Ok((L, R, a_vec_folded, b_vec_folded, ck_folded))
+    };
+
+    // two vectors to hold the logarithmic number of group elements
+    let mut L_vec: Vec<CompressedCommitment<E>> = Vec::new();
+    let mut R_vec: Vec<CompressedCommitment<E>> = Vec::new();
+
+    // we create mutable copies of vectors and generators
+    let mut a_vec = W.a_vec.to_vec();
+    let mut b_vec = U.b_vec.to_vec();
+    let mut ck = ck;
+    for _i in 0..usize::try_from(U.b_vec.len().ilog2()).unwrap() {
+      let (L, R, a_vec_folded, b_vec_folded, ck_folded) =
+        prove_inner(&a_vec, &b_vec, &ck, transcript)?;
+      L_vec.push(L);
+      R_vec.push(R);
+
+      a_vec = a_vec_folded;
+      b_vec = b_vec_folded;
+      ck = ck_folded;
+    }
+
+    Ok(Self {
+      L_vec,
+      R_vec,
+      a_hat: a_vec[0],
+    })
+  }
+
+  fn verify(
+    &self,
+    ck: &CommitmentKey<E>,
+    ck_c: &CommitmentKey<E>,
+    n: usize,
+    U: &InnerProductInstance<E>,
+    transcript: &mut E::TE,
+  ) -> Result<(), NovaError> {
+    let (ck, _) = ck.split_at(U.b_vec.len());
+
+    transcript.dom_sep(Self::protocol_name());
+    if U.b_vec.len() != n
+      || n != (1 << self.L_vec.len())
+      || self.L_vec.len() != self.R_vec.len()
+      || self.L_vec.len() >= 32
+    {
+      return Err(NovaError::InvalidInputLength);
+    }
+
+    // absorb the instance in the transcript
+    transcript.absorb(b"U", U);
+
+    // sample a random base for commiting to the inner product
+    let r = transcript.squeeze(b"r")?;
+    let ck_c = ck_c.scale(&r);
+
+    let P = U.comm_a_vec + CE::<E>::commit(&ck_c, &[U.c]);
+
+    let batch_invert = |v: &[E::Scalar]| -> Result<Vec<E::Scalar>, NovaError> {
+      let mut products = vec![E::Scalar::ZERO; v.len()];
+      let mut acc = E::Scalar::ONE;
+
+      for i in 0..v.len() {
+        products[i] = acc;
+        acc *= v[i];
+      }
+
+      // return error if acc is zero
+      acc = match Option::from(acc.invert()) {
+        Some(inv) => inv,
+        None => return Err(NovaError::InternalError),
+      };
+
+      // compute the inverse once for all entries
+      let mut inv = vec![E::Scalar::ZERO; v.len()];
+      for i in (0..v.len()).rev() {
+        let tmp = acc * v[i];
+        inv[i] = products[i] * acc;
+        acc = tmp;
+      }
+
+      Ok(inv)
+    };
+
+    // compute a vector of public coins using self.L_vec and self.R_vec
+    let r = (0..self.L_vec.len())
+      .map(|i| {
+        transcript.absorb(b"L", &self.L_vec[i]);
+        transcript.absorb(b"R", &self.R_vec[i]);
+        transcript.squeeze(b"r")
+      })
+      .collect::<Result<Vec<E::Scalar>, NovaError>>()?;
+
+    // precompute scalars necessary for verification
+    let r_square: Vec<E::Scalar> = (0..self.L_vec.len())
+      .into_par_iter()
+      .map(|i| r[i] * r[i])
+      .collect();
+    let r_inverse = batch_invert(&r)?;
+    let r_inverse_square: Vec<E::Scalar> = (0..self.L_vec.len())
+      .into_par_iter()
+      .map(|i| r_inverse[i] * r_inverse[i])
+      .collect();
+
+    // compute the vector with the tensor structure
+    let s = {
+      let mut s = vec![E::Scalar::ZERO; n];
+      s[0] = {
+        let mut v = E::Scalar::ONE;
+        for r_inverse_i in r_inverse {
+          v *= r_inverse_i;
+        }
+        v
+      };
+      for i in 1..n {
+        let pos_in_r = (31 - (i as u32).leading_zeros()) as usize;
+        s[i] = s[i - (1 << pos_in_r)] * r_square[(self.L_vec.len() - 1) - pos_in_r];
+      }
+      s
+    };
+
+    let ck_hat = {
+      let c = CE::<E>::commit(&ck, &s).compress();
+      CommitmentKey::<E>::reinterpret_commitments_as_ck(&[c])?
+    };
+
+    let b_hat = inner_product(&U.b_vec, &s);
+
+    let P_hat = {
+      let ck_folded = {
+        let ck_L = CommitmentKey::<E>::reinterpret_commitments_as_ck(&self.L_vec)?;
+        let ck_R = CommitmentKey::<E>::reinterpret_commitments_as_ck(&self.R_vec)?;
+        let ck_P = CommitmentKey::<E>::reinterpret_commitments_as_ck(&[P.compress()])?;
+        ck_L.combine(&ck_R).combine(&ck_P)
+      };
+
+      CE::<E>::commit(
+        &ck_folded,
+        &r_square
+          .iter()
+          .chain(r_inverse_square.iter())
+          .chain(iter::once(&E::Scalar::ONE))
+          .copied()
+          .collect::<Vec<E::Scalar>>(),
+      )
+    };
+
+    if P_hat == CE::<E>::commit(&ck_hat.combine(&ck_c), &[self.a_hat, self.a_hat * b_hat]) {
+      Ok(())
+    } else {
+      Err(NovaError::PCSError(PCSError::InvalidIPA))
+    }
+  }
+}
+
+#[cfg(test)]
+mod test {
+  use crate::provider::ipa_pc::EvaluationEngine;
+  use crate::provider::util::test_utils::prove_verify_from_num_vars;
+  use crate::provider::GrumpkinEngine;
+
+  #[test]
+  fn test_multiple_polynomial_size() {
+    for num_vars in [4, 5, 6] {
+      prove_verify_from_num_vars::<_, EvaluationEngine<GrumpkinEngine>>(num_vars);
+    }
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/keccak.rs.html b/docs/src/arecibo/provider/keccak.rs.html new file mode 100644 index 000000000..d605c70d5 --- /dev/null +++ b/docs/src/arecibo/provider/keccak.rs.html @@ -0,0 +1,509 @@ +keccak.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+
//! This module provides an implementation of `TranscriptEngineTrait` using keccak256
+use crate::traits::PrimeFieldExt;
+use crate::{
+  errors::NovaError,
+  traits::{Engine, TranscriptEngineTrait, TranscriptReprTrait},
+};
+use core::marker::PhantomData;
+use sha3::{Digest, Keccak256};
+
+const PERSONA_TAG: &[u8] = b"NoTR";
+const DOM_SEP_TAG: &[u8] = b"NoDS";
+const KECCAK256_STATE_SIZE: usize = 64;
+const KECCAK256_PREFIX_CHALLENGE_LO: u8 = 0;
+const KECCAK256_PREFIX_CHALLENGE_HI: u8 = 1;
+
+/// Provides an implementation of `TranscriptEngine`
+#[derive(Debug, Clone)]
+pub struct Keccak256Transcript<E: Engine> {
+  round: u16,
+  state: [u8; KECCAK256_STATE_SIZE],
+  transcript: Keccak256,
+  _p: PhantomData<E>,
+}
+
+fn compute_updated_state(keccak_instance: Keccak256, input: &[u8]) -> [u8; KECCAK256_STATE_SIZE] {
+  let mut updated_instance = keccak_instance;
+  updated_instance.update(input);
+
+  let input_lo = &[KECCAK256_PREFIX_CHALLENGE_LO];
+  let input_hi = &[KECCAK256_PREFIX_CHALLENGE_HI];
+
+  let mut hasher_lo = updated_instance.clone();
+  let mut hasher_hi = updated_instance;
+
+  hasher_lo.update(input_lo);
+  hasher_hi.update(input_hi);
+
+  let output_lo = hasher_lo.finalize();
+  let output_hi = hasher_hi.finalize();
+
+  [output_lo, output_hi]
+    .concat()
+    .as_slice()
+    .try_into()
+    .unwrap()
+}
+
+impl<E: Engine> TranscriptEngineTrait<E> for Keccak256Transcript<E> {
+  fn new(label: &'static [u8]) -> Self {
+    let keccak_instance = Keccak256::new();
+    let input = [PERSONA_TAG, label].concat();
+    let output = compute_updated_state(keccak_instance.clone(), &input);
+
+    Self {
+      round: 0u16,
+      state: output,
+      transcript: keccak_instance,
+      _p: PhantomData,
+    }
+  }
+
+  fn squeeze(&mut self, label: &'static [u8]) -> Result<E::Scalar, NovaError> {
+    // we gather the full input from the round, preceded by the current state of the transcript
+    let input = [
+      DOM_SEP_TAG,
+      self.round.to_le_bytes().as_ref(),
+      self.state.as_ref(),
+      label,
+    ]
+    .concat();
+    let output = compute_updated_state(self.transcript.clone(), &input);
+
+    // update state
+    self.round = {
+      if let Some(v) = self.round.checked_add(1) {
+        v
+      } else {
+        return Err(NovaError::InternalTranscriptError);
+      }
+    };
+    self.state.copy_from_slice(&output);
+    self.transcript = Keccak256::new();
+
+    // squeeze out a challenge
+    Ok(E::Scalar::from_uniform(&output))
+  }
+
+  fn absorb<T: TranscriptReprTrait<E::GE>>(&mut self, label: &'static [u8], o: &T) {
+    self.transcript.update(label);
+    self.transcript.update(&o.to_transcript_bytes());
+  }
+
+  fn dom_sep(&mut self, bytes: &'static [u8]) {
+    self.transcript.update(DOM_SEP_TAG);
+    self.transcript.update(bytes);
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use crate::{
+    provider::keccak::Keccak256Transcript,
+    provider::{
+      Bn256Engine, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine,
+    },
+    traits::{Engine, PrimeFieldExt, TranscriptEngineTrait, TranscriptReprTrait},
+  };
+  use ff::PrimeField;
+  use rand::Rng;
+  use sha3::{Digest, Keccak256};
+
+  fn test_keccak_transcript_with<E: Engine>(expected_h1: &'static str, expected_h2: &'static str) {
+    let mut transcript: Keccak256Transcript<E> = Keccak256Transcript::new(b"test");
+
+    // two scalars
+    let s1 = <E as Engine>::Scalar::from(2u64);
+    let s2 = <E as Engine>::Scalar::from(5u64);
+
+    // add the scalars to the transcript
+    transcript.absorb(b"s1", &s1);
+    transcript.absorb(b"s2", &s2);
+
+    // make a challenge
+    let c1: <E as Engine>::Scalar = transcript.squeeze(b"c1").unwrap();
+    assert_eq!(hex::encode(c1.to_repr().as_ref()), expected_h1);
+
+    // a scalar
+    let s3 = <E as Engine>::Scalar::from(128u64);
+
+    // add the scalar to the transcript
+    transcript.absorb(b"s3", &s3);
+
+    // make a challenge
+    let c2: <E as Engine>::Scalar = transcript.squeeze(b"c2").unwrap();
+    assert_eq!(hex::encode(c2.to_repr().as_ref()), expected_h2);
+  }
+
+  #[test]
+  fn test_keccak_transcript() {
+    test_keccak_transcript_with::<PallasEngine>(
+      "5ddffa8dc091862132788b8976af88b9a2c70594727e611c7217ba4c30c8c70a",
+      "4d4bf42c065870395749fa1c4fb641df1e0d53f05309b03d5b1db7f0be3aa13d",
+    );
+
+    test_keccak_transcript_with::<Bn256Engine>(
+      "9fb71e3b74bfd0b60d97349849b895595779a240b92a6fae86bd2812692b6b0e",
+      "bfd4c50b7d6317e9267d5d65c985eb455a3561129c0b3beef79bfc8461a84f18",
+    );
+
+    test_keccak_transcript_with::<Secp256k1Engine>(
+      "9723aafb69ec8f0e9c7de756df0993247d98cf2b2f72fa353e3de654a177e310",
+      "a6a90fcb6e1b1a2a2f84c950ef1510d369aea8e42085f5c629bfa66d00255f25",
+    );
+  }
+
+  #[test]
+  fn test_keccak_example() {
+    let mut hasher = Keccak256::new();
+    hasher.update(0xffffffff_u32.to_le_bytes());
+    let output: [u8; 32] = hasher.finalize().into();
+    assert_eq!(
+      hex::encode(output),
+      "29045a592007d0c246ef02c2223570da9522d0cf0f73282c79a1bc8f0bb2c238"
+    );
+  }
+
+  use super::{
+    DOM_SEP_TAG, KECCAK256_PREFIX_CHALLENGE_HI, KECCAK256_PREFIX_CHALLENGE_LO,
+    KECCAK256_STATE_SIZE, PERSONA_TAG,
+  };
+
+  fn compute_updated_state_for_testing(input: &[u8]) -> [u8; KECCAK256_STATE_SIZE] {
+    let input_lo = [input, &[KECCAK256_PREFIX_CHALLENGE_LO]].concat();
+    let input_hi = [input, &[KECCAK256_PREFIX_CHALLENGE_HI]].concat();
+
+    let mut hasher_lo = Keccak256::new();
+    let mut hasher_hi = Keccak256::new();
+
+    hasher_lo.update(&input_lo);
+    hasher_hi.update(&input_hi);
+
+    let output_lo = hasher_lo.finalize();
+    let output_hi = hasher_hi.finalize();
+
+    [output_lo, output_hi]
+      .concat()
+      .as_slice()
+      .try_into()
+      .unwrap()
+  }
+
+  fn squeeze_for_testing(
+    transcript: &[u8],
+    round: u16,
+    state: [u8; KECCAK256_STATE_SIZE],
+    label: &'static [u8],
+  ) -> [u8; 64] {
+    let input = [
+      transcript,
+      DOM_SEP_TAG,
+      round.to_le_bytes().as_ref(),
+      state.as_ref(),
+      label,
+    ]
+    .concat();
+    compute_updated_state_for_testing(&input)
+  }
+
+  // This test is meant to ensure compatibility between the incremental way of computing the transcript above, and
+  // the former, which materialized the entirety of the input vector before calling Keccak256 on it.
+  fn test_keccak_transcript_incremental_vs_explicit_with<E: Engine>() {
+    let test_label = b"test";
+    let mut transcript: Keccak256Transcript<E> = Keccak256Transcript::new(test_label);
+    let mut rng = rand::thread_rng();
+
+    // ten scalars
+    let scalars = std::iter::from_fn(|| Some(<E as Engine>::Scalar::from(rng.gen::<u64>())))
+      .take(10)
+      .collect::<Vec<_>>();
+
+    // add the scalars to the transcripts,
+    let mut manual_transcript: Vec<u8> = vec![];
+    let labels = [
+      b"s1", b"s2", b"s3", b"s4", b"s5", b"s6", b"s7", b"s8", b"s9", b"s0",
+    ];
+
+    for i in 0..10 {
+      transcript.absorb(&labels[i][..], &scalars[i]);
+      manual_transcript.extend(labels[i]);
+      manual_transcript.extend(scalars[i].to_transcript_bytes());
+    }
+
+    // compute the initial state
+    let input = [PERSONA_TAG, test_label].concat();
+    let initial_state = compute_updated_state_for_testing(&input);
+
+    // make a challenge
+    let c1: <E as Engine>::Scalar = transcript.squeeze(b"c1").unwrap();
+
+    let c1_bytes = squeeze_for_testing(&manual_transcript[..], 0u16, initial_state, b"c1");
+    let to_hex = |g: E::Scalar| hex::encode(g.to_repr().as_ref());
+    assert_eq!(to_hex(c1), to_hex(E::Scalar::from_uniform(&c1_bytes)));
+  }
+
+  #[test]
+  fn test_keccak_transcript_incremental_vs_explicit() {
+    test_keccak_transcript_incremental_vs_explicit_with::<PallasEngine>();
+    test_keccak_transcript_incremental_vs_explicit_with::<VestaEngine>();
+    test_keccak_transcript_incremental_vs_explicit_with::<Bn256Engine>();
+    test_keccak_transcript_incremental_vs_explicit_with::<GrumpkinEngine>();
+    test_keccak_transcript_incremental_vs_explicit_with::<Secp256k1Engine>();
+    test_keccak_transcript_incremental_vs_explicit_with::<Secq256k1Engine>();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/kzg_commitment.rs.html b/docs/src/arecibo/provider/kzg_commitment.rs.html new file mode 100644 index 000000000..1cc282a3e --- /dev/null +++ b/docs/src/arecibo/provider/kzg_commitment.rs.html @@ -0,0 +1,157 @@ +kzg_commitment.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+
//! Commitment engine for KZG commitments
+//!
+
+use std::marker::PhantomData;
+
+use ff::PrimeFieldBits;
+use group::{prime::PrimeCurveAffine, Curve};
+use pairing::Engine;
+use rand::rngs::StdRng;
+use rand_core::SeedableRng;
+use serde::{Deserialize, Serialize};
+
+use crate::traits::{
+  commitment::{CommitmentEngineTrait, Len},
+  Engine as NovaEngine, Group,
+};
+
+use crate::provider::{
+  non_hiding_kzg::{UVKZGCommitment, UniversalKZGParam},
+  pedersen::Commitment,
+  traits::DlogGroup,
+};
+
+/// Provides a commitment engine
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct KZGCommitmentEngine<E> {
+  _p: PhantomData<E>,
+}
+
+impl<E: Engine, NE: NovaEngine<GE = E::G1, Scalar = E::Fr>> CommitmentEngineTrait<NE>
+  for KZGCommitmentEngine<E>
+where
+  E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+  E::G1Affine: Serialize + for<'de> Deserialize<'de>,
+  E::G2Affine: Serialize + for<'de> Deserialize<'de>,
+  E::Fr: PrimeFieldBits, // TODO due to use of gen_srs_for_testing, make optional
+{
+  type CommitmentKey = UniversalKZGParam<E>;
+  type Commitment = Commitment<NE>;
+
+  fn setup(label: &'static [u8], n: usize) -> Self::CommitmentKey {
+    // TODO: this is just for testing, replace by grabbing from a real setup for production
+    let mut bytes = [0u8; 32];
+    let len = label.len().min(32);
+    bytes[..len].copy_from_slice(&label[..len]);
+    let rng = &mut StdRng::from_seed(bytes);
+    UniversalKZGParam::gen_srs_for_testing(rng, n.next_power_of_two())
+  }
+
+  fn commit(ck: &Self::CommitmentKey, v: &[<E::G1 as Group>::Scalar]) -> Self::Commitment {
+    assert!(ck.length() >= v.len());
+    Commitment {
+      comm: E::G1::vartime_multiscalar_mul(v, &ck.powers_of_g[..v.len()]),
+    }
+  }
+}
+
+impl<E: Engine, NE: NovaEngine<GE = E::G1, Scalar = E::Fr>> From<Commitment<NE>>
+  for UVKZGCommitment<E>
+where
+  E::G1: Group,
+{
+  fn from(c: Commitment<NE>) -> Self {
+    Self(c.comm.to_affine())
+  }
+}
+
+impl<E: Engine, NE: NovaEngine<GE = E::G1, Scalar = E::Fr>> From<UVKZGCommitment<E>>
+  for Commitment<NE>
+where
+  E::G1: Group,
+{
+  fn from(c: UVKZGCommitment<E>) -> Self {
+    Self {
+      comm: c.0.to_curve(),
+    }
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/mlkzg.rs.html b/docs/src/arecibo/provider/mlkzg.rs.html new file mode 100644 index 000000000..2ef6f184a --- /dev/null +++ b/docs/src/arecibo/provider/mlkzg.rs.html @@ -0,0 +1,1187 @@ +mlkzg.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+
//! This module implements Nova's evaluation engine using multilinear KZG
+#![allow(non_snake_case)]
+use crate::{
+  errors::NovaError,
+  provider::{
+    kzg_commitment::KZGCommitmentEngine,
+    non_hiding_kzg::{KZGProverKey, KZGVerifierKey, UniversalKZGParam},
+    pedersen::Commitment,
+    traits::DlogGroup,
+  },
+  spartan::polys::univariate::UniPoly,
+  traits::{
+    commitment::{CommitmentEngineTrait, Len},
+    evaluation::EvaluationEngineTrait,
+    Engine as NovaEngine, Group, TranscriptEngineTrait, TranscriptReprTrait,
+  },
+  zip_with,
+};
+use core::marker::PhantomData;
+use ff::{Field, PrimeFieldBits};
+use group::{Curve, Group as _};
+use itertools::Itertools as _;
+use pairing::{Engine, MillerLoopResult, MultiMillerLoop};
+use rayon::prelude::*;
+use ref_cast::RefCast as _;
+use serde::{de::DeserializeOwned, Deserialize, Serialize};
+
+/// Provides an implementation of a polynomial evaluation argument
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound(
+  serialize = "E::G1Affine: Serialize, E::Fr: Serialize",
+  deserialize = "E::G1Affine: Deserialize<'de>, E::Fr: Deserialize<'de>"
+))]
+pub struct EvaluationArgument<E: Engine> {
+  comms: Vec<E::G1Affine>,
+  w: Vec<E::G1Affine>,
+  evals: Vec<Vec<E::Fr>>,
+}
+
+/// Provides an implementation of a polynomial evaluation engine using KZG
+#[derive(Clone, Debug, Serialize, Deserialize)]
+pub struct EvaluationEngine<E, NE> {
+  _p: PhantomData<(E, NE)>,
+}
+
+// This impl block defines helper functions that are not a part of
+// EvaluationEngineTrait, but that we will use to implement the trait methods.
+impl<E, NE> EvaluationEngine<E, NE>
+where
+  E: Engine,
+  NE: NovaEngine<GE = E::G1, Scalar = E::Fr>,
+  E::G1: DlogGroup,
+  E::Fr: TranscriptReprTrait<E::G1>,
+  E::G1Affine: TranscriptReprTrait<E::G1>, // TODO: this bound on DlogGroup is really unusable!
+{
+  fn compute_challenge(
+    com: &[E::G1Affine],
+    transcript: &mut impl TranscriptEngineTrait<NE>,
+  ) -> E::Fr {
+    transcript.absorb(b"c", &com.to_vec().as_slice());
+    transcript.squeeze(b"c").unwrap()
+  }
+
+  // Compute challenge q = Hash(vk, C0, ..., C_{k-1}, u0, ...., u_{t-1},
+  // (f_i(u_j))_{i=0..k-1,j=0..t-1})
+  // It is assumed that both 'C' and 'u' are already absorbed by the transcript
+  fn get_batch_challenge(
+    v: &[Vec<E::Fr>],
+    transcript: &mut impl TranscriptEngineTrait<NE>,
+  ) -> E::Fr {
+    transcript.absorb(
+      b"v",
+      &v.iter()
+        .flatten()
+        .cloned()
+        .collect::<Vec<E::Fr>>()
+        .as_slice(),
+    );
+
+    transcript.squeeze(b"r").unwrap()
+  }
+
+  fn batch_challenge_powers(q: E::Fr, k: usize) -> Vec<E::Fr> {
+    // Compute powers of q : (1, q, q^2, ..., q^(k-1))
+    std::iter::successors(Some(E::Fr::ONE), |&x| Some(x * q))
+      .take(k)
+      .collect()
+  }
+
+  fn verifier_second_challenge(
+    W: &[E::G1Affine],
+    transcript: &mut impl TranscriptEngineTrait<NE>,
+  ) -> E::Fr {
+    transcript.absorb(b"W", &W.to_vec().as_slice());
+
+    transcript.squeeze(b"d").unwrap()
+  }
+}
+
+impl<E, NE> EvaluationEngineTrait<NE> for EvaluationEngine<E, NE>
+where
+  E: MultiMillerLoop,
+  NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>,
+  E::Fr: Serialize + DeserializeOwned,
+  E::G1Affine: Serialize + DeserializeOwned,
+  E::G2Affine: Serialize + DeserializeOwned,
+  E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+  <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>, // Note: due to the move of the bound TranscriptReprTrait<G> on G::Base from Group to Engine
+  E::Fr: PrimeFieldBits, // TODO due to use of gen_srs_for_testing, make optional
+  E::Fr: TranscriptReprTrait<E::G1>,
+  E::G1Affine: TranscriptReprTrait<E::G1>,
+{
+  type EvaluationArgument = EvaluationArgument<E>;
+  type ProverKey = KZGProverKey<E>;
+  type VerifierKey = KZGVerifierKey<E>;
+
+  fn setup(ck: &UniversalKZGParam<E>) -> (Self::ProverKey, Self::VerifierKey) {
+    ck.trim(ck.length() - 1)
+  }
+
+  fn prove(
+    ck: &UniversalKZGParam<E>,
+    _pk: &Self::ProverKey,
+    transcript: &mut <NE as NovaEngine>::TE,
+    _C: &Commitment<NE>,
+    hat_P: &[E::Fr],
+    point: &[E::Fr],
+    _eval: &E::Fr,
+  ) -> Result<Self::EvaluationArgument, NovaError> {
+    let x: Vec<E::Fr> = point.to_vec();
+
+    //////////////// begin helper closures //////////
+    let kzg_open = |f: &[E::Fr], u: E::Fr| -> E::G1Affine {
+      // On input f(x) and u compute the witness polynomial used to prove
+      // that f(u) = v. The main part of this is to compute the
+      // division (f(x) - f(u)) / (x - u), but we don't use a general
+      // division algorithm, we make use of the fact that the division
+      // never has a remainder, and that the denominator is always a linear
+      // polynomial. The cost is (d-1) mults + (d-1) adds in E::Scalar, where
+      // d is the degree of f.
+      //
+      // We use the fact that if we compute the quotient of f(x)/(x-u),
+      // there will be a remainder, but it'll be v = f(u).  Put another way
+      // the quotient of f(x)/(x-u) and (f(x) - f(v))/(x-u) is the
+      // same.  One advantage is that computing f(u) could be decoupled
+      // from kzg_open, it could be done later or separate from computing W.
+
+      let compute_witness_polynomial = |f: &[E::Fr], u: E::Fr| -> Vec<E::Fr> {
+        let d = f.len();
+
+        // Compute h(x) = f(x)/(x - u)
+        let mut h = vec![E::Fr::ZERO; d];
+        for i in (1..d).rev() {
+          h[i - 1] = f[i] + h[i] * u;
+        }
+
+        h
+      };
+
+      let h = compute_witness_polynomial(f, u);
+
+      <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &h)
+        .comm
+        .to_affine()
+    };
+
+    let kzg_open_batch = |f: &[Vec<E::Fr>],
+                          u: &[E::Fr],
+                          transcript: &mut <NE as NovaEngine>::TE|
+     -> (Vec<E::G1Affine>, Vec<Vec<E::Fr>>) {
+      let scalar_vector_muladd = |a: &mut Vec<E::Fr>, v: &Vec<E::Fr>, s: E::Fr| {
+        assert!(a.len() >= v.len());
+        #[allow(clippy::disallowed_methods)]
+        a.par_iter_mut()
+          .zip(v.par_iter())
+          .for_each(|(c, v)| *c += s * v);
+      };
+
+      let kzg_compute_batch_polynomial = |f: &[Vec<E::Fr>], q: E::Fr| -> Vec<E::Fr> {
+        let k = f.len(); // Number of polynomials we're batching
+
+        let q_powers = Self::batch_challenge_powers(q, k);
+
+        // Compute B(x) = f[0] + q*f[1] + q^2 * f[2] + ... q^(k-1) * f[k-1]
+        let mut B = f[0].clone();
+        for i in 1..k {
+          scalar_vector_muladd(&mut B, &f[i], q_powers[i]); // B += q_powers[i] * f[i]
+        }
+
+        B
+      };
+      ///////// END kzg_open_batch closure helpers
+
+      let k = f.len();
+      let t = u.len();
+
+      // The verifier needs f_i(u_j), so we compute them here
+      // (V will compute B(u_j) itself)
+      let mut v = vec![vec!(E::Fr::ZERO; k); t];
+      v.par_iter_mut().enumerate().for_each(|(i, v_i)| {
+        // for each point u
+        v_i.par_iter_mut().zip_eq(f).for_each(|(v_ij, f)| {
+          // for each poly f (except the last one - since it is constant)
+          *v_ij = UniPoly::ref_cast(f).evaluate(&u[i]);
+        });
+      });
+
+      let q = Self::get_batch_challenge(&v, transcript);
+      let B = kzg_compute_batch_polynomial(f, q);
+
+      // Now open B at u0, ..., u_{t-1}
+      let w = u.par_iter().map(|ui| kzg_open(&B, *ui)).collect::<Vec<_>>();
+
+      // The prover computes the challenge to keep the transcript in the same
+      // state as that of the verifier
+      let _d_0 = Self::verifier_second_challenge(&w, transcript);
+      (w, v)
+    };
+
+    ///// END helper closures //////////
+
+    let ell = x.len();
+    let n = hat_P.len();
+    assert_eq!(n, 1 << ell); // Below we assume that n is a power of two
+
+    // Phase 1  -- create commitments com_1, ..., com_\ell
+    let mut polys: Vec<Vec<E::Fr>> = Vec::new();
+    polys.push(hat_P.to_vec());
+
+    // We don't compute final Pi (and its commitment) as it is constant and equals to 'eval'
+    // also known to verifier, so can be derived on its side as well
+    for i in 0..x.len() - 1 {
+      let Pi_len = polys[i].len() / 2;
+      let mut Pi = vec![E::Fr::ZERO; Pi_len];
+
+      #[allow(clippy::needless_range_loop)]
+      Pi.par_iter_mut().enumerate().for_each(|(j, Pi_j)| {
+        *Pi_j = x[ell - i - 1] * (polys[i][2 * j + 1] - polys[i][2 * j]) + polys[i][2 * j];
+      });
+
+      polys.push(Pi);
+    }
+
+    // We do not need to commit to the first polynomial as it is already committed.
+    // Compute commitments in parallel
+    let comms: Vec<E::G1Affine> = (1..polys.len())
+      .into_par_iter()
+      .map(|i| {
+        <NE::CE as CommitmentEngineTrait<NE>>::commit(ck, &polys[i])
+          .comm
+          .to_affine()
+      })
+      .collect();
+
+    // Phase 2
+    // We do not need to add x to the transcript, because in our context x was
+    // obtained from the transcript.
+    let r = Self::compute_challenge(&comms, transcript);
+    let u = vec![r, -r, r * r];
+
+    // Phase 3 -- create response
+    let (w, evals) = kzg_open_batch(&polys, &u, transcript);
+
+    Ok(EvaluationArgument { comms, w, evals })
+  }
+
+  /// A method to verify purported evaluations of a batch of polynomials
+  fn verify(
+    vk: &Self::VerifierKey,
+    transcript: &mut <NE as NovaEngine>::TE,
+    C: &Commitment<NE>,
+    point: &[E::Fr],
+    P_of_x: &E::Fr,
+    pi: &Self::EvaluationArgument,
+  ) -> Result<(), NovaError> {
+    let x = point.to_vec();
+    let y = P_of_x;
+
+    // vk is hashed in transcript already, so we do not add it here
+
+    let kzg_verify_batch = |vk: &KZGVerifierKey<E>,
+                            C: &Vec<E::G1Affine>,
+                            W: &Vec<E::G1Affine>,
+                            u: &Vec<E::Fr>,
+                            v: &Vec<Vec<E::Fr>>,
+                            transcript: &mut <NE as NovaEngine>::TE|
+     -> bool {
+      let k = C.len();
+      let t = u.len();
+
+      let q = Self::get_batch_challenge(v, transcript);
+      let q_powers = Self::batch_challenge_powers(q, k); // 1, q, q^2, ..., q^(k-1)
+
+      let d_0 = Self::verifier_second_challenge(W, transcript);
+      let d_1 = d_0 * d_0;
+
+      assert!(t == 3);
+      assert!(W.len() == 3);
+      // We write a special case for t=3, since this what is required for
+      // mlkzg. Following the paper directly, we must compute:
+      // let L0 = C_B - vk.G * B_u[0] + W[0] * u[0];
+      // let L1 = C_B - vk.G * B_u[1] + W[1] * u[1];
+      // let L2 = C_B - vk.G * B_u[2] + W[2] * u[2];
+      // let R0 = -W[0];
+      // let R1 = -W[1];
+      // let R2 = -W[2];
+      // let L = L0 + L1*d_0 + L2*d_1;
+      // let R = R0 + R1*d_0 + R2*d_1;
+      //
+      // We group terms to reduce the number of scalar mults (to seven):
+      // In Rust, we could use MSMs for these, and speed up verification.
+      //
+      // Note, that while computing L, the intermediate computation of C_B together with computing
+      // L0, L1, L2 can be replaced by single MSM of C with the powers of q multiplied by (1 + d_0 + d_1)
+      // with additionally concatenated inputs for scalars/bases.
+
+      let q_power_multiplier = E::Fr::ONE + d_0 + d_1;
+
+      let q_powers_multiplied: Vec<E::Fr> = q_powers
+        .par_iter()
+        .map(|q_power| *q_power * q_power_multiplier)
+        .collect();
+
+      // Compute the batched openings
+      // compute B(u_i) = v[i][0] + q*v[i][1] + ... + q^(t-1) * v[i][t-1]
+      let B_u = v
+        .into_par_iter()
+        .map(|v_i| zip_with!(iter, (q_powers, v_i), |a, b| *a * *b).sum())
+        .collect::<Vec<E::Fr>>();
+
+      let L = NE::GE::vartime_multiscalar_mul(
+        &[
+          &q_powers_multiplied[..k],
+          &[
+            u[0],
+            (u[1] * d_0),
+            (u[2] * d_1),
+            (B_u[0] + d_0 * B_u[1] + d_1 * B_u[2]),
+          ],
+        ]
+        .concat(),
+        &[
+          &C[..k],
+          &[
+            E::G1::from(W[0]).into(),
+            E::G1::from(W[1]).into(),
+            E::G1::from(W[2]).into(),
+            (-E::G1::from(vk.g)).into(),
+          ],
+        ]
+        .concat(),
+      );
+
+      let R0 = E::G1::from(W[0]);
+      let R1 = E::G1::from(W[1]);
+      let R2 = E::G1::from(W[2]);
+      let R = R0 + R1 * d_0 + R2 * d_1;
+
+      // Check that e(L, vk.H) == e(R, vk.tau_H)
+      let pairing_inputs = [
+        (&(-L).to_affine(), &E::G2Prepared::from(vk.h)),
+        (&R.to_affine(), &E::G2Prepared::from(vk.beta_h)),
+      ];
+
+      let pairing_result = E::multi_miller_loop(&pairing_inputs).final_exponentiation();
+      pairing_result.is_identity().into()
+    };
+    ////// END verify() closure helpers
+
+    let ell = x.len();
+
+    let mut com = pi.comms.clone();
+
+    // we do not need to add x to the transcript, because in our context x was
+    // obtained from the transcript
+    let r = Self::compute_challenge(&com, transcript);
+    if r == E::Fr::ZERO || C.comm == E::G1::identity() {
+      return Err(NovaError::ProofVerifyError);
+    }
+    com.insert(0, C.comm.to_affine()); // set com_0 = C, shifts other commitments to the right
+
+    let u = vec![r, -r, r * r];
+
+    // Setup vectors (Y, ypos, yneg) from pi.v
+    let v = &pi.evals;
+    if v.len() != 3 {
+      return Err(NovaError::ProofVerifyError);
+    }
+    if v[0].len() != ell || v[1].len() != ell || v[2].len() != ell {
+      return Err(NovaError::ProofVerifyError);
+    }
+    let ypos = &v[0];
+    let yneg = &v[1];
+    let mut Y = v[2].to_vec();
+    Y.push(*y);
+
+    // Check consistency of (Y, ypos, yneg)
+    let two = E::Fr::from(2u64);
+    for i in 0..ell {
+      if two * r * Y[i + 1]
+        != r * (E::Fr::ONE - x[ell - i - 1]) * (ypos[i] + yneg[i])
+          + x[ell - i - 1] * (ypos[i] - yneg[i])
+      {
+        return Err(NovaError::ProofVerifyError);
+      }
+      // Note that we don't make any checks about Y[0] here, but our batching
+      // check below requires it
+    }
+
+    // Check commitments to (Y, ypos, yneg) are valid
+    if !kzg_verify_batch(vk, &com, &pi.w, &u, &pi.evals, transcript) {
+      return Err(NovaError::ProofVerifyError);
+    }
+
+    Ok(())
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::provider::util::test_utils::prove_verify_from_num_vars;
+  use crate::{
+    provider::keccak::Keccak256Transcript, traits::commitment::CommitmentTrait, CommitmentKey,
+  };
+  use bincode::Options;
+
+  type E = halo2curves::bn256::Bn256;
+  type NE = crate::provider::Bn256EngineKZG;
+  type Fr = <NE as NovaEngine>::Scalar;
+
+  #[test]
+  fn test_mlkzg_eval() {
+    // Test with poly(X1, X2) = 1 + X1 + X2 + X1*X2
+    let n = 4;
+    let ck: CommitmentKey<NE> =
+      <KZGCommitmentEngine<E> as CommitmentEngineTrait<NE>>::setup(b"test", n);
+    let (pk, _vk): (KZGProverKey<E>, KZGVerifierKey<E>) = EvaluationEngine::<E, NE>::setup(&ck);
+
+    // poly is in eval. representation; evaluated at [(0,0), (0,1), (1,0), (1,1)]
+    let poly = vec![Fr::from(1), Fr::from(2), Fr::from(2), Fr::from(4)];
+
+    let C = <KZGCommitmentEngine<E> as CommitmentEngineTrait<NE>>::commit(&ck, &poly);
+    let mut tr = Keccak256Transcript::<NE>::new(b"TestEval");
+
+    // Call the prover with a (point, eval) pair. The prover recomputes
+    // poly(point) = eval', and fails if eval' != eval
+    let point = vec![Fr::from(0), Fr::from(0)];
+    let eval = Fr::ONE;
+    assert!(EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut tr, &C, &poly, &point, &eval).is_ok());
+
+    let point = vec![Fr::from(0), Fr::from(1)];
+    let eval = Fr::from(2);
+    assert!(EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut tr, &C, &poly, &point, &eval).is_ok());
+
+    let point = vec![Fr::from(1), Fr::from(1)];
+    let eval = Fr::from(4);
+    assert!(EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut tr, &C, &poly, &point, &eval).is_ok());
+
+    let point = vec![Fr::from(0), Fr::from(2)];
+    let eval = Fr::from(3);
+    assert!(EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut tr, &C, &poly, &point, &eval).is_ok());
+
+    let point = vec![Fr::from(2), Fr::from(2)];
+    let eval = Fr::from(9);
+    assert!(EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut tr, &C, &poly, &point, &eval).is_ok());
+  }
+
+  #[test]
+  fn test_mlkzg_alternative() {
+    fn test_inner(n: usize, poly: &[Fr], point: &[Fr], eval: Fr) -> Result<(), NovaError> {
+      let ck: CommitmentKey<NE> =
+        <KZGCommitmentEngine<E> as CommitmentEngineTrait<NE>>::setup(b"test", n);
+      let (pk, vk): (KZGProverKey<E>, KZGVerifierKey<E>) = EvaluationEngine::<E, NE>::setup(&ck);
+
+      // make a commitment
+      let C = KZGCommitmentEngine::commit(&ck, poly);
+
+      // prove an evaluation
+      let mut prover_transcript = Keccak256Transcript::new(b"TestEval");
+      let proof =
+        EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut prover_transcript, &C, poly, point, &eval)
+          .unwrap();
+
+      // verify the evaluation
+      let mut verifier_transcript = Keccak256Transcript::<NE>::new(b"TestEval");
+      EvaluationEngine::<E, NE>::verify(&vk, &mut verifier_transcript, &C, point, &eval, &proof)
+    }
+
+    let n = 8;
+
+    // poly = [1, 2, 1, 4, 1, 2, 1, 4]
+    let poly = vec![
+      Fr::ONE,
+      Fr::from(2),
+      Fr::from(1),
+      Fr::from(4),
+      Fr::ONE,
+      Fr::from(2),
+      Fr::from(1),
+      Fr::from(4),
+    ];
+
+    // point = [4,3,8]
+    let point = vec![Fr::from(4), Fr::from(3), Fr::from(8)];
+
+    // eval = 57
+    let eval = Fr::from(57);
+
+    assert!(test_inner(n, &poly, &point, eval).is_ok());
+
+    // wrong eval
+    let eval = Fr::from(56);
+    assert!(test_inner(n, &poly, &point, eval).is_err());
+  }
+
+  #[test]
+  fn test_mlkzg() {
+    let n = 4;
+
+    // poly = [1, 2, 1, 4]
+    let poly = vec![Fr::ONE, Fr::from(2), Fr::from(1), Fr::from(4)];
+
+    // point = [4,3]
+    let point = vec![Fr::from(4), Fr::from(3)];
+
+    // eval = 28
+    let eval = Fr::from(28);
+
+    let ck: CommitmentKey<NE> =
+      <KZGCommitmentEngine<E> as CommitmentEngineTrait<NE>>::setup(b"test", n);
+    let (pk, vk): (KZGProverKey<E>, KZGVerifierKey<E>) = EvaluationEngine::<E, NE>::setup(&ck);
+
+    // make a commitment
+    let C = KZGCommitmentEngine::commit(&ck, &poly);
+
+    // prove an evaluation
+    let mut prover_transcript = Keccak256Transcript::new(b"TestEval");
+    let proof =
+      EvaluationEngine::<E, NE>::prove(&ck, &pk, &mut prover_transcript, &C, &poly, &point, &eval)
+        .unwrap();
+    let post_c_p = prover_transcript.squeeze(b"c").unwrap();
+
+    // verify the evaluation
+    let mut verifier_transcript = Keccak256Transcript::<NE>::new(b"TestEval");
+    assert!(EvaluationEngine::<E, NE>::verify(
+      &vk,
+      &mut verifier_transcript,
+      &C,
+      &point,
+      &eval,
+      &proof
+    )
+    .is_ok());
+    let post_c_v = verifier_transcript.squeeze(b"c").unwrap();
+
+    // check if the prover transcript and verifier transcript are kept in the
+    // same state
+    assert_eq!(post_c_p, post_c_v);
+
+    let my_options = bincode::DefaultOptions::new()
+      .with_big_endian()
+      .with_fixint_encoding();
+    let mut output_bytes = my_options.serialize(&vk).unwrap();
+    output_bytes.append(&mut my_options.serialize(&C.compress()).unwrap());
+    output_bytes.append(&mut my_options.serialize(&point).unwrap());
+    output_bytes.append(&mut my_options.serialize(&eval).unwrap());
+    output_bytes.append(&mut my_options.serialize(&proof).unwrap());
+    println!("total output = {} bytes", output_bytes.len());
+
+    // Change the proof and expect verification to fail
+    let mut bad_proof = proof.clone();
+    bad_proof.comms[0] = (bad_proof.comms[0] + bad_proof.comms[0] * Fr::from(123)).to_affine();
+    let mut verifier_transcript2 = Keccak256Transcript::<NE>::new(b"TestEval");
+    assert!(EvaluationEngine::<E, NE>::verify(
+      &vk,
+      &mut verifier_transcript2,
+      &C,
+      &point,
+      &eval,
+      &bad_proof
+    )
+    .is_err());
+  }
+
+  #[test]
+  fn test_mlkzg_more() {
+    // test the mlkzg prover and verifier with random instances (derived from a seed)
+    for num_vars in [4, 5, 6] {
+      prove_verify_from_num_vars::<_, EvaluationEngine<E, NE>>(num_vars);
+    }
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/mod.rs.html b/docs/src/arecibo/provider/mod.rs.html new file mode 100644 index 000000000..9e6b0fd6e --- /dev/null +++ b/docs/src/arecibo/provider/mod.rs.html @@ -0,0 +1,471 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+
//! This module implements Nova's traits using the following several different combinations
+
+// public modules to be used as an evaluation engine with Spartan
+pub mod ipa_pc;
+pub mod mlkzg;
+pub mod non_hiding_zeromorph;
+
+// crate-public modules, made crate-public mostly for tests
+pub(crate) mod bn256_grumpkin;
+mod pasta;
+mod pedersen;
+pub(crate) mod poseidon;
+pub(crate) mod secp_secq;
+pub(crate) mod traits;
+// a non-hiding variant of {kzg, zeromorph}
+mod kzg_commitment;
+mod non_hiding_kzg;
+mod util;
+
+// crate-private modules
+mod keccak;
+
+use crate::{
+  provider::{
+    bn256_grumpkin::{bn256, grumpkin},
+    keccak::Keccak256Transcript,
+    pedersen::CommitmentEngine as PedersenCommitmentEngine,
+    poseidon::{PoseidonRO, PoseidonROCircuit},
+    secp_secq::{secp256k1, secq256k1},
+  },
+  traits::Engine,
+};
+use halo2curves::bn256::Bn256;
+use pasta_curves::{pallas, vesta};
+
+use self::kzg_commitment::KZGCommitmentEngine;
+
+/// An implementation of the Nova `Engine` trait with BN254 curve and Pedersen commitment scheme
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct Bn256Engine;
+
+/// An implementation of the Nova `Engine` trait with Grumpkin curve and Pedersen commitment scheme
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct GrumpkinEngine;
+
+impl Engine for Bn256Engine {
+  type Base = bn256::Base;
+  type Scalar = bn256::Scalar;
+  type GE = bn256::Point;
+  type RO = PoseidonRO<Self::Base, Self::Scalar>;
+  type ROCircuit = PoseidonROCircuit<Self::Base>;
+  type TE = Keccak256Transcript<Self>;
+  type CE = PedersenCommitmentEngine<Self>;
+}
+
+impl Engine for GrumpkinEngine {
+  type Base = grumpkin::Base;
+  type Scalar = grumpkin::Scalar;
+  type GE = grumpkin::Point;
+  type RO = PoseidonRO<Self::Base, Self::Scalar>;
+  type ROCircuit = PoseidonROCircuit<Self::Base>;
+  type TE = Keccak256Transcript<Self>;
+  type CE = PedersenCommitmentEngine<Self>;
+}
+
+/// An implementation of the Nova `Engine` trait with BN254 curve and Zeromorph commitment scheme
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct Bn256EngineZM;
+
+impl Engine for Bn256EngineZM {
+  type Base = bn256::Base;
+  type Scalar = bn256::Scalar;
+  type GE = bn256::Point;
+  type RO = PoseidonRO<Self::Base, Self::Scalar>;
+  type ROCircuit = PoseidonROCircuit<Self::Base>;
+  type TE = Keccak256Transcript<Self>;
+  type CE = KZGCommitmentEngine<Bn256>;
+}
+/// An implementation of Nova traits with multilinear KZG over the BN256 curve
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct Bn256EngineKZG;
+
+impl Engine for Bn256EngineKZG {
+  type Base = bn256::Base;
+  type Scalar = bn256::Scalar;
+  type GE = bn256::Point;
+  type RO = PoseidonRO<Self::Base, Self::Scalar>;
+  type ROCircuit = PoseidonROCircuit<Self::Base>;
+  type TE = Keccak256Transcript<Self>;
+  type CE = KZGCommitmentEngine<Bn256>;
+}
+
+/// An implementation of the Nova `Engine` trait with Secp256k1 curve and Pedersen commitment scheme
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct Secp256k1Engine;
+
+/// An implementation of the Nova `Engine` trait with Secp256k1 curve and Pedersen commitment scheme
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct Secq256k1Engine;
+
+impl Engine for Secp256k1Engine {
+  type Base = secp256k1::Base;
+  type Scalar = secp256k1::Scalar;
+  type GE = secp256k1::Point;
+  type RO = PoseidonRO<Self::Base, Self::Scalar>;
+  type ROCircuit = PoseidonROCircuit<Self::Base>;
+  type TE = Keccak256Transcript<Self>;
+  type CE = PedersenCommitmentEngine<Self>;
+}
+
+impl Engine for Secq256k1Engine {
+  type Base = secq256k1::Base;
+  type Scalar = secq256k1::Scalar;
+  type GE = secq256k1::Point;
+  type RO = PoseidonRO<Self::Base, Self::Scalar>;
+  type ROCircuit = PoseidonROCircuit<Self::Base>;
+  type TE = Keccak256Transcript<Self>;
+  type CE = PedersenCommitmentEngine<Self>;
+}
+
+/// An implementation of the Nova `Engine` trait with Pallas curve and Pedersen commitment scheme
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct PallasEngine;
+
+/// An implementation of the Nova `Engine` trait with Vesta curve and Pedersen commitment scheme
+#[derive(Clone, Copy, Debug, Eq, PartialEq)]
+pub struct VestaEngine;
+
+impl Engine for PallasEngine {
+  type Base = pallas::Base;
+  type Scalar = pallas::Scalar;
+  type GE = pallas::Point;
+  type RO = PoseidonRO<Self::Base, Self::Scalar>;
+  type ROCircuit = PoseidonROCircuit<Self::Base>;
+  type TE = Keccak256Transcript<Self>;
+  type CE = PedersenCommitmentEngine<Self>;
+}
+
+impl Engine for VestaEngine {
+  type Base = vesta::Base;
+  type Scalar = vesta::Scalar;
+  type GE = vesta::Point;
+  type RO = PoseidonRO<Self::Base, Self::Scalar>;
+  type ROCircuit = PoseidonROCircuit<Self::Base>;
+  type TE = Keccak256Transcript<Self>;
+  type CE = PedersenCommitmentEngine<Self>;
+}
+
+#[cfg(test)]
+mod tests {
+  use crate::provider::{
+    bn256_grumpkin::{bn256, grumpkin},
+    secp_secq::{secp256k1, secq256k1},
+    traits::DlogGroup,
+    util::msm::cpu_best_msm,
+  };
+  use digest::{ExtendableOutput, Update};
+  use group::{ff::Field, Curve, Group};
+  use halo2curves::{CurveAffine, CurveExt};
+  use itertools::Itertools as _;
+  use pasta_curves::{pallas, vesta};
+  use rand_core::OsRng;
+  use sha3::Shake256;
+  use std::io::Read;
+
+  macro_rules! impl_cycle_pair_test {
+    ($curve:ident) => {
+      fn from_label_serial(label: &'static [u8], n: usize) -> Vec<$curve::Affine> {
+        let mut shake = Shake256::default();
+        shake.update(label);
+        let mut reader = shake.finalize_xof();
+        (0..n)
+          .map(|_| {
+            let mut uniform_bytes = [0u8; 32];
+            reader.read_exact(&mut uniform_bytes).unwrap();
+            let hash = $curve::Point::hash_to_curve("from_uniform_bytes");
+            hash(&uniform_bytes).to_affine()
+          })
+          .collect()
+      }
+
+      let label = b"test_from_label";
+      for n in [
+        1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 1021,
+      ] {
+        let ck_par = <$curve::Point as DlogGroup>::from_label(label, n);
+        let ck_ser = from_label_serial(label, n);
+        assert_eq!(ck_par.len(), n);
+        assert_eq!(ck_ser.len(), n);
+        assert_eq!(ck_par, ck_ser);
+      }
+    };
+  }
+
+  fn test_msm_with<F: Field, A: CurveAffine<ScalarExt = F>>() {
+    let n = 8;
+    let coeffs = (0..n).map(|_| F::random(OsRng)).collect::<Vec<_>>();
+    let bases = (0..n)
+      .map(|_| A::from(A::generator() * F::random(OsRng)))
+      .collect::<Vec<_>>();
+    let naive = coeffs
+      .iter()
+      .zip_eq(bases.iter())
+      .fold(A::CurveExt::identity(), |acc, (coeff, base)| {
+        acc + *base * coeff
+      });
+
+    assert_eq!(naive, cpu_best_msm(&bases, &coeffs))
+  }
+
+  #[test]
+  fn test_msm() {
+    test_msm_with::<pallas::Scalar, pallas::Affine>();
+    test_msm_with::<vesta::Scalar, vesta::Affine>();
+    test_msm_with::<bn256::Scalar, bn256::Affine>();
+    test_msm_with::<grumpkin::Scalar, grumpkin::Affine>();
+    test_msm_with::<secp256k1::Scalar, secp256k1::Affine>();
+    test_msm_with::<secq256k1::Scalar, secq256k1::Affine>();
+  }
+
+  #[test]
+  fn test_bn256_from_label() {
+    impl_cycle_pair_test!(bn256);
+  }
+
+  #[test]
+  fn test_pallas_from_label() {
+    impl_cycle_pair_test!(pallas);
+  }
+
+  #[test]
+  fn test_secp256k1_from_label() {
+    impl_cycle_pair_test!(secp256k1);
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/non_hiding_kzg.rs.html b/docs/src/arecibo/provider/non_hiding_kzg.rs.html new file mode 100644 index 000000000..de7d60889 --- /dev/null +++ b/docs/src/arecibo/provider/non_hiding_kzg.rs.html @@ -0,0 +1,763 @@ +non_hiding_kzg.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+
//! Non-hiding variant of KZG10 scheme for univariate polynomials.
+use abomonation_derive::Abomonation;
+use ff::{Field, PrimeField, PrimeFieldBits};
+use group::{prime::PrimeCurveAffine, Curve, Group as _};
+use pairing::{Engine, MillerLoopResult, MultiMillerLoop};
+use rand_core::{CryptoRng, RngCore};
+use serde::{Deserialize, Serialize};
+use std::{borrow::Borrow, marker::PhantomData, ops::Mul};
+
+use crate::{
+  errors::{NovaError, PCSError},
+  provider::traits::DlogGroup,
+  provider::util::fb_msm,
+  traits::{commitment::Len, Group, TranscriptReprTrait},
+};
+
+/// `UniversalParams` are the universal parameters for the KZG10 scheme.
+#[derive(Debug, Clone, Eq, Serialize, Deserialize, Abomonation)]
+#[serde(bound(
+  serialize = "E::G1Affine: Serialize, E::G2Affine: Serialize",
+  deserialize = "E::G1Affine: Deserialize<'de>, E::G2Affine: Deserialize<'de>"
+))]
+#[abomonation_omit_bounds]
+pub struct UniversalKZGParam<E: Engine> {
+  /// Group elements of the form `{ β^i G }`, where `i` ranges from 0 to
+  /// `degree`.
+  #[abomonate_with(Vec<[u64; 8]>)] // // this is a hack; we just assume the size of the element.
+  pub powers_of_g: Vec<E::G1Affine>,
+  /// Group elements of the form `{ β^i H }`, where `i` ranges from 0 to
+  /// `degree`.
+  #[abomonate_with(Vec<[u64; 16]>)] // this is a hack; we just assume the size of the element.
+  pub powers_of_h: Vec<E::G2Affine>,
+}
+
+impl<E: Engine> PartialEq for UniversalKZGParam<E> {
+  fn eq(&self, other: &Self) -> bool {
+    self.powers_of_g == other.powers_of_g && self.powers_of_h == other.powers_of_h
+  }
+}
+
+// for the purpose of the Len trait, we count commitment bases, i.e. G1 elements
+impl<E: Engine> Len for UniversalKZGParam<E> {
+  fn length(&self) -> usize {
+    self.powers_of_g.len()
+  }
+}
+
+/// `UnivariateProverKey` is used to generate a proof
+#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Abomonation)]
+#[abomonation_omit_bounds]
+#[serde(bound(
+  serialize = "E::G1Affine: Serialize",
+  deserialize = "E::G1Affine: Deserialize<'de>"
+))]
+pub struct KZGProverKey<E: Engine> {
+  /// generators
+  #[abomonate_with(Vec<[u64; 8]>)] // this is a hack; we just assume the size of the element.
+  pub powers_of_g: Vec<E::G1Affine>,
+}
+
+/// `UVKZGVerifierKey` is used to check evaluation proofs for a given
+/// commitment.
+#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Abomonation)]
+#[abomonation_omit_bounds]
+#[serde(bound(
+  serialize = "E::G1Affine: Serialize, E::G2Affine: Serialize",
+  deserialize = "E::G1Affine: Deserialize<'de>, E::G2Affine: Deserialize<'de>"
+))]
+pub struct KZGVerifierKey<E: Engine> {
+  /// The generator of G1.
+  #[abomonate_with([u64; 8])] // this is a hack; we just assume the size of the element.
+  pub g: E::G1Affine,
+  /// The generator of G2.
+  #[abomonate_with([u64; 16])] // this is a hack; we just assume the size of the element.
+  pub h: E::G2Affine,
+  /// β times the above generator of G2.
+  #[abomonate_with([u64; 16])] // this is a hack; we just assume the size of the element.
+  pub beta_h: E::G2Affine,
+}
+
+impl<E: Engine> UniversalKZGParam<E> {
+  /// Returns the maximum supported degree
+  pub fn max_degree(&self) -> usize {
+    self.powers_of_g.len()
+  }
+
+  /// Returns the prover parameters
+  ///
+  /// # Panics
+  /// if `supported_size` is greater than `self.max_degree()`
+  pub fn extract_prover_key(&self, supported_size: usize) -> KZGProverKey<E> {
+    let powers_of_g = self.powers_of_g[..=supported_size].to_vec();
+    KZGProverKey { powers_of_g }
+  }
+
+  /// Returns the verifier parameters
+  ///
+  /// # Panics
+  /// If self.prover_params is empty.
+  pub fn extract_verifier_key(&self, supported_size: usize) -> KZGVerifierKey<E> {
+    assert!(
+      self.powers_of_g.len() >= supported_size,
+      "supported_size is greater than self.max_degree()"
+    );
+    KZGVerifierKey {
+      g: self.powers_of_g[0],
+      h: self.powers_of_h[0],
+      beta_h: self.powers_of_h[1],
+    }
+  }
+
+  /// Trim the universal parameters to specialize the public parameters
+  /// for univariate polynomials to the given `supported_size`, and
+  /// returns prover key and verifier key. `supported_size` should
+  /// be in range `1..params.len()`
+  ///
+  /// # Panics
+  /// If `supported_size` is greater than `self.max_degree()`, or `self.max_degree()` is zero.
+  pub fn trim(&self, supported_size: usize) -> (KZGProverKey<E>, KZGVerifierKey<E>) {
+    let powers_of_g = self.powers_of_g[..=supported_size].to_vec();
+
+    let pk = KZGProverKey { powers_of_g };
+    let vk = KZGVerifierKey {
+      g: self.powers_of_g[0],
+      h: self.powers_of_h[0],
+      beta_h: self.powers_of_h[1],
+    };
+    (pk, vk)
+  }
+}
+
+impl<E: Engine> UniversalKZGParam<E>
+where
+  E::Fr: PrimeFieldBits,
+{
+  /// Build SRS for testing.
+  /// WARNING: THIS FUNCTION IS FOR TESTING PURPOSE ONLY.
+  /// THE OUTPUT SRS SHOULD NOT BE USED IN PRODUCTION.
+  pub fn gen_srs_for_testing<R: RngCore + CryptoRng>(mut rng: &mut R, max_degree: usize) -> Self {
+    let beta = E::Fr::random(&mut rng);
+    let g = E::G1::random(&mut rng);
+    let h = E::G2::random(rng);
+
+    let nz_powers_of_beta = (0..=max_degree)
+      .scan(beta, |acc, _| {
+        let val = *acc;
+        *acc *= beta;
+        Some(val)
+      })
+      .collect::<Vec<E::Fr>>();
+
+    let window_size = fb_msm::get_mul_window_size(max_degree);
+    let scalar_bits = E::Fr::NUM_BITS as usize;
+
+    let (powers_of_g_projective, powers_of_h_projective) = rayon::join(
+      || {
+        let g_table = fb_msm::get_window_table(scalar_bits, window_size, g);
+        fb_msm::multi_scalar_mul::<E::G1>(scalar_bits, window_size, &g_table, &nz_powers_of_beta)
+      },
+      || {
+        let h_table = fb_msm::get_window_table(scalar_bits, window_size, h);
+        fb_msm::multi_scalar_mul::<E::G2>(scalar_bits, window_size, &h_table, &nz_powers_of_beta)
+      },
+    );
+
+    let mut powers_of_g = vec![E::G1Affine::identity(); powers_of_g_projective.len()];
+    let mut powers_of_h = vec![E::G2Affine::identity(); powers_of_h_projective.len()];
+
+    rayon::join(
+      || E::G1::batch_normalize(&powers_of_g_projective, &mut powers_of_g),
+      || E::G2::batch_normalize(&powers_of_h_projective, &mut powers_of_h),
+    );
+
+    Self {
+      powers_of_g,
+      powers_of_h,
+    }
+  }
+}
+/// Commitments
+#[derive(Debug, Clone, Copy, Eq, PartialEq, Default, Serialize, Deserialize)]
+#[serde(bound(
+  serialize = "E::G1Affine: Serialize",
+  deserialize = "E::G1Affine: Deserialize<'de>"
+))]
+pub struct UVKZGCommitment<E: Engine>(
+  /// the actual commitment is an affine point.
+  pub E::G1Affine,
+);
+
+impl<E: Engine> TranscriptReprTrait<E::G1> for UVKZGCommitment<E>
+where
+  E::G1: DlogGroup,
+  // Note: due to the move of the bound TranscriptReprTrait<G> on G::Base from Group to Engine
+  <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>,
+{
+  fn to_transcript_bytes(&self) -> Vec<u8> {
+    // TODO: avoid the round-trip through the group (to_curve .. to_coordinates)
+    let (x, y, is_infinity) = self.0.to_curve().to_coordinates();
+    let is_infinity_byte = (!is_infinity).into();
+    [
+      x.to_transcript_bytes(),
+      y.to_transcript_bytes(),
+      [is_infinity_byte].to_vec(),
+    ]
+    .concat()
+  }
+}
+
+/// Polynomial Evaluation
+#[derive(Debug, Clone, Eq, PartialEq, Default)]
+pub struct UVKZGEvaluation<E: Engine>(pub E::Fr);
+
+#[derive(Debug, Clone, Eq, PartialEq, Default)]
+
+/// Proofs
+pub struct UVKZGProof<E: Engine> {
+  /// proof
+  pub proof: E::G1Affine,
+}
+
+/// Polynomial and its associated types
+pub type UVKZGPoly<F> = crate::spartan::polys::univariate::UniPoly<F>;
+
+#[derive(Debug, Clone, Eq, PartialEq, Default)]
+/// KZG Polynomial Commitment Scheme on univariate polynomial.
+/// Note: this is non-hiding, which is why we will implement traits on this token struct,
+/// as we expect to have several impls for the trait pegged on the same instance of a pairing::Engine.
+#[allow(clippy::upper_case_acronyms)]
+pub struct UVKZGPCS<E> {
+  #[doc(hidden)]
+  phantom: PhantomData<E>,
+}
+
+impl<E: MultiMillerLoop> UVKZGPCS<E>
+where
+  E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+{
+  pub fn commit_offset(
+    prover_param: impl Borrow<KZGProverKey<E>>,
+    poly: &UVKZGPoly<E::Fr>,
+    offset: usize,
+  ) -> Result<UVKZGCommitment<E>, NovaError> {
+    let prover_param = prover_param.borrow();
+
+    if poly.degree() > prover_param.powers_of_g.len() {
+      return Err(NovaError::PCSError(PCSError::LengthError));
+    }
+
+    let scalars = poly.coeffs.as_slice();
+    let bases = prover_param.powers_of_g.as_slice();
+
+    // We can avoid some scalar multiplications if 'scalars' contains a lot of leading zeroes using
+    // offset, that points where non-zero scalars start.
+    let C = <E::G1 as DlogGroup>::vartime_multiscalar_mul(
+      &scalars[offset..],
+      &bases[offset..scalars.len()],
+    );
+
+    Ok(UVKZGCommitment(C.to_affine()))
+  }
+
+  /// Generate a commitment for a polynomial
+  /// Note that the scheme is not hidding
+  pub fn commit(
+    prover_param: impl Borrow<KZGProverKey<E>>,
+    poly: &UVKZGPoly<E::Fr>,
+  ) -> Result<UVKZGCommitment<E>, NovaError> {
+    let prover_param = prover_param.borrow();
+
+    if poly.degree() > prover_param.powers_of_g.len() {
+      return Err(NovaError::PCSError(PCSError::LengthError));
+    }
+    let C = <E::G1 as DlogGroup>::vartime_multiscalar_mul(
+      poly.coeffs.as_slice(),
+      &prover_param.powers_of_g.as_slice()[..poly.coeffs.len()],
+    );
+    Ok(UVKZGCommitment(C.to_affine()))
+  }
+
+  /// On input a polynomial `p` and a point `point`, outputs a proof for the
+  /// same.
+  pub fn open(
+    prover_param: impl Borrow<KZGProverKey<E>>,
+    polynomial: &UVKZGPoly<E::Fr>,
+    point: &E::Fr,
+  ) -> Result<(UVKZGProof<E>, UVKZGEvaluation<E>), NovaError> {
+    let prover_param = prover_param.borrow();
+    let divisor = UVKZGPoly {
+      coeffs: vec![-*point, E::Fr::ONE],
+    };
+    let witness_polynomial = polynomial
+      .divide_with_q_and_r(&divisor)
+      .map(|(q, _r)| q)
+      .ok_or(NovaError::PCSError(PCSError::ZMError))?;
+    let proof = <E::G1 as DlogGroup>::vartime_multiscalar_mul(
+      witness_polynomial.coeffs.as_slice(),
+      &prover_param.powers_of_g.as_slice()[..witness_polynomial.coeffs.len()],
+    );
+    let evaluation = UVKZGEvaluation(polynomial.evaluate(point));
+
+    Ok((
+      UVKZGProof {
+        proof: proof.to_affine(),
+      },
+      evaluation,
+    ))
+  }
+
+  /// Verifies that `value` is the evaluation at `x` of the polynomial
+  /// committed inside `comm`.
+  #[allow(dead_code, clippy::unnecessary_wraps)]
+  fn verify(
+    verifier_param: impl Borrow<KZGVerifierKey<E>>,
+    commitment: &UVKZGCommitment<E>,
+    point: &E::Fr,
+    proof: &UVKZGProof<E>,
+    evaluation: &UVKZGEvaluation<E>,
+  ) -> Result<bool, NovaError> {
+    let verifier_param = verifier_param.borrow();
+
+    let pairing_inputs: Vec<(E::G1Affine, E::G2Prepared)> = vec![
+      (
+        (verifier_param.g.mul(evaluation.0) - proof.proof.mul(point) - commitment.0.to_curve())
+          .to_affine(),
+        verifier_param.h.into(),
+      ),
+      (proof.proof, verifier_param.beta_h.into()),
+    ];
+    let pairing_input_refs = pairing_inputs
+      .iter()
+      .map(|(a, b)| (a, b))
+      .collect::<Vec<_>>();
+    let pairing_result = E::multi_miller_loop(pairing_input_refs.as_slice()).final_exponentiation();
+    Ok(pairing_result.is_identity().into())
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::spartan::polys::univariate::UniPoly;
+  use rand::{thread_rng, Rng};
+  use rand_core::{CryptoRng, RngCore};
+
+  fn random<F: PrimeField, R: RngCore + CryptoRng>(degree: usize, mut rng: &mut R) -> UVKZGPoly<F> {
+    let coeffs = (0..=degree).map(|_| F::random(&mut rng)).collect();
+    UniPoly::new(coeffs)
+  }
+
+  fn end_to_end_test_template<E>() -> Result<(), NovaError>
+  where
+    E: MultiMillerLoop,
+    E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+    E::Fr: PrimeFieldBits,
+  {
+    for _ in 0..100 {
+      let mut rng = &mut thread_rng();
+      let degree = rng.gen_range(2..20);
+
+      let pp = UniversalKZGParam::<E>::gen_srs_for_testing(&mut rng, degree);
+      let (ck, vk) = pp.trim(degree);
+      let p = random(degree, rng);
+      let comm = UVKZGPCS::<E>::commit(&ck, &p)?;
+      let point = E::Fr::random(rng);
+      let (proof, value) = UVKZGPCS::<E>::open(&ck, &p, &point)?;
+      assert!(
+        UVKZGPCS::<E>::verify(&vk, &comm, &point, &proof, &value)?,
+        "proof was incorrect for max_degree = {}, polynomial_degree = {}",
+        degree,
+        p.degree(),
+      );
+    }
+    Ok(())
+  }
+
+  #[test]
+  fn end_to_end_test() {
+    end_to_end_test_template::<halo2curves::bn256::Bn256>().expect("test failed for Bn256");
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/non_hiding_zeromorph.rs.html b/docs/src/arecibo/provider/non_hiding_zeromorph.rs.html new file mode 100644 index 000000000..c4c7f2bd5 --- /dev/null +++ b/docs/src/arecibo/provider/non_hiding_zeromorph.rs.html @@ -0,0 +1,1791 @@ +non_hiding_zeromorph.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+
//! Non-hiding Zeromorph scheme for Multilinear Polynomials.
+//!
+//!
+
+use crate::{
+  errors::{NovaError, PCSError},
+  provider::{
+    non_hiding_kzg::{
+      KZGProverKey, KZGVerifierKey, UVKZGCommitment, UVKZGEvaluation, UVKZGPoly, UVKZGProof,
+      UniversalKZGParam, UVKZGPCS,
+    },
+    traits::DlogGroup,
+  },
+  spartan::polys::multilinear::MultilinearPolynomial,
+  traits::{
+    commitment::Len, evaluation::EvaluationEngineTrait, Engine as NovaEngine, Group,
+    TranscriptEngineTrait, TranscriptReprTrait,
+  },
+  Commitment,
+};
+use abomonation_derive::Abomonation;
+use ff::{BatchInvert, Field, PrimeField, PrimeFieldBits};
+use group::{Curve, Group as _};
+use itertools::Itertools as _;
+use pairing::{Engine, MillerLoopResult, MultiMillerLoop};
+use rayon::{
+  iter::IntoParallelRefIterator,
+  prelude::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator},
+};
+use ref_cast::RefCast;
+use serde::{Deserialize, Serialize};
+use std::{borrow::Borrow, iter, marker::PhantomData};
+
+use crate::provider::kzg_commitment::KZGCommitmentEngine;
+
+/// `ZMProverKey` is used to generate a proof
+#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Abomonation)]
+#[abomonation_omit_bounds]
+#[serde(bound(
+  serialize = "E::G1Affine: Serialize",
+  deserialize = "E::G1Affine: Deserialize<'de>"
+))]
+pub struct ZMProverKey<E: Engine> {
+  commit_pp: KZGProverKey<E>,
+  open_pp: KZGProverKey<E>,
+}
+
+/// `ZMVerifierKey` is used to check evaluation proofs for a given
+/// commitment.
+#[derive(Clone, Debug, Eq, PartialEq, Serialize, Deserialize, Abomonation)]
+#[abomonation_omit_bounds]
+#[serde(bound(
+  serialize = "E::G1Affine: Serialize, E::G2Affine: Serialize",
+  deserialize = "E::G1Affine: Deserialize<'de>, E::G2Affine: Deserialize<'de>"
+))]
+pub struct ZMVerifierKey<E: Engine> {
+  vp: KZGVerifierKey<E>,
+  #[abomonate_with([u64; 16])] // this is a hack; we just assume the size of the element.
+  s_offset_h: E::G2Affine,
+}
+
+/// Trim the universal parameters to specialize the public parameters
+/// for multilinear polynomials to the given `max_degree`, and
+/// returns prover key and verifier key. `supported_size` should
+/// be in range `1..params.len()`
+///
+/// # Panics
+/// If `supported_size` is greater than `self.max_degree()`, or `self.max_degree()` is zero.
+//
+// TODO: important, we need a better way to handle that the commitment key should be 2^max_degree sized,
+// see the runtime error in commit() below
+fn trim<E: Engine>(
+  params: &UniversalKZGParam<E>,
+  max_degree: usize,
+) -> (ZMProverKey<E>, ZMVerifierKey<E>) {
+  let (commit_pp, vp) = params.trim(max_degree);
+  let offset = params.powers_of_g.len() - max_degree;
+  let open_pp = {
+    let offset_powers_of_g1 = params.powers_of_g[offset..].to_vec();
+    KZGProverKey {
+      powers_of_g: offset_powers_of_g1,
+    }
+  };
+  let s_offset_h = params.powers_of_h[offset];
+
+  (
+    ZMProverKey { commit_pp, open_pp },
+    ZMVerifierKey { vp, s_offset_h },
+  )
+}
+
+/// Commitments
+#[derive(Debug, Clone, Eq, PartialEq, Default, Serialize, Deserialize)]
+pub struct ZMCommitment<E: Engine>(
+  /// the actual commitment is an affine point.
+  E::G1Affine,
+);
+
+impl<E: Engine> From<UVKZGCommitment<E>> for ZMCommitment<E> {
+  fn from(value: UVKZGCommitment<E>) -> Self {
+    Self(value.0)
+  }
+}
+
+impl<E: Engine> From<ZMCommitment<E>> for UVKZGCommitment<E> {
+  fn from(value: ZMCommitment<E>) -> Self {
+    Self(value.0)
+  }
+}
+
+/// Polynomial Evaluation
+#[derive(Debug, Clone, Eq, PartialEq, Default)]
+pub struct ZMEvaluation<E: Engine>(E::Fr);
+
+impl<E: Engine> From<UVKZGEvaluation<E>> for ZMEvaluation<E> {
+  fn from(value: UVKZGEvaluation<E>) -> Self {
+    Self(value.0)
+  }
+}
+
+#[derive(Debug, Clone, Eq, PartialEq, Default, Serialize, Deserialize)]
+#[serde(bound(
+  serialize = "E::G1Affine: Serialize",
+  deserialize = "E::G1Affine: Deserialize<'de>"
+))]
+/// Proofs
+pub struct ZMProof<E: Engine> {
+  /// proof
+  pi: E::G1Affine,
+  /// Polynomial commitment to qhat
+  cqhat: UVKZGCommitment<E>,
+  /// Polynomial commitment to qk
+  ck: Vec<UVKZGCommitment<E>>,
+}
+
+#[derive(Debug, Clone, Eq, PartialEq, Default)]
+/// Zeromorph Polynomial Commitment Scheme on multilinear polynomials.
+/// Note: this is non-hiding, which is why we will implement the EvaluationEngineTrait on this token struct,
+/// as we will have several impls for the trait pegged on the same instance of a pairing::Engine.
+#[allow(clippy::upper_case_acronyms)]
+pub struct ZMPCS<E, NE> {
+  #[doc(hidden)]
+  phantom: PhantomData<(E, NE)>,
+}
+
+impl<E: MultiMillerLoop, NE: NovaEngine<GE = E::G1, Scalar = E::Fr>> ZMPCS<E, NE>
+where
+  E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+  // Note: due to the move of the bound TranscriptReprTrait<G> on G::Base from Group to Engine
+  <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>,
+{
+  const fn protocol_name() -> &'static [u8] {
+    b"Zeromorph"
+  }
+
+  /// Generate a commitment for a polynomial
+  /// Note that the scheme is not hidding
+  fn commit(
+    pp: impl Borrow<ZMProverKey<E>>,
+    poly: &MultilinearPolynomial<E::Fr>,
+  ) -> Result<ZMCommitment<E>, NovaError> {
+    let pp = pp.borrow();
+    if pp.commit_pp.powers_of_g.len() < poly.Z.len() {
+      return Err(PCSError::LengthError.into());
+    }
+    UVKZGPCS::commit(&pp.commit_pp, UVKZGPoly::ref_cast(&poly.Z)).map(|c| c.into())
+  }
+
+  /// On input a polynomial `poly` and a point `point`, outputs a proof for the
+  /// same.
+  fn open(
+    pp: &impl Borrow<ZMProverKey<E>>,
+    comm: &ZMCommitment<E>,
+    poly: &MultilinearPolynomial<E::Fr>,
+    point: &[E::Fr],
+    eval: &ZMEvaluation<E>,
+    transcript: &mut impl TranscriptEngineTrait<NE>,
+  ) -> Result<ZMProof<E>, NovaError> {
+    transcript.dom_sep(Self::protocol_name());
+
+    let pp = pp.borrow();
+    if pp.commit_pp.powers_of_g.len() < poly.Z.len() {
+      return Err(NovaError::PCSError(PCSError::LengthError));
+    }
+
+    debug_assert_eq!(Self::commit(pp, poly).unwrap().0, comm.0);
+    debug_assert_eq!(poly.evaluate(point), eval.0);
+
+    let (quotients, remainder) = quotients(poly, point);
+    debug_assert_eq!(quotients.len(), poly.get_num_vars());
+    debug_assert_eq!(remainder, eval.0);
+
+    // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1})
+    let quotients_polys = quotients
+      .into_iter()
+      .map(UVKZGPoly::new)
+      .collect::<Vec<_>>();
+
+    // Compute and absorb commitments C_{q_k} = [q_k], k = 0,...,d-1
+    let q_comms = quotients_polys
+      .par_iter()
+      .map(|q| UVKZGPCS::commit(&pp.commit_pp, q))
+      .collect::<Result<Vec<_>, _>>()?;
+    q_comms.iter().for_each(|c| transcript.absorb(b"quo", c));
+
+    // Get challenge y
+    let y = transcript.squeeze(b"y")?;
+
+    // Compute the batched, lifted-degree quotient `\hat{q}`
+    // qq_hat = ∑_{i=0}^{num_vars-1} y^i * X^(2^num_vars - d_k - 1) * q_i(x)
+    let (q_hat, offset) = batched_lifted_degree_quotient(y, &quotients_polys);
+
+    // Compute and absorb the commitment C_q = [\hat{q}]
+    let q_hat_comm = UVKZGPCS::commit_offset(&pp.commit_pp, &q_hat, offset)?;
+    transcript.absorb(b"q_hat", &q_hat_comm);
+
+    // Get challenges x and z
+    let x = transcript.squeeze(b"x")?;
+    let z = transcript.squeeze(b"z")?;
+
+    // Compute batched degree and ZM-identity quotient polynomial pi
+    let (eval_scalar, (degree_check_q_scalars, zmpoly_q_scalars)) =
+      eval_and_quotient_scalars(y, x, z, point);
+    // f = z * poly.Z + q_hat + (-z * Φ_n(x) * e) + ∑_k (q_scalars_k * q_k)
+    let mut f = UVKZGPoly::new(poly.Z.clone());
+    f *= &z;
+    f += &q_hat;
+    f[0] += eval_scalar * eval.0;
+    quotients_polys
+      .into_iter()
+      .zip_eq(degree_check_q_scalars)
+      .zip_eq(zmpoly_q_scalars)
+      .for_each(|((mut q, degree_check_scalar), zm_poly_scalar)| {
+        q *= &(degree_check_scalar + zm_poly_scalar);
+        f += &q;
+      });
+    debug_assert_eq!(f.evaluate(&x), E::Fr::ZERO);
+    // hence uveval == Fr::ZERO
+
+    // Compute and send proof commitment pi
+    let (uvproof, _uveval): (UVKZGProof<_>, UVKZGEvaluation<_>) =
+      UVKZGPCS::<E>::open(&pp.open_pp, &f, &x)?;
+
+    let proof = ZMProof {
+      pi: uvproof.proof,
+      cqhat: q_hat_comm,
+      ck: q_comms,
+    };
+
+    Ok(proof)
+  }
+
+  /// Verifies that `value` is the evaluation at `x` of the polynomial
+  /// committed inside `comm`.
+  fn verify(
+    vk: &impl Borrow<ZMVerifierKey<E>>,
+    transcript: &mut impl TranscriptEngineTrait<NE>,
+    comm: &ZMCommitment<E>,
+    point: &[E::Fr],
+    evaluation: &ZMEvaluation<E>,
+    proof: &ZMProof<E>,
+  ) -> Result<bool, NovaError> {
+    transcript.dom_sep(Self::protocol_name());
+
+    let vk = vk.borrow();
+
+    // Receive commitments [q_k]
+    proof.ck.iter().for_each(|c| transcript.absorb(b"quo", c));
+
+    // Challenge y
+    let y = transcript.squeeze(b"y")?;
+
+    // Receive commitment C_{q}
+    transcript.absorb(b"q_hat", &proof.cqhat);
+
+    // Challenges x, z
+    let x = transcript.squeeze(b"x")?;
+    let z = transcript.squeeze(b"z")?;
+
+    let (eval_scalar, (mut q_scalars, zmpoly_q_scalars)) =
+      eval_and_quotient_scalars(y, x, z, point);
+    q_scalars
+      .iter_mut()
+      .zip_eq(zmpoly_q_scalars)
+      .for_each(|(scalar, zm_poly_scalar)| {
+        *scalar += zm_poly_scalar;
+      });
+    let scalars = [vec![E::Fr::ONE, z, eval_scalar * evaluation.0], q_scalars].concat();
+    let bases = [
+      vec![proof.cqhat.0, comm.0, vk.vp.g],
+      proof.ck.iter().map(|c| c.0).collect(),
+    ]
+    .concat();
+    let c = <E::G1 as DlogGroup>::vartime_multiscalar_mul(&scalars, &bases).to_affine();
+
+    let pi = proof.pi;
+
+    let pairing_inputs = [
+      (&c, &(-vk.s_offset_h).into()),
+      (
+        &pi,
+        &(E::G2::from(vk.vp.beta_h) - (vk.vp.h * x))
+          .to_affine()
+          .into(),
+      ),
+    ];
+
+    let pairing_result = E::multi_miller_loop(&pairing_inputs).final_exponentiation();
+    Ok(pairing_result.is_identity().into())
+  }
+}
+
+/// Computes the quotient polynomials of a given multilinear polynomial with respect to a specific input point.
+///
+/// Given a multilinear polynomial `poly` and a point `point`, this function calculates the quotient polynomials `q_k`
+/// and the evaluation at `point`, such that:
+///
+/// ```text
+/// poly - poly(point) = Σ (X_k - point_k) * q_k(X_0, ..., X_{k-1})
+/// ```
+///
+/// where `poly(point)` is the evaluation of `poly` at `point`, and each `q_k` is a polynomial in `k` variables.
+///
+/// Since our evaluations are presented in order reverse from the coefficients, if we want to interpret index q_k
+/// to be the k-th coefficient in the polynomials returned here, the equality that holds is:
+///
+/// ```text
+/// poly - poly(point) = Σ (X_{n-1-k} - point_{n-1-k}) * q_k(X_0, ..., X_{k-1})
+/// ```
+///
+fn quotients<F: PrimeField>(poly: &MultilinearPolynomial<F>, point: &[F]) -> (Vec<Vec<F>>, F) {
+  let num_var = poly.get_num_vars();
+  assert_eq!(num_var, point.len());
+
+  let mut remainder = poly.Z.to_vec();
+  let mut quotients = point
+    .iter()
+    .enumerate()
+    .map(|(idx, x_i)| {
+      let (remainder_lo, remainder_hi) = remainder.split_at_mut(1 << (num_var - 1 - idx));
+      let mut quotient = vec![F::ZERO; remainder_lo.len()];
+
+      quotient
+        .par_iter_mut()
+        .zip_eq(&*remainder_lo)
+        .zip_eq(&*remainder_hi)
+        .for_each(|((q, r_lo), r_hi)| {
+          *q = *r_hi - *r_lo;
+        });
+      remainder_lo
+        .par_iter_mut()
+        .zip_eq(remainder_hi)
+        .for_each(|(r_lo, r_hi)| {
+          *r_lo += (*r_hi - r_lo as &_) * x_i;
+        });
+
+      remainder.truncate(1 << (num_var - 1 - idx));
+
+      quotient
+    })
+    .collect::<Vec<Vec<F>>>();
+  quotients.reverse();
+
+  (quotients, remainder[0])
+}
+
+// Compute the batched, lifted-degree quotient `\hat{q}`
+fn batched_lifted_degree_quotient<F: PrimeField>(
+  y: F,
+  quotients_polys: &[UVKZGPoly<F>],
+) -> (UVKZGPoly<F>, usize) {
+  let num_vars = quotients_polys.len();
+
+  let powers_of_y = (0..num_vars)
+    .scan(F::ONE, |acc, _| {
+      let val = *acc;
+      *acc *= y;
+      Some(val)
+    })
+    .collect::<Vec<F>>();
+
+  #[allow(clippy::disallowed_methods)]
+  let q_hat = powers_of_y
+    .iter()
+    .zip_eq(quotients_polys.iter().map(|qp| qp.as_ref()))
+    .enumerate()
+    .fold(
+      vec![F::ZERO; 1 << num_vars],
+      |mut q_hat, (idx, (power_of_y, q))| {
+        q_hat[(1 << num_vars) - (1 << idx)..]
+          .par_iter_mut()
+          .zip(q)
+          .for_each(|(q_hat, q)| {
+            *q_hat += *power_of_y * *q;
+          });
+        q_hat
+      },
+    );
+
+  (UVKZGPoly::new(q_hat), 1 << (num_vars - 1))
+}
+
+/// Computes some key terms necessary for computing the partially evaluated univariate ZM polynomial
+fn eval_and_quotient_scalars<F: Field>(y: F, x: F, z: F, point: &[F]) -> (F, (Vec<F>, Vec<F>)) {
+  let num_vars = point.len();
+
+  // squares_of_x = [x, x^2, .. x^{2^k}, .. x^{2^num_vars}]
+  let squares_of_x = iter::successors(Some(x), |&x| Some(x.square()))
+    .take(num_vars + 1)
+    .collect::<Vec<_>>();
+  // offsets_of_x = [Π_{j=i}^{num_vars-1} x^(2^j), i ∈ [0, num_vars-1]] = [x^(2^num_vars - d_i - 1), i ∈ [0, num_vars-1]]
+  let offsets_of_x = {
+    let mut offsets_of_x = squares_of_x
+      .iter()
+      .rev()
+      .skip(1)
+      .scan(F::ONE, |state, power_of_x| {
+        *state *= power_of_x;
+        Some(*state)
+      })
+      .collect::<Vec<_>>();
+    offsets_of_x.reverse();
+    offsets_of_x
+  };
+
+  // vs = [ (x^(2^num_vars) - 1) / (x^(2^i) - 1), i ∈ [0, num_vars-1]]
+  // Note Φ_(n-i)(x^(2^i)) = (x^(2^i))^(2^(n-i) - 1) / (x^(2^i) - 1) = (x^(2^num_vars) - 1) / (x^(2^i) - 1) = vs[i]
+  //      Φ_(n-i-1)(x^(2^(i+1))) = (x^(2^(i+1)))^(2^(n-i-1)) - 1 / (x^(2^(i+1)) - 1) = (x^(2^num_vars) - 1) / (x^(2^(i+1)) - 1) = vs[i+1]
+  let vs = {
+    let v_numer = squares_of_x[num_vars] - F::ONE;
+    let mut v_denoms = squares_of_x
+      .iter()
+      .map(|square_of_x| *square_of_x - F::ONE)
+      .collect::<Vec<_>>();
+    v_denoms.iter_mut().batch_invert();
+    v_denoms
+      .iter()
+      .map(|v_denom| v_numer * v_denom)
+      .collect::<Vec<_>>()
+  };
+
+  // q_scalars = [- (y^i * x^(2^num_vars - d_i - 1) + z * (x^(2^i) * vs[i+1] - u_i * vs[i])), i ∈ [0, num_vars-1]]
+  //           = [- (y^i * x^(2^num_vars - d_i - 1) + z * (x^(2^i) * Φ_(n-i-1)(x^(2^(i+1))) - u_i * Φ_(n-i)(x^(2^i)))), i ∈ [0, num_vars-1]]
+  #[allow(clippy::disallowed_methods)]
+  let q_scalars = iter::successors(Some(F::ONE), |acc| Some(*acc * y)).take(num_vars)
+      .zip_eq(offsets_of_x)
+      // length: num_vars + 1
+      .zip(squares_of_x)
+      // length: num_vars + 1
+      .zip(&vs)
+      .zip_eq(&vs[1..])
+      .zip_eq(point.iter().rev()) // assume variables come in BE form
+      .map(
+        |(((((power_of_y, offset_of_x), square_of_x), v_i), v_j), u_i)| {
+          (-(power_of_y * offset_of_x), -(z * (square_of_x * v_j - *u_i * v_i)))
+        },
+      )
+      .unzip();
+
+  // -vs[0] * z = -z * (x^(2^num_vars) - 1) / (x - 1) = -z Φ_n(x)
+  (-vs[0] * z, q_scalars)
+}
+
+impl<E: MultiMillerLoop, NE: NovaEngine<GE = E::G1, Scalar = E::Fr, CE = KZGCommitmentEngine<E>>>
+  EvaluationEngineTrait<NE> for ZMPCS<E, NE>
+where
+  E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+  E::G1Affine: Serialize + for<'de> Deserialize<'de>,
+  E::G2Affine: Serialize + for<'de> Deserialize<'de>,
+  <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>, // Note: due to the move of the bound TranscriptReprTrait<G> on G::Base from Group to Engine
+  E::Fr: PrimeFieldBits, // TODO due to use of gen_srs_for_testing, make optional
+{
+  type ProverKey = ZMProverKey<E>;
+  type VerifierKey = ZMVerifierKey<E>;
+
+  type EvaluationArgument = ZMProof<E>;
+
+  fn setup(ck: &UniversalKZGParam<E>) -> (Self::ProverKey, Self::VerifierKey) {
+    trim(ck, ck.length() - 1)
+  }
+
+  fn prove(
+    _ck: &UniversalKZGParam<E>,
+    pk: &Self::ProverKey,
+    transcript: &mut NE::TE,
+    comm: &Commitment<NE>,
+    poly: &[NE::Scalar],
+    point: &[NE::Scalar],
+    eval: &NE::Scalar,
+  ) -> Result<Self::EvaluationArgument, NovaError> {
+    let commitment = ZMCommitment::from(UVKZGCommitment::from(*comm));
+    let polynomial = MultilinearPolynomial::new(poly.to_vec());
+    let evaluation = ZMEvaluation(*eval);
+
+    Self::open(pk, &commitment, &polynomial, point, &evaluation, transcript)
+  }
+
+  fn verify(
+    vk: &Self::VerifierKey,
+    transcript: &mut NE::TE,
+    comm: &Commitment<NE>,
+    point: &[NE::Scalar],
+    eval: &NE::Scalar,
+    arg: &Self::EvaluationArgument,
+  ) -> Result<(), NovaError> {
+    let commitment = ZMCommitment::from(UVKZGCommitment::from(*comm));
+    let evaluation = ZMEvaluation(*eval);
+
+    if !Self::verify(vk, transcript, &commitment, point, &evaluation, arg)? {
+      return Err(NovaError::UnSat);
+    }
+    Ok(())
+  }
+}
+
+#[cfg(test)]
+mod test {
+  use std::borrow::Borrow;
+  use std::iter;
+
+  use ff::{Field, PrimeField, PrimeFieldBits};
+  use group::Curve;
+  use halo2curves::bn256::Bn256;
+  use halo2curves::bn256::Fr as Scalar;
+  use itertools::Itertools as _;
+  use pairing::MultiMillerLoop;
+  use rand::thread_rng;
+  use rand_chacha::ChaCha20Rng;
+  use rand_core::SeedableRng;
+
+  use super::quotients;
+
+  use crate::{
+    errors::PCSError,
+    provider::{
+      keccak::Keccak256Transcript,
+      non_hiding_kzg::{KZGProverKey, UVKZGCommitment, UVKZGPoly, UniversalKZGParam, UVKZGPCS},
+      non_hiding_zeromorph::{
+        batched_lifted_degree_quotient, eval_and_quotient_scalars, trim, ZMEvaluation, ZMPCS,
+      },
+      traits::DlogGroup,
+      util::test_utils::prove_verify_from_num_vars,
+      Bn256Engine, Bn256EngineZM,
+    },
+    spartan::polys::multilinear::MultilinearPolynomial,
+    traits::{Engine as NovaEngine, Group, TranscriptEngineTrait, TranscriptReprTrait},
+    NovaError,
+  };
+
+  fn commit_open_verify_with<E: MultiMillerLoop, NE: NovaEngine<GE = E::G1, Scalar = E::Fr>>()
+  where
+    E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+    <E::G1 as Group>::Base: TranscriptReprTrait<E::G1>, // Note: due to the move of the bound TranscriptReprTrait<G> on G::Base from Group to Engine
+    E::Fr: PrimeFieldBits,
+  {
+    let max_vars = 16;
+    let mut rng = thread_rng();
+    let max_poly_size = 1 << (max_vars + 1);
+    let universal_setup = UniversalKZGParam::<E>::gen_srs_for_testing(&mut rng, max_poly_size);
+
+    for num_vars in 3..max_vars {
+      // Setup
+      let (pp, vk) = {
+        let poly_size = 1 << (num_vars + 1);
+
+        trim(&universal_setup, poly_size)
+      };
+
+      // Commit and open
+      let mut transcript = Keccak256Transcript::<NE>::new(b"test");
+      let poly = MultilinearPolynomial::<E::Fr>::random(num_vars, &mut thread_rng());
+      let comm = ZMPCS::<E, NE>::commit(&pp, &poly).unwrap();
+      let point = iter::from_fn(|| transcript.squeeze(b"pt").ok())
+        .take(num_vars)
+        .collect::<Vec<_>>();
+      let eval = ZMEvaluation(poly.evaluate(&point));
+
+      let mut transcript_prover = Keccak256Transcript::<NE>::new(b"test");
+      let proof = ZMPCS::open(&pp, &comm, &poly, &point, &eval, &mut transcript_prover).unwrap();
+
+      // Verify
+      let mut transcript_verifier = Keccak256Transcript::<NE>::new(b"test");
+      let result = ZMPCS::verify(
+        &vk,
+        &mut transcript_verifier,
+        &comm,
+        point.as_slice(),
+        &eval,
+        &proof,
+      );
+
+      // check both random oracles are synced, as expected
+      assert_eq!(
+        transcript_prover.squeeze(b"test"),
+        transcript_verifier.squeeze(b"test")
+      );
+
+      result.unwrap();
+    }
+  }
+
+  #[test]
+  fn test_commit_open_verify() {
+    commit_open_verify_with::<Bn256, Bn256Engine>();
+  }
+
+  #[test]
+  fn test_multiple_polynomial_size() {
+    for num_vars in [4, 5, 6] {
+      prove_verify_from_num_vars::<_, ZMPCS<Bn256, Bn256EngineZM>>(num_vars);
+    }
+  }
+
+  #[test]
+  fn test_quotients() {
+    // Define size parameters
+    let num_vars = 4; // Example number of variables for the multilinear polynomial
+
+    // Construct a random multilinear polynomial f, and u such that f(u) = v.
+    let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
+    let poly = MultilinearPolynomial::random(num_vars, &mut rng);
+    let u_challenge: Vec<_> = (0..num_vars).map(|_| Scalar::random(&mut rng)).collect();
+    let v_evaluation = poly.evaluate(&u_challenge);
+
+    // Compute the multilinear quotients q_k = q_k(X_0, ..., X_{k-1})
+    let (quotients, constant_term) = quotients(&poly, &u_challenge);
+
+    // Assert that the constant term is equal to v_evaluation
+    assert_eq!(constant_term, v_evaluation, "The constant term should be equal to the evaluation of the polynomial at the challenge point.");
+
+    // Check that the identity holds for a random evaluation point z
+    // poly - poly(z) = Σ (X_k - z_k) * q_k(X_0, ..., X_{k-1})
+    // except for our inversion of coefficient order in polynomials and points (see below)
+    let z_challenge: Vec<_> = (0..num_vars).map(|_| Scalar::random(&mut rng)).collect();
+    let mut result = poly.evaluate(&z_challenge);
+    result -= v_evaluation;
+
+    for (k, q_k) in quotients.iter().enumerate() {
+      let q_k_poly = MultilinearPolynomial::new(q_k.clone());
+      // the following looks weird because the quotient polynomials are coefficiented in reverse order from evaluation
+      // IOW in 'normal evaluation order' this should be let z_partial = &z_challenge[..k];
+      let z_partial = &z_challenge[z_challenge.len() - k..];
+
+      let q_k_eval = q_k_poly.evaluate(z_partial);
+      // the following looks weird because the quotient polynomials are coefficiented in reverse order from evaluation
+      // IOW in 'normal evaluation order' this should be
+      // result -= (z_challenge[k] - u_challenge[k]) * q_k_eval;
+      result -= (z_challenge[z_challenge.len() - k - 1] - u_challenge[z_challenge.len() - k - 1])
+        * q_k_eval;
+    }
+
+    // Assert that the result is zero, which verifies the correctness of the quotients
+    assert!(
+      bool::from(result.is_zero()),
+      "The computed quotients should satisfy the polynomial identity."
+    );
+  }
+
+  #[test]
+  fn test_batched_lifted_degree_quotient() {
+    let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
+
+    let num_vars = 3;
+    let n = 1 << num_vars; // Assuming N = 2^num_vars
+
+    // Define mock q_k with deg(q_k) = 2^k - 1
+    let q_0 = UVKZGPoly::new(vec![Scalar::one()]);
+    let q_1 = UVKZGPoly::new(vec![Scalar::from(2), Scalar::from(3)]);
+    let q_2 = UVKZGPoly::new(vec![
+      Scalar::from(4),
+      Scalar::from(5),
+      Scalar::from(6),
+      Scalar::from(7),
+    ]);
+    let quotients = vec![q_0, q_1, q_2];
+
+    // Generate a random y challenge
+    let y_challenge = Scalar::random(&mut rng);
+
+    // Compute batched quotient \hat{q} using the function
+    let batched_quotient = batched_lifted_degree_quotient(y_challenge, &quotients);
+
+    // Now explicitly define q_k_lifted = X^{N-2^k} * q_k and compute the expected batched result
+    let q_0_lifted = [vec![Scalar::zero(); n - 1], vec![Scalar::one()]].concat();
+    let q_1_lifted = [
+      vec![Scalar::zero(); n - 2],
+      vec![Scalar::from(2), Scalar::from(3)],
+    ]
+    .concat();
+    let q_2_lifted = [
+      vec![Scalar::zero(); n - 4],
+      vec![
+        Scalar::from(4),
+        Scalar::from(5),
+        Scalar::from(6),
+        Scalar::from(7),
+      ],
+    ]
+    .concat();
+
+    // Explicitly compute \hat{q}
+    let mut batched_quotient_expected = vec![Scalar::zero(); n];
+    batched_quotient_expected
+      .iter_mut()
+      .zip_eq(q_0_lifted)
+      .zip_eq(q_1_lifted)
+      .zip_eq(q_2_lifted)
+      .for_each(|(((res, q_0), q_1), q_2)| {
+        *res += q_0 + y_challenge * q_1 + y_challenge * y_challenge * q_2;
+      });
+
+    // Compare the computed and expected batched quotients
+    assert_eq!(
+      batched_quotient.0,
+      UVKZGPoly::new(batched_quotient_expected)
+    );
+  }
+
+  #[test]
+  fn test_partially_evaluated_quotient_zeta() {
+    let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
+
+    let num_vars = 3;
+
+    // Define some mock q_k with deg(q_k) = 2^k - 1
+    let _q_0 = UVKZGPoly::new(vec![Scalar::one()]);
+    let _q_1 = UVKZGPoly::new(vec![Scalar::from(2), Scalar::from(3)]);
+    let _q_2 = UVKZGPoly::new(vec![
+      Scalar::from(4),
+      Scalar::from(5),
+      Scalar::from(6),
+      Scalar::from(7),
+    ]);
+
+    let y_challenge = Scalar::random(&mut rng);
+
+    let x_challenge = Scalar::random(&mut rng);
+
+    // Unused in this test
+    let u_challenge: Vec<_> = (0..num_vars).map(|_| Scalar::random(&mut rng)).collect();
+    let z_challenge = Scalar::random(&mut rng);
+
+    // Construct ζ_x using the function
+    let (_eval_scalar, (zeta_x_scalars, _right_quo_scalars)) =
+      eval_and_quotient_scalars(y_challenge, x_challenge, z_challenge, &u_challenge);
+
+    // Now construct ζ_x explicitly
+    let n: u64 = 1 << num_vars;
+    // q_batched - \sum_k q_k * y^k * x^{N - deg(q_k) - 1}
+    assert_eq!(zeta_x_scalars[0], -x_challenge.pow([n - 1]));
+    assert_eq!(
+      zeta_x_scalars[1],
+      -y_challenge * x_challenge.pow_vartime([n - 1 - 1])
+    );
+    assert_eq!(
+      zeta_x_scalars[2],
+      -y_challenge * y_challenge * x_challenge.pow_vartime([n - 3 - 1])
+    );
+  }
+
+  // Evaluate phi using an inefficient formula
+  fn phi<F: PrimeField>(challenge: F, n: usize) -> F {
+    let length = 1 << n;
+    let mut result = F::ZERO;
+    let mut current = F::ONE; // Start with x^0
+
+    for _ in 0..length {
+      result += current;
+      current *= challenge; // Increment the power of x for the next iteration
+    }
+
+    result
+  }
+
+  #[test]
+  fn test_partially_evaluated_quotient_z() {
+    let num_vars: usize = 3;
+
+    let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
+
+    // Define some mock q_k with deg(q_k) = 2^k - 1
+    let _q_0 = UVKZGPoly::new(vec![Scalar::one()]);
+    let _q_1 = UVKZGPoly::new(vec![Scalar::from(2), Scalar::from(3)]);
+    let _q_2 = UVKZGPoly::new(vec![
+      Scalar::from(4),
+      Scalar::from(5),
+      Scalar::from(6),
+      Scalar::from(7),
+    ]);
+
+    // Unused in this test
+    let y_challenge = Scalar::random(&mut rng);
+
+    let x_challenge = Scalar::random(&mut rng);
+    let z_challenge = Scalar::random(&mut rng);
+
+    let u_challenge: Vec<_> = (0..num_vars).map(|_| Scalar::random(&mut rng)).collect();
+
+    // Construct Z_x using the function
+    let (_eval_scalar, (_left_quo_scalars, zeta_x_scalars)) =
+      eval_and_quotient_scalars(y_challenge, x_challenge, z_challenge, &u_challenge);
+
+    // beware the Nova coefficient evaluation order!
+    let u_rev = {
+      let mut res = u_challenge.clone();
+      res.reverse();
+      res
+    };
+
+    // Compute Z_x directly
+    for k in 0..num_vars {
+      let x_pow_2k = x_challenge.pow([1 << k]);
+      let x_pow_2kp1 = x_challenge.pow([1 << (k + 1)]);
+      let mut scalar =
+        x_pow_2k * phi(x_pow_2kp1, num_vars - k - 1) - u_rev[k] * phi(x_pow_2k, num_vars - k);
+      scalar *= z_challenge;
+      scalar *= -Scalar::ONE;
+      assert_eq!(zeta_x_scalars[k], scalar);
+    }
+  }
+
+  fn commit_filtered<E>(
+    prover_param: impl Borrow<KZGProverKey<E>>,
+    poly: &UVKZGPoly<E::Fr>,
+  ) -> Result<UVKZGCommitment<E>, NovaError>
+  where
+    E: MultiMillerLoop,
+    E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+    E::Fr: PrimeFieldBits,
+  {
+    let prover_param = prover_param.borrow();
+
+    if poly.degree() > prover_param.powers_of_g.len() {
+      return Err(NovaError::PCSError(PCSError::LengthError));
+    }
+
+    // We use following filter to optimise MSM for cases where scalars contain a lot of zeroes
+    let initial_bases = &prover_param.powers_of_g.as_slice()[..poly.coeffs.len()].to_vec();
+    let mut scalars = vec![];
+    let mut bases = vec![];
+    for (index, scalar) in poly.coeffs.iter().enumerate() {
+      if !scalar.is_zero_vartime() {
+        scalars.push(*scalar);
+        bases.push(initial_bases[index]);
+      }
+    }
+
+    let C = <E::G1 as DlogGroup>::vartime_multiscalar_mul(&scalars, &bases);
+
+    Ok(UVKZGCommitment(C.to_affine()))
+  }
+
+  fn test_ZM_commit_sparsity_template<E>() -> Result<(), NovaError>
+  where
+    E: MultiMillerLoop,
+    E::G1: DlogGroup<ScalarExt = E::Fr, AffineExt = E::G1Affine>,
+    E::Fr: PrimeFieldBits,
+  {
+    let degree = 10;
+    let num_vars_multilinear = 3;
+
+    let mut rng = &mut thread_rng();
+    let multilinear_poly = MultilinearPolynomial::<E::Fr>::random(num_vars_multilinear, &mut rng);
+
+    let mut random_points = vec![];
+    for _ in 0..num_vars_multilinear {
+      random_points.push(E::Fr::random(&mut rng));
+    }
+
+    let (quotients, _remainder) = quotients(&multilinear_poly, random_points.as_slice());
+    let quotients_polys = quotients
+      .into_iter()
+      .map(UVKZGPoly::new)
+      .collect::<Vec<_>>();
+
+    let (q_hat, offset) = batched_lifted_degree_quotient(E::Fr::random(&mut rng), &quotients_polys);
+
+    let pp = UniversalKZGParam::<E>::gen_srs_for_testing(&mut rng, degree);
+    let (ck, _vk) = pp.trim(degree);
+
+    let commitment_expected = UVKZGPCS::commit(&ck, &q_hat)?;
+    let commitment_actual_1 = commit_filtered(&ck, &q_hat)?;
+    let commitment_actual_2 = UVKZGPCS::commit_offset(&ck, &q_hat, offset)?;
+
+    assert_eq!(commitment_expected.0, commitment_actual_1.0);
+    assert_eq!(commitment_expected.0, commitment_actual_2.0);
+
+    Ok(())
+  }
+
+  #[test]
+  fn test_ZM_commit_sparsity() {
+    test_ZM_commit_sparsity_template::<Bn256>().expect("test failed for Bn256");
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/pasta.rs.html b/docs/src/arecibo/provider/pasta.rs.html new file mode 100644 index 000000000..d00293537 --- /dev/null +++ b/docs/src/arecibo/provider/pasta.rs.html @@ -0,0 +1,451 @@ +pasta.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+
//! This module implements the Nova traits for `pallas::Point`, `pallas::Scalar`, `vesta::Point`, `vesta::Scalar`.
+use crate::{
+  provider::{traits::DlogGroup, util::msm::cpu_best_msm},
+  traits::{Group, PrimeFieldExt, TranscriptReprTrait},
+};
+use derive_more::{From, Into};
+use digest::{ExtendableOutput, Update};
+use ff::{FromUniformBytes, PrimeField};
+use group::{prime::PrimeCurveAffine, Curve};
+use num_bigint::BigInt;
+use num_traits::Num;
+use pasta_curves::{
+  self,
+  arithmetic::{CurveAffine, CurveExt},
+  pallas, vesta,
+};
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+use sha3::Shake256;
+use std::io::Read;
+
+/// A wrapper for compressed group elements of pallas
+#[derive(Clone, Copy, Debug, Eq, From, Into, PartialEq, Serialize, Deserialize)]
+pub struct PallasCompressedElementWrapper([u8; 32]);
+
+/// A wrapper for compressed group elements of vesta
+#[derive(Clone, Copy, Debug, Eq, From, Into, PartialEq, Serialize, Deserialize)]
+pub struct VestaCompressedElementWrapper([u8; 32]);
+
+macro_rules! impl_traits {
+  (
+    $name:ident,
+    $name_compressed:ident,
+    $order_str:literal,
+    $base_str:literal
+  ) => {
+    impl Group for $name::Point {
+      type Base = $name::Base;
+      type Scalar = $name::Scalar;
+
+      fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt) {
+        let A = $name::Point::a();
+        let B = $name::Point::b();
+        let order = BigInt::from_str_radix($order_str, 16).unwrap();
+        let base = BigInt::from_str_radix($base_str, 16).unwrap();
+
+        (A, B, order, base)
+      }
+    }
+
+    impl DlogGroup for $name::Point {
+      type ScalarExt = $name::Scalar;
+      type AffineExt = $name::Affine;
+      type Compressed = $name_compressed;
+
+      #[tracing::instrument(
+        skip_all,
+        level = "trace",
+        name = "<_ as Group>::vartime_multiscalar_mul"
+      )]
+      fn vartime_multiscalar_mul(scalars: &[Self::ScalarExt], bases: &[Self::Affine]) -> Self {
+        #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
+        if scalars.len() >= 128 {
+          grumpkin_msm::pasta::$name(bases, scalars)
+        } else {
+          cpu_best_msm(bases, scalars)
+        }
+        #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
+        cpu_best_msm(bases, scalars)
+      }
+
+      fn from_label(label: &'static [u8], n: usize) -> Vec<Self::Affine> {
+        let mut shake = Shake256::default();
+        shake.update(label);
+        let mut reader = shake.finalize_xof();
+        let mut uniform_bytes_vec = Vec::new();
+        for _ in 0..n {
+          let mut uniform_bytes = [0u8; 32];
+          reader.read_exact(&mut uniform_bytes).unwrap();
+          uniform_bytes_vec.push(uniform_bytes);
+        }
+        let ck_proj: Vec<$name::Point> = (0..n)
+          .into_par_iter()
+          .map(|i| {
+            let hash = $name::Point::hash_to_curve("from_uniform_bytes");
+            hash(&uniform_bytes_vec[i])
+          })
+          .collect();
+
+        let num_threads = rayon::current_num_threads();
+        if ck_proj.len() > num_threads {
+          let chunk = (ck_proj.len() as f64 / num_threads as f64).ceil() as usize;
+          (0..num_threads)
+            .into_par_iter()
+            .flat_map(|i| {
+              let start = i * chunk;
+              let end = if i == num_threads - 1 {
+                ck_proj.len()
+              } else {
+                core::cmp::min((i + 1) * chunk, ck_proj.len())
+              };
+              if end > start {
+                let mut ck = vec![$name::Affine::identity(); end - start];
+                <Self as Curve>::batch_normalize(&ck_proj[start..end], &mut ck);
+                ck
+              } else {
+                vec![]
+              }
+            })
+            .collect()
+        } else {
+          let mut ck = vec![$name::Affine::identity(); n];
+          <Self as Curve>::batch_normalize(&ck_proj, &mut ck);
+          ck
+        }
+      }
+
+      fn to_coordinates(&self) -> (Self::Base, Self::Base, bool) {
+        let coordinates = self.to_affine().coordinates();
+        if coordinates.is_some().unwrap_u8() == 1 {
+          (*coordinates.unwrap().x(), *coordinates.unwrap().y(), false)
+        } else {
+          (Self::Base::zero(), Self::Base::zero(), true)
+        }
+      }
+    }
+
+    impl PrimeFieldExt for $name::Scalar {
+      fn from_uniform(bytes: &[u8]) -> Self {
+        let bytes_arr: [u8; 64] = bytes.try_into().unwrap();
+        $name::Scalar::from_uniform_bytes(&bytes_arr)
+      }
+    }
+
+    impl<G: DlogGroup> TranscriptReprTrait<G> for $name_compressed {
+      fn to_transcript_bytes(&self) -> Vec<u8> {
+        self.0.to_vec()
+      }
+    }
+
+    impl<G: Group> TranscriptReprTrait<G> for $name::Scalar {
+      fn to_transcript_bytes(&self) -> Vec<u8> {
+        self.to_repr().to_vec()
+      }
+    }
+
+    impl<G: DlogGroup> TranscriptReprTrait<G> for $name::Affine {
+      fn to_transcript_bytes(&self) -> Vec<u8> {
+        let (x, y, is_infinity_byte) = {
+          let coordinates = self.coordinates();
+          if coordinates.is_some().unwrap_u8() == 1 {
+            (
+              *coordinates.unwrap().x(),
+              *coordinates.unwrap().y(),
+              u8::from(false),
+            )
+          } else {
+            ($name::Base::zero(), $name::Base::zero(), u8::from(true))
+          }
+        };
+
+        x.to_repr()
+          .into_iter()
+          .chain(y.to_repr().into_iter())
+          .chain(std::iter::once(is_infinity_byte))
+          .collect()
+      }
+    }
+  };
+}
+
+impl_traits!(
+  pallas,
+  PallasCompressedElementWrapper,
+  "40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001",
+  "40000000000000000000000000000000224698fc094cf91b992d30ed00000001"
+);
+
+impl_traits!(
+  vesta,
+  VestaCompressedElementWrapper,
+  "40000000000000000000000000000000224698fc094cf91b992d30ed00000001",
+  "40000000000000000000000000000000224698fc0994a8dd8c46eb2100000001"
+);
+
+#[cfg(test)]
+mod tests {
+  use ff::Field;
+  use pasta_curves::{pallas, vesta};
+  use rand::thread_rng;
+
+  use crate::provider::{traits::DlogGroup, util::msm::cpu_best_msm};
+
+  #[test]
+  fn test_pallas_msm_correctness() {
+    let npoints = 1usize << 16;
+    let points = pallas::Point::from_label(b"test", npoints);
+
+    let mut rng = thread_rng();
+    let scalars = (0..npoints)
+      .map(|_| pallas::Scalar::random(&mut rng))
+      .collect::<Vec<_>>();
+
+    let cpu_msm = cpu_best_msm(&points, &scalars);
+    let gpu_msm = pallas::Point::vartime_multiscalar_mul(&scalars, &points);
+
+    assert_eq!(cpu_msm, gpu_msm);
+  }
+
+  #[test]
+  fn test_vesta_msm_correctness() {
+    let npoints = 1usize << 16;
+    let points = vesta::Point::from_label(b"test", npoints);
+
+    let mut rng = thread_rng();
+    let scalars = (0..npoints)
+      .map(|_| vesta::Scalar::random(&mut rng))
+      .collect::<Vec<_>>();
+
+    let cpu_msm = cpu_best_msm(&points, &scalars);
+    let gpu_msm = vesta::Point::vartime_multiscalar_mul(&scalars, &points);
+
+    assert_eq!(cpu_msm, gpu_msm);
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/pedersen.rs.html b/docs/src/arecibo/provider/pedersen.rs.html new file mode 100644 index 000000000..6f308cd67 --- /dev/null +++ b/docs/src/arecibo/provider/pedersen.rs.html @@ -0,0 +1,665 @@ +pedersen.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+
//! This module provides an implementation of a commitment engine
+use crate::{
+  errors::NovaError,
+  provider::traits::DlogGroup,
+  traits::{
+    commitment::{CommitmentEngineTrait, CommitmentTrait, Len},
+    AbsorbInROTrait, Engine, ROTrait, TranscriptReprTrait,
+  },
+};
+use abomonation_derive::Abomonation;
+use core::{
+  fmt::Debug,
+  marker::PhantomData,
+  ops::{Add, Mul, MulAssign},
+};
+use ff::Field;
+use group::{prime::PrimeCurve, Curve, Group, GroupEncoding};
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+
+/// A type that holds commitment generators
+#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
+#[abomonation_omit_bounds]
+pub struct CommitmentKey<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  #[abomonate_with(Vec<[u64; 8]>)] // this is a hack; we just assume the size of the element.
+  ck: Vec<<E::GE as PrimeCurve>::Affine>,
+}
+
+/// [CommitmentKey]s are often large, and this helps with cloning bottlenecks
+impl<E> Clone for CommitmentKey<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  fn clone(&self) -> Self {
+    Self {
+      ck: self.ck[..].par_iter().cloned().collect(),
+    }
+  }
+}
+
+impl<E> Len for CommitmentKey<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  fn length(&self) -> usize {
+    self.ck.len()
+  }
+}
+
+/// A type that holds a commitment
+#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_omit_bounds]
+pub struct Commitment<E: Engine> {
+  #[abomonate_with(Vec<[u64; 12]>)] // this is a hack; we just assume the size of the element.
+  pub(crate) comm: E::GE,
+}
+
+/// A type that holds a compressed commitment
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct CompressedCommitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  comm: <E::GE as DlogGroup>::Compressed,
+}
+
+impl<E> CommitmentTrait<E> for Commitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  type CompressedCommitment = CompressedCommitment<E>;
+
+  fn compress(&self) -> Self::CompressedCommitment {
+    CompressedCommitment {
+      comm: <E::GE as GroupEncoding>::to_bytes(&self.comm).into(),
+    }
+  }
+
+  fn to_coordinates(&self) -> (E::Base, E::Base, bool) {
+    self.comm.to_coordinates()
+  }
+
+  fn decompress(c: &Self::CompressedCommitment) -> Result<Self, NovaError> {
+    let opt_comm = <<E as Engine>::GE as GroupEncoding>::from_bytes(&c.comm.clone().into());
+    let Some(comm) = Option::from(opt_comm) else {
+      return Err(NovaError::DecompressionError);
+    };
+    Ok(Self { comm })
+  }
+}
+
+impl<E> Default for Commitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup,
+{
+  fn default() -> Self {
+    Self {
+      comm: E::GE::identity(),
+    }
+  }
+}
+
+impl<E> TranscriptReprTrait<E::GE> for Commitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup,
+{
+  fn to_transcript_bytes(&self) -> Vec<u8> {
+    let (x, y, is_infinity) = self.comm.to_coordinates();
+    let is_infinity_byte = (!is_infinity).into();
+    [
+      x.to_transcript_bytes(),
+      y.to_transcript_bytes(),
+      [is_infinity_byte].to_vec(),
+    ]
+    .concat()
+  }
+}
+
+impl<E> AbsorbInROTrait<E> for Commitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup,
+{
+  fn absorb_in_ro(&self, ro: &mut E::RO) {
+    let (x, y, is_infinity) = self.comm.to_coordinates();
+    ro.absorb(x);
+    ro.absorb(y);
+    ro.absorb(if is_infinity {
+      E::Base::ONE
+    } else {
+      E::Base::ZERO
+    });
+  }
+}
+
+impl<E> TranscriptReprTrait<E::GE> for CompressedCommitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  fn to_transcript_bytes(&self) -> Vec<u8> {
+    self.comm.to_transcript_bytes()
+  }
+}
+
+impl<E> MulAssign<E::Scalar> for Commitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  fn mul_assign(&mut self, scalar: E::Scalar) {
+    *self = Self {
+      comm: self.comm * scalar,
+    };
+  }
+}
+
+impl<'a, 'b, E> Mul<&'b E::Scalar> for &'a Commitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  type Output = Commitment<E>;
+  fn mul(self, scalar: &'b E::Scalar) -> Commitment<E> {
+    Commitment {
+      comm: self.comm * scalar,
+    }
+  }
+}
+
+impl<E> Mul<E::Scalar> for Commitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  type Output = Self;
+
+  fn mul(self, scalar: E::Scalar) -> Self {
+    Self {
+      comm: self.comm * scalar,
+    }
+  }
+}
+
+impl<E> Add for Commitment<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  type Output = Self;
+
+  fn add(self, other: Self) -> Self {
+    Self {
+      comm: self.comm + other.comm,
+    }
+  }
+}
+
+/// Provides a commitment engine
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct CommitmentEngine<E> {
+  _p: PhantomData<E>,
+}
+
+impl<E> CommitmentEngineTrait<E> for CommitmentEngine<E>
+where
+  E: Engine,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  type CommitmentKey = CommitmentKey<E>;
+  type Commitment = Commitment<E>;
+
+  fn setup(label: &'static [u8], n: usize) -> Self::CommitmentKey {
+    Self::CommitmentKey {
+      ck: E::GE::from_label(label, n.next_power_of_two()),
+    }
+  }
+
+  fn commit(ck: &Self::CommitmentKey, v: &[E::Scalar]) -> Self::Commitment {
+    assert!(ck.ck.len() >= v.len());
+    Commitment {
+      comm: E::GE::vartime_multiscalar_mul(v, &ck.ck[..v.len()]),
+    }
+  }
+}
+
+/// A trait listing properties of a commitment key that can be managed in a divide-and-conquer fashion
+pub trait CommitmentKeyExtTrait<E>
+where
+  E: Engine,
+  E::GE: DlogGroup,
+{
+  /// Splits the commitment key into two pieces at a specified point
+  fn split_at(&self, n: usize) -> (Self, Self)
+  where
+    Self: Sized;
+
+  /// Combines two commitment keys into one
+  fn combine(&self, other: &Self) -> Self;
+
+  /// Folds the two commitment keys into one using the provided weights
+  fn fold(&self, w1: &E::Scalar, w2: &E::Scalar) -> Self;
+
+  /// Scales the commitment key using the provided scalar
+  fn scale(&self, r: &E::Scalar) -> Self;
+
+  /// Reinterprets commitments as commitment keys
+  fn reinterpret_commitments_as_ck(
+    c: &[<<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment as CommitmentTrait<E>>::CompressedCommitment],
+  ) -> Result<Self, NovaError>
+  where
+    Self: Sized;
+}
+
+impl<E> CommitmentKeyExtTrait<E> for CommitmentKey<E>
+where
+  E: Engine<CE = CommitmentEngine<E>>,
+  E::GE: DlogGroup<ScalarExt = E::Scalar>,
+{
+  fn split_at(&self, n: usize) -> (Self, Self) {
+    (
+      Self {
+        ck: self.ck[0..n].to_vec(),
+      },
+      Self {
+        ck: self.ck[n..].to_vec(),
+      },
+    )
+  }
+
+  fn combine(&self, other: &Self) -> Self {
+    let ck = {
+      let mut c = self.ck.clone();
+      c.extend(other.ck.clone());
+      c
+    };
+    Self { ck }
+  }
+
+  // combines the left and right halves of `self` using `w1` and `w2` as the weights
+  fn fold(&self, w1: &E::Scalar, w2: &E::Scalar) -> Self {
+    let w = vec![*w1, *w2];
+    let (L, R) = self.split_at(self.ck.len() / 2);
+
+    let ck = (0..self.ck.len() / 2)
+      .into_par_iter()
+      .map(|i| {
+        let bases = [L.ck[i].clone(), R.ck[i].clone()].to_vec();
+        E::GE::vartime_multiscalar_mul(&w, &bases).to_affine()
+      })
+      .collect();
+
+    Self { ck }
+  }
+
+  /// Scales each element in `self` by `r`
+  fn scale(&self, r: &E::Scalar) -> Self {
+    let ck_scaled = self
+      .ck
+      .clone()
+      .into_par_iter()
+      .map(|g| E::GE::vartime_multiscalar_mul(&[*r], &[g]).to_affine())
+      .collect();
+
+    Self { ck: ck_scaled }
+  }
+
+  /// reinterprets a vector of commitments as a set of generators
+  fn reinterpret_commitments_as_ck(c: &[CompressedCommitment<E>]) -> Result<Self, NovaError> {
+    let d = (0..c.len())
+      .into_par_iter()
+      .map(|i| Commitment::<E>::decompress(&c[i]))
+      .collect::<Result<Vec<Commitment<E>>, NovaError>>()?;
+    let ck = (0..d.len())
+      .into_par_iter()
+      .map(|i| d[i].comm.to_affine())
+      .collect();
+    Ok(Self { ck })
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/poseidon.rs.html b/docs/src/arecibo/provider/poseidon.rs.html new file mode 100644 index 000000000..3146e66ea --- /dev/null +++ b/docs/src/arecibo/provider/poseidon.rs.html @@ -0,0 +1,515 @@ +poseidon.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+
//! Poseidon Constants and Poseidon-based RO used in Nova
+use crate::traits::{ROCircuitTrait, ROTrait};
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use bellpepper_core::{
+  boolean::{AllocatedBit, Boolean},
+  num::AllocatedNum,
+  ConstraintSystem, SynthesisError,
+};
+use core::marker::PhantomData;
+use ff::{PrimeField, PrimeFieldBits};
+use generic_array::typenum::U24;
+use neptune::{
+  circuit2::Elt,
+  poseidon::PoseidonConstants,
+  sponge::{
+    api::{IOPattern, SpongeAPI, SpongeOp},
+    circuit::SpongeCircuit,
+    vanilla::{Mode::Simplex, Sponge, SpongeTrait},
+  },
+  Strength,
+};
+use serde::{Deserialize, Serialize};
+
+/// All Poseidon Constants that are used in Nova
+#[derive(Clone, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
+#[abomonation_bounds(where Scalar::Repr: Abomonation)]
+pub struct PoseidonConstantsCircuit<Scalar: PrimeField>(PoseidonConstants<Scalar, U24>);
+
+impl<Scalar: PrimeField> Default for PoseidonConstantsCircuit<Scalar> {
+  /// Generate Poseidon constants
+  fn default() -> Self {
+    Self(Sponge::<Scalar, U24>::api_constants(Strength::Standard))
+  }
+}
+
+/// A Poseidon-based RO to use outside circuits
+#[derive(Serialize, Deserialize, Abomonation)]
+#[abomonation_bounds(
+  where
+    Base: PrimeField,
+    Scalar: PrimeField,
+    <Base as PrimeField>::Repr: Abomonation
+)]
+pub struct PoseidonRO<Base, Scalar>
+where
+  Base: PrimeField,
+  Scalar: PrimeField,
+{
+  // Internal State
+  #[abomonate_with(Vec<Base::Repr>)]
+  state: Vec<Base>,
+  constants: PoseidonConstantsCircuit<Base>,
+  num_absorbs: usize,
+  squeezed: bool,
+  _p: PhantomData<Scalar>,
+}
+
+impl<Base, Scalar> ROTrait<Base, Scalar> for PoseidonRO<Base, Scalar>
+where
+  Base: PrimeField + PrimeFieldBits + Serialize + for<'de> Deserialize<'de>,
+  Base::Repr: Abomonation,
+  Scalar: PrimeField,
+{
+  type CircuitRO = PoseidonROCircuit<Base>;
+  type Constants = PoseidonConstantsCircuit<Base>;
+
+  fn new(constants: PoseidonConstantsCircuit<Base>, num_absorbs: usize) -> Self {
+    Self {
+      state: Vec::new(),
+      constants,
+      num_absorbs,
+      squeezed: false,
+      _p: PhantomData,
+    }
+  }
+
+  /// Absorb a new number into the state of the oracle
+  fn absorb(&mut self, e: Base) {
+    assert!(!self.squeezed, "Cannot absorb after squeezing");
+    self.state.push(e);
+  }
+
+  /// Compute a challenge by hashing the current state
+  fn squeeze(&mut self, num_bits: usize) -> Scalar {
+    // check if we have squeezed already
+    assert!(!self.squeezed, "Cannot squeeze again after squeezing");
+    self.squeezed = true;
+
+    let mut sponge = Sponge::new_with_constants(&self.constants.0, Simplex);
+    let acc = &mut ();
+    let parameter = IOPattern(vec![
+      SpongeOp::Absorb(self.num_absorbs as u32),
+      SpongeOp::Squeeze(1u32),
+    ]);
+
+    sponge.start(parameter, None, acc);
+    assert_eq!(self.num_absorbs, self.state.len());
+    SpongeAPI::absorb(&mut sponge, self.num_absorbs as u32, &self.state, acc);
+    let hash = SpongeAPI::squeeze(&mut sponge, 1, acc);
+    sponge.finish(acc).unwrap();
+
+    // Only return `num_bits`
+    let bits = hash[0].to_le_bits();
+    let mut res = Scalar::ZERO;
+    let mut coeff = Scalar::ONE;
+    for bit in bits[0..num_bits].into_iter() {
+      if *bit {
+        res += coeff;
+      }
+      coeff += coeff;
+    }
+    res
+  }
+}
+
+/// A Poseidon-based RO gadget to use inside the verifier circuit.
+#[derive(Serialize, Deserialize)]
+pub struct PoseidonROCircuit<Scalar: PrimeField> {
+  // Internal state
+  state: Vec<AllocatedNum<Scalar>>,
+  constants: PoseidonConstantsCircuit<Scalar>,
+  num_absorbs: usize,
+  squeezed: bool,
+}
+
+impl<Scalar> ROCircuitTrait<Scalar> for PoseidonROCircuit<Scalar>
+where
+  Scalar: PrimeField + PrimeFieldBits + Serialize + for<'de> Deserialize<'de>,
+  Scalar::Repr: Abomonation,
+{
+  type NativeRO<T: PrimeField> = PoseidonRO<Scalar, T>;
+  type Constants = PoseidonConstantsCircuit<Scalar>;
+
+  /// Initialize the internal state and set the poseidon constants
+  fn new(constants: PoseidonConstantsCircuit<Scalar>, num_absorbs: usize) -> Self {
+    Self {
+      state: Vec::new(),
+      constants,
+      num_absorbs,
+      squeezed: false,
+    }
+  }
+
+  /// Absorb a new number into the state of the oracle
+  fn absorb(&mut self, e: &AllocatedNum<Scalar>) {
+    assert!(!self.squeezed, "Cannot absorb after squeezing");
+    self.state.push(e.clone());
+  }
+
+  /// Compute a challenge by hashing the current state
+  fn squeeze<CS: ConstraintSystem<Scalar>>(
+    &mut self,
+    mut cs: CS,
+    num_bits: usize,
+  ) -> Result<Vec<AllocatedBit>, SynthesisError> {
+    // check if we have squeezed already
+    assert!(!self.squeezed, "Cannot squeeze again after squeezing");
+    self.squeezed = true;
+    let parameter = IOPattern(vec![
+      SpongeOp::Absorb(self.num_absorbs as u32),
+      SpongeOp::Squeeze(1u32),
+    ]);
+    let mut ns = cs.namespace(|| "ns");
+
+    let hash = {
+      let mut sponge = SpongeCircuit::new_with_constants(&self.constants.0, Simplex);
+      let acc = &mut ns;
+      assert_eq!(self.num_absorbs, self.state.len());
+
+      sponge.start(parameter, None, acc);
+      neptune::sponge::api::SpongeAPI::absorb(
+        &mut sponge,
+        self.num_absorbs as u32,
+        &(0..self.state.len())
+          .map(|i| Elt::Allocated(self.state[i].clone()))
+          .collect::<Vec<Elt<Scalar>>>(),
+        acc,
+      );
+
+      let output = neptune::sponge::api::SpongeAPI::squeeze(&mut sponge, 1, acc);
+      sponge.finish(acc).unwrap();
+      output
+    };
+
+    let hash = Elt::ensure_allocated(&hash[0], &mut ns.namespace(|| "ensure allocated"), true)?;
+
+    // return the hash as a vector of bits, truncated
+    Ok(
+      hash
+        .to_bits_le_strict(ns.namespace(|| "poseidon hash to boolean"))?
+        .iter()
+        .map(|boolean| match boolean {
+          Boolean::Is(ref x) => x.clone(),
+          _ => panic!("Wrong type of input. We should have never reached there"),
+        })
+        .collect::<Vec<AllocatedBit>>()[..num_bits]
+        .into(),
+    )
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::provider::{
+    Bn256Engine, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine, VestaEngine,
+  };
+  use crate::{
+    bellpepper::solver::SatisfyingAssignment, constants::NUM_CHALLENGE_BITS,
+    gadgets::utils::le_bits_to_num, traits::Engine,
+  };
+  use ff::Field;
+  use rand::rngs::OsRng;
+
+  fn test_poseidon_ro_with<E: Engine>()
+  where
+    // we can print the field elements we get from E's Base & Scalar fields,
+    // and compare their byte representations
+    <<E as Engine>::Base as PrimeField>::Repr: std::fmt::Debug + Abomonation,
+    <<E as Engine>::Scalar as PrimeField>::Repr: std::fmt::Debug + Abomonation,
+    <<E as Engine>::Base as PrimeField>::Repr:
+      PartialEq<<<E as Engine>::Scalar as PrimeField>::Repr>,
+  {
+    // Check that the number computed inside the circuit is equal to the number computed outside the circuit
+    let mut csprng: OsRng = OsRng;
+    let constants = PoseidonConstantsCircuit::<E::Scalar>::default();
+    let num_absorbs = 32;
+    let mut ro: PoseidonRO<E::Scalar, E::Base> = PoseidonRO::new(constants.clone(), num_absorbs);
+    let mut ro_gadget: PoseidonROCircuit<E::Scalar> =
+      PoseidonROCircuit::new(constants, num_absorbs);
+    let mut cs = SatisfyingAssignment::<E>::new();
+    for i in 0..num_absorbs {
+      let num = E::Scalar::random(&mut csprng);
+      ro.absorb(num);
+      let num_gadget = AllocatedNum::alloc_infallible(cs.namespace(|| format!("data {i}")), || num);
+      num_gadget
+        .inputize(&mut cs.namespace(|| format!("input {i}")))
+        .unwrap();
+      ro_gadget.absorb(&num_gadget);
+    }
+    let num = ro.squeeze(NUM_CHALLENGE_BITS);
+    let num2_bits = ro_gadget.squeeze(&mut cs, NUM_CHALLENGE_BITS).unwrap();
+    let num2 = le_bits_to_num(&mut cs, &num2_bits).unwrap();
+    assert_eq!(num.to_repr(), num2.get_value().unwrap().to_repr());
+  }
+
+  #[test]
+  fn test_poseidon_ro() {
+    test_poseidon_ro_with::<PallasEngine>();
+    test_poseidon_ro_with::<VestaEngine>();
+    test_poseidon_ro_with::<Bn256Engine>();
+    test_poseidon_ro_with::<GrumpkinEngine>();
+    test_poseidon_ro_with::<Secp256k1Engine>();
+    test_poseidon_ro_with::<Secq256k1Engine>();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/secp_secq.rs.html b/docs/src/arecibo/provider/secp_secq.rs.html new file mode 100644 index 000000000..8c2e26efa --- /dev/null +++ b/docs/src/arecibo/provider/secp_secq.rs.html @@ -0,0 +1,85 @@ +secp_secq.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+
//! This module implements the Nova traits for `secp::Point`, `secp::Scalar`, `secq::Point`, `secq::Scalar`.
+use crate::{
+  impl_traits,
+  provider::{traits::DlogGroup, util::msm::cpu_best_msm},
+  traits::{Group, PrimeFieldExt, TranscriptReprTrait},
+};
+use digest::{ExtendableOutput, Update};
+use ff::{FromUniformBytes, PrimeField};
+use group::{cofactor::CofactorCurveAffine, Curve, Group as AnotherGroup};
+use num_bigint::BigInt;
+use num_traits::Num;
+use pasta_curves::arithmetic::{CurveAffine, CurveExt};
+use rayon::prelude::*;
+use sha3::Shake256;
+use std::io::Read;
+/// Re-exports that give access to the standard aliases used in the code base, for secp
+pub mod secp256k1 {
+  pub use halo2curves::secp256k1::{
+    Fp as Base, Fq as Scalar, Secp256k1 as Point, Secp256k1Affine as Affine,
+    Secp256k1Compressed as Compressed,
+  };
+}
+
+/// Re-exports that give access to the standard aliases used in the code base, for secq
+pub mod secq256k1 {
+  pub use halo2curves::secq256k1::{
+    Fp as Base, Fq as Scalar, Secq256k1 as Point, Secq256k1Affine as Affine,
+    Secq256k1Compressed as Compressed,
+  };
+}
+
+impl_traits!(
+  secp256k1,
+  "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141",
+  "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
+);
+
+impl_traits!(
+  secq256k1,
+  "fffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f",
+  "fffffffffffffffffffffffffffffffebaaedce6af48a03bbfd25e8cd0364141"
+);
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/traits.rs.html b/docs/src/arecibo/provider/traits.rs.html new file mode 100644 index 000000000..28016dc72 --- /dev/null +++ b/docs/src/arecibo/provider/traits.rs.html @@ -0,0 +1,365 @@ +traits.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+
use crate::traits::{Group, TranscriptReprTrait};
+use group::{prime::PrimeCurve, GroupEncoding};
+use serde::{Deserialize, Serialize};
+use std::fmt::Debug;
+
+/// A trait that defines extensions to the Group trait
+pub trait DlogGroup:
+  Group<Scalar = <Self as DlogGroup>::ScalarExt>
+  + Serialize
+  + for<'de> Deserialize<'de>
+  + PrimeCurve<Scalar = <Self as DlogGroup>::ScalarExt, Affine = <Self as DlogGroup>::AffineExt>
+{
+  type ScalarExt;
+  type AffineExt: Clone + Debug + Eq + Serialize + for<'de> Deserialize<'de> + Sync + Send;
+  type Compressed: Clone
+    + Debug
+    + Eq
+    + From<<Self as GroupEncoding>::Repr>
+    + Into<<Self as GroupEncoding>::Repr>
+    + Serialize
+    + for<'de> Deserialize<'de>
+    + Sync
+    + Send
+    + TranscriptReprTrait<Self>;
+
+  /// A method to compute a multiexponentation
+  fn vartime_multiscalar_mul(scalars: &[Self::ScalarExt], bases: &[Self::AffineExt]) -> Self;
+
+  /// Produce a vector of group elements using a static label
+  fn from_label(label: &'static [u8], n: usize) -> Vec<Self::Affine>;
+
+  /// Returns the affine coordinates (x, y, infinty) for the point
+  fn to_coordinates(&self) -> (<Self as Group>::Base, <Self as Group>::Base, bool);
+}
+
+/// This implementation behaves in ways specific to the halo2curves suite of curves in:
+// - to_coordinates,
+// - vartime_multiscalar_mul, where it does not call into accelerated implementations.
+// A specific reimplementation exists for the pasta curves in their own module.
+#[macro_export]
+macro_rules! impl_traits {
+  (
+    $name:ident,
+    $order_str:literal,
+    $base_str:literal
+  ) => {
+    $crate::impl_traits!($name, $order_str, $base_str, cpu_best_msm);
+  };
+  (
+    $name:ident,
+    $order_str:literal,
+    $base_str:literal,
+    $large_msm_method: ident
+  ) => {
+    impl Group for $name::Point {
+      type Base = $name::Base;
+      type Scalar = $name::Scalar;
+
+      fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt) {
+        let A = $name::Point::a();
+        let B = $name::Point::b();
+        let order = BigInt::from_str_radix($order_str, 16).unwrap();
+        let base = BigInt::from_str_radix($base_str, 16).unwrap();
+
+        (A, B, order, base)
+      }
+    }
+
+    impl DlogGroup for $name::Point {
+      type ScalarExt = $name::Scalar;
+      type AffineExt = $name::Affine;
+      // note: for halo2curves implementations, $name::Compressed == <$name::Point as GroupEncoding>::Repr
+      // so the blanket impl<T> From<T> for T and impl<T> Into<T> apply.
+      type Compressed = $name::Compressed;
+
+      fn vartime_multiscalar_mul(scalars: &[Self::ScalarExt], bases: &[Self::AffineExt]) -> Self {
+        #[cfg(any(target_arch = "x86_64", target_arch = "aarch64"))]
+        if scalars.len() >= 128 {
+          $large_msm_method(bases, scalars)
+        } else {
+          cpu_best_msm(bases, scalars)
+        }
+        #[cfg(not(any(target_arch = "x86_64", target_arch = "aarch64")))]
+        cpu_best_msm(bases, scalars)
+      }
+
+      fn from_label(label: &'static [u8], n: usize) -> Vec<Self::Affine> {
+        let mut shake = Shake256::default();
+        shake.update(label);
+        let mut reader = shake.finalize_xof();
+        let mut uniform_bytes_vec = Vec::new();
+        for _ in 0..n {
+          let mut uniform_bytes = [0u8; 32];
+          reader.read_exact(&mut uniform_bytes).unwrap();
+          uniform_bytes_vec.push(uniform_bytes);
+        }
+        let gens_proj: Vec<$name::Point> = (0..n)
+          .into_par_iter()
+          .map(|i| {
+            let hash = $name::Point::hash_to_curve("from_uniform_bytes");
+            hash(&uniform_bytes_vec[i])
+          })
+          .collect();
+
+        let num_threads = rayon::current_num_threads();
+        if gens_proj.len() > num_threads {
+          let chunk = (gens_proj.len() as f64 / num_threads as f64).ceil() as usize;
+          (0..num_threads)
+            .into_par_iter()
+            .flat_map(|i| {
+              let start = i * chunk;
+              let end = if i == num_threads - 1 {
+                gens_proj.len()
+              } else {
+                core::cmp::min((i + 1) * chunk, gens_proj.len())
+              };
+              if end > start {
+                let mut gens = vec![$name::Affine::identity(); end - start];
+                <Self as Curve>::batch_normalize(&gens_proj[start..end], &mut gens);
+                gens
+              } else {
+                vec![]
+              }
+            })
+            .collect()
+        } else {
+          let mut gens = vec![$name::Affine::identity(); n];
+          <Self as Curve>::batch_normalize(&gens_proj, &mut gens);
+          gens
+        }
+      }
+
+      fn to_coordinates(&self) -> (Self::Base, Self::Base, bool) {
+        let coordinates = self.to_affine().coordinates();
+        if coordinates.is_some().unwrap_u8() == 1 && ($name::Point::identity() != *self) {
+          (*coordinates.unwrap().x(), *coordinates.unwrap().y(), false)
+        } else {
+          (Self::Base::zero(), Self::Base::zero(), true)
+        }
+      }
+    }
+
+    impl PrimeFieldExt for $name::Scalar {
+      fn from_uniform(bytes: &[u8]) -> Self {
+        let bytes_arr: [u8; 64] = bytes.try_into().unwrap();
+        $name::Scalar::from_uniform_bytes(&bytes_arr)
+      }
+    }
+
+    impl<G: DlogGroup> TranscriptReprTrait<G> for $name::Compressed {
+      fn to_transcript_bytes(&self) -> Vec<u8> {
+        self.as_ref().to_vec()
+      }
+    }
+
+    impl<G: Group> TranscriptReprTrait<G> for $name::Scalar {
+      fn to_transcript_bytes(&self) -> Vec<u8> {
+        self.to_repr().to_vec()
+      }
+    }
+
+    impl<G: DlogGroup> TranscriptReprTrait<G> for $name::Affine {
+      fn to_transcript_bytes(&self) -> Vec<u8> {
+        let (x, y, is_infinity_byte) = {
+          let coordinates = self.coordinates();
+          if coordinates.is_some().unwrap_u8() == 1 && ($name::Affine::identity() != *self) {
+            let c = coordinates.unwrap();
+            (*c.x(), *c.y(), u8::from(false))
+          } else {
+            ($name::Base::zero(), $name::Base::zero(), u8::from(false))
+          }
+        };
+
+        x.to_repr()
+          .into_iter()
+          .chain(y.to_repr().into_iter())
+          .chain(std::iter::once(is_infinity_byte))
+          .collect()
+      }
+    }
+  };
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/util/fb_msm.rs.html b/docs/src/arecibo/provider/util/fb_msm.rs.html new file mode 100644 index 000000000..be68a6c6a --- /dev/null +++ b/docs/src/arecibo/provider/util/fb_msm.rs.html @@ -0,0 +1,261 @@ +fb_msm.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+
/// # Fixed-base Scalar Multiplication
+///
+/// This module provides an implementation of fixed-base scalar multiplication on elliptic curves.
+///
+/// The multiplication is optimized through a windowed method, where scalars are broken into fixed-size
+/// windows, pre-computation tables are generated, and results are efficiently combined.
+use ff::{PrimeField, PrimeFieldBits};
+use group::{prime::PrimeCurve, Curve};
+
+use rayon::prelude::*;
+
+/// Determines the window size for scalar multiplication based on the number of scalars.
+///
+/// This is used to balance between pre-computation and number of point additions.
+pub(crate) fn get_mul_window_size(num_scalars: usize) -> usize {
+  if num_scalars < 32 {
+    3
+  } else {
+    (num_scalars as f64).ln().ceil() as usize
+  }
+}
+
+/// Generates a table of multiples of a base point `g` for use in windowed scalar multiplication.
+///
+/// This pre-computes multiples of a base point for each window and organizes them
+/// into a table for quick lookup during the scalar multiplication process. The table is a vector
+/// of vectors, each inner vector corresponding to a window and containing the multiples of `g`
+/// for that window.
+pub(crate) fn get_window_table<T>(
+  scalar_size: usize,
+  window: usize,
+  g: T,
+) -> Vec<Vec<T::AffineRepr>>
+where
+  T: Curve,
+  T::AffineRepr: Send,
+{
+  let in_window = 1 << window;
+  // Number of outer iterations needed to cover the entire scalar
+  let outerc = (scalar_size + window - 1) / window;
+
+  // Number of multiples of the window's "outer point" needed for each window (fewer for the last window)
+  let last_in_window = 1 << (scalar_size - (outerc - 1) * window);
+
+  let mut multiples_of_g = vec![vec![T::identity(); in_window]; outerc];
+
+  // Compute the multiples of g for each window
+  // g_outers = [ 2^{k*window}*g for k in 0..outerc]
+  let mut g_outer = g;
+  let mut g_outers = Vec::with_capacity(outerc);
+  for _ in 0..outerc {
+    g_outers.push(g_outer);
+    for _ in 0..window {
+      g_outer = g_outer.double();
+    }
+  }
+  multiples_of_g
+    .par_iter_mut()
+    .enumerate()
+    .zip_eq(g_outers)
+    .for_each(|((outer, multiples_of_g), g_outer)| {
+      let cur_in_window = if outer == outerc - 1 {
+        last_in_window
+      } else {
+        in_window
+      };
+
+      // multiples_of_g = [id, g_outer, 2*g_outer, 3*g_outer, ...],
+      // where g_outer = 2^{outer*window}*g
+      let mut g_inner = T::identity();
+      for inner in multiples_of_g.iter_mut().take(cur_in_window) {
+        *inner = g_inner;
+        g_inner.add_assign(&g_outer);
+      }
+    });
+  multiples_of_g
+    .par_iter()
+    .map(|s| s.iter().map(|s| s.to_affine()).collect())
+    .collect()
+}
+
+/// Performs the actual windowed scalar multiplication using a pre-computed table of points.
+///
+/// Given a scalar and a table of pre-computed multiples of a base point, this function
+/// efficiently computes the scalar multiplication by breaking the scalar into windows and
+/// adding the corresponding multiples from the table.
+fn windowed_mul<T>(
+  outerc: usize,
+  window: usize,
+  multiples_of_g: &[Vec<T::Affine>],
+  scalar: &T::Scalar,
+) -> T
+where
+  T: PrimeCurve,
+  T::Scalar: PrimeFieldBits,
+{
+  let modulus_size = <T::Scalar as PrimeField>::NUM_BITS as usize;
+  let scalar_val: Vec<bool> = scalar.to_le_bits().into_iter().collect();
+
+  let mut res = T::identity();
+  for outer in 0..outerc {
+    let mut inner = 0usize;
+    for i in 0..window {
+      if outer * window + i < modulus_size && scalar_val[outer * window + i] {
+        inner |= 1 << i;
+      }
+    }
+    res.add_assign(&multiples_of_g[outer][inner]);
+  }
+  res
+}
+
+/// Computes multiple scalar multiplications simultaneously using the windowed method.
+pub(crate) fn multi_scalar_mul<T>(
+  scalar_size: usize,
+  window: usize,
+  table: &[Vec<T::AffineRepr>],
+  v: &[T::Scalar],
+) -> Vec<T>
+where
+  T: PrimeCurve,
+  T::Scalar: PrimeFieldBits,
+{
+  let outerc = (scalar_size + window - 1) / window;
+  assert!(outerc <= table.len());
+
+  v.par_iter()
+    .map(|e| windowed_mul::<T>(outerc, window, table, e))
+    .collect::<Vec<_>>()
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/provider/util/mod.rs.html b/docs/src/arecibo/provider/util/mod.rs.html new file mode 100644 index 000000000..54b74a954 --- /dev/null +++ b/docs/src/arecibo/provider/util/mod.rs.html @@ -0,0 +1,269 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+
//! Utilities for provider module.
+pub(in crate::provider) mod fb_msm;
+pub mod msm {
+  use halo2curves::msm::best_multiexp;
+  use halo2curves::CurveAffine;
+
+  // this argument swap is useful until Rust gets named arguments
+  // and saves significant complexity in macro code
+  pub fn cpu_best_msm<C: CurveAffine>(bases: &[C], scalars: &[C::Scalar]) -> C::Curve {
+    best_multiexp(scalars, bases)
+  }
+}
+
+#[cfg(test)]
+pub mod test_utils {
+  //! Contains utilities for testing and benchmarking.
+  use crate::spartan::polys::multilinear::MultilinearPolynomial;
+  use crate::traits::{
+    commitment::CommitmentEngineTrait, evaluation::EvaluationEngineTrait, Engine,
+  };
+  use ff::Field;
+  use rand::rngs::StdRng;
+  use rand_core::{CryptoRng, RngCore};
+
+  /// Returns a random polynomial, a point and calculate its evaluation.
+  fn random_poly_with_eval<E: Engine, R: RngCore + CryptoRng>(
+    num_vars: usize,
+    mut rng: &mut R,
+  ) -> (
+    MultilinearPolynomial<<E as Engine>::Scalar>,
+    Vec<<E as Engine>::Scalar>,
+    <E as Engine>::Scalar,
+  ) {
+    // Generate random polynomial and point.
+    let poly = MultilinearPolynomial::random(num_vars, &mut rng);
+    let point = (0..num_vars)
+      .map(|_| <E as Engine>::Scalar::random(&mut rng))
+      .collect::<Vec<_>>();
+
+    // Calculation evaluation of point over polynomial.
+    let eval = MultilinearPolynomial::evaluate_with(poly.evaluations(), &point);
+
+    (poly, point, eval)
+  }
+
+  /// Methods used to test the prove and verify flow of [`MultilinearPolynomial`] Commitment Schemes
+  /// (PCS).
+  ///
+  /// Generates a random polynomial and point from a seed to test a proving/verifying flow of one
+  /// of our [`EvaluationEngine`].
+  pub(crate) fn prove_verify_from_num_vars<E: Engine, EE: EvaluationEngineTrait<E>>(
+    num_vars: usize,
+  ) {
+    use rand_core::SeedableRng;
+
+    let mut rng = rand::rngs::StdRng::seed_from_u64(num_vars as u64);
+
+    let (poly, point, eval) = random_poly_with_eval::<E, StdRng>(num_vars, &mut rng);
+
+    // Mock commitment key.
+    let ck = E::CE::setup(b"test", 1 << num_vars);
+    // Commits to the provided vector using the provided generators.
+    let commitment = E::CE::commit(&ck, poly.evaluations());
+
+    prove_verify_with::<E, EE>(&ck, &commitment, &poly, &point, &eval, true)
+  }
+
+  fn prove_verify_with<E: Engine, EE: EvaluationEngineTrait<E>>(
+    ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+    commitment: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment,
+    poly: &MultilinearPolynomial<<E as Engine>::Scalar>,
+    point: &[<E as Engine>::Scalar],
+    eval: &<E as Engine>::Scalar,
+    evaluate_bad_proof: bool,
+  ) {
+    use crate::traits::TranscriptEngineTrait;
+    use std::ops::Add;
+
+    // Generate Prover and verifier key for given commitment key.
+    let (prover_key, verifier_key) = EE::setup(ck);
+
+    // Generate proof.
+    let mut prover_transcript = E::TE::new(b"TestEval");
+    let proof = EE::prove(
+      ck,
+      &prover_key,
+      &mut prover_transcript,
+      commitment,
+      poly.evaluations(),
+      point,
+      eval,
+    )
+    .unwrap();
+    let pcp = prover_transcript.squeeze(b"c").unwrap();
+
+    // Verify proof.
+    let mut verifier_transcript = E::TE::new(b"TestEval");
+    EE::verify(
+      &verifier_key,
+      &mut verifier_transcript,
+      commitment,
+      point,
+      eval,
+      &proof,
+    )
+    .unwrap();
+    let pcv = verifier_transcript.squeeze(b"c").unwrap();
+
+    // Check if the prover transcript and verifier transcript are kept in the same state.
+    assert_eq!(pcp, pcv);
+
+    if evaluate_bad_proof {
+      // Generate another point to verify proof. Also produce eval.
+      let altered_verifier_point = point
+        .iter()
+        .map(|s| s.add(<E as Engine>::Scalar::ONE))
+        .collect::<Vec<_>>();
+      let altered_verifier_eval =
+        MultilinearPolynomial::evaluate_with(poly.evaluations(), &altered_verifier_point);
+
+      // Verify proof, should fail.
+      let mut verifier_transcript = E::TE::new(b"TestEval");
+      assert!(EE::verify(
+        &verifier_key,
+        &mut verifier_transcript,
+        commitment,
+        &altered_verifier_point,
+        &altered_verifier_eval,
+        &proof,
+      )
+      .is_err());
+    }
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/r1cs/mod.rs.html b/docs/src/arecibo/r1cs/mod.rs.html new file mode 100644 index 000000000..6b5cbf6b4 --- /dev/null +++ b/docs/src/arecibo/r1cs/mod.rs.html @@ -0,0 +1,1877 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+
//! This module defines R1CS related types and a folding scheme for Relaxed R1CS
+mod sparse;
+#[cfg(test)]
+pub(crate) mod util;
+
+use crate::{
+  constants::{BN_LIMB_WIDTH, BN_N_LIMBS},
+  digest::{DigestComputer, SimpleDigestible},
+  errors::NovaError,
+  gadgets::{
+    nonnative::{bignat::nat_to_limbs, util::f_to_nat},
+    utils::scalar_as_base,
+  },
+  traits::{
+    commitment::CommitmentEngineTrait, AbsorbInROTrait, Engine, ROTrait, TranscriptReprTrait,
+  },
+  zip_with, Commitment, CommitmentKey, CE,
+};
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use core::cmp::max;
+use ff::{Field, PrimeField};
+use once_cell::sync::OnceCell;
+use rand_core::{CryptoRng, RngCore};
+
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+
+pub(crate) use self::sparse::SparseMatrix;
+
+/// A type that holds the shape of the R1CS matrices
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
+#[abomonation_bounds(where <E::Scalar as PrimeField>::Repr: Abomonation)]
+pub struct R1CSShape<E: Engine> {
+  pub(crate) num_cons: usize,
+  pub(crate) num_vars: usize,
+  pub(crate) num_io: usize,
+  pub(crate) A: SparseMatrix<E::Scalar>,
+  pub(crate) B: SparseMatrix<E::Scalar>,
+  pub(crate) C: SparseMatrix<E::Scalar>,
+  #[serde(skip, default = "OnceCell::new")]
+  #[abomonate_with(<E::Scalar as PrimeField>::Repr)]
+  pub(crate) digest: OnceCell<E::Scalar>,
+}
+
+impl<E: Engine> SimpleDigestible for R1CSShape<E> {}
+
+/// A type that holds the result of a R1CS multiplication
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct R1CSResult<E: Engine> {
+  pub(crate) AZ: Vec<E::Scalar>,
+  pub(crate) BZ: Vec<E::Scalar>,
+  pub(crate) CZ: Vec<E::Scalar>,
+}
+
+/// A type that holds a witness for a given R1CS instance
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct R1CSWitness<E: Engine> {
+  W: Vec<E::Scalar>,
+}
+
+/// A type that holds an R1CS instance
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct R1CSInstance<E: Engine> {
+  pub(crate) comm_W: Commitment<E>,
+  pub(crate) X: Vec<E::Scalar>,
+}
+
+/// A type that holds a witness for a given Relaxed R1CS instance
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+pub struct RelaxedR1CSWitness<E: Engine> {
+  pub(crate) W: Vec<E::Scalar>,
+  pub(crate) E: Vec<E::Scalar>,
+}
+
+/// A type that holds a Relaxed R1CS instance
+#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct RelaxedR1CSInstance<E: Engine> {
+  pub(crate) comm_W: Commitment<E>,
+  pub(crate) comm_E: Commitment<E>,
+  pub(crate) X: Vec<E::Scalar>,
+  pub(crate) u: E::Scalar,
+}
+
+/// A type for functions that hints commitment key sizing by returning the floor of the number of required generators.
+pub type CommitmentKeyHint<E> = dyn Fn(&R1CSShape<E>) -> usize;
+
+/// Generates public parameters for a Rank-1 Constraint System (R1CS).
+///
+/// This function takes into consideration the shape of the R1CS matrices and a hint function
+/// for the number of generators. It returns a `CommitmentKey`.
+///
+/// # Arguments
+///
+/// * `S`: The shape of the R1CS matrices.
+/// * `ck_floor`: A function that provides a floor for the number of generators. A good function to
+///   provide is the `commitment_key_floor` field in the trait `RelaxedR1CSSNARKTrait`.
+///
+pub fn commitment_key<E: Engine>(
+  S: &R1CSShape<E>,
+  ck_floor: &CommitmentKeyHint<E>,
+) -> CommitmentKey<E> {
+  let size = commitment_key_size(S, ck_floor);
+  E::CE::setup(b"ck", size)
+}
+
+/// Computes the number of generators required for the commitment key corresponding to shape `S`.
+pub fn commitment_key_size<E: Engine>(S: &R1CSShape<E>, ck_floor: &CommitmentKeyHint<E>) -> usize {
+  let num_cons = S.num_cons;
+  let num_vars = S.num_vars;
+  let ck_hint = ck_floor(S);
+  max(max(num_cons, num_vars), ck_hint)
+}
+
+impl<E: Engine> R1CSShape<E> {
+  /// Create an object of type `R1CSShape` from the explicitly specified R1CS matrices
+  pub fn new(
+    num_cons: usize,
+    num_vars: usize,
+    num_io: usize,
+    A: SparseMatrix<E::Scalar>,
+    B: SparseMatrix<E::Scalar>,
+    C: SparseMatrix<E::Scalar>,
+  ) -> Result<Self, NovaError> {
+    let is_valid = |num_cons: usize,
+                    num_vars: usize,
+                    num_io: usize,
+                    M: &SparseMatrix<E::Scalar>|
+     -> Result<Vec<()>, NovaError> {
+      M.iter()
+        .map(|(row, col, _val)| {
+          if row >= num_cons || col > num_io + num_vars {
+            Err(NovaError::InvalidIndex)
+          } else {
+            Ok(())
+          }
+        })
+        .collect::<Result<Vec<()>, NovaError>>()
+    };
+
+    is_valid(num_cons, num_vars, num_io, &A)?;
+    is_valid(num_cons, num_vars, num_io, &B)?;
+    is_valid(num_cons, num_vars, num_io, &C)?;
+
+    // We require the number of public inputs/outputs to be even
+    if num_io % 2 != 0 {
+      return Err(NovaError::OddInputLength);
+    }
+
+    Ok(Self {
+      num_cons,
+      num_vars,
+      num_io,
+      A,
+      B,
+      C,
+      digest: OnceCell::new(),
+    })
+  }
+
+  /// Generate a random [R1CSShape] with the specified number of constraints, variables, and public inputs/outputs.
+  pub fn random<R: RngCore + CryptoRng>(
+    num_cons: usize,
+    num_vars: usize,
+    num_io: usize,
+    num_entries: usize,
+    mut rng: &mut R,
+  ) -> Self {
+    assert!(num_cons.is_power_of_two());
+    assert!(num_vars.is_power_of_two());
+    assert!(num_entries.is_power_of_two());
+    assert!(num_io < num_vars);
+
+    let num_rows = num_cons;
+    let num_cols = num_vars + 1 + num_io;
+
+    let (NA, NB, NC) = {
+      let N_div_3 = num_entries / 3;
+      let NC = num_entries - (2 * N_div_3);
+      (N_div_3, N_div_3, NC)
+    };
+
+    let A = SparseMatrix::random(num_rows, num_cols, NA, &mut rng);
+    let B = SparseMatrix::random(num_rows, num_cols, NB, &mut rng);
+    let C = SparseMatrix::random(num_rows, num_cols, NC, &mut rng);
+
+    Self {
+      num_cons,
+      num_vars,
+      num_io,
+      A,
+      B,
+      C,
+      digest: Default::default(),
+    }
+  }
+
+  /// Generate a satisfying [RelaxedR1CSWitness] and [RelaxedR1CSInstance] for this [R1CSShape].
+  pub fn random_witness_instance<R: RngCore + CryptoRng>(
+    &self,
+    commitment_key: &CommitmentKey<E>,
+    mut rng: &mut R,
+  ) -> (RelaxedR1CSWitness<E>, RelaxedR1CSInstance<E>) {
+    // Sample a random witness and compute the error term
+    let W = (0..self.num_vars)
+      .map(|_| E::Scalar::random(&mut rng))
+      .collect::<Vec<E::Scalar>>();
+    let u = E::Scalar::random(&mut rng);
+    let X = (0..self.num_io)
+      .map(|_| E::Scalar::random(&mut rng))
+      .collect::<Vec<E::Scalar>>();
+
+    let E = self.compute_E(&W, &u, &X).unwrap();
+
+    let (comm_W, comm_E) = rayon::join(
+      || CE::<E>::commit(commitment_key, &W),
+      || CE::<E>::commit(commitment_key, &E),
+    );
+
+    let witness = RelaxedR1CSWitness { W, E };
+    let instance = RelaxedR1CSInstance {
+      comm_W,
+      comm_E,
+      u,
+      X,
+    };
+
+    (witness, instance)
+  }
+
+  /// returned the digest of the `R1CSShape`
+  pub fn digest(&self) -> E::Scalar {
+    self
+      .digest
+      .get_or_try_init(|| DigestComputer::new(self).digest())
+      .cloned()
+      .expect("Failure retrieving digest")
+  }
+
+  // Checks regularity conditions on the R1CSShape, required in Spartan-class SNARKs
+  // Returns false if num_cons, num_vars, or num_io are not powers of two, or if num_io > num_vars
+  #[inline]
+  pub(crate) fn is_regular_shape(&self) -> bool {
+    let cons_valid = self.num_cons.next_power_of_two() == self.num_cons;
+    let vars_valid = self.num_vars.next_power_of_two() == self.num_vars;
+    let io_valid = self.num_io.next_power_of_two() == self.num_io;
+    let io_lt_vars = self.num_io < self.num_vars;
+    cons_valid && vars_valid && io_valid && io_lt_vars
+  }
+
+  pub(crate) fn multiply_vec(
+    &self,
+    z: &[E::Scalar],
+  ) -> Result<(Vec<E::Scalar>, Vec<E::Scalar>, Vec<E::Scalar>), NovaError> {
+    if z.len() != self.num_io + self.num_vars + 1 {
+      return Err(NovaError::InvalidWitnessLength);
+    }
+
+    let (Az, (Bz, Cz)) = rayon::join(
+      || self.A.multiply_vec(z),
+      || rayon::join(|| self.B.multiply_vec(z), || self.C.multiply_vec(z)),
+    );
+
+    Ok((Az, Bz, Cz))
+  }
+
+  pub(crate) fn multiply_witness(
+    &self,
+    W: &[E::Scalar],
+    u: &E::Scalar,
+    X: &[E::Scalar],
+  ) -> Result<(Vec<E::Scalar>, Vec<E::Scalar>, Vec<E::Scalar>), NovaError> {
+    if X.len() != self.num_io || W.len() != self.num_vars {
+      return Err(NovaError::InvalidWitnessLength);
+    }
+
+    let (Az, (Bz, Cz)) = rayon::join(
+      || self.A.multiply_witness(W, u, X),
+      || {
+        rayon::join(
+          || self.B.multiply_witness(W, u, X),
+          || self.C.multiply_witness(W, u, X),
+        )
+      },
+    );
+
+    Ok((Az, Bz, Cz))
+  }
+
+  pub(crate) fn multiply_witness_into(
+    &self,
+    W: &[E::Scalar],
+    u: &E::Scalar,
+    X: &[E::Scalar],
+    ABC_Z: &mut R1CSResult<E>,
+  ) -> Result<(), NovaError> {
+    if X.len() != self.num_io || W.len() != self.num_vars {
+      return Err(NovaError::InvalidWitnessLength);
+    }
+
+    let R1CSResult { AZ, BZ, CZ } = ABC_Z;
+
+    rayon::join(
+      || self.A.multiply_witness_into(W, u, X, AZ),
+      || {
+        rayon::join(
+          || self.B.multiply_witness_into(W, u, X, BZ),
+          || self.C.multiply_witness_into(W, u, X, CZ),
+        )
+      },
+    );
+
+    Ok(())
+  }
+
+  /// Computes the error term E = Az * Bz - u*Cz.
+  fn compute_E(
+    &self,
+    W: &[E::Scalar],
+    u: &E::Scalar,
+    X: &[E::Scalar],
+  ) -> Result<Vec<E::Scalar>, NovaError> {
+    if X.len() != self.num_io || W.len() != self.num_vars {
+      return Err(NovaError::InvalidWitnessLength);
+    }
+
+    let (Az, (Bz, Cz)) = rayon::join(
+      || self.A.multiply_witness(W, u, X),
+      || {
+        rayon::join(
+          || self.B.multiply_witness(W, u, X),
+          || self.C.multiply_witness(W, u, X),
+        )
+      },
+    );
+
+    let E = zip_with!(
+      (Az.into_par_iter(), Bz.into_par_iter(), Cz.into_par_iter()),
+      |a, b, c| a * b - c * u
+    )
+    .collect::<Vec<E::Scalar>>();
+
+    Ok(E)
+  }
+
+  /// Checks if the Relaxed R1CS instance is satisfiable given a witness and its shape
+  pub fn is_sat_relaxed(
+    &self,
+    ck: &CommitmentKey<E>,
+    U: &RelaxedR1CSInstance<E>,
+    W: &RelaxedR1CSWitness<E>,
+  ) -> Result<(), NovaError> {
+    assert_eq!(W.W.len(), self.num_vars);
+    assert_eq!(W.E.len(), self.num_cons);
+    assert_eq!(U.X.len(), self.num_io);
+
+    // verify if Az * Bz - u*Cz = E
+    let E = self.compute_E(&W.W, &U.u, &U.X)?;
+    W.E
+      .par_iter()
+      .zip_eq(E.into_par_iter())
+      .enumerate()
+      .try_for_each(|(i, (we, e))| {
+        if *we != e {
+          // constraint failed, retrieve constraint name
+          Err(NovaError::UnSatIndex(i))
+        } else {
+          Ok(())
+        }
+      })?;
+
+    // verify if comm_E and comm_W are commitments to E and W
+    let res_comm = {
+      let (comm_W, comm_E) =
+        rayon::join(|| CE::<E>::commit(ck, &W.W), || CE::<E>::commit(ck, &W.E));
+      U.comm_W == comm_W && U.comm_E == comm_E
+    };
+
+    if !res_comm {
+      return Err(NovaError::UnSat);
+    }
+    Ok(())
+  }
+
+  /// Checks if the R1CS instance is satisfiable given a witness and its shape
+  pub fn is_sat(
+    &self,
+    ck: &CommitmentKey<E>,
+    U: &R1CSInstance<E>,
+    W: &R1CSWitness<E>,
+  ) -> Result<(), NovaError> {
+    assert_eq!(W.W.len(), self.num_vars);
+    assert_eq!(U.X.len(), self.num_io);
+
+    // verify if Az * Bz - u*Cz = 0
+    let E = self.compute_E(&W.W, &E::Scalar::ONE, &U.X)?;
+    E.into_par_iter().enumerate().try_for_each(|(i, e)| {
+      if e != E::Scalar::ZERO {
+        Err(NovaError::UnSatIndex(i))
+      } else {
+        Ok(())
+      }
+    })?;
+
+    // verify if comm_W is a commitment to W
+    if U.comm_W != CE::<E>::commit(ck, &W.W) {
+      return Err(NovaError::UnSat);
+    }
+    Ok(())
+  }
+
+  /// A method to compute a commitment to the cross-term `T` given a
+  /// Relaxed R1CS instance-witness pair and an R1CS instance-witness pair
+  pub fn commit_T(
+    &self,
+    ck: &CommitmentKey<E>,
+    U1: &RelaxedR1CSInstance<E>,
+    W1: &RelaxedR1CSWitness<E>,
+    U2: &R1CSInstance<E>,
+    W2: &R1CSWitness<E>,
+  ) -> Result<(Vec<E::Scalar>, Commitment<E>), NovaError> {
+    let (AZ_1, BZ_1, CZ_1) = tracing::trace_span!("AZ_1, BZ_1, CZ_1")
+      .in_scope(|| self.multiply_witness(&W1.W, &U1.u, &U1.X))?;
+
+    let (AZ_2, BZ_2, CZ_2) = tracing::trace_span!("AZ_2, BZ_2, CZ_2")
+      .in_scope(|| self.multiply_witness(&W2.W, &E::Scalar::ONE, &U2.X))?;
+
+    let (AZ_1_circ_BZ_2, AZ_2_circ_BZ_1, u_1_cdot_CZ_2, u_2_cdot_CZ_1) =
+      tracing::trace_span!("cross terms").in_scope(|| {
+        let AZ_1_circ_BZ_2 = (0..AZ_1.len())
+          .into_par_iter()
+          .map(|i| AZ_1[i] * BZ_2[i])
+          .collect::<Vec<E::Scalar>>();
+        let AZ_2_circ_BZ_1 = (0..AZ_2.len())
+          .into_par_iter()
+          .map(|i| AZ_2[i] * BZ_1[i])
+          .collect::<Vec<E::Scalar>>();
+        let u_1_cdot_CZ_2 = (0..CZ_2.len())
+          .into_par_iter()
+          .map(|i| U1.u * CZ_2[i])
+          .collect::<Vec<E::Scalar>>();
+        let u_2_cdot_CZ_1 = (0..CZ_1.len())
+          .into_par_iter()
+          .map(|i| CZ_1[i])
+          .collect::<Vec<E::Scalar>>();
+        (AZ_1_circ_BZ_2, AZ_2_circ_BZ_1, u_1_cdot_CZ_2, u_2_cdot_CZ_1)
+      });
+
+    let T = tracing::trace_span!("T").in_scope(|| {
+      AZ_1_circ_BZ_2
+        .par_iter()
+        .zip_eq(&AZ_2_circ_BZ_1)
+        .zip_eq(&u_1_cdot_CZ_2)
+        .zip_eq(&u_2_cdot_CZ_1)
+        .map(|(((a, b), c), d)| *a + *b - *c - *d)
+        .collect::<Vec<E::Scalar>>()
+    });
+
+    let comm_T = CE::<E>::commit(ck, &T);
+
+    Ok((T, comm_T))
+  }
+
+  /// A method to compute a commitment to the cross-term `T` given a
+  /// Relaxed R1CS instance-witness pair and an R1CS instance-witness pair
+  ///
+  /// This is [`R1CSShape::commit_T`] but into a buffer.
+  pub fn commit_T_into(
+    &self,
+    ck: &CommitmentKey<E>,
+    U1: &RelaxedR1CSInstance<E>,
+    W1: &RelaxedR1CSWitness<E>,
+    U2: &R1CSInstance<E>,
+    W2: &R1CSWitness<E>,
+    T: &mut Vec<E::Scalar>,
+    ABC_Z_1: &mut R1CSResult<E>,
+    ABC_Z_2: &mut R1CSResult<E>,
+  ) -> Result<Commitment<E>, NovaError> {
+    tracing::info_span!("AZ_1, BZ_1, CZ_1")
+      .in_scope(|| self.multiply_witness_into(&W1.W, &U1.u, &U1.X, ABC_Z_1))?;
+
+    let R1CSResult {
+      AZ: AZ_1,
+      BZ: BZ_1,
+      CZ: CZ_1,
+    } = ABC_Z_1;
+
+    tracing::info_span!("AZ_2, BZ_2, CZ_2")
+      .in_scope(|| self.multiply_witness_into(&W2.W, &E::Scalar::ONE, &U2.X, ABC_Z_2))?;
+
+    let R1CSResult {
+      AZ: AZ_2,
+      BZ: BZ_2,
+      CZ: CZ_2,
+    } = ABC_Z_2;
+
+    // this doesn't allocate memory but has bad temporal cache locality -- should test to see which is faster
+    T.clear();
+    tracing::info_span!("T").in_scope(|| {
+      (0..AZ_1.len())
+        .into_par_iter()
+        .map(|i| {
+          let AZ_1_circ_BZ_2 = AZ_1[i] * BZ_2[i];
+          let AZ_2_circ_BZ_1 = AZ_2[i] * BZ_1[i];
+          let u_1_cdot_Cz_2_plus_Cz_1 = U1.u * CZ_2[i] + CZ_1[i];
+          AZ_1_circ_BZ_2 + AZ_2_circ_BZ_1 - u_1_cdot_Cz_2_plus_Cz_1
+        })
+        .collect_into_vec(T)
+    });
+
+    Ok(CE::<E>::commit(ck, T))
+  }
+
+  /// Pads the `R1CSShape` so that the number of variables is a power of two
+  /// Renumbers variables to accommodate padded variables
+  pub fn pad(&self) -> Self {
+    // equalize the number of variables and constraints
+    let m = max(self.num_vars, self.num_cons).next_power_of_two();
+
+    // check if the provided R1CSShape is already as required
+    if self.num_vars == m && self.num_cons == m {
+      return self.clone();
+    }
+
+    // check if the number of variables are as expected, then
+    // we simply set the number of constraints to the next power of two
+    if self.num_vars == m {
+      return Self {
+        num_cons: m,
+        num_vars: m,
+        num_io: self.num_io,
+        A: self.A.clone(),
+        B: self.B.clone(),
+        C: self.C.clone(),
+        digest: OnceCell::new(),
+      };
+    }
+
+    // otherwise, we need to pad the number of variables and renumber variable accesses
+    let num_vars_padded = m;
+    let num_cons_padded = m;
+
+    let apply_pad = |mut M: SparseMatrix<E::Scalar>| -> SparseMatrix<E::Scalar> {
+      M.indices.par_iter_mut().for_each(|c| {
+        if *c >= self.num_vars {
+          *c += num_vars_padded - self.num_vars
+        }
+      });
+
+      M.cols += num_vars_padded - self.num_vars;
+
+      let ex = {
+        let nnz = M.indptr.last().unwrap();
+        vec![*nnz; num_cons_padded - self.num_cons]
+      };
+      M.indptr.extend(ex);
+      M
+    };
+
+    let A_padded = apply_pad(self.A.clone());
+    let B_padded = apply_pad(self.B.clone());
+    let C_padded = apply_pad(self.C.clone());
+
+    Self {
+      num_cons: num_cons_padded,
+      num_vars: num_vars_padded,
+      num_io: self.num_io,
+      A: A_padded,
+      B: B_padded,
+      C: C_padded,
+      digest: OnceCell::new(),
+    }
+  }
+}
+
+impl<E: Engine> R1CSResult<E> {
+  /// Produces a default `R1CSResult` given an `R1CSShape`
+  pub fn default(num_cons: usize) -> Self {
+    Self {
+      AZ: vec![E::Scalar::ZERO; num_cons],
+      BZ: vec![E::Scalar::ZERO; num_cons],
+      CZ: vec![E::Scalar::ZERO; num_cons],
+    }
+  }
+}
+
+impl<E: Engine> R1CSWitness<E> {
+  /// A method to create a witness object using a vector of scalars
+  pub fn new(S: &R1CSShape<E>, W: Vec<E::Scalar>) -> Result<Self, NovaError> {
+    if S.num_vars != W.len() {
+      Err(NovaError::InvalidWitnessLength)
+    } else {
+      Ok(Self { W })
+    }
+  }
+
+  /// Commits to the witness using the supplied generators
+  pub fn commit(&self, ck: &CommitmentKey<E>) -> Commitment<E> {
+    CE::<E>::commit(ck, &self.W)
+  }
+}
+
+impl<E: Engine> R1CSInstance<E> {
+  /// A method to create an instance object using constituent elements
+  pub fn new(
+    S: &R1CSShape<E>,
+    comm_W: Commitment<E>,
+    X: Vec<E::Scalar>,
+  ) -> Result<Self, NovaError> {
+    if S.num_io != X.len() {
+      Err(NovaError::InvalidInputLength)
+    } else {
+      Ok(Self { comm_W, X })
+    }
+  }
+}
+
+impl<E: Engine> AbsorbInROTrait<E> for R1CSInstance<E> {
+  fn absorb_in_ro(&self, ro: &mut E::RO) {
+    self.comm_W.absorb_in_ro(ro);
+    for x in &self.X {
+      ro.absorb(scalar_as_base::<E>(*x));
+    }
+  }
+}
+
+impl<E: Engine> RelaxedR1CSWitness<E> {
+  /// Produces a default `RelaxedR1CSWitness` given an `R1CSShape`
+  pub fn default(S: &R1CSShape<E>) -> Self {
+    Self {
+      W: vec![E::Scalar::ZERO; S.num_vars],
+      E: vec![E::Scalar::ZERO; S.num_cons],
+    }
+  }
+
+  /// Initializes a new `RelaxedR1CSWitness` from an `R1CSWitness`
+  pub fn from_r1cs_witness(S: &R1CSShape<E>, witness: R1CSWitness<E>) -> Self {
+    Self {
+      W: witness.W,
+      E: vec![E::Scalar::ZERO; S.num_cons],
+    }
+  }
+
+  /// Commits to the witness using the supplied generators
+  pub fn commit(&self, ck: &CommitmentKey<E>) -> (Commitment<E>, Commitment<E>) {
+    (CE::<E>::commit(ck, &self.W), CE::<E>::commit(ck, &self.E))
+  }
+
+  /// Folds an incoming `R1CSWitness` into the current one
+  pub fn fold(
+    &self,
+    W2: &R1CSWitness<E>,
+    T: &[E::Scalar],
+    r: &E::Scalar,
+  ) -> Result<Self, NovaError> {
+    let (W1, E1) = (&self.W, &self.E);
+    let W2 = &W2.W;
+
+    if W1.len() != W2.len() {
+      return Err(NovaError::InvalidWitnessLength);
+    }
+
+    let W = W1
+      .par_iter()
+      .zip_eq(W2)
+      .map(|(a, b)| *a + *r * *b)
+      .collect::<Vec<E::Scalar>>();
+    let E = E1
+      .par_iter()
+      .zip_eq(T)
+      .map(|(a, b)| *a + *r * *b)
+      .collect::<Vec<E::Scalar>>();
+    Ok(Self { W, E })
+  }
+
+  /// Mutably folds an incoming `R1CSWitness` into the current one
+  pub fn fold_mut(
+    &mut self,
+    W2: &R1CSWitness<E>,
+    T: &[E::Scalar],
+    r: &E::Scalar,
+  ) -> Result<(), NovaError> {
+    if self.W.len() != W2.W.len() {
+      return Err(NovaError::InvalidWitnessLength);
+    }
+
+    self
+      .W
+      .par_iter_mut()
+      .zip_eq(&W2.W)
+      .for_each(|(a, b)| *a += *r * *b);
+    self
+      .E
+      .par_iter_mut()
+      .zip_eq(T)
+      .for_each(|(a, b)| *a += *r * *b);
+
+    Ok(())
+  }
+
+  /// Pads the provided witness to the correct length
+  pub fn pad(&self, S: &R1CSShape<E>) -> Self {
+    let mut W = self.W.clone();
+    W.extend(vec![E::Scalar::ZERO; S.num_vars - W.len()]);
+
+    let mut E = self.E.clone();
+    E.extend(vec![E::Scalar::ZERO; S.num_cons - E.len()]);
+
+    Self { W, E }
+  }
+}
+
+impl<E: Engine> RelaxedR1CSInstance<E> {
+  /// Produces a default `RelaxedR1CSInstance` given `R1CSGens` and `R1CSShape`
+  pub fn default(_ck: &CommitmentKey<E>, S: &R1CSShape<E>) -> Self {
+    let (comm_W, comm_E) = (Commitment::<E>::default(), Commitment::<E>::default());
+    Self {
+      comm_W,
+      comm_E,
+      u: E::Scalar::ZERO,
+      X: vec![E::Scalar::ZERO; S.num_io],
+    }
+  }
+
+  /// Initializes a new `RelaxedR1CSInstance` from an `R1CSInstance`
+  pub fn from_r1cs_instance(
+    _ck: &CommitmentKey<E>,
+    S: &R1CSShape<E>,
+    instance: R1CSInstance<E>,
+  ) -> Self {
+    assert_eq!(S.num_io, instance.X.len());
+
+    Self {
+      comm_W: instance.comm_W,
+      comm_E: Commitment::<E>::default(),
+      u: E::Scalar::ONE,
+      X: instance.X,
+    }
+  }
+
+  /// Initializes a new `RelaxedR1CSInstance` from an `R1CSInstance`
+  pub fn from_r1cs_instance_unchecked(comm_W: &Commitment<E>, X: &[E::Scalar]) -> Self {
+    Self {
+      comm_W: *comm_W,
+      comm_E: Commitment::<E>::default(),
+      u: E::Scalar::ONE,
+      X: X.to_vec(),
+    }
+  }
+
+  /// Folds an incoming `RelaxedR1CSInstance` into the current one
+  pub fn fold(&self, U2: &R1CSInstance<E>, comm_T: &Commitment<E>, r: &E::Scalar) -> Self {
+    let (X1, u1, comm_W_1, comm_E_1) =
+      (&self.X, &self.u, &self.comm_W.clone(), &self.comm_E.clone());
+    let (X2, comm_W_2) = (&U2.X, &U2.comm_W);
+
+    // weighted sum of X, comm_W, comm_E, and u
+    let X = X1
+      .par_iter()
+      .zip_eq(X2)
+      .map(|(a, b)| *a + *r * *b)
+      .collect::<Vec<E::Scalar>>();
+    let comm_W = *comm_W_1 + *comm_W_2 * *r;
+    let comm_E = *comm_E_1 + *comm_T * *r;
+    let u = *u1 + *r;
+
+    Self {
+      comm_W,
+      comm_E,
+      X,
+      u,
+    }
+  }
+
+  /// Mutably folds an incoming `RelaxedR1CSInstance` into the current one
+  pub fn fold_mut(&mut self, U2: &R1CSInstance<E>, comm_T: &Commitment<E>, r: &E::Scalar) {
+    let (X2, comm_W_2) = (&U2.X, &U2.comm_W);
+
+    // weighted sum of X, comm_W, comm_E, and u
+    self.X.par_iter_mut().zip_eq(X2).for_each(|(a, b)| {
+      *a += *r * *b;
+    });
+    self.comm_W = self.comm_W + *comm_W_2 * *r;
+    self.comm_E = self.comm_E + *comm_T * *r;
+    self.u += *r;
+  }
+}
+
+impl<E: Engine> TranscriptReprTrait<E::GE> for RelaxedR1CSInstance<E> {
+  fn to_transcript_bytes(&self) -> Vec<u8> {
+    [
+      self.comm_W.to_transcript_bytes(),
+      self.comm_E.to_transcript_bytes(),
+      self.u.to_transcript_bytes(),
+      self.X.as_slice().to_transcript_bytes(),
+    ]
+    .concat()
+  }
+}
+
+impl<E: Engine> AbsorbInROTrait<E> for RelaxedR1CSInstance<E> {
+  fn absorb_in_ro(&self, ro: &mut E::RO) {
+    self.comm_W.absorb_in_ro(ro);
+    self.comm_E.absorb_in_ro(ro);
+    ro.absorb(scalar_as_base::<E>(self.u));
+
+    // absorb each element of self.X in bignum format
+    for x in &self.X {
+      let limbs: Vec<E::Scalar> = nat_to_limbs(&f_to_nat(x), BN_LIMB_WIDTH, BN_N_LIMBS).unwrap();
+      for limb in limbs {
+        ro.absorb(scalar_as_base::<E>(limb));
+      }
+    }
+  }
+}
+
+/// Empty buffer for `commit_T_into`
+pub fn default_T<E: Engine>(num_cons: usize) -> Vec<E::Scalar> {
+  Vec::with_capacity(num_cons)
+}
+
+#[cfg(test)]
+mod tests {
+  use ff::Field;
+  use rand_chacha::ChaCha20Rng;
+  use rand_core::SeedableRng;
+
+  use super::*;
+  use crate::{
+    provider::{Bn256Engine, PallasEngine, Secp256k1Engine},
+    r1cs::sparse::SparseMatrix,
+    traits::Engine,
+  };
+
+  fn tiny_r1cs<E: Engine>(num_vars: usize) -> R1CSShape<E> {
+    let one = <E::Scalar as Field>::ONE;
+    let (num_cons, num_vars, num_io, A, B, C) = {
+      let num_cons = 4;
+      let num_io = 2;
+
+      // Consider a cubic equation: `x^3 + x + 5 = y`, where `x` and `y` are respectively the input and output.
+      // The R1CS for this problem consists of the following constraints:
+      // `I0 * I0 - Z0 = 0`
+      // `Z0 * I0 - Z1 = 0`
+      // `(Z1 + I0) * 1 - Z2 = 0`
+      // `(Z2 + 5) * 1 - I1 = 0`
+
+      // Relaxed R1CS is a set of three sparse matrices (A B C), where there is a row for every
+      // constraint and a column for every entry in z = (vars, u, inputs)
+      // An R1CS instance is satisfiable iff:
+      // Az \circ Bz = u \cdot Cz + E, where z = (vars, 1, inputs)
+      let mut A: Vec<(usize, usize, E::Scalar)> = Vec::new();
+      let mut B: Vec<(usize, usize, E::Scalar)> = Vec::new();
+      let mut C: Vec<(usize, usize, E::Scalar)> = Vec::new();
+
+      // constraint 0 entries in (A,B,C)
+      // `I0 * I0 - Z0 = 0`
+      A.push((0, num_vars + 1, one));
+      B.push((0, num_vars + 1, one));
+      C.push((0, 0, one));
+
+      // constraint 1 entries in (A,B,C)
+      // `Z0 * I0 - Z1 = 0`
+      A.push((1, 0, one));
+      B.push((1, num_vars + 1, one));
+      C.push((1, 1, one));
+
+      // constraint 2 entries in (A,B,C)
+      // `(Z1 + I0) * 1 - Z2 = 0`
+      A.push((2, 1, one));
+      A.push((2, num_vars + 1, one));
+      B.push((2, num_vars, one));
+      C.push((2, 2, one));
+
+      // constraint 3 entries in (A,B,C)
+      // `(Z2 + 5) * 1 - I1 = 0`
+      A.push((3, 2, one));
+      A.push((3, num_vars, one + one + one + one + one));
+      B.push((3, num_vars, one));
+      C.push((3, num_vars + 2, one));
+
+      (num_cons, num_vars, num_io, A, B, C)
+    };
+
+    // create a shape object
+    let rows = num_cons;
+    let cols = num_vars + num_io + 1;
+
+    let res = R1CSShape::new(
+      num_cons,
+      num_vars,
+      num_io,
+      SparseMatrix::new(&A, rows, cols),
+      SparseMatrix::new(&B, rows, cols),
+      SparseMatrix::new(&C, rows, cols),
+    );
+    assert!(res.is_ok());
+    res.unwrap()
+  }
+
+  fn test_pad_tiny_r1cs_with<E: Engine>() {
+    let padded_r1cs = tiny_r1cs::<E>(3).pad();
+    assert!(padded_r1cs.is_regular_shape());
+
+    let expected_r1cs = tiny_r1cs::<E>(4);
+
+    assert_eq!(padded_r1cs, expected_r1cs);
+  }
+
+  #[test]
+  fn test_pad_tiny_r1cs() {
+    test_pad_tiny_r1cs_with::<PallasEngine>();
+    test_pad_tiny_r1cs_with::<Bn256Engine>();
+    test_pad_tiny_r1cs_with::<Secp256k1Engine>();
+  }
+
+  fn test_random_r1cs_with<E: Engine>() {
+    let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
+
+    let ck_size: usize = 16_384;
+    let ck = E::CE::setup(b"ipa", ck_size);
+
+    let cases = [(16, 16, 2, 16), (16, 32, 12, 8), (256, 256, 2, 1024)];
+
+    for (num_cons, num_vars, num_io, num_entries) in cases {
+      let S = R1CSShape::<E>::random(num_cons, num_vars, num_io, num_entries, &mut rng);
+      let (W, U) = S.random_witness_instance(&ck, &mut rng);
+      assert!(S.is_sat_relaxed(&ck, &U, &W).is_ok());
+    }
+  }
+
+  #[test]
+  fn test_random_r1cs() {
+    test_random_r1cs_with::<Bn256Engine>();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/r1cs/sparse.rs.html b/docs/src/arecibo/r1cs/sparse.rs.html new file mode 100644 index 000000000..73efd1010 --- /dev/null +++ b/docs/src/arecibo/r1cs/sparse.rs.html @@ -0,0 +1,671 @@ +sparse.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+
//! # Sparse Matrices
+//!
+//! This module defines a custom implementation of CSR/CSC sparse matrices.
+//! Specifically, we implement sparse matrix / dense vector multiplication
+//! to compute the `A z`, `B z`, and `C z` in Nova.
+
+use std::cmp::Ordering;
+use std::collections::BTreeSet;
+
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use ff::PrimeField;
+use itertools::Itertools as _;
+use rand_core::{CryptoRng, RngCore};
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+
+/// CSR format sparse matrix, We follow the names used by scipy.
+/// Detailed explanation here: <https://stackoverflow.com/questions/52299420/scipy-csr-matrix-understand-indptr>
+#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
+#[abomonation_bounds(where <F as PrimeField>::Repr: Abomonation)]
+pub struct SparseMatrix<F: PrimeField> {
+  #[abomonate_with(Vec<F::Repr>)]
+  /// all non-zero values in the matrix
+  pub data: Vec<F>,
+  /// column indices
+  pub indices: Vec<usize>,
+  /// row information
+  pub indptr: Vec<usize>,
+  /// number of columns
+  pub cols: usize,
+}
+
+/// [SparseMatrix]s are often large, and this helps with cloning bottlenecks
+impl<F: PrimeField> Clone for SparseMatrix<F> {
+  fn clone(&self) -> Self {
+    Self {
+      data: self.data.par_iter().cloned().collect(),
+      indices: self.indices.par_iter().cloned().collect(),
+      indptr: self.indptr.par_iter().cloned().collect(),
+      cols: self.cols,
+    }
+  }
+}
+
+impl<F: PrimeField> SparseMatrix<F> {
+  /// 0x0 empty matrix
+  pub fn empty() -> Self {
+    Self {
+      data: vec![],
+      indices: vec![],
+      indptr: vec![0],
+      cols: 0,
+    }
+  }
+
+  /// Construct from the COO representation; Vec<usize(row), usize(col), F>.
+  /// We assume that the rows are sorted during construction.
+  pub fn new(matrix: &[(usize, usize, F)], rows: usize, cols: usize) -> Self {
+    let mut new_matrix = vec![vec![]; rows];
+    for (row, col, val) in matrix {
+      new_matrix[*row].push((*col, *val));
+    }
+
+    for row in new_matrix.iter() {
+      assert!(row.windows(2).all(|w| w[0].0 < w[1].0));
+    }
+
+    let mut indptr = vec![0; rows + 1];
+    for (i, col) in new_matrix.iter().enumerate() {
+      indptr[i + 1] = indptr[i] + col.len();
+    }
+
+    let mut indices = vec![];
+    let mut data = vec![];
+    for col in new_matrix {
+      let (idx, val): (Vec<_>, Vec<_>) = col.into_iter().unzip();
+      indices.extend(idx);
+      data.extend(val);
+    }
+
+    Self {
+      data,
+      indices,
+      indptr,
+      cols,
+    }
+  }
+
+  /// Samples a new random matrix of size `rows` x `cols` with `num_entries` non-zero entries.
+  pub fn random<R: RngCore + CryptoRng>(
+    rows: usize,
+    cols: usize,
+    num_entries: usize,
+    mut rng: &mut R,
+  ) -> Self {
+    assert!(num_entries <= rows * cols);
+
+    let mut indices = BTreeSet::<(usize, usize)>::new();
+    while indices.len() < num_entries {
+      let row = rng.next_u32() as usize % rows;
+      let col = rng.next_u32() as usize % cols;
+      indices.insert((row, col));
+    }
+
+    let matrix = indices
+      .into_iter()
+      .map(|(row, col)| (row, col, F::random(&mut rng)))
+      .collect::<Vec<_>>();
+
+    Self::new(&matrix, rows, cols)
+  }
+
+  /// Retrieves the data for row slice [i..j] from `ptrs`.
+  /// We assume that `ptrs` is indexed from `indptrs` and do not check if the
+  /// returned slice is actually a valid row.
+  pub fn get_row_unchecked(&self, ptrs: &[usize; 2]) -> impl Iterator<Item = (&F, &usize)> {
+    self.data[ptrs[0]..ptrs[1]]
+      .iter()
+      .zip_eq(&self.indices[ptrs[0]..ptrs[1]])
+  }
+
+  /// Multiply by a dense vector; uses rayon to parallelize.
+  pub fn multiply_vec(&self, vector: &[F]) -> Vec<F> {
+    assert_eq!(self.cols, vector.len(), "invalid shape");
+
+    self.multiply_vec_unchecked(vector)
+  }
+
+  /// Multiply by a dense vector; uses rayon to parallelize.
+  /// This does not check that the shape of the matrix/vector are compatible.
+  #[tracing::instrument(
+    skip_all,
+    level = "trace",
+    name = "SparseMatrix::multiply_vec_unchecked"
+  )]
+  pub fn multiply_vec_unchecked(&self, vector: &[F]) -> Vec<F> {
+    self
+      .indptr
+      .par_windows(2)
+      .map(|ptrs| {
+        self
+          .get_row_unchecked(ptrs.try_into().unwrap())
+          .map(|(val, col_idx)| *val * vector[*col_idx])
+          .sum()
+      })
+      .collect()
+  }
+
+  /// Multiply by a witness representing a dense vector; uses rayon to parallelize.
+  pub fn multiply_witness(&self, W: &[F], u: &F, X: &[F]) -> Vec<F> {
+    assert_eq!(self.cols, W.len() + X.len() + 1, "invalid shape");
+
+    self.multiply_witness_unchecked(W, u, X)
+  }
+
+  /// Multiply by a witness representing a dense vector; uses rayon to parallelize.
+  /// This does not check that the shape of the matrix/vector are compatible.
+  #[tracing::instrument(
+    skip_all,
+    level = "trace",
+    name = "SparseMatrix::multiply_vec_unchecked"
+  )]
+  pub fn multiply_witness_unchecked(&self, W: &[F], u: &F, X: &[F]) -> Vec<F> {
+    // preallocate the result vector
+    let mut sink = Vec::with_capacity(self.indptr.len() - 1);
+    self.multiply_witness_into_unchecked(W, u, X, &mut sink);
+    sink
+  }
+
+  /// Multiply by a witness representing a dense vector; uses rayon to parallelize.
+  pub fn multiply_witness_into(&self, W: &[F], u: &F, X: &[F], sink: &mut Vec<F>) {
+    assert_eq!(self.cols, W.len() + X.len() + 1, "invalid shape");
+
+    self.multiply_witness_into_unchecked(W, u, X, sink);
+  }
+
+  /// Multiply by a witness representing a dense vector; uses rayon to parallelize.
+  /// This does not check that the shape of the matrix/vector are compatible.
+  pub fn multiply_witness_into_unchecked(&self, W: &[F], u: &F, X: &[F], sink: &mut Vec<F>) {
+    let num_vars = W.len();
+    self
+      .indptr
+      .par_windows(2)
+      .map(|ptrs| {
+        self
+          .get_row_unchecked(ptrs.try_into().unwrap())
+          .fold(F::ZERO, |acc, (val, col_idx)| {
+            let val = match col_idx.cmp(&num_vars) {
+              Ordering::Less => *val * W[*col_idx],
+              Ordering::Equal => *val * *u,
+              Ordering::Greater => *val * X[*col_idx - num_vars - 1],
+            };
+            acc + val
+          })
+      })
+      .collect_into_vec(sink);
+  }
+
+  /// number of non-zero entries
+  pub fn len(&self) -> usize {
+    *self.indptr.last().unwrap()
+  }
+
+  /// empty matrix
+  pub fn is_empty(&self) -> bool {
+    self.len() == 0
+  }
+
+  /// returns a custom iterator
+  pub fn iter(&self) -> Iter<'_, F> {
+    let mut row = 0;
+    while self.indptr[row + 1] == 0 {
+      row += 1;
+    }
+    Iter {
+      matrix: self,
+      row,
+      i: 0,
+      nnz: *self.indptr.last().unwrap(),
+    }
+  }
+}
+
+/// Iterator for sparse matrix
+pub struct Iter<'a, F: PrimeField> {
+  matrix: &'a SparseMatrix<F>,
+  row: usize,
+  i: usize,
+  nnz: usize,
+}
+
+impl<'a, F: PrimeField> Iterator for Iter<'a, F> {
+  type Item = (usize, usize, F);
+
+  fn next(&mut self) -> Option<Self::Item> {
+    // are we at the end?
+    if self.i == self.nnz {
+      return None;
+    }
+
+    // compute current item
+    let curr_item = (
+      self.row,
+      self.matrix.indices[self.i],
+      self.matrix.data[self.i],
+    );
+
+    // advance the iterator
+    self.i += 1;
+    // edge case at the end
+    if self.i == self.nnz {
+      return Some(curr_item);
+    }
+    // if `i` has moved to next row
+    while self.i >= self.matrix.indptr[self.row + 1] {
+      self.row += 1;
+    }
+
+    Some(curr_item)
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::SparseMatrix;
+  #[cfg(not(target_arch = "wasm32"))]
+  use crate::r1cs::util::FWrap;
+  use crate::{
+    provider::PallasEngine,
+    traits::{Engine, Group},
+  };
+  #[cfg(not(target_arch = "wasm32"))]
+  use proptest::{
+    prelude::*,
+    strategy::{BoxedStrategy, Just, Strategy},
+  };
+
+  type G = <PallasEngine as Engine>::GE;
+  type Fr = <G as Group>::Scalar;
+
+  #[test]
+  fn test_matrix_creation() {
+    let matrix_data = vec![
+      (0, 1, Fr::from(2)),
+      (1, 2, Fr::from(3)),
+      (2, 0, Fr::from(4)),
+    ];
+    let sparse_matrix = SparseMatrix::<Fr>::new(&matrix_data, 3, 3);
+
+    assert_eq!(
+      sparse_matrix.data,
+      vec![Fr::from(2), Fr::from(3), Fr::from(4)]
+    );
+    assert_eq!(sparse_matrix.indices, vec![1, 2, 0]);
+    assert_eq!(sparse_matrix.indptr, vec![0, 1, 2, 3]);
+  }
+
+  #[test]
+  fn test_matrix_vector_multiplication() {
+    let matrix_data = vec![
+      (0, 1, Fr::from(2)),
+      (0, 2, Fr::from(7)),
+      (1, 2, Fr::from(3)),
+      (2, 0, Fr::from(4)),
+    ];
+    let sparse_matrix = SparseMatrix::<Fr>::new(&matrix_data, 3, 3);
+    let vector = vec![Fr::from(1), Fr::from(2), Fr::from(3)];
+
+    let result = sparse_matrix.multiply_vec(&vector);
+
+    assert_eq!(result, vec![Fr::from(25), Fr::from(9), Fr::from(4)]);
+  }
+
+  #[cfg(not(target_arch = "wasm32"))]
+  fn coo_strategy() -> BoxedStrategy<Vec<(usize, usize, FWrap<Fr>)>> {
+    let coo_strategy = any::<FWrap<Fr>>().prop_flat_map(|f| (0usize..100, 0usize..100, Just(f)));
+    proptest::collection::vec(coo_strategy, 10).boxed()
+  }
+
+  #[cfg(not(target_arch = "wasm32"))]
+  proptest! {
+      #[test]
+      fn test_matrix_iter(mut coo_matrix in coo_strategy()) {
+        // process the randomly generated coo matrix
+        coo_matrix.sort_by_key(|(row, col, _val)| (*row, *col));
+        coo_matrix.dedup_by_key(|(row, col, _val)| (*row, *col));
+        let coo_matrix = coo_matrix.into_iter().map(|(row, col, val)| { (row, col, val.0) }).collect::<Vec<_>>();
+
+        let matrix = SparseMatrix::new(&coo_matrix, 100, 100);
+
+        prop_assert_eq!(coo_matrix, matrix.iter().collect::<Vec<_>>());
+    }
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/batched.rs.html b/docs/src/arecibo/spartan/batched.rs.html new file mode 100644 index 000000000..ff3eb9984 --- /dev/null +++ b/docs/src/arecibo/spartan/batched.rs.html @@ -0,0 +1,1255 @@ +batched.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+
//! This module implements `BatchedRelaxedR1CSSNARKTrait` using Spartan that is generic over the polynomial commitment
+//! and evaluation argument (i.e., a PCS) This version of Spartan does not use preprocessing so the verifier keeps the
+//! entire description of R1CS matrices. This is essentially optimal for the verifier when using an IPA-based polynomial
+//! commitment scheme. This batched implementation batches the outer and inner sumchecks of the Spartan SNARK.
+
+use ff::Field;
+use serde::{Deserialize, Serialize};
+
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use itertools::Itertools;
+use once_cell::sync::OnceCell;
+use rayon::prelude::*;
+
+use super::{
+  compute_eval_table_sparse,
+  math::Math,
+  polys::{eq::EqPolynomial, multilinear::MultilinearPolynomial},
+  powers,
+  snark::batch_eval_prove,
+  sumcheck::SumcheckProof,
+  PolyEvalInstance, PolyEvalWitness,
+};
+
+use crate::{
+  digest::{DigestComputer, SimpleDigestible},
+  errors::NovaError,
+  r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness, SparseMatrix},
+  spartan::{
+    polys::{multilinear::SparsePolynomial, power::PowPolynomial},
+    snark::batch_eval_verify,
+  },
+  traits::{
+    evaluation::EvaluationEngineTrait,
+    snark::{BatchedRelaxedR1CSSNARKTrait, DigestHelperTrait},
+    Engine, TranscriptEngineTrait,
+  },
+  zip_with, CommitmentKey,
+};
+
+/// A succinct proof of knowledge of a witness to a batch of relaxed R1CS instances
+/// The proof is produced using Spartan's combination of the sum-check and
+/// the commitment to a vector viewed as a polynomial commitment
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct BatchedRelaxedR1CSSNARK<E: Engine, EE: EvaluationEngineTrait<E>> {
+  sc_proof_outer: SumcheckProof<E>,
+  // Claims ([Azᵢ(τᵢ)], [Bzᵢ(τᵢ)], [Czᵢ(τᵢ)])
+  claims_outer: (Vec<E::Scalar>, Vec<E::Scalar>, Vec<E::Scalar>),
+  // [Eᵢ(r_x)]
+  evals_E: Vec<E::Scalar>,
+  sc_proof_inner: SumcheckProof<E>,
+  // [Wᵢ(r_y[1..])]
+  evals_W: Vec<E::Scalar>,
+  sc_proof_batch: SumcheckProof<E>,
+  // [Wᵢ(r_z), Eᵢ(r_z)]
+  evals_batch: Vec<E::Scalar>,
+  eval_arg: EE::EvaluationArgument,
+}
+
+/// A type that represents the prover's key
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as ff::PrimeField>::Repr: Abomonation)]
+pub struct ProverKey<E: Engine, EE: EvaluationEngineTrait<E>> {
+  pk_ee: EE::ProverKey,
+  #[abomonate_with(<E::Scalar as ff::PrimeField>::Repr)]
+  vk_digest: E::Scalar, // digest of the verifier's key
+}
+
+/// A type that represents the verifier's key
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as ff::PrimeField>::Repr: Abomonation)]
+pub struct VerifierKey<E: Engine, EE: EvaluationEngineTrait<E>> {
+  vk_ee: EE::VerifierKey,
+  S: Vec<R1CSShape<E>>,
+  #[abomonation_skip]
+  #[serde(skip, default = "OnceCell::new")]
+  digest: OnceCell<E::Scalar>,
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> VerifierKey<E, EE> {
+  fn new(shapes: Vec<R1CSShape<E>>, vk_ee: EE::VerifierKey) -> Self {
+    Self {
+      vk_ee,
+      S: shapes,
+      digest: OnceCell::new(),
+    }
+  }
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> SimpleDigestible for VerifierKey<E, EE> {}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for VerifierKey<E, EE> {
+  /// Returns the digest of the verifier's key.
+  fn digest(&self) -> E::Scalar {
+    self
+      .digest
+      .get_or_try_init(|| {
+        let dc = DigestComputer::<E::Scalar, _>::new(self);
+        dc.digest()
+      })
+      .cloned()
+      .expect("Failure to retrieve digest!")
+  }
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> BatchedRelaxedR1CSSNARKTrait<E>
+  for BatchedRelaxedR1CSSNARK<E, EE>
+where
+  <E::Scalar as ff::PrimeField>::Repr: Abomonation,
+{
+  type ProverKey = ProverKey<E, EE>;
+
+  type VerifierKey = VerifierKey<E, EE>;
+
+  fn setup(
+    ck: &CommitmentKey<E>,
+    S: Vec<&R1CSShape<E>>,
+  ) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError> {
+    let (pk_ee, vk_ee) = EE::setup(ck);
+
+    let S = S.iter().map(|s| s.pad()).collect();
+
+    let vk = VerifierKey::new(S, vk_ee);
+
+    let pk = ProverKey {
+      pk_ee,
+      vk_digest: vk.digest(),
+    };
+
+    Ok((pk, vk))
+  }
+
+  fn prove(
+    ck: &CommitmentKey<E>,
+    pk: &Self::ProverKey,
+    S: Vec<&R1CSShape<E>>,
+    U: &[RelaxedR1CSInstance<E>],
+    W: &[RelaxedR1CSWitness<E>],
+  ) -> Result<Self, NovaError> {
+    let num_instances = U.len();
+    // Pad shapes and ensure their sizes are correct
+    let S = S
+      .iter()
+      .map(|s| {
+        let s = s.pad();
+        if s.is_regular_shape() {
+          Ok(s)
+        } else {
+          Err(NovaError::InternalError)
+        }
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+
+    // Pad (W,E) for each instance
+    let W = zip_with!(iter, (W, S), |w, s| w.pad(s)).collect::<Vec<RelaxedR1CSWitness<E>>>();
+
+    let mut transcript = E::TE::new(b"BatchedRelaxedR1CSSNARK");
+
+    transcript.absorb(b"vk", &pk.vk_digest);
+    if num_instances > 1 {
+      let num_instances_field = E::Scalar::from(num_instances as u64);
+      transcript.absorb(b"n", &num_instances_field);
+    }
+    for u in U.iter() {
+      transcript.absorb(b"U", u);
+    }
+
+    let (polys_W, polys_E): (Vec<_>, Vec<_>) = W.into_iter().map(|w| (w.W, w.E)).unzip();
+
+    // Append public inputs to W: Z = [W, u, X]
+    let polys_Z = zip_with!(iter, (polys_W, U), |w, u| [
+      w.clone(),
+      vec![u.u],
+      u.X.clone()
+    ]
+    .concat())
+    .collect::<Vec<Vec<_>>>();
+
+    let (num_rounds_x, num_rounds_y): (Vec<_>, Vec<_>) = S
+      .iter()
+      .map(|s| (s.num_cons.log_2(), s.num_vars.log_2() + 1))
+      .unzip();
+    let num_rounds_x_max = *num_rounds_x.iter().max().unwrap();
+    let num_rounds_y_max = *num_rounds_y.iter().max().unwrap();
+
+    // Generate tau polynomial corresponding to eq(τ, τ², τ⁴ , …)
+    // for a random challenge τ
+    let tau = transcript.squeeze(b"t")?;
+    let all_taus = PowPolynomial::squares(&tau, num_rounds_x_max);
+
+    let polys_tau = num_rounds_x
+      .iter()
+      .map(|&num_rounds_x| PowPolynomial::evals_with_powers(&all_taus, num_rounds_x))
+      .map(MultilinearPolynomial::new)
+      .collect::<Vec<_>>();
+
+    // Compute MLEs of Az, Bz, Cz, uCz + E
+    let (polys_Az, polys_Bz, polys_Cz): (Vec<_>, Vec<_>, Vec<_>) =
+      zip_with!(par_iter, (S, polys_Z), |s, poly_Z| {
+        let (poly_Az, poly_Bz, poly_Cz) = s.multiply_vec(poly_Z)?;
+        Ok((poly_Az, poly_Bz, poly_Cz))
+      })
+      .collect::<Result<Vec<_>, NovaError>>()?
+      .into_iter()
+      .multiunzip();
+
+    let polys_uCz_E = zip_with!(par_iter, (U, polys_E, polys_Cz), |u, poly_E, poly_Cz| {
+      zip_with!(par_iter, (poly_Cz, poly_E), |cz, e| u.u * cz + e).collect::<Vec<E::Scalar>>()
+    })
+    .collect::<Vec<_>>();
+
+    let comb_func_outer =
+      |poly_A_comp: &E::Scalar,
+       poly_B_comp: &E::Scalar,
+       poly_C_comp: &E::Scalar,
+       poly_D_comp: &E::Scalar|
+       -> E::Scalar { *poly_A_comp * (*poly_B_comp * *poly_C_comp - *poly_D_comp) };
+
+    // Sample challenge for random linear-combination of outer claims
+    let outer_r = transcript.squeeze(b"out_r")?;
+    let outer_r_powers = powers::<E>(&outer_r, num_instances);
+
+    // Verify outer sumcheck: Az * Bz - uCz_E for each instance
+    let (sc_proof_outer, r_x, claims_outer) = SumcheckProof::prove_cubic_with_additive_term_batch(
+      &vec![E::Scalar::ZERO; num_instances],
+      &num_rounds_x,
+      polys_tau,
+      polys_Az
+        .into_iter()
+        .map(MultilinearPolynomial::new)
+        .collect(),
+      polys_Bz
+        .into_iter()
+        .map(MultilinearPolynomial::new)
+        .collect(),
+      polys_uCz_E
+        .into_iter()
+        .map(MultilinearPolynomial::new)
+        .collect(),
+      &outer_r_powers,
+      comb_func_outer,
+      &mut transcript,
+    )?;
+
+    let r_x = num_rounds_x
+      .iter()
+      .map(|&num_rounds| r_x[(num_rounds_x_max - num_rounds)..].to_vec())
+      .collect::<Vec<_>>();
+
+    // Extract evaluations of Az, Bz from Sumcheck and Cz, E at r_x
+    let (evals_Az_Bz_Cz, evals_E): (Vec<_>, Vec<_>) = zip_with!(
+      par_iter,
+      (claims_outer[1], claims_outer[2], polys_Cz, polys_E, r_x),
+      |eval_Az, eval_Bz, poly_Cz, poly_E, r_x| {
+        let (eval_Cz, eval_E) = rayon::join(
+          || MultilinearPolynomial::evaluate_with(poly_Cz, r_x),
+          || MultilinearPolynomial::evaluate_with(poly_E, r_x),
+        );
+        ((*eval_Az, *eval_Bz, eval_Cz), eval_E)
+      }
+    )
+    .unzip();
+
+    evals_Az_Bz_Cz.iter().zip_eq(evals_E.iter()).for_each(
+      |(&(eval_Az, eval_Bz, eval_Cz), &eval_E)| {
+        transcript.absorb(
+          b"claims_outer",
+          &[eval_Az, eval_Bz, eval_Cz, eval_E].as_slice(),
+        )
+      },
+    );
+
+    let inner_r = transcript.squeeze(b"in_r")?;
+    let inner_r_square = inner_r.square();
+    let inner_r_cube = inner_r_square * inner_r;
+    let inner_r_powers = powers::<E>(&inner_r_cube, num_instances);
+
+    let claims_inner_joint = evals_Az_Bz_Cz
+      .iter()
+      .map(|(eval_Az, eval_Bz, eval_Cz)| *eval_Az + inner_r * eval_Bz + inner_r_square * eval_Cz)
+      .collect::<Vec<_>>();
+
+    let polys_ABCs = {
+      let inner = |M_evals_As: Vec<E::Scalar>,
+                   M_evals_Bs: Vec<E::Scalar>,
+                   M_evals_Cs: Vec<E::Scalar>|
+       -> Vec<E::Scalar> {
+        zip_with!(
+          into_par_iter,
+          (M_evals_As, M_evals_Bs, M_evals_Cs),
+          |eval_A, eval_B, eval_C| eval_A + inner_r * eval_B + inner_r_square * eval_C
+        )
+        .collect::<Vec<_>>()
+      };
+
+      zip_with!(par_iter, (S, r_x), |s, r_x| {
+        let evals_rx = EqPolynomial::evals_from_points(r_x);
+        let (eval_A, eval_B, eval_C) = compute_eval_table_sparse(s, &evals_rx);
+        MultilinearPolynomial::new(inner(eval_A, eval_B, eval_C))
+      })
+      .collect::<Vec<_>>()
+    };
+
+    let polys_Z = polys_Z
+      .into_iter()
+      .zip_eq(num_rounds_y.iter())
+      .map(|(mut z, &num_rounds_y)| {
+        z.resize(1 << num_rounds_y, E::Scalar::ZERO);
+        MultilinearPolynomial::new(z)
+      })
+      .collect::<Vec<_>>();
+
+    let comb_func = |poly_A_comp: &E::Scalar, poly_B_comp: &E::Scalar| -> E::Scalar {
+      *poly_A_comp * *poly_B_comp
+    };
+
+    let (sc_proof_inner, r_y, _claims_inner): (SumcheckProof<E>, Vec<E::Scalar>, (Vec<_>, Vec<_>)) =
+      SumcheckProof::prove_quad_batch(
+        &claims_inner_joint,
+        &num_rounds_y,
+        polys_ABCs,
+        polys_Z,
+        &inner_r_powers,
+        comb_func,
+        &mut transcript,
+      )?;
+
+    let r_y = num_rounds_y
+      .iter()
+      .map(|num_rounds| {
+        let (_, r_y_hi) = r_y.split_at(num_rounds_y_max - num_rounds);
+        r_y_hi
+      })
+      .collect::<Vec<_>>();
+
+    let evals_W = zip_with!(par_iter, (polys_W, r_y), |poly, r_y| {
+      MultilinearPolynomial::evaluate_with(poly, &r_y[1..])
+    })
+    .collect::<Vec<_>>();
+
+    // Create evaluation instances for W(r_y[1..]) and E(r_x)
+    let (w_vec, u_vec) = {
+      let mut w_vec = Vec::with_capacity(2 * num_instances);
+      let mut u_vec = Vec::with_capacity(2 * num_instances);
+      w_vec.extend(polys_W.into_iter().map(|poly| PolyEvalWitness { p: poly }));
+      u_vec.extend(zip_with!(iter, (evals_W, U, r_y), |eval, u, r_y| {
+        PolyEvalInstance {
+          c: u.comm_W,
+          x: r_y[1..].to_vec(),
+          e: *eval,
+        }
+      }));
+
+      w_vec.extend(polys_E.into_iter().map(|poly| PolyEvalWitness { p: poly }));
+      u_vec.extend(zip_with!(
+        (evals_E.iter(), U.iter(), r_x),
+        |eval_E, u, r_x| PolyEvalInstance {
+          c: u.comm_E,
+          x: r_x,
+          e: *eval_E,
+        }
+      ));
+      (w_vec, u_vec)
+    };
+
+    let (batched_u, batched_w, sc_proof_batch, claims_batch_left) =
+      batch_eval_prove(u_vec, w_vec, &mut transcript)?;
+
+    let eval_arg = EE::prove(
+      ck,
+      &pk.pk_ee,
+      &mut transcript,
+      &batched_u.c,
+      &batched_w.p,
+      &batched_u.x,
+      &batched_u.e,
+    )?;
+
+    let (evals_Az, evals_Bz, evals_Cz): (Vec<_>, Vec<_>, Vec<_>) =
+      evals_Az_Bz_Cz.into_iter().multiunzip();
+
+    Ok(Self {
+      sc_proof_outer,
+      claims_outer: (evals_Az, evals_Bz, evals_Cz),
+      evals_E,
+      sc_proof_inner,
+      evals_W,
+      sc_proof_batch,
+      evals_batch: claims_batch_left,
+      eval_arg,
+    })
+  }
+
+  fn verify(&self, vk: &Self::VerifierKey, U: &[RelaxedR1CSInstance<E>]) -> Result<(), NovaError> {
+    let num_instances = U.len();
+    let mut transcript = E::TE::new(b"BatchedRelaxedR1CSSNARK");
+
+    transcript.absorb(b"vk", &vk.digest());
+    if num_instances > 1 {
+      let num_instances_field = E::Scalar::from(num_instances as u64);
+      transcript.absorb(b"n", &num_instances_field);
+    }
+    for u in U.iter() {
+      transcript.absorb(b"U", u);
+    }
+
+    let num_instances = U.len();
+
+    let (num_rounds_x, num_rounds_y): (Vec<_>, Vec<_>) = vk
+      .S
+      .iter()
+      .map(|s| (s.num_cons.log_2(), s.num_vars.log_2() + 1))
+      .unzip();
+    let num_rounds_x_max = *num_rounds_x.iter().max().unwrap();
+    let num_rounds_y_max = *num_rounds_y.iter().max().unwrap();
+
+    // Define τ polynomials of the appropriate size for each instance
+    let polys_tau = {
+      let tau = transcript.squeeze(b"t")?;
+
+      num_rounds_x
+        .iter()
+        .map(|&num_rounds| PowPolynomial::new(&tau, num_rounds))
+        .collect::<Vec<_>>()
+    };
+
+    // Sample challenge for random linear-combination of outer claims
+    let outer_r = transcript.squeeze(b"out_r")?;
+    let outer_r_powers = powers::<E>(&outer_r, num_instances);
+
+    let (claim_outer_final, r_x) = self.sc_proof_outer.verify_batch(
+      &vec![E::Scalar::ZERO; num_instances],
+      &num_rounds_x,
+      &outer_r_powers,
+      3,
+      &mut transcript,
+    )?;
+
+    // Since each instance has a different number of rounds, the Sumcheck
+    // prover skips the first num_rounds_x_max - num_rounds_x rounds.
+    // The evaluation point for each instance is therefore r_x[num_rounds_x_max - num_rounds_x..]
+    let r_x = num_rounds_x
+      .iter()
+      .map(|num_rounds| r_x[(num_rounds_x_max - num_rounds)..].to_vec())
+      .collect::<Vec<_>>();
+
+    // Extract evaluations into a vector [(Azᵢ, Bzᵢ, Czᵢ, Eᵢ)]
+    // TODO: This is a multizip, simplify
+    let ABCE_evals = zip_with!(
+      iter,
+      (
+        self.evals_E,
+        self.claims_outer.0,
+        self.claims_outer.1,
+        self.claims_outer.2
+      ),
+      |eval_E, claim_Az, claim_Bz, claim_Cz| (*claim_Az, *claim_Bz, *claim_Cz, *eval_E)
+    )
+    .collect::<Vec<_>>();
+
+    // Add evaluations of Az, Bz, Cz, E to transcript
+    for (claim_Az, claim_Bz, claim_Cz, eval_E) in ABCE_evals.iter() {
+      transcript.absorb(
+        b"claims_outer",
+        &[*claim_Az, *claim_Bz, *claim_Cz, *eval_E].as_slice(),
+      )
+    }
+
+    // Evaluate τ(rₓ) for each instance
+    let evals_tau = zip_with!(iter, (polys_tau, r_x), |poly_tau, r_x| poly_tau
+      .evaluate(r_x));
+
+    // Compute expected claim for all instances ∑ᵢ rⁱ⋅τ(rₓ)⋅(Azᵢ⋅Bzᵢ − uᵢ⋅Czᵢ − Eᵢ)
+    let claim_outer_final_expected = zip_with!(
+      (
+        ABCE_evals.iter().copied(),
+        U.iter(),
+        evals_tau,
+        outer_r_powers.iter()
+      ),
+      |ABCE_eval, u, eval_tau, r| {
+        let (claim_Az, claim_Bz, claim_Cz, eval_E) = ABCE_eval;
+        *r * eval_tau * (claim_Az * claim_Bz - u.u * claim_Cz - eval_E)
+      }
+    )
+    .sum::<E::Scalar>();
+
+    if claim_outer_final != claim_outer_final_expected {
+      return Err(NovaError::InvalidSumcheckProof);
+    }
+
+    let inner_r = transcript.squeeze(b"in_r")?;
+    let inner_r_square = inner_r.square();
+    let inner_r_cube = inner_r_square * inner_r;
+    let inner_r_powers = powers::<E>(&inner_r_cube, num_instances);
+
+    // Compute inner claims Mzᵢ = (Azᵢ + r⋅Bzᵢ + r²⋅Czᵢ),
+    // which are batched by Sumcheck into one claim:  ∑ᵢ r³ⁱ⋅Mzᵢ
+    let claims_inner = ABCE_evals
+      .into_iter()
+      .map(|(claim_Az, claim_Bz, claim_Cz, _)| {
+        claim_Az + inner_r * claim_Bz + inner_r_square * claim_Cz
+      })
+      .collect::<Vec<_>>();
+
+    let (claim_inner_final, r_y) = self.sc_proof_inner.verify_batch(
+      &claims_inner,
+      &num_rounds_y,
+      &inner_r_powers,
+      2,
+      &mut transcript,
+    )?;
+    let r_y: Vec<Vec<E::Scalar>> = num_rounds_y
+      .iter()
+      .map(|num_rounds| r_y[(num_rounds_y_max - num_rounds)..].to_vec())
+      .collect();
+
+    // Compute evaluations of Zᵢ = [Wᵢ, uᵢ, Xᵢ] at r_y
+    // Zᵢ(r_y) = (1−r_y[0])⋅W(r_y[1..]) + r_y[0]⋅MLE([uᵢ, Xᵢ])(r_y[1..])
+    let evals_Z = zip_with!(iter, (self.evals_W, U, r_y), |eval_W, U, r_y| {
+      let eval_X = {
+        // constant term
+        let mut poly_X = vec![(0, U.u)];
+        //remaining inputs
+        poly_X.extend(
+          U.X
+            .iter()
+            .enumerate()
+            .map(|(i, x_i)| (i + 1, *x_i))
+            .collect::<Vec<(usize, E::Scalar)>>(),
+        );
+        SparsePolynomial::new(r_y.len() - 1, poly_X).evaluate(&r_y[1..])
+      };
+      (E::Scalar::ONE - r_y[0]) * eval_W + r_y[0] * eval_X
+    })
+    .collect::<Vec<_>>();
+
+    // compute evaluations of R1CS matrices M(r_x, r_y) = eq(r_y)ᵀ⋅M⋅eq(r_x)
+    let multi_evaluate = |M_vec: &[&SparseMatrix<E::Scalar>],
+                          r_x: &[E::Scalar],
+                          r_y: &[E::Scalar]|
+     -> Vec<E::Scalar> {
+      let evaluate_with_table =
+        // TODO(@winston-h-zhang): review
+        |M: &SparseMatrix<E::Scalar>, T_x: &[E::Scalar], T_y: &[E::Scalar]| -> E::Scalar {
+          M.indptr
+            .par_windows(2)
+            .enumerate()
+            .map(|(row_idx, ptrs)| {
+              M.get_row_unchecked(ptrs.try_into().unwrap())
+                .map(|(val, col_idx)| T_x[row_idx] * T_y[*col_idx] * val)
+                .sum::<E::Scalar>()
+            })
+            .sum()
+        };
+
+      let (T_x, T_y) = rayon::join(
+        || EqPolynomial::evals_from_points(r_x),
+        || EqPolynomial::evals_from_points(r_y),
+      );
+
+      M_vec
+        .par_iter()
+        .map(|&M_vec| evaluate_with_table(M_vec, &T_x, &T_y))
+        .collect()
+    };
+
+    // Compute inner claim ∑ᵢ r³ⁱ⋅(Aᵢ(r_x, r_y) + r⋅Bᵢ(r_x, r_y) + r²⋅Cᵢ(r_x, r_y))⋅Zᵢ(r_y)
+    let claim_inner_final_expected = zip_with!(
+      iter,
+      (vk.S, r_x, r_y, evals_Z, inner_r_powers),
+      |S, r_x, r_y, eval_Z, r_i| {
+        let evals = multi_evaluate(&[&S.A, &S.B, &S.C], r_x, r_y);
+        let eval = evals[0] + inner_r * evals[1] + inner_r_square * evals[2];
+        eval * r_i * eval_Z
+      }
+    )
+    .sum::<E::Scalar>();
+
+    if claim_inner_final != claim_inner_final_expected {
+      return Err(NovaError::InvalidSumcheckProof);
+    }
+
+    // Create evaluation instances for W(r_y[1..]) and E(r_x)
+    let u_vec = {
+      let mut u_vec = Vec::with_capacity(2 * num_instances);
+      u_vec.extend(zip_with!(iter, (self.evals_W, U, r_y), |eval, u, r_y| {
+        PolyEvalInstance {
+          c: u.comm_W,
+          x: r_y[1..].to_vec(),
+          e: *eval,
+        }
+      }));
+
+      u_vec.extend(zip_with!(iter, (self.evals_E, U, r_x), |eval, u, r_x| {
+        PolyEvalInstance {
+          c: u.comm_E,
+          x: r_x.to_vec(),
+          e: *eval,
+        }
+      }));
+      u_vec
+    };
+
+    let batched_u = batch_eval_verify(
+      u_vec,
+      &mut transcript,
+      &self.sc_proof_batch,
+      &self.evals_batch,
+    )?;
+
+    // verify
+    EE::verify(
+      &vk.vk_ee,
+      &mut transcript,
+      &batched_u.c,
+      &batched_u.x,
+      &batched_u.e,
+      &self.eval_arg,
+    )?;
+
+    Ok(())
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/batched_ppsnark.rs.html b/docs/src/arecibo/spartan/batched_ppsnark.rs.html new file mode 100644 index 000000000..cbaa14dd1 --- /dev/null +++ b/docs/src/arecibo/spartan/batched_ppsnark.rs.html @@ -0,0 +1,2727 @@ +batched_ppsnark.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+1155
+1156
+1157
+1158
+1159
+1160
+1161
+1162
+1163
+1164
+1165
+1166
+1167
+1168
+1169
+1170
+1171
+1172
+1173
+1174
+1175
+1176
+1177
+1178
+1179
+1180
+1181
+1182
+1183
+1184
+1185
+1186
+1187
+1188
+1189
+1190
+1191
+1192
+1193
+1194
+1195
+1196
+1197
+1198
+1199
+1200
+1201
+1202
+1203
+1204
+1205
+1206
+1207
+1208
+1209
+1210
+1211
+1212
+1213
+1214
+1215
+1216
+1217
+1218
+1219
+1220
+1221
+1222
+1223
+1224
+1225
+1226
+1227
+1228
+1229
+1230
+1231
+1232
+1233
+1234
+1235
+1236
+1237
+1238
+1239
+1240
+1241
+1242
+1243
+1244
+1245
+1246
+1247
+1248
+1249
+1250
+1251
+1252
+1253
+1254
+1255
+1256
+1257
+1258
+1259
+1260
+1261
+1262
+1263
+1264
+1265
+1266
+1267
+1268
+1269
+1270
+1271
+1272
+1273
+1274
+1275
+1276
+1277
+1278
+1279
+1280
+1281
+1282
+1283
+1284
+1285
+1286
+1287
+1288
+1289
+1290
+1291
+1292
+1293
+1294
+1295
+1296
+1297
+1298
+1299
+1300
+1301
+1302
+1303
+1304
+1305
+1306
+1307
+1308
+1309
+1310
+1311
+1312
+1313
+1314
+1315
+1316
+1317
+1318
+1319
+1320
+1321
+1322
+1323
+1324
+1325
+1326
+1327
+1328
+1329
+1330
+1331
+1332
+1333
+1334
+1335
+1336
+1337
+1338
+1339
+1340
+1341
+1342
+1343
+1344
+1345
+1346
+1347
+1348
+1349
+1350
+1351
+1352
+1353
+1354
+1355
+1356
+1357
+1358
+1359
+1360
+1361
+1362
+1363
+
//! batched pp snark
+//!
+//!
+
+use crate::{
+  digest::{DigestComputer, SimpleDigestible},
+  errors::NovaError,
+  r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness},
+  spartan::{
+    math::Math,
+    polys::{
+      eq::EqPolynomial,
+      identity::IdentityPolynomial,
+      masked_eq::MaskedEqPolynomial,
+      multilinear::MultilinearPolynomial,
+      multilinear::SparsePolynomial,
+      power::PowPolynomial,
+      univariate::{CompressedUniPoly, UniPoly},
+    },
+    powers,
+    ppsnark::{R1CSShapeSparkCommitment, R1CSShapeSparkRepr},
+    sumcheck::engine::{
+      InnerSumcheckInstance, MemorySumcheckInstance, OuterSumcheckInstance, SumcheckEngine,
+      WitnessBoundSumcheck,
+    },
+    sumcheck::SumcheckProof,
+    PolyEvalInstance, PolyEvalWitness,
+  },
+  traits::{
+    commitment::{CommitmentEngineTrait, CommitmentTrait, Len},
+    evaluation::EvaluationEngineTrait,
+    snark::{BatchedRelaxedR1CSSNARKTrait, DigestHelperTrait},
+    Engine, TranscriptEngineTrait,
+  },
+  zip_with, zip_with_for_each, Commitment, CommitmentKey, CompressedCommitment,
+};
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use ff::{Field, PrimeField};
+use itertools::{chain, Itertools as _};
+use once_cell::sync::*;
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+
+/// A type that represents the prover's key
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where < E::Scalar as PrimeField >::Repr: Abomonation)]
+pub struct ProverKey<E: Engine, EE: EvaluationEngineTrait<E>> {
+  pk_ee: EE::ProverKey,
+  S_repr: Vec<R1CSShapeSparkRepr<E>>,
+  S_comm: Vec<R1CSShapeSparkCommitment<E>>,
+  #[abomonate_with(<E::Scalar as PrimeField >::Repr)]
+  vk_digest: E::Scalar, // digest of verifier's key
+}
+
+/// A type that represents the verifier's key
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where < E::Scalar as PrimeField >::Repr: Abomonation)]
+pub struct VerifierKey<E: Engine, EE: EvaluationEngineTrait<E>> {
+  vk_ee: EE::VerifierKey,
+  S_comm: Vec<R1CSShapeSparkCommitment<E>>,
+  num_vars: Vec<usize>,
+  #[abomonation_skip]
+  #[serde(skip, default = "OnceCell::new")]
+  digest: OnceCell<E::Scalar>,
+}
+impl<E: Engine, EE: EvaluationEngineTrait<E>> VerifierKey<E, EE> {
+  fn new(
+    num_vars: Vec<usize>,
+    S_comm: Vec<R1CSShapeSparkCommitment<E>>,
+    vk_ee: EE::VerifierKey,
+  ) -> Self {
+    Self {
+      num_vars,
+      S_comm,
+      vk_ee,
+      digest: Default::default(),
+    }
+  }
+}
+impl<E: Engine, EE: EvaluationEngineTrait<E>> SimpleDigestible for VerifierKey<E, EE> {}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for VerifierKey<E, EE> {
+  /// Returns the digest of the verifier's key
+  fn digest(&self) -> E::Scalar {
+    self
+      .digest
+      .get_or_try_init(|| {
+        let dc = DigestComputer::new(self);
+        dc.digest()
+      })
+      .cloned()
+      .expect("Failure to retrieve digest!")
+  }
+}
+
+/// A succinct proof of knowledge of a witness to a relaxed R1CS instance
+/// The proof is produced using Spartan's combination of the sum-check and
+/// the commitment to a vector viewed as a polynomial commitment
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct BatchedRelaxedR1CSSNARK<E: Engine, EE: EvaluationEngineTrait<E>> {
+  // commitment to oracles: the first three are for Az, Bz, Cz,
+  // and the last two are for memory reads
+  comms_Az_Bz_Cz: Vec<[CompressedCommitment<E>; 3]>,
+  comms_L_row_col: Vec<[CompressedCommitment<E>; 2]>,
+  // commitments to aid the memory checks
+  // [t_plus_r_inv_row, w_plus_r_inv_row, t_plus_r_inv_col, w_plus_r_inv_col]
+  comms_mem_oracles: Vec<[CompressedCommitment<E>; 4]>,
+
+  // claims about Az, Bz, and Cz polynomials
+  evals_Az_Bz_Cz_at_tau: Vec<[E::Scalar; 3]>,
+
+  // sum-check
+  sc: SumcheckProof<E>,
+
+  // claims from the end of sum-check
+  evals_Az_Bz_Cz_W_E: Vec<[E::Scalar; 5]>,
+  evals_L_row_col: Vec<[E::Scalar; 2]>,
+  // [t_plus_r_inv_row, w_plus_r_inv_row, t_plus_r_inv_col, w_plus_r_inv_col]
+  evals_mem_oracle: Vec<[E::Scalar; 4]>,
+  // [val_A, val_B, val_C, row, col, ts_row, ts_col]
+  evals_mem_preprocessed: Vec<[E::Scalar; 7]>,
+
+  // a PCS evaluation argument
+  eval_arg: EE::EvaluationArgument,
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> BatchedRelaxedR1CSSNARKTrait<E>
+  for BatchedRelaxedR1CSSNARK<E, EE>
+where
+  <E::Scalar as PrimeField>::Repr: Abomonation,
+{
+  type ProverKey = ProverKey<E, EE>;
+  type VerifierKey = VerifierKey<E, EE>;
+
+  fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize> {
+    Box::new(|shape: &R1CSShape<E>| -> usize {
+      // the commitment key should be large enough to commit to the R1CS matrices
+      std::cmp::max(
+        shape.A.len() + shape.B.len() + shape.C.len(),
+        std::cmp::max(shape.num_cons, 2 * shape.num_vars),
+      )
+    })
+  }
+
+  fn setup(
+    ck: &CommitmentKey<E>,
+    S: Vec<&R1CSShape<E>>,
+  ) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError> {
+    for s in S.iter() {
+      // check the provided commitment key meets minimal requirements
+      if ck.length() < Self::ck_floor()(s) {
+        // return Err(NovaError::InvalidCommitmentKeyLength);
+        return Err(NovaError::InternalError);
+      }
+    }
+    let (pk_ee, vk_ee) = EE::setup(ck);
+
+    let S = S.iter().map(|s| s.pad()).collect::<Vec<_>>();
+    let S_repr = S.iter().map(R1CSShapeSparkRepr::new).collect::<Vec<_>>();
+    let S_comm = S_repr
+      .iter()
+      .map(|s_repr| s_repr.commit(ck))
+      .collect::<Vec<_>>();
+    let num_vars = S.iter().map(|s| s.num_vars).collect::<Vec<_>>();
+    let vk = VerifierKey::new(num_vars, S_comm.clone(), vk_ee);
+    let pk = ProverKey {
+      pk_ee,
+      S_repr,
+      S_comm,
+      vk_digest: vk.digest(),
+    };
+    Ok((pk, vk))
+  }
+
+  fn prove(
+    ck: &CommitmentKey<E>,
+    pk: &Self::ProverKey,
+    S: Vec<&R1CSShape<E>>,
+    U: &[RelaxedR1CSInstance<E>],
+    W: &[RelaxedR1CSWitness<E>],
+  ) -> Result<Self, NovaError> {
+    // Pad shapes so that num_vars = num_cons = Nᵢ and check the sizes are correct
+    let S = S
+      .par_iter()
+      .map(|s| {
+        let s = s.pad();
+        if s.is_regular_shape() {
+          Ok(s)
+        } else {
+          Err(NovaError::InternalError)
+        }
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+
+    // N[i] = max(|Aᵢ|+|Bᵢ|+|Cᵢ|, 2*num_varsᵢ, num_consᵢ)
+    let N = pk.S_repr.iter().map(|s| s.N).collect::<Vec<_>>();
+    assert!(N.iter().all(|&Ni| Ni.is_power_of_two()));
+
+    let num_instances = U.len();
+
+    // Pad [(Wᵢ,Eᵢ)] to the next power of 2 (not to Ni)
+    let W = zip_with!(par_iter, (W, S), |w, s| w.pad(s)).collect::<Vec<RelaxedR1CSWitness<E>>>();
+
+    // number of rounds of sum-check
+    let num_rounds_sc = N.iter().max().unwrap().log_2();
+
+    // Initialize transcript with vk || [Uᵢ]
+    let mut transcript = E::TE::new(b"BatchedRelaxedR1CSSNARK");
+    transcript.absorb(b"vk", &pk.vk_digest);
+    if num_instances > 1 {
+      let num_instances_field = E::Scalar::from(num_instances as u64);
+      transcript.absorb(b"n", &num_instances_field);
+    }
+    for u in U.iter() {
+      transcript.absorb(b"U", u);
+    }
+
+    // Append public inputs to Wᵢ: Zᵢ = [Wᵢ, uᵢ, Xᵢ]
+    let polys_Z = zip_with!(par_iter, (W, U, N), |W, U, Ni| {
+      // poly_Z will be resized later, so we preallocate the correct capacity
+      let mut poly_Z = Vec::with_capacity(*Ni);
+      poly_Z.extend(W.W.iter().chain([&U.u]).chain(U.X.iter()));
+      poly_Z
+    })
+    .collect::<Vec<Vec<E::Scalar>>>();
+
+    // Move polys_W and polys_E, as well as U.u out of U
+    let (comms_W_E, us): (Vec<_>, Vec<_>) = U.iter().map(|U| ([U.comm_W, U.comm_E], U.u)).unzip();
+    let (polys_W, polys_E): (Vec<_>, Vec<_>) = W.into_iter().map(|w| (w.W, w.E)).unzip();
+
+    // Compute [Az, Bz, Cz]
+    let mut polys_Az_Bz_Cz = zip_with!(par_iter, (polys_Z, S), |z, s| {
+      let (Az, Bz, Cz) = s.multiply_vec(z)?;
+      Ok([Az, Bz, Cz])
+    })
+    .collect::<Result<Vec<_>, NovaError>>()?;
+
+    // Commit to [Az, Bz, Cz] and add to transcript
+    let comms_Az_Bz_Cz = polys_Az_Bz_Cz
+      .par_iter()
+      .map(|[Az, Bz, Cz]| {
+        let (comm_Az, (comm_Bz, comm_Cz)) = rayon::join(
+          || E::CE::commit(ck, Az),
+          || rayon::join(|| E::CE::commit(ck, Bz), || E::CE::commit(ck, Cz)),
+        );
+        [comm_Az, comm_Bz, comm_Cz]
+      })
+      .collect::<Vec<_>>();
+    comms_Az_Bz_Cz
+      .iter()
+      .for_each(|comms| transcript.absorb(b"c", &comms.as_slice()));
+
+    // Compute eq(tau) for each instance in log2(Ni) variables
+    let tau = transcript.squeeze(b"t")?;
+    let (polys_tau, coords_tau): (Vec<_>, Vec<_>) = N
+      .iter()
+      .map(|&N_i| {
+        let log_Ni = N_i.log_2();
+        let poly = PowPolynomial::new(&tau, log_Ni);
+        let evals = poly.evals();
+        let coords = poly.coordinates();
+        (evals, coords)
+      })
+      .unzip();
+
+    // Pad [Az, Bz, Cz] to Ni
+    polys_Az_Bz_Cz
+      .par_iter_mut()
+      .zip_eq(N.par_iter())
+      .for_each(|(az_bz_cz, &Ni)| {
+        az_bz_cz
+          .par_iter_mut()
+          .for_each(|mz| mz.resize(Ni, E::Scalar::ZERO))
+      });
+
+    // Evaluate and commit to [Az(tau), Bz(tau), Cz(tau)]
+    let evals_Az_Bz_Cz_at_tau = zip_with!(
+      par_iter,
+      (polys_Az_Bz_Cz, coords_tau),
+      |ABCs, tau_coords| {
+        let [Az, Bz, Cz] = ABCs;
+        let (eval_Az, (eval_Bz, eval_Cz)) = rayon::join(
+          || MultilinearPolynomial::evaluate_with(Az, tau_coords),
+          || {
+            rayon::join(
+              || MultilinearPolynomial::evaluate_with(Bz, tau_coords),
+              || MultilinearPolynomial::evaluate_with(Cz, tau_coords),
+            )
+          },
+        );
+        [eval_Az, eval_Bz, eval_Cz]
+      }
+    )
+    .collect::<Vec<_>>();
+
+    // absorb the claimed evaluations into the transcript
+    for evals in evals_Az_Bz_Cz_at_tau.iter() {
+      transcript.absorb(b"e", &evals.as_slice());
+    }
+
+    // Pad Zᵢ, E to Nᵢ
+    let polys_Z = polys_Z
+      .into_par_iter()
+      .zip_eq(N.par_iter())
+      .map(|(mut poly_Z, &Ni)| {
+        poly_Z.resize(Ni, E::Scalar::ZERO);
+        poly_Z
+      })
+      .collect::<Vec<_>>();
+
+    // Pad both W,E to have the same size. This is inefficient for W since the second half is empty,
+    // but it makes it easier to handle the batching at the end.
+    let polys_E = polys_E
+      .into_par_iter()
+      .zip_eq(N.par_iter())
+      .map(|(mut poly_E, &Ni)| {
+        poly_E.resize(Ni, E::Scalar::ZERO);
+        poly_E
+      })
+      .collect::<Vec<_>>();
+
+    let polys_W = polys_W
+      .into_par_iter()
+      .zip_eq(N.par_iter())
+      .map(|(mut poly_W, &Ni)| {
+        poly_W.resize(Ni, E::Scalar::ZERO);
+        poly_W
+      })
+      .collect::<Vec<_>>();
+
+    // (2) send commitments to the following two oracles
+    // L_row(i) = eq(tau, row(i)) for all i in [0..Nᵢ]
+    // L_col(i) = z(col(i)) for all i in [0..Nᵢ]
+    let polys_L_row_col = zip_with!(
+      par_iter,
+      (S, N, polys_Z, polys_tau),
+      |S, Ni, poly_Z, poly_tau| {
+        let mut L_row = vec![poly_tau[0]; *Ni]; // we place mem_row[0] since resized row is appended with 0s
+        let mut L_col = vec![poly_Z[Ni - 1]; *Ni]; // we place mem_col[Ni-1] since resized col is appended with Ni-1
+
+        for (i, (val_r, val_c)) in S
+          .A
+          .iter()
+          .chain(S.B.iter())
+          .chain(S.C.iter())
+          .map(|(r, c, _)| (poly_tau[r], poly_Z[c]))
+          .enumerate()
+        {
+          L_row[i] = val_r;
+          L_col[i] = val_c;
+        }
+
+        [L_row, L_col]
+      }
+    )
+    .collect::<Vec<_>>();
+
+    let comms_L_row_col = polys_L_row_col
+      .par_iter()
+      .map(|[L_row, L_col]| {
+        let (comm_L_row, comm_L_col) =
+          rayon::join(|| E::CE::commit(ck, L_row), || E::CE::commit(ck, L_col));
+        [comm_L_row, comm_L_col]
+      })
+      .collect::<Vec<_>>();
+
+    // absorb commitments to L_row and L_col in the transcript
+    for comms in comms_L_row_col.iter() {
+      transcript.absorb(b"e", &comms.as_slice());
+    }
+
+    // For each instance, batch Mz = Az + c*Bz + c^2*Cz
+    let c = transcript.squeeze(b"c")?;
+
+    let polys_Mz: Vec<_> = polys_Az_Bz_Cz
+      .par_iter()
+      .map(|polys_Az_Bz_Cz| {
+        let poly_vec: Vec<&Vec<_>> = polys_Az_Bz_Cz.iter().collect();
+        let w = PolyEvalWitness::<E>::batch(&poly_vec[..], &c);
+        w.p
+      })
+      .collect();
+
+    let evals_Mz: Vec<_> = zip_with!(
+      iter,
+      (comms_Az_Bz_Cz, evals_Az_Bz_Cz_at_tau),
+      |comm_Az_Bz_Cz, evals_Az_Bz_Cz_at_tau| {
+        let u = PolyEvalInstance::<E>::batch(
+          comm_Az_Bz_Cz.as_slice(),
+          &[], // ignored by the function
+          evals_Az_Bz_Cz_at_tau.as_slice(),
+          &c,
+        );
+        u.e
+      }
+    )
+    .collect();
+
+    // we now need to prove three claims for each instance
+    // (outer)
+    //   0 = \sum_x poly_tau(x) * (poly_Az(x) * poly_Bz(x) - poly_uCz_E(x))
+    //   eval_Az_at_tau + c * eval_Bz_at_tau + c^2 * eval_Cz_at_tau = (Az+c*Bz+c^2*Cz)(tau)
+    // (inner)
+    //   eval_Az_at_tau + c * eval_Bz_at_tau + c^2 * eval_Cz_at_tau = \sum_y L_row(y) * (val_A(y) + c * val_B(y) + c^2 * val_C(y)) * L_col(y)
+    // (mem)
+    //   L_row(i) = eq(tau, row(i))
+    //   L_col(i) = z(col(i))
+    let outer_sc_inst = zip_with!(
+      (
+        polys_Az_Bz_Cz.par_iter(),
+        polys_E.par_iter(),
+        polys_Mz.into_par_iter(),
+        polys_tau.par_iter(),
+        evals_Mz.par_iter(),
+        us.par_iter()
+      ),
+      |poly_ABC, poly_E, poly_Mz, poly_tau, eval_Mz, u| {
+        let [poly_Az, poly_Bz, poly_Cz] = poly_ABC;
+        let poly_uCz_E = zip_with!(par_iter, (poly_Cz, poly_E), |cz, e| *u * cz + e).collect();
+        OuterSumcheckInstance::new(
+          poly_tau.clone(),
+          poly_Az.clone(),
+          poly_Bz.clone(),
+          poly_uCz_E,
+          poly_Mz, // Mz = Az + c * Bz + c^2 * Cz
+          eval_Mz, // eval_Az_at_tau + c * eval_Az_at_tau + c^2 * eval_Cz_at_tau
+        )
+      }
+    )
+    .collect::<Vec<_>>();
+
+    let inner_sc_inst = zip_with!(
+      par_iter,
+      (pk.S_repr, evals_Mz, polys_L_row_col),
+      |s_repr, eval_Mz, poly_L| {
+        let [poly_L_row, poly_L_col] = poly_L;
+        let c_square = c.square();
+        let val = zip_with!(
+          par_iter,
+          (s_repr.val_A, s_repr.val_B, s_repr.val_C),
+          |v_a, v_b, v_c| *v_a + c * *v_b + c_square * *v_c
+        )
+        .collect::<Vec<_>>();
+
+        InnerSumcheckInstance::new(
+          *eval_Mz,
+          MultilinearPolynomial::new(poly_L_row.clone()),
+          MultilinearPolynomial::new(poly_L_col.clone()),
+          MultilinearPolynomial::new(val),
+        )
+      }
+    )
+    .collect::<Vec<_>>();
+
+    // a third sum-check instance to prove the read-only memory claim
+    // we now need to prove that L_row and L_col are well-formed
+    let (mem_sc_inst, comms_mem_oracles, polys_mem_oracles) = {
+      let gamma = transcript.squeeze(b"g")?;
+      let r = transcript.squeeze(b"r")?;
+
+      // We start by computing oracles and auxiliary polynomials to help prove the claim
+      // oracles correspond to [t_plus_r_inv_row, w_plus_r_inv_row, t_plus_r_inv_col, w_plus_r_inv_col]
+      let (comms_mem_oracles, polys_mem_oracles, mem_aux) = pk
+        .S_repr
+        .iter()
+        .zip_eq(polys_tau.iter())
+        .zip_eq(polys_Z.iter())
+        .zip_eq(polys_L_row_col.iter())
+        .try_fold(
+          (Vec::new(), Vec::new(), Vec::new()),
+          |(mut comms, mut polys, mut aux), (((s_repr, poly_tau), poly_Z), [L_row, L_col])| {
+            let (comm, poly, a) = MemorySumcheckInstance::<E>::compute_oracles(
+              ck,
+              &r,
+              &gamma,
+              poly_tau,
+              &s_repr.row,
+              L_row,
+              &s_repr.ts_row,
+              poly_Z,
+              &s_repr.col,
+              L_col,
+              &s_repr.ts_col,
+            )?;
+
+            comms.push(comm);
+            polys.push(poly);
+            aux.push(a);
+
+            Ok::<_, NovaError>((comms, polys, aux))
+          },
+        )?;
+
+      // Commit to oracles
+      for comms in comms_mem_oracles.iter() {
+        transcript.absorb(b"l", &comms.as_slice());
+      }
+
+      // Sample new random variable for eq polynomial
+      let rho = transcript.squeeze(b"r")?;
+      let N_max = N.iter().max().unwrap();
+      let all_rhos = PowPolynomial::squares(&rho, N_max.log_2());
+
+      let instances = zip_with!(
+        (
+          pk.S_repr.par_iter(),
+          N.par_iter(),
+          polys_mem_oracles.par_iter(),
+          mem_aux.into_par_iter()
+        ),
+        |s_repr, Ni, polys_mem_oracles, polys_aux| {
+          MemorySumcheckInstance::<E>::new(
+            polys_mem_oracles.clone(),
+            polys_aux,
+            PowPolynomial::evals_with_powers(&all_rhos, Ni.log_2()),
+            s_repr.ts_row.clone(),
+            s_repr.ts_col.clone(),
+          )
+        }
+      )
+      .collect::<Vec<_>>();
+      (instances, comms_mem_oracles, polys_mem_oracles)
+    };
+
+    let witness_sc_inst = zip_with!(par_iter, (polys_W, S), |poly_W, S| {
+      WitnessBoundSumcheck::new(tau, poly_W.clone(), S.num_vars)
+    })
+    .collect::<Vec<_>>();
+
+    // Run batched Sumcheck for the 3 claims for all instances.
+    // Note that the polynomials for claims relating to instance i have size Ni.
+    let (sc, rand_sc, claims_outer, claims_inner, claims_mem, claims_witness) = Self::prove_helper(
+      num_rounds_sc,
+      mem_sc_inst,
+      outer_sc_inst,
+      inner_sc_inst,
+      witness_sc_inst,
+      &mut transcript,
+    )?;
+
+    let (evals_Az_Bz_Cz_W_E, evals_L_row_col, evals_mem_oracle, evals_mem_preprocessed) = {
+      let evals_Az_Bz = claims_outer
+        .into_iter()
+        .map(|claims| [claims[0][0], claims[0][1]])
+        .collect::<Vec<_>>();
+
+      let evals_L_row_col = claims_inner
+        .into_iter()
+        .map(|claims| {
+          // [L_row, L_col]
+          [claims[0][0], claims[0][1]]
+        })
+        .collect::<Vec<_>>();
+
+      let (evals_mem_oracle, evals_mem_ts): (Vec<_>, Vec<_>) = claims_mem
+        .into_iter()
+        .map(|claims| {
+          (
+            // [t_plus_r_inv_row, w_plus_r_inv_row, t_plus_r_inv_col, w_plus_r_inv_col]
+            [claims[0][0], claims[0][1], claims[1][0], claims[1][1]],
+            // [ts_row, ts_col]
+            [claims[0][2], claims[1][2]],
+          )
+        })
+        .unzip();
+
+      let evals_W = claims_witness
+        .into_iter()
+        .map(|claims| claims[0][0])
+        .collect::<Vec<_>>();
+
+      let (evals_Cz_E, evals_mem_val_row_col): (Vec<_>, Vec<_>) = zip_with!(
+        iter,
+        (polys_Az_Bz_Cz, polys_E, pk.S_repr),
+        |ABCzs, poly_E, s_repr| {
+          let [_, _, Cz] = ABCzs;
+          let log_Ni = s_repr.N.log_2();
+          let (_, rand_sc) = rand_sc.split_at(num_rounds_sc - log_Ni);
+          let rand_sc_evals = EqPolynomial::evals_from_points(rand_sc);
+          let e = [
+            Cz,
+            poly_E,
+            &s_repr.val_A,
+            &s_repr.val_B,
+            &s_repr.val_C,
+            &s_repr.row,
+            &s_repr.col,
+          ]
+          .into_iter()
+          .map(|p| {
+            // Manually compute evaluation to avoid recomputing rand_sc_evals
+            zip_with!(par_iter, (p, rand_sc_evals), |p, eq| *p * eq).sum()
+          })
+          .collect::<Vec<E::Scalar>>();
+          ([e[0], e[1]], [e[2], e[3], e[4], e[5], e[6]])
+        }
+      )
+      .unzip();
+
+      let evals_Az_Bz_Cz_W_E = zip_with!(
+        (evals_Az_Bz.into_iter(), evals_Cz_E.into_iter(), evals_W),
+        |Az_Bz, Cz_E, W| {
+          let [Az, Bz] = Az_Bz;
+          let [Cz, E] = Cz_E;
+          [Az, Bz, Cz, W, E]
+        }
+      )
+      .collect::<Vec<_>>();
+
+      // [val_A, val_B, val_C, row, col, ts_row, ts_col]
+      let evals_mem_preprocessed = zip_with!(
+        (evals_mem_val_row_col.into_iter(), evals_mem_ts),
+        |eval_mem_val_row_col, eval_mem_ts| {
+          let [val_A, val_B, val_C, row, col] = eval_mem_val_row_col;
+          let [ts_row, ts_col] = eval_mem_ts;
+          [val_A, val_B, val_C, row, col, ts_row, ts_col]
+        }
+      )
+      .collect::<Vec<_>>();
+      (
+        evals_Az_Bz_Cz_W_E,
+        evals_L_row_col,
+        evals_mem_oracle,
+        evals_mem_preprocessed,
+      )
+    };
+
+    let evals_vec = zip_with!(
+      iter,
+      (
+        evals_Az_Bz_Cz_W_E,
+        evals_L_row_col,
+        evals_mem_oracle,
+        evals_mem_preprocessed
+      ),
+      |Az_Bz_Cz_W_E, L_row_col, mem_oracles, mem_preprocessed| {
+        chain![Az_Bz_Cz_W_E, L_row_col, mem_oracles, mem_preprocessed]
+          .cloned()
+          .collect::<Vec<_>>()
+      }
+    )
+    .collect::<Vec<_>>();
+
+    let comms_vec = zip_with!(
+      iter,
+      (
+        comms_Az_Bz_Cz,
+        comms_W_E,
+        comms_L_row_col,
+        comms_mem_oracles,
+        pk.S_comm
+      ),
+      |Az_Bz_Cz, comms_W_E, L_row_col, mem_oracles, S_comm| {
+        chain![
+          Az_Bz_Cz,
+          comms_W_E,
+          L_row_col,
+          mem_oracles,
+          [
+            &S_comm.comm_val_A,
+            &S_comm.comm_val_B,
+            &S_comm.comm_val_C,
+            &S_comm.comm_row,
+            &S_comm.comm_col,
+            &S_comm.comm_ts_row,
+            &S_comm.comm_ts_col,
+          ]
+        ]
+      }
+    )
+    .flatten()
+    .cloned()
+    .collect::<Vec<_>>();
+
+    let w_vec = zip_with!(
+      (
+        polys_Az_Bz_Cz.into_iter(),
+        polys_W.into_iter(),
+        polys_E.into_iter(),
+        polys_L_row_col.into_iter(),
+        polys_mem_oracles.into_iter(),
+        pk.S_repr.iter()
+      ),
+      |Az_Bz_Cz, W, E, L_row_col, mem_oracles, S_repr| {
+        chain![
+          Az_Bz_Cz,
+          [W, E],
+          L_row_col,
+          mem_oracles,
+          [
+            S_repr.val_A.clone(),
+            S_repr.val_B.clone(),
+            S_repr.val_C.clone(),
+            S_repr.row.clone(),
+            S_repr.col.clone(),
+            S_repr.ts_row.clone(),
+            S_repr.ts_col.clone(),
+          ]
+        ]
+      }
+    )
+    .flatten()
+    .map(|p| PolyEvalWitness::<E> { p })
+    .collect::<Vec<_>>();
+
+    for evals in evals_vec.iter() {
+      transcript.absorb(b"e", &evals.as_slice()); // comm_vec is already in the transcript
+    }
+    let evals_vec = evals_vec.into_iter().flatten().collect::<Vec<_>>();
+
+    let c = transcript.squeeze(b"c")?;
+
+    // Compute number of variables for each polynomial
+    let num_vars_u = w_vec.iter().map(|w| w.p.len().log_2()).collect::<Vec<_>>();
+    let u_batch =
+      PolyEvalInstance::<E>::batch_diff_size(&comms_vec, &evals_vec, &num_vars_u, rand_sc, c);
+    let w_batch = PolyEvalWitness::<E>::batch_diff_size(w_vec, c);
+
+    let eval_arg = EE::prove(
+      ck,
+      &pk.pk_ee,
+      &mut transcript,
+      &u_batch.c,
+      &w_batch.p,
+      &u_batch.x,
+      &u_batch.e,
+    )?;
+
+    let comms_Az_Bz_Cz = comms_Az_Bz_Cz
+      .into_iter()
+      .map(|comms| comms.map(|comm| comm.compress()))
+      .collect();
+    let comms_L_row_col = comms_L_row_col
+      .into_iter()
+      .map(|comms| comms.map(|comm| comm.compress()))
+      .collect();
+    let comms_mem_oracles = comms_mem_oracles
+      .into_iter()
+      .map(|comms| comms.map(|comm| comm.compress()))
+      .collect();
+
+    Ok(Self {
+      comms_Az_Bz_Cz,
+      comms_L_row_col,
+      comms_mem_oracles,
+      evals_Az_Bz_Cz_at_tau,
+      sc,
+      evals_Az_Bz_Cz_W_E,
+      evals_L_row_col,
+      evals_mem_oracle,
+      evals_mem_preprocessed,
+      eval_arg,
+    })
+  }
+
+  fn verify(&self, vk: &Self::VerifierKey, U: &[RelaxedR1CSInstance<E>]) -> Result<(), NovaError> {
+    let num_instances = U.len();
+    let num_claims_per_instance = 10;
+
+    // number of rounds of sum-check
+    let num_rounds = vk.S_comm.iter().map(|s| s.N.log_2()).collect::<Vec<_>>();
+    let num_rounds_max = *num_rounds.iter().max().unwrap();
+
+    let mut transcript = E::TE::new(b"BatchedRelaxedR1CSSNARK");
+
+    transcript.absorb(b"vk", &vk.digest());
+    if num_instances > 1 {
+      let num_instances_field = E::Scalar::from(num_instances as u64);
+      transcript.absorb(b"n", &num_instances_field);
+    }
+    for u in U.iter() {
+      transcript.absorb(b"U", u);
+    }
+
+    // Decompress commitments
+    let comms_Az_Bz_Cz = self
+      .comms_Az_Bz_Cz
+      .iter()
+      .map(|comms| {
+        comms
+          .iter()
+          .map(Commitment::<E>::decompress)
+          .collect::<Result<Vec<_>, _>>()
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+
+    let comms_L_row_col = self
+      .comms_L_row_col
+      .iter()
+      .map(|comms| {
+        comms
+          .iter()
+          .map(Commitment::<E>::decompress)
+          .collect::<Result<Vec<_>, _>>()
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+
+    let comms_mem_oracles = self
+      .comms_mem_oracles
+      .iter()
+      .map(|comms| {
+        comms
+          .iter()
+          .map(Commitment::<E>::decompress)
+          .collect::<Result<Vec<_>, _>>()
+      })
+      .collect::<Result<Vec<_>, _>>()?;
+
+    // Add commitments [Az, Bz, Cz] to the transcript
+    comms_Az_Bz_Cz
+      .iter()
+      .for_each(|comms| transcript.absorb(b"c", &comms.as_slice()));
+
+    let tau = transcript.squeeze(b"t")?;
+    let tau_coords = PowPolynomial::new(&tau, num_rounds_max).coordinates();
+
+    // absorb the claimed evaluations into the transcript
+    self.evals_Az_Bz_Cz_at_tau.iter().for_each(|evals| {
+      transcript.absorb(b"e", &evals.as_slice());
+    });
+
+    // absorb commitments to L_row and L_col in the transcript
+    for comms in comms_L_row_col.iter() {
+      transcript.absorb(b"e", &comms.as_slice());
+    }
+
+    // Batch at tau for each instance
+    let c = transcript.squeeze(b"c")?;
+
+    // Compute eval_Mz = eval_Az_at_tau + c * eval_Bz_at_tau + c^2 * eval_Cz_at_tau
+    let evals_Mz: Vec<_> = zip_with!(
+      iter,
+      (comms_Az_Bz_Cz, self.evals_Az_Bz_Cz_at_tau),
+      |comm_Az_Bz_Cz, evals_Az_Bz_Cz_at_tau| {
+        let u = PolyEvalInstance::<E>::batch(
+          comm_Az_Bz_Cz.as_slice(),
+          &tau_coords,
+          evals_Az_Bz_Cz_at_tau.as_slice(),
+          &c,
+        );
+        u.e
+      }
+    )
+    .collect();
+
+    let gamma = transcript.squeeze(b"g")?;
+    let r = transcript.squeeze(b"r")?;
+
+    for comms in comms_mem_oracles.iter() {
+      transcript.absorb(b"l", &comms.as_slice());
+    }
+
+    let rho = transcript.squeeze(b"r")?;
+
+    let s = transcript.squeeze(b"r")?;
+    let s_powers = powers::<E>(&s, num_instances * num_claims_per_instance);
+
+    let (claim_sc_final, rand_sc) = {
+      // Gather all claims into a single vector
+      let claims = evals_Mz
+        .iter()
+        .flat_map(|&eval_Mz| {
+          let mut claims = vec![E::Scalar::ZERO; num_claims_per_instance];
+          claims[7] = eval_Mz;
+          claims[8] = eval_Mz;
+          claims.into_iter()
+        })
+        .collect::<Vec<_>>();
+
+      // Number of rounds for each claim
+      let num_rounds_by_claim = num_rounds
+        .iter()
+        .flat_map(|num_rounds_i| vec![*num_rounds_i; num_claims_per_instance].into_iter())
+        .collect::<Vec<_>>();
+
+      self
+        .sc
+        .verify_batch(&claims, &num_rounds_by_claim, &s_powers, 3, &mut transcript)?
+    };
+
+    // Truncated sumcheck randomness for each instance
+    let rand_sc_i = num_rounds
+      .iter()
+      .map(|num_rounds| rand_sc[(num_rounds_max - num_rounds)..].to_vec())
+      .collect::<Vec<_>>();
+
+    let claim_sc_final_expected = zip_with!(
+      (
+        vk.num_vars.iter(),
+        rand_sc_i.iter(),
+        U.iter(),
+        self.evals_Az_Bz_Cz_W_E.iter().cloned(),
+        self.evals_L_row_col.iter().cloned(),
+        self.evals_mem_oracle.iter().cloned(),
+        self.evals_mem_preprocessed.iter().cloned()
+      ),
+      |num_vars,
+       rand_sc,
+       U,
+       evals_Az_Bz_Cz_W_E,
+       evals_L_row_col,
+       eval_mem_oracle,
+       eval_mem_preprocessed| {
+        let [Az, Bz, Cz, W, E] = evals_Az_Bz_Cz_W_E;
+        let [L_row, L_col] = evals_L_row_col;
+        let [t_plus_r_inv_row, w_plus_r_inv_row, t_plus_r_inv_col, w_plus_r_inv_col] =
+          eval_mem_oracle;
+        let [val_A, val_B, val_C, row, col, ts_row, ts_col] = eval_mem_preprocessed;
+
+        let num_rounds_i = rand_sc.len();
+        let num_vars_log = num_vars.log_2();
+
+        let eq_rho = {
+          let rho_coords = PowPolynomial::new(&rho, num_rounds_i).coordinates();
+          EqPolynomial::new(rho_coords).evaluate(rand_sc)
+        };
+
+        let (eq_tau, eq_masked_tau) = {
+          let tau_coords = PowPolynomial::new(&tau, num_rounds_i).coordinates();
+          let eq_tau = EqPolynomial::new(tau_coords);
+
+          let eq_tau_at_rand = eq_tau.evaluate(rand_sc);
+          let eq_masked_tau = MaskedEqPolynomial::new(&eq_tau, num_vars_log).evaluate(rand_sc);
+
+          (eq_tau_at_rand, eq_masked_tau)
+        };
+
+        // Evaluate identity polynomial
+        let id = IdentityPolynomial::new(num_rounds_i).evaluate(rand_sc);
+
+        let Z = {
+          // rand_sc was padded, so we now remove the padding
+          let (factor, rand_sc_unpad) = {
+            let l = num_rounds_i - (num_vars_log + 1);
+
+            let (rand_sc_lo, rand_sc_hi) = rand_sc.split_at(l);
+
+            let factor = rand_sc_lo
+              .iter()
+              .fold(E::Scalar::ONE, |acc, r_p| acc * (E::Scalar::ONE - r_p));
+
+            (factor, rand_sc_hi)
+          };
+
+          let X = {
+            // constant term
+            let mut poly_X = vec![(0, U.u)];
+            //remaining inputs
+            poly_X.extend(
+              (0..U.X.len())
+                .map(|i| (i + 1, U.X[i]))
+                .collect::<Vec<(usize, E::Scalar)>>(),
+            );
+            SparsePolynomial::new(num_vars_log, poly_X).evaluate(&rand_sc_unpad[1..])
+          };
+
+          // W was evaluated as if it was padded to logNi variables,
+          // so we don't multiply it by (1-rand_sc_unpad[0])
+          W + factor * rand_sc_unpad[0] * X
+        };
+
+        let t_plus_r_row = {
+          let addr_row = id;
+          let val_row = eq_tau;
+          let t = addr_row + gamma * val_row;
+          t + r
+        };
+
+        let w_plus_r_row = {
+          let addr_row = row;
+          let val_row = L_row;
+          let w = addr_row + gamma * val_row;
+          w + r
+        };
+
+        let t_plus_r_col = {
+          let addr_col = id;
+          let val_col = Z;
+          let t = addr_col + gamma * val_col;
+          t + r
+        };
+
+        let w_plus_r_col = {
+          let addr_col = col;
+          let val_col = L_col;
+          let w = addr_col + gamma * val_col;
+          w + r
+        };
+
+        let claims_mem = [
+          t_plus_r_inv_row - w_plus_r_inv_row,
+          t_plus_r_inv_col - w_plus_r_inv_col,
+          eq_rho * (t_plus_r_inv_row * t_plus_r_row - ts_row),
+          eq_rho * (w_plus_r_inv_row * w_plus_r_row - E::Scalar::ONE),
+          eq_rho * (t_plus_r_inv_col * t_plus_r_col - ts_col),
+          eq_rho * (w_plus_r_inv_col * w_plus_r_col - E::Scalar::ONE),
+        ];
+
+        let claims_outer = [
+          eq_tau * (Az * Bz - U.u * Cz - E),
+          eq_tau * (Az + c * Bz + c * c * Cz),
+        ];
+        let claims_inner = [L_row * L_col * (val_A + c * val_B + c * c * val_C)];
+
+        let claims_witness = [eq_masked_tau * W];
+
+        chain![claims_mem, claims_outer, claims_inner, claims_witness]
+      }
+    )
+    .flatten()
+    .zip_eq(s_powers)
+    .fold(E::Scalar::ZERO, |acc, (claim, s)| acc + s * claim);
+
+    if claim_sc_final_expected != claim_sc_final {
+      return Err(NovaError::InvalidSumcheckProof);
+    }
+
+    let evals_vec = zip_with!(
+      iter,
+      (
+        self.evals_Az_Bz_Cz_W_E,
+        self.evals_L_row_col,
+        self.evals_mem_oracle,
+        self.evals_mem_preprocessed
+      ),
+      |Az_Bz_Cz_W_E, L_row_col, mem_oracles, mem_preprocessed| {
+        chain![Az_Bz_Cz_W_E, L_row_col, mem_oracles, mem_preprocessed]
+          .cloned()
+          .collect::<Vec<_>>()
+      }
+    )
+    .collect::<Vec<_>>();
+
+    // Add all Sumcheck evaluations to the transcript
+    for evals in evals_vec.iter() {
+      transcript.absorb(b"e", &evals.as_slice()); // comm_vec is already in the transcript
+    }
+
+    let c = transcript.squeeze(b"c")?;
+
+    // Compute batched polynomial evaluation instance at rand_sc
+    let u = {
+      let num_evals = evals_vec[0].len();
+
+      let evals_vec = evals_vec.into_iter().flatten().collect::<Vec<_>>();
+
+      let num_vars = num_rounds
+        .iter()
+        .flat_map(|num_rounds| vec![*num_rounds; num_evals].into_iter())
+        .collect::<Vec<_>>();
+
+      let comms_vec = zip_with!(
+        (
+          comms_Az_Bz_Cz.into_iter(),
+          U.iter(),
+          comms_L_row_col.into_iter(),
+          comms_mem_oracles.into_iter(),
+          vk.S_comm.iter()
+        ),
+        |Az_Bz_Cz, U, L_row_col, mem_oracles, S_comm| {
+          chain![
+            Az_Bz_Cz,
+            [U.comm_W, U.comm_E],
+            L_row_col,
+            mem_oracles,
+            [
+              S_comm.comm_val_A,
+              S_comm.comm_val_B,
+              S_comm.comm_val_C,
+              S_comm.comm_row,
+              S_comm.comm_col,
+              S_comm.comm_ts_row,
+              S_comm.comm_ts_col,
+            ]
+          ]
+        }
+      )
+      .flatten()
+      .collect::<Vec<_>>();
+
+      PolyEvalInstance::<E>::batch_diff_size(&comms_vec, &evals_vec, &num_vars, rand_sc, c)
+    };
+
+    // verify
+    EE::verify(&vk.vk_ee, &mut transcript, &u.c, &u.x, &u.e, &self.eval_arg)?;
+
+    Ok(())
+  }
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> BatchedRelaxedR1CSSNARK<E, EE>
+where
+  <E::Scalar as PrimeField>::Repr: Abomonation,
+{
+  /// Runs the batched Sumcheck protocol for the claims of multiple instance of possibly different sizes.
+  ///
+  /// # Details
+  ///
+  /// In order to avoid padding all polynomials to the same maximum size, we adopt the following strategy.
+  ///
+  /// Let n be the number of variables for the largest instance,
+  /// and let m be the number of variables for a shorter one.
+  /// Let P(X_{0},...,X_{m-1}) be one of the MLEs of the short instance, which has been committed to
+  /// by taking the MSM of its evaluations with the first 2^m basis points of the commitment key.
+  ///
+  /// This Sumcheck prover will interpret it as the polynomial
+  ///   P'(X_{0},...,X_{n-1}) = P(X_{n-m},...,X_{n-1}),
+  /// whose MLE evaluations over {0,1}^m is equal to 2^{n-m} repetitions of the evaluations of P.
+  ///
+  /// In order to account for these "imagined" repetitions, the initial claims for this short instances
+  /// are scaled by 2^{n-m}.
+  ///
+  /// For the first n-m rounds, the univariate polynomials relating to this shorter claim will be constant,
+  /// and equal to the initial claims, scaled by 2^{n-m-i}, where i is the round number.
+  /// By definition, P' does not depend on X_i, so binding P' to r_i has no effect on the evaluations.
+  /// The Sumcheck prover will then interpret the polynomial P' as having half as many repetitions
+  /// in the next round.
+  ///
+  /// When we get to round n-m, the Sumcheck proceeds as usual since the polynomials are the expected size
+  /// for the round.
+  ///
+  /// Note that at the end of the protocol, the prover returns the evaluation
+  ///   u' = P'(r_{0},...,r_{n-1}) = P(r_{n-m},...,r_{n-1})
+  /// However, the polynomial we actually committed to over {0,1}^n is
+  ///   P''(X_{0},...,X_{n-1}) = L_0(X_{0},...,X_{n-m-1}) * P(X_{n-m},...,X_{n-1})
+  /// The SNARK prover/verifier will need to rescale the evaluation by the first Lagrange polynomial
+  ///   u'' = L_0(r_{0},...,r_{n-m-1}) * u'
+  /// in order batch all evaluations with a single PCS call.
+  fn prove_helper<T1, T2, T3, T4>(
+    num_rounds: usize,
+    mut mem: Vec<T1>,
+    mut outer: Vec<T2>,
+    mut inner: Vec<T3>,
+    mut witness: Vec<T4>,
+    transcript: &mut E::TE,
+  ) -> Result<
+    (
+      SumcheckProof<E>,
+      Vec<E::Scalar>,
+      Vec<Vec<Vec<E::Scalar>>>,
+      Vec<Vec<Vec<E::Scalar>>>,
+      Vec<Vec<Vec<E::Scalar>>>,
+      Vec<Vec<Vec<E::Scalar>>>,
+    ),
+    NovaError,
+  >
+  where
+    T1: SumcheckEngine<E>,
+    T2: SumcheckEngine<E>,
+    T3: SumcheckEngine<E>,
+    T4: SumcheckEngine<E>,
+  {
+    // sanity checks
+    let num_instances = mem.len();
+    assert_eq!(outer.len(), num_instances);
+    assert_eq!(inner.len(), num_instances);
+    assert_eq!(witness.len(), num_instances);
+
+    for inst in mem.iter_mut() {
+      assert!(inst.size().is_power_of_two());
+    }
+    for inst in outer.iter() {
+      assert!(inst.size().is_power_of_two());
+    }
+    for inst in inner.iter() {
+      assert!(inst.size().is_power_of_two());
+    }
+    for inst in witness.iter() {
+      assert!(inst.size().is_power_of_two());
+    }
+
+    let degree = mem[0].degree();
+    assert!(mem.iter().all(|inst| inst.degree() == degree));
+    assert!(outer.iter().all(|inst| inst.degree() == degree));
+    assert!(inner.iter().all(|inst| inst.degree() == degree));
+    assert!(witness.iter().all(|inst| inst.degree() == degree));
+
+    // Collect all claims from the instances. If the instances is defined over `m` variables,
+    // which is less that the total number of rounds `n`,
+    // the individual claims σ are scaled by 2^{n-m}.
+    let claims = zip_with!(
+      iter,
+      (mem, outer, inner, witness),
+      |mem, outer, inner, witness| {
+        Self::scaled_claims(mem, num_rounds)
+          .into_iter()
+          .chain(Self::scaled_claims(outer, num_rounds))
+          .chain(Self::scaled_claims(inner, num_rounds))
+          .chain(Self::scaled_claims(witness, num_rounds))
+      }
+    )
+    .flatten()
+    .collect::<Vec<E::Scalar>>();
+
+    // Sample a challenge for the random linear combination of all scaled claims
+    let s = transcript.squeeze(b"r")?;
+    let coeffs = powers::<E>(&s, claims.len());
+
+    // At the start of each round, the running claim is equal to the random linear combination
+    // of the Sumcheck claims, evaluated over the bound polynomials.
+    // Initially, it is equal to the random linear combination of the scaled input claims.
+    let mut running_claim = zip_with!(iter, (claims, coeffs), |c_1, c_2| *c_1 * c_2).sum();
+
+    // Keep track of the verifier challenges r, and the univariate polynomials sent by the prover
+    // in each round
+    let mut r: Vec<E::Scalar> = Vec::new();
+    let mut cubic_polys: Vec<CompressedUniPoly<E::Scalar>> = Vec::new();
+
+    for i in 0..num_rounds {
+      // At the start of round i, there input polynomials are defined over at most n-i variables.
+      let remaining_variables = num_rounds - i;
+
+      // For each claim j, compute the evaluations of its univariate polynomial S_j(X_i)
+      // at X = 0, 2, 3. The polynomial is such that S_{j-1}(r_{j-1}) = S_j(0) + S_j(1).
+      // If the number of variable m of the claim is m < n-i, then the polynomial is
+      // constants and equal to the initial claim σ_j scaled by 2^{n-m-i-1}.
+      let evals = zip_with!(
+        par_iter,
+        (mem, outer, inner, witness),
+        |mem, outer, inner, witness| {
+          let ((evals_mem, evals_outer), (evals_inner, evals_witness)) = rayon::join(
+            || {
+              rayon::join(
+                || Self::get_evals(mem, remaining_variables),
+                || Self::get_evals(outer, remaining_variables),
+              )
+            },
+            || {
+              rayon::join(
+                || Self::get_evals(inner, remaining_variables),
+                || Self::get_evals(witness, remaining_variables),
+              )
+            },
+          );
+          evals_mem
+            .into_par_iter()
+            .chain(evals_outer.into_par_iter())
+            .chain(evals_inner.into_par_iter())
+            .chain(evals_witness.into_par_iter())
+        }
+      )
+      .flatten()
+      .collect::<Vec<_>>();
+
+      assert_eq!(evals.len(), claims.len());
+
+      // Random linear combination of the univariate evaluations at X_i = 0, 2, 3
+      let evals_combined_0 = (0..evals.len()).map(|i| evals[i][0] * coeffs[i]).sum();
+      let evals_combined_2 = (0..evals.len()).map(|i| evals[i][1] * coeffs[i]).sum();
+      let evals_combined_3 = (0..evals.len()).map(|i| evals[i][2] * coeffs[i]).sum();
+
+      let evals = vec![
+        evals_combined_0,
+        running_claim - evals_combined_0,
+        evals_combined_2,
+        evals_combined_3,
+      ];
+      // Coefficient representation of S(X_i)
+      let poly = UniPoly::from_evals(&evals);
+
+      // append the prover's message to the transcript
+      transcript.absorb(b"p", &poly);
+
+      // derive the verifier's challenge for the next round
+      let r_i = transcript.squeeze(b"c")?;
+      r.push(r_i);
+
+      // Bind the variable X_i of polynomials across all claims to r_i.
+      // If the claim is defined over m variables and m < n-i, then
+      // binding has no effect on the polynomial.
+      zip_with_for_each!(
+        par_iter_mut,
+        (mem, outer, inner, witness),
+        |mem, outer, inner, witness| {
+          rayon::join(
+            || {
+              rayon::join(
+                || Self::bind(mem, remaining_variables, &r_i),
+                || Self::bind(outer, remaining_variables, &r_i),
+              )
+            },
+            || {
+              rayon::join(
+                || Self::bind(inner, remaining_variables, &r_i),
+                || Self::bind(witness, remaining_variables, &r_i),
+              )
+            },
+          );
+        }
+      );
+
+      running_claim = poly.evaluate(&r_i);
+      cubic_polys.push(poly.compress());
+    }
+
+    // Collect evaluations at (r_{n-m}, ..., r_{n-1}) of polynomials over all claims,
+    // where m is the initial number of variables the individual claims are defined over.
+    let claims_outer = outer.into_iter().map(|inst| inst.final_claims()).collect();
+    let claims_inner = inner.into_iter().map(|inst| inst.final_claims()).collect();
+    let claims_mem = mem.into_iter().map(|inst| inst.final_claims()).collect();
+    let claims_witness = witness
+      .into_iter()
+      .map(|inst| inst.final_claims())
+      .collect();
+
+    Ok((
+      SumcheckProof::new(cubic_polys),
+      r,
+      claims_outer,
+      claims_inner,
+      claims_mem,
+      claims_witness,
+    ))
+  }
+
+  /// In round i, computes the evaluations at X_i = 0, 2, 3 of the univariate polynomials S(X_i)
+  /// for each claim in the instance.
+  /// Let `n` be the total number of Sumcheck rounds, and assume the instance is defined over `m` variables.
+  /// We define `remaining_variables` as n-i.
+  /// If m < n-i, then the polynomials in the instance are not defined over X_i, so the univariate
+  /// polynomial is constant and equal to 2^{n-m-i-1}*σ, where σ is the initial claim.
+  fn get_evals<T: SumcheckEngine<E>>(inst: &T, remaining_variables: usize) -> Vec<Vec<E::Scalar>> {
+    let num_instance_variables = inst.size().log_2(); // m
+    if num_instance_variables < remaining_variables {
+      let deg = inst.degree();
+
+      // The evaluations at X_i = 0, 2, 3 are all equal to the scaled claim
+      Self::scaled_claims(inst, remaining_variables - 1)
+        .into_iter()
+        .map(|scaled_claim| vec![scaled_claim; deg])
+        .collect()
+    } else {
+      inst.evaluation_points()
+    }
+  }
+
+  /// In round i after receiving challenge r_i, we partially evaluate all polynomials in the instance
+  /// at X_i = r_i. If the instance is defined over m variables m which is less than n-i, then
+  /// the polynomials do not depend on X_i, so binding them to r_i has no effect.  
+  fn bind<T: SumcheckEngine<E>>(inst: &mut T, remaining_variables: usize, r: &E::Scalar) {
+    let num_instance_variables = inst.size().log_2(); // m
+    if remaining_variables <= num_instance_variables {
+      inst.bound(r)
+    }
+  }
+
+  /// Given an instance defined over m variables, the sum over n = `remaining_variables` is equal
+  /// to the initial claim scaled by 2^{n-m}, when m ≤ n.   
+  fn scaled_claims<T: SumcheckEngine<E>>(inst: &T, remaining_variables: usize) -> Vec<E::Scalar> {
+    let num_instance_variables = inst.size().log_2(); // m
+    let num_repetitions = 1 << (remaining_variables - num_instance_variables);
+    let scaling = E::Scalar::from(num_repetitions as u64);
+    inst
+      .initial_claims()
+      .iter()
+      .map(|claim| scaling * claim)
+      .collect()
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/macros.rs.html b/docs/src/arecibo/spartan/macros.rs.html new file mode 100644 index 000000000..798089173 --- /dev/null +++ b/docs/src/arecibo/spartan/macros.rs.html @@ -0,0 +1,207 @@ +macros.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+
/// Macros to give syntactic sugar for zipWith pattern and variants.
+///
+/// ```ignore
+/// use crate::spartan::zip_with;
+/// use itertools::Itertools as _; // we use zip_eq to zip!
+/// let v = vec![0, 1, 2];
+/// let w = vec![2, 3, 4];
+/// let y = vec![4, 5, 6];
+///
+/// // Using the `zip_with!` macro to zip three iterators together and apply a closure
+/// // that sums the elements of each iterator.
+/// let res = zip_with!((v.iter(), w.iter(), y.iter()), |a, b, c| a + b + c)
+///     .collect::<Vec<_>>();
+///
+/// println!("{:?}", res); // Output: [6, 9, 12]
+/// ```
+
+#[macro_export]
+macro_rules! zip_with {
+    // no iterator projection specified: the macro assumes the arguments *are* iterators
+    // ```ignore
+    // zip_with!((iter1, iter2, iter3), |a, b, c| a + b + c) ->
+    //   iter1.zip_eq(iter2.zip_eq(iter3)).map(|(a, (b, c))| a + b + c)
+    // ```
+    //
+    // iterator projection specified: use it on each argument
+    // ```ignore
+    // zip_with!(par_iter, (vec1, vec2, vec3), |a, b, c| a + b + c) ->
+    //   vec1.par_iter().zip_eq(vec2.par_iter().zip_eq(vec3.par_iter())).map(|(a, (b, c))| a + b + c)
+    // ````
+    ($($f:ident,)? ($e:expr $(, $rest:expr)*), $($move:ident)? |$($i:ident),+ $(,)?| $($work:tt)*) => {{
+        $crate::zip_with!($($f,)? ($e $(, $rest)*), map, $($move)? |$($i),+| $($work)*)
+    }};
+    // no iterator projection specified: the macro assumes the arguments *are* iterators
+    // optional zipping function specified as well: use it instead of map
+    // ```ignore
+    // zip_with!((iter1, iter2, iter3), for_each, |a, b, c| a + b + c) ->
+    //   iter1.zip_eq(iter2.zip_eq(iter3)).for_each(|(a, (b, c))| a + b + c)
+    // ```
+    //
+    //
+    // iterator projection specified: use it on each argument
+    // optional zipping function specified as well: use it instead of map
+    // ```ignore
+    // zip_with!(par_iter, (vec1, vec2, vec3), for_each, |a, b, c| a + b + c) ->
+    //   vec1.part_iter().zip_eq(vec2.par_iter().zip_eq(vec3.par_iter())).for_each(|(a, (b, c))| a + b + c)
+    // ```
+    ($($f:ident,)? ($e:expr $(, $rest:expr)*), $worker:ident, $($move:ident,)? |$($i:ident),+ $(,)?|  $($work:tt)*) => {{
+        $crate::zip_all!($($f,)? ($e $(, $rest)*))
+            .$worker($($move)? |$crate::nested_idents!($($i),+)| {
+                $($work)*
+            })
+    }};
+}
+
+/// Like `zip_with` but use `for_each` instead of `map`.
+#[macro_export]
+macro_rules! zip_with_for_each {
+    // no iterator projection specified: the macro assumes the arguments *are* iterators
+    // ```ignore
+    // zip_with_for_each!((iter1, iter2, iter3), |a, b, c| a + b + c) ->
+    //   iter1.zip_eq(iter2.zip_eq(iter3)).for_each(|(a, (b, c))| a + b + c)
+    // ```
+    //
+    // iterator projection specified: use it on each argument
+    // ```ignore
+    // zip_with_for_each!(par_iter, (vec1, vec2, vec3), |a, b, c| a + b + c) ->
+    //   vec1.par_iter().zip_eq(vec2.par_iter().zip_eq(vec3.par_iter())).for_each(|(a, (b, c))| a + b + c)
+    // ````
+    ($($f:ident,)? ($e:expr $(, $rest:expr)*), $($move:ident)? |$($i:ident),+ $(,)?| $($work:tt)*) => {{
+        $crate::zip_with!($($f,)? ($e $(, $rest)*), for_each, $($move)? |$($i),+| $($work)*)
+    }};
+}
+
+// Foldright-like nesting for idents (a, b, c) -> (a, (b, c))
+#[doc(hidden)]
+#[macro_export]
+macro_rules! nested_idents {
+    ($a:ident, $b:ident) => {
+        ($a, $b)
+    };
+    ($first:ident, $($rest:ident),+) => {
+        ($first, $crate::nested_idents!($($rest),+))
+    };
+}
+
+// Fold-right like zipping, with an optional function `f` to apply to each argument
+#[doc(hidden)]
+#[macro_export]
+macro_rules! zip_all {
+    (($e:expr,)) => {
+        $e
+    };
+    ($f:ident, ($e:expr,)) => {
+        $e.$f()
+    };
+    ($f:ident, ($first:expr, $second:expr $(, $rest:expr)*)) => {
+        ($first.$f().zip_eq($crate::zip_all!($f, ($second, $( $rest),*))))
+    };
+    (($first:expr, $second:expr $(, $rest:expr)*)) => {
+        ($first.zip_eq($crate::zip_all!(($second, $( $rest),*))))
+    };
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/math.rs.html b/docs/src/arecibo/spartan/math.rs.html new file mode 100644 index 000000000..e3c44f22d --- /dev/null +++ b/docs/src/arecibo/spartan/math.rs.html @@ -0,0 +1,61 @@ +math.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+
pub trait Math {
+  fn pow2(self) -> usize;
+  fn get_bits(self, num_bits: usize) -> Vec<bool>;
+  fn log_2(self) -> usize;
+}
+
+impl Math for usize {
+  #[inline]
+  fn pow2(self) -> usize {
+    let base: Self = 2;
+    base.pow(self as u32)
+  }
+
+  /// Returns the `num_bits` from n in a canonical order
+  fn get_bits(self, num_bits: usize) -> Vec<bool> {
+    (0..num_bits)
+      .map(|shift_amount| ((self & (1 << (num_bits - shift_amount - 1))) > 0))
+      .collect::<Vec<bool>>()
+  }
+
+  fn log_2(self) -> usize {
+    assert_ne!(self, 0);
+
+    if self.is_power_of_two() {
+      (1usize.leading_zeros() - self.leading_zeros()) as Self
+    } else {
+      (0usize.leading_zeros() - self.leading_zeros()) as Self
+    }
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/mod.rs.html b/docs/src/arecibo/spartan/mod.rs.html new file mode 100644 index 000000000..7e97d0922 --- /dev/null +++ b/docs/src/arecibo/spartan/mod.rs.html @@ -0,0 +1,451 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+
//! This module implements `RelaxedR1CSSNARKTrait` using Spartan that is generic
+//! over the polynomial commitment and evaluation argument (i.e., a PCS)
+//! We provide two implementations, one in snark.rs (which does not use any preprocessing)
+//! and another in ppsnark.rs (which uses preprocessing to keep the verifier's state small if the PCS provides a succinct verifier)
+//! We also provide direct.rs that allows proving a step circuit directly with either of the two SNARKs.
+//!
+//! In polynomial.rs we also provide foundational types and functions for manipulating multilinear polynomials.
+
+pub mod batched;
+pub mod batched_ppsnark;
+#[macro_use]
+mod macros;
+mod math;
+pub mod polys;
+pub mod ppsnark;
+pub mod snark;
+mod sumcheck;
+
+use crate::{
+  r1cs::{R1CSShape, SparseMatrix},
+  traits::Engine,
+  Commitment,
+};
+use ff::Field;
+use itertools::Itertools as _;
+use polys::multilinear::SparsePolynomial;
+use rayon::{iter::IntoParallelRefIterator, prelude::*};
+
+// Creates a vector of the first `n` powers of `s`.
+fn powers<E: Engine>(s: &E::Scalar, n: usize) -> Vec<E::Scalar> {
+  assert!(n >= 1);
+  std::iter::successors(Some(E::Scalar::ONE), |&x| Some(x * s))
+    .take(n)
+    .collect()
+}
+
+/// A type that holds a witness to a polynomial evaluation instance
+struct PolyEvalWitness<E: Engine> {
+  p: Vec<E::Scalar>, // polynomial
+}
+
+impl<E: Engine> PolyEvalWitness<E> {
+  /// Given [Pᵢ] and s, compute P = ∑ᵢ sⁱ⋅Pᵢ
+  ///
+  /// # Details
+  ///
+  /// We allow the input polynomials to have different sizes, and interpret smaller ones as
+  /// being padded with 0 to the maximum size of all polynomials.
+  fn batch_diff_size(W: Vec<Self>, s: E::Scalar) -> Self {
+    let powers = powers::<E>(&s, W.len());
+
+    let size_max = W.iter().map(|w| w.p.len()).max().unwrap();
+    // Scale the input polynomials by the power of s
+    let p = W
+      .into_par_iter()
+      .zip_eq(powers.par_iter())
+      .map(|(mut w, s)| {
+        if *s != E::Scalar::ONE {
+          w.p.par_iter_mut().for_each(|e| *e *= s);
+        }
+        w.p
+      })
+      .reduce(
+        || vec![E::Scalar::ZERO; size_max],
+        |left, right| {
+          // Sum into the largest polynomial
+          let (mut big, small) = if left.len() > right.len() {
+            (left, right)
+          } else {
+            (right, left)
+          };
+
+          #[allow(clippy::disallowed_methods)]
+          big
+            .par_iter_mut()
+            .zip(small.par_iter())
+            .for_each(|(b, s)| *b += s);
+
+          big
+        },
+      );
+
+    Self { p }
+  }
+
+  /// Given a set of polynomials \[Pᵢ\] and a scalar `s`, this method computes the weighted sum
+  /// of the polynomials, where each polynomial Pᵢ is scaled by sⁱ. The method handles polynomials
+  /// of different sizes by padding smaller ones with zeroes up to the size of the largest polynomial.
+  ///
+  /// # Panics
+  ///
+  /// This method panics if the polynomials in `p_vec` are not all of the same length.
+  fn batch(p_vec: &[&Vec<E::Scalar>], s: &E::Scalar) -> Self {
+    p_vec
+      .iter()
+      .for_each(|p| assert_eq!(p.len(), p_vec[0].len()));
+
+    let powers_of_s = powers::<E>(s, p_vec.len());
+
+    let p = zip_with!(par_iter, (p_vec, powers_of_s), |v, weight| {
+      // compute the weighted sum for each vector
+      v.iter().map(|&x| x * *weight).collect::<Vec<E::Scalar>>()
+    })
+    .reduce(
+      || vec![E::Scalar::ZERO; p_vec[0].len()],
+      |acc, v| {
+        // perform vector addition to combine the weighted vectors
+        acc.into_iter().zip_eq(v).map(|(x, y)| x + y).collect()
+      },
+    );
+
+    Self { p }
+  }
+}
+
+/// A type that holds a polynomial evaluation instance
+struct PolyEvalInstance<E: Engine> {
+  c: Commitment<E>,  // commitment to the polynomial
+  x: Vec<E::Scalar>, // evaluation point
+  e: E::Scalar,      // claimed evaluation
+}
+
+impl<E: Engine> PolyEvalInstance<E> {
+  fn batch_diff_size(
+    c_vec: &[Commitment<E>],
+    e_vec: &[E::Scalar],
+    num_vars: &[usize],
+    x: Vec<E::Scalar>,
+    s: E::Scalar,
+  ) -> Self {
+    let num_instances = num_vars.len();
+    assert_eq!(c_vec.len(), num_instances);
+    assert_eq!(e_vec.len(), num_instances);
+
+    let num_vars_max = x.len();
+    let powers: Vec<E::Scalar> = powers::<E>(&s, num_instances);
+    // Rescale evaluations by the first Lagrange polynomial,
+    // so that we can check its evaluation against x
+    let evals_scaled = zip_with!(iter, (e_vec, num_vars), |eval, num_rounds| {
+      // x_lo = [ x[0]   , ..., x[n-nᵢ-1] ]
+      // x_hi = [ x[n-nᵢ], ..., x[n]      ]
+      let (r_lo, _r_hi) = x.split_at(num_vars_max - num_rounds);
+      // Compute L₀(x_lo)
+      let lagrange_eval = r_lo
+        .iter()
+        .map(|r| E::Scalar::ONE - r)
+        .product::<E::Scalar>();
+
+      // vᵢ = L₀(x_lo)⋅Pᵢ(x_hi)
+      lagrange_eval * eval
+    })
+    .collect::<Vec<_>>();
+
+    // C = ∑ᵢ γⁱ⋅Cᵢ
+    let comm_joint = zip_with!(iter, (c_vec, powers), |c, g_i| *c * *g_i)
+      .fold(Commitment::<E>::default(), |acc, item| acc + item);
+
+    // v = ∑ᵢ γⁱ⋅vᵢ
+    let eval_joint = zip_with!((evals_scaled.into_iter(), powers.iter()), |e, g_i| e * g_i).sum();
+
+    Self {
+      c: comm_joint,
+      x,
+      e: eval_joint,
+    }
+  }
+
+  fn batch(c_vec: &[Commitment<E>], x: &[E::Scalar], e_vec: &[E::Scalar], s: &E::Scalar) -> Self {
+    let num_instances = c_vec.len();
+    assert_eq!(e_vec.len(), num_instances);
+
+    let powers_of_s = powers::<E>(s, num_instances);
+    // Weighted sum of evaluations
+    let e = zip_with!(par_iter, (e_vec, powers_of_s), |e, p| *e * p).sum();
+    // Weighted sum of commitments
+    let c = zip_with!(par_iter, (c_vec, powers_of_s), |c, p| *c * *p)
+      .reduce(Commitment::<E>::default, |acc, item| acc + item);
+
+    Self {
+      c,
+      x: x.to_vec(),
+      e,
+    }
+  }
+}
+
+/// Bounds "row" variables of (A, B, C) matrices viewed as 2d multilinear polynomials
+fn compute_eval_table_sparse<E: Engine>(
+  S: &R1CSShape<E>,
+  rx: &[E::Scalar],
+) -> (Vec<E::Scalar>, Vec<E::Scalar>, Vec<E::Scalar>) {
+  assert_eq!(rx.len(), S.num_cons);
+
+  let inner = |M: &SparseMatrix<E::Scalar>, M_evals: &mut Vec<E::Scalar>| {
+    for (row_idx, ptrs) in M.indptr.windows(2).enumerate() {
+      for (val, col_idx) in M.get_row_unchecked(ptrs.try_into().unwrap()) {
+        M_evals[*col_idx] += rx[row_idx] * val;
+      }
+    }
+  };
+
+  let (A_evals, (B_evals, C_evals)) = rayon::join(
+    || {
+      let mut A_evals: Vec<E::Scalar> = vec![E::Scalar::ZERO; 2 * S.num_vars];
+      inner(&S.A, &mut A_evals);
+      A_evals
+    },
+    || {
+      rayon::join(
+        || {
+          let mut B_evals: Vec<E::Scalar> = vec![E::Scalar::ZERO; 2 * S.num_vars];
+          inner(&S.B, &mut B_evals);
+          B_evals
+        },
+        || {
+          let mut C_evals: Vec<E::Scalar> = vec![E::Scalar::ZERO; 2 * S.num_vars];
+          inner(&S.C, &mut C_evals);
+          C_evals
+        },
+      )
+    },
+  );
+
+  (A_evals, B_evals, C_evals)
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/polys/eq.rs.html b/docs/src/arecibo/spartan/polys/eq.rs.html new file mode 100644 index 000000000..21c984a0b --- /dev/null +++ b/docs/src/arecibo/spartan/polys/eq.rs.html @@ -0,0 +1,235 @@ +eq.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+
//! `EqPolynomial`: Represents multilinear extension of equality polynomials, evaluated based on binary input values.
+
+use ff::PrimeField;
+use rayon::prelude::{IndexedParallelIterator, IntoParallelRefMutIterator, ParallelIterator};
+
+/// Represents the multilinear extension polynomial (MLE) of the equality polynomial $eq(x,e)$, denoted as $\tilde{eq}(x, e)$.
+///
+/// The polynomial is defined by the formula:
+/// $$
+/// \tilde{eq}(x, e) = \prod_{i=1}^m(e_i * x_i + (1 - e_i) * (1 - x_i))
+/// $$
+///
+/// Each element in the vector `r` corresponds to a component $e_i$, representing a bit from the binary representation of an input value $e$.
+/// This polynomial evaluates to 1 if every component $x_i$ equals its corresponding $e_i$, and 0 otherwise.
+///
+/// For instance, for e = 6 (with a binary representation of 0b110), the vector r would be [1, 1, 0].
+#[derive(Debug)]
+pub struct EqPolynomial<Scalar> {
+  pub(crate) r: Vec<Scalar>,
+}
+
+impl<Scalar: PrimeField> EqPolynomial<Scalar> {
+  /// Creates a new `EqPolynomial` from a vector of Scalars `r`.
+  ///
+  /// Each Scalar in `r` corresponds to a bit from the binary representation of an input value `e`.
+  pub const fn new(r: Vec<Scalar>) -> Self {
+    Self { r }
+  }
+
+  /// Evaluates the `EqPolynomial` at a given point `rx`.
+  ///
+  /// This function computes the value of the polynomial at the point specified by `rx`.
+  /// It expects `rx` to have the same length as the internal vector `r`.
+  ///
+  /// Panics if `rx` and `r` have different lengths.
+  pub fn evaluate(&self, rx: &[Scalar]) -> Scalar {
+    assert_eq!(self.r.len(), rx.len());
+    (0..rx.len())
+      .map(|i| self.r[i] * rx[i] + (Scalar::ONE - self.r[i]) * (Scalar::ONE - rx[i]))
+      .fold(Scalar::ONE, |acc, item| acc * item)
+  }
+
+  /// Evaluates the `EqPolynomial` at all the `2^|r|` points in its domain.
+  ///
+  /// Returns a vector of Scalars, each corresponding to the polynomial evaluation at a specific point.
+  pub fn evals(&self) -> Vec<Scalar> {
+    Self::evals_from_points(&self.r)
+  }
+
+  /// Evaluates the `EqPolynomial` from the `2^|r|` points in its domain, without creating an intermediate polynomial
+  /// representation.
+  ///
+  /// Returns a vector of Scalars, each corresponding to the polynomial evaluation at a specific point.
+  pub fn evals_from_points(r: &[Scalar]) -> Vec<Scalar> {
+    let ell = r.len();
+    let mut evals: Vec<Scalar> = vec![Scalar::ZERO; (2_usize).pow(ell as u32)];
+    let mut size = 1;
+    evals[0] = Scalar::ONE;
+
+    for r in r.iter().rev() {
+      let (evals_left, evals_right) = evals.split_at_mut(size);
+      let (evals_right, _) = evals_right.split_at_mut(size);
+
+      evals_left
+        .par_iter_mut()
+        .zip_eq(evals_right.par_iter_mut())
+        .for_each(|(x, y)| {
+          *y = *x * r;
+          *x -= &*y;
+        });
+
+      size *= 2;
+    }
+
+    evals
+  }
+}
+
+impl<Scalar: PrimeField> FromIterator<Scalar> for EqPolynomial<Scalar> {
+  fn from_iter<I: IntoIterator<Item = Scalar>>(iter: I) -> Self {
+    let r: Vec<_> = iter.into_iter().collect();
+    Self { r }
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use crate::provider;
+
+  use super::*;
+  use pasta_curves::Fp;
+
+  fn test_eq_polynomial_with<F: PrimeField>() {
+    let eq_poly = EqPolynomial::<F>::new(vec![F::ONE, F::ZERO, F::ONE]);
+    let y = eq_poly.evaluate(vec![F::ONE, F::ONE, F::ONE].as_slice());
+    assert_eq!(y, F::ZERO);
+
+    let y = eq_poly.evaluate(vec![F::ONE, F::ZERO, F::ONE].as_slice());
+    assert_eq!(y, F::ONE);
+
+    let eval_list = eq_poly.evals();
+    for (i, &coeff) in eval_list.iter().enumerate().take((2_usize).pow(3)) {
+      if i == 5 {
+        assert_eq!(coeff, F::ONE);
+      } else {
+        assert_eq!(coeff, F::ZERO);
+      }
+    }
+  }
+
+  #[test]
+  fn test_eq_polynomial() {
+    test_eq_polynomial_with::<Fp>();
+    test_eq_polynomial_with::<provider::bn256_grumpkin::bn256::Scalar>();
+    test_eq_polynomial_with::<provider::secp_secq::secp256k1::Scalar>();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/polys/identity.rs.html b/docs/src/arecibo/spartan/polys/identity.rs.html new file mode 100644 index 000000000..04bec09f1 --- /dev/null +++ b/docs/src/arecibo/spartan/polys/identity.rs.html @@ -0,0 +1,59 @@ +identity.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+
use core::marker::PhantomData;
+use ff::PrimeField;
+
+pub struct IdentityPolynomial<Scalar> {
+  ell: usize,
+  _p: PhantomData<Scalar>,
+}
+
+impl<Scalar: PrimeField> IdentityPolynomial<Scalar> {
+  pub fn new(ell: usize) -> Self {
+    Self {
+      ell,
+      _p: PhantomData,
+    }
+  }
+
+  pub fn evaluate(&self, r: &[Scalar]) -> Scalar {
+    assert_eq!(self.ell, r.len());
+    let mut power_of_two = 1_u64;
+    (0..self.ell)
+      .rev()
+      .map(|i| {
+        let result = Scalar::from(power_of_two) * r[i];
+        power_of_two *= 2;
+        result
+      })
+      .fold(Scalar::ZERO, |acc, item| acc + item)
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/polys/masked_eq.rs.html b/docs/src/arecibo/spartan/polys/masked_eq.rs.html new file mode 100644 index 000000000..788e97ace --- /dev/null +++ b/docs/src/arecibo/spartan/polys/masked_eq.rs.html @@ -0,0 +1,301 @@ +masked_eq.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+
//! `MaskedEqPolynomial`: Represents the `eq` polynomial over n variables, where the first 2^m entries are 0.
+
+use crate::spartan::polys::eq::EqPolynomial;
+use ff::PrimeField;
+use itertools::zip_eq;
+
+/// Represents the multilinear extension polynomial (MLE) of the equality polynomial $eqₘ(x,r)$
+/// over n variables, where the first 2^m evaluations are 0.
+///
+/// The polynomial is defined by the formula:
+/// eqₘ(x,r) = eq(x,r) - ( ∏_{0 ≤ i < n-m} (1−rᵢ)(1−xᵢ) )⋅( ∏_{n-m ≤ i < n} (1−rᵢ)(1−xᵢ) + rᵢ⋅xᵢ )
+#[derive(Debug)]
+pub struct MaskedEqPolynomial<'a, Scalar> {
+  eq: &'a EqPolynomial<Scalar>,
+  num_masked_vars: usize,
+}
+
+impl<'a, Scalar: PrimeField> MaskedEqPolynomial<'a, Scalar> {
+  /// Creates a new `MaskedEqPolynomial` from a vector of Scalars `r` of size n, with the number of
+  /// masked variables m = `num_masked_vars`.
+  pub const fn new(eq: &'a EqPolynomial<Scalar>, num_masked_vars: usize) -> Self {
+    MaskedEqPolynomial {
+      eq,
+      num_masked_vars,
+    }
+  }
+
+  /// Evaluates the `MaskedEqPolynomial` at a given point `rx`.
+  ///
+  /// This function computes the value of the polynomial at the point specified by `rx`.
+  /// It expects `rx` to have the same length as the internal vector `r`.
+  ///
+  /// Panics if `rx` and `r` have different lengths.
+  pub fn evaluate(&self, rx: &[Scalar]) -> Scalar {
+    let r = &self.eq.r;
+    assert_eq!(r.len(), rx.len());
+    let split_idx = r.len() - self.num_masked_vars;
+
+    let (r_lo, r_hi) = r.split_at(split_idx);
+    let (rx_lo, rx_hi) = rx.split_at(split_idx);
+    let eq_lo = zip_eq(r_lo, rx_lo)
+      .map(|(r, rx)| *r * rx + (Scalar::ONE - r) * (Scalar::ONE - rx))
+      .product::<Scalar>();
+    let eq_hi = zip_eq(r_hi, rx_hi)
+      .map(|(r, rx)| *r * rx + (Scalar::ONE - r) * (Scalar::ONE - rx))
+      .product::<Scalar>();
+    let mask_lo = zip_eq(r_lo, rx_lo)
+      .map(|(r, rx)| (Scalar::ONE - r) * (Scalar::ONE - rx))
+      .product::<Scalar>();
+
+    (eq_lo - mask_lo) * eq_hi
+  }
+
+  /// Evaluates the `MaskedEqPolynomial` at all the `2^|r|` points in its domain.
+  ///
+  /// Returns a vector of Scalars, each corresponding to the polynomial evaluation at a specific point.
+  pub fn evals(&self) -> Vec<Scalar> {
+    Self::evals_from_points(&self.eq.r, self.num_masked_vars)
+  }
+
+  /// Evaluates the `MaskedEqPolynomial` from the `2^|r|` points in its domain, without creating an intermediate polynomial
+  /// representation.
+  ///
+  /// Returns a vector of Scalars, each corresponding to the polynomial evaluation at a specific point.
+  fn evals_from_points(r: &[Scalar], num_masked_vars: usize) -> Vec<Scalar> {
+    let mut evals = EqPolynomial::evals_from_points(r);
+
+    // replace the first 2^m evaluations with 0
+    let num_masked_evals = 1 << num_masked_vars;
+    evals[..num_masked_evals]
+      .iter_mut()
+      .for_each(|e| *e = Scalar::ZERO);
+
+    evals
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use crate::provider;
+
+  use super::*;
+  use crate::spartan::polys::eq::EqPolynomial;
+  use pasta_curves::Fp;
+  use rand_chacha::ChaCha20Rng;
+  use rand_core::{CryptoRng, RngCore, SeedableRng};
+
+  fn test_masked_eq_polynomial_with<F: PrimeField, R: RngCore + CryptoRng>(
+    num_vars: usize,
+    num_masked_vars: usize,
+    mut rng: &mut R,
+  ) {
+    let num_masked_evals = 1 << num_masked_vars;
+
+    // random point
+    let r = std::iter::from_fn(|| Some(F::random(&mut rng)))
+      .take(num_vars)
+      .collect::<Vec<_>>();
+    // evaluation point
+    let rx = std::iter::from_fn(|| Some(F::random(&mut rng)))
+      .take(num_vars)
+      .collect::<Vec<_>>();
+
+    let poly_eq = EqPolynomial::new(r);
+    let poly_eq_evals = poly_eq.evals();
+
+    let masked_eq_poly = MaskedEqPolynomial::new(&poly_eq, num_masked_vars);
+    let masked_eq_poly_evals = masked_eq_poly.evals();
+
+    // ensure the first 2^m entries are 0
+    assert_eq!(
+      masked_eq_poly_evals[..num_masked_evals],
+      vec![F::ZERO; num_masked_evals]
+    );
+    // ensure the remaining evaluations match eq(r)
+    assert_eq!(
+      masked_eq_poly_evals[num_masked_evals..],
+      poly_eq_evals[num_masked_evals..]
+    );
+
+    // compute the evaluation at rx succinctly
+    let masked_eq_eval = masked_eq_poly.evaluate(&rx);
+
+    // compute the evaluation as a MLE
+    let rx_evals = EqPolynomial::evals_from_points(&rx);
+    let expected_masked_eq_eval = zip_eq(rx_evals, masked_eq_poly_evals)
+      .map(|(rx, r)| rx * r)
+      .sum();
+
+    assert_eq!(masked_eq_eval, expected_masked_eq_eval);
+  }
+
+  #[test]
+  fn test_masked_eq_polynomial() {
+    let mut rng = ChaCha20Rng::from_seed([0u8; 32]);
+    let num_vars = 5;
+    let num_masked_vars = 2;
+    test_masked_eq_polynomial_with::<Fp, _>(num_vars, num_masked_vars, &mut rng);
+    test_masked_eq_polynomial_with::<provider::bn256_grumpkin::bn256::Scalar, _>(
+      num_vars,
+      num_masked_vars,
+      &mut rng,
+    );
+    test_masked_eq_polynomial_with::<provider::secp_secq::secp256k1::Scalar, _>(
+      num_vars,
+      num_masked_vars,
+      &mut rng,
+    );
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/polys/mod.rs.html b/docs/src/arecibo/spartan/polys/mod.rs.html new file mode 100644 index 000000000..bdaa7f52d --- /dev/null +++ b/docs/src/arecibo/spartan/polys/mod.rs.html @@ -0,0 +1,15 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+
//! This module contains the definitions of polynomial types used in the Spartan SNARK.
+pub(crate) mod eq;
+pub(crate) mod identity;
+pub(crate) mod masked_eq;
+pub mod multilinear;
+pub(crate) mod power;
+pub(crate) mod univariate;
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/polys/multilinear.rs.html b/docs/src/arecibo/spartan/polys/multilinear.rs.html new file mode 100644 index 000000000..d79d1dbb4 --- /dev/null +++ b/docs/src/arecibo/spartan/polys/multilinear.rs.html @@ -0,0 +1,719 @@ +multilinear.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+
//! Main components:
+//! - `MultilinearPolynomial`: Dense representation of multilinear polynomials, represented by evaluations over all possible binary inputs.
+//! - `SparsePolynomial`: Efficient representation of sparse multilinear polynomials, storing only non-zero evaluations.
+
+use std::ops::{Add, Index};
+
+use ff::PrimeField;
+use itertools::Itertools as _;
+use rand_core::{CryptoRng, RngCore};
+use rayon::prelude::{
+  IndexedParallelIterator, IntoParallelIterator, IntoParallelRefIterator,
+  IntoParallelRefMutIterator, ParallelIterator,
+};
+use serde::{Deserialize, Serialize};
+
+use crate::spartan::{math::Math, polys::eq::EqPolynomial};
+
+/// A multilinear extension of a polynomial $Z(\cdot)$, denote it as $\tilde{Z}(x_1, ..., x_m)$
+/// where the degree of each variable is at most one.
+///
+/// This is the dense representation of a multilinear poynomial.
+/// Let it be $\mathbb{G}(\cdot): \mathbb{F}^m \rightarrow \mathbb{F}$, it can be represented uniquely by the list of
+/// evaluations of $\mathbb{G}(\cdot)$ over the Boolean hypercube $\{0, 1\}^m$.
+///
+/// For example, a 3 variables multilinear polynomial can be represented by evaluation
+/// at points $[0, 2^3-1]$.
+///
+/// The implementation follows
+/// $$
+/// \tilde{Z}(x_1, ..., x_m) = \sum_{e\in {0,1}^m}Z(e) \cdot \prod_{i=1}^m(x_i \cdot e_i + (1-x_i) \cdot (1-e_i))
+/// $$
+///
+/// Vector $Z$ indicates $Z(e)$ where $e$ ranges from $0$ to $2^m-1$.
+#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
+pub struct MultilinearPolynomial<Scalar> {
+  num_vars: usize,           // the number of variables in the multilinear polynomial
+  pub(crate) Z: Vec<Scalar>, // evaluations of the polynomial in all the 2^num_vars Boolean inputs
+}
+
+impl<Scalar: PrimeField> MultilinearPolynomial<Scalar> {
+  /// Creates a new `MultilinearPolynomial` from the given evaluations.
+  ///
+  /// # Panics
+  /// The number of evaluations must be a power of two.
+  pub fn new(Z: Vec<Scalar>) -> Self {
+    let num_vars = Z.len().log_2();
+    assert_eq!(Z.len(), 1 << num_vars);
+    Self { num_vars, Z }
+  }
+
+  /// evaluations of the polynomial in all the 2^num_vars Boolean inputs
+  pub fn evaluations(&self) -> &[Scalar] {
+    &self.Z[..]
+  }
+
+  /// Returns the number of variables in the multilinear polynomial
+  pub const fn get_num_vars(&self) -> usize {
+    self.num_vars
+  }
+
+  /// Returns the total number of evaluations.
+  pub fn len(&self) -> usize {
+    self.Z.len()
+  }
+
+  /// Returns true if no evaluations.
+  pub fn is_empty(&self) -> bool {
+    self.Z.len() == 0
+  }
+
+  /// Returns a random polynomial
+  pub fn random<R: RngCore + CryptoRng>(num_vars: usize, mut rng: &mut R) -> Self {
+    Self::new(
+      std::iter::from_fn(|| Some(Scalar::random(&mut rng)))
+        .take(1 << num_vars)
+        .collect(),
+    )
+  }
+
+  /// Binds the polynomial's top variable using the given scalar.
+  ///
+  /// This operation modifies the polynomial in-place.
+  pub fn bind_poly_var_top(&mut self, r: &Scalar) {
+    assert!(self.num_vars > 0);
+
+    let n = self.len() / 2;
+
+    let (left, right) = self.Z.split_at_mut(n);
+
+    left
+      .par_iter_mut()
+      .zip_eq(right.par_iter())
+      .for_each(|(a, b)| {
+        *a += *r * (*b - *a);
+      });
+
+    self.Z.resize(n, Scalar::ZERO);
+    self.num_vars -= 1;
+  }
+
+  /// Evaluates the polynomial at the given point.
+  /// Returns Z(r) in O(n) time.
+  ///
+  /// The point must have a value for each variable.
+  pub fn evaluate(&self, r: &[Scalar]) -> Scalar {
+    // r must have a value for each variable
+    assert_eq!(r.len(), self.get_num_vars());
+    let chis = EqPolynomial::evals_from_points(r);
+
+    zip_with!(
+      (chis.into_par_iter(), self.Z.par_iter()),
+      |chi_i, Z_i| chi_i * Z_i
+    )
+    .sum()
+  }
+
+  /// Evaluates the polynomial with the given evaluations and point.
+  pub fn evaluate_with(Z: &[Scalar], r: &[Scalar]) -> Scalar {
+    zip_with!(
+      (
+        EqPolynomial::evals_from_points(r).into_par_iter(),
+        Z.par_iter()
+      ),
+      |a, b| a * b
+    )
+    .sum()
+  }
+}
+
+impl<Scalar: PrimeField> Index<usize> for MultilinearPolynomial<Scalar> {
+  type Output = Scalar;
+
+  #[inline(always)]
+  fn index(&self, _index: usize) -> &Scalar {
+    &(self.Z[_index])
+  }
+}
+
+/// Sparse multilinear polynomial, which means the $Z(\cdot)$ is zero at most points.
+/// So we do not have to store every evaluations of $Z(\cdot)$, only store the non-zero points.
+///
+/// For example, the evaluations are [0, 0, 0, 1, 0, 1, 0, 2].
+/// The sparse polynomial only store the non-zero values, [(3, 1), (5, 1), (7, 2)].
+/// In the tuple, the first is index, the second is value.
+pub(crate) struct SparsePolynomial<Scalar> {
+  num_vars: usize,
+  Z: Vec<(usize, Scalar)>,
+}
+
+impl<Scalar: PrimeField> SparsePolynomial<Scalar> {
+  pub fn new(num_vars: usize, Z: Vec<(usize, Scalar)>) -> Self {
+    Self { num_vars, Z }
+  }
+
+  /// Computes the $\tilde{eq}$ extension polynomial.
+  /// return 1 when a == r, otherwise return 0.
+  fn compute_chi(a: &[bool], r: &[Scalar]) -> Scalar {
+    assert_eq!(a.len(), r.len());
+    let mut chi_i = Scalar::ONE;
+    for j in 0..r.len() {
+      if a[j] {
+        chi_i *= r[j];
+      } else {
+        chi_i *= Scalar::ONE - r[j];
+      }
+    }
+    chi_i
+  }
+
+  // Takes O(m log n) where m is the number of non-zero evaluations and n is the number of variables.
+  pub fn evaluate(&self, r: &[Scalar]) -> Scalar {
+    assert_eq!(self.num_vars, r.len());
+
+    (0..self.Z.len())
+      .into_par_iter()
+      .map(|i| {
+        let bits = (self.Z[i].0).get_bits(r.len());
+        Self::compute_chi(&bits, r) * self.Z[i].1
+      })
+      .sum()
+  }
+}
+
+/// Adds another multilinear polynomial to `self`.
+/// Assumes the two polynomials have the same number of variables.
+impl<Scalar: PrimeField> Add for MultilinearPolynomial<Scalar> {
+  type Output = Result<Self, &'static str>;
+
+  fn add(self, other: Self) -> Self::Output {
+    if self.get_num_vars() != other.get_num_vars() {
+      return Err("The two polynomials must have the same number of variables");
+    }
+
+    let sum: Vec<Scalar> = zip_with!(into_iter, (self.Z, other.Z), |a, b| a + b).collect();
+
+    Ok(Self::new(sum))
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use crate::provider::{self, bn256_grumpkin::bn256, secp_secq::secp256k1};
+
+  use super::*;
+  use rand_chacha::ChaCha20Rng;
+  use rand_core::SeedableRng;
+
+  fn make_mlp<F: PrimeField>(len: usize, value: F) -> MultilinearPolynomial<F> {
+    MultilinearPolynomial {
+      num_vars: len.count_ones() as usize,
+      Z: vec![value; len],
+    }
+  }
+
+  fn test_multilinear_polynomial_with<F: PrimeField>() {
+    // Let the polynomial has 3 variables, p(x_1, x_2, x_3) = (x_1 + x_2) * x_3
+    // Evaluations of the polynomial at boolean cube are [0, 0, 0, 1, 0, 1, 0, 2].
+
+    let TWO = F::from(2);
+
+    let Z = vec![
+      F::ZERO,
+      F::ZERO,
+      F::ZERO,
+      F::ONE,
+      F::ZERO,
+      F::ONE,
+      F::ZERO,
+      TWO,
+    ];
+    let m_poly = MultilinearPolynomial::<F>::new(Z.clone());
+    assert_eq!(m_poly.get_num_vars(), 3);
+
+    let x = vec![F::ONE, F::ONE, F::ONE];
+    assert_eq!(m_poly.evaluate(x.as_slice()), TWO);
+
+    let y = MultilinearPolynomial::<F>::evaluate_with(Z.as_slice(), x.as_slice());
+    assert_eq!(y, TWO);
+  }
+
+  fn test_sparse_polynomial_with<F: PrimeField>() {
+    // Let the polynomial have 3 variables, p(x_1, x_2, x_3) = (x_1 + x_2) * x_3
+    // Evaluations of the polynomial at boolean cube are [0, 0, 0, 1, 0, 1, 0, 2].
+
+    let TWO = F::from(2);
+    let Z = vec![(3, F::ONE), (5, F::ONE), (7, TWO)];
+    let m_poly = SparsePolynomial::<F>::new(3, Z);
+
+    let x = vec![F::ONE, F::ONE, F::ONE];
+    assert_eq!(m_poly.evaluate(x.as_slice()), TWO);
+
+    let x = vec![F::ONE, F::ZERO, F::ONE];
+    assert_eq!(m_poly.evaluate(x.as_slice()), F::ONE);
+  }
+
+  #[test]
+  fn test_multilinear_polynomial() {
+    test_multilinear_polynomial_with::<pasta_curves::Fp>();
+  }
+
+  #[test]
+  fn test_sparse_polynomial() {
+    test_sparse_polynomial_with::<pasta_curves::Fp>();
+  }
+
+  fn test_mlp_add_with<F: PrimeField>() {
+    let mlp1 = make_mlp(4, F::from(3));
+    let mlp2 = make_mlp(4, F::from(7));
+
+    let mlp3 = mlp1.add(mlp2).unwrap();
+
+    assert_eq!(mlp3.Z, vec![F::from(10); 4]);
+  }
+
+  #[test]
+  fn test_mlp_add() {
+    test_mlp_add_with::<pasta_curves::Fp>();
+    test_mlp_add_with::<bn256::Scalar>();
+    test_mlp_add_with::<secp256k1::Scalar>();
+  }
+
+  fn test_evaluation_with<F: PrimeField>() {
+    let num_evals = 4;
+    let mut evals: Vec<F> = Vec::with_capacity(num_evals);
+    for _ in 0..num_evals {
+      evals.push(F::from(8));
+    }
+    let dense_poly: MultilinearPolynomial<F> = MultilinearPolynomial::new(evals.clone());
+
+    // Evaluate at 3:
+    // (0, 0) = 1
+    // (0, 1) = 1
+    // (1, 0) = 1
+    // (1, 1) = 1
+    // g(x_0,x_1) => c_0*(1 - x_0)(1 - x_1) + c_1*(1-x_0)(x_1) + c_2*(x_0)(1-x_1) + c_3*(x_0)(x_1)
+    // g(3, 4) = 8*(1 - 3)(1 - 4) + 8*(1-3)(4) + 8*(3)(1-4) + 8*(3)(4) = 48 + -64 + -72 + 96  = 8
+    // g(5, 10) = 8*(1 - 5)(1 - 10) + 8*(1 - 5)(10) + 8*(5)(1-10) + 8*(5)(10) = 96 + -16 + -72 + 96  = 8
+    assert_eq!(
+      dense_poly.evaluate(vec![F::from(3), F::from(4)].as_slice()),
+      F::from(8)
+    );
+    assert_eq!(
+      dense_poly.evaluate(vec![F::from(5), F::from(10)].as_slice()),
+      F::from(8)
+    );
+  }
+
+  #[test]
+  fn test_evaluation() {
+    test_evaluation_with::<pasta_curves::Fp>();
+    test_evaluation_with::<provider::bn256_grumpkin::bn256::Scalar>();
+    test_evaluation_with::<provider::secp_secq::secp256k1::Scalar>();
+  }
+
+  /// This binds the variables of a multilinear polynomial to a provided sequence
+  /// of values.
+  ///
+  /// Assuming `bind_poly_var_top` defines the "top" variable of the polynomial,
+  /// this aims to test whether variables should be provided to the
+  /// `evaluate` function in topmost-first (big endian) of topmost-last (lower endian)
+  /// order.
+  fn bind_sequence<F: PrimeField>(
+    poly: &MultilinearPolynomial<F>,
+    values: &[F],
+  ) -> MultilinearPolynomial<F> {
+    // Assert that the size of the polynomial being evaluated is a power of 2 greater than (1 << values.len())
+    assert!(poly.Z.len().is_power_of_two());
+    assert!(poly.Z.len() >= 1 << values.len());
+
+    let mut tmp = poly.clone();
+    for v in values.iter() {
+      tmp.bind_poly_var_top(v);
+    }
+    tmp
+  }
+
+  fn bind_and_evaluate_with<F: PrimeField>() {
+    for i in 0..50 {
+      // Initialize a random polynomial
+      let n = 7;
+      let mut rng = ChaCha20Rng::from_seed([i as u8; 32]);
+      let poly = MultilinearPolynomial::random(n, &mut rng);
+
+      // draw a random point
+      let pt: Vec<_> = std::iter::from_fn(|| Some(F::random(&mut rng)))
+        .take(n)
+        .collect();
+      // this shows the order in which coordinates are evaluated
+      assert_eq!(poly.evaluate(&pt), bind_sequence(&poly, &pt).Z[0])
+    }
+  }
+
+  #[test]
+  fn test_bind_and_evaluate() {
+    bind_and_evaluate_with::<pasta_curves::Fp>();
+    bind_and_evaluate_with::<bn256::Scalar>();
+    bind_and_evaluate_with::<secp256k1::Scalar>();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/polys/power.rs.html b/docs/src/arecibo/spartan/polys/power.rs.html new file mode 100644 index 000000000..25e172855 --- /dev/null +++ b/docs/src/arecibo/spartan/polys/power.rs.html @@ -0,0 +1,127 @@ +power.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+
//! `PowPolynomial`: Represents multilinear extension of power polynomials
+
+use crate::spartan::polys::eq::EqPolynomial;
+use ff::PrimeField;
+use std::iter::successors;
+
+/// Represents the multilinear extension polynomial (MLE) of the equality polynomial $pow(x,t)$, denoted as $\tilde{pow}(x, t)$.
+///
+/// The polynomial is defined by the formula:
+/// $$
+/// \tilde{power}(x, t) = \prod_{i=1}^m(1 + (t^{2^i} - 1) * x_i)
+/// $$
+pub struct PowPolynomial<Scalar> {
+  eq: EqPolynomial<Scalar>,
+}
+
+impl<Scalar: PrimeField> PowPolynomial<Scalar> {
+  /// Creates a new `PowPolynomial` from a Scalars `t`.
+  pub fn new(t: &Scalar, ell: usize) -> Self {
+    // t_pow = [t^{2^0}, t^{2^1}, ..., t^{2^{ell-1}}]
+    let t_pow = Self::squares(t, ell);
+
+    Self {
+      eq: EqPolynomial::new(t_pow),
+    }
+  }
+
+  /// Create powers the following powers of `t`:
+  /// [t^{2^0}, t^{2^1}, ..., t^{2^{ell-1}}]
+  pub(in crate::spartan) fn squares(t: &Scalar, ell: usize) -> Vec<Scalar> {
+    successors(Some(*t), |p: &Scalar| Some(p.square()))
+      .take(ell)
+      .collect::<Vec<_>>()
+  }
+
+  /// Creates the evals corresponding to a `PowPolynomial` from an already-existing vector of powers.
+  /// `t_pow.len() > ell` must be true.
+  pub(crate) fn evals_with_powers(powers: &[Scalar], ell: usize) -> Vec<Scalar> {
+    let t_pow = powers[..ell].to_vec();
+    EqPolynomial::evals_from_points(&t_pow)
+  }
+
+  /// Evaluates the `PowPolynomial` at a given point `rx`.
+  ///
+  /// This function computes the value of the polynomial at the point specified by `rx`.
+  /// It expects `rx` to have the same length as the internal vector `t_pow`.
+  ///
+  /// Panics if `rx` and `t_pow` have different lengths.
+  pub fn evaluate(&self, rx: &[Scalar]) -> Scalar {
+    self.eq.evaluate(rx)
+  }
+
+  pub fn coordinates(self) -> Vec<Scalar> {
+    self.eq.r
+  }
+
+  /// Evaluates the `PowPolynomial` at all the `2^|t_pow|` points in its domain.
+  ///
+  /// Returns a vector of Scalars, each corresponding to the polynomial evaluation at a specific point.
+  pub fn evals(&self) -> Vec<Scalar> {
+    self.eq.evals()
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/polys/univariate.rs.html b/docs/src/arecibo/spartan/polys/univariate.rs.html new file mode 100644 index 000000000..179ff77bc --- /dev/null +++ b/docs/src/arecibo/spartan/polys/univariate.rs.html @@ -0,0 +1,607 @@ +univariate.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+
//! Main components:
+//! - `UniPoly`: an univariate dense polynomial in coefficient form (big endian),
+//! - `CompressedUniPoly`: a univariate dense polynomial, compressed (omitted linear term), in coefficient form (little endian),
+use std::{
+  cmp::Ordering,
+  ops::{AddAssign, Index, IndexMut, MulAssign},
+};
+
+use ff::PrimeField;
+use rayon::prelude::{IntoParallelIterator, IntoParallelRefMutIterator, ParallelIterator};
+use ref_cast::RefCast;
+use serde::{Deserialize, Serialize};
+
+use crate::traits::{Group, TranscriptReprTrait};
+
+// ax^2 + bx + c stored as vec![c, b, a]
+// ax^3 + bx^2 + cx + d stored as vec![d, c, b, a]
+#[derive(Debug, Clone, PartialEq, Eq, RefCast)]
+#[repr(transparent)]
+pub struct UniPoly<Scalar> {
+  pub coeffs: Vec<Scalar>,
+}
+
+// ax^2 + bx + c stored as vec![c, a]
+// ax^3 + bx^2 + cx + d stored as vec![d, c, a]
+#[derive(Clone, Debug, Serialize, Deserialize)]
+pub struct CompressedUniPoly<Scalar> {
+  coeffs_except_linear_term: Vec<Scalar>,
+}
+
+impl<Scalar: PrimeField> UniPoly<Scalar> {
+  pub fn new(coeffs: Vec<Scalar>) -> Self {
+    let mut res = Self { coeffs };
+    res.truncate_leading_zeros();
+    res
+  }
+
+  fn zero() -> Self {
+    Self::new(Vec::new())
+  }
+
+  /// Divide self by another polynomial, and returns the
+  /// quotient and remainder.
+  pub fn divide_with_q_and_r(&self, divisor: &Self) -> Option<(Self, Self)> {
+    if self.is_zero() {
+      Some((Self::zero(), Self::zero()))
+    } else if divisor.is_zero() {
+      None
+    } else if self.degree() < divisor.degree() {
+      Some((Self::zero(), self.clone()))
+    } else {
+      // Now we know that self.degree() >= divisor.degree();
+      let mut quotient = vec![Scalar::ZERO; self.degree() - divisor.degree() + 1];
+      let mut remainder: Self = self.clone();
+      // Can unwrap here because we know self is not zero.
+      let divisor_leading_inv = divisor.leading_coefficient().unwrap().invert().unwrap();
+      while !remainder.is_zero() && remainder.degree() >= divisor.degree() {
+        let cur_q_coeff = *remainder.leading_coefficient().unwrap() * divisor_leading_inv;
+        let cur_q_degree = remainder.degree() - divisor.degree();
+        quotient[cur_q_degree] = cur_q_coeff;
+
+        for (i, div_coeff) in divisor.coeffs.iter().enumerate() {
+          remainder.coeffs[cur_q_degree + i] -= &(cur_q_coeff * div_coeff);
+        }
+        while let Some(true) = remainder.coeffs.last().map(|c| c == &Scalar::ZERO) {
+          remainder.coeffs.pop();
+        }
+      }
+      Some((Self::new(quotient), remainder))
+    }
+  }
+
+  fn is_zero(&self) -> bool {
+    self.coeffs.is_empty() || self.coeffs.iter().all(|c| c == &Scalar::ZERO)
+  }
+
+  fn truncate_leading_zeros(&mut self) {
+    while self.coeffs.last().map_or(false, |c| c == &Scalar::ZERO) {
+      self.coeffs.pop();
+    }
+  }
+
+  fn leading_coefficient(&self) -> Option<&Scalar> {
+    self.coeffs.last()
+  }
+
+  pub fn from_evals(evals: &[Scalar]) -> Self {
+    // we only support degree-2 or degree-3 univariate polynomials
+    assert!(evals.len() == 3 || evals.len() == 4);
+    let two_inv = Scalar::from(2).invert().unwrap();
+    let coeffs = if evals.len() == 3 {
+      // ax^2 + bx + c
+      let c = evals[0];
+      let a = two_inv * (evals[2] - evals[1] - evals[1] + c);
+      let b = evals[1] - c - a;
+      vec![c, b, a]
+    } else {
+      // ax^3 + bx^2 + cx + d
+      let six_inv = Scalar::from(6).invert().unwrap();
+
+      let d = evals[0];
+      let a = six_inv
+        * (evals[3] - evals[2] - evals[2] - evals[2] + evals[1] + evals[1] + evals[1] - evals[0]);
+      let b = two_inv
+        * (evals[0] + evals[0] - evals[1] - evals[1] - evals[1] - evals[1] - evals[1]
+          + evals[2]
+          + evals[2]
+          + evals[2]
+          + evals[2]
+          - evals[3]);
+      let c = evals[1] - d - a - b;
+      vec![d, c, b, a]
+    };
+
+    Self { coeffs }
+  }
+
+  pub fn degree(&self) -> usize {
+    self.coeffs.len() - 1
+  }
+
+  pub fn eval_at_zero(&self) -> Scalar {
+    self.coeffs[0]
+  }
+
+  pub fn eval_at_one(&self) -> Scalar {
+    (0..self.coeffs.len())
+      .into_par_iter()
+      .map(|i| self.coeffs[i])
+      .sum()
+  }
+
+  pub fn evaluate(&self, r: &Scalar) -> Scalar {
+    let mut eval = self.coeffs[0];
+    let mut power = *r;
+    for coeff in self.coeffs.iter().skip(1) {
+      eval += power * coeff;
+      power *= r;
+    }
+    eval
+  }
+
+  pub fn compress(&self) -> CompressedUniPoly<Scalar> {
+    let coeffs_except_linear_term = [&self.coeffs[0..1], &self.coeffs[2..]].concat();
+    assert_eq!(coeffs_except_linear_term.len() + 1, self.coeffs.len());
+    CompressedUniPoly {
+      coeffs_except_linear_term,
+    }
+  }
+}
+
+impl<Scalar: PrimeField> CompressedUniPoly<Scalar> {
+  // we require eval(0) + eval(1) = hint, so we can solve for the linear term as:
+  // linear_term = hint - 2 * constant_term - deg2 term - deg3 term
+  pub fn decompress(&self, hint: &Scalar) -> UniPoly<Scalar> {
+    let mut linear_term =
+      *hint - self.coeffs_except_linear_term[0] - self.coeffs_except_linear_term[0];
+    for i in 1..self.coeffs_except_linear_term.len() {
+      linear_term -= self.coeffs_except_linear_term[i];
+    }
+
+    let mut coeffs: Vec<Scalar> = Vec::new();
+    coeffs.push(self.coeffs_except_linear_term[0]);
+    coeffs.push(linear_term);
+    coeffs.extend(&self.coeffs_except_linear_term[1..]);
+    assert_eq!(self.coeffs_except_linear_term.len() + 1, coeffs.len());
+    UniPoly { coeffs }
+  }
+}
+
+impl<G: Group> TranscriptReprTrait<G> for UniPoly<G::Scalar> {
+  fn to_transcript_bytes(&self) -> Vec<u8> {
+    let coeffs = self.compress().coeffs_except_linear_term;
+    coeffs
+      .iter()
+      .flat_map(|&t| t.to_repr().as_ref().to_vec())
+      .collect::<Vec<u8>>()
+  }
+}
+
+impl<Scalar: PrimeField> Index<usize> for UniPoly<Scalar> {
+  type Output = Scalar;
+
+  fn index(&self, index: usize) -> &Self::Output {
+    &self.coeffs[index]
+  }
+}
+
+impl<Scalar: PrimeField> IndexMut<usize> for UniPoly<Scalar> {
+  fn index_mut(&mut self, index: usize) -> &mut Self::Output {
+    &mut self.coeffs[index]
+  }
+}
+
+impl<Scalar: PrimeField> AddAssign<&Scalar> for UniPoly<Scalar> {
+  fn add_assign(&mut self, rhs: &Scalar) {
+    self.coeffs.par_iter_mut().for_each(|c| *c += rhs);
+  }
+}
+
+impl<Scalar: PrimeField> MulAssign<&Scalar> for UniPoly<Scalar> {
+  fn mul_assign(&mut self, rhs: &Scalar) {
+    self.coeffs.par_iter_mut().for_each(|c| *c *= rhs);
+  }
+}
+
+impl<Scalar: PrimeField> AddAssign<&Self> for UniPoly<Scalar> {
+  fn add_assign(&mut self, rhs: &Self) {
+    let ordering = self.coeffs.len().cmp(&rhs.coeffs.len());
+    #[allow(clippy::disallowed_methods)]
+    for (lhs, rhs) in self.coeffs.iter_mut().zip(&rhs.coeffs) {
+      *lhs += rhs;
+    }
+    if matches!(ordering, Ordering::Less) {
+      self
+        .coeffs
+        .extend(rhs.coeffs[self.coeffs.len()..].iter().cloned());
+    }
+    if matches!(ordering, Ordering::Equal) {
+      self.truncate_leading_zeros();
+    }
+  }
+}
+
+impl<Scalar: PrimeField> AsRef<Vec<Scalar>> for UniPoly<Scalar> {
+  fn as_ref(&self) -> &Vec<Scalar> {
+    &self.coeffs
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::provider::{bn256_grumpkin, secp_secq::secp256k1};
+
+  fn test_from_evals_quad_with<F: PrimeField>() {
+    // polynomial is 2x^2 + 3x + 1
+    let e0 = F::ONE;
+    let e1 = F::from(6);
+    let e2 = F::from(15);
+    let evals = vec![e0, e1, e2];
+    let poly = UniPoly::from_evals(&evals);
+
+    assert_eq!(poly.eval_at_zero(), e0);
+    assert_eq!(poly.eval_at_one(), e1);
+    assert_eq!(poly.coeffs.len(), 3);
+    assert_eq!(poly.coeffs[0], F::ONE);
+    assert_eq!(poly.coeffs[1], F::from(3));
+    assert_eq!(poly.coeffs[2], F::from(2));
+
+    let hint = e0 + e1;
+    let compressed_poly = poly.compress();
+    let decompressed_poly = compressed_poly.decompress(&hint);
+    for i in 0..decompressed_poly.coeffs.len() {
+      assert_eq!(decompressed_poly.coeffs[i], poly.coeffs[i]);
+    }
+
+    let e3 = F::from(28);
+    assert_eq!(poly.evaluate(&F::from(3)), e3);
+  }
+
+  #[test]
+  fn test_from_evals_quad() {
+    test_from_evals_quad_with::<pasta_curves::pallas::Scalar>();
+    test_from_evals_quad_with::<bn256_grumpkin::bn256::Scalar>();
+    test_from_evals_quad_with::<secp256k1::Scalar>();
+  }
+
+  fn test_from_evals_cubic_with<F: PrimeField>() {
+    // polynomial is x^3 + 2x^2 + 3x + 1
+    let e0 = F::ONE;
+    let e1 = F::from(7);
+    let e2 = F::from(23);
+    let e3 = F::from(55);
+    let evals = vec![e0, e1, e2, e3];
+    let poly = UniPoly::from_evals(&evals);
+
+    assert_eq!(poly.eval_at_zero(), e0);
+    assert_eq!(poly.eval_at_one(), e1);
+    assert_eq!(poly.coeffs.len(), 4);
+
+    assert_eq!(poly.coeffs[1], F::from(3));
+    assert_eq!(poly.coeffs[2], F::from(2));
+    assert_eq!(poly.coeffs[3], F::from(1));
+
+    let hint = e0 + e1;
+    let compressed_poly = poly.compress();
+    let decompressed_poly = compressed_poly.decompress(&hint);
+    for i in 0..decompressed_poly.coeffs.len() {
+      assert_eq!(decompressed_poly.coeffs[i], poly.coeffs[i]);
+    }
+
+    let e4 = F::from(109);
+    assert_eq!(poly.evaluate(&F::from(4)), e4);
+  }
+
+  #[test]
+  fn test_from_evals_cubic() {
+    test_from_evals_cubic_with::<pasta_curves::pallas::Scalar>();
+    test_from_evals_cubic_with::<bn256_grumpkin::bn256::Scalar>();
+    test_from_evals_cubic_with::<secp256k1::Scalar>()
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/ppsnark.rs.html b/docs/src/arecibo/spartan/ppsnark.rs.html new file mode 100644 index 000000000..c4861c24a --- /dev/null +++ b/docs/src/arecibo/spartan/ppsnark.rs.html @@ -0,0 +1,2187 @@ +ppsnark.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+
//! This module implements `RelaxedR1CSSNARK` traits using a spark-based approach to prove evaluations of
+//! sparse multilinear polynomials involved in Spartan's sum-check protocol, thereby providing a preprocessing SNARK
+//! The verifier in this preprocessing SNARK maintains a commitment to R1CS matrices. This is beneficial when using a
+//! polynomial commitment scheme in which the verifier's costs is succinct.
+//! This code includes experimental optimizations to reduce runtimes and proof sizes.
+use crate::{
+  digest::{DigestComputer, SimpleDigestible},
+  errors::NovaError,
+  r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness},
+  spartan::{
+    math::Math,
+    polys::{
+      eq::EqPolynomial,
+      identity::IdentityPolynomial,
+      multilinear::MultilinearPolynomial,
+      power::PowPolynomial,
+      univariate::{CompressedUniPoly, UniPoly},
+    },
+    powers,
+    sumcheck::{
+      engine::{
+        InnerSumcheckInstance, MemorySumcheckInstance, OuterSumcheckInstance, SumcheckEngine,
+        WitnessBoundSumcheck,
+      },
+      SumcheckProof,
+    },
+    PolyEvalInstance, PolyEvalWitness, SparsePolynomial,
+  },
+  traits::{
+    commitment::{CommitmentEngineTrait, CommitmentTrait, Len},
+    evaluation::EvaluationEngineTrait,
+    snark::{DigestHelperTrait, RelaxedR1CSSNARKTrait},
+    Engine, TranscriptEngineTrait, TranscriptReprTrait,
+  },
+  zip_with, Commitment, CommitmentKey, CompressedCommitment,
+};
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use core::cmp::max;
+use ff::{Field, PrimeField};
+use itertools::Itertools as _;
+use once_cell::sync::OnceCell;
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+
+use super::polys::masked_eq::MaskedEqPolynomial;
+
+fn padded<E: Engine>(v: &[E::Scalar], n: usize, e: &E::Scalar) -> Vec<E::Scalar> {
+  let mut v_padded = vec![*e; n];
+  v_padded[..v.len()].copy_from_slice(v);
+  v_padded
+}
+
+/// A type that holds `R1CSShape` in a form amenable to memory checking
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as PrimeField>::Repr: Abomonation)]
+pub struct R1CSShapeSparkRepr<E: Engine> {
+  pub(in crate::spartan) N: usize, // size of the vectors
+
+  // dense representation
+  #[abomonate_with(Vec<<E::Scalar as PrimeField>::Repr>)]
+  pub(in crate::spartan) row: Vec<E::Scalar>,
+  #[abomonate_with(Vec<<E::Scalar as PrimeField>::Repr>)]
+  pub(in crate::spartan) col: Vec<E::Scalar>,
+  #[abomonate_with(Vec<<E::Scalar as PrimeField>::Repr>)]
+  pub(in crate::spartan) val_A: Vec<E::Scalar>,
+  #[abomonate_with(Vec<<E::Scalar as PrimeField>::Repr>)]
+  pub(in crate::spartan) val_B: Vec<E::Scalar>,
+  #[abomonate_with(Vec<<E::Scalar as PrimeField>::Repr>)]
+  pub(in crate::spartan) val_C: Vec<E::Scalar>,
+
+  // timestamp polynomials
+  #[abomonate_with(Vec<<E::Scalar as PrimeField>::Repr>)]
+  pub(in crate::spartan) ts_row: Vec<E::Scalar>,
+  #[abomonate_with(Vec<<E::Scalar as PrimeField>::Repr>)]
+  pub(in crate::spartan) ts_col: Vec<E::Scalar>,
+}
+
+/// A type that holds a commitment to a sparse polynomial
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as PrimeField>::Repr: Abomonation)]
+pub struct R1CSShapeSparkCommitment<E: Engine> {
+  pub(in crate::spartan) N: usize, // size of each vector
+
+  // commitments to the dense representation
+  pub(in crate::spartan) comm_row: Commitment<E>,
+  pub(in crate::spartan) comm_col: Commitment<E>,
+  pub(in crate::spartan) comm_val_A: Commitment<E>,
+  pub(in crate::spartan) comm_val_B: Commitment<E>,
+  pub(in crate::spartan) comm_val_C: Commitment<E>,
+
+  // commitments to the timestamp polynomials
+  pub(in crate::spartan) comm_ts_row: Commitment<E>,
+  pub(in crate::spartan) comm_ts_col: Commitment<E>,
+}
+
+impl<E: Engine> TranscriptReprTrait<E::GE> for R1CSShapeSparkCommitment<E> {
+  fn to_transcript_bytes(&self) -> Vec<u8> {
+    [
+      self.comm_row,
+      self.comm_col,
+      self.comm_val_A,
+      self.comm_val_B,
+      self.comm_val_C,
+      self.comm_ts_row,
+      self.comm_ts_col,
+    ]
+    .as_slice()
+    .to_transcript_bytes()
+  }
+}
+
+impl<E: Engine> R1CSShapeSparkRepr<E> {
+  /// represents `R1CSShape` in a Spark-friendly format amenable to memory checking
+  pub fn new(S: &R1CSShape<E>) -> Self {
+    let N = {
+      let total_nz = S.A.len() + S.B.len() + S.C.len();
+      max(total_nz, max(2 * S.num_vars, S.num_cons)).next_power_of_two()
+    };
+
+    // we make col lookup into the last entry of z, so we commit to zeros
+    let (mut row, mut col, mut val_A, mut val_B, mut val_C) = (
+      vec![0; N],
+      vec![N - 1; N],
+      vec![E::Scalar::ZERO; N],
+      vec![E::Scalar::ZERO; N],
+      vec![E::Scalar::ZERO; N],
+    );
+
+    for (i, entry) in S.A.iter().enumerate() {
+      let (r, c, v) = entry;
+      row[i] = r;
+      col[i] = c;
+      val_A[i] = v;
+    }
+
+    let b_offset = S.A.len();
+    for (i, entry) in S.B.iter().enumerate() {
+      let (r, c, v) = entry;
+      row[b_offset + i] = r;
+      col[b_offset + i] = c;
+      val_B[b_offset + i] = v;
+    }
+
+    let c_offset = S.A.len() + S.B.len();
+    for (i, entry) in S.C.iter().enumerate() {
+      let (r, c, v) = entry;
+      row[c_offset + i] = r;
+      col[c_offset + i] = c;
+      val_C[c_offset + i] = v;
+    }
+
+    // timestamp calculation routine
+    let timestamp_calc = |num_ops: usize, num_cells: usize, addr_trace: &[usize]| -> Vec<usize> {
+      let mut ts = vec![0usize; num_cells];
+
+      assert!(num_ops >= addr_trace.len());
+      for addr in addr_trace {
+        assert!(*addr < num_cells);
+        ts[*addr] += 1;
+      }
+      ts
+    };
+
+    // timestamp polynomials for row
+    let (ts_row, ts_col) =
+      rayon::join(|| timestamp_calc(N, N, &row), || timestamp_calc(N, N, &col));
+
+    // a routine to turn a vector of usize into a vector scalars
+    let to_vec_scalar = |v: &[usize]| -> Vec<E::Scalar> {
+      v.iter()
+        .map(|x| E::Scalar::from(*x as u64))
+        .collect::<Vec<_>>()
+    };
+
+    Self {
+      N,
+
+      // dense representation
+      row: to_vec_scalar(&row),
+      col: to_vec_scalar(&col),
+      val_A,
+      val_B,
+      val_C,
+
+      // timestamp polynomials
+      ts_row: to_vec_scalar(&ts_row),
+      ts_col: to_vec_scalar(&ts_col),
+    }
+  }
+
+  pub(in crate::spartan) fn commit(&self, ck: &CommitmentKey<E>) -> R1CSShapeSparkCommitment<E> {
+    let comm_vec: Vec<Commitment<E>> = [
+      &self.row,
+      &self.col,
+      &self.val_A,
+      &self.val_B,
+      &self.val_C,
+      &self.ts_row,
+      &self.ts_col,
+    ]
+    .par_iter()
+    .map(|v| E::CE::commit(ck, v))
+    .collect();
+
+    R1CSShapeSparkCommitment {
+      N: self.row.len(),
+      comm_row: comm_vec[0],
+      comm_col: comm_vec[1],
+      comm_val_A: comm_vec[2],
+      comm_val_B: comm_vec[3],
+      comm_val_C: comm_vec[4],
+      comm_ts_row: comm_vec[5],
+      comm_ts_col: comm_vec[6],
+    }
+  }
+
+  // computes evaluation oracles
+  fn evaluation_oracles(
+    &self,
+    S: &R1CSShape<E>,
+    r_x: &E::Scalar,
+    z: &[E::Scalar],
+  ) -> (
+    Vec<E::Scalar>,
+    Vec<E::Scalar>,
+    Vec<E::Scalar>,
+    Vec<E::Scalar>,
+  ) {
+    let mem_row = PowPolynomial::new(r_x, self.N.log_2()).evals();
+    let mem_col = padded::<E>(z, self.N, &E::Scalar::ZERO);
+
+    let (L_row, L_col) = {
+      let mut L_row = vec![mem_row[0]; self.N]; // we place mem_row[0] since resized row is appended with 0s
+      let mut L_col = vec![mem_col[self.N - 1]; self.N]; // we place mem_col[N-1] since resized col is appended with N-1
+
+      for (i, (val_r, val_c)) in S
+        .A
+        .iter()
+        .chain(S.B.iter())
+        .chain(S.C.iter())
+        .map(|(r, c, _)| (mem_row[r], mem_col[c]))
+        .enumerate()
+      {
+        L_row[i] = val_r;
+        L_col[i] = val_c;
+      }
+      (L_row, L_col)
+    };
+
+    (mem_row, mem_col, L_row, L_col)
+  }
+}
+
+/// A type that represents the prover's key
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as PrimeField>::Repr: Abomonation)]
+pub struct ProverKey<E: Engine, EE: EvaluationEngineTrait<E>> {
+  pk_ee: EE::ProverKey,
+  S_repr: R1CSShapeSparkRepr<E>,
+  S_comm: R1CSShapeSparkCommitment<E>,
+  #[abomonate_with(<E::Scalar as PrimeField>::Repr)]
+  vk_digest: E::Scalar, // digest of verifier's key
+}
+
+/// A type that represents the verifier's key
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as PrimeField>::Repr: Abomonation)]
+pub struct VerifierKey<E: Engine, EE: EvaluationEngineTrait<E>> {
+  num_cons: usize,
+  num_vars: usize,
+  vk_ee: EE::VerifierKey,
+  S_comm: R1CSShapeSparkCommitment<E>,
+  #[abomonation_skip]
+  #[serde(skip, default = "OnceCell::new")]
+  digest: OnceCell<E::Scalar>,
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> SimpleDigestible for VerifierKey<E, EE> {}
+
+/// A succinct proof of knowledge of a witness to a relaxed R1CS instance
+/// The proof is produced using Spartan's combination of the sum-check and
+/// the commitment to a vector viewed as a polynomial commitment
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct RelaxedR1CSSNARK<E: Engine, EE: EvaluationEngineTrait<E>> {
+  // commitment to oracles: the first three are for Az, Bz, Cz,
+  // and the last two are for memory reads
+  comm_Az: CompressedCommitment<E>,
+  comm_Bz: CompressedCommitment<E>,
+  comm_Cz: CompressedCommitment<E>,
+  comm_L_row: CompressedCommitment<E>,
+  comm_L_col: CompressedCommitment<E>,
+
+  // commitments to aid the memory checks
+  comm_t_plus_r_inv_row: CompressedCommitment<E>,
+  comm_w_plus_r_inv_row: CompressedCommitment<E>,
+  comm_t_plus_r_inv_col: CompressedCommitment<E>,
+  comm_w_plus_r_inv_col: CompressedCommitment<E>,
+
+  // claims about Az, Bz, and Cz polynomials
+  eval_Az_at_tau: E::Scalar,
+  eval_Bz_at_tau: E::Scalar,
+  eval_Cz_at_tau: E::Scalar,
+
+  // sum-check
+  sc: SumcheckProof<E>,
+
+  // claims from the end of sum-check
+  eval_Az: E::Scalar,
+  eval_Bz: E::Scalar,
+  eval_Cz: E::Scalar,
+  eval_E: E::Scalar,
+  eval_L_row: E::Scalar,
+  eval_L_col: E::Scalar,
+  eval_val_A: E::Scalar,
+  eval_val_B: E::Scalar,
+  eval_val_C: E::Scalar,
+
+  eval_W: E::Scalar,
+
+  eval_t_plus_r_inv_row: E::Scalar,
+  eval_row: E::Scalar, // address
+  eval_w_plus_r_inv_row: E::Scalar,
+  eval_ts_row: E::Scalar,
+
+  eval_t_plus_r_inv_col: E::Scalar,
+  eval_col: E::Scalar, // address
+  eval_w_plus_r_inv_col: E::Scalar,
+  eval_ts_col: E::Scalar,
+
+  // a PCS evaluation argument
+  eval_arg: EE::EvaluationArgument,
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> RelaxedR1CSSNARK<E, EE>
+where
+  <E::Scalar as PrimeField>::Repr: Abomonation,
+{
+  fn prove_helper<T1, T2, T3, T4>(
+    mem: &mut T1,
+    outer: &mut T2,
+    inner: &mut T3,
+    witness: &mut T4,
+    transcript: &mut E::TE,
+  ) -> Result<
+    (
+      SumcheckProof<E>,
+      Vec<E::Scalar>,
+      Vec<Vec<E::Scalar>>,
+      Vec<Vec<E::Scalar>>,
+      Vec<Vec<E::Scalar>>,
+      Vec<Vec<E::Scalar>>,
+    ),
+    NovaError,
+  >
+  where
+    T1: SumcheckEngine<E>,
+    T2: SumcheckEngine<E>,
+    T3: SumcheckEngine<E>,
+    T4: SumcheckEngine<E>,
+  {
+    // sanity checks
+    assert_eq!(mem.size(), outer.size());
+    assert_eq!(mem.size(), inner.size());
+    assert_eq!(mem.size(), witness.size());
+    assert_eq!(mem.degree(), outer.degree());
+    assert_eq!(mem.degree(), inner.degree());
+    assert_eq!(mem.degree(), witness.degree());
+
+    // these claims are already added to the transcript, so we do not need to add
+    let claims = mem
+      .initial_claims()
+      .into_iter()
+      .chain(outer.initial_claims())
+      .chain(inner.initial_claims())
+      .chain(witness.initial_claims())
+      .collect::<Vec<E::Scalar>>();
+
+    let s = transcript.squeeze(b"r")?;
+    let coeffs = powers::<E>(&s, claims.len());
+
+    // compute the joint claim
+    let claim = zip_with!((claims.iter(), coeffs.iter()), |c_1, c_2| *c_1 * c_2).sum();
+
+    let mut e = claim;
+    let mut r: Vec<E::Scalar> = Vec::new();
+    let mut cubic_polys: Vec<CompressedUniPoly<E::Scalar>> = Vec::new();
+    let num_rounds = mem.size().log_2();
+    for _ in 0..num_rounds {
+      let ((evals_mem, evals_outer), (evals_inner, evals_witness)) = rayon::join(
+        || rayon::join(|| mem.evaluation_points(), || outer.evaluation_points()),
+        || rayon::join(|| inner.evaluation_points(), || witness.evaluation_points()),
+      );
+
+      let evals: Vec<Vec<E::Scalar>> = evals_mem
+        .into_iter()
+        .chain(evals_outer.into_iter())
+        .chain(evals_inner.into_iter())
+        .chain(evals_witness.into_iter())
+        .collect::<Vec<Vec<E::Scalar>>>();
+      assert_eq!(evals.len(), claims.len());
+
+      let evals_combined_0 = (0..evals.len()).map(|i| evals[i][0] * coeffs[i]).sum();
+      let evals_combined_2 = (0..evals.len()).map(|i| evals[i][1] * coeffs[i]).sum();
+      let evals_combined_3 = (0..evals.len()).map(|i| evals[i][2] * coeffs[i]).sum();
+
+      let evals = vec![
+        evals_combined_0,
+        e - evals_combined_0,
+        evals_combined_2,
+        evals_combined_3,
+      ];
+      let poly = UniPoly::from_evals(&evals);
+
+      // append the prover's message to the transcript
+      transcript.absorb(b"p", &poly);
+
+      // derive the verifier's challenge for the next round
+      let r_i = transcript.squeeze(b"c")?;
+      r.push(r_i);
+
+      let _ = rayon::join(
+        || rayon::join(|| mem.bound(&r_i), || outer.bound(&r_i)),
+        || rayon::join(|| inner.bound(&r_i), || witness.bound(&r_i)),
+      );
+
+      e = poly.evaluate(&r_i);
+      cubic_polys.push(poly.compress());
+    }
+
+    let mem_claims = mem.final_claims();
+    let outer_claims = outer.final_claims();
+    let inner_claims = inner.final_claims();
+    let witness_claims = witness.final_claims();
+
+    Ok((
+      SumcheckProof::new(cubic_polys),
+      r,
+      mem_claims,
+      outer_claims,
+      inner_claims,
+      witness_claims,
+    ))
+  }
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> VerifierKey<E, EE> {
+  fn new(
+    num_cons: usize,
+    num_vars: usize,
+    S_comm: R1CSShapeSparkCommitment<E>,
+    vk_ee: EE::VerifierKey,
+  ) -> Self {
+    Self {
+      num_cons,
+      num_vars,
+      S_comm,
+      vk_ee,
+      digest: Default::default(),
+    }
+  }
+}
+impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for VerifierKey<E, EE> {
+  /// Returns the digest of the verifier's key
+  fn digest(&self) -> E::Scalar {
+    self
+      .digest
+      .get_or_try_init(|| {
+        let dc = DigestComputer::new(self);
+        dc.digest()
+      })
+      .cloned()
+      .expect("Failure to retrieve digest!")
+  }
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> RelaxedR1CSSNARKTrait<E> for RelaxedR1CSSNARK<E, EE>
+where
+  <E::Scalar as PrimeField>::Repr: Abomonation,
+{
+  type ProverKey = ProverKey<E, EE>;
+  type VerifierKey = VerifierKey<E, EE>;
+
+  fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize> {
+    Box::new(|shape: &R1CSShape<E>| -> usize {
+      // the commitment key should be large enough to commit to the R1CS matrices
+      shape.A.len() + shape.B.len() + shape.C.len()
+    })
+  }
+
+  fn setup(
+    ck: &CommitmentKey<E>,
+    S: &R1CSShape<E>,
+  ) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError> {
+    // check the provided commitment key meets minimal requirements
+    if ck.length() < Self::ck_floor()(S) {
+      return Err(NovaError::InvalidCommitmentKeyLength);
+    }
+    let (pk_ee, vk_ee) = EE::setup(ck);
+
+    // pad the R1CS matrices
+    let S = S.pad();
+
+    let S_repr = R1CSShapeSparkRepr::new(&S);
+    let S_comm = S_repr.commit(ck);
+
+    let vk = VerifierKey::new(S.num_cons, S.num_vars, S_comm.clone(), vk_ee);
+
+    let pk = ProverKey {
+      pk_ee,
+      S_repr,
+      S_comm,
+      vk_digest: vk.digest(),
+    };
+
+    Ok((pk, vk))
+  }
+
+  /// produces a succinct proof of satisfiability of a `RelaxedR1CS` instance
+  #[tracing::instrument(skip_all, name = "PPSNARK::prove")]
+  fn prove(
+    ck: &CommitmentKey<E>,
+    pk: &Self::ProverKey,
+    S: &R1CSShape<E>,
+    U: &RelaxedR1CSInstance<E>,
+    W: &RelaxedR1CSWitness<E>,
+  ) -> Result<Self, NovaError> {
+    // pad the R1CSShape
+    let S = S.pad();
+    // sanity check that R1CSShape has all required size characteristics
+    assert!(S.is_regular_shape());
+
+    let W = W.pad(&S); // pad the witness
+    let mut transcript = E::TE::new(b"RelaxedR1CSSNARK");
+
+    // append the verifier key (which includes commitment to R1CS matrices) and the RelaxedR1CSInstance to the transcript
+    transcript.absorb(b"vk", &pk.vk_digest);
+    transcript.absorb(b"U", U);
+
+    // compute the full satisfying assignment by concatenating W.W, U.u, and U.X
+    let z = [W.W.clone(), vec![U.u], U.X.clone()].concat();
+
+    // compute Az, Bz, Cz
+    let (mut Az, mut Bz, mut Cz) = S.multiply_vec(&z)?;
+
+    // commit to Az, Bz, Cz
+    let (comm_Az, (comm_Bz, comm_Cz)) = rayon::join(
+      || E::CE::commit(ck, &Az),
+      || rayon::join(|| E::CE::commit(ck, &Bz), || E::CE::commit(ck, &Cz)),
+    );
+
+    transcript.absorb(b"c", &[comm_Az, comm_Bz, comm_Cz].as_slice());
+
+    // number of rounds of sum-check
+    let num_rounds_sc = pk.S_repr.N.log_2();
+    let tau = transcript.squeeze(b"t")?;
+    let tau_coords = PowPolynomial::new(&tau, num_rounds_sc).coordinates();
+
+    // (1) send commitments to Az, Bz, and Cz along with their evaluations at tau
+    let (Az, Bz, Cz, W, E) = {
+      Az.resize(pk.S_repr.N, E::Scalar::ZERO);
+      Bz.resize(pk.S_repr.N, E::Scalar::ZERO);
+      Cz.resize(pk.S_repr.N, E::Scalar::ZERO);
+      let E = padded::<E>(&W.E, pk.S_repr.N, &E::Scalar::ZERO);
+      let W = padded::<E>(&W.W, pk.S_repr.N, &E::Scalar::ZERO);
+
+      (Az, Bz, Cz, W, E)
+    };
+    let (eval_Az_at_tau, eval_Bz_at_tau, eval_Cz_at_tau) = {
+      let evals_at_tau = [&Az, &Bz, &Cz]
+        .into_par_iter()
+        .map(|p| MultilinearPolynomial::evaluate_with(p, &tau_coords))
+        .collect::<Vec<E::Scalar>>();
+      (evals_at_tau[0], evals_at_tau[1], evals_at_tau[2])
+    };
+
+    // (2) send commitments to the following two oracles
+    // L_row(i) = eq(tau, row(i)) for all i
+    // L_col(i) = z(col(i)) for all i
+    let (mem_row, mem_col, L_row, L_col) = pk.S_repr.evaluation_oracles(&S, &tau, &z);
+    let (comm_L_row, comm_L_col) =
+      rayon::join(|| E::CE::commit(ck, &L_row), || E::CE::commit(ck, &L_col));
+
+    // since all the three polynomials are opened at tau,
+    // we can combine them into a single polynomial opened at tau
+    let eval_vec = vec![eval_Az_at_tau, eval_Bz_at_tau, eval_Cz_at_tau];
+
+    // absorb the claimed evaluations into the transcript
+    transcript.absorb(b"e", &eval_vec.as_slice());
+    // absorb commitments to L_row and L_col in the transcript
+    transcript.absorb(b"e", &vec![comm_L_row, comm_L_col].as_slice());
+    let comm_vec = vec![comm_Az, comm_Bz, comm_Cz];
+    let poly_vec = vec![&Az, &Bz, &Cz];
+    let c = transcript.squeeze(b"c")?;
+    let w: PolyEvalWitness<E> = PolyEvalWitness::batch(&poly_vec, &c);
+    let u: PolyEvalInstance<E> = PolyEvalInstance::batch(&comm_vec, &tau_coords, &eval_vec, &c);
+
+    // we now need to prove three claims
+    // (1) 0 = \sum_x poly_tau(x) * (poly_Az(x) * poly_Bz(x) - poly_uCz_E(x)), and eval_Az_at_tau + r * eval_Bz_at_tau + r^2 * eval_Cz_at_tau = (Az+r*Bz+r^2*Cz)(tau)
+    // (2) eval_Az_at_tau + c * eval_Bz_at_tau + c^2 * eval_Cz_at_tau = \sum_y L_row(y) * (val_A(y) + c * val_B(y) + c^2 * val_C(y)) * L_col(y)
+    // (3) L_row(i) = eq(tau, row(i)) and L_col(i) = z(col(i))
+    let gamma = transcript.squeeze(b"g")?;
+    let r = transcript.squeeze(b"r")?;
+
+    let ((mut outer_sc_inst, mut inner_sc_inst), mem_res) = rayon::join(
+      || {
+        // a sum-check instance to prove the first claim
+        let outer_sc_inst = OuterSumcheckInstance::new(
+          PowPolynomial::new(&tau, num_rounds_sc).evals(),
+          Az.clone(),
+          Bz.clone(),
+          (0..Cz.len())
+            .map(|i| U.u * Cz[i] + E[i])
+            .collect::<Vec<E::Scalar>>(),
+          w.p.clone(), // Mz = Az + r * Bz + r^2 * Cz
+          &u.e,        // eval_Az_at_tau + r * eval_Az_at_tau + r^2 * eval_Cz_at_tau
+        );
+
+        // a sum-check instance to prove the second claim
+        let val = pk
+          .S_repr
+          .val_A
+          .par_iter()
+          .zip_eq(pk.S_repr.val_B.par_iter())
+          .zip_eq(pk.S_repr.val_C.par_iter())
+          .map(|((v_a, v_b), v_c)| *v_a + c * *v_b + c * c * *v_c)
+          .collect::<Vec<E::Scalar>>();
+        let inner_sc_inst = InnerSumcheckInstance {
+          claim: eval_Az_at_tau + c * eval_Bz_at_tau + c * c * eval_Cz_at_tau,
+          poly_L_row: MultilinearPolynomial::new(L_row.clone()),
+          poly_L_col: MultilinearPolynomial::new(L_col.clone()),
+          poly_val: MultilinearPolynomial::new(val),
+        };
+
+        (outer_sc_inst, inner_sc_inst)
+      },
+      || {
+        // a third sum-check instance to prove the read-only memory claim
+        // we now need to prove that L_row and L_col are well-formed
+
+        // hash the tuples of (addr,val) memory contents and read responses into a single field element using `hash_func`
+
+        let (comm_mem_oracles, mem_oracles, mem_aux) =
+          MemorySumcheckInstance::<E>::compute_oracles(
+            ck,
+            &r,
+            &gamma,
+            &mem_row,
+            &pk.S_repr.row,
+            &L_row,
+            &pk.S_repr.ts_row,
+            &mem_col,
+            &pk.S_repr.col,
+            &L_col,
+            &pk.S_repr.ts_col,
+          )?;
+        // absorb the commitments
+        transcript.absorb(b"l", &comm_mem_oracles.as_slice());
+
+        let rho = transcript.squeeze(b"r")?;
+        let poly_eq = MultilinearPolynomial::new(PowPolynomial::new(&rho, num_rounds_sc).evals());
+
+        Ok::<_, NovaError>((
+          MemorySumcheckInstance::new(
+            mem_oracles.clone(),
+            mem_aux,
+            poly_eq.Z,
+            pk.S_repr.ts_row.clone(),
+            pk.S_repr.ts_col.clone(),
+          ),
+          comm_mem_oracles,
+          mem_oracles,
+        ))
+      },
+    );
+
+    let (mut mem_sc_inst, comm_mem_oracles, mem_oracles) = mem_res?;
+
+    let mut witness_sc_inst = WitnessBoundSumcheck::new(tau, W.clone(), S.num_vars);
+
+    let (sc, rand_sc, claims_mem, claims_outer, claims_inner, claims_witness) = Self::prove_helper(
+      &mut mem_sc_inst,
+      &mut outer_sc_inst,
+      &mut inner_sc_inst,
+      &mut witness_sc_inst,
+      &mut transcript,
+    )?;
+
+    // claims from the end of the sum-check
+    let eval_Az = claims_outer[0][0];
+    let eval_Bz = claims_outer[0][1];
+
+    let eval_L_row = claims_inner[0][0];
+    let eval_L_col = claims_inner[0][1];
+
+    let eval_t_plus_r_inv_row = claims_mem[0][0];
+    let eval_w_plus_r_inv_row = claims_mem[0][1];
+    let eval_ts_row = claims_mem[0][2];
+
+    let eval_t_plus_r_inv_col = claims_mem[1][0];
+    let eval_w_plus_r_inv_col = claims_mem[1][1];
+    let eval_ts_col = claims_mem[1][2];
+    let eval_W = claims_witness[0][0];
+
+    // compute the remaining claims that did not come for free from the sum-check prover
+    let (eval_Cz, eval_E, eval_val_A, eval_val_B, eval_val_C, eval_row, eval_col) = {
+      let e = [
+        &Cz,
+        &E,
+        &pk.S_repr.val_A,
+        &pk.S_repr.val_B,
+        &pk.S_repr.val_C,
+        &pk.S_repr.row,
+        &pk.S_repr.col,
+      ]
+      .into_par_iter()
+      .map(|p| MultilinearPolynomial::evaluate_with(p, &rand_sc))
+      .collect::<Vec<E::Scalar>>();
+      (e[0], e[1], e[2], e[3], e[4], e[5], e[6])
+    };
+
+    // all the evaluations are at rand_sc, we can fold them into one claim
+    let eval_vec = vec![
+      eval_W,
+      eval_Az,
+      eval_Bz,
+      eval_Cz,
+      eval_E,
+      eval_L_row,
+      eval_L_col,
+      eval_val_A,
+      eval_val_B,
+      eval_val_C,
+      eval_t_plus_r_inv_row,
+      eval_row,
+      eval_w_plus_r_inv_row,
+      eval_ts_row,
+      eval_t_plus_r_inv_col,
+      eval_col,
+      eval_w_plus_r_inv_col,
+      eval_ts_col,
+    ];
+
+    let comm_vec = [
+      U.comm_W,
+      comm_Az,
+      comm_Bz,
+      comm_Cz,
+      U.comm_E,
+      comm_L_row,
+      comm_L_col,
+      pk.S_comm.comm_val_A,
+      pk.S_comm.comm_val_B,
+      pk.S_comm.comm_val_C,
+      comm_mem_oracles[0],
+      pk.S_comm.comm_row,
+      comm_mem_oracles[1],
+      pk.S_comm.comm_ts_row,
+      comm_mem_oracles[2],
+      pk.S_comm.comm_col,
+      comm_mem_oracles[3],
+      pk.S_comm.comm_ts_col,
+    ];
+    let poly_vec = [
+      &W,
+      &Az,
+      &Bz,
+      &Cz,
+      &E,
+      &L_row,
+      &L_col,
+      &pk.S_repr.val_A,
+      &pk.S_repr.val_B,
+      &pk.S_repr.val_C,
+      mem_oracles[0].as_ref(),
+      &pk.S_repr.row,
+      mem_oracles[1].as_ref(),
+      &pk.S_repr.ts_row,
+      mem_oracles[2].as_ref(),
+      &pk.S_repr.col,
+      mem_oracles[3].as_ref(),
+      &pk.S_repr.ts_col,
+    ];
+    transcript.absorb(b"e", &eval_vec.as_slice()); // comm_vec is already in the transcript
+    let c = transcript.squeeze(b"c")?;
+    let w: PolyEvalWitness<E> = PolyEvalWitness::batch(&poly_vec, &c);
+    let u: PolyEvalInstance<E> = PolyEvalInstance::batch(&comm_vec, &rand_sc, &eval_vec, &c);
+
+    let eval_arg = EE::prove(ck, &pk.pk_ee, &mut transcript, &u.c, &w.p, &rand_sc, &u.e)?;
+
+    Ok(Self {
+      comm_Az: comm_Az.compress(),
+      comm_Bz: comm_Bz.compress(),
+      comm_Cz: comm_Cz.compress(),
+      comm_L_row: comm_L_row.compress(),
+      comm_L_col: comm_L_col.compress(),
+
+      comm_t_plus_r_inv_row: comm_mem_oracles[0].compress(),
+      comm_w_plus_r_inv_row: comm_mem_oracles[1].compress(),
+      comm_t_plus_r_inv_col: comm_mem_oracles[2].compress(),
+      comm_w_plus_r_inv_col: comm_mem_oracles[3].compress(),
+
+      eval_Az_at_tau,
+      eval_Bz_at_tau,
+      eval_Cz_at_tau,
+
+      sc,
+
+      eval_Az,
+      eval_Bz,
+      eval_Cz,
+      eval_E,
+      eval_L_row,
+      eval_L_col,
+      eval_val_A,
+      eval_val_B,
+      eval_val_C,
+
+      eval_W,
+
+      eval_t_plus_r_inv_row,
+      eval_row,
+      eval_w_plus_r_inv_row,
+      eval_ts_row,
+
+      eval_col,
+      eval_t_plus_r_inv_col,
+      eval_w_plus_r_inv_col,
+      eval_ts_col,
+
+      eval_arg,
+    })
+  }
+
+  /// verifies a proof of satisfiability of a `RelaxedR1CS` instance
+  fn verify(&self, vk: &Self::VerifierKey, U: &RelaxedR1CSInstance<E>) -> Result<(), NovaError> {
+    let mut transcript = E::TE::new(b"RelaxedR1CSSNARK");
+
+    // append the verifier key (including commitment to R1CS matrices) and the RelaxedR1CSInstance to the transcript
+    transcript.absorb(b"vk", &vk.digest());
+    transcript.absorb(b"U", U);
+
+    let comm_Az = Commitment::<E>::decompress(&self.comm_Az)?;
+    let comm_Bz = Commitment::<E>::decompress(&self.comm_Bz)?;
+    let comm_Cz = Commitment::<E>::decompress(&self.comm_Cz)?;
+    let comm_L_row = Commitment::<E>::decompress(&self.comm_L_row)?;
+    let comm_L_col = Commitment::<E>::decompress(&self.comm_L_col)?;
+    let comm_t_plus_r_inv_row = Commitment::<E>::decompress(&self.comm_t_plus_r_inv_row)?;
+    let comm_w_plus_r_inv_row = Commitment::<E>::decompress(&self.comm_w_plus_r_inv_row)?;
+    let comm_t_plus_r_inv_col = Commitment::<E>::decompress(&self.comm_t_plus_r_inv_col)?;
+    let comm_w_plus_r_inv_col = Commitment::<E>::decompress(&self.comm_w_plus_r_inv_col)?;
+
+    transcript.absorb(b"c", &[comm_Az, comm_Bz, comm_Cz].as_slice());
+
+    let num_rounds_sc = vk.S_comm.N.log_2();
+    let tau = transcript.squeeze(b"t")?;
+    let tau_coords = PowPolynomial::new(&tau, num_rounds_sc).coordinates();
+
+    // add claims about Az, Bz, and Cz to be checked later
+    // since all the three polynomials are opened at tau,
+    // we can combine them into a single polynomial opened at tau
+    let eval_vec = vec![
+      self.eval_Az_at_tau,
+      self.eval_Bz_at_tau,
+      self.eval_Cz_at_tau,
+    ];
+
+    transcript.absorb(b"e", &eval_vec.as_slice());
+
+    transcript.absorb(b"e", &vec![comm_L_row, comm_L_col].as_slice());
+    let comm_vec = vec![comm_Az, comm_Bz, comm_Cz];
+    let c = transcript.squeeze(b"c")?;
+    let u: PolyEvalInstance<E> = PolyEvalInstance::batch(&comm_vec, &tau_coords, &eval_vec, &c);
+    let claim = u.e;
+
+    let gamma = transcript.squeeze(b"g")?;
+
+    let r = transcript.squeeze(b"r")?;
+
+    transcript.absorb(
+      b"l",
+      &vec![
+        comm_t_plus_r_inv_row,
+        comm_w_plus_r_inv_row,
+        comm_t_plus_r_inv_col,
+        comm_w_plus_r_inv_col,
+      ]
+      .as_slice(),
+    );
+
+    let rho = transcript.squeeze(b"r")?;
+
+    let num_claims = 10;
+    let s = transcript.squeeze(b"r")?;
+    let coeffs = powers::<E>(&s, num_claims);
+    let claim = (coeffs[7] + coeffs[8]) * claim; // rest are zeros
+
+    // verify sc
+    let (claim_sc_final, rand_sc) = self.sc.verify(claim, num_rounds_sc, 3, &mut transcript)?;
+
+    // verify claim_sc_final
+    let claim_sc_final_expected = {
+      let rand_eq_bound_rand_sc = {
+        let poly_eq_coords = PowPolynomial::new(&rho, num_rounds_sc).coordinates();
+        EqPolynomial::new(poly_eq_coords).evaluate(&rand_sc)
+      };
+      let taus_coords = PowPolynomial::new(&tau, num_rounds_sc).coordinates();
+      let eq_tau = EqPolynomial::new(taus_coords);
+
+      let taus_bound_rand_sc = eq_tau.evaluate(&rand_sc);
+      let taus_masked_bound_rand_sc =
+        MaskedEqPolynomial::new(&eq_tau, vk.num_vars.log_2()).evaluate(&rand_sc);
+
+      let eval_t_plus_r_row = {
+        let eval_addr_row = IdentityPolynomial::new(num_rounds_sc).evaluate(&rand_sc);
+        let eval_val_row = taus_bound_rand_sc;
+        let eval_t = eval_addr_row + gamma * eval_val_row;
+        eval_t + r
+      };
+
+      let eval_w_plus_r_row = {
+        let eval_addr_row = self.eval_row;
+        let eval_val_row = self.eval_L_row;
+        let eval_w = eval_addr_row + gamma * eval_val_row;
+        eval_w + r
+      };
+
+      let eval_t_plus_r_col = {
+        let eval_addr_col = IdentityPolynomial::new(num_rounds_sc).evaluate(&rand_sc);
+
+        // memory contents is z, so we compute eval_Z from eval_W and eval_X
+        let eval_val_col = {
+          // rand_sc was padded, so we now remove the padding
+          let (factor, rand_sc_unpad) = {
+            let l = vk.S_comm.N.log_2() - (2 * vk.num_vars).log_2();
+
+            let mut factor = E::Scalar::ONE;
+            for r_p in rand_sc.iter().take(l) {
+              factor *= E::Scalar::ONE - r_p
+            }
+
+            let rand_sc_unpad = rand_sc[l..].to_vec();
+
+            (factor, rand_sc_unpad)
+          };
+
+          let eval_X = {
+            // constant term
+            let mut poly_X = vec![(0, U.u)];
+            //remaining inputs
+            poly_X.extend(
+              (0..U.X.len())
+                .map(|i| (i + 1, U.X[i]))
+                .collect::<Vec<(usize, E::Scalar)>>(),
+            );
+            SparsePolynomial::new(vk.num_vars.log_2(), poly_X).evaluate(&rand_sc_unpad[1..])
+          };
+
+          self.eval_W + factor * rand_sc_unpad[0] * eval_X
+        };
+        let eval_t = eval_addr_col + gamma * eval_val_col;
+        eval_t + r
+      };
+
+      let eval_w_plus_r_col = {
+        let eval_addr_col = self.eval_col;
+        let eval_val_col = self.eval_L_col;
+        let eval_w = eval_addr_col + gamma * eval_val_col;
+        eval_w + r
+      };
+
+      let claim_mem_final_expected: E::Scalar = coeffs[0]
+        * (self.eval_t_plus_r_inv_row - self.eval_w_plus_r_inv_row)
+        + coeffs[1] * (self.eval_t_plus_r_inv_col - self.eval_w_plus_r_inv_col)
+        + coeffs[2]
+          * (rand_eq_bound_rand_sc
+            * (self.eval_t_plus_r_inv_row * eval_t_plus_r_row - self.eval_ts_row))
+        + coeffs[3]
+          * (rand_eq_bound_rand_sc
+            * (self.eval_w_plus_r_inv_row * eval_w_plus_r_row - E::Scalar::ONE))
+        + coeffs[4]
+          * (rand_eq_bound_rand_sc
+            * (self.eval_t_plus_r_inv_col * eval_t_plus_r_col - self.eval_ts_col))
+        + coeffs[5]
+          * (rand_eq_bound_rand_sc
+            * (self.eval_w_plus_r_inv_col * eval_w_plus_r_col - E::Scalar::ONE));
+
+      let claim_outer_final_expected = coeffs[6]
+        * taus_bound_rand_sc
+        * (self.eval_Az * self.eval_Bz - U.u * self.eval_Cz - self.eval_E)
+        + coeffs[7] * taus_bound_rand_sc * (self.eval_Az + c * self.eval_Bz + c * c * self.eval_Cz);
+      let claim_inner_final_expected = coeffs[8]
+        * self.eval_L_row
+        * self.eval_L_col
+        * (self.eval_val_A + c * self.eval_val_B + c * c * self.eval_val_C);
+
+      let claim_witness_final_expected = coeffs[9] * taus_masked_bound_rand_sc * self.eval_W;
+
+      claim_mem_final_expected
+        + claim_outer_final_expected
+        + claim_inner_final_expected
+        + claim_witness_final_expected
+    };
+
+    if claim_sc_final_expected != claim_sc_final {
+      return Err(NovaError::InvalidSumcheckProof);
+    }
+
+    let eval_vec = vec![
+      self.eval_W,
+      self.eval_Az,
+      self.eval_Bz,
+      self.eval_Cz,
+      self.eval_E,
+      self.eval_L_row,
+      self.eval_L_col,
+      self.eval_val_A,
+      self.eval_val_B,
+      self.eval_val_C,
+      self.eval_t_plus_r_inv_row,
+      self.eval_row,
+      self.eval_w_plus_r_inv_row,
+      self.eval_ts_row,
+      self.eval_t_plus_r_inv_col,
+      self.eval_col,
+      self.eval_w_plus_r_inv_col,
+      self.eval_ts_col,
+    ];
+
+    let comm_vec = [
+      U.comm_W,
+      comm_Az,
+      comm_Bz,
+      comm_Cz,
+      U.comm_E,
+      comm_L_row,
+      comm_L_col,
+      vk.S_comm.comm_val_A,
+      vk.S_comm.comm_val_B,
+      vk.S_comm.comm_val_C,
+      comm_t_plus_r_inv_row,
+      vk.S_comm.comm_row,
+      comm_w_plus_r_inv_row,
+      vk.S_comm.comm_ts_row,
+      comm_t_plus_r_inv_col,
+      vk.S_comm.comm_col,
+      comm_w_plus_r_inv_col,
+      vk.S_comm.comm_ts_col,
+    ];
+    transcript.absorb(b"e", &eval_vec.as_slice()); // comm_vec is already in the transcript
+    let c = transcript.squeeze(b"c")?;
+    let u: PolyEvalInstance<E> = PolyEvalInstance::batch(&comm_vec, &rand_sc, &eval_vec, &c);
+
+    // verify
+    EE::verify(
+      &vk.vk_ee,
+      &mut transcript,
+      &u.c,
+      &rand_sc,
+      &u.e,
+      &self.eval_arg,
+    )?;
+
+    Ok(())
+  }
+}
+#[cfg(test)]
+mod tests {
+  use crate::provider::PallasEngine;
+
+  use super::*;
+  use ff::Field;
+  use pasta_curves::Fq as Scalar;
+
+  #[test]
+  fn test_padded() {
+    let mut rng = rand::thread_rng();
+    let e = Scalar::random(&mut rng);
+    let v: Vec<Scalar> = (0..10).map(|_| Scalar::random(&mut rng)).collect();
+    let n = 20;
+
+    let result = padded::<PallasEngine>(&v, n, &e);
+
+    assert_eq!(result.len(), n);
+    assert_eq!(&result[0..10], &v[..]);
+    assert!(result[10..].iter().all(|&i| i == e));
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/snark.rs.html b/docs/src/arecibo/spartan/snark.rs.html new file mode 100644 index 000000000..cbf408788 --- /dev/null +++ b/docs/src/arecibo/spartan/snark.rs.html @@ -0,0 +1,1121 @@ +snark.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+
//! This module implements `RelaxedR1CSSNARKTrait` using Spartan that is generic
+//! over the polynomial commitment and evaluation argument (i.e., a PCS)
+//! This version of Spartan does not use preprocessing so the verifier keeps the entire
+//! description of R1CS matrices. This is essentially optimal for the verifier when using
+//! an IPA-based polynomial commitment scheme.
+
+use crate::{
+  digest::{DigestComputer, SimpleDigestible},
+  errors::NovaError,
+  r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness, SparseMatrix},
+  spartan::{
+    compute_eval_table_sparse,
+    polys::{eq::EqPolynomial, multilinear::MultilinearPolynomial, multilinear::SparsePolynomial},
+    powers,
+    sumcheck::SumcheckProof,
+    PolyEvalInstance, PolyEvalWitness,
+  },
+  traits::{
+    evaluation::EvaluationEngineTrait,
+    snark::{DigestHelperTrait, RelaxedR1CSSNARKTrait},
+    Engine, TranscriptEngineTrait,
+  },
+  CommitmentKey,
+};
+
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use ff::Field;
+use itertools::Itertools as _;
+use once_cell::sync::OnceCell;
+
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+
+/// A type that represents the prover's key
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as ff::PrimeField>::Repr: Abomonation)]
+pub struct ProverKey<E: Engine, EE: EvaluationEngineTrait<E>> {
+  pk_ee: EE::ProverKey,
+  #[abomonate_with(<E::Scalar as ff::PrimeField>::Repr)]
+  vk_digest: E::Scalar, // digest of the verifier's key
+}
+
+/// A type that represents the verifier's key
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(where <E::Scalar as ff::PrimeField>::Repr: Abomonation)]
+pub struct VerifierKey<E: Engine, EE: EvaluationEngineTrait<E>> {
+  vk_ee: EE::VerifierKey,
+  S: R1CSShape<E>,
+  #[abomonation_skip]
+  #[serde(skip, default = "OnceCell::new")]
+  digest: OnceCell<E::Scalar>,
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> SimpleDigestible for VerifierKey<E, EE> {}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> VerifierKey<E, EE> {
+  fn new(shape: R1CSShape<E>, vk_ee: EE::VerifierKey) -> Self {
+    Self {
+      vk_ee,
+      S: shape,
+      digest: OnceCell::new(),
+    }
+  }
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> DigestHelperTrait<E> for VerifierKey<E, EE> {
+  /// Returns the digest of the verifier's key.
+  fn digest(&self) -> E::Scalar {
+    self
+      .digest
+      .get_or_try_init(|| {
+        let dc = DigestComputer::<E::Scalar, _>::new(self);
+        dc.digest()
+      })
+      .cloned()
+      .expect("Failure to retrieve digest!")
+  }
+}
+
+/// A succinct proof of knowledge of a witness to a relaxed R1CS instance
+/// The proof is produced using Spartan's combination of the sum-check and
+/// the commitment to a vector viewed as a polynomial commitment
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct RelaxedR1CSSNARK<E: Engine, EE: EvaluationEngineTrait<E>> {
+  sc_proof_outer: SumcheckProof<E>,
+  claims_outer: (E::Scalar, E::Scalar, E::Scalar),
+  eval_E: E::Scalar,
+  sc_proof_inner: SumcheckProof<E>,
+  eval_W: E::Scalar,
+  sc_proof_batch: SumcheckProof<E>,
+  evals_batch: Vec<E::Scalar>,
+  eval_arg: EE::EvaluationArgument,
+}
+
+impl<E: Engine, EE: EvaluationEngineTrait<E>> RelaxedR1CSSNARKTrait<E> for RelaxedR1CSSNARK<E, EE>
+where
+  <E::Scalar as ff::PrimeField>::Repr: Abomonation,
+{
+  type ProverKey = ProverKey<E, EE>;
+  type VerifierKey = VerifierKey<E, EE>;
+
+  fn setup(
+    ck: &CommitmentKey<E>,
+    S: &R1CSShape<E>,
+  ) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError> {
+    let (pk_ee, vk_ee) = EE::setup(ck);
+
+    let S = S.pad();
+
+    let vk: VerifierKey<E, EE> = VerifierKey::new(S, vk_ee);
+
+    let pk = ProverKey {
+      pk_ee,
+      vk_digest: vk.digest(),
+    };
+
+    Ok((pk, vk))
+  }
+
+  /// produces a succinct proof of satisfiability of a `RelaxedR1CS` instance
+  #[tracing::instrument(skip_all, name = "SNARK::prove")]
+  fn prove(
+    ck: &CommitmentKey<E>,
+    pk: &Self::ProverKey,
+    S: &R1CSShape<E>,
+    U: &RelaxedR1CSInstance<E>,
+    W: &RelaxedR1CSWitness<E>,
+  ) -> Result<Self, NovaError> {
+    // pad the R1CSShape
+    let S = S.pad();
+    // sanity check that R1CSShape has all required size characteristics
+    assert!(S.is_regular_shape());
+
+    let W = W.pad(&S); // pad the witness
+    let mut transcript = E::TE::new(b"RelaxedR1CSSNARK");
+
+    // append the digest of vk (which includes R1CS matrices) and the RelaxedR1CSInstance to the transcript
+    transcript.absorb(b"vk", &pk.vk_digest);
+    transcript.absorb(b"U", U);
+
+    // compute the full satisfying assignment by concatenating W.W, U.u, and U.X
+    let mut z = [W.W.clone(), vec![U.u], U.X.clone()].concat();
+
+    let (num_rounds_x, num_rounds_y) = (
+      usize::try_from(S.num_cons.ilog2()).unwrap(),
+      (usize::try_from(S.num_vars.ilog2()).unwrap() + 1),
+    );
+
+    // outer sum-check
+    let tau = (0..num_rounds_x)
+      .map(|_i| transcript.squeeze(b"t"))
+      .collect::<Result<EqPolynomial<_>, NovaError>>()?;
+
+    let mut poly_tau = MultilinearPolynomial::new(tau.evals());
+    let (mut poly_Az, mut poly_Bz, poly_Cz, mut poly_uCz_E) = {
+      let (poly_Az, poly_Bz, poly_Cz) = S.multiply_vec(&z)?;
+      let poly_uCz_E = (0..S.num_cons)
+        .map(|i| U.u * poly_Cz[i] + W.E[i])
+        .collect::<Vec<E::Scalar>>();
+      (
+        MultilinearPolynomial::new(poly_Az),
+        MultilinearPolynomial::new(poly_Bz),
+        MultilinearPolynomial::new(poly_Cz),
+        MultilinearPolynomial::new(poly_uCz_E),
+      )
+    };
+
+    let comb_func_outer =
+      |poly_A_comp: &E::Scalar,
+       poly_B_comp: &E::Scalar,
+       poly_C_comp: &E::Scalar,
+       poly_D_comp: &E::Scalar|
+       -> E::Scalar { *poly_A_comp * (*poly_B_comp * *poly_C_comp - *poly_D_comp) };
+    let (sc_proof_outer, r_x, claims_outer) = SumcheckProof::prove_cubic_with_additive_term(
+      &E::Scalar::ZERO, // claim is zero
+      num_rounds_x,
+      &mut poly_tau,
+      &mut poly_Az,
+      &mut poly_Bz,
+      &mut poly_uCz_E,
+      comb_func_outer,
+      &mut transcript,
+    )?;
+
+    // claims from the end of sum-check
+    let (claim_Az, claim_Bz): (E::Scalar, E::Scalar) = (claims_outer[1], claims_outer[2]);
+    let claim_Cz = poly_Cz.evaluate(&r_x);
+    let eval_E = MultilinearPolynomial::new(W.E.clone()).evaluate(&r_x);
+    transcript.absorb(
+      b"claims_outer",
+      &[claim_Az, claim_Bz, claim_Cz, eval_E].as_slice(),
+    );
+
+    // inner sum-check
+    let r = transcript.squeeze(b"r")?;
+    let claim_inner_joint = claim_Az + r * claim_Bz + r * r * claim_Cz;
+
+    let poly_ABC = {
+      // compute the initial evaluation table for R(\tau, x)
+      let evals_rx = EqPolynomial::evals_from_points(&r_x.clone());
+
+      let (evals_A, evals_B, evals_C) = compute_eval_table_sparse(&S, &evals_rx);
+
+      assert_eq!(evals_A.len(), evals_B.len());
+      assert_eq!(evals_A.len(), evals_C.len());
+      (0..evals_A.len())
+        .into_par_iter()
+        .map(|i| evals_A[i] + r * evals_B[i] + r * r * evals_C[i])
+        .collect::<Vec<E::Scalar>>()
+    };
+
+    let poly_z = {
+      z.resize(S.num_vars * 2, E::Scalar::ZERO);
+      z
+    };
+
+    let comb_func = |poly_A_comp: &E::Scalar, poly_B_comp: &E::Scalar| -> E::Scalar {
+      *poly_A_comp * *poly_B_comp
+    };
+    let (sc_proof_inner, r_y, _claims_inner) = SumcheckProof::prove_quad(
+      &claim_inner_joint,
+      num_rounds_y,
+      &mut MultilinearPolynomial::new(poly_ABC),
+      &mut MultilinearPolynomial::new(poly_z),
+      comb_func,
+      &mut transcript,
+    )?;
+
+    // Add additional claims about W and E polynomials to the list from CC
+    // We will reduce a vector of claims of evaluations at different points into claims about them at the same point.
+    // For example, eval_W =? W(r_y[1..]) and eval_E =? E(r_x) into
+    // two claims: eval_W_prime =? W(rz) and eval_E_prime =? E(rz)
+    // We can them combine the two into one: eval_W_prime + gamma * eval_E_prime =? (W + gamma*E)(rz),
+    // where gamma is a public challenge
+    // Since commitments to W and E are homomorphic, the verifier can compute a commitment
+    // to the batched polynomial.
+    let eval_W = MultilinearPolynomial::evaluate_with(&W.W, &r_y[1..]);
+
+    let w_vec = vec![PolyEvalWitness { p: W.W }, PolyEvalWitness { p: W.E }];
+    let u_vec = vec![
+      PolyEvalInstance {
+        c: U.comm_W,
+        x: r_y[1..].to_vec(),
+        e: eval_W,
+      },
+      PolyEvalInstance {
+        c: U.comm_E,
+        x: r_x,
+        e: eval_E,
+      },
+    ];
+
+    let (batched_u, batched_w, sc_proof_batch, claims_batch_left) =
+      batch_eval_prove(u_vec, w_vec, &mut transcript)?;
+
+    let eval_arg = EE::prove(
+      ck,
+      &pk.pk_ee,
+      &mut transcript,
+      &batched_u.c,
+      &batched_w.p,
+      &batched_u.x,
+      &batched_u.e,
+    )?;
+
+    Ok(Self {
+      sc_proof_outer,
+      claims_outer: (claim_Az, claim_Bz, claim_Cz),
+      eval_E,
+      sc_proof_inner,
+      eval_W,
+      sc_proof_batch,
+      evals_batch: claims_batch_left,
+      eval_arg,
+    })
+  }
+
+  /// verifies a proof of satisfiability of a `RelaxedR1CS` instance
+  fn verify(&self, vk: &Self::VerifierKey, U: &RelaxedR1CSInstance<E>) -> Result<(), NovaError> {
+    let mut transcript = E::TE::new(b"RelaxedR1CSSNARK");
+
+    // append the digest of R1CS matrices and the RelaxedR1CSInstance to the transcript
+    transcript.absorb(b"vk", &vk.digest());
+    transcript.absorb(b"U", U);
+
+    let (num_rounds_x, num_rounds_y) = (
+      usize::try_from(vk.S.num_cons.ilog2()).unwrap(),
+      (usize::try_from(vk.S.num_vars.ilog2()).unwrap() + 1),
+    );
+
+    // outer sum-check
+    let tau = (0..num_rounds_x)
+      .map(|_i| transcript.squeeze(b"t"))
+      .collect::<Result<EqPolynomial<_>, NovaError>>()?;
+
+    let (claim_outer_final, r_x) =
+      self
+        .sc_proof_outer
+        .verify(E::Scalar::ZERO, num_rounds_x, 3, &mut transcript)?;
+
+    // verify claim_outer_final
+    let (claim_Az, claim_Bz, claim_Cz) = self.claims_outer;
+    let taus_bound_rx = tau.evaluate(&r_x);
+    let claim_outer_final_expected =
+      taus_bound_rx * (claim_Az * claim_Bz - U.u * claim_Cz - self.eval_E);
+    if claim_outer_final != claim_outer_final_expected {
+      return Err(NovaError::InvalidSumcheckProof);
+    }
+
+    transcript.absorb(
+      b"claims_outer",
+      &[
+        self.claims_outer.0,
+        self.claims_outer.1,
+        self.claims_outer.2,
+        self.eval_E,
+      ]
+      .as_slice(),
+    );
+
+    // inner sum-check
+    let r = transcript.squeeze(b"r")?;
+    let claim_inner_joint =
+      self.claims_outer.0 + r * self.claims_outer.1 + r * r * self.claims_outer.2;
+
+    let (claim_inner_final, r_y) =
+      self
+        .sc_proof_inner
+        .verify(claim_inner_joint, num_rounds_y, 2, &mut transcript)?;
+
+    // verify claim_inner_final
+    let eval_Z = {
+      let eval_X = {
+        // constant term
+        let mut poly_X = vec![(0, U.u)];
+        //remaining inputs
+        poly_X.extend(
+          (0..U.X.len())
+            .map(|i| (i + 1, U.X[i]))
+            .collect::<Vec<(usize, E::Scalar)>>(),
+        );
+        SparsePolynomial::new(usize::try_from(vk.S.num_vars.ilog2()).unwrap(), poly_X)
+          .evaluate(&r_y[1..])
+      };
+      (E::Scalar::ONE - r_y[0]) * self.eval_W + r_y[0] * eval_X
+    };
+
+    // compute evaluations of R1CS matrices
+    let multi_evaluate = |M_vec: &[&SparseMatrix<E::Scalar>],
+                          r_x: &[E::Scalar],
+                          r_y: &[E::Scalar]|
+     -> Vec<E::Scalar> {
+      let evaluate_with_table =
+        |M: &SparseMatrix<E::Scalar>, T_x: &[E::Scalar], T_y: &[E::Scalar]| -> E::Scalar {
+          M.indptr
+            .par_windows(2)
+            .enumerate()
+            .map(|(row_idx, ptrs)| {
+              M.get_row_unchecked(ptrs.try_into().unwrap())
+                .map(|(val, col_idx)| T_x[row_idx] * T_y[*col_idx] * val)
+                .sum::<E::Scalar>()
+            })
+            .sum()
+        };
+
+      let (T_x, T_y) = rayon::join(
+        || EqPolynomial::evals_from_points(r_x),
+        || EqPolynomial::evals_from_points(r_y),
+      );
+
+      (0..M_vec.len())
+        .into_par_iter()
+        .map(|i| evaluate_with_table(M_vec[i], &T_x, &T_y))
+        .collect()
+    };
+
+    let evals = multi_evaluate(&[&vk.S.A, &vk.S.B, &vk.S.C], &r_x, &r_y);
+
+    let claim_inner_final_expected = (evals[0] + r * evals[1] + r * r * evals[2]) * eval_Z;
+    if claim_inner_final != claim_inner_final_expected {
+      return Err(NovaError::InvalidSumcheckProof);
+    }
+
+    // add claims about W and E polynomials
+    let u_vec: Vec<PolyEvalInstance<E>> = vec![
+      PolyEvalInstance {
+        c: U.comm_W,
+        x: r_y[1..].to_vec(),
+        e: self.eval_W,
+      },
+      PolyEvalInstance {
+        c: U.comm_E,
+        x: r_x,
+        e: self.eval_E,
+      },
+    ];
+
+    let batched_u = batch_eval_verify(
+      u_vec,
+      &mut transcript,
+      &self.sc_proof_batch,
+      &self.evals_batch,
+    )?;
+
+    // verify
+    EE::verify(
+      &vk.vk_ee,
+      &mut transcript,
+      &batched_u.c,
+      &batched_u.x,
+      &batched_u.e,
+      &self.eval_arg,
+    )?;
+
+    Ok(())
+  }
+}
+
+/// Proves a batch of polynomial evaluation claims using Sumcheck
+/// reducing them to a single claim at the same point.
+///
+/// # Details
+///
+/// We are given as input a list of instance/witness pairs
+/// u = [(Cᵢ, xᵢ, eᵢ)], w = [Pᵢ], such that
+/// - nᵢ = |xᵢ|
+/// - Cᵢ = Commit(Pᵢ)
+/// - eᵢ = Pᵢ(xᵢ)
+/// - |Pᵢ| = 2^nᵢ
+///
+/// We allow the polynomial Pᵢ to have different sizes, by appropriately scaling
+/// the claims and resulting evaluations from Sumcheck.
+pub(in crate::spartan) fn batch_eval_prove<E: Engine>(
+  u_vec: Vec<PolyEvalInstance<E>>,
+  w_vec: Vec<PolyEvalWitness<E>>,
+  transcript: &mut E::TE,
+) -> Result<
+  (
+    PolyEvalInstance<E>,
+    PolyEvalWitness<E>,
+    SumcheckProof<E>,
+    Vec<E::Scalar>,
+  ),
+  NovaError,
+> {
+  let num_claims = u_vec.len();
+  assert_eq!(w_vec.len(), num_claims);
+
+  // Compute nᵢ and n = maxᵢ{nᵢ}
+  let num_rounds = u_vec.iter().map(|u| u.x.len()).collect::<Vec<_>>();
+
+  // Check polynomials match number of variables, i.e. |Pᵢ| = 2^nᵢ
+  w_vec
+    .iter()
+    .zip_eq(num_rounds.iter())
+    .for_each(|(w, num_vars)| assert_eq!(w.p.len(), 1 << num_vars));
+
+  // generate a challenge, and powers of it for random linear combination
+  let rho = transcript.squeeze(b"r")?;
+  let powers_of_rho = powers::<E>(&rho, num_claims);
+
+  let (claims, u_xs, comms): (Vec<_>, Vec<_>, Vec<_>) =
+    u_vec.into_iter().map(|u| (u.e, u.x, u.c)).multiunzip();
+
+  // Create clones of polynomials to be given to Sumcheck
+  // Pᵢ(X)
+  let polys_P: Vec<MultilinearPolynomial<E::Scalar>> = w_vec
+    .iter()
+    .map(|w| MultilinearPolynomial::new(w.p.clone()))
+    .collect();
+  // eq(xᵢ, X)
+  let polys_eq: Vec<MultilinearPolynomial<E::Scalar>> = u_xs
+    .into_iter()
+    .map(|ux| MultilinearPolynomial::new(EqPolynomial::evals_from_points(&ux)))
+    .collect();
+
+  // For each i, check eᵢ = ∑ₓ Pᵢ(x)eq(xᵢ,x), where x ∈ {0,1}^nᵢ
+  let comb_func = |poly_P: &E::Scalar, poly_eq: &E::Scalar| -> E::Scalar { *poly_P * *poly_eq };
+  let (sc_proof_batch, r, claims_batch) = SumcheckProof::prove_quad_batch(
+    &claims,
+    &num_rounds,
+    polys_P,
+    polys_eq,
+    &powers_of_rho,
+    comb_func,
+    transcript,
+  )?;
+
+  let (claims_batch_left, _): (Vec<E::Scalar>, Vec<E::Scalar>) = claims_batch;
+
+  transcript.absorb(b"l", &claims_batch_left.as_slice());
+
+  // we now combine evaluation claims at the same point r into one
+  let gamma = transcript.squeeze(b"g")?;
+
+  let u_joint =
+    PolyEvalInstance::batch_diff_size(&comms, &claims_batch_left, &num_rounds, r, gamma);
+
+  // P = ∑ᵢ γⁱ⋅Pᵢ
+  let w_joint = PolyEvalWitness::batch_diff_size(w_vec, gamma);
+
+  Ok((u_joint, w_joint, sc_proof_batch, claims_batch_left))
+}
+
+/// Verifies a batch of polynomial evaluation claims using Sumcheck
+/// reducing them to a single claim at the same point.
+pub(in crate::spartan) fn batch_eval_verify<E: Engine>(
+  u_vec: Vec<PolyEvalInstance<E>>,
+  transcript: &mut E::TE,
+  sc_proof_batch: &SumcheckProof<E>,
+  evals_batch: &[E::Scalar],
+) -> Result<PolyEvalInstance<E>, NovaError> {
+  let num_claims = u_vec.len();
+  assert_eq!(evals_batch.len(), num_claims);
+
+  // generate a challenge
+  let rho = transcript.squeeze(b"r")?;
+  let powers_of_rho = powers::<E>(&rho, num_claims);
+
+  // Compute nᵢ and n = maxᵢ{nᵢ}
+  let num_rounds = u_vec.iter().map(|u| u.x.len()).collect::<Vec<_>>();
+  let num_rounds_max = *num_rounds.iter().max().unwrap();
+
+  let claims = u_vec.iter().map(|u| u.e).collect::<Vec<_>>();
+
+  let (claim_batch_final, r) =
+    sc_proof_batch.verify_batch(&claims, &num_rounds, &powers_of_rho, 2, transcript)?;
+
+  let claim_batch_final_expected = {
+    let evals_r = u_vec.iter().map(|u| {
+      let (_, r_hi) = r.split_at(num_rounds_max - u.x.len());
+      EqPolynomial::new(r_hi.to_vec()).evaluate(&u.x)
+    });
+
+    evals_r
+      .zip_eq(evals_batch.iter())
+      .zip_eq(powers_of_rho.iter())
+      .map(|((e_i, p_i), rho_i)| e_i * *p_i * rho_i)
+      .sum()
+  };
+
+  if claim_batch_final != claim_batch_final_expected {
+    return Err(NovaError::InvalidSumcheckProof);
+  }
+
+  transcript.absorb(b"l", &evals_batch);
+
+  // we now combine evaluation claims at the same point r into one
+  let gamma = transcript.squeeze(b"g")?;
+
+  let comms = u_vec.into_iter().map(|u| u.c).collect::<Vec<_>>();
+
+  let u_joint = PolyEvalInstance::batch_diff_size(&comms, evals_batch, &num_rounds, r, gamma);
+
+  Ok(u_joint)
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/sumcheck/engine.rs.html b/docs/src/arecibo/spartan/sumcheck/engine.rs.html new file mode 100644 index 000000000..92f2d1fbc --- /dev/null +++ b/docs/src/arecibo/spartan/sumcheck/engine.rs.html @@ -0,0 +1,1287 @@ +engine.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+
use ff::Field;
+use rayon::prelude::*;
+
+use crate::spartan::math::Math;
+use crate::spartan::polys::{
+  eq::EqPolynomial, masked_eq::MaskedEqPolynomial, multilinear::MultilinearPolynomial,
+  power::PowPolynomial,
+};
+use crate::spartan::sumcheck::SumcheckProof;
+use crate::traits::commitment::CommitmentEngineTrait;
+use crate::{Commitment, CommitmentKey, Engine, NovaError};
+
+/// Defines a trait for implementing sum-check in a generic manner
+pub trait SumcheckEngine<E: Engine>: Send + Sync {
+  /// returns the initial claims
+  fn initial_claims(&self) -> Vec<E::Scalar>;
+
+  /// degree of the sum-check polynomial
+  fn degree(&self) -> usize;
+
+  /// the size of the polynomials
+  fn size(&self) -> usize;
+
+  /// returns evaluation points at 0, 2, d-1 (where d is the degree of the sum-check polynomial)
+  fn evaluation_points(&self) -> Vec<Vec<E::Scalar>>;
+
+  /// bounds a variable in the constituent polynomials
+  fn bound(&mut self, r: &E::Scalar);
+
+  /// returns the final claims
+  fn final_claims(&self) -> Vec<Vec<E::Scalar>>;
+}
+
+/// The [WitnessBoundSumcheck] ensures that the witness polynomial W defined over n = log(N) variables,
+/// is zero outside of the first `num_vars = 2^m` entries.
+///
+/// # Details
+///
+/// The `W` polynomial is padded with zeros to size N = 2^n.
+/// The `masked_eq` polynomials is defined as with regards to a random challenge `tau` as
+/// the eq(tau) polynomial, where the first 2^m evaluations to 0.
+///
+/// The instance is given by
+///  `0 = ∑_{0≤i<2^n} masked_eq[i] * W[i]`.
+/// It is equivalent to the expression
+///  `0 = ∑_{2^m≤i<2^n} eq[i] * W[i]`
+/// Since `eq` is random, the instance is only satisfied if `W[2^{m}..] = 0`.
+pub(in crate::spartan) struct WitnessBoundSumcheck<E: Engine> {
+  poly_W: MultilinearPolynomial<E::Scalar>,
+  poly_masked_eq: MultilinearPolynomial<E::Scalar>,
+}
+
+impl<E: Engine> WitnessBoundSumcheck<E> {
+  pub fn new(tau: E::Scalar, poly_W_padded: Vec<E::Scalar>, num_vars: usize) -> Self {
+    let num_vars_log = num_vars.log_2();
+    // When num_vars = num_rounds, we shouldn't have to prove anything
+    // but we still want this instance to compute the evaluation of W
+    let num_rounds = poly_W_padded.len().log_2();
+    assert!(num_vars_log < num_rounds);
+
+    let tau_coords = PowPolynomial::new(&tau, num_rounds).coordinates();
+    let poly_masked_eq_evals =
+      MaskedEqPolynomial::new(&EqPolynomial::new(tau_coords), num_vars_log).evals();
+
+    Self {
+      poly_W: MultilinearPolynomial::new(poly_W_padded),
+      poly_masked_eq: MultilinearPolynomial::new(poly_masked_eq_evals),
+    }
+  }
+}
+impl<E: Engine> SumcheckEngine<E> for WitnessBoundSumcheck<E> {
+  fn initial_claims(&self) -> Vec<E::Scalar> {
+    vec![E::Scalar::ZERO]
+  }
+
+  fn degree(&self) -> usize {
+    3
+  }
+
+  fn size(&self) -> usize {
+    assert_eq!(self.poly_W.len(), self.poly_masked_eq.len());
+    self.poly_W.len()
+  }
+
+  fn evaluation_points(&self) -> Vec<Vec<E::Scalar>> {
+    let comb_func = |poly_A_comp: &E::Scalar,
+                     poly_B_comp: &E::Scalar,
+                     _: &E::Scalar|
+     -> E::Scalar { *poly_A_comp * *poly_B_comp };
+
+    let (eval_point_0, eval_point_2, eval_point_3) = SumcheckProof::<E>::compute_eval_points_cubic(
+      &self.poly_masked_eq,
+      &self.poly_W,
+      &self.poly_W, // unused
+      &comb_func,
+    );
+
+    vec![vec![eval_point_0, eval_point_2, eval_point_3]]
+  }
+
+  fn bound(&mut self, r: &E::Scalar) {
+    [&mut self.poly_W, &mut self.poly_masked_eq]
+      .par_iter_mut()
+      .for_each(|poly| poly.bind_poly_var_top(r));
+  }
+
+  fn final_claims(&self) -> Vec<Vec<E::Scalar>> {
+    vec![vec![self.poly_W[0], self.poly_masked_eq[0]]]
+  }
+}
+
+pub(in crate::spartan) struct MemorySumcheckInstance<E: Engine> {
+  // row
+  w_plus_r_row: MultilinearPolynomial<E::Scalar>,
+  t_plus_r_row: MultilinearPolynomial<E::Scalar>,
+  t_plus_r_inv_row: MultilinearPolynomial<E::Scalar>,
+  w_plus_r_inv_row: MultilinearPolynomial<E::Scalar>,
+  ts_row: MultilinearPolynomial<E::Scalar>,
+
+  // col
+  w_plus_r_col: MultilinearPolynomial<E::Scalar>,
+  t_plus_r_col: MultilinearPolynomial<E::Scalar>,
+  t_plus_r_inv_col: MultilinearPolynomial<E::Scalar>,
+  w_plus_r_inv_col: MultilinearPolynomial<E::Scalar>,
+  ts_col: MultilinearPolynomial<E::Scalar>,
+
+  // eq
+  poly_eq: MultilinearPolynomial<E::Scalar>,
+
+  // zero polynomial
+  poly_zero: MultilinearPolynomial<E::Scalar>,
+}
+
+impl<E: Engine> MemorySumcheckInstance<E> {
+  /// Computes witnesses for MemoryInstanceSumcheck
+  ///
+  /// # Description
+  /// We use the logUp protocol to prove that
+  /// ∑ TS[i]/(T[i] + r) - 1/(W[i] + r) = 0
+  /// where
+  ///   T_row[i] = mem_row[i]      * gamma + i
+  ///            = eq(tau)[i]      * gamma + i
+  ///   W_row[i] = L_row[i]        * gamma + addr_row[i]
+  ///            = eq(tau)[row[i]] * gamma + addr_row[i]
+  ///   T_col[i] = mem_col[i]      * gamma + i
+  ///            = z[i]            * gamma + i
+  ///   W_col[i] = addr_col[i]     * gamma + addr_col[i]
+  ///            = z[col[i]]       * gamma + addr_col[i]
+  /// and
+  ///   TS_row, TS_col are integer-valued vectors representing the number of reads
+  ///   to each memory cell of L_row, L_col
+  ///
+  /// The function returns oracles for the polynomials TS[i]/(T[i] + r), 1/(W[i] + r),
+  /// as well as auxiliary polynomials T[i] + r, W[i] + r
+  pub fn compute_oracles(
+    ck: &CommitmentKey<E>,
+    r: &E::Scalar,
+    gamma: &E::Scalar,
+    mem_row: &[E::Scalar],
+    addr_row: &[E::Scalar],
+    L_row: &[E::Scalar],
+    ts_row: &[E::Scalar],
+    mem_col: &[E::Scalar],
+    addr_col: &[E::Scalar],
+    L_col: &[E::Scalar],
+    ts_col: &[E::Scalar],
+  ) -> Result<([Commitment<E>; 4], [Vec<E::Scalar>; 4], [Vec<E::Scalar>; 4]), NovaError> {
+    // hash the tuples of (addr,val) memory contents and read responses into a single field element using `hash_func`
+    let hash_func_vec = |mem: &[E::Scalar],
+                         addr: &[E::Scalar],
+                         lookups: &[E::Scalar]|
+     -> (Vec<E::Scalar>, Vec<E::Scalar>) {
+      let hash_func = |addr: &E::Scalar, val: &E::Scalar| -> E::Scalar { *val * gamma + *addr };
+      assert_eq!(addr.len(), lookups.len());
+      rayon::join(
+        || {
+          (0..mem.len())
+            .map(|i| hash_func(&E::Scalar::from(i as u64), &mem[i]))
+            .collect::<Vec<E::Scalar>>()
+        },
+        || {
+          (0..addr.len())
+            .map(|i| hash_func(&addr[i], &lookups[i]))
+            .collect::<Vec<E::Scalar>>()
+        },
+      )
+    };
+
+    let ((T_row, W_row), (T_col, W_col)) = rayon::join(
+      || hash_func_vec(mem_row, addr_row, L_row),
+      || hash_func_vec(mem_col, addr_col, L_col),
+    );
+
+    let batch_invert = |v: &[E::Scalar]| -> Result<Vec<E::Scalar>, NovaError> {
+      let mut products = vec![E::Scalar::ZERO; v.len()];
+      let mut acc = E::Scalar::ONE;
+
+      for i in 0..v.len() {
+        products[i] = acc;
+        acc *= v[i];
+      }
+
+      // we can compute an inversion only if acc is non-zero
+      if acc == E::Scalar::ZERO {
+        return Err(NovaError::InternalError);
+      }
+
+      // compute the inverse once for all entries
+      acc = acc.invert().unwrap();
+
+      let mut inv = vec![E::Scalar::ZERO; v.len()];
+      for i in 0..v.len() {
+        let tmp = acc * v[v.len() - 1 - i];
+        inv[v.len() - 1 - i] = products[v.len() - 1 - i] * acc;
+        acc = tmp;
+      }
+
+      Ok(inv)
+    };
+
+    // compute vectors TS[i]/(T[i] + r) and 1/(W[i] + r)
+    let helper = |T: &[E::Scalar],
+                  W: &[E::Scalar],
+                  TS: &[E::Scalar],
+                  r: &E::Scalar|
+     -> (
+      (
+        Result<Vec<E::Scalar>, NovaError>,
+        Result<Vec<E::Scalar>, NovaError>,
+      ),
+      (Vec<E::Scalar>, Vec<E::Scalar>),
+    ) {
+      rayon::join(
+        || {
+          rayon::join(
+            || {
+              let inv = batch_invert(&T.par_iter().map(|e| *e + *r).collect::<Vec<_>>())?;
+
+              // compute inv[i] * TS[i] in parallel
+              Ok(
+                zip_with!((inv.into_par_iter(), TS.par_iter()), |e1, e2| e1 * *e2)
+                  .collect::<Vec<_>>(),
+              )
+            },
+            || batch_invert(&W.par_iter().map(|e| *e + *r).collect::<Vec<_>>()),
+          )
+        },
+        || {
+          rayon::join(
+            || T.par_iter().map(|e| *e + *r).collect(),
+            || W.par_iter().map(|e| *e + *r).collect(),
+          )
+        },
+      )
+    };
+
+    let (
+      ((t_plus_r_inv_row, w_plus_r_inv_row), (t_plus_r_row, w_plus_r_row)),
+      ((t_plus_r_inv_col, w_plus_r_inv_col), (t_plus_r_col, w_plus_r_col)),
+    ) = rayon::join(
+      || helper(&T_row, &W_row, ts_row, r),
+      || helper(&T_col, &W_col, ts_col, r),
+    );
+
+    let t_plus_r_inv_row = t_plus_r_inv_row?;
+    let w_plus_r_inv_row = w_plus_r_inv_row?;
+    let t_plus_r_inv_col = t_plus_r_inv_col?;
+    let w_plus_r_inv_col = w_plus_r_inv_col?;
+
+    let (
+      (comm_t_plus_r_inv_row, comm_w_plus_r_inv_row),
+      (comm_t_plus_r_inv_col, comm_w_plus_r_inv_col),
+    ) = rayon::join(
+      || {
+        rayon::join(
+          || E::CE::commit(ck, &t_plus_r_inv_row),
+          || E::CE::commit(ck, &w_plus_r_inv_row),
+        )
+      },
+      || {
+        rayon::join(
+          || E::CE::commit(ck, &t_plus_r_inv_col),
+          || E::CE::commit(ck, &w_plus_r_inv_col),
+        )
+      },
+    );
+
+    let comm_vec = [
+      comm_t_plus_r_inv_row,
+      comm_w_plus_r_inv_row,
+      comm_t_plus_r_inv_col,
+      comm_w_plus_r_inv_col,
+    ];
+
+    let poly_vec = [
+      t_plus_r_inv_row,
+      w_plus_r_inv_row,
+      t_plus_r_inv_col,
+      w_plus_r_inv_col,
+    ];
+
+    let aux_poly_vec = [t_plus_r_row, w_plus_r_row, t_plus_r_col, w_plus_r_col];
+
+    Ok((comm_vec, poly_vec, aux_poly_vec))
+  }
+
+  pub fn new(
+    polys_oracle: [Vec<E::Scalar>; 4],
+    polys_aux: [Vec<E::Scalar>; 4],
+    poly_eq: Vec<E::Scalar>,
+    ts_row: Vec<E::Scalar>,
+    ts_col: Vec<E::Scalar>,
+  ) -> Self {
+    let [t_plus_r_inv_row, w_plus_r_inv_row, t_plus_r_inv_col, w_plus_r_inv_col] = polys_oracle;
+    let [t_plus_r_row, w_plus_r_row, t_plus_r_col, w_plus_r_col] = polys_aux;
+
+    let zero = vec![E::Scalar::ZERO; poly_eq.len()];
+
+    Self {
+      w_plus_r_row: MultilinearPolynomial::new(w_plus_r_row),
+      t_plus_r_row: MultilinearPolynomial::new(t_plus_r_row),
+      t_plus_r_inv_row: MultilinearPolynomial::new(t_plus_r_inv_row),
+      w_plus_r_inv_row: MultilinearPolynomial::new(w_plus_r_inv_row),
+      ts_row: MultilinearPolynomial::new(ts_row),
+      w_plus_r_col: MultilinearPolynomial::new(w_plus_r_col),
+      t_plus_r_col: MultilinearPolynomial::new(t_plus_r_col),
+      t_plus_r_inv_col: MultilinearPolynomial::new(t_plus_r_inv_col),
+      w_plus_r_inv_col: MultilinearPolynomial::new(w_plus_r_inv_col),
+      ts_col: MultilinearPolynomial::new(ts_col),
+      poly_eq: MultilinearPolynomial::new(poly_eq),
+      poly_zero: MultilinearPolynomial::new(zero),
+    }
+  }
+}
+
+impl<E: Engine> SumcheckEngine<E> for MemorySumcheckInstance<E> {
+  fn initial_claims(&self) -> Vec<E::Scalar> {
+    vec![E::Scalar::ZERO; 6]
+  }
+
+  fn degree(&self) -> usize {
+    3
+  }
+
+  fn size(&self) -> usize {
+    // sanity checks
+    assert_eq!(self.w_plus_r_row.len(), self.t_plus_r_row.len());
+    assert_eq!(self.w_plus_r_row.len(), self.ts_row.len());
+    assert_eq!(self.w_plus_r_row.len(), self.w_plus_r_col.len());
+    assert_eq!(self.w_plus_r_row.len(), self.t_plus_r_col.len());
+    assert_eq!(self.w_plus_r_row.len(), self.ts_col.len());
+
+    self.w_plus_r_row.len()
+  }
+
+  fn evaluation_points(&self) -> Vec<Vec<E::Scalar>> {
+    let comb_func = |poly_A_comp: &E::Scalar,
+                     poly_B_comp: &E::Scalar,
+                     _poly_C_comp: &E::Scalar|
+     -> E::Scalar { *poly_A_comp - *poly_B_comp };
+
+    let comb_func2 =
+      |poly_A_comp: &E::Scalar,
+       poly_B_comp: &E::Scalar,
+       poly_C_comp: &E::Scalar,
+       _poly_D_comp: &E::Scalar|
+       -> E::Scalar { *poly_A_comp * (*poly_B_comp * *poly_C_comp - E::Scalar::ONE) };
+
+    let comb_func3 =
+      |poly_A_comp: &E::Scalar,
+       poly_B_comp: &E::Scalar,
+       poly_C_comp: &E::Scalar,
+       poly_D_comp: &E::Scalar|
+       -> E::Scalar { *poly_A_comp * (*poly_B_comp * *poly_C_comp - *poly_D_comp) };
+
+    // inv related evaluation points
+    // 0 = ∑ TS[i]/(T[i] + r) - 1/(W[i] + r)
+    let (eval_inv_0_row, eval_inv_2_row, eval_inv_3_row) =
+      SumcheckProof::<E>::compute_eval_points_cubic(
+        &self.t_plus_r_inv_row,
+        &self.w_plus_r_inv_row,
+        &self.poly_zero,
+        &comb_func,
+      );
+
+    let (eval_inv_0_col, eval_inv_2_col, eval_inv_3_col) =
+      SumcheckProof::<E>::compute_eval_points_cubic(
+        &self.t_plus_r_inv_col,
+        &self.w_plus_r_inv_col,
+        &self.poly_zero,
+        &comb_func,
+      );
+
+    // row related evaluation points
+    // 0 = ∑ eq[i] * (inv_T[i] * (T[i] + r) - TS[i]))
+    let (eval_T_0_row, eval_T_2_row, eval_T_3_row) =
+      SumcheckProof::<E>::compute_eval_points_cubic_with_additive_term(
+        &self.poly_eq,
+        &self.t_plus_r_inv_row,
+        &self.t_plus_r_row,
+        &self.ts_row,
+        &comb_func3,
+      );
+    // 0 = ∑ eq[i] * (inv_W[i] * (T[i] + r) - 1))
+    let (eval_W_0_row, eval_W_2_row, eval_W_3_row) =
+      SumcheckProof::<E>::compute_eval_points_cubic_with_additive_term(
+        &self.poly_eq,
+        &self.w_plus_r_inv_row,
+        &self.w_plus_r_row,
+        &self.poly_zero,
+        &comb_func2,
+      );
+
+    // column related evaluation points
+    let (eval_T_0_col, eval_T_2_col, eval_T_3_col) =
+      SumcheckProof::<E>::compute_eval_points_cubic_with_additive_term(
+        &self.poly_eq,
+        &self.t_plus_r_inv_col,
+        &self.t_plus_r_col,
+        &self.ts_col,
+        &comb_func3,
+      );
+    let (eval_W_0_col, eval_W_2_col, eval_W_3_col) =
+      SumcheckProof::<E>::compute_eval_points_cubic_with_additive_term(
+        &self.poly_eq,
+        &self.w_plus_r_inv_col,
+        &self.w_plus_r_col,
+        &self.poly_zero,
+        &comb_func2,
+      );
+
+    vec![
+      vec![eval_inv_0_row, eval_inv_2_row, eval_inv_3_row],
+      vec![eval_inv_0_col, eval_inv_2_col, eval_inv_3_col],
+      vec![eval_T_0_row, eval_T_2_row, eval_T_3_row],
+      vec![eval_W_0_row, eval_W_2_row, eval_W_3_row],
+      vec![eval_T_0_col, eval_T_2_col, eval_T_3_col],
+      vec![eval_W_0_col, eval_W_2_col, eval_W_3_col],
+    ]
+  }
+
+  fn bound(&mut self, r: &E::Scalar) {
+    [
+      &mut self.t_plus_r_row,
+      &mut self.t_plus_r_inv_row,
+      &mut self.w_plus_r_row,
+      &mut self.w_plus_r_inv_row,
+      &mut self.ts_row,
+      &mut self.t_plus_r_col,
+      &mut self.t_plus_r_inv_col,
+      &mut self.w_plus_r_col,
+      &mut self.w_plus_r_inv_col,
+      &mut self.ts_col,
+      &mut self.poly_eq,
+    ]
+    .par_iter_mut()
+    .for_each(|poly| poly.bind_poly_var_top(r));
+  }
+
+  fn final_claims(&self) -> Vec<Vec<E::Scalar>> {
+    let poly_row_final = vec![
+      self.t_plus_r_inv_row[0],
+      self.w_plus_r_inv_row[0],
+      self.ts_row[0],
+    ];
+
+    let poly_col_final = vec![
+      self.t_plus_r_inv_col[0],
+      self.w_plus_r_inv_col[0],
+      self.ts_col[0],
+    ];
+
+    vec![poly_row_final, poly_col_final]
+  }
+}
+
+pub(in crate::spartan) struct OuterSumcheckInstance<E: Engine> {
+  poly_tau: MultilinearPolynomial<E::Scalar>,
+  poly_Az: MultilinearPolynomial<E::Scalar>,
+  poly_Bz: MultilinearPolynomial<E::Scalar>,
+  poly_uCz_E: MultilinearPolynomial<E::Scalar>,
+
+  poly_Mz: MultilinearPolynomial<E::Scalar>,
+  eval_Mz_at_tau: E::Scalar,
+
+  poly_zero: MultilinearPolynomial<E::Scalar>,
+}
+
+impl<E: Engine> OuterSumcheckInstance<E> {
+  pub fn new(
+    tau: Vec<E::Scalar>,
+    Az: Vec<E::Scalar>,
+    Bz: Vec<E::Scalar>,
+    uCz_E: Vec<E::Scalar>,
+    Mz: Vec<E::Scalar>,
+    eval_Mz_at_tau: &E::Scalar,
+  ) -> Self {
+    let zero = vec![E::Scalar::ZERO; tau.len()];
+    Self {
+      poly_tau: MultilinearPolynomial::new(tau),
+      poly_Az: MultilinearPolynomial::new(Az),
+      poly_Bz: MultilinearPolynomial::new(Bz),
+      poly_uCz_E: MultilinearPolynomial::new(uCz_E),
+      poly_Mz: MultilinearPolynomial::new(Mz),
+      eval_Mz_at_tau: *eval_Mz_at_tau,
+      poly_zero: MultilinearPolynomial::new(zero),
+    }
+  }
+}
+
+impl<E: Engine> SumcheckEngine<E> for OuterSumcheckInstance<E> {
+  fn initial_claims(&self) -> Vec<E::Scalar> {
+    vec![E::Scalar::ZERO, self.eval_Mz_at_tau]
+  }
+
+  fn degree(&self) -> usize {
+    3
+  }
+
+  fn size(&self) -> usize {
+    assert_eq!(self.poly_tau.len(), self.poly_Az.len());
+    assert_eq!(self.poly_tau.len(), self.poly_Bz.len());
+    assert_eq!(self.poly_tau.len(), self.poly_uCz_E.len());
+    assert_eq!(self.poly_tau.len(), self.poly_Mz.len());
+    self.poly_tau.len()
+  }
+
+  fn evaluation_points(&self) -> Vec<Vec<E::Scalar>> {
+    let comb_func =
+      |poly_A_comp: &E::Scalar,
+       poly_B_comp: &E::Scalar,
+       poly_C_comp: &E::Scalar,
+       poly_D_comp: &E::Scalar|
+       -> E::Scalar { *poly_A_comp * (*poly_B_comp * *poly_C_comp - *poly_D_comp) };
+
+    let (eval_point_h_0, eval_point_h_2, eval_point_h_3) =
+      SumcheckProof::<E>::compute_eval_points_cubic_with_additive_term(
+        &self.poly_tau,
+        &self.poly_Az,
+        &self.poly_Bz,
+        &self.poly_uCz_E,
+        &comb_func,
+      );
+
+    let comb_func2 = |poly_A_comp: &E::Scalar,
+                      poly_B_comp: &E::Scalar,
+                      _poly_C_comp: &E::Scalar|
+     -> E::Scalar { *poly_A_comp * *poly_B_comp };
+
+    let (eval_point_e_0, eval_point_e_2, eval_point_e_3) =
+      SumcheckProof::<E>::compute_eval_points_cubic(
+        &self.poly_tau,
+        &self.poly_Mz,
+        &self.poly_zero,
+        &comb_func2,
+      );
+
+    vec![
+      vec![eval_point_h_0, eval_point_h_2, eval_point_h_3],
+      vec![eval_point_e_0, eval_point_e_2, eval_point_e_3],
+    ]
+  }
+
+  fn bound(&mut self, r: &E::Scalar) {
+    [
+      &mut self.poly_tau,
+      &mut self.poly_Az,
+      &mut self.poly_Bz,
+      &mut self.poly_uCz_E,
+      &mut self.poly_Mz,
+    ]
+    .par_iter_mut()
+    .for_each(|poly| poly.bind_poly_var_top(r));
+  }
+
+  fn final_claims(&self) -> Vec<Vec<E::Scalar>> {
+    vec![vec![self.poly_Az[0], self.poly_Bz[0]]]
+  }
+}
+
+pub(in crate::spartan) struct InnerSumcheckInstance<E: Engine> {
+  pub(in crate::spartan) claim: E::Scalar,
+  pub(in crate::spartan) poly_L_row: MultilinearPolynomial<E::Scalar>,
+  pub(in crate::spartan) poly_L_col: MultilinearPolynomial<E::Scalar>,
+  pub(in crate::spartan) poly_val: MultilinearPolynomial<E::Scalar>,
+}
+impl<E: Engine> InnerSumcheckInstance<E> {
+  pub fn new(
+    claim: E::Scalar,
+    poly_L_row: MultilinearPolynomial<E::Scalar>,
+    poly_L_col: MultilinearPolynomial<E::Scalar>,
+    poly_val: MultilinearPolynomial<E::Scalar>,
+  ) -> Self {
+    Self {
+      claim,
+      poly_L_row,
+      poly_L_col,
+      poly_val,
+    }
+  }
+}
+impl<E: Engine> SumcheckEngine<E> for InnerSumcheckInstance<E> {
+  fn initial_claims(&self) -> Vec<E::Scalar> {
+    vec![self.claim]
+  }
+
+  fn degree(&self) -> usize {
+    3
+  }
+
+  fn size(&self) -> usize {
+    assert_eq!(self.poly_L_row.len(), self.poly_val.len());
+    assert_eq!(self.poly_L_row.len(), self.poly_L_col.len());
+    self.poly_L_row.len()
+  }
+
+  fn evaluation_points(&self) -> Vec<Vec<E::Scalar>> {
+    let (poly_A, poly_B, poly_C) = (&self.poly_L_row, &self.poly_L_col, &self.poly_val);
+    let comb_func = |poly_A_comp: &E::Scalar,
+                     poly_B_comp: &E::Scalar,
+                     poly_C_comp: &E::Scalar|
+     -> E::Scalar { *poly_A_comp * *poly_B_comp * *poly_C_comp };
+
+    let (eval_point_0, eval_point_2, eval_point_3) =
+      SumcheckProof::<E>::compute_eval_points_cubic(poly_A, poly_B, poly_C, &comb_func);
+
+    vec![vec![eval_point_0, eval_point_2, eval_point_3]]
+  }
+
+  fn bound(&mut self, r: &E::Scalar) {
+    [
+      &mut self.poly_L_row,
+      &mut self.poly_L_col,
+      &mut self.poly_val,
+    ]
+    .par_iter_mut()
+    .for_each(|poly| poly.bind_poly_var_top(r));
+  }
+
+  fn final_claims(&self) -> Vec<Vec<E::Scalar>> {
+    vec![vec![self.poly_L_row[0], self.poly_L_col[0]]]
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/spartan/sumcheck/mod.rs.html b/docs/src/arecibo/spartan/sumcheck/mod.rs.html new file mode 100644 index 000000000..d4369b7c4 --- /dev/null +++ b/docs/src/arecibo/spartan/sumcheck/mod.rs.html @@ -0,0 +1,1229 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+
use crate::errors::NovaError;
+use crate::spartan::polys::{
+  multilinear::MultilinearPolynomial,
+  univariate::{CompressedUniPoly, UniPoly},
+};
+use crate::traits::{Engine, TranscriptEngineTrait};
+use ff::Field;
+use itertools::Itertools as _;
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+
+pub(in crate::spartan) mod engine;
+
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub(crate) struct SumcheckProof<E: Engine> {
+  compressed_polys: Vec<CompressedUniPoly<E::Scalar>>,
+}
+
+impl<E: Engine> SumcheckProof<E> {
+  pub fn new(compressed_polys: Vec<CompressedUniPoly<E::Scalar>>) -> Self {
+    Self { compressed_polys }
+  }
+
+  pub fn verify(
+    &self,
+    claim: E::Scalar,
+    num_rounds: usize,
+    degree_bound: usize,
+    transcript: &mut E::TE,
+  ) -> Result<(E::Scalar, Vec<E::Scalar>), NovaError> {
+    let mut e = claim;
+    let mut r: Vec<E::Scalar> = Vec::new();
+
+    // verify that there is a univariate polynomial for each round
+    if self.compressed_polys.len() != num_rounds {
+      return Err(NovaError::InvalidSumcheckProof);
+    }
+
+    for i in 0..self.compressed_polys.len() {
+      let poly = self.compressed_polys[i].decompress(&e);
+
+      // verify degree bound
+      if poly.degree() != degree_bound {
+        return Err(NovaError::InvalidSumcheckProof);
+      }
+
+      // we do not need to check if poly(0) + poly(1) = e, as
+      // decompress() call above already ensures that holds
+      debug_assert_eq!(poly.eval_at_zero() + poly.eval_at_one(), e);
+
+      // append the prover's message to the transcript
+      transcript.absorb(b"p", &poly);
+
+      //derive the verifier's challenge for the next round
+      let r_i = transcript.squeeze(b"c")?;
+
+      r.push(r_i);
+
+      // evaluate the claimed degree-ell polynomial at r_i
+      e = poly.evaluate(&r_i);
+    }
+
+    Ok((e, r))
+  }
+
+  pub fn verify_batch(
+    &self,
+    claims: &[E::Scalar],
+    num_rounds: &[usize],
+    coeffs: &[E::Scalar],
+    degree_bound: usize,
+    transcript: &mut E::TE,
+  ) -> Result<(E::Scalar, Vec<E::Scalar>), NovaError> {
+    let num_instances = claims.len();
+    assert_eq!(num_rounds.len(), num_instances);
+    assert_eq!(coeffs.len(), num_instances);
+
+    // n = maxᵢ{nᵢ}
+    let num_rounds_max = *num_rounds.iter().max().unwrap();
+
+    // Random linear combination of claims,
+    // where each claim is scaled by 2^{n-nᵢ} to account for the padding.
+    //
+    // claim = ∑ᵢ coeffᵢ⋅2^{n-nᵢ}⋅cᵢ
+    let claim = zip_with!(
+      (
+        zip_with!(iter, (claims, num_rounds), |claim, num_rounds| {
+          let scaling_factor = 1 << (num_rounds_max - num_rounds);
+          E::Scalar::from(scaling_factor as u64) * claim
+        }),
+        coeffs.iter()
+      ),
+      |scaled_claim, coeff| scaled_claim * coeff
+    )
+    .sum();
+
+    self.verify(claim, num_rounds_max, degree_bound, transcript)
+  }
+
+  #[inline]
+  fn compute_eval_points_quad<F>(
+    poly_A: &MultilinearPolynomial<E::Scalar>,
+    poly_B: &MultilinearPolynomial<E::Scalar>,
+    comb_func: &F,
+  ) -> (E::Scalar, E::Scalar)
+  where
+    F: Fn(&E::Scalar, &E::Scalar) -> E::Scalar + Sync,
+  {
+    let len = poly_A.len() / 2;
+    (0..len)
+      .into_par_iter()
+      .map(|i| {
+        // eval 0: bound_func is A(low)
+        let eval_point_0 = comb_func(&poly_A[i], &poly_B[i]);
+
+        // eval 2: bound_func is -A(low) + 2*A(high)
+        let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
+        let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
+        let eval_point_2 = comb_func(&poly_A_bound_point, &poly_B_bound_point);
+        (eval_point_0, eval_point_2)
+      })
+      .reduce(
+        || (E::Scalar::ZERO, E::Scalar::ZERO),
+        |a, b| (a.0 + b.0, a.1 + b.1),
+      )
+  }
+
+  pub fn prove_quad<F>(
+    claim: &E::Scalar,
+    num_rounds: usize,
+    poly_A: &mut MultilinearPolynomial<E::Scalar>,
+    poly_B: &mut MultilinearPolynomial<E::Scalar>,
+    comb_func: F,
+    transcript: &mut E::TE,
+  ) -> Result<(Self, Vec<E::Scalar>, Vec<E::Scalar>), NovaError>
+  where
+    F: Fn(&E::Scalar, &E::Scalar) -> E::Scalar + Sync,
+  {
+    let mut r: Vec<E::Scalar> = Vec::new();
+    let mut polys: Vec<CompressedUniPoly<E::Scalar>> = Vec::new();
+    let mut claim_per_round = *claim;
+    for _ in 0..num_rounds {
+      let poly = {
+        let (eval_point_0, eval_point_2) =
+          Self::compute_eval_points_quad(poly_A, poly_B, &comb_func);
+
+        let evals = vec![eval_point_0, claim_per_round - eval_point_0, eval_point_2];
+        UniPoly::from_evals(&evals)
+      };
+
+      // append the prover's message to the transcript
+      transcript.absorb(b"p", &poly);
+
+      //derive the verifier's challenge for the next round
+      let r_i = transcript.squeeze(b"c")?;
+      r.push(r_i);
+      polys.push(poly.compress());
+
+      // Set up next round
+      claim_per_round = poly.evaluate(&r_i);
+
+      // bind all tables to the verifier's challenge
+      rayon::join(
+        || poly_A.bind_poly_var_top(&r_i),
+        || poly_B.bind_poly_var_top(&r_i),
+      );
+    }
+
+    Ok((
+      Self {
+        compressed_polys: polys,
+      },
+      r,
+      vec![poly_A[0], poly_B[0]],
+    ))
+  }
+
+  pub fn prove_quad_batch<F>(
+    claims: &[E::Scalar],
+    num_rounds: &[usize],
+    mut poly_A_vec: Vec<MultilinearPolynomial<E::Scalar>>,
+    mut poly_B_vec: Vec<MultilinearPolynomial<E::Scalar>>,
+    coeffs: &[E::Scalar],
+    comb_func: F,
+    transcript: &mut E::TE,
+  ) -> Result<(Self, Vec<E::Scalar>, (Vec<E::Scalar>, Vec<E::Scalar>)), NovaError>
+  where
+    F: Fn(&E::Scalar, &E::Scalar) -> E::Scalar + Sync,
+  {
+    let num_claims = claims.len();
+
+    assert_eq!(num_rounds.len(), num_claims);
+    assert_eq!(poly_A_vec.len(), num_claims);
+    assert_eq!(poly_B_vec.len(), num_claims);
+    assert_eq!(coeffs.len(), num_claims);
+
+    for (i, &num_rounds) in num_rounds.iter().enumerate() {
+      let expected_size = 1 << num_rounds;
+
+      // Direct indexing with the assumption that the index will always be in bounds
+      let a = &poly_A_vec[i];
+      let b = &poly_B_vec[i];
+
+      for (l, polyname) in [(a.len(), "poly_A_vec"), (b.len(), "poly_B_vec")].iter() {
+        assert_eq!(
+          *l, expected_size,
+          "Mismatch in size for {} at index {}",
+          polyname, i
+        );
+      }
+    }
+
+    let num_rounds_max = *num_rounds.iter().max().unwrap();
+    let mut e = zip_with!(
+      iter,
+      (claims, num_rounds, coeffs),
+      |claim, num_rounds, coeff| {
+        let scaled_claim = E::Scalar::from((1 << (num_rounds_max - num_rounds)) as u64) * claim;
+        scaled_claim * coeff
+      }
+    )
+    .sum();
+    let mut r: Vec<E::Scalar> = Vec::new();
+    let mut quad_polys: Vec<CompressedUniPoly<E::Scalar>> = Vec::new();
+
+    for current_round in 0..num_rounds_max {
+      let remaining_rounds = num_rounds_max - current_round;
+      let evals: Vec<(E::Scalar, E::Scalar)> = zip_with!(
+        par_iter,
+        (num_rounds, claims, poly_A_vec, poly_B_vec),
+        |num_rounds, claim, poly_A, poly_B| {
+          if remaining_rounds <= *num_rounds {
+            Self::compute_eval_points_quad(poly_A, poly_B, &comb_func)
+          } else {
+            let remaining_variables = remaining_rounds - num_rounds - 1;
+            let scaled_claim = E::Scalar::from((1 << remaining_variables) as u64) * claim;
+            (scaled_claim, scaled_claim)
+          }
+        }
+      )
+      .collect();
+
+      let evals_combined_0 = (0..evals.len()).map(|i| evals[i].0 * coeffs[i]).sum();
+      let evals_combined_2 = (0..evals.len()).map(|i| evals[i].1 * coeffs[i]).sum();
+
+      let evals = vec![evals_combined_0, e - evals_combined_0, evals_combined_2];
+      let poly = UniPoly::from_evals(&evals);
+
+      // append the prover's message to the transcript
+      transcript.absorb(b"p", &poly);
+
+      // derive the verifier's challenge for the next round
+      let r_i = transcript.squeeze(b"c")?;
+      r.push(r_i);
+
+      // bound all tables to the verifier's challenge
+      zip_with_for_each!(
+        (
+          num_rounds.par_iter(),
+          poly_A_vec.par_iter_mut(),
+          poly_B_vec.par_iter_mut()
+        ),
+        |num_rounds, poly_A, poly_B| {
+          if remaining_rounds <= *num_rounds {
+            let _ = rayon::join(
+              || poly_A.bind_poly_var_top(&r_i),
+              || poly_B.bind_poly_var_top(&r_i),
+            );
+          }
+        }
+      );
+
+      e = poly.evaluate(&r_i);
+      quad_polys.push(poly.compress());
+    }
+    poly_A_vec.iter().for_each(|p| assert_eq!(p.len(), 1));
+    poly_B_vec.iter().for_each(|p| assert_eq!(p.len(), 1));
+
+    let poly_A_final = poly_A_vec
+      .into_iter()
+      .map(|poly| poly[0])
+      .collect::<Vec<_>>();
+    let poly_B_final = poly_B_vec
+      .into_iter()
+      .map(|poly| poly[0])
+      .collect::<Vec<_>>();
+
+    let eval_expected = zip_with!(
+      iter,
+      (poly_A_final, poly_B_final, coeffs),
+      |eA, eB, coeff| comb_func(eA, eB) * coeff
+    )
+    .sum::<E::Scalar>();
+    assert_eq!(e, eval_expected);
+
+    let claims_prod = (poly_A_final, poly_B_final);
+
+    Ok((Self::new(quad_polys), r, claims_prod))
+  }
+
+  #[inline]
+  fn compute_eval_points_cubic<F>(
+    poly_A: &MultilinearPolynomial<E::Scalar>,
+    poly_B: &MultilinearPolynomial<E::Scalar>,
+    poly_C: &MultilinearPolynomial<E::Scalar>,
+    comb_func: &F,
+  ) -> (E::Scalar, E::Scalar, E::Scalar)
+  where
+    F: Fn(&E::Scalar, &E::Scalar, &E::Scalar) -> E::Scalar + Sync,
+  {
+    let len = poly_A.len() / 2;
+    (0..len)
+      .into_par_iter()
+      .map(|i| {
+        // eval 0: bound_func is A(low)
+        let eval_point_0 = comb_func(&poly_A[i], &poly_B[i], &poly_C[i]);
+
+        // eval 2: bound_func is -A(low) + 2*A(high)
+        let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
+        let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
+        let poly_C_bound_point = poly_C[len + i] + poly_C[len + i] - poly_C[i];
+        let eval_point_2 = comb_func(
+          &poly_A_bound_point,
+          &poly_B_bound_point,
+          &poly_C_bound_point,
+        );
+
+        // eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
+        let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
+        let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
+        let poly_C_bound_point = poly_C_bound_point + poly_C[len + i] - poly_C[i];
+        let eval_point_3 = comb_func(
+          &poly_A_bound_point,
+          &poly_B_bound_point,
+          &poly_C_bound_point,
+        );
+        (eval_point_0, eval_point_2, eval_point_3)
+      })
+      .reduce(
+        || (E::Scalar::ZERO, E::Scalar::ZERO, E::Scalar::ZERO),
+        |a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
+      )
+  }
+
+  #[inline]
+  fn compute_eval_points_cubic_with_additive_term<F>(
+    poly_A: &MultilinearPolynomial<E::Scalar>,
+    poly_B: &MultilinearPolynomial<E::Scalar>,
+    poly_C: &MultilinearPolynomial<E::Scalar>,
+    poly_D: &MultilinearPolynomial<E::Scalar>,
+    comb_func: &F,
+  ) -> (E::Scalar, E::Scalar, E::Scalar)
+  where
+    F: Fn(&E::Scalar, &E::Scalar, &E::Scalar, &E::Scalar) -> E::Scalar + Sync,
+  {
+    let len = poly_A.len() / 2;
+    (0..len)
+      .into_par_iter()
+      .map(|i| {
+        // eval 0: bound_func is A(low)
+        let eval_point_0 = comb_func(&poly_A[i], &poly_B[i], &poly_C[i], &poly_D[i]);
+
+        // eval 2: bound_func is -A(low) + 2*A(high)
+        let poly_A_bound_point = poly_A[len + i] + poly_A[len + i] - poly_A[i];
+        let poly_B_bound_point = poly_B[len + i] + poly_B[len + i] - poly_B[i];
+        let poly_C_bound_point = poly_C[len + i] + poly_C[len + i] - poly_C[i];
+        let poly_D_bound_point = poly_D[len + i] + poly_D[len + i] - poly_D[i];
+        let eval_point_2 = comb_func(
+          &poly_A_bound_point,
+          &poly_B_bound_point,
+          &poly_C_bound_point,
+          &poly_D_bound_point,
+        );
+
+        // eval 3: bound_func is -2A(low) + 3A(high); computed incrementally with bound_func applied to eval(2)
+        let poly_A_bound_point = poly_A_bound_point + poly_A[len + i] - poly_A[i];
+        let poly_B_bound_point = poly_B_bound_point + poly_B[len + i] - poly_B[i];
+        let poly_C_bound_point = poly_C_bound_point + poly_C[len + i] - poly_C[i];
+        let poly_D_bound_point = poly_D_bound_point + poly_D[len + i] - poly_D[i];
+        let eval_point_3 = comb_func(
+          &poly_A_bound_point,
+          &poly_B_bound_point,
+          &poly_C_bound_point,
+          &poly_D_bound_point,
+        );
+        (eval_point_0, eval_point_2, eval_point_3)
+      })
+      .reduce(
+        || (E::Scalar::ZERO, E::Scalar::ZERO, E::Scalar::ZERO),
+        |a, b| (a.0 + b.0, a.1 + b.1, a.2 + b.2),
+      )
+  }
+
+  pub fn prove_cubic_with_additive_term<F>(
+    claim: &E::Scalar,
+    num_rounds: usize,
+    poly_A: &mut MultilinearPolynomial<E::Scalar>,
+    poly_B: &mut MultilinearPolynomial<E::Scalar>,
+    poly_C: &mut MultilinearPolynomial<E::Scalar>,
+    poly_D: &mut MultilinearPolynomial<E::Scalar>,
+    comb_func: F,
+    transcript: &mut E::TE,
+  ) -> Result<(Self, Vec<E::Scalar>, Vec<E::Scalar>), NovaError>
+  where
+    F: Fn(&E::Scalar, &E::Scalar, &E::Scalar, &E::Scalar) -> E::Scalar + Sync,
+  {
+    let mut r: Vec<E::Scalar> = Vec::new();
+    let mut polys: Vec<CompressedUniPoly<E::Scalar>> = Vec::new();
+    let mut claim_per_round = *claim;
+
+    for _ in 0..num_rounds {
+      let poly = {
+        // Make an iterator returning the contributions to the evaluations
+        let (eval_point_0, eval_point_2, eval_point_3) =
+          Self::compute_eval_points_cubic_with_additive_term(
+            poly_A, poly_B, poly_C, poly_D, &comb_func,
+          );
+
+        let evals = vec![
+          eval_point_0,
+          claim_per_round - eval_point_0,
+          eval_point_2,
+          eval_point_3,
+        ];
+        UniPoly::from_evals(&evals)
+      };
+
+      // append the prover's message to the transcript
+      transcript.absorb(b"p", &poly);
+
+      //derive the verifier's challenge for the next round
+      let r_i = transcript.squeeze(b"c")?;
+      r.push(r_i);
+      polys.push(poly.compress());
+
+      // Set up next round
+      claim_per_round = poly.evaluate(&r_i);
+
+      // bound all tables to the verifier's challenge
+      rayon::join(
+        || {
+          rayon::join(
+            || poly_A.bind_poly_var_top(&r_i),
+            || poly_B.bind_poly_var_top(&r_i),
+          )
+        },
+        || {
+          rayon::join(
+            || poly_C.bind_poly_var_top(&r_i),
+            || poly_D.bind_poly_var_top(&r_i),
+          )
+        },
+      );
+    }
+
+    Ok((
+      Self {
+        compressed_polys: polys,
+      },
+      r,
+      vec![poly_A[0], poly_B[0], poly_C[0], poly_D[0]],
+    ))
+  }
+
+  pub fn prove_cubic_with_additive_term_batch<F>(
+    claims: &[E::Scalar],
+    num_rounds: &[usize],
+    mut poly_A_vec: Vec<MultilinearPolynomial<E::Scalar>>,
+    mut poly_B_vec: Vec<MultilinearPolynomial<E::Scalar>>,
+    mut poly_C_vec: Vec<MultilinearPolynomial<E::Scalar>>,
+    mut poly_D_vec: Vec<MultilinearPolynomial<E::Scalar>>,
+    coeffs: &[E::Scalar],
+    comb_func: F,
+    transcript: &mut E::TE,
+  ) -> Result<(Self, Vec<E::Scalar>, Vec<Vec<E::Scalar>>), NovaError>
+  where
+    F: Fn(&E::Scalar, &E::Scalar, &E::Scalar, &E::Scalar) -> E::Scalar + Sync,
+  {
+    let num_instances = claims.len();
+    assert_eq!(num_rounds.len(), num_instances);
+    assert_eq!(coeffs.len(), num_instances);
+    assert_eq!(poly_A_vec.len(), num_instances);
+    assert_eq!(poly_B_vec.len(), num_instances);
+    assert_eq!(poly_C_vec.len(), num_instances);
+    assert_eq!(poly_D_vec.len(), num_instances);
+
+    for (i, &num_rounds) in num_rounds.iter().enumerate() {
+      let expected_size = 1 << num_rounds;
+
+      // Direct indexing with the assumption that the index will always be in bounds
+      let a = &poly_A_vec[i];
+      let b = &poly_B_vec[i];
+      let c = &poly_C_vec[i];
+      let d = &poly_D_vec[i];
+
+      for (l, polyname) in [
+        (a.len(), "poly_A"),
+        (b.len(), "poly_B"),
+        (c.len(), "poly_C"),
+        (d.len(), "poly_D"),
+      ]
+      .iter()
+      {
+        assert_eq!(
+          *l, expected_size,
+          "Mismatch in size for {} at index {}",
+          polyname, i
+        );
+      }
+    }
+
+    let num_rounds_max = *num_rounds.iter().max().unwrap();
+
+    let mut r: Vec<E::Scalar> = Vec::new();
+    let mut polys: Vec<CompressedUniPoly<E::Scalar>> = Vec::new();
+    let mut claim_per_round = zip_with!(
+      iter,
+      (claims, num_rounds, coeffs),
+      |claim, num_rounds, coeff| {
+        let scaled_claim = E::Scalar::from((1 << (num_rounds_max - num_rounds)) as u64) * claim;
+        scaled_claim * *coeff
+      }
+    )
+    .sum();
+
+    for current_round in 0..num_rounds_max {
+      let remaining_rounds = num_rounds_max - current_round;
+      let evals: Vec<(E::Scalar, E::Scalar, E::Scalar)> = zip_with!(
+        par_iter,
+        (num_rounds, claims, poly_A_vec, poly_B_vec, poly_C_vec, poly_D_vec),
+        |num_rounds, claim, poly_A, poly_B, poly_C, poly_D| {
+          if remaining_rounds <= *num_rounds {
+            Self::compute_eval_points_cubic_with_additive_term(
+              poly_A, poly_B, poly_C, poly_D, &comb_func,
+            )
+          } else {
+            let remaining_variables = remaining_rounds - num_rounds - 1;
+            let scaled_claim = E::Scalar::from((1 << remaining_variables) as u64) * claim;
+            (scaled_claim, scaled_claim, scaled_claim)
+          }
+        }
+      )
+      .collect();
+
+      let evals_combined_0 = (0..num_instances).map(|i| evals[i].0 * coeffs[i]).sum();
+      let evals_combined_2 = (0..num_instances).map(|i| evals[i].1 * coeffs[i]).sum();
+      let evals_combined_3 = (0..num_instances).map(|i| evals[i].2 * coeffs[i]).sum();
+
+      let evals = vec![
+        evals_combined_0,
+        claim_per_round - evals_combined_0,
+        evals_combined_2,
+        evals_combined_3,
+      ];
+      let poly = UniPoly::from_evals(&evals);
+
+      // append the prover's message to the transcript
+      transcript.absorb(b"p", &poly);
+
+      //derive the verifier's challenge for the next round
+      let r_i = transcript.squeeze(b"c")?;
+      r.push(r_i);
+
+      polys.push(poly.compress());
+
+      // Set up next round
+      claim_per_round = poly.evaluate(&r_i);
+
+      // bound all the tables to the verifier's challenge
+
+      zip_with_for_each!(
+        (
+          num_rounds.par_iter(),
+          poly_A_vec.par_iter_mut(),
+          poly_B_vec.par_iter_mut(),
+          poly_C_vec.par_iter_mut(),
+          poly_D_vec.par_iter_mut()
+        ),
+        |num_rounds, poly_A, poly_B, poly_C, poly_D| {
+          if remaining_rounds <= *num_rounds {
+            let _ = rayon::join(
+              || {
+                rayon::join(
+                  || poly_A.bind_poly_var_top(&r_i),
+                  || poly_B.bind_poly_var_top(&r_i),
+                )
+              },
+              || {
+                rayon::join(
+                  || poly_C.bind_poly_var_top(&r_i),
+                  || poly_D.bind_poly_var_top(&r_i),
+                )
+              },
+            );
+          }
+        }
+      );
+    }
+
+    let poly_A_final = poly_A_vec.into_iter().map(|poly| poly[0]).collect();
+    let poly_B_final = poly_B_vec.into_iter().map(|poly| poly[0]).collect();
+    let poly_C_final = poly_C_vec.into_iter().map(|poly| poly[0]).collect();
+    let poly_D_final = poly_D_vec.into_iter().map(|poly| poly[0]).collect();
+
+    Ok((
+      Self {
+        compressed_polys: polys,
+      },
+      r,
+      vec![poly_A_final, poly_B_final, poly_C_final, poly_D_final],
+    ))
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/supernova/circuit.rs.html b/docs/src/arecibo/supernova/circuit.rs.html new file mode 100644 index 000000000..6f5aedd6f --- /dev/null +++ b/docs/src/arecibo/supernova/circuit.rs.html @@ -0,0 +1,1761 @@ +circuit.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+
//! Supernova implementation support arbitrary argumented circuits and running instances.
+//! There are two Verification Circuits for each argumented circuit: The primary and the secondary.
+//! Each of them is over a Pasta curve but
+//! only the primary executes the next step of the computation.
+//! Each circuit takes as input 2 hashes.
+//! Each circuit folds the last invocation of the other into the respective running instance, specified by `augmented_circuit_index`
+//!
+//! The augmented circuit F' for `SuperNova` that includes everything from Nova
+//!   and additionally checks:
+//!    1. Ui[] are contained in X[0] hash pre-image.
+//!    2. R1CS Instance u is folded into Ui[augmented_circuit_index] correctly; just like Nova IVC.
+//!    3. (optional by F logic) F circuit might check `program_counter_{i}` invoked current F circuit is legal or not.
+//!    3. F circuit produce `program_counter_{i+1}` and sent to next round for optionally constraint the next F' argumented circuit.
+use crate::{
+  constants::NUM_HASH_BITS,
+  gadgets::{
+    ecc::AllocatedPoint,
+    r1cs::{
+      conditionally_select_alloc_relaxed_r1cs,
+      conditionally_select_vec_allocated_relaxed_r1cs_instance, AllocatedR1CSInstance,
+      AllocatedRelaxedR1CSInstance,
+    },
+    utils::{
+      alloc_num_equals, alloc_scalar_as_base, alloc_zero, conditionally_select_vec, le_bits_to_num,
+    },
+  },
+  r1cs::{R1CSInstance, RelaxedR1CSInstance},
+  traits::{commitment::CommitmentTrait, Engine, ROCircuitTrait, ROConstantsCircuit},
+  Commitment,
+};
+use bellpepper_core::{
+  boolean::{AllocatedBit, Boolean},
+  num::AllocatedNum,
+  ConstraintSystem, SynthesisError,
+};
+
+use bellpepper::gadgets::Assignment;
+
+use abomonation_derive::Abomonation;
+use ff::{Field, PrimeField};
+use itertools::Itertools as _;
+use serde::{Deserialize, Serialize};
+use std::marker::PhantomData;
+
+use crate::supernova::{
+  num_ro_inputs,
+  utils::{get_from_vec_alloc_relaxed_r1cs, get_selector_vec_from_index},
+};
+
+/// A helper trait for a step of the incremental computation for `SuperNova` (i.e., circuit for F) -- to be implemented by
+/// applications.
+pub trait StepCircuit<F: PrimeField>: Send + Sync + Clone {
+  /// Return the the number of inputs or outputs of each step
+  /// (this method is called only at circuit synthesis time)
+  /// `synthesize` and `output` methods are expected to take as
+  /// input a vector of size equal to arity and output a vector of size equal to arity
+  fn arity(&self) -> usize;
+
+  /// Return this `StepCircuit`'s assigned index, for use when enforcing the program counter.
+  fn circuit_index(&self) -> usize;
+
+  /// Synthesize the circuit for a computation step and return variable
+  /// that corresponds to the output of the step `pc_{i+1}` and `z_{i+1}`
+  fn synthesize<CS: ConstraintSystem<F>>(
+    &self,
+    cs: &mut CS,
+    pc: Option<&AllocatedNum<F>>,
+    z: &[AllocatedNum<F>],
+  ) -> Result<(Option<AllocatedNum<F>>, Vec<AllocatedNum<F>>), SynthesisError>;
+}
+
+/// A helper trait for a step of the incremental computation for `SuperNova` (i.e., circuit for F) -- automatically
+/// implemented for `StepCircuit` and used internally to enforce that the circuit selected by the program counter is used
+/// at each step.
+pub trait EnforcingStepCircuit<F: PrimeField>: Send + Sync + Clone + StepCircuit<F> {
+  /// Delegate synthesis to `StepCircuit::synthesize`, and additionally, enforce the constraint that program counter
+  /// `pc`, if supplied, is equal to the circuit's assigned index.
+  fn enforcing_synthesize<CS: ConstraintSystem<F>>(
+    &self,
+    cs: &mut CS,
+    pc: Option<&AllocatedNum<F>>,
+    z: &[AllocatedNum<F>],
+  ) -> Result<(Option<AllocatedNum<F>>, Vec<AllocatedNum<F>>), SynthesisError> {
+    if let Some(pc) = pc {
+      let circuit_index = F::from(self.circuit_index() as u64);
+
+      // pc * 1 = circuit_index
+      cs.enforce(
+        || "pc matches circuit index",
+        |lc| lc + pc.get_variable(),
+        |lc| lc + CS::one(),
+        |lc| lc + (circuit_index, CS::one()),
+      );
+    }
+    self.synthesize(cs, pc, z)
+  }
+}
+
+impl<F: PrimeField, S: StepCircuit<F>> EnforcingStepCircuit<F> for S {}
+
+/// A trivial step circuit that simply returns the input
+#[derive(Clone, Debug, Default)]
+pub struct TrivialTestCircuit<F> {
+  _p: PhantomData<F>,
+}
+
+impl<F> StepCircuit<F> for TrivialTestCircuit<F>
+where
+  F: PrimeField,
+{
+  fn arity(&self) -> usize {
+    1
+  }
+
+  fn circuit_index(&self) -> usize {
+    0
+  }
+
+  fn synthesize<CS: ConstraintSystem<F>>(
+    &self,
+    _cs: &mut CS,
+    program_counter: Option<&AllocatedNum<F>>,
+    z: &[AllocatedNum<F>],
+  ) -> Result<(Option<AllocatedNum<F>>, Vec<AllocatedNum<F>>), SynthesisError> {
+    Ok((program_counter.cloned(), z.to_vec()))
+  }
+}
+
+/// A trivial step circuit that simply returns the input, for use on the secondary circuit when implementing NIVC.
+/// NOTE: This should not be needed. The secondary circuit doesn't need the program counter at all.
+/// Ideally, the need this fills could be met by `traits::circuit::TrivialTestCircuit` (or equivalent).
+#[derive(Clone, Debug, Default)]
+pub struct TrivialSecondaryCircuit<F> {
+  _p: PhantomData<F>,
+}
+
+impl<F> StepCircuit<F> for TrivialSecondaryCircuit<F>
+where
+  F: PrimeField,
+{
+  fn arity(&self) -> usize {
+    1
+  }
+
+  fn circuit_index(&self) -> usize {
+    0
+  }
+
+  fn synthesize<CS: ConstraintSystem<F>>(
+    &self,
+    _cs: &mut CS,
+    program_counter: Option<&AllocatedNum<F>>,
+    z: &[AllocatedNum<F>],
+  ) -> Result<(Option<AllocatedNum<F>>, Vec<AllocatedNum<F>>), SynthesisError> {
+    assert!(program_counter.is_none());
+    assert_eq!(z.len(), 1, "Arity of trivial step circuit should be 1");
+    Ok((None, z.to_vec()))
+  }
+}
+
+#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, Abomonation)]
+pub struct SuperNovaAugmentedCircuitParams {
+  limb_width: usize,
+  n_limbs: usize,
+  is_primary_circuit: bool, // A boolean indicating if this is the primary circuit
+}
+
+impl SuperNovaAugmentedCircuitParams {
+  pub const fn new(limb_width: usize, n_limbs: usize, is_primary_circuit: bool) -> Self {
+    Self {
+      limb_width,
+      n_limbs,
+      is_primary_circuit,
+    }
+  }
+
+  pub fn get_n_limbs(&self) -> usize {
+    self.n_limbs
+  }
+}
+
+#[derive(Debug)]
+pub struct SuperNovaAugmentedCircuitInputs<'a, E: Engine> {
+  pp_digest: E::Scalar,
+  i: E::Base,
+  /// Input to the circuit for the base case
+  z0: &'a [E::Base],
+  /// Input to the circuit for the non-base case
+  zi: Option<&'a [E::Base]>,
+  /// List of `RelaxedR1CSInstance`.
+  /// `None` if this is the base case.
+  /// Elements are `None` if the circuit at that index was not yet executed.
+  U: Option<&'a [Option<RelaxedR1CSInstance<E>>]>,
+  /// R1CS proof to be folded into U
+  u: Option<&'a R1CSInstance<E>>,
+  /// Nova folding proof for accumulating u into U[j]
+  T: Option<&'a Commitment<E>>,
+  /// Index of the current circuit
+  program_counter: Option<E::Base>,
+  /// Index j of circuit being folded into U[j]
+  last_augmented_circuit_index: E::Base,
+}
+
+impl<'a, E: Engine> SuperNovaAugmentedCircuitInputs<'a, E> {
+  /// Create new inputs/witness for the verification circuit
+  pub fn new(
+    pp_digest: E::Scalar,
+    i: E::Base,
+    z0: &'a [E::Base],
+    zi: Option<&'a [E::Base]>,
+    U: Option<&'a [Option<RelaxedR1CSInstance<E>>]>,
+    u: Option<&'a R1CSInstance<E>>,
+    T: Option<&'a Commitment<E>>,
+    program_counter: Option<E::Base>,
+    last_augmented_circuit_index: E::Base,
+  ) -> Self {
+    Self {
+      pp_digest,
+      i,
+      z0,
+      zi,
+      U,
+      u,
+      T,
+      program_counter,
+      last_augmented_circuit_index,
+    }
+  }
+}
+
+/// The augmented circuit F' in `SuperNova` that includes a step circuit F
+/// and the circuit for the verifier in `SuperNova`'s non-interactive folding scheme,
+/// `SuperNova` NIFS will fold strictly r1cs instance u with respective relaxed r1cs instance `U[last_augmented_circuit_index]`
+pub struct SuperNovaAugmentedCircuit<'a, E: Engine, SC: EnforcingStepCircuit<E::Base>> {
+  params: &'a SuperNovaAugmentedCircuitParams,
+  ro_consts: ROConstantsCircuit<E>,
+  inputs: Option<SuperNovaAugmentedCircuitInputs<'a, E>>,
+  step_circuit: &'a SC,          // The function that is applied for each step
+  num_augmented_circuits: usize, // number of overall augmented circuits
+}
+
+impl<'a, E: Engine, SC: EnforcingStepCircuit<E::Base>> SuperNovaAugmentedCircuit<'a, E, SC> {
+  /// Create a new verification circuit for the input relaxed r1cs instances
+  pub const fn new(
+    params: &'a SuperNovaAugmentedCircuitParams,
+    inputs: Option<SuperNovaAugmentedCircuitInputs<'a, E>>,
+    step_circuit: &'a SC,
+    ro_consts: ROConstantsCircuit<E>,
+    num_augmented_circuits: usize,
+  ) -> Self {
+    Self {
+      params,
+      inputs,
+      step_circuit,
+      ro_consts,
+      num_augmented_circuits,
+    }
+  }
+
+  /// Allocate all witnesses from the augmented function's non-deterministic inputs.
+  /// Optional entries are allocated as their default values.
+  fn alloc_witness<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    mut cs: CS,
+    arity: usize,
+    num_augmented_circuits: usize,
+  ) -> Result<
+    (
+      AllocatedNum<E::Base>,
+      AllocatedNum<E::Base>,
+      Vec<AllocatedNum<E::Base>>,
+      Vec<AllocatedNum<E::Base>>,
+      Vec<AllocatedRelaxedR1CSInstance<E>>,
+      AllocatedR1CSInstance<E>,
+      AllocatedPoint<E>,
+      Option<AllocatedNum<E::Base>>,
+      Vec<Boolean>,
+    ),
+    SynthesisError,
+  > {
+    let last_augmented_circuit_index =
+      AllocatedNum::alloc(cs.namespace(|| "last_augmented_circuit_index"), || {
+        Ok(self.inputs.get()?.last_augmented_circuit_index)
+      })?;
+
+    // Allocate the params
+    let params = alloc_scalar_as_base::<E, _>(
+      cs.namespace(|| "params"),
+      self.inputs.as_ref().map(|inputs| inputs.pp_digest),
+    )?;
+
+    // Allocate i
+    let i = AllocatedNum::alloc(cs.namespace(|| "i"), || Ok(self.inputs.get()?.i))?;
+
+    // Allocate program_counter only on primary circuit
+    let program_counter = if self.params.is_primary_circuit {
+      Some(AllocatedNum::alloc(
+        cs.namespace(|| "program_counter"),
+        || {
+          Ok(
+            self
+              .inputs
+              .get()?
+              .program_counter
+              .expect("program_counter missing"),
+          )
+        },
+      )?)
+    } else {
+      None
+    };
+
+    // Allocate z0
+    let z_0 = (0..arity)
+      .map(|i| {
+        AllocatedNum::alloc(cs.namespace(|| format!("z0_{i}")), || {
+          Ok(self.inputs.get()?.z0[i])
+        })
+      })
+      .collect::<Result<Vec<AllocatedNum<E::Base>>, _>>()?;
+
+    // Allocate zi. If inputs.zi is not provided (base case) allocate default value 0
+    let zero = vec![E::Base::ZERO; arity];
+    let z_i = (0..arity)
+      .map(|i| {
+        AllocatedNum::alloc(cs.namespace(|| format!("zi_{i}")), || {
+          Ok(self.inputs.get()?.zi.unwrap_or(&zero)[i])
+        })
+      })
+      .collect::<Result<Vec<AllocatedNum<E::Base>>, _>>()?;
+
+    // Allocate the running instances
+    let U = (0..num_augmented_circuits)
+      .map(|i| {
+        AllocatedRelaxedR1CSInstance::alloc(
+          cs.namespace(|| format!("Allocate U {:?}", i)),
+          self
+            .inputs
+            .as_ref()
+            .and_then(|inputs| inputs.U.and_then(|U| U[i].as_ref())),
+          self.params.limb_width,
+          self.params.n_limbs,
+        )
+      })
+      .collect::<Result<Vec<AllocatedRelaxedR1CSInstance<E>>, _>>()?;
+
+    // Allocate the r1cs instance to be folded in
+    let u = AllocatedR1CSInstance::alloc(
+      cs.namespace(|| "allocate instance u to fold"),
+      self.inputs.as_ref().and_then(|inputs| inputs.u),
+    )?;
+
+    // Allocate T
+    let T = AllocatedPoint::alloc(
+      cs.namespace(|| "allocate T"),
+      self
+        .inputs
+        .as_ref()
+        .and_then(|inputs| inputs.T.map(|T| T.to_coordinates())),
+    )?;
+    T.check_on_curve(cs.namespace(|| "check T on curve"))?;
+
+    // Compute instance selector
+    let last_augmented_circuit_selector = get_selector_vec_from_index(
+      cs.namespace(|| "instance selector"),
+      &last_augmented_circuit_index,
+      num_augmented_circuits,
+    )?;
+
+    Ok((
+      params,
+      i,
+      z_0,
+      z_i,
+      U,
+      u,
+      T,
+      program_counter,
+      last_augmented_circuit_selector,
+    ))
+  }
+
+  /// Synthesizes base case and returns the new relaxed `R1CSInstance`
+  fn synthesize_base_case<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    mut cs: CS,
+    u: AllocatedR1CSInstance<E>,
+    last_augmented_circuit_selector: &[Boolean],
+  ) -> Result<Vec<AllocatedRelaxedR1CSInstance<E>>, SynthesisError> {
+    let mut cs = cs.namespace(|| "alloc U_i default");
+
+    // Allocate a default relaxed r1cs instance
+    let default = AllocatedRelaxedR1CSInstance::default(
+      cs.namespace(|| "Allocate primary U_default".to_string()),
+      self.params.limb_width,
+      self.params.n_limbs,
+    )?;
+
+    // The primary circuit just initialize single AllocatedRelaxedR1CSInstance
+    let U_default = if self.params.is_primary_circuit {
+      vec![default]
+    } else {
+      // The secondary circuit convert the incoming R1CS instance on index which match last_augmented_circuit_index
+      let incoming_r1cs = AllocatedRelaxedR1CSInstance::from_r1cs_instance(
+        cs.namespace(|| "Allocate incoming_r1cs"),
+        u,
+        self.params.limb_width,
+        self.params.n_limbs,
+      )?;
+
+      last_augmented_circuit_selector
+        .iter()
+        .enumerate()
+        .map(|(i, equal_bit)| {
+          // If index match last_augmented_circuit_index, then return incoming_r1cs,
+          // otherwise return the default one
+          conditionally_select_alloc_relaxed_r1cs(
+            cs.namespace(|| format!("select on index namespace {:?}", i)),
+            &incoming_r1cs,
+            &default,
+            equal_bit,
+          )
+        })
+        .collect::<Result<Vec<AllocatedRelaxedR1CSInstance<E>>, _>>()?
+    };
+    Ok(U_default)
+  }
+
+  /// Synthesizes non base case and returns the new relaxed `R1CSInstance`
+  /// And a boolean indicating if all checks pass
+  fn synthesize_non_base_case<CS: ConstraintSystem<<E as Engine>::Base>>(
+    &self,
+    mut cs: CS,
+    params: &AllocatedNum<E::Base>,
+    i: &AllocatedNum<E::Base>,
+    z_0: &[AllocatedNum<E::Base>],
+    z_i: &[AllocatedNum<E::Base>],
+    U: &[AllocatedRelaxedR1CSInstance<E>],
+    u: &AllocatedR1CSInstance<E>,
+    T: &AllocatedPoint<E>,
+    arity: usize,
+    last_augmented_circuit_selector: &[Boolean],
+    program_counter: &Option<AllocatedNum<E::Base>>,
+  ) -> Result<(Vec<AllocatedRelaxedR1CSInstance<E>>, AllocatedBit), SynthesisError> {
+    // Check that u.x[0] = Hash(params, i, program_counter, z0, zi, U[])
+    let mut ro = E::ROCircuit::new(
+      self.ro_consts.clone(),
+      num_ro_inputs(
+        self.num_augmented_circuits,
+        self.params.get_n_limbs(),
+        arity,
+        self.params.is_primary_circuit,
+      ),
+    );
+    ro.absorb(params);
+    ro.absorb(i);
+
+    if self.params.is_primary_circuit {
+      if let Some(program_counter) = program_counter.as_ref() {
+        ro.absorb(program_counter)
+      } else {
+        Err(SynthesisError::AssignmentMissing)?
+      }
+    }
+
+    for e in z_0 {
+      ro.absorb(e);
+    }
+    for e in z_i {
+      ro.absorb(e);
+    }
+
+    U.iter().enumerate().try_for_each(|(i, U)| {
+      U.absorb_in_ro(cs.namespace(|| format!("absorb U {:?}", i)), &mut ro)
+    })?;
+
+    let hash_bits = ro.squeeze(cs.namespace(|| "Input hash"), NUM_HASH_BITS)?;
+    let hash = le_bits_to_num(cs.namespace(|| "bits to hash"), &hash_bits)?;
+    let check_pass: AllocatedBit = alloc_num_equals(
+      cs.namespace(|| "check consistency of u.X[0] with H(params, U, i, z0, zi)"),
+      &u.X0,
+      &hash,
+    )?;
+
+    // Run NIFS Verifier
+    let U_to_fold = get_from_vec_alloc_relaxed_r1cs(
+      cs.namespace(|| "U to fold"),
+      U,
+      last_augmented_circuit_selector,
+    )?;
+    let U_fold = U_to_fold.fold_with_r1cs(
+      cs.namespace(|| "compute fold of U and u"),
+      params,
+      u,
+      T,
+      self.ro_consts.clone(),
+      self.params.limb_width,
+      self.params.n_limbs,
+    )?;
+
+    // update AllocatedRelaxedR1CSInstance on index match augmented circuit index
+    let U_next: Vec<AllocatedRelaxedR1CSInstance<E>> = U
+      .iter()
+      .zip_eq(last_augmented_circuit_selector.iter())
+      .map(|(U, equal_bit)| {
+        conditionally_select_alloc_relaxed_r1cs(
+          cs.namespace(|| "select on index namespace"),
+          &U_fold,
+          U,
+          equal_bit,
+        )
+      })
+      .collect::<Result<Vec<AllocatedRelaxedR1CSInstance<E>>, _>>()?;
+
+    Ok((U_next, check_pass))
+  }
+
+  pub fn synthesize<CS: ConstraintSystem<<E as Engine>::Base>>(
+    self,
+    cs: &mut CS,
+  ) -> Result<(Option<AllocatedNum<E::Base>>, Vec<AllocatedNum<E::Base>>), SynthesisError> {
+    let arity = self.step_circuit.arity();
+    let num_augmented_circuits = if self.params.is_primary_circuit {
+      // primary circuit only fold single running instance with secondary output strict r1cs instance
+      1
+    } else {
+      // secondary circuit contains the logic to choose one of multiple augments running instance to fold
+      self.num_augmented_circuits
+    };
+
+    if self.inputs.is_some() {
+      // Check arity of z0
+      let z0_len = self.inputs.as_ref().map_or(0, |inputs| inputs.z0.len());
+      if self.step_circuit.arity() != z0_len {
+        return Err(SynthesisError::IncompatibleLengthVector(format!(
+          "z0_len {:?} != arity length {:?}",
+          z0_len,
+          self.step_circuit.arity()
+        )));
+      }
+
+      // The primary curve should always fold the circuit with index 0
+      let last_augmented_circuit_index = self
+        .inputs
+        .get()
+        .map_or(E::Base::ZERO, |inputs| inputs.last_augmented_circuit_index);
+      if self.params.is_primary_circuit && last_augmented_circuit_index != E::Base::ZERO {
+        return Err(SynthesisError::IncompatibleLengthVector(
+          "primary circuit running instance only valid on index 0".to_string(),
+        ));
+      }
+    }
+
+    // Allocate witnesses
+    let (params, i, z_0, z_i, U, u, T, program_counter, last_augmented_circuit_selector) = self
+      .alloc_witness(
+        cs.namespace(|| "allocate the circuit witness"),
+        arity,
+        num_augmented_circuits,
+      )?;
+
+    // Compute variable indicating if this is the base case
+    let zero = alloc_zero(cs.namespace(|| "zero"));
+    let is_base_case = alloc_num_equals(cs.namespace(|| "Check if base case"), &i.clone(), &zero)?;
+
+    // Synthesize the circuit for the non-base case and get the new running
+    // instances along with a boolean indicating if all checks have passed
+    // must use return `last_augmented_circuit_index_checked` since it got range checked
+    let (U_next_non_base, check_non_base_pass) = self.synthesize_non_base_case(
+      cs.namespace(|| "synthesize non base case"),
+      &params,
+      &i,
+      &z_0,
+      &z_i,
+      &U,
+      &u,
+      &T,
+      arity,
+      &last_augmented_circuit_selector,
+      &program_counter,
+    )?;
+
+    // Synthesize the circuit for the base case and get the new running instances
+    let U_next_base = self.synthesize_base_case(
+      cs.namespace(|| "base case"),
+      u.clone(),
+      &last_augmented_circuit_selector,
+    )?;
+
+    // Either check_non_base_pass=true or we are in the base case
+    let should_be_false = AllocatedBit::nor(
+      cs.namespace(|| "check_non_base_pass nor base_case"),
+      &check_non_base_pass,
+      &is_base_case,
+    )?;
+    cs.enforce(
+      || "check_non_base_pass nor base_case = false",
+      |lc| lc + should_be_false.get_variable(),
+      |lc| lc + CS::one(),
+      |lc| lc,
+    );
+
+    // Compute the U_next
+    let U_next = conditionally_select_vec_allocated_relaxed_r1cs_instance(
+      cs.namespace(|| "U_next"),
+      &U_next_base[..],
+      &U_next_non_base[..],
+      &Boolean::from(is_base_case.clone()),
+    )?;
+
+    // Compute i + 1
+    let i_next = AllocatedNum::alloc(cs.namespace(|| "i + 1"), || {
+      Ok(*i.get_value().get()? + E::Base::ONE)
+    })?;
+    cs.enforce(
+      || "check i + 1",
+      |lc| lc + i.get_variable() + CS::one(),
+      |lc| lc + CS::one(),
+      |lc| lc + i_next.get_variable(),
+    );
+
+    // Compute z_{i+1}
+    let z_input = conditionally_select_vec(
+      cs.namespace(|| "select input to F"),
+      &z_0,
+      &z_i,
+      &Boolean::from(is_base_case),
+    )?;
+
+    let (program_counter_new, z_next) = self.step_circuit.enforcing_synthesize(
+      &mut cs.namespace(|| "F"),
+      program_counter.as_ref(),
+      &z_input,
+    )?;
+
+    if z_next.len() != arity {
+      return Err(SynthesisError::IncompatibleLengthVector(
+        "z_next".to_string(),
+      ));
+    }
+
+    // To check correct folding sequencing we are just going to make a hash.
+    // The next RunningInstance folding can take the pre-image of this hash as witness and check.
+
+    // "Finally, there is a subtle sizing issue in the above description: in each step,
+    // because Ui+1 is produced as the public IO of F0 program_counter+1, it must be contained in
+    // the public IO of instance ui+1. In the next iteration, because ui+1 is folded
+    // into Ui+1[program_counter+1], this means that Ui+1[program_counter+1] is at least as large as Ui by the
+    // properties of the folding scheme. This means that the list of running instances
+    // grows in each step. To alleviate this issue, we have each F0j only produce a hash
+    // of its outputs as public output. In the subsequent step, the next augmented
+    // function takes as non-deterministic input a preimage to this hash." pg.16
+
+    // https://eprint.iacr.org/2022/1758.pdf
+
+    // Compute the new hash H(params, i+1, program_counter, z0, z_{i+1}, U_next)
+    let mut ro = E::ROCircuit::new(
+      self.ro_consts.clone(),
+      num_ro_inputs(
+        self.num_augmented_circuits,
+        self.params.get_n_limbs(),
+        self.step_circuit.arity(),
+        self.params.is_primary_circuit,
+      ),
+    );
+    ro.absorb(&params);
+    ro.absorb(&i_next);
+    // optionally absorb program counter if exist
+    if program_counter.is_some() {
+      ro.absorb(
+        program_counter_new
+          .as_ref()
+          .expect("new program counter missing"),
+      )
+    }
+    for e in &z_0 {
+      ro.absorb(e);
+    }
+    for e in &z_next {
+      ro.absorb(e);
+    }
+    U_next.iter().enumerate().try_for_each(|(i, U)| {
+      U.absorb_in_ro(cs.namespace(|| format!("absorb U_new {:?}", i)), &mut ro)
+    })?;
+
+    let hash_bits = ro.squeeze(cs.namespace(|| "output hash bits"), NUM_HASH_BITS)?;
+    let hash = le_bits_to_num(cs.namespace(|| "convert hash to num"), &hash_bits)?;
+
+    // We are cycling of curve implementation, so primary/secondary will rotate hash in IO for the others to check
+    // bypass unmodified hash of other circuit as next X[0]
+    // and output the computed the computed hash as next X[1]
+    u.X1
+      .inputize(cs.namespace(|| "bypass unmodified hash of the other circuit"))?;
+    hash.inputize(cs.namespace(|| "output new hash of this circuit"))?;
+
+    Ok((program_counter_new, z_next))
+  }
+}
+
+#[cfg(test)]
+mod tests {
+  use super::*;
+  use crate::{
+    bellpepper::{
+      r1cs::{NovaShape, NovaWitness},
+      solver::SatisfyingAssignment,
+      test_shape_cs::TestShapeCS,
+    },
+    constants::{BN_LIMB_WIDTH, BN_N_LIMBS},
+    gadgets::utils::scalar_as_base,
+    provider::{
+      poseidon::PoseidonConstantsCircuit,
+      {Bn256Engine, GrumpkinEngine}, {PallasEngine, VestaEngine},
+      {Secp256k1Engine, Secq256k1Engine},
+    },
+    supernova::circuit::TrivialTestCircuit,
+    traits::snark::default_ck_hint,
+  };
+  use expect_test::{expect, Expect};
+
+  // In the following we use 1 to refer to the primary, and 2 to refer to the secondary circuit
+  fn test_supernova_recursive_circuit_with<E1, E2>(
+    primary_params: &SuperNovaAugmentedCircuitParams,
+    secondary_params: &SuperNovaAugmentedCircuitParams,
+    ro_consts1: ROConstantsCircuit<E2>,
+    ro_consts2: ROConstantsCircuit<E1>,
+    num_constraints_primary: &Expect,
+    num_constraints_secondary: &Expect,
+    num_augmented_circuits: usize,
+  ) where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    let tc1 = TrivialTestCircuit::default();
+    // Initialize the shape and ck for the primary
+    let circuit1: SuperNovaAugmentedCircuit<'_, E2, TrivialTestCircuit<<E2 as Engine>::Base>> =
+      SuperNovaAugmentedCircuit::new(
+        primary_params,
+        None,
+        &tc1,
+        ro_consts1.clone(),
+        num_augmented_circuits,
+      );
+    let mut cs: TestShapeCS<E1> = TestShapeCS::new();
+    let _ = circuit1.synthesize(&mut cs);
+    let (shape1, ck1) = cs.r1cs_shape_and_key(&*default_ck_hint());
+
+    num_constraints_primary.assert_eq(&cs.num_constraints().to_string());
+
+    let tc2 = TrivialTestCircuit::default();
+    // Initialize the shape and ck for the secondary
+    let circuit2: SuperNovaAugmentedCircuit<'_, E1, TrivialTestCircuit<<E1 as Engine>::Base>> =
+      SuperNovaAugmentedCircuit::new(
+        secondary_params,
+        None,
+        &tc2,
+        ro_consts2.clone(),
+        num_augmented_circuits,
+      );
+    let mut cs: TestShapeCS<E2> = TestShapeCS::new();
+    let _ = circuit2.synthesize(&mut cs);
+    let (shape2, ck2) = cs.r1cs_shape_and_key(&*default_ck_hint());
+
+    num_constraints_secondary.assert_eq(&cs.num_constraints().to_string());
+
+    // Execute the base case for the primary
+    let zero1 = <<E2 as Engine>::Base as Field>::ZERO;
+    let mut cs1 = SatisfyingAssignment::<E1>::new();
+    let vzero1 = vec![zero1];
+    let inputs1: SuperNovaAugmentedCircuitInputs<'_, E2> = SuperNovaAugmentedCircuitInputs::new(
+      scalar_as_base::<E1>(zero1), // pass zero for testing
+      zero1,
+      &vzero1,
+      None,
+      None,
+      None,
+      None,
+      Some(zero1),
+      zero1,
+    );
+    let circuit1: SuperNovaAugmentedCircuit<'_, E2, TrivialTestCircuit<<E2 as Engine>::Base>> =
+      SuperNovaAugmentedCircuit::new(
+        primary_params,
+        Some(inputs1),
+        &tc1,
+        ro_consts1,
+        num_augmented_circuits,
+      );
+    let _ = circuit1.synthesize(&mut cs1);
+    let (inst1, witness1) = cs1.r1cs_instance_and_witness(&shape1, &ck1).unwrap();
+    // Make sure that this is satisfiable
+    assert!(shape1.is_sat(&ck1, &inst1, &witness1).is_ok());
+
+    // Execute the base case for the secondary
+    let zero2 = <<E1 as Engine>::Base as Field>::ZERO;
+    let mut cs2 = SatisfyingAssignment::<E2>::new();
+    let vzero2 = vec![zero2];
+    let inputs2: SuperNovaAugmentedCircuitInputs<'_, E1> = SuperNovaAugmentedCircuitInputs::new(
+      scalar_as_base::<E2>(zero2), // pass zero for testing
+      zero2,
+      &vzero2,
+      None,
+      None,
+      Some(&inst1),
+      None,
+      Some(zero2),
+      zero2,
+    );
+    let circuit2: SuperNovaAugmentedCircuit<'_, E1, TrivialTestCircuit<<E1 as Engine>::Base>> =
+      SuperNovaAugmentedCircuit::new(
+        secondary_params,
+        Some(inputs2),
+        &tc2,
+        ro_consts2,
+        num_augmented_circuits,
+      );
+    let _ = circuit2.synthesize(&mut cs2);
+    let (inst2, witness2) = cs2.r1cs_instance_and_witness(&shape2, &ck2).unwrap();
+    // Make sure that it is satisfiable
+    assert!(shape2.is_sat(&ck2, &inst2, &witness2).is_ok());
+  }
+
+  #[test]
+  fn test_supernova_recursive_circuit_pasta() {
+    // this test checks against values that must be replicated in benchmarks if changed here
+    let params1 = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+    let params2 = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
+    let ro_consts1: ROConstantsCircuit<VestaEngine> = PoseidonConstantsCircuit::default();
+    let ro_consts2: ROConstantsCircuit<PallasEngine> = PoseidonConstantsCircuit::default();
+
+    test_supernova_recursive_circuit_with::<PallasEngine, VestaEngine>(
+      &params1,
+      &params2,
+      ro_consts1,
+      ro_consts2,
+      &expect!["9844"],
+      &expect!["10392"],
+      1,
+    );
+    // TODO: extend to num_augmented_circuits >= 2
+  }
+
+  #[test]
+  fn test_supernova_recursive_circuit_grumpkin() {
+    let params1 = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+    let params2 = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
+    let ro_consts1: ROConstantsCircuit<GrumpkinEngine> = PoseidonConstantsCircuit::default();
+    let ro_consts2: ROConstantsCircuit<Bn256Engine> = PoseidonConstantsCircuit::default();
+
+    test_supernova_recursive_circuit_with::<Bn256Engine, GrumpkinEngine>(
+      &params1,
+      &params2,
+      ro_consts1,
+      ro_consts2,
+      &expect!["10012"],
+      &expect!["10581"],
+      1,
+    );
+    // TODO: extend to num_augmented_circuits >= 2
+  }
+
+  #[test]
+  fn test_supernova_recursive_circuit_secp() {
+    let params1 = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+    let params2 = SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
+    let ro_consts1: ROConstantsCircuit<Secq256k1Engine> = PoseidonConstantsCircuit::default();
+    let ro_consts2: ROConstantsCircuit<Secp256k1Engine> = PoseidonConstantsCircuit::default();
+
+    test_supernova_recursive_circuit_with::<Secp256k1Engine, Secq256k1Engine>(
+      &params1,
+      &params2,
+      ro_consts1,
+      ro_consts2,
+      &expect!["10291"],
+      &expect!["11004"],
+      1,
+    );
+    // TODO: extend to num_augmented_circuits >= 2
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/supernova/error.rs.html b/docs/src/arecibo/supernova/error.rs.html new file mode 100644 index 000000000..ec30b3478 --- /dev/null +++ b/docs/src/arecibo/supernova/error.rs.html @@ -0,0 +1,39 @@ +error.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+
//! This module defines errors returned by the library.
+use core::fmt::Debug;
+use thiserror::Error;
+
+use crate::errors::NovaError;
+
+/// Errors returned by Nova
+#[derive(Clone, Debug, Eq, PartialEq, Error)]
+pub enum SuperNovaError {
+  /// Nova error
+  #[error("NovaError")]
+  NovaError(#[from] NovaError),
+  /// missing commitment key
+  #[error("MissingCK")]
+  MissingCK,
+  /// Extended error for supernova
+  #[error("UnSatIndex")]
+  UnSatIndex(&'static str, usize),
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/supernova/mod.rs.html b/docs/src/arecibo/supernova/mod.rs.html new file mode 100644 index 000000000..f16637259 --- /dev/null +++ b/docs/src/arecibo/supernova/mod.rs.html @@ -0,0 +1,2309 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+777
+778
+779
+780
+781
+782
+783
+784
+785
+786
+787
+788
+789
+790
+791
+792
+793
+794
+795
+796
+797
+798
+799
+800
+801
+802
+803
+804
+805
+806
+807
+808
+809
+810
+811
+812
+813
+814
+815
+816
+817
+818
+819
+820
+821
+822
+823
+824
+825
+826
+827
+828
+829
+830
+831
+832
+833
+834
+835
+836
+837
+838
+839
+840
+841
+842
+843
+844
+845
+846
+847
+848
+849
+850
+851
+852
+853
+854
+855
+856
+857
+858
+859
+860
+861
+862
+863
+864
+865
+866
+867
+868
+869
+870
+871
+872
+873
+874
+875
+876
+877
+878
+879
+880
+881
+882
+883
+884
+885
+886
+887
+888
+889
+890
+891
+892
+893
+894
+895
+896
+897
+898
+899
+900
+901
+902
+903
+904
+905
+906
+907
+908
+909
+910
+911
+912
+913
+914
+915
+916
+917
+918
+919
+920
+921
+922
+923
+924
+925
+926
+927
+928
+929
+930
+931
+932
+933
+934
+935
+936
+937
+938
+939
+940
+941
+942
+943
+944
+945
+946
+947
+948
+949
+950
+951
+952
+953
+954
+955
+956
+957
+958
+959
+960
+961
+962
+963
+964
+965
+966
+967
+968
+969
+970
+971
+972
+973
+974
+975
+976
+977
+978
+979
+980
+981
+982
+983
+984
+985
+986
+987
+988
+989
+990
+991
+992
+993
+994
+995
+996
+997
+998
+999
+1000
+1001
+1002
+1003
+1004
+1005
+1006
+1007
+1008
+1009
+1010
+1011
+1012
+1013
+1014
+1015
+1016
+1017
+1018
+1019
+1020
+1021
+1022
+1023
+1024
+1025
+1026
+1027
+1028
+1029
+1030
+1031
+1032
+1033
+1034
+1035
+1036
+1037
+1038
+1039
+1040
+1041
+1042
+1043
+1044
+1045
+1046
+1047
+1048
+1049
+1050
+1051
+1052
+1053
+1054
+1055
+1056
+1057
+1058
+1059
+1060
+1061
+1062
+1063
+1064
+1065
+1066
+1067
+1068
+1069
+1070
+1071
+1072
+1073
+1074
+1075
+1076
+1077
+1078
+1079
+1080
+1081
+1082
+1083
+1084
+1085
+1086
+1087
+1088
+1089
+1090
+1091
+1092
+1093
+1094
+1095
+1096
+1097
+1098
+1099
+1100
+1101
+1102
+1103
+1104
+1105
+1106
+1107
+1108
+1109
+1110
+1111
+1112
+1113
+1114
+1115
+1116
+1117
+1118
+1119
+1120
+1121
+1122
+1123
+1124
+1125
+1126
+1127
+1128
+1129
+1130
+1131
+1132
+1133
+1134
+1135
+1136
+1137
+1138
+1139
+1140
+1141
+1142
+1143
+1144
+1145
+1146
+1147
+1148
+1149
+1150
+1151
+1152
+1153
+1154
+
#![doc = include_str!("./Readme.md")]
+
+use std::marker::PhantomData;
+use std::ops::Index;
+
+use crate::{
+  bellpepper::shape_cs::ShapeCS,
+  constants::{BN_LIMB_WIDTH, BN_N_LIMBS, NUM_HASH_BITS},
+  digest::{DigestComputer, SimpleDigestible},
+  errors::NovaError,
+  r1cs::{
+    self, commitment_key_size, CommitmentKeyHint, R1CSInstance, R1CSResult, R1CSShape, R1CSWitness,
+    RelaxedR1CSInstance, RelaxedR1CSWitness,
+  },
+  scalar_as_base,
+  traits::{
+    commitment::{CommitmentEngineTrait, CommitmentTrait},
+    AbsorbInROTrait, Engine, ROConstants, ROConstantsCircuit, ROTrait,
+  },
+  Commitment, CommitmentKey, R1CSWithArity,
+};
+
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use bellpepper_core::SynthesisError;
+use ff::{Field, PrimeField};
+use itertools::Itertools as _;
+use once_cell::sync::OnceCell;
+use rayon::prelude::*;
+use serde::{Deserialize, Serialize};
+use tracing::debug;
+
+use crate::bellpepper::{
+  r1cs::{NovaShape, NovaWitness},
+  solver::SatisfyingAssignment,
+};
+use bellpepper_core::ConstraintSystem;
+
+use crate::nifs::NIFS;
+
+mod circuit; // declare the module first
+pub use circuit::{StepCircuit, TrivialSecondaryCircuit, TrivialTestCircuit};
+use circuit::{
+  SuperNovaAugmentedCircuit, SuperNovaAugmentedCircuitInputs, SuperNovaAugmentedCircuitParams,
+};
+use error::SuperNovaError;
+
+/// A struct that manages all the digests of the primary circuits of a SuperNova instance
+#[derive(Clone, PartialEq, Eq, Serialize, Deserialize)]
+pub struct CircuitDigests<E: Engine> {
+  digests: Vec<E::Scalar>,
+}
+
+impl<E: Engine> SimpleDigestible for CircuitDigests<E> {}
+
+impl<E: Engine> std::ops::Deref for CircuitDigests<E> {
+  type Target = Vec<E::Scalar>;
+
+  fn deref(&self) -> &Self::Target {
+    &self.digests
+  }
+}
+
+impl<E: Engine> CircuitDigests<E> {
+  /// Construct a new [CircuitDigests]
+  pub fn new(digests: Vec<E::Scalar>) -> Self {
+    Self { digests }
+  }
+
+  /// Return the [CircuitDigests]' digest.
+  pub fn digest(&self) -> E::Scalar {
+    let dc: DigestComputer<'_, <E as Engine>::Scalar, Self> = DigestComputer::new(self);
+    dc.digest().expect("Failure in computing digest")
+  }
+}
+
+/// A vector of [R1CSWithArity] adjoined to a set of [PublicParams]
+#[derive(Clone, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct PublicParams<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  /// The internal circuit shapes
+  circuit_shapes: Vec<R1CSWithArity<E1>>,
+
+  ro_consts_primary: ROConstants<E1>,
+  ro_consts_circuit_primary: ROConstantsCircuit<E2>,
+  ck_primary: CommitmentKey<E1>, // This is shared between all circuit params
+  augmented_circuit_params_primary: SuperNovaAugmentedCircuitParams,
+
+  ro_consts_secondary: ROConstants<E2>,
+  ro_consts_circuit_secondary: ROConstantsCircuit<E1>,
+  ck_secondary: CommitmentKey<E2>,
+  circuit_shape_secondary: R1CSWithArity<E2>,
+  augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams,
+
+  /// Digest constructed from this `PublicParams`' parameters
+  #[serde(skip, default = "OnceCell::new")]
+  digest: OnceCell<E1::Scalar>,
+  _p: PhantomData<(C1, C2)>,
+}
+
+/// Auxiliary [PublicParams] information about the commitment keys and
+/// secondary circuit. This is used as a helper struct when reconstructing
+/// [PublicParams] downstream in lurk.
+#[derive(Clone, PartialEq, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  <E1::Scalar as PrimeField>::Repr: Abomonation,
+  <E2::Scalar as PrimeField>::Repr: Abomonation,
+)]
+pub struct AuxParams<E1, E2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+{
+  ro_consts_primary: ROConstants<E1>,
+  ro_consts_circuit_primary: ROConstantsCircuit<E2>,
+  ck_primary: CommitmentKey<E1>, // This is shared between all circuit params
+  augmented_circuit_params_primary: SuperNovaAugmentedCircuitParams,
+
+  ro_consts_secondary: ROConstants<E2>,
+  ro_consts_circuit_secondary: ROConstantsCircuit<E1>,
+  ck_secondary: CommitmentKey<E2>,
+  circuit_shape_secondary: R1CSWithArity<E2>,
+  augmented_circuit_params_secondary: SuperNovaAugmentedCircuitParams,
+
+  #[abomonate_with(<E1::Scalar as PrimeField>::Repr)]
+  digest: E1::Scalar,
+}
+
+impl<E1, E2, C1, C2> Index<usize> for PublicParams<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  type Output = R1CSWithArity<E1>;
+
+  fn index(&self, index: usize) -> &Self::Output {
+    &self.circuit_shapes[index]
+  }
+}
+
+impl<E1, E2, C1, C2> SimpleDigestible for PublicParams<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+}
+
+impl<E1, E2, C1, C2> PublicParams<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  /// Construct a new [PublicParams]
+  ///
+  /// # Note
+  ///
+  /// Public parameters set up a number of bases for the homomorphic commitment scheme of Nova.
+  ///
+  /// Some final compressing SNARKs, like variants of Spartan, use computation commitments that require
+  /// larger sizes for these parameters. These SNARKs provide a hint for these values by
+  /// implementing `RelaxedR1CSSNARKTrait::commitment_key_floor()`, which can be passed to this function.
+  ///
+  /// If you're not using such a SNARK, pass `&(|_| 0)` instead.
+  ///
+  /// # Arguments
+  ///
+  /// * `non_uniform_circuit`: The non-uniform circuit of type `NC`.
+  /// * `ck_hint1`: A `CommitmentKeyHint` for `E1`, which is a function that provides a hint
+  ///    for the number of generators required in the commitment scheme for the primary circuit.
+  /// * `ck_hint2`: A `CommitmentKeyHint` for `E2`, similar to `ck_hint1`, but for the secondary circuit.
+  pub fn setup<NC: NonUniformCircuit<E1, E2, C1, C2>>(
+    non_uniform_circuit: &NC,
+    ck_hint1: &CommitmentKeyHint<E1>,
+    ck_hint2: &CommitmentKeyHint<E2>,
+  ) -> Self {
+    let num_circuits = non_uniform_circuit.num_circuits();
+
+    let augmented_circuit_params_primary =
+      SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+    let ro_consts_primary: ROConstants<E1> = ROConstants::<E1>::default();
+    // ro_consts_circuit_primary are parameterized by E2 because the type alias uses E2::Base = E1::Scalar
+    let ro_consts_circuit_primary: ROConstantsCircuit<E2> = ROConstantsCircuit::<E2>::default();
+
+    let circuit_shapes = (0..num_circuits)
+      .map(|i| {
+        let c_primary = non_uniform_circuit.primary_circuit(i);
+        let F_arity = c_primary.arity();
+        // Initialize ck for the primary
+        let circuit_primary: SuperNovaAugmentedCircuit<'_, E2, C1> = SuperNovaAugmentedCircuit::new(
+          &augmented_circuit_params_primary,
+          None,
+          &c_primary,
+          ro_consts_circuit_primary.clone(),
+          num_circuits,
+        );
+        let mut cs: ShapeCS<E1> = ShapeCS::new();
+        circuit_primary
+          .synthesize(&mut cs)
+          .expect("circuit synthesis failed");
+
+        // We use the largest commitment_key for all instances
+        let r1cs_shape_primary = cs.r1cs_shape();
+        R1CSWithArity::new(r1cs_shape_primary, F_arity)
+      })
+      .collect::<Vec<_>>();
+
+    let ck_primary = Self::compute_primary_ck(&circuit_shapes, ck_hint1);
+
+    let augmented_circuit_params_secondary =
+      SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, false);
+    let ro_consts_secondary: ROConstants<E2> = ROConstants::<E2>::default();
+    let c_secondary = non_uniform_circuit.secondary_circuit();
+    let F_arity_secondary = c_secondary.arity();
+    let ro_consts_circuit_secondary: ROConstantsCircuit<E1> = ROConstantsCircuit::<E1>::default();
+
+    let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, C2> = SuperNovaAugmentedCircuit::new(
+      &augmented_circuit_params_secondary,
+      None,
+      &c_secondary,
+      ro_consts_circuit_secondary.clone(),
+      num_circuits,
+    );
+    let mut cs: ShapeCS<E2> = ShapeCS::new();
+    circuit_secondary
+      .synthesize(&mut cs)
+      .expect("circuit synthesis failed");
+    let (r1cs_shape_secondary, ck_secondary) = cs.r1cs_shape_and_key(ck_hint2);
+    let circuit_shape_secondary = R1CSWithArity::new(r1cs_shape_secondary, F_arity_secondary);
+
+    let pp = Self {
+      circuit_shapes,
+      ro_consts_primary,
+      ro_consts_circuit_primary,
+      ck_primary,
+      augmented_circuit_params_primary,
+      ro_consts_secondary,
+      ro_consts_circuit_secondary,
+      ck_secondary,
+      circuit_shape_secondary,
+      augmented_circuit_params_secondary,
+      digest: OnceCell::new(),
+      _p: PhantomData,
+    };
+
+    // make sure to initialize the `OnceCell` and compute the digest
+    // and avoid paying for unexpected performance costs later
+    pp.digest();
+    pp
+  }
+
+  /// Breaks down an instance of [PublicParams] into the circuit params and auxiliary params.
+  pub fn into_parts(self) -> (Vec<R1CSWithArity<E1>>, AuxParams<E1, E2>) {
+    let digest = self.digest();
+
+    let Self {
+      circuit_shapes,
+      ro_consts_primary,
+      ro_consts_circuit_primary,
+      ck_primary,
+      augmented_circuit_params_primary,
+      ro_consts_secondary,
+      ro_consts_circuit_secondary,
+      ck_secondary,
+      circuit_shape_secondary,
+      augmented_circuit_params_secondary,
+      digest: _digest,
+      _p,
+    } = self;
+
+    let aux_params = AuxParams {
+      ro_consts_primary,
+      ro_consts_circuit_primary,
+      ck_primary,
+      augmented_circuit_params_primary,
+      ro_consts_secondary,
+      ro_consts_circuit_secondary,
+      ck_secondary,
+      circuit_shape_secondary,
+      augmented_circuit_params_secondary,
+      digest,
+    };
+
+    (circuit_shapes, aux_params)
+  }
+
+  /// Create a [PublicParams] from a vector of raw [R1CSWithArity] and auxiliary params.
+  pub fn from_parts(circuit_shapes: Vec<R1CSWithArity<E1>>, aux_params: AuxParams<E1, E2>) -> Self {
+    let pp = Self {
+      circuit_shapes,
+      ro_consts_primary: aux_params.ro_consts_primary,
+      ro_consts_circuit_primary: aux_params.ro_consts_circuit_primary,
+      ck_primary: aux_params.ck_primary,
+      augmented_circuit_params_primary: aux_params.augmented_circuit_params_primary,
+      ro_consts_secondary: aux_params.ro_consts_secondary,
+      ro_consts_circuit_secondary: aux_params.ro_consts_circuit_secondary,
+      ck_secondary: aux_params.ck_secondary,
+      circuit_shape_secondary: aux_params.circuit_shape_secondary,
+      augmented_circuit_params_secondary: aux_params.augmented_circuit_params_secondary,
+      digest: OnceCell::new(),
+      _p: PhantomData,
+    };
+    assert_eq!(
+      aux_params.digest,
+      pp.digest(),
+      "param data is invalid; aux_params contained the incorrect digest"
+    );
+    pp
+  }
+
+  /// Create a [PublicParams] from a vector of raw [R1CSWithArity] and auxiliary params.
+  /// We don't check that the `aux_params.digest` is a valid digest for the created params.
+  pub fn from_parts_unchecked(
+    circuit_shapes: Vec<R1CSWithArity<E1>>,
+    aux_params: AuxParams<E1, E2>,
+  ) -> Self {
+    Self {
+      circuit_shapes,
+      ro_consts_primary: aux_params.ro_consts_primary,
+      ro_consts_circuit_primary: aux_params.ro_consts_circuit_primary,
+      ck_primary: aux_params.ck_primary,
+      augmented_circuit_params_primary: aux_params.augmented_circuit_params_primary,
+      ro_consts_secondary: aux_params.ro_consts_secondary,
+      ro_consts_circuit_secondary: aux_params.ro_consts_circuit_secondary,
+      ck_secondary: aux_params.ck_secondary,
+      circuit_shape_secondary: aux_params.circuit_shape_secondary,
+      augmented_circuit_params_secondary: aux_params.augmented_circuit_params_secondary,
+      digest: aux_params.digest.into(),
+      _p: PhantomData,
+    }
+  }
+
+  /// Compute primary and secondary commitment keys sized to handle the largest of the circuits in the provided
+  /// `R1CSWithArity`.
+  fn compute_primary_ck(
+    circuit_params: &[R1CSWithArity<E1>],
+    ck_hint1: &CommitmentKeyHint<E1>,
+  ) -> CommitmentKey<E1> {
+    let size_primary = circuit_params
+      .iter()
+      .map(|circuit| commitment_key_size(&circuit.r1cs_shape, ck_hint1))
+      .max()
+      .unwrap();
+
+    E1::CE::setup(b"ck", size_primary)
+  }
+
+  /// Return the [PublicParams]' digest.
+  pub fn digest(&self) -> E1::Scalar {
+    self
+      .digest
+      .get_or_try_init(|| {
+        let dc: DigestComputer<'_, <E1 as Engine>::Scalar, Self> = DigestComputer::new(self);
+        dc.digest()
+      })
+      .cloned()
+      .expect("Failure in retrieving digest")
+  }
+
+  /// All of the primary circuit digests of this [PublicParams]
+  pub fn circuit_param_digests(&self) -> CircuitDigests<E1> {
+    let digests = self
+      .circuit_shapes
+      .iter()
+      .map(|cp| cp.digest())
+      .collect::<Vec<_>>();
+    CircuitDigests { digests }
+  }
+
+  /// Returns all the primary R1CS Shapes
+  fn primary_r1cs_shapes(&self) -> Vec<&R1CSShape<E1>> {
+    self
+      .circuit_shapes
+      .iter()
+      .map(|cs| &cs.r1cs_shape)
+      .collect::<Vec<_>>()
+  }
+}
+
+/// A resource buffer for SuperNova's [`RecursiveSNARK`] for storing scratch values that are computed by `prove_step`,
+/// which allows the reuse of memory allocations and avoids unnecessary new allocations in the critical section.
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+struct ResourceBuffer<E: Engine> {
+  l_w: Option<R1CSWitness<E>>,
+  l_u: Option<R1CSInstance<E>>,
+
+  ABC_Z_1: R1CSResult<E>,
+  ABC_Z_2: R1CSResult<E>,
+
+  /// buffer for `commit_T`
+  T: Vec<E::Scalar>,
+}
+
+/// A SNARK that proves the correct execution of an non-uniform incremental computation
+#[derive(Clone, Debug, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct RecursiveSNARK<E1, E2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+{
+  // Cached digest of the public parameters
+  pp_digest: E1::Scalar,
+  num_augmented_circuits: usize,
+
+  // Number of iterations performed up to now
+  i: usize,
+
+  // Inputs and outputs of the primary circuits
+  z0_primary: Vec<E1::Scalar>,
+  zi_primary: Vec<E1::Scalar>,
+
+  // Proven circuit index, and current program counter
+  proven_circuit_index: usize,
+  program_counter: E1::Scalar,
+
+  /// Buffer for memory needed by the primary fold-step
+  buffer_primary: ResourceBuffer<E1>,
+  /// Buffer for memory needed by the secondary fold-step
+  buffer_secondary: ResourceBuffer<E2>,
+
+  // Relaxed instances for the primary circuits
+  // Entries are `None` if the circuit has not been executed yet
+  r_W_primary: Vec<Option<RelaxedR1CSWitness<E1>>>,
+  r_U_primary: Vec<Option<RelaxedR1CSInstance<E1>>>,
+
+  // Inputs and outputs of the secondary circuit
+  z0_secondary: Vec<E2::Scalar>,
+  zi_secondary: Vec<E2::Scalar>,
+  // Relaxed instance for the secondary circuit
+  r_W_secondary: RelaxedR1CSWitness<E2>,
+  r_U_secondary: RelaxedR1CSInstance<E2>,
+  // Proof for the secondary circuit to be accumulated into r_secondary in the next iteration
+  l_w_secondary: R1CSWitness<E2>,
+  l_u_secondary: R1CSInstance<E2>,
+}
+
+impl<E1, E2> RecursiveSNARK<E1, E2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+{
+  /// iterate base step to get new instance of recursive SNARK
+  #[allow(clippy::too_many_arguments)]
+  pub fn new<
+    C0: NonUniformCircuit<E1, E2, C1, C2>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+  >(
+    pp: &PublicParams<E1, E2, C1, C2>,
+    non_uniform_circuit: &C0,
+    c_primary: &C1,
+    c_secondary: &C2,
+    z0_primary: &[E1::Scalar],
+    z0_secondary: &[E2::Scalar],
+  ) -> Result<Self, SuperNovaError> {
+    let num_augmented_circuits = non_uniform_circuit.num_circuits();
+    let circuit_index = non_uniform_circuit.initial_circuit_index();
+
+    let r1cs_secondary = &pp.circuit_shape_secondary.r1cs_shape;
+
+    // check the length of the secondary initial input
+    if z0_secondary.len() != pp.circuit_shape_secondary.F_arity {
+      return Err(SuperNovaError::NovaError(
+        NovaError::InvalidStepOutputLength,
+      ));
+    }
+
+    // check the arity of all the primary circuits match the initial input length
+    pp.circuit_shapes.iter().try_for_each(|circuit| {
+      if circuit.F_arity != z0_primary.len() {
+        return Err(SuperNovaError::NovaError(
+          NovaError::InvalidStepOutputLength,
+        ));
+      }
+      Ok(())
+    })?;
+
+    // base case for the primary
+    let mut cs_primary = SatisfyingAssignment::<E1>::new();
+    let program_counter = E1::Scalar::from(circuit_index as u64);
+    let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, E2> =
+      SuperNovaAugmentedCircuitInputs::new(
+        scalar_as_base::<E1>(pp.digest()),
+        E1::Scalar::ZERO,
+        z0_primary,
+        None,                  // zi = None for basecase
+        None,                  // U = [None], since no previous proofs have been computed
+        None,                  // u = None since we are not verifying a secondary circuit
+        None,                  // T = None since there is not proof to fold
+        Some(program_counter), // pc = initial_program_counter for primary circuit
+        E1::Scalar::ZERO,      // u_index is always zero for the primary circuit
+      );
+
+    let circuit_primary: SuperNovaAugmentedCircuit<'_, E2, C1> = SuperNovaAugmentedCircuit::new(
+      &pp.augmented_circuit_params_primary,
+      Some(inputs_primary),
+      c_primary,
+      pp.ro_consts_circuit_primary.clone(),
+      num_augmented_circuits,
+    );
+
+    let (zi_primary_pc_next, zi_primary) =
+      circuit_primary.synthesize(&mut cs_primary).map_err(|err| {
+        debug!("err {:?}", err);
+        NovaError::from(err)
+      })?;
+    if zi_primary.len() != pp[circuit_index].F_arity {
+      return Err(SuperNovaError::NovaError(
+        NovaError::InvalidStepOutputLength,
+      ));
+    }
+    let (u_primary, w_primary) = cs_primary
+      .r1cs_instance_and_witness(&pp[circuit_index].r1cs_shape, &pp.ck_primary)
+      .map_err(|err| {
+        debug!("err {:?}", err);
+        err
+      })?;
+
+    // base case for the secondary
+    let mut cs_secondary = SatisfyingAssignment::<E2>::new();
+    let u_primary_index = E2::Scalar::from(circuit_index as u64);
+    let inputs_secondary: SuperNovaAugmentedCircuitInputs<'_, E1> =
+      SuperNovaAugmentedCircuitInputs::new(
+        pp.digest(),
+        E2::Scalar::ZERO,
+        z0_secondary,
+        None,             // zi = None for basecase
+        None,             // U = Empty list of accumulators for the primary circuits
+        Some(&u_primary), // Proof for first iteration of current primary circuit
+        None,             // T = None, since we just copy u_primary rather than fold it
+        None,             // program_counter is always None for secondary circuit
+        u_primary_index,  // index of the circuit proof u_primary
+      );
+    let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, C2> = SuperNovaAugmentedCircuit::new(
+      &pp.augmented_circuit_params_secondary,
+      Some(inputs_secondary),
+      c_secondary,
+      pp.ro_consts_circuit_secondary.clone(),
+      num_augmented_circuits,
+    );
+    let (_, zi_secondary) = circuit_secondary
+      .synthesize(&mut cs_secondary)
+      .map_err(NovaError::from)?;
+    if zi_secondary.len() != pp.circuit_shape_secondary.F_arity {
+      return Err(NovaError::InvalidStepOutputLength.into());
+    }
+    let (u_secondary, w_secondary) = cs_secondary
+      .r1cs_instance_and_witness(r1cs_secondary, &pp.ck_secondary)
+      .map_err(|_| SuperNovaError::NovaError(NovaError::UnSat))?;
+
+    // IVC proof for the primary circuit
+    let l_w_primary = w_primary;
+    let l_u_primary = u_primary;
+    let r_W_primary =
+      RelaxedR1CSWitness::from_r1cs_witness(&pp[circuit_index].r1cs_shape, l_w_primary);
+
+    let r_U_primary = RelaxedR1CSInstance::from_r1cs_instance(
+      &pp.ck_primary,
+      &pp[circuit_index].r1cs_shape,
+      l_u_primary,
+    );
+
+    // IVC proof of the secondary circuit
+    let l_w_secondary = w_secondary;
+    let l_u_secondary = u_secondary;
+
+    // Initialize relaxed instance/witness pair for the secondary circuit proofs
+    let r_W_secondary: RelaxedR1CSWitness<E2> = RelaxedR1CSWitness::<E2>::default(r1cs_secondary);
+    let r_U_secondary = RelaxedR1CSInstance::default(&pp.ck_secondary, r1cs_secondary);
+
+    // Outputs of the two circuits and next program counter thus far.
+    let zi_primary = zi_primary
+      .iter()
+      .map(|v| {
+        v.get_value()
+          .ok_or(NovaError::from(SynthesisError::AssignmentMissing).into())
+      })
+      .collect::<Result<Vec<<E1 as Engine>::Scalar>, SuperNovaError>>()?;
+    let zi_primary_pc_next = zi_primary_pc_next
+      .expect("zi_primary_pc_next missing")
+      .get_value()
+      .ok_or::<SuperNovaError>(NovaError::from(SynthesisError::AssignmentMissing).into())?;
+    let zi_secondary = zi_secondary
+      .iter()
+      .map(|v| {
+        v.get_value()
+          .ok_or(NovaError::from(SynthesisError::AssignmentMissing).into())
+      })
+      .collect::<Result<Vec<<E2 as Engine>::Scalar>, SuperNovaError>>()?;
+
+    // handle the base case by initialize U_next in next round
+    let r_W_primary_initial_list = (0..num_augmented_circuits)
+      .map(|i| (i == circuit_index).then(|| r_W_primary.clone()))
+      .collect::<Vec<Option<RelaxedR1CSWitness<E1>>>>();
+
+    let r_U_primary_initial_list = (0..num_augmented_circuits)
+      .map(|i| (i == circuit_index).then(|| r_U_primary.clone()))
+      .collect::<Vec<Option<RelaxedR1CSInstance<E1>>>>();
+
+    // find the largest length r1cs shape for the buffer size
+    let max_num_cons = pp
+      .circuit_shapes
+      .iter()
+      .map(|circuit| circuit.r1cs_shape.num_cons)
+      .max()
+      .unwrap();
+
+    let buffer_primary = ResourceBuffer {
+      l_w: None,
+      l_u: None,
+      ABC_Z_1: R1CSResult::default(max_num_cons),
+      ABC_Z_2: R1CSResult::default(max_num_cons),
+      T: r1cs::default_T::<E1>(max_num_cons),
+    };
+
+    let buffer_secondary = ResourceBuffer {
+      l_w: None,
+      l_u: None,
+      ABC_Z_1: R1CSResult::default(r1cs_secondary.num_cons),
+      ABC_Z_2: R1CSResult::default(r1cs_secondary.num_cons),
+      T: r1cs::default_T::<E2>(r1cs_secondary.num_cons),
+    };
+
+    Ok(Self {
+      pp_digest: pp.digest(),
+      num_augmented_circuits,
+      i: 0_usize, // after base case, next iteration start from 1
+      z0_primary: z0_primary.to_vec(),
+      zi_primary,
+
+      proven_circuit_index: circuit_index,
+      program_counter: zi_primary_pc_next,
+
+      buffer_primary,
+      buffer_secondary,
+
+      r_W_primary: r_W_primary_initial_list,
+      r_U_primary: r_U_primary_initial_list,
+      z0_secondary: z0_secondary.to_vec(),
+      zi_secondary,
+      r_W_secondary,
+      r_U_secondary,
+      l_w_secondary,
+      l_u_secondary,
+    })
+  }
+
+  /// executing a step of the incremental computation
+  #[allow(clippy::too_many_arguments)]
+  #[tracing::instrument(skip_all, name = "supernova::RecursiveSNARK::prove_step")]
+  pub fn prove_step<C1: StepCircuit<E1::Scalar>, C2: StepCircuit<E2::Scalar>>(
+    &mut self,
+    pp: &PublicParams<E1, E2, C1, C2>,
+    c_primary: &C1,
+    c_secondary: &C2,
+  ) -> Result<(), SuperNovaError> {
+    // First step was already done in the constructor
+    if self.i == 0 {
+      self.i = 1;
+      return Ok(());
+    }
+
+    // save the inputs before proceeding to the `i+1`th step
+    let r_U_primary_i = self.r_U_primary.clone();
+    // Create single-entry accumulator list for the secondary circuit to hand to SuperNovaAugmentedCircuitInputs
+    let r_U_secondary_i = vec![Some(self.r_U_secondary.clone())];
+    let l_u_secondary_i = self.l_u_secondary.clone();
+
+    let circuit_index = c_primary.circuit_index();
+    assert_eq!(self.program_counter, E1::Scalar::from(circuit_index as u64));
+
+    // fold the secondary circuit's instance
+    let nifs_secondary = NIFS::prove_mut(
+      &pp.ck_secondary,
+      &pp.ro_consts_secondary,
+      &scalar_as_base::<E1>(self.pp_digest),
+      &pp.circuit_shape_secondary.r1cs_shape,
+      &mut self.r_U_secondary,
+      &mut self.r_W_secondary,
+      &self.l_u_secondary,
+      &self.l_w_secondary,
+      &mut self.buffer_secondary.T,
+      &mut self.buffer_secondary.ABC_Z_1,
+      &mut self.buffer_secondary.ABC_Z_2,
+    )
+    .map_err(SuperNovaError::NovaError)?;
+
+    let mut cs_primary = SatisfyingAssignment::<E1>::with_capacity(
+      pp[circuit_index].r1cs_shape.num_io + 1,
+      pp[circuit_index].r1cs_shape.num_vars,
+    );
+    let T: <<E2 as Engine>::CE as CommitmentEngineTrait<E2>>::Commitment =
+      Commitment::<E2>::decompress(&nifs_secondary.comm_T).map_err(SuperNovaError::NovaError)?;
+    let inputs_primary: SuperNovaAugmentedCircuitInputs<'_, E2> =
+      SuperNovaAugmentedCircuitInputs::new(
+        scalar_as_base::<E1>(self.pp_digest),
+        E1::Scalar::from(self.i as u64),
+        &self.z0_primary,
+        Some(&self.zi_primary),
+        Some(&r_U_secondary_i),
+        Some(&l_u_secondary_i),
+        Some(&T),
+        Some(self.program_counter),
+        E1::Scalar::ZERO,
+      );
+
+    let circuit_primary: SuperNovaAugmentedCircuit<'_, E2, C1> = SuperNovaAugmentedCircuit::new(
+      &pp.augmented_circuit_params_primary,
+      Some(inputs_primary),
+      c_primary,
+      pp.ro_consts_circuit_primary.clone(),
+      self.num_augmented_circuits,
+    );
+
+    let (zi_primary_pc_next, zi_primary) = circuit_primary
+      .synthesize(&mut cs_primary)
+      .map_err(NovaError::from)?;
+    if zi_primary.len() != pp[circuit_index].F_arity {
+      return Err(SuperNovaError::NovaError(
+        NovaError::InvalidInitialInputLength,
+      ));
+    }
+
+    let (l_u_primary, l_w_primary) = cs_primary
+      .r1cs_instance_and_witness(&pp[circuit_index].r1cs_shape, &pp.ck_primary)
+      .map_err(SuperNovaError::NovaError)?;
+
+    let (r_U_primary, r_W_primary) = if let (Some(Some(r_U_primary)), Some(Some(r_W_primary))) = (
+      self.r_U_primary.get_mut(circuit_index),
+      self.r_W_primary.get_mut(circuit_index),
+    ) {
+      (r_U_primary, r_W_primary)
+    } else {
+      self.r_U_primary[circuit_index] = Some(RelaxedR1CSInstance::default(
+        &pp.ck_primary,
+        &pp[circuit_index].r1cs_shape,
+      ));
+      self.r_W_primary[circuit_index] =
+        Some(RelaxedR1CSWitness::default(&pp[circuit_index].r1cs_shape));
+      (
+        self.r_U_primary[circuit_index].as_mut().unwrap(),
+        self.r_W_primary[circuit_index].as_mut().unwrap(),
+      )
+    };
+
+    let nifs_primary = NIFS::prove_mut(
+      &pp.ck_primary,
+      &pp.ro_consts_primary,
+      &self.pp_digest,
+      &pp[circuit_index].r1cs_shape,
+      r_U_primary,
+      r_W_primary,
+      &l_u_primary,
+      &l_w_primary,
+      &mut self.buffer_primary.T,
+      &mut self.buffer_primary.ABC_Z_1,
+      &mut self.buffer_primary.ABC_Z_2,
+    )
+    .map_err(SuperNovaError::NovaError)?;
+
+    let mut cs_secondary = SatisfyingAssignment::<E2>::with_capacity(
+      pp.circuit_shape_secondary.r1cs_shape.num_io + 1,
+      pp.circuit_shape_secondary.r1cs_shape.num_vars,
+    );
+    let binding =
+      Commitment::<E1>::decompress(&nifs_primary.comm_T).map_err(SuperNovaError::NovaError)?;
+    let inputs_secondary: SuperNovaAugmentedCircuitInputs<'_, E1> =
+      SuperNovaAugmentedCircuitInputs::new(
+        self.pp_digest,
+        E2::Scalar::from(self.i as u64),
+        &self.z0_secondary,
+        Some(&self.zi_secondary),
+        Some(&r_U_primary_i),
+        Some(&l_u_primary),
+        Some(&binding),
+        None, // pc is always None for secondary circuit
+        E2::Scalar::from(circuit_index as u64),
+      );
+
+    let circuit_secondary: SuperNovaAugmentedCircuit<'_, E1, C2> = SuperNovaAugmentedCircuit::new(
+      &pp.augmented_circuit_params_secondary,
+      Some(inputs_secondary),
+      c_secondary,
+      pp.ro_consts_circuit_secondary.clone(),
+      self.num_augmented_circuits,
+    );
+    let (_, zi_secondary) = circuit_secondary
+      .synthesize(&mut cs_secondary)
+      .map_err(NovaError::from)?;
+    if zi_secondary.len() != pp.circuit_shape_secondary.F_arity {
+      return Err(SuperNovaError::NovaError(
+        NovaError::InvalidInitialInputLength,
+      ));
+    }
+
+    let (l_u_secondary_next, l_w_secondary_next) = cs_secondary
+      .r1cs_instance_and_witness(&pp.circuit_shape_secondary.r1cs_shape, &pp.ck_secondary)?;
+
+    // update the running instances and witnesses
+    let zi_primary = zi_primary
+      .iter()
+      .map(|v| {
+        v.get_value()
+          .ok_or(NovaError::from(SynthesisError::AssignmentMissing).into())
+      })
+      .collect::<Result<Vec<<E1 as Engine>::Scalar>, SuperNovaError>>()?;
+    let zi_primary_pc_next = zi_primary_pc_next
+      .expect("zi_primary_pc_next missing")
+      .get_value()
+      .ok_or::<SuperNovaError>(NovaError::from(SynthesisError::AssignmentMissing).into())?;
+    let zi_secondary = zi_secondary
+      .iter()
+      .map(|v| {
+        v.get_value()
+          .ok_or(NovaError::from(SynthesisError::AssignmentMissing).into())
+      })
+      .collect::<Result<Vec<<E2 as Engine>::Scalar>, SuperNovaError>>()?;
+
+    if zi_primary.len() != pp[circuit_index].F_arity
+      || zi_secondary.len() != pp.circuit_shape_secondary.F_arity
+    {
+      return Err(SuperNovaError::NovaError(
+        NovaError::InvalidStepOutputLength,
+      ));
+    }
+
+    self.l_w_secondary = l_w_secondary_next;
+    self.l_u_secondary = l_u_secondary_next;
+    self.i += 1;
+    self.zi_primary = zi_primary;
+    self.zi_secondary = zi_secondary;
+    self.proven_circuit_index = circuit_index;
+    self.program_counter = zi_primary_pc_next;
+    Ok(())
+  }
+
+  /// verify recursive snark
+  pub fn verify<C1: StepCircuit<E1::Scalar>, C2: StepCircuit<E2::Scalar>>(
+    &self,
+    pp: &PublicParams<E1, E2, C1, C2>,
+    z0_primary: &[E1::Scalar],
+    z0_secondary: &[E2::Scalar],
+  ) -> Result<(Vec<E1::Scalar>, Vec<E2::Scalar>), SuperNovaError> {
+    // number of steps cannot be zero
+    if self.i == 0 {
+      debug!("must verify on valid RecursiveSNARK where i > 0");
+      return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError));
+    }
+
+    // Check lengths of r_primary
+    if self.r_U_primary.len() != self.num_augmented_circuits
+      || self.r_W_primary.len() != self.num_augmented_circuits
+    {
+      debug!("r_primary length mismatch");
+      return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError));
+    }
+
+    // Check that there are no missing instance/witness pairs
+    self
+      .r_U_primary
+      .iter()
+      .zip_eq(self.r_W_primary.iter())
+      .enumerate()
+      .try_for_each(|(i, (u, w))| match (u, w) {
+        (Some(_), Some(_)) | (None, None) => Ok(()),
+        _ => {
+          debug!("r_primary[{:?}]: mismatched instance/witness pair", i);
+          Err(SuperNovaError::NovaError(NovaError::ProofVerifyError))
+        }
+      })?;
+
+    let circuit_index = self.proven_circuit_index;
+
+    // check we have an instance/witness pair for the circuit_index
+    if self.r_U_primary[circuit_index].is_none() {
+      debug!(
+        "r_primary[{:?}]: instance/witness pair is missing",
+        circuit_index
+      );
+      return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError));
+    }
+
+    // check the (relaxed) R1CS instances public outputs.
+    {
+      for (i, r_U_primary_i) in self.r_U_primary.iter().enumerate() {
+        if let Some(u) = r_U_primary_i {
+          if u.X.len() != 2 {
+            debug!(
+              "r_U_primary[{:?}] got instance length {:?} != 2",
+              i,
+              u.X.len(),
+            );
+            return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError));
+          }
+        }
+      }
+
+      if self.l_u_secondary.X.len() != 2 {
+        debug!(
+          "l_U_secondary got instance length {:?} != 2",
+          self.l_u_secondary.X.len(),
+        );
+        return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError));
+      }
+
+      if self.r_U_secondary.X.len() != 2 {
+        debug!(
+          "r_U_secondary got instance length {:?} != 2",
+          self.r_U_secondary.X.len(),
+        );
+        return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError));
+      }
+    }
+
+    let hash_primary = {
+      let num_absorbs = num_ro_inputs(
+        self.num_augmented_circuits,
+        pp.augmented_circuit_params_primary.get_n_limbs(),
+        pp[circuit_index].F_arity,
+        true, // is_primary
+      );
+
+      let mut hasher = <E2 as Engine>::RO::new(pp.ro_consts_secondary.clone(), num_absorbs);
+      hasher.absorb(self.pp_digest);
+      hasher.absorb(E1::Scalar::from(self.i as u64));
+      hasher.absorb(self.program_counter);
+
+      for e in z0_primary {
+        hasher.absorb(*e);
+      }
+      for e in &self.zi_primary {
+        hasher.absorb(*e);
+      }
+
+      self.r_U_secondary.absorb_in_ro(&mut hasher);
+      hasher.squeeze(NUM_HASH_BITS)
+    };
+
+    let hash_secondary = {
+      let num_absorbs = num_ro_inputs(
+        self.num_augmented_circuits,
+        pp.augmented_circuit_params_secondary.get_n_limbs(),
+        pp.circuit_shape_secondary.F_arity,
+        false, // is_primary
+      );
+      let mut hasher = <E1 as Engine>::RO::new(pp.ro_consts_primary.clone(), num_absorbs);
+      hasher.absorb(scalar_as_base::<E1>(self.pp_digest));
+      hasher.absorb(E2::Scalar::from(self.i as u64));
+
+      for e in z0_secondary {
+        hasher.absorb(*e);
+      }
+      for e in &self.zi_secondary {
+        hasher.absorb(*e);
+      }
+
+      self.r_U_primary.iter().enumerate().for_each(|(i, U)| {
+        U.as_ref()
+          .unwrap_or(&RelaxedR1CSInstance::default(
+            &pp.ck_primary,
+            &pp[i].r1cs_shape,
+          ))
+          .absorb_in_ro(&mut hasher);
+      });
+      hasher.squeeze(NUM_HASH_BITS)
+    };
+
+    if hash_primary != self.l_u_secondary.X[0] {
+      debug!(
+        "hash_primary {:?} not equal l_u_secondary.X[0] {:?}",
+        hash_primary, self.l_u_secondary.X[0]
+      );
+      return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError));
+    }
+    if hash_secondary != scalar_as_base::<E2>(self.l_u_secondary.X[1]) {
+      debug!(
+        "hash_secondary {:?} not equal l_u_secondary.X[1] {:?}",
+        hash_secondary, self.l_u_secondary.X[1]
+      );
+      return Err(SuperNovaError::NovaError(NovaError::ProofVerifyError));
+    }
+
+    // check the satisfiability of all instance/witness pairs
+    let (res_r_primary, (res_r_secondary, res_l_secondary)) = rayon::join(
+      || {
+        self
+          .r_U_primary
+          .par_iter()
+          .zip_eq(self.r_W_primary.par_iter())
+          .enumerate()
+          .try_for_each(|(i, (u, w))| {
+            if let (Some(u), Some(w)) = (u, w) {
+              pp[i].r1cs_shape.is_sat_relaxed(&pp.ck_primary, u, w)?
+            }
+            Ok(())
+          })
+      },
+      || {
+        rayon::join(
+          || {
+            pp.circuit_shape_secondary.r1cs_shape.is_sat_relaxed(
+              &pp.ck_secondary,
+              &self.r_U_secondary,
+              &self.r_W_secondary,
+            )
+          },
+          || {
+            pp.circuit_shape_secondary.r1cs_shape.is_sat(
+              &pp.ck_secondary,
+              &self.l_u_secondary,
+              &self.l_w_secondary,
+            )
+          },
+        )
+      },
+    );
+
+    res_r_primary.map_err(|err| match err {
+      NovaError::UnSatIndex(i) => SuperNovaError::UnSatIndex("r_primary", i),
+      e => SuperNovaError::NovaError(e),
+    })?;
+    res_r_secondary.map_err(|err| match err {
+      NovaError::UnSatIndex(i) => SuperNovaError::UnSatIndex("r_secondary", i),
+      e => SuperNovaError::NovaError(e),
+    })?;
+    res_l_secondary.map_err(|err| match err {
+      NovaError::UnSatIndex(i) => SuperNovaError::UnSatIndex("l_secondary", i),
+      e => SuperNovaError::NovaError(e),
+    })?;
+
+    Ok((self.zi_primary.clone(), self.zi_secondary.clone()))
+  }
+}
+
+/// SuperNova helper trait, for implementors that provide sets of sub-circuits to be proved via NIVC. `C1` must be a
+/// type (likely an `Enum`) for which a potentially-distinct instance can be supplied for each `index` below
+/// `self.num_circuits()`.
+pub trait NonUniformCircuit<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  /// Initial circuit index, defaults to zero.
+  fn initial_circuit_index(&self) -> usize {
+    0
+  }
+
+  /// How many circuits are provided?
+  fn num_circuits(&self) -> usize;
+
+  /// Return a new instance of the primary circuit at `index`.
+  fn primary_circuit(&self, circuit_index: usize) -> C1;
+
+  /// Return a new instance of the secondary circuit.
+  fn secondary_circuit(&self) -> C2;
+}
+
+/// Extension trait to simplify getting scalar form of initial circuit index.
+trait InitialProgramCounter<E1, E2, C1, C2>: NonUniformCircuit<E1, E2, C1, C2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+  /// Initial program counter is the initial circuit index as a `Scalar`.
+  fn initial_program_counter(&self) -> E1::Scalar {
+    E1::Scalar::from(self.initial_circuit_index() as u64)
+  }
+}
+
+impl<E1, E2, C1, C2, T: NonUniformCircuit<E1, E2, C1, C2>> InitialProgramCounter<E1, E2, C1, C2>
+  for T
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+{
+}
+
+/// Compute the circuit digest of a supernova [StepCircuit].
+///
+/// Note for callers: This function should be called with its performance characteristics in mind.
+/// It will synthesize and digest the full `circuit` given.
+pub fn circuit_digest<
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C: StepCircuit<E1::Scalar>,
+>(
+  circuit: &C,
+  num_augmented_circuits: usize,
+) -> E1::Scalar {
+  let augmented_circuit_params =
+    SuperNovaAugmentedCircuitParams::new(BN_LIMB_WIDTH, BN_N_LIMBS, true);
+
+  // ro_consts_circuit are parameterized by E2 because the type alias uses E2::Base = E1::Scalar
+  let ro_consts_circuit: ROConstantsCircuit<E2> = ROConstantsCircuit::<E2>::default();
+
+  // Initialize ck for the primary
+  let augmented_circuit: SuperNovaAugmentedCircuit<'_, E2, C> = SuperNovaAugmentedCircuit::new(
+    &augmented_circuit_params,
+    None,
+    circuit,
+    ro_consts_circuit,
+    num_augmented_circuits,
+  );
+  let mut cs: ShapeCS<E1> = ShapeCS::new();
+  let _ = augmented_circuit.synthesize(&mut cs);
+
+  let F_arity = circuit.arity();
+  let circuit_params = R1CSWithArity::new(cs.r1cs_shape(), F_arity);
+  circuit_params.digest()
+}
+
+/// Compute the number of absorbs for the random-oracle computing the circuit output
+/// X = H(vk, i, pc, z0, zi, U)
+fn num_ro_inputs(num_circuits: usize, num_limbs: usize, arity: usize, is_primary: bool) -> usize {
+  let num_circuits = if is_primary { 1 } else { num_circuits };
+
+  // [W(x,y,∞), E(x,y,∞), u] + [X0, X1] * #num_limb
+  let instance_size = 3 + 3 + 1 + 2 * num_limbs;
+
+  2 // params, i
+    + usize::from(is_primary) // optional program counter
+      + 2 * arity // z0, zi
+      + num_circuits * instance_size
+}
+
+pub mod error;
+pub mod snark;
+mod utils;
+
+#[cfg(test)]
+mod test;
+
\ No newline at end of file diff --git a/docs/src/arecibo/supernova/snark.rs.html b/docs/src/arecibo/supernova/snark.rs.html new file mode 100644 index 000000000..9606bf6ab --- /dev/null +++ b/docs/src/arecibo/supernova/snark.rs.html @@ -0,0 +1,1553 @@ +snark.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+180
+181
+182
+183
+184
+185
+186
+187
+188
+189
+190
+191
+192
+193
+194
+195
+196
+197
+198
+199
+200
+201
+202
+203
+204
+205
+206
+207
+208
+209
+210
+211
+212
+213
+214
+215
+216
+217
+218
+219
+220
+221
+222
+223
+224
+225
+226
+227
+228
+229
+230
+231
+232
+233
+234
+235
+236
+237
+238
+239
+240
+241
+242
+243
+244
+245
+246
+247
+248
+249
+250
+251
+252
+253
+254
+255
+256
+257
+258
+259
+260
+261
+262
+263
+264
+265
+266
+267
+268
+269
+270
+271
+272
+273
+274
+275
+276
+277
+278
+279
+280
+281
+282
+283
+284
+285
+286
+287
+288
+289
+290
+291
+292
+293
+294
+295
+296
+297
+298
+299
+300
+301
+302
+303
+304
+305
+306
+307
+308
+309
+310
+311
+312
+313
+314
+315
+316
+317
+318
+319
+320
+321
+322
+323
+324
+325
+326
+327
+328
+329
+330
+331
+332
+333
+334
+335
+336
+337
+338
+339
+340
+341
+342
+343
+344
+345
+346
+347
+348
+349
+350
+351
+352
+353
+354
+355
+356
+357
+358
+359
+360
+361
+362
+363
+364
+365
+366
+367
+368
+369
+370
+371
+372
+373
+374
+375
+376
+377
+378
+379
+380
+381
+382
+383
+384
+385
+386
+387
+388
+389
+390
+391
+392
+393
+394
+395
+396
+397
+398
+399
+400
+401
+402
+403
+404
+405
+406
+407
+408
+409
+410
+411
+412
+413
+414
+415
+416
+417
+418
+419
+420
+421
+422
+423
+424
+425
+426
+427
+428
+429
+430
+431
+432
+433
+434
+435
+436
+437
+438
+439
+440
+441
+442
+443
+444
+445
+446
+447
+448
+449
+450
+451
+452
+453
+454
+455
+456
+457
+458
+459
+460
+461
+462
+463
+464
+465
+466
+467
+468
+469
+470
+471
+472
+473
+474
+475
+476
+477
+478
+479
+480
+481
+482
+483
+484
+485
+486
+487
+488
+489
+490
+491
+492
+493
+494
+495
+496
+497
+498
+499
+500
+501
+502
+503
+504
+505
+506
+507
+508
+509
+510
+511
+512
+513
+514
+515
+516
+517
+518
+519
+520
+521
+522
+523
+524
+525
+526
+527
+528
+529
+530
+531
+532
+533
+534
+535
+536
+537
+538
+539
+540
+541
+542
+543
+544
+545
+546
+547
+548
+549
+550
+551
+552
+553
+554
+555
+556
+557
+558
+559
+560
+561
+562
+563
+564
+565
+566
+567
+568
+569
+570
+571
+572
+573
+574
+575
+576
+577
+578
+579
+580
+581
+582
+583
+584
+585
+586
+587
+588
+589
+590
+591
+592
+593
+594
+595
+596
+597
+598
+599
+600
+601
+602
+603
+604
+605
+606
+607
+608
+609
+610
+611
+612
+613
+614
+615
+616
+617
+618
+619
+620
+621
+622
+623
+624
+625
+626
+627
+628
+629
+630
+631
+632
+633
+634
+635
+636
+637
+638
+639
+640
+641
+642
+643
+644
+645
+646
+647
+648
+649
+650
+651
+652
+653
+654
+655
+656
+657
+658
+659
+660
+661
+662
+663
+664
+665
+666
+667
+668
+669
+670
+671
+672
+673
+674
+675
+676
+677
+678
+679
+680
+681
+682
+683
+684
+685
+686
+687
+688
+689
+690
+691
+692
+693
+694
+695
+696
+697
+698
+699
+700
+701
+702
+703
+704
+705
+706
+707
+708
+709
+710
+711
+712
+713
+714
+715
+716
+717
+718
+719
+720
+721
+722
+723
+724
+725
+726
+727
+728
+729
+730
+731
+732
+733
+734
+735
+736
+737
+738
+739
+740
+741
+742
+743
+744
+745
+746
+747
+748
+749
+750
+751
+752
+753
+754
+755
+756
+757
+758
+759
+760
+761
+762
+763
+764
+765
+766
+767
+768
+769
+770
+771
+772
+773
+774
+775
+776
+
//! This module defines a final compressing SNARK for supernova proofs
+
+use super::{error::SuperNovaError, PublicParams, RecursiveSNARK};
+use crate::{
+  constants::NUM_HASH_BITS,
+  r1cs::{R1CSInstance, RelaxedR1CSWitness},
+  supernova::StepCircuit,
+  traits::{
+    snark::{BatchedRelaxedR1CSSNARKTrait, RelaxedR1CSSNARKTrait},
+    AbsorbInROTrait, Engine, ROTrait,
+  },
+};
+use crate::{errors::NovaError, scalar_as_base, RelaxedR1CSInstance, NIFS};
+
+use abomonation::Abomonation;
+use abomonation_derive::Abomonation;
+use ff::PrimeField;
+use serde::{Deserialize, Serialize};
+use std::marker::PhantomData;
+
+/// A type that holds the prover key for `CompressedSNARK`
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+  )]
+pub struct ProverKey<E1, E2, C1, C2, S1, S2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+  S2: RelaxedR1CSSNARKTrait<E2>,
+{
+  pk_primary: S1::ProverKey,
+  pk_secondary: S2::ProverKey,
+  _p: PhantomData<(C1, C2)>,
+}
+
+/// A type that holds the verifier key for `CompressedSNARK`
+#[derive(Clone, Serialize, Deserialize, Abomonation)]
+#[serde(bound = "")]
+#[abomonation_bounds(
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    C1: StepCircuit<E1::Scalar>,
+    C2: StepCircuit<E2::Scalar>,
+    S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+  )]
+pub struct VerifierKey<E1, E2, C1, C2, S1, S2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+  S2: RelaxedR1CSSNARKTrait<E2>,
+{
+  vk_primary: S1::VerifierKey,
+  vk_secondary: S2::VerifierKey,
+  _p: PhantomData<(C1, C2)>,
+}
+
+/// A SNARK that proves the knowledge of a valid `RecursiveSNARK`
+#[derive(Debug, Clone, Serialize, Deserialize)]
+#[serde(bound = "")]
+pub struct CompressedSNARK<E1, E2, C1, C2, S1, S2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+  S2: RelaxedR1CSSNARKTrait<E2>,
+{
+  r_U_primary: Vec<RelaxedR1CSInstance<E1>>,
+  r_W_snark_primary: S1,
+
+  r_U_secondary: RelaxedR1CSInstance<E2>,
+  l_u_secondary: R1CSInstance<E2>,
+  nifs_secondary: NIFS<E2>,
+  f_W_snark_secondary: S2,
+
+  num_steps: usize,
+  program_counter: E1::Scalar,
+
+  zn_primary: Vec<E1::Scalar>,
+  zn_secondary: Vec<E2::Scalar>,
+  _p: PhantomData<(E1, E2, C1, C2, S1, S2)>,
+}
+
+impl<E1, E2, C1, C2, S1, S2> CompressedSNARK<E1, E2, C1, C2, S1, S2>
+where
+  E1: Engine<Base = <E2 as Engine>::Scalar>,
+  E2: Engine<Base = <E1 as Engine>::Scalar>,
+  C1: StepCircuit<E1::Scalar>,
+  C2: StepCircuit<E2::Scalar>,
+  S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+  S2: RelaxedR1CSSNARKTrait<E2>,
+{
+  /// Creates prover and verifier keys for `CompressedSNARK`
+  pub fn setup(
+    pp: &PublicParams<E1, E2, C1, C2>,
+  ) -> Result<
+    (
+      ProverKey<E1, E2, C1, C2, S1, S2>,
+      VerifierKey<E1, E2, C1, C2, S1, S2>,
+    ),
+    SuperNovaError,
+  > {
+    let (pk_primary, vk_primary) = S1::setup(&pp.ck_primary, pp.primary_r1cs_shapes())?;
+
+    let (pk_secondary, vk_secondary) =
+      S2::setup(&pp.ck_secondary, &pp.circuit_shape_secondary.r1cs_shape)?;
+
+    let prover_key = ProverKey {
+      pk_primary,
+      pk_secondary,
+      _p: PhantomData,
+    };
+    let verifier_key = VerifierKey {
+      vk_primary,
+      vk_secondary,
+      _p: PhantomData,
+    };
+
+    Ok((prover_key, verifier_key))
+  }
+
+  /// Create a new `CompressedSNARK`
+  pub fn prove(
+    pp: &PublicParams<E1, E2, C1, C2>,
+    pk: &ProverKey<E1, E2, C1, C2, S1, S2>,
+    recursive_snark: &RecursiveSNARK<E1, E2>,
+  ) -> Result<Self, SuperNovaError> {
+    // fold the secondary circuit's instance
+    let res_secondary = NIFS::prove(
+      &pp.ck_secondary,
+      &pp.ro_consts_secondary,
+      &scalar_as_base::<E1>(pp.digest()),
+      &pp.circuit_shape_secondary.r1cs_shape,
+      &recursive_snark.r_U_secondary,
+      &recursive_snark.r_W_secondary,
+      &recursive_snark.l_u_secondary,
+      &recursive_snark.l_w_secondary,
+    );
+
+    let (nifs_secondary, (f_U_secondary, f_W_secondary)) = res_secondary?;
+
+    // Prepare the list of primary Relaxed R1CS instances (a default instance is provided for
+    // uninitialized circuits)
+    let r_U_primary = recursive_snark
+      .r_U_primary
+      .iter()
+      .enumerate()
+      .map(|(idx, r_U)| {
+        r_U
+          .clone()
+          .unwrap_or_else(|| RelaxedR1CSInstance::default(&pp.ck_primary, &pp[idx].r1cs_shape))
+      })
+      .collect::<Vec<_>>();
+
+    // Prepare the list of primary relaxed R1CS witnesses (a default witness is provided for
+    // uninitialized circuits)
+    let r_W_primary: Vec<RelaxedR1CSWitness<E1>> = recursive_snark
+      .r_W_primary
+      .iter()
+      .enumerate()
+      .map(|(idx, r_W)| {
+        r_W
+          .clone()
+          .unwrap_or_else(|| RelaxedR1CSWitness::default(&pp[idx].r1cs_shape))
+      })
+      .collect::<Vec<_>>();
+
+    // Generate a primary SNARK proof for the list of primary circuits
+    let r_W_snark_primary = S1::prove(
+      &pp.ck_primary,
+      &pk.pk_primary,
+      pp.primary_r1cs_shapes(),
+      &r_U_primary,
+      &r_W_primary,
+    )?;
+
+    // Generate a secondary SNARK proof for the secondary circuit
+    let f_W_snark_secondary = S2::prove(
+      &pp.ck_secondary,
+      &pk.pk_secondary,
+      &pp.circuit_shape_secondary.r1cs_shape,
+      &f_U_secondary,
+      &f_W_secondary,
+    )?;
+
+    let compressed_snark = Self {
+      r_U_primary,
+      r_W_snark_primary,
+
+      r_U_secondary: recursive_snark.r_U_secondary.clone(),
+      l_u_secondary: recursive_snark.l_u_secondary.clone(),
+      nifs_secondary,
+      f_W_snark_secondary,
+
+      num_steps: recursive_snark.i,
+      program_counter: recursive_snark.program_counter,
+
+      zn_primary: recursive_snark.zi_primary.clone(),
+      zn_secondary: recursive_snark.zi_secondary.clone(),
+
+      _p: PhantomData,
+    };
+
+    Ok(compressed_snark)
+  }
+
+  /// Verify the correctness of the `CompressedSNARK`
+  pub fn verify(
+    &self,
+    pp: &PublicParams<E1, E2, C1, C2>,
+    vk: &VerifierKey<E1, E2, C1, C2, S1, S2>,
+    z0_primary: &[E1::Scalar],
+    z0_secondary: &[E2::Scalar],
+  ) -> Result<(Vec<E1::Scalar>, Vec<E2::Scalar>), SuperNovaError> {
+    let last_circuit_idx = field_as_usize(self.program_counter);
+
+    let num_field_primary_ro = 3 // params_next, i_new, program_counter_new
+    + 2 * pp[last_circuit_idx].F_arity // zo, z1
+    + (7 + 2 * pp.augmented_circuit_params_primary.get_n_limbs()); // # 1 * (7 + [X0, X1]*#num_limb)
+
+    // secondary circuit
+    // NOTE: This count ensure the number of witnesses sent by the prover must equal the number of
+    // NIVC circuits
+    let num_field_secondary_ro = 2 // params_next, i_new
+    + 2 * pp.circuit_shape_secondary.F_arity // zo, z1
+    + pp.circuit_shapes.len() * (7 + 2 * pp.augmented_circuit_params_primary.get_n_limbs()); // #num_augment
+
+    // Compute the primary and secondary hashes given the digest, program counter, instances, and
+    // witnesses provided by the prover
+    let (hash_primary, hash_secondary) = {
+      let mut hasher =
+        <E2 as Engine>::RO::new(pp.ro_consts_secondary.clone(), num_field_primary_ro);
+
+      hasher.absorb(pp.digest());
+      hasher.absorb(E1::Scalar::from(self.num_steps as u64));
+      hasher.absorb(self.program_counter);
+
+      for e in z0_primary {
+        hasher.absorb(*e);
+      }
+
+      for e in &self.zn_primary {
+        hasher.absorb(*e);
+      }
+
+      self.r_U_secondary.absorb_in_ro(&mut hasher);
+
+      let mut hasher2 =
+        <E1 as Engine>::RO::new(pp.ro_consts_primary.clone(), num_field_secondary_ro);
+
+      hasher2.absorb(scalar_as_base::<E1>(pp.digest()));
+      hasher2.absorb(E2::Scalar::from(self.num_steps as u64));
+
+      for e in z0_secondary {
+        hasher2.absorb(*e);
+      }
+
+      for e in &self.zn_secondary {
+        hasher2.absorb(*e);
+      }
+
+      self.r_U_primary.iter().for_each(|U| {
+        U.absorb_in_ro(&mut hasher2);
+      });
+
+      (
+        hasher.squeeze(NUM_HASH_BITS),
+        hasher2.squeeze(NUM_HASH_BITS),
+      )
+    };
+
+    // Compare the computed hashes with the public IO of the last invocation of `prove_step`
+    if hash_primary != self.l_u_secondary.X[0] {
+      return Err(NovaError::ProofVerifyError.into());
+    }
+
+    if hash_secondary != scalar_as_base::<E2>(self.l_u_secondary.X[1]) {
+      return Err(NovaError::ProofVerifyError.into());
+    }
+
+    // Verify the primary SNARK
+    let res_primary = self
+      .r_W_snark_primary
+      .verify(&vk.vk_primary, &self.r_U_primary);
+
+    // Fold the secondary circuit's instance
+    let f_U_secondary = self.nifs_secondary.verify(
+      &pp.ro_consts_secondary,
+      &scalar_as_base::<E1>(pp.digest()),
+      &self.r_U_secondary,
+      &self.l_u_secondary,
+    )?;
+
+    // Verify the secondary SNARK
+    let res_secondary = self
+      .f_W_snark_secondary
+      .verify(&vk.vk_secondary, &f_U_secondary);
+
+    res_primary?;
+
+    res_secondary?;
+
+    Ok((self.zn_primary.clone(), self.zn_secondary.clone()))
+  }
+}
+
+fn field_as_usize<F: PrimeField>(x: F) -> usize {
+  u32::from_le_bytes(x.to_repr().as_ref()[0..4].try_into().unwrap()) as usize
+}
+
+#[cfg(test)]
+mod test {
+  use super::*;
+  use crate::{
+    provider::{
+      ipa_pc, Bn256Engine, GrumpkinEngine, PallasEngine, Secp256k1Engine, Secq256k1Engine,
+      VestaEngine,
+    },
+    spartan::{batched, batched_ppsnark, snark::RelaxedR1CSSNARK},
+    supernova::{circuit::TrivialSecondaryCircuit, NonUniformCircuit},
+  };
+
+  use abomonation::Abomonation;
+  use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError};
+  use ff::{Field, PrimeField};
+
+  type EE<E> = ipa_pc::EvaluationEngine<E>;
+  type S1<E> = batched::BatchedRelaxedR1CSSNARK<E, EE<E>>;
+  type S1PP<E> = batched_ppsnark::BatchedRelaxedR1CSSNARK<E, EE<E>>;
+  type S2<E> = RelaxedR1CSSNARK<E, EE<E>>;
+
+  #[derive(Clone)]
+  struct SquareCircuit<E> {
+    _p: PhantomData<E>,
+  }
+
+  impl<E: Engine> StepCircuit<E::Scalar> for SquareCircuit<E> {
+    fn arity(&self) -> usize {
+      1
+    }
+
+    fn circuit_index(&self) -> usize {
+      0
+    }
+
+    fn synthesize<CS: ConstraintSystem<E::Scalar>>(
+      &self,
+      cs: &mut CS,
+      _pc: Option<&AllocatedNum<E::Scalar>>,
+      z: &[AllocatedNum<E::Scalar>],
+    ) -> Result<
+      (
+        Option<AllocatedNum<E::Scalar>>,
+        Vec<AllocatedNum<E::Scalar>>,
+      ),
+      SynthesisError,
+    > {
+      let z_i = &z[0];
+
+      let z_next = z_i.square(cs.namespace(|| "z_i^2"))?;
+
+      let next_pc = AllocatedNum::alloc(cs.namespace(|| "next_pc"), || Ok(E::Scalar::from(1u64)))?;
+
+      cs.enforce(
+        || "next_pc = 1",
+        |lc| lc + CS::one(),
+        |lc| lc + next_pc.get_variable(),
+        |lc| lc + CS::one(),
+      );
+
+      Ok((Some(next_pc), vec![z_next]))
+    }
+  }
+
+  #[derive(Clone)]
+  struct CubeCircuit<E> {
+    _p: PhantomData<E>,
+  }
+
+  impl<E: Engine> StepCircuit<E::Scalar> for CubeCircuit<E> {
+    fn arity(&self) -> usize {
+      1
+    }
+
+    fn circuit_index(&self) -> usize {
+      1
+    }
+
+    fn synthesize<CS: ConstraintSystem<E::Scalar>>(
+      &self,
+      cs: &mut CS,
+      _pc: Option<&AllocatedNum<E::Scalar>>,
+      z: &[AllocatedNum<E::Scalar>],
+    ) -> Result<
+      (
+        Option<AllocatedNum<E::Scalar>>,
+        Vec<AllocatedNum<E::Scalar>>,
+      ),
+      SynthesisError,
+    > {
+      let z_i = &z[0];
+
+      let z_sq = z_i.square(cs.namespace(|| "z_i^2"))?;
+      let z_cu = z_sq.mul(cs.namespace(|| "z_i^3"), z_i)?;
+
+      let next_pc = AllocatedNum::alloc(cs.namespace(|| "next_pc"), || Ok(E::Scalar::from(0u64)))?;
+
+      cs.enforce(
+        || "next_pc = 0",
+        |lc| lc + CS::one(),
+        |lc| lc + next_pc.get_variable(),
+        |lc| lc,
+      );
+
+      Ok((Some(next_pc), vec![z_cu]))
+    }
+  }
+
+  #[derive(Clone)]
+  enum TestCircuit<E: Engine> {
+    Square(SquareCircuit<E>),
+    Cube(CubeCircuit<E>),
+  }
+
+  impl<E: Engine> TestCircuit<E> {
+    fn new(num_steps: usize) -> Vec<Self> {
+      let mut circuits = Vec::new();
+
+      for idx in 0..num_steps {
+        if idx % 2 == 0 {
+          circuits.push(Self::Square(SquareCircuit { _p: PhantomData }))
+        } else {
+          circuits.push(Self::Cube(CubeCircuit { _p: PhantomData }))
+        }
+      }
+
+      circuits
+    }
+  }
+
+  impl<E: Engine> StepCircuit<E::Scalar> for TestCircuit<E> {
+    fn arity(&self) -> usize {
+      1
+    }
+
+    fn circuit_index(&self) -> usize {
+      match self {
+        Self::Square(c) => c.circuit_index(),
+        Self::Cube(c) => c.circuit_index(),
+      }
+    }
+
+    fn synthesize<CS: ConstraintSystem<E::Scalar>>(
+      &self,
+      cs: &mut CS,
+      pc: Option<&AllocatedNum<E::Scalar>>,
+      z: &[AllocatedNum<E::Scalar>],
+    ) -> Result<
+      (
+        Option<AllocatedNum<E::Scalar>>,
+        Vec<AllocatedNum<E::Scalar>>,
+      ),
+      SynthesisError,
+    > {
+      match self {
+        Self::Square(c) => c.synthesize(cs, pc, z),
+        Self::Cube(c) => c.synthesize(cs, pc, z),
+      }
+    }
+  }
+
+  impl<E1, E2> NonUniformCircuit<E1, E2, Self, TrivialSecondaryCircuit<E2::Scalar>>
+    for TestCircuit<E1>
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    fn num_circuits(&self) -> usize {
+      2
+    }
+
+    fn primary_circuit(&self, circuit_index: usize) -> Self {
+      match circuit_index {
+        0 => Self::Square(SquareCircuit { _p: PhantomData }),
+        1 => Self::Cube(CubeCircuit { _p: PhantomData }),
+        _ => panic!("Invalid circuit index"),
+      }
+    }
+
+    fn secondary_circuit(&self) -> TrivialSecondaryCircuit<E2::Scalar> {
+      Default::default()
+    }
+  }
+
+  fn test_nivc_trivial_with_compression_with<E1, E2, S1, S2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+    <E2::Scalar as PrimeField>::Repr: Abomonation,
+  {
+    const NUM_STEPS: usize = 6;
+
+    let secondary_circuit = TrivialSecondaryCircuit::default();
+    let test_circuits = TestCircuit::new(NUM_STEPS);
+
+    let pp = PublicParams::setup(&test_circuits[0], &*S1::ck_floor(), &*S2::ck_floor());
+
+    let z0_primary = vec![E1::Scalar::from(17u64)];
+    let z0_secondary = vec![<E2 as Engine>::Scalar::ZERO];
+
+    let mut recursive_snark = RecursiveSNARK::new(
+      &pp,
+      &test_circuits[0],
+      &test_circuits[0],
+      &secondary_circuit,
+      &z0_primary,
+      &z0_secondary,
+    )
+    .unwrap();
+
+    for circuit in test_circuits.iter().take(NUM_STEPS) {
+      let prove_res = recursive_snark.prove_step(&pp, circuit, &secondary_circuit);
+
+      let verify_res = recursive_snark.verify(&pp, &z0_primary, &z0_secondary);
+
+      assert!(prove_res.is_ok());
+      assert!(verify_res.is_ok());
+    }
+
+    let (prover_key, verifier_key) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap();
+
+    let compressed_prove_res = CompressedSNARK::prove(&pp, &prover_key, &recursive_snark);
+
+    assert!(compressed_prove_res.is_ok());
+
+    let compressed_snark = compressed_prove_res.unwrap();
+
+    let compressed_verify_res =
+      compressed_snark.verify(&pp, &verifier_key, &z0_primary, &z0_secondary);
+
+    assert!(compressed_verify_res.is_ok());
+  }
+
+  #[test]
+  fn test_nivc_trivial_with_compression() {
+    // ppSNARK
+    test_nivc_trivial_with_compression_with::<PallasEngine, VestaEngine, S1PP<_>, S2<_>>();
+    test_nivc_trivial_with_compression_with::<Bn256Engine, GrumpkinEngine, S1PP<_>, S2<_>>();
+    test_nivc_trivial_with_compression_with::<Secp256k1Engine, Secq256k1Engine, S1PP<_>, S2<_>>();
+    // classic SNARK
+    test_nivc_trivial_with_compression_with::<PallasEngine, VestaEngine, S1<_>, S2<_>>();
+    test_nivc_trivial_with_compression_with::<Bn256Engine, GrumpkinEngine, S1<_>, S2<_>>();
+    test_nivc_trivial_with_compression_with::<Secp256k1Engine, Secq256k1Engine, S1<_>, S2<_>>();
+  }
+
+  #[derive(Clone)]
+  struct BigPowerCircuit<E> {
+    _p: PhantomData<E>,
+  }
+
+  impl<E: Engine> StepCircuit<E::Scalar> for BigPowerCircuit<E> {
+    fn arity(&self) -> usize {
+      1
+    }
+
+    fn circuit_index(&self) -> usize {
+      1
+    }
+
+    fn synthesize<CS: ConstraintSystem<E::Scalar>>(
+      &self,
+      cs: &mut CS,
+      _pc: Option<&AllocatedNum<E::Scalar>>,
+      z: &[AllocatedNum<E::Scalar>],
+    ) -> Result<
+      (
+        Option<AllocatedNum<E::Scalar>>,
+        Vec<AllocatedNum<E::Scalar>>,
+      ),
+      SynthesisError,
+    > {
+      let mut x = z[0].clone();
+      let mut y = x.clone();
+      for i in 0..10_000 {
+        y = x.square(cs.namespace(|| format!("x_sq_{i}")))?;
+        x = y.clone();
+      }
+
+      let next_pc = AllocatedNum::alloc(cs.namespace(|| "next_pc"), || Ok(E::Scalar::from(0u64)))?;
+
+      cs.enforce(
+        || "next_pc = 0",
+        |lc| lc + CS::one(),
+        |lc| lc + next_pc.get_variable(),
+        |lc| lc,
+      );
+
+      Ok((Some(next_pc), vec![y]))
+    }
+  }
+
+  #[derive(Clone)]
+  enum BigTestCircuit<E: Engine> {
+    Square(SquareCircuit<E>),
+    BigPower(BigPowerCircuit<E>),
+  }
+
+  impl<E: Engine> BigTestCircuit<E> {
+    fn new(num_steps: usize) -> Vec<Self> {
+      let mut circuits = Vec::new();
+
+      for idx in 0..num_steps {
+        if idx % 2 == 0 {
+          circuits.push(Self::Square(SquareCircuit { _p: PhantomData }))
+        } else {
+          circuits.push(Self::BigPower(BigPowerCircuit { _p: PhantomData }))
+        }
+      }
+
+      circuits
+    }
+  }
+
+  impl<E: Engine> StepCircuit<E::Scalar> for BigTestCircuit<E> {
+    fn arity(&self) -> usize {
+      1
+    }
+
+    fn circuit_index(&self) -> usize {
+      match self {
+        Self::Square(c) => c.circuit_index(),
+        Self::BigPower(c) => c.circuit_index(),
+      }
+    }
+
+    fn synthesize<CS: ConstraintSystem<E::Scalar>>(
+      &self,
+      cs: &mut CS,
+      pc: Option<&AllocatedNum<E::Scalar>>,
+      z: &[AllocatedNum<E::Scalar>],
+    ) -> Result<
+      (
+        Option<AllocatedNum<E::Scalar>>,
+        Vec<AllocatedNum<E::Scalar>>,
+      ),
+      SynthesisError,
+    > {
+      match self {
+        Self::Square(c) => c.synthesize(cs, pc, z),
+        Self::BigPower(c) => c.synthesize(cs, pc, z),
+      }
+    }
+  }
+
+  impl<E1, E2> NonUniformCircuit<E1, E2, Self, TrivialSecondaryCircuit<E2::Scalar>>
+    for BigTestCircuit<E1>
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+  {
+    fn num_circuits(&self) -> usize {
+      2
+    }
+
+    fn primary_circuit(&self, circuit_index: usize) -> Self {
+      match circuit_index {
+        0 => Self::Square(SquareCircuit { _p: PhantomData }),
+        1 => Self::BigPower(BigPowerCircuit { _p: PhantomData }),
+        _ => panic!("Invalid circuit index"),
+      }
+    }
+
+    fn secondary_circuit(&self) -> TrivialSecondaryCircuit<E2::Scalar> {
+      Default::default()
+    }
+  }
+
+  fn test_compression_with_circuit_size_difference_with<E1, E2, S1, S2>()
+  where
+    E1: Engine<Base = <E2 as Engine>::Scalar>,
+    E2: Engine<Base = <E1 as Engine>::Scalar>,
+    S1: BatchedRelaxedR1CSSNARKTrait<E1>,
+    S2: RelaxedR1CSSNARKTrait<E2>,
+    <E1::Scalar as PrimeField>::Repr: Abomonation,
+    <E2::Scalar as PrimeField>::Repr: Abomonation,
+  {
+    const NUM_STEPS: usize = 4;
+
+    let secondary_circuit = TrivialSecondaryCircuit::default();
+    let test_circuits = BigTestCircuit::new(NUM_STEPS);
+
+    let pp = PublicParams::setup(&test_circuits[0], &*S1::ck_floor(), &*S2::ck_floor());
+
+    let z0_primary = vec![E1::Scalar::from(17u64)];
+    let z0_secondary = vec![<E2 as Engine>::Scalar::ZERO];
+
+    let mut recursive_snark = RecursiveSNARK::new(
+      &pp,
+      &test_circuits[0],
+      &test_circuits[0],
+      &secondary_circuit,
+      &z0_primary,
+      &z0_secondary,
+    )
+    .unwrap();
+
+    for circuit in test_circuits.iter().take(NUM_STEPS) {
+      let prove_res = recursive_snark.prove_step(&pp, circuit, &secondary_circuit);
+
+      let verify_res = recursive_snark.verify(&pp, &z0_primary, &z0_secondary);
+
+      assert!(prove_res.is_ok());
+      assert!(verify_res.is_ok());
+    }
+
+    let (prover_key, verifier_key) = CompressedSNARK::<_, _, _, _, S1, S2>::setup(&pp).unwrap();
+
+    let compressed_prove_res = CompressedSNARK::prove(&pp, &prover_key, &recursive_snark);
+
+    assert!(compressed_prove_res.is_ok());
+
+    let compressed_snark = compressed_prove_res.unwrap();
+
+    let compressed_verify_res =
+      compressed_snark.verify(&pp, &verifier_key, &z0_primary, &z0_secondary);
+
+    assert!(compressed_verify_res.is_ok());
+  }
+
+  #[test]
+  fn test_compression_with_circuit_size_difference() {
+    // ppSNARK
+    test_compression_with_circuit_size_difference_with::<PallasEngine, VestaEngine, S1PP<_>, S2<_>>(
+    );
+    test_compression_with_circuit_size_difference_with::<Bn256Engine, GrumpkinEngine, S1PP<_>, S2<_>>(
+    );
+    test_compression_with_circuit_size_difference_with::<
+      Secp256k1Engine,
+      Secq256k1Engine,
+      S1PP<_>,
+      S2<_>,
+    >();
+    // classic SNARK
+    test_compression_with_circuit_size_difference_with::<PallasEngine, VestaEngine, S1<_>, S2<_>>();
+    test_compression_with_circuit_size_difference_with::<Bn256Engine, GrumpkinEngine, S1<_>, S2<_>>(
+    );
+    test_compression_with_circuit_size_difference_with::<
+      Secp256k1Engine,
+      Secq256k1Engine,
+      S1<_>,
+      S2<_>,
+    >();
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/supernova/utils.rs.html b/docs/src/arecibo/supernova/utils.rs.html new file mode 100644 index 000000000..1bd03480f --- /dev/null +++ b/docs/src/arecibo/supernova/utils.rs.html @@ -0,0 +1,359 @@ +utils.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+165
+166
+167
+168
+169
+170
+171
+172
+173
+174
+175
+176
+177
+178
+179
+
use bellpepper_core::{
+  boolean::{AllocatedBit, Boolean},
+  num::AllocatedNum,
+  ConstraintSystem, LinearCombination, SynthesisError,
+};
+use ff::PrimeField;
+use itertools::Itertools as _;
+
+use crate::{
+  gadgets::r1cs::{conditionally_select_alloc_relaxed_r1cs, AllocatedRelaxedR1CSInstance},
+  traits::Engine,
+};
+
+/// Return the element of `a` given by the indicator bit in `selector_vec`.
+///
+/// This function assumes `selector_vec` has been properly constrained", i.e. that exactly one entry is equal to 1.  
+//
+// NOTE: When `a` is greater than 5 (estimated), it will be cheaper to use a multicase gadget.
+//
+// We should plan to rely on a well-designed gadget offering a common interface but that adapts its implementation based
+// on the size of inputs (known at synthesis time). The threshold size depends on the size of the elements of `a`. The
+// larger the elements, the fewer are needed before multicase becomes cost-effective.
+pub fn get_from_vec_alloc_relaxed_r1cs<E: Engine, CS: ConstraintSystem<<E as Engine>::Base>>(
+  mut cs: CS,
+  a: &[AllocatedRelaxedR1CSInstance<E>],
+  selector_vec: &[Boolean],
+) -> Result<AllocatedRelaxedR1CSInstance<E>, SynthesisError> {
+  assert_eq!(a.len(), selector_vec.len());
+
+  // Compare all instances in `a` to the first one
+  let first: AllocatedRelaxedR1CSInstance<E> = a
+    .first()
+    .cloned()
+    .ok_or_else(|| SynthesisError::IncompatibleLengthVector("empty vec length".to_string()))?;
+
+  // Since `selector_vec` is correct, only one entry is 1.
+  // If selector_vec[0] is 1, then all `conditionally_select` will return `first`.
+  // Otherwise, the correct instance will be selected.
+  let selected = a
+    .iter()
+    .zip_eq(selector_vec.iter())
+    .enumerate()
+    .skip(1)
+    .try_fold(first, |matched, (i, (candidate, equal_bit))| {
+      conditionally_select_alloc_relaxed_r1cs(
+        cs.namespace(|| format!("next_matched_allocated-{:?}", i)),
+        candidate,
+        &matched,
+        equal_bit,
+      )
+    })?;
+
+  Ok(selected)
+}
+
+/// Compute a selector vector `s` of size `num_indices`, such that
+/// `s[i] == 1` if i == `target_index` and 0 otherwise.
+pub fn get_selector_vec_from_index<F: PrimeField, CS: ConstraintSystem<F>>(
+  mut cs: CS,
+  target_index: &AllocatedNum<F>,
+  num_indices: usize,
+) -> Result<Vec<Boolean>, SynthesisError> {
+  assert_ne!(num_indices, 0);
+
+  // Compute the selector vector non-deterministically
+  let selector = (0..num_indices)
+    .map(|idx| {
+      // b <- idx == target_index
+      Ok(Boolean::Is(AllocatedBit::alloc(
+        cs.namespace(|| format!("allocate s_{:?}", idx)),
+        target_index.get_value().map(|v| v == F::from(idx as u64)),
+      )?))
+    })
+    .collect::<Result<Vec<Boolean>, SynthesisError>>()?;
+
+  // Enforce ∑ selector[i] = 1
+  {
+    let selected_sum = selector.iter().fold(LinearCombination::zero(), |lc, bit| {
+      lc + &bit.lc(CS::one(), F::ONE)
+    });
+    cs.enforce(
+      || "exactly-one-selection",
+      |_| selected_sum,
+      |lc| lc + CS::one(),
+      |lc| lc + CS::one(),
+    );
+  }
+
+  // Enforce `target_index - ∑ i * selector[i] = 0``
+  {
+    let selected_value = selector
+      .iter()
+      .enumerate()
+      .fold(LinearCombination::zero(), |lc, (i, bit)| {
+        lc + &bit.lc(CS::one(), F::from(i as u64))
+      });
+    cs.enforce(
+      || "target_index - ∑ i * selector[i] = 0",
+      |lc| lc,
+      |lc| lc,
+      |lc| lc + target_index.get_variable() - &selected_value,
+    );
+  }
+
+  Ok(selector)
+}
+
+#[cfg(test)]
+mod test {
+  use crate::provider::PallasEngine;
+
+  use super::*;
+  use bellpepper_core::test_cs::TestConstraintSystem;
+  use pasta_curves::pallas::Base;
+
+  #[test]
+  fn test_get_from_vec_alloc_relaxed_r1cs_bounds() {
+    let n = 3;
+    for selected in 0..(2 * n) {
+      let mut cs = TestConstraintSystem::<Base>::new();
+
+      let allocated_target = AllocatedNum::alloc_infallible(&mut cs.namespace(|| "target"), || {
+        Base::from(selected as u64)
+      });
+
+      let selector_vec = get_selector_vec_from_index(&mut cs, &allocated_target, n).unwrap();
+
+      let vec = (0..n)
+        .map(|i| {
+          AllocatedRelaxedR1CSInstance::<PallasEngine>::default(
+            &mut cs.namespace(|| format!("elt-{i}")),
+            4,
+            64,
+          )
+          .unwrap()
+        })
+        .collect::<Vec<_>>();
+
+      get_from_vec_alloc_relaxed_r1cs(&mut cs.namespace(|| "test-fn"), &vec, &selector_vec)
+        .unwrap();
+
+      if selected < n {
+        assert!(cs.is_satisfied())
+      } else {
+        // If selected is out of range, the circuit must be unsatisfied.
+        assert!(!cs.is_satisfied())
+      }
+    }
+  }
+
+  #[test]
+  fn test_get_selector() {
+    for n in 1..4 {
+      for selected in 0..(2 * n) {
+        let mut cs = TestConstraintSystem::<Base>::new();
+
+        let allocated_target =
+          AllocatedNum::alloc_infallible(&mut cs.namespace(|| "target"), || {
+            Base::from(selected as u64)
+          });
+
+        let selector_vec = get_selector_vec_from_index(&mut cs, &allocated_target, n).unwrap();
+
+        if selected < n {
+          // Check that the selector bits are correct
+          assert_eq!(selector_vec.len(), n);
+          for (i, bit) in selector_vec.iter().enumerate() {
+            assert_eq!(bit.get_value().unwrap(), i == selected);
+          }
+
+          assert!(cs.is_satisfied());
+        } else {
+          // If selected is out of range, the circuit must be unsatisfied.
+          assert!(!cs.is_satisfied());
+        }
+      }
+    }
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/traits/circuit.rs.html b/docs/src/arecibo/traits/circuit.rs.html new file mode 100644 index 000000000..b64f351da --- /dev/null +++ b/docs/src/arecibo/traits/circuit.rs.html @@ -0,0 +1,83 @@ +circuit.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+
//! This module defines traits that a step function must implement
+use bellpepper_core::{num::AllocatedNum, ConstraintSystem, SynthesisError};
+use core::marker::PhantomData;
+use ff::PrimeField;
+
+/// A helper trait for a step of the incremental computation (i.e., circuit for F)
+pub trait StepCircuit<F: PrimeField>: Send + Sync + Clone {
+  /// Return the number of inputs or outputs of each step
+  /// (this method is called only at circuit synthesis time)
+  /// `synthesize` and `output` methods are expected to take as
+  /// input a vector of size equal to arity and output a vector of size equal to arity
+  fn arity(&self) -> usize;
+
+  /// Sythesize the circuit for a computation step and return variable
+  /// that corresponds to the output of the step `z_{i+1}`
+  fn synthesize<CS: ConstraintSystem<F>>(
+    &self,
+    cs: &mut CS,
+    z: &[AllocatedNum<F>],
+  ) -> Result<Vec<AllocatedNum<F>>, SynthesisError>;
+}
+
+/// A trivial step circuit that simply returns the input
+#[derive(Clone, Debug, Default, PartialEq, Eq)]
+pub struct TrivialCircuit<F> {
+  _p: PhantomData<F>,
+}
+
+impl<F: PrimeField> StepCircuit<F> for TrivialCircuit<F> {
+  fn arity(&self) -> usize {
+    1
+  }
+
+  fn synthesize<CS: ConstraintSystem<F>>(
+    &self,
+    _cs: &mut CS,
+    z: &[AllocatedNum<F>],
+  ) -> Result<Vec<AllocatedNum<F>>, SynthesisError> {
+    Ok(z.to_vec())
+  }
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/traits/commitment.rs.html b/docs/src/arecibo/traits/commitment.rs.html new file mode 100644 index 000000000..38e451fd9 --- /dev/null +++ b/docs/src/arecibo/traits/commitment.rs.html @@ -0,0 +1,177 @@ +commitment.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+
//! This module defines a collection of traits that define the behavior of a commitment engine
+//! We require the commitment engine to provide a commitment to vectors with a single group element
+use crate::{
+  errors::NovaError,
+  traits::{AbsorbInROTrait, Engine, TranscriptReprTrait},
+};
+use abomonation::Abomonation;
+use core::{
+  fmt::Debug,
+  ops::{Add, Mul, MulAssign},
+};
+use serde::{Deserialize, Serialize};
+
+/// A helper trait for types implementing scalar multiplication.
+pub trait ScalarMul<Rhs, Output = Self>: Mul<Rhs, Output = Output> + MulAssign<Rhs> {}
+
+impl<T, Rhs, Output> ScalarMul<Rhs, Output> for T where T: Mul<Rhs, Output = Output> + MulAssign<Rhs>
+{}
+
+/// This trait defines the behavior of the commitment
+pub trait CommitmentTrait<E: Engine>:
+  Clone
+  + Copy
+  + Debug
+  + Default
+  + PartialEq
+  + Eq
+  + Send
+  + Sync
+  + TranscriptReprTrait<E::GE>
+  + Serialize
+  + for<'de> Deserialize<'de>
+  + Abomonation
+  + AbsorbInROTrait<E>
+  + Add<Self, Output = Self>
+  + ScalarMul<E::Scalar>
+{
+  /// Holds the type of the compressed commitment
+  type CompressedCommitment: Clone
+    + Debug
+    + PartialEq
+    + Eq
+    + Send
+    + Sync
+    + TranscriptReprTrait<E::GE>
+    + Serialize
+    + for<'de> Deserialize<'de>;
+
+  /// Compresses self into a compressed commitment
+  fn compress(&self) -> Self::CompressedCommitment;
+
+  /// Returns the coordinate representation of the commitment
+  fn to_coordinates(&self) -> (E::Base, E::Base, bool);
+
+  /// Decompresses a compressed commitment into a commitment
+  fn decompress(c: &Self::CompressedCommitment) -> Result<Self, NovaError>;
+}
+
+/// A trait that helps determine the lenght of a structure.
+/// Note this does not impose any memory representation contraints on the structure.
+pub trait Len {
+  /// Returns the length of the structure.
+  fn length(&self) -> usize;
+}
+
+/// A trait that ties different pieces of the commitment generation together
+pub trait CommitmentEngineTrait<E: Engine>: Clone + Send + Sync {
+  /// Holds the type of the commitment key
+  /// The key should quantify its length in terms of group generators.
+  type CommitmentKey: Len
+    + Clone
+    + PartialEq
+    + Debug
+    + Send
+    + Sync
+    + Serialize
+    + for<'de> Deserialize<'de>
+    + Abomonation;
+
+  /// Holds the type of the commitment
+  type Commitment: CommitmentTrait<E>;
+
+  /// Samples a new commitment key of a specified size
+  fn setup(label: &'static [u8], n: usize) -> Self::CommitmentKey;
+
+  /// Commits to the provided vector using the provided generators
+  fn commit(ck: &Self::CommitmentKey, v: &[E::Scalar]) -> Self::Commitment;
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/traits/evaluation.rs.html b/docs/src/arecibo/traits/evaluation.rs.html new file mode 100644 index 000000000..79c57f910 --- /dev/null +++ b/docs/src/arecibo/traits/evaluation.rs.html @@ -0,0 +1,95 @@ +evaluation.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+
//! This module defines a collection of traits that define the behavior of a polynomial evaluation engine
+//! A vector of size N is treated as a multilinear polynomial in \log{N} variables,
+//! and a commitment provided by the commitment engine is treated as a multilinear polynomial commitment
+use crate::{
+  errors::NovaError,
+  traits::{commitment::CommitmentEngineTrait, Engine},
+};
+use abomonation::Abomonation;
+use serde::{Deserialize, Serialize};
+
+/// A trait that ties different pieces of the commitment evaluation together
+pub trait EvaluationEngineTrait<E: Engine>: Clone + Send + Sync {
+  /// A type that holds the prover key
+  type ProverKey: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+
+  /// A type that holds the verifier key
+  type VerifierKey: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+
+  /// A type that holds the evaluation argument
+  type EvaluationArgument: Clone + Send + Sync + Serialize + for<'de> Deserialize<'de>;
+
+  /// A method to perform any additional setup needed to produce proofs of evaluations
+  fn setup(
+    ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+  ) -> (Self::ProverKey, Self::VerifierKey);
+
+  /// A method to prove the evaluation of a multilinear polynomial
+  fn prove(
+    ck: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::CommitmentKey,
+    pk: &Self::ProverKey,
+    transcript: &mut E::TE,
+    comm: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment,
+    poly: &[E::Scalar],
+    point: &[E::Scalar],
+    eval: &E::Scalar,
+  ) -> Result<Self::EvaluationArgument, NovaError>;
+
+  /// A method to verify the purported evaluation of a multilinear polynomials
+  fn verify(
+    vk: &Self::VerifierKey,
+    transcript: &mut E::TE,
+    comm: &<<E as Engine>::CE as CommitmentEngineTrait<E>>::Commitment,
+    point: &[E::Scalar],
+    eval: &E::Scalar,
+    arg: &Self::EvaluationArgument,
+  ) -> Result<(), NovaError>;
+}
+
\ No newline at end of file diff --git a/docs/src/arecibo/traits/mod.rs.html b/docs/src/arecibo/traits/mod.rs.html new file mode 100644 index 000000000..518a32edf --- /dev/null +++ b/docs/src/arecibo/traits/mod.rs.html @@ -0,0 +1,329 @@ +mod.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+111
+112
+113
+114
+115
+116
+117
+118
+119
+120
+121
+122
+123
+124
+125
+126
+127
+128
+129
+130
+131
+132
+133
+134
+135
+136
+137
+138
+139
+140
+141
+142
+143
+144
+145
+146
+147
+148
+149
+150
+151
+152
+153
+154
+155
+156
+157
+158
+159
+160
+161
+162
+163
+164
+
//! This module defines various traits required by the users of the library to implement.
+use crate::errors::NovaError;
+use abomonation::Abomonation;
+use bellpepper_core::{boolean::AllocatedBit, num::AllocatedNum, ConstraintSystem, SynthesisError};
+use core::fmt::Debug;
+use ff::{PrimeField, PrimeFieldBits};
+use num_bigint::BigInt;
+use serde::{Deserialize, Serialize};
+
+pub mod commitment;
+
+use commitment::CommitmentEngineTrait;
+
+/// Represents an element of a group
+/// This is currently tailored for an elliptic curve group
+pub trait Group: Clone + Copy + Debug + Send + Sync + Sized + Eq + PartialEq {
+  /// A type representing an element of the base field of the group
+  type Base: PrimeFieldBits + Serialize + for<'de> Deserialize<'de>;
+
+  /// A type representing an element of the scalar field of the group
+  type Scalar: PrimeFieldBits + PrimeFieldExt + Send + Sync + Serialize + for<'de> Deserialize<'de>;
+
+  /// Returns A, B, the order of the group, the size of the base field as big integers
+  fn group_params() -> (Self::Base, Self::Base, BigInt, BigInt);
+}
+
+/// A collection of engines that are required by the library
+pub trait Engine: Clone + Copy + Debug + Send + Sync + Sized + Eq + PartialEq {
+  /// A type representing an element of the base field of the group
+  type Base: PrimeFieldBits + TranscriptReprTrait<Self::GE> + Serialize + for<'de> Deserialize<'de>;
+
+  /// A type representing an element of the scalar field of the group
+  type Scalar: PrimeFieldBits
+    + PrimeFieldExt
+    + Send
+    + Sync
+    + TranscriptReprTrait<Self::GE>
+    + Serialize
+    + for<'de> Deserialize<'de>;
+
+  /// A type that represents an element of the group
+  type GE: Group<Base = Self::Base, Scalar = Self::Scalar> + Serialize + for<'de> Deserialize<'de>;
+
+  /// A type that represents a circuit-friendly sponge that consumes elements
+  /// from the base field and squeezes out elements of the scalar field
+  type RO: ROTrait<Self::Base, Self::Scalar>;
+
+  /// An alternate implementation of `Self::RO` in the circuit model
+  type ROCircuit: ROCircuitTrait<Self::Base>;
+
+  /// A type that provides a generic Fiat-Shamir transcript to be used when externalizing proofs
+  type TE: TranscriptEngineTrait<Self>;
+
+  /// A type that defines a commitment engine over scalars in the group
+  type CE: CommitmentEngineTrait<Self>;
+}
+
+/// A helper trait to absorb different objects in RO
+pub trait AbsorbInROTrait<E: Engine> {
+  /// Absorbs the value in the provided RO
+  fn absorb_in_ro(&self, ro: &mut E::RO);
+}
+
+/// A helper trait that defines the behavior of a hash function that we use as an RO
+pub trait ROTrait<Base: PrimeField, Scalar> {
+  /// The circuit alter ego of this trait impl - this constrains it to use the same constants
+  type CircuitRO: ROCircuitTrait<Base, Constants = Self::Constants>;
+
+  /// A type representing constants/parameters associated with the hash function
+  type Constants: Default
+    + Clone
+    + PartialEq
+    + Send
+    + Sync
+    + Serialize
+    + for<'de> Deserialize<'de>
+    + Abomonation;
+
+  /// Initializes the hash function
+  fn new(constants: Self::Constants, num_absorbs: usize) -> Self;
+
+  /// Adds a scalar to the internal state
+  fn absorb(&mut self, e: Base);
+
+  /// Returns a challenge of `num_bits` by hashing the internal state
+  fn squeeze(&mut self, num_bits: usize) -> Scalar;
+}
+
+/// A helper trait that defines the behavior of a hash function that we use as an RO in the circuit model
+pub trait ROCircuitTrait<Base: PrimeField> {
+  /// the vanilla alter ego of this trait - this constrains it to use the same constants
+  type NativeRO<T: PrimeField>: ROTrait<Base, T, Constants = Self::Constants>;
+
+  /// A type representing constants/parameters associated with the hash function on this Base field
+  type Constants: Default
+    + Clone
+    + PartialEq
+    + Send
+    + Sync
+    + Serialize
+    + for<'de> Deserialize<'de>
+    + Abomonation;
+
+  /// Initializes the hash function
+  fn new(constants: Self::Constants, num_absorbs: usize) -> Self;
+
+  /// Adds a scalar to the internal state
+  fn absorb(&mut self, e: &AllocatedNum<Base>);
+
+  /// Returns a challenge of `num_bits` by hashing the internal state
+  fn squeeze<CS: ConstraintSystem<Base>>(
+    &mut self,
+    cs: CS,
+    num_bits: usize,
+  ) -> Result<Vec<AllocatedBit>, SynthesisError>;
+}
+
+/// An alias for constants associated with E::RO
+pub type ROConstants<E> =
+  <<E as Engine>::RO as ROTrait<<E as Engine>::Base, <E as Engine>::Scalar>>::Constants;
+
+/// An alias for constants associated with `E::ROCircuit`
+pub type ROConstantsCircuit<E> =
+  <<E as Engine>::ROCircuit as ROCircuitTrait<<E as Engine>::Base>>::Constants;
+
+/// This trait allows types to implement how they want to be added to `TranscriptEngine`
+pub trait TranscriptReprTrait<G: Group>: Send + Sync {
+  /// returns a byte representation of self to be added to the transcript
+  fn to_transcript_bytes(&self) -> Vec<u8>;
+}
+
+/// This trait defines the behavior of a transcript engine compatible with Spartan
+pub trait TranscriptEngineTrait<E: Engine>: Send + Sync {
+  /// initializes the transcript
+  fn new(label: &'static [u8]) -> Self;
+
+  /// returns a scalar element of the group as a challenge
+  fn squeeze(&mut self, label: &'static [u8]) -> Result<E::Scalar, NovaError>;
+
+  /// absorbs any type that implements `TranscriptReprTrait` under a label
+  fn absorb<T: TranscriptReprTrait<E::GE>>(&mut self, label: &'static [u8], o: &T);
+
+  /// adds a domain separator
+  fn dom_sep(&mut self, bytes: &'static [u8]);
+}
+
+/// Defines additional methods on `PrimeField` objects
+pub trait PrimeFieldExt: PrimeField {
+  /// Returns a scalar representing the bytes
+  fn from_uniform(bytes: &[u8]) -> Self;
+}
+
+impl<G: Group, T: TranscriptReprTrait<G>> TranscriptReprTrait<G> for &[T] {
+  fn to_transcript_bytes(&self) -> Vec<u8> {
+    self
+      .iter()
+      .flat_map(|t| t.to_transcript_bytes())
+      .collect::<Vec<u8>>()
+  }
+}
+
+pub mod circuit;
+pub mod evaluation;
+pub mod snark;
+
\ No newline at end of file diff --git a/docs/src/arecibo/traits/snark.rs.html b/docs/src/arecibo/traits/snark.rs.html new file mode 100644 index 000000000..109f83293 --- /dev/null +++ b/docs/src/arecibo/traits/snark.rs.html @@ -0,0 +1,221 @@ +snark.rs - source
1
+2
+3
+4
+5
+6
+7
+8
+9
+10
+11
+12
+13
+14
+15
+16
+17
+18
+19
+20
+21
+22
+23
+24
+25
+26
+27
+28
+29
+30
+31
+32
+33
+34
+35
+36
+37
+38
+39
+40
+41
+42
+43
+44
+45
+46
+47
+48
+49
+50
+51
+52
+53
+54
+55
+56
+57
+58
+59
+60
+61
+62
+63
+64
+65
+66
+67
+68
+69
+70
+71
+72
+73
+74
+75
+76
+77
+78
+79
+80
+81
+82
+83
+84
+85
+86
+87
+88
+89
+90
+91
+92
+93
+94
+95
+96
+97
+98
+99
+100
+101
+102
+103
+104
+105
+106
+107
+108
+109
+110
+
//! This module defines a collection of traits that define the behavior of a `zkSNARK` for `RelaxedR1CS`
+use crate::{
+  errors::NovaError,
+  r1cs::{R1CSShape, RelaxedR1CSInstance, RelaxedR1CSWitness},
+  traits::Engine,
+  CommitmentKey,
+};
+
+use abomonation::Abomonation;
+use serde::{Deserialize, Serialize};
+
+/// Public parameter creation takes a size hint. This size hint carries the particular requirements of
+/// the final compressing SNARK the user expected to use with these public parameters, and the below
+/// is a sensible default, which is to not require any more bases then the usual (maximum of the number of
+/// variables and constraints of the involved R1CS circuit).
+pub fn default_ck_hint<E: Engine>() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize> {
+  // The default is to not put an additional floor on the size of the commitment key
+  Box::new(|_shape: &R1CSShape<E>| 0)
+}
+
+/// A trait that defines the behavior of a `zkSNARK`
+pub trait RelaxedR1CSSNARKTrait<E: Engine>:
+  Send + Sync + Serialize + for<'de> Deserialize<'de>
+{
+  /// A type that represents the prover's key
+  type ProverKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+
+  /// A type that represents the verifier's key
+  type VerifierKey: Send
+    + Sync
+    + Serialize
+    + for<'de> Deserialize<'de>
+    + DigestHelperTrait<E>
+    + Abomonation;
+
+  /// This associated function (not a method) provides a hint that offers
+  /// a minimum sizing cue for the commitment key used by this SNARK
+  /// implementation. The commitment key passed in setup should then
+  /// be at least as large as this hint.
+  fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize> {
+    // The default is to not put an additional floor on the size of the commitment key
+    default_ck_hint()
+  }
+
+  /// Produces the keys for the prover and the verifier
+  fn setup(
+    ck: &CommitmentKey<E>,
+    S: &R1CSShape<E>,
+  ) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>;
+
+  /// Produces a new SNARK for a relaxed R1CS
+  fn prove(
+    ck: &CommitmentKey<E>,
+    pk: &Self::ProverKey,
+    S: &R1CSShape<E>,
+    U: &RelaxedR1CSInstance<E>,
+    W: &RelaxedR1CSWitness<E>,
+  ) -> Result<Self, NovaError>;
+
+  /// Verifies a SNARK for a relaxed R1CS
+  fn verify(&self, vk: &Self::VerifierKey, U: &RelaxedR1CSInstance<E>) -> Result<(), NovaError>;
+}
+
+/// A trait that defines the behavior of a `zkSNARK` to prove knowledge of satisfying witness to batches of relaxed R1CS instances.
+pub trait BatchedRelaxedR1CSSNARKTrait<E: Engine>:
+  Send + Sync + Serialize + for<'de> Deserialize<'de>
+{
+  /// A type that represents the prover's key
+  type ProverKey: Send + Sync + Serialize + for<'de> Deserialize<'de> + Abomonation;
+
+  /// A type that represents the verifier's key
+  type VerifierKey: Send
+    + Sync
+    + Serialize
+    + for<'de> Deserialize<'de>
+    + DigestHelperTrait<E>
+    + Abomonation;
+
+  /// This associated function (not a method) provides a hint that offers
+  /// a minimum sizing cue for the commitment key used by this SNARK
+  /// implementation. The commitment key passed in setup should then
+  /// be at least as large as this hint.
+  fn ck_floor() -> Box<dyn for<'a> Fn(&'a R1CSShape<E>) -> usize> {
+    default_ck_hint()
+  }
+
+  /// Produces the keys for the prover and the verifier
+  fn setup(
+    ck: &CommitmentKey<E>,
+    S: Vec<&R1CSShape<E>>,
+  ) -> Result<(Self::ProverKey, Self::VerifierKey), NovaError>;
+
+  /// Produces a new SNARK for a batch of relaxed R1CS
+  fn prove(
+    ck: &CommitmentKey<E>,
+    pk: &Self::ProverKey,
+    S: Vec<&R1CSShape<E>>,
+    U: &[RelaxedR1CSInstance<E>],
+    W: &[RelaxedR1CSWitness<E>],
+  ) -> Result<Self, NovaError>;
+
+  /// Verifies a SNARK for a batch of relaxed R1CS
+  fn verify(&self, vk: &Self::VerifierKey, U: &[RelaxedR1CSInstance<E>]) -> Result<(), NovaError>;
+}
+
+/// A helper trait that defines the behavior of a verifier key of `zkSNARK`
+pub trait DigestHelperTrait<E: Engine> {
+  /// Returns the digest of the verifier's key
+  fn digest(&self) -> E::Scalar;
+}
+
\ No newline at end of file diff --git a/docs/static.files/COPYRIGHT-23e9bde6c69aea69.txt b/docs/static.files/COPYRIGHT-23e9bde6c69aea69.txt new file mode 100644 index 000000000..1447df792 --- /dev/null +++ b/docs/static.files/COPYRIGHT-23e9bde6c69aea69.txt @@ -0,0 +1,50 @@ +# REUSE-IgnoreStart + +These documentation pages include resources by third parties. This copyright +file applies only to those resources. The following third party resources are +included, and carry their own copyright notices and license terms: + +* Fira Sans (FiraSans-Regular.woff2, FiraSans-Medium.woff2): + + Copyright (c) 2014, Mozilla Foundation https://mozilla.org/ + with Reserved Font Name Fira Sans. + + Copyright (c) 2014, Telefonica S.A. + + Licensed under the SIL Open Font License, Version 1.1. + See FiraSans-LICENSE.txt. + +* rustdoc.css, main.js, and playpen.js: + + Copyright 2015 The Rust Developers. + Licensed under the Apache License, Version 2.0 (see LICENSE-APACHE.txt) or + the MIT license (LICENSE-MIT.txt) at your option. + +* normalize.css: + + Copyright (c) Nicolas Gallagher and Jonathan Neal. + Licensed under the MIT license (see LICENSE-MIT.txt). + +* Source Code Pro (SourceCodePro-Regular.ttf.woff2, + SourceCodePro-Semibold.ttf.woff2, SourceCodePro-It.ttf.woff2): + + Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), + with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark + of Adobe Systems Incorporated in the United States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceCodePro-LICENSE.txt. + +* Source Serif 4 (SourceSerif4-Regular.ttf.woff2, SourceSerif4-Bold.ttf.woff2, + SourceSerif4-It.ttf.woff2): + + Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name + 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United + States and/or other countries. + + Licensed under the SIL Open Font License, Version 1.1. + See SourceSerif4-LICENSE.md. + +This copyright file is intended to be distributed with rustdoc output. + +# REUSE-IgnoreEnd diff --git a/docs/static.files/FiraSans-LICENSE-db4b642586e02d97.txt b/docs/static.files/FiraSans-LICENSE-db4b642586e02d97.txt new file mode 100644 index 000000000..d7e9c149b --- /dev/null +++ b/docs/static.files/FiraSans-LICENSE-db4b642586e02d97.txt @@ -0,0 +1,98 @@ +// REUSE-IgnoreStart + +Digitized data copyright (c) 2012-2015, The Mozilla Foundation and Telefonica S.A. +with Reserved Font Name < Fira >, + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/docs/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 b/docs/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 new file mode 100644 index 000000000..7a1e5fc54 Binary files /dev/null and b/docs/static.files/FiraSans-Medium-8f9a781e4970d388.woff2 differ diff --git a/docs/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 b/docs/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 new file mode 100644 index 000000000..e766e06cc Binary files /dev/null and b/docs/static.files/FiraSans-Regular-018c141bf0843ffd.woff2 differ diff --git a/docs/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt b/docs/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt new file mode 100644 index 000000000..16fe87b06 --- /dev/null +++ b/docs/static.files/LICENSE-APACHE-b91fa81cba47b86a.txt @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + +TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + +1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + +2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + +3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + +4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + +5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + +6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + +7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + +8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + +9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + +END OF TERMS AND CONDITIONS + +APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + +Copyright [yyyy] [name of copyright owner] + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/docs/static.files/LICENSE-MIT-65090b722b3f6c56.txt b/docs/static.files/LICENSE-MIT-65090b722b3f6c56.txt new file mode 100644 index 000000000..31aa79387 --- /dev/null +++ b/docs/static.files/LICENSE-MIT-65090b722b3f6c56.txt @@ -0,0 +1,23 @@ +Permission is hereby granted, free of charge, to any +person obtaining a copy of this software and associated +documentation files (the "Software"), to deal in the +Software without restriction, including without +limitation the rights to use, copy, modify, merge, +publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software +is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice +shall be included in all copies or substantial portions +of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF +ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED +TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A +PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT +SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY +CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR +IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +DEALINGS IN THE SOFTWARE. diff --git a/docs/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 b/docs/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 new file mode 100644 index 000000000..1866ad4bc Binary files /dev/null and b/docs/static.files/NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2 differ diff --git a/docs/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt b/docs/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt new file mode 100644 index 000000000..4b3edc29e --- /dev/null +++ b/docs/static.files/NanumBarunGothic-LICENSE-18c5adf4b52b4041.txt @@ -0,0 +1,103 @@ +// REUSE-IgnoreStart + +Copyright (c) 2010, NAVER Corporation (https://www.navercorp.com/), + +with Reserved Font Name Nanum, Naver Nanum, NanumGothic, Naver NanumGothic, +NanumMyeongjo, Naver NanumMyeongjo, NanumBrush, Naver NanumBrush, NanumPen, +Naver NanumPen, Naver NanumGothicEco, NanumGothicEco, Naver NanumMyeongjoEco, +NanumMyeongjoEco, Naver NanumGothicLight, NanumGothicLight, NanumBarunGothic, +Naver NanumBarunGothic, NanumSquareRound, NanumBarunPen, MaruBuri + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/docs/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 b/docs/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 new file mode 100644 index 000000000..462c34efc Binary files /dev/null and b/docs/static.files/SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2 differ diff --git a/docs/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt b/docs/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt new file mode 100644 index 000000000..0d2941e14 --- /dev/null +++ b/docs/static.files/SourceCodePro-LICENSE-d180d465a756484a.txt @@ -0,0 +1,97 @@ +// REUSE-IgnoreStart + +Copyright 2010, 2012 Adobe Systems Incorporated (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe Systems Incorporated in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + +// REUSE-IgnoreEnd diff --git a/docs/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 b/docs/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 new file mode 100644 index 000000000..10b558e0b Binary files /dev/null and b/docs/static.files/SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2 differ diff --git a/docs/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 b/docs/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 new file mode 100644 index 000000000..5ec64eef0 Binary files /dev/null and b/docs/static.files/SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2 differ diff --git a/docs/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 b/docs/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 new file mode 100644 index 000000000..181a07f63 Binary files /dev/null and b/docs/static.files/SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2 differ diff --git a/docs/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 b/docs/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 new file mode 100644 index 000000000..2ae08a7be Binary files /dev/null and b/docs/static.files/SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2 differ diff --git a/docs/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md b/docs/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md new file mode 100644 index 000000000..175fa4f47 --- /dev/null +++ b/docs/static.files/SourceSerif4-LICENSE-3bb119e13b1258b7.md @@ -0,0 +1,98 @@ + + +Copyright 2014-2021 Adobe (http://www.adobe.com/), with Reserved Font Name 'Source'. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. +Copyright 2014 - 2023 Adobe (http://www.adobe.com/), with Reserved Font Name ‘Source’. All Rights Reserved. Source is a trademark of Adobe in the United States and/or other countries. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. + +This license is copied below, and is also available with a FAQ at: http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. + + diff --git a/docs/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 b/docs/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 new file mode 100644 index 000000000..0263fc304 Binary files /dev/null and b/docs/static.files/SourceSerif4-Regular-46f98efaafac5295.ttf.woff2 differ diff --git a/docs/static.files/ayu-fd19013d6ce078bf.css b/docs/static.files/ayu-fd19013d6ce078bf.css new file mode 100644 index 000000000..ba3aa60e0 --- /dev/null +++ b/docs/static.files/ayu-fd19013d6ce078bf.css @@ -0,0 +1 @@ + :root{--main-background-color:#0f1419;--main-color:#c5c5c5;--settings-input-color:#ffb454;--settings-input-border-color:#999;--settings-button-color:#fff;--settings-button-border-focus:#e0e0e0;--sidebar-background-color:#14191f;--sidebar-background-color-hover:rgba(70,70,70,0.33);--code-block-background-color:#191f26;--scrollbar-track-background-color:transparent;--scrollbar-thumb-background-color:#5c6773;--scrollbar-color:#5c6773 #24292f;--headings-border-bottom-color:#5c6773;--border-color:#5c6773;--button-background-color:#141920;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#5c6773;--copy-path-button-color:#fff;--copy-path-img-filter:invert(70%);--copy-path-img-hover-filter:invert(100%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#ffa0a5;--trait-link-color:#39afd7;--assoc-item-link-color:#39afd7;--function-link-color:#fdd687;--macro-link-color:#a37acc;--keyword-link-color:#39afd7;--mod-link-color:#39afd7;--link-color:#39afd7;--sidebar-link-color:#53b1db;--sidebar-current-link-background-color:transparent;--search-result-link-focus-background-color:#3c3c3c;--search-result-border-color:#aaa3;--search-color:#fff;--search-error-code-background-color:#4f4c4c;--search-results-alias-color:#c5c5c5;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:none;--search-tab-button-not-selected-background:transparent !important;--search-tab-button-selected-border-top-color:none;--search-tab-button-selected-background:#141920 !important;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ff7733;--code-highlight-kw-2-color:#ff7733;--code-highlight-lifetime-color:#ff7733;--code-highlight-prelude-color:#69f2df;--code-highlight-prelude-val-color:#ff7733;--code-highlight-number-color:#b8cc52;--code-highlight-string-color:#b8cc52;--code-highlight-literal-color:#ff7733;--code-highlight-attribute-color:#e6e1cf;--code-highlight-self-color:#36a3d9;--code-highlight-macro-color:#a37acc;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#788797;--code-highlight-doc-comment-color:#a1ac88;--src-line-numbers-span-color:#5c6773;--src-line-number-highlighted-background-color:rgba(255,236,164,0.06);--test-arrow-color:#788797;--test-arrow-background-color:rgba(57,175,215,0.09);--test-arrow-hover-color:#c5c5c5;--test-arrow-hover-background-color:rgba(57,175,215,0.368);--target-background-color:rgba(255,236,164,0.06);--target-border-color:rgba(255,180,76,0.85);--kbd-color:#c5c5c5;--kbd-background:#314559;--kbd-box-shadow-color:#5c6773;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(41%) sepia(12%) saturate(487%) hue-rotate(171deg) brightness(94%) contrast(94%);--crate-search-div-hover-filter:invert(98%) sepia(12%) saturate(81%) hue-rotate(343deg) brightness(113%) contrast(76%);--crate-search-hover-border:#e0e0e0;--src-sidebar-background-selected:#14191f;--src-sidebar-background-hover:#14191f;--table-alt-row-background-color:#191f26;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:rgb(91,59,1);--scrape-example-code-line-highlight-focus:rgb(124,75,15);--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(15,20,25,1);--scrape-example-code-wrapper-background-end:rgba(15,20,25,0);}h1,h2,h3,h4,h1 a,.sidebar h2 a,.sidebar h3 a,#src-sidebar>.title{color:#fff;}h4{border:none;}.docblock code{color:#ffb454;}.docblock a>code{color:#39AFD7 !important;}.code-header,.docblock pre>code,pre,pre>code,.item-info code,.rustdoc.src .example-wrap{color:#e6e1cf;}.sidebar .current,.sidebar a:hover,#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus,#src-sidebar div.files>a.selected{color:#ffb44c;}.sidebar-elems .location{color:#ff7733;}.src-line-numbers .line-highlighted{color:#708090;padding-right:7px;border-right:1px solid #ffb44c;}.search-results a:hover,.search-results a:focus{color:#fff !important;background-color:#3c3c3c;}.search-results a{color:#0096cf;}.search-results a div.desc{color:#c5c5c5;}.result-name .primitive>i,.result-name .keyword>i{color:#788797;}#search-tabs>button.selected{border-bottom:1px solid #ffb44c !important;border-top:none;}#search-tabs>button:not(.selected){border:none;background-color:transparent !important;}#search-tabs>button:hover{border-bottom:1px solid rgba(242,151,24,0.3);}#settings-menu>a img{filter:invert(100);} \ No newline at end of file diff --git a/docs/static.files/clipboard-7571035ce49a181d.svg b/docs/static.files/clipboard-7571035ce49a181d.svg new file mode 100644 index 000000000..8adbd9963 --- /dev/null +++ b/docs/static.files/clipboard-7571035ce49a181d.svg @@ -0,0 +1 @@ + diff --git a/docs/static.files/dark-0a43001d3fc2282c.css b/docs/static.files/dark-0a43001d3fc2282c.css new file mode 100644 index 000000000..81032b2fa --- /dev/null +++ b/docs/static.files/dark-0a43001d3fc2282c.css @@ -0,0 +1 @@ +:root{--main-background-color:#353535;--main-color:#ddd;--settings-input-color:#2196f3;--settings-input-border-color:#999;--settings-button-color:#000;--settings-button-border-focus:#ffb900;--sidebar-background-color:#505050;--sidebar-background-color-hover:#676767;--code-block-background-color:#2A2A2A;--scrollbar-track-background-color:#717171;--scrollbar-thumb-background-color:rgba(32,34,37,.6);--scrollbar-color:rgba(32,34,37,.6) #5a5a5a;--headings-border-bottom-color:#d2d2d2;--border-color:#e0e0e0;--button-background-color:#f0f0f0;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:invert(100%);--search-input-focused-border-color:#008dfd;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(65%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#2dbfb8;--trait-link-color:#b78cf2;--assoc-item-link-color:#d2991d;--function-link-color:#2bab63;--macro-link-color:#09bd00;--keyword-link-color:#d2991d;--mod-link-color:#d2991d;--link-color:#d2991d;--sidebar-link-color:#fdbf35;--sidebar-current-link-background-color:#444;--search-result-link-focus-background-color:#616161;--search-result-border-color:#aaa3;--search-color:#111;--search-error-code-background-color:#484848;--search-results-alias-color:#fff;--search-results-grey-color:#ccc;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#252525;--search-tab-button-not-selected-background:#252525;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#353535;--stab-background-color:#314559;--stab-code-color:#e6e1cf;--code-highlight-kw-color:#ab8ac1;--code-highlight-kw-2-color:#769acb;--code-highlight-lifetime-color:#d97f26;--code-highlight-prelude-color:#769acb;--code-highlight-prelude-val-color:#ee6868;--code-highlight-number-color:#83a300;--code-highlight-string-color:#83a300;--code-highlight-literal-color:#ee6868;--code-highlight-attribute-color:#ee6868;--code-highlight-self-color:#ee6868;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8d8d8b;--code-highlight-doc-comment-color:#8ca375;--src-line-numbers-span-color:#3b91e2;--src-line-number-highlighted-background-color:#0a042f;--test-arrow-color:#dedede;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#dedede;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#494a3d;--target-border-color:#bb7410;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:drop-shadow(1px 0 0px #fff) drop-shadow(0 1px 0 #fff) drop-shadow(-1px 0 0 #fff) drop-shadow(0 -1px 0 #fff);--crate-search-div-filter:invert(94%) sepia(0%) saturate(721%) hue-rotate(255deg) brightness(90%) contrast(90%);--crate-search-div-hover-filter:invert(69%) sepia(60%) saturate(6613%) hue-rotate(184deg) brightness(100%) contrast(91%);--crate-search-hover-border:#2196f3;--src-sidebar-background-selected:#333;--src-sidebar-background-hover:#444;--table-alt-row-background-color:#2A2A2A;--codeblock-link-background:#333;--scrape-example-toggle-line-background:#999;--scrape-example-toggle-line-hover-background:#c5c5c5;--scrape-example-code-line-highlight:rgb(91,59,1);--scrape-example-code-line-highlight-focus:rgb(124,75,15);--scrape-example-help-border-color:#aaa;--scrape-example-help-color:#eee;--scrape-example-help-hover-border-color:#fff;--scrape-example-help-hover-color:#fff;--scrape-example-code-wrapper-background-start:rgba(53,53,53,1);--scrape-example-code-wrapper-background-end:rgba(53,53,53,0);} \ No newline at end of file diff --git a/docs/static.files/favicon-16x16-8b506e7a72182f1c.png b/docs/static.files/favicon-16x16-8b506e7a72182f1c.png new file mode 100644 index 000000000..ea4b45cae Binary files /dev/null and b/docs/static.files/favicon-16x16-8b506e7a72182f1c.png differ diff --git a/docs/static.files/favicon-2c020d218678b618.svg b/docs/static.files/favicon-2c020d218678b618.svg new file mode 100644 index 000000000..8b34b5119 --- /dev/null +++ b/docs/static.files/favicon-2c020d218678b618.svg @@ -0,0 +1,24 @@ + + + + + diff --git a/docs/static.files/favicon-32x32-422f7d1d52889060.png b/docs/static.files/favicon-32x32-422f7d1d52889060.png new file mode 100644 index 000000000..69b8613ce Binary files /dev/null and b/docs/static.files/favicon-32x32-422f7d1d52889060.png differ diff --git a/docs/static.files/light-1596385f77d47ef2.css b/docs/static.files/light-1596385f77d47ef2.css new file mode 100644 index 000000000..50adde5b0 --- /dev/null +++ b/docs/static.files/light-1596385f77d47ef2.css @@ -0,0 +1 @@ +:root{--main-background-color:white;--main-color:black;--settings-input-color:#2196f3;--settings-input-border-color:#717171;--settings-button-color:#000;--settings-button-border-focus:#717171;--sidebar-background-color:#F5F5F5;--sidebar-background-color-hover:#E0E0E0;--code-block-background-color:#F5F5F5;--scrollbar-track-background-color:#dcdcdc;--scrollbar-thumb-background-color:rgba(36,37,39,0.6);--scrollbar-color:rgba(36,37,39,0.6) #d9d9d9;--headings-border-bottom-color:#ddd;--border-color:#e0e0e0;--button-background-color:#fff;--right-side-color:grey;--code-attribute-color:#999;--toggles-color:#999;--toggle-filter:none;--search-input-focused-border-color:#66afe9;--copy-path-button-color:#999;--copy-path-img-filter:invert(50%);--copy-path-img-hover-filter:invert(35%);--codeblock-error-hover-color:rgb(255,0,0);--codeblock-error-color:rgba(255,0,0,.5);--codeblock-ignore-hover-color:rgb(255,142,0);--codeblock-ignore-color:rgba(255,142,0,.6);--type-link-color:#ad378a;--trait-link-color:#6e4fc9;--assoc-item-link-color:#3873ad;--function-link-color:#ad7c37;--macro-link-color:#068000;--keyword-link-color:#3873ad;--mod-link-color:#3873ad;--link-color:#3873ad;--sidebar-link-color:#356da4;--sidebar-current-link-background-color:#fff;--search-result-link-focus-background-color:#ccc;--search-result-border-color:#aaa3;--search-color:#000;--search-error-code-background-color:#d0cccc;--search-results-alias-color:#000;--search-results-grey-color:#999;--search-tab-title-count-color:#888;--search-tab-button-not-selected-border-top-color:#e6e6e6;--search-tab-button-not-selected-background:#e6e6e6;--search-tab-button-selected-border-top-color:#0089ff;--search-tab-button-selected-background:#ffffff;--stab-background-color:#fff5d6;--stab-code-color:#000;--code-highlight-kw-color:#8959a8;--code-highlight-kw-2-color:#4271ae;--code-highlight-lifetime-color:#b76514;--code-highlight-prelude-color:#4271ae;--code-highlight-prelude-val-color:#c82829;--code-highlight-number-color:#718c00;--code-highlight-string-color:#718c00;--code-highlight-literal-color:#c82829;--code-highlight-attribute-color:#c82829;--code-highlight-self-color:#c82829;--code-highlight-macro-color:#3e999f;--code-highlight-question-mark-color:#ff9011;--code-highlight-comment-color:#8e908c;--code-highlight-doc-comment-color:#4d4d4c;--src-line-numbers-span-color:#c67e2d;--src-line-number-highlighted-background-color:#fdffd3;--test-arrow-color:#f5f5f5;--test-arrow-background-color:rgba(78,139,202,0.2);--test-arrow-hover-color:#f5f5f5;--test-arrow-hover-background-color:rgb(78,139,202);--target-background-color:#fdffd3;--target-border-color:#ad7c37;--kbd-color:#000;--kbd-background:#fafbfc;--kbd-box-shadow-color:#c6cbd1;--rust-logo-filter:initial;--crate-search-div-filter:invert(100%) sepia(0%) saturate(4223%) hue-rotate(289deg) brightness(114%) contrast(76%);--crate-search-div-hover-filter:invert(44%) sepia(18%) saturate(23%) hue-rotate(317deg) brightness(96%) contrast(93%);--crate-search-hover-border:#717171;--src-sidebar-background-selected:#fff;--src-sidebar-background-hover:#e0e0e0;--table-alt-row-background-color:#F5F5F5;--codeblock-link-background:#eee;--scrape-example-toggle-line-background:#ccc;--scrape-example-toggle-line-hover-background:#999;--scrape-example-code-line-highlight:#fcffd6;--scrape-example-code-line-highlight-focus:#f6fdb0;--scrape-example-help-border-color:#555;--scrape-example-help-color:#333;--scrape-example-help-hover-border-color:#000;--scrape-example-help-hover-color:#000;--scrape-example-code-wrapper-background-start:rgba(255,255,255,1);--scrape-example-code-wrapper-background-end:rgba(255,255,255,0);} \ No newline at end of file diff --git a/docs/static.files/main-0795b7d26be81095.js b/docs/static.files/main-0795b7d26be81095.js new file mode 100644 index 000000000..87b433898 --- /dev/null +++ b/docs/static.files/main-0795b7d26be81095.js @@ -0,0 +1,12 @@ +"use strict";window.RUSTDOC_TOOLTIP_HOVER_MS=300;window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS=450;function resourcePath(basename,extension){return getVar("root-path")+basename+getVar("resource-suffix")+extension}function hideMain(){addClass(document.getElementById(MAIN_ID),"hidden")}function showMain(){removeClass(document.getElementById(MAIN_ID),"hidden")}function elemIsInParent(elem,parent){while(elem&&elem!==document.body){if(elem===parent){return true}elem=elem.parentElement}return false}function blurHandler(event,parentElem,hideCallback){if(!elemIsInParent(document.activeElement,parentElem)&&!elemIsInParent(event.relatedTarget,parentElem)){hideCallback()}}window.rootPath=getVar("root-path");window.currentCrate=getVar("current-crate");function setMobileTopbar(){const mobileLocationTitle=document.querySelector(".mobile-topbar h2");const locationTitle=document.querySelector(".sidebar h2.location");if(mobileLocationTitle&&locationTitle){mobileLocationTitle.innerHTML=locationTitle.innerHTML}}function getVirtualKey(ev){if("key"in ev&&typeof ev.key!=="undefined"){return ev.key}const c=ev.charCode||ev.keyCode;if(c===27){return"Escape"}return String.fromCharCode(c)}const MAIN_ID="main-content";const SETTINGS_BUTTON_ID="settings-menu";const ALTERNATIVE_DISPLAY_ID="alternative-display";const NOT_DISPLAYED_ID="not-displayed";const HELP_BUTTON_ID="help-button";function getSettingsButton(){return document.getElementById(SETTINGS_BUTTON_ID)}function getHelpButton(){return document.getElementById(HELP_BUTTON_ID)}function getNakedUrl(){return window.location.href.split("?")[0].split("#")[0]}function insertAfter(newNode,referenceNode){referenceNode.parentNode.insertBefore(newNode,referenceNode.nextSibling)}function getOrCreateSection(id,classes){let el=document.getElementById(id);if(!el){el=document.createElement("section");el.id=id;el.className=classes;insertAfter(el,document.getElementById(MAIN_ID))}return el}function getAlternativeDisplayElem(){return getOrCreateSection(ALTERNATIVE_DISPLAY_ID,"content hidden")}function getNotDisplayedElem(){return getOrCreateSection(NOT_DISPLAYED_ID,"hidden")}function switchDisplayedElement(elemToDisplay){const el=getAlternativeDisplayElem();if(el.children.length>0){getNotDisplayedElem().appendChild(el.firstElementChild)}if(elemToDisplay===null){addClass(el,"hidden");showMain();return}el.appendChild(elemToDisplay);hideMain();removeClass(el,"hidden")}function browserSupportsHistoryApi(){return window.history&&typeof window.history.pushState==="function"}function loadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="stylesheet";document.getElementsByTagName("head")[0].appendChild(link)}function preLoadCss(cssUrl){const link=document.createElement("link");link.href=cssUrl;link.rel="preload";link.as="style";document.getElementsByTagName("head")[0].appendChild(link)}(function(){const isHelpPage=window.location.pathname.endsWith("/help.html");function loadScript(url){const script=document.createElement("script");script.src=url;document.head.append(script)}getSettingsButton().onclick=event=>{if(event.ctrlKey||event.altKey||event.metaKey){return}window.hideAllModals(false);addClass(getSettingsButton(),"rotate");event.preventDefault();loadCss(getVar("static-root-path")+getVar("settings-css"));loadScript(getVar("static-root-path")+getVar("settings-js"));preLoadCss(getVar("static-root-path")+getVar("theme-light-css"));preLoadCss(getVar("static-root-path")+getVar("theme-dark-css"));preLoadCss(getVar("static-root-path")+getVar("theme-ayu-css"));setTimeout(()=>{const themes=getVar("themes").split(",");for(const theme of themes){if(theme!==""){preLoadCss(getVar("root-path")+theme+".css")}}},0)};window.searchState={loadingText:"Loading search results...",input:document.getElementsByClassName("search-input")[0],outputElement:()=>{let el=document.getElementById("search");if(!el){el=document.createElement("section");el.id="search";getNotDisplayedElem().appendChild(el)}return el},title:document.title,titleBeforeSearch:document.title,timeout:null,currentTab:0,focusedByTab:[null,null,null],clearInputTimeout:()=>{if(searchState.timeout!==null){clearTimeout(searchState.timeout);searchState.timeout=null}},isDisplayed:()=>searchState.outputElement().parentElement.id===ALTERNATIVE_DISPLAY_ID,focus:()=>{searchState.input.focus()},defocus:()=>{searchState.input.blur()},showResults:search=>{if(search===null||typeof search==="undefined"){search=searchState.outputElement()}switchDisplayedElement(search);searchState.mouseMovedAfterSearch=false;document.title=searchState.title},removeQueryParameters:()=>{document.title=searchState.titleBeforeSearch;if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.hash)}},hideResults:()=>{switchDisplayedElement(null);searchState.removeQueryParameters()},getQueryStringParams:()=>{const params={};window.location.search.substring(1).split("&").map(s=>{const pair=s.split("=");params[decodeURIComponent(pair[0])]=typeof pair[1]==="undefined"?null:decodeURIComponent(pair[1])});return params},setup:()=>{const search_input=searchState.input;if(!searchState.input){return}let searchLoaded=false;function loadSearch(){if(!searchLoaded){searchLoaded=true;loadScript(getVar("static-root-path")+getVar("search-js"));loadScript(resourcePath("search-index",".js"))}}search_input.addEventListener("focus",()=>{search_input.origPlaceholder=search_input.placeholder;search_input.placeholder="Type your search here.";loadSearch()});if(search_input.value!==""){loadSearch()}const params=searchState.getQueryStringParams();if(params.search!==undefined){searchState.setLoadingSearch();loadSearch()}},setLoadingSearch:()=>{const search=searchState.outputElement();search.innerHTML="

"+searchState.loadingText+"

";searchState.showResults(search)},};const toggleAllDocsId="toggle-all-docs";let savedHash="";function handleHashes(ev){if(ev!==null&&searchState.isDisplayed()&&ev.newURL){switchDisplayedElement(null);const hash=ev.newURL.slice(ev.newURL.indexOf("#")+1);if(browserSupportsHistoryApi()){history.replaceState(null,"",getNakedUrl()+window.location.search+"#"+hash)}const elem=document.getElementById(hash);if(elem){elem.scrollIntoView()}}const pageId=window.location.hash.replace(/^#/,"");if(savedHash!==pageId){savedHash=pageId;if(pageId!==""){expandSection(pageId)}}}function onHashChange(ev){hideSidebar();handleHashes(ev)}function openParentDetails(elem){while(elem){if(elem.tagName==="DETAILS"){elem.open=true}elem=elem.parentNode}}function expandSection(id){openParentDetails(document.getElementById(id))}function handleEscape(ev){searchState.clearInputTimeout();searchState.hideResults();ev.preventDefault();searchState.defocus();window.hideAllModals(true)}function handleShortcut(ev){const disableShortcuts=getSettingValue("disable-shortcuts")==="true";if(ev.ctrlKey||ev.altKey||ev.metaKey||disableShortcuts){return}if(document.activeElement.tagName==="INPUT"&&document.activeElement.type!=="checkbox"&&document.activeElement.type!=="radio"){switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break}}else{switch(getVirtualKey(ev)){case"Escape":handleEscape(ev);break;case"s":case"S":ev.preventDefault();searchState.focus();break;case"+":ev.preventDefault();expandAllDocs();break;case"-":ev.preventDefault();collapseAllDocs();break;case"?":showHelp();break;default:break}}}document.addEventListener("keypress",handleShortcut);document.addEventListener("keydown",handleShortcut);function addSidebarItems(){if(!window.SIDEBAR_ITEMS){return}const sidebar=document.getElementsByClassName("sidebar-elems")[0];function block(shortty,id,longty){const filtered=window.SIDEBAR_ITEMS[shortty];if(!filtered){return}const h3=document.createElement("h3");h3.innerHTML=`${longty}`;const ul=document.createElement("ul");ul.className="block "+shortty;for(const name of filtered){let path;if(shortty==="mod"){path=name+"/index.html"}else{path=shortty+"."+name+".html"}const current_page=document.location.href.split("/").pop();const link=document.createElement("a");link.href=path;if(path===current_page){link.className="current"}link.textContent=name;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebar.appendChild(h3);sidebar.appendChild(ul)}if(sidebar){block("primitive","primitives","Primitive Types");block("mod","modules","Modules");block("macro","macros","Macros");block("struct","structs","Structs");block("enum","enums","Enums");block("union","unions","Unions");block("constant","constants","Constants");block("static","static","Statics");block("trait","traits","Traits");block("fn","functions","Functions");block("type","types","Type Definitions");block("foreigntype","foreign-types","Foreign Types");block("keyword","keywords","Keywords");block("traitalias","trait-aliases","Trait Aliases")}}window.register_implementors=imp=>{const implementors=document.getElementById("implementors-list");const synthetic_implementors=document.getElementById("synthetic-implementors-list");const inlined_types=new Set();const TEXT_IDX=0;const SYNTHETIC_IDX=1;const TYPES_IDX=2;if(synthetic_implementors){onEachLazy(synthetic_implementors.getElementsByClassName("impl"),el=>{const aliases=el.getAttribute("data-aliases");if(!aliases){return}aliases.split(",").forEach(alias=>{inlined_types.add(alias)})})}let currentNbImpls=implementors.getElementsByClassName("impl").length;const traitName=document.querySelector(".main-heading h1 > .trait").textContent;const baseIdName="impl-"+traitName+"-";const libs=Object.getOwnPropertyNames(imp);const script=document.querySelector("script[data-ignore-extern-crates]");const ignoreExternCrates=new Set((script?script.getAttribute("data-ignore-extern-crates"):"").split(","));for(const lib of libs){if(lib===window.currentCrate||ignoreExternCrates.has(lib)){continue}const structs=imp[lib];struct_loop:for(const struct of structs){const list=struct[SYNTHETIC_IDX]?synthetic_implementors:implementors;if(struct[SYNTHETIC_IDX]){for(const struct_type of struct[TYPES_IDX]){if(inlined_types.has(struct_type)){continue struct_loop}inlined_types.add(struct_type)}}const code=document.createElement("h3");code.innerHTML=struct[TEXT_IDX];addClass(code,"code-header");onEachLazy(code.getElementsByTagName("a"),elem=>{const href=elem.getAttribute("href");if(href&&!/^(?:[a-z+]+:)?\/\//.test(href)){elem.setAttribute("href",window.rootPath+href)}});const currentId=baseIdName+currentNbImpls;const anchor=document.createElement("a");anchor.href="#"+currentId;addClass(anchor,"anchor");const display=document.createElement("div");display.id=currentId;addClass(display,"impl");display.appendChild(anchor);display.appendChild(code);list.appendChild(display);currentNbImpls+=1}}};if(window.pending_implementors){window.register_implementors(window.pending_implementors)}function addSidebarCrates(){if(!window.ALL_CRATES){return}const sidebarElems=document.getElementsByClassName("sidebar-elems")[0];if(!sidebarElems){return}const h3=document.createElement("h3");h3.innerHTML="Crates";const ul=document.createElement("ul");ul.className="block crate";for(const crate of window.ALL_CRATES){const link=document.createElement("a");link.href=window.rootPath+crate+"/index.html";if(window.rootPath!=="./"&&crate===window.currentCrate){link.className="current"}link.textContent=crate;const li=document.createElement("li");li.appendChild(link);ul.appendChild(li)}sidebarElems.appendChild(h3);sidebarElems.appendChild(ul)}function expandAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);removeClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hasClass(e,"type-contents-toggle")&&!hasClass(e,"more-examples-toggle")){e.open=true}});innerToggle.title="collapse all docs";innerToggle.children[0].innerText="\u2212"}function collapseAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);addClass(innerToggle,"will-expand");onEachLazy(document.getElementsByClassName("toggle"),e=>{if(e.parentNode.id!=="implementations-list"||(!hasClass(e,"implementors-toggle")&&!hasClass(e,"type-contents-toggle"))){e.open=false}});innerToggle.title="expand all docs";innerToggle.children[0].innerText="+"}function toggleAllDocs(){const innerToggle=document.getElementById(toggleAllDocsId);if(!innerToggle){return}if(hasClass(innerToggle,"will-expand")){expandAllDocs()}else{collapseAllDocs()}}(function(){const toggles=document.getElementById(toggleAllDocsId);if(toggles){toggles.onclick=toggleAllDocs}const hideMethodDocs=getSettingValue("auto-hide-method-docs")==="true";const hideImplementations=getSettingValue("auto-hide-trait-implementations")==="true";const hideLargeItemContents=getSettingValue("auto-hide-large-items")!=="false";function setImplementorsTogglesOpen(id,open){const list=document.getElementById(id);if(list!==null){onEachLazy(list.getElementsByClassName("implementors-toggle"),e=>{e.open=open})}}if(hideImplementations){setImplementorsTogglesOpen("trait-implementations-list",false);setImplementorsTogglesOpen("blanket-implementations-list",false)}onEachLazy(document.getElementsByClassName("toggle"),e=>{if(!hideLargeItemContents&&hasClass(e,"type-contents-toggle")){e.open=true}if(hideMethodDocs&&hasClass(e,"method-toggle")){e.open=false}})}());window.rustdoc_add_line_numbers_to_examples=()=>{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");if(line_numbers.length>0){return}const count=x.textContent.split("\n").length;const elems=[];for(let i=0;i{onEachLazy(document.getElementsByClassName("rust-example-rendered"),x=>{const parent=x.parentNode;const line_numbers=parent.querySelectorAll(".example-line-numbers");for(const node of line_numbers){parent.removeChild(node)}})};if(getSettingValue("line-numbers")==="true"){window.rustdoc_add_line_numbers_to_examples()}function showSidebar(){window.hideAllModals(false);const sidebar=document.getElementsByClassName("sidebar")[0];addClass(sidebar,"shown")}function hideSidebar(){const sidebar=document.getElementsByClassName("sidebar")[0];removeClass(sidebar,"shown")}window.addEventListener("resize",()=>{if(window.CURRENT_TOOLTIP_ELEMENT){const base=window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE;const force_visible=base.TOOLTIP_FORCE_VISIBLE;hideTooltip(false);if(force_visible){showTooltip(base);base.TOOLTIP_FORCE_VISIBLE=true}}});const mainElem=document.getElementById(MAIN_ID);if(mainElem){mainElem.addEventListener("click",hideSidebar)}onEachLazy(document.querySelectorAll("a[href^='#']"),el=>{el.addEventListener("click",()=>{expandSection(el.hash.slice(1));hideSidebar()})});onEachLazy(document.querySelectorAll(".toggle > summary:not(.hideme)"),el=>{el.addEventListener("click",e=>{if(e.target.tagName!=="SUMMARY"&&e.target.tagName!=="A"){e.preventDefault()}})});function showTooltip(e){const notable_ty=e.getAttribute("data-notable-ty");if(!window.NOTABLE_TRAITS&¬able_ty){const data=document.getElementById("notable-traits-data");if(data){window.NOTABLE_TRAITS=JSON.parse(data.innerText)}else{throw new Error("showTooltip() called with notable without any notable traits!")}}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE===e){clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);return}window.hideAllModals(false);const wrapper=document.createElement("div");if(notable_ty){wrapper.innerHTML="
"+window.NOTABLE_TRAITS[notable_ty]+"
"}else{if(e.getAttribute("title")!==null){e.setAttribute("data-title",e.getAttribute("title"));e.removeAttribute("title")}if(e.getAttribute("data-title")!==null){const titleContent=document.createElement("div");titleContent.className="content";titleContent.appendChild(document.createTextNode(e.getAttribute("data-title")));wrapper.appendChild(titleContent)}}wrapper.className="tooltip popover";const focusCatcher=document.createElement("div");focusCatcher.setAttribute("tabindex","0");focusCatcher.onfocus=hideTooltip;wrapper.appendChild(focusCatcher);const pos=e.getBoundingClientRect();wrapper.style.top=(pos.top+window.scrollY+pos.height)+"px";wrapper.style.left=0;wrapper.style.right="auto";wrapper.style.visibility="hidden";const body=document.getElementsByTagName("body")[0];body.appendChild(wrapper);const wrapperPos=wrapper.getBoundingClientRect();const finalPos=pos.left+window.scrollX-wrapperPos.width+24;if(finalPos>0){wrapper.style.left=finalPos+"px"}else{wrapper.style.setProperty("--popover-arrow-offset",(wrapperPos.right-pos.right+4)+"px")}wrapper.style.visibility="";window.CURRENT_TOOLTIP_ELEMENT=wrapper;window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE=e;clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);wrapper.onpointerenter=function(ev){if(ev.pointerType!=="mouse"){return}clearTooltipHoverTimeout(e)};wrapper.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!e.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,e)){setTooltipHoverTimeout(e,false);addClass(wrapper,"fade-out")}}}function setTooltipHoverTimeout(element,show){clearTooltipHoverTimeout(element);if(!show&&!window.CURRENT_TOOLTIP_ELEMENT){return}if(show&&window.CURRENT_TOOLTIP_ELEMENT){return}if(window.CURRENT_TOOLTIP_ELEMENT&&window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE!==element){return}element.TOOLTIP_HOVER_TIMEOUT=setTimeout(()=>{if(show){showTooltip(element)}else if(!element.TOOLTIP_FORCE_VISIBLE){hideTooltip(false)}},show?window.RUSTDOC_TOOLTIP_HOVER_MS:window.RUSTDOC_TOOLTIP_HOVER_EXIT_MS)}function clearTooltipHoverTimeout(element){if(element.TOOLTIP_HOVER_TIMEOUT!==undefined){removeClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out");clearTimeout(element.TOOLTIP_HOVER_TIMEOUT);delete element.TOOLTIP_HOVER_TIMEOUT}}function tooltipBlurHandler(event){if(window.CURRENT_TOOLTIP_ELEMENT&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)&&!elemIsInParent(document.activeElement,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)&&!elemIsInParent(event.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE)){setTimeout(()=>hideTooltip(false),0)}}function hideTooltip(focus){if(window.CURRENT_TOOLTIP_ELEMENT){if(window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE){if(focus){window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.focus()}window.CURRENT_TOOLTIP_ELEMENT.TOOLTIP_BASE.TOOLTIP_FORCE_VISIBLE=false}const body=document.getElementsByTagName("body")[0];body.removeChild(window.CURRENT_TOOLTIP_ELEMENT);clearTooltipHoverTimeout(window.CURRENT_TOOLTIP_ELEMENT);window.CURRENT_TOOLTIP_ELEMENT=null}}onEachLazy(document.getElementsByClassName("tooltip"),e=>{e.onclick=function(){this.TOOLTIP_FORCE_VISIBLE=this.TOOLTIP_FORCE_VISIBLE?false:true;if(window.CURRENT_TOOLTIP_ELEMENT&&!this.TOOLTIP_FORCE_VISIBLE){hideTooltip(true)}else{showTooltip(this);window.CURRENT_TOOLTIP_ELEMENT.setAttribute("tabindex","0");window.CURRENT_TOOLTIP_ELEMENT.focus();window.CURRENT_TOOLTIP_ELEMENT.onblur=tooltipBlurHandler}return false};e.onpointerenter=function(ev){if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(this,true)};e.onpointermove=function(ev){if(ev.pointerType!=="mouse"){return}setTooltipHoverTimeout(this,true)};e.onpointerleave=function(ev){if(ev.pointerType!=="mouse"){return}if(!this.TOOLTIP_FORCE_VISIBLE&&!elemIsInParent(ev.relatedTarget,window.CURRENT_TOOLTIP_ELEMENT)){setTooltipHoverTimeout(e,false);addClass(window.CURRENT_TOOLTIP_ELEMENT,"fade-out")}}});const sidebar_menu_toggle=document.getElementsByClassName("sidebar-menu-toggle")[0];if(sidebar_menu_toggle){sidebar_menu_toggle.addEventListener("click",()=>{const sidebar=document.getElementsByClassName("sidebar")[0];if(!hasClass(sidebar,"shown")){showSidebar()}else{hideSidebar()}})}function helpBlurHandler(event){blurHandler(event,getHelpButton(),window.hidePopoverMenus)}function buildHelpMenu(){const book_info=document.createElement("span");const channel=getVar("channel");book_info.className="top";book_info.innerHTML=`You can find more information in \ +the rustdoc book.`;const shortcuts=[["?","Show this help dialog"],["S","Focus the search field"],["↑","Move up in search results"],["↓","Move down in search results"],["← / →","Switch result tab (when results focused)"],["⏎","Go to active search result"],["+","Expand all sections"],["-","Collapse all sections"],].map(x=>"
"+x[0].split(" ").map((y,index)=>((index&1)===0?""+y+"":" "+y+" ")).join("")+"
"+x[1]+"
").join("");const div_shortcuts=document.createElement("div");addClass(div_shortcuts,"shortcuts");div_shortcuts.innerHTML="

Keyboard Shortcuts

"+shortcuts+"
";const infos=[`For a full list of all search features, take a look here.`,"Prefix searches with a type followed by a colon (e.g., fn:) to \ + restrict the search to a given item kind.","Accepted kinds are: fn, mod, struct, \ + enum, trait, type, macro, \ + and const.","Search functions by type signature (e.g., vec -> usize or \ + -> vec or String, enum:Cow -> bool)","You can look for items with an exact name by putting double quotes around \ + your request: \"string\"","Look for functions that accept or return \ + slices and \ + arrays by writing \ + square brackets (e.g., -> [u8] or [] -> Option)","Look for items inside another one by searching for a path: vec::Vec",].map(x=>"

"+x+"

").join("");const div_infos=document.createElement("div");addClass(div_infos,"infos");div_infos.innerHTML="

Search Tricks

"+infos;const rustdoc_version=document.createElement("span");rustdoc_version.className="bottom";const rustdoc_version_code=document.createElement("code");rustdoc_version_code.innerText="rustdoc "+getVar("rustdoc-version");rustdoc_version.appendChild(rustdoc_version_code);const container=document.createElement("div");if(!isHelpPage){container.className="popover"}container.id="help";container.style.display="none";const side_by_side=document.createElement("div");side_by_side.className="side-by-side";side_by_side.appendChild(div_shortcuts);side_by_side.appendChild(div_infos);container.appendChild(book_info);container.appendChild(side_by_side);container.appendChild(rustdoc_version);if(isHelpPage){const help_section=document.createElement("section");help_section.appendChild(container);document.getElementById("main-content").appendChild(help_section);container.style.display="block"}else{const help_button=getHelpButton();help_button.appendChild(container);container.onblur=helpBlurHandler;help_button.onblur=helpBlurHandler;help_button.children[0].onblur=helpBlurHandler}return container}window.hideAllModals=function(switchFocus){hideSidebar();window.hidePopoverMenus();hideTooltip(switchFocus)};window.hidePopoverMenus=function(){onEachLazy(document.querySelectorAll(".search-form .popover"),elem=>{elem.style.display="none"})};function getHelpMenu(buildNeeded){let menu=getHelpButton().querySelector(".popover");if(!menu&&buildNeeded){menu=buildHelpMenu()}return menu}function showHelp(){getHelpButton().querySelector("a").focus();const menu=getHelpMenu(true);if(menu.style.display==="none"){window.hideAllModals();menu.style.display=""}}if(isHelpPage){showHelp();document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault()})}else{document.querySelector(`#${HELP_BUTTON_ID} > a`).addEventListener("click",event=>{const target=event.target;if(target.tagName!=="A"||target.parentElement.id!==HELP_BUTTON_ID||event.ctrlKey||event.altKey||event.metaKey){return}event.preventDefault();const menu=getHelpMenu(true);const shouldShowHelp=menu.style.display==="none";if(shouldShowHelp){showHelp()}else{window.hidePopoverMenus()}})}setMobileTopbar();addSidebarItems();addSidebarCrates();onHashChange(null);window.addEventListener("hashchange",onHashChange);searchState.setup()}());(function(){let reset_button_timeout=null;const but=document.getElementById("copy-path");if(!but){return}but.onclick=()=>{const parent=but.parentElement;const path=[];onEach(parent.childNodes,child=>{if(child.tagName==="A"){path.push(child.textContent)}});const el=document.createElement("textarea");el.value=path.join("::");el.setAttribute("readonly","");el.style.position="absolute";el.style.left="-9999px";document.body.appendChild(el);el.select();document.execCommand("copy");document.body.removeChild(el);but.children[0].style.display="none";let tmp;if(but.childNodes.length<2){tmp=document.createTextNode("✓");but.appendChild(tmp)}else{onEachLazy(but.childNodes,e=>{if(e.nodeType===Node.TEXT_NODE){tmp=e;return true}});tmp.textContent="✓"}if(reset_button_timeout!==null){window.clearTimeout(reset_button_timeout)}function reset_button(){tmp.textContent="";reset_button_timeout=null;but.children[0].style.display=""}reset_button_timeout=window.setTimeout(reset_button,1000)}}()) \ No newline at end of file diff --git a/docs/static.files/normalize-76eba96aa4d2e634.css b/docs/static.files/normalize-76eba96aa4d2e634.css new file mode 100644 index 000000000..469959f13 --- /dev/null +++ b/docs/static.files/normalize-76eba96aa4d2e634.css @@ -0,0 +1,2 @@ + /*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */ +html{line-height:1.15;-webkit-text-size-adjust:100%}body{margin:0}main{display:block}h1{font-size:2em;margin:0.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-0.25em}sup{top:-0.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type="button"],[type="reset"],[type="submit"],button{-webkit-appearance:button}[type="button"]::-moz-focus-inner,[type="reset"]::-moz-focus-inner,[type="submit"]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type="button"]:-moz-focusring,[type="reset"]:-moz-focusring,[type="submit"]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:0.35em 0.75em 0.625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type="checkbox"],[type="radio"]{box-sizing:border-box;padding:0}[type="number"]::-webkit-inner-spin-button,[type="number"]::-webkit-outer-spin-button{height:auto}[type="search"]{-webkit-appearance:textfield;outline-offset:-2px}[type="search"]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}template{display:none}[hidden]{display:none} \ No newline at end of file diff --git a/docs/static.files/noscript-cffde32267a19fd6.css b/docs/static.files/noscript-cffde32267a19fd6.css new file mode 100644 index 000000000..12d3f6dd5 --- /dev/null +++ b/docs/static.files/noscript-cffde32267a19fd6.css @@ -0,0 +1 @@ + #main-content .attributes{margin-left:0 !important;}#copy-path{display:none;}nav.sub{display:none;}.src .sidebar{display:none;}.notable-traits{display:none;} \ No newline at end of file diff --git a/docs/static.files/rust-logo-151179464ae7ed46.svg b/docs/static.files/rust-logo-151179464ae7ed46.svg new file mode 100644 index 000000000..62424d8ff --- /dev/null +++ b/docs/static.files/rust-logo-151179464ae7ed46.svg @@ -0,0 +1,61 @@ + + + diff --git a/docs/static.files/rustdoc-cb6f1f67f1bcd037.css b/docs/static.files/rustdoc-cb6f1f67f1bcd037.css new file mode 100644 index 000000000..ac787240c --- /dev/null +++ b/docs/static.files/rustdoc-cb6f1f67f1bcd037.css @@ -0,0 +1,8 @@ + :root{--nav-sub-mobile-padding:8px;--search-typename-width:6.75rem;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:400;src:local('Fira Sans'),url("FiraSans-Regular-018c141bf0843ffd.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Fira Sans';font-style:normal;font-weight:500;src:local('Fira Sans Medium'),url("FiraSans-Medium-8f9a781e4970d388.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:400;src:local('Source Serif 4'),url("SourceSerif4-Regular-46f98efaafac5295.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:italic;font-weight:400;src:local('Source Serif 4 Italic'),url("SourceSerif4-It-acdfaf1a8af734b1.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Serif 4';font-style:normal;font-weight:700;src:local('Source Serif 4 Bold'),url("SourceSerif4-Bold-a2c9cd1067f8b328.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:400;src:url("SourceCodePro-Regular-562dcc5011b6de7d.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:italic;font-weight:400;src:url("SourceCodePro-It-1cc31594bf4f1f79.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'Source Code Pro';font-style:normal;font-weight:600;src:url("SourceCodePro-Semibold-d899c5a5c4aeb14a.ttf.woff2") format("woff2");font-display:swap;}@font-face {font-family:'NanumBarunGothic';src:url("NanumBarunGothic-0f09457c7a19b7c6.ttf.woff2") format("woff2");font-display:swap;unicode-range:U+AC00-D7AF,U+1100-11FF,U+3130-318F,U+A960-A97F,U+D7B0-D7FF;}*{box-sizing:border-box;}body{font:1rem/1.5 "Source Serif 4",NanumBarunGothic,serif;margin:0;position:relative;overflow-wrap:break-word;overflow-wrap:anywhere;font-feature-settings:"kern","liga";background-color:var(--main-background-color);color:var(--main-color);}h1{font-size:1.5rem;}h2{font-size:1.375rem;}h3{font-size:1.25rem;}h1,h2,h3,h4,h5,h6{font-weight:500;}h1,h2,h3,h4{margin:25px 0 15px 0;padding-bottom:6px;}.docblock h3,.docblock h4,h5,h6{margin:15px 0 5px 0;}.docblock>h2:first-child,.docblock>h3:first-child,.docblock>h4:first-child,.docblock>h5:first-child,.docblock>h6:first-child{margin-top:0;}.main-heading h1{margin:0;padding:0;flex-grow:1;overflow-wrap:break-word;overflow-wrap:anywhere;}.main-heading{display:flex;flex-wrap:wrap;padding-bottom:6px;margin-bottom:15px;}.content h2,.top-doc .docblock>h3,.top-doc .docblock>h4{border-bottom:1px solid var(--headings-border-bottom-color);}h1,h2{line-height:1.25;padding-top:3px;padding-bottom:9px;}h3.code-header{font-size:1.125rem;}h4.code-header{font-size:1rem;}.code-header{font-weight:600;margin:0;padding:0;white-space:pre-wrap;}#crate-search,h1,h2,h3,h4,h5,h6,.sidebar,.mobile-topbar,.search-input,.search-results .result-name,.item-name>a,.out-of-band,span.since,a.src,#help-button>a,summary.hideme,.scraped-example-list,ul.all-items{font-family:"Fira Sans",Arial,NanumBarunGothic,sans-serif;}#toggle-all-docs,a.anchor,.small-section-header a,#src-sidebar a,.rust a,.sidebar h2 a,.sidebar h3 a,.mobile-topbar h2 a,h1 a,.search-results a,.stab,.result-name i{color:var(--main-color);}span.enum,a.enum,span.struct,a.struct,span.union,a.union,span.primitive,a.primitive,span.type,a.type,span.foreigntype,a.foreigntype{color:var(--type-link-color);}span.trait,a.trait,span.traitalias,a.traitalias{color:var(--trait-link-color);}span.associatedtype,a.associatedtype,span.constant,a.constant,span.static,a.static{color:var(--assoc-item-link-color);}span.fn,a.fn,span.method,a.method,span.tymethod,a.tymethod{color:var(--function-link-color);}span.attr,a.attr,span.derive,a.derive,span.macro,a.macro{color:var(--macro-link-color);}span.mod,a.mod{color:var(--mod-link-color);}span.keyword,a.keyword{color:var(--keyword-link-color);}a{color:var(--link-color);text-decoration:none;}ol,ul{padding-left:24px;}ul ul,ol ul,ul ol,ol ol{margin-bottom:.625em;}p{margin:0 0 .75em 0;}p:last-child{margin:0;}button{padding:1px 6px;cursor:pointer;}button#toggle-all-docs{padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.rustdoc{display:flex;flex-direction:row;flex-wrap:nowrap;}main{position:relative;flex-grow:1;padding:10px 15px 40px 45px;min-width:0;}.src main{padding:15px;}.width-limiter{max-width:960px;margin-right:auto;}details:not(.toggle) summary{margin-bottom:.6em;}code,pre,a.test-arrow,.code-header{font-family:"Source Code Pro",monospace;}.docblock code,.docblock-short code{border-radius:3px;padding:0 0.125em;}.docblock pre code,.docblock-short pre code{padding:0;}pre{padding:14px;line-height:1.5;}pre.item-decl{overflow-x:auto;}.item-decl .type-contents-toggle{contain:initial;}.src .content pre{padding:20px;}.rustdoc.src .example-wrap pre.src-line-numbers{padding:20px 0 20px 4px;}img{max-width:100%;}.sub-logo-container,.logo-container{line-height:0;display:block;}.sub-logo-container{margin-right:32px;}.sub-logo-container>img{height:60px;width:60px;object-fit:contain;}.rust-logo{filter:var(--rust-logo-filter);}.sidebar{font-size:0.875rem;flex:0 0 200px;overflow-y:scroll;overscroll-behavior:contain;position:sticky;height:100vh;top:0;left:0;}.rustdoc.src .sidebar{flex-basis:50px;border-right:1px solid;overflow-x:hidden;overflow-y:hidden;z-index:1;}.sidebar,.mobile-topbar,.sidebar-menu-toggle,#src-sidebar-toggle,#src-sidebar{background-color:var(--sidebar-background-color);}#src-sidebar-toggle>button:hover,#src-sidebar-toggle>button:focus{background-color:var(--sidebar-background-color-hover);}.src .sidebar>*:not(#src-sidebar-toggle){visibility:hidden;}.src-sidebar-expanded .src .sidebar{overflow-y:auto;flex-basis:300px;}.src-sidebar-expanded .src .sidebar>*:not(#src-sidebar-toggle){visibility:visible;}#all-types{margin-top:1em;}*{scrollbar-width:initial;scrollbar-color:var(--scrollbar-color);}.sidebar{scrollbar-width:thin;scrollbar-color:var(--scrollbar-color);}::-webkit-scrollbar{width:12px;}.sidebar::-webkit-scrollbar{width:8px;}::-webkit-scrollbar-track{-webkit-box-shadow:inset 0;background-color:var(--scrollbar-track-background-color);}.sidebar::-webkit-scrollbar-track{background-color:var(--scrollbar-track-background-color);}::-webkit-scrollbar-thumb,.sidebar::-webkit-scrollbar-thumb{background-color:var(--scrollbar-thumb-background-color);}.hidden{display:none !important;}.sidebar .logo-container{margin-top:10px;margin-bottom:10px;text-align:center;}.version{overflow-wrap:break-word;}.logo-container>img{height:100px;width:100px;}ul.block,.block li{padding:0;margin:0;list-style:none;}.sidebar-elems a,.sidebar>h2 a{display:block;padding:0.25rem;margin-left:-0.25rem;}.sidebar h2{overflow-wrap:anywhere;padding:0;margin:0.7rem 0;}.sidebar h3{font-size:1.125rem;padding:0;margin:0;}.sidebar-elems,.sidebar>h2{padding-left:24px;}.sidebar a{color:var(--sidebar-link-color);}.sidebar .current,.sidebar a:hover:not(.logo-container){background-color:var(--sidebar-current-link-background-color);}.sidebar-elems .block{margin-bottom:2em;}.sidebar-elems .block li a{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;}.mobile-topbar{display:none;}.rustdoc .example-wrap{display:flex;position:relative;margin-bottom:10px;}.rustdoc .example-wrap:last-child{margin-bottom:0px;}.rustdoc .example-wrap pre{margin:0;flex-grow:1;}.rustdoc:not(.src) .example-wrap pre{overflow:auto hidden;}.rustdoc .example-wrap pre.example-line-numbers,.rustdoc .example-wrap pre.src-line-numbers{flex-grow:0;min-width:fit-content;overflow:initial;text-align:right;-webkit-user-select:none;user-select:none;padding:14px 8px;color:var(--src-line-numbers-span-color);}.rustdoc .example-wrap pre.src-line-numbers{padding:14px 0;}.src-line-numbers a,.src-line-numbers span{color:var(--src-line-numbers-span-color);padding:0 8px;}.src-line-numbers :target{background-color:transparent;border-right:none;padding:0 8px;}.src-line-numbers .line-highlighted{background-color:var(--src-line-number-highlighted-background-color);}.search-loading{text-align:center;}.docblock-short{overflow-wrap:break-word;overflow-wrap:anywhere;}.docblock :not(pre)>code,.docblock-short code{white-space:pre-wrap;}.top-doc .docblock h2{font-size:1.375rem;}.top-doc .docblock h3{font-size:1.25rem;}.top-doc .docblock h4,.top-doc .docblock h5{font-size:1.125rem;}.top-doc .docblock h6{font-size:1rem;}.docblock h5{font-size:1rem;}.docblock h6{font-size:0.875rem;}.docblock{margin-left:24px;position:relative;}.docblock>:not(.more-examples-toggle):not(.example-wrap){max-width:100%;overflow-x:auto;}.out-of-band{flex-grow:0;font-size:1.125rem;}.docblock code,.docblock-short code,pre,.rustdoc.src .example-wrap{background-color:var(--code-block-background-color);}#main-content{position:relative;}.docblock table{margin:.5em 0;border-collapse:collapse;}.docblock table td,.docblock table th{padding:.5em;border:1px solid var(--border-color);}.docblock table tbody tr:nth-child(2n){background:var(--table-alt-row-background-color);}.method .where,.fn .where,.where.fmt-newline{display:block;white-space:pre-wrap;font-size:0.875rem;}.item-info{display:block;margin-left:24px;}.item-info code{font-size:0.875rem;}#main-content>.item-info{margin-left:0;}nav.sub{flex-grow:1;flex-flow:row nowrap;margin:4px 0 25px 0;display:flex;align-items:center;}.search-form{position:relative;display:flex;height:34px;flex-grow:1;}.src nav.sub{margin:0 0 15px 0;}.small-section-header{display:block;position:relative;}.small-section-header:hover>.anchor,.impl:hover>.anchor,.trait-impl:hover>.anchor,.variant:hover>.anchor{display:initial;}.anchor{display:none;position:absolute;left:-0.5em;background:none !important;}.anchor.field{left:-5px;}.small-section-header>.anchor{left:-15px;padding-right:8px;}h2.small-section-header>.anchor{padding-right:6px;}.main-heading a:hover,.example-wrap .rust a:hover,.all-items a:hover,.docblock a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.docblock-short a:not(.test-arrow):not(.scrape-help):not(.tooltip):hover,.item-info a{text-decoration:underline;}.crate.block a.current{font-weight:500;}table,.item-table{overflow-wrap:break-word;}.item-table{display:table;padding:0;margin:0;}.item-table>li{display:table-row;}.item-table>li>div{display:table-cell;}.item-table>li>.item-name{padding-right:1.25rem;}.search-results-title{margin-top:0;white-space:nowrap;display:flex;align-items:baseline;}#crate-search-div{position:relative;min-width:5em;}#crate-search{min-width:115px;padding:0 23px 0 4px;max-width:100%;text-overflow:ellipsis;border:1px solid var(--border-color);border-radius:4px;outline:none;cursor:pointer;-moz-appearance:none;-webkit-appearance:none;text-indent:0.01px;background-color:var(--main-background-color);color:inherit;line-height:1.5;font-weight:500;}#crate-search:hover,#crate-search:focus{border-color:var(--crate-search-hover-border);}#crate-search-div::after{pointer-events:none;width:100%;height:100%;position:absolute;top:0;left:0;content:"";background-repeat:no-repeat;background-size:20px;background-position:calc(100% - 2px) 56%;background-image:url('data:image/svg+xml, \ + ');filter:var(--crate-search-div-filter);}#crate-search-div:hover::after,#crate-search-div:focus-within::after{filter:var(--crate-search-div-hover-filter);}#crate-search>option{font-size:1rem;}.search-input{-webkit-appearance:none;outline:none;border:1px solid var(--border-color);border-radius:2px;padding:8px;font-size:1rem;flex-grow:1;background-color:var(--button-background-color);color:var(--search-color);}.search-input:focus{border-color:var(--search-input-focused-border-color);}.search-results{display:none;}.search-results.active{display:block;}.search-results>a{display:flex;margin-left:2px;margin-right:2px;border-bottom:1px solid var(--search-result-border-color);gap:1em;}.search-results>a>div.desc{white-space:nowrap;text-overflow:ellipsis;overflow:hidden;flex:2;}.search-results a:hover,.search-results a:focus{background-color:var(--search-result-link-focus-background-color);}.search-results .result-name{display:flex;align-items:center;justify-content:start;flex:3;}.search-results .result-name .alias{color:var(--search-results-alias-color);}.search-results .result-name .grey{color:var(--search-results-grey-color);}.search-results .result-name .typename{color:var(--search-results-grey-color);font-size:0.875rem;width:var(--search-typename-width);}.search-results .result-name .path{word-break:break-all;max-width:calc(100% - var(--search-typename-width));display:inline-block;}.search-results .result-name .path>*{display:inline;}.popover{position:absolute;top:100%;right:0;z-index:2;margin-top:7px;border-radius:3px;border:1px solid var(--border-color);background-color:var(--main-background-color);color:var(--main-color);--popover-arrow-offset:11px;}.popover::before{content:'';position:absolute;right:var(--popover-arrow-offset);border:solid var(--border-color);border-width:1px 1px 0 0;background-color:var(--main-background-color);padding:4px;transform:rotate(-45deg);top:-5px;}#help.popover{max-width:600px;--popover-arrow-offset:48px;}#help dt{float:left;clear:left;margin-right:0.5rem;}#help span.top,#help span.bottom{text-align:center;display:block;font-size:1.125rem;}#help span.top{margin:10px 0;border-bottom:1px solid var(--border-color);padding-bottom:4px;margin-bottom:6px;}#help span.bottom{clear:both;border-top:1px solid var(--border-color);}.side-by-side>div{width:50%;float:left;padding:0 20px 20px 17px;}.item-info .stab{min-height:36px;display:flex;padding:3px;margin-bottom:5px;align-items:center;vertical-align:text-bottom;}.item-name .stab{margin-left:0.3125em;}.stab{padding:0 2px;font-size:0.875rem;font-weight:normal;color:var(--main-color);background-color:var(--stab-background-color);width:fit-content;white-space:pre-wrap;border-radius:3px;display:inline;}.stab.portability>code{background:none;color:var(--stab-code-color);}.stab .emoji{font-size:1.25rem;margin-right:0.3rem;}.emoji{text-shadow:1px 0 0 black,-1px 0 0 black,0 1px 0 black,0 -1px 0 black;}.since{font-weight:normal;font-size:initial;}.rightside{padding-left:12px;float:right;}.rightside:not(a),.out-of-band{color:var(--right-side-color);}pre.rust{tab-size:4;-moz-tab-size:4;}pre.rust .kw{color:var(--code-highlight-kw-color);}pre.rust .kw-2{color:var(--code-highlight-kw-2-color);}pre.rust .lifetime{color:var(--code-highlight-lifetime-color);}pre.rust .prelude-ty{color:var(--code-highlight-prelude-color);}pre.rust .prelude-val{color:var(--code-highlight-prelude-val-color);}pre.rust .string{color:var(--code-highlight-string-color);}pre.rust .number{color:var(--code-highlight-number-color);}pre.rust .bool-val{color:var(--code-highlight-literal-color);}pre.rust .self{color:var(--code-highlight-self-color);}pre.rust .attr{color:var(--code-highlight-attribute-color);}pre.rust .macro,pre.rust .macro-nonterminal{color:var(--code-highlight-macro-color);}pre.rust .question-mark{font-weight:bold;color:var(--code-highlight-question-mark-color);}pre.rust .comment{color:var(--code-highlight-comment-color);}pre.rust .doccomment{color:var(--code-highlight-doc-comment-color);}.rustdoc.src .example-wrap pre.rust a{background:var(--codeblock-link-background);}.example-wrap.compile_fail,.example-wrap.should_panic{border-left:2px solid var(--codeblock-error-color);}.ignore.example-wrap{border-left:2px solid var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover,.example-wrap.should_panic:hover{border-left:2px solid var(--codeblock-error-hover-color);}.example-wrap.ignore:hover{border-left:2px solid var(--codeblock-ignore-hover-color);}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip{color:var(--codeblock-error-color);}.example-wrap.ignore .tooltip{color:var(--codeblock-ignore-color);}.example-wrap.compile_fail:hover .tooltip,.example-wrap.should_panic:hover .tooltip{color:var(--codeblock-error-hover-color);}.example-wrap.ignore:hover .tooltip{color:var(--codeblock-ignore-hover-color);}.example-wrap .tooltip{position:absolute;display:block;left:-25px;top:5px;margin:0;line-height:1;}.example-wrap.compile_fail .tooltip,.example-wrap.should_panic .tooltip,.example-wrap.ignore .tooltip{font-weight:bold;font-size:1.25rem;}a.test-arrow{visibility:hidden;position:absolute;padding:5px 10px 5px 10px;border-radius:5px;font-size:1.375rem;top:5px;right:5px;z-index:1;color:var(--test-arrow-color);background-color:var(--test-arrow-background-color);}a.test-arrow:hover{color:var(--test-arrow-hover-color);background-color:var(--test-arrow-hover-background-color);}.example-wrap:hover .test-arrow{visibility:visible;}.code-attribute{font-weight:300;color:var(--code-attribute-color);}.item-spacer{width:100%;height:12px;display:block;}.out-of-band>span.since{font-size:1.25rem;}.sub-variant h4{font-size:1rem;font-weight:400;margin-top:0;margin-bottom:0;}.sub-variant{margin-left:24px;margin-bottom:40px;}.sub-variant>.sub-variant-field{margin-left:24px;}:target{padding-right:3px;background-color:var(--target-background-color);border-right:3px solid var(--target-border-color);}.code-header a.tooltip{color:inherit;margin-right:15px;position:relative;}.code-header a.tooltip:hover{color:var(--link-color);}a.tooltip:hover::after{position:absolute;top:calc(100% - 10px);left:-15px;right:-15px;height:20px;content:"\00a0";}.fade-out{opacity:0;transition:opacity 0.45s cubic-bezier(0,0,0.1,1.0);}.popover.tooltip .content{margin:0.25em 0.5em;}.popover.tooltip .content pre,.popover.tooltip .content code{background:transparent;margin:0;padding:0;font-size:1.25rem;white-space:pre-wrap;}.popover.tooltip .content>h3:first-child{margin:0 0 5px 0;}.search-failed{text-align:center;margin-top:20px;display:none;}.search-failed.active{display:block;}.search-failed>ul{text-align:left;max-width:570px;margin-left:auto;margin-right:auto;}#search-tabs{display:flex;flex-direction:row;gap:1px;margin-bottom:4px;}#search-tabs button{text-align:center;font-size:1.125rem;border:0;border-top:2px solid;flex:1;line-height:1.5;color:inherit;}#search-tabs button:not(.selected){background-color:var(--search-tab-button-not-selected-background);border-top-color:var(--search-tab-button-not-selected-border-top-color);}#search-tabs button:hover,#search-tabs button.selected{background-color:var(--search-tab-button-selected-background);border-top-color:var(--search-tab-button-selected-border-top-color);}#search-tabs .count{font-size:1rem;color:var(--search-tab-title-count-color);}#search .error code{border-radius:3px;background-color:var(--search-error-code-background-color);}.search-corrections{font-weight:normal;}#src-sidebar-toggle{position:sticky;top:0;left:0;font-size:1.25rem;border-bottom:1px solid;display:flex;height:40px;justify-content:stretch;align-items:stretch;z-index:10;}#src-sidebar{width:100%;overflow:auto;}#src-sidebar>.title{font-size:1.5rem;text-align:center;border-bottom:1px solid var(--border-color);margin-bottom:6px;}#src-sidebar div.files>a:hover,details.dir-entry summary:hover,#src-sidebar div.files>a:focus,details.dir-entry summary:focus{background-color:var(--src-sidebar-background-hover);}#src-sidebar div.files>a.selected{background-color:var(--src-sidebar-background-selected);}#src-sidebar-toggle>button{font-size:inherit;font-weight:bold;background:none;color:inherit;text-align:center;border:none;outline:none;flex:1 1;-webkit-appearance:none;opacity:1;}#settings-menu,#help-button{margin-left:4px;display:flex;}#settings-menu>a,#help-button>a{display:flex;align-items:center;justify-content:center;background-color:var(--button-background-color);border:1px solid var(--border-color);border-radius:2px;color:var(--settings-button-color);font-size:20px;width:33px;}#settings-menu>a:hover,#settings-menu>a:focus,#help-button>a:hover,#help-button>a:focus{border-color:var(--settings-button-border-focus);}#copy-path{color:var(--copy-path-button-color);background:var(--main-background-color);height:34px;margin-left:10px;padding:0;padding-left:2px;border:0;width:33px;}#copy-path>img{filter:var(--copy-path-img-filter);}#copy-path:hover>img{filter:var(--copy-path-img-hover-filter);}@keyframes rotating{from{transform:rotate(0deg);}to{transform:rotate(360deg);}}#settings-menu.rotate>a img{animation:rotating 2s linear infinite;}kbd{display:inline-block;padding:3px 5px;font:15px monospace;line-height:10px;vertical-align:middle;border:solid 1px var(--border-color);border-radius:3px;color:var(--kbd-color);background-color:var(--kbd-background);box-shadow:inset 0 -1px 0 var(--kbd-box-shadow-color);}ul.all-items>li{list-style:none;}details.dir-entry{padding-left:4px;}details.dir-entry>summary{margin:0 0 0 -4px;padding:0 0 0 4px;cursor:pointer;}details.dir-entry div.folders,details.dir-entry div.files{padding-left:23px;}details.dir-entry a{display:block;}details.toggle{contain:layout;position:relative;}details.toggle>summary.hideme{cursor:pointer;font-size:1rem;}details.toggle>summary{list-style:none;outline:none;}details.toggle>summary::-webkit-details-marker,details.toggle>summary::marker{display:none;}details.toggle>summary.hideme>span{margin-left:9px;}details.toggle>summary::before{background:url('data:image/svg+xml,') no-repeat top left;content:"";cursor:pointer;width:16px;height:16px;display:inline-block;vertical-align:middle;opacity:.5;filter:var(--toggle-filter);}details.toggle>summary.hideme>span,.more-examples-toggle summary,.more-examples-toggle .hide-more{color:var(--toggles-color);}details.toggle>summary::after{content:"Expand";overflow:hidden;width:0;height:0;position:absolute;}details.toggle>summary.hideme::after{content:"";}details.toggle>summary:focus::before,details.toggle>summary:hover::before{opacity:1;}details.toggle>summary:focus-visible::before{outline:1px dotted #000;outline-offset:1px;}details.non-exhaustive{margin-bottom:8px;}details.toggle>summary.hideme::before{position:relative;}details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;top:4px;}.impl-items>details.toggle>summary:not(.hideme)::before{position:absolute;left:-24px;}details.toggle[open] >summary.hideme{position:absolute;}details.toggle[open] >summary.hideme>span{display:none;}details.toggle[open] >summary::before{background:url('data:image/svg+xml,') no-repeat top left;}details.toggle[open] >summary::after{content:"Collapse";}.docblock summary>*{display:inline-block;}.docblock>.example-wrap:first-child .tooltip{margin-top:16px;}@media (max-width:700px){*[id]{scroll-margin-top:45px;}.rustdoc{display:block;}main{padding-left:15px;padding-top:0px;}.main-heading{flex-direction:column;}.out-of-band{text-align:left;margin-left:initial;padding:initial;}.out-of-band .since::before{content:"Since ";}.sidebar .logo-container,.sidebar .location{display:none;}.sidebar{position:fixed;top:45px;left:-1000px;z-index:11;height:calc(100vh - 45px);width:200px;}.src main,.rustdoc.src .sidebar{top:0;padding:0;height:100vh;border:0;}.sidebar.shown,.src-sidebar-expanded .src .sidebar,.rustdoc:not(.src) .sidebar:focus-within{left:0;}.mobile-topbar h2{padding-bottom:0;margin:auto 0.5em auto auto;overflow:hidden;font-size:24px;}.mobile-topbar h2 a{display:block;text-overflow:ellipsis;overflow:hidden;white-space:nowrap;}.mobile-topbar .logo-container>img{max-width:35px;max-height:35px;margin:5px 0 5px 20px;}.mobile-topbar{display:flex;flex-direction:row;position:sticky;z-index:10;font-size:2rem;height:45px;width:100%;left:0;top:0;}.sidebar-menu-toggle{width:45px;font-size:32px;border:none;color:var(--main-color);}.sidebar-elems{margin-top:1em;}.anchor{display:none !important;}#search-tabs .count{display:block;}#main-content>details.toggle>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}#src-sidebar-toggle{position:fixed;left:1px;top:100px;width:30px;font-size:1.5rem;padding:0;z-index:10;border-top-right-radius:3px;border-bottom-right-radius:3px;border:1px solid;border-left:0;}.src-sidebar-expanded #src-sidebar-toggle{left:unset;top:unset;width:unset;border-top-right-radius:unset;border-bottom-right-radius:unset;position:sticky;border:0;border-bottom:1px solid;}#copy-path,#help-button{display:none;}.item-table,.item-row,.item-table>li,.item-table>li>div,.search-results>a,.search-results>a>div{display:block;}.search-results>a{padding:5px 0px;}.search-results>a>div.desc,.item-table>li>div.desc{padding-left:2em;}.search-results .result-name{display:block;}.search-results .result-name .typename{width:initial;margin-right:0;}.search-results .result-name .typename,.search-results .result-name .path{display:inline;}.src-sidebar-expanded .src .sidebar{max-width:100vw;width:100vw;}details.toggle:not(.top-doc)>summary{margin-left:10px;}.impl-items>details.toggle>summary:not(.hideme)::before,#main-content>details.toggle:not(.top-doc)>summary::before,#main-content>div>details.toggle>summary::before{left:-11px;}.impl-items>.item-info{margin-left:34px;}.src nav.sub{margin:0;padding:var(--nav-sub-mobile-padding);}}@media (min-width:701px){.scraped-example-title{position:absolute;z-index:10;background:var(--main-background-color);bottom:8px;right:5px;padding:2px 4px;box-shadow:0 0 4px var(--main-background-color);}}@media print{nav.sidebar,nav.sub,.out-of-band,a.src,#copy-path,details.toggle[open] >summary::before,details.toggle>summary::before,details.toggle.top-doc>summary{display:none;}.docblock{margin-left:0;}main{padding:10px;}}@media (max-width:464px){.docblock{margin-left:12px;}.docblock code{overflow-wrap:break-word;overflow-wrap:anywhere;}nav.sub{flex-direction:column;}.search-form{align-self:stretch;}.sub-logo-container>img{height:35px;width:35px;margin-bottom:var(--nav-sub-mobile-padding);}}.variant,.implementors-toggle>summary,.impl,#implementors-list>.docblock,.impl-items>section,.impl-items>.toggle>summary,.methods>section,.methods>.toggle>summary{margin-bottom:0.75em;}.variants>.docblock,.implementors-toggle>.docblock,.impl-items>.toggle[open]:not(:last-child),.methods>.toggle[open]:not(:last-child),.implementors-toggle[open]:not(:last-child){margin-bottom:2em;}#trait-implementations-list .impl-items>.toggle:not(:last-child),#synthetic-implementations-list .impl-items>.toggle:not(:last-child),#blanket-implementations-list .impl-items>.toggle:not(:last-child){margin-bottom:1em;}.scraped-example-list .scrape-help{margin-left:10px;padding:0 4px;font-weight:normal;font-size:12px;position:relative;bottom:1px;border:1px solid var(--scrape-example-help-border-color);border-radius:50px;color:var(--scrape-example-help-color);}.scraped-example-list .scrape-help:hover{border-color:var(--scrape-example-help-hover-border-color);color:var(--scrape-example-help-hover-color);}.scraped-example{position:relative;}.scraped-example .code-wrapper{position:relative;display:flex;flex-direction:row;flex-wrap:wrap;width:100%;}.scraped-example:not(.expanded) .code-wrapper{max-height:calc(1.5em * 5 + 10px);}.scraped-example:not(.expanded) .code-wrapper pre{overflow-y:hidden;padding-bottom:0;max-height:calc(1.5em * 5 + 10px);}.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper,.more-scraped-examples .scraped-example:not(.expanded) .code-wrapper pre{max-height:calc(1.5em * 10 + 10px);}.scraped-example .code-wrapper .next,.scraped-example .code-wrapper .prev,.scraped-example .code-wrapper .expand{color:var(--main-color);position:absolute;top:0.25em;z-index:1;padding:0;background:none;border:none;-webkit-appearance:none;opacity:1;}.scraped-example .code-wrapper .prev{right:2.25em;}.scraped-example .code-wrapper .next{right:1.25em;}.scraped-example .code-wrapper .expand{right:0.25em;}.scraped-example:not(.expanded) .code-wrapper::before,.scraped-example:not(.expanded) .code-wrapper::after{content:" ";width:100%;height:5px;position:absolute;z-index:1;}.scraped-example:not(.expanded) .code-wrapper::before{top:0;background:linear-gradient(to bottom,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example:not(.expanded) .code-wrapper::after{bottom:0;background:linear-gradient(to top,var(--scrape-example-code-wrapper-background-start),var(--scrape-example-code-wrapper-background-end));}.scraped-example .code-wrapper .example-wrap{width:100%;overflow-y:hidden;margin-bottom:0;}.scraped-example:not(.expanded) .code-wrapper .example-wrap{overflow-x:hidden;}.scraped-example .example-wrap .rust span.highlight{background:var(--scrape-example-code-line-highlight);}.scraped-example .example-wrap .rust span.highlight.focus{background:var(--scrape-example-code-line-highlight-focus);}.more-examples-toggle{max-width:calc(100% + 25px);margin-top:10px;margin-left:-25px;}.more-examples-toggle .hide-more{margin-left:25px;cursor:pointer;}.more-scraped-examples{margin-left:25px;position:relative;}.toggle-line{position:absolute;top:5px;bottom:0;right:calc(100% + 10px);padding:0 4px;cursor:pointer;}.toggle-line-inner{min-width:2px;height:100%;background:var(--scrape-example-toggle-line-background);}.toggle-line:hover .toggle-line-inner{background:var(--scrape-example-toggle-line-hover-background);}.more-scraped-examples .scraped-example,.example-links{margin-top:20px;}.more-scraped-examples .scraped-example:first-child{margin-top:5px;}.example-links ul{margin-bottom:0;} \ No newline at end of file diff --git a/docs/static.files/scrape-examples-ef1e698c1d417c0c.js b/docs/static.files/scrape-examples-ef1e698c1d417c0c.js new file mode 100644 index 000000000..ba830e374 --- /dev/null +++ b/docs/static.files/scrape-examples-ef1e698c1d417c0c.js @@ -0,0 +1 @@ +"use strict";(function(){const DEFAULT_MAX_LINES=5;const HIDDEN_MAX_LINES=10;function scrollToLoc(elt,loc,isHidden){const lines=elt.querySelector(".src-line-numbers");let scrollOffset;const maxLines=isHidden?HIDDEN_MAX_LINES:DEFAULT_MAX_LINES;if(loc[1]-loc[0]>maxLines){const line=Math.max(0,loc[0]-1);scrollOffset=lines.children[line].offsetTop}else{const wrapper=elt.querySelector(".code-wrapper");const halfHeight=wrapper.offsetHeight/2;const offsetTop=lines.children[loc[0]].offsetTop;const lastLine=lines.children[loc[1]];const offsetBot=lastLine.offsetTop+lastLine.offsetHeight;const offsetMid=(offsetTop+offsetBot)/2;scrollOffset=offsetMid-halfHeight}lines.scrollTo(0,scrollOffset);elt.querySelector(".rust").scrollTo(0,scrollOffset)}function updateScrapedExample(example,isHidden){const locs=JSON.parse(example.attributes.getNamedItem("data-locs").textContent);let locIndex=0;const highlights=Array.prototype.slice.call(example.querySelectorAll(".highlight"));const link=example.querySelector(".scraped-example-title a");if(locs.length>1){const onChangeLoc=changeIndex=>{removeClass(highlights[locIndex],"focus");changeIndex();scrollToLoc(example,locs[locIndex][0],isHidden);addClass(highlights[locIndex],"focus");const url=locs[locIndex][1];const title=locs[locIndex][2];link.href=url;link.innerHTML=title};example.querySelector(".prev").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex-1+locs.length)%locs.length})});example.querySelector(".next").addEventListener("click",()=>{onChangeLoc(()=>{locIndex=(locIndex+1)%locs.length})})}const expandButton=example.querySelector(".expand");if(expandButton){expandButton.addEventListener("click",()=>{if(hasClass(example,"expanded")){removeClass(example,"expanded");scrollToLoc(example,locs[0][0],isHidden)}else{addClass(example,"expanded")}})}scrollToLoc(example,locs[0][0],isHidden)}const firstExamples=document.querySelectorAll(".scraped-example-list > .scraped-example");onEachLazy(firstExamples,el=>updateScrapedExample(el,false));onEachLazy(document.querySelectorAll(".more-examples-toggle"),toggle=>{onEachLazy(toggle.querySelectorAll(".toggle-line, .hide-more"),button=>{button.addEventListener("click",()=>{toggle.open=false})});const moreExamples=toggle.querySelectorAll(".scraped-example");toggle.querySelector("summary").addEventListener("click",()=>{setTimeout(()=>{onEachLazy(moreExamples,el=>updateScrapedExample(el,true))})},{once:true})})})() \ No newline at end of file diff --git a/docs/static.files/search-6dfdfced5eff6596.js b/docs/static.files/search-6dfdfced5eff6596.js new file mode 100644 index 000000000..90d0eb753 --- /dev/null +++ b/docs/static.files/search-6dfdfced5eff6596.js @@ -0,0 +1,5 @@ +"use strict";(function(){const itemTypes=["mod","externcrate","import","struct","enum","fn","type","static","trait","impl","tymethod","method","structfield","variant","macro","primitive","associatedtype","constant","associatedconstant","union","foreigntype","keyword","existential","attr","derive","traitalias",];const longItemTypes=["module","extern crate","re-export","struct","enum","function","type alias","static","trait","","trait method","method","struct field","enum variant","macro","primitive type","assoc type","constant","assoc const","union","foreign type","keyword","existential type","attribute macro","derive macro","trait alias",];const TY_PRIMITIVE=itemTypes.indexOf("primitive");const TY_KEYWORD=itemTypes.indexOf("keyword");const ROOT_PATH=typeof window!=="undefined"?window.rootPath:"../";function hasOwnPropertyRustdoc(obj,property){return Object.prototype.hasOwnProperty.call(obj,property)}function printTab(nb){let iter=0;let foundCurrentTab=false;let foundCurrentResultSet=false;onEachLazy(document.getElementById("search-tabs").childNodes,elem=>{if(nb===iter){addClass(elem,"selected");foundCurrentTab=true}else{removeClass(elem,"selected")}iter+=1});const isTypeSearch=(nb>0||iter===1);iter=0;onEachLazy(document.getElementById("results").childNodes,elem=>{if(nb===iter){addClass(elem,"active");foundCurrentResultSet=true}else{removeClass(elem,"active")}iter+=1});if(foundCurrentTab&&foundCurrentResultSet){searchState.currentTab=nb;const correctionsElem=document.getElementsByClassName("search-corrections");if(isTypeSearch){removeClass(correctionsElem[0],"hidden")}else{addClass(correctionsElem[0],"hidden")}}else if(nb!==0){printTab(0)}}const editDistanceState={current:[],prev:[],prevPrev:[],calculate:function calculate(a,b,limit){if(a.lengthlimit){return limit+1}while(b.length>0&&b[0]===a[0]){a=a.substring(1);b=b.substring(1)}while(b.length>0&&b[b.length-1]===a[a.length-1]){a=a.substring(0,a.length-1);b=b.substring(0,b.length-1)}if(b.length===0){return minDist}const aLength=a.length;const bLength=b.length;for(let i=0;i<=bLength;++i){this.current[i]=0;this.prev[i]=i;this.prevPrev[i]=Number.MAX_VALUE}for(let i=1;i<=aLength;++i){this.current[0]=i;const aIdx=i-1;for(let j=1;j<=bLength;++j){const bIdx=j-1;const substitutionCost=a[aIdx]===b[bIdx]?0:1;this.current[j]=Math.min(this.prev[j]+1,this.current[j-1]+1,this.prev[j-1]+substitutionCost);if((i>1)&&(j>1)&&(a[aIdx]===b[bIdx-1])&&(a[aIdx-1]===b[bIdx])){this.current[j]=Math.min(this.current[j],this.prevPrev[j-2]+1)}}const prevPrevTmp=this.prevPrev;this.prevPrev=this.prev;this.prev=this.current;this.current=prevPrevTmp}const distance=this.prev[bLength];return distance<=limit?distance:(limit+1)},};function editDistance(a,b,limit){return editDistanceState.calculate(a,b,limit)}function initSearch(rawSearchIndex){const MAX_RESULTS=200;const NO_TYPE_FILTER=-1;let searchIndex;let currentResults;let typeNameIdMap;const ALIASES=new Map();let typeNameIdOfArray;let typeNameIdOfSlice;let typeNameIdOfArrayOrSlice;function buildTypeMapIndex(name){if(name===""||name===null){return-1}if(typeNameIdMap.has(name)){return typeNameIdMap.get(name)}else{const id=typeNameIdMap.size;typeNameIdMap.set(name,id);return id}}function isWhitespace(c){return" \t\n\r".indexOf(c)!==-1}function isSpecialStartCharacter(c){return"<\"".indexOf(c)!==-1}function isEndCharacter(c){return",>-]".indexOf(c)!==-1}function isStopCharacter(c){return isEndCharacter(c)}function isErrorCharacter(c){return"()".indexOf(c)!==-1}function itemTypeFromName(typename){const index=itemTypes.findIndex(i=>i===typename);if(index<0){throw["Unknown type filter ",typename]}return index}function getStringElem(query,parserState,isInGenerics){if(isInGenerics){throw["Unexpected ","\""," in generics"]}else if(query.literalSearch){throw["Cannot have more than one literal search element"]}else if(parserState.totalElems-parserState.genericsElems>0){throw["Cannot use literal search when there is more than one element"]}parserState.pos+=1;const start=parserState.pos;const end=getIdentEndPosition(parserState);if(parserState.pos>=parserState.length){throw["Unclosed ","\""]}else if(parserState.userQuery[end]!=="\""){throw["Unexpected ",parserState.userQuery[end]," in a string element"]}else if(start===end){throw["Cannot have empty string element"]}parserState.pos+=1;query.literalSearch=true}function isPathStart(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="::"}function isReturnArrow(parserState){return parserState.userQuery.slice(parserState.pos,parserState.pos+2)==="->"}function isIdentCharacter(c){return(c==="_"||(c>="0"&&c<="9")||(c>="a"&&c<="z")||(c>="A"&&c<="Z"))}function isSeparatorCharacter(c){return c===","}function isPathSeparator(c){return c===":"||isWhitespace(c)}function prevIs(parserState,lookingFor){let pos=parserState.pos;while(pos>0){const c=parserState.userQuery[pos-1];if(c===lookingFor){return true}else if(!isWhitespace(c)){break}pos-=1}return false}function isLastElemGeneric(elems,parserState){return(elems.length>0&&elems[elems.length-1].generics.length>0)||prevIs(parserState,">")}function skipWhitespace(parserState){while(parserState.pos0){throw["Cannot have more than one element if you use quotes"]}const typeFilter=parserState.typeFilter;parserState.typeFilter=null;if(name==="!"){if(typeFilter!==null&&typeFilter!=="primitive"){throw["Invalid search type: primitive never type ","!"," and ",typeFilter," both specified",]}if(generics.length!==0){throw["Never type ","!"," does not accept generic parameters",]}return{name:"never",id:-1,fullPath:["never"],pathWithoutLast:[],pathLast:"never",generics:[],typeFilter:"primitive",}}if(path.startsWith("::")){throw["Paths cannot start with ","::"]}else if(path.endsWith("::")){throw["Paths cannot end with ","::"]}else if(path.includes("::::")){throw["Unexpected ","::::"]}else if(path.includes(" ::")){throw["Unexpected "," ::"]}else if(path.includes(":: ")){throw["Unexpected ",":: "]}const pathSegments=path.split(/::|\s+/);if(pathSegments.length===0||(pathSegments.length===1&&pathSegments[0]==="")){if(generics.length>0||prevIs(parserState,">")){throw["Found generics without a path"]}else{throw["Unexpected ",parserState.userQuery[parserState.pos]]}}for(const[i,pathSegment]of pathSegments.entries()){if(pathSegment==="!"){if(i!==0){throw["Never type ","!"," is not associated item"]}pathSegments[i]="never"}}parserState.totalElems+=1;if(isInGenerics){parserState.genericsElems+=1}return{name:name.trim(),id:-1,fullPath:pathSegments,pathWithoutLast:pathSegments.slice(0,pathSegments.length-1),pathLast:pathSegments[pathSegments.length-1],generics:generics,typeFilter,}}function getIdentEndPosition(parserState){const start=parserState.pos;let end=parserState.pos;let foundExclamation=-1;while(parserState.pos=end){throw["Found generics without a path"]}parserState.pos+=1;getItemsBefore(query,parserState,generics,">")}if(isStringElem){skipWhitespace(parserState)}if(start>=end&&generics.length===0){return}elems.push(createQueryElement(query,parserState,parserState.userQuery.slice(start,end),generics,isInGenerics))}}function getItemsBefore(query,parserState,elems,endChar){let foundStopChar=true;let start=parserState.pos;const oldTypeFilter=parserState.typeFilter;parserState.typeFilter=null;let extra="";if(endChar===">"){extra="<"}else if(endChar==="]"){extra="["}else if(endChar===""){extra="->"}else{extra=endChar}while(parserState.pos"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(endChar!==""){throw["Expected ",","," or ",endChar,...extra,", found ",c,]}throw["Expected ",",",...extra,", found ",c,]}const posBefore=parserState.pos;start=parserState.pos;getNextElem(query,parserState,elems,endChar!=="");if(endChar!==""&&parserState.pos>=parserState.length){throw["Unclosed ",extra]}if(posBefore===parserState.pos){parserState.pos+=1}foundStopChar=false}if(parserState.pos>=parserState.length&&endChar!==""){throw["Unclosed ",extra]}parserState.pos+=1;parserState.typeFilter=oldTypeFilter}function checkExtraTypeFilterCharacters(start,parserState){const query=parserState.userQuery.slice(start,parserState.pos).trim();for(const c in query){if(!isIdentCharacter(query[c])){throw["Unexpected ",query[c]," in type filter (before ",":",")",]}}}function parseInput(query,parserState){let foundStopChar=true;let start=parserState.pos;while(parserState.pos"){if(isReturnArrow(parserState)){break}throw["Unexpected ",c," (did you mean ","->","?)"]}throw["Unexpected ",c]}else if(c===":"&&!isPathStart(parserState)){if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}else if(query.elems.length===0){throw["Expected type filter before ",":"]}else if(query.literalSearch){throw["Cannot use quotes on type filter"]}const typeFilterElem=query.elems.pop();checkExtraTypeFilterCharacters(start,parserState);parserState.typeFilter=typeFilterElem.name;parserState.pos+=1;parserState.totalElems-=1;query.literalSearch=false;foundStopChar=true;continue}else if(isWhitespace(c)){skipWhitespace(parserState);continue}if(!foundStopChar){let extra="";if(isLastElemGeneric(query.elems,parserState)){extra=[" after ",">"]}else if(prevIs(parserState,"\"")){throw["Cannot have more than one element if you use quotes"]}if(parserState.typeFilter!==null){throw["Expected ",","," or ","->",...extra,", found ",c,]}throw["Expected ",",",", ",":"," or ","->",...extra,", found ",c,]}const before=query.elems.length;start=parserState.pos;getNextElem(query,parserState,query.elems,false);if(query.elems.length===before){parserState.pos+=1}foundStopChar=false}if(parserState.typeFilter!==null){throw["Unexpected ",":"," (expected path after type filter ",parserState.typeFilter+":",")",]}while(parserState.pos"]}break}else{parserState.pos+=1}}}function newParsedQuery(userQuery){return{original:userQuery,userQuery:userQuery.toLowerCase(),elems:[],returned:[],foundElems:0,literalSearch:false,error:null,correction:null,}}function buildUrl(search,filterCrates){let extra="?search="+encodeURIComponent(search);if(filterCrates!==null){extra+="&filter-crate="+encodeURIComponent(filterCrates)}return getNakedUrl()+extra+window.location.hash}function getFilterCrates(){const elem=document.getElementById("crate-search");if(elem&&elem.value!=="all crates"&&hasOwnPropertyRustdoc(rawSearchIndex,elem.value)){return elem.value}return null}function parseQuery(userQuery){function convertTypeFilterOnElem(elem){if(elem.typeFilter!==null){let typeFilter=elem.typeFilter;if(typeFilter==="const"){typeFilter="constant"}elem.typeFilter=itemTypeFromName(typeFilter)}else{elem.typeFilter=NO_TYPE_FILTER}for(const elem2 of elem.generics){convertTypeFilterOnElem(elem2)}}userQuery=userQuery.trim();const parserState={length:userQuery.length,pos:0,totalElems:0,genericsElems:0,typeFilter:null,userQuery:userQuery.toLowerCase(),};let query=newParsedQuery(userQuery);try{parseInput(query,parserState);for(const elem of query.elems){convertTypeFilterOnElem(elem)}for(const elem of query.returned){convertTypeFilterOnElem(elem)}}catch(err){query=newParsedQuery(userQuery);query.error=err;return query}if(!query.literalSearch){query.literalSearch=parserState.totalElems>1}query.foundElems=query.elems.length+query.returned.length;return query}function createQueryResults(results_in_args,results_returned,results_others,parsedQuery){return{"in_args":results_in_args,"returned":results_returned,"others":results_others,"query":parsedQuery,}}function execQuery(parsedQuery,searchWords,filterCrates,currentCrate){const results_others=new Map(),results_in_args=new Map(),results_returned=new Map();function transformResults(results){const duplicates=new Set();const out=[];for(const result of results){if(result.id>-1){const obj=searchIndex[result.id];obj.dist=result.dist;const res=buildHrefAndPath(obj);obj.displayPath=pathSplitter(res[0]);obj.fullPath=obj.displayPath+obj.name;obj.fullPath+="|"+obj.ty;if(duplicates.has(obj.fullPath)){continue}duplicates.add(obj.fullPath);obj.href=res[1];out.push(obj);if(out.length>=MAX_RESULTS){break}}}return out}function sortResults(results,isType,preferredCrate){if(results.size===0){return[]}const userQuery=parsedQuery.userQuery;const result_list=[];for(const result of results.values()){result.word=searchWords[result.id];result.item=searchIndex[result.id]||{};result_list.push(result)}result_list.sort((aaa,bbb)=>{let a,b;a=(aaa.word!==userQuery);b=(bbb.word!==userQuery);if(a!==b){return a-b}a=(aaa.index<0);b=(bbb.index<0);if(a!==b){return a-b}a=aaa.path_dist;b=bbb.path_dist;if(a!==b){return a-b}a=aaa.index;b=bbb.index;if(a!==b){return a-b}a=(aaa.dist);b=(bbb.dist);if(a!==b){return a-b}a=aaa.item.deprecated;b=bbb.item.deprecated;if(a!==b){return a-b}a=(aaa.item.crate!==preferredCrate);b=(bbb.item.crate!==preferredCrate);if(a!==b){return a-b}a=aaa.word.length;b=bbb.word.length;if(a!==b){return a-b}a=aaa.word;b=bbb.word;if(a!==b){return(a>b?+1:-1)}if((aaa.item.ty===TY_PRIMITIVE&&bbb.item.ty!==TY_KEYWORD)||(aaa.item.ty===TY_KEYWORD&&bbb.item.ty!==TY_PRIMITIVE)){return-1}if((bbb.item.ty===TY_PRIMITIVE&&aaa.item.ty!==TY_PRIMITIVE)||(bbb.item.ty===TY_KEYWORD&&aaa.item.ty!==TY_KEYWORD)){return 1}a=(aaa.item.desc==="");b=(bbb.item.desc==="");if(a!==b){return a-b}a=aaa.item.ty;b=bbb.item.ty;if(a!==b){return a-b}a=aaa.item.path;b=bbb.item.path;if(a!==b){return(a>b?+1:-1)}return 0});let nameSplit=null;if(parsedQuery.elems.length===1){const hasPath=typeof parsedQuery.elems[0].path==="undefined";nameSplit=hasPath?null:parsedQuery.elems[0].path}for(const result of result_list){if(result.dontValidate){continue}const name=result.item.name.toLowerCase(),path=result.item.path.toLowerCase(),parent=result.item.parent;if(!isType&&!validateResult(name,path,nameSplit,parent)){result.id=-1}}return transformResults(result_list)}function checkGenerics(fnType,queryElem){return unifyFunctionTypes(fnType.generics,queryElem.generics)}function unifyFunctionTypes(fnTypes,queryElems){if(queryElems.length===0){return true}if(!fnTypes||fnTypes.length===0){return false}const queryElemSet=new Map();const addQueryElemToQueryElemSet=function addQueryElemToQueryElemSet(queryElem){let currentQueryElemList;if(queryElemSet.has(queryElem.id)){currentQueryElemList=queryElemSet.get(queryElem.id)}else{currentQueryElemList=[];queryElemSet.set(queryElem.id,currentQueryElemList)}currentQueryElemList.push(queryElem)};for(const queryElem of queryElems){addQueryElemToQueryElemSet(queryElem)}const fnTypeSet=new Map();const addFnTypeToFnTypeSet=function addFnTypeToFnTypeSet(fnType){const queryContainsArrayOrSliceElem=queryElemSet.has(typeNameIdOfArrayOrSlice);if(fnType.id===-1||!(queryElemSet.has(fnType.id)||(fnType.id===typeNameIdOfSlice&&queryContainsArrayOrSliceElem)||(fnType.id===typeNameIdOfArray&&queryContainsArrayOrSliceElem))){for(const innerFnType of fnType.generics){addFnTypeToFnTypeSet(innerFnType)}return}let currentQueryElemList=queryElemSet.get(fnType.id)||[];let matchIdx=currentQueryElemList.findIndex(queryElem=>{return typePassesFilter(queryElem.typeFilter,fnType.ty)&&checkGenerics(fnType,queryElem)});if(matchIdx===-1&&(fnType.id===typeNameIdOfSlice||fnType.id===typeNameIdOfArray)&&queryContainsArrayOrSliceElem){currentQueryElemList=queryElemSet.get(typeNameIdOfArrayOrSlice)||[];matchIdx=currentQueryElemList.findIndex(queryElem=>{return typePassesFilter(queryElem.typeFilter,fnType.ty)&&checkGenerics(fnType,queryElem)})}if(matchIdx===-1){for(const innerFnType of fnType.generics){addFnTypeToFnTypeSet(innerFnType)}return}let currentFnTypeList;if(fnTypeSet.has(fnType.id)){currentFnTypeList=fnTypeSet.get(fnType.id)}else{currentFnTypeList=[];fnTypeSet.set(fnType.id,currentFnTypeList)}currentFnTypeList.push(fnType)};for(const fnType of fnTypes){addFnTypeToFnTypeSet(fnType)}const doHandleQueryElemList=(currentFnTypeList,queryElemList)=>{if(queryElemList.length===0){return true}const queryElem=queryElemList.pop();const l=currentFnTypeList.length;for(let i=0;i{if(!fnTypeSet.has(id)){if(id===typeNameIdOfArrayOrSlice){return handleQueryElemList(typeNameIdOfSlice,queryElemList)||handleQueryElemList(typeNameIdOfArray,queryElemList)}return false}const currentFnTypeList=fnTypeSet.get(id);if(currentFnTypeList.length0?checkIfInList(row.generics,elem):false}const matchesExact=row.id===elem.id;const matchesArrayOrSlice=elem.id===typeNameIdOfArrayOrSlice&&(row.id===typeNameIdOfSlice||row.id===typeNameIdOfArray);if((matchesExact||matchesArrayOrSlice)&&typePassesFilter(elem.typeFilter,row.ty)){if(elem.generics.length>0){return checkGenerics(row,elem)}return true}return checkIfInList(row.generics,elem)}function checkPath(contains,ty,maxEditDistance){if(contains.length===0){return 0}let ret_dist=maxEditDistance+1;const path=ty.path.split("::");if(ty.parent&&ty.parent.name){path.push(ty.parent.name.toLowerCase())}const length=path.length;const clength=contains.length;if(clength>length){return maxEditDistance+1}for(let i=0;ilength){break}let dist_total=0;let aborted=false;for(let x=0;xmaxEditDistance){aborted=true;break}dist_total+=dist}if(!aborted){ret_dist=Math.min(ret_dist,Math.round(dist_total/clength))}}return ret_dist}function typePassesFilter(filter,type){if(filter<=NO_TYPE_FILTER||filter===type)return true;const name=itemTypes[type];switch(itemTypes[filter]){case"constant":return name==="associatedconstant";case"fn":return name==="method"||name==="tymethod";case"type":return name==="primitive"||name==="associatedtype";case"trait":return name==="traitalias"}return false}function createAliasFromItem(item){return{crate:item.crate,name:item.name,path:item.path,desc:item.desc,ty:item.ty,parent:item.parent,type:item.type,is_alias:true,deprecated:item.deprecated,}}function handleAliases(ret,query,filterCrates,currentCrate){const lowerQuery=query.toLowerCase();const aliases=[];const crateAliases=[];if(filterCrates!==null){if(ALIASES.has(filterCrates)&&ALIASES.get(filterCrates).has(lowerQuery)){const query_aliases=ALIASES.get(filterCrates).get(lowerQuery);for(const alias of query_aliases){aliases.push(createAliasFromItem(searchIndex[alias]))}}}else{for(const[crate,crateAliasesIndex]of ALIASES){if(crateAliasesIndex.has(lowerQuery)){const pushTo=crate===currentCrate?crateAliases:aliases;const query_aliases=crateAliasesIndex.get(lowerQuery);for(const alias of query_aliases){pushTo.push(createAliasFromItem(searchIndex[alias]))}}}}const sortFunc=(aaa,bbb)=>{if(aaa.path{alias.alias=query;const res=buildHrefAndPath(alias);alias.displayPath=pathSplitter(res[0]);alias.fullPath=alias.displayPath+alias.name;alias.href=res[1];ret.others.unshift(alias);if(ret.others.length>MAX_RESULTS){ret.others.pop()}};aliases.forEach(pushFunc);crateAliases.forEach(pushFunc)}function addIntoResults(results,fullId,id,index,dist,path_dist,maxEditDistance){const inBounds=dist<=maxEditDistance||index!==-1;if(dist===0||(!parsedQuery.literalSearch&&inBounds)){if(results.has(fullId)){const result=results.get(fullId);if(result.dontValidate||result.dist<=dist){return}}results.set(fullId,{id:id,index:index,dontValidate:parsedQuery.literalSearch,dist:dist,path_dist:path_dist,})}}function handleSingleArg(row,pos,elem,results_others,results_in_args,results_returned,maxEditDistance){if(!row||(filterCrates!==null&&row.crate!==filterCrates)){return}let index=-1,path_dist=0;const fullId=row.id;const searchWord=searchWords[pos];const in_args=row.type&&row.type.inputs&&checkIfInList(row.type.inputs,elem);if(in_args){addIntoResults(results_in_args,fullId,pos,-1,0,0,maxEditDistance)}const returned=row.type&&row.type.output&&checkIfInList(row.type.output,elem);if(returned){addIntoResults(results_returned,fullId,pos,-1,0,0,maxEditDistance)}if(!typePassesFilter(elem.typeFilter,row.ty)){return}const row_index=row.normalizedName.indexOf(elem.pathLast);const word_index=searchWord.indexOf(elem.pathLast);if(row_index===-1){index=word_index}else if(word_index===-1){index=row_index}else if(word_index1){path_dist=checkPath(elem.pathWithoutLast,row,maxEditDistance);if(path_dist>maxEditDistance){return}}if(parsedQuery.literalSearch){if(searchWord===elem.name){addIntoResults(results_others,fullId,pos,index,0,path_dist)}return}const dist=editDistance(searchWord,elem.pathLast,maxEditDistance);if(index===-1&&dist+path_dist>maxEditDistance){return}addIntoResults(results_others,fullId,pos,index,dist,path_dist,maxEditDistance)}function handleArgs(row,pos,results){if(!row||(filterCrates!==null&&row.crate!==filterCrates)||!row.type){return}if(!unifyFunctionTypes(row.type.inputs,parsedQuery.elems)){return}if(!unifyFunctionTypes(row.type.output,parsedQuery.returned)){return}addIntoResults(results,row.id,pos,0,0,0,Number.MAX_VALUE)}function innerRunQuery(){let elem,i,nSearchWords,in_returned,row;let queryLen=0;for(const elem of parsedQuery.elems){queryLen+=elem.name.length}for(const elem of parsedQuery.returned){queryLen+=elem.name.length}const maxEditDistance=Math.floor(queryLen/3);function convertNameToId(elem){if(typeNameIdMap.has(elem.name)){elem.id=typeNameIdMap.get(elem.name)}else if(!parsedQuery.literalSearch){let match=-1;let matchDist=maxEditDistance+1;let matchName="";for(const[name,id]of typeNameIdMap){const dist=editDistance(name,elem.name,maxEditDistance);if(dist<=matchDist&&dist<=maxEditDistance){if(dist===matchDist&&matchName>name){continue}match=id;matchDist=dist;matchName=name}}if(match!==-1){parsedQuery.correction=matchName}elem.id=match}for(const elem2 of elem.generics){convertNameToId(elem2)}}for(const elem of parsedQuery.elems){convertNameToId(elem)}for(const elem of parsedQuery.returned){convertNameToId(elem)}if(parsedQuery.foundElems===1){if(parsedQuery.elems.length===1){elem=parsedQuery.elems[0];for(i=0,nSearchWords=searchWords.length;i0){for(i=0,nSearchWords=searchWords.length;i-1||path.indexOf(key)>-1||(parent!==undefined&&parent.name!==undefined&&parent.name.toLowerCase().indexOf(key)>-1)||editDistance(name,key,maxEditDistance)<=maxEditDistance)){return false}}return true}function nextTab(direction){const next=(searchState.currentTab+direction+3)%searchState.focusedByTab.length;searchState.focusedByTab[searchState.currentTab]=document.activeElement;printTab(next);focusSearchResult()}function focusSearchResult(){const target=searchState.focusedByTab[searchState.currentTab]||document.querySelectorAll(".search-results.active a").item(0)||document.querySelectorAll("#search-tabs button").item(searchState.currentTab);searchState.focusedByTab[searchState.currentTab]=null;if(target){target.focus()}}function buildHrefAndPath(item){let displayPath;let href;const type=itemTypes[item.ty];const name=item.name;let path=item.path;if(type==="mod"){displayPath=path+"::";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+name+"/index.html"}else if(type==="import"){displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/index.html#reexport."+name}else if(type==="primitive"||type==="keyword"){displayPath="";href=ROOT_PATH+path.replace(/::/g,"/")+"/"+type+"."+name+".html"}else if(type==="externcrate"){displayPath="";href=ROOT_PATH+name+"/index.html"}else if(item.parent!==undefined){const myparent=item.parent;let anchor="#"+type+"."+name;const parentType=itemTypes[myparent.ty];let pageType=parentType;let pageName=myparent.name;if(parentType==="primitive"){displayPath=myparent.name+"::"}else if(type==="structfield"&&parentType==="variant"){const enumNameIdx=item.path.lastIndexOf("::");const enumName=item.path.substr(enumNameIdx+2);path=item.path.substr(0,enumNameIdx);displayPath=path+"::"+enumName+"::"+myparent.name+"::";anchor="#variant."+myparent.name+".field."+name;pageType="enum";pageName=enumName}else{displayPath=path+"::"+myparent.name+"::"}href=ROOT_PATH+path.replace(/::/g,"/")+"/"+pageType+"."+pageName+".html"+anchor}else{displayPath=item.path+"::";href=ROOT_PATH+item.path.replace(/::/g,"/")+"/"+type+"."+name+".html"}return[displayPath,href]}function pathSplitter(path){const tmp=""+path.replace(/::/g,"::");if(tmp.endsWith("")){return tmp.slice(0,tmp.length-6)}return tmp}function addTab(array,query,display){let extraClass="";if(display===true){extraClass=" active"}const output=document.createElement("div");let length=0;if(array.length>0){output.className="search-results "+extraClass;array.forEach(item=>{const name=item.name;const type=itemTypes[item.ty];const longType=longItemTypes[item.ty];const typeName=longType.length!==0?`${longType}`:"?";length+=1;const link=document.createElement("a");link.className="result-"+type;link.href=item.href;const resultName=document.createElement("div");resultName.className="result-name";resultName.insertAdjacentHTML("beforeend",`${typeName}`);link.appendChild(resultName);let alias=" ";if(item.is_alias){alias=`
\ +${item.alias} - see \ +
`}resultName.insertAdjacentHTML("beforeend",`
${alias}\ +${item.displayPath}${name}\ +
`);const description=document.createElement("div");description.className="desc";description.insertAdjacentHTML("beforeend",item.desc);link.appendChild(description);output.appendChild(link)})}else if(query.error===null){output.className="search-failed"+extraClass;output.innerHTML="No results :(
"+"Try on DuckDuckGo?

"+"Or try looking in one of these:"}return[output,length]}function makeTabHeader(tabNb,text,nbElems){if(searchState.currentTab===tabNb){return""}return""}function showResults(results,go_to_first,filterCrates){const search=searchState.outputElement();if(go_to_first||(results.others.length===1&&getSettingValue("go-to-only-result")==="true")){window.onunload=()=>{};searchState.removeQueryParameters();const elem=document.createElement("a");elem.href=results.others[0].href;removeClass(elem,"active");document.body.appendChild(elem);elem.click();return}if(results.query===undefined){results.query=parseQuery(searchState.input.value)}currentResults=results.query.userQuery;const ret_others=addTab(results.others,results.query,true);const ret_in_args=addTab(results.in_args,results.query,false);const ret_returned=addTab(results.returned,results.query,false);let currentTab=searchState.currentTab;if((currentTab===0&&ret_others[1]===0)||(currentTab===1&&ret_in_args[1]===0)||(currentTab===2&&ret_returned[1]===0)){if(ret_others[1]!==0){currentTab=0}else if(ret_in_args[1]!==0){currentTab=1}else if(ret_returned[1]!==0){currentTab=2}}let crates="";const crates_list=Object.keys(rawSearchIndex);if(crates_list.length>1){crates=" in 
"}let output=`

Results${crates}

`;if(results.query.error!==null){const error=results.query.error;error.forEach((value,index)=>{value=value.split("<").join("<").split(">").join(">");if(index%2!==0){error[index]=`${value.replaceAll(" ", " ")}`}else{error[index]=value}});output+=`

Query parser error: "${error.join("")}".

`;output+="
"+makeTabHeader(0,"In Names",ret_others[1])+"
";currentTab=0}else if(results.query.foundElems<=1&&results.query.returned.length===0){output+="
"+makeTabHeader(0,"In Names",ret_others[1])+makeTabHeader(1,"In Parameters",ret_in_args[1])+makeTabHeader(2,"In Return Types",ret_returned[1])+"
"}else{const signatureTabTitle=results.query.elems.length===0?"In Function Return Types":results.query.returned.length===0?"In Function Parameters":"In Function Signatures";output+="
"+makeTabHeader(0,signatureTabTitle,ret_others[1])+"
";currentTab=0}if(results.query.correction!==null){const orig=results.query.returned.length>0?results.query.returned[0].name:results.query.elems[0].name;output+="

"+`Type "${orig}" not found. `+"Showing results for closest type name "+`"${results.query.correction}" instead.

`}const resultsElem=document.createElement("div");resultsElem.id="results";resultsElem.appendChild(ret_others[0]);resultsElem.appendChild(ret_in_args[0]);resultsElem.appendChild(ret_returned[0]);search.innerHTML=output;const crateSearch=document.getElementById("crate-search");if(crateSearch){crateSearch.addEventListener("input",updateCrate)}search.appendChild(resultsElem);searchState.showResults(search);const elems=document.getElementById("search-tabs").childNodes;searchState.focusedByTab=[];let i=0;for(const elem of elems){const j=i;elem.onclick=()=>printTab(j);searchState.focusedByTab.push(null);i+=1}printTab(currentTab)}function updateSearchHistory(url){if(!browserSupportsHistoryApi()){return}const params=searchState.getQueryStringParams();if(!history.state&&!params.search){history.pushState(null,"",url)}else{history.replaceState(null,"",url)}}function search(e,forced){if(e){e.preventDefault()}const query=parseQuery(searchState.input.value.trim());let filterCrates=getFilterCrates();if(!forced&&query.userQuery===currentResults){if(query.userQuery.length>0){putBackSearch()}return}searchState.setLoadingSearch();const params=searchState.getQueryStringParams();if(filterCrates===null&¶ms["filter-crate"]!==undefined){filterCrates=params["filter-crate"]}searchState.title="Results for "+query.original+" - Rust";updateSearchHistory(buildUrl(query.original,filterCrates));showResults(execQuery(query,searchWords,filterCrates,window.currentCrate),params.go_to_first,filterCrates)}function buildItemSearchTypeAll(types,lowercasePaths){const PATH_INDEX_DATA=0;const GENERICS_DATA=1;return types.map(type=>{let pathIndex,generics;if(typeof type==="number"){pathIndex=type;generics=[]}else{pathIndex=type[PATH_INDEX_DATA];generics=buildItemSearchTypeAll(type[GENERICS_DATA],lowercasePaths)}return{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:generics,}})}function buildFunctionSearchType(functionSearchType,lowercasePaths){const INPUTS_DATA=0;const OUTPUT_DATA=1;if(functionSearchType===0){return null}let inputs,output;if(typeof functionSearchType[INPUTS_DATA]==="number"){const pathIndex=functionSearchType[INPUTS_DATA];inputs=[{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{inputs=buildItemSearchTypeAll(functionSearchType[INPUTS_DATA],lowercasePaths)}if(functionSearchType.length>1){if(typeof functionSearchType[OUTPUT_DATA]==="number"){const pathIndex=functionSearchType[OUTPUT_DATA];output=[{id:pathIndex===0?-1:buildTypeMapIndex(lowercasePaths[pathIndex-1].name),ty:pathIndex===0?null:lowercasePaths[pathIndex-1].ty,generics:[],}]}else{output=buildItemSearchTypeAll(functionSearchType[OUTPUT_DATA],lowercasePaths)}}else{output=[]}return{inputs,output,}}function buildIndex(rawSearchIndex){searchIndex=[];const searchWords=[];typeNameIdMap=new Map();const charA="A".charCodeAt(0);let currentIndex=0;let id=0;typeNameIdOfArray=buildTypeMapIndex("array");typeNameIdOfSlice=buildTypeMapIndex("slice");typeNameIdOfArrayOrSlice=buildTypeMapIndex("[]");for(const crate in rawSearchIndex){if(!hasOwnPropertyRustdoc(rawSearchIndex,crate)){continue}let crateSize=0;const crateCorpus=rawSearchIndex[crate];searchWords.push(crate);const crateRow={crate:crate,ty:1,name:crate,path:"",desc:crateCorpus.doc,parent:undefined,type:null,id:id,normalizedName:crate.indexOf("_")===-1?crate:crate.replace(/_/g,""),deprecated:null,};id+=1;searchIndex.push(crateRow);currentIndex+=1;const itemTypes=crateCorpus.t;const itemNames=crateCorpus.n;const itemPaths=new Map(crateCorpus.q);const itemDescs=crateCorpus.d;const itemParentIdxs=crateCorpus.i;const itemFunctionSearchTypes=crateCorpus.f;const deprecatedItems=new Set(crateCorpus.c);const paths=crateCorpus.p;const aliases=crateCorpus.a;const lowercasePaths=[];let len=paths.length;for(let i=0;i0?paths[itemParentIdxs[i]-1]:undefined,type:buildFunctionSearchType(itemFunctionSearchTypes[i],lowercasePaths),id:id,normalizedName:word.indexOf("_")===-1?word:word.replace(/_/g,""),deprecated:deprecatedItems.has(i),};id+=1;searchIndex.push(row);lastPath=row.path;crateSize+=1}if(aliases){const currentCrateAliases=new Map();ALIASES.set(crate,currentCrateAliases);for(const alias_name in aliases){if(!hasOwnPropertyRustdoc(aliases,alias_name)){continue}let currentNameAliases;if(currentCrateAliases.has(alias_name)){currentNameAliases=currentCrateAliases.get(alias_name)}else{currentNameAliases=[];currentCrateAliases.set(alias_name,currentNameAliases)}for(const local_alias of aliases[alias_name]){currentNameAliases.push(local_alias+currentIndex)}}}currentIndex+=crateSize}return searchWords}function onSearchSubmit(e){e.preventDefault();searchState.clearInputTimeout();search()}function putBackSearch(){const search_input=searchState.input;if(!searchState.input){return}if(search_input.value!==""&&!searchState.isDisplayed()){searchState.showResults();if(browserSupportsHistoryApi()){history.replaceState(null,"",buildUrl(search_input.value,getFilterCrates()))}document.title=searchState.title}}function registerSearchEvents(){const params=searchState.getQueryStringParams();if(searchState.input.value===""){searchState.input.value=params.search||""}const searchAfter500ms=()=>{searchState.clearInputTimeout();if(searchState.input.value.length===0){searchState.hideResults()}else{searchState.timeout=setTimeout(search,500)}};searchState.input.onkeyup=searchAfter500ms;searchState.input.oninput=searchAfter500ms;document.getElementsByClassName("search-form")[0].onsubmit=onSearchSubmit;searchState.input.onchange=e=>{if(e.target!==document.activeElement){return}searchState.clearInputTimeout();setTimeout(search,0)};searchState.input.onpaste=searchState.input.onchange;searchState.outputElement().addEventListener("keydown",e=>{if(e.altKey||e.ctrlKey||e.shiftKey||e.metaKey){return}if(e.which===38){const previous=document.activeElement.previousElementSibling;if(previous){previous.focus()}else{searchState.focus()}e.preventDefault()}else if(e.which===40){const next=document.activeElement.nextElementSibling;if(next){next.focus()}const rect=document.activeElement.getBoundingClientRect();if(window.innerHeight-rect.bottom{if(e.which===40){focusSearchResult();e.preventDefault()}});searchState.input.addEventListener("focus",()=>{putBackSearch()});searchState.input.addEventListener("blur",()=>{searchState.input.placeholder=searchState.input.origPlaceholder});if(browserSupportsHistoryApi()){const previousTitle=document.title;window.addEventListener("popstate",e=>{const params=searchState.getQueryStringParams();document.title=previousTitle;currentResults=null;if(params.search&¶ms.search.length>0){searchState.input.value=params.search;search(e)}else{searchState.input.value="";searchState.hideResults()}})}window.onpageshow=()=>{const qSearch=searchState.getQueryStringParams().search;if(searchState.input.value===""&&qSearch){searchState.input.value=qSearch}search()}}function updateCrate(ev){if(ev.target.value==="all crates"){const query=searchState.input.value.trim();updateSearchHistory(buildUrl(query,null))}currentResults=null;search(undefined,true)}const searchWords=buildIndex(rawSearchIndex);if(typeof window!=="undefined"){registerSearchEvents();if(window.searchState.getQueryStringParams().search){search()}}if(typeof exports!=="undefined"){exports.initSearch=initSearch;exports.execQuery=execQuery;exports.parseQuery=parseQuery}return searchWords}if(typeof window!=="undefined"){window.initSearch=initSearch;if(window.searchIndex!==undefined){initSearch(window.searchIndex)}}else{initSearch({})}})() \ No newline at end of file diff --git a/docs/static.files/settings-8c76f75bfb6bd192.css b/docs/static.files/settings-8c76f75bfb6bd192.css new file mode 100644 index 000000000..5241bb861 --- /dev/null +++ b/docs/static.files/settings-8c76f75bfb6bd192.css @@ -0,0 +1,3 @@ +.setting-line{margin:1.2em 0.6em;}.setting-radio input,.setting-check input{margin-right:0.3em;height:1.2rem;width:1.2rem;border:2px solid var(--settings-input-border-color);outline:none;-webkit-appearance:none;cursor:pointer;}.setting-radio input{border-radius:50%;}.setting-radio span,.setting-check span{padding-bottom:1px;}.setting-radio{margin-top:0.1em;margin-bottom:0.1em;min-width:3.8em;padding:0.3em;display:inline-flex;align-items:center;cursor:pointer;}.setting-radio+.setting-radio{margin-left:0.5em;}.setting-check{margin-right:20px;display:flex;align-items:center;cursor:pointer;}.setting-radio input:checked{box-shadow:inset 0 0 0 3px var(--main-background-color);background-color:var(--settings-input-color);}.setting-check input:checked{background-color:var(--settings-input-color);border-width:1px;content:url('data:image/svg+xml,\ + \ + ');}.setting-radio input:focus,.setting-check input:focus{box-shadow:0 0 1px 1px var(--settings-input-color);}.setting-radio input:checked:focus{box-shadow:inset 0 0 0 3px var(--main-background-color),0 0 2px 2px var(--settings-input-color);}.setting-radio input:hover,.setting-check input:hover{border-color:var(--settings-input-color) !important;} \ No newline at end of file diff --git a/docs/static.files/settings-de11bff964e9d4e5.js b/docs/static.files/settings-de11bff964e9d4e5.js new file mode 100644 index 000000000..cc508a861 --- /dev/null +++ b/docs/static.files/settings-de11bff964e9d4e5.js @@ -0,0 +1,17 @@ +"use strict";(function(){const isSettingsPage=window.location.pathname.endsWith("/settings.html");function changeSetting(settingName,value){if(settingName==="theme"){const useSystem=value==="system preference"?"true":"false";updateLocalStorage("use-system-theme",useSystem)}updateLocalStorage(settingName,value);switch(settingName){case"theme":case"preferred-dark-theme":case"preferred-light-theme":updateTheme();updateLightAndDark();break;case"line-numbers":if(value===true){window.rustdoc_add_line_numbers_to_examples()}else{window.rustdoc_remove_line_numbers_from_examples()}break}}function showLightAndDark(){removeClass(document.getElementById("preferred-light-theme"),"hidden");removeClass(document.getElementById("preferred-dark-theme"),"hidden")}function hideLightAndDark(){addClass(document.getElementById("preferred-light-theme"),"hidden");addClass(document.getElementById("preferred-dark-theme"),"hidden")}function updateLightAndDark(){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||(useSystem===null&&getSettingValue("theme")===null)){showLightAndDark()}else{hideLightAndDark()}}function setEvents(settingsElement){updateLightAndDark();onEachLazy(settingsElement.querySelectorAll("input[type=\"checkbox\"]"),toggle=>{const settingId=toggle.id;const settingValue=getSettingValue(settingId);if(settingValue!==null){toggle.checked=settingValue==="true"}toggle.onchange=function(){changeSetting(this.id,this.checked)}});onEachLazy(settingsElement.querySelectorAll("input[type=\"radio\"]"),elem=>{const settingId=elem.name;let settingValue=getSettingValue(settingId);if(settingId==="theme"){const useSystem=getSettingValue("use-system-theme");if(useSystem==="true"||settingValue===null){settingValue=useSystem==="false"?"light":"system preference"}}if(settingValue!==null&&settingValue!=="null"){elem.checked=settingValue===elem.value}elem.addEventListener("change",ev=>{changeSetting(ev.target.name,ev.target.value)})})}function buildSettingsPageSections(settings){let output="";for(const setting of settings){const js_data_name=setting["js_name"];const setting_name=setting["name"];if(setting["options"]!==undefined){output+=`\ +
+
${setting_name}
+
`;onEach(setting["options"],option=>{const checked=option===setting["default"]?" checked":"";const full=`${js_data_name}-${option.replace(/ /g,"-")}`;output+=`\ + `});output+=`\ +
+
`}else{const checked=setting["default"]===true?" checked":"";output+=`\ +
\ + \ +
`}}return output}function buildSettingsPage(){const theme_names=getVar("themes").split(",").filter(t=>t);theme_names.push("light","dark","ayu");const settings=[{"name":"Theme","js_name":"theme","default":"system preference","options":theme_names.concat("system preference"),},{"name":"Preferred light theme","js_name":"preferred-light-theme","default":"light","options":theme_names,},{"name":"Preferred dark theme","js_name":"preferred-dark-theme","default":"dark","options":theme_names,},{"name":"Auto-hide item contents for large items","js_name":"auto-hide-large-items","default":true,},{"name":"Auto-hide item methods' documentation","js_name":"auto-hide-method-docs","default":false,},{"name":"Auto-hide trait implementation documentation","js_name":"auto-hide-trait-implementations","default":false,},{"name":"Directly go to item in search if there is only one result","js_name":"go-to-only-result","default":false,},{"name":"Show line numbers on code examples","js_name":"line-numbers","default":false,},{"name":"Disable keyboard shortcuts","js_name":"disable-shortcuts","default":false,},];const elementKind=isSettingsPage?"section":"div";const innerHTML=`
${buildSettingsPageSections(settings)}
`;const el=document.createElement(elementKind);el.id="settings";if(!isSettingsPage){el.className="popover"}el.innerHTML=innerHTML;if(isSettingsPage){document.getElementById(MAIN_ID).appendChild(el)}else{el.setAttribute("tabindex","-1");getSettingsButton().appendChild(el)}return el}const settingsMenu=buildSettingsPage();function displaySettings(){settingsMenu.style.display=""}function settingsBlurHandler(event){blurHandler(event,getSettingsButton(),window.hidePopoverMenus)}if(isSettingsPage){getSettingsButton().onclick=function(event){event.preventDefault()}}else{const settingsButton=getSettingsButton();const settingsMenu=document.getElementById("settings");settingsButton.onclick=function(event){if(elemIsInParent(event.target,settingsMenu)){return}event.preventDefault();const shouldDisplaySettings=settingsMenu.style.display==="none";window.hideAllModals();if(shouldDisplaySettings){displaySettings()}};settingsButton.onblur=settingsBlurHandler;settingsButton.querySelector("a").onblur=settingsBlurHandler;onEachLazy(settingsMenu.querySelectorAll("input"),el=>{el.onblur=settingsBlurHandler});settingsMenu.onblur=settingsBlurHandler}setTimeout(()=>{setEvents(settingsMenu);if(!isSettingsPage){displaySettings()}removeClass(getSettingsButton(),"rotate")},0)})() \ No newline at end of file diff --git a/docs/static.files/src-script-3280b574d94e47b4.js b/docs/static.files/src-script-3280b574d94e47b4.js new file mode 100644 index 000000000..9ea88921e --- /dev/null +++ b/docs/static.files/src-script-3280b574d94e47b4.js @@ -0,0 +1 @@ +"use strict";(function(){const rootPath=getVar("root-path");const NAME_OFFSET=0;const DIRS_OFFSET=1;const FILES_OFFSET=2;const RUSTDOC_MOBILE_BREAKPOINT=700;function closeSidebarIfMobile(){if(window.innerWidth"){addClass(document.documentElement,"src-sidebar-expanded");child.innerText="<";updateLocalStorage("source-sidebar-show","true")}else{removeClass(document.documentElement,"src-sidebar-expanded");child.innerText=">";updateLocalStorage("source-sidebar-show","false")}}function createSidebarToggle(){const sidebarToggle=document.createElement("div");sidebarToggle.id="src-sidebar-toggle";const inner=document.createElement("button");if(getCurrentValue("source-sidebar-show")==="true"){inner.innerText="<"}else{inner.innerText=">"}inner.onclick=toggleSidebar;sidebarToggle.appendChild(inner);return sidebarToggle}function createSrcSidebar(){const container=document.querySelector("nav.sidebar");const sidebarToggle=createSidebarToggle();container.insertBefore(sidebarToggle,container.firstChild);const sidebar=document.createElement("div");sidebar.id="src-sidebar";let hasFoundFile=false;const title=document.createElement("div");title.className="title";title.innerText="Files";sidebar.appendChild(title);Object.keys(srcIndex).forEach(key=>{srcIndex[key][NAME_OFFSET]=key;hasFoundFile=createDirEntry(srcIndex[key],sidebar,"",hasFoundFile)});container.appendChild(sidebar);const selected_elem=sidebar.getElementsByClassName("selected")[0];if(typeof selected_elem!=="undefined"){selected_elem.focus()}}const lineNumbersRegex=/^#?(\d+)(?:-(\d+))?$/;function highlightSrcLines(match){if(typeof match==="undefined"){match=window.location.hash.match(lineNumbersRegex)}if(!match){return}let from=parseInt(match[1],10);let to=from;if(typeof match[2]!=="undefined"){to=parseInt(match[2],10)}if(to{onEachLazy(e.getElementsByTagName("a"),i_e=>{removeClass(i_e,"line-highlighted")})});for(let i=from;i<=to;++i){elem=document.getElementById(i);if(!elem){break}addClass(elem,"line-highlighted")}}const handleSrcHighlight=(function(){let prev_line_id=0;const set_fragment=name=>{const x=window.scrollX,y=window.scrollY;if(browserSupportsHistoryApi()){history.replaceState(null,null,"#"+name);highlightSrcLines()}else{location.replace("#"+name)}window.scrollTo(x,y)};return ev=>{let cur_line_id=parseInt(ev.target.id,10);if(isNaN(cur_line_id)||ev.ctrlKey||ev.altKey||ev.metaKey){return}ev.preventDefault();if(ev.shiftKey&&prev_line_id){if(prev_line_id>cur_line_id){const tmp=prev_line_id;prev_line_id=cur_line_id;cur_line_id=tmp}set_fragment(prev_line_id+"-"+cur_line_id)}else{prev_line_id=cur_line_id;set_fragment(cur_line_id)}}}());window.addEventListener("hashchange",()=>{const match=window.location.hash.match(lineNumbersRegex);if(match){return highlightSrcLines(match)}});onEachLazy(document.getElementsByClassName("src-line-numbers"),el=>{el.addEventListener("click",handleSrcHighlight)});highlightSrcLines();window.createSrcSidebar=createSrcSidebar})() \ No newline at end of file diff --git a/docs/static.files/storage-db41da1a38ea3cb8.js b/docs/static.files/storage-db41da1a38ea3cb8.js new file mode 100644 index 000000000..b87281359 --- /dev/null +++ b/docs/static.files/storage-db41da1a38ea3cb8.js @@ -0,0 +1 @@ +"use strict";const darkThemes=["dark","ayu"];window.currentTheme=document.getElementById("themeStyle");const settingsDataset=(function(){const settingsElement=document.getElementById("default-settings");return settingsElement&&settingsElement.dataset?settingsElement.dataset:null})();function getSettingValue(settingName){const current=getCurrentValue(settingName);if(current===null&&settingsDataset!==null){const def=settingsDataset[settingName.replace(/-/g,"_")];if(def!==undefined){return def}}return current}const localStoredTheme=getSettingValue("theme");function hasClass(elem,className){return elem&&elem.classList&&elem.classList.contains(className)}function addClass(elem,className){if(elem&&elem.classList){elem.classList.add(className)}}function removeClass(elem,className){if(elem&&elem.classList){elem.classList.remove(className)}}function onEach(arr,func,reversed){if(arr&&arr.length>0){if(reversed){for(let i=arr.length-1;i>=0;--i){if(func(arr[i])){return true}}}else{for(const elem of arr){if(func(elem)){return true}}}}return false}function onEachLazy(lazyArray,func,reversed){return onEach(Array.prototype.slice.call(lazyArray),func,reversed)}function updateLocalStorage(name,value){try{window.localStorage.setItem("rustdoc-"+name,value)}catch(e){}}function getCurrentValue(name){try{return window.localStorage.getItem("rustdoc-"+name)}catch(e){return null}}const getVar=(function getVar(name){const el=document.querySelector("head > meta[name='rustdoc-vars']");return el?el.attributes["data-"+name].value:null});function switchTheme(newThemeName,saveTheme){if(saveTheme){updateLocalStorage("theme",newThemeName)}let newHref;if(newThemeName==="light"||newThemeName==="dark"||newThemeName==="ayu"){newHref=getVar("static-root-path")+getVar("theme-"+newThemeName+"-css")}else{newHref=getVar("root-path")+newThemeName+getVar("resource-suffix")+".css"}if(!window.currentTheme){document.write(``);window.currentTheme=document.getElementById("themeStyle")}else if(newHref!==window.currentTheme.href){window.currentTheme.href=newHref}}const updateTheme=(function(){const mql=window.matchMedia("(prefers-color-scheme: dark)");function updateTheme(){if(getSettingValue("use-system-theme")!=="false"){const lightTheme=getSettingValue("preferred-light-theme")||"light";const darkTheme=getSettingValue("preferred-dark-theme")||"dark";updateLocalStorage("use-system-theme","true");switchTheme(mql.matches?darkTheme:lightTheme,true)}else{switchTheme(getSettingValue("theme"),false)}}mql.addEventListener("change",updateTheme);return updateTheme})();if(getSettingValue("use-system-theme")!=="false"&&window.matchMedia){if(getSettingValue("use-system-theme")===null&&getSettingValue("preferred-dark-theme")===null&&darkThemes.indexOf(localStoredTheme)>=0){updateLocalStorage("preferred-dark-theme",localStoredTheme)}}updateTheme();if(getSettingValue("source-sidebar-show")==="true"){addClass(document.documentElement,"src-sidebar-expanded")}window.addEventListener("pageshow",ev=>{if(ev.persisted){setTimeout(updateTheme,0)}}) \ No newline at end of file diff --git a/docs/static.files/wheel-7b819b6101059cd0.svg b/docs/static.files/wheel-7b819b6101059cd0.svg new file mode 100644 index 000000000..83c07f63d --- /dev/null +++ b/docs/static.files/wheel-7b819b6101059cd0.svg @@ -0,0 +1 @@ + \ No newline at end of file