merkle_damgard_construction.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020 Alexander Sokolov <asokolov@nil.foundation>
4 //
5 // MIT License
6 //
7 // Permission is hereby granted, free of charge, to any person obtaining a copy
8 // of this software and associated documentation files (the "Software"), to deal
9 // in the Software without restriction, including without limitation the rights
10 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 // copies of the Software, and to permit persons to whom the Software is
12 // furnished to do so, subject to the following conditions:
13 //
14 // The above copyright notice and this permission notice shall be included in all
15 // copies or substantial portions of the Software.
16 //
17 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 // SOFTWARE.
24 //---------------------------------------------------------------------------//
25 
26 #ifndef CRYPTO3_HASH_MERKLE_DAMGARD_CONSTRUCTION_HPP
27 #define CRYPTO3_HASH_MERKLE_DAMGARD_CONSTRUCTION_HPP
28 
30 
31 #include <nil/crypto3/detail/static_digest.hpp>
32 #include <nil/crypto3/detail/pack.hpp>
33 
34 namespace nil {
35  namespace crypto3 {
36  namespace hashes {
53  template<typename Params, typename IV, typename Compressor, typename Padding,
54  typename Finalizer = detail::nop_finalizer>
56  public:
57  typedef IV iv_generator;
58  typedef Compressor compressor_functor;
59  typedef Padding padding_functor;
60  typedef Finalizer finalizer_functor;
61 
62  typedef typename Params::digest_endian endian_type;
63 
64  constexpr static const std::size_t word_bits = compressor_functor::word_bits;
65  typedef typename compressor_functor::word_type word_type;
66 
67  constexpr static const std::size_t state_bits = compressor_functor::state_bits;
68  constexpr static const std::size_t state_words = compressor_functor::state_words;
69  typedef typename compressor_functor::state_type state_type;
70 
71  constexpr static const std::size_t block_bits = compressor_functor::block_bits;
72  constexpr static const std::size_t block_words = compressor_functor::block_words;
73  typedef typename compressor_functor::block_type block_type;
74 
75  constexpr static const std::size_t digest_bits = Params::digest_bits;
76  constexpr static const std::size_t digest_bytes = digest_bits / octet_bits;
77  constexpr static const std::size_t digest_words = digest_bits / word_bits;
79 
80  protected:
81  constexpr static const std::size_t length_bits = Params::length_bits;
82  // FIXME: do something more intelligent than capping at 64
83  constexpr static const std::size_t length_type_bits = length_bits < word_bits ? word_bits :
84  length_bits > 64 ? 64 :
86  typedef typename boost::uint_t<length_type_bits>::least length_type;
87  constexpr static const std::size_t length_words = length_bits / word_bits;
89 
90  public:
91  template<typename Integer = std::size_t>
92  inline merkle_damgard_construction &process_block(const block_type &block, Integer seen = Integer()) {
93  compressor_functor::process_block(state_, block);
94  return *this;
95  }
96 
98  length_type total_seen = length_type()) {
99  using namespace nil::crypto3::detail;
100 
101  block_type b = block;
102  std::size_t block_seen = total_seen % block_bits;
103  // Process block if block is full
104  if (total_seen && !block_seen)
105  process_block(b);
106 
107  // Pad last message block
108  padding_functor padding;
109  padding(b, block_seen);
110 
111  // Process block if total length cannot be appended
112  if (block_seen + length_bits > block_bits) {
113  process_block(b);
114  std::fill(b.begin(), b.end(), 0);
115  }
116 
117  // Append total length to the last block
118  append_length<int>(b, total_seen);
119 
120  // Process the last block
121  process_block(b);
122 
123  // Apply finalizer
125 
126  // Convert digest to byte representation
127  digest_type d;
128  pack_from<endian_type, word_bits, octet_bits>(state_.begin(), state_.begin() + digest_words,
129  d.begin());
130  return d;
131  }
132 
134  reset();
135  }
136 
137  inline void reset(const state_type &s) {
138  state_ = s;
139  }
140 
141  inline void reset() {
142  iv_generator iv;
143  reset(iv());
144  }
145 
146  inline const state_type &state() const {
147  return state_;
148  }
149 
150  protected:
151  template<typename Dummy>
152  typename std::enable_if<length_bits && sizeof(Dummy)>::type append_length(block_type &block,
153  length_type length) {
154  using namespace nil::crypto3::detail;
155 
156  std::array<length_type, 1> length_array = {{length}};
157  std::array<word_type, length_words> length_words_array;
158  pack<endian_type, endian_type, length_bits, word_bits>(length_array.begin(), length_array.end(),
159  length_words_array.begin());
160  // Append length
161  for (std::size_t i = length_words; i; --i)
162  block[block_words - i] = length_words_array[length_words - i];
163  }
164 
165  template<typename Dummy>
166  typename std::enable_if<!(length_bits && sizeof(Dummy))>::type append_length(block_type &block,
167  length_type length) {
168  // No appending requested, so nothing to do
169  }
171  };
172 
173  } // namespace hashes
174  } // namespace crypto3
175 } // namespace nil
176 
177 #endif // CRYPTO3_HASH_MERKLE_DAMGARD_BLOCK_HASH_HPP
Definition: merkle_damgard_construction.hpp:55
BOOST_STATIC_ASSERT(!length_bits||length_bits % word_bits==0)
compressor_functor::state_type state_type
Definition: merkle_damgard_construction.hpp:69
Padding padding_functor
Definition: merkle_damgard_construction.hpp:59
constexpr static const std::size_t block_bits
Definition: merkle_damgard_construction.hpp:71
const state_type & state() const
Definition: merkle_damgard_construction.hpp:146
IV iv_generator
Definition: merkle_damgard_construction.hpp:57
merkle_damgard_construction()
Definition: merkle_damgard_construction.hpp:133
constexpr static const std::size_t digest_bytes
Definition: merkle_damgard_construction.hpp:76
constexpr static const std::size_t state_bits
Definition: merkle_damgard_construction.hpp:67
constexpr static const std::size_t block_words
Definition: merkle_damgard_construction.hpp:72
boost::uint_t< length_type_bits >::least length_type
Definition: merkle_damgard_construction.hpp:86
void reset()
Definition: merkle_damgard_construction.hpp:141
constexpr static const std::size_t word_bits
Definition: merkle_damgard_construction.hpp:64
static_digest< digest_bits > digest_type
Definition: merkle_damgard_construction.hpp:78
compressor_functor::word_type word_type
Definition: merkle_damgard_construction.hpp:65
state_type state_
Definition: merkle_damgard_construction.hpp:170
constexpr static const std::size_t state_words
Definition: merkle_damgard_construction.hpp:68
constexpr static const std::size_t length_bits
Definition: merkle_damgard_construction.hpp:81
constexpr static const std::size_t length_words
Definition: merkle_damgard_construction.hpp:87
Params::digest_endian endian_type
Definition: merkle_damgard_construction.hpp:62
std::enable_if<!(length_bits &&sizeof(Dummy))>::type append_length(block_type &block, length_type length)
Definition: merkle_damgard_construction.hpp:166
std::enable_if< length_bits &&sizeof(Dummy)>::type append_length(block_type &block, length_type length)
Definition: merkle_damgard_construction.hpp:152
void reset(const state_type &s)
Definition: merkle_damgard_construction.hpp:137
Finalizer finalizer_functor
Definition: merkle_damgard_construction.hpp:60
constexpr static const std::size_t digest_bits
Definition: merkle_damgard_construction.hpp:75
merkle_damgard_construction & process_block(const block_type &block, Integer seen=Integer())
Definition: merkle_damgard_construction.hpp:92
digest_type digest(const block_type &block=block_type(), length_type total_seen=length_type())
Definition: merkle_damgard_construction.hpp:97
Compressor compressor_functor
Definition: merkle_damgard_construction.hpp:58
compressor_functor::block_type block_type
Definition: merkle_damgard_construction.hpp:73
constexpr static const std::size_t digest_words
Definition: merkle_damgard_construction.hpp:77
constexpr static const std::size_t length_type_bits
Definition: merkle_damgard_construction.hpp:83
Definition: block/include/nil/crypto3/detail/static_digest.hpp:72
constexpr matrix< T, N, M > fill(T value)
generates a matrix containing a single value
Definition: matrix/utility.hpp:102
boost::mpl::apply< AccumulatorSet, tag::block< Mode > >::type::result_type block(const AccumulatorSet &acc)
Definition: accumulators/block.hpp:259
Definition: algebra/include/nil/crypto3/detail/make_array.hpp:33
Definition: pair.hpp:31