From 26ca12b4198172406492ac93500be6639ebcd6ea Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Sat, 2 Nov 2024 14:18:10 +0100 Subject: [PATCH 1/4] feat: Add more tests to b2p edge cases --- src/tasks/tasks01/block2poly.rs | 42 +++++++++++++++++++++++++++++++++ src/utils/poly.rs | 40 +++++++++++++++++-------------- 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/src/tasks/tasks01/block2poly.rs b/src/tasks/tasks01/block2poly.rs index dbdaf66..b6a215d 100644 --- a/src/tasks/tasks01/block2poly.rs +++ b/src/tasks/tasks01/block2poly.rs @@ -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/utils/poly.rs b/src/utils/poly.rs index ec316a4..50e7ce6 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -104,31 +104,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 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) } - 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 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) } - output.sort(); - Ok(output) + _ => Err(anyhow!("Error in b2p")), } - _ => Err(anyhow!("Error in b2p")), } } From 1ce30e1cead53d656b2d4e5c7193cffb4dfab830 Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Sat, 2 Nov 2024 14:19:21 +0100 Subject: [PATCH 2/4] refactor: Apply cargo reccomended cleanups --- src/main.rs | 2 +- src/tasks/mod.rs | 2 +- src/tasks/tasks01/block2poly.rs | 4 ++-- src/tasks/tasks01/gfmul.rs | 7 ++----- src/tasks/tasks01/poly2block.rs | 3 +-- src/tasks/tasks01/sea128.rs | 2 +- src/utils/ciphers.rs | 1 - src/utils/field.rs | 2 +- src/utils/math.rs | 4 +--- src/utils/parse.rs | 2 +- src/utils/poly.rs | 4 +--- 11 files changed, 12 insertions(+), 21 deletions(-) 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..f0adb70 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -8,7 +8,7 @@ use tasks01::{ gfmul::gfmul_task, poly2block::poly2block, sea128::sea128, - xex::{self, fde_xex}, + xex::{fde_xex}, }; use anyhow::{anyhow, Result}; diff --git a/src/tasks/tasks01/block2poly.rs b/src/tasks/tasks01/block2poly.rs index b6a215d..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::*; diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index c4acefe..b398b6e 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,7 @@ pub fn gfmul_task(args: &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::*; 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..62413a8 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}; diff --git a/src/utils/field.rs b/src/utils/field.rs index afa9b06..f2c80b4 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -101,7 +101,7 @@ impl ByteArray { #[cfg(test)] mod tests { use super::*; - use std::fs; + #[test] fn test_byte_array_shift1() { diff --git a/src/utils/math.rs b/src/utils/math.rs index 4021522..fa82819 100644 --- a/src/utils/math.rs +++ b/src/utils/math.rs @@ -1,7 +1,5 @@ -use anyhow::{anyhow, Ok, Result}; -use base64::Engine; +use anyhow::{Ok, Result}; -use super::poly::gfmul; pub fn xor_bytes(vec1: &Vec, mut vec2: Vec) -> Result> { for (byte1, byte2) in vec1.iter().zip(vec2.iter_mut()) { 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 50e7ce6..4b984ea 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,10 +1,8 @@ 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> { @@ -167,7 +165,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 From 1e51015a1416d9caaa030e236abc3d971de58e1c Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Sat, 2 Nov 2024 16:12:51 +0100 Subject: [PATCH 3/4] WIP: feat: working on gfmul gcm --- src/tasks/mod.rs | 6 +---- src/tasks/tasks01/gfmul.rs | 25 ++++++++++++++++++- src/utils/field.rs | 51 ++++++++++++++++++++------------------ src/utils/math.rs | 7 +++++- src/utils/poly.rs | 39 +++++++++++++++++++++-------- 5 files changed, 86 insertions(+), 42 deletions(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index f0adb70..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::{fde_xex}, + block2poly::block2poly, gfmul::gfmul_task, poly2block::poly2block, sea128::sea128, xex::fde_xex, }; use anyhow::{anyhow, Result}; diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index b398b6e..95d0a4c 100644 --- a/src/tasks/tasks01/gfmul.rs +++ b/src/tasks/tasks01/gfmul.rs @@ -21,7 +21,8 @@ pub fn gfmul_task(args: &Value) -> Result> { #[cfg(test)] mod tests { use serde_json::json; - + + use crate::utils::math::reverse_bits_in_bytevec; // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; @@ -105,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/utils/field.rs b/src/utils/field.rs index f2c80b4..2670b2d 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -22,7 +22,7 @@ impl ByteArray { let mut carry = 0u8; for byte in self.0.iter_mut() { let new_carry = *byte & 1; - *byte = (*byte >> 1) | (carry << 7); + *byte = (*byte >> 1) | carry << 7; carry = new_carry; } Ok(carry) @@ -31,24 +31,6 @@ impl ByteArray { } } - 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" => { @@ -73,6 +55,24 @@ impl ByteArray { } } + 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 xor_byte_arrays(&mut self, vec2: &ByteArray) { self.0 .iter_mut() @@ -80,7 +80,7 @@ impl ByteArray { .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 } @@ -96,12 +96,15 @@ impl ByteArray { } true } + + pub fn reverse_bits_in_bytevec(&mut self) { + self.0 = self.0.iter_mut().map(|byte| byte.reverse_bits()).collect(); + } } #[cfg(test)] mod tests { use super::*; - #[test] fn test_byte_array_shift1() { @@ -167,13 +170,13 @@ mod tests { #[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] diff --git a/src/utils/math.rs b/src/utils/math.rs index fa82819..df3fe7c 100644 --- a/src/utils/math.rs +++ b/src/utils/math.rs @@ -1,6 +1,5 @@ use anyhow::{Ok, Result}; - pub fn xor_bytes(vec1: &Vec, mut vec2: Vec) -> Result> { for (byte1, byte2) in vec1.iter().zip(vec2.iter_mut()) { *byte2 ^= byte1; @@ -8,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/poly.rs b/src/utils/poly.rs index 4b984ea..8f525bf 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -9,27 +9,44 @@ 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); + red_poly_bytes.reverse_bits_in_bytevec(); + let mut poly1: ByteArray = ByteArray(poly_a); poly1.0.push(0x00); let mut poly2: ByteArray = ByteArray(poly_b); poly2.0.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]); - 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); } @@ -108,10 +125,10 @@ 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); + for byte in 0u8..=15 { + for bit in 0u8..=7 { + if (block[byte as usize] >> bit) & 1 == 1 { + output.push(8 * byte + bit); } } } @@ -119,10 +136,10 @@ pub fn block_2_polynomial(block: Vec, semantic: &str) -> Result> { 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); + for byte in 0u8..=15 { + for bit in 0u8..=7 { + if (block[byte as usize] >> bit) & 1 == 1 { + output.push(8 * byte + 7 - bit); } } } From 28216d2e2f623917abfb5b793490c2eed65f11f3 Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Sat, 2 Nov 2024 17:58:53 +0100 Subject: [PATCH 4/4] WIP: feat: start on gcm --- src/utils/ciphers.rs | 48 ++++++++++++++++++++--- src/utils/field.rs | 92 +++++++++++++++++++++++++------------------- src/utils/poly.rs | 19 ++++----- 3 files changed, 104 insertions(+), 55 deletions(-) diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index 885b1c3..7c70808 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -65,12 +65,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 +81,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 +99,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 +114,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 +122,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..98deb9e 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,7 +22,7 @@ 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; @@ -37,13 +39,13 @@ impl ByteArray { let alpha_poly: Vec = base64::prelude::BASE64_STANDARD .decode("AgAAAAAAAAAAAAAAAAAAAA==") .expect("Decode failed"); - self.0 = gfmul(self.0.clone(), alpha_poly, "xex").unwrap(); + 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.0 = gfmul(self.0.clone(), alpha_poly, "gcm").unwrap(); + self.vector = gfmul(self.vector.clone(), alpha_poly, "gcm").unwrap(); } _ => {} } @@ -53,7 +55,7 @@ impl ByteArray { match semantic { "xex" => { let mut carry = 0u8; - for byte in self.0.iter_mut().rev() { + for byte in self.vector.iter_mut().rev() { let new_carry = *byte & 1; *byte = (*byte >> 1) | (carry << 7); carry = new_carry; @@ -62,7 +64,7 @@ impl ByteArray { } "gcm" => { let mut carry = 0u8; - for byte in self.0.iter_mut().rev() { + for byte in self.vector.iter_mut().rev() { let new_carry = *byte & 1; *byte = (*byte << 1) | carry; carry = new_carry; @@ -74,28 +76,38 @@ impl ByteArray { } 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 { - (self.0.first().unwrap() & 1) == 1 + (self.vector.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 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)] @@ -105,94 +117,94 @@ mod tests { #[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]); + let byte_array: ByteArray = ByteArray::from(vec![0x00, 0xFF]); assert!(!byte_array.LSB_is_one()); - let byte_array2: ByteArray = ByteArray(vec![0x02, 0xFF]); + let byte_array2: ByteArray = ByteArray::from(vec![0x02, 0xFF]); assert!(!byte_array2.LSB_is_one()); - let byte_array3: ByteArray = ByteArray(vec![0xFF, 0x00]); + let byte_array3: ByteArray = ByteArray::from(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]); + 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/poly.rs b/src/utils/poly.rs index ec316a4..3dedd5d 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -8,16 +8,17 @@ 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); + let mut poly1: ByteArray = ByteArray::from(poly_a); + poly1.vector.push(0x00); - let mut poly2: ByteArray = ByteArray(poly_b); - poly2.0.push(0x00); + let mut poly2: ByteArray = ByteArray::from(poly_b); + poly2.vector.push(0x00); - 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() { result.xor_byte_arrays(&poly1); @@ -38,9 +39,9 @@ pub fn gfmul(poly_a: Vec, poly_b: Vec, semantic: &str) -> Result 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> {