Generating .onion Addresses: A Step-by-Step Guide (Tor v2 & v3)
📅 Update: This article from January 2018 covers both Tor v2 and v3 address generation. Note that Tor v2 addresses are now deprecated. Modern Tor hidden services exclusively use v3 addresses with ed25519/curve25519 cryptography.
While researching hidden services, I have diagrammed the process of generating .onion domains. Interestingly, this process shares similarities with Bitcoin address generation: both start with a random private key, which is then transformed into a public key, hashed, and finally re-encoded using BASE encoding. This method ensures the randomness and uniqueness of both Bitcoin addresses and .onion domains.
Tor v2 vs v3 Address Generation Comparison
graph TD
subgraph "Tor v2 (Deprecated)"
A1[Random Private Key] -->|RSA-1024| B1[Public Key<br/>1024-bit]
B1 -->|SHA-1 Hash| C1[Hash Result<br/>160-bit]
C1 -->|Take First 80 bits| D1[Base32 Encode]
D1 --> E1[16-character<br/>.onion Address]
end
subgraph "Tor v3 (Current)"
A2[Random Seed<br/>256-bit] -->|ed25519| B2[Public Key<br/>32 bytes]
B2 --> C2[Public Key +<br/>Checksum + Version]
C2 -->|SHA3-256| D2[Generate Checksum]
D2 -->|Base32 Encode| E2[56-character<br/>.onion Address]
end
style A1 fill:#FF5722
style E1 fill:#FF5722
style A2 fill:#4CAF50
style E2 fill:#4CAF50
Key Differences:
| Feature | Tor v2 (Deprecated) | Tor v3 (Current) |
|---|---|---|
| Cryptography | RSA-1024 (insecure) | ed25519 (secure) |
| Hash Function | SHA-1 (broken) | SHA3-256 (modern) |
| Address Length | 16 characters | 56 characters |
| Security Level | ~80-bit | ~128-bit |
| Address Space | 2⁸⁰ (~1.2×10²⁴) | 2²⁵⁶ (enormous) |
| Status | Deprecated (2021) | Active |
v2 .onion Address Generation Process
Generating a visually appealing domain name or Bitcoin address is possible with enough resources and time.

It’s evident that the cryptographic algorithms used in the onion network, like SHA-1 and RSA-1024, are somewhat outdated. Recognizing this, the Tor Project introduced improvements in the latest v3 protocol1, replacing SHA-1 with SHA-3 and RSA-1024 with elliptic curve cryptography.
“Better crypto (replaced SHA1/DH/RSA1024 with SHA3/ed25519/curve25519)”
Notable .onion Domain Websites
- Facebook: Used over 500,000 cores and spent approximately US$100,000 over a week to generate the domain “facebookcorewwwi.onion”.
- BlockChain.info: Cost around 200-300 USD and took about 24 hours using AWS G1 instances and six ATIs to create “blockchainbdgpzk.onion”.
- ExpressVPN: A typical computer took about two weeks to generate “expressobutiolem.onion” 2.
v3 .onion Address Generation Process
The v3 address generation has abandoned SHA-1 and has not adopted the new SHA-3.
“256-bit ECC keys are roughly equivalent to 3072-bit RSA keys (based on the best current attack algorithms).”

The v3 protocol introduces the use of the ed25519 algorithm2 for public-private key transformations, moving away from the less secure RSA algorithm. Ed25519 is known for its efficiency and high security level, currently being used in many cryptographic projects like Zcash, Factom, NEM, and plans for implementation in Ethereum. Ed25519 offers significant improvements in computational efficiency without compromising security, equivalent to a 128-bit security level, similar to secp256k1.
A unique aspect of v3 is the addition of a CHECKSUM, which differs from the CHECKSUM used in Bitcoin address generation. Bitcoin employs a double sha-256 and takes the first few bits as the CHECKSUM, while .onion v3 uses a signature algorithm for its CHECKSUM.
The final step involves combining the Public Key, CHECKSUM, and version number, and encoding them with base32, resulting in a 56-character long .onion address.
Original Documentation for v3 Address Generation
1. Encoding onion addresses [ONIONADDRESS]
The onion address of a hidden service includes its identity public key, a
version field and a basic checksum. All this information is then base32
encoded as shown below:
onion_address = base32(PUBKEY | CHECKSUM | VERSION) + ".onion"
CHECKSUM = H(".onion checksum" | PUBKEY | VERSION)[:2]
where:
- PUBKEY is the 32 bytes ed25519 master pubkey of the hidden service.
- VERSION is a one-byte version field (default value '\x03')
- ".onion checksum" is a constant string
- CHECKSUM is truncated to two bytes before inserting it in onion_address
Enjoy Reading This Article?
Here are some more articles you might like to read next: