Skip to content

KZG Correctness + Function Binding#263

Draft
tobias-rothmann wants to merge 49 commits intomainfrom
kzg
Draft

KZG Correctness + Function Binding#263
tobias-rothmann wants to merge 49 commits intomainfrom
kzg

Conversation

@tobias-rothmann
Copy link
Collaborator

@tobias-rothmann tobias-rothmann commented Oct 20, 2025

  • Update the KZG to computable polynomials
  • Update CommitmentScheme to use a KeyGen function
  • Instantiate the KZG as a CommitmentScheme
  • Prove Correctness for the KZG (wire-up to CommitmentScheme Correctness)
  • Formalize Function Binding in CommitmentScheme
  • Formalize ARSDH
  • Formalize the Reduction
  • Prove Function Binding for the KZG

@alexanderlhicks
Copy link
Collaborator

Thanks for the PR!
Just a heads up that we should be splitting off computable polynomials into their own library. Hopefully this should happen sooner rather than later and will then require you to update your dependencies accordingly.
We also have a review bot available which can take in both external references (html or pdf) and internal (specific sections of ArkLib) and a custom prompt. This is sometimes able to catch (mis-)formalization issues and/or make helpful style suggestions, and works well as an intermediary review step for work in progress pending a manual review. Let us know if/when that would be helpful.

Comment on lines +885 to +886
-- TODO is this the right place?
/-- degree is the mathlib degree + 1 -/
Copy link
Collaborator

Choose a reason for hiding this comment

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

This seems fine to me. Eventually we could have a Lemmas.lean file inside UniPoly folder for stuff like this

@tobias-rothmann
Copy link
Collaborator Author

tobias-rothmann commented Oct 21, 2025

We also have a review bot available which can take in both external references (html or pdf) and internal (specific sections of ArkLib) and a custom prompt. This is sometimes able to catch (mis-)formalization issues and/or make helpful style suggestions, and works well as an intermediary review step for work in progress pending a manual review. Let us know if/when that would be helpful.

@alexanderlhicks That sounds really helpful! Happy to use the review bot as soon as possible. Where can I find more information on that?

@alexanderlhicks
Copy link
Collaborator

/review

External:
https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf

Internal:
ArkLib/AGM/Basic.lean
ArkLib/Data/UniPoly/Basic.lean
ArkLib/CommitmentScheme/

Comments:
Please review with a focus on the use of ArkLib machinery to formalise KZG, the correctness of the formalisation with resptect to the reference paper, and indicate any potential issues or improvements that could be made.

@github-actions
Copy link

🤖 AI Review (with external context)\n\nGenerating AI review...

Excellent, I will now review the pull request based on the provided information and instructions.

Code Review Report

High-level Summary

This pull request refactors the KZG polynomial commitment scheme to use the UniPoly datatype, a computable representation of polynomials from ArkLib, instead of mathlib's Polynomial. This is a positive change that aligns with the library's goal of providing computable cryptographic components, evidenced by generateOpening and verifyOpening becoming computable (def instead of noncomputable def).

The PR also introduces a formal correctness proof for the scheme and adds key theorems to UniPoly/Basic.lean that connect UniPoly's degree with mathlib's Polynomial.natDegree.

However, the PR is currently incomplete, with sorry placeholders in the main correctness proof and a key helper theorem. There is also a significant inconsistency in the use of the parameter n (representing degree/length) that appears to cause type errors.


Correctness with Respect to Reference Paper

The formalization in ArkLib/CommitmentScheme/KZG.lean correctly models the PolyCommitDL scheme described in Section 3.2 of the reference paper ("Constant-Size Commitments to Polynomials and Their Applications").

  • commit: The implementation correctly computes C = g^φ(α) as Π (g^{α^j})^{φ_j}.
  • generateOpening: The witness w_i is correctly computed as a commitment to the quotient polynomial ψ_i(x) = (φ(x) - φ(i)) / (x - i).
  • verifyOpening: The verification check correctly and efficiently implements the identity e(C / g^{φ(i)}, g) = e(w_i, g^α / g^i) which verifies that φ(α) - φ(i) = ψ_i(α)(α - i) in the exponent.

The transition to UniPoly makes these definitions computable, which is a great improvement.


Potential Issues and Improvements

Here are specific, actionable points for improving the code.

1. Inconsistent Parameterization and Type Errors

There appears to be a critical type mismatch in the definition and usage of the commit function.

File: ArkLib/CommitmentScheme/KZG.lean

Issue:
The commit function is defined as:

def commit (srs : Vector G₁ n) (coeffs : Fin n → ZMod p) : G₁ := ...

It takes a structured reference string (srs) of length n. However, in commit_eq_UniPoly and correctness, it is called with towerOfExponents g₁ a n, which has type Vector G₁ (n + 1). This will not compile.

The parameter n should be used consistently, ideally to represent the maximum degree of the polynomial, as in the reference paper.

Suggestion:
Standardize the API around the maximum degree, let's call it d. A polynomial of degree d has d+1 coefficients. The SRS should contain d+1 elements (g, g^α, ..., g^{α^d}).

I recommend changing the signature of commit and related functions:

--- a/ArkLib/CommitmentScheme/KZG.lean
+++ b/ArkLib/CommitmentScheme/KZG.lean
@@ -48,8 +48,8 @@ def generateSrs (n : ℕ) (a : ZMod p) : Vector G₁ (n + 1) × Vector G₂ 2 :=
 
 /-- To commit to an `n`-tuple of coefficients `coeffs` (corresponding to a polynomial of degree less
     than `n`), we compute: `∏ i : Fin n, srs[i] ^ (p.coeff i)` -/
