const EC_POINT* crypt_ec_helper::from_base58(std::string base58) { const char* psz = base58.c_str(); std::vector<unsigned char> vch; // Skip leading spaces. while (*psz && isspace(*psz)) psz++; // Skip and count leading '1's. int zeroes = 0; while (*psz == '1') { zeroes++; psz++; } // Allocate enough space in big-endian base256 representation. std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up. // Process the characters. while (*psz && !isspace(*psz)) { // Decode base58 character const char* ch = strchr(pszBase58, *psz); if (ch == NULL) return NULL; // Apply "b256 = b256 * 58 + ch". int carry = ch - pszBase58; for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) { carry += 58 * (*it); *it = carry % 256; carry /= 256; } assert(carry == 0); psz++; } // Skip trailing spaces. while (isspace(*psz)) psz++; if (*psz != 0) return NULL; // Skip leading zeroes in b256. std::vector<unsigned char>::iterator it = b256.begin(); while (it != b256.end() && *it == 0) it++; // Copy result into output vector. vch.reserve(zeroes + (b256.end() - it)); vch.assign(zeroes, 0x00); while (it != b256.end()) vch.push_back(*(it++)); EC_GROUP *ecgrp = EC_GROUP_new_by_curve_name(NID_secp256k1); pub = EC_POINT_new(ecgrp); size_t len = EC_POINT_oct2point(ecgrp, pub, vch.data(), vch.size(), NULL); EC_GROUP_free(ecgrp); return pub; }
bool DecodeBase58(const char *psz, std::vector<uint8_t> &vch) { // Skip leading spaces. while (*psz && isspace(*psz)) { psz++; } // Skip and count leading '1's. int zeroes = 0; int length = 0; while (*psz == '1') { zeroes++; psz++; } // Allocate enough space in big-endian base256 representation. // log(58) / log(256), rounded up. int size = strlen(psz) * 733 / 1000 + 1; std::vector<uint8_t> b256(size); // Process the characters. while (*psz && !isspace(*psz)) { // Decode base58 character const char *ch = strchr(pszBase58, *psz); if (ch == nullptr) { return false; } // Apply "b256 = b256 * 58 + ch". int carry = ch - pszBase58; int i = 0; for (std::vector<uint8_t>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) { carry += 58 * (*it); *it = carry % 256; carry /= 256; } assert(carry == 0); length = i; psz++; } // Skip trailing spaces. while (isspace(*psz)) { psz++; } if (*psz != 0) { return false; } // Skip leading zeroes in b256. std::vector<uint8_t>::iterator it = b256.begin() + (size - length); while (it != b256.end() && *it == 0) it++; // Copy result into output vector. vch.reserve(zeroes + (b256.end() - it)); vch.assign(zeroes, 0x00); while (it != b256.end()) { vch.push_back(*(it++)); } return true; }
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch) { // Skip leading spaces. while (*psz && isspace(*psz)) psz++; // Skip and count leading '1's. size_t zeroes = 0; size_t length = 0; while (*psz == '1') { zeroes++; psz++; } // Allocate enough space in big-endian base256 representation. size_t size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up. std::vector<unsigned char> b256(size); // Process the characters. while (*psz && !isspace(*psz)) { // Decode base58 character const char* ch = strchr(pszBase58, *psz); if (ch == nullptr) return false; // Apply "b256 = b256 * 58 + ch". auto carry = ch - pszBase58; size_t i = 0; for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) { carry += 58 * (*it); *it = static_cast<unsigned char>(carry % 256); carry /= 256; } assert(carry == 0); length = i; psz++; } // Skip trailing spaces. while (isspace(*psz)) psz++; if (*psz != 0) return false; // Skip leading zeroes in b256. auto it = b256.begin(); std::advance(it, static_cast<int64_t>(size - length)); while (it != b256.end() && *it == 0) ++it; // Copy result into output vector. vch.reserve(zeroes + static_cast<size_t>(std::distance(it, b256.end()))); vch.assign(zeroes, 0x00); while (it != b256.end()) vch.push_back(*(it++)); return true; }
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vch) { // Skip leading spaces. while (*psz && isspace(*psz)) psz++; // Skip and count leading '1's. int zeroes = 0; int length = 0; while (*psz == '1') { zeroes++; psz++; } // Allocate enough space in big-endian base256 representation. int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up. std::vector<unsigned char> b256(size); // Process the characters. static_assert(sizeof(mapBase58)/sizeof(mapBase58[0]) == 256, "mapBase58.size() should be 256"); // guarantee not out of range while (*psz && !isspace(*psz)) { // Decode base58 character int carry = mapBase58[(uint8_t)*psz]; if (carry == -1) // Invalid b58 character return false; int i = 0; for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); (carry != 0 || i < length) && (it != b256.rend()); ++it, ++i) { carry += 58 * (*it); *it = carry % 256; carry /= 256; } assert(carry == 0); length = i; psz++; } // Skip trailing spaces. while (isspace(*psz)) psz++; if (*psz != 0) return false; // Skip leading zeroes in b256. std::vector<unsigned char>::iterator it = b256.begin() + (size - length); while (it != b256.end() && *it == 0) it++; // Copy result into output vector. vch.reserve(zeroes + (b256.end() - it)); vch.assign(zeroes, 0x00); while (it != b256.end()) vch.push_back(*(it++)); return true; }
static std::string decodeBase58 (std::string const& s, InverseArray const& inv) { auto psz = s.c_str(); auto remain = s.size(); // Skip and count leading zeroes int zeroes = 0; while (remain > 0 && inv[*psz] == 0) { ++zeroes; ++psz; --remain; } // Allocate enough space in big-endian base256 representation. // log(58) / log(256), rounded up. std::vector<unsigned char> b256( remain * 733 / 1000 + 1); while (remain > 0) { auto carry = inv[*psz]; if (carry == -1) return {}; // Apply "b256 = b256 * 58 + carry". for (auto iter = b256.rbegin(); iter != b256.rend(); ++iter) { carry += 58 * *iter; *iter = carry % 256; carry /= 256; } assert(carry == 0); ++psz; --remain; } // Skip leading zeroes in b256. auto iter = std::find_if( b256.begin(), b256.end(),[](unsigned char c) { return c != 0; }); std::string result; result.reserve (zeroes + (b256.end() - iter)); result.assign (zeroes, 0x00); while (iter != b256.end()) result.push_back(*(iter++)); return result; }
bool decodebase58(const char* psz, std::vector<unsigned char>& vch) { // skip leading spaces. while (*psz && isspace(*psz)) psz++; // skip and count leading '1's. int zeroes = 0; while (*psz == '1') { zeroes++; psz++; } // allocate enough space in big-endian base256 representation. std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up. // process the characters. while (*psz && !isspace(*psz)) { // decode base58 character const char* ch = strchr(pszbase58, *psz); if (ch == null) return false; // apply "b256 = b256 * 58 + ch". int carry = ch - pszbase58; for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) { carry += 58 * (*it); *it = carry % 256; carry /= 256; } assert(carry == 0); psz++; } // skip trailing spaces. while (isspace(*psz)) psz++; if (*psz != 0) return false; // skip leading zeroes in b256. std::vector<unsigned char>::iterator it = b256.begin(); while (it != b256.end() && *it == 0) it++; // copy result into output vector. vch.reserve(zeroes + (b256.end() - it)); vch.assign(zeroes, 0x00); while (it != b256.end()) vch.push_back(*(it++)); return true; }
bool DecodeBase58(const char* psz, std::vector<unsigned char>& vchRet) { CAutoBN_CTX pctx; vchRet.clear(); CBigNum bn58 = 58; CBigNum bn = 0; CBigNum bnChar; // Skip leading spaces. while (*psz && isspace(*psz)) psz++; // Skip and count leading '1's. int zeroes = 0; while (*psz == '1') { zeroes++; psz++; } // Convert big endian string to bignum for (const char* p = psz; *p; p++) { const char* p1 = strchr(pszBase58, *p); if (p1 == NULL) { while (isspace(*p)) p++; if (*p != '\0') return false; break; } bnChar.setulong(p1 - pszBase58); if (!BN_mul(&bn, &bn, &bn58, pctx)) throw bignum_error("DecodeBase58 : BN_mul failed"); bn += bnChar; } // Get bignum as little endian data std::vector<unsigned char> vchTmp = bn.getvch(); // Trim off sign byte if present if (vchTmp.size() >= 2 && vchTmp.end()[-1] == 0 && vchTmp.end()[-2] >= 0x80) vchTmp.erase(vchTmp.end()-1); // Restore leading zeros int nLeadingZeros = 0; for (const char* p = psz; *p == pszBase58[0]; p++) nLeadingZeros++; vchRet.assign(nLeadingZeros + vchTmp.size(), 0); // Convert little endian data to big endian reverse_copy(vchTmp.begin(), vchTmp.end(), vchRet.end() - vchTmp.size()); return true; // Allocate enough space in big-endian base256 representation. std::vector<unsigned char> b256(strlen(psz) * 733 / 1000 + 1); // log(58) / log(256), rounded up. // Process the characters. while (*psz && !isspace(*psz)) { // Decode base58 character const char *ch = strchr(pszBase58, *psz); if (ch == NULL) return false; // Apply "b256 = b256 * 58 + ch". int carry = ch - pszBase58; for (std::vector<unsigned char>::reverse_iterator it = b256.rbegin(); it != b256.rend(); it++) { carry += 58 * (*it); *it = carry % 256; carry /= 256; } assert(carry == 0); psz++; } // Skip trailing spaces. while (isspace(*psz)) psz++; if (*psz != 0) return false; // Skip leading zeroes in b256. std::vector<unsigned char>::iterator it = b256.begin(); while (it != b256.end() && *it == 0) it++; // Copy result into output vector. vchRet.reserve(zeroes + (b256.end() - it)); vchRet.assign(zeroes, 0x00); while (it != b256.end()) vchRet.push_back(*(it++)); return true; }