Privacy-preserving misconduct reporting using Fully Homomorphic Encryption (FHE).
HushSignal enables anonymous misconduct reporting while protecting reporter privacy. Individual report severities are encrypted and aggregated on-chain via FHE — aggregate patterns trigger investigations, individual reports are never exposed.
"We preserve reporter privacy while enabling verifiable institutional response."
Traditional reporting systems create an impossible tradeoff: reports are stored in plaintext (vulnerable to access, subpoenas, insider threats) or so heavily encrypted that meaningful aggregate analysis is impossible.
HushSignal uses FHE to break this tradeoff:
- Report severity is encrypted before submission — on-chain FHE computation is real; client-side encryption is format-compatible (MVP requires TEE for tamper-proof client)
- On-chain aggregation happens on ciphertext — counts and thresholds computed without decryption (real FHE)
- Threshold breaches emit public signals — aggregate risk emerges without exposing individuals
- Reviewers receive controlled outputs — only what the FHE computation is designed to reveal
Security Note: The on-chain FHE is cryptographically secure. Client-side encryption in the MVP is format-compatible but not tamper-proof. See docs/TRUST_MODEL.md for full details.
Without FHE, any system that allows aggregate queries on private data must decrypt that data to compute. This creates an exploitable attack surface:
- Database admins can read reports
- subpoenas compel plaintext disclosure
- Hacked systems expose everything
FHE allows the blockchain to compute on encrypted data. The system can verify that 5+ reports exist in a cluster and that their combined severity is high enough to warrant investigation — all without ever decrypting individual reports.
| Layer | Technology |
|---|---|
| Smart Contracts | Solidity 0.8.25, Hardhat, CoFHE library |
| Web App | Next.js 14, TypeScript, Tailwind CSS, viem v2 |
| Marketing Site | Next.js 14, TypeScript, Tailwind CSS |
| Monorepo | pnpm workspaces |
Reporter Browser Blockchain Reviewer Dashboard
│ │ │
│ 1. Encrypt severity (FHE) │ │
│─────────────────────────────────▶│ │
│ │ 2. Store ciphertext │
│ │────────────────────────────────▶│
│ │ │
│ │ 3. FHE.add() aggregates │
│ │────────────────────────────────▶│
│ │ │
│ │ 4. Threshold breach event ──────▶│
│ │ │
│ │ 5. Reviewer views aggregate │
│ │ (no individual reports) │
What stays encrypted: Report contents, individual severity values, reporter identity What is public: Aggregate counts, severity sums (encrypted), threshold breach events, case status
hushsignal/
├── apps/
│ ├── web/ # User dApp (Next.js 14)
│ │ ├── app/ # App router pages
│ │ │ ├── app/ # Authenticated app pages
│ │ │ │ ├── submit/ # Submit encrypted report
│ │ │ │ ├── activity/ # Submission history
│ │ │ │ ├── reviewer/ # Reviewer dashboard
│ │ │ │ ├── privacy/ # Privacy explainers
│ │ │ │ └── transparency/# System transparency
│ │ │ ├── page.tsx # Landing page
│ │ │ └── layout.tsx # App shell
│ │ ├── components/ # UI components
│ │ │ ├── ui/ # Base components
│ │ │ ├── layout/ # Header, Footer, Shell
│ │ │ ├── features/ # ReportForm, ActivityList
│ │ │ └── dashboard/ # Reviewer dashboard components
│ │ ├── hooks/ # useWallet, useContract, useReviewerAccess
│ │ ├── lib/ # fhe.ts, contracts.ts, mockReviewerData.ts
│ │ └── styles/ # globals.css with design tokens
│ └── site/ # Marketing website (Next.js 14)
│ ├── app/ # Marketing pages
│ ├── components/ # Marketing components
│ └── README.md # Site documentation
├── contracts/ # Hardhat project
│ ├── src/
│ │ ├── HushSignal.sol # Main FHE reporting contract
│ │ ├── HushSignalMock.sol # Mock for local testing
│ │ ├── Threshold.sol # Threshold logic
│ │ └── Verifier.sol # FHE verification
│ ├── test/
│ │ ├── helpers.ts # Test utilities
│ │ └── hushsignal-comprehensive.test.ts # 100 tests
│ ├── scripts/
│ │ ├── deploy.js # Deployment script
│ │ └── seed.js # Demo data seeder
│ └── README.md # Contract documentation
├── docs/ # Documentation
│ ├── architecture/
│ │ ├── privacy-model.md # Privacy guarantees & limits
│ │ └── data-flow.md # Data flow diagrams
│ ├── demos/
│ │ └── demo-script.md # Demo walkthrough
│ └── product/
│ └── mvp-vs-future.md # MVP vs production differences
├── packages/ # Shared packages (future)
└── README.md # This file
- Node.js 18+
- pnpm 8+
- MetaMask or WalletConnect-compatible wallet
pnpm installpnpm --filter @hushsignal/contracts hardhat nodeThis starts a Hardhat node on http://localhost:8545.
# In a new terminal
pnpm --filter @hushsignal/contracts hardhat run scripts/deploy.js --network localhostpnpm --filter @hushsignal/contracts hardhat run scripts/seed.js --network localhostpnpm --filter @hushsignal/web devThe app runs at http://localhost:3000.
For live demo evaluation — 3-5 minutes
- Open
http://localhost:3000in browser - Click "Submit Encrypted Report" (hero CTA)
- Connect MetaMask wallet
- Select any category (e.g., "Harassment")
- Select any severity (e.g., "Medium")
- Click "Encrypt & Submit"
- Approve transaction in MetaMask
- Submit 4 more reports (same category/severity) to trigger threshold
- Each submission shows "Encrypting..." → "Submitting..." → "Confirmed"
- After 5th submission, threshold breaches (5/5 reports)
- Dashboard shows red "Alert" badge on the category
- Review Portal shows the threshold breach in alert queue
| View | Wallet Address | Role |
|---|---|---|
| Submit Reports | Any MetaMask wallet | Reporter |
| Review Dashboard | 0x1234567890123456789012345678901234567890 |
Reviewer |
| Review Dashboard | 0x2345678901234567890123456789012345678901 |
Ombuds |
| Review Dashboard | 0x3456789012345678901234567890123456789012 |
Admin |
To switch: MetaMask → Account menu → Import account → paste address + private key
Privacy Guarantees:
- No name/email fields in report form
- Commitment hash shown (not report content)
- Transaction hash shown (no wallet address linked)
- Reviewer view shows ONLY: count, severity sum, category — NOT individual reports
Honest Limitations (MVP):
- Client-side encryption is format-compatible (not tamper-proof)
- Real FHE on Fhenix testnet for production
- See
/privacy-architecturefor full trust model
- Encryption step — Show "Encrypting your report..." in browser
- Confirmation state — Show commitment hash (receipt, not content)
- Threshold breach — Dashboard shows red alert at 5/5
- Reviewer view — Show aggregate-only access, no individual data
- Privacy notice — Show "Privacy Protected" badge on detail panel
# See docs/demos/screenshots.md for screenshot sequence
# See docs/demos/demo-runbook.md for full demo scriptcd contracts
npx hardhat node # Terminal 1: start node
npx hardhat run scripts/deploy.js --network localhost # Terminal 2: deploy
npx hardhat run scripts/seed.js --network localhost # Terminal 3: seed demo datapnpm --filter @hushsignal/contracts test100 comprehensive tests covering: deployment, report submission, threshold logic, cluster independence, investigation cases, access control, metadata & privacy, edge cases.
# Configure .env with Fhenix RPC and deployer private key
FHENIX_RPC=https://rpc.fhenix.io
DEPLOYER_PRIVATE_KEY=0x...
npx hardhat run scripts/deploy.js --network fhenixcd apps/web
pnpm devcd apps/web
pnpm build
pnpm startcp apps/web/.env.example apps/web/.env.localRequired variables:
NEXT_PUBLIC_RPC_URL— Ethereum RPC URLNEXT_PUBLIC_HUSHSIGNAL_ADDRESS— Deployed contract address
| Data | Protection |
|---|---|
| Report contents | FHE encrypted, never decrypted |
| Individual severity (0,1,2) | FHE encrypted onchain |
| Reporter identity | No address linked to reports |
| Evidence references | Hashed or offchain |
| Data | Visibility |
|---|---|
| Aggregate counts per cluster | Public |
| Severity sums | FHE encrypted, can be decrypted by authorized parties |
| Threshold breach events | Public event emits when count >= threshold |
| Case status | Pending → Investigating → Resolved/Dismissed |
| Cluster metadata | Category, org unit, time bucket (no PII) |
These are real limitations that production hardening would address:
-
Client-side encryption is not tamper-proof — A sophisticated attacker could modify the JS to log plaintext before encryption. Production requires trusted execution environments or server-side preprocessing.
-
Metadata correlation is possible — Transaction sender address, gas, and timing could theoretically correlate multiple reports from the same wallet. Mixing services or delayed submissions help but don't solve this.
-
CoFHE is a mock library — Current implementation uses simulated FHE. Real FHE on Fhenix requires the actual CoFHE library integration.
-
No slashing or reputation — There's no mechanism to penalize false reports. Threshold helps but doesn't eliminate this risk.
-
Reviewer authorization is centralized — The contract owner adds reviewers. This is a trusted role.
- Client-side FHE encryption (mock)
- Onchain encrypted storage (simulated)
- Threshold-based triggers
- Reporter dashboard
- Reviewer dashboard
- Marketing website
- Real CoFHE integration on Fhenix
- Encrypted reviewer notes
- Case assignment workflow
- Real wallet-based reviewer auth
- ZK proof integration for reporter identity
- Encrypted evidence storage (IPFS + FHE)
- Formal security audit
- Multi-chain deployment
- Wallet connect — Show MetaMask connection, emphasize no identity linking
- Submit first report — Select category/severity, show encryption happening client-side
- Submit 2-3 more reports — Same cluster, watch count increment
- Threshold trigger — Show public event emit, explain this is the only thing visible
- Reviewer dashboard — Open dashboard with authorized wallet, show aggregate view
- Privacy explanation — Walk through what reviewer can and cannot see
- "No other system does this" — FHE enables aggregate computation on private data
- "We don't store reports" — Only encrypted ciphertexts + commitment hashes
- "Threshold prevents abuse" — Can't expose individuals with a single report
- "Onchain = verifiable" — Anyone can audit the aggregate counts
- The cryptographic privacy is architectural, not policy
- Even if we (the builders) wanted to expose reports, we couldn't
- The blockchain acts as a trustable intermediary for aggregate computation
- Don't claim the encryption is bulletproof (MVP uses mock FHE)
- Don't claim complete anonymity (metadata is still there)
- Don't claim no false reports possible (threshold reduces but doesn't eliminate)
- Don't claim production-ready (explicitly label it MVP)
MIT