-def commit (srs : Vector G₁ n) (coeffs : Fin n → ZMod p) : G₁ :=
-  ∏ i : Fin n, srs[i] ^ (coeffs i).val
+def commit {d : ℕ} (srs : Vector G₁ (d + 1)) (coeffs : Fin (d + 1) → ZMod p) : G₁ :=
+  ∏ i : Fin (d + 1), srs[i] ^ (coeffs i).val

This change will make the parameterization consistent with the SRS generation and the degree of polynomials being committed to.

2. Incomplete Proofs

The PR is blocked by two incomplete proofs.

Issue: The theorems commit_eq_UniPoly and correctness both end in sorry. These are essential for verifying the scheme's correctness.

Suggestion:

  1. Complete commit_eq_UniPoly: The proof sketch is good, but it needs to be completed. The inconsistent parameterization mentioned above must be fixed first. Once fixed, the proof should follow from eval_eq_sum and properties of Finset.sum over a sub-range.

  2. Complete the correctness theorem: This is the main goal of the PR. The proof requires showing that the verification equation holds. Here is a high-level plan to complete the proof, which you can translate into Lean tactics:

    • Goal: verifyOpening ... C opening z v
    • Step 1: Unfold verifyOpening to get the pairing equation: pairing (C / g₁ ^ v.val) (vsrs[0]) = pairing opening (vsrs[1] / g₂ ^ z.val).
    • Step 2: Substitute vsrs with its definition from generateSrs: vsrs[0] = g₂ and vsrs[1] = g₂ ^ a.val.
    • Step 3: Use commit_eq_UniPoly to substitute C with g₁ ^ (poly.eval a).val and opening with g₁ ^ (q.eval a).val, where q is the quotient polynomial.
    • Step 4: Apply the bilinearity of the pairing map (pairing (g^x) (h^y) = pairing g h ^ (x*y)) to move all terms into the exponent of pairing g₁ g₂. The goal will become an equality in ZMod p:
      (poly.eval a - v) = q.eval a * (a - z)
      
    • Step 5: Use the properties of UniPoly. Since v = poly.eval z and q = (poly - C v) / (X - C z), you need to show that (poly - C v).eval a = q.eval a * (a - z). This follows from the fact that polynomial division guarantees poly - C v = q * (X - C z) (since z is a root of the numerator, the remainder is zero). Evaluating both sides at a completes the proof. You will likely need lemmas about UniPoly.eval respecting arithmetic operations.

3. Minor Style and Convention Issues

File: ArkLib/CommitmentScheme/KZG.lean, line 83

Issue: letI is used to introduce poly and q. letI is intended for introducing typeclass instances. For regular variable bindings, let is the standard convention.

-- Current
letI poly : UniPoly (ZMod p) := UniPoly.mk (Array.ofFn coeffs)
letI q : UniPoly (ZMod p) := ...

-- Suggested
let poly : UniPoly (ZMod p) := UniPoly.mk (Array.ofFn coeffs)
let q : UniPoly (ZMod p) := ...

This is a minor point but improves adherence to Lean conventions.

4. UniPoly Helper Theorems

File: ArkLib/Data/UniPoly/Basic.lean

The new theorems degree_toPoly and degree_toPoly' are excellent additions for bridging the gap between UniPoly and mathlib's Polynomial. The proofs are non-trivial and seem correct.

Suggestion (Optional): The proof of degree_toPoly is quite dense. Consider adding a few comments to explain the key steps, such as why coeff_last_nonzero is important and what each branch of the le_antisymm proof for natDeg_eq is establishing. This would improve maintainability.


Conclusion

This is a valuable PR that moves the KZG implementation towards being fully computable and formally verified within ArkLib. The core logic is sound and correctly follows the reference paper.

To get this merged, the primary action items are:

  1. Resolve the inconsistent parameterization of n across the API.
  2. Complete the sorry'd proofs in commit_eq_UniPoly and correctness.

Once these are addressed, this will be a strong contribution to the library.

@alexanderlhicks
Copy link
Collaborator

We also have a review bot available which can take in both external references (html or pdf) and internal (specific sections of ArkLib) and a custom prompt. This is sometimes able to catch (mis-)formalization issues and/or make helpful style suggestions, and works well as an intermediary review step for work in progress pending a manual review. Let us know if/when that would be helpful.

@alexanderlhicks That sounds really helpful! Happy to use the review bot as soon as possible. Where can I find more information on that?

See above for an example :)
You have write access to the repository so you should be able to use this as necessary. Any feedback about what more this workflow could offer is very welcome!

@tobias-rothmann
Copy link
Collaborator Author

/review

External:
https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf

Internal:
ArkLib/Data/UniPoly/Basic.lean
ArkLib/CommitmentScheme/

Comments:
Please review with a focus on the use of ArkLib machinery to formalize the KZG and instantiate it as a Commitment Scheme, focus on the correctness of the formalization with respect to the reference paper, and indicate any potential issues or improvements that could be made.

@alexanderlhicks
Copy link
Collaborator

For some reason some new dependency was required ("packaging", presumably stopped being important by something else) which was messing with the summary/review scripts but it should be fixed now.

@alexanderlhicks
Copy link
Collaborator

/review

External:
https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf

Internal:
ArkLib/Data/UniPoly/Basic.lean
ArkLib/CommitmentScheme/

Comments:
Please review with a focus on the use of ArkLib machinery to formalize the KZG and instantiate it as a Commitment Scheme, focus on the correctness of the formalization with respect to the reference paper, and indicate any potential issues or improvements that could be made.

