1#[rustfmt::skip]
15const SBOX1: [u8; 256] = [
16 112, 130, 44, 236, 179, 39, 192, 229, 228, 133, 87, 53, 234, 12, 174, 65,
17 35, 239, 107, 147, 69, 25, 165, 33, 237, 14, 79, 78, 29, 101, 146, 189,
18 134, 184, 175, 143, 124, 235, 31, 206, 62, 48, 220, 95, 94, 197, 11, 26,
19 166, 225, 57, 202, 213, 71, 93, 61, 217, 1, 90, 214, 81, 86, 108, 77,
20 139, 13, 154, 102, 251, 204, 176, 45, 116, 18, 43, 32, 240, 177, 132, 153,
21 223, 76, 203, 194, 52, 126, 118, 5, 109, 183, 169, 49, 209, 23, 4, 215,
22 20, 88, 58, 97, 222, 27, 17, 28, 50, 15, 156, 22, 83, 24, 242, 34,
23 254, 68, 207, 178, 195, 181, 122, 145, 36, 8, 232, 168, 96, 252, 105, 80,
24 170, 208, 160, 125, 161, 137, 98, 151, 84, 91, 30, 149, 224, 255, 100, 210,
25 16, 196, 0, 72, 163, 247, 117, 219, 138, 3, 230, 218, 9, 63, 221, 148,
26 135, 92, 131, 2, 205, 74, 144, 51, 115, 103, 246, 243, 157, 127, 191, 226,
27 82, 155, 216, 38, 200, 55, 198, 59, 129, 150, 111, 75, 19, 190, 99, 46,
28 233, 121, 167, 140, 159, 110, 188, 142, 41, 245, 249, 182, 47, 253, 180, 89,
29 120, 152, 6, 106, 231, 70, 113, 186, 212, 37, 171, 66, 136, 162, 141, 250,
30 114, 7, 185, 85, 248, 238, 172, 10, 54, 73, 42, 104, 60, 56, 241, 164,
31 64, 40, 211, 123, 187, 201, 67, 193, 21, 227, 173, 244, 119, 199, 128, 158,
32];
33
34const SIGMA: [u64; 6] = [
36 0xA09E_667F_3BCC_908B,
37 0xB67A_E858_4CAA_73B2,
38 0xC6EF_372F_E94F_82BE,
39 0x54FF_53A5_F1D3_6F1C,
40 0x10E5_27FA_DE68_2D1D,
41 0xB056_88C2_B3E6_C1FD,
42];
43
44const SBOX1_ANF: [[u128; 2]; 8] = crate::ct::build_byte_sbox_anf(&SBOX1);
45
46const fn build_sbox2() -> [u8; 256] {
47 let mut out = [0u8; 256];
48 let mut i = 0usize;
49 while i < 256 {
50 let v = SBOX1[i];
51 out[i] = v.rotate_left(1);
52 i += 1;
53 }
54 out
55}
56
57const fn build_sbox3() -> [u8; 256] {
58 let mut out = [0u8; 256];
59 let mut i = 0usize;
60 while i < 256 {
61 let v = SBOX1[i];
62 out[i] = v.rotate_left(7);
63 i += 1;
64 }
65 out
66}
67
68const fn build_sbox4() -> [u8; 256] {
69 let mut out = [0u8; 256];
70 let mut i = 0usize;
71 while i < 256 {
72 let x = i as u8;
74 let rotated = x.rotate_left(1);
75 out[i] = SBOX1[rotated as usize];
76 i += 1;
77 }
78 out
79}
80
81const SBOX2: [u8; 256] = build_sbox2();
82const SBOX3: [u8; 256] = build_sbox3();
83const SBOX4: [u8; 256] = build_sbox4();
84
85#[derive(Clone, Copy)]
86struct Subkeys18 {
87 kw: [u64; 4],
88 k: [u64; 18],
89 ke: [u64; 4],
90}
91
92#[derive(Clone, Copy)]
93struct Subkeys24 {
94 kw: [u64; 4],
95 k: [u64; 24],
96 ke: [u64; 6],
97}
98
99#[inline]
100fn sbox1(x: u8) -> u8 {
101 SBOX1[x as usize]
102}
103
104#[inline]
105fn sbox1_ct(x: u8) -> u8 {
106 crate::ct::eval_byte_sbox(&SBOX1_ANF, x)
107}
108
109#[inline]
110fn sbox2(x: u8) -> u8 {
111 SBOX2[x as usize]
112}
113
114#[inline]
115fn sbox3(x: u8) -> u8 {
116 SBOX3[x as usize]
117}
118
119#[inline]
120fn sbox4(x: u8) -> u8 {
121 SBOX4[x as usize]
122}
123
124#[inline]
125fn sbox2_ct(x: u8) -> u8 {
126 sbox1_ct(x).rotate_left(1)
127}
128
129#[inline]
130fn sbox3_ct(x: u8) -> u8 {
131 sbox1_ct(x).rotate_left(7)
132}
133
134#[inline]
135fn sbox4_ct(x: u8) -> u8 {
136 sbox1_ct(x.rotate_left(1))
137}
138
139#[inline]
140fn camellia_f(input: u64, subkey: u64) -> u64 {
141 let x = (input ^ subkey).to_be_bytes();
142
143 let t1 = sbox1(x[0]);
144 let t2 = sbox2(x[1]);
145 let t3 = sbox3(x[2]);
146 let t4 = sbox4(x[3]);
147 let t5 = sbox2(x[4]);
148 let t6 = sbox3(x[5]);
149 let t7 = sbox4(x[6]);
150 let t8 = sbox1(x[7]);
151
152 u64::from_be_bytes([
153 t1 ^ t3 ^ t4 ^ t6 ^ t7 ^ t8,
154 t1 ^ t2 ^ t4 ^ t5 ^ t7 ^ t8,
155 t1 ^ t2 ^ t3 ^ t5 ^ t6 ^ t8,
156 t2 ^ t3 ^ t4 ^ t5 ^ t6 ^ t7,
157 t1 ^ t2 ^ t6 ^ t7 ^ t8,
158 t2 ^ t3 ^ t5 ^ t7 ^ t8,
159 t3 ^ t4 ^ t5 ^ t6 ^ t8,
160 t1 ^ t4 ^ t5 ^ t6 ^ t7,
161 ])
162}
163
164#[inline]
165fn camellia_f_ct(input: u64, subkey: u64) -> u64 {
166 let x = (input ^ subkey).to_be_bytes();
167
168 let t1 = sbox1_ct(x[0]);
169 let t2 = sbox2_ct(x[1]);
170 let t3 = sbox3_ct(x[2]);
171 let t4 = sbox4_ct(x[3]);
172 let t5 = sbox2_ct(x[4]);
173 let t6 = sbox3_ct(x[5]);
174 let t7 = sbox4_ct(x[6]);
175 let t8 = sbox1_ct(x[7]);
176
177 u64::from_be_bytes([
178 t1 ^ t3 ^ t4 ^ t6 ^ t7 ^ t8,
179 t1 ^ t2 ^ t4 ^ t5 ^ t7 ^ t8,
180 t1 ^ t2 ^ t3 ^ t5 ^ t6 ^ t8,
181 t2 ^ t3 ^ t4 ^ t5 ^ t6 ^ t7,
182 t1 ^ t2 ^ t6 ^ t7 ^ t8,
183 t2 ^ t3 ^ t5 ^ t7 ^ t8,
184 t3 ^ t4 ^ t5 ^ t6 ^ t8,
185 t1 ^ t4 ^ t5 ^ t6 ^ t7,
186 ])
187}
188
189#[inline]
190fn fl(x: u64, ke: u64) -> u64 {
191 let (mut x1, mut x2) = split_u64_words(x);
192 let (k1, k2) = split_u64_words(ke);
193 x2 ^= (x1 & k1).rotate_left(1);
194 x1 ^= x2 | k2;
195 (u64::from(x1) << 32) | u64::from(x2)
196}
197
198#[inline]
199fn fl_inv(x: u64, ke: u64) -> u64 {
200 let (mut y1, mut y2) = split_u64_words(x);
201 let (k1, k2) = split_u64_words(ke);
202 y1 ^= y2 | k2;
203 y2 ^= (y1 & k1).rotate_left(1);
204 (u64::from(y1) << 32) | u64::from(y2)
205}
206
207#[inline]
208fn halves(x: u128) -> (u64, u64) {
209 let bytes = x.to_be_bytes();
210 (
211 u64::from_be_bytes([
212 bytes[0], bytes[1], bytes[2], bytes[3], bytes[4], bytes[5], bytes[6], bytes[7],
213 ]),
214 u64::from_be_bytes([
215 bytes[8], bytes[9], bytes[10], bytes[11], bytes[12], bytes[13], bytes[14], bytes[15],
216 ]),
217 )
218}
219
220#[inline]
221fn split_u64_words(x: u64) -> (u32, u32) {
222 let bytes = x.to_be_bytes();
223 (
224 u32::from_be_bytes([bytes[0], bytes[1], bytes[2], bytes[3]]),
225 u32::from_be_bytes([bytes[4], bytes[5], bytes[6], bytes[7]]),
226 )
227}
228
229#[inline]
230fn rot_pair(x: u128, bits: u32) -> (u64, u64) {
231 halves(x.rotate_left(bits))
232}
233
234fn derive_ka(kl: u128, kr: u128, use_ct: bool) -> u128 {
235 let x = kl ^ kr;
237 let (mut d1, mut d2) = halves(x);
238 let (kl_l, kl_r) = halves(kl);
239
240 let f = if use_ct { camellia_f_ct } else { camellia_f };
241
242 d2 ^= f(d1, SIGMA[0]);
243 d1 ^= f(d2, SIGMA[1]);
244 d1 ^= kl_l;
245 d2 ^= kl_r;
246 d2 ^= f(d1, SIGMA[2]);
247 d1 ^= f(d2, SIGMA[3]);
248
249 (u128::from(d1) << 64) | u128::from(d2)
250}
251
252fn derive_kb(ka: u128, kr: u128, use_ct: bool) -> u128 {
253 let (kr_l, kr_r) = halves(kr);
255 let (mut d1, mut d2) = halves(ka);
256
257 let f = if use_ct { camellia_f_ct } else { camellia_f };
258
259 d1 ^= kr_l;
260 d2 ^= kr_r;
261 d2 ^= f(d1, SIGMA[4]);
262 d1 ^= f(d2, SIGMA[5]);
263
264 (u128::from(d1) << 64) | u128::from(d2)
265}
266
267fn expand_128(key: &[u8; 16], use_ct: bool) -> Subkeys18 {
268 let kl = u128::from_be_bytes(*key);
269 let ka = derive_ka(kl, 0, use_ct);
270
271 let left_key_rotations = [
273 rot_pair(kl, 0),
274 rot_pair(kl, 15),
275 rot_pair(kl, 45),
276 rot_pair(kl, 60),
277 rot_pair(kl, 77),
278 rot_pair(kl, 94),
279 rot_pair(kl, 111),
280 ];
281 let aux_key_rotations = [
282 rot_pair(ka, 0),
283 rot_pair(ka, 15),
284 rot_pair(ka, 30),
285 rot_pair(ka, 45),
286 rot_pair(ka, 60),
287 rot_pair(ka, 94),
288 rot_pair(ka, 111),
289 ];
290
291 let mut out = Subkeys18 {
292 kw: [0; 4],
293 k: [0; 18],
294 ke: [0; 4],
295 };
296
297 out.kw[0] = left_key_rotations[0].0;
298 out.kw[1] = left_key_rotations[0].1;
299 out.kw[2] = aux_key_rotations[6].0;
300 out.kw[3] = aux_key_rotations[6].1;
301
302 out.k[0] = aux_key_rotations[0].0;
303 out.k[1] = aux_key_rotations[0].1;
304 out.k[2] = left_key_rotations[1].0;
305 out.k[3] = left_key_rotations[1].1;
306 out.k[4] = aux_key_rotations[1].0;
307 out.k[5] = aux_key_rotations[1].1;
308 out.ke[0] = aux_key_rotations[2].0;
309 out.ke[1] = aux_key_rotations[2].1;
310 out.k[6] = left_key_rotations[2].0;
311 out.k[7] = left_key_rotations[2].1;
312 out.k[8] = aux_key_rotations[3].0;
313 out.k[9] = left_key_rotations[3].1;
314 out.k[10] = aux_key_rotations[4].0;
315 out.k[11] = aux_key_rotations[4].1;
316 out.ke[2] = left_key_rotations[4].0;
317 out.ke[3] = left_key_rotations[4].1;
318 out.k[12] = left_key_rotations[5].0;
319 out.k[13] = left_key_rotations[5].1;
320 out.k[14] = aux_key_rotations[5].0;
321 out.k[15] = aux_key_rotations[5].1;
322 out.k[16] = left_key_rotations[6].0;
323 out.k[17] = left_key_rotations[6].1;
324
325 out
326}
327
328fn expand_192_256(kl: u128, kr: u128, use_ct: bool) -> Subkeys24 {
329 let ka = derive_ka(kl, kr, use_ct);
330 let kb = derive_kb(ka, kr, use_ct);
331
332 let left_key_rotations = [
335 rot_pair(kl, 0),
336 rot_pair(kl, 45),
337 rot_pair(kl, 60),
338 rot_pair(kl, 77),
339 rot_pair(kl, 111),
340 ];
341 let right_key_rotations = [
342 rot_pair(kr, 15),
343 rot_pair(kr, 30),
344 rot_pair(kr, 60),
345 rot_pair(kr, 94),
346 ];
347 let aux_key_rotations = [
348 rot_pair(ka, 15),
349 rot_pair(ka, 45),
350 rot_pair(ka, 77),
351 rot_pair(ka, 94),
352 ];
353 let secondary_key_rotations = [
354 rot_pair(kb, 0),
355 rot_pair(kb, 30),
356 rot_pair(kb, 60),
357 rot_pair(kb, 111),
358 ];
359
360 let mut out = Subkeys24 {
361 kw: [0; 4],
362 k: [0; 24],
363 ke: [0; 6],
364 };
365
366 out.kw[0] = left_key_rotations[0].0;
367 out.kw[1] = left_key_rotations[0].1;
368 out.kw[2] = secondary_key_rotations[3].0;
369 out.kw[3] = secondary_key_rotations[3].1;
370
371 out.k[0] = secondary_key_rotations[0].0;
372 out.k[1] = secondary_key_rotations[0].1;
373 out.k[2] = right_key_rotations[0].0;
374 out.k[3] = right_key_rotations[0].1;
375 out.k[4] = aux_key_rotations[0].0;
376 out.k[5] = aux_key_rotations[0].1;
377 out.ke[0] = right_key_rotations[1].0;
378 out.ke[1] = right_key_rotations[1].1;
379 out.k[6] = secondary_key_rotations[1].0;
380 out.k[7] = secondary_key_rotations[1].1;
381 out.k[8] = left_key_rotations[1].0;
382 out.k[9] = left_key_rotations[1].1;
383 out.k[10] = aux_key_rotations[1].0;
384 out.k[11] = aux_key_rotations[1].1;
385 out.ke[2] = left_key_rotations[2].0;
386 out.ke[3] = left_key_rotations[2].1;
387 out.k[12] = right_key_rotations[2].0;
388 out.k[13] = right_key_rotations[2].1;
389 out.k[14] = secondary_key_rotations[2].0;
390 out.k[15] = secondary_key_rotations[2].1;
391 out.k[16] = left_key_rotations[3].0;
392 out.k[17] = left_key_rotations[3].1;
393 out.ke[4] = aux_key_rotations[2].0;
394 out.ke[5] = aux_key_rotations[2].1;
395 out.k[18] = right_key_rotations[3].0;
396 out.k[19] = right_key_rotations[3].1;
397 out.k[20] = aux_key_rotations[3].0;
398 out.k[21] = aux_key_rotations[3].1;
399 out.k[22] = left_key_rotations[4].0;
400 out.k[23] = left_key_rotations[4].1;
401
402 out
403}
404
405fn camellia_encrypt_18(block: [u8; 16], sk: &Subkeys18, use_ct: bool) -> [u8; 16] {
406 let mut d1 = u64::from_be_bytes(block[..8].try_into().unwrap());
407 let mut d2 = u64::from_be_bytes(block[8..].try_into().unwrap());
408 let f = if use_ct { camellia_f_ct } else { camellia_f };
409
410 d1 ^= sk.kw[0];
411 d2 ^= sk.kw[1];
412
413 let mut idx = 0usize;
414 while idx < 6 {
415 d2 ^= f(d1, sk.k[idx]);
416 d1 ^= f(d2, sk.k[idx + 1]);
417 idx += 2;
418 }
419 d1 = fl(d1, sk.ke[0]);
420 d2 = fl_inv(d2, sk.ke[1]);
421
422 while idx < 12 {
423 d2 ^= f(d1, sk.k[idx]);
424 d1 ^= f(d2, sk.k[idx + 1]);
425 idx += 2;
426 }
427 d1 = fl(d1, sk.ke[2]);
428 d2 = fl_inv(d2, sk.ke[3]);
429
430 while idx < 18 {
431 d2 ^= f(d1, sk.k[idx]);
432 d1 ^= f(d2, sk.k[idx + 1]);
433 idx += 2;
434 }
435
436 let mut out = [0u8; 16];
437 out[..8].copy_from_slice(&(d2 ^ sk.kw[2]).to_be_bytes());
438 out[8..].copy_from_slice(&(d1 ^ sk.kw[3]).to_be_bytes());
439 out
440}
441
442fn camellia_decrypt_18(block: [u8; 16], sk: &Subkeys18, use_ct: bool) -> [u8; 16] {
443 let mut d2 = u64::from_be_bytes(block[..8].try_into().unwrap()) ^ sk.kw[2];
444 let mut d1 = u64::from_be_bytes(block[8..].try_into().unwrap()) ^ sk.kw[3];
445 let f = if use_ct { camellia_f_ct } else { camellia_f };
446
447 let mut idx = 18usize;
448 while idx > 12 {
449 idx -= 2;
450 d1 ^= f(d2, sk.k[idx + 1]);
451 d2 ^= f(d1, sk.k[idx]);
452 }
453 d2 = fl(d2, sk.ke[3]);
454 d1 = fl_inv(d1, sk.ke[2]);
455
456 while idx > 6 {
457 idx -= 2;
458 d1 ^= f(d2, sk.k[idx + 1]);
459 d2 ^= f(d1, sk.k[idx]);
460 }
461 d2 = fl(d2, sk.ke[1]);
462 d1 = fl_inv(d1, sk.ke[0]);
463
464 while idx > 0 {
465 idx -= 2;
466 d1 ^= f(d2, sk.k[idx + 1]);
467 d2 ^= f(d1, sk.k[idx]);
468 }
469
470 let mut out = [0u8; 16];
471 out[..8].copy_from_slice(&(d1 ^ sk.kw[0]).to_be_bytes());
472 out[8..].copy_from_slice(&(d2 ^ sk.kw[1]).to_be_bytes());
473 out
474}
475
476fn camellia_encrypt_24(block: [u8; 16], sk: &Subkeys24, use_ct: bool) -> [u8; 16] {
477 let mut d1 = u64::from_be_bytes(block[..8].try_into().unwrap());
478 let mut d2 = u64::from_be_bytes(block[8..].try_into().unwrap());
479 let f = if use_ct { camellia_f_ct } else { camellia_f };
480
481 d1 ^= sk.kw[0];
482 d2 ^= sk.kw[1];
483
484 let mut idx = 0usize;
485 while idx < 6 {
486 d2 ^= f(d1, sk.k[idx]);
487 d1 ^= f(d2, sk.k[idx + 1]);
488 idx += 2;
489 }
490 d1 = fl(d1, sk.ke[0]);
491 d2 = fl_inv(d2, sk.ke[1]);
492
493 while idx < 12 {
494 d2 ^= f(d1, sk.k[idx]);
495 d1 ^= f(d2, sk.k[idx + 1]);
496 idx += 2;
497 }
498 d1 = fl(d1, sk.ke[2]);
499 d2 = fl_inv(d2, sk.ke[3]);
500
501 while idx < 18 {
502 d2 ^= f(d1, sk.k[idx]);
503 d1 ^= f(d2, sk.k[idx + 1]);
504 idx += 2;
505 }
506 d1 = fl(d1, sk.ke[4]);
507 d2 = fl_inv(d2, sk.ke[5]);
508
509 while idx < 24 {
510 d2 ^= f(d1, sk.k[idx]);
511 d1 ^= f(d2, sk.k[idx + 1]);
512 idx += 2;
513 }
514
515 let mut out = [0u8; 16];
516 out[..8].copy_from_slice(&(d2 ^ sk.kw[2]).to_be_bytes());
517 out[8..].copy_from_slice(&(d1 ^ sk.kw[3]).to_be_bytes());
518 out
519}
520
521fn camellia_decrypt_24(block: [u8; 16], sk: &Subkeys24, use_ct: bool) -> [u8; 16] {
522 let mut d2 = u64::from_be_bytes(block[..8].try_into().unwrap()) ^ sk.kw[2];
523 let mut d1 = u64::from_be_bytes(block[8..].try_into().unwrap()) ^ sk.kw[3];
524 let f = if use_ct { camellia_f_ct } else { camellia_f };
525
526 let mut idx = 24usize;
527 while idx > 18 {
528 idx -= 2;
529 d1 ^= f(d2, sk.k[idx + 1]);
530 d2 ^= f(d1, sk.k[idx]);
531 }
532 d2 = fl(d2, sk.ke[5]);
533 d1 = fl_inv(d1, sk.ke[4]);
534
535 while idx > 12 {
536 idx -= 2;
537 d1 ^= f(d2, sk.k[idx + 1]);
538 d2 ^= f(d1, sk.k[idx]);
539 }
540 d2 = fl(d2, sk.ke[3]);
541 d1 = fl_inv(d1, sk.ke[2]);
542
543 while idx > 6 {
544 idx -= 2;
545 d1 ^= f(d2, sk.k[idx + 1]);
546 d2 ^= f(d1, sk.k[idx]);
547 }
548 d2 = fl(d2, sk.ke[1]);
549 d1 = fl_inv(d1, sk.ke[0]);
550
551 while idx > 0 {
552 idx -= 2;
553 d1 ^= f(d2, sk.k[idx + 1]);
554 d2 ^= f(d1, sk.k[idx]);
555 }
556
557 let mut out = [0u8; 16];
558 out[..8].copy_from_slice(&(d1 ^ sk.kw[0]).to_be_bytes());
559 out[8..].copy_from_slice(&(d2 ^ sk.kw[1]).to_be_bytes());
560 out
561}
562
563pub struct Camellia128 {
565 subkeys: Subkeys18,
566}
567
568impl Camellia128 {
569 #[must_use]
570 pub fn new(key: &[u8; 16]) -> Self {
571 Self {
572 subkeys: expand_128(key, false),
573 }
574 }
575
576 pub fn new_wiping(key: &mut [u8; 16]) -> Self {
577 let out = Self::new(key);
578 crate::ct::zeroize_slice(key.as_mut_slice());
579 out
580 }
581
582 #[must_use]
583 pub fn encrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
584 camellia_encrypt_18(*block, &self.subkeys, false)
585 }
586
587 #[must_use]
588 pub fn decrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
589 camellia_decrypt_18(*block, &self.subkeys, false)
590 }
591}
592
593pub struct Camellia128Ct {
595 subkeys: Subkeys18,
596}
597
598impl Camellia128Ct {
599 #[must_use]
600 pub fn new(key: &[u8; 16]) -> Self {
601 Self {
602 subkeys: expand_128(key, true),
603 }
604 }
605
606 pub fn new_wiping(key: &mut [u8; 16]) -> Self {
607 let out = Self::new(key);
608 crate::ct::zeroize_slice(key.as_mut_slice());
609 out
610 }
611
612 #[must_use]
613 pub fn encrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
614 camellia_encrypt_18(*block, &self.subkeys, true)
615 }
616
617 #[must_use]
618 pub fn decrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
619 camellia_decrypt_18(*block, &self.subkeys, true)
620 }
621}
622
623pub struct Camellia192 {
625 subkeys: Subkeys24,
626}
627
628impl Camellia192 {
629 #[must_use]
630 pub fn new(key: &[u8; 24]) -> Self {
631 let mut kl_bytes = [0u8; 16];
632 kl_bytes.copy_from_slice(&key[..16]);
633 let kl = u128::from_be_bytes(kl_bytes);
634 let mut tail_bytes = [0u8; 8];
635 tail_bytes.copy_from_slice(&key[16..]);
636 let tail = u64::from_be_bytes(tail_bytes);
637 let kr = (u128::from(tail) << 64) | u128::from(!tail);
638 Self {
639 subkeys: expand_192_256(kl, kr, false),
640 }
641 }
642
643 pub fn new_wiping(key: &mut [u8; 24]) -> Self {
644 let out = Self::new(key);
645 crate::ct::zeroize_slice(key.as_mut_slice());
646 out
647 }
648
649 #[must_use]
650 pub fn encrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
651 camellia_encrypt_24(*block, &self.subkeys, false)
652 }
653
654 #[must_use]
655 pub fn decrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
656 camellia_decrypt_24(*block, &self.subkeys, false)
657 }
658}
659
660pub struct Camellia192Ct {
662 subkeys: Subkeys24,
663}
664
665impl Camellia192Ct {
666 #[must_use]
667 pub fn new(key: &[u8; 24]) -> Self {
668 let mut kl_bytes = [0u8; 16];
669 kl_bytes.copy_from_slice(&key[..16]);
670 let kl = u128::from_be_bytes(kl_bytes);
671 let mut tail_bytes = [0u8; 8];
672 tail_bytes.copy_from_slice(&key[16..]);
673 let tail = u64::from_be_bytes(tail_bytes);
674 let kr = (u128::from(tail) << 64) | u128::from(!tail);
675 Self {
676 subkeys: expand_192_256(kl, kr, true),
677 }
678 }
679
680 pub fn new_wiping(key: &mut [u8; 24]) -> Self {
681 let out = Self::new(key);
682 crate::ct::zeroize_slice(key.as_mut_slice());
683 out
684 }
685
686 #[must_use]
687 pub fn encrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
688 camellia_encrypt_24(*block, &self.subkeys, true)
689 }
690
691 #[must_use]
692 pub fn decrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
693 camellia_decrypt_24(*block, &self.subkeys, true)
694 }
695}
696
697pub struct Camellia256 {
699 subkeys: Subkeys24,
700}
701
702impl Camellia256 {
703 #[must_use]
704 pub fn new(key: &[u8; 32]) -> Self {
705 let mut left_key_bytes = [0u8; 16];
706 left_key_bytes.copy_from_slice(&key[..16]);
707 let kl = u128::from_be_bytes(left_key_bytes);
708 let mut right_key_bytes = [0u8; 16];
709 right_key_bytes.copy_from_slice(&key[16..]);
710 let kr = u128::from_be_bytes(right_key_bytes);
711 Self {
712 subkeys: expand_192_256(kl, kr, false),
713 }
714 }
715
716 pub fn new_wiping(key: &mut [u8; 32]) -> Self {
717 let out = Self::new(key);
718 crate::ct::zeroize_slice(key.as_mut_slice());
719 out
720 }
721
722 #[must_use]
723 pub fn encrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
724 camellia_encrypt_24(*block, &self.subkeys, false)
725 }
726
727 #[must_use]
728 pub fn decrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
729 camellia_decrypt_24(*block, &self.subkeys, false)
730 }
731}
732
733pub struct Camellia256Ct {
735 subkeys: Subkeys24,
736}
737
738impl Camellia256Ct {
739 #[must_use]
740 pub fn new(key: &[u8; 32]) -> Self {
741 let mut left_key_bytes = [0u8; 16];
742 left_key_bytes.copy_from_slice(&key[..16]);
743 let kl = u128::from_be_bytes(left_key_bytes);
744 let mut right_key_bytes = [0u8; 16];
745 right_key_bytes.copy_from_slice(&key[16..]);
746 let kr = u128::from_be_bytes(right_key_bytes);
747 Self {
748 subkeys: expand_192_256(kl, kr, true),
749 }
750 }
751
752 pub fn new_wiping(key: &mut [u8; 32]) -> Self {
753 let out = Self::new(key);
754 crate::ct::zeroize_slice(key.as_mut_slice());
755 out
756 }
757
758 #[must_use]
759 pub fn encrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
760 camellia_encrypt_24(*block, &self.subkeys, true)
761 }
762
763 #[must_use]
764 pub fn decrypt_block(&self, block: &[u8; 16]) -> [u8; 16] {
765 camellia_decrypt_24(*block, &self.subkeys, true)
766 }
767}
768
769pub type Camellia = Camellia128;
771pub type CamelliaCt = Camellia128Ct;
773
774macro_rules! impl_block_cipher {
775 ($name:ty) => {
776 impl crate::BlockCipher for $name {
777 const BLOCK_LEN: usize = 16;
778 fn encrypt(&self, block: &mut [u8]) {
779 let arr: &[u8; 16] = (&*block).try_into().expect("wrong block length");
780 block.copy_from_slice(&self.encrypt_block(arr));
781 }
782 fn decrypt(&self, block: &mut [u8]) {
783 let arr: &[u8; 16] = (&*block).try_into().expect("wrong block length");
784 block.copy_from_slice(&self.decrypt_block(arr));
785 }
786 }
787 };
788}
789
790impl_block_cipher!(Camellia128);
791impl_block_cipher!(Camellia128Ct);
792impl_block_cipher!(Camellia192);
793impl_block_cipher!(Camellia192Ct);
794impl_block_cipher!(Camellia256);
795impl_block_cipher!(Camellia256Ct);
796
797impl Drop for Camellia128 {
798 fn drop(&mut self) {
799 crate::ct::zeroize_slice(self.subkeys.kw.as_mut_slice());
800 crate::ct::zeroize_slice(self.subkeys.k.as_mut_slice());
801 crate::ct::zeroize_slice(self.subkeys.ke.as_mut_slice());
802 }
803}
804
805impl Drop for Camellia128Ct {
806 fn drop(&mut self) {
807 crate::ct::zeroize_slice(self.subkeys.kw.as_mut_slice());
808 crate::ct::zeroize_slice(self.subkeys.k.as_mut_slice());
809 crate::ct::zeroize_slice(self.subkeys.ke.as_mut_slice());
810 }
811}
812
813impl Drop for Camellia192 {
814 fn drop(&mut self) {
815 crate::ct::zeroize_slice(self.subkeys.kw.as_mut_slice());
816 crate::ct::zeroize_slice(self.subkeys.k.as_mut_slice());
817 crate::ct::zeroize_slice(self.subkeys.ke.as_mut_slice());
818 }
819}
820
821impl Drop for Camellia192Ct {
822 fn drop(&mut self) {
823 crate::ct::zeroize_slice(self.subkeys.kw.as_mut_slice());
824 crate::ct::zeroize_slice(self.subkeys.k.as_mut_slice());
825 crate::ct::zeroize_slice(self.subkeys.ke.as_mut_slice());
826 }
827}
828
829impl Drop for Camellia256 {
830 fn drop(&mut self) {
831 crate::ct::zeroize_slice(self.subkeys.kw.as_mut_slice());
832 crate::ct::zeroize_slice(self.subkeys.k.as_mut_slice());
833 crate::ct::zeroize_slice(self.subkeys.ke.as_mut_slice());
834 }
835}
836
837impl Drop for Camellia256Ct {
838 fn drop(&mut self) {
839 crate::ct::zeroize_slice(self.subkeys.kw.as_mut_slice());
840 crate::ct::zeroize_slice(self.subkeys.k.as_mut_slice());
841 crate::ct::zeroize_slice(self.subkeys.ke.as_mut_slice());
842 }
843}
844
845#[cfg(test)]
846mod tests {
847 use super::*;
848
849 fn xorshift64(state: &mut u64) -> u64 {
850 let mut x = *state;
851 x ^= x << 13;
852 x ^= x >> 7;
853 x ^= x << 17;
854 *state = x;
855 x
856 }
857
858 fn fill_bytes(state: &mut u64, out: &mut [u8]) {
859 for chunk in out.chunks_mut(8) {
860 let bytes = xorshift64(state).to_le_bytes();
861 let n = chunk.len();
862 chunk.copy_from_slice(&bytes[..n]);
863 }
864 }
865
866 fn h16(s: &str) -> [u8; 16] {
867 let b: Vec<u8> = (0..s.len())
868 .step_by(2)
869 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
870 .collect();
871 b.try_into().unwrap()
872 }
873
874 fn h24(s: &str) -> [u8; 24] {
875 let b: Vec<u8> = (0..s.len())
876 .step_by(2)
877 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
878 .collect();
879 b.try_into().unwrap()
880 }
881
882 fn h32(s: &str) -> [u8; 32] {
883 let b: Vec<u8> = (0..s.len())
884 .step_by(2)
885 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
886 .collect();
887 b.try_into().unwrap()
888 }
889
890 #[test]
891 fn ct_sbox_matches_table() {
892 for x in 0u8..=255 {
893 assert_eq!(sbox1_ct(x), sbox1(x));
894 }
895 }
896
897 #[test]
898 fn camellia_fast_and_ct_match_random_vectors() {
899 let mut seed = 0x9e37_79b9_7f4a_7c15u64;
900 for _ in 0..128 {
901 let mut block = [0u8; 16];
902 fill_bytes(&mut seed, &mut block);
903
904 let mut k128 = [0u8; 16];
905 fill_bytes(&mut seed, &mut k128);
906 let fast128 = Camellia128::new(&k128);
907 let ct128 = Camellia128Ct::new(&k128);
908 let c128 = fast128.encrypt_block(&block);
909 assert_eq!(c128, ct128.encrypt_block(&block));
910 assert_eq!(block, fast128.decrypt_block(&c128));
911 assert_eq!(block, ct128.decrypt_block(&c128));
912
913 let mut k192 = [0u8; 24];
914 fill_bytes(&mut seed, &mut k192);
915 let fast192 = Camellia192::new(&k192);
916 let ct192 = Camellia192Ct::new(&k192);
917 let c192 = fast192.encrypt_block(&block);
918 assert_eq!(c192, ct192.encrypt_block(&block));
919 assert_eq!(block, fast192.decrypt_block(&c192));
920 assert_eq!(block, ct192.decrypt_block(&c192));
921
922 let mut k256 = [0u8; 32];
923 fill_bytes(&mut seed, &mut k256);
924 let fast256 = Camellia256::new(&k256);
925 let ct256 = Camellia256Ct::new(&k256);
926 let c256 = fast256.encrypt_block(&block);
927 assert_eq!(c256, ct256.encrypt_block(&block));
928 assert_eq!(block, fast256.decrypt_block(&c256));
929 assert_eq!(block, ct256.decrypt_block(&c256));
930 }
931 }
932
933 #[test]
934 fn camellia128_kat() {
935 let key = h16("0123456789abcdeffedcba9876543210");
936 let pt = h16("0123456789abcdeffedcba9876543210");
937 let ct = h16("67673138549669730857065648eabe43");
938 let cipher = Camellia128::new(&key);
939 assert_eq!(cipher.encrypt_block(&pt), ct);
940 assert_eq!(cipher.decrypt_block(&ct), pt);
941 }
942
943 #[test]
944 fn camellia128_ct_kat() {
945 let key = h16("0123456789abcdeffedcba9876543210");
946 let pt = h16("0123456789abcdeffedcba9876543210");
947 let ct = h16("67673138549669730857065648eabe43");
948 let cipher = Camellia128Ct::new(&key);
949 assert_eq!(cipher.encrypt_block(&pt), ct);
950 assert_eq!(cipher.decrypt_block(&ct), pt);
951 }
952
953 #[test]
954 fn camellia192_kat() {
955 let key = h24("0123456789abcdeffedcba98765432100011223344556677");
956 let pt = h16("0123456789abcdeffedcba9876543210");
957 let ct = h16("b4993401b3e996f84ee5cee7d79b09b9");
958 let cipher = Camellia192::new(&key);
959 assert_eq!(cipher.encrypt_block(&pt), ct);
960 assert_eq!(cipher.decrypt_block(&ct), pt);
961 }
962
963 #[test]
964 fn camellia192_ct_kat() {
965 let key = h24("0123456789abcdeffedcba98765432100011223344556677");
966 let pt = h16("0123456789abcdeffedcba9876543210");
967 let ct = h16("b4993401b3e996f84ee5cee7d79b09b9");
968 let cipher = Camellia192Ct::new(&key);
969 assert_eq!(cipher.encrypt_block(&pt), ct);
970 assert_eq!(cipher.decrypt_block(&ct), pt);
971 }
972
973 #[test]
974 fn camellia256_kat() {
975 let key = h32("0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff");
976 let pt = h16("0123456789abcdeffedcba9876543210");
977 let ct = h16("9acc237dff16d76c20ef7c919e3a7509");
978 let cipher = Camellia256::new(&key);
979 assert_eq!(cipher.encrypt_block(&pt), ct);
980 assert_eq!(cipher.decrypt_block(&ct), pt);
981 }
982
983 #[test]
984 fn camellia256_ct_kat() {
985 let key = h32("0123456789abcdeffedcba987654321000112233445566778899aabbccddeeff");
986 let pt = h16("0123456789abcdeffedcba9876543210");
987 let ct = h16("9acc237dff16d76c20ef7c919e3a7509");
988 let cipher = Camellia256Ct::new(&key);
989 assert_eq!(cipher.encrypt_block(&pt), ct);
990 assert_eq!(cipher.decrypt_block(&ct), pt);
991 }
992
993 #[test]
994 fn camellia128_matches_openssl_ecb() {
995 let key_hex = "0123456789abcdeffedcba9876543210";
996 let pt_hex = "0123456789abcdeffedcba9876543210";
997 let Some(expected) =
998 crate::test_utils::run_openssl_enc("-camellia-128-ecb", key_hex, None, &h16(pt_hex))
999 else {
1000 return;
1001 };
1002
1003 let cipher = Camellia128::new(&h16(key_hex));
1004 assert_eq!(
1005 cipher.encrypt_block(&h16(pt_hex)).as_slice(),
1006 expected.as_slice()
1007 );
1008 }
1009}