rippled
digest_test.cpp
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #include <ripple/beast/unit_test.h>
21 #include <ripple/beast/utility/rngfill.h>
22 #include <ripple/beast/xor_shift_engine.h>
23 #include <ripple/protocol/digest.h>
24 #include <algorithm>
25 #include <array>
26 #include <chrono>
27 #include <cmath>
28 #include <numeric>
29 #include <vector>
30 
31 namespace ripple {
32 
33 class digest_test : public beast::unit_test::suite
34 {
36 
37  template <class Hasher>
38  void
39  test(char const* name)
40  {
41  using namespace std::chrono;
42 
43  // Prime the cache
44  for (int i = 0; i != 4; i++)
45  {
46  for (auto const& x : dataset1)
47  {
48  Hasher h;
49  h(x.data(), x.size());
50  (void)static_cast<typename Hasher::result_type>(h);
51  }
52  }
53 
55 
56  for (auto& result : results)
57  {
58  auto const start = high_resolution_clock::now();
59 
60  for (auto const& x : dataset1)
61  {
62  Hasher h;
63  h(x.data(), x.size());
64  (void)static_cast<typename Hasher::result_type>(h);
65  }
66 
67  auto const d = high_resolution_clock::now() - start;
68 
69  result = d;
70  }
71 
72  log << " " << name << ":" << '\n';
73 
74  auto const sum =
75  std::accumulate(results.begin(), results.end(), nanoseconds{0});
76  {
77  auto s = duration_cast<seconds>(sum);
78  auto ms = duration_cast<milliseconds>(sum) - s;
79  log << " Total Time = " << s.count() << "." << ms.count()
80  << " seconds" << std::endl;
81  }
82 
83  auto const mean = sum / results.size();
84  {
85  auto s = duration_cast<seconds>(mean);
86  auto ms = duration_cast<milliseconds>(mean) - s;
87  log << " Mean Time = " << s.count() << "." << ms.count()
88  << " seconds" << std::endl;
89  }
90 
91  std::vector<nanoseconds::rep> diff(results.size());
93  results.begin(),
94  results.end(),
95  diff.begin(),
96  [&mean](nanoseconds trial) { return (trial - mean).count(); });
97  auto const sq_sum =
98  std::inner_product(diff.begin(), diff.end(), diff.begin(), 0.0);
99  {
100  nanoseconds const stddev{static_cast<nanoseconds::rep>(
101  std::sqrt(sq_sum / results.size()))};
102  auto s = duration_cast<seconds>(stddev);
103  auto ms = duration_cast<milliseconds>(stddev) - s;
104  log << " Std Dev = " << s.count() << "." << ms.count()
105  << " seconds" << std::endl;
106  }
107  }
108 
109 public:
111  {
112  beast::xor_shift_engine g(19207813);
114 
115  for (int i = 0; i < 1000000; i++)
116  {
117  beast::rngfill(buf.data(), buf.size(), g);
118  dataset1.push_back(uint256{buf});
119  }
120  }
121 
122  void
124  {
125  testcase("SHA512");
126  test<openssl_ripemd160_hasher>("OpenSSL");
127  test<beast::ripemd160_hasher>("Beast");
128  pass();
129  }
130 
131  void
133  {
134  testcase("SHA256");
135  test<openssl_sha256_hasher>("OpenSSL");
136  test<beast::sha256_hasher>("Beast");
137  pass();
138  }
139 
140  void
142  {
143  testcase("RIPEMD160");
144  test<openssl_ripemd160_hasher>("OpenSSL");
145  test<beast::ripemd160_hasher>("Beast");
146  pass();
147  }
148 
149  void
150  run() override
151  {
152  testSHA512();
153  testSHA256();
154  testRIPEMD160();
155  }
156 };
157 
159 
160 } // namespace ripple
std::inner_product
T inner_product(T... args)
ripple::digest_test::test
void test(char const *name)
Definition: digest_test.cpp:39
ripple::digest_test::run
void run() override
Definition: digest_test.cpp:150
vector
std::array::size
T size(T... args)
std::chrono::nanoseconds
ripple::digest_test::dataset1
std::vector< uint256 > dataset1
Definition: digest_test.cpp:35
ripple::SBoxCmp::diff
@ diff
ripple::digest_test::digest_test
digest_test()
Definition: digest_test.cpp:110
cmath
algorithm
std::sqrt
T sqrt(T... args)
ripple::digest
static Hasher::result_type digest(void const *data, std::size_t size) noexcept
Definition: tokens.cpp:43
ripple::digest_test::testRIPEMD160
void testRIPEMD160()
Definition: digest_test.cpp:141
ripple::base_uint< 256 >
chrono
ripple::digest_test
Definition: digest_test.cpp:33
array
std::accumulate
T accumulate(T... args)
std::transform
T transform(T... args)
ripple::digest_test::testSHA256
void testSHA256()
Definition: digest_test.cpp:132
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
std::endl
T endl(T... args)
beast::rngfill
void rngfill(void *buffer, std::size_t bytes, Generator &g)
Definition: rngfill.h:32
ripple::BEAST_DEFINE_TESTSUITE_MANUAL_PRIO
BEAST_DEFINE_TESTSUITE_MANUAL_PRIO(digest, ripple_data, ripple, 20)
beast::detail::xor_shift_engine
Definition: xor_shift_engine.h:32
numeric
ripple::sum
static auto sum(TCollection const &col)
Definition: BookStep.cpp:693
ripple::digest_test::testSHA512
void testSHA512()
Definition: digest_test.cpp:123
std::array::data
T data(T... args)
std::chrono