Coverage Report

Created: 2023-06-07 07:00

/src/botan/src/lib/block/threefish_512/threefish_512.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Threefish-512
3
* (C) 2013,2014,2016 Jack Lloyd
4
*
5
* Botan is released under the Simplified BSD License (see license.txt)
6
*/
7
8
#include <botan/internal/threefish_512.h>
9
10
#include <botan/internal/cpuid.h>
11
#include <botan/internal/loadstor.h>
12
#include <botan/internal/rotate.h>
13
14
namespace Botan {
15
16
namespace Threefish_F {
17
18
template <size_t R1, size_t R2, size_t R3, size_t R4>
19
BOTAN_FORCE_INLINE void e_round(
20
0
   uint64_t& X0, uint64_t& X1, uint64_t& X2, uint64_t& X3, uint64_t& X4, uint64_t& X5, uint64_t& X6, uint64_t& X7) {
21
0
   X0 += X4;
22
0
   X1 += X5;
23
0
   X2 += X6;
24
0
   X3 += X7;
25
0
   X4 = rotl<R1>(X4);
26
0
   X5 = rotl<R2>(X5);
27
0
   X6 = rotl<R3>(X6);
28
0
   X7 = rotl<R4>(X7);
29
0
   X4 ^= X0;
30
0
   X5 ^= X1;
31
0
   X6 ^= X2;
32
0
   X7 ^= X3;
33
0
}
Unexecuted instantiation: void Botan::Threefish_F::e_round<46ul, 36ul, 19ul, 37ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::e_round<33ul, 27ul, 14ul, 42ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::e_round<17ul, 49ul, 36ul, 39ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::e_round<44ul, 9ul, 54ul, 56ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::e_round<39ul, 30ul, 34ul, 24ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::e_round<13ul, 50ul, 10ul, 17ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::e_round<25ul, 29ul, 39ul, 43ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::e_round<8ul, 35ul, 56ul, 22ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
34
35
template <size_t R1, size_t R2, size_t R3, size_t R4>
36
BOTAN_FORCE_INLINE void d_round(
37
0
   uint64_t& X0, uint64_t& X1, uint64_t& X2, uint64_t& X3, uint64_t& X4, uint64_t& X5, uint64_t& X6, uint64_t& X7) {
38
0
   X4 ^= X0;
39
0
   X5 ^= X1;
40
0
   X6 ^= X2;
41
0
   X7 ^= X3;
42
0
   X4 = rotr<R1>(X4);
43
0
   X5 = rotr<R2>(X5);
44
0
   X6 = rotr<R3>(X6);
45
0
   X7 = rotr<R4>(X7);
46
0
   X0 -= X4;
47
0
   X1 -= X5;
48
0
   X2 -= X6;
49
0
   X3 -= X7;
50
0
}
Unexecuted instantiation: void Botan::Threefish_F::d_round<8ul, 35ul, 56ul, 22ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::d_round<25ul, 29ul, 39ul, 43ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::d_round<13ul, 50ul, 10ul, 17ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::d_round<39ul, 30ul, 34ul, 24ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::d_round<44ul, 9ul, 54ul, 56ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::d_round<17ul, 49ul, 36ul, 39ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::d_round<33ul, 27ul, 14ul, 42ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
Unexecuted instantiation: void Botan::Threefish_F::d_round<46ul, 36ul, 19ul, 37ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&)
51
52
class Key_Inserter {
53
   public:
54
0
      Key_Inserter(const uint64_t* K, const uint64_t* T) : m_K(K), m_T(T) {}
55
56
      inline void e_add(size_t R,
57
                        uint64_t& X0,
58
                        uint64_t& X1,
59
                        uint64_t& X2,
60
                        uint64_t& X3,
61
                        uint64_t& X4,
62
                        uint64_t& X5,
63
                        uint64_t& X6,
64
0
                        uint64_t& X7) const {
65
0
         X0 += m_K[(R) % 9];
66
0
         X1 += m_K[(R + 1) % 9];
67
0
         X2 += m_K[(R + 2) % 9];
68
0
         X3 += m_K[(R + 3) % 9];
69
0
         X4 += m_K[(R + 4) % 9];
70
0
         X5 += m_K[(R + 5) % 9] + m_T[(R) % 3];
71
0
         X6 += m_K[(R + 6) % 9] + m_T[(R + 1) % 3];
72
0
         X7 += m_K[(R + 7) % 9] + R;
73
0
      }
74
75
      inline void d_add(size_t R,
76
                        uint64_t& X0,
77
                        uint64_t& X1,
78
                        uint64_t& X2,
79
                        uint64_t& X3,
80
                        uint64_t& X4,
81
                        uint64_t& X5,
82
                        uint64_t& X6,
83
0
                        uint64_t& X7) const {
84
0
         X0 -= m_K[(R) % 9];
85
0
         X1 -= m_K[(R + 1) % 9];
86
0
         X2 -= m_K[(R + 2) % 9];
87
0
         X3 -= m_K[(R + 3) % 9];
88
0
         X4 -= m_K[(R + 4) % 9];
89
0
         X5 -= m_K[(R + 5) % 9] + m_T[(R) % 3];
90
0
         X6 -= m_K[(R + 6) % 9] + m_T[(R + 1) % 3];
91
0
         X7 -= m_K[(R + 7) % 9] + R;
92
0
      }
93
94
   private:
95
      const uint64_t* m_K;
96
      const uint64_t* m_T;
97
};
98
99
template <size_t R1, size_t R2>
100
BOTAN_FORCE_INLINE void e8_rounds(uint64_t& X0,
101
                                  uint64_t& X1,
102
                                  uint64_t& X2,
103
                                  uint64_t& X3,
104
                                  uint64_t& X4,
105
                                  uint64_t& X5,
106
                                  uint64_t& X6,
107
                                  uint64_t& X7,
108
0
                                  const Key_Inserter& key) {
109
0
   e_round<46, 36, 19, 37>(X0, X2, X4, X6, X1, X3, X5, X7);
110
0
   e_round<33, 27, 14, 42>(X2, X4, X6, X0, X1, X7, X5, X3);
111
0
   e_round<17, 49, 36, 39>(X4, X6, X0, X2, X1, X3, X5, X7);
112
0
   e_round<44, 9, 54, 56>(X6, X0, X2, X4, X1, X7, X5, X3);
113
0
   key.e_add(R1, X0, X1, X2, X3, X4, X5, X6, X7);
114
115
0
   e_round<39, 30, 34, 24>(X0, X2, X4, X6, X1, X3, X5, X7);
116
0
   e_round<13, 50, 10, 17>(X2, X4, X6, X0, X1, X7, X5, X3);
117
0
   e_round<25, 29, 39, 43>(X4, X6, X0, X2, X1, X3, X5, X7);
118
0
   e_round<8, 35, 56, 22>(X6, X0, X2, X4, X1, X7, X5, X3);
119
0
   key.e_add(R2, X0, X1, X2, X3, X4, X5, X6, X7);
120
0
}
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<1ul, 2ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<3ul, 4ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<5ul, 6ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<7ul, 8ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<9ul, 10ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<11ul, 12ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<13ul, 14ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<15ul, 16ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::e8_rounds<17ul, 18ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
121
122
template <size_t R1, size_t R2>
123
BOTAN_FORCE_INLINE void d8_rounds(uint64_t& X0,
124
                                  uint64_t& X1,
125
                                  uint64_t& X2,
126
                                  uint64_t& X3,
127
                                  uint64_t& X4,
128
                                  uint64_t& X5,
129
                                  uint64_t& X6,
130
                                  uint64_t& X7,
131
0
                                  const Key_Inserter& key) {
132
0
   d_round<8, 35, 56, 22>(X6, X0, X2, X4, X1, X7, X5, X3);
133
0
   d_round<25, 29, 39, 43>(X4, X6, X0, X2, X1, X3, X5, X7);
134
0
   d_round<13, 50, 10, 17>(X2, X4, X6, X0, X1, X7, X5, X3);
135
0
   d_round<39, 30, 34, 24>(X0, X2, X4, X6, X1, X3, X5, X7);
136
0
   key.d_add(R1, X0, X1, X2, X3, X4, X5, X6, X7);
137
138
0
   d_round<44, 9, 54, 56>(X6, X0, X2, X4, X1, X7, X5, X3);
139
0
   d_round<17, 49, 36, 39>(X4, X6, X0, X2, X1, X3, X5, X7);
140
0
   d_round<33, 27, 14, 42>(X2, X4, X6, X0, X1, X7, X5, X3);
141
0
   d_round<46, 36, 19, 37>(X0, X2, X4, X6, X1, X3, X5, X7);
142
0
   key.d_add(R2, X0, X1, X2, X3, X4, X5, X6, X7);
143
0
}
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<17ul, 16ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<15ul, 14ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<13ul, 12ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<11ul, 10ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<9ul, 8ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<7ul, 6ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<5ul, 4ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<3ul, 2ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
Unexecuted instantiation: void Botan::Threefish_F::d8_rounds<1ul, 0ul>(unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, unsigned long&, Botan::Threefish_F::Key_Inserter const&)
144
145
}  // namespace Threefish_F
146
147
0
void Threefish_512::skein_feedfwd(const secure_vector<uint64_t>& M, const secure_vector<uint64_t>& T) {
148
0
   using namespace Threefish_F;
149
150
0
   BOTAN_ASSERT(m_K.size() == 9, "Key was set");
151
0
   BOTAN_ASSERT(M.size() == 8, "Single block");
152
153
0
   m_T[0] = T[0];
154
0
   m_T[1] = T[1];
155
0
   m_T[2] = T[0] ^ T[1];
156
157
0
   const Key_Inserter key(m_K.data(), m_T.data());
158
159
0
   uint64_t X0 = M[0];
160
0
   uint64_t X1 = M[1];
161
0
   uint64_t X2 = M[2];
162
0
   uint64_t X3 = M[3];
163
0
   uint64_t X4 = M[4];
164
0
   uint64_t X5 = M[5];
165
0
   uint64_t X6 = M[6];
166
0
   uint64_t X7 = M[7];
167
168
0
   key.e_add(0, X0, X1, X2, X3, X4, X5, X6, X7);
169
170
0
   e8_rounds<1, 2>(X0, X1, X2, X3, X4, X5, X6, X7, key);
171
0
   e8_rounds<3, 4>(X0, X1, X2, X3, X4, X5, X6, X7, key);
172
0
   e8_rounds<5, 6>(X0, X1, X2, X3, X4, X5, X6, X7, key);
173
0
   e8_rounds<7, 8>(X0, X1, X2, X3, X4, X5, X6, X7, key);
174
0
   e8_rounds<9, 10>(X0, X1, X2, X3, X4, X5, X6, X7, key);
175
0
   e8_rounds<11, 12>(X0, X1, X2, X3, X4, X5, X6, X7, key);
176
0
   e8_rounds<13, 14>(X0, X1, X2, X3, X4, X5, X6, X7, key);
177
0
   e8_rounds<15, 16>(X0, X1, X2, X3, X4, X5, X6, X7, key);
178
0
   e8_rounds<17, 18>(X0, X1, X2, X3, X4, X5, X6, X7, key);
179
180
0
   m_K[0] = M[0] ^ X0;
181
0
   m_K[1] = M[1] ^ X1;
182
0
   m_K[2] = M[2] ^ X2;
183
0
   m_K[3] = M[3] ^ X3;
184
0
   m_K[4] = M[4] ^ X4;
185
0
   m_K[5] = M[5] ^ X5;
186
0
   m_K[6] = M[6] ^ X6;
187
0
   m_K[7] = M[7] ^ X7;
188
189
0
   m_K[8] = m_K[0] ^ m_K[1] ^ m_K[2] ^ m_K[3] ^ m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22;
190
0
}
191
192
0
void Threefish_512::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
193
0
   using namespace Threefish_F;
