This runs a real (toy-sized) Paillier cryptosystem, the textbook additively-homomorphic scheme. Key generation picks primes p, q, sets n = p·q, g = n+1, and λ = lcm(p−1, q−1):
Encrypt: c = (1 + m·n) · r^n mod n² (r random, gcd(r,n)=1)
Combine: C = c₁ · c₂ · … · c_k mod n² = Enc(m₁ + m₂ + … + m_k)
Decrypt: m = L(C^λ mod n²) · μ mod n, L(x) = (x−1)/n
The combine step is pure ciphertext multiplication — no key is involved and no individual m_i is ever recovered. Because Paillier is additively homomorphic, multiplying ciphertexts together produces the encryption of the sum of the plaintexts. Every voter encrypts their own ✓/✗ ballot (1 or 0) with the authority's public key (n, g); ballots are multiplied together as they arrive, and only the final product is ever decrypted with the private key (λ, μ) — revealing the tally without ever exposing a single vote.
- Ring canvas (top) — every ballot appears as a dot on the ciphertext ring Zn², placed by its own encrypted value mod n²; the pulsing hexagon at the centre is the running homomorphic product. Drag the ring to rotate it, or set an auto-rotate speed.
- Strip canvas (bottom) — one bar per ballot in cast order, height = log₁₀ of that ballot's own ciphertext magnitude (a genuine ~3233–9797² range depending on key size), so you can see how the ciphertext space grows with a bigger modulus.
- Key Size — swapping p, q changes n, n², λ and μ and re-derives the whole keypair live; casting resumes with a fresh empty tally.
- Tally Election — runs the actual decryption formula above on the combined ciphertext and reveals the sum of Yes votes.
Real deployments (Paillier-based e-voting trials, Google's private ad-conversion measurement, encrypted database aggregation) use 2048-bit primes instead of the small demo primes here, but the arithmetic is identical.