Etherveil - An Ethereum Privacy Browser

Important: This document is a work in progress and represents an early-stage architectural proposal. It defines intended system boundaries & design principles, but does not specify finalised implementations or security guarantees. Please note that Etherveil is a tentative name. The purpose of this post is to gather community feedback, so please share your feedback!

Vision

Etherveil is a Firefox/Gecko-based browser built on the Tor Browser’s patch set, with Kohaku embedded as a native wallet engine. The core premise is simple: privacy should be a property of the runtime, not something users configure.

Most privacy tools put the burden on the user, i.e. install this extension, route through this VPN, remember to use your shielded address etc., you name it. Etherveil treats that as a design failure. The browser enforces privacy-by-default across three layers: network (IP & traffic metadata), execution (browser fingerprint surfaces), and on-chain (addresses, transaction origin, balances). A user should be able to open the browser, navigate to some Ethereum-supporting site, and transact without generating stable, linkable distinguishable signals beyond their assigned anonymity class (and without requiring the user to understand the underlying mechanisms). Etherveil replaces probabilistic privacy mechanisms with deterministic constraint enforcement over all observable execution surfaces.

System Invariant

Invariant: all observable browser APIs must resolve into a finite set of equivalence classes shared across users within the same Fingerprint Profile class.

In simple words: Everyone using the same privacy profile looks exactly the same to websites, because the browser forces all observable behaviour into a small number of standardised patterns.

Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚     Etherveil Browser Shell (Firefox/Tor Fork)     β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  Execution & Fingerprint  β”‚  Kohaku Engine         β”‚
β”‚  Normalisation Layer      β”‚  (Wallet + Tx)         β”‚
β”‚  (Tor Browser Base)       β”‚                        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚      Network Privacy & Verification Layer          β”‚
β”‚  Tor/Optional Mixnet, Helios Light Client          β”‚
β”‚  ERC-4337 Bundler Relay                            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Fingerprint Normalisation Layer

The Tor Browser already solves most of the hard fingerprinting problems; we’re extending it, not reinventing it. The main addition is what we call a Fingerprint Profile: a fixed, precomputed equivalence class over browser observables, constructed as a constraint-satisfying tuple over correlated browser signals derived from empirical distributions, assigned per browsing context and immutable for the lifetime of a session. This ensures cross-field consistency (e.g. timezone-locale-language coherence) and prevents independent attribute spoofing.

The key design decision is that this is not per-user configuration or runtime randomisation. Randomisation is actually counterproductive: if your canvas noise seed changes between page loads, that transition is a fingerprint. Instead, each profile is a consistent snapshot derived offline from real-world distributions, but not sampled at runtime, chosen to maximise the size of the anonymity set it belongs to. If a site breaks under an assigned profile, the entire browsing context restarts under a different compatible class. There is no mid-session mutation.

Surfaces normalised at Gecko/SpiderMonkey level via deterministic API interception and rewriting (not content scripts, which are detectable):

  • navigator.*: UA, platform, hardware concurrency, device memory
  • Intl/Date: timezone, locale, language negotiation headers
  • Canvas/WebGL: deterministic per-profile outputs; vendor and renderer strings aligned to class distribution
  • screen.*, devicePixelRatio
  • WebRTC: ICE candidates suppressed or standardised
  • High-entropy APIs (audio, fonts, performance timing): quantised across profile class

All high-entropy APIs are either quantised, unified, or mapped into profile-bounded equivalence classes.

Storage & Interaction Isolation

Storage (IndexedDB, localStorage, cookies, cache) is partitioned per origin and profile with no cross-profile leakage. Beyond storage, interaction signals - scroll timing, pointer movement, keystroke cadence - are smoothed and quantised within bounded stochastic models. The goal is to reduce behavioural entropy enough to defeat biometric re-identification without making the browser feel broken to use. The usability-entropy tradeoff boundary is a core open design parameter of the system.

Kohaku Wallet Engine

The wallet is a native browser subsystem, not an extension. The browser exposes a single transaction API to dApps and deliberately does not surface whether a given transaction is executing privately or publicly. That distinction is an implementation detail of the engine, not something dApps need to know.

