All articles
solanavanitytoolinggpurustcryptography

vanity v0.8.0: keypair grinding gets the speed treatment — AVX-512 ed25519 and a tuned OpenCL path

cavemanloverboy's vanity v0.8.0 lands on crates.io: 8-lane AVX-512 IFMA ed25519 keygen on CPU, batch field inversion and comb scalarmult in the OpenCL kernels, and a new benchmark table — 8.6B seeds/s and 65M keypairs/s on one RTX 4090.

Share
devrels.xyz/a/144short link

When we covered cavemanloverboy's vanity in May, the pitch was "don't grind keypairs, grind seeds" — and the catch was that the fast path only produced CreateAccountWithSeed addresses, not real signable keypairs. If you wanted a vanity wallet, you were back to the slow classic grind.

vanity v0.8.0 benchmark table: CUDA on RTX 4090 does ~8.6B seeds/s and ~65M keypairs/s; CPU on a 48-thread EPYC 9275F with AVX-512 IFMA does ~201M seeds/s and ~33M keypairs/s; OpenCL on Apple Silicon does ~315M seeds/s and ~15M keypairs/s.

v0.8.0, published to crates.io on July 12th, is the release that closes that gap. The whole update is performance work on the keypair modes — the ones that produce a genuine ed25519 keypair you can drop into Phantom, sign with, or use as a token mint authority. The commit log reads like a cryptography engineering seminar: 8-lane AVX-512 IFMA keygen, Montgomery batch inversion, radix-32 comb scalar multiplication, fused base58 early-reject.

The three grind modes, thirty seconds

Since v0.7.0, vanity exposes three subcommands that share the same mining flags:

  • grind — the original fast path. Searches seeds for CreateAccountWithSeed; each attempt is one SHA-256 hash. Fastest by orders of magnitude, but the resulting address is controlled by your base keypair, not a standalone key.
  • grind-keypair — the classic vanity wallet/mint case. Searches real ed25519 keypairs whose public key matches a base58 --prefix and/or --suffix. Each attempt is a full SHA-512 + ed25519 scalar multiplication.
  • grind-doppler — the exotic one. Searches keypairs whose public key packs into sign-extendable 32-bit immediates, so sBPF programs can compare key segments with cheaper instructions (inspired by Blueshift's doppler-keygen).

grind was already absurdly fast. v0.8.0 is about making the other two respectable.

What v0.8.0 actually ships

CPU: 8-lane AVX-512 IFMA ed25519 keygen

The CPU keypair path now uses a batched custom ed25519 implementation that processes eight keys per instruction stream using AVX-512 IFMA — the integer fused multiply-add extension that gives you 52-bit multiplies across 512-bit vector lanes. Field arithmetic for eight candidate keys advances in lockstep instead of one at a time.

The result: a 48-thread AMD EPYC 9275F now grinds ~33 million keypairs per second — half the throughput of an RTX 4090, from a CPU. If your build machine has IFMA (Ice Lake or later on Intel, Zen 4 or later on AMD), you get this automatically.

OpenCL: the kernel optimization tour

The OpenCL backend (added in v0.7.0 for machines without CUDA — AMD, Intel, and Apple GPUs) got four distinct optimizations to its keypair kernels:

  • Batch field inversion — converting an ed25519 point to affine coordinates (to read out the public key bytes) requires a field inversion, the most expensive single operation in the loop. Montgomery's trick amortizes one inversion across 8 keys per work-item: multiply the values together, invert once, unwind.
  • Radix-32 comb scalarmult — public key derivation is a scalar multiplication against a fixed base point, so the kernel now uses a 52-window precomputed comb table, the same shape as the fastest SIMD CPU implementations.
  • Direct table lookup in ge_select — production ed25519 libraries select precomputed points with constant-time cmov ladders to resist side channels. A local grinder discarding billions of random candidates doesn't need that, so selection is now a direct indexed load.
  • Fused base58 early-reject — instead of fully encoding each candidate pubkey to base58 and string-comparing, the match check is fused into the encoding and bails on the first non-matching character.

The same optimizations were applied to the doppler kernels, and the June commits brought the CUDA keypair path the precomputed-table and early-reject treatment too.

The new numbers

The refreshed benchmark table from the repo, per single device:

  • CUDA, RTX 4090: ~8.6B seeds/s · ~65M keypairs/s
  • CPU, EPYC 9275F (48 threads, AVX-512 IFMA): ~201M seeds/s · ~33M keypairs/s
  • OpenCL, Apple Silicon: ~315M seeds/s · ~15M keypairs/s

Two things worth noticing. First, the seed path itself has come a long way: when we wrote about this tool in May, a 4090 did ~1.3B seeds/s — a batch of SHA-256 kernel work (precomputed midstates, registers-only digests, hoisted message schedules) has since pushed that to ~8.6B/s, a ~6.6× jump on the same silicon. Second, your MacBook is now a legitimate grinder: the OpenCL backend exposes the identical CLI, and Apple Silicon does 15M keypairs/s.

What that means in wall-clock time

A case-sensitive base58 prefix costs roughly 58× per character. At 65M keypairs/s on one 4090, expected times look like:

  • 4 characters (~11M attempts): well under a second
  • 5 characters (~660M): ~10 seconds
  • 6 characters (~38B): ~10 minutes
  • 7 characters (~2.2T): ~9 hours

--case-insensitive roughly halves the per-character cost, so a 7-character insensitive prefix lands back in coffee-break territory. And if you don't need a standalone keypair, the seed path at 8.6B/s does a case-sensitive 7-character prefix in about four minutes and 8 characters in an afternoon. Throughput scales linearly with --num-gpus.

Using it

sh
# CPU (AVX-512 IFMA used automatically when available)
cargo install vanity

# NVIDIA — set your compute capability for a targeted build (89 = RTX 4090)
VANITY_CUDA_ARCH=89 cargo install vanity --features=gpu

# Everything else (Apple Silicon, AMD, Intel GPUs)
cargo install vanity --features=opencl

Grinding a real vanity keypair:

sh
vanity grind-keypair --prefix bob --suffix xyz --num-gpus 1

On a match it prints the pubkey, the seed in hex, and a Solana-compatible keypair JSON array you can write straight to a file and use with the CLI or any SDK:

text
gpu 0 match: bob... in 0.4s
pubkey:   bob...xyz
seed hex: 68e36f80...
keypair json (solana-compatible): [104, 227, 111, ...]

The seed path is unchanged (vanity grind --base ... --owner ... --prefix ...), and vanity verify recomputes a seed-derived address at any time.

The takeaway

The original insight behind vanity was picking a cheaper primitive: SHA-256 instead of curve math. v0.8.0 is the complementary move — accepting the expensive primitive and engineering it down: batching across vector lanes, amortizing inversions, precomputing everything precomputable, and rejecting losers before they finish encoding. The gap between "vanity program address" and "vanity wallet you actually hold the key for" used to be a categorical trade-off. Now it's mostly a factor you can buy back with a GPU — or apparently, a laptop.

Resources

Keep reading

Get new articles in your inbox

Technical deep-dives on Solana tooling, infrastructure, and ecosystem. No noise.

vanity v0.8.0: keypair grinding gets the speed treatment — AVX-512 ed25519 and a tuned OpenCL path | devrels.xyz