cathugger / mkp224o

vanity address generator for tor onion v3 (ed25519) hidden services
Creative Commons Zero v1.0 Universal
1.27k stars 150 forks source link

Feature request: Vanity public key #31

Open AlexGustafsson opened 4 years ago

AlexGustafsson commented 4 years ago

I'd like to be able to generate vanity ed25519 public keys, not just full-blown onion addresses. Is this something that's easily done with the current code base or is this project not a good fit for that?

cathugger commented 4 years ago

vanity onion keys in what format? hex? base32? base64? something else? that's not exactly problem, though, could be configurable and work.. but bigger issue is format of private keys. tor uses expanded key format, but the most software I know uses either just seed or seed+pubkey formats. heck, even current onionbalance for v3 addresses uses something looking like seed rather than expanded key. not totally certain this is true but it looked like that when I looked into it. issue with that is that one cannot use any of the tricks which are implemented in current mkp224o, because seed expansion is SHA512 which isn't really reversible operation. and that's what the most of ed25519 libraries use. I'm not saying it couldn't be bruteforced, but it's much less fun and would need different code path than tor stuff, and would be much slower. and also this stuff would probably need different UI..

there is a thing for just ed25519 keys: https://github.com/Yawning/horse25519 however, it uses only ref10 implementation which is slow. but it COULD be improved upon. other than ref10 implementations compatibility could be pulled out from mkp224o. I think that uses expanded key format too tho. but it's more generic base than mkp224o so I think that it'd be better starting point.

so yeah I think one would need to do different tool than mkp224o for this, rather than hacking it into mkp224o. it could be inside mkp224o repo if reusing stuff from ed25519.h makes a lot of sense but it would be kinda separate tool anyway.

I'm not going to work on this myself because I'm sorta busy with other stuff and it's much less fun because of annoyances mentioned above. still could maybe give some implementation tips if anyone would want to take this upon themselves.

adapt-L commented 1 year ago

I have a personal use-case for vanity monero keypairs, so I would be willing to work on this if I better understood the mp244o codebase. In another project, I came up with a way to abstract the filter for both monero and tor keypairs. It only required two "format-dependent" routines:

One routine to convert the filter into a "bitmask" and "filterbits". The bitmask is just a bunch of 1's that represent the bits of the key being filtered (5 bits per char for tor addresses), and the filterbits are the bits needed to recreate the filter in the address format (for tor, the inverse of crockford's base32). The keys would then be filtered by checking if ( PK && bitmask ) == filterbits.

The second routine would be to abstract the output formatting of the address from the keypair's bits. For example with tor this means formatting the tor service directory. With monero, this might be something like spitting it out in their custom base32, or working backwards to determine the seedphrase.

cathugger commented 1 year ago

One routine to convert the filter into a "bitmask" and "filterbits". The bitmask is just a bunch of 1's that represent the bits of the key being filtered (5 bits per char for tor addresses), and the filterbits are the bits needed to recreate the filter in the address format (for tor, the inverse of crockford's base32). The keys would then be filtered by checking if ( PK && bitmask ) == filterbits.

we sorta have this. the way filtering is done is currently configurable (fast uint32 vs uint64 prefix checks, or proper variable-length byte-per-byte masks), and works against raw calculated public keys without some of bits at the end & before SHA3 checksum is computed (these are computed later after keys pass filter tests).

i don't really know monero's public key format & its encoding, could you summarize that or point to relevant documentation? so that i can know how much it's different from what we currently are doing.