dApp -> Wallet API -> Kohaku Engine -> Privacy Relay -> Chain
Component Role
tornado-cash Default shielded transaction layer
provider Unified RPC (Helios/external nodes/local client)
pq-account Post-quantum ERC-4337 default account type

All new accounts are pq-account smart accounts by default. Transactions route through Tornado Cash (or more generally, an abstract zk shielding layer) unless the user explicitly opts into a public flow. UserOperations are submitted via Tor-routed ERC-4337 bundlers, so the user’s IP is never associated with a transaction in the public mempool.

Network Privacy Layer

The network stack is inherited from Tor Browser and extended:

  • Tor (default): per-origin circuit isolation; all traffic and DNS fully routed
  • Mixnet (optional): stronger metadata resistance against timing correlation attacks, at the cost of latency; whether this should be opt-in or default is deferred
  • Helios light client: local Ethereum state verification via sync committee proofs, eliminating reliance on centralised RPC providers; ENS resolution goes through Helios only
  • Traffic shaping: deterministic latency padding and request batching to reduce timing correlation

Threat Model

The browser is designed to defend against:

  • ISP and exit-node traffic analysis
  • Cross-site fingerprinting via canvas, WebGL, and other high-entropy APIs
  • RPC endpoint surveillance (address queries to Infura/Alchemy etc.)
  • On-chain address clustering and transaction graph analysis
  • Behavioural biometric re-identification (bounded mitigation)

It does not fully solve (and makes no claim to solve) attacks by global passive adversaries with complete network visibility, OS or hardware-level side channels, or user operational security failures.

Non-Goals

A few things explicitly out of scope, to keep the design coherent:

  • Extension compatibility: WebExtension APIs reintroduce identity surface that would undermine the fingerprint model
  • User-controlled fingerprint tuning: the anonymity guarantee depends on users being indistinguishable from each other, not on individual customisation
  • Opt-in or β€œbest-effort” privacy modes: the model only works if it’s enforced uniformly
  • Exposing execution mode (private vs public) to dApps

Deferred Design Questions

A few decisions that need to be made before implementation but don’t have obvious right answers yet:

  • Profile persistence: should the same profile be assigned to a given origin across sessions, or rotated per session? Per-origin consistency is better for usability; rotation is better for unlinkability.
  • Mixnet defaulting: Tor-only as the baseline with mixnet as opt-in, or default-on with an escape hatch for latency-sensitive contexts?
  • Interaction hardening: where is the acceptable tradeoff between behavioural entropy suppression and usability?
  • Web compatibility: some sites will break under strict fingerprint classes. What’s the escalation path when no compatible high-population profile class renders the site correctly?
8 Likes

Great initiative!

While Firefox has historically been the more privacy conscious base browser (hence Tor), my impression has been that they’ve really slipped in the last 5 years or so. In addition, non-Chromium itself is rapidly becoming a failure vector.

Would it be worth considering using a fork of Brave? Brave also has Tor compatability, if that’s important, and ships with its own fingerprinting protection. (See Brave Shields - Blocking Ads, Trackers & more | Brave, there’s a section called Fingerprint Randomization.)

2 Likes

Very promising! Curious would ad blocking also be included in this? Besides being a UX benefit, it would prevent the threat of potential malware injected through ads.

well randomisation is the problem, not the fix, per-session noise is itself a fingerprint (as I state in the spec). Brave’s anonset is also much smaller than Tor browser’s. Chromium concerns are valid and fair tbh, but the answer is largest non-randomising anonset, which is Tor Browser.

imho out of scope for this spec. ad/tracker blocking is orthogonal to the fingerprint/network/on-chain invariants here, could be a separate follow-up also.

I think I might be misunderstanding - are you proposing for the browser to have a torified connection? If so, Brave does also have functionality to connect to Tor.

ok I was confused as well lol - I re-read now your original question. Let me elaborate: possibly but the main reason I started from Tor browser is that the proposal relies on deterministic fingerprint normalisation rather than runtime randomisation. The browser choice is probably secondary; the invariant is that users within the same profile class should be indistinguishable from one another. That being said, the Chromium vs. Gecko tradeoff is one of the biggest open architectural questions, so I’d definitely welcome more discussion on it.