@github-actions
Copy link

🤖 AI Review (with external context)\n\nGenerating AI review...

Excellent, this pull request introduces a formalization of the KZG polynomial commitment scheme. The approach of using the CommitmentScheme machinery from ArkLib is sound, and the transition to a computable UniPoly representation for polynomials is a significant step towards a fully executable and verifiable implementation.

Here is my detailed review with a focus on correctness with respect to the reference paper and the ArkLib framework integration.

High-Level Summary

The pull request successfully implements the core components of the KZG polynomial commitment scheme as described in the reference paper ("PolyCommitDL"). It defines the commitment, witness generation (generateOpening), and verification logic. The PR also laudably integrates this scheme into the Commitment.Scheme framework, formalizing its structure as a non-interactive proof of evaluation.

The main areas for improvement are the completion of several key correctness proofs, which are currently marked with sorry.

Formalization Correctness

The formalization of the KZG scheme aligns well with the "PolyCommitDL" construction in Section 3.2 of the reference paper.

  1. Setup (generateSrs): The generateSrs function correctly constructs the structured reference string ⟨g, g^α, ..., g^(α^t)⟩, which corresponds to the public key PK in the paper.
  2. Commit (commit): The commit function correctly implements C = g^(φ(α)) by computing the multi-exponentiation Π (g^(α^j))^φ_j.
  3. Witness Generation (generateOpening): This correctly computes the commitment to the quotient polynomial ψ_i(x) = (φ(x) - φ(i))/(x - i). The use of UniPoly.div is clean and appropriate.
  4. Verification (verifyOpening): The verification equation pairing(C / g₁^v, g₂) = pairing(opening, g₂^α / g₂^z) is a valid and correct reformulation of the equation from the paper. It correctly checks the relationship φ(α) - φ(z) = ψ_z(α)(α - z) in the exponent.
  5. Module Linearity: The change of the pairing from a -bilinear map to a ZMod p-bilinear map is an excellent improvement. It makes the formalization more precise and simplifies reasoning, as all scalar operations are naturally in ZMod p.

Actionable Suggestions

The implementation is structurally sound, but its correctness hinges on completing the proofs. Here are specific, actionable items to address.

1. Complete the correctness Theorem

The correctness theorem is the cornerstone of the scheme's soundness. The proof is currently sorry. This proof should be completed to show that honestly generated proofs are always accepted.

Recommendation:

The proof can be completed by applying the bilinearity of the pairing and the properties of polynomial evaluation. A sketch of the required argument is:

  1. Unfold all definitions (verifyOpening, commit, generateOpening, srs).
  2. Use commit_eq_UniPoly to express the commitment and the opening in terms of polynomial evaluation at a.
  3. Apply the bilinearity of the pairing to move the exponents out.
  4. The final goal is to prove poly.eval a - poly.eval z = q.eval a * (a - z). This follows from the polynomial remainder theorem: since q is the quotient of poly(X) - poly(z) by (X - z), we have poly(X) - poly(z) = q(X) * (X - z). Evaluating both sides at a yields the desired equality. You will need to formalize this property for UniPoly.

Additionally, the syntax in the theorem statement needs correction. The let bindings should be part of the proof block.

-  verifyOpening pairing (g₁:=g₁) (g₂:=g₂) vsrs C opening z v := by
-
-  intro poly v
-  unfold verifyOpening generateSrs
-  simp
-
-  have hcoeffs : coeffs = (coeff poly) ∘ Fin.val := by
-    simp_all only [poly]
-    ext x : 1
-    simp only [Function.comp_apply]
-    simp only [Array.getD_eq_getD_getElem?, Array.size_ofFn, Fin.is_lt, getElem?_pos,
-    Array.getElem_ofFn, Fin.eta, Option.getD_some]
-
-
-  have hpdeg : degree poly ≤ n+1 := by
-    simp_rw [←Trim.size_eq_degree]
-    apply le_trans (Trim.size_le_size (p := poly))
-    simp_rw [poly]
-    simp
-
-  simp_rw [hcoeffs, commit_eq_UniPoly hpG1 poly hpdeg]
-  sorry
+  verifyOpening pairing (g₁:=g₁) (g₂:=g₂) vsrs C opening z v := by
+  -- Proof logic here...
+  -- 1. Unfold definitions
+  unfold verifyOpening generateOpening commit generateSrs towerOfExponents
+  -- 2. Use `commit_eq_UniPoly` to rewrite C and opening
+  -- ...
+  -- 3. Use pairing properties.
+  -- ...
+  -- 4. Use polynomial remainder theorem for UniPoly.
+  sorry

2. Complete the Commitment.perfectCorrectness Proof

Similarly, the correctness' theorem, which proves the scheme's integration with the CommitmentScheme framework, is essential and needs to be completed.

Recommendation:

Unfold the definition of Commitment.perfectCorrectness and Commitment.correctness. The proof will involve simulating the prover and verifier runs and showing that the final verifyOpening check succeeds. This will ultimately rely on the correctness theorem you proved in the previous step.

