From 31e9a25bb8f5b3e84e844fa8a23334ac013e7d10 Mon Sep 17 00:00:00 2001 From: saymrwulf Date: Tue, 7 Jul 2026 16:31:43 +0200 Subject: [PATCH] Cockpit MathML converter: sums, products, dots; verified in browser MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Extend the LaTeX→MathML converter for the deep-instrumentation notation: big operators ∏ ∑ with msubsup limits (\sum_{i=1}^{m}), ∘ ∗ ∼ log, and the dots family (\cdots ⋯, \ldots …, \vdots, \ddots). Handle _{}^{} pairs as msubsup and ignore \textstyle/\Bigg. Trim the shuffle-argument template so the core relation fits without wrapping. Verified in a real browser (6-voter run, full 2×3 shuffle matrix so every sub-argument fires): Pedersen commitment, all five Bayer-Groth sub-arguments (shuffle, product, Hadamard, zero, SVP, multi-exp), and partial decryption all render as clean typeset math with live values — no console errors. Co-Authored-By: Claude Fable 5 --- cmd/evote/web/cockpit.html | 20 ++++++++++++++++---- pkg/mixnet/shuffle_argument.go | 4 ++-- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/cmd/evote/web/cockpit.html b/cmd/evote/web/cockpit.html index 4f50363..bf38298 100644 --- a/cmd/evote/web/cockpit.html +++ b/cmd/evote/web/cockpit.html @@ -81,7 +81,11 @@ function short(s){ if(s.length<=15) return s; return s.slice(0,8)+"…"+s.slice( // ============================================================ const GREEK={sigma:"σ",gamma:"γ",rho:"ρ",pi:"π",phi:"φ",tau:"τ",lambda:"λ",mu:"μ",delta:"δ"}; const OPS={cdot:"⋅",in:"∈",gets:"←",Vert:"∥",times:"×",oplus:"⊕",bmod:"mod", + circ:"∘",ast:"∗",sim:"∼",log:"log",prod:"∏",sum:"∑", + cdots:"⋯",ldots:"…",dots:"…",vdots:"⋮",ddots:"⋱", qquad:" ",quad:" "}; +// big operators get msubsup limits from a following _{}^{} +const BIGOP={prod:"∏",sum:"∑"}; const BB={Z:"ℤ",X:"𝕏",N:"ℕ",G:"𝔾",F:"𝔽",Q:"ℚ"}; const CAL={H:"ℋ",R:"ℛ",C:"𝒞",E:"ℰ"}; const MML="http://www.w3.org/1998/Math/MathML"; @@ -117,9 +121,17 @@ function render(src,values){ const tk=toks[i]; if(tk.t==="^"||tk.t==="_"){ const base=nodes.pop()||mi(""); - const nxt=toks[++i]; - const sub=nxt.t==="grp"?groupOf(render(nxt.v,values)):renderOne(nxt,values); - nodes.push(el(tk.t==="^"?"msup":"msub",base,sub||mi(""))); + const readScript=()=>{ const nxt=toks[++i]; return nxt&&nxt.t==="grp"?groupOf(render(nxt.v,values)):(nxt?renderOne(nxt,values):null)||mi(""); }; + let sup=null,sub=null; + if(tk.t==="^") sup=readScript(); else sub=readScript(); + // pair a complementary script if the next token supplies it (x_{..}^{..}) + const nx=toks[i+1]; + if(nx&&(nx.t==="^"||nx.t==="_")&&((nx.t==="^")!==(sup!=null))){ + i++; if(nx.t==="^") sup=readScript(); else sub=readScript(); + } + if(sub&&sup) nodes.push(el("msubsup",base,sub,sup)); + else if(sub) nodes.push(el("msub",base,sub)); + else nodes.push(el("msup",base,sup)); continue; } const consume=()=>toks[++i]; @@ -157,7 +169,7 @@ function renderOne(tk,values,consume){ if(v==="sqrt"){ const a=consume&&consume(); return el("msqrt",groupOf(render(a?a.v:"",values))); } if(v==="xleftarrow"){ const a=consume&&consume(); return el("mover",mo("←"),el("mtext",a?a.v.replace(/\\\$/,"$"):"")); } - if(v==="big"||v==="Big"||v==="bigg"||v==="left"||v==="right"||v==="displaystyle") return null; + if(v==="big"||v==="Big"||v==="bigg"||v==="Bigg"||v==="left"||v==="right"||v==="displaystyle"||v==="textstyle") return null; // spacing control symbols: \, \: \; \ (backslash-space) -> spaces; \! -> nothing if(v==="!") return null; if(v==="," ){ const s=el("mspace"); s.setAttribute("width","0.17em"); return s; } diff --git a/pkg/mixnet/shuffle_argument.go b/pkg/mixnet/shuffle_argument.go index a39b70b..91fe044 100644 --- a/pkg/mixnet/shuffle_argument.go +++ b/pkg/mixnet/shuffle_argument.go @@ -32,8 +32,8 @@ func GenShuffleArgument( emitArgument("shuffle", "Shuffle argument: prove C' is a permutation + re-encryption of C, without revealing π", - `\text{ShuffleArgument}:\ \prod_i C_i^{x^i} \;\sim\; \prod_i C'^{\,x^{\pi(i)}}_i \ \text{via commitments } \mathbf{c}_A, \mathbf{c}_B \text{ and challenges } x,y,z`, - "ShuffleArgument: bind C and C' through commitments c_A, c_B and challenges x, y, z", + `\text{ShuffleArgument}:\ \prod_i C_i^{\,x^{i}} \;\sim\; \prod_i C'^{\,x^{\pi(i)}}_i`, + "ShuffleArgument: Π_i C_i^{x^i} ~ Π_i C'_i^{x^π(i)} (bound via c_A, c_B; challenges x,y,z)", dims(m, n)) // 1. Convert permutation to m×n matrix A