1 Like

I see, ok. Yeah I believe definitely worth some kind of follow-up since from what I’ve read, fingerprinting can also be done from code injection through ads on websites. My knowledge is limited there so correct me if I’m wrong. Also ad/tracker blockers seem essential nowadays and I assume most people who would use this browser already use one in their current browser whether its uBlock Origin, Brave Shields, etc. Given that, they would probably either expect this baked-in or can at least install the extension (which is explicitly out of this scope as well for understandable fingerprinting reasons).

wrt β€œThe usability-entropy tradeoff boundary is a core open design parameter of the system.” : you can do empirical testing on this. it is possible to jury rig approximately your concept today by sticking tor-firefox in a container, installing and configuring a wallet, and then using tbselenium to see how many defi etc sites still work. you’d have to inject the β€œbehavioural entropy” yourself but that is both straightforward and part of getting selenium to handle add-ins popups anyway. the automation scripts will be a bit flaky as is the way for selenium. but those failure rates are a good proxy for usability.

so you can measure how locked down the browser needs to be to keep X% of sites working. to me that’s the big open question here. this scheme will β€œwork” in that you can glue something equivalent together already and it runs on more than 0 relevant sites. does it work across enough real sites to be useful? no clue. it is probably a good vulnerability scan on that front as well!

The reason we use farbling instead of a deterministic fingerprint is because it often breaks sites and causes web compatibility issues. Also, the simple fact that a user injects window.ethereum into the DOM via extension produces a highly unique fingerprint on it’s own. I think it’s something like less than 1% of Web users would include this JS.

Might I suggest an alternative based on my experience doing security and privacy in the browser and our wallet at Brave for the past 4 years? I’d suggest instead that we move away from the leaky abstraction of wallet APIs which rely on the site structuring transaction data and instead start encapsulating most of this into the wallet. This can be done by more wallets implementing the standardized interfaces of metamask snaps and then capabilities enabled in kohaku are converted into wallet snaps. Additionally, as more CROPS protocols are built they can be plugged in the same way. Then for the average web developer who wants to rely on the capabilities of wallets without thinking about if they need to use a multicall, what byte ordering they need, or what the right contract address is they can just call to a high level API that encapsulates this for them.

BTW, brave is already working in this direction of adding snaps to our wallet.

Here’s some other lessons you’ll likely find as you attempt something like this more too:

  1. The size of this project is a multi year effort that would take a team of at least 30 engineers with deep knowledge of browsers to ship this. That sounds expensive, How are you going to fund it? Don’t forget that the code is constantly shifting under your feet too whether its built on Gecko, Chromium, Webkit, or even ladybird so you’ll need to rebase quite often too.

  2. Most people run their wallets off mobile devices, are you planning to support both Android and iOS? If you support iOS, you’ll need a specialist team who knows how to integrate the codebase into webkit because iOS still requires the usage of Webkit.

  3. On that note, do you expect the average user will accept the usability constraints of running everything off TOR?

  4. In the case where a user doesn’t have enough hardware to run something like a lightclient is there an acceptable downgraded model of relying on RPCs for it?

  5. When it comes to reliance on API calls, how are you planning to handle fingerprinting based on assets such as coins or NFTs held that are looked up by balances or to acquire the USD value (or another currency because yes, unfortunately most users expect these basic features) as @scburgel showed was possible, how do you plan to farble these?

  6. Should the wallet API leak the wallet address to the site causing a unique fingerprint?

That’s just the start of the questions. There’s likely many more that exist beyond simple web3 related concerns that would run very deep just on the browser side of things which are going to encounter major usability tradeoffs. This then reduces the total number of users who might use it and a lot of costs to change and maintain features like this. In saying all that, I do recognize there’s some useful capabilities in here which I’ll take back and see what we can get added to Brave Wallet. And if you find a way to fund and pull something as ambitious as this off I’m keen to watch and see what we can learn from it to improve Brave too.

3 Likes