194
195
0
   assert_key_material_set();
196
197
0
   const Key_Inserter key(m_K.data(), m_T.data());
198
199
0
   BOTAN_PARALLEL_SIMD_FOR(size_t i = 0; i < blocks; ++i) {
200
0
      uint64_t X0, X1, X2, X3, X4, X5, X6, X7;
201
0
      load_le(in + BLOCK_SIZE * i, X0, X1, X2, X3, X4, X5, X6, X7);
202
203
0
      key.e_add(0, X0, X1, X2, X3, X4, X5, X6, X7);
204
205
0
      e8_rounds<1, 2>(X0, X1, X2, X3, X4, X5, X6, X7, key);
206
0
      e8_rounds<3, 4>(X0, X1, X2, X3, X4, X5, X6, X7, key);
207
0
      e8_rounds<5, 6>(X0, X1, X2, X3, X4, X5, X6, X7, key);
208
0
      e8_rounds<7, 8>(X0, X1, X2, X3, X4, X5, X6, X7, key);
209
0
      e8_rounds<9, 10>(X0, X1, X2, X3, X4, X5, X6, X7, key);
210
0
      e8_rounds<11, 12>(X0, X1, X2, X3, X4, X5, X6, X7, key);
211
0
      e8_rounds<13, 14>(X0, X1, X2, X3, X4, X5, X6, X7, key);
212
0
      e8_rounds<15, 16>(X0, X1, X2, X3, X4, X5, X6, X7, key);
213
0
      e8_rounds<17, 18>(X0, X1, X2, X3, X4, X5, X6, X7, key);
214
215
0
      store_le(out + BLOCK_SIZE * i, X0, X1, X2, X3, X4, X5, X6, X7);
216
0
   }