-theorem correctness' (a : ZMod p) {g₁ : G₁} {g₂ : G₂}
-    [Fintype G₁] [Inhabited G₁] :
-    Commitment.perfectCorrectness (kzg (n:=n) (g₁:=g₁) (g₂:=g₂) (pairing:=pairing)
-    (generateSrs (g₁:=g₁) (g₂:=g₂) n a)) := by
-    set pSpec : ProtocolSpec 1 := ⟨!v[.P_to_V], !v[G₁]⟩
-    simp only [perfectCorrectness, Commitment.correctness]
-    intro data randomness query
-    set S := kzg pairing (generateSrs n a)
-    simp only [Reduction.run]
-    -- simp only [Prover.run, Verifier.run]
-    -- simp only [Prover.runToRound]
-
-
-    sorry
+theorem correctness' (hpG1 : Nat.card G₁ = p) (a : ZMod p) {g₁ : G₁} {g₂ : G₂}
+    [Fintype G₁] [Inhabited G₁] [DecidableEq G₁] :
+    Commitment.perfectCorrectness (kzg (n:=n) (g₁:=g₁) (g₂:=g₂) (pairing:=pairing)
+    (generateSrs (g₁:=g₁) (g₂:=g₂) n a)) := by
+  simp [perfectCorrectness, Commitment.correctness]
+  intro data randomness query
+  -- Unfold the scheme's run procedure
+  simp [kzg, Scheme.commit, Scheme.opening, Opening.run, Prover.run, Verifier.run, Prover.runToRound]
+  -- The logic will reduce to showing that `verifyOpening` returns true,
+  -- which is exactly the statement of the `correctness` theorem.
+  apply correctness -- (with appropriate arguments)
+  sorry

3. Complete the commit_eq_UniPoly Proof

This theorem is a key lemma connecting the commit operation to polynomial evaluation. The proof structure is good, but it ends in sorry.

Recommendation:

The remaining step is to show that the sum over poly.toPoly.support is equal to the original sum in the definition of commit. This appears to be a straightforward application of Finset.sum_congr and properties of UniPoly.coeff.

-    rw [Polynomial.sum_eq_of_subset
-      (R := ZMod p) (S := ZMod p) (p := poly.toPoly)
-      f hf (s := Finset.range (n + 1)) hs]
-    simp_rw [f, coeff_toPoly, Array.getD_eq_getD_getElem?]
-    simp only [mul_comm]
-    rw [Fin.sum_univ_eq_sum_range (fun x => a ^ x * poly[x]?.getD 0) (n+1)]
+    rw [Polynomial.sum_eq_of_subset (R := ZMod p) (S := ZMod p) (p := poly.toPoly) f hf (s := Finset.range (n + 1)) hs]
+    apply Fintype.sum_congr
+    intro x
+    rw [coeff_toPoly]
+    simp [f, mul_comm]

4. Minor: Clarify Data Type in kzg Definition

The Data type for the commitment scheme is Fin (n + 1) → ZMod p. While correct, the prover immediately converts this to a UniPoly. Consider adding a comment to clarify that this function represents the coefficients of a polynomial. The current approach is fine as using a subtype for bounded-degree UniPoly could add complexity. No change is strictly necessary, but it's worth being aware of.

UniPoly Changes

The additions to ArkLib/Data/UniPoly/Basic.lean are excellent. The degree_toPoly theorem correctly relates the degree definition of UniPoly to mathlib.Polynomial.natDegree, which is a crucial property for proving correctness of the SRS size and other degree-related arguments. The proof is detailed and appears correct.


Overall, this is a strong contribution that lays the correct foundation for the KZG scheme in ArkLib. Once the key correctness proofs are completed, this will be a valuable addition. Great work

@tobias-rothmann
Copy link
Collaborator Author

/review

External:
https://www.iacr.org/archive/asiacrypt2010/6477178/6477178.pdf

Internal:
ArkLib/Data/UniPoly/Basic.lean
ArkLib/CommitmentScheme/
ArkLib/OracleReduction/

Comments:
Please review with a focus on the use of the ArkLib machinery to instantiate the KZG as a Commitment Scheme, especially the opening Reduction, and the corresponding correctness proof correctness'. Focus on the correctness of the formalization and the proof with respect to ArkLib's Reduction and the original paper, and indicate any potential issues or improvements that could be made.

@github-actions
Copy link

🤖 AI Review (with external context)\n\nGenerating AI review...

Hello, I have reviewed the pull request. Here is my expert code review.

High-level summary

This pull request introduces a formalization of the KZG polynomial commitment scheme. The changes include:

  1. Defining the core KZG algorithms (commit, generateOpening, verifyOpening) based on the reference paper.
  2. Switching the underlying polynomial representation from mathlib's Polynomial to a custom computable UniPoly type and adding necessary helper lemmas.
  3. Instantiating KZG as a Commitment.Scheme using the ArkLib framework, where the opening proof is modeled as a non-interactive Reduction.
  4. Adding theorems to prove the correctness of the scheme, although the proofs are currently incomplete.

The formalization correctly captures the essence of the KZG scheme and demonstrates a good use of the ArkLib library's abstractions for commitment schemes and interactive proofs. However, the PR is not ready to merge due to incomplete proofs.

Review of the Formalization and Proofs

The submission correctly models the KZG scheme (referred to as PolyCommitDL in the paper) and its opening procedure. The use of the Commitment.Scheme structure with a non-interactive Reduction for the opening is a clean and appropriate way to formalize this within the ArkLib framework.

Core Logic

  • The functions commit, generateOpening, and verifyOpening correctly implement the logic described in Section 3.2 of the reference paper.
  • The verification equation pairing (commitment / g₁ ^ v.val) (verifySrs[0]) = pairing opening (verifySrs[1] / g₂ ^ z.val) is a correct translation of the identity e(C/g^v, g) = e(O, g^a/g^z), which is equivalent to the paper's verification equation.
  • The change of the pairing to be a ZMod p-bilinear map is a great improvement, making the formalization more precise.

