Zcash Vanity Address Generator
I just thought of something. Eventually there'll be some interest in brute force scanning bitcoin addresses to find one with the first few characters customized to your name, kind of like getting a phone number that spells out something. Just by chance I have my initials.
—Satoshi Nakamoto in an email to Hal Finney in 2009, referring to 1NSwywA5Dvuyw89sfs3oLPvLiDNGf48cPD.
First you need to install Rust.
cargo install zcash-vanity.
zcash-vanity --help for usage information.
You can load multiple patterns from a file (
-f), and optionally turn on case-insensitive matching (
-i) to reduce the search space.
The following address was found by searching for the prefix
Each additional character will of course take around 58 times longer than this for an exact match. For every character that has two cases available in the base58 alphabet, the expected time can be halved, so enabling case-insensitivity may be worthwhile for longer prefixes.
To receive a Zcash payment on the Zcash blockchain, the recipient needs to provide two pieces of information to the sender: a paying key apk and a transmission key pkenc, which together form a payment address.
Zcash encodes a payment address as follows:
- The raw address consists of a 2-byte prefix followed by apk (32 bytes) and pkenc (32 bytes).
- This is encoded using Base58Check, which first appends a 4-byte checksum and then converts the amended raw address to base 58, treating it as big-endian.
Both the paying key and the transmission key are derived from a 252-bit secret key ask. Since we’re only interested in finding z-addrs that match particular prefixes, we can ignore the transmission key as it appears after the paying key in the raw address, and set it to some fixed value such as all zeroes for the brute-force search.
The paying key apk is derived from the secret key ask by applying SHA256Compress to the secret key (along with some additional fixed data). Therefore the brute-force search simply runs SHA256Compress on random ask until it finds a matching apk.
There are a few tricks that we can use to optimise performance on GPUs:
- Instead of converting every candidate raw address to base58 on the GPU (expensive), we convert each base58 prefix pattern into a range of possible raw addresses, represented by a minimum and maximum raw address.
- Instead of storing the full 70-byte minimum and maximum raw addresses, we can truncate to the first 64 bits, as it’s quite rare that we’ll match all 64 initial bits, and we can do a more expensive check on the full address on the host CPU when a potential match is found.
- To support searching multiple prefixes at once, e.g. when loading arbitrary prefixes from a file or when case-insensitive matching is turned on, we use binary search on the set of truncated ranges.
- On GPUs, branch divergence occurs when threads in a workgroup take different execution paths through a branch. This is extremely costly and can be avoided for binary search by using a fixed search depth.
Range of Valid Addresses
A maximum range of possible encoded shielded addresses can be calculated by taking the smallest/largest possible raw addresses and encoding them, i.e.
base58(0x169ac000…00) → zc8E5gYid86n4bo2Usdq1cpr7PpfoJGzttwBHEEgGhGkLUg7SPPVFNB2AkRFXZ7usfphup5426dt1buMmY3fkYeRrJD8PUK
base58(0x169acfff…ff) → zchid4y8fAVDtAb9Q4G3QiPJbNaocboTwXCdmQ9EhvpdMg4HK8hxRFafoMDjjmaLXHkqy68w4dk2nG4XhLJaKpBLh88zPav
This gives us a range of possible encoded prefixes for z-addrs.
In other words, the third character can match
[8-9A-Za-h], but in the case of
h, subsequent characters will be restricted.
Zcash-vanity detects if any input patterns are outside of the allowed range and throws an error.
- zcash-mini, a portable wallet generator written in Go by Filippo Valsorda, which supports vanity address generation (z-addrs) too but CPU-only at the moment.
- vanitygen_z, a modified version of Bitcoin's vanitygen, for generating transparent Zcash addresses (t-addrs) only (using OpenCL).
Zcash-vanity was written by Jason Davies. Thanks to Sean Bowe for providing encouragement and feedback.
You may send a donation to the address below if you wish to support development:
© 2017 PlutoMonkey