articleJul 23, 2025
Exploring KZG polynomial commitments
Why constant-size polynomial commitments beat per-coefficient Pedersen commits, how pairings and t-SDH/t-BSDH underwrite KZG, and the Setup / Commit / CreateWitness / VerifyEval flow.
Exploring KZG polynomial commitments
Review: Constant-Size Commitments to Polynomials and Their Applications
This note answers a basic question: why should we use polynomial commitment schemes instead of existing commitment schemes like Pedersen commitments? While Pedersen commitments are well-suited for committing to message strings, they prove inefficient when we need to hide an entire polynomial while revealing only specific evaluation values. Moreover, if we commit to polynomial coefficients individually, the commitment size grows proportionally to the polynomial degree—a significant drawback. In essence, polynomial commitments address a crucial need in cryptographic protocols: hiding not just single values but entire collections of data or functions themselves while still proving their properties. Before examining polynomial commitment schemes, we need to understand Pedersen commitments.
1. Pedersen Commitment Scheme
"Individually..." Essentially, this is a commitment for single values—to commit to n values, you must create n independent commitments.
Assuming we have n messages m₁, m₂, ..., mₙ, we can express this as follows:
\begin{align} C_1 &= g^{m_1}h^{r_1} \ C_2 &= g^{m_2}h^{r_2} \ &\vdots \ C_n &= g^{m_n}h^{r_n} \end{align}
This generates n commitments (C₁, C₂, ..., Cₙ). To prove that mᵢ is correct, one must reveal rᵢ and verify that it matches Cᵢ.
Security Properties
Each Pedersen commitment fundamentally possesses hiding and binding properties:
-
Hiding
- From commitment alone, no information about message can be obtained.
- Since one can select a different random value to create for , it's impossible to infer what is.
-
Binding
- The committed message is fixed based on the DLP. That is, changing to while maintaining the same commitment is considered computationally infeasible.
-
Opening and Verifying
- To prove that is correct, the committer reveals the random value used along with the message
- The verifier checks whether holds
- Since each commitment is independent, opening or verifying one commitment has no effect on the commitments of other messages.
Limitations
This becomes particularly problematic when committing to polynomial coefficients. For example, if we individually commit to the coefficients of a polynomial of degree , the total commitment size grows to group elements—increasing proportionally to the polynomial degree. This results in inefficient performance for certain cryptographic applications that require constant-size commitments (such as when revealing only polynomial evaluations while keeping the entire polynomial hidden). These limitations led to the emergence of new polynomial commitment schemes (PolyCommit_DL, PolyCommit_Ped).
2. Understanding the Concept
Why Are Pairings Necessary?
Without Pairings
Consider a typical ECC group with generator . We can easily compute values like .
-
What we can do: Verify addition/subtraction relationships in the exponent
- We can check if equals → This verifies the relationship
-
What we cannot do: Verify multiplication/division relationships in the exponent
- There's no direct way to verify if equals
- Computing from only without knowing is called the Computational Diffie-Hellman (CDH) problem—a very hard problem
In other words, we have no way to verify non-linear relationships like multiplication/division between values hidden in exponents.
With Pairings
→ The pairing of and equals the -th power of the pairing of with itself.
Verifying Multiplication Relationships in Exponents
Suppose someone claims "I know and these three numbers satisfy ." They give the verifier .
- Without pairings → We can only trust this claim
- With pairings → We can verify:
- Compute (result is )
- Compute (result is )
- Compare the two results
If they're equal, then , so we can be confident that holds.
Bilinear Pairings
Next, let's examine bilinear pairings. The choice of pairing affects not only theoretical distinctions but also implementation efficiency and security models.
The notation we'll use:
- G (Source Group): The source group. Elements are typically represented as points on an elliptic curve
- (Target Group): The target group
- g: Generator of group G, meaning all elements of G can be created by repeated operations on g (e.g., g, g², g³, ...)
- e: A function that takes two elements from group G and outputs one element in group
Bilinear pairings are broadly classified into three types.
Type 1: Symmetric Pairing
(e is a function that takes two elements from G and outputs one element in G_T)
Both input values of the pairing function come from the same group G. That is, and . This is sometimes expressed as .
Conceptually, the function must satisfy three properties:
Bilinearity
- For arbitrary integers : for all
- Specifically with generator :
- This property enables verification of multiplication relationships between values in exponents.
Non-degeneracy
- is not the identity element of . That is, .
- Ensures pairing results don't always produce meaningless values
- Non-degeneracy guarantees that operation results aren't fixed to a meaningless 1, ensuring cryptographically significant values can be generated
Computability
- For given , we can compute in polynomial time.
Type 2: Asymmetric Pairing
Type 1 can have inferior performance (element size, operation speed) compared to asymmetric pairings. Type 2 addresses these limitations.
(where ). This function takes one element from group G₁ and one element from group G₂ as inputs.
Type 2's special feature is the existence of an isomorphism (psi takes an element from group and maps it to the corresponding element in G₁). This means elements from G₂ can be easily converted to elements in .
The notation we'll use:
- (source groups): Two different groups
- (target group): The group containing pairing results
- (pairing function): where
- (isomorphism function)
- takes an element from G₂ and converts it to an element in G₁
- preserves group structure:
The existence of isomorphism is the most important distinction between Type 2 and Type 3.
The function still includes three properties, with the isomorphism affecting bilinearity:
Bilinearity
- With as generator of and as generator of :
- Due to isomorphism , relationships like (or a power of ) hold
Vulnerability Due to Property
The existence of can create vulnerabilities to specific attacks, limiting its use in certain security models. Consider the following attack scenario:
Attack Scenario: Attack
-
Assumption: The attacker knows
-
Goal: Break hash function . For example, given , the attacker wants to find 's discrete log—i.e., find where
-
Scenario:
- First use a secure hash function that hashes to group G₁. The attacker computes . P is an element of G₁.
- Attempt to find P's discrete log —i.e., find where . This is the discrete logarithm problem (DLP), which is very hard. But what if the attacker somehow learns this x? (e.g., if the protocol is designed to reveal x for certain messages)
- (Attack): The attacker now directly computes . This is an element of G₂.
- Apply isomorphism to to compute . Since preserves group structure, . If , then .
- The attacker can establish the relationship . This means becomes a (preimage) by transferring the relationship of in G₁ to G₂, breaking the independence between the two groups.
-
G₁ and G₂ should originally be separate groups. What happens in G₁ shouldn't affect G₂, and vice versa
-
But due to ψ's existence, relationships in G₁ (e.g., ) can be easily transferred to relationships in G₂ (e.g., )
-
This means the discrete logarithm problems in groups G₁ and G₂ are not independent, and information from one side can leak to the other
Type 3: Asymmetric Pairing
To address the vulnerability of Type 2, Type 3 is used. Like Type 2, the two input values come from different groups G₁ and G₂. However, no efficiently computable isomorphism exists between G₁ and G₂. That is, we can assume that converting an element from one group to an element in the other group is as hard as the discrete logarithm problem.
3. Cryptographic Assumptions
Before diving into the KZG polynomial commitment scheme, I'll discuss the assumptions used in the security proofs of the PolyCommit_DL and PolyCommit_Ped schemes.
Discrete Logarithm Assumption
Let me remind you of the DL assumption:
Given a generator of a cyclic group and a random element (where is a secret exponent), the probability that an attacker using a probabilistic polynomial-time (PPT) algorithm can find is a negligible function that becomes arbitrarily small as the security parameter grows sufficiently large.
What is the significance of the DL assumption?
While computing given and (modular exponentiation) can be performed efficiently in polynomial time (e.g., using "repeated squaring" or "Montgomery ladder exponentiation"), computing in reverse given and (finding the discrete log) has no known efficient general algorithm that can solve it in polynomial time with current computing resources. This assumption of "computational difficulty" serves as the core foundation supporting the security of many public-key cryptosystems like the Diffie-Hellman key exchange protocol. The Hiding property of the PolyCommit_DL scheme can be proven based on the DL assumption.
t-Polynomial Diffie-Hellman (t-polyDH) Assumption
This is a cryptographic assumption stating that certain computational problems are difficult to solve efficiently in specific group settings. This assumption is a generalized form of the t-Diffie-Hellman Inversion (t-DHI) assumption, and is considered stronger than the t-DHI assumption, especially for large values of t.
To understand this, let me explain step by step how t-polyDH works. For each step, I'll explain using three aspects: "Given", "Problem to solve", and "Meaning".
Step 1: Generalization - t-Diffie-Hellman Inversion Problem (t-DHI)
This explains t-DHI, the immediate predecessor of t-polyDH.
- Given: (t powers of α)
- Problem to solve: Compute
- Meaning: Even knowing polynomial values up to degree of in the exponent, computing the inverse in the exponent remains difficult.
Therefore, t-DHI quantifies the "difficulty of inversion attacks" as a basic assumption that can support the binding security of pairing-based schemes like polynomial commitments.
Polynomial Commitment Binding: In PolyCommit_DL (KZG), when ensuring that an attacker cannot extract or from a polynomial 's commitment value to arbitrarily modify , we can prove binding using the t-DHI hardness ("the fraction cannot be computed").
Step 2: Final - t-Polynomial Diffie-Hellman Problem (t-polyDH)
Looking at this assumption again, it extends the previous t-DHI problem to a more general polynomial form. In other words, t-polyDH is a hardened assumption that encompasses t-DHI.
- Given: (For a secret value , this is equivalent to receiving evaluations of polynomials in the exponent of )
- Problem to solve: Find the following pair
- : A freely chosen new polynomial
- Condition: The degree of must be greater than (restricted to )
- : The value obtained by evaluating the chosen polynomial at the secret value and placing it in the exponent of
The conclusion is that even if an attacker freely chooses a polynomial of degree higher than , it remains difficult to produce the correct computational result .
Role in KZG Polynomial Commitments
This assumption ensures the Strong Correctness property of KZG commitments—that the Committer cannot lie about the polynomial's degree.
Let's think about it:
- The system's public key () is . This system is designed to handle polynomials up to degree only.
- Assume an attacking Committer wants to commit to a polynomial of degree higher than (e.g., degree ).
- To compute the commitment, they need to calculate .
- However, since is a degree polynomial, computing using its coefficients requires the term , which is not in the public key.
- Therefore, the attacker faces the difficulty of computing using only the public key .
| Category | Description | Role |
|---|---|---|
| t-polyDH Problem | Computing for any polynomial of degree higher than using | (Cryptographic hard problem) |
| t-polyDH Assumption | The belief that solving the t-polyDH problem is infeasible | (KZG's security foundation) |
| Role in KZG | Because this assumption holds, the Committer cannot commit to polynomials of degree higher than the specified degree () | Strong Correctness (preventing degree fraud) |
t-Strong Diffie-Hellman (t-SDH) Assumption
This assumption states that certain computational problems are difficult for efficient attackers to solve. This assumption is more hardened than the t-Diffie-Hellman Inversion (t-DHI) assumption and has the characteristic that it can have "exponentially many non-trivially different solutions."
Please read the explanation from the t-SDH assumption onward with a focus on the security hardening perspective.
As a stronger assumption used to guarantee the binding property of the PolyCommit_DL/KZG scheme, it can be defined as follows:
- Select a cyclic group of order and generator according to security parameter
- Choose a secret trapdoor value
- Distribute public parameters
The assumption that the probability of an attacker finding both an arbitrary and pair simultaneously, given only the public , is negligible.
That is,
- : An arbitrary value that the attacker can freely choose
- : A group element with the inverse of "" as the exponent
Why is it Harder than t-DHI?
- t-DHI assumes the difficulty of only the case where "c=0", i.e., finding only
- t-SDH prevents creating for all values of c, thus covering a broader range where the attacker can freely choose c.
To arbitrarily forge a commitment in PolyCommit_DL (KZG)?
An attacker would need to create a form like by choosing with a polynomial like .
If the t-SDH assumption holds, all such forgery attempts become negligibly difficult.
Ultimately, t-SDH is the core security premise that ensures arbitrarily manipulating committed polynomial opening values (or evaluation proofs) cannot go undetected.
From the Attacker's Perspective
- Input
- The attacker receives a (t+1)-tuple for a randomly selected . Here, is the generator of group .
- Attacker's Goal
- Based on this input, the attacker must output a pair for an arbitrary value . That is, they must find a specific form of inverse value without knowing .
- Success Probability
- The probability that the attacker () solves this problem must be negligibly small (), where denotes a negligible function with respect to the security parameter .
What if the attacker chooses c=0?
If the attacker chooses c=0, the problem to solve becomes t-DHI itself. If t-SDH holds, then the t-DHI hardness is naturally satisfied as well.
t-Bilinear Strong Diffie-Hellman (t-BSDH) Assumption
This security assumption can be viewed as the bilinear pairing version of the previously explained t-SDH assumption. I'll explain this assumption through comparison with t-SDH.
| t-SDH | t-BSDH | |
|---|---|---|
| Given | (Same) | |
| Problem to Solve | Find pair | Find pair |
| Difference | Result is in group G | Result is in group G_T (power of ) |
| Note | "Inverse computation problem in exponent" | "Inverse computation problem in paired exponent" |
As you can see, only the result the attacker must produce has changed from a power of to a power of —the fundamental structure of the problem remains the same.
In t-BSDH, one must find the following pair :
- : A chosen number (where )
- : A value satisfying (This value is an element of group G_T)
"Given , no attacker can efficiently compute a valid pair of the form (the probability is negligibly small)."
This essentially assumes that if the t-SDH problem is hard, then finding the paired value of that result would also be hard.
Role in KZG Polynomial Commitments
The t-BSDH assumption guarantees the Binding property of Batch Opening in KZG commitments.
Batch Opening: An efficient method to bundle proofs for evaluations at multiple points into a single witness and verify them all at once.
Potential Attack Scenario
- The Committer publishes the commitment .
- Subsequently, the Committer claims through Batch Opening that "the polynomial values at the set of points match ."
- If a malicious Committer attempts to deceive in this Batch Opening, it becomes a more complex attack than forging a single-value proof.
- The Batch Opening verification equation involves multiple pairing terms, resulting in a more intricate form.
- Successfully breaching this complex verification equation mathematically implies that the attacker can solve the t-BSDH problem.
Because the t-BSDH assumption holds—that is, solving the t-SDH problem in the pairing space is difficult—the attacker cannot deceive in Batch Opening. Therefore, even when opening multiple values at once, the contents remain bound.
In conclusion, t-SDH and t-BSDH can be understood as nearly identical assumptions. The key differences are as follows:
- t-SDH → Security for single opening
- t-BSDH → Security for batch opening
4. Polynomial Commitment Scheme
In this section, we'll explore how the six algorithms—Setup, Commit, CreateWitness, VerifyEval, and others—form the complete KZG system.
Building Blocks
The Committer generates a short commitment for their chosen secret polynomial and publishes it. Later, they must prove to the Verifier that a specific evaluation at point is correct using a witness , without revealing the secret polynomial itself.
In polynomial commitments, the Committer and Prover can be considered the same entity.
Committer
- Selects their secret polynomial .
- Uses the Commit algorithm to convert it into and publishes it.
- "I've set a certain polynomial inside this , and I won't change my story later"—this is the commitment part.
Prover
- When the Verifier requests the evaluation at a specific point ,
- Computes and generates witness using the CreateWitness algorithm to prove its correctness.
- Sends the tuple to the Verifier to prove it.
To achieve these goals, the polynomial commitment scheme consists of the following six algorithms.
Before explaining these six algorithms, I'll structure the discussion around the points of "Purpose," "Input," and "Output" for each.
1.
- Purpose: Sets up the public environment needed to use the commitment scheme; this is executed only once for the entire system.
- Input:
- : The security parameter (κ-bit), where a larger number increases the system's security level.
- Takes the security parameter κ and the maximum polynomial degree as input → This generates the Structured Reference String (SRS).
- : The maximum degree of polynomials the system can handle.
- : The security parameter (κ-bit), where a larger number increases the system's security level.
- Output → pair
- Public Key (PK): Publicly available information needed for creating and verifying commitments ("Public Parameters") (e.g., ).
- Secret Key (SK): A secret value used only during the Setup phase (e.g., ). After Setup, this secret key is no longer needed in the scheme, so it can be discarded—this is known as a "trusted setup."
- If the publicly agreed-upon values from the trusted setup are not discarded, it can lead to security issues, often referred to as "cryptographic toxic waste."
2.
- Purpose: The Committer generates a commitment for their polynomial .
- Input:
- : The public key generated from Setup.
- : The polynomial to commit to (degree at most ).
- Output:
- : The commitment to the polynomial (e.g., → a single group element).
- : Additional information needed for commitment opening (not used in the basic configuration).
3.
- Input:
- Public key , commitment , polynomial , and related decryption information .
- Output:
- The committed polynomial → Can be implemented as a public coin protocol between the Prover (PPC) and Verifier (VPC).
4.
- Purpose: The Committer proves that commitment corresponds to the entire polynomial , and the Verifier confirms this. This is a stronger form of opening than revealing only specific values.
- Input:
- Verifies whether is a commitment to along with .
- Output:
- VerifyPoly returns 1 (success) or 0 (failure) as the verification result.
5.
- Purpose: Generates a 'witness' to reveal and prove only the evaluation at a specific point , without revealing the entire polynomial.
- Input:
- : Public key.
- : The original polynomial (known only to the Committer).
- : The point to evaluate (x-coordinate).
- Output:
- : The tuple to reveal.
- : Evaluation point.
- : Evaluation value at (y-coordinate).
- : The witness proving that is the correct evaluation value.
- : The tuple to reveal.
6.
- Purpose: The Verifier checks whether the evaluation value presented by the Committer is indeed the i-th evaluation () of the polynomial corresponding to commitment . The Verifier does this without knowing , using only and public information.
- Input:
- : Public key.
- : The previously published commitment.
- : The (evaluation point, evaluation value, witness) presented by the Committer.
- Output: 1 (success) or 0 (failure).
Security Requirements
For the above algorithms to operate securely, they must satisfy the following three properties.
- Correctness
- Honest users following the protocol must always succeed.
- If the Committer honestly generates and , the Verifier must always return 1 (success) when executing VerifyPoly and VerifyEval. This is the most fundamental requirement of the system.
- Binding
- Once committed, one cannot change their story later.
- This property prevents malicious Committers from cheating and is divided into two levels.
- Polynomial Binding → Keeping protection
- A malicious Committer cannot create a single commitment and later claim "This is for " while also successfully claiming "Actually, it's for a different polynomial ." In other words, must be fixed to one polynomial.
- Evaluation Binding
- This is more practically important: A malicious Committer cannot, for a single commitment and specific point , claim "The evaluation is " with a valid witness while also claiming "The evaluation is a different " with a valid witness . That is, the evaluation value for the pair must be unique.
- Polynomial Binding → Keeping protection
- Hiding
- One cannot learn the original secret information just by looking at the commitment.
- Even if a malicious Verifier sees the commitment , they must not be able to extract any information about the original polynomial .
- More specifically, even if fewer than the polynomial's degree (t) evaluation values are revealed, it must be impossible to guess the evaluation at an unrevealed point .
- Computational Hiding: Attackers with limited computational power cannot extract the information.
- Unconditional Hiding: Even attackers with unlimited computational power cannot extract the information (similar to Pedersen commitments).
Practical Implementation: Ethereum KZG Ceremony

The trusted setup described in the Setup algorithm, where the secret must be securely discarded to prevent cryptographic vulnerabilities, is critical for KZG commitments. In practice, generating the Structured Reference String (SRS) without relying on a single trusted party is achieved through multi-party computation (MPC). A prominent example is Ethereum KZG Ceremony (2023), which supported the Dencun upgrade (EIP-4844) for scalable data availability in Layer 2 rollups. Over 140,000 participants globally contributed randomness via a public protocol (https://ceremony.ethereum.org/), ensuring remains unknown as long as at least one contributor deletes their secret. This decentralized approach eliminates the "trusted authority" risk, aligning with the security requirements of PolyCommit_DL and enabling efficient, secure polynomial commitments in blockchain applications.
5. PolyCommit_DL Design Rationale
In this section, we'll explore how the abstract requirements of the polynomial commitment scheme defined earlier are implemented using concrete mathematical methods. I've implemented a Proof of Concept (POC) for this scheme and analyzed its operational process, which I'll explain here.
Concept
For any polynomial and arbitrary constant , always divides the new polynomial exactly.
(By the factor theorem for polynomials, when , the value of is , so must be a factor.)
Therefore, the quotient polynomial always exists.
PolyCommit_DL implements this property over groups where bilinear pairings are possible. That is, it is based on the algebraic attribute that perfectly divides for the polynomial .
1.
- Select groups and where a bilinear pairing is defined ( is the prime order of the group).
- Choose a generator of .
- A Trusted Authority randomly selects a secret value (alpha), and this must remain unknown to everyone.
- Computations and Outputs:
- (Secret Key): (must be discarded immediately after generation).
- (Public Key): .
- This public key is a tuple of group elements where powers of are placed in the exponent of .
- cannot be recovered from these values alone (due to the hardness of the discrete logarithm problem).
- This public key is shared by all participants in the system and constitutes a "trusted setup."
- Computations and Outputs:
POC Implementation Notes
- For the initial environment, using a primitive root as the generator is preferable, but for this POC, we assume a value of 2.
- Implements polynomial division over finite fields.
- Uses modular arithmetic instead of actual elliptic curves.
- Setup() → ():
- Trusted setup: Computes powers of and discards .
- Args:
- security_param: Security parameter .
- max_degree: Maximum supported polynomial degree .
- Returns:
- PK: Public key [].
- SK: Secret key (returned for simulation purposes; in practice, discarded immediately).
- Args:
- Randomly selects secret value (avoiding 0 and 1).
- Generates public key: [].
- Exponents are computed modulo using Fermat's Little Theorem.
- Trusted setup: Computes powers of and discards .
def __init__(self, prime: int = 2**61 - 1):
self.p = prime
self.g = 2
print(f"p = {self.p}")
print(f"g = {self.g}")
def mod_inverse(self, n: int) -> int:
return pow(n, -1, self.p)
def Setup(self, security_param: int, max_degree: int) -> Tuple[List[int], int]:
print(f"\n[Setup] max degree t = {max_degree}")
alpha = random.randint(2, self.p - 2)
print(f"secret vlaue α = {alpha}")
PK = []
for i in range(max_degree + 1):
alpha_i = pow(alpha, i, self.p - 1)
g_alpha_i = pow(self.g, alpha_i, self.p)
PK.append(g_alpha_i)
print(f"generated Public Key: {len(PK)}")
return PK, alpha2.
- Input: Public key , polynomial to commit .
- Computation:
- The Committer needs to evaluate at the secret value to get , but since they don't know , direct computation is impossible.
- Instead, use the public key to compute .
- Since are all publicly available in , the Committer can take these values, raise them to the powers of their coefficients , and multiply them together to obtain .
- Output:
- Commitment .
- No matter how large the polynomial degree is, the commitment is a single element of group . This achieves the "constant-size commitment."
POC Implementation Notes Commit() →
- Commits to the polynomial .
- Args:
- PK: Public key.
- coeffs: Polynomial coefficients (all less than ).
- Returns:
- C: Commitment .
- Initialize
C=1, then implement .
def Commit(self, PK: List[int], coeffs: List[int]) -> int:
degree = len(coeffs) - 1
print(f"\n[Commit] poly degree: {degree}")
C = 1
for i, coeff in enumerate(coeffs):
if i >= len(PK):
raise ValueError("exceed")
term = pow(PK[i], coeff, self.p)
C = (C * term) % self.p
print(f"Commitment C = {C}")
return C3.
- Purpose: The process of creating evidence that the evaluation at point is correct.
- Computation:
- The Committer first computes the quotient polynomial . Since is represented by its coefficients, this computation can be easily performed through polynomial division.
- Using the exact same method as in Commit, compute for this new quotient polynomial .
- Output:
- is the "witness," and it too is a single element of group .
POC Implementation Notes: CreateWitness(PK, \phi(x), i) → (i, \phi(i), w_i)
- Args:
- PK: Public key.
- coeffs: Polynomial coefficients.
- i: Evaluation point.
- Returns: (i, y, w_i): Evaluation point, evaluation value, witness.
- Compute (polynomial evaluation over finite fields).
2.
self._evaluate_poly(coeffs, i) - Compute quotient polynomial , with dividend: .
phi_minus_y = list(coeffs)
phi_minus_y[0] = (phi_minus_y[0] - y + self.p) % self.p- Compute divisor as coefficients :
x_minus_i = [(-i + self.p) % self.p, 1]to handle modular arithmetic.
- Compute witness :
w_i = self.Commit(PK, psi_coeffs)using the Commit algorithm with the coefficients of .
def polynomial_division_field(self, dividend: List[int], divisor: List[int]) -> Tuple[List[int], List[int]]:
rem = list(dividend)
deg_rem = len(rem) - 1
deg_div = len(divisor) - 1
if deg_div < 0:
raise ValueError("not zero.")
quot = [0] * (deg_rem - deg_div + 1)
lead_div_inv = self.mod_inverse(divisor[-1])
for i in range(deg_rem - deg_div, -1, -1):
if len(rem) - 1 < i + deg_div:
continue
coeff = (rem[i + deg_div] * lead_div_inv) % self.p
quot[i] = coeff
for j in range(deg_div + 1):
rem[i + j] = (rem[i + j] - coeff * divisor[j]) % self.p
while len(rem) > 1 and rem[-1] == 0:
rem.pop()
return quot, rem
def _evaluate_poly(self, coeffs: List[int], x: int) -> int:
y = 0
for i, coeff in enumerate(coeffs):
y = (y + coeff * pow(x, i, self.p)) % self.p
return y
def CreateWitness(self, PK: List[int], coeffs: List[int], i: int) -> Tuple[int, int, int]:
print(f"\n[CreateWitness] evaluation point i = {i}")
y = self._evaluate_poly(coeffs, i)
print(f"φ({i}) = {y} (mod {self.p})")
phi_minus_y = list(coeffs)
phi_minus_y[0] = (phi_minus_y[0] - y + self.p) % self.p
x_minus_i = [(-i + self.p) % self.p, 1]
psi_coeffs, remainder = self.polynomial_division_field(phi_minus_y, x_minus_i)
if not (len(remainder) == 1 and remainder[0] == 0):
print(f"remainder is no zero : {remainder}")
print(f"ψ_i(x) coeffs: {len(psi_coeffs)-1}")
w_i = self.Commit(PK, psi_coeffs)
print(f"Witness w_i = {w_i}")
return i, y, w_i4.
- Purpose: The Verifier uses the received from the Committer along with the previously received commitment to confirm whether truly holds. The Verifier does not know itself.
- Verification Logic:
- The Verifier checks whether the following equation holds:
- The Verifier checks whether the following equation holds:
- Why Does This Equation Hold?
- The core idea is that evaluating at gives .
- Raising this equation to the exponent of yields .
- Since and , this resembles (by exponent rules).
We cannot verify this relationship directly, so we apply the bilinear map to both sides to transform it into a verifiable form. Left Side: Right Side: - - - (assuming is correct) - - (by the core idea)
In conclusion, left side = right side holds. If the Committer fabricates the value or creates an incorrect , this equation will fail to hold with very high probability.
POC Implementation Notes
- For VerifyEval testing, we verify the equation directly at the exponent level instead of using pairings. This function aims to recover the secret value for verification purposes.
- Verification equation:
- Simplified →
Final Implementation Check
- Polynomial:
- Secret Value:
- Evaluation Point:
- Commitment :
- Evaluation :
- Quotient Polynomial :
- The quotient polynomial is of degree 1, confirming the output check.
- Witness :
- Re-calling the Commit function yields , matching this result.
- Verification:
- LHS (Left Side):
- RHS (Right Side):
- The output shows LHS and RHS values exactly match at 348765865.
- Checked based on the equation .
Attack Scenario Check
- Assume the commitment and witness are generated honestly.
- However, the Committer sends a fabricated instead of 57 to the Verifier.
Verification:
- LHS (Left Side): (unchanged).
- RHS (Right Side): .
- Since changed from 57 to 58, the term in the right side shifts from to , effectively multiplying the original right side by an extra .
- → This relation holds.
- As a result, LHS and RHS values differ, and the verification output is: failure. This confirms that the scheme's Binding property is functioning correctly.
In Summary
Since both the commitment and witness are constant size (O(1)), communication efficiency is very high. From a security perspective, not being able to recover from just relies on the hardness of the discrete logarithm (DL) problem (specifically, when fewer than points are revealed). The inability of the Committer to use fakes relies on the hardness of the t-SDH assumption. In other words, creating two different valid evaluations and for a single is as difficult as solving the t-SDH problem.
The PolyCommit_DL construction is the most basic form of the KZG (or Kate) commitment used in modern zero-knowledge proof systems.
6. PolyCommit_Ped Design Rationale
As the name suggests, "Ped" indicates that this scheme draws inspiration from the Pedersen Commitment. While PolyCommit_DL provides computational hiding, PolyCommit_Ped goes a step further by offering unconditional hiding as its most prominent feature.
Why Is It Stronger...?
A commitment of the form makes it hard to compute from the pair alone (due to the discrete logarithm problem), but theoretically, it is fixed to a unique value . The assumption is that an attacker with unlimited computational power could find this value. In contrast, the form uses both a secret value and a random value . Even given , there are infinitely many possible pairs, so cannot be pinpointed—even by an attacker with unlimited computational power. This is unconditional hiding.
PolyCommit_Ped can be seen as applying this idea to polynomial commitments.
- In addition to the original polynomial to commit to, it uses another completely randomly selected polynomial .
- Two different generators and are used to weave these two polynomials into a single commitment.
- Unconditional Hiding: It uses the same algebraic properties as PolyCommit_DL but achieves unconditional hiding by leveraging an additional random polynomial .
- Homomorphic Utilization: Combines commitments to and by exploiting the homomorphic properties of PolyCommit_DL.
- Commit: Computed as .
- Uses .
- CreateWitness: Computes and respectively, and outputs as the witness.
- VerifyEval: Verifies via .
- Security: Secure under the t-SDH assumption, with unconditional hiding.
Algorithm-Specific Implementation
1.
- Select bilinear map groups as in PolyCommit_DL.
- In addition to generator , select another generator . The discrete logarithm relationship between and must remain unknown to everyone (i.e., if , no one should know ).
- A trusted authority randomly selects a secret value .
- Computations and Outputs:
- (Secret Key): .
- (Public Key): .
- Includes two sets: the tuple of powers for and the tuple of powers for .
2.
- Input: Public key , polynomial to commit .
- Computation:
- The Committer secretly generates a random polynomial of degree . The coefficients of are chosen completely at random; this plays a role similar to the random value in Pedersen commitments.
- Commit to using and to using , then multiply the results.
- is computed using the set in .
- is computed using the set in .
- Output:
- Commitment .
- (decommitment information): Needed later for opening the commitment; here, the random polynomial itself serves as .
3.
- Purpose: The process of creating a witness for the evaluation at .
- Computation:
- The Committer computes the quotient polynomial for .
- Simultaneously, for the random polynomial , compute the evaluation at and the quotient polynomial .
- Combine and into a single witness using and .
- .
- Output:
- Here, not only but also the evaluation of the random polynomial must be revealed.
4.
- Purpose: The process for the Verifier to confirm that and .
- Verification Logic:
- The Verifier checks whether the following equation holds:
- The Verifier checks whether the following equation holds:
- Why Does This Equation Hold?
- .
- .
- .
- Substituting these relations into and simplifying shows that the left and right sides of the verification equation match.
- Left Side: .
- Right Side:
- (assuming , )
- .
- In conclusion, left side = right side holds.
Conclusion
| Property | PolyCommit_DL | PolyCommit_Ped |
|---|---|---|
| Commitment | ||
| Hiding | Computational | Unconditional |
| Binding | Relies on t-SDH assumption (computational) | Relies on t-SDH assumption (computational) |
| Setup | Tuple of powers for | Tuples of powers for and (twice as large) |
| Commitment/Witness Size | 1 group element | 1 group element |
| Opening Information | (adds random evaluation) | |
| Complexity | Relatively simple | Slightly more complex in Setup, computations, etc. |
PolyCommit_Ped provides stronger privacy protection (unconditional hiding) but at the cost of doubling the Setup size and introducing slight overhead from handling an additional random polynomial during commitment and proof. I recommend choosing the scheme based on the security level required by the specific application protocol.