8#include <botan/internal/des.h>
10#include <botan/compiler.h>
11#include <botan/internal/bit_ops.h>
12#include <botan/internal/loadstor.h>
38BOTAN_FORCE_INLINE void SBox1(T a1, T a2, T a3, T a4, T a5, T a6, T& out1, T& out2, T& out3, T& out4) {
39 const T x1 = a1 & ~a5;
45 const T x7 = x6 & ~x2;
49 const T x10 = x2 & ~x9;
50 const T x11 = a6 | x5;
51 const T x12 = x10 ^ x11;
52 const T x13 = x12 & ~x7;
54 const T x14 = a1 | a6;
55 const T x15 = x12 | x14;
56 const T x16 = a5 & ~x6;
57 const T x17 = x15 ^ x16;
59 const T x18 = a4 & ~x14;
60 const T x19 = x16 ^ x18;
61 const T x20 = x8 & ~x4;
62 const T x21 = x19 | x20;
64 const T x22 = a3 & ~x1;
65 const T x23 = x2 ^ x15;
66 const T x24 = x23 & ~x22;
68 const T x26 = x3 & x12;
69 const T x27 = x25 ^ x26;
70 const T x28 = x17 & ~a2;
71 const T x29 = x28 ^ x27;
74 const T x30 = x8 ^ x24;
75 const T x31 = x16 | x30;
76 const T x32 = x3 ^ x31;
77 const T x33 = a1 ^ x32;
78 const T x34 = x27 ^ x33;
79 const T x35 = x7 | a2;
80 const T x36 = x35 ^ x34;
83 const T x37 = x2 & ~x21;
84 const T x38 = x30 ^ x37;
85 const T x39 = x16 ^ x32;
86 const T x40 = x34 & ~x39;
87 const T x41 = x38 ^ x40;
88 const T x42 = a2 & ~x13;
89 const T x43 = x42 ^ x41;
92 const T x44 = x9 ^ x20;
93 const T x45 = x14 ^ x40;
94 const T x46 = x45 & ~x44;
95 const T x47 = x41 ^ x46;
96 const T x48 = x47 | a2;
97 const T x49 = x48 ^ x21;
101template <BitsliceT T>
102BOTAN_FORCE_INLINE void SBox2(T a1, T a2, T a3, T a4, T a5, T a6, T& out1, T& out2, T& out3, T& out4) {
103 const T x1 = a2 ^ a5;
105 const T x2 = a1 & ~a6;
106 const T x3 = a5 & ~x2;
107 const T x4 = a2 | x3;
109 const T x5 = x1 & ~a6;
110 const T x6 = a1 & x1;
111 const T x7 = a5 ^ x6;
112 const T x8 = x7 & ~x5;
114 const T x9 = a3 & a6;
115 const T x10 = x3 ^ x5;
116 const T x11 = x4 & x10;
117 const T x12 = x11 & ~x9;
119 const T x13 = a3 & x11;
121 const T x15 = x13 ^ x14;
122 const T x16 = a6 ^ x1;
123 const T x17 = x16 & ~x9;
124 const T x18 = x15 ^ x17;
125 const T x19 = a4 & ~x12;
126 const T x20 = x19 ^ x18;
129 const T x21 = a2 & ~x17;
130 const T x22 = x7 ^ x21;
131 const T x23 = x15 & ~x22;
132 const T x24 = a3 ^ x16;
133 const T x25 = x23 ^ x24;
134 const T x26 = x4 & ~a4;
135 const T x27 = x26 ^ x25;
138 const T x28 = a2 & ~x9;
139 const T x29 = x24 | x28;
140 const T x30 = x4 ^ x18;
141 const T x31 = x9 | x30;
142 const T x32 = x29 ^ x31;
144 const T x33 = x11 ^ x18;
145 const T x34 = x25 ^ x33;
146 const T x35 = x31 & x34;
147 const T x36 = x1 & x29;
148 const T x37 = x35 ^ x36;
149 const T x38 = x37 | a4;
150 const T x39 = x38 ^ x32;
153 const T x40 = x37 & ~x22;
154 const T x41 = x16 | x30;
155 const T x42 = x40 ^ x41;
156 const T x43 = x8 | a4;
157 const T x44 = x43 ^ x42;
161template <BitsliceT T>
162BOTAN_FORCE_INLINE void SBox3(T a1, T a2, T a3, T a4, T a5, T a6, T& out1, T& out2, T& out3, T& out4) {
163 const T x1 = a1 & ~a2;
164 const T x2 = a3 ^ a6;
165 const T x3 = x1 | x2;
166 const T x4 = a4 ^ a6;
167 const T x5 = x4 & ~a1;
168 const T x6 = x3 ^ x5;
170 const T x7 = a2 ^ x2;
171 const T x8 = x7 & ~a6;
172 const T x9 = x3 ^ x8;
173 const T x10 = x6 & ~x9;
175 const T x11 = a6 & x6;
176 const T x12 = a4 | x11;
177 const T x13 = a1 & x12;
178 const T x14 = x7 ^ x13;
179 const T x15 = x6 & ~a5;
180 const T x16 = x15 ^ x14;
183 const T x17 = x2 & x4;
184 const T x18 = a1 ^ a4;
185 const T x19 = x9 ^ x18;
186 const T x20 = a3 | x19;
187 const T x21 = x20 & ~x17;
189 const T x22 = x5 | x18;
190 const T x23 = x14 & ~x22;
191 const T x24 = a4 & a6;
192 const T x25 = x24 & ~a2;
193 const T x26 = x23 ^ x25;
195 const T x27 = x9 & x26;
196 const T x28 = x7 | x24;
197 const T x29 = x28 & ~x27;
198 const T x30 = a1 ^ x29;
199 const T x31 = x21 & a5;
200 const T x32 = x31 ^ x30;
203 const T x33 = x6 & ~a2;
204 const T x34 = x33 & ~a3;
206 const T x36 = x22 ^ x35;
207 const T x37 = x34 ^ x36;
208 const T x38 = a5 & ~x10;
209 const T x39 = x38 ^ x37;
212 const T x40 = x34 | x36;
213 const T x41 = x5 | x33;
214 const T x42 = x40 ^ x41;
215 const T x43 = a4 & ~x6;
216 const T x44 = x42 | x43;
217 const T x45 = a5 & ~x26;
218 const T x46 = x45 ^ x44;
222template <BitsliceT T>
223BOTAN_FORCE_INLINE void SBox4(T a1, T a2, T a3, T a4, T a5, T a6, T& out1, T& out2, T& out3, T& out4) {
224 const T x1 = a1 ^ a3;
225 const T x2 = a3 ^ a5;
226 const T x3 = a2 | a4;
227 const T x4 = a5 ^ x3;
228 const T x5 = x2 & ~x4;
229 const T x6 = x2 & ~a2;
230 const T x7 = a4 ^ x6;
231 const T x8 = x1 | x7;
232 const T x9 = x8 & ~x5;
233 const T x10 = a2 ^ x9;
235 const T x11 = x7 & x10;
236 const T x12 = x2 & ~x11;
237 const T x13 = x1 ^ x10;
238 const T x14 = x13 & ~x12;
239 const T x15 = x5 ^ x14;
241 const T x16 = a2 ^ a4;
242 const T x17 = a5 | x6;
243 const T x18 = x13 ^ x17;
244 const T x19 = x18 & ~x16;
245 const T x20 = x9 ^ x19;
246 const T x21 = a6 & ~x15;
247 const T x22 = x21 ^ x20;
251 const T x24 = x15 & ~a6;
252 const T x25 = x24 ^ x23;
255 const T x26 = x15 ^ x23;
256 const T x27 = x26 & ~x16;
257 const T x28 = x11 | x27;
258 const T x29 = x18 ^ x28;
259 const T x30 = x10 | a6;
260 const T x31 = x30 ^ x29;
263 const T x32 = a6 & x10;
264 const T x33 = x32 ^ x29;
268template <BitsliceT T>
269BOTAN_FORCE_INLINE void SBox5(T a1, T a2, T a3, T a4, T a5, T a6, T& out1, T& out2, T& out3, T& out4) {
270 const T x1 = a1 | a3;
271 const T x2 = x1 & ~a6;
272 const T x3 = a1 ^ x2;
273 const T x4 = a3 ^ x3;
274 const T x5 = a4 | x4;
276 const T x6 = x2 & ~a4;
277 const T x7 = a3 ^ x6;
278 const T x8 = a5 & x7;
279 const T x9 = a1 | x4;
280 const T x10 = x8 ^ x9;
281 const T x11 = a4 ^ x10;
283 const T x12 = a6 ^ x11;
284 const T x13 = x3 | x12;
285 const T x14 = a5 & x13;
286 const T x15 = x3 ^ x14;
287 const T x16 = a4 & x9;
288 const T x17 = x15 ^ x16;
290 const T x18 = x13 & ~a1;
291 const T x19 = x7 ^ x18;
292 const T x20 = a5 ^ x5;
293 const T x21 = x20 & ~x19;
295 const T x23 = x22 & ~a2;
296 const T x24 = x23 ^ x11;
299 const T x25 = x7 & ~x14;
300 const T x26 = x18 ^ x20;
301 const T x27 = x17 | x26;
302 const T x28 = x27 & ~x25;
303 const T x29 = x5 & ~x28;
305 const T x30 = x12 & x28;
306 const T x31 = x20 ^ x30;
307 const T x32 = x7 & x9;
308 const T x33 = x31 | x32;
309 const T x34 = x14 ^ x33;
310 const T x35 = x34 & a2;
311 const T x36 = x35 ^ x17;
314 const T x37 = x1 ^ x28;
315 const T x38 = a1 ^ x37;
316 const T x39 = a4 & x31;
317 const T x40 = x38 ^ x39;
318 const T x41 = x29 | a2;
319 const T x42 = x41 ^ x40;
322 const T x43 = x5 ^ x7;
323 const T x44 = x43 & ~x40;
324 const T x45 = x3 ^ x31;
325 const T x46 = x44 ^ x45;
326 const T x47 = x5 & a2;
327 const T x48 = x47 ^ x46;
331template <BitsliceT T>
332BOTAN_FORCE_INLINE void SBox6(T a1, T a2, T a3, T a4, T a5, T a6, T& out1, T& out2, T& out3, T& out4) {
333 const T x1 = a2 ^ a5;
335 const T x2 = a2 | a6;
336 const T x3 = a1 & x2;
337 const T x4 = x1 ^ x3;
338 const T x5 = a6 ^ x4;
339 const T x6 = a5 & ~x5;
341 const T x7 = a1 & x5;
342 const T x8 = a2 ^ x7;
343 const T x9 = a1 ^ a3;
344 const T x10 = x8 | x9;
345 const T x11 = x4 ^ x10;
347 const T x12 = a3 & x11;
348 const T x13 = x12 & ~a6;
349 const T x14 = x6 | x8;
350 const T x15 = x13 ^ x14;
351 const T x16 = x15 & a4;
352 const T x17 = x16 ^ x11;
355 const T x18 = a2 ^ x10;
356 const T x19 = a6 & ~x18;
357 const T x20 = a3 ^ x19;
358 const T x21 = a5 & ~x12;
359 const T x22 = x20 | x21;
361 const T x23 = a2 | x9;
362 const T x24 = x15 ^ x23;
363 const T x25 = x3 | x22;
364 const T x26 = x24 ^ x25;
366 const T x27 = a1 | x11;
367 const T x28 = x14 & x27;
368 const T x29 = x20 ^ x28;
369 const T x30 = x29 & ~x13;
370 const T x31 = x6 | a4;
371 const T x32 = x31 ^ x30;
374 const T x33 = x4 ^ x29;
375 const T x34 = a5 & ~x33;
377 const T x36 = x18 ^ x35;
378 const T x37 = x34 ^ x36;
379 const T x38 = x37 & ~a4;
380 const T x39 = x38 ^ x26;
383 const T x40 = a6 ^ x7;
384 const T x41 = a1 ^ x20;
385 const T x42 = x40 & x41;
386 const T x43 = x12 ^ x36;
387 const T x44 = x42 ^ x43;
388 const T x45 = x22 & ~a4;
389 const T x46 = x45 ^ x44;
393template <BitsliceT T>
394BOTAN_FORCE_INLINE void SBox7(T a1, T a2, T a3, T a4, T a5, T a6, T& out1, T& out2, T& out3, T& out4) {
395 const T x1 = a4 ^ a5;
396 const T x2 = a3 ^ x1;
397 const T x3 = a6 & x2;
398 const T x4 = a4 & x1;
399 const T x5 = a2 ^ x4;
400 const T x6 = x3 & x5;
402 const T x7 = a6 & x4;
403 const T x8 = a3 ^ x7;
404 const T x9 = x5 | x8;
405 const T x10 = a6 ^ x1;
406 const T x11 = x9 ^ x10;
407 const T x12 = a1 & ~x6;
408 const T x13 = x12 ^ x11;
411 const T x14 = a5 & ~x2;
412 const T x15 = x5 | x14;
413 const T x16 = x3 ^ x8;
414 const T x17 = x15 ^ x16;
416 const T x18 = x3 ^ x10;
417 const T x19 = a4 & ~x18;
418 const T x20 = x5 & ~x19;
419 const T x21 = a5 ^ x16;
420 const T x22 = x20 ^ x21;
422 const T x23 = x18 & ~x7;
423 const T x24 = x19 | x23;
424 const T x25 = a2 ^ x9;
425 const T x26 = x22 & x25;
426 const T x27 = x24 ^ x26;
427 const T x28 = x27 & a1;
428 const T x29 = x28 ^ x22;
431 const T x30 = x5 & ~a3;
432 const T x31 = x23 | x30;
433 const T x32 = x4 | x22;
434 const T x33 = x31 & x32;
435 const T x34 = x27 ^ x33;
437 const T x35 = x17 | x24;
438 const T x36 = x14 ^ x35;
439 const T x37 = a6 & x36;
440 const T x38 = x33 ^ x37;
441 const T x39 = x38 & ~a1;
442 const T x40 = x39 ^ x17;
446 const T x42 = a2 | x41;
447 const T x43 = x17 ^ x33;
448 const T x44 = x42 ^ x43;
449 const T x45 = x34 | a1;
450 const T x46 = x45 ^ x44;
454template <BitsliceT T>
455BOTAN_FORCE_INLINE void SBox8(T a1, T a2, T a3, T a4, T a5, T a6, T& out1, T& out2, T& out3, T& out4) {
456 const T x1 = a3 & ~a2;
457 const T x2 = a5 & ~a3;
458 const T x3 = a4 ^ x2;
459 const T x4 = a1 & x3;
460 const T x5 = x4 & ~x1;
462 const T x6 = a2 & ~x3;
463 const T x7 = a1 | x6;
464 const T x8 = a2 & ~a3;
465 const T x9 = a5 ^ x8;
466 const T x10 = x7 & x9;
467 const T x11 = x4 | x10;
470 const T x13 = x10 ^ x12;
471 const T x14 = a3 & ~x7;
472 const T x15 = x13 ^ x14;
473 const T x16 = x1 ^ x15;
474 const T x17 = x5 | a6;
475 const T x18 = x17 ^ x16;
478 const T x19 = a1 ^ x16;
479 const T x20 = a5 & x19;
480 const T x21 = a2 ^ x15;
481 const T x22 = x20 ^ x21;
482 const T x23 = x6 ^ x22;
484 const T x24 = x11 ^ x22;
485 const T x25 = a2 | x24;
486 const T x26 = a5 ^ x19;
487 const T x27 = x25 ^ x26;
488 const T x28 = x11 & a6;
489 const T x29 = x28 ^ x27;
492 const T x30 = x9 ^ x23;
493 const T x31 = a4 | x21;
494 const T x32 = x30 ^ x31;
495 const T x33 = a1 ^ x32;
496 const T x34 = x33 & a6;
497 const T x35 = x34 ^ x23;
500 const T x36 = x30 & ~a4;
501 const T x37 = x27 & x36;
502 const T x38 = x5 ^ x32;
503 const T x39 = x37 ^ x38;
504 const T x40 = x39 | a6;
505 const T x41 = x40 ^ x23;
509void des_transpose(uint64_t M[32]) {
510 for(
size_t i = 0; i != 16; ++i) {
514 for(
size_t i = 0; i != 32; i += 16) {
515 for(
size_t j = 0; j != 8; ++j) {
520 for(
size_t i = 0; i != 32; i += 8) {
521 for(
size_t j = 0; j != 4; ++j) {
526 for(
size_t i = 0; i != 32; i += 4) {
527 for(
size_t j = 0; j != 2; ++j) {
532 for(
size_t i = 0; i != 32; i += 2) {
537void transpose_in(uint32_t B[64],
const uint8_t in[],
size_t n_blocks) {
545 static constexpr uint8_t IP[64] = {
546 57, 49, 41, 33, 25, 17, 9, 1,
547 59, 51, 43, 35, 27, 19, 11, 3,
548 61, 53, 45, 37, 29, 21, 13, 5,
549 63, 55, 47, 39, 31, 23, 15, 7,
550 56, 48, 40, 32, 24, 16, 8, 0,
551 58, 50, 42, 34, 26, 18, 10, 2,
552 60, 52, 44, 36, 28, 20, 12, 4,
553 62, 54, 46, 38, 30, 22, 14, 6
557 for(
size_t i = 0; i < 64; ++i) {
558 const uint8_t src = IP[i];
560 B[i] =
static_cast<uint32_t
>(M[31 - src] >> 32);
562 B[i] =
static_cast<uint32_t
>(M[63 - src]);
567void transpose_out(uint8_t out[],
const uint32_t B[64],
size_t n_blocks) {
569 static constexpr uint8_t FP[64] = {
570 39, 7, 47, 15, 55, 23, 63, 31,
571 38, 6, 46, 14, 54, 22, 62, 30,
572 37, 5, 45, 13, 53, 21, 61, 29,
573 36, 4, 44, 12, 52, 20, 60, 28,
574 35, 3, 43, 11, 51, 19, 59, 27,
575 34, 2, 42, 10, 50, 18, 58, 26,
576 33, 1, 41, 9, 49, 17, 57, 25,
577 32, 0, 40, 8, 48, 16, 56, 24
582 for(
size_t i = 0; i != 32; ++i) {
584 M[i] = (
static_cast<uint64_t
>(B[FP[31 - i] ^ 32]) << 32) | B[FP[63 - i] ^ 32];
589 for(
size_t i = 0; i != n_blocks; ++i) {
602void des_round(uint32_t L[32],
const uint32_t R[32],
const uint32_t RK[48]) {
604 SBox1(R[31] ^ RK[ 0], R[ 0] ^ RK[ 1], R[ 1] ^ RK[ 2],
605 R[ 2] ^ RK[ 3], R[ 3] ^ RK[ 4], R[ 4] ^ RK[ 5],
606 L[ 8], L[16], L[22], L[30]);
608 SBox2(R[ 3] ^ RK[ 6], R[ 4] ^ RK[ 7], R[ 5] ^ RK[ 8],
609 R[ 6] ^ RK[ 9], R[ 7] ^ RK[10], R[ 8] ^ RK[11],
610 L[12], L[27], L[ 1], L[17]);
612 SBox3(R[ 7] ^ RK[12], R[ 8] ^ RK[13], R[ 9] ^ RK[14],
613 R[10] ^ RK[15], R[11] ^ RK[16], R[12] ^ RK[17],
614 L[23], L[15], L[29], L[ 5]);
616 SBox4(R[11] ^ RK[18], R[12] ^ RK[19], R[13] ^ RK[20],
617 R[14] ^ RK[21], R[15] ^ RK[22], R[16] ^ RK[23],
618 L[25], L[19], L[ 9], L[ 0]);
620 SBox5(R[15] ^ RK[24], R[16] ^ RK[25], R[17] ^ RK[26],
621 R[18] ^ RK[27], R[19] ^ RK[28], R[20] ^ RK[29],
622 L[ 7], L[13], L[24], L[ 2]);
624 SBox6(R[19] ^ RK[30], R[20] ^ RK[31], R[21] ^ RK[32],
625 R[22] ^ RK[33], R[23] ^ RK[34], R[24] ^ RK[35],
626 L[ 3], L[28], L[10], L[18]);
628 SBox7(R[23] ^ RK[36], R[24] ^ RK[37], R[25] ^ RK[38],
629 R[26] ^ RK[39], R[27] ^ RK[40], R[28] ^ RK[41],
630 L[31], L[11], L[21], L[ 6]);
632 SBox8(R[27] ^ RK[42], R[28] ^ RK[43], R[29] ^ RK[44],
633 R[30] ^ RK[45], R[31] ^ RK[46], R[ 0] ^ RK[47],
634 L[ 4], L[26], L[14], L[20]);
638void des_encrypt(uint32_t L[32], uint32_t R[32],
const uint32_t round_key[]) {
639 for(
size_t round = 0; round < 16; round += 2) {
640 des_round(L, R, &round_key[round * 48]);
641 des_round(R, L, &round_key[(round + 1) * 48]);
645void des_decrypt(uint32_t L[32], uint32_t R[32],
const uint32_t round_key[]) {
646 for(
size_t round = 16; round > 0; round -= 2) {
647 des_round(L, R, &round_key[(round - 1) * 48]);
648 des_round(R, L, &round_key[(round - 2) * 48]);
656void des_key_schedule(uint32_t round_key[],
const uint8_t key[8]) {
657 static const uint8_t ROT[16] = {1, 1, 2, 2, 2, 2, 2, 2, 1, 2, 2, 2, 2, 2, 2, 1};
659 uint32_t C = ((key[7] & 0x80) << 20) | ((key[6] & 0x80) << 19) | ((key[5] & 0x80) << 18) | ((key[4] & 0x80) << 17) |
660 ((key[3] & 0x80) << 16) | ((key[2] & 0x80) << 15) | ((key[1] & 0x80) << 14) | ((key[0] & 0x80) << 13) |
661 ((key[7] & 0x40) << 13) | ((key[6] & 0x40) << 12) | ((key[5] & 0x40) << 11) | ((key[4] & 0x40) << 10) |
662 ((key[3] & 0x40) << 9) | ((key[2] & 0x40) << 8) | ((key[1] & 0x40) << 7) | ((key[0] & 0x40) << 6) |
663 ((key[7] & 0x20) << 6) | ((key[6] & 0x20) << 5) | ((key[5] & 0x20) << 4) | ((key[4] & 0x20) << 3) |
664 ((key[3] & 0x20) << 2) | ((key[2] & 0x20) << 1) | ((key[1] & 0x20)) | ((key[0] & 0x20) >> 1) |
665 ((key[7] & 0x10) >> 1) | ((key[6] & 0x10) >> 2) | ((key[5] & 0x10) >> 3) | ((key[4] & 0x10) >> 4);
666 uint32_t D = ((key[7] & 0x02) << 26) | ((key[6] & 0x02) << 25) | ((key[5] & 0x02) << 24) | ((key[4] & 0x02) << 23) |
667 ((key[3] & 0x02) << 22) | ((key[2] & 0x02) << 21) | ((key[1] & 0x02) << 20) | ((key[0] & 0x02) << 19) |
668 ((key[7] & 0x04) << 17) | ((key[6] & 0x04) << 16) | ((key[5] & 0x04) << 15) | ((key[4] & 0x04) << 14) |
669 ((key[3] & 0x04) << 13) | ((key[2] & 0x04) << 12) | ((key[1] & 0x04) << 11) | ((key[0] & 0x04) << 10) |
670 ((key[7] & 0x08) << 8) | ((key[6] & 0x08) << 7) | ((key[5] & 0x08) << 6) | ((key[4] & 0x08) << 5) |
671 ((key[3] & 0x08) << 4) | ((key[2] & 0x08) << 3) | ((key[1] & 0x08) << 2) | ((key[0] & 0x08) << 1) |
672 ((key[3] & 0x10) >> 1) | ((key[2] & 0x10) >> 2) | ((key[1] & 0x10) >> 3) | ((key[0] & 0x10) >> 4);
674 static const uint8_t PC2_C[24] = {13, 16, 10, 23, 0, 4, 2, 27, 14, 5, 20, 9,
675 22, 18, 11, 3, 25, 7, 15, 6, 26, 19, 12, 1};
677 static const uint8_t PC2_D[24] = {12, 23, 2, 8, 18, 26, 1, 11, 22, 16, 4, 19,
678 15, 20, 10, 27, 5, 24, 17, 13, 21, 7, 0, 3};
680 for(
size_t i = 0; i != 16; ++i) {
681 C = ((C << ROT[i]) | (C >> (28 - ROT[i]))) & 0x0FFFFFFF;
682 D = ((D << ROT[i]) | (D >> (28 - ROT[i]))) & 0x0FFFFFFF;
684 uint32_t* rk = &round_key[i * 48];
686 for(
size_t j = 0; j < 24; ++j) {
687 const uint32_t bit = (C >> (27 - PC2_C[j])) & 1;
688 rk[j] =
static_cast<uint32_t
>(0) - bit;
691 for(
size_t j = 0; j < 24; ++j) {
692 const uint32_t bit = (D >> (27 - PC2_D[j])) & 1;
693 rk[24 + j] =
static_cast<uint32_t
>(0) - bit;
708 while(blocks >= 32) {
709 transpose_in(B, in, 32);
710 des_encrypt(&B[0], &B[32], m_round_key.data());
711 transpose_out(out, B, 32);
719 transpose_in(B, in, blocks);
720 des_encrypt(&B[0], &B[32], m_round_key.data());
721 transpose_out(out, B, blocks);
733 while(blocks >= 32) {
734 transpose_in(B, in, 32);
735 des_decrypt(&B[0], &B[32], m_round_key.data());
736 transpose_out(out, B, 32);
744 transpose_in(B, in, blocks);
745 des_decrypt(&B[0], &B[32], m_round_key.data());
746 transpose_out(out, B, blocks);
751 return !m_round_key.empty();
757void DES::key_schedule(std::span<const uint8_t> key) {
758 m_round_key.resize(16 * 48);
759 des_key_schedule(m_round_key.data(), key.data());
772 const uint32_t* k1 = m_round_key.data();
773 const uint32_t* k2 = k1 + 16 * 48;
774 const uint32_t* k3 = k2 + 16 * 48;
778 while(blocks >= 32) {
779 transpose_in(B, in, 32);
780 des_encrypt(&B[0], &B[32], k1);
781 des_decrypt(&B[32], &B[0], k2);
782 des_encrypt(&B[0], &B[32], k3);
783 transpose_out(out, B, 32);
791 transpose_in(B, in, blocks);
792 des_encrypt(&B[0], &B[32], k1);
793 des_decrypt(&B[32], &B[0], k2);
794 des_encrypt(&B[0], &B[32], k3);
795 transpose_out(out, B, blocks);
805 const uint32_t* k1 = m_round_key.data();
806 const uint32_t* k2 = k1 + 16 * 48;
807 const uint32_t* k3 = k2 + 16 * 48;
811 while(blocks >= 32) {
812 transpose_in(B, in, 32);
813 des_decrypt(&B[0], &B[32], k3);
814 des_encrypt(&B[32], &B[0], k2);
815 des_decrypt(&B[0], &B[32], k1);
816 transpose_out(out, B, 32);
824 transpose_in(B, in, blocks);
825 des_decrypt(&B[0], &B[32], k3);
826 des_encrypt(&B[32], &B[0], k2);
827 des_decrypt(&B[0], &B[32], k1);
828 transpose_out(out, B, blocks);
833 return !m_round_key.empty();
839void TripleDES::key_schedule(std::span<const uint8_t> key) {
840 m_round_key.resize(3 * 16 * 48);
841 des_key_schedule(m_round_key.data(), key.first(8).data());
842 des_key_schedule(m_round_key.data() + 16 * 48, key.subspan(8, 8).data());
844 if(key.size() == 24) {
845 des_key_schedule(m_round_key.data() + 2 * 16 * 48, key.last(8).data());
847 copy_mem(m_round_key.data() + 2 * 16 * 48, m_round_key.data(), 16 * 48);
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
bool has_keying_material() const override
void assert_key_material_set() const
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
bool has_keying_material() const override
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
#define BOTAN_FORCE_INLINE
constexpr void copy_mem(T *out, const T *in, size_t n)
void zap(std::vector< T, Alloc > &vec)
BOTAN_FORCE_INLINE constexpr void swap_bits(T &x, T &y, T mask, size_t shift)
constexpr auto store_be(ParamTs &&... params)
constexpr auto load_be(ParamTs &&... params)