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: usizeThe number of input/output values, which are public but chosen per instance.
n_private: usizeThe 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
impl ConstraintSystem
Sourcepub const SERIALIZATION_VERSION: u32 = 10
pub const SERIALIZATION_VERSION: u32 = 10
Serialization format version for compatibility checking
Sourcepub const fn offset_inout(&self) -> usize
pub const fn offset_inout(&self) -> usize
Returns the index of the first inout value.
Sourcepub const fn n_public_values(&self) -> usize
pub const fn n_public_values(&self) -> usize
Returns the number of public values: the constants and the inout values.
Sourcepub const fn n_public_words(&self, inout: InoutSegment) -> usize
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.
Sourcepub const fn log_public_words(&self, inout: InoutSegment) -> usize
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.
Returns the number of words in the hidden segment.
This is the private values, preceded by the inout values when they are placed there.
Sourcepub const fn log_witness_words(&self, inout: InoutSegment) -> usize
pub const fn log_witness_words(&self, inout: InoutSegment) -> usize
Returns the number of word-index variables the hidden segment spans.
Sourcepub const fn log_segment_words(&self, inout: InoutSegment) -> usize
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.
Sourcepub const fn segment_len(&self, segment: ValueSegment) -> usize
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.
Sourcepub const fn word_offset(&self, index: ValueIndex) -> usize
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.
Sourcepub fn value_vec_from_data(&self, inout: &[Word], private: &[Word]) -> ValueVec
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.
Sourcepub fn validate(&self) -> Result<(), ConstraintSystemError>
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.
Sourcepub fn verify(&self, values: &ValueVec) -> Result<(), VerificationError>
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.
Sourcepub fn operand_fault(&self, operand: &Operand) -> Option<OperandFault>
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.
Sourcepub const fn n_zero_constraints(&self) -> usize
pub const fn n_zero_constraints(&self) -> usize
Returns the number of ZERO constraints in the system.
Sourcepub const fn n_and_constraints(&self) -> usize
pub const fn n_and_constraints(&self) -> usize
Returns the number of AND constraints in the system.
Sourcepub const fn n_imul_constraints(&self) -> usize
pub const fn n_imul_constraints(&self) -> usize
Returns the number of IMUL constraints in the system.
Sourcepub const fn n_bmul_constraints(&self) -> usize
pub const fn n_bmul_constraints(&self) -> usize
Returns the number of BMUL constraints in the system.
Sourcepub const fn log_zero_constraints(&self) -> Option<usize>
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.
Sourcepub const fn log_and_constraints(&self) -> Option<usize>
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.
Sourcepub const fn log_imul_constraints(&self) -> Option<usize>
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.
Sourcepub const fn log_bmul_constraints(&self) -> Option<usize>
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.
Sourcepub const fn value_vec_len(&self) -> usize
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
impl Clone for ConstraintSystem
Source§fn clone(&self) -> ConstraintSystem
fn clone(&self) -> ConstraintSystem
1.0.0 (const: unstable) · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for ConstraintSystem
impl Debug for ConstraintSystem
Source§impl DeserializeBytes for ConstraintSystem
impl DeserializeBytes for ConstraintSystem
fn deserialize(read_buf: impl Buf) -> Result<Self, SerializationError>where
Self: Sized,
Source§impl SerializeBytes for ConstraintSystem
impl SerializeBytes for ConstraintSystem
Auto Trait Implementations§
impl Freeze for ConstraintSystem
impl RefUnwindSafe for ConstraintSystem
impl Send for ConstraintSystem
impl Sync for ConstraintSystem
impl Unpin for ConstraintSystem
impl UnsafeUnpin for ConstraintSystem
impl UnwindSafe for ConstraintSystem
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more