Post
Topic
Board Development & Technical Discussion
Re: VanitySearch (Yet another address prefix finder)
by
NotATether
on 17/02/2021, 14:07:08 UTC
I cannot understand what exactly this command gives me. how exactly the search algorithm goes?

Quote
VanitySearch.exe -t 0 -gpu -gpuId 0 -g 24,128 -i all_btc_balance.txt -o output.txt

He starts with a hex key? and ascending searches?
Quote
0000000000000000000000000000000000000000000000000000000000000001
or randomly generates a hex key? and ascending searches?
Quote
634C5BDB134FBFDD1D32D9E0922D664CA22A9339466D4621D26D3C9D838C2B7C


On CPU, VanitySearch can generate a random 256-bit starting private key every rekey MKeys, and adds CPU_GRP_SIZE/2 to the key to get the final starting key. But this is not enabled by default because rekey is set to 0. That means it will start with a fixed starting key. From diving into the code I found that it starts with 0

Now since rekey is hardcoded to 0 by default, it's going to add the starting point to the thread ID of the CPU (which VanitySearch gives it) shifted left by 64 bits. So each thread will have starting points at least 2^64 apart from each other.

CPU_GRP_Size is set to 1024 and if you're familiar with how GPUs assign several points per thread, VanitySearch's CPU implementation does something similar.

If you see "Base Key: Randomly changed every x Mkeys" in the output then that's the value of rekey and it's generating random starting keys. On he other hand if you just see "Base Key:" and then a number then a static key (0x0 in this case) is being used.

In Vanity.cpp:

Code:
void VanitySearch::getCPUStartingKey(int thId,Int& key,Point& startP) {

  if (rekey > 0) {
    key.Rand(256);
  } else {
    key.Set(&startKey);
    Int off((int64_t)thId);
    off.ShiftL(64);
    key.Add(&off);
  }
  Int km(&key);
  km.Add((uint64_t)CPU_GRP_SIZE / 2);
  startP = secp->ComputePublicKey(&km);
  if(startPubKeySpecified)
   startP = secp->AddDirect(startP,startPubKey);

}

We have similar code for getting the GPU starting key:

Code:
void VanitySearch::getGPUStartingKeys(int thId, int groupSize, int nbThread, Int *keys, Point *p) {

  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);
    }
    Int k(keys + i);
    // Starting key is at the middle of the group
    k.Add((uint64_t)(groupSize / 2));
    p[i] = secp->ComputePublicKey(&k);
    if (startPubKeySpecified)
      p[i] = secp->AddDirect(p[i], startPubKey);
  }

}