[Notice: banality of following post due to it being co-authored by AI]
My Hackathon Project: Attempting a Bitcoin Vanity Address Generator in Mojo
Hey everyone!
I just wrapped up a hackathon project and wanted to share what I learned, even though I didn’t quite get to where I originally planned. Hope this might be useful for others exploring Mojo’s GPU capabilities!
What I Was Trying to Build
I set out to build a Bitcoin vanity address generator. A vanity address is a Bitcoin address that starts with a specific pattern or word (like “1Kiss…” or “1Hack…”) instead of random characters - they’re purely cosmetic but people like them for branding or personalization. The catch is that Bitcoin addresses are cryptographic hashes, so you can’t just choose what you want - you have to generate millions of random addresses until you find one that matches your desired pattern
The full pipeline should have been:
-
Generate private keys
-
Derive public keys using ECDSA (secp256k1 curve)
-
Hash the public key (SHA-256 + RIPEMD-160)
-
Encode as a proper Bitcoin address
-
Check if it matches the desired pattern
What I Actually Got Working
Well… I definitely bit off more than I could chew in a hackathon timeframe!
What works:
-
Hash160 implementation (SHA-256 + RIPEMD-160) in both CPU and GPU versions
-
GPU-accelerated brute force search for hash patterns
-
Performance benchmarking between CPU and GPU implementations
-
Pattern matching against hex prefixes
What I completely punted on:
-
The entire ECDSA secp256k1 implementation. I’ve implemented this in python in the past, but without built-in bignum support, a lot needs to be hand-rolled.
-
Proper base 58 bitcoin address encoding. Same problem. There is a rust crate that works for fixed-length binary blobs that would likely be straightforward to port, especially with AI, but there’s no getting around that divisions by non-powers of 2 are expensive and complicated.
So basically, I ended up with a really fast way to search for patterns in hashes, but not actual Bitcoin addresses. Not exactly what I planned, but hey, I learned a ton!
Some Technical Bits (For Those Interested)
I got to play with some really cool Mojo features:
-
GPU kernels targeting NVIDIA A6000 (tried to max out those 10,752 CUDA cores)
-
Stack-allocated buffers to avoid memory allocation overhead in GPU code
-
Mojo’s new origin tracking and span types for memory safety
-
Direct CUDA intrinsics through Mojo’s GPU module
The benchmark runs about 67 million hash operations and compares CPU vs GPU performance. The GPU version definitely shows speedup. On my lambda instance, doing 2^26 hashes is sped up by a factor of about 117.
Lessons Learned (The Hard Way)
-
Scope creep is real - Implementing secp256k1 from scratch would have been a project in itself
-
GPU memory management matters - Avoiding allocations in hot paths made a huge difference. Before removing dynamic allocations, the GPU implementation was actually a bit slower than the CPU. Do not call
malloc
in hot loops. I knew that already, but didn’t realize just how much truer it is for GPUs. -
Mojo’s GPU capabilities are impressive - When you get it right, the performance is there
-
Start smaller next time - Should have focused on just the hash acceleration first
The Code
I’ve got it working with a simple benchmark:
sh build.sh
python go.py
This runs both CPU and GPU versions and shows the timing comparison. Nothing fancy, but it does what it says on the tin.
What I’d Do Differently
If I were starting over (or continuing this):
-
Start with just the hash functions and get those rock solid
-
Use an existing ECDSA library and focus on the Mojo GPU integration
-
Add proper Bitcoin address formatting as a separate step
Worth It?
Absolutely! Even though I didn’t hit my original goal, I learned a ton about Mojo’s GPU programming model and got hands-on experience with modern GPU optimization techniques. Plus, the hash search part actually works pretty well!
Anyone else been experimenting with Mojo’s GPU features? Would love to hear about your experiences or if you’ve tackled similar cryptographic challenges.