{"id":51578770,"url":"https://github.com/systemslibrarian/crypto-lab-elgamal-plain","last_synced_at":"2026-07-11T03:32:25.361Z","repository":{"id":365814624,"uuid":"1214720558","full_name":"systemslibrarian/crypto-lab-elgamal-plain","owner":"systemslibrarian","description":"Browser-based ElGamal encryption demo — Taher ElGamal's 1985 public-key scheme over RFC 3526 Group 14 and toy 11-bit parameters. Natural non-determinism via fresh ephemeral k, multiplicative homomorphism, ciphertext re-randomization for mix-nets. The direct ancestor of DSA and the structural basis of threshold decryption. No backends. No simulated ","archived":false,"fork":false,"pushed_at":"2026-06-28T02:02:59.000Z","size":169,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-28T03:07:20.252Z","etag":null,"topics":["crypto-lab","cryptography","discrete-logarithm","dsa","e-voting","elgamal","homomorphic-encryption","mix-nets","public-key-encryption","rfc-3526"],"latest_commit_sha":null,"homepage":"https://systemslibrarian.github.io/crypto-lab-elgamal-plain/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/systemslibrarian.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-19T00:36:26.000Z","updated_at":"2026-06-28T02:02:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/systemslibrarian/crypto-lab-elgamal-plain","commit_stats":null,"previous_names":["systemslibrarian/crypto-lab-elgamal-plain"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/systemslibrarian/crypto-lab-elgamal-plain","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fcrypto-lab-elgamal-plain","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fcrypto-lab-elgamal-plain/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fcrypto-lab-elgamal-plain/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fcrypto-lab-elgamal-plain/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/systemslibrarian","download_url":"https://codeload.github.com/systemslibrarian/crypto-lab-elgamal-plain/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/systemslibrarian%2Fcrypto-lab-elgamal-plain/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35350133,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["crypto-lab","cryptography","discrete-logarithm","dsa","e-voting","elgamal","homomorphic-encryption","mix-nets","public-key-encryption","rfc-3526"],"created_at":"2026-07-11T03:32:25.273Z","updated_at":"2026-07-11T03:32:25.353Z","avatar_url":"https://github.com/systemslibrarian.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# crypto-lab-elgamal-plain\n\n## What It Is\n\nThis project is an educational, no-backend lab for plain ElGamal encryption, implementing Taher ElGamal's 1985 scheme over RFC 3526 Group 14 (2048-bit) and a toy 11-bit group for transparent arithmetic:\n\n- Opens with a **guided walkthrough** that steps through one full encrypt/decrypt with live values\n- Uses BigInt for all modular arithmetic\n- Uses square-and-multiply modular exponentiation\n- Uses `crypto.getRandomValues` for all randomness\n- Demonstrates natural non-determinism (fresh ephemeral `k`)\n- Visualizes the discrete-log hardness with an interactive `g^x mod p` scatter plot\n- Demonstrates multiplicative homomorphism\n- Demonstrates ciphertext re-randomization for mix-net style unlinkability\n- Implements the **ElGamal signature scheme** (sign / verify) over a primitive-root group\n- Includes an interactive **Security Lab** that lets you break the scheme yourself\n- Includes a side-by-side ElGamal vs RSA exhibit\n\nThe app includes two parameter sets:\n\n- TOY group (`p = 2039`) for visible math in the UI\n- RFC 3526 Group 14 for realistic large-prime behavior\n\n## When to Use It\n\nUse this project when you want to:\n\n- Understand why ElGamal is the direct ancestor of DSA and, structurally, ECDSA\n- Learn discrete-log public-key encryption by stepping through concrete arithmetic\n- See core homomorphic behavior: multiply ciphertexts, decrypt a product\n- Understand how re-randomization supports mix-nets and private e-voting\n- Build intuition for threshold ElGamal and related distributed decryption systems\n\nDo not use this for bulk file encryption. Plain ElGamal ciphertexts are large and malleable; production systems use hybrid authenticated encryption.\n\n## Live Demo\n\n**[systemslibrarian.github.io/crypto-lab-elgamal-plain](https://systemslibrarian.github.io/crypto-lab-elgamal-plain/)**\n\nThe demo opens with a guided encrypt/decrypt walkthrough showing live values, plots the discrete-log hardness as a `g^x mod p` scatter, and demonstrates multiplicative homomorphism and ciphertext re-randomization. A Security Lab lets you trigger the failure modes yourself — discrete-log key recovery on the toy group, ephemeral-key reuse, ciphertext malleability, and signature nonce reuse — and an authenticated ElGamal exhibit shows the fix. You can switch between the toy group (`p = 2039`) and RFC 3526 Group 14.\n\n## What Can Go Wrong\n\n- Plain ElGamal is malleable. An attacker can transform ciphertexts algebraically into related plaintexts. (Exhibit 6)\n- Reusing ephemeral `k` is catastrophic: it leaks a message in encryption (Exhibit 5) and the entire private key in signatures (Exhibit 9).\n- Weak message encodings can leak structure (`m=0`, `m=1`, or low-entropy domains).\n- The toy group is intentionally insecure and brute-force breakable. (Exhibit 4)\n- Post-quantum note: ElGamal over finite fields is broken by Shor's algorithm on a large quantum computer.\n\n## Real-World Usage\n\nTaher ElGamal's 1985 paper, _A Public Key Cryptosystem and a Signature Scheme Based on Discrete Logarithms_, introduced a practical DLP-based public-key design that strongly influenced modern cryptography.\n\n- DSA standardized ElGamal's signature lineage\n- Threshold ElGamal is used in distributed decryption and voting pipelines\n- Exponential ElGamal appears in privacy-preserving vote tally systems\n- Cramer-Shoup can be seen as a hardened ElGamal-family construction\n- RFC 3526 Group 14 is widely deployed in historical DH deployments (IPsec, SSH, TLS 1.2 finite-field DH)\n\n## How to Run Locally\n\n```bash\ngit clone https://github.com/systemslibrarian/crypto-lab-elgamal-plain\ncd crypto-lab-elgamal-plain\nnpm install\nnpm run dev\n```\n\n## Related Demos\n\n- [crypto-lab-rsa-forge](https://systemslibrarian.github.io/crypto-lab-rsa-forge/) — the other classic public-key family, contrasted with ElGamal in the demo.\n- [crypto-lab-paillier-gate](https://systemslibrarian.github.io/crypto-lab-paillier-gate/) — additively homomorphic encryption for private voting and aggregation.\n- [crypto-lab-threshold-decrypt](https://systemslibrarian.github.io/crypto-lab-threshold-decrypt/) — t-of-n threshold ElGamal decryption with NIZK proofs.\n- [crypto-lab-key-exchange](https://systemslibrarian.github.io/crypto-lab-key-exchange/) — Diffie-Hellman, the discrete-log key agreement ElGamal is built on.\n\n## Development \u0026 Tests\n\n```bash\nnpm install\nnpm run dev     # local dev server\nnpm run build   # type-check (tsc) + production build\nnpm test        # Vitest suite (run once)\nnpm run test:watch\n```\n\nA committed Vitest suite proves the correctness of every primitive and every attack, so the\neducational claims are permanent and regression-checked, not ad hoc:\n\n- `modular.test.ts` — modexp, extended GCD, modular inverse, rejection-sampled randomness, primality\n- `elgamal.test.ts` — encrypt/decrypt round-trips, non-determinism, homomorphism, re-randomization, text codec\n- `attacks.test.ts` — baby-step/giant-step key recovery, and the feasibility guard refusing the 2048-bit group\n- `authenticated.test.ts` — authenticated round-trip plus rejection of malleability and forged tags\n- `signatures.test.ts` — sign/verify, forgery rejection, the congruence solver, and full key recovery from a reused nonce\n\nCI runs the suite on every pull request (`.github/workflows/ci.yml`) and gates the GitHub Pages\ndeploy on a green run (`.github/workflows/deploy.yml`).\n\n## Security Lab\n\nThe app does not just describe the failure modes — it lets you trigger them and watch the math:\n\n- **Cracking the key (Exhibit 4):** recovers a toy private key from its public key with a\n  baby-step/giant-step discrete-log solver (`src/attacks.ts`). The same routine is hard-guarded\n  against the 2048-bit group, encoding the security argument as code.\n- **Ephemeral-key reuse (Exhibit 5):** encrypts two messages under one reused `k`; the shared `c1`\n  lets an attacker who knows one plaintext recover the other with a single modular division — no\n  private key involved.\n- **Ciphertext malleability (Exhibit 6):** an attacker multiplies `c2` by a factor `t` with no key\n  and no knowledge of the plaintext, and the owner's decryption silently becomes `m·t`, showing why\n  plain ElGamal is not CCA-secure.\n- **Authenticated ElGamal — the fix (Exhibit 7):** a DHIES/ECIES-style construction\n  (`src/authenticated.ts`) derives an HMAC-SHA-256 key from the Diffie-Hellman shared secret and tags\n  the ciphertext. The exact Exhibit 6 attack is now detected and decryption is refused — at the cost of\n  the homomorphism, the tradeoff that pushes voting systems toward Cramer-Shoup or zero-knowledge proofs.\n- **Signature nonce reuse — total key recovery (Exhibit 9):** signing two messages with the same `k`\n  (`src/signatures.ts`) makes the signatures share `r`; solving the resulting linear congruences recovers\n  the signer's entire private key. This is the real Sony PS3 ECDSA break, and a far worse outcome than the\n  single-message leak from encryption-side reuse (Exhibit 5).\n\n---\n\n*One of 120+ browser demos in the [Crypto Lab](https://crypto-lab.systemslibrarian.dev/) suite.*\n\n*\"So whether you eat or drink or whatever you do, do it all for the glory of God.\" — 1 Corinthians 10:31*\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsystemslibrarian%2Fcrypto-lab-elgamal-plain","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsystemslibrarian%2Fcrypto-lab-elgamal-plain","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsystemslibrarian%2Fcrypto-lab-elgamal-plain/lists"}