Skip to main content

ConstraintSystem

Struct ConstraintSystem 

Source
pub struct ConstraintSystem {
    pub constants: Vec<Word>,
    pub n_inout: usize,
    pub n_private: usize,
    pub zero_constraints: Vec<ZeroConstraint>,
    pub and_constraints: Vec<AndConstraint>,
    pub imul_constraints: Vec<ImulConstraint>,
    pub bmul_constraints: Vec<BmulConstraint>,
}
Expand description

The ConstraintSystem is the core data structure in Binius64 that defines the computational constraints to be proven in zero-knowledge. It represents a system of equations over 64-bit words that must be satisfied by a valid values vector ValueVec.

§Value vector shape

The constraints reference words of a value vector partitioned into two segments. The public segment holds the words the verifier evaluates itself; the hidden segment holds the words the prover commits. The constants are always public and the private values always hidden; the inout values sit in whichever segment the proving protocol places them in, which every segment-length accessor takes as an InoutSegment. Each group of values is followed by padding, so under InoutSegment::Public the value vector runs

[ constants | inout | pad ][ private | pad ]
 \--- public segment ---/  \- hidden segment -/

Both segments are padded by the proving protocol rather than by the system: the public segment up to a power of two, and the hidden segment up to at least the public length. The system stores the value counts and derives the padded lengths from them.

A constraint names a word by its ValueSegment and its position within that segment, so the padding is unaddressable: an index reaches only the values of its own segment, and where those values sit in the vector is the layout’s business rather than the constraint’s.

§Constraint counts

The ZERO, AND, IMUL and BMUL constraint counts are the true counts; none of them is rounded up to a power of two. The reductions run over power-of-two-sized operand columns, so the prover rounds each count up to a power of two and zero-fills the tail when it materializes the column; Self::log_and_constraints and its ZERO, IMUL and BMUL siblings report the resulting variable count. Zero is a valid padding row for every constraint type: an empty operand evaluates to Word::ZERO, and 0 = 0, 0 & 0 ^ 0 = 0 and 0 * 0 = 0 || 0 all hold.

§Clone

While this type is cloneable it may be expensive to do so since the constraint systems often can have millions of constraints.

Fields§

§constants: Vec<Word>

The constants that this constraint system defines.

Those constants will be going to be available for constraints in the value vector. Those are known to both prover and verifier.

§n_inout: usize

The number of input/output values, which are public but chosen per instance.

§n_private: usize

The number of private values, which only the prover knows.

§zero_constraints: Vec<ZeroConstraint>

List of ZERO constraints that must be satisfied by the values vector.

§and_constraints: Vec<AndConstraint>

List of AND constraints that must be satisfied by the values vector.

§imul_constraints: Vec<ImulConstraint>

List of IMUL constraints that must be satisfied by the values vector.

§bmul_constraints: Vec<BmulConstraint>

List of BMUL constraints that must be satisfied by the values vector.

Implementations§

Source§

impl ConstraintSystem

Source

pub const SERIALIZATION_VERSION: u32 = 10

Serialization format version for compatibility checking

Source

pub const fn n_const(&self) -> usize

Returns the number of constants.

Source

pub const fn offset_inout(&self) -> usize

Returns the index of the first inout value.

Source

pub const fn n_public_values(&self) -> usize

Returns the number of public values: the constants and the inout values.

Source

pub const fn n_public_words(&self, inout: InoutSegment) -> usize

Returns the number of words in the public segment.

This is the constants, followed by the inout values when they are placed there.

Source

pub const fn log_public_words(&self, inout: InoutSegment) -> usize

Returns the number of word-index variables the public segment spans.

The word count need not be a power of two; the reductions read the words past it as zero.

Source

pub const fn n_hidden_words(&self, inout: InoutSegment) -> usize

Returns the number of words in the hidden segment.

This is the private values, preceded by the inout values when they are placed there.

Source

pub const fn log_witness_words(&self, inout: InoutSegment) -> usize

Returns the number of word-index variables the hidden segment spans.

Source

pub const fn log_segment_words(&self, inout: InoutSegment) -> usize

Returns the number of word-index variables the shift reduction runs over.

The reduction addresses both segments with one set of word-index challenges, so it needs as many as the wider of the two spans. The narrower segment reads the extra coordinates as zero.

Source

pub const fn segment_len(&self, segment: ValueSegment) -> usize

Returns the number of values the given segment holds, excluding the padding after them.

The scratch segment holds no values a constraint may name, so it reports zero: every index into it is out of range as far as this system is concerned.

Source

pub const fn word_offset(&self, index: ValueIndex) -> usize

Returns the position of the word a ValueIndex names within the value vector.

