This project implements detecting generative‑AI watermarks in fully homomorphic encryption (FHE) encrypted text. It adapts the principles behind DeepMind's SynthID watermarking scheme to text and executes the detector entirely on encrypted data. The client keeps all clear‑text locally; the server only ever sees ciphertexts.
At a glance:
| Step | Who does it? | In clear‑text? | Purpose |
|---|---|---|---|
| Key generation | Browser (WASM) | ✅ | Produce client & server FHE keys |
| Tokenisation & encryption | Browser (WASM) | ✅ → 🔒 | Convert text → integer tokens → ciphertext |
| Watermark detection | Server | 🔒 | Compute SynthID score inside FHE |
| Result decryption | Browser (WASM) | 🔒 → ✅ | Show flag (= watermarked?) and score |
tfhe‑rs– Rust implementation of the SynthID detection algorithm.concrete‑ml‑extensions‑wasm– WebAssembly bindings that enable client‑side keygen, encryption and decryption in the browser.- Vanilla HTML/CSS/JS frontend – single‑page app with two web‑workers (
keygen‑worker.js,encrypt‑worker.js) for heavy crypto. - LLM Tokenizer (
llama‑1b) – converts arbitrary text into integer IDs that the detector can process.
sequenceDiagram
participant User🧑💻
participant Browser🔐
participant Rust Server🦀
User🧑💻->>Browser🔐: 1️⃣ "Generate keys"
Browser🔐->>Browser🔐: TFHE keygen (WASM)
Browser🔐->>Rust Server🦀: 2️⃣ /handshake (server_key_b64)
Rust Server🦀->>Browser🔐: UID (uuid‑v4)
User🧑💻->>Browser🔐: 3️⃣ Enter text
Browser🔐->>Browser🔐: Tokenise ◁ HF tokenizer
Browser🔐->>Browser🔐: Encrypt tokens (WASM)
Browser🔐->>Rust Server🦀: 4️⃣ /detect (uid, ciphertext_b64)
Rust Server🦀->>Rust Server🦀: FHE SynthID detect
Rust Server🦀->>Browser🔐: Encrypted result_b64
Browser🔐->>Browser🔐: Decrypt result (WASM)
Browser🔐-->>User🧑💻: flag / score / g
Key points:
- The server currently stores the watermarking key in clear memory (
SECRET_KEYSindetect_fhe_core.rs). Running crypting that key under FHE is possible with minor changes. - Ciphertexts are serialised with
bincode+ Base64 for transport. - A UUID returned by
/handshakeroutes subsequent/detectcalls to the right server key instance.
| Text fragment | Watermark score (≈) | Flag | Interpretation |
|---|---|---|---|
| Watermarked (see below) | 0.6697 | 1 | Highly likely to be generated by a watermarked model |
| Regular (see below) | 0.5242 | 0 | Looks like ordinary text |
The future of artificial intelligence for privacy is fully homomorphic encryption. While this still isn't fully accessible, many are exploring the potential of using it, which will help us in many different ways. This article will cover several examples of homomorphic encryption and see what its significance is for privacy.
Can Homomorphic Encryption be Applied to Privacy Issues?
Homomorphic encryption has been around for a very long time, especially in the areas of cryptography and mathematics. Some of it is for use in the military, while some of it in the private sector. Homomorphic encryption allows
Watermark score: 0.6697 (based on 110 tokens)
The future of artificial intelligence for privacy is fully homomorphic encryption. Homomorphic encryption allows the secure transmission and execution of data without revealing the original data, preserving privacy. But how can we use future artificial intelligence to achieve greater privacy? Read on to find out.
Artificial intelligence is at an interesting place. It is becoming more powerful by the day, allowing it to run sophisticated analyses, even on extremely large datasets.
But this means that more and more personal data is being stored and used. The question is whether this will inevitably lead to more personal data
Watermark score: 0.5242 (based on 110 tokens)
repo/
├─ server/ # Rust crate that exposes /handshake and /detect (Actix‑web)
│ ├─ src/
│ └─ tests/ # Rust unit & integration tests
├─ web/ # All static site files and web tooling live here
│ ├─ index.html
│ ├─ wasm-demo.js
│ ├─ concrete-ml-extensions-wasm/
│ ├─ package.json, pnpm-lock.yaml, node_modules/
│ ├─ playwright.config.ts, e2e/, __tests__/, test-results/
│ └─ ...
├─ docker/ # Dockerfile (+ docker-compose.yml optional)
└─ README.md # This file
| Action | Command |
|---|---|
| Run backend & frontend (development) | make run-dev |
| Only start the Rust server | make run-server |
| Only serve the static web UI | make run-web |
| Build & run the server inside Docker | make run-docker |
| Spin up the full CI stack (Rust + Playwright) | make run-docker-compose |
| Execute Rust unit & integration tests | make test-rust |
| Execute browser end‑to‑end tests | make test-browser |
| Clean build artefacts & node_modules | make clean |
All those targets live in the root‑level Makefile. Check it out to tweak ports, flags, or timeouts as needed.