15 #ifndef BITCOIN_BASE58_H
16 #define BITCOIN_BASE58_H
29 #include <openssl/bn.h>
31 namespace fc {
namespace detail {
53 throw bignum_error(
"CAutoBN_CTX : BN_CTX_new() returned NULL");
62 operator BN_CTX*() {
return pctx; }
80 if (!BN_copy(bn, b.bn))
83 throw bignum_error(
"CBigNum::CBigNum(const CBigNum&) : BN_copy failed");
89 if (!BN_copy(bn, b.bn))
90 throw bignum_error(
"CBigNum::operator= : BN_copy failed");
109 explicit CBigNum(
const std::vector<unsigned char>& vch)
117 if (!BN_set_word(bn, n))
118 throw bignum_error(
"CBigNum conversion from unsigned long : BN_set_word failed");
123 return BN_get_word(bn);
128 return BN_get_word(bn);
133 unsigned long n = BN_get_word(bn);
134 if (!BN_is_negative(bn))
135 return (n > (
unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::max() : n);
137 return (n > (
unsigned long)std::numeric_limits<int>::max() ? std::numeric_limits<int>::min() : -(
int)n);
142 unsigned char pch[
sizeof(n) + 6];
143 unsigned char* p = pch + 4;
144 bool fNegative =
false;
150 bool fLeadingZeroes =
true;
151 for (
int i = 0; i < 8; i++)
153 unsigned char c = (n >> 56) & 0xff;
160 *p++ = (fNegative ? 0x80 : 0);
163 fLeadingZeroes =
false;
167 unsigned int nSize = p - (pch + 4);
168 pch[0] = (nSize >> 24) & 0xff;
169 pch[1] = (nSize >> 16) & 0xff;
170 pch[2] = (nSize >> 8) & 0xff;
171 pch[3] = (nSize) & 0xff;
172 BN_mpi2bn(pch, p - pch, bn);
177 unsigned char pch[
sizeof(n) + 6];
178 unsigned char* p = pch + 4;
179 bool fLeadingZeroes =
true;
180 for (
int i = 0; i < 8; i++)
182 unsigned char c = (n >> 56) & 0xff;
190 fLeadingZeroes =
false;
194 unsigned int nSize = p - (pch + 4);
195 pch[0] = (nSize >> 24) & 0xff;
196 pch[1] = (nSize >> 16) & 0xff;
197 pch[2] = (nSize >> 8) & 0xff;
198 pch[3] = (nSize) & 0xff;
199 BN_mpi2bn(pch, p - pch, bn);
203 void setvch(
const std::vector<unsigned char>& vch)
205 std::vector<unsigned char> vch2(vch.size() + 4);
206 unsigned int nSize = vch.size();
209 vch2[0] = (nSize >> 24) & 0xff;
210 vch2[1] = (nSize >> 16) & 0xff;
211 vch2[2] = (nSize >> 8) & 0xff;
212 vch2[3] = (nSize >> 0) & 0xff;
214 reverse_copy(vch.begin(), vch.end(), vch2.begin() + 4);
215 BN_mpi2bn(&vch2[0], vch2.size(), bn);
218 std::vector<unsigned char>
getvch()
const
220 unsigned int nSize = BN_bn2mpi(bn, NULL);
222 return std::vector<unsigned char>();
223 std::vector<unsigned char> vch(nSize);
224 BN_bn2mpi(bn, &vch[0]);
225 vch.erase(vch.begin(), vch.begin() + 4);
226 reverse(vch.begin(), vch.end());
232 unsigned int nSize = nCompact >> 24;
233 std::vector<unsigned char> vch(4 + nSize);
235 if (nSize >= 1) vch[4] = (nCompact >> 16) & 0xff;
236 if (nSize >= 2) vch[5] = (nCompact >> 8) & 0xff;
237 if (nSize >= 3) vch[6] = (nCompact >> 0) & 0xff;
238 BN_mpi2bn(&vch[0], vch.size(), bn);
244 unsigned int nSize = BN_bn2mpi(bn, NULL);
245 std::vector<unsigned char> vch(nSize);
247 BN_bn2mpi(bn, &vch[0]);
248 unsigned int nCompact = nSize << 24;
249 if (nSize >= 1) nCompact |= (vch[4] << 16);
250 if (nSize >= 2) nCompact |= (vch[5] << 8);
251 if (nSize >= 3) nCompact |= (vch[6] << 0);
258 const char* psz = str.c_str();
259 while (isspace(*psz))
261 bool fNegative =
false;
267 if (psz[0] ==
'0' && tolower(psz[1]) ==
'x')
269 while (isspace(*psz))
273 static signed char phexdigit[256] = { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, 0,0xa,0xb,0xc,0xd,0xe,0xf,0,0,0,0,0,0,0,0,0 };
275 while (isxdigit(*psz))
278 int n = phexdigit[(
unsigned char)*psz++];
282 BN_set_negative(bn, 1);
292 BN_set_negative(bn.bn,
false);
295 if (BN_cmp(bn.bn, bn0.bn) == 0)
297 while (BN_cmp(bn.bn, bn0.bn) > 0)
299 if (!BN_div(dv.bn, rem.bn, bn.bn, bnBase.bn, pctx))
300 throw bignum_error(
"CBigNum::ToString() : BN_div failed");
303 str +=
"0123456789abcdef"[c];
305 if (BN_is_negative(this->bn))
307 reverse(str.begin(), str.end());
320 return BN_is_zero(bn);
325 if (!BN_add(bn, bn, b.bn))
326 throw bignum_error(
"CBigNum::operator+= : BN_add failed");
332 if (!BN_sub(bn, bn, b.bn))
333 throw bignum_error(
"CBigNum::operator-= : BN_sub failed");
340 if (!BN_mul(bn, bn, b.bn, pctx))
341 throw bignum_error(
"CBigNum::operator*= : BN_mul failed");
348 if (!BN_div(bn, NULL, bn, b.bn, pctx))
349 throw bignum_error(
"CBigNum::operator/= : BN_div failed");
356 if (!BN_div(NULL, bn, bn, b.bn, pctx))
357 throw bignum_error(
"CBigNum::operator%= : BN_div failed");
363 if (!BN_lshift(bn, bn, shift))
364 throw bignum_error(
"CBigNum:operator<<= : BN_lshift failed");
374 if (BN_cmp(a.bn, bn) > 0)
380 if (!BN_rshift(bn, bn, shift))
381 throw bignum_error(
"CBigNum:operator>>= : BN_rshift failed");
389 if (!BN_add(bn, bn, BN_value_one()))
390 throw bignum_error(
"CBigNum::operator++ : BN_add failed");
406 if (!BN_sub(r.bn, bn, BN_value_one()))
407 throw bignum_error(
"CBigNum::operator-- : BN_sub failed");
434 throw bignum_error(
"CBigNum::operator+ : BN_add failed");
442 throw bignum_error(
"CBigNum::operator- : BN_sub failed");
458 throw bignum_error(
"CBigNum::operator* : BN_mul failed");
467 throw bignum_error(
"CBigNum::operator/ : BN_div failed");
476 throw bignum_error(
"CBigNum::operator% : BN_div failed");
484 throw bignum_error(
"CBigNum:operator<< : BN_lshift failed");
503 static const char* pszBase58 =
"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz";
506 inline std::string
EncodeBase58(
const unsigned char* pbegin,
const unsigned char* pend)
514 std::vector<unsigned char> vchTmp(pend-pbegin+1, 0);
515 reverse_copy(pbegin, pend, vchTmp.begin());
525 str.reserve((pend - pbegin) * 138 / 100 + 1);
538 for (
const unsigned char* p = pbegin; p < pend && *p == 0; p++)
542 reverse(str.begin(), str.end());
555 inline bool DecodeBase58(
const char* psz, std::vector<unsigned char>& vchRet)
562 while (isspace(*psz))
566 for (
const char* p = psz; *p; p++)
568 const char* p1 = strchr(pszBase58, *p);
586 std::vector<unsigned char> vchTmp = bn.
getvch();
589 if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80)
590 vchTmp.erase(vchTmp.end()-1);
593 int nLeadingZeros = 0;
594 for (
const char* p = psz; *p == pszBase58[0]; p++)
596 vchRet.assign(nLeadingZeros + vchTmp.size(), 0);
599 reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size());
605 inline bool DecodeBase58(
const std::string& str, std::vector<unsigned char>& vchRet)
620 return std::string();
623 std::vector<unsigned char> out;
625 FC_THROW_EXCEPTION( parse_error_exception,
"Unable to decode base58 string ${base58_str}",
626 (
"base58_str",base58_str) );
628 return std::vector<char>((
const char*)out.data(), ((
const char*)out.data())+out.size() );
633 size_t from_base58(
const std::string& base58_str,
char* out_data,
size_t out_data_len ) {
634 std::vector<unsigned char> out;
636 FC_THROW_EXCEPTION( parse_error_exception,
"Unable to decode base58 string ${base58_str}",
637 (
"base58_str",base58_str) );
641 memcpy( out_data, out.data(), out.size() );