I'll be talking about the details.
An ECC public key is of the form dG, where G is the generator point (a curve parameter) and d is your private key (must be between 1 and prime order-1 inclusive)
d can't be found without brute-forcing points, if you know the public key (dg).
The goal is to make someone find an appropriate dG that Hash(dG) is in the expected range.
So, you'll need to be keeping a part of d to yourself, and then combine it. How?
For all methods, the beginning is the same:
You calculate some d_1 and keep it to yourself, while sharing (d_1)G
To start with, let's review the properties of EC points.
Linearity:
(d_1)G + (d_2)G = (d_1 + d_2)G
(d_1)(kG) = (k * d_1)G
Method 1) Additive
This is the method used by Vanitygen, and it's way more popular than the others.
A bounty hunter tries many random d_2 values that make Hash((d_2)G + (d_1)G) in the expected pattern range. If the hunter succeeds, he sends d_2 to the bounty giver (either public or private). Now the vanity "assigner" can combine d_1 and d_2 to create the final private & public keys.
Note that (d_1 + d_2)G can also be calculated by third parties, which means other people will be able to track his/her payments. (because d_2 can be shared by the bounty hunter, G is already known, and (d_1)G was published by the assigner, so (d_2)G + ((d_1)G)) This also applies to all known methods.
Method 2) Multiplicative
This is used rarely.
Now that the bounty hunter wanted Hash((d_1 + d_2)G) in the expected pattern range, he wanted something different, and used a different way to do trustless vanity generation.
The innovative bounty hunter calculates a d_2 value, by brute-forcing Hash(d_2((d_1)G)): He computes multiples of (d_1)G and checks them.
Now, do you understand that d_2 must be between 1 and prime order-1, also in this method? (Hint: What's the meaning of the prime order?)
It uses the fact that d_2((d_1)G) = (d_2 * d_1)G (with appropriate modulo operations)
Method 3: Combined
I've never seen this mentioned anywhere. It's not very useful.
Simple: The bounty hunter finds d_2 and d_3 values such that Hash((d_1 * d_2)G + (d_3)G) is in the expected pattern range. This is more complex, because it has two variables. No research has been made on this. At first glance, it looks slower, but there's nothing that stops the vanity miner from fixing d_2 or d_3.
2Hmm, very interesting and a bit mind boggling... – ThePiachu – 2012-05-28T01:38:44.877
I think there are some errors in Joel's post, for example "reduce it modulo the SECP256k1 generator". You never use the generator in that way, instead you should reduce it modulo the order of the underlying field, p. Also, there's no need to chose numbers smaller than the generator. Finally, it may not be clear that when adding points on the curve (x1,y1) and (x2,y2), their sum isn't (x1+x2,y1+y2), but rather uses a special addition function, described on page 12 of http://cs.ucsb.edu/~koc/ccs130h/notes/ecdsa-cert.pdf
– Chris Moore – 2012-05-30T11:24:36.4431@ChrisMoore Actually, I think it might be N - the order of the generator. I've been playing with those concepts a bit recently and N appeared to be giving me the proper results... – ThePiachu – 2012-05-31T23:46:57.703
@ThePiachu that makes sense. I've also been playing with these concepts, and using the order of the underlying field has been giving me the wrong results ;) – Chris Moore – 2012-06-01T04:49:27.270