Bitcoin Core Enables Tor Proof-of-Work Defenses for Hidden Services

Bitcoin Index · · 6 min read
Bitcoin Core Enables Tor Proof-of-Work Defenses for Hidden Services

Bitcoin Core merged PR #33414 on March 23, 2026, adding support for Tor’s proof-of-work (PoW) defense mechanism for automatically created onion services. The feature helps Bitcoin nodes running as Tor hidden services defend against denial-of-service attacks without compromising the anonymity that makes Tor valuable.

When a hidden service comes under attack, it can now require clients to solve computational puzzles before connecting. Clients that solve harder puzzles get priority in the connection queue, making sustained DoS attacks expensive while legitimate users can still get through.

Why hidden services need this

Bitcoin nodes running as Tor hidden services face a specific vulnerability. An attacker can flood the node’s introduction points with connection requests, consuming resources and blocking legitimate connections. Traditional IP-based rate limiting doesn’t work because Tor’s anonymity design means the service can’t see where connections originate.

Tor’s PoW defense solves this by moving the cost to the attacker. During normal operation, no puzzles are required. When the service detects high load, it publishes a “suggested effort” level. Clients solve puzzles with that effort and submit the solution during introduction. The service verifies solutions and prioritizes connections by effort level.

For an attacker maintaining a flood, they must now solve increasingly difficult puzzles for each connection attempt. A legitimate user only needs to solve one puzzle to connect, even during an active attack.

How Bitcoin Core implements it

Bitcoin Core has supported automatic hidden service creation since version 0.12.0 (February 2016). When you run a node with Tor configured, Bitcoin Core creates an ephemeral onion service by sending an ADD_ONION command to Tor’s control port.

PR #33414 modifies this command to include PoWDefensesEnabled=1 when creating the service. The implementation is deliberately simple:

  1. Bitcoin Core tries ADD_ONION with PoW enabled
  2. If Tor returns a syntax error (code 512), the Tor version doesn’t support PoW
  3. Bitcoin Core retries without the parameter and continues normally

The graceful fallback means nodes work on any Tor version, but get PoW protection when available. The code changes span about 50 lines across 5 files.

Here’s the core logic:

static std::string MakeAddOnionCmd(const std::string& private_key, 
                                    const std::string& target, 
                                    bool enable_pow)
{
    return strprintf("ADD_ONION %s%s Port=%i,%s",
                     private_key,
                     enable_pow ? " PoWDefensesEnabled=1" : "",
                     Params().GetDefaultPort(),
                     target);
}

The implementation also adds debug logging to show whether PoW defenses were successfully enabled, helping node operators verify the feature is active.

What about manual configurations?

If you configure your Bitcoin node’s hidden service manually (by editing /etc/tor/torrc), you’ll need to add the PoW setting yourself:

HiddenServiceDir /var/lib/tor/bitcoin-service/
HiddenServicePort 8333 127.0.0.1:8334
HiddenServicePoWDefensesEnabled 1

First verify your Tor version supports PoW:

tor --list-modules
# Should show: pow: yes

tor --version
# Should mention GNU General Public License

The PoW module requires Tor 0.4.9.2-alpha or later (released April 2, 2025) and depends on GPL-licensed libraries. Most distribution packages include this by default, but if you compile Tor yourself, you must use ./configure --enable-gpl.

How the puzzle works

Tor’s PoW uses a hash function called Equi-X, designed by tevador (the same developer behind RandomX used in Monero mining). The algorithm is:

  • Fast to verify (critical for the server)
  • ASIC-resistant (prevents attackers from building specialized hardware)
  • Memory-hard (reduces the advantage of GPUs over CPUs)

When a service enables PoW, it publishes parameters in its hidden service descriptor:

pow-params v1 <seed-b64> <suggested-effort> <expiration-time>

The suggested-effort starts at 0 (PoW dormant) and increases dynamically when the service detects high load. Clients use this value to determine how much work to do, but they can choose to do more if previous connection attempts failed.

The service maintains a priority queue based on effort. Highest effort connections are processed first. Lower effort connections may timeout if the queue is full. Connections without PoW solutions get the lowest priority.

Why this works

The PoW defense creates an economic disincentive for attackers.

Without PoW, an attacker with a botnet can flood the service with millions of requests at minimal cost. The service spends CPU cycles processing each connection attempt equally.

