@@ -580,6 +580,56 @@ func (builder *builder[E]) Compiler() frontend.Compiler {
580580 return builder
581581}
582582
583+ // AddPlonkCommitmentInputs registers variables to be committed to. The method
584+ // iterates over the variables and adds constraints to indicate they are to be
585+ // committed to. The method returns the list of constraint indexes corresponding
586+ // to each input variable. Does not perform any deduplication or constant
587+ // filtering.
588+ //
589+ // NB! This method does not create the commitment itself. The user must call the
590+ // hint for computing the commitment value, registering the commitment output
591+ // using [AddPlonkCommitmentOutputs]. Note: [AddPlonkCommitmentOutputs] already
592+ // handles adding the commitment to the constraint system, so the user does not
593+ // need to call [constraint.System.AddCommitment] separately.
594+ //
595+ // This method is not exposed in standard APIs - it is meant to be used
596+ // externally for implementing wide commitments. We also use it internally in
597+ // the [Commit] method.
598+ func (builder * builder [E ]) AddPlonkCommitmentInputs (inputs []frontend.Variable ) []int {
599+ committed := make ([]int , len (inputs ))
600+ for i , vI := range inputs { // TODO @Tabaie Perf; If public, just hash it
601+ vINeg := builder .Neg (vI ).(expr.Term [E ])
602+ committed [i ] = builder .cs .GetNbConstraints ()
603+ // a constraint to enforce consistency between the commitment and committed value
604+ // - v + comm(n) = 0
605+ builder .addPlonkConstraint (sparseR1C [E ]{xa : vINeg .VID , qL : vINeg .Coeff , commitment : constraint .COMMITTED })
606+ }
607+ return committed
608+ }
609+
610+ // AddPlonkCommitmentOutputs registers the outputs of a commitment. The method
611+ // adds constraints to the constraint system to indicate that the outputs of a
612+ // commitment will be provided at proof time. The method takes as input the list
613+ // of constraint indexes corresponding to the committed variables and the list
614+ // of output variables.
615+ //
616+ // This method is not exposed in standard APIs - it is meant to be used
617+ // externally for implementing wide commitments. We also use it internally in
618+ // the [Commit] method.
619+ func (builder * builder [E ]) AddPlonkCommitmentOutputs (committed []int , outs []frontend.Variable ) error {
620+ commitmentConstraintIndex := builder .cs .GetNbConstraints ()
621+ for _ , out := range outs {
622+ outNeg := builder .Neg (out ).(expr.Term [E ])
623+ // RHS will be provided by both prover and verifier independently, as for a public wire
624+ builder .addPlonkConstraint (sparseR1C [E ]{xa : outNeg .VID , qL : outNeg .Coeff , commitment : constraint .COMMITMENT }) // value will be injected later
625+ }
626+ return builder .cs .AddCommitment (constraint.PlonkCommitment {
627+ CommitmentIndex : commitmentConstraintIndex ,
628+ Committed : committed ,
629+ Width : len (outs ),
630+ })
631+ }
632+
583633func (builder * builder [E ]) Commit (v ... frontend.Variable ) (frontend.Variable , error ) {
584634 if smallfields .IsSmallField (builder .Field ()) {
585635 return nil , fmt .Errorf ("commitment not supported for small field %s" , builder .Field ())
@@ -588,15 +638,7 @@ func (builder *builder[E]) Commit(v ...frontend.Variable) (frontend.Variable, er
588638 commitments := builder .cs .GetCommitments ().(constraint.PlonkCommitments )
589639 v = filterConstants [E ](v ) // TODO: @Tabaie Settle on a way to represent even constants; conventional hash?
590640
591- committed := make ([]int , len (v ))
592-
593- for i , vI := range v { // TODO @Tabaie Perf; If public, just hash it
594- vINeg := builder .Neg (vI ).(expr.Term [E ])
595- committed [i ] = builder .cs .GetNbConstraints ()
596- // a constraint to enforce consistency between the commitment and committed value
597- // - v + comm(n) = 0
598- builder .addPlonkConstraint (sparseR1C [E ]{xa : vINeg .VID , qL : vINeg .Coeff , commitment : constraint .COMMITTED })
599- }
641+ committed := builder .AddPlonkCommitmentInputs (v )
600642
601643 inputs := make ([]frontend.Variable , len (v )+ 1 )
602644 inputs [0 ] = len (commitments ) // commitment depth
@@ -605,16 +647,8 @@ func (builder *builder[E]) Commit(v ...frontend.Variable) (frontend.Variable, er
605647 if err != nil {
606648 return nil , err
607649 }
608-
609- commitmentVar := builder .Neg (outs [0 ]).(expr.Term [E ])
610- commitmentConstraintIndex := builder .cs .GetNbConstraints ()
611- // RHS will be provided by both prover and verifier independently, as for a public wire
612- builder .addPlonkConstraint (sparseR1C [E ]{xa : commitmentVar .VID , qL : commitmentVar .Coeff , commitment : constraint .COMMITMENT }) // value will be injected later
613-
614- return outs [0 ], builder .cs .AddCommitment (constraint.PlonkCommitment {
615- CommitmentIndex : commitmentConstraintIndex ,
616- Committed : committed ,
617- })
650+ outs = outs [:1 ]
651+ return outs [0 ], builder .AddPlonkCommitmentOutputs (committed , outs )
618652}
619653
620654// EvaluatePlonkExpression in the form of res = qL.a + qR.b + qM.ab + qC
0 commit comments