Nostr の Vanity address を掘る

Nostr という分散型SNSのプロトコルがあって最近良く見かけます．

Nostr, a simple protocol for decentralizing social media that has a chance of working

このSNSの個人認識に秘密鍵と公開鍵のペアを作成してそれを利用します．鍵ペアは初回に自動生成されるのですが，公開鍵の文字列をたくさん計算して好みのアドレスが含まれたアドレスを掘るプログラムがあったので試してみました．

tonyinit/nostrogen: simple nostr vanity address generator

このプログラムはbech32で表現される公開鍵の npub1 の後ろの文字列を任意の文字列から始まるものにしたいというvanity アドレスを彫りたい人向けのものです．

導入

cargo insrtall で導入できるはずですが，手元のDebian bookworm testing amd64 環境ではrustc が 1.63 に対してrana は 1.64.0 以上が必要だということで古くて失敗しました．

$ cargo install rana
Updating crates.io index
Installing rana v0.5.1
Downloaded is-terminal v0.4.4
Downloaded clap_lex v0.3.2
Downloaded syn v1.0.109
Downloaded bip39 v1.2.0
Downloaded 4 crates (346.5 KB) in 2.86s
error: failed to compile `rana v0.5.1`, intermediate artifacts can be found at `/tmp/cargo-installvCF9z2`

Caused by:
package `clap_derive v4.1.0` cannot be built because it requires rustc 1.64.0 or newer, while the currently active rustc version is 1.63.0
Try re-running cargo install with `--locked`
$ dpkg-query -W rustc
rustc 1.63.0+dfsg1-2

Rust Forge で新しいStable(1.67.1)を貰ってきて使おうかとも思いましたが，インストーラーを叩く形で環境が汚れそうで少し面倒そう．

Other Installation Methods – Rust Forge

Docker を使うことにします．

rust – Official Image | Docker Hub

公式イメージだけあって最新の 1.67.1 です．rana もさくっと動きました．

$ script ./nostr_vanity.log
$ docker run --rm -it rust
# rustc --version
rustc 1.67.1 (d5a82bbd2 2023-02-07)
# adduser matoken
# su - matoken
$ export PATH=/usr/local/cargo/bin:$PATH
$ rustup default stable
$ cargo install rana
$ rana --help
Rana 🐸

o o
( -- )
/\( , ,)/\
^^ ^^ ^^ ^^

A simple CLI to generate nostr vanity addresses

Francisco Calderón <negrunch@grunch.dev>

Usage: rana [OPTIONS]

Options:
-d, --difficulty <DIFFICULTY>
Enter the number of starting bits that should be 0. [default: 0]
-v, --vanity <VANITY_PREFIX>
Enter the prefix your public key should have when expressed
as hexadecimal. [default: ]
-n, --vanity-n-prefix <VANITY_NPUB_PREFIXES_RAW_INPUT>
Enter the prefix your public key should have when expressed
in npub format (Bech32 encoding). Specify multiple vanity
targets as a comma-separated list. [default: ]
-s, --vanity-n-suffix <VANITY_NPUB_SUFFIXES_RAW_INPUT>
Enter the suffix your public key should have when expressed
in npub format (Bech32 encoding). Specify multiple vanity
targets as a comma-separated list. [default: ]
-c, --cores <NUM_CORES>
Number of processor cores to use [default: 4]
-r, --restore <MNEMONIC>
Restore from mnemonic to public private key [default: ]
-g, --generate <WORD_COUNT>
Generate mnemonic using wordcount. Should be 12,18 or 24 [default: 0]
-p, --passphrase <MNEMONIC_PASSPHRASE>
Passphrase used for restoring mnemonic to keypair [default: ]
-q, --qr
Print QR code of the private key
-h, --help
Print help
-V, --version
Print version

why can’t we use characters b, i, o, or 1?
the characters have to be in the bech32 character set.

— nostrogen
https://github.com/tonyinit/nostrogen#why-cant-we-use-characters-b-i-o-or-1

公開鍵は Bech32 形式で 023456789acdefghjklmnpqrstuvwxyz が利用できます．以下は Bech32 で使えない o を使って怒られた例です．

$ rana --vanity-n-prefix matok
thread 'main' panicked at 'The vanity npub prefix can only contain characters supported by Bech32: 023456789acdefghjklmnpqrstuvwxyz', /usr/local/cargo/registry/src/github.com-1ecc6299db9ec823/rana-0.5.1/src/cli.rs:146:17
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

oを0に置き換えて動かしてみます．

$ rana --vanity-n-prefix mat0k | tee rana.log
Started mining process for vanity bech32 prefix[es]: 'npub1["mat0k"]' (estimated pow: 20)
Benchmarking of cores disabled for vanity npub key upon proper calculation.
Mining using 4 cores...

さて，これで待っていれば鍵が掘れるのですが，以下のように新しいラップトップで以下のような速度で掘れるとのことです．あまり長くするとなかなか掘れないので気をつけましょう．

how fast will nostrogen find my addresses?
this depends entirely upon how fast your machine is, but here are some rough estimates for a modern laptop or mobile phone:

1 character = usually less than a 0.1 seconds
2 characters = usually less than a 1 second
3 characters = usually less than a 30 seconds
4 characters = usually less than a 10 minutes
5 characters = usually less than a 1 hour
6+ characters = keep fire extinguisher handy

— nostrogen
https://github.com/tonyinit/nostrogen#how-fast-will-nostrogen-find-my-addresses

以下のような感じで結果が表示されます．Npub public key の npub1の後ろが指定したmat0kから始まっています．

$ rana --vanity-n-prefix mat0k | tee rana.log
Started mining process for vanity bech32 prefix[es]: 'npub1["mat0k"]' (estimated pow: 20)
Benchmarking of cores disabled for vanity npub key upon proper calculation.
Mining using 4 cores...
<<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>><<>>
Vanity npub found: mat0k
Found matching Nostr public key:
Hex public key: df56fb6cce5a60eac0a55b09ff6d5fbb565b07da6f64a2578ae827d70a21873b
Hex private key: 7a1a088022c3110fabc445af28681c0d2c349a2123f38fe83fbc809d7c8ed6bb
Npub public key: npub1mat0kmxwtfsw4s99tvyl7m2lhdt9kp76daj2y4u2aqnawz3psuass9qwnz
Nsec private key: nsec10gdq3qpzcvgsl27ygkhjs6qup5krfx3py0ecl6plhjqf6lyw66as4gyfat
26169409 iterations (about 2x10^7 hashes) in 3199 seconds. Avg rate 8180 hashes/second

Warning

公開されているこの鍵は利用しないでください

手元の，NotePCの Intel® Core i5-7300U CPU @ 2.60GHz と Oeracle Free Tier VPS Arm Ampere A1 共に8000〜8200 hashes/secod という感じでした．

3日ほど走らせて mak0 から始まるものたくさん，mat0ke から始まるものが2つ出てきました． cpu fan うるさいしmat0ken は諦めてこの辺にしとこうかな?

Npub public key: npub1mat0kejpylctwszs3h0jcaw24vsmzvx0h44hl2qf3ghuz2ggekjqkwyeq5

そういえば以前はTor の Vanity address も掘っていました……．

torのhidden serviceで使うアドレスを計算する(Vanity Addresses) – matoken’s meme