I would like to generate a WIF private key from a random 256 bit private key.
I use the private key given in "mastering Bitcoin" :
http://chimera.labs.oreilly.com/books/1234000001802/ch04.html#_implementing_keys_and_addresses_in_pythonExample 4-4.
print "Private Key (hex) is: ", private_key
print "Private Key (decimal) is: ", decoded_private_key
# Convert private key to WIF format
wif_encoded_private_key = bitcoin.encode_privkey(decoded_private_key, 'wif')
print "Private Key (WIF) is: ", wif_encoded_private_key
the output is:
Private Key (hex) is: 3aba4162c7251c891207b747840551a71939b0de081f85c4e44cf7c13e41daa6
Private Key (decimal) is: 26563230048437957592232553826663696440606756685920117476832299673293013768870
Private Key (WIF) is: 5JG9hT3beGTJuUAmCQEmNaxAuMacCTfXuw1R3FCXig23RQHMr4K
Here is my code (with GMP: GNU Multiple Precision Arithmetic Library):
#include
#include
#include
#include
using namespace std;
mpz_class base58ToBigNum (const string);
string bigNum2base58 (mpz_class);
int main (void)
{
mpz_class bigNumber = 0;
string privKeyHexa("3aba4162c7251c891207b747840551a71939b0de081f85c4e44cf7c13e41daa6");
cout << endl << "privKeyHexa:" << privKeyHexa << endl;
bigNumber = hexaToBigNum(privKeyHexa);
cout << endl << "bigNumber: " << bigNumber << endl;
string strBase58WIF = bigNum2base58(bigNumber);
cout << "strBase58WIF : " << strBase58WIF << endl << endl;
return 0;
}
// ex: A259BD07F
// = 10 * 16^8 + 2 * 16^7 + 5 * 16^6 + 9 * 16^5 + 11 * 16^4 + 13 * 16^3 + 0 * 16^2 + 7 * 16^1 + 15 * 16^0
// = 43580641407
mpz_class hexaToBigNum (const string myString)
{
string hexa_digits = "0123456789ABCDEF";
int index;
mpz_class m = 0;
for( size_t i = 0; i < myString.size(); i++ ) {
m *= 16;
index = hexa_digits.find(toupper(myString[i]));
m += index;
}
return m;
}
string bigNum2base58 (mpz_class bigNumber)
{
string b58_digits = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
string base58string;
string mycharString;
mpz_class divisor(58), quotient, remainder;
mpz_class x = bigNumber;
while (x > 0) {
mpz_fdiv_qr(quotient.get_mpz_t(), remainder.get_mpz_t(), x.get_mpz_t(), divisor.get_mpz_t());
mycharString = string(1, b58_digits[mpz_get_ui(remainder.get_mpz_t())]);
base58string.insert(0, mycharString);
x = quotient;
}
return base58string;
}
The while loop in pseudocode is simply:
while(x > 0)
{
(x, remainder) = divide(x, 58)
output_string.append(b58_digits[remainder])
}
and my output is
privKeyHexa: 3aba4162c7251c891207b747840551a71939b0de081f85c4e44cf7c13e41daa6
bigNumber: 26563230048437957592232553826663696440606756685920117476832299673293013768870
base58 : 4xFNZQXb9uCKNsupB4AsWmiyd1N7Rk1ibQ42GbytvTed
The base58 string (WIF) should start with 5.
Questions:
according to: mastering Bitcoin Table 4-1.
I have to add a version prefix of 0x80, but where ?
I have the same bigNumber than Example 4-4.
if I add 0x80 to privKeyHexa : 803aba4162c7251c89....
I have a different big number and a wrong result: f6Lnp6NkNmwag....
So where do I add this prefix ?
And do I have to do a checksum somewhere ?