1const SBOX: [u8; 16] = [
22 0xC, 0x5, 0x6, 0xB, 0x9, 0x0, 0xA, 0xD, 0x3, 0xE, 0xF, 0x8, 0x4, 0x7, 0x1, 0x2,
23];
24const INV_SBOX: [u8; 16] = [
25 0x5, 0xE, 0xF, 0x8, 0xC, 0x1, 0x2, 0xD, 0xB, 0x4, 0x6, 0x3, 0x0, 0x7, 0x9, 0xA,
26];
27
28const SBOX_ANF: [u16; 4] = crate::ct::build_nibble_sbox_anf(&SBOX);
29const INV_SBOX_ANF: [u16; 4] = crate::ct::build_nibble_sbox_anf(&INV_SBOX);
30
31#[inline]
32fn sbox_ct_nibble(input: u8) -> u8 {
33 crate::ct::eval_nibble_sbox(SBOX_ANF, input)
34}
35
36#[inline]
37fn inv_sbox_ct_nibble(input: u8) -> u8 {
38 crate::ct::eval_nibble_sbox(INV_SBOX_ANF, input)
39}
40
41#[inline]
42fn sbox_layer(state: u64) -> u64 {
43 let mut out = 0u64;
44 let mut i = 0usize;
45 while i < 16 {
46 let nibble = ((state >> (4 * i)) & 0x0f) as usize;
47 out |= u64::from(SBOX[nibble]) << (4 * i);
48 i += 1;
49 }
50 out
51}
52
53#[inline]
54fn inv_sbox_layer(state: u64) -> u64 {
55 let mut out = 0u64;
56 let mut i = 0usize;
57 while i < 16 {
58 let nibble = ((state >> (4 * i)) & 0x0f) as usize;
59 out |= u64::from(INV_SBOX[nibble]) << (4 * i);
60 i += 1;
61 }
62 out
63}
64
65#[inline]
66fn sbox_layer_ct(state: u64) -> u64 {
67 let mut out = 0u64;
68 let mut i = 0usize;
69 while i < 16 {
70 let nibble = ((state >> (4 * i)) & 0x0f) as u8;
71 out |= u64::from(sbox_ct_nibble(nibble)) << (4 * i);
72 i += 1;
73 }
74 out
75}
76
77#[inline]
78fn inv_sbox_layer_ct(state: u64) -> u64 {
79 let mut out = 0u64;
80 let mut i = 0usize;
81 while i < 16 {
82 let nibble = ((state >> (4 * i)) & 0x0f) as u8;
83 out |= u64::from(inv_sbox_ct_nibble(nibble)) << (4 * i);
84 i += 1;
85 }
86 out
87}
88
89#[inline]
102fn p_layer(state: u64) -> u64 {
103 let mut out = 0u64;
107 let mut bit = 0usize;
108 while bit < 63 {
109 let dst = (16 * bit) % 63;
110 out |= ((state >> bit) & 1) << dst;
111 bit += 1;
112 }
113 out |= ((state >> 63) & 1) << 63;
114 out
115}
116
117#[inline]
124fn inv_p_layer(state: u64) -> u64 {
125 let mut out = 0u64;
126 let mut bit = 0usize;
127 while bit < 63 {
128 let src = (16 * bit) % 63;
129 out |= ((state >> src) & 1) << bit;
130 bit += 1;
131 }
132 out |= ((state >> 63) & 1) << 63;
133 out
134}
135
136fn present_encrypt(state: u64, round_keys: &[u64; 32]) -> u64 {
137 let mut s = state;
138 let mut round = 0usize;
139 while round < 31 {
140 s ^= round_keys[round];
141 s = sbox_layer(s);
142 s = p_layer(s);
143 round += 1;
144 }
145 s ^ round_keys[31]
146}
147
148fn present_encrypt_ct(state: u64, round_keys: &[u64; 32]) -> u64 {
149 let mut s = state;
150 let mut round = 0usize;
151 while round < 31 {
152 s ^= round_keys[round];
153 s = sbox_layer_ct(s);
154 s = p_layer(s);
155 round += 1;
156 }
157 s ^ round_keys[31]
158}
159
160fn present_decrypt(state: u64, round_keys: &[u64; 32]) -> u64 {
161 let mut s = state ^ round_keys[31];
162 let mut round = 31usize;
163 while round > 0 {
164 round -= 1;
165 s = inv_p_layer(s);
166 s = inv_sbox_layer(s);
167 s ^= round_keys[round];
168 }
169 s
170}
171
172fn present_decrypt_ct(state: u64, round_keys: &[u64; 32]) -> u64 {
173 let mut s = state ^ round_keys[31];
174 let mut round = 31usize;
175 while round > 0 {
176 round -= 1;
177 s = inv_p_layer(s);
178 s = inv_sbox_layer_ct(s);
179 s ^= round_keys[round];
180 }
181 s
182}
183
184fn expand_round_keys_80(key: &[u8; 10]) -> [u64; 32] {
185 let mut reg = 0u128;
186 for &b in key {
187 reg = (reg << 8) | u128::from(b);
188 }
189
190 let mask80 = (1u128 << 80) - 1;
191 let mut out = [0u64; 32];
192
193 for round in 1..=32u8 {
194 out[(round - 1) as usize] = ((reg >> 16) & 0xffff_ffff_ffff_ffff) as u64;
195 if round == 32 {
196 break;
197 }
198
199 reg = ((reg << 61) | (reg >> 19)) & mask80;
200 let top = ((reg >> 76) & 0x0f) as usize;
201 reg &= !(0x0fu128 << 76);
202 reg |= u128::from(SBOX[top]) << 76;
203 reg ^= u128::from(round) << 15;
204 }
205
206 out
207}
208
209fn expand_round_keys_128(key: &[u8; 16]) -> [u64; 32] {
210 let mut reg = u128::from_be_bytes(*key);
211 let mut out = [0u64; 32];
212
213 for round in 1..=32u8 {
214 out[(round - 1) as usize] = (reg >> 64) as u64;
215 if round == 32 {
216 break;
217 }
218
219 reg = reg.rotate_left(61);
220
221 let top = ((reg >> 124) & 0x0f) as usize;
222 reg &= !(0x0fu128 << 124);
223 reg |= u128::from(SBOX[top]) << 124;
224
225 let next = ((reg >> 120) & 0x0f) as usize;
226 reg &= !(0x0fu128 << 120);
227 reg |= u128::from(SBOX[next]) << 120;
228
229 reg ^= u128::from(round) << 62;
230 }
231
232 out
233}
234
235pub struct Present80 {
237 round_keys: [u64; 32],
238}
239
240impl Present80 {
241 #[must_use]
242 pub fn new(key: &[u8; 10]) -> Self {
243 Self {
244 round_keys: expand_round_keys_80(key),
245 }
246 }
247
248 pub fn new_wiping(key: &mut [u8; 10]) -> Self {
249 let out = Self::new(key);
250 crate::ct::zeroize_slice(key.as_mut_slice());
251 out
252 }
253
254 #[must_use]
255 pub fn encrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
256 present_encrypt(u64::from_be_bytes(*block), &self.round_keys).to_be_bytes()
257 }
258
259 #[must_use]
260 pub fn decrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
261 present_decrypt(u64::from_be_bytes(*block), &self.round_keys).to_be_bytes()
262 }
263}
264
265pub struct Present80Ct {
267 round_keys: [u64; 32],
268}
269
270impl Present80Ct {
271 #[must_use]
272 pub fn new(key: &[u8; 10]) -> Self {
273 Self {
274 round_keys: expand_round_keys_80(key),
275 }
276 }
277
278 pub fn new_wiping(key: &mut [u8; 10]) -> Self {
279 let out = Self::new(key);
280 crate::ct::zeroize_slice(key.as_mut_slice());
281 out
282 }
283
284 #[must_use]
285 pub fn encrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
286 present_encrypt_ct(u64::from_be_bytes(*block), &self.round_keys).to_be_bytes()
287 }
288
289 #[must_use]
290 pub fn decrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
291 present_decrypt_ct(u64::from_be_bytes(*block), &self.round_keys).to_be_bytes()
292 }
293}
294
295pub struct Present128 {
297 round_keys: [u64; 32],
298}
299
300impl Present128 {
301 #[must_use]
302 pub fn new(key: &[u8; 16]) -> Self {
303 Self {
304 round_keys: expand_round_keys_128(key),
305 }
306 }
307
308 pub fn new_wiping(key: &mut [u8; 16]) -> Self {
309 let out = Self::new(key);
310 crate::ct::zeroize_slice(key.as_mut_slice());
311 out
312 }
313
314 #[must_use]
315 pub fn encrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
316 present_encrypt(u64::from_be_bytes(*block), &self.round_keys).to_be_bytes()
317 }
318
319 #[must_use]
320 pub fn decrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
321 present_decrypt(u64::from_be_bytes(*block), &self.round_keys).to_be_bytes()
322 }
323}
324
325pub struct Present128Ct {
327 round_keys: [u64; 32],
328}
329
330impl Present128Ct {
331 #[must_use]
332 pub fn new(key: &[u8; 16]) -> Self {
333 Self {
334 round_keys: expand_round_keys_128(key),
335 }
336 }
337
338 pub fn new_wiping(key: &mut [u8; 16]) -> Self {
339 let out = Self::new(key);
340 crate::ct::zeroize_slice(key.as_mut_slice());
341 out
342 }
343
344 #[must_use]
345 pub fn encrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
346 present_encrypt_ct(u64::from_be_bytes(*block), &self.round_keys).to_be_bytes()
347 }
348
349 #[must_use]
350 pub fn decrypt_block(&self, block: &[u8; 8]) -> [u8; 8] {
351 present_decrypt_ct(u64::from_be_bytes(*block), &self.round_keys).to_be_bytes()
352 }
353}
354
355pub type Present = Present80;
357pub type PresentCt = Present80Ct;
359
360macro_rules! impl_block_cipher {
361 ($name:ty) => {
362 impl crate::BlockCipher for $name {
363 const BLOCK_LEN: usize = 8;
364 fn encrypt(&self, block: &mut [u8]) {
365 let arr: &[u8; 8] = (&*block).try_into().expect("wrong block length");
366 block.copy_from_slice(&self.encrypt_block(arr));
367 }
368 fn decrypt(&self, block: &mut [u8]) {
369 let arr: &[u8; 8] = (&*block).try_into().expect("wrong block length");
370 block.copy_from_slice(&self.decrypt_block(arr));
371 }
372 }
373 };
374}
375
376impl_block_cipher!(Present80);
377impl_block_cipher!(Present80Ct);
378impl_block_cipher!(Present128);
379impl_block_cipher!(Present128Ct);
380
381macro_rules! impl_drop_zeroize {
382 ($name:ty) => {
383 impl Drop for $name {
384 fn drop(&mut self) {
385 crate::ct::zeroize_slice(self.round_keys.as_mut_slice());
386 }
387 }
388 };
389}
390
391impl_drop_zeroize!(Present80);
392impl_drop_zeroize!(Present80Ct);
393impl_drop_zeroize!(Present128);
394impl_drop_zeroize!(Present128Ct);
395
396#[cfg(test)]
397mod tests {
398 use super::*;
399
400 fn h8(s: &str) -> [u8; 8] {
401 let b: Vec<u8> = (0..s.len())
402 .step_by(2)
403 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
404 .collect();
405 b.try_into().unwrap()
406 }
407
408 fn h10(s: &str) -> [u8; 10] {
409 let b: Vec<u8> = (0..s.len())
410 .step_by(2)
411 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
412 .collect();
413 b.try_into().unwrap()
414 }
415
416 fn h16(s: &str) -> [u8; 16] {
417 let b: Vec<u8> = (0..s.len())
418 .step_by(2)
419 .map(|i| u8::from_str_radix(&s[i..i + 2], 16).unwrap())
420 .collect();
421 b.try_into().unwrap()
422 }
423
424 #[test]
425 fn ct_sbox_matches_tables() {
426 for x in 0u8..16 {
427 assert_eq!(sbox_ct_nibble(x), SBOX[x as usize]);
428 assert_eq!(inv_sbox_ct_nibble(x), INV_SBOX[x as usize]);
429 }
430 }
431
432 #[test]
433 fn present80_kats() {
434 let cases = [
436 (
437 h10("00000000000000000000"),
438 h8("0000000000000000"),
439 h8("5579c1387b228445"),
440 ),
441 (
442 h10("ffffffffffffffffffff"),
443 h8("0000000000000000"),
444 h8("e72c46c0f5945049"),
445 ),
446 (
447 h10("00000000000000000000"),
448 h8("ffffffffffffffff"),
449 h8("a112ffc72f68417b"),
450 ),
451 (
452 h10("ffffffffffffffffffff"),
453 h8("ffffffffffffffff"),
454 h8("3333dcd3213210d2"),
455 ),
456 ];
457
458 for (key, pt, ct) in cases {
459 let cipher = Present80::new(&key);
460 assert_eq!(cipher.encrypt_block(&pt), ct);
461 assert_eq!(cipher.decrypt_block(&ct), pt);
462 }
463 }
464
465 #[test]
466 fn present80_ct_kats() {
467 let cases = [
468 (
469 h10("00000000000000000000"),
470 h8("0000000000000000"),
471 h8("5579c1387b228445"),
472 ),
473 (
474 h10("ffffffffffffffffffff"),
475 h8("0000000000000000"),
476 h8("e72c46c0f5945049"),
477 ),
478 (
479 h10("00000000000000000000"),
480 h8("ffffffffffffffff"),
481 h8("a112ffc72f68417b"),
482 ),
483 (
484 h10("ffffffffffffffffffff"),
485 h8("ffffffffffffffff"),
486 h8("3333dcd3213210d2"),
487 ),
488 ];
489
490 for (key, pt, ct) in cases {
491 let cipher = Present80Ct::new(&key);
492 assert_eq!(cipher.encrypt_block(&pt), ct);
493 assert_eq!(cipher.decrypt_block(&ct), pt);
494 }
495 }
496
497 #[test]
498 fn present128_kats() {
499 let cases = [
501 (
502 h16("00000000000000000000000000000000"),
503 h8("0000000000000000"),
504 h8("96db702a2e6900af"),
505 ),
506 (
507 h16("ffffffffffffffffffffffffffffffff"),
508 h8("0000000000000000"),
509 h8("13238c710272a5d8"),
510 ),
511 (
512 h16("00000000000000000000000000000000"),
513 h8("ffffffffffffffff"),
514 h8("3c6019e5e5edd563"),
515 ),
516 (
517 h16("ffffffffffffffffffffffffffffffff"),
518 h8("ffffffffffffffff"),
519 h8("628d9fbd4218e5b4"),
520 ),
521 ];
522
523 for (key, pt, ct) in cases {
524 let cipher = Present128::new(&key);
525 assert_eq!(cipher.encrypt_block(&pt), ct);
526 assert_eq!(cipher.decrypt_block(&ct), pt);
527 }
528 }
529
530 #[test]
531 fn present128_ct_kats() {
532 let cases = [
533 (
534 h16("00000000000000000000000000000000"),
535 h8("0000000000000000"),
536 h8("96db702a2e6900af"),
537 ),
538 (
539 h16("ffffffffffffffffffffffffffffffff"),
540 h8("0000000000000000"),
541 h8("13238c710272a5d8"),
542 ),
543 (
544 h16("00000000000000000000000000000000"),
545 h8("ffffffffffffffff"),
546 h8("3c6019e5e5edd563"),
547 ),
548 (
549 h16("ffffffffffffffffffffffffffffffff"),
550 h8("ffffffffffffffff"),
551 h8("628d9fbd4218e5b4"),
552 ),
553 ];
554
555 for (key, pt, ct) in cases {
556 let cipher = Present128Ct::new(&key);
557 assert_eq!(cipher.encrypt_block(&pt), ct);
558 assert_eq!(cipher.decrypt_block(&ct), pt);
559 }
560 }
561}