Tor's proof-of-work defense: pricing out onion-service denial of service
An onion service under flood cannot do what a normal website does: there are no IP addresses to rate-limit, because neither the visitors nor the attackers reveal one. Tor's answer, shipped in Tor 0.4.8 and announced on the project blog in August 2023, is to price the introduction step in processor time. The design descends from proposal 327, drafted in April 2020 by George Kadianakis, Mike Perry, David Goulet and tevador, which framed the core problem plainly: building rendezvous circuits is expensive for the service and for the network, and rate-limiting alone never changed that.
A puzzle that only appears under load
The scheme is transparent in the protocol sense: there is no extra challenge round-trip. The puzzle parameters live inside the onion service descriptor that clients fetch anyway - a version tag, a 32-byte seed, a suggested effort level and an expiration. As long as the suggested effort stays zero, the defense is dormant and introductions proceed exactly as before. When the service detects overload, it raises the suggested effort. Clients then run Equi-X, the puzzle function specified in the proposal, over a challenge built from a personalization string, the blinded service ID, the seed, a random 16-byte nonce and the chosen effort. The resulting 43-byte solution rides inside the INTRODUCE1 cell as an extension. According to the Tor blog, a first solve costs around 5 milliseconds on a fast machine and up to about 30 on slower hardware; under sustained attack the required work can climb toward a minute of compute.The queue pays by effort
Checking a solution is deliberately cheap; the expensive part - building the rendezvous circuit - is deferred. Requests that pass verification enter a priority queue ordered by claimed effort, with older entries winning ties, and a scheduler drains it at a controlled pace. Difficulty follows an add-increase, multiply-decrease cycle over 300-second windows: while the queue stays saturated, the service raises effort to either its previous value plus one or the average effort of handled introductions, whichever is larger; when pressure drops, effort decays by about a third. Clients retry with escalating effort - doubling below 1,000, then multiplying by 1.5 - between bounds the spec sets at 8 and 10,000. Seeds rotate roughly every two hours, with the previous seed accepted briefly to avoid races.Why ordinary users mostly don't notice
Because the puzzle exists only while the service is stressed, ordinary traffic at low load pays nothing. A person clicking through a handful of pages during an attack spends milliseconds, an experience the blog compares to waiting on a slow connection, while an attacker spamming millions of introductions pays for every single one. The Tor Project's summary of the design:"Blocks attackers while giving real users a chance to reach their destination" - Tor Project blog, August 2023
How services opt in
Operators control the defense through torrc. The switches documented in the project's onion-service DoS guide:- HiddenServicePoWDefensesEnabled - publishes the puzzle in the descriptor and switches on the effort-ordered queue
- HiddenServicePoWQueueRate and HiddenServicePoWQueueBurst - how fast verified requests drain from the queue
- CompiledProofOfWorkHash - a global option selecting the hash function used for puzzles










