8#include <botan/internal/camellia.h>
9#include <botan/internal/loadstor.h>
10#include <botan/internal/rotate.h>
11#include <botan/internal/prefetch.h>
19alignas(256)
const uint8_t SBOX1[256] = {
20 0x70, 0x82, 0x2C, 0xEC, 0xB3, 0x27, 0xC0, 0xE5, 0xE4, 0x85, 0x57,
21 0x35, 0xEA, 0x0C, 0xAE, 0x41, 0x23, 0xEF, 0x6B, 0x93, 0x45, 0x19,
22 0xA5, 0x21, 0xED, 0x0E, 0x4F, 0x4E, 0x1D, 0x65, 0x92, 0xBD, 0x86,
23 0xB8, 0xAF, 0x8F, 0x7C, 0xEB, 0x1F, 0xCE, 0x3E, 0x30, 0xDC, 0x5F,
24 0x5E, 0xC5, 0x0B, 0x1A, 0xA6, 0xE1, 0x39, 0xCA, 0xD5, 0x47, 0x5D,
25 0x3D, 0xD9, 0x01, 0x5A, 0xD6, 0x51, 0x56, 0x6C, 0x4D, 0x8B, 0x0D,
26 0x9A, 0x66, 0xFB, 0xCC, 0xB0, 0x2D, 0x74, 0x12, 0x2B, 0x20, 0xF0,
27 0xB1, 0x84, 0x99, 0xDF, 0x4C, 0xCB, 0xC2, 0x34, 0x7E, 0x76, 0x05,
28 0x6D, 0xB7, 0xA9, 0x31, 0xD1, 0x17, 0x04, 0xD7, 0x14, 0x58, 0x3A,
29 0x61, 0xDE, 0x1B, 0x11, 0x1C, 0x32, 0x0F, 0x9C, 0x16, 0x53, 0x18,
30 0xF2, 0x22, 0xFE, 0x44, 0xCF, 0xB2, 0xC3, 0xB5, 0x7A, 0x91, 0x24,
31 0x08, 0xE8, 0xA8, 0x60, 0xFC, 0x69, 0x50, 0xAA, 0xD0, 0xA0, 0x7D,
32 0xA1, 0x89, 0x62, 0x97, 0x54, 0x5B, 0x1E, 0x95, 0xE0, 0xFF, 0x64,
33 0xD2, 0x10, 0xC4, 0x00, 0x48, 0xA3, 0xF7, 0x75, 0xDB, 0x8A, 0x03,
34 0xE6, 0xDA, 0x09, 0x3F, 0xDD, 0x94, 0x87, 0x5C, 0x83, 0x02, 0xCD,
35 0x4A, 0x90, 0x33, 0x73, 0x67, 0xF6, 0xF3, 0x9D, 0x7F, 0xBF, 0xE2,
36 0x52, 0x9B, 0xD8, 0x26, 0xC8, 0x37, 0xC6, 0x3B, 0x81, 0x96, 0x6F,
37 0x4B, 0x13, 0xBE, 0x63, 0x2E, 0xE9, 0x79, 0xA7, 0x8C, 0x9F, 0x6E,
38 0xBC, 0x8E, 0x29, 0xF5, 0xF9, 0xB6, 0x2F, 0xFD, 0xB4, 0x59, 0x78,
39 0x98, 0x06, 0x6A, 0xE7, 0x46, 0x71, 0xBA, 0xD4, 0x25, 0xAB, 0x42,
40 0x88, 0xA2, 0x8D, 0xFA, 0x72, 0x07, 0xB9, 0x55, 0xF8, 0xEE, 0xAC,
41 0x0A, 0x36, 0x49, 0x2A, 0x68, 0x3C, 0x38, 0xF1, 0xA4, 0x40, 0x28,
42 0xD3, 0x7B, 0xBB, 0xC9, 0x43, 0xC1, 0x15, 0xE3, 0xAD, 0xF4, 0x77,
46alignas(256)
const uint8_t SBOX2[256] = {
47 0xE0, 0x05, 0x58, 0xD9, 0x67, 0x4E, 0x81, 0xCB, 0xC9, 0x0B, 0xAE,
48 0x6A, 0xD5, 0x18, 0x5D, 0x82, 0x46, 0xDF, 0xD6, 0x27, 0x8A, 0x32,
49 0x4B, 0x42, 0xDB, 0x1C, 0x9E, 0x9C, 0x3A, 0xCA, 0x25, 0x7B, 0x0D,
50 0x71, 0x5F, 0x1F, 0xF8, 0xD7, 0x3E, 0x9D, 0x7C, 0x60, 0xB9, 0xBE,
51 0xBC, 0x8B, 0x16, 0x34, 0x4D, 0xC3, 0x72, 0x95, 0xAB, 0x8E, 0xBA,
52 0x7A, 0xB3, 0x02, 0xB4, 0xAD, 0xA2, 0xAC, 0xD8, 0x9A, 0x17, 0x1A,
53 0x35, 0xCC, 0xF7, 0x99, 0x61, 0x5A, 0xE8, 0x24, 0x56, 0x40, 0xE1,
54 0x63, 0x09, 0x33, 0xBF, 0x98, 0x97, 0x85, 0x68, 0xFC, 0xEC, 0x0A,
55 0xDA, 0x6F, 0x53, 0x62, 0xA3, 0x2E, 0x08, 0xAF, 0x28, 0xB0, 0x74,
56 0xC2, 0xBD, 0x36, 0x22, 0x38, 0x64, 0x1E, 0x39, 0x2C, 0xA6, 0x30,
57 0xE5, 0x44, 0xFD, 0x88, 0x9F, 0x65, 0x87, 0x6B, 0xF4, 0x23, 0x48,
58 0x10, 0xD1, 0x51, 0xC0, 0xF9, 0xD2, 0xA0, 0x55, 0xA1, 0x41, 0xFA,
59 0x43, 0x13, 0xC4, 0x2F, 0xA8, 0xB6, 0x3C, 0x2B, 0xC1, 0xFF, 0xC8,
60 0xA5, 0x20, 0x89, 0x00, 0x90, 0x47, 0xEF, 0xEA, 0xB7, 0x15, 0x06,
61 0xCD, 0xB5, 0x12, 0x7E, 0xBB, 0x29, 0x0F, 0xB8, 0x07, 0x04, 0x9B,
62 0x94, 0x21, 0x66, 0xE6, 0xCE, 0xED, 0xE7, 0x3B, 0xFE, 0x7F, 0xC5,
63 0xA4, 0x37, 0xB1, 0x4C, 0x91, 0x6E, 0x8D, 0x76, 0x03, 0x2D, 0xDE,
64 0x96, 0x26, 0x7D, 0xC6, 0x5C, 0xD3, 0xF2, 0x4F, 0x19, 0x3F, 0xDC,
65 0x79, 0x1D, 0x52, 0xEB, 0xF3, 0x6D, 0x5E, 0xFB, 0x69, 0xB2, 0xF0,
66 0x31, 0x0C, 0xD4, 0xCF, 0x8C, 0xE2, 0x75, 0xA9, 0x4A, 0x57, 0x84,
67 0x11, 0x45, 0x1B, 0xF5, 0xE4, 0x0E, 0x73, 0xAA, 0xF1, 0xDD, 0x59,
68 0x14, 0x6C, 0x92, 0x54, 0xD0, 0x78, 0x70, 0xE3, 0x49, 0x80, 0x50,
69 0xA7, 0xF6, 0x77, 0x93, 0x86, 0x83, 0x2A, 0xC7, 0x5B, 0xE9, 0xEE,
73alignas(256)
const uint8_t SBOX3[256] = {
74 0x38, 0x41, 0x16, 0x76, 0xD9, 0x93, 0x60, 0xF2, 0x72, 0xC2, 0xAB,
75 0x9A, 0x75, 0x06, 0x57, 0xA0, 0x91, 0xF7, 0xB5, 0xC9, 0xA2, 0x8C,
76 0xD2, 0x90, 0xF6, 0x07, 0xA7, 0x27, 0x8E, 0xB2, 0x49, 0xDE, 0x43,
77 0x5C, 0xD7, 0xC7, 0x3E, 0xF5, 0x8F, 0x67, 0x1F, 0x18, 0x6E, 0xAF,
78 0x2F, 0xE2, 0x85, 0x0D, 0x53, 0xF0, 0x9C, 0x65, 0xEA, 0xA3, 0xAE,
79 0x9E, 0xEC, 0x80, 0x2D, 0x6B, 0xA8, 0x2B, 0x36, 0xA6, 0xC5, 0x86,
80 0x4D, 0x33, 0xFD, 0x66, 0x58, 0x96, 0x3A, 0x09, 0x95, 0x10, 0x78,
81 0xD8, 0x42, 0xCC, 0xEF, 0x26, 0xE5, 0x61, 0x1A, 0x3F, 0x3B, 0x82,
82 0xB6, 0xDB, 0xD4, 0x98, 0xE8, 0x8B, 0x02, 0xEB, 0x0A, 0x2C, 0x1D,
83 0xB0, 0x6F, 0x8D, 0x88, 0x0E, 0x19, 0x87, 0x4E, 0x0B, 0xA9, 0x0C,
84 0x79, 0x11, 0x7F, 0x22, 0xE7, 0x59, 0xE1, 0xDA, 0x3D, 0xC8, 0x12,
85 0x04, 0x74, 0x54, 0x30, 0x7E, 0xB4, 0x28, 0x55, 0x68, 0x50, 0xBE,
86 0xD0, 0xC4, 0x31, 0xCB, 0x2A, 0xAD, 0x0F, 0xCA, 0x70, 0xFF, 0x32,
87 0x69, 0x08, 0x62, 0x00, 0x24, 0xD1, 0xFB, 0xBA, 0xED, 0x45, 0x81,
88 0x73, 0x6D, 0x84, 0x9F, 0xEE, 0x4A, 0xC3, 0x2E, 0xC1, 0x01, 0xE6,
89 0x25, 0x48, 0x99, 0xB9, 0xB3, 0x7B, 0xF9, 0xCE, 0xBF, 0xDF, 0x71,
90 0x29, 0xCD, 0x6C, 0x13, 0x64, 0x9B, 0x63, 0x9D, 0xC0, 0x4B, 0xB7,
91 0xA5, 0x89, 0x5F, 0xB1, 0x17, 0xF4, 0xBC, 0xD3, 0x46, 0xCF, 0x37,
92 0x5E, 0x47, 0x94, 0xFA, 0xFC, 0x5B, 0x97, 0xFE, 0x5A, 0xAC, 0x3C,
93 0x4C, 0x03, 0x35, 0xF3, 0x23, 0xB8, 0x5D, 0x6A, 0x92, 0xD5, 0x21,
94 0x44, 0x51, 0xC6, 0x7D, 0x39, 0x83, 0xDC, 0xAA, 0x7C, 0x77, 0x56,
95 0x05, 0x1B, 0xA4, 0x15, 0x34, 0x1E, 0x1C, 0xF8, 0x52, 0x20, 0x14,
96 0xE9, 0xBD, 0xDD, 0xE4, 0xA1, 0xE0, 0x8A, 0xF1, 0xD6, 0x7A, 0xBB,
100alignas(256)
const uint8_t SBOX4[256] = {
101 0x70, 0x2C, 0xB3, 0xC0, 0xE4, 0x57, 0xEA, 0xAE, 0x23, 0x6B, 0x45,
102 0xA5, 0xED, 0x4F, 0x1D, 0x92, 0x86, 0xAF, 0x7C, 0x1F, 0x3E, 0xDC,
103 0x5E, 0x0B, 0xA6, 0x39, 0xD5, 0x5D, 0xD9, 0x5A, 0x51, 0x6C, 0x8B,
104 0x9A, 0xFB, 0xB0, 0x74, 0x2B, 0xF0, 0x84, 0xDF, 0xCB, 0x34, 0x76,
105 0x6D, 0xA9, 0xD1, 0x04, 0x14, 0x3A, 0xDE, 0x11, 0x32, 0x9C, 0x53,
106 0xF2, 0xFE, 0xCF, 0xC3, 0x7A, 0x24, 0xE8, 0x60, 0x69, 0xAA, 0xA0,
107 0xA1, 0x62, 0x54, 0x1E, 0xE0, 0x64, 0x10, 0x00, 0xA3, 0x75, 0x8A,
108 0xE6, 0x09, 0xDD, 0x87, 0x83, 0xCD, 0x90, 0x73, 0xF6, 0x9D, 0xBF,
109 0x52, 0xD8, 0xC8, 0xC6, 0x81, 0x6F, 0x13, 0x63, 0xE9, 0xA7, 0x9F,
110 0xBC, 0x29, 0xF9, 0x2F, 0xB4, 0x78, 0x06, 0xE7, 0x71, 0xD4, 0xAB,
111 0x88, 0x8D, 0x72, 0xB9, 0xF8, 0xAC, 0x36, 0x2A, 0x3C, 0xF1, 0x40,
112 0xD3, 0xBB, 0x43, 0x15, 0xAD, 0x77, 0x80, 0x82, 0xEC, 0x27, 0xE5,
113 0x85, 0x35, 0x0C, 0x41, 0xEF, 0x93, 0x19, 0x21, 0x0E, 0x4E, 0x65,
114 0xBD, 0xB8, 0x8F, 0xEB, 0xCE, 0x30, 0x5F, 0xC5, 0x1A, 0xE1, 0xCA,
115 0x47, 0x3D, 0x01, 0xD6, 0x56, 0x4D, 0x0D, 0x66, 0xCC, 0x2D, 0x12,
116 0x20, 0xB1, 0x99, 0x4C, 0xC2, 0x7E, 0x05, 0xB7, 0x31, 0x17, 0xD7,
117 0x58, 0x61, 0x1B, 0x1C, 0x0F, 0x16, 0x18, 0x22, 0x44, 0xB2, 0xB5,
118 0x91, 0x08, 0xA8, 0xFC, 0x50, 0xD0, 0x7D, 0x89, 0x97, 0x5B, 0x95,
119 0xFF, 0xD2, 0xC4, 0x48, 0xF7, 0xDB, 0x03, 0xDA, 0x3F, 0x94, 0x5C,
120 0x02, 0x4A, 0x33, 0x67, 0xF3, 0x7F, 0xE2, 0x9B, 0x26, 0x37, 0x3B,
121 0x96, 0x4B, 0xBE, 0x2E, 0x79, 0x8C, 0x6E, 0x8E, 0xF5, 0xB6, 0xFD,
122 0x59, 0x98, 0x6A, 0x46, 0xBA, 0x25, 0x42, 0xA2, 0xFA, 0x07, 0x55,
123 0xEE, 0x0A, 0x49, 0x68, 0x38, 0xA4, 0x28, 0x7B, 0xC9, 0xC1, 0xE3,
126uint64_t F(uint64_t v, uint64_t K)
128 const uint64_t M1 = 0x0101010001000001;
129 const uint64_t M2 = 0x0001010101010000;
130 const uint64_t M3 = 0x0100010100010100;
131 const uint64_t M4 = 0x0101000100000101;
132 const uint64_t M5 = 0x0001010100010101;
133 const uint64_t M6 = 0x0100010101000101;
134 const uint64_t M7 = 0x0101000101010001;
135 const uint64_t M8 = 0x0101010001010100;
137 const uint64_t x = v ^ K;
139 const uint64_t Z1 = M1 * SBOX1[get_byte<0>(x)];
140 const uint64_t Z2 = M2 * SBOX2[get_byte<1>(x)];
141 const uint64_t Z3 = M3 * SBOX3[get_byte<2>(x)];
142 const uint64_t Z4 = M4 * SBOX4[get_byte<3>(x)];
143 const uint64_t Z5 = M5 * SBOX2[get_byte<4>(x)];
144 const uint64_t Z6 = M6 * SBOX3[get_byte<5>(x)];
145 const uint64_t Z7 = M7 * SBOX4[get_byte<6>(x)];
146 const uint64_t Z8 = M8 * SBOX1[get_byte<7>(x)];
148 return Z1 ^ Z2 ^ Z3 ^ Z4 ^ Z5 ^ Z6 ^ Z7 ^ Z8;
151inline uint64_t FL(uint64_t v, uint64_t K)
153 uint32_t x1 =
static_cast<uint32_t
>(v >> 32);
154 uint32_t x2 =
static_cast<uint32_t
>(v & 0xFFFFFFFF);
156 const uint32_t k1 =
static_cast<uint32_t
>(K >> 32);
157 const uint32_t k2 =
static_cast<uint32_t
>(K & 0xFFFFFFFF);
159 x2 ^= rotl<1>(x1 & k1);
162 return ((
static_cast<uint64_t
>(x1) << 32) | x2);
165inline uint64_t FLINV(uint64_t v, uint64_t K)
167 uint32_t x1 =
static_cast<uint32_t
>(v >> 32);
168 uint32_t x2 =
static_cast<uint32_t
>(v & 0xFFFFFFFF);
170 const uint32_t k1 =
static_cast<uint32_t
>(K >> 32);
171 const uint32_t k2 =
static_cast<uint32_t
>(K & 0xFFFFFFFF);
174 x2 ^= rotl<1>(x1 & k1);
176 return ((
static_cast<uint64_t
>(x1) << 32) | x2);
182void encrypt(
const uint8_t in[], uint8_t out[],
size_t blocks,
185 prefetch_arrays(SBOX1, SBOX2, SBOX3, SBOX4);
187 for(
size_t i = 0; i < blocks; ++i)
192 const uint64_t* K = SK.data();
200 for(
size_t r = 1; r != rounds - 1; ++r)
205 D2 = FLINV(D2, *K++);
225void decrypt(
const uint8_t in[], uint8_t out[],
size_t blocks,
228 prefetch_arrays(SBOX1, SBOX2, SBOX3, SBOX4);
230 for(
size_t i = 0; i < blocks; ++i)
235 const uint64_t* K = &SK[SK.size()-1];
243 for(
size_t r = 1; r != rounds - 1; ++r)
248 D2 = FLINV(D2, *K--);
265inline uint64_t left_rot_hi(uint64_t h, uint64_t l,
size_t shift)
269 return (h << shift) | (l >> (64-shift));
272inline uint64_t left_rot_lo(uint64_t h, uint64_t l,
size_t shift)
276 return (h >> (64-shift)) | (l << shift);
284 const uint64_t Sigma1 = 0xA09E667F3BCC908B;
285 const uint64_t Sigma2 = 0xB67AE8584CAA73B2;
286 const uint64_t Sigma3 = 0xC6EF372FE94F82BE;
287 const uint64_t Sigma4 = 0x54FF53A5F1D36F1C;
288 const uint64_t Sigma5 = 0x10E527FADE682D1D;
289 const uint64_t Sigma6 = 0xB05688C2B3E6C1FD;
295 const uint64_t KR_L =
298 uint64_t D1 = KL_H ^ KR_H;
299 uint64_t D2 = KL_L ^ KR_L;
307 const uint64_t KA_H = D1;
308 const uint64_t KA_L = D2;
315 const uint64_t KB_H = D1;
316 const uint64_t KB_L = D2;
326 SK[ 4] = left_rot_hi(KL_H, KL_L, 15);
327 SK[ 5] = left_rot_lo(KL_H, KL_L, 15);
328 SK[ 6] = left_rot_hi(KA_H, KA_L, 15);
329 SK[ 7] = left_rot_lo(KA_H, KA_L, 15);
330 SK[ 8] = left_rot_hi(KA_H, KA_L, 30);
331 SK[ 9] = left_rot_lo(KA_H, KA_L, 30);
332 SK[10] = left_rot_hi(KL_H, KL_L, 45);
333 SK[11] = left_rot_lo(KL_H, KL_L, 45);
334 SK[12] = left_rot_hi(KA_H, KA_L, 45);
335 SK[13] = left_rot_lo(KL_H, KL_L, 60);
336 SK[14] = left_rot_hi(KA_H, KA_L, 60);
337 SK[15] = left_rot_lo(KA_H, KA_L, 60);
338 SK[16] = left_rot_lo(KL_H, KL_L, 77);
339 SK[17] = left_rot_hi(KL_H, KL_L, 77);
340 SK[18] = left_rot_lo(KL_H, KL_L, 94);
341 SK[19] = left_rot_hi(KL_H, KL_L, 94);
342 SK[20] = left_rot_lo(KA_H, KA_L, 94);
343 SK[21] = left_rot_hi(KA_H, KA_L, 94);
344 SK[22] = left_rot_lo(KL_H, KL_L, 111);
345 SK[23] = left_rot_hi(KL_H, KL_L, 111);
346 SK[24] = left_rot_lo(KA_H, KA_L, 111);
347 SK[25] = left_rot_hi(KA_H, KA_L, 111);
358 SK[ 4] = left_rot_hi(KR_H, KR_L, 15);
359 SK[ 5] = left_rot_lo(KR_H, KR_L, 15);
360 SK[ 6] = left_rot_hi(KA_H, KA_L, 15);
361 SK[ 7] = left_rot_lo(KA_H, KA_L, 15);
363 SK[ 8] = left_rot_hi(KR_H, KR_L, 30);
364 SK[ 9] = left_rot_lo(KR_H, KR_L, 30);
365 SK[10] = left_rot_hi(KB_H, KB_L, 30);
366 SK[11] = left_rot_lo(KB_H, KB_L, 30);
368 SK[12] = left_rot_hi(KL_H, KL_L, 45);
369 SK[13] = left_rot_lo(KL_H, KL_L, 45);
370 SK[14] = left_rot_hi(KA_H, KA_L, 45);
371 SK[15] = left_rot_lo(KA_H, KA_L, 45);
373 SK[16] = left_rot_hi(KL_H, KL_L, 60);
374 SK[17] = left_rot_lo(KL_H, KL_L, 60);
375 SK[18] = left_rot_hi(KR_H, KR_L, 60);
376 SK[19] = left_rot_lo(KR_H, KR_L, 60);
377 SK[20] = left_rot_hi(KB_H, KB_L, 60);
378 SK[21] = left_rot_lo(KB_H, KB_L, 60);
380 SK[22] = left_rot_lo(KL_H, KL_L, 77);
381 SK[23] = left_rot_hi(KL_H, KL_L, 77);
382 SK[24] = left_rot_lo(KA_H, KA_L, 77);
383 SK[25] = left_rot_hi(KA_H, KA_L, 77);
385 SK[26] = left_rot_lo(KR_H, KR_L, 94);
386 SK[27] = left_rot_hi(KR_H, KR_L, 94);
387 SK[28] = left_rot_lo(KA_H, KA_L, 94);
388 SK[29] = left_rot_hi(KA_H, KA_L, 94);
389 SK[30] = left_rot_lo(KL_H, KL_L, 111);
390 SK[31] = left_rot_hi(KL_H, KL_L, 111);
391 SK[32] = left_rot_lo(KB_H, KB_L, 111);
392 SK[33] = left_rot_hi(KB_H, KB_L, 111);
403 Camellia_F::encrypt(in, out, blocks, m_SK, 9);
409 Camellia_F::encrypt(in, out, blocks, m_SK, 12);
415 Camellia_F::encrypt(in, out, blocks, m_SK, 12);
421 Camellia_F::decrypt(in, out, blocks, m_SK, 9);
427 Camellia_F::decrypt(in, out, blocks, m_SK, 12);
433 Camellia_F::decrypt(in, out, blocks, m_SK, 12);
440void Camellia_128::key_schedule(
const uint8_t key[],
size_t length)
442 Camellia_F::key_schedule(m_SK, key, length);
445void Camellia_192::key_schedule(
const uint8_t key[],
size_t length)
447 Camellia_F::key_schedule(m_SK, key, length);
450void Camellia_256::key_schedule(
const uint8_t key[],
size_t length)
452 Camellia_F::key_schedule(m_SK, key, length);
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
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
bool has_keying_material() const override
void decrypt_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 encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override
void assert_key_material_set() const
void zap(std::vector< T, Alloc > &vec)
constexpr uint64_t load_be< uint64_t >(const uint8_t in[], size_t off)
constexpr void store_be(uint16_t in, uint8_t out[2])
std::vector< T, secure_allocator< T > > secure_vector
constexpr T load_be(const uint8_t in[], size_t off)