Instantiating the Commitment Scheme

  • The kzg definition correctly instantiates Commitment.Scheme.
  • The Data type is correctly set to the polynomial's coefficients.
  • The opening is correctly modeled as a single-message Reduction (a Proof), where the prover sends the opening witness w_i and the verifier performs the pairing check. The statement for this proof is (Commitment, Query, Response), i.e., (C, z, v), which is also correct.
  • The OracleInterface instance for the coefficient function Fin (n + 1) → ZMod p is an elegant way to abstract the polynomial evaluation oracle.

Actionable Feedback

Major Issues: Incomplete Proofs

The PR is blocked by two incomplete proofs. The scheme cannot be considered correct without them.

  1. theorem correctness is sorry'd.
    This theorem is fundamental as it proves that an honestly generated opening will always be accepted by the verifier.

    Recommendation: Please complete this proof. The proof should follow from the polynomial identity p(X) - v = q(X) * (X - z), where v = p.eval(z). A sketch of the proof steps:

    1. Use commit_eq_UniPoly to express the commitment C as g₁ ^ (p.eval a).val and the opening O as g₁ ^ (q.eval a).val.
    2. Substitute these into the verifyOpening equation.
    3. Use the bilinearity of the pairing to move the exponents out. The goal becomes proving the identity p.eval(a) - v = (q.eval a) * (a - z) in the field ZMod p.
    4. This identity follows from the fact that eval a is a ring homomorphism and the definition of q.

    Potential Gap: This proof will likely require a lemma stating that UniPoly.div correctly implements polynomial division and interacts well with eval. Specifically, you may need a lemma like:

    theorem toPoly_div (p q : UniPoly (ZMod p)) :
      (p.div q).toPoly = p.toPoly / q.toPoly

    or an equivalent property relating eval and div. Please add and use such a lemma.

  2. theorem correctness' proof is incomplete.
    This theorem proves that the entire Commitment.Scheme construction satisfies perfect correctness. This proof depends on the correctness theorem above.

    Recommendation: Once theorem correctness is proven, you can complete this proof. The steps should be:

    1. Unfold perfectCorrectness and correctness.
    2. Use Reduction.run_of_prover_first to expand the execution of the opening protocol.
    3. The goal will simplify to showing that the boolean result from verifier.verify is true.
    4. This follows directly from theorem correctness.

Here is an example of how you might structure the correctness proof:

theorem correctness (hpG1 : Nat.card G₁ = p) (n : ℕ) (a : ZMod p)
  (coeffs : Fin (n + 1) → ZMod p) (z : ZMod p) :
  let poly : UniPoly (ZMod p) := UniPoly.mk (Array.ofFn coeffs)
  let v : ZMod p := poly.eval z
  let (psrs,vsrs) : Vector G₁ (n + 1) × Vector G₂ 2 := generateSrs (g₁:=g₁) (g₂:=g₂) n a
  let C : G₁ := commit psrs coeffs
  let q : UniPoly (ZMod p) := UniPoly.div (poly - UniPoly.C v) (UniPoly.X - UniPoly.C z)
  let opening: G₁ := commit psrs ((coeff q) ∘ Fin.val)
  verifyOpening pairing (g₁:=g₁) (g₂:=g₂) vsrs C opening z v := by
  
  -- 1. State polynomial identity
  have h_poly_identity : poly - UniPoly.C v = q * (UniPoly.X - UniPoly.C z) := by
    -- This will require a proof about UniPoly.div, e.g., using toPoly
    sorry

  -- 2. Use eval as a homomorphism on the identity
  have h_eval_identity : (poly - UniPoly.C v).eval a = (q * (UniPoly.X - UniPoly.C z)).eval a := by
    rw [h_poly_identity]
  
  -- Assuming you have lemmas for eval_sub, eval_mul, eval_C, eval_X...
  simp only [eval_sub, eval_C, eval_mul, eval_X] at h_eval_identity
  -- h_eval_identity is now `poly.eval a - v = q.eval a * (a - z)`

  -- 3. Unfold verifyOpening and substitute commitments
  unfold verifyOpening
  
  have hC : C = g₁ ^ (poly.eval a).val := by
    -- Use commit_eq_UniPoly
    sorry
  
  have hO : opening = g₁ ^ (q.eval a).val := by
    -- Use commit_eq_UniPoly
    sorry
  
  rw [hC, hO]
  
  -- 4. Use bilinearity of pairing to prove the final goal
  -- This step involves manipulating group operations and pairing properties
  -- to show both sides are equal, using h_eval_identity.
  sorry

Conclusion

This is a valuable contribution that formalizes an important cryptographic primitive. The modeling choices are excellent. The main blocker is the incompleteness of the correctness proofs. Once those are addressed (including any necessary lemmas about UniPoly), this PR will be in great shape.

@tobias-rothmann
Copy link
Collaborator Author

/review

External:
https://eprint.iacr.org/2025/902.pdf

Internal:
ArkLib/CommitmentScheme/
ArkLib/OracleReduction/
ArkLib/Data/UniPoly/Basic.lean

Please review the formalization of the Function Binding reduction from the paper’s Proof of Lemma 9.1, with particular attention to the definition map_FB_instance_to_ARSDH_inst.
Your review should address:

  • Correctness of the reduction — Does the formalization faithfully implement the reduction described in the paper?
  • Integration with ArkLib — Does the construction align properly with the surrounding ArkLib framework and its conventions?

Additionally, please review the formalization of the functionBinding theorem and evaluate whether it correctly states the result implied by the Function Binding reduction.

@github-actions
Copy link

🤖 AI Review (with external context)\n\nGenerating AI review...

