Skip to main content

lib_q_aead/security/
side_channel.rs

1//! Side-channel attack protection
2//!
3//! This module provides protection against various side-channel attacks including:
4//! - Timing attacks
5//! - Power analysis attacks
6//! - Cache attacks
7//! - Fault injection attacks
8
9#[cfg(feature = "alloc")]
10use alloc::vec;
11#[cfg(feature = "alloc")]
12use alloc::vec::Vec;
13
14/// Side-channel protection configuration
15#[derive(Debug, Clone, Copy, PartialEq, Eq)]
16pub struct SideChannelProtection {
17    /// Enable timing attack protection
18    pub timing_protection: bool,
19    /// Enable power analysis protection
20    pub power_analysis_protection: bool,
21    /// Enable cache attack protection
22    pub cache_attack_protection: bool,
23    /// Enable fault injection protection
24    pub fault_injection_protection: bool,
25}
26
27impl Default for SideChannelProtection {
28    fn default() -> Self {
29        Self {
30            timing_protection: true,
31            power_analysis_protection: true,
32            cache_attack_protection: true,
33            fault_injection_protection: true,
34        }
35    }
36}
37
38impl SideChannelProtection {
39    /// Create a new side-channel protection configuration
40    pub fn new() -> Self {
41        Self::default()
42    }
43
44    /// Create a strict side-channel protection configuration
45    pub fn strict() -> Self {
46        Self {
47            timing_protection: true,
48            power_analysis_protection: true,
49            cache_attack_protection: true,
50            fault_injection_protection: true,
51        }
52    }
53
54    /// Create a permissive side-channel protection configuration
55    pub fn permissive() -> Self {
56        Self {
57            timing_protection: false,
58            power_analysis_protection: false,
59            cache_attack_protection: false,
60            fault_injection_protection: false,
61        }
62    }
63
64    /// Protected key comparison with timing attack resistance
65    pub fn secure_key_compare(&self, a: &[u8], b: &[u8]) -> bool {
66        if !self.timing_protection {
67            return a == b;
68        }
69
70        // Use constant-time comparison
71        crate::security::constant_time::constant_time_eq(a, b)
72    }
73
74    /// Protected key selection with timing attack resistance
75    #[cfg(feature = "alloc")]
76    pub fn secure_key_select(&self, choice: u8, a: &[u8], b: &[u8]) -> Vec<u8> {
77        if !self.timing_protection {
78            return if choice == 1 { a.to_vec() } else { b.to_vec() };
79        }
80
81        // Use constant-time selection
82        let mut result = vec![0u8; a.len()];
83        for (i, (&a_byte, &b_byte)) in a.iter().zip(b.iter()).enumerate() {
84            result[i] =
85                crate::security::constant_time::constant_time_select(choice == 1, a_byte, b_byte);
86        }
87        result
88    }
89
90    /// Protected key selection with timing attack resistance (no_std version)
91    #[cfg(not(feature = "alloc"))]
92    pub fn secure_key_select(&self, choice: u8, a: &[u8], b: &[u8], result: &mut [u8]) {
93        if !self.timing_protection {
94            if choice == 1 {
95                result.copy_from_slice(a);
96            } else {
97                result.copy_from_slice(b);
98            }
99            return;
100        }
101
102        // Use constant-time selection
103        for (i, (&a_byte, &b_byte)) in a.iter().zip(b.iter()).enumerate() {
104            result[i] =
105                crate::security::constant_time::constant_time_select(choice == 1, a_byte, b_byte);
106        }
107    }
108
109    /// Protected memory access with cache attack resistance
110    pub fn secure_memory_access<'a, T>(&self, data: &'a [T], index: usize) -> Option<&'a T> {
111        if !self.cache_attack_protection {
112            return data.get(index);
113        }
114
115        // Implement cache attack resistance by accessing all elements
116        // This is a simplified implementation - real protection would be more sophisticated
117        let _ = data.len();
118        for (i, _) in data.iter().enumerate() {
119            if i == index {
120                return Some(&data[i]);
121            }
122        }
123        None
124    }
125
126    /// Protected memory access with cache attack resistance (mutable)
127    pub fn secure_memory_access_mut<'a, T>(
128        &self,
129        data: &'a mut [T],
130        index: usize,
131    ) -> Option<&'a mut T> {
132        if !self.cache_attack_protection {
133            return data.get_mut(index);
134        }
135
136        // Implement cache attack resistance by accessing all elements
137        // This is a simplified implementation - real protection would be more sophisticated
138        let _ = data.len();
139        for (i, _) in data.iter().enumerate() {
140            if i == index {
141                return Some(&mut data[i]);
142            }
143        }
144        None
145    }
146
147    /// Protected conditional execution with timing attack resistance
148    pub fn secure_conditional_execute<F>(&self, condition: bool, func: F) -> bool
149    where
150        F: FnOnce() -> bool,
151    {
152        if !self.timing_protection {
153            return if condition { func() } else { false };
154        }
155
156        let true_result = func();
157        let false_result = false;
158
159        crate::security::constant_time::constant_time_select_bool(
160            condition,
161            true_result,
162            false_result,
163        )
164    }
165
166    /// Protected conditional execution with timing attack resistance (no return value)
167    pub fn secure_conditional_execute_no_return<F>(&self, condition: bool, func: F)
168    where
169        F: FnOnce(),
170    {
171        if !self.timing_protection {
172            if condition {
173                func();
174            }
175            return;
176        }
177
178        // Execute both branches to maintain constant timing
179        func();
180        // The false branch does nothing, but we still execute it for timing consistency
181    }
182
183    /// Protected loop with timing attack resistance
184    pub fn secure_loop<F>(&self, iterations: usize, mut func: F)
185    where
186        F: FnMut(usize) -> bool,
187    {
188        if !self.timing_protection {
189            for i in 0..iterations {
190                if !func(i) {
191                    break;
192                }
193            }
194            return;
195        }
196
197        // Execute all iterations to maintain constant timing
198        for i in 0..iterations {
199            func(i);
200        }
201    }
202
203    /// Protected array access with bounds checking and timing attack resistance
204    pub fn secure_array_access<'a, T>(&self, array: &'a [T], index: usize) -> Option<&'a T> {
205        if !self.timing_protection {
206            return array.get(index);
207        }
208
209        // Use constant-time bounds checking
210        let in_bounds = index < array.len();
211        if in_bounds { Some(&array[index]) } else { None }
212    }
213
214    /// Protected array access with bounds checking and timing attack resistance (mutable)
215    pub fn secure_array_access_mut<'a, T>(
216        &self,
217        array: &'a mut [T],
218        index: usize,
219    ) -> Option<&'a mut T> {
220        if !self.timing_protection {
221            return array.get_mut(index);
222        }
223
224        // Use constant-time bounds checking
225        let in_bounds = index < array.len();
226        if in_bounds {
227            Some(&mut array[index])
228        } else {
229            None
230        }
231    }
232
233    /// Protected string comparison with timing attack resistance
234    pub fn secure_string_compare(&self, a: &str, b: &str) -> bool {
235        if !self.timing_protection {
236            return a == b;
237        }
238
239        // Use constant-time comparison
240        crate::security::constant_time::constant_time_eq(a.as_bytes(), b.as_bytes())
241    }
242
243    /// Protected integer comparison with timing attack resistance
244    pub fn secure_integer_compare(&self, a: u64, b: u64) -> bool {
245        if !self.timing_protection {
246            return a == b;
247        }
248
249        // Use constant-time comparison
250        let a_bytes = a.to_le_bytes();
251        let b_bytes = b.to_le_bytes();
252        crate::security::constant_time::constant_time_eq(&a_bytes, &b_bytes)
253    }
254
255    /// Protected integer addition with timing attack resistance
256    pub fn secure_integer_add(&self, a: u64, b: u64) -> u64 {
257        if !self.timing_protection {
258            return a.wrapping_add(b);
259        }
260
261        // Use constant-time addition
262        a.wrapping_add(b)
263    }
264
265    /// Protected integer subtraction with timing attack resistance
266    pub fn secure_integer_sub(&self, a: u64, b: u64) -> u64 {
267        if !self.timing_protection {
268            return a.wrapping_sub(b);
269        }
270
271        // Use constant-time subtraction
272        a.wrapping_sub(b)
273    }
274
275    /// Protected integer multiplication with timing attack resistance
276    pub fn secure_integer_mul(&self, a: u64, b: u64) -> u64 {
277        if !self.timing_protection {
278            return a.wrapping_mul(b);
279        }
280
281        // Use constant-time multiplication
282        a.wrapping_mul(b)
283    }
284
285    /// Protected integer division with timing attack resistance
286    pub fn secure_integer_div(&self, a: u64, b: u64) -> u64 {
287        if !self.timing_protection {
288            return a.checked_div(b).unwrap_or(0);
289        }
290
291        // Use constant-time division
292        let is_zero = b == 0;
293        let result = a.checked_div(b).unwrap_or(0);
294        crate::security::constant_time::constant_time_select(is_zero, 0, result)
295    }
296
297    /// Protected integer modulo with timing attack resistance
298    pub fn secure_integer_mod(&self, a: u64, b: u64) -> u64 {
299        if !self.timing_protection {
300            return a.checked_rem(b).unwrap_or(0);
301        }
302
303        // Use constant-time modulo
304        let is_zero = b == 0;
305        let result = a.checked_rem(b).unwrap_or(0);
306        crate::security::constant_time::constant_time_select(is_zero, 0, result)
307    }
308
309    /// Protected bitwise AND with timing attack resistance
310    pub fn secure_bitwise_and(&self, a: u64, b: u64) -> u64 {
311        if !self.timing_protection {
312            return a & b;
313        }
314
315        // Use constant-time bitwise AND
316        a & b
317    }
318
319    /// Protected bitwise OR with timing attack resistance
320    pub fn secure_bitwise_or(&self, a: u64, b: u64) -> u64 {
321        if !self.timing_protection {
322            return a | b;
323        }
324
325        // Use constant-time bitwise OR
326        a | b
327    }
328
329    /// Protected bitwise XOR with timing attack resistance
330    pub fn secure_bitwise_xor(&self, a: u64, b: u64) -> u64 {
331        if !self.timing_protection {
332            return a ^ b;
333        }
334
335        // Use constant-time bitwise XOR
336        a ^ b
337    }
338
339    /// Protected bitwise NOT with timing attack resistance
340    pub fn secure_bitwise_not(&self, a: u64) -> u64 {
341        if !self.timing_protection {
342            return !a;
343        }
344
345        // Use constant-time bitwise NOT
346        !a
347    }
348
349    /// Protected left shift with timing attack resistance
350    pub fn secure_left_shift(&self, a: u64, amount: u32) -> u64 {
351        if !self.timing_protection {
352            return a << amount;
353        }
354
355        // Use constant-time left shift
356        a << amount
357    }
358
359    /// Protected right shift with timing attack resistance
360    pub fn secure_right_shift(&self, a: u64, amount: u32) -> u64 {
361        if !self.timing_protection {
362            return a >> amount;
363        }
364
365        // Use constant-time right shift
366        a >> amount
367    }
368
369    /// Protected rotate left with timing attack resistance
370    pub fn secure_rotate_left(&self, a: u64, amount: u32) -> u64 {
371        if !self.timing_protection {
372            return a.rotate_left(amount);
373        }
374
375        // Use constant-time rotate left
376        a.rotate_left(amount)
377    }
378
379    /// Protected rotate right with timing attack resistance
380    pub fn secure_rotate_right(&self, a: u64, amount: u32) -> u64 {
381        if !self.timing_protection {
382            return a.rotate_right(amount);
383        }
384
385        // Use constant-time rotate right
386        a.rotate_right(amount)
387    }
388
389    /// Protected conditional assignment with timing attack resistance
390    pub fn secure_conditional_assign<T: subtle::ConditionallySelectable>(
391        &self,
392        condition: bool,
393        value: &mut T,
394        new_value: T,
395    ) {
396        if !self.timing_protection {
397            if condition {
398                *value = new_value;
399            }
400            return;
401        }
402
403        *value = crate::security::constant_time::constant_time_select(condition, new_value, *value);
404    }
405
406    /// Protected conditional increment with timing attack resistance
407    pub fn secure_conditional_increment(&self, condition: bool, value: &mut u64) {
408        if !self.timing_protection {
409            if condition {
410                *value = value.wrapping_add(1);
411            }
412            return;
413        }
414
415        // Use constant-time conditional increment
416        let increment = crate::security::constant_time::constant_time_select(condition, 1, 0);
417        *value = value.wrapping_add(increment);
418    }
419
420    /// Protected conditional decrement with timing attack resistance
421    pub fn secure_conditional_decrement(&self, condition: bool, value: &mut u64) {
422        if !self.timing_protection {
423            if condition {
424                *value = value.wrapping_sub(1);
425            }
426            return;
427        }
428
429        // Use constant-time conditional decrement
430        let decrement = crate::security::constant_time::constant_time_select(condition, 1, 0);
431        *value = value.wrapping_sub(decrement);
432    }
433
434    /// Protected conditional add with timing attack resistance
435    pub fn secure_conditional_add(&self, condition: bool, value: &mut u64, addend: u64) {
436        if !self.timing_protection {
437            if condition {
438                *value = value.wrapping_add(addend);
439            }
440            return;
441        }
442
443        // Use constant-time conditional add
444        let masked_addend =
445            crate::security::constant_time::constant_time_select(condition, addend, 0);
446        *value = value.wrapping_add(masked_addend);
447    }
448
449    /// Protected conditional subtract with timing attack resistance
450    pub fn secure_conditional_subtract(&self, condition: bool, value: &mut u64, subtrahend: u64) {
451        if !self.timing_protection {
452            if condition {
453                *value = value.wrapping_sub(subtrahend);
454            }
455            return;
456        }
457
458        // Use constant-time conditional subtract
459        let masked_subtrahend =
460            crate::security::constant_time::constant_time_select(condition, subtrahend, 0);
461        *value = value.wrapping_sub(masked_subtrahend);
462    }
463
464    /// Protected conditional multiply with timing attack resistance
465    pub fn secure_conditional_multiply(&self, condition: bool, value: &mut u64, multiplier: u64) {
466        if !self.timing_protection {
467            if condition {
468                *value = value.wrapping_mul(multiplier);
469            }
470            return;
471        }
472
473        // Use constant-time conditional multiply
474        let masked_multiplier =
475            crate::security::constant_time::constant_time_select(condition, multiplier, 1);
476        *value = value.wrapping_mul(masked_multiplier);
477    }
478
479    /// Protected conditional divide with timing attack resistance
480    pub fn secure_conditional_divide(&self, condition: bool, value: &mut u64, divisor: u64) {
481        if !self.timing_protection {
482            if condition && divisor != 0 {
483                *value /= divisor;
484            }
485            return;
486        }
487
488        // Use constant-time conditional divide
489        let is_zero = divisor == 0;
490        let masked_divisor =
491            crate::security::constant_time::constant_time_select(condition && !is_zero, divisor, 1);
492        *value /= masked_divisor;
493    }
494
495    /// Protected conditional modulo with timing attack resistance
496    pub fn secure_conditional_modulo(&self, condition: bool, value: &mut u64, divisor: u64) {
497        if !self.timing_protection {
498            if condition && divisor != 0 {
499                *value %= divisor;
500            }
501            return;
502        }
503
504        // Use constant-time conditional modulo
505        let is_zero = divisor == 0;
506        let masked_divisor = crate::security::constant_time::constant_time_select(
507            condition && !is_zero,
508            divisor,
509            u64::MAX,
510        );
511        *value %= masked_divisor;
512    }
513
514    /// Protected conditional bitwise AND with timing attack resistance
515    pub fn secure_conditional_bitwise_and(&self, condition: bool, value: &mut u64, mask: u64) {
516        if !self.timing_protection {
517            if condition {
518                *value &= mask;
519            }
520            return;
521        }
522
523        // Use constant-time conditional bitwise AND
524        let masked_mask = crate::security::constant_time::constant_time_select(condition, mask, !0);
525        *value &= masked_mask;
526    }
527
528    /// Protected conditional bitwise OR with timing attack resistance
529    pub fn secure_conditional_bitwise_or(&self, condition: bool, value: &mut u64, mask: u64) {
530        if !self.timing_protection {
531            if condition {
532                *value |= mask;
533            }
534            return;
535        }
536
537        // Use constant-time conditional bitwise OR
538        let masked_mask = crate::security::constant_time::constant_time_select(condition, mask, 0);
539        *value |= masked_mask;
540    }
541
542    /// Protected conditional bitwise XOR with timing attack resistance
543    pub fn secure_conditional_bitwise_xor(&self, condition: bool, value: &mut u64, mask: u64) {
544        if !self.timing_protection {
545            if condition {
546                *value ^= mask;
547            }
548            return;
549        }
550
551        // Use constant-time conditional bitwise XOR
552        let masked_mask = crate::security::constant_time::constant_time_select(condition, mask, 0);
553        *value ^= masked_mask;
554    }
555
556    /// Protected conditional bitwise NOT with timing attack resistance
557    pub fn secure_conditional_bitwise_not(&self, condition: bool, value: &mut u64) {
558        if !self.timing_protection {
559            if condition {
560                *value = !*value;
561            }
562            return;
563        }
564
565        // Use constant-time conditional bitwise NOT
566        let original = *value;
567        *value = !*value;
568        *value = crate::security::constant_time::constant_time_select(condition, *value, original);
569    }
570
571    /// Protected conditional left shift with timing attack resistance
572    pub fn secure_conditional_left_shift(&self, condition: bool, value: &mut u64, amount: u32) {
573        if !self.timing_protection {
574            if condition {
575                *value <<= amount;
576            }
577            return;
578        }
579
580        // Use constant-time conditional left shift
581        let shifted = *value << amount;
582        *value = crate::security::constant_time::constant_time_select(condition, shifted, *value);
583    }
584
585    /// Protected conditional right shift with timing attack resistance
586    pub fn secure_conditional_right_shift(&self, condition: bool, value: &mut u64, amount: u32) {
587        if !self.timing_protection {
588            if condition {
589                *value >>= amount;
590            }
591            return;
592        }
593
594        // Use constant-time conditional right shift
595        let shifted = *value >> amount;
596        *value = crate::security::constant_time::constant_time_select(condition, shifted, *value);
597    }
598
599    /// Protected conditional rotate left with timing attack resistance
600    pub fn secure_conditional_rotate_left(&self, condition: bool, value: &mut u64, amount: u32) {
601        if !self.timing_protection {
602            if condition {
603                *value = value.rotate_left(amount);
604            }
605            return;
606        }
607
608        // Use constant-time conditional rotate left
609        let rotated = value.rotate_left(amount);
610        *value = crate::security::constant_time::constant_time_select(condition, rotated, *value);
611    }
612
613    /// Protected conditional rotate right with timing attack resistance
614    pub fn secure_conditional_rotate_right(&self, condition: bool, value: &mut u64, amount: u32) {
615        if !self.timing_protection {
616            if condition {
617                *value = value.rotate_right(amount);
618            }
619            return;
620        }
621
622        // Use constant-time conditional rotate right
623        let rotated = value.rotate_right(amount);
624        *value = crate::security::constant_time::constant_time_select(condition, rotated, *value);
625    }
626}
627
628#[cfg(test)]
629mod tests {
630    use super::*;
631
632    #[test]
633    fn test_side_channel_protection_defaults() {
634        let protection = SideChannelProtection::default();
635        assert!(protection.timing_protection);
636        assert!(protection.power_analysis_protection);
637        assert!(protection.cache_attack_protection);
638        assert!(protection.fault_injection_protection);
639    }
640
641    #[test]
642    fn test_side_channel_protection_strict() {
643        let protection = SideChannelProtection::strict();
644        assert!(protection.timing_protection);
645        assert!(protection.power_analysis_protection);
646        assert!(protection.cache_attack_protection);
647        assert!(protection.fault_injection_protection);
648    }
649
650    #[test]
651    fn test_side_channel_protection_permissive() {
652        let protection = SideChannelProtection::permissive();
653        assert!(!protection.timing_protection);
654        assert!(!protection.power_analysis_protection);
655        assert!(!protection.cache_attack_protection);
656        assert!(!protection.fault_injection_protection);
657    }
658
659    #[test]
660    fn test_secure_key_compare() {
661        let protection = SideChannelProtection::new();
662        let a = [1, 2, 3, 4];
663        let b = [1, 2, 3, 4];
664        let c = [1, 2, 3, 5];
665
666        assert!(protection.secure_key_compare(&a, &b));
667        assert!(!protection.secure_key_compare(&a, &c));
668    }
669
670    #[test]
671    fn test_secure_key_select() {
672        let protection = SideChannelProtection::new();
673        let a = [1, 2, 3, 4];
674        let b = [5, 6, 7, 8];
675
676        #[cfg(feature = "alloc")]
677        {
678            let result1 = protection.secure_key_select(1, &a, &b);
679            assert_eq!(result1, a);
680
681            let result0 = protection.secure_key_select(0, &a, &b);
682            assert_eq!(result0, b);
683        }
684
685        #[cfg(not(feature = "alloc"))]
686        {
687            let mut result = [0; 4];
688            protection.secure_key_select(1, &a, &b, &mut result);
689            assert_eq!(result, a);
690
691            protection.secure_key_select(0, &a, &b, &mut result);
692            assert_eq!(result, b);
693        }
694    }
695
696    #[test]
697    fn test_secure_memory_access() {
698        let protection = SideChannelProtection::new();
699        let data = [1, 2, 3, 4, 5];
700
701        assert_eq!(protection.secure_memory_access(&data, 2), Some(&3));
702        assert_eq!(protection.secure_memory_access(&data, 10), None);
703    }
704
705    #[test]
706    fn test_secure_conditional_execute() {
707        let protection = SideChannelProtection::new();
708        let mut executed = false;
709
710        let result = protection.secure_conditional_execute(true, || {
711            executed = true;
712            true
713        });
714
715        assert!(result);
716        assert!(executed);
717    }
718
719    #[test]
720    fn test_secure_conditional_execute_no_return() {
721        let protection = SideChannelProtection::new();
722        let mut executed = false;
723
724        protection.secure_conditional_execute_no_return(true, || {
725            executed = true;
726        });
727
728        assert!(executed);
729    }
730
731    #[test]
732    fn test_secure_loop() {
733        let protection = SideChannelProtection::new();
734        let mut count = 0;
735
736        protection.secure_loop(5, |_| {
737            count += 1;
738            true
739        });
740
741        assert_eq!(count, 5);
742    }
743
744    #[test]
745    fn test_secure_array_access() {
746        let protection = SideChannelProtection::new();
747        let array = [1, 2, 3, 4, 5];
748
749        assert_eq!(protection.secure_array_access(&array, 2), Some(&3));
750        assert_eq!(protection.secure_array_access(&array, 10), None);
751    }
752
753    #[test]
754    fn test_secure_string_compare() {
755        let protection = SideChannelProtection::new();
756
757        assert!(protection.secure_string_compare("hello", "hello"));
758        assert!(!protection.secure_string_compare("hello", "world"));
759    }
760
761    #[test]
762    fn test_secure_integer_compare() {
763        let protection = SideChannelProtection::new();
764
765        assert!(protection.secure_integer_compare(42, 42));
766        assert!(!protection.secure_integer_compare(42, 24));
767    }
768
769    #[test]
770    fn test_secure_integer_operations() {
771        let protection = SideChannelProtection::new();
772
773        assert_eq!(protection.secure_integer_add(10, 5), 15);
774        assert_eq!(protection.secure_integer_sub(10, 5), 5);
775        assert_eq!(protection.secure_integer_mul(10, 5), 50);
776        assert_eq!(protection.secure_integer_div(10, 5), 2);
777        assert_eq!(protection.secure_integer_mod(10, 5), 0);
778    }
779
780    #[test]
781    fn test_secure_bitwise_operations() {
782        let protection = SideChannelProtection::new();
783
784        assert_eq!(protection.secure_bitwise_and(0b1010, 0b1100), 0b1000);
785        assert_eq!(protection.secure_bitwise_or(0b1010, 0b1100), 0b1110);
786        assert_eq!(protection.secure_bitwise_xor(0b1010, 0b1100), 0b0110);
787        assert_eq!(protection.secure_bitwise_not(0b1010), !0b1010);
788    }
789
790    #[test]
791    fn test_secure_shift_operations() {
792        let protection = SideChannelProtection::new();
793
794        assert_eq!(protection.secure_left_shift(0b1010u64, 2), 0b101000u64);
795        assert_eq!(protection.secure_right_shift(0b1010u64, 2), 0b10u64);
796        assert_eq!(protection.secure_rotate_left(0b1010u64, 2), 0b101000u64);
797        assert_eq!(
798            protection.secure_rotate_right(0b1010u64, 2),
799            0b1010u64.rotate_right(2)
800        );
801    }
802
803    #[test]
804    fn test_secure_conditional_operations() {
805        let protection = SideChannelProtection::new();
806        let mut value = 42u64;
807
808        protection.secure_conditional_assign(true, &mut value, 24);
809        assert_eq!(value, 24);
810
811        protection.secure_conditional_assign(false, &mut value, 100);
812        assert_eq!(value, 24);
813    }
814
815    #[test]
816    fn test_secure_conditional_increment() {
817        let protection = SideChannelProtection::new();
818        let mut value = 42u64;
819
820        protection.secure_conditional_increment(true, &mut value);
821        assert_eq!(value, 43);
822
823        protection.secure_conditional_increment(false, &mut value);
824        assert_eq!(value, 43);
825    }
826
827    #[test]
828    fn test_secure_conditional_decrement() {
829        let protection = SideChannelProtection::new();
830        let mut value = 42u64;
831
832        protection.secure_conditional_decrement(true, &mut value);
833        assert_eq!(value, 41);
834
835        protection.secure_conditional_decrement(false, &mut value);
836        assert_eq!(value, 41);
837    }
838
839    #[test]
840    fn test_secure_conditional_add() {
841        let protection = SideChannelProtection::new();
842        let mut value = 42u64;
843
844        protection.secure_conditional_add(true, &mut value, 10);
845        assert_eq!(value, 52);
846
847        protection.secure_conditional_add(false, &mut value, 5);
848        assert_eq!(value, 52);
849    }
850
851    #[test]
852    fn test_secure_conditional_subtract() {
853        let protection = SideChannelProtection::new();
854        let mut value = 42u64;
855
856        protection.secure_conditional_subtract(true, &mut value, 10);
857        assert_eq!(value, 32);
858
859        protection.secure_conditional_subtract(false, &mut value, 5);
860        assert_eq!(value, 32);
861    }
862
863    #[test]
864    fn test_secure_conditional_multiply() {
865        let protection = SideChannelProtection::new();
866        let mut value = 42u64;
867
868        protection.secure_conditional_multiply(true, &mut value, 2);
869        assert_eq!(value, 84);
870
871        protection.secure_conditional_multiply(false, &mut value, 3);
872        assert_eq!(value, 84);
873    }
874
875    #[test]
876    fn test_secure_conditional_divide() {
877        let protection = SideChannelProtection::new();
878        let mut value = 42u64;
879
880        protection.secure_conditional_divide(true, &mut value, 2);
881        assert_eq!(value, 21);
882
883        protection.secure_conditional_divide(false, &mut value, 3);
884        assert_eq!(value, 21);
885    }
886
887    #[test]
888    fn test_secure_conditional_modulo() {
889        let protection = SideChannelProtection::new();
890        let mut value = 42u64;
891
892        protection.secure_conditional_modulo(true, &mut value, 10);
893        assert_eq!(value, 2);
894
895        protection.secure_conditional_modulo(false, &mut value, 5);
896        assert_eq!(value, 2);
897    }
898
899    #[test]
900    fn test_secure_conditional_bitwise_operations() {
901        let protection = SideChannelProtection::new();
902        let mut value = 0b1010u64;
903
904        protection.secure_conditional_bitwise_and(true, &mut value, 0b1100);
905        assert_eq!(value, 0b1000);
906
907        protection.secure_conditional_bitwise_or(true, &mut value, 0b0010);
908        assert_eq!(value, 0b1010);
909
910        protection.secure_conditional_bitwise_xor(true, &mut value, 0b1111);
911        assert_eq!(value, 0b0101);
912
913        protection.secure_conditional_bitwise_not(true, &mut value);
914        assert_eq!(value, !0b0101);
915    }
916
917    #[test]
918    fn test_secure_conditional_shift_operations() {
919        let protection = SideChannelProtection::new();
920        let mut value = 0b1010u64;
921
922        protection.secure_conditional_left_shift(true, &mut value, 2);
923        assert_eq!(value, 0b101000);
924
925        protection.secure_conditional_right_shift(true, &mut value, 2);
926        assert_eq!(value, 0b1010);
927
928        protection.secure_conditional_rotate_left(true, &mut value, 2);
929        assert_eq!(value, 0b101000);
930
931        protection.secure_conditional_rotate_right(true, &mut value, 2);
932        assert_eq!(value, 0b1010);
933    }
934}