block/include/nil/crypto3/block/md5.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_MD5_HPP
27 #define CRYPTO3_BLOCK_MD5_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 md5 {
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  md5(const key_type &k) : key(k) {
88  }
89 
90  virtual ~md5() {
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  protected:
104 
105  static inline block_type encrypt_block(key_type const &key, block_type const &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_MD5_ENCRYPT_STEP(aa, bb, cc, dd, fun, k, s, i) \
111  { \
112  word_type T = \
113  aa + policy_type::fun(bb, cc, dd) + key[policy_type::key_indexes[k]] + policy_type::constants[i - 1]; \
114  aa = bb + policy_type::rotl<s>(T); \
115  }
116  for (unsigned t = 0; t < policy_type::rounds / 4; t += 4) {
117  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(a, b, c, d, ff, t + 0, 7, t + 1)
118  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(d, a, b, c, ff, t + 1, 12, t + 2)
119  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(c, d, a, b, ff, t + 2, 17, t + 3)
120  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(b, c, d, a, ff, t + 3, 22, t + 4)
121  }
122  for (unsigned t = policy_type::rounds / 4; t < policy_type::rounds / 2; t += 4) {
123  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(a, b, c, d, gg, t + 0, 5, t + 1)
124  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(d, a, b, c, gg, t + 1, 9, t + 2)
125  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(c, d, a, b, gg, t + 2, 14, t + 3)
126  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(b, c, d, a, gg, t + 3, 20, t + 4)
127  }
128  for (unsigned t = policy_type::rounds / 2; t < 3 * policy_type::rounds / 4; t += 4) {
129  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(a, b, c, d, hh, t + 0, 4, t + 1)
130  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(d, a, b, c, hh, t + 1, 11, t + 2)
131  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(c, d, a, b, hh, t + 2, 16, t + 3)
132  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(b, c, d, a, hh, t + 3, 23, t + 4)
133  }
134  for (unsigned t = 3 * policy_type::rounds / 4; t < policy_type::rounds; t += 4) {
135  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(a, b, c, d, ii, t + 0, 6, t + 1)
136  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(d, a, b, c, ii, t + 1, 10, t + 2)
137  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(c, d, a, b, ii, t + 2, 15, t + 3)
138  CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(b, c, d, a, ii, t + 3, 21, t + 4)
139  }
140 
141  return {{a, b, c, d}};
142  }
143 
144  static inline block_type decrypt_block(key_type const &key, const block_type &ciphertext) {
145  // Initialize working variables with block
146  word_type a = ciphertext[0], b = ciphertext[1], c = ciphertext[2], d = ciphertext[3];
147 
148  // Decipher block
149 #define CRYPTO3_BLOCK_MD5_DECRYPT_STEP(aa, bb, cc, dd, fun, k, s, i) \
150  { \
151  word_type T = policy_type::rotr<s>(aa - bb); \
152  aa = T - policy_type::fun(bb, cc, dd) - key[policy_type::key_indexes[k]] - policy_type::constants[i - 1]; \
153  }
154  for (unsigned t = policy_type::rounds; t -= 4, t >= 3 * policy_type::rounds / 4;) {
155  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(b, c, d, a, ii, t + 3, 21, t + 4)
156  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(c, d, a, b, ii, t + 2, 15, t + 3)
157  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(d, a, b, c, ii, t + 1, 10, t + 2)
158  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(a, b, c, d, ii, t + 0, 6, t + 1)
159  }
160  for (unsigned t = 3 * policy_type::rounds / 4; t -= 4, t >= policy_type::rounds / 2;) {
161  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(b, c, d, a, hh, t + 3, 23, t + 4)
162  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(c, d, a, b, hh, t + 2, 16, t + 3)
163  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(d, a, b, c, hh, t + 1, 11, t + 2)
164  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(a, b, c, d, hh, t + 0, 4, t + 1)
165  }
166  for (unsigned t = policy_type::rounds / 2; t -= 4, t >= policy_type::rounds / 4;) {
167  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(b, c, d, a, gg, t + 3, 20, t + 4)
168  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(c, d, a, b, gg, t + 2, 14, t + 3)
169  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(d, a, b, c, gg, t + 1, 9, t + 2)
170  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(a, b, c, d, gg, t + 0, 5, t + 1)
171  }
172  for (unsigned t = policy_type::rounds / 4; t -= 4, t < policy_type::rounds / 4;) {
173  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(b, c, d, a, ff, t + 3, 22, t + 4)
174  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(c, d, a, b, ff, t + 2, 17, t + 3)
175  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(d, a, b, c, ff, t + 1, 12, t + 2)
176  CRYPTO3_BLOCK_MD5_DECRYPT_STEP(a, b, c, d, ff, t + 0, 7, t + 1)
177  }
178 
179  return {{a, b, c, d}};
180  }
181  };
182  } // namespace block
183  } // namespace crypto3
184 } // namespace nil
185 
186 #endif // CRYPTO3_BLOCK_CIPHERS_MD5_HPP
#define CRYPTO3_BLOCK_MD5_ENCRYPT_STEP(aa, bb, cc, dd, fun, k, s, i)
#define CRYPTO3_BLOCK_MD5_DECRYPT_STEP(aa, bb, cc, dd, fun, k, s, i)
MD5 block cipher. Stands as a foundation for MD5 hashes.
Definition: block/include/nil/crypto3/block/md5.hpp:57
constexpr static const std::size_t block_bits
Definition: block/include/nil/crypto3/block/md5.hpp:70
stream_endian::little_octet_big_bit endian_type
Definition: block/include/nil/crypto3/block/md5.hpp:85
static block_type decrypt_block(key_type const &key, const block_type &ciphertext)
Definition: block/include/nil/crypto3/block/md5.hpp:144
policy_type::word_type word_type
Definition: block/include/nil/crypto3/block/md5.hpp:64
block_type decrypt(const block_type &ciphertext) const
Definition: block/include/nil/crypto3/block/md5.hpp:98
constexpr static const std::size_t block_words
Definition: block/include/nil/crypto3/block/md5.hpp:71
md5(const key_type &k)
Definition: block/include/nil/crypto3/block/md5.hpp:87
block_type encrypt(const block_type &plaintext) const
Definition: block/include/nil/crypto3/block/md5.hpp:94
key_type key
Definition: block/include/nil/crypto3/block/md5.hpp:103
constexpr static const std::size_t rounds
Definition: block/include/nil/crypto3/block/md5.hpp:61
constexpr static const std::size_t key_bits
Definition: block/include/nil/crypto3/block/md5.hpp:66
constexpr static const std::size_t word_bits
Definition: block/include/nil/crypto3/block/md5.hpp:63
virtual ~md5()
Definition: block/include/nil/crypto3/block/md5.hpp:90
policy_type::key_type key_type
Definition: block/include/nil/crypto3/block/md5.hpp:68
static block_type encrypt_block(key_type const &key, block_type const &plaintext)
Definition: block/include/nil/crypto3/block/md5.hpp:105
constexpr static const std::size_t key_words
Definition: block/include/nil/crypto3/block/md5.hpp:67
policy_type::block_type block_type
Definition: block/include/nil/crypto3/block/md5.hpp:72
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/md5/md5_policy.hpp:37
constexpr static const std::size_t block_words
Definition: block/include/nil/crypto3/block/detail/md5/md5_policy.hpp:40
std::array< word_type, block_words > block_type
Definition: block/include/nil/crypto3/block/detail/md5/md5_policy.hpp:41
constexpr static const std::size_t block_bits
Definition: block/include/nil/crypto3/block/detail/md5/md5_policy.hpp:39
std::array< word_type, key_words > key_type
Definition: block/include/nil/crypto3/block/detail/md5/md5_policy.hpp:45
constexpr static const std::size_t key_words
Definition: block/include/nil/crypto3/block/detail/md5/md5_policy.hpp:43
constexpr static const std::size_t rounds
Definition: block/include/nil/crypto3/block/detail/md5/md5_policy.hpp:47
constexpr static const std::size_t key_bits
Definition: block/include/nil/crypto3/block/detail/md5/md5_policy.hpp:44
Definition: block/include/nil/crypto3/block/md5.hpp:76
constexpr static const std::size_t value_bits
Definition: block/include/nil/crypto3/block/md5.hpp:78
constexpr static const std::size_t length_bits
Definition: block/include/nil/crypto3/block/md5.hpp:79
Definition: block/include/nil/crypto3/block/md5.hpp:75
block_stream_processor< Mode, StateAccumulator, params_type > type
Definition: block/include/nil/crypto3/block/md5.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