bool key_from_base58(secp256k1_context *secpctx, const char *base58, size_t base58_len, bool *test_net, struct privkey *priv, struct pubkey *key) { // 1 byte version, 32 byte private key, 1 byte compressed, 4 byte checksum u8 keybuf[1 + 32 + 1 + 4]; size_t keybuflen = sizeof(keybuf); b58tobin(keybuf, &keybuflen, base58, base58_len); if (b58check(keybuf, sizeof(keybuf), base58, base58_len) < 0) return false; /* Byte after key should be 1 to represent a compressed key. */ if (keybuf[1 + 32] != 1) return false; if (keybuf[0] == 128) *test_net = false; else if (keybuf[0] == 239) *test_net = true; else return false; /* Copy out secret. */ memcpy(priv->secret, keybuf + 1, sizeof(priv->secret)); if (!secp256k1_ec_seckey_verify(secpctx, priv->secret)) return false; /* Get public key, too. */ if (!pubkey_from_privkey(secpctx, priv, key)) return false; return true; }
static bool from_base58(u8 *version, struct ripemd160 *rmd, const char *base58, size_t base58_len) { u8 buf[1 + sizeof(*rmd) + 4]; b58_sha256_impl = my_sha256; size_t buflen = sizeof(buf); b58tobin(buf, &buflen, base58, base58_len); int r = b58check(buf, sizeof(buf), base58, base58_len); *version = buf[0]; memcpy(rmd, buf + 1, sizeof(*rmd)); return r > 0; }
int base58_decode_check(const char *str, uint8_t *data, int datalen) { if (datalen > 128) { return 0; } uint8_t d[datalen + 4]; size_t res = datalen + 4; if (b58tobin(d, &res, str) != true) { return 0; } uint8_t *nd = d + datalen + 4 - res; if (b58check(nd, res, str) < 0) { return 0; } memcpy(data, nd, res - 4); return res - 4; }
int base58_decode_check(const char *str, uint8_t *data, int datalen) { int ret; if (datalen > 128) { return 0; } uint8_t d[datalen + 4]; size_t res = datalen + 4; if (b58tobin(d, &res, str) != true) { ret = 0; } else if (res != (size_t)datalen + 4) { ret = 0; } else if (b58check(d, res, str) < 0) { ret = 0; } else { memcpy(data, d, datalen); ret = datalen; } utils_zero(d, sizeof(d)); return ret; }
size_t blkmk_address_to_script(void *out, size_t outsz, const char *addr) { unsigned char addrbin[25]; unsigned char *cout = out; const size_t b58sz = strlen(addr); int addrver; size_t rv; rv = sizeof(addrbin); if (!b58_sha256_impl) b58_sha256_impl = blkmk_sha256_impl; if (!b58tobin(addrbin, &rv, addr, b58sz)) return 0; addrver = b58check(addrbin, sizeof(addrbin), addr, b58sz); switch (addrver) { case 0: // Bitcoin pubkey hash case 111: // Testnet pubkey hash if (outsz < (rv = 25)) return rv; cout[ 0] = 0x76; // OP_DUP cout[ 1] = 0xa9; // OP_HASH160 cout[ 2] = 0x14; // push 20 bytes memcpy(&cout[3], &addrbin[1], 20); cout[23] = 0x88; // OP_EQUALVERIFY cout[24] = 0xac; // OP_CHECKSIG return rv; case 5: // Bitcoin script hash case 196: // Testnet script hash if (outsz < (rv = 23)) return rv; cout[ 0] = 0xa9; // OP_HASH160 cout[ 1] = 0x14; // push 20 bytes memcpy(&cout[2], &addrbin[1], 20); cout[22] = 0x87; // OP_EQUAL return rv; default: return 0; } }
bool _blkmk_b58tobin(void *bin, size_t binsz, const char *b58, size_t b58sz) { return b58tobin(bin, &binsz, b58, b58sz); }
bool PubAddr::loadAddr(ustring address) { unsigned int i = 0; string BM = address.getString(3, i); if (strncmp(BM.c_str(), "BM-", 3) != 0) { i = 0; } char retu[100]; size_t size2 = 50; if (b58tobin(retu, &size2, (char *)address.getRest(i).c_str()) != true) { return false; //ignoring key not valid } ustring _buffer; retu[size2] = 0x00; for (unsigned int j = 0; j < size2; j++) _buffer += retu[j]; i = 0; unsigned int checkPos = _buffer.length() - 4; if (checkPos < (unsigned int)0) return false; ustring buffer = _buffer.getUstring(checkPos, i); byte checksum[4]; memcpy(checksum, _buffer.getUstring(4, checkPos).c_str(), sizeof checksum); CryptoPP::SHA512 hash; byte digest[CryptoPP::SHA512::DIGESTSIZE]; byte digest2[CryptoPP::SHA512::DIGESTSIZE]; hash.CalculateDigest(digest, (byte*)buffer.c_str(), buffer.length()); hash.CalculateDigest(digest2, digest, sizeof digest); if (memcmp(digest2, checksum, sizeof checksum)!=0) { return false; //ignoring key not valid } i = 0; std::unique_lock<std::shared_timed_mutex> mlock(this->mutex_); this->address = address; int tmp_vers = (int)buffer.getVarInt_B(i); int tmp_stream = (int)buffer.getVarInt_B(i); ustring tmp_ripe = buffer.getRest(i); if (tmp_ripe.length() > 20) return false; //too long if (tmp_ripe.length() < 4) return false; //too short this->version = tmp_vers; this->stream = tmp_stream; while (tmp_ripe.length() != 20) //todo add function prepend { ustring tmp2; tmp2.appendInt8(0); tmp2+=tmp_ripe; tmp_ripe = tmp2; } this->ripe.clear(); this->ripe = tmp_ripe; buffer.clear(); buffer.appendVarInt_B(this->version); buffer.appendVarInt_B(this->stream); buffer += this->ripe; hash.CalculateDigest(digest, (byte*)buffer.c_str(), buffer.length()); hash.CalculateDigest(digest2, digest, sizeof digest); this->tagE.clear(); this->tagE.append(digest2, 32); this->tag.clear(); this->tag.append(&(digest2[32]), 32); this->empty = true; mlock.unlock(); return true; }