crypto_hash.cpp raw

   1  // Copyright (c) 2016-present The Bitcoin Core developers
   2  // Distributed under the MIT software license, see the accompanying
   3  // file COPYING or http://www.opensource.org/licenses/mit-license.php.
   4  
   5  #include <bench/bench.h>
   6  #include <crypto/muhash.h>
   7  #include <crypto/ripemd160.h>
   8  #include <crypto/sha1.h>
   9  #include <crypto/sha256.h>
  10  #include <crypto/sha3.h>
  11  #include <crypto/sha512.h>
  12  #include <crypto/siphash.h>
  13  #include <random.h>
  14  #include <tinyformat.h>
  15  #include <uint256.h>
  16  
  17  #include <cstdint>
  18  #include <span>
  19  #include <string>
  20  #include <vector>
  21  
  22  /* Number of bytes to hash per iteration */
  23  static const uint64_t BUFFER_SIZE = 1000*1000;
  24  
  25  static void BenchRIPEMD160(benchmark::Bench& bench)
  26  {
  27      uint8_t hash[CRIPEMD160::OUTPUT_SIZE];
  28      std::vector<uint8_t> in(BUFFER_SIZE,0);
  29      bench.batch(in.size()).unit("byte").run([&] {
  30          CRIPEMD160().Write(in.data(), in.size()).Finalize(hash);
  31      });
  32  }
  33  
  34  static void SHA1(benchmark::Bench& bench)
  35  {
  36      uint8_t hash[CSHA1::OUTPUT_SIZE];
  37      std::vector<uint8_t> in(BUFFER_SIZE,0);
  38      bench.batch(in.size()).unit("byte").run([&] {
  39          CSHA1().Write(in.data(), in.size()).Finalize(hash);
  40      });
  41  }
  42  
  43  static void SHA256_STANDARD(benchmark::Bench& bench)
  44  {
  45      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::STANDARD)));
  46      uint8_t hash[CSHA256::OUTPUT_SIZE];
  47      std::vector<uint8_t> in(BUFFER_SIZE,0);
  48      bench.batch(in.size()).unit("byte").run([&] {
  49          CSHA256().Write(in.data(), in.size()).Finalize(hash);
  50      });
  51      SHA256AutoDetect();
  52  }
  53  
  54  static void SHA256_SSE4(benchmark::Bench& bench)
  55  {
  56      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4)));
  57      uint8_t hash[CSHA256::OUTPUT_SIZE];
  58      std::vector<uint8_t> in(BUFFER_SIZE,0);
  59      bench.batch(in.size()).unit("byte").run([&] {
  60          CSHA256().Write(in.data(), in.size()).Finalize(hash);
  61      });
  62      SHA256AutoDetect();
  63  }
  64  
  65  static void SHA256_AVX2(benchmark::Bench& bench)
  66  {
  67      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4_AND_AVX2)));
  68      uint8_t hash[CSHA256::OUTPUT_SIZE];
  69      std::vector<uint8_t> in(BUFFER_SIZE,0);
  70      bench.batch(in.size()).unit("byte").run([&] {
  71          CSHA256().Write(in.data(), in.size()).Finalize(hash);
  72      });
  73      SHA256AutoDetect();
  74  }
  75  
  76  static void SHA256_SHANI(benchmark::Bench& bench)
  77  {
  78      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4_AND_SHANI)));
  79      uint8_t hash[CSHA256::OUTPUT_SIZE];
  80      std::vector<uint8_t> in(BUFFER_SIZE,0);
  81      bench.batch(in.size()).unit("byte").run([&] {
  82          CSHA256().Write(in.data(), in.size()).Finalize(hash);
  83      });
  84      SHA256AutoDetect();
  85  }
  86  
  87  static void SHA3_256_1M(benchmark::Bench& bench)
  88  {
  89      uint8_t hash[SHA3_256::OUTPUT_SIZE];
  90      std::vector<uint8_t> in(BUFFER_SIZE,0);
  91      bench.batch(in.size()).unit("byte").run([&] {
  92          SHA3_256().Write(in).Finalize(hash);
  93      });
  94  }
  95  
  96  static void SHA256_32b_STANDARD(benchmark::Bench& bench)
  97  {
  98      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::STANDARD)));
  99      std::vector<uint8_t> in(32,0);
 100      bench.batch(in.size()).unit("byte").run([&] {
 101          CSHA256()
 102              .Write(in.data(), in.size())
 103              .Finalize(in.data());
 104      });
 105      SHA256AutoDetect();
 106  }
 107  
 108  static void SHA256_32b_SSE4(benchmark::Bench& bench)
 109  {
 110      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4)));
 111      std::vector<uint8_t> in(32,0);
 112      bench.batch(in.size()).unit("byte").run([&] {
 113          CSHA256()
 114              .Write(in.data(), in.size())
 115              .Finalize(in.data());
 116      });
 117      SHA256AutoDetect();
 118  }
 119  
 120  static void SHA256_32b_AVX2(benchmark::Bench& bench)
 121  {
 122      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4_AND_AVX2)));
 123      std::vector<uint8_t> in(32,0);
 124      bench.batch(in.size()).unit("byte").run([&] {
 125          CSHA256()
 126              .Write(in.data(), in.size())
 127              .Finalize(in.data());
 128      });
 129      SHA256AutoDetect();
 130  }
 131  
 132  static void SHA256_32b_SHANI(benchmark::Bench& bench)
 133  {
 134      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4_AND_SHANI)));
 135      std::vector<uint8_t> in(32,0);
 136      bench.batch(in.size()).unit("byte").run([&] {
 137          CSHA256()
 138              .Write(in.data(), in.size())
 139              .Finalize(in.data());
 140      });
 141      SHA256AutoDetect();
 142  }
 143  
 144  static void SHA256D64_1024_STANDARD(benchmark::Bench& bench)
 145  {
 146      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::STANDARD)));
 147      std::vector<uint8_t> in(64 * 1024, 0);
 148      bench.batch(in.size()).unit("byte").run([&] {
 149          SHA256D64(in.data(), in.data(), 1024);
 150      });
 151      SHA256AutoDetect();
 152  }
 153  
 154  static void SHA256D64_1024_SSE4(benchmark::Bench& bench)
 155  {
 156      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4)));
 157      std::vector<uint8_t> in(64 * 1024, 0);
 158      bench.batch(in.size()).unit("byte").run([&] {
 159          SHA256D64(in.data(), in.data(), 1024);
 160      });
 161      SHA256AutoDetect();
 162  }
 163  
 164  static void SHA256D64_1024_AVX2(benchmark::Bench& bench)
 165  {
 166      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4_AND_AVX2)));
 167      std::vector<uint8_t> in(64 * 1024, 0);
 168      bench.batch(in.size()).unit("byte").run([&] {
 169          SHA256D64(in.data(), in.data(), 1024);
 170      });
 171      SHA256AutoDetect();
 172  }
 173  
 174  static void SHA256D64_1024_SHANI(benchmark::Bench& bench)
 175  {
 176      bench.name(strprintf("%s using the '%s' SHA256 implementation", __func__, SHA256AutoDetect(sha256_implementation::USE_SSE4_AND_SHANI)));
 177      std::vector<uint8_t> in(64 * 1024, 0);
 178      bench.batch(in.size()).unit("byte").run([&] {
 179          SHA256D64(in.data(), in.data(), 1024);
 180      });
 181      SHA256AutoDetect();
 182  }
 183  
 184  static void SHA512(benchmark::Bench& bench)
 185  {
 186      uint8_t hash[CSHA512::OUTPUT_SIZE];
 187      std::vector<uint8_t> in(BUFFER_SIZE,0);
 188      bench.batch(in.size()).unit("byte").run([&] {
 189          CSHA512().Write(in.data(), in.size()).Finalize(hash);
 190      });
 191  }
 192  
 193  static void SipHash_32b(benchmark::Bench& bench)
 194  {
 195      FastRandomContext rng{/*fDeterministic=*/true};
 196      PresaltedSipHasher presalted_sip_hasher(rng.rand64(), rng.rand64());
 197      auto val{rng.rand256()};
 198      auto i{0U};
 199      bench.run([&] {
 200          ankerl::nanobench::doNotOptimizeAway(presalted_sip_hasher(val));
 201          ++i;
 202          val.data()[i % uint256::size()] ^= i & 0xFF;
 203      });
 204  }
 205  
 206  static void MuHash(benchmark::Bench& bench)
 207  {
 208      MuHash3072 acc;
 209      unsigned char key[32] = {0};
 210      uint32_t i = 0;
 211      bench.run([&] {
 212          key[0] = ++i & 0xFF;
 213          acc *= MuHash3072(key);
 214      });
 215  }
 216  
 217  static void MuHashMul(benchmark::Bench& bench)
 218  {
 219      MuHash3072 acc;
 220      FastRandomContext rng(true);
 221      MuHash3072 muhash{rng.randbytes(32)};
 222  
 223      bench.run([&] {
 224          acc *= muhash;
 225      });
 226  }
 227  
 228  static void MuHashDiv(benchmark::Bench& bench)
 229  {
 230      MuHash3072 acc;
 231      FastRandomContext rng(true);
 232      MuHash3072 muhash{rng.randbytes(32)};
 233  
 234      bench.run([&] {
 235          acc /= muhash;
 236      });
 237  }
 238  
 239  static void MuHashPrecompute(benchmark::Bench& bench)
 240  {
 241      MuHash3072 acc;
 242      FastRandomContext rng(true);
 243      std::vector<unsigned char> key{rng.randbytes(32)};
 244  
 245      bench.run([&] {
 246          MuHash3072{key};
 247      });
 248  }
 249  
 250  static void MuHashFinalize(benchmark::Bench& bench)
 251  {
 252      FastRandomContext rng(true);
 253      MuHash3072 acc{rng.randbytes(32)};
 254      acc /= MuHash3072{rng.rand256()};
 255  
 256      bench.run([&] {
 257          uint256 out;
 258          acc.Finalize(out);
 259          acc /= MuHash3072{out};
 260      });
 261  }
 262  
 263  BENCHMARK(BenchRIPEMD160);
 264  BENCHMARK(SHA1);
 265  BENCHMARK(SHA256_STANDARD);
 266  BENCHMARK(SHA256_SSE4);
 267  BENCHMARK(SHA256_AVX2);
 268  BENCHMARK(SHA256_SHANI);
 269  BENCHMARK(SHA512);
 270  BENCHMARK(SHA3_256_1M);
 271  
 272  BENCHMARK(SHA256_32b_STANDARD);
 273  BENCHMARK(SHA256_32b_SSE4);
 274  BENCHMARK(SHA256_32b_AVX2);
 275  BENCHMARK(SHA256_32b_SHANI);
 276  BENCHMARK(SipHash_32b);
 277  BENCHMARK(SHA256D64_1024_STANDARD);
 278  BENCHMARK(SHA256D64_1024_SSE4);
 279  BENCHMARK(SHA256D64_1024_AVX2);
 280  BENCHMARK(SHA256D64_1024_SHANI);
 281  
 282  BENCHMARK(MuHash);
 283  BENCHMARK(MuHashMul);
 284  BENCHMARK(MuHashDiv);
 285  BENCHMARK(MuHashPrecompute);
 286  BENCHMARK(MuHashFinalize);
 287