With PoW, the attacker must solve puzzles with increasing effort to maintain the attack. As legitimate users also solve puzzles, the suggested effort rises. To keep flooding the service, the attacker needs to either solve puzzles with effort higher than legitimate users (extremely expensive at scale) or accept that their flood requests get deprioritized and timeout.

Meanwhile, a legitimate user only needs to solve one puzzle to connect.

Performance and energy concerns

Puzzle-solving speed depends on CPU architecture. On x86_64 and aarch64 (64-bit) systems, the HashX implementation compiles to native code and solves puzzles in 5-30 milliseconds each on modern hardware. Other architectures run HashX in interpreted mode, roughly 10-40× slower.

For the hardcoded maximum effort of 10,000:

  • Fast desktop: ~40 seconds
  • Average computer: ~55 seconds
  • 2018-era smartphone: ~115 seconds
  • Older/interpreted architectures: 13-25 minutes

During an attack, services typically don’t push effort to the maximum. Tor Project testing suggests most real-world effort levels will be tolerable even on mobile devices.

The design specifically addresses environmental concerns. The system is deterrent-based, not always-on:

  • PoW is dormant when the service is not under attack
  • Effort increases only during active attacks
  • The attack becomes unprofitable before significant energy is wasted
  • Successful deterrence means attacks stop happening, eliminating the ongoing energy waste of both the attack and the defense

As Tor’s documentation notes: “The expected result is that attackers won’t try to DoS the service for too long, or won’t even have an incentive to do so, and the PoW protection will tend to be disabled.”

Client support

Bitcoin Core nodes connecting to hidden services with PoW enabled will automatically solve puzzles if they’re running Tor 0.4.8.1-alpha or later. No Bitcoin Core configuration changes are needed because puzzle-solving happens transparently at the Tor layer.

Older Tor clients can still connect but will receive lower priority during attacks, as their connection requests won’t include puzzle solutions.

The review process

PR #33414 was opened on September 17, 2025, and took six months to merge. The review process included an interesting exchange about whether Bitcoin Core should implement client-side PoW solving.

Contributor dergoegge asked: “Should we then also add PoW to the connections that we make to other nodes running behind hidden services?”

Reviewer willcl-ark clarified that the Tor FAQ shows the feature supports older clients without PoW capability, giving them lower priority during DoS. When the client’s Tor is new enough, puzzle-solving is automatically handled by Tor during the introduction phase with no changes needed in Bitcoin Core’s connection code.

The PR underwent one rebase in February 2026 due to conflicts. Reviewers suggested (but ultimately didn’t require) refactoring for cleaner code organization. Maintainer fanquake merged the PR after receiving ACKs from willcl-ark, fjahr, and sedited.

Why this matters for Bitcoin

Bitcoin Core’s integration with Tor has deepened over the past decade, recognizing that privacy and censorship resistance are critical for a permissionless monetary network. Key milestones:

  • 2015: Bitcoin Core 0.12.0 added automatic hidden service creation
  • 2021: Bitcoin Core 22.0 dropped Tor v2 support, requiring v3 onion services only
  • 2026: Bitcoin Core enables PoW defenses for automatic hidden services (this update)

Bitcoin nodes accessible via Tor serve several important use cases:

  1. Privacy-conscious users running nodes behind Tor prevent ISPs and network observers from linking IP addresses to Bitcoin activity

  2. Censorship resistance for users in countries that block Bitcoin, who can connect to nodes via Tor bridges and hidden services

  3. Geographic diversity by adding connection paths that bypass traditional internet infrastructure

DoS attacks against these nodes undermine all three goals. By adopting Tor’s PoW defense, Bitcoin Core helps ensure that privacy and censorship-resistant infrastructure remains available even under attack.

Monitoring and next steps

Node operators can monitor PoW defense status using Tor’s MetricsPort feature, which exports:

  • tor_hs_rdv_pow_pqueue_count: Number of requests waiting in the priority queue
  • tor_hs_pow_suggested_effort: Current suggested effort level

Rising suggested effort indicates the service is under load. Operators can use these metrics to detect DoS attacks early and correlate them with other system metrics like CPU, memory, and bandwidth.

This feature will be included in the next Bitcoin Core release. Nodes running from the master branch can use it immediately if they have Tor 0.4.9.2-alpha or later.

The Tor Project’s roadmap for PoW includes client-configurable effort limits, time-based effort budgets, and better user feedback. Applications like Tor Browser could eventually display when a service has PoW enabled and what effort level is required, helping users understand connection delays.

Sources

Data as of March 23, 2026.