Skip to main content

CircuitM4

Struct CircuitM4 

Source
pub struct CircuitM4 {
    pub main: EmbeddedCircuit,
    pub chips: Vec<(EmbeddedCircuit, usize)>,
}
Expand description

A circuit composed of chips, as the circuits that generate their witnesses.

main is the entry point: it calls chips, but no chip ID names it, so nothing calls it. The chips have an ID equal to their index in chips.

Fields§

§main: EmbeddedCircuit

The entry point, which runs once.

§chips: Vec<(EmbeddedCircuit, usize)>

The chips, indexed by chip ID, each paired with its number of active instances.

A chip runs once per call that reaches it, and those instances are the active ones: only they have their own chip calls enforced. The instances past them pad the count up to a power of two.

The count is denormalized — it says what the call graph already says, and Self::recompute_instances derives it, along with the instance each call claims. Self::validate holds the two to each other.

Implementations§

Source§

impl CircuitM4

Source

pub fn validate(&self) -> Result<(), CircuitM4Error>

Checks that this system can be populated in one pass over the chips, in ID order.

Specifically checks that:

  • every chip call names a chip of this system, passes no more operands than that chip has inout values, and reads only committed words of its own caller;
  • the chips are in topological order, each calling only chips with a higher ID, so every caller of a chip is populated before the chip itself;
  • each chip’s declared active-instance count is the number of invocations that reach it, no chip is left uncalled, and no count outgrows a usize;
  • each call names the callee instance the call graph gives it.

A system that passes here lowers to one that passes ConstraintSystemM4::validate, which requires the same ordering and additionally validates each chip’s compiled constraint system — the one thing here the compiler rather than this check keeps well-formed. Nothing downstream therefore has to run the lowered check to know its preconditions hold.

Source

pub fn recompute_instances(&mut self)

Gives each call the callee instances it invokes, and each chip the count of the ones it is left with.

A chip is invoked once per call site naming it, per active instance of the caller, and a call site’s invocations are consecutive instances of the callee: the caller’s instance i invokes the call’s first_instance plus i. Main runs once, so each of its call sites claims a single instance.

This is what Self::validate checks the declared counts and instances against, so a system whose call sites have just been written or rewritten passes it here rather than counting by hand.

A count that outgrows a usize saturates rather than wrapping, so it stays too large for the invocations that reach the chip and Self::validate reports it.

§Panics

Panics if a chip call names a chip this system does not have. Chips out of topological order are not detected here: a call to a lower ID counts against a total already written back, and Self::validate is what rejects the result.

Source

pub fn to_constraint_system(&self) -> ConstraintSystemM4

Lowers this system to the constraint-system form the proving protocol consumes.

Each circuit contributes its compiled constraint system; the chip calls and the active-instance counts carry over unchanged.

Source

pub fn generate_witness<F>( &self, fill_main: F, ) -> Result<WitnessM4, PopulateM4Error>
where F: FnOnce(&mut WitnessFiller<'_>),

Generates the witness for a whole system from the main circuit’s inputs.

fill_main assigns the witness inputs of the main circuit; every other value in the system is derived from them. Each chip’s table holds one instance per invocation that reaches it, each at the row the invoking call names. The instance count is rounded up to a power of two by repeating the last invocation, which satisfies the chip because the invocation it copies does.

§Panics

Panics if the system does not pass Self::validate, which covers both the ordering this walks the chips in and the well-formedness of the operands it evaluates.

Trait Implementations§

Source§

impl From<Circuit> for CircuitM4

Source§

fn from(circuit: Circuit) -> Self

Makes a circuit the whole system, as a main that calls no chips.

Auto Trait Implementations§

Blanket Implementations§

Source§

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

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

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

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

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

Source§

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

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

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

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

fn in_current_span(self) -> Instrumented<Self>

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

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

Source§

fn into(self) -> U

Calls U::from(self).

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

Source§

impl<T> IntoEither for T

Source§

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

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

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

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

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

Initializes a with the given initializer. Read more
§

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

Dereferences the given pointer. Read more
§

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

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

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

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

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

Source§

type Error = Infallible

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

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

Performs the conversion.
Source§

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

Source§

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

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

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

Performs the conversion.
§

impl<T> WithSubscriber for T

§

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

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

fn with_current_subscriber(self) -> WithDispatch<Self>

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