Skip to content

Commit the Miller value only when the degree needs it: −15% transaction weight - #2

Merged
mjthatch merged 1 commit into
research/poly-identityfrom
research/sparse-commit
Oct 20, 2026
Merged

mjthatch merged 1 commit into
research/poly-identityfrom
research/sparse-commit

Conversation

@mjthatch

@mjthatch mjthatch commented Oct 14, 2026 •

Copy link
Copy Markdown
Collaborator

Stacked on #1 (one polynomial identity).

Summary

After #1 the transaction weight comes from bytes, not cost: the program's bytes earn more budget than it spends. The biggest part of the witness was the 88 committed Miller values (12 words each, 34 kB). This PR commits only 35 of them.

#1 this PR
program cost 81.7 M mWU 68.5 M mWU
pruned program 61.4 kB 60.3 kB
witness 45.3 kB 29.7 kB
spend on Elements 23.3.1 regtest 107.4 kWU, 26.9 kvB 90.8 kWU, 22.7 kvB
relations, degree of S, coefficients of Q 203, 61, 50 150, 211, 200

How it works

When step i doesn't commit f', the relation f² ℓ_B ℓ_γ ℓ_δ − f' is dropped. f' then becomes the product itself, a polynomial of higher degree, and the next committed relation checks the steps since the last commitment at once. The program doesn't need f' at all: it carries the number e' = f'(z) = e² ℓ_B(z) ℓ_γ(z) ℓ_δ(z) to the next step. The slope and inverse relations of every step stay as before.

Each skipped commitment saves 12 witness words but raises the degree of the identity, and Q grows by one word per degree. schedule(cap) walks the steps left to right and skips a commitment whenever the degree of S stays within the cap. Of all caps, 211 gives the fewest words: 35 commitments and a 200-word Q, against 88 and 50 before. That's 20.6 kB of committed words instead of 35.4 kB. Soundness is unchanged in kind; the bound goes from 61/p to 211/p per hash query, still about 2⁻²⁴⁵.

Steps without a commitment use their own functions (STEP_D_, STEP_F_): no 12-term dot product, no 2-bit checks, no hashing of f'. A doubling without a commitment costs 0.39 M mWU, with one 0.61 M.

A 200-word Q would have added 7 kB of unrolled code. Instead Q(z) is evaluated by one shared function, QCHUNK: qz' = qz·z⁸ + (8 coefficients at z), 25 calls on 8-word halves of Q's hashing blocks. Its code is in the program once, and the pruned program ends up 1 kB smaller than before.

Changes

  • groth/pairing.py:
    • COMMIT = schedule(DEG_CAP);
    • relations(..., commit);
    • the prover commits only the scheduled values;
    • step functions per (kind, commit);
    • QCHUNK;
    • leaf layout per step.
  • tests/test_pairing.py: the tampered Miller value is now taken at a committed step.
  • Docs, benchmarks, README cost table, examples/multiplier/ regenerated from a new regtest spend.

Testing

  • All tests pass (fp, poly, curve, pairing, g2_check, binding, groth16, bn254_ref), with predicted costs equal to hand's.
  • The tampered witnesses, re-sealed with r, Q and z recomputed, are rejected: wrong slope, wrong committed Miller value, wrong inverse, wrong s, wrong challenge.
  • Elements 23.3.1 regtest, tools/regtest.sh:
    • proof spend beba377d…: 90,804 WU;
    • the redirected proof is rejected (Assertion failed inside jet);
    • second spend 511a3da3… (the example files);
    • key-path spend 5b6b46f1….
  • The example's program and witness regenerate byte for byte.

Where the bytes go now

bytes
line constants of γ, δ (4 words per pair and step) 22,528
program code ~26,000
35 Miller values 13,440
MSM (selected entries and pruned case branches) ~11,400
Q 6,400
B's slopes 5,632

Cost is 68.5 M against a 90.2 M budget, so there's room to trade cost for bytes next.

🤖 Generated with Claude Code

After the polynomial identity the weight is set by bytes, and most of
the witness was the 88 committed Miller values.  A step without a
commitment drops its main relation: f' is the product itself, and the
next committed relation checks both steps.  schedule(cap) skips a
commitment whenever S stays within the degree cap; 211 gives the fewest
words: 35 Miller values and a quotient of 200 words, against 88 and 50.

Q(z) is evaluated eight coefficients at a time by one shared function,
so the larger quotient adds no unrolled code.

Regtest spend: 107.4 kWU -> 90.8 kWU; cost 81.7 M -> 68.5 M mWU.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@mjthatch
mjthatch force-pushed the research/poly-identity branch from 7238b04 to eb91114 Compare October 15, 2026 11:27
@mjthatch
mjthatch force-pushed the research/sparse-commit branch from b94abe5 to eede6aa Compare October 15, 2026 11:27
@mjthatch
mjthatch merged commit 01b9c51 into research/poly-identity Oct 20, 2026
16 checks passed
mjthatch added a commit that referenced this pull request Oct 20, 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.

2 participants