Bitcoin Forum
November 09, 2024, 06:02:42 AM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Rebuilding the wheel (Vanity mining)  (Read 6747 times)
Kontakt (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 250



View Profile
May 19, 2013, 04:07:08 AM
Last edit: May 22, 2013, 02:58:21 PM by Kontakt
 #1

I'm making a Vanity address miner that generates compressed addresses, mostly because I'm bored, took an intro C++ course, and think cryptography is nifty. Feel free to call me an idiot, or encourage me. Tips and advice appreciated.

I'm using CryptoPP because VanityGen uses OpenSSL, and I wanted to make mine different. No particular reason other than that.

I'll post source code for interesting bits here, and give an idea of my progress.

Goals:
Create a working CPU miner
Create a working GPU miner
Implement getwork
Implement shares system
Huh
Profit

Progress to make:
Comparison
Modular add/multiply
Getwork
Shares/proof of work

Nifty codes:
Base58 to Hex, returns cryptopp Integer
Code:
Integer base58decode(string input)
{
    int parse;
    Integer key;
    for(int i = 0; i < input.length(); i++)
    {
        parse = 0;
        while(true)
        {
            if(input[i] == b58[parse])
            {
                key = (key + parse)*58;
                break;
            }
            else
                parse++;
        }
    }
    key = key/58;
    return key;
}
Integer and leading zeroes to Base58
Code:
string base58encode(Integer plain, int zeros)
{
    string adr;
    Integer remainder, temp;
    while(plain != 0)
    {
        plain.Divide(remainder, temp, plain, 58);
        plain = temp;
        adr = b58[remainder.ConvertToLong()] + adr;
    }
    while(zeros)
    {
        adr = "1" + adr;
        zeros--;
    }
    return adr;
}

The whole program, messy as it is.
Code:
#include <iostream>
#include <iomanip>

// CryptoPP includes
#include <cryptopp\cryptlib.h>
#include <cryptopp\filters.h>
#include <cryptopp\eccrypto.h>
#include <cryptopp\hex.h>
#include <cryptopp\osrng.h>
#include <cryptopp\sha.h>
#include <cryptopp\ripemd.h>
#include <cryptopp\integer.h>
#include <cryptopp\oids.h>

using namespace std;
using namespace CryptoPP;

string b58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
byte odd[] = {0x03};
byte eve[] = {0x02};
AutoSeededRandomPool prng;
ECDSA<ECP, SHA256>::PrivateKey Priv;
ECDSA<ECP, SHA256>::PublicKey Pub;

bool loop(byte* goal);
string digest2hex(byte* digest, int len);
byte* str2hexarr(char* in, int len);
byte* step(string raw);
string base58encode(Integer plain, int zeros);
Integer base58decode(string input);
string process(string raw);

int
main()
{
    Integer loops;
    byte goal[] = {0x01};
    while(loop(goal) == false && loops < 800)
    {
        loops++;
        cout << "\r" << std::dec << loops;
    }

}

bool
loop(byte* goal)
{
    string temp;
    byte x[32];
    Priv.Initialize( prng, CryptoPP::ASN1::secp256k1());
    Priv.MakePublicKey(Pub);
    SHA256 crunchy;
    if(Pub.GetPublicElement().y.IsEven() == 0)
        crunchy.Update(odd, 1);
    else
        crunchy.Update(eve, 1);
    Pub.GetPublicElement().x.Encode(x, 32);
    crunchy.Update(x,32);
    byte digestA[32];
    crunchy.Final(digestA);
    byte digestB[20];
    RIPEMD160().CalculateDigest(digestB, digestA, 32);
    if(digestB[0] == goal[0])
    {
    cout << endl << std::hex << Priv.GetPrivateExponent();
    return true;
    }
    else
        return false;
}

string
digest2hex(byte* digest, int len)
{
    string output;
    HexEncoder encoder;
    StringSink *SS = new StringSink(output);
    encoder.Attach(SS);
    encoder.Put(digest,len);
    encoder.MessageEnd();
    return output;
}

byte*
str2hexarr(char* in, int len)
{
    for(int i = 0; in[i]; i++)
        in[i] = toupper(in[i]);
    byte part2[len/2];
    unsigned int i, t, hn, ln;
    for (t = 0,i = 0; i < len; i+=2,++t)
    {
        hn = in[i] > '9' ? in[i] - 'A' + 10 : in[i] - '0';
        ln = in[i+1] > '9' ? in[i+1] - 'A' + 10 : in[i+1] - '0';
        part2[t] = (hn << 4 ) | ln;
    }
    return part2;
}

byte*
step(string raw)
{
    SHA256 hash;
    RIPEMD160 more_hash;
    byte digest[SHA256::DIGESTSIZE];
    byte digest2[RIPEMD160::DIGESTSIZE];
    hash.CalculateDigest(digest,(const byte *)raw.c_str(),raw.size());
    more_hash.CalculateDigest(digest2, digest, SHA256::DIGESTSIZE);
    Integer d = Integer(digest2, RIPEMD160::DIGESTSIZE+4);
    cout << endl << std::hex << d;
    cout << endl << base58encode(d, 0);
    return digest2;
}

string
base58encode(Integer plain, int zeros)
{
    string adr;
    Integer remainder, temp;
    while(plain != 0)
    {
        plain.Divide(remainder, temp, plain, 58);
        plain = temp;
        adr = b58[remainder.ConvertToLong()] + adr;
    }
    while(zeros)
    {
        adr = "1" + adr;
        zeros--;
    }
    return adr;
}

Integer
base58decode(string input)
{
    int parse;
    Integer key;
    for(int i = 0; i < input.length(); i++)
    {
        parse = 0;
        while(true)
        {
            if(input[i] == b58[parse])
            {
                key = (key + parse)*58;
                break;
            }
            else
                parse++;
        }
    }
    key = key/58;
    return key;
}

string
process(string raw)
{
    SHA256 hash;
    RIPEMD160 more_hash;
    byte digest[SHA256::DIGESTSIZE];
    byte digest2[RIPEMD160::DIGESTSIZE];
    byte digest2_mod[RIPEMD160::DIGESTSIZE+5];
    hash.CalculateDigest(digest,(const byte *)raw.c_str(),raw.size());
    more_hash.CalculateDigest(digest2, digest, SHA256::DIGESTSIZE);
    digest2_mod[0]=0x00;
    for(int i = 0; i<= RIPEMD160::DIGESTSIZE; i++)
        digest2_mod[i+1] = digest2[i];
    hash.CalculateDigest(digest,digest2_mod,RIPEMD160::DIGESTSIZE+1);
    hash.CalculateDigest(digest,digest,SHA256::DIGESTSIZE);
    for(int i = 0; i< 4; i++)
        digest2_mod[i+RIPEMD160::DIGESTSIZE+1] = digest[i];
    Integer out = Integer(digest2_mod, RIPEMD160::DIGESTSIZE+5);
    int lead;
    for(lead = 0; digest2_mod[lead] == 0; lead++);
    string ret = base58encode(out, lead);
    return ret;
}

Kontakt (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 250



View Profile
May 19, 2013, 06:23:59 AM
 #2

Coding coding all night long I'm coding and haters be like 'Error invalid type cast'
scintill
Sr. Member
****
Offline Offline

Activity: 448
Merit: 254


View Profile WWW
May 19, 2013, 06:33:49 AM
 #3

Cool idea.  Vanity addresses might be what needs compressed pubkey most -- they're likely to be spent from a lot.

1SCiN5kqkAbxxwesKMsH9GvyWnWP5YK2W | donations
Kontakt (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 250



View Profile
May 19, 2013, 06:47:00 AM
 #4

Vanitygen CAN be modified fairly easily to produce compressed addresses, but I wanted to do things the hard way.
I completely agree with you, though. Vanity addresses will be used as long as the owner keeps the name, especially for Cascasius and SatoshiDice.
Although single use throw away addresses will probably remain the highest portion of transactions.
scintill
Sr. Member
****
Offline Offline

Activity: 448
Merit: 254


View Profile WWW
May 19, 2013, 06:56:56 PM
 #5

Vanitygen CAN be modified fairly easily to produce compressed addresses, but I wanted to do things the hard way.

True, I guess I mostly meant it's cool to do it yourself from scratch.  The code seems more compact than what I remember seeing in vanitygen, maybe because it can use C++ overloaded operators and stuff.

1SCiN5kqkAbxxwesKMsH9GvyWnWP5YK2W | donations
Kontakt (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 250



View Profile
May 19, 2013, 06:58:53 PM
 #6

That codes is nowhere near finished or operational. It'll probably look closer to Vanitygen when I get through. Smiley
Kontakt (OP)
Sr. Member
****
Offline Offline

Activity: 266
Merit: 250



View Profile
May 20, 2013, 05:23:37 AM
 #7

So I can generate a correct compressed address from scratch.
Not much, but getting there.

Current goal, compare generated key to desired pattern.
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!