A Preact + Vite + TypeScript frontend that implements the Electronic Voting Machine (EVM) client UI for the AVID distributed voting flow.
The app collects a voter ID and ballot choice, then performs:
- one-hot vote encoding
- random vote masking
- payload encryption
- key-share generation
- deterministic server selection (
2f + 1) - parallel submission to distributed voting servers
- receipt hash generation (
sha256)
- Preact
- Vite
- TypeScript
tweetnaclfor symmetric encryption primitivesjs-sha256for hashing
All frontend code is under src/frontend/:
src/frontend/
├── main.tsx
├── App.tsx
├── styles/
├── config/
├── types/
├── utils/
├── services/
├── hooks/
├── components/
└── pages/
- Node.js 20+ (recommended)
- npm
npm installnpm run devDefault local URL: http://localhost:5173
npm run buildnpm run previewSubmission pipeline in src/frontend/services/votingApi.ts:
- Encode selected candidate into one-hot vector (
encodeVote) - Generate random vector (
generateRandomVector) - Mask vote (
maskVote = vote + random) - Generate symmetric key (
generateSymmetricKey) - Encrypt payload (
encryptPayload) - Split key into shares (
splitKeyShares) - Deterministically select
2f+1servers (selectVotingServers) - Send
(payload, keyShare, voterId, electionId)to each server in parallel - Compute receipt hash:
0x${sha256(encryptedPayload)}
The UI marks submission successful when at least one selected server responds with HTTP success.
Hardcoded election config:
- File:
src/frontend/config/election.ts - Election ID:
2026 - Election Name:
National General Election - Position:
President - Candidates:
Candidate A,Candidate B,Candidate C
Default server pool in src/frontend/utils/serverSelection.ts:
http://localhost:9001http://localhost:9002http://localhost:9003http://localhost:9004http://localhost:9005http://localhost:9006http://localhost:9007
Selected endpoint per server:
POST /vote
Request body sent by client:
{
"payload": "<encrypted-base64>",
"keyShare": "<base64-share>",
"voterId": "<voter-id>",
"electionId": "2026"
}- Election header
- Voter ID input (required)
- Candidate cards (single selection/radio semantics)
- Submit button (disabled until valid input)
- Success receipt with
0x...hash - Secure terminal cues:
SECURE EVM TERMINAL✓ Cryptographic masking enabled✓ Distributed vote submission active
- This is a frontend protocol prototype and not a complete production-grade election system.
- Key-share logic is lightweight for demo behavior and should be replaced with audited threshold cryptography for production.
- Ensure backend voting servers allow CORS from the frontend origin during local development.