Skip to content

feat: add built-in zero wire (Aux(0)) to constraint system#491

Open
sai-deng wants to merge 3 commits intomicrosoft:mainfrom
sai-deng:feat/builtin-zero-wire
Open

feat: add built-in zero wire (Aux(0)) to constraint system#491
sai-deng wants to merge 3 commits intomicrosoft:mainfrom
sai-deng:feat/builtin-zero-wire

Conversation

@sai-deng
Copy link
Copy Markdown
Contributor

@sai-deng sai-deng commented Apr 3, 2026

Reserve Aux(0) as a built-in zero variable, enforced with a single 0 * 0 = Aux(0) constraint at CS construction time. This makes AllocatedNum::zero() and alloc_zero() free (zero additional constraints or variables), mirroring AllocatedNum::one().

  • Add CS::zero() -> Variable to ConstraintSystem trait + all impls
  • All CS types (ShapeCS, WitnessCS, TestShapeCS, TestConstraintSystem) initialize with Aux(0)=0 and the enforcement constraint
  • WitnessCS::extend() skips aux[0] like it skips input[0]
  • AllocatedNum::zero() wraps CS::zero() with no constraints
  • alloc_zero() delegates to AllocatedNum::zero()
  • Net savings: ~7 constraints per augmented circuit

Reserve Aux(0) as a built-in zero variable, enforced with a single
0 * 0 = Aux(0) constraint at CS construction time. This makes
AllocatedNum::zero() and alloc_zero() free (zero additional
constraints or variables), mirroring AllocatedNum::one().

- Add CS::zero() -> Variable to ConstraintSystem trait + all impls
- All CS types (ShapeCS, WitnessCS, TestShapeCS, TestConstraintSystem)
  initialize with Aux(0)=0 and the enforcement constraint
- WitnessCS::extend() skips aux[0] like it skips input[0]
- AllocatedNum::zero() wraps CS::zero() with no constraints
- alloc_zero() delegates to AllocatedNum::zero()
- Net savings: ~7 constraints per augmented circuit
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a built-in “zero wire” (Aux(0)) across the bellpepper-style constraint systems in this repo, enforced once at CS construction time via a 0 * 0 = Aux(0) constraint. This makes AllocatedNum::zero() / alloc_zero() effectively free and reduces constraint counts in Nova/Neutron augmented circuits.

Changes:

  • Add ConstraintSystem::zero() -> Variable (defaulting to Aux(0)) and thread it through wrapper CS types.
  • Initialize all CS implementations with Aux(0)=0 plus a single enforcement constraint 0 * 0 = Aux(0); ensure WitnessCS::extend() skips aux[0].
  • Switch AllocatedNum::zero() and alloc_zero() to use the built-in zero wire; update expected digests/constraint-count tests accordingly.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
src/frontend/constraint_system.rs Adds ConstraintSystem::zero() and forwards it through Namespace / &mut CS impls.
src/frontend/shape_cs.rs Reserves Aux(0) and injects the single “zero enforcement” constraint into shapes.
src/frontend/util_cs/witness_cs.rs Pre-initializes aux with 0 and updates extend() to skip aux[0].
src/frontend/util_cs/test_cs.rs Test CS now starts with Aux(0)=0 and a built-in “ZERO” constraint.
src/frontend/test_shape_cs.rs Test shape CS now reserves Aux(0) and records the built-in constraint/aux name.
src/frontend/gadgets/num.rs Adds AllocatedNum::zero() and updates constraint-count assertions in tests.
src/frontend/gadgets/multieq.rs Forwards zero() through the MultiEq CS wrapper.
src/gadgets/utils.rs Makes alloc_zero() delegate to AllocatedNum::zero() (no alloc/enforce).
src/nova/circuit/mod.rs Updates expected constraint counts reflecting net savings.
src/nova/mod.rs Updates expected public-parameter digest test vectors due to shape/witness layout changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

sai-deng added 2 commits April 3, 2026 04:32
… neutron expects

- Remove default impl for CS::zero(); all root CS types now provide
  explicit impls. Prevents soundness footgun for external impls.
- Add doc comment on zero() specifying implementor invariants
  (reserve Aux(0), enforce 0*0=Aux(0), exclude from alloc).
- Add test_allocated_num_zero unit test.
- Fix extend() comments to say 'built-in reserved slot' not 'temporarily allocated'.
- Update neutron circuit constraint counts and pp_digest expects
  (behind 'experimental' feature).
Replace all 8 alloc_zero() call sites with AllocatedNum::zero::<CS>()
and remove the alloc_zero function entirely, matching how alloc_one
was previously removed in favor of AllocatedNum::one().
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants