I am surprised LloyceV would say it should not happen because I know he knows about vanity addresses/search. If one is searching for 1Bxyz, in a given range, you will find many, and obviously if you are searching in a given range, many keys will be "close".
I have never seen this behaviour in
vanitygen. I think it should always get a new random starting point after finding a match, otherwise the private keys you create are linked together, and compromising one means someone could brute force your other addresses.
If you use the rekey, it generates random starting points for each thread and then searches sequentially until the rekey number is met; then it rinses and repeats.
Is "rekey" an option instead of the default?
The rekey option is not default. You have to pass the flag -r and whatever number.
Here is the code that separates the threads:
for (int i = 0; i < nbThread; i++) {
if (rekey > 0) {
keys[i].Rand(256);
} else {
keys[i].Set(&startKey);
Int offT((uint64_t)i);
offT.ShiftL(80);
Int offG((uint64_t)thId);
offG.ShiftL(112);
keys[i].Add(&offT);
keys[i].Add(&offG);
}
So if you use the rekey option, it will generate (whatever your CPU thread x 1024 or your GPU grid size X x Y) random points throughout the curve and then work sequentially, until rekey number is met.
If no rekey flag is passed, the program generates a new base key, every time the program starts, then shifts out 112 bits and 80 bits. The odds of someone starting at the same base key is well, a little less than 2^256.
// Protect seed against "seed search attack" using pbkdf2_hmac_sha512
string salt = "VanitySearch";
unsigned char hseed[64];
pbkdf2_hmac_sha512(hseed, 64, (const uint8_t *)seed.c_str(), seed.length(),
(const uint8_t *)salt.c_str(), salt.length(),
2048);
startKey.SetInt32(0);
sha256(hseed, 64, (unsigned char *)startKey.bits64);
char *ctimeBuff;
time_t now = time(NULL);
ctimeBuff = ctime(&now);
printf("Start %s", ctimeBuff);
if (rekey > 0) {
printf("Base Key: Randomly changed every %.0f Mkeys\n",(double)rekey);
} else {
printf("Base Key: %s\n", startKey.GetBase16().c_str());
}
}
Also note, the program also checks the current points, Point + endo1 + endo2 + symmetries.
Remember, a smaller vanity will result in many matches. If a vanity is 1Bf2f, that's what, roughly 58^4 checks before a match is found? Which is 11,316,496, which means, roughly every 11,316,496 keys checked, a match will be found. GPUs nowadays, can check up to 25,000,000,000 key/s.
Normally, a person is searching for a longer Vanity address, if they plan on using it, or to distinguish it from other addresses.
I am sure the code can be tweaked to regen points after a match is found, if that would really make someone feel more secure. Finding matches with close proximity private keys is small with a more difficult vanity address.