.

Writing mostly about computers and math.

📅 

A house address.

Original image from Michael Carian on Flickr. Some rights reserved: cc by-sa.

If you use Tor then you've probably noticed that some .onion sites have addresses that don't look totally random, like facebookcorewwwi.onion or demonhkzoijsvvui.onion. Tor addresses are supposed to be randomly-generated — how do these have words in them?

Well, as you may have guessed, the solution pretty much comes down to generating tons of keys and seeing which ones look nice. Here's how a .onion address is supposed to be generated:

  1. Generate a 1024-bit RSA keypair
  2. Take the SHA-1 of the public key
  3. Base32 encode the first 80 bytes of the hash...
  4. ... and that's your .onion address.

    There are a few programs out there designed specifically for generating tons of these hashes. Two popular ones are Scallion and Eschalot. Scallion is written in C# but supports GPU acceleration and so is very fast. Eschalot is written in C and lets you use a wordlist to search but doesn't have GPU support yet (I'm working on it though). I'll write this for Eschalot since I couldn't get Scallion to compile on my machine. The options work pretty much the same way for Scallion, so if you're using that instead then you should still be able to follow along.

    Installing Eschalot

    Eschalot is pretty simple to install. It has a few dependencies but compiling it is easy and it should compile on Windows, macOS, Linux, and BSD. Here's how I build it on Debian.

    $ sudo apt install build-essential libssl-dev
    $ git clone https://github.com/ReclaimYourPrivacy/eschalot.git
    Cloning into 'eschalot'...
    remote: Counting objects: 51, done.
    remote: Total 51 (delta 0), reused 0 (delta 0), pack-reused 51
    Unpacking objects: 100% (51/51), done.
    $ cd eschalot
    $ make

    That's it. Now we can start generating keys and looking for an address we like.

    Generating Keys

    Eschalot has a few search modes but let's say we're interested in a single prefix — how about "example". We can specify the number of threads with -t and and with -v we get some extra output. We use -p to tell it the prefix to search for and voilĂ :
    $ ./eschalot -vp example -t 8 > example.txt
    Verbose, single result, no digits, 8 threads, prefixes 7-7 characters long.
    Thread #1 started.
    Thread #2 started.
    Thread #3 started.
    Thread #4 started.
    Thread #5 started.
    Thread #6 started.
    Thread #7 started.
    Thread #8 started.
    Running, collecting performance data...
    Total hashes: 241503935, running time: 10 seconds, hashes per second: 24150393
    Total hashes: 738951074, running time: 30 seconds, hashes per second: 24631702
    Total hashes: 1723765467, running time: 70 seconds, hashes per second: 24625220
    Total hashes: 3663782163, running time: 150 seconds, hashes per second: 24425214
    Total hashes: 7485469816, running time: 310 seconds, hashes per second: 24146676
    Total hashes: 14577250049, running time: 630 seconds, hashes per second: 23138492
    Total hashes: 28260847673, running time: 1270 seconds, hashes per second: 22252635
    Total hashes: 55946077304, running time: 2550 seconds, hashes per second: 21939638
    Total hashes: 114012026840, running time: 5110 seconds, hashes per second: 22311551
    Found a key for example (7) - examplelatozpqzz.onion

    After 90 minutes and about 115 billion hashes, we find a private key that gives us an address with our prefix in example.txt:

    examplelatozpqzz.onion
    -----BEGIN RSA PRIVATE KEY-----
    MIICXQIBAAKBgQDK/xoS3witc3krmLCifMarbH40g2bj0RI8sSuTXWQdt7YPNSTk
    bFdCs5fexbTJoWQTq4tsyHW151KwIgsotzp/IFIynp7nguP5NdPGmcJQDAfvLOh4
    w3JSIg/qLOzsqU1hm8WKjW74TQAhHgA5k3PiJ8GwxzD251+oVw+0oOdCdQIETVgN
    VQKBgAd7vLTv9fT81UyIc3UWyOJhNNs/6eGahXtuOPnwIcSk7Pz7OIw13esNXW38
    l4+PF8BV5dPdzJBRCwO4SPXzyb6V+FL8lNO1lZb8JB1ONssLdDVQuQkUVOV/GF6U
    612xw44HQ4YwTxo6tbdntP1mW0Mt7q15BeRM2TF16Xnzvax1AkEA+fqDpeej3ivY
    o29fUqXpDvtAXEocKwaahbkRCIS5Omt7KOg3fctbtnQor+ggMRE1ZRji47+bKZJf
    DHPwGOXuuQJBAM/i37qrnN1vJXtaWbMdzOoqICOd4ma1Sc+a3ma8Ce+jKR6RMF0C
    6Swa7Oy9SfKjBJoTI3jjIjNJOdSr42V9M50CQAkp+pZFrDHVTundOxC72ix5Hvvy
    4oBrEScKMQwqUg+e+ASXMOcJToYtibevaI3wzehA6J3EpF5VBCWnD30uLlUCQEKG
    3zlWxm3IRZDFA/q6jlB/HcPguEyF2+Knan74Hh5ugNDARfDKL5qmb3iZxWitlJiV
    5w7zI/Sthkq/3tJgFbUCQQCGea+mKe/fJMJF4Ucw+gysxp1l+hQsG+gZS96NITFc
    +cS0GWFvX1iBZMVBlbu3HLDc7s0Bs86Hjf5tM6cqS7I/
    -----END RSA PRIVATE KEY-----
    

    Installing the Key

    So now that we've got our private key, where do we put it? Assuming you've already installed and configured Tor to host a hidden service, there's just one file to change. I configured Tor to use /var/lib/tor/hidden_service, but you can pick whatever directory you want in your torrc. The file we're interested in is called private_key.

    You can probably guess what goes in this file: the private key. Copy the lines -----BEGIN RSA PRIVATE KEY----- and -----END RSA PRIVATE KEY----- and everything in between them into this file. Restart Tor and you should be able to access your new hidden service at examplelatozpqzz.onion. I'm still waiting to find an address with a particularly long prefix, but in the meantime you can get to this website at peterbe4r52vseqd.onion.

    Update 2020-01-23: I finally found a long prefix that I like: peterbeard5li3n7.onion. I came back to this recently on my fancy new computer and it took about a week to find that one; I'm pretty pleased with it.