Commit graph

5 commits

Author SHA1 Message Date
31e9a25bb8 Cockpit MathML converter: sums, products, dots; verified in browser
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 <noreply@anthropic.com>
2026-07-07 16:31:43 +02:00
c24650885e Instrument the deep Bayer-Groth layers: commitments, sub-arguments, decryption
Take the live-math cockpit down to the level of the Swiss Post crypto-primitives
class structure. The shuffle proof is no longer one line — you can now watch it
being constructed:

- Pedersen matrix commitment (CommitmentService analog): c_A = Comm(A; r),
  c_{A,j} = h^{r_j} Π g_i^{A_ij}, emitted from CommitMatrix.
- All five Bayer-Groth sub-arguments, mirroring the *ArgumentService classes:
  ShuffleArgument (composition + x,y,z challenges), ProductArgument,
  HadamardArgument (entrywise product), ZeroArgument (bilinear star-map),
  SingleValueProductArgument, MultiExponentiationArgument — each emits its
  defining relation as LaTeX with live dimensions.
- Partial decryption + decryption proof (DecryptionProofService analog):
  φ'_i = φ_i·γ_i^{-sk} with the ZK proof that log_g(pk) = log_γ(γ^sk).

New trace.KindArgument. Low-level Commit stays uninstrumented (called in
verification too — would flood the stream); CommitMatrix is the semantic step.

Test: a 6-voter ceremony (N=6 → 2×3 shuffle matrix, so m>1 and the full argument
tree runs) captures 345 live events across 8 kinds, and asserts all five named
sub-arguments appear.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 16:26:03 +02:00
bc43c3d3aa Instrument real crypto ops to emit live LaTeX events
The running cryptography now narrates itself. Each headline operation emits a
trace.Event carrying its LaTeX notation plus the actual runtime values, the
instant it executes:

- Ed25519 signature on every inter-party message (envelope.Seal)
- X25519 ECDH key agreement for confidential card delivery (NewSecureChannel)
- ElGamal ballot encryption E1 = (g^r, pk^r·m) with the real r (castBallot)
- Fiat-Shamir challenge e = H(...) mod q (Schnorr proof)
- Bayer-Groth verifiable shuffle C' = {ReEnc_pk(C_π(i))} with N (mix-net)

Ceremony phases set trace phase/party context so events are attributed to the
acting stakeholder and phase. Instrumentation is behind the enabled-check, so
normal runs pay nothing.

Test: a full traced ceremony captures 184 live events across all five headline
kinds, each with non-empty LaTeX and live values, correctly phase/party-tagged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:06:08 +02:00
ec4be74e17 Due-diligence hardening + Rust transport-security layer
Correctness/security review of the whole PoC, with fixes and regression tests.

Cryptographic soundness:
- mixnet: enforce the multi-exponentiation c_{B_m}=commit(0;0) check that was
  stubbed out with an empty if — without it a malicious mixer can prove a
  non-permutation shuffle.
- zkp: derive all four Fiat-Shamir challenges via RecursiveHashToZq instead of
  a biased `hash mod q` (which also capped the challenge space at 256 bits for
  production-sized groups).

Verification honesty:
- protocol: VerifyTally now actually calls zkp.VerifySchnorrProof and returns
  the true aggregate result instead of an unconditional true.
- protocol: persist the padded mix input (event.MixInput) so the verifier checks
  shuffle 0 against the same padding the tally used (fixes false INVALID for N<2).

Other correctness:
- kdf: length-prefix BuildKDFInfo parts so the info encoding is injective.
- math: GqElementFromSquareRoot accepts the valid root q (off-by-one that could
  panic in HashAndSquare); RandomGqElement samples the full canonical range.
- cmd: validate demo --voters/--options instead of panicking on degenerate values.
- protocol: use crypto/rand in the demo driver (drop the last math/rand import).

Transport security (new): pkg/transportsec exposes Ed25519 signatures and X25519
ECDH — implemented in Rust (rust/transportsec: ed25519-dalek, x25519-dalek),
linked into Go via cgo. No RSA. Cross-language conformance test proves the Rust
Ed25519 signatures interoperate with Go's crypto/ed25519. Makefile builds the
Rust static lib before the Go binary.

Tests: added unit/round-trip/tamper coverage for math, hash, elgamal, zkp,
mixnet, kdf, returncodes, protocol (end-to-end), and the Rust FFI bridge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:42:34 +02:00
e8b6f30871 Swiss Post E-Voting Go PoC
Proof-of-concept reimplementation of the Swiss Post e-voting
cryptographic protocol in Go. Single binary, 52 source files,
2 dependencies. Covers ElGamal encryption, Bayer-Groth verifiable
shuffles, zero-knowledge proofs, return codes, and a full
election ceremony demo.
2026-02-13 19:53:09 +01:00