#pragma once
#include "risc0/zkp/core/sha256.h"
namespace risc0 {
inline ShaDigest shaHash(const uint8_t* data, size_t size) {
uint64_t bitSize = size * uint64_t(8);
ShaDigest state = impl::initState();
uint32_t words[16];
while (size >= 64) {
impl::endianEncode(words, data);
impl::compress(state, words);
data += 64;
size -= 64;
}
uint8_t final[64] = {0};
memcpy(final, data, size);
final[size] = 0x80;
impl::endianEncode(words, final);
if (size + 1 > 56) {
impl::compress(state, words);
memset(words, 0, 64);
}
words[14] = bitSize >> 32;
words[15] = bitSize & 0xffffffff;
impl::compress(state, words);
return state;
}
inline ShaDigest shaHash(const std::string& str) {
return shaHash(reinterpret_cast<const uint8_t*>(str.data()), str.size());
}
inline std::string hexDigest(const ShaDigest& digest) {
const char* hexdigits = "0123456789abcdef";
std::string r(64, 0);
for (size_t i = 0; i < 8; i++) {
uint32_t word = digest.words[i];
for (size_t j = 0; j < 4; j++) {
uint8_t byte = word >> 24;
r[i * 8 + j * 2] = hexdigits[byte >> 4];
r[i * 8 + j * 2 + 1] = hexdigits[byte & 0xf];
word <<= 8;
}
}
return r;
}
inline std::ostream& operator<<(std::ostream& os, const ShaDigest& x) {
os << hexDigest(x);
return os;
}
}