Back to home page

Bitcoin sources

 
 

    


0001 // Copyright (c) 2009-2010 Satoshi Nakamoto
0002 // Copyright (c) 2011 The Bitcoin Developers
0003 // Distributed under the MIT/X11 software license, see the accompanying
0004 // file license.txt or http://www.opensource.org/licenses/mit-license.php.
0005 
0006 
0007 //
0008 // Why base-58 instead of standard base-64 encoding?
0009 // - Don't want 0OIl characters that look the same in some fonts and
0010 //      could be used to create visually identical looking account numbers.
0011 // - A string with non-alphanumeric characters is not as easily accepted as an account number.
0012 // - E-mail usually won't line-break if there's no punctuation to break at.
0013 // - Doubleclicking selects the whole number as one word if it's all alphanumeric.
0014 //
0015 #ifndef BITCOIN_BASE58_H
0016 #define BITCOIN_BASE58_H
0017 
0018 #include <string>
0019 #include <vector>
0020 #include "bignum.h"
0021 
0022 static const char* pszBase58 = "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
0023 
0024 // Encode a byte sequence as a base58-encoded string
0025 inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
0026 {
0027     CAutoBN_CTX pctx;
0028     CBigNum bn58 = 58;
0029     CBigNum bn0 = 0;
0030 
0031     // Convert big endian data to little endian
0032     // Extra zero at the end make sure bignum will interpret as a positive number
0033     std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
0034     reverse_copy(pbegin, pend, vchTmp.begin());
0035 
0036     // Convert little endian data to bignum
0037     CBigNum bn;
0038     bn.setvch(vchTmp);
0039 
0040     // Convert bignum to std::string
0041     std::string str;
0042     // Expected size increase from base58 conversion is approximately 137%
0043     // use 138% to be safe
0044     str.reserve((pend - pbegin) * 138 / 100 + 1);
0045     CBigNum dv;
0046     CBigNum rem;
0047     while (bn > bn0)
0048     {
0049         if (!BN_div(&dv, &rem, &bn, &bn58, pctx))
0050             throw bignum_error("EncodeBase58 : BN_div failed");
0051         bn = dv;
0052         unsigned int c = rem.getulong();
0053         str += pszBase58[c];
0054     }
0055 
0056     // Leading zeroes encoded as base58 zeros
0057     for (const unsigned char* p = pbegin; p < pend && *p == 0; p++)
0058         str += pszBase58[0];
0059 
0060     // Convert little endian std::string to big endian
0061     reverse(str.begin(), str.end());
0062     return str;
0063 }
0064 
0065 // Encode a byte vector as a base58-encoded string
0066 inline std::string EncodeBase58(const std::vector<unsigned char>& vch)
0067 {
0068     return EncodeBase58(&vch[0], &vch[0] + vch.size());
0069 }
0070 
0071 // Decode a base58-encoded string psz into byte vector vchRet
0072 // returns true if decoding is succesful
0073 inline bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet)
0074 {
0075     CAutoBN_CTX pctx;
0076     vchRet.clear();
0077     CBigNum bn58 = 58;
0078     CBigNum bn = 0;
0079     CBigNum bnChar;
0080     while (isspace(*psz))
0081         psz++;
0082 
0083     // Convert big endian string to bignum
0084     for (const char* p = psz; *p; p++)
0085     {
0086         const char* p1 = strchr(pszBase58, *p);
0087         if (p1 == NULL)
0088         {
0089             while (isspace(*p))
0090                 p++;
0091             if (*p != '\0')
0092                 return false;
0093             break;
0094         }
0095         bnChar.setulong(p1 - pszBase58);
0096         if (!BN_mul(&bn, &bn, &bn58, pctx))
0097             throw bignum_error("DecodeBase58 : BN_mul failed");
0098         bn += bnChar;
0099     }
0100 
0101     // Get bignum as little endian data
0102     std::vector<unsigned char> vchTmp = bn.getvch();
0103 
0104     // Trim off sign byte if present
0105     if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
0106         vchTmp.erase(vchTmp.end()-1);
0107 
0108     // Restore leading zeros
0109     int nLeadingZeros = 0;
0110     for (const char* p = psz; *p == pszBase58[0]; p++)
0111         nLeadingZeros++;
0112     vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
0113 
0114     // Convert little endian data to big endian
0115     reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
0116     return true;
0117 }
0118 
0119 // Decode a base58-encoded string str into byte vector vchRet
0120 // returns true if decoding is succesful
0121 inline bool DecodeBase58(const std::string& str, std::vector<unsigned char>& vchRet)
0122 {
0123     return DecodeBase58(str.c_str(), vchRet);
0124 }
0125 
0126 
0127 
0128 
0129 // Encode a byte vector to a base58-encoded string, including checksum
0130 inline std::string EncodeBase58Check(const std::vector<unsigned char>& vchIn)
0131 {
0132     // add 4-byte hash check to the end
0133     std::vector<unsigned char> vch(vchIn);
0134     uint256 hash = Hash(vch.begin(), vch.end());
0135     vch.insert(vch.end(), (unsigned char*)&hash, (unsigned char*)&hash + 4);
0136     return EncodeBase58(vch);
0137 }
0138 
0139 // Decode a base58-encoded string psz that includes a checksum, into byte vector vchRet
0140 // returns true if decoding is succesful
0141 inline bool DecodeBase58Check(const char* psz, std::vector<unsigned char>& vchRet)
0142 {
0143     if (!DecodeBase58(psz, vchRet))
0144         return false;
0145     if (vchRet.size() < 4)
0146     {
0147         vchRet.clear();
0148         return false;
0149     }
0150     uint256 hash = Hash(vchRet.begin(), vchRet.end()-4);
0151     if (memcmp(&hash, &vchRet.end()[-4], 4) != 0)
0152     {
0153         vchRet.clear();
0154         return false;
0155     }
0156     vchRet.resize(vchRet.size()-4);
0157     return true;
0158 }
0159 
0160 // Decode a base58-encoded string str that includes a checksum, into byte vector vchRet
0161 // returns true if decoding is succesful
0162 inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>& vchRet)
0163 {
0164     return DecodeBase58Check(str.c_str(), vchRet);
0165 }
0166 
0167 
0168 
0169 
0170 
0171 // Base class for all base58-encoded data
0172 class CBase58Data
0173 {
0174 protected:
0175     // the version byte
0176     unsigned char nVersion;
0177 
0178     // the actually encoded data
0179     std::vector<unsigned char> vchData;
0180 
0181     CBase58Data()
0182     {
0183         nVersion = 0;
0184         vchData.clear();
0185     }
0186 
0187     ~CBase58Data()
0188     {
0189         // zero the memory, as it may contain sensitive data
0190         if (!vchData.empty())
0191             memset(&vchData[0], 0, vchData.size());
0192     }
0193 
0194     void SetData(int nVersionIn, const void* pdata, size_t nSize)
0195     {
0196         nVersion = nVersionIn;
0197         vchData.resize(nSize);
0198         if (!vchData.empty())
0199             memcpy(&vchData[0], pdata, nSize);
0200     }
0201 
0202     void SetData(int nVersionIn, const unsigned char *pbegin, const unsigned char *pend)
0203     {
0204         SetData(nVersionIn, (void*)pbegin, pend - pbegin);
0205     }
0206 
0207 public:
0208     bool SetString(const char* psz)
0209     {
0210         std::vector<unsigned char> vchTemp;
0211         DecodeBase58Check(psz, vchTemp);
0212         if (vchTemp.empty())
0213         {
0214             vchData.clear();
0215             nVersion = 0;
0216             return false;
0217         }
0218         nVersion = vchTemp[0];
0219         vchData.resize(vchTemp.size() - 1);
0220         if (!vchData.empty())
0221             memcpy(&vchData[0], &vchTemp[1], vchData.size());
0222         memset(&vchTemp[0], 0, vchTemp.size());
0223         return true;
0224     }
0225 
0226     bool SetString(const std::string& str)
0227     {
0228         return SetString(str.c_str());
0229     }
0230 
0231     std::string ToString() const
0232     {
0233         std::vector<unsigned char> vch(1, nVersion);
0234         vch.insert(vch.end(), vchData.begin(), vchData.end());
0235         return EncodeBase58Check(vch);
0236     }
0237 
0238     int CompareTo(const CBase58Data& b58) const
0239     {
0240         if (nVersion < b58.nVersion) return -1;
0241         if (nVersion > b58.nVersion) return  1;
0242         if (vchData < b58.vchData)   return -1;
0243         if (vchData > b58.vchData)   return  1;
0244         return 0;
0245     }
0246 
0247     bool operator==(const CBase58Data& b58) const { return CompareTo(b58) == 0; }
0248     bool operator<=(const CBase58Data& b58) const { return CompareTo(b58) <= 0; }
0249     bool operator>=(const CBase58Data& b58) const { return CompareTo(b58) >= 0; }
0250     bool operator< (const CBase58Data& b58) const { return CompareTo(b58) <  0; }
0251     bool operator> (const CBase58Data& b58) const { return CompareTo(b58) >  0; }
0252 };
0253 
0254 // base58-encoded bitcoin addresses
0255 // Addresses have version 0 or 111 (testnet)
0256 // The data vector contains RIPEMD160(SHA256(pubkey)), where pubkey is the serialized public key
0257 class CBitcoinAddress : public CBase58Data
0258 {
0259 public:
0260     bool SetHash160(const uint160& hash160)
0261     {
0262         SetData(fTestNet ? 111 : 0, &hash160, 20);
0263         return true;
0264     }
0265 
0266     bool SetPubKey(const std::vector<unsigned char>& vchPubKey)
0267     {
0268         return SetHash160(Hash160(vchPubKey));
0269     }
0270 
0271     bool IsValid() const
0272     {
0273         int nExpectedSize = 20;
0274         bool fExpectTestNet = false;
0275         switch(nVersion)
0276         {
0277             case 0:
0278                 break;
0279 
0280             case 111:
0281                 fExpectTestNet = true;
0282                 break;
0283 
0284             default:
0285                 return false;
0286         }
0287         return fExpectTestNet == fTestNet && vchData.size() == nExpectedSize;
0288     }
0289 
0290     CBitcoinAddress()
0291     {
0292     }
0293 
0294     CBitcoinAddress(uint160 hash160In)
0295     {
0296         SetHash160(hash160In);
0297     }
0298 
0299     CBitcoinAddress(const std::vector<unsigned char>& vchPubKey)
0300     {
0301         SetPubKey(vchPubKey);
0302     }
0303 
0304     CBitcoinAddress(const std::string& strAddress)
0305     {
0306         SetString(strAddress);
0307     }
0308 
0309     CBitcoinAddress(const char* pszAddress)
0310     {
0311         SetString(pszAddress);
0312     }
0313 
0314     uint160 GetHash160() const
0315     {
0316         assert(vchData.size() == 20);
0317         uint160 hash160;
0318         memcpy(&hash160, &vchData[0], 20);
0319         return hash160;
0320     }
0321 };
0322 
0323 #endif