Excellent, this pull request aims to formalize the KZG polynomial commitment scheme and its function binding security property based on the ARSDH assumption, as detailed in the paper "On the Fiat–Shamir Security of Succinct Arguments from Functional Commitments." This is a significant contribution to the library.

My review focuses on the correctness of the formalization against the paper, its integration with the existing ArkLib framework, and the completeness of the implementation.

High-Level Summary

The pull request introduces the following key changes:

  1. KZG Commitment Scheme: A formalization of the KZG polynomial commitment scheme is added in ArkLib/CommitmentScheme/KZG.lean, defining its key generation, commitment, and opening procedures as a Commitment.Scheme.
  2. Function Binding Security: The Commitment.Scheme framework in ArkLib/CommitmentScheme/Basic.lean is extended with a formal definition of functionBinding, a crucial security property for functional commitments.
  3. Hardness Assumptions: A new file, ArkLib/CommitmentScheme/HardnessAssumptions.lean, is introduced to define the Adaptive Rational Strong Diffie-Hellman (ARSDH) assumption.
  4. Security Reduction: The core of the PR is the formalization of the security reduction from KZG's function binding property to the ARSDH assumption. This is implemented in ArkLib/CommitmentScheme/KZG.lean.
  5. Computable Polynomials: The UniPoly library for computable polynomials is extended with essential functionalities for Lagrange interpolation.

Overall, the structure is sound, and the formalization closely follows the provided reference material. However, the implementation is currently incomplete, with several key components marked as sorry.

Conformance with Reference Document

The formalization of the function binding property and the structure of the security reduction align well with the definitions and proofs in the provided paper (eprint.iacr.org/2025/902.pdf).

  • The definition of Commitment.functionBinding in ArkLib/CommitmentScheme/Basic.lean correctly captures the essence of Definition 3.17 from the paper, generalized to an interactive opening protocol.
  • The reduction in ArkLib/CommitmentScheme/KZG.lean correctly outlines the two cases from the "Proof of Lemma 9.1": one for handling inconsistent evaluations (evaluation binding failure) and one for handling degree violations.
  • The theorem statement functionBinding in KZG.lean accurately reflects the main result of Lemma 9.1, which bounds the function binding error by the ARSDH advantage.

Specific, Actionable Feedback

While the overall direction is excellent, several areas require attention before this PR can be merged. The most critical issue is the incompleteness of the proofs.

1. Incomplete Proofs and sorrys

The PR contains a significant number of sorry placeholders. These must be completed to ensure the correctness of the formalization.

  • Critical: The core security reduction in ArkLib/CommitmentScheme/KZG.lean relies on map_FB_instance_to_ARSDH_inst, which in turn depends on several sorry'd components like choose_S_conflict and Lagrange interpolation on UniPoly. The final proof in the functionBinding theorem is also sorry.
  • Fundamental: Many new additions to ArkLib/Data/UniPoly/Basic.lean, such as the Lagrange interpolation functions and algebraic properties (CommMonoid instance), are placeholders. These are foundational for the KZG proofs and must be implemented and proven correct.

Recommendation: Please prioritize completing the proofs in ArkLib/Data/UniPoly/Basic.lean first, as the correctness of the KZG formalization depends heavily on them. Then, fill in the sorrys within the security reduction in KZG.lean.

2. Logical Error in Reduction Logic

There appears to be a logical error and an omission in the implementation of the first case of the reduction (when an evaluation binding conflict is found).

File: ArkLib/CommitmentScheme/KZG.lean

Issue: The function choose_S_conflict is intended to implement Step 3a from the paper's proof of Lemma 9.1: "Choose S to be a size-(D + 1) subset of 𝔽 such that αᵢ∈ S...". The current implementation has two issues:

  1. It takes n elements, but it should be n + 1 (or D + 1 in the paper's notation).
  2. It does not ensure αᵢ is in the set S. The comment ∪ {αᵢ} suggests this was intended, but it's missing from the code.

Suggested Change:

-- ArkLib/CommitmentScheme/KZG.lean

-- ...
/- step 3 a) Choose S to be a size-(D + 1) subset of 𝔽 such that αᵢ∈ S and [Zₛ(τ)]₁ ≠ [0]₁ -/
def choose_S_conflict (αᵢ : ZMod p) (srs : Vector G₁ (n + 1) × Vector G₂ 2)
    (hn : 1 ≤ n) : Finset (ZMod p) :=
  -- This logic is complex and may need a more robust way to find a non-zero Zₛ(τ).
  -- For now, let's fix the size and inclusion issues.
  let other_elements := (Array.range p).filterMap fun i =>
    if h : i < p then
      let x : ZMod p := (⟨i, h⟩ : Fin p)
      -- A simple filter to get some other elements. This might not be sufficient to guarantee Zₛ(τ) ≠ 0.
      if x ≠ αᵢ then some x else none
    else none
  -- Take n elements and add αᵢ to get a set of size n+1
  (other_elements.take n).toList.toFinset ∪ {αᵢ}

3. Separation of Concerns for Hardness Assumptions

Placing scheme-specific setup functions like generateSrs and towerOfExponents in ArkLib/CommitmentScheme/HardnessAssumptions.lean mixes concerns. This file should ideally contain only the abstract hardness assumptions.

Recommendation: Move towerOfExponents and generateSrs from HardnessAssumptions.lean to KZG.lean, as they are part of the KZG scheme's trusted setup.

4. UniPoly Correctness

The UniPoly type is crucial here. The new CommMonoid instance has sorry'd proofs. Polynomial multiplication is non-trivial to implement correctly and prove. Furthermore, UniPoly equality is physical array equality, which is not the same as polynomial equality (which should be agnostic to trailing zeros).

