The Catalog That Doesn't Spy.
The marketplace delivers personalized recommendations without ever seeing the user's history.
Scenario
A marketplace user encrypts a behavior profile (8 dimensions: categories, price, frequency). The marketplace ranks the catalog under encryption.
Problem
Personalization today requires a persistent profile on the server. LGPD tightens. Consent fatigue destroys conversion. FHE breaks that trade-off.
Guarantee
The server runs scoring under encryption. Returns a ranking. Never sees the profile. No persistent profile, no regulatory risk, no consent fatigue.
Define the parameters.
Before encrypting the behavior profile, we choose CKKS parameters. CKKS is the natural scheme for catalog ranking over feature vectors.
Capacity · CKKS
What each term means
CKKS ("approximate" scheme) — FHE family for real numbers. Controlled approximation noise (~10⁻¹⁰). The standard for recommender systems, semantic search and ranking — exactly what e-commerce needs.
8 192 slots — Each ciphertext is a vector of 8 192 values. The 8 behavior dimensions occupy 8 slots; a single ciphertext carries the full user profile.
Multiplicative depth 3 — How many chained multiplications. For ranking over 5 products, depth 3 is more than enough.
~128 bits of security — Industry standard. Breaking the key would require ~2128 operations.
RLWE base — Same problem behind ML-KEM/ML-DSA standardized by NIST as post-quantum cryptography.
Keys generated in the browser.
Unlike the traditional model where the server controls everything, here it is the user's BROWSER that generates the key pair. The secret key lives in IndexedDB or similar. The marketplace only receives the public key.
Generation
Why browser-side
Power inversion — In traditional e-commerce the user hands over history to the marketplace via cookies/server-side. Under FHE with browser-side keys, the user holds control: they can revoke, export, delete — and the marketplace literally loses access.
Lattigo via WASM — Lattigo (Go) compiles to WebAssembly and runs in any modern browser. Key generation in ~50 ms is viable without hurting UX.
Local storage — The secret key is persisted in IndexedDB (cryptographically protected by the browser). It survives closing the tab. It does not leak to the server even if the user tries.
Profile encrypted locally.
The 8 dimensions below are didactic projections of the user embedding. In real production, the vector has 128-512 dimensions coming from a two-tower model trained on the catalog itself.
8 dims (didactic projection)
In production: 128-512 dim two-tower embedding
Two-tower model — Amazon, Mercado Livre and Shopee use two-tower architectures: one tower learns user embeddings (history → dense vector), another learns product embeddings. The recommendation is the inner product between the two vectors.
Trained on the catalog itself — Embeddings are learned offline from (user, clicked product) pairs over millions of interactions. They are dense 128-512 float vectors, not interpretable features.
In this demo — We use 8 dims with readable names for didactic clarity. In real production, what changes is the dimension (128-512 vs 8). The FHE pipeline stays identical.
Scalability — CKKS processes 128 dims in ~20 ms and 512 dims in ~60 ms. For Top-100 ranking over a Top-1000 pre-filtered set, total time lands at 5-10 s — acceptable for personalization that loads after first paint.
What the marketplace receives.
Just 1 MB of pseudo-random bytes. The marketplace has no way to reconstruct the profile — not now, not later. It resolves two regulatory problems simultaneously.
Incoming bytes
74 65 78 74 4d 65 74 61
44 61 74 61 22 3a 7b 22
53 63 61 6c 65 22 3a 7b
...
The two problems it solves
1. Consent fatigue — Studies show funnel conversion with explicit consent banners fell 15-35% over the last 24 months. Users are tired. Under FHE, the consent screen can be drastically simplified because the marketplace technically NEVER has personal data to "process" in the legal LGPD sense.
2. Regulatory risk — LGPD fines for secondary use of data are the Achilles heel of digital retail. Under FHE, secondary use becomes mathematically impossible. Reduces exposure to fines, class actions and post-breach reputational damage.
Catalog ranked under encryption.
For each product in the catalog (5 in this demo, millions in real production), the marketplace computes an affinity score by taking the inner product between the product weights (public) and the user profile (encrypted).
The algorithm · per-product loop
for prod in catalog {
// product weights (public)
ptW := encoder.Encode(prod.weights)
// encrypted Mul × public
ctMul := evaluator.Mul(ctProfile, ptW)
// sum slots = inner product
ctScore := evaluator.InnerSum(ctMul)
evaluator.Add(ctScore, prod.bias)
}
Performance and scale
How does it scale? For millions of products, the marketplace pre-filters using traditional non-personalized search (Top 100 by category) and applies FHE scoring only on the Top 100. 100 × 40 ms = 4 seconds. Acceptable for personalization that loads after first paint.
Ranking decrypted.
Top 5 (computed without the server seeing the profile)
- iPremium Smartphone 256GB+1.61
- iiBluetooth Headphones+1.58
- iiiItalian Leather Boots+1.36
- ivEducational Tablet+1.32
- vFloral Summer Dress+0.43
Mathematical validation.
Dishonest marketplace.
- 1 — Infer profile from ranking5 scores, 8 dimensions. Under-determined.
- 2 — Repeated sessionsReveals only relative order, never absolute values.
- 3 — Recover skInfeasible.
Private recommendation.
Flow
- Browser encrypted behavior profile
- Sent ciphertext to the marketplace
- Marketplace ranked 5 products under encryption (197 ms)
- Browser decrypted and displayed the top 5