diff --git a/src/main.rs b/src/main.rs index 5816ecb..201533c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use std::{ - env::{self, args}, + env::{self}, fs, }; diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 168747e..f053cfc 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -4,11 +4,7 @@ use std::collections::HashMap; use crate::utils::parse::{Responses, Testcase, Testcases}; use tasks01::{ - block2poly::block2poly, - gfmul::gfmul_task, - poly2block::poly2block, - sea128::sea128, - xex::{self, fde_xex}, + block2poly::block2poly, gfmul::gfmul_task, poly2block::poly2block, sea128::sea128, xex::fde_xex, }; use anyhow::{anyhow, Result}; diff --git a/src/tasks/tasks01/block2poly.rs b/src/tasks/tasks01/block2poly.rs index dbdaf66..66cccc5 100644 --- a/src/tasks/tasks01/block2poly.rs +++ b/src/tasks/tasks01/block2poly.rs @@ -1,4 +1,4 @@ -use crate::utils::poly::{b64_2_num, block_2_polynomial, get_coefficients}; +use crate::utils::poly::block_2_polynomial; use anyhow::Result; use base64::prelude::*; use serde_json::Value; @@ -19,7 +19,7 @@ pub fn block2poly(val: &Value) -> Result> { #[cfg(test)] mod tests { use serde_json::json; - use std::str::FromStr; + // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; @@ -51,4 +51,46 @@ mod tests { Ok(()) } + + #[test] + fn block2poly_task03() -> Result<()> { + let block: Value = json!({"block" : "AAAAAAAAAAAAAAAAAAAAAA==", "semantic" : "gcm"}); + let coefficients: Vec = vec![]; + assert_eq!( + block2poly(&block)?, + coefficients, + "Coefficients were: {:?}", + block2poly(&block)? + ); + + Ok(()) + } + + #[test] + fn block2poly_task04() -> Result<()> { + let block: Value = json!({"block" : "", "semantic" : "gcm"}); + let coefficients: Vec = vec![]; + assert_eq!( + block2poly(&block)?, + coefficients, + "Coefficients were: {:?}", + block2poly(&block)? + ); + + Ok(()) + } + + #[test] + fn block2poly_task_empty_xex() -> Result<()> { + let block: Value = json!({"block" : "", "semantic" : "xex"}); + let coefficients: Vec = vec![]; + assert_eq!( + block2poly(&block)?, + coefficients, + "Coefficients were: {:?}", + block2poly(&block)? + ); + + Ok(()) + } } diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index c4acefe..95d0a4c 100644 --- a/src/tasks/tasks01/gfmul.rs +++ b/src/tasks/tasks01/gfmul.rs @@ -1,7 +1,4 @@ -use crate::utils::{ - field::ByteArray, - poly::{b64_2_num, coefficient_to_binary, gfmul}, -}; +use crate::utils::poly::gfmul; use anyhow::Result; use base64::prelude::*; @@ -24,7 +21,8 @@ pub fn gfmul_task(args: &Value) -> Result> { #[cfg(test)] mod tests { use serde_json::json; - use std::str::FromStr; + + use crate::utils::math::reverse_bits_in_bytevec; // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; @@ -108,4 +106,26 @@ mod tests { ); Ok(()) } + + #[test] + fn gfmul_task_gcm01() -> Result<()> { + let args: Value = json!({"a": "ARIAAAAAAAAAAAAAAAAAgA==", "b": "AgAAAAAAAAAAAAAAAAAAAA=="}); + + let poly1_text: String = serde_json::from_value(args["a"].clone())?; + let poly_a = reverse_bits_in_bytevec(BASE64_STANDARD.decode(poly1_text)?); + + let poly2_text: String = serde_json::from_value(args["b"].clone())?; + let poly_b = reverse_bits_in_bytevec(BASE64_STANDARD.decode(poly2_text)?); + let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "gcm")?); + + assert_eq!( + result, + BASE64_STANDARD.encode(reverse_bits_in_bytevec( + BASE64_STANDARD.decode("hSQAAAAAAAAAAAAAAAAAAA==")? + )), + "Failure. Calulated result was: {}", + result + ); + Ok(()) + } } diff --git a/src/tasks/tasks01/poly2block.rs b/src/tasks/tasks01/poly2block.rs index 293d1c3..6d5ad95 100644 --- a/src/tasks/tasks01/poly2block.rs +++ b/src/tasks/tasks01/poly2block.rs @@ -1,6 +1,5 @@ -use crate::utils::poly::{self, polynomial_2_block}; +use crate::utils::poly::{polynomial_2_block}; use anyhow::{Ok, Result}; -use base64::prelude::*; use serde_json::Value; pub fn poly2block(args: &Value) -> Result> { diff --git a/src/tasks/tasks01/sea128.rs b/src/tasks/tasks01/sea128.rs index 3f5c40d..09170dc 100644 --- a/src/tasks/tasks01/sea128.rs +++ b/src/tasks/tasks01/sea128.rs @@ -34,7 +34,7 @@ pub fn sea128(args: &Value) -> Result { #[cfg(test)] mod tests { - use std::fs; + use anyhow::Result; use serde_json::json; diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index 885b1c3..6b9f624 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -1,4 +1,3 @@ -use std::io::BufRead; use anyhow::Result; use openssl::symm::{Cipher, Crypter, Mode}; @@ -65,12 +64,12 @@ pub fn xex_encrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result let mut output: Vec = vec![]; //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); - let mut tweak_block: ByteArray = ByteArray(sea_128_encrypt(&key2, tweak)?); + let mut tweak_block: ByteArray = ByteArray::from(sea_128_encrypt(&key2, tweak)?); //dbg!("input_chunks: {:001X?}", &input_chunks); for chunk in input_chunks { - let plaintext_intermediate = xor_bytes(&tweak_block.0, chunk)?; + let plaintext_intermediate = xor_bytes(&tweak_block.vector, chunk)?; /* assert!( plaintext_intermediate.len() % 16 == 0, @@ -81,7 +80,7 @@ pub fn xex_encrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); let cypher_block_intermediate = sea_128_encrypt(&key, &plaintext_intermediate)?; - let mut cypher_block = xor_bytes(&tweak_block.0, cypher_block_intermediate)?; + let mut cypher_block = xor_bytes(&tweak_block.vector, cypher_block_intermediate)?; output.append(cypher_block.as_mut()); tweak_block.left_shift_reduce("xex"); } @@ -99,10 +98,10 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result let mut output: Vec = vec![]; //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); - let mut tweak_block: ByteArray = ByteArray(sea_128_encrypt(&key2, tweak)?); + let mut tweak_block: ByteArray = ByteArray::from(sea_128_encrypt(&key2, tweak)?); for chunk in input_chunks { - let cyphertext_intermediate = xor_bytes(&tweak_block.0, chunk)?; + let cyphertext_intermediate = xor_bytes(&tweak_block.vector, chunk)?; /* assert!( @@ -114,7 +113,7 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); */ let plaintext_block_intermediate = sea_128_decrypt(&key, &cyphertext_intermediate)?; - let mut cypher_block = xor_bytes(&tweak_block.0, plaintext_block_intermediate)?; + let mut cypher_block = xor_bytes(&tweak_block.vector, plaintext_block_intermediate)?; output.append(cypher_block.as_mut()); tweak_block.left_shift_reduce("xex"); } @@ -122,6 +121,42 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result Ok(output) } +pub fn gcm_aes_encrypt( + action: &str, + mut nonce: Vec, + key: Vec, + plaintext: Vec, + ad: ByteArray, +) -> Result> { + nonce.append(vec![0x01].as_mut()); + + let auth_text_xor_block = aes_128_encrypt(&key, &nonce); + + let auth_key_h = aes_128_encrypt(&key, &vec![0]); + + let plaintext: Vec> = plaintext.chunks(16).map(|x| x.to_vec()).collect(); + + let mut output: Vec> = vec![]; + + for (ctr, chunk) in plaintext.iter().enumerate() { + nonce.pop(); + nonce.push(ctr as u8); + + let intermediate = aes_128_encrypt(&key, &nonce)?; + + let intermediate2 = xor_bytes(chunk, intermediate)?; + + output.push(intermediate2); + } + todo!(); +} + +pub fn ghash(auth_key_h: Vec, ad: Vec, ciphertext: Vec>) { + let output: Vec = vec![0, 16]; + + let inter1 = xor_bytes(&output, ad); +} + /* * let mut bytes: [u8; 16] = [0u8; 16]; bytes.copy_from_slice(&ciphertext); diff --git a/src/utils/field.rs b/src/utils/field.rs index afa9b06..5221c30 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -4,14 +4,16 @@ use base64::Engine; use super::poly::gfmul; #[derive(Debug)] -pub struct ByteArray(pub Vec); +pub struct ByteArray { + pub vector: Vec, +} impl ByteArray { pub fn left_shift(&mut self, semantic: &str) -> Result { match semantic { "xex" => { let mut carry = 0u8; - for byte in self.0.iter_mut() { + for byte in self.vector.iter_mut() { let new_carry = *byte >> 7; *byte = (*byte << 1) | carry; carry = new_carry; @@ -20,14 +22,56 @@ impl ByteArray { } "gcm" => { let mut carry = 0u8; - for byte in self.0.iter_mut() { + for byte in self.vector.iter_mut() { + let new_carry = *byte & 1; + *byte = (*byte >> 1) | carry << 7; + carry = new_carry; + } + Ok(carry) + } + _ => Err(anyhow!("Failure in lsh. No compatible action found")), + } + } + + pub fn left_shift_reduce(&mut self, semantic: &str) { + match semantic { + "xex" => { + let alpha_poly: Vec = base64::prelude::BASE64_STANDARD + .decode("AgAAAAAAAAAAAAAAAAAAAA==") + .expect("Decode failed"); + self.vector = gfmul(self.vector.clone(), alpha_poly, "xex").unwrap(); + } + "gcm" => { + let alpha_poly: Vec = base64::prelude::BASE64_STANDARD + .decode("AgAAAAAAAAAAAAAAAAAAAA==") + .expect("Decode failed"); + self.vector = gfmul(self.vector.clone(), alpha_poly, "gcm").unwrap(); + } + _ => {} + } + } + + pub fn right_shift(&mut self, semantic: &str) -> Result { + match semantic { + "xex" => { + let mut carry = 0u8; + for byte in self.vector.iter_mut().rev() { let new_carry = *byte & 1; *byte = (*byte >> 1) | (carry << 7); carry = new_carry; } Ok(carry) } - _ => Err(anyhow!("Failure in lsh. No compatible action found")), + "gcm" => { + let mut carry = 0u8; + for byte in self.vector.iter_mut().rev() { + let new_carry = *byte & 1; + *byte = (*byte << 1) | carry; + carry = new_carry; + } + Ok(carry) + } + _ => Err(anyhow!("Failure in rsh. No valid semantic found")), } } @@ -49,150 +93,139 @@ impl ByteArray { } } - pub fn right_shift(&mut self, semantic: &str) -> Result { - match semantic { - "xex" => { - let mut carry = 0u8; - for byte in self.0.iter_mut().rev() { - let new_carry = *byte & 1; - *byte = (*byte >> 1) | (carry << 7); - carry = new_carry; - } - Ok(carry) - } - "gcm" => { - let mut carry = 0u8; - for byte in self.0.iter_mut().rev() { - let new_carry = *byte & 1; - *byte = (*byte << 1) | carry; - carry = new_carry; - } - Ok(carry) - } - _ => Err(anyhow!("Failure in rsh. No valid semantic found")), - } - } - pub fn xor_byte_arrays(&mut self, vec2: &ByteArray) { - self.0 + self.vector .iter_mut() - .zip(vec2.0.iter()) + .zip(vec2.vector.iter()) .for_each(|(x1, x2)| *x1 ^= *x2); } - pub fn LSB_is_one(&self) -> bool { + pub fn lsb_is_one(&self) -> bool { (self.0.first().unwrap() & 1) == 1 } pub fn msb_is_one(&self) -> bool { - (self.0.last().unwrap() & 1) == 1 + (self.vector.last().unwrap() & 1) == 1 } pub fn is_empty(&self) -> bool { - for i in self.0.iter() { + for i in self.vector.iter() { if *i != 0 { return false; } } true } + + pub fn reverse_bits_in_bytevec(&mut self) { + self.0 = self.0.iter_mut().map(|byte| byte.reverse_bits()).collect(); + } + + pub fn append_vec(&mut self, mut other: Vec) { + self.vector.append(other.as_mut()); + } +} + +impl From> for ByteArray { + fn from(item: Vec) -> Self { + ByteArray { vector: item } + } } #[cfg(test)] mod tests { use super::*; - use std::fs; #[test] fn test_byte_array_shift1() { - let mut byte_array: ByteArray = ByteArray(vec![0x00, 0x01]); - let shifted_array: ByteArray = ByteArray(vec![0x00, 0x02]); + let mut byte_array: ByteArray = ByteArray::from(vec![0x00, 0x01]); + let shifted_array: ByteArray = ByteArray::from(vec![0x00, 0x02]); byte_array.left_shift("xex"); - assert_eq!(byte_array.0, shifted_array.0); + assert_eq!(byte_array.vector, shifted_array.vector); } #[test] fn test_byte_array_shift2() { - let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); - let shifted_array: ByteArray = ByteArray(vec![0xFE, 0x01]); + let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]); + let shifted_array: ByteArray = ByteArray::from(vec![0xFE, 0x01]); byte_array.left_shift("xex"); assert_eq!( - byte_array.0, shifted_array.0, + byte_array.vector, shifted_array.vector, "Failure: Shifted array was: {:?}", - byte_array.0 + byte_array.vector ); } #[test] fn test_byte_array_shift1_gcm() { - let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); - let shifted_array: ByteArray = ByteArray(vec![0x7F, 0x80]); + let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]); + let shifted_array: ByteArray = ByteArray::from(vec![0x7F, 0x80]); byte_array.left_shift("gcm"); assert_eq!( - byte_array.0, shifted_array.0, + byte_array.vector, shifted_array.vector, "Failure: Shifted array was: {:02X?}", - byte_array.0 + byte_array.vector ); } #[test] fn test_byte_array_shift1_right_gcm() { - let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); - let shifted_array: ByteArray = ByteArray(vec![0xFE, 0x00]); + let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]); + let shifted_array: ByteArray = ByteArray::from(vec![0xFE, 0x00]); byte_array.right_shift("gcm"); assert_eq!( - byte_array.0, shifted_array.0, + byte_array.vector, shifted_array.vector, "Failure: Shifted array was: {:02X?}", - byte_array.0 + byte_array.vector ); } #[test] fn test_byte_array_shift_right() { - let mut byte_array: ByteArray = ByteArray(vec![0x02]); - let shifted_array: ByteArray = ByteArray(vec![0x01]); + let mut byte_array: ByteArray = ByteArray::from(vec![0x02]); + let shifted_array: ByteArray = ByteArray::from(vec![0x01]); byte_array.right_shift("xex"); assert_eq!( - byte_array.0, shifted_array.0, + byte_array.vector, shifted_array.vector, "Failure: Shifted array was: {:?}", - byte_array.0 + byte_array.vector ); } #[test] fn test_lsb_one() { let byte_array: ByteArray = ByteArray(vec![0x00, 0xFF]); - assert!(!byte_array.LSB_is_one()); + assert!(!byte_array.lsb_is_one()); let byte_array2: ByteArray = ByteArray(vec![0x02, 0xFF]); - assert!(!byte_array2.LSB_is_one()); + assert!(!byte_array2.lsb_is_one()); let byte_array3: ByteArray = ByteArray(vec![0xFF, 0x00]); - assert!(byte_array3.LSB_is_one()); + assert!(byte_array3.lsb_is_one()); } #[test] fn test_byte_xor() { - let mut byte_array: ByteArray = ByteArray(vec![0x25, 0x25]); - let byte_array2: ByteArray = ByteArray(vec![0x55, 0x55]); + let mut byte_array: ByteArray = ByteArray::from(vec![0x25, 0x25]); + let byte_array2: ByteArray = ByteArray::from(vec![0x55, 0x55]); byte_array.xor_byte_arrays(&byte_array2); - assert_eq!(byte_array.0, vec![0x70, 0x70]); + assert_eq!(byte_array.vector, vec![0x70, 0x70]); } #[test] fn test_byte_xor2() { - let mut byte_array: ByteArray = ByteArray(vec![0x00, 0x00]); - let byte_array2: ByteArray = ByteArray(vec![0x55, 0x55]); + let mut byte_array: ByteArray = ByteArray::from(vec![0x00, 0x00]); + let byte_array2: ByteArray = ByteArray::from(vec![0x55, 0x55]); byte_array.xor_byte_arrays(&byte_array2); - assert_eq!(byte_array.0, vec![0x55, 0x55]); + assert_eq!(byte_array.vector, vec![0x55, 0x55]); } } diff --git a/src/utils/math.rs b/src/utils/math.rs index 4021522..df3fe7c 100644 --- a/src/utils/math.rs +++ b/src/utils/math.rs @@ -1,7 +1,4 @@ -use anyhow::{anyhow, Ok, Result}; -use base64::Engine; - -use super::poly::gfmul; +use anyhow::{Ok, Result}; pub fn xor_bytes(vec1: &Vec, mut vec2: Vec) -> Result> { for (byte1, byte2) in vec1.iter().zip(vec2.iter_mut()) { @@ -10,3 +7,9 @@ pub fn xor_bytes(vec1: &Vec, mut vec2: Vec) -> Result> { Ok(vec2) } + +pub fn reverse_bits_in_bytevec(mut vec: Vec) -> Vec { + vec = vec.iter_mut().map(|byte| byte.reverse_bits()).collect(); + + vec +} diff --git a/src/utils/parse.rs b/src/utils/parse.rs index 5cc1781..e9a9fb8 100644 --- a/src/utils/parse.rs +++ b/src/utils/parse.rs @@ -28,7 +28,7 @@ pub fn parse_json(json: String) -> Result { mod tests { use std::fs; - use serde_json::json; + // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; diff --git a/src/utils/poly.rs b/src/utils/poly.rs index ec316a4..56579a4 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,46 +1,63 @@ use crate::utils::field::ByteArray; use anyhow::{anyhow, Result}; use base64::prelude::*; -use serde_json::Value; use std::{str::FromStr, u128, u8, usize}; -use super::field; pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000; pub fn gfmul(poly_a: Vec, poly_b: Vec, semantic: &str) -> Result> { - let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec()); - red_poly_bytes.0.push(0x01); + let mut red_poly_bytes: ByteArray = ByteArray::from(RED_POLY.to_be_bytes().to_vec()); + red_poly_bytes.vector.push(0x01); - let mut poly1: ByteArray = ByteArray(poly_a); - poly1.0.push(0x00); + red_poly_bytes.reverse_bits_in_bytevec(); - let mut poly2: ByteArray = ByteArray(poly_b); - poly2.0.push(0x00); + let mut poly1: ByteArray = ByteArray::from(poly_a); + poly1.vector.push(0x00); + + let mut poly2: ByteArray = ByteArray::from(poly_b); + poly2.vector.push(0x00); + + eprintln!( + "poly1 is: {:001X?} \n poly2 is: {:001X?} \n gen poly is: {:001X?} \n", + poly1, poly2, red_poly_bytes + ); let mut result: ByteArray = ByteArray(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + let mut result: ByteArray = + ByteArray::from(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); - if poly2.LSB_is_one() { + if poly2.msb_is_one() { result.xor_byte_arrays(&poly1); } poly2.right_shift(semantic)?; + eprintln!( + "poly1 is: {:001X?} \n poly2 is: {:001X?} \n gen poly is: {:001X?} \n result is: {:001X?} \n ", + poly1, poly2, red_poly_bytes, result + ); + while !poly2.is_empty() { + eprintln!( + "poly1 is: {:001X?} \n poly2 is: {:001X?} \n gen poly is: {:001X?} \n result is: {:001X?} \n ", + poly1, poly2, red_poly_bytes, result + ); poly1.left_shift(semantic)?; - if poly1.msb_is_one() { + if poly1.lsb_is_one() { poly1.xor_byte_arrays(&red_poly_bytes); } - if poly2.LSB_is_one() { + if poly2.msb_is_one() { + eprintln!("poly write to result"); result.xor_byte_arrays(&poly1); } poly2.right_shift(semantic)?; } - result.0.remove(16); + result.vector.remove(16); - Ok(result.0) + Ok(result.vector) } pub fn convert_gcm_to_xex(gcm_poly: Vec) -> Result> { @@ -104,31 +121,35 @@ pub fn get_bit_indices_from_byte(byte: u8) -> Vec { } pub fn block_2_polynomial(block: Vec, semantic: &str) -> Result> { - let mut output: Vec = vec![]; - match semantic { - "xex" => { - for i in 0u8..=15 { - for j in 0u8..=7 { - if (block[i as usize] >> j) & 1 == 1 { - output.push(8 * i + j); + if block.len() == 0 { + Ok(Vec::new()) + } else { + let mut output: Vec = vec![]; + match semantic { + "xex" => { + for byte in 0u8..=15 { + for bit in 0u8..=7 { + if (block[byte as usize] >> bit) & 1 == 1 { + output.push(8 * byte + bit); + } } } + output.sort(); + Ok(output) } - output.sort(); - Ok(output) - } - "gcm" => { - for i in 0u8..=15 { - for j in 0u8..=7 { - if (block[i as usize] >> j) & 1 == 1 { - output.push(8 * i + 7 - j); + "gcm" => { + for byte in 0u8..=15 { + for bit in 0u8..=7 { + if (block[byte as usize] >> bit) & 1 == 1 { + output.push(8 * byte + 7 - bit); + } } } + output.sort(); + Ok(output) } - output.sort(); - Ok(output) + _ => Err(anyhow!("Error in b2p")), } - _ => Err(anyhow!("Error in b2p")), } } @@ -163,7 +184,7 @@ pub fn coefficients_to_byte_arr_xex(coeffs: Vec) -> Vec { let mut byte_array: Vec = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; for coeff in coeffs { let block_num = coeff / 8; - byte_array[usize::from(block_num)] |= (1 << (coeff % 7)); + byte_array[usize::from(block_num)] |= 1 << (coeff % 7); } byte_array