Recommendation:
Ensure the proofs for the CommMonoid instance correctly handle the notion of polynomial equivalence (perhaps by using trim before comparison). It seems you are building this with equiv and trim, which is the right path, but it needs to be completed. A correct toPoly_mul theorem will be a key part of this.

-- In ArkLib/Data/UniPoly/Basic.lean
theorem toPoly_mul {p q : UniPoly R} : (p * q).toPoly = p.toPoly * q.toPoly := by
  -- This proof will be essential. It should show that your `mul` implementation
  -- correctly computes the convolution of coefficients.
  ext n
  rw [Polynomial.coeff_mul, coeff_toPoly]
  -- ... prove that (p * q).coeff n is the convolution sum
  sorry -- This needs to be implemented.

Conclusion

This is a well-structured and promising PR that tackles a complex but important formalization task. The main blocker is the widespread use of sorry. Once the proofs are completed and the minor logical issue in the reduction is addressed, this will be a valuable addition. I'm looking forward to seeing the completed version

@github-actions
Copy link

github-actions bot commented Jan 9, 2026

🤖 Gemini PR Summary

This Pull Request advances the formalization of the KZG (Kate-Zaverucha-Goldberg) polynomial commitment scheme and its security properties. The primary focus is on standardizing the commitment scheme interface to include key generation, formalizing the Adaptive Rational Strong Diffie–Hellman (ARSDH) assumption, and proving the correctness and function binding properties of KZG.

Features

  • KZG Implementation: Formalized the KZG polynomial commitment scheme as a functional commitment scheme.
  • Security Formalization: Introduced the "Function Binding" security property and the Adaptive Rational Strong Diffie–Hellman (ARSDH) hardness assumption, including its associated security experiment.
  • Interface Upgrade: Updated the CommitmentScheme definition to support key generation, specifically introducing Commitment Keys (CK) and Verification Keys (VK).
  • Algebraic Enhancements: Expanded the UniPoly library by adding CommMonoid instances and providing lemmas to map UniPoly operations to Mathlib’s Polynomial equivalents.
  • Probabilistic Reasoning: Added utility lemmas and congruence rules for reasoning about distributional equivalence in OracleComp and StateT.

Fixes

  • Interface Alignment: Updated the SimpleRO commitment scheme to comply with the revised CommitmentScheme interface (incorporating public/verification keys).
  • Proof Stability: Updated identity reduction completeness proofs in OracleReduction to explicitly unfold definitions, ensuring more robust simplification during verification.

Refactoring

  • Namespace Organization: Exported HardnessAssumptions within the CommitmentScheme namespace in the top-level ArkLib module for better discoverability.
  • Polynomial Mapping: Established a more formal morphism (toPoly) between internal polynomial representations and Mathlib to leverage existing algebraic theorems.

Documentation

  • None specifically noted in the file changes, though the formalizations serve as executable specifications for the schemes and assumptions.

Analysis of Changes

Metric Count
📝 Files Changed 8
Lines Added 1307
Lines Removed 75

sorry Tracking

✅ **Removed:** 2 `sorry`(s)
  • def interpolate {R : Type*} [Ring R] (n : ℕ) (ω : R) (r : Vector R n) : UniPoly R in ArkLib/Data/UniPoly/Basic.lean
  • def nodal {R : Type*} [Ring R] (n : ℕ) (ω : R) : UniPoly R in ArkLib/Data/UniPoly/Basic.lean
❌ **Added:** 16 `sorry`(s)
  • theorem degree_div [Field R] {p q : UniPoly R} (hq : q.trim ≠ 0) : degree (p.div q) ≤ degree p in ArkLib/Data/UniPoly/Basic.lean
  • theorem mul_comm' {R : Type*} [CommRing R] [BEq R] [LawfulBEq R] in ArkLib/Data/UniPoly/Basic.lean
  • lemma FB_cond_le_ARSDH_cond {n L : ℕ} {AuxState : Type} [SelectableType G₁] in ArkLib/CommitmentScheme/KZG.lean
  • theorem degree_sub [Field R] (p q : UniPoly R) : degree (p - q) ≤ max (degree p) (degree q) in ArkLib/Data/UniPoly/Basic.lean
  • def find_S (srs : Vector G₁ (n + 1) × Vector G₂ 2) (cm : G₁) (diversion : ZMod p × ZMod p × G₁) in ArkLib/CommitmentScheme/KZG.lean
  • theorem toPoly_mul {p q : UniPoly R} : (p * q).toPoly = p.toPoly * q.toPoly in ArkLib/Data/UniPoly/Basic.lean
  • theorem monic_X_sub_C (x : R) : monic (UniPoly.X - UniPoly.C x) in ArkLib/Data/UniPoly/Basic.lean
  • lemma vector_map_mapM {n : ℕ} (xs : Vector α n) in ArkLib/ToVCVio/DistEq.lean
  • theorem mul_assoc' {R : Type*} [CommRing R] [BEq R] [LawfulBEq R] in ArkLib/Data/UniPoly/Basic.lean
  • theorem toPoly_divByMonic {R : Type*} [Field R] [BEq R] {p q : UniPoly R} (hq : monic q) : in ArkLib/Data/UniPoly/Basic.lean
  • theorem one_mul' {R : Type*} [CommRing R] [BEq R] [LawfulBEq R] in ArkLib/Data/UniPoly/Basic.lean
  • lemma ARSDH_game_eq {n L : ℕ} {AuxState : Type} [SelectableType G₁] in ArkLib/CommitmentScheme/KZG.lean
  • theorem mul_one' {R : Type*} [CommRing R] [BEq R] [LawfulBEq R] in ArkLib/Data/UniPoly/Basic.lean
  • def map_FB_instance_to_ARSDH_inst' {L : ℕ} in ArkLib/CommitmentScheme/KZG.lean
  • theorem toPoly_div {R : Type*} [Field R] [BEq R] {p q : UniPoly R} : in ArkLib/Data/UniPoly/Basic.lean
  • theorem degree_divByMonic [Field R] {p q : UniPoly R} (hq : monic q = true) : in ArkLib/Data/UniPoly/Basic.lean
