SPB Git

spb/wp40_uqo

Public MIT
3.5 KB · 67 lines cpp
1#include "raid/core/hash.hpp"2#include "raid/core/error.hpp"3#include <cstring>4#include <fstream>5#include <vector>67namespace raid {89namespace {10constexpr std::uint32_t K[64] = {11 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,12 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,13 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,14 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2};15inline std::uint32_t rotr(std::uint32_t x, int n) { return (x >> n) | (x << (32 - n)); }16}1718Sha256::Sha256() : h_{0x6a09e667,0xbb67ae85,0x3c6ef372,0xa54ff53a,0x510e527f,0x9b05688c,0x1f83d9ab,0x5be0cd19} {}1920void Sha256::transform(const std::uint8_t* p) {21  std::uint32_t w[64];22  for (int i = 0; i < 16; ++i) w[i] = (std::uint32_t(p[4*i]) << 24) | (std::uint32_t(p[4*i+1]) << 16) | (std::uint32_t(p[4*i+2]) << 8) | p[4*i+3];23  for (int i = 16; i < 64; ++i) { const std::uint32_t s0 = rotr(w[i-15],7) ^ rotr(w[i-15],18) ^ (w[i-15] >> 3), s1 = rotr(w[i-2],17) ^ rotr(w[i-2],19) ^ (w[i-2] >> 10); w[i] = w[i-16] + s0 + w[i-7] + s1; }24  std::uint32_t a=h_[0],b=h_[1],c=h_[2],d=h_[3],e=h_[4],f=h_[5],g=h_[6],h=h_[7];25  for (int i = 0; i < 64; ++i) {26    const std::uint32_t S1 = rotr(e,6) ^ rotr(e,11) ^ rotr(e,25), ch = (e & f) ^ (~e & g), t1 = h + S1 + ch + K[i] + w[i];27    const std::uint32_t S0 = rotr(a,2) ^ rotr(a,13) ^ rotr(a,22), maj = (a & b) ^ (a & c) ^ (b & c), t2 = S0 + maj;28    h = g; g = f; f = e; e = d + t1; d = c; c = b; b = a; a = t1 + t2;29  }30  h_[0]+=a; h_[1]+=b; h_[2]+=c; h_[3]+=d; h_[4]+=e; h_[5]+=f; h_[6]+=g; h_[7]+=h;31}3233void Sha256::update(const void* data, std::size_t len) {34  const auto* p = static_cast<const std::uint8_t*>(data); total_ += len;35  while (len > 0) {36    const std::size_t take = std::min(len, 64 - buf_len_);37    std::memcpy(buf_.data() + buf_len_, p, take); buf_len_ += take; p += take; len -= take;38    if (buf_len_ == 64) { transform(buf_.data()); buf_len_ = 0; }39  }40}4142std::array<std::uint8_t, 32> Sha256::digest() {43  const std::uint64_t bits = total_ * 8;44  std::uint8_t pad = 0x80; update(&pad, 1);45  const std::uint8_t zero = 0; while (buf_len_ != 56) update(&zero, 1);46  std::uint8_t len[8]; for (int i = 0; i < 8; ++i) len[i] = static_cast<std::uint8_t>(bits >> (56 - 8 * i));47  update(len, 8);48  std::array<std::uint8_t, 32> out{};49  for (int i = 0; i < 8; ++i) { out[4*i] = static_cast<std::uint8_t>(h_[i] >> 24); out[4*i+1] = static_cast<std::uint8_t>(h_[i] >> 16); out[4*i+2] = static_cast<std::uint8_t>(h_[i] >> 8); out[4*i+3] = static_cast<std::uint8_t>(h_[i]); }50  return out;51}5253std::string Sha256::hex() {54  const auto d = digest(); static const char* hx = "0123456789abcdef"; std::string s; s.reserve(64);55  for (auto b : d) { s += hx[b >> 4]; s += hx[b & 15]; }56  return s;57}5859std::string Sha256::of_file(const std::string& path) {60  std::ifstream f(path, std::ios::binary); RAID_REQUIRE(f.good(), io, "cannot open " + path);61  Sha256 h; std::vector<char> buf(1 << 20);62  while (f) { f.read(buf.data(), static_cast<std::streamsize>(buf.size())); h.update(buf.data(), static_cast<std::size_t>(f.gcount())); }63  return h.hex();64}6566}  // namespace raid67
Files · 54c354ddfb230b05a57348bbf797ba24505b7ae4
Menu

Theme