217
0
}
218
219
#undef THREEFISH_ENC_8_ROUNDS
220
221
0
void Threefish_512::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
222
0
   using namespace Threefish_F;
223
224
0
   assert_key_material_set();
225
226
0
   const Key_Inserter key(m_K.data(), m_T.data());
227
228
0
   BOTAN_PARALLEL_SIMD_FOR(size_t i = 0; i < blocks; ++i) {
229
0
      uint64_t X0, X1, X2, X3, X4, X5, X6, X7;
230
0
      load_le(in + BLOCK_SIZE * i, X0, X1, X2, X3, X4, X5, X6, X7);
231
232
0
      key.d_add(18, X0, X1, X2, X3, X4, X5, X6, X7);
233
234
0
      d8_rounds<17, 16>(X0, X1, X2, X3, X4, X5, X6, X7, key);
235
0
      d8_rounds<15, 14>(X0, X1, X2, X3, X4, X5, X6, X7, key);
236
0
      d8_rounds<13, 12>(X0, X1, X2, X3, X4, X5, X6, X7, key);
237
0
      d8_rounds<11, 10>(X0, X1, X2, X3, X4, X5, X6, X7, key);
238
0
      d8_rounds<9, 8>(X0, X1, X2, X3, X4, X5, X6, X7, key);
239
0
      d8_rounds<7, 6>(X0, X1, X2, X3, X4, X5, X6, X7, key);
240
0
      d8_rounds<5, 4>(X0, X1, X2, X3, X4, X5, X6, X7, key);
241
0
      d8_rounds<3, 2>(X0, X1, X2, X3, X4, X5, X6, X7, key);
242
0
      d8_rounds<1, 0>(X0, X1, X2, X3, X4, X5, X6, X7, key);
243
244
0
      store_le(out + BLOCK_SIZE * i, X0, X1, X2, X3, X4, X5, X6, X7);
245
0
   }
