long_hash hmac_sha512_hash(data_slice data, data_slice key) { long_hash hash; HMACSHA512(data.data(), data.size(), key.data(), key.size(), hash.data()); return hash; }
hash_digest hmac_sha256_hash(data_slice data, data_slice key) { hash_digest hash; HMACSHA256(data.data(), data.size(), key.data(), key.size(), hash.data()); return hash; }
data_chunk scrypt(data_slice data, data_slice salt, uint64_t N, uint32_t p, uint32_t r, size_t length) { data_chunk output(length); const auto result = crypto_scrypt(data.data(), data.size(), salt.data(), salt.size(), N, r, p, output.data(), output.size()); handle_script_result(result); return output; }
hash_digest sha256_hash(data_slice first, data_slice second) { hash_digest hash; SHA256CTX context; SHA256Init(&context); SHA256Update(&context, first.data(), first.size()); SHA256Update(&context, second.data(), second.size()); SHA256Final(&context, hash.data()); return hash; }
long_hash pkcs5_pbkdf2_hmac_sha512(data_slice passphrase, data_slice salt, size_t iterations) { long_hash hash; const auto result = pkcs5_pbkdf2(passphrase.data(), passphrase.size(), salt.data(), salt.size(), hash.data(), hash.size(), iterations); if (result != 0) throw std::bad_alloc(); return hash; }
bool is_uncompressed_key(data_slice point) { const auto size = point.size(); if (size != ec_uncompressed_size) return false; const auto first = point.data()[0]; return first == uncompressed; }
// This verifies the checksum. bool unwrap(wallet::wrapped_data& data, data_slice wrapped) { if (!verify_checksum(wrapped)) return false; data.version = wrapped.data()[0]; const auto payload_begin = std::begin(wrapped) + 1; const auto checksum_begin = std::end(wrapped) - checksum_size; data.payload.resize(checksum_begin - payload_begin); std::copy(payload_begin, checksum_begin, data.payload.begin()); data.checksum = from_little_endian_unsafe<uint32_t>(checksum_begin); return true; }
bool unwrap(uint8_t& version, data_chunk& payload, uint32_t& checksum, data_slice wrapped) { constexpr size_t version_length = sizeof(version); constexpr size_t checksum_length = sizeof(checksum); // guard against insufficient buffer length if (wrapped.size() < version_length + checksum_length) return false; if (!verify_checksum(wrapped)) return false; // set return values version = wrapped.data()[0]; payload = data_chunk(wrapped.begin() + version_length, wrapped.end() - checksum_length); const auto checksum_start = wrapped.end() - checksum_length; auto deserial = make_deserializer(checksum_start, wrapped.end()); checksum = deserial.read_4_bytes(); return true; }
bool verify_signature(data_slice point, const hash_digest& hash, const ec_signature& signature) { // Copy to avoid exposing external types. secp256k1_ecdsa_signature parsed; std::copy(signature.begin(), signature.end(), std::begin(parsed.data)); // secp256k1_ecdsa_verify rejects non-normalized (low-s) signatures, but // bitcoin does not have such a limitation, so we always normalize. secp256k1_ecdsa_signature normal; const auto context = verification.context(); secp256k1_ecdsa_signature_normalize(context, &normal, &parsed); // This uses a data slice and calls secp256k1_ec_pubkey_parse() in place of // parse() so that we can support the der_verify data_chunk optimization. secp256k1_pubkey pubkey; const auto size = point.size(); return secp256k1_ec_pubkey_parse(context, &pubkey, point.data(), size) == 1 && secp256k1_ecdsa_verify(context, &normal, hash.data(), &pubkey) == 1; }
long_hash sha512_hash(data_slice data) { long_hash hash; SHA512_(data.data(), data.size(), hash.data()); return hash; }
hash_digest sha256_hash(data_slice data) { hash_digest hash; SHA256_(data.data(), data.size(), hash.data()); return hash; }
short_hash sha1_hash(data_slice data) { short_hash hash; SHA1_(data.data(), data.size(), hash.data()); return hash; }
short_hash ripemd160_hash(data_slice data) { short_hash hash; RMD160(data.data(), data.size(), hash.data()); return hash; }
data_chunk sha256_hash_chunk(data_slice data) { data_chunk hash(hash_size); SHA256_(data.data(), data.size(), hash.data()); return hash; }
data_chunk sha1_hash_chunk(data_slice data) { data_chunk hash(short_hash_size); SHA1_(data.data(), data.size(), hash.data()); return hash; }
data_chunk ripemd160_hash_chunk(data_slice data) { data_chunk hash(short_hash_size); RMD160(data.data(), data.size(), hash.data()); return hash; }