kasumi.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_KASUMI_HPP
27 #define CRYPTO3_BLOCK_KASUMI_HPP
28 
29 #include <boost/endian/arithmetic.hpp>
30 #include <boost/endian/conversion.hpp>
31 
33 
36 
37 namespace nil {
38  namespace crypto3 {
39  namespace block {
46  class kasumi {
47  protected:
49 
50  constexpr static const std::size_t key_schedule_size = policy_type::key_schedule_size;
52 
53  public:
54  constexpr static const std::size_t rounds = policy_type::rounds;
55 
56  constexpr static const std::size_t word_bits = policy_type::word_bits;
58 
59  constexpr static const std::size_t block_bits = policy_type::block_bits;
60  constexpr static const std::size_t block_words = policy_type::block_words;
62 
63  constexpr static const std::size_t key_bits = policy_type::key_bits;
64  constexpr static const std::size_t key_words = policy_type::key_words;
65  typedef typename policy_type::key_type key_type;
66 
67  template<class Mode, typename StateAccumulator, std::size_t ValueBits>
69  struct params_type {
70 
71  constexpr static const std::size_t value_bits = ValueBits;
72  constexpr static const std::size_t length_bits = policy_type::word_bits * 2;
73  };
74 
76  };
77 
79 
80  kasumi(const key_type &key) {
82  }
83 
84  ~kasumi() {
85  key_schedule.fill(0);
86  }
87 
88  inline block_type encrypt(const block_type &plaintext) const {
89  return encrypt_block(plaintext, key_schedule);
90  }
91 
92  inline block_type decrypt(const block_type &ciphertext) const {
93  return decrypt_block(ciphertext, key_schedule);
94  }
95 
96  protected:
97  inline block_type encrypt_block(const block_type &plaintext,
98  const key_schedule_type &key_schedule) const {
99  word_type B0 = boost::endian::native_to_big(plaintext[0]);
100  word_type B1 = boost::endian::native_to_big(plaintext[1]);
101  word_type B2 = boost::endian::native_to_big(plaintext[2]);
102  word_type B3 = boost::endian::native_to_big(plaintext[3]);
103 
104  for (size_t j = 0; j != rounds; j += 2) {
105  const word_type *K = &key_schedule[8 * j];
106 
107  word_type R = B1 ^ (policy_type::template rotl<1>(B0) & K[0]);
108  word_type L = B0 ^ (policy_type::template rotl<1>(R) | K[1]);
109 
110  L = policy_type::FI(L ^ K[2], K[3]) ^ R;
111  R = policy_type::FI(R ^ K[4], K[5]) ^ L;
112  L = policy_type::FI(L ^ K[6], K[7]) ^ R;
113 
114  R = B2 ^= R;
115  L = B3 ^= L;
116 
117  R = policy_type::FI(R ^ K[10], K[11]) ^ L;
118  L = policy_type::FI(L ^ K[12], K[13]) ^ R;
119  R = policy_type::FI(R ^ K[14], K[15]) ^ L;
120 
121  R ^= (policy_type::template rotl<1>(L) & K[8]);
122  L ^= (policy_type::template rotl<1>(R) | K[9]);
123 
124  B0 ^= L;
125  B1 ^= R;
126  }
127 
128  return {boost::endian::big_to_native(B0), boost::endian::big_to_native(B1),
129  boost::endian::big_to_native(B2), boost::endian::big_to_native(B3)};
130  }
131 
132  inline block_type decrypt_block(const block_type &ciphertext,
133  const key_schedule_type &key_schedule) const {
134  word_type B0 = boost::endian::native_to_big(ciphertext[0]);
135  word_type B1 = boost::endian::native_to_big(ciphertext[1]);
136  word_type B2 = boost::endian::native_to_big(ciphertext[2]);
137  word_type B3 = boost::endian::native_to_big(ciphertext[3]);
138 
139  for (size_t j = 0; j != rounds; j += 2) {
140  const word_type *K = &key_schedule[8 * (6 - j)];
141 
142  word_type L = B2, R = B3;
143 
144  L = policy_type::FI(L ^ K[10], K[11]) ^ R;
145  R = policy_type::FI(R ^ K[12], K[13]) ^ L;
146  L = policy_type::FI(L ^ K[14], K[15]) ^ R;
147 
148  L ^= (policy_type::template rotl<1>(R) & K[8]);
149  R ^= (policy_type::template rotl<1>(L) | K[9]);
150 
151  R = B0 ^= R;
152  L = B1 ^= L;
153 
154  L ^= (policy_type::template rotl<1>(R) & K[0]);
155  R ^= (policy_type::template rotl<1>(L) | K[1]);
156 
157  R = policy_type::FI(R ^ K[2], K[3]) ^ L;
158  L = policy_type::FI(L ^ K[4], K[5]) ^ R;
159  R = policy_type::FI(R ^ K[6], K[7]) ^ L;
160 
161  B2 ^= L;
162  B3 ^= R;
163  }
164 
165  return {boost::endian::big_to_native(B0), boost::endian::big_to_native(B1),
166  boost::endian::big_to_native(B2), boost::endian::big_to_native(B3)};
167  }
168 
170 
172  std::array<word_type, 16> K = {0};
173  for (size_t i = 0; i != rounds; ++i) {
174  K[i] = boost::endian::native_to_big(key[i]);
175  K[i + 8] = K[i] ^ policy_type::round_constants[i];
176  }
177 
178  for (size_t i = 0; i != rounds; ++i) {
179  key_schedule[8 * i] = policy_type::template rotl<2>(K[(i + 0) % 8]);
180  key_schedule[8 * i + 1] = policy_type::template rotl<1>(K[(i + 2) % 8 + 8]);
181  key_schedule[8 * i + 2] = policy_type::template rotl<5>(K[(i + 1) % 8]);
182  key_schedule[8 * i + 3] = K[(i + 4) % 8 + 8];
183  key_schedule[8 * i + 4] = policy_type::template rotl<8>(K[(i + 5) % 8]);
184  key_schedule[8 * i + 5] = K[(i + 3) % 8 + 8];
185  key_schedule[8 * i + 6] = policy_type::template rotl<13>(K[(i + 6) % 8]);
186  key_schedule[8 * i + 7] = K[(i + 7) % 8 + 8];
187  }
188 
189  K.fill(0);
190  }
191  };
192  } // namespace block
193  } // namespace crypto3
194 } // namespace nil
195 #endif
Kasumi. A 64-bit cipher used in 3GPP mobile phone protocols. There is no reason to use it outside of ...
Definition: kasumi.hpp:46
policy_type::word_type word_type
Definition: kasumi.hpp:57
policy_type::key_type key_type
Definition: kasumi.hpp:65
constexpr static const std::size_t key_bits
Definition: kasumi.hpp:63
detail::kasumi_functions policy_type
Definition: kasumi.hpp:48
constexpr static const std::size_t block_words
Definition: kasumi.hpp:60
constexpr static const std::size_t block_bits
Definition: kasumi.hpp:59
kasumi(const key_type &key)
Definition: kasumi.hpp:80
key_schedule_type key_schedule
Definition: kasumi.hpp:169
constexpr static const std::size_t rounds
Definition: kasumi.hpp:54
block_type encrypt(const block_type &plaintext) const
Definition: kasumi.hpp:88
void schedule_key(key_schedule_type &key_schedule, const key_type &key)
Definition: kasumi.hpp:171
policy_type::key_schedule_type key_schedule_type
Definition: kasumi.hpp:51
constexpr static const std::size_t word_bits
Definition: kasumi.hpp:56
constexpr static const std::size_t key_words
Definition: kasumi.hpp:64
block_type decrypt(const block_type &ciphertext) const
Definition: kasumi.hpp:92
constexpr static const std::size_t key_schedule_size
Definition: kasumi.hpp:50
~kasumi()
Definition: kasumi.hpp:84
policy_type::block_type block_type
Definition: kasumi.hpp:61
block_type encrypt_block(const block_type &plaintext, const key_schedule_type &key_schedule) const
Definition: kasumi.hpp:97
block_type decrypt_block(const block_type &ciphertext, const key_schedule_type &key_schedule) const
Definition: kasumi.hpp:132
stream_endian::little_octet_big_bit endian_type
Definition: kasumi.hpp:78
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: kasumi_functions.hpp:34
kasumi_policy::word_type word_type
Definition: kasumi_functions.hpp:36
static word_type FI(word_type I, word_type K)
Definition: kasumi_functions.hpp:38
constexpr static const std::size_t word_bits
Definition: kasumi_functions.hpp:35
constexpr static const std::size_t key_schedule_size
Definition: kasumi_policy.hpp:51
std::array< word_type, block_words > block_type
Definition: kasumi_policy.hpp:43
constexpr static const std::size_t key_bits
Definition: kasumi_policy.hpp:45
constexpr static const round_constants_type round_constants
Definition: kasumi_policy.hpp:57
std::array< word_type, key_schedule_size > key_schedule_type
Definition: kasumi_policy.hpp:52
constexpr static const std::size_t key_words
Definition: kasumi_policy.hpp:46
constexpr static const std::size_t block_bits
Definition: kasumi_policy.hpp:41
constexpr static const std::size_t block_words
Definition: kasumi_policy.hpp:42
constexpr static const std::size_t rounds
Definition: kasumi_policy.hpp:49
std::array< word_type, key_words > key_type
Definition: kasumi_policy.hpp:47
constexpr static const std::size_t length_bits
Definition: kasumi.hpp:72
constexpr static const std::size_t value_bits
Definition: kasumi.hpp:71
block_stream_processor< Mode, StateAccumulator, params_type > type
Definition: kasumi.hpp:75
Definition: algebra/include/nil/crypto3/detail/stream_endian.hpp:45