Zeeka saysKZG commits to a whole polynomial in one group element, then opens it at any point with a constant-size proof — the divisibility check (x−z) | (p(x)−y) is its heart.
KZG (Kate) commitments compress an entire polynomial into a single group element using a trusted-setup structured reference string. To open p(x) at a point z with claimed value y, the prover shows that p(x) − y is divisible by (x − z) — equivalently, that the quotient q(x) = (p(x) − y)/(x − z) exists with no remainder. Verification is one pairing equation and constant-size, no matter how big the polynomial.
KZG underpins proto-danksharding blobs (EIP-4844) and many zk-rollups because it lets a chain commit to large data and later prove individual pieces cheaply. The full scheme hides the evaluation behind pairings; the demo runs the real polynomial-division identity over GF(97), which is exactly the algebra the proof certifies.
Power-ups you unlock
Commit to p(x) as a single point using a trusted-setup SRS
To open at z: prove p(x) − y is divisible by (x − z)
The quotient q(x) = (p(x) − y)/(x − z) is the proof
Verification is one pairing equation, constant size
Powers proto-danksharding blobs and many zk-rollups
The Collision attacks — common mistakes
Trusting a setup whose toxic waste was not destroyed
Opening at a point where divisibility fails (invalid proof)
Confusing the commitment with a hash — it is algebraic, not a digest
Treating the division demo as the full pairing-secured scheme
Boss battleFor p(x)=5+3x+2x² over GF(97), open at z=4 and verify p(x)−y is divisible by (x−4).
Example code
<!doctype html><html><head><meta charset="utf-8"></head>
<body style="background:#06040d;color:#e6e0ff;font-family:monospace;padding:20px"><pre id="o"></pre>
<script>
// KZG core (illustrative): opening p(x) at z proves (x−z) | (p(x)−y).
// Real polynomial division over GF(97); pairing-hiding is described in the lesson.
const p=97, mod=(n)=>((n%p)+p)%p;
const pwf=(a,e)=>{ let r=1; a=mod(a); while(e>0){ if(e&1) r=mod(r*a); a=mod(a*a); e>>=1; } return r; };
const ev=(c,x)=> mod(c.reduce((s,a,i)=> s + a*pwf(x,i), 0));
const P=[5,3,2], z=4; // p(x) = 5 + 3x + 2x² (low→high)
const y = ev(P,z); // claimed evaluation p(z)
const hi=[...P].reverse(); hi[hi.length-1]=mod(hi[hi.length-1]-y); // p(x) − y, high→low
const qHi=[]; let carry=0, rem=0; // synthetic division by (x − z)
for(let i=0;i<hi.length;i++){
const cur=mod(hi[i]+carry);
if(i<hi.length-1){ qHi.push(cur); carry=mod(cur*z); } else { rem=cur; }
}
const q=[...qHi].reverse(); // quotient, low→high
const r=11; // spot-check at a random point
const recon = mod( ev(q,r)*mod(r - z) + y ); // q(x)·(x−z) + y
document.getElementById('o').textContent = [
'p(x) = 5 + 3x + 2x² over GF(97)',
'open at z=4 → y = p(4) = ' + y,
'quotient q(x) coeffs (low→high) = [' + q.join(', ') + '] remainder = ' + rem,
'check q(x)·(x−z)+y at x=11 → ' + recon + ' p(11) = ' + ev(P,r),
'divisible? ' + (rem === 0 && recon === ev(P,r)) + ' → the opening is valid'
].join('\n');
</script></body></html>