block/include/nil/crypto3/block/md4.hpp
Go to the documentation of this file.
1 //---------------------------------------------------------------------------//
2 // Copyright (c) 2018-2020 Mikhail Komarov <nemo@nil.foundation>
3 // Copyright (c) 2020 Nikita Kaskov <nbering@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_BLOCK_MD4_HPP
27 #define CRYPTO3_BLOCK_MD4_HPP
28 
30 
33 
34 #ifdef CRYPTO3_BLOCK_SHOW_PROGRESS
35 #include <cstdio>
36 #endif
37 
38 namespace nil {
39  namespace crypto3 {
40  namespace block {
57  class md4 {
59 
60  public:
61  constexpr static const std::size_t rounds = policy_type::rounds;
62 
63  constexpr static const std::size_t word_bits = policy_type::word_bits;
65 
66  constexpr static const std::size_t key_bits = policy_type::key_bits;
67  constexpr static const std::size_t key_words = policy_type::key_words;
69 
70  constexpr static const std::size_t block_bits = policy_type::block_bits;
71  constexpr static const std::size_t block_words = policy_type::block_words;
73 
74  template<class Mode, typename StateAccumulator, std::size_t ValueBits>
76  struct params_type {
77 
78  constexpr static const std::size_t value_bits = ValueBits;
79  constexpr static const std::size_t length_bits = policy_type::word_bits * 2;
80  };
81 
83  };
84 
86 
87  md4(const key_type &k) : key(k) {
88  }
89 
90  virtual ~md4() {
91  key.fill(0);
92  }
93 
94  inline block_type encrypt(const block_type &plaintext) const {
95  return encrypt_block(key, plaintext);
96  }
97 
98  inline block_type decrypt(const block_type &ciphertext) const {
99  return decrypt_block(key, ciphertext);
100  }
101 
102  private:
103  key_type key;
104 
105  inline static block_type encrypt_block(const key_type &key, const block_type &plaintext) {
106  // Initialize working variables with block
107  word_type a = plaintext[0], b = plaintext[1], c = plaintext[2], d = plaintext[3];
108 
109  // Encipher block
110 #define CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(aa, bb, cc, dd, fun, k, s, val) \
111  { \
112  word_type T = aa + policy_type::fun(bb, cc, dd) + key[policy_type::key_indexes[k]] + val; \
113  aa = policy_type::rotl<s>(T); \
114  }
115  for (unsigned t = 0; t < policy_type::rounds / 3; t += 4) {
116  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(a, b, c, d, ff, t + 0, 3, 0x00000000)
117  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(d, a, b, c, ff, t + 1, 7, 0x00000000)
118  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(c, d, a, b, ff, t + 2, 11, 0x00000000)
119  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(b, c, d, a, ff, t + 3, 19, 0x00000000)
120  }
121 
122  for (unsigned t = 0; t < policy_type::rounds / 12; t += 1) {
123  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(a, b, c, d, gg, t + 0, 3, 0x5a827999)
124  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(d, a, b, c, gg, t + 4, 5, 0x5a827999)
125  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(c, d, a, b, gg, t + 8, 9, 0x5a827999)
126  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(b, c, d, a, gg, t + 12, 13, 0x5a827999)
127  }
128  std::array<unsigned, 4> t_step3 {{0, 2, 1, 3}};
129  for (unsigned int &t : t_step3) {
130  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(a, b, c, d, hh, t + 0, 3, 0x6ed9eba1)
131  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(d, a, b, c, hh, t + 8, 9, 0x6ed9eba1)
132  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(c, d, a, b, hh, t + 4, 11, 0x6ed9eba1)
133  CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(b, c, d, a, hh, t + 12, 15, 0x6ed9eba1)
134  }
135 
136  return {{a, b, c, d}};
137  }
138 
139  inline static block_type decrypt_block(const key_type &key, const block_type &ciphertext) {
140  // Initialize working variables with block
141  word_type a = ciphertext[0], b = ciphertext[1], c = ciphertext[2], d = ciphertext[3];
142 
143  // Decipher block
144 #define CRYPTO3_BLOCK_MD4_DECRYPT_STEP(aa, bb, cc, dd, fun, k, s, val) \
145  { \
146  word_type T = policy_type::rotr<s>(aa); \
147  aa = T - policy_type::fun(bb, cc, dd) - key[policy_type::key_indexes[k]] - val; \
148  }
149  for (unsigned t = policy_type::rounds; t -= 4, t >= 2 * policy_type::rounds / 3;) {
150  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(b, c, d, a, hh, t + 3, 15, 0x6ed9eba1)
151  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(c, d, a, b, hh, t + 2, 11, 0x6ed9eba1)
152  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(d, a, b, c, hh, t + 1, 9, 0x6ed9eba1)
153  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(a, b, c, d, hh, t + 0, 3, 0x6ed9eba1)
154  }
155  for (unsigned t = 2 * policy_type::rounds / 3; t -= 4, t >= policy_type::rounds / 3;) {
156  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(b, c, d, a, gg, t + 3, 13, 0x5a827999)
157  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(c, d, a, b, gg, t + 2, 9, 0x5a827999)
158  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(d, a, b, c, gg, t + 1, 5, 0x5a827999)
159  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(a, b, c, d, gg, t + 0, 3, 0x5a827999)
160  }
161  for (unsigned t = policy_type::rounds / 3; t -= 4, t < policy_type::rounds / 3;) {
162  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(b, c, d, a, ff, t + 3, 19, 0x00000000)
163  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(c, d, a, b, ff, t + 2, 11, 0x00000000)
164  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(d, a, b, c, ff, t + 1, 7, 0x00000000)
165  CRYPTO3_BLOCK_MD4_DECRYPT_STEP(a, b, c, d, ff, t + 0, 3, 0x00000000)
166  }
167 
168  return {{a, b, c, d}};
169  }
170  };
171  } // namespace block
172  } // namespace crypto3
173 } // namespace nil
174 
175 #endif // CRYPTO3_BLOCK_CIPHERS_MD4_HPP
#define CRYPTO3_BLOCK_MD4_ENCRYPT_STEP(aa, bb, cc, dd, fun, k, s, val)
#define CRYPTO3_BLOCK_MD4_DECRYPT_STEP(aa, bb, cc, dd, fun, k, s, val)
MD4 block cipher. Stands as a foundation for MD4 hashes.
Definition: block/include/nil/crypto3/block/md4.hpp:57
policy_type::key_type key_type
Definition: block/include/nil/crypto3/block/md4.hpp:68
policy_type::word_type word_type
Definition: block/include/nil/crypto3/block/md4.hpp:64
policy_type::block_type block_type
Definition: block/include/nil/crypto3/block/md4.hpp:72
constexpr static const std::size_t block_words
Definition: block/include/nil/crypto3/block/md4.hpp:71
virtual ~md4()
Definition: block/include/nil/crypto3/block/md4.hpp:90
constexpr static const std::size_t block_bits
Definition: block/include/nil/crypto3/block/md4.hpp:70
block_type encrypt(const block_type &plaintext) const
Definition: block/include/nil/crypto3/block/md4.hpp:94
md4(const key_type &k)
Definition: block/include/nil/crypto3/block/md4.hpp:87
constexpr static const std::size_t word_bits
Definition: block/include/nil/crypto3/block/md4.hpp:63
stream_endian::little_octet_big_bit endian_type
Definition: block/include/nil/crypto3/block/md4.hpp:85
constexpr static const std::size_t rounds
Definition: block/include/nil/crypto3/block/md4.hpp:61
block_type decrypt(const block_type &ciphertext) const
Definition: block/include/nil/crypto3/block/md4.hpp:98
constexpr static const std::size_t key_bits
Definition: block/include/nil/crypto3/block/md4.hpp:66
constexpr static const std::size_t key_words
Definition: block/include/nil/crypto3/block/md4.hpp:67
boost::mpl::apply< AccumulatorSet, tag::block< Mode > >::type::result_type block(const AccumulatorSet &acc)
Definition: accumulators/block.hpp:259
Definition: pair.hpp:31
Definition: block/include/nil/crypto3/block/detail/block_stream_processor.hpp:50
Definition: block/include/nil/crypto3/block/detail/md4/md4_policy.hpp:36
constexpr static const std::size_t rounds
Definition: block/include/nil/crypto3/block/detail/md4/md4_policy.hpp:46
constexpr static const std::size_t block_bits
Definition: block/include/nil/crypto3/block/detail/md4/md4_policy.hpp:38
std::array< word_type, key_words > key_type
Definition: block/include/nil/crypto3/block/detail/md4/md4_policy.hpp:44
constexpr static const std::size_t block_words
Definition: block/include/nil/crypto3/block/detail/md4/md4_policy.hpp:39
constexpr static const std::size_t key_bits
Definition: block/include/nil/crypto3/block/detail/md4/md4_policy.hpp:43
std::array< word_type, block_words > block_type
Definition: block/include/nil/crypto3/block/detail/md4/md4_policy.hpp:40
constexpr static const std::size_t key_words
Definition: block/include/nil/crypto3/block/detail/md4/md4_policy.hpp:42
Definition: block/include/nil/crypto3/block/md4.hpp:76
constexpr static const std::size_t value_bits
Definition: block/include/nil/crypto3/block/md4.hpp:78
constexpr static const std::size_t length_bits
Definition: block/include/nil/crypto3/block/md4.hpp:79
Definition: block/include/nil/crypto3/block/md4.hpp:75
block_stream_processor< Mode, StateAccumulator, params_type > type
Definition: block/include/nil/crypto3/block/md4.hpp:82
constexpr static const std::size_t word_bits
Definition: block/include/nil/crypto3/detail/basic_functions.hpp:88
boost::uint_t< word_bits >::exact word_type
Definition: block/include/nil/crypto3/detail/basic_functions.hpp:89
Definition: algebra/include/nil/crypto3/detail/stream_endian.hpp:45