✏️ **Affected:** 2 `sorry`(s) (line number changed)
  • def commitmentScheme : Commitment.Scheme (oSpec α β γ) α β γ Unit Unit !p[] where in ArkLib/CommitmentScheme/SimpleRO.lean moved from L60 to L61
  • def hiding' (scheme : Scheme oSpec Data Randomness Commitment ComKey VerifKey pSpec) : Prop in ArkLib/CommitmentScheme/Basic.lean moved from L165 to L255

🎨 **Style Guide Adherence**

ArkLib/CommitmentScheme/Basic.lean

  • Lines 1-13 (File Header): Violates "Include a References section: Each file that cites papers should have a ## References section in its docstring header."
  • Line 181: def functionBinding_Experiment violates "Please follow the mathlib Style Guide. This covers naming conventions..." (Mathlib naming: definitions of terms should be lowerCamelCase).
  • Line 211: Note: This is an adaption of the function binding property introduced in https://eprint.iacr.org/2025/902 -/ violates "Use citation keys in text: Reference papers with citation keys like [ACFY24] rather than full titles or URLs."
  • Lines 458, 465, 474, 495: def FB_cond, def FB_cond_ext, def FB_game, def FB_game_ext violate "Please follow the mathlib Style Guide. This covers naming conventions..." (Mathlib naming: definitions of terms should be lowerCamelCase).

ArkLib/CommitmentScheme/HardnessAssumptions.lean

  • Lines 1-8 (File Header): Violates "Include a References section: Each file that cites papers should have a ## References section in its docstring header."
  • Line 63: noncomputable def ARSDH_Experiment violates "Please follow the mathlib Style Guide. This covers naming conventions..." (Mathlib naming: definitions of terms should be lowerCamelCase).
  • Line 74: Taken from Def. 9.6 in "On the Fiat–Shamir Security of Succinct Arguments from Functional Commitments" (see https://eprint.iacr.org/2025/902.pdf) violates "Use citation keys in text: Reference papers with citation keys like [ACFY24] rather than full titles or URLs."

ArkLib/CommitmentScheme/KZG.lean

  • Lines 1-10 (File Header): Violates "Include a References section: Each file that cites papers should have a ## References section in its docstring header."
  • Lines 333: ...from Chiesa, Guan, Knabenhans, and Yu's "On the Fiat–Shamir Security of Succinct Arguments from Functional Commitments" (https://eprint.iacr.org/2025/902.pdf). violates "Use citation keys in text: Reference papers with citation keys like [ACFY24] rather than full titles or URLs."
  • Lines 352, 367, 374, 380, 387, 401, 425, 432: def find_conflict, def choose_S_conflict, def erase_duplicates, def find_diversion, def find_S, def map_FB_instance_to_ARSDH_inst', def map_FB_instance_to_ARSDH_inst, def map_FB_to_ARSDH violate "Please follow the mathlib Style Guide. This covers naming conventions..." (Mathlib naming: definitions of terms should be lowerCamelCase).
  • Line 414: The redution follows the proof of lemma 9.1 (under Def. 9.6) in https://eprint.iacr.org/2025/902.pdf -/ violates "Use citation keys in text: Reference papers with citation keys like [ACFY24] rather than full titles or URLs."

📄 **Per-File Summaries**
  • ArkLib.lean: This change exports the HardnessAssumptions module within the CommitmentScheme namespace.
  • ArkLib/CommitmentScheme/Basic.lean: The changes update the commitment scheme definition to include key generation (adding commitment and verification keys) and introduce a new function binding security property.
  • ArkLib/CommitmentScheme/HardnessAssumptions.lean: This file defines the Adaptive Rational Strong Diffie–Hellman (ARSDH) hardness assumption and its associated security experiment for use in proving the security of commitment schemes.
  • ArkLib/CommitmentScheme/KZG.lean: This update formalizes the KZG polynomial commitment scheme as a functional commitment scheme and provides formal proofs for its correctness and function binding property under the ARSDH hardness assumption.
  • ArkLib/CommitmentScheme/SimpleRO.lean: Update the commitmentScheme definition to include key generation and align with a revised interface that incorporates public and verification keys.
  • ArkLib/Data/UniPoly/Basic.lean: This PR establishes the algebraic properties of UniPoly by adding a CommMonoid instance and providing numerous lemmas that map its operations—such as multiplication, division, and degree—to their Mathlib Polynomial equivalents via the toPoly morphism.
  • ArkLib/OracleReduction/Security/Basic.lean: Update the proofs for identity reduction completeness to explicitly unfold relevant definitions during simplification.
  • ArkLib/ToVCVio/DistEq.lean: Adds a collection of utility lemmas and congruence rules to facilitate reasoning about the distributional equivalence of probabilistic computations involving OracleComp and StateT.

Last updated: 2026-02-04 08:09 UTC.

@Verified-zkEVM Verified-zkEVM deleted a comment from github-actions bot Feb 13, 2026
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.

3 participants

Comments