1use crate::errors::*;
6
7#[inline]
8fn is_pow2(x: usize) -> bool {
9 x != 0 && (x & (x - 1)) == 0
10}
11
12pub fn xor_layers_forward(buf: &mut [u8]) -> Result<()> {
14 let n = buf.len();
15 if !is_pow2(n) {
16 return Err(S3pError::Invalid(
17 "xor_layers_forward: length must be power of two".into(),
18 ));
19 }
20 let mut step = 1;
21 while step < n {
22 let stride = step * 2;
23 for i in (0..n).step_by(stride) {
24 for j in 0..step {
25 let a = i + j;
26 let b = a + step;
27 let a0 = buf[a];
28 let b0 = buf[b];
29 buf[a] = a0 ^ b0;
30 buf[b] = a0;
31 }
32 }
33 step <<= 1;
34 }
35 Ok(())
36}
37
38pub fn xor_layers_inverse(buf: &mut [u8]) -> Result<()> {
40 let n = buf.len();
41 if !is_pow2(n) {
42 return Err(S3pError::Invalid(
43 "xor_layers_inverse: length must be power of two".into(),
44 ));
45 }
46 let mut step = n >> 1;
47 while step > 0 {
48 let stride = step * 2;
49 for i in (0..n).step_by(stride) {
50 for j in 0..step {
51 let a = i + j;
52 let b = a + step;
53 let x = buf[a];
55 let y = buf[b];
56 buf[b] = x ^ y; buf[a] = y; }
59 }
60 step >>= 1;
61 }
62 Ok(())
63}