This is the address the proving protocol reads the word at: the constants, then the inout values, then the private ones. Where the segment boundary falls does not enter, so the address is the same under either InoutSegment placement. Scratch words are not part of a constraint system, so a scratch index lands past the last word — Self::validate rejects any constraint naming one.

Source

pub fn value_vec_from_data(&self, inout: &[Word], private: &[Word]) -> ValueVec

Builds a value vector from the inout values and the private values.

The constants come from the system itself, so a caller supplies only what varies per instance — the same split Self::validate enforces and the verifier takes.

Source

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

Ensures that this constraint system is well-formed and ready for proving.

Specifically checks that:

  • every shifted value index is canonical.
  • referenced value indices are within their segment.
  • constraints do not reference scratch values.
  • shifts amounts are valid.
  • a lone shift sits in the inner slot of its shift sequence.
  • a genuine shift pair does not collapse to one shift, nor clear the word.
Source

pub fn verify(&self, values: &ValueVec) -> Result<(), VerificationError>

Checks that a value vector satisfies this constraint system.

Specifically checks that:

  • the value vector opens the declared constants to their declared words.
  • every constraint holds, in kind order: zero, then AND, then IMUL, then BMUL.

Operands are evaluated one word at a time, directly off the value vector. That makes this the reference the prover’s packed evaluation is checked against.

§Errors

Reports the first failure found, in the order listed above. A reported constraint position counts within that constraint’s own kind.

Source

pub fn operand_fault(&self, operand: &Operand) -> Option<OperandFault>

Returns the first way a term of an operand is malformed, or None when every term is well-formed.

The fault says nothing about where the operand sits, so a constraint operand and a chip-call operand can both report it under their own naming.

Source

pub const fn n_zero_constraints(&self) -> usize

Returns the number of ZERO constraints in the system.

Source

pub const fn n_and_constraints(&self) -> usize

Returns the number of AND constraints in the system.

Source

pub const fn n_imul_constraints(&self) -> usize

Returns the number of IMUL constraints in the system.

Source

pub const fn n_bmul_constraints(&self) -> usize

Returns the number of BMUL constraints in the system.

Source

pub const fn log_zero_constraints(&self) -> Option<usize>

Returns the number of variables the Zero reduction runs over, or None when the system has no ZERO constraints.

This is ceil(log2(n_zero_constraints)), matching the zero-padded operand column the reduction consumes. As with Self::log_and_constraints, the Zero reduction always runs: a system with no ZERO constraints still gets a single all-zero row, which the constraint vacuously satisfies. Such a system reduces over zero variables, so its callers read None as zero.

Source

pub const fn log_and_constraints(&self) -> Option<usize>

Returns the number of variables the BitAnd reduction runs over, or None when the system has no AND constraints.

The reduction operates on operand columns with one row per AND constraint, zero-padded up to a power of two, so it has ceil(log2(n_and_constraints)) variables. Unlike the two multiplication reductions, the BitAnd reduction always runs: a system with no AND constraints still gets a single all-zero row, which every constraint type satisfies. Such a system reduces over zero variables, so its callers read None as zero.

Source

pub const fn log_imul_constraints(&self) -> Option<usize>

Returns the number of variables the IntMul reduction runs over, or None when the system has no IMUL constraints.

This is ceil(log2(n_imul_constraints)), matching the zero-padded operand columns the reduction consumes. None is the skip signal: an empty IMUL set makes the prover and verifier skip the IntMul reduction entirely, rather than run it over a single dummy constraint.

Source

pub const fn log_bmul_constraints(&self) -> Option<usize>

Returns the number of variables the BinMul reduction runs over, or None when the system has no BMUL constraints.

This is ceil(log2(n_bmul_constraints)), matching the zero-padded operand columns the reduction consumes. As with Self::log_imul_constraints, None is the skip signal; both sides skip the BinMul reduction for an empty BMUL set.

Source

pub const fn value_vec_len(&self) -> usize

The total length of the ValueVec expected by this constraint system.

Trait Implementations§

Source§

impl Clone for ConstraintSystem

Source§

fn clone(&self) -> ConstraintSystem

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

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

Performs copy-assignment from source. Read more
Source§

impl Debug for ConstraintSystem

Source§

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

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

impl DeserializeBytes for ConstraintSystem

Source§

fn deserialize(read_buf: impl Buf) -> Result<Self, SerializationError>
where Self: Sized,

Source§

impl SerializeBytes for ConstraintSystem

Source§

fn serialize(&self, write_buf: impl BufMut) -> Result<(), SerializationError>

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> CloneToUninit for T
where T: Clone,

Source§

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

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

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

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

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

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

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

Source§

type Error = 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