diff --git a/src/main.rs b/src/main.rs index 59e561b..5816ecb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,8 +3,6 @@ use std::{ fs, }; -// TESTING - use anyhow::Result; fn main() -> Result<()> { diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 0e0f3c3..168747e 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -27,7 +27,7 @@ pub fn task_deploy(testcase: &Testcase) -> Result { match testcase.action.as_str() { "poly2block" => { - let result = poly2block(args); + let result = BASE64_STANDARD.encode(poly2block(args)?); let json = json!({"block" : result}); Ok(json) } diff --git a/src/tasks/tasks01/block2poly.rs b/src/tasks/tasks01/block2poly.rs index 69b564f..dbdaf66 100644 --- a/src/tasks/tasks01/block2poly.rs +++ b/src/tasks/tasks01/block2poly.rs @@ -1,15 +1,17 @@ -use crate::utils::poly::{b64_2_num, get_coefficients}; +use crate::utils::poly::{b64_2_num, block_2_polynomial, get_coefficients}; use anyhow::Result; +use base64::prelude::*; use serde_json::Value; pub fn block2poly(val: &Value) -> Result> { // Convert JSON data in to a u128 // TODO: Transfer decoding into own function? let string: String = serde_json::from_value(val["block"].clone())?; + let block = BASE64_STANDARD.decode(string)?; - let number = b64_2_num(&string)?; + let semantic: String = serde_json::from_value(val["semantic"].clone())?; - let coefficients: Vec = get_coefficients(number); + let coefficients: Vec = block_2_polynomial(block, &semantic)?; //get_coefficients(number); Ok(coefficients) } @@ -24,7 +26,7 @@ mod tests { #[test] fn block2poly_task01() -> Result<()> { - let block: Value = json!({"block" : "ARIAAAAAAAAAAAAAAAAAgA=="}); + let block: Value = json!({"block" : "ARIAAAAAAAAAAAAAAAAAgA==", "semantic" : "xex"}); let coefficients: Vec = vec![0, 9, 12, 127]; assert_eq!( block2poly(&block)?, @@ -35,4 +37,18 @@ mod tests { Ok(()) } + + #[test] + fn block2poly_task02() -> Result<()> { + let block: Value = json!({"block" : "ARIAAAAAAAAAAAAAAAAAgA==", "semantic" : "gcm"}); + let coefficients: Vec = vec![7, 11, 14, 120]; + 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 0ca5480..c4acefe 100644 --- a/src/tasks/tasks01/gfmul.rs +++ b/src/tasks/tasks01/gfmul.rs @@ -1,5 +1,5 @@ use crate::utils::{ - math::ByteArray, + field::ByteArray, poly::{b64_2_num, coefficient_to_binary, gfmul}, }; diff --git a/src/tasks/tasks01/poly2block.rs b/src/tasks/tasks01/poly2block.rs index 0c958a8..293d1c3 100644 --- a/src/tasks/tasks01/poly2block.rs +++ b/src/tasks/tasks01/poly2block.rs @@ -1,8 +1,9 @@ -use crate::utils::poly::{self}; +use crate::utils::poly::{self, polynomial_2_block}; +use anyhow::{Ok, Result}; use base64::prelude::*; use serde_json::Value; -pub fn poly2block(args: &Value) -> String { +pub fn poly2block(args: &Value) -> Result> { let coefficients: Vec = args["coefficients"] .as_array() .unwrap() @@ -10,5 +11,9 @@ pub fn poly2block(args: &Value) -> String { .map(|x| x.as_u64().unwrap() as u8) .collect(); - BASE64_STANDARD.encode(poly::coefficient_to_binary(coefficients).to_ne_bytes()) + let semantic: String = serde_json::from_value(args["semantic"].clone())?; + + let result = polynomial_2_block(coefficients, &semantic).unwrap(); + + Ok(result) } diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index a9548e8..885b1c3 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -3,7 +3,7 @@ use std::io::BufRead; use anyhow::Result; use openssl::symm::{Cipher, Crypter, Mode}; -use crate::utils::math::ByteArray; +use crate::utils::field::ByteArray; use super::math::xor_bytes; diff --git a/src/utils/field.rs b/src/utils/field.rs new file mode 100644 index 0000000..afa9b06 --- /dev/null +++ b/src/utils/field.rs @@ -0,0 +1,198 @@ +use anyhow::{anyhow, Ok, Result}; +use base64::Engine; + +use super::poly::gfmul; + +#[derive(Debug)] +pub struct ByteArray(pub 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() { + let new_carry = *byte >> 7; + *byte = (*byte << 1) | carry; + carry = new_carry; + } + Ok(carry) + } + "gcm" => { + let mut carry = 0u8; + for byte in self.0.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.0 = gfmul(self.0.clone(), alpha_poly, "xex").unwrap(); + } + "gcm" => { + let alpha_poly: Vec = base64::prelude::BASE64_STANDARD + .decode("AgAAAAAAAAAAAAAAAAAAAA==") + .expect("Decode failed"); + self.0 = gfmul(self.0.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.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 + .iter_mut() + .zip(vec2.0.iter()) + .for_each(|(x1, x2)| *x1 ^= *x2); + } + + 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 + } + + pub fn is_empty(&self) -> bool { + for i in self.0.iter() { + if *i != 0 { + return false; + } + } + true + } +} + +#[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]); + byte_array.left_shift("xex"); + + assert_eq!(byte_array.0, shifted_array.0); + } + + #[test] + fn test_byte_array_shift2() { + let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); + let shifted_array: ByteArray = ByteArray(vec![0xFE, 0x01]); + byte_array.left_shift("xex"); + + assert_eq!( + byte_array.0, shifted_array.0, + "Failure: Shifted array was: {:?}", + byte_array.0 + ); + } + + #[test] + fn test_byte_array_shift1_gcm() { + let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); + let shifted_array: ByteArray = ByteArray(vec![0x7F, 0x80]); + byte_array.left_shift("gcm"); + + assert_eq!( + byte_array.0, shifted_array.0, + "Failure: Shifted array was: {:02X?}", + byte_array.0 + ); + } + + #[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]); + byte_array.right_shift("gcm"); + + assert_eq!( + byte_array.0, shifted_array.0, + "Failure: Shifted array was: {:02X?}", + byte_array.0 + ); + } + + #[test] + fn test_byte_array_shift_right() { + let mut byte_array: ByteArray = ByteArray(vec![0x02]); + let shifted_array: ByteArray = ByteArray(vec![0x01]); + byte_array.right_shift("xex"); + + assert_eq!( + byte_array.0, shifted_array.0, + "Failure: Shifted array was: {:?}", + byte_array.0 + ); + } + + #[test] + fn test_lsb_one() { + let byte_array: ByteArray = ByteArray(vec![0x00, 0xFF]); + assert!(!byte_array.LSB_is_one()); + + let byte_array2: ByteArray = ByteArray(vec![0x02, 0xFF]); + assert!(!byte_array2.LSB_is_one()); + + let byte_array3: ByteArray = ByteArray(vec![0xFF, 0x00]); + 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]); + + byte_array.xor_byte_arrays(&byte_array2); + + assert_eq!(byte_array.0, 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]); + + byte_array.xor_byte_arrays(&byte_array2); + + assert_eq!(byte_array.0, vec![0x55, 0x55]); + } +} diff --git a/src/utils/math.rs b/src/utils/math.rs index 98836a9..4021522 100644 --- a/src/utils/math.rs +++ b/src/utils/math.rs @@ -10,197 +10,3 @@ pub fn xor_bytes(vec1: &Vec, mut vec2: Vec) -> Result> { Ok(vec2) } - -#[derive(Debug)] -pub struct ByteArray(pub 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() { - let new_carry = *byte >> 7; - *byte = (*byte << 1) | carry; - carry = new_carry; - } - Ok(carry) - } - "gcm" => { - let mut carry = 0u8; - for byte in self.0.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.0 = gfmul(self.0.clone(), alpha_poly, "xex").unwrap(); - } - "gcm" => { - let alpha_poly: Vec = base64::prelude::BASE64_STANDARD - .decode("AgAAAAAAAAAAAAAAAAAAAA==") - .expect("Decode failed"); - self.0 = gfmul(self.0.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.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 - .iter_mut() - .zip(vec2.0.iter()) - .for_each(|(x1, x2)| *x1 ^= *x2); - } - - 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 - } - - pub fn is_empty(&self) -> bool { - for i in self.0.iter() { - if *i != 0 { - return false; - } - } - true - } -} - -#[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]); - byte_array.left_shift("xex"); - - assert_eq!(byte_array.0, shifted_array.0); - } - - #[test] - fn test_byte_array_shift2() { - let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); - let shifted_array: ByteArray = ByteArray(vec![0xFE, 0x01]); - byte_array.left_shift("xex"); - - assert_eq!( - byte_array.0, shifted_array.0, - "Failure: Shifted array was: {:?}", - byte_array.0 - ); - } - - #[test] - fn test_byte_array_shift1_gcm() { - let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); - let shifted_array: ByteArray = ByteArray(vec![0x7F, 0x80]); - byte_array.left_shift("gcm"); - - assert_eq!( - byte_array.0, shifted_array.0, - "Failure: Shifted array was: {:02X?}", - byte_array.0 - ); - } - - #[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]); - byte_array.right_shift("gcm"); - - assert_eq!( - byte_array.0, shifted_array.0, - "Failure: Shifted array was: {:02X?}", - byte_array.0 - ); - } - - #[test] - fn test_byte_array_shift_right() { - let mut byte_array: ByteArray = ByteArray(vec![0x02]); - let shifted_array: ByteArray = ByteArray(vec![0x01]); - byte_array.right_shift("xex"); - - assert_eq!( - byte_array.0, shifted_array.0, - "Failure: Shifted array was: {:?}", - byte_array.0 - ); - } - - #[test] - fn test_lsb_one() { - let byte_array: ByteArray = ByteArray(vec![0x00, 0xFF]); - assert!(!byte_array.LSB_is_one()); - - let byte_array2: ByteArray = ByteArray(vec![0x02, 0xFF]); - assert!(!byte_array2.LSB_is_one()); - - let byte_array3: ByteArray = ByteArray(vec![0xFF, 0x00]); - 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]); - - byte_array.xor_byte_arrays(&byte_array2); - - assert_eq!(byte_array.0, 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]); - - byte_array.xor_byte_arrays(&byte_array2); - - assert_eq!(byte_array.0, vec![0x55, 0x55]); - } -} diff --git a/src/utils/mod.rs b/src/utils/mod.rs index fcbb75b..2f12ed4 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,4 +1,5 @@ pub mod ciphers; +pub mod field; pub mod math; pub mod parse; pub mod poly; diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 82336d7..ec316a4 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,8 +1,10 @@ -use crate::utils::math::ByteArray; -use anyhow::Result; +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> { @@ -41,6 +43,15 @@ pub fn gfmul(poly_a: Vec, poly_b: Vec, semantic: &str) -> Result Ok(result.0) } +pub fn convert_gcm_to_xex(gcm_poly: Vec) -> Result> { + let xex_poly = gcm_poly + .into_iter() + .map(|block| block.reverse_bits()) + .collect(); + + Ok(xex_poly) +} + pub fn get_alpha_rep(num: u128) -> String { let powers: Vec = get_coefficients(num); @@ -92,6 +103,62 @@ pub fn get_bit_indices_from_byte(byte: u8) -> Vec { coefficients } +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); + } + } + } + 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); + } + } + } + output.sort(); + Ok(output) + } + _ => Err(anyhow!("Error in b2p")), + } +} + +pub fn polynomial_2_block(coefficients: Vec, semantic: &str) -> Result> { + let mut output: Vec = Vec::with_capacity(16); + output.resize(16, 0); + + match semantic { + "xex" => { + for coefficient in coefficients { + let byte_position = coefficient / 8; + let bit_position = coefficient % 8; + + output[byte_position as usize] ^= 1 << bit_position; + } + Ok(output) + } + "gcm" => { + for coefficient in coefficients { + let byte_position = coefficient / 8; + let bit_position = coefficient % 8; + + output[byte_position as usize] ^= 1 << 7 - bit_position; + } + Ok(output) + } + _ => Err(anyhow!("Error in b2p")), + } +} + 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 {