246
0
}
247
248
0
void Threefish_512::set_tweak(const uint8_t tweak[], size_t len) {
249
0
   BOTAN_ARG_CHECK(len == 16, "Threefish-512 requires 128 bit tweak");
250
251
0
   m_T.resize(3);
252
0
   m_T[0] = load_le<uint64_t>(tweak, 0);
253
0
   m_T[1] = load_le<uint64_t>(tweak, 1);
254
0
   m_T[2] = m_T[0] ^ m_T[1];
255
0
}
256
257
0
bool Threefish_512::has_keying_material() const { return !m_K.empty(); }
258
259
0
void Threefish_512::key_schedule(const uint8_t key[], size_t /*length*/) {
260
   // todo: define key schedule for smaller keys
261
0
   m_K.resize(9);
262
263
0
   for(size_t i = 0; i != 8; ++i) {
264
0
      m_K[i] = load_le<uint64_t>(key, i);
265
0
   }
266
267
0
   m_K[8] = m_K[0] ^ m_K[1] ^ m_K[2] ^ m_K[3] ^ m_K[4] ^ m_K[5] ^ m_K[6] ^ m_K[7] ^ 0x1BD11BDAA9FC1A22;
268
269
   // Reset tweak to all zeros on key reset
270
0
   m_T.resize(3);
271
0
   zeroise(m_T);
272
0
}
273
274
0
void Threefish_512::clear() {
275
0
   zap(m_K);
276
0
   zap(m_T);
277
0
}
278
279
}  // namespace Botan