Skip to content

BINIUS-114: switch multilinears to the monomial (infinity hypercube) basis#1565

Closed
benji-potamus wants to merge 3 commits into
mainfrom
benji/binius-114-switch-to-multilinear-monomial-basis
Closed

BINIUS-114: switch multilinears to the monomial (infinity hypercube) basis#1565
benji-potamus wants to merge 3 commits into
mainfrom
benji/binius-114-switch-to-multilinear-monomial-basis

Conversation

@benji-potamus

Copy link
Copy Markdown
Contributor

Draft — work in progress, opened for early review of BINIUS-114. Per the issue, this is one large change split by commit, and some commits are intentionally red. Not all tests pass yet — see "Open question" below; there's an active discussion on the Linear issue.

Switches the multilinear polynomial representation from the {0,1} evaluation (Lagrange) basis to the monomial basis — i.e. evaluation on the infinity hypercube {0,∞}ⁿ, where a multilinear's value list is its monomial-coefficient vector. Grounded in eprint 2026/762 and the companion spec PR binius-zk/binius.xyz#117.

Commits

1. eq indicator + multilinear fold → monomial basis (crates/math/src/multilinear/{eq,fold,evaluate}.rs)

  • eq̃(X,Y) = 1 + XY (not the char-2 1+X+Y); tensor factor (1−xᵢ, xᵢ) → (1, xᵢ); eq_ind_zero → identically 1; eq_ind_truncate_low → prefix truncation.
  • fold_highest_var_inplace: zero += r·(one−zero)zero += r·one (the two halves are now the coefficients [c0, c1]). Same change to the scalar evaluator.
  • eq_ind_partial_eval now returns monomial coefficients, so it is no longer eq_ind at literal {0,1} vertices (only under projective {0,∞} evaluation); evaluate (an inner product with that tensor) stays correct unchanged. Unit tests rewritten to the monomial-coefficient / zeta-transform invariants.
  • binius-math: all lib tests pass, clippy -D warnings clean.

2. sumcheck & MLE-check round identities → monomial basis (crates/ip/src/{sumcheck/common,mlecheck}.rs, crates/ip-prover/src/sumcheck/*)

  • Bare sumcheck verifier check R(0)+R(∞)=s; recovera_d = s − a₀.
  • MLE-check: per-prover Karatsuba half-swap (M(1)=lo+hi, M(∞)=hi), interpolate_eqy₀ = s − α·y_inf (the (1−α)⁻¹ drops out), recovera₀ = eval − α·a_d, round_coeffs_by_eqprime·(1+αX), lerp_over_endpointsr₀ + α·r_inf. gruen32 needs no change.
  • Green: test_bivariate_product_sumcheck, and the homogeneous degree-2 MLE-checks (a*b, (a+b)(c+d)) at all sizes.

Open question (blocking the rest)

Non-homogeneous / lower-degree composites — a+b and the mul gate a*b − c — reduce correctly at one round but fail across multiple rounds (the degree-2 framing's ∞ = X²-coeff doesn't match the carried claim for the lower-degree terms). I've asked on the Linear issue whether the MLE-check round poly should be the bare prime (degree d, current) or the eq-weighted degree-(d+1) poly with extracting x^{d+1}, and whether a degree-1 composition should use a degree-1 prover.

Still to come (after the above resolves)

  • Ring-switch indicator evaluation (issue item 3).
  • Downstream green-up across the workspace (prover/verifier/iop/spartan), then code review.

🤖 Generated with Claude Code

@linear-code

linear-code Bot commented Jun 23, 2026

Copy link
Copy Markdown

BINIUS-114

…oes not work under unchanged verifier)

Tests jimpo's proposed alternative for the broken non-homogeneous mul-gate
MLE-check: instead of one QuadraticMleCheckProver for A*B - C, split into a
quadratic prover for the homogeneous product A*B and a separate prover for the
multilinear C, driven in lockstep like batch_prove_mle but combined with
hardcoded weights +1/-1 instead of a random batch coefficient. The verifier is
the unchanged single degree-2 mlecheck::verify.

run_split_mul_gate_experiment is a non-panicking harness parameterized over the
C sub-prover framing (degree-1 MultilinearEvalProver vs degree-2-framed
QuadraticMleCheckProver) and the C claim (evaluate(C,point) vs c[0]).
test_split_mul_gate_experiment_matrix tabulates outcomes:

  MultilinearEvalProver (deg1) | claim_C=evaluate(C) | n=1:FAIL n=2:FAIL n=3:FAIL n=8:FAIL
  QuadraticMleCheckProver (deg2)| claim_C=c[0]       | n=1:PASS n=2:FAIL n=3:FAIL n=8:FAIL

Conclusion: the split does not rescue the protocol under the unchanged degree-2
verifier. The verifier's per-round identity eval = R(0) + alpha*R(inf) extracts
exactly one infinity coefficient (the degree-2 leading = the product's a1*b1).
A lower-degree term like -C carries infinity-hypercube mass through its own
degree-1 leading coefficient, for which the degree-2 framing has no slot: framing
C at degree 2 zeroes that mass (reproducing the original multi-round bug — deg2 +
c[0] passes only at n=1, then matches the single prover), and framing C at degree
1 makes the carried claim over-count C's infinity mass so the verifier's single
infinity slot cannot carry it (fails even at n=1). The fix must live in the round
polynomial / verifier identity (e.g. the eq-weighted degree-(d+1) form), not in
how provers are composed.
@jimpo jimpo closed this Jul 17, 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