From f4c49a913779ff17265e180e52018be78a8b3bfd Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Tue, 29 Oct 2024 13:53:10 +0100 Subject: [PATCH] refactor: externalise gfmul to make it more accessible and semantic support --- src/tasks/mod.rs | 10 ++----- src/tasks/tasks01/gfmul.rs | 51 +++++++++-------------------------- src/utils/ciphers.rs | 4 +-- src/utils/math.rs | 55 +++++++++++++++++++++++++++----------- src/utils/poly.rs | 40 ++++++++++++++++++++++++++- 5 files changed, 96 insertions(+), 64 deletions(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 13f27d8..0e0f3c3 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -5,7 +5,7 @@ use std::collections::HashMap; use crate::utils::parse::{Responses, Testcase, Testcases}; use tasks01::{ block2poly::block2poly, - gfmul::gfmul, + gfmul::gfmul_task, poly2block::poly2block, sea128::sea128, xex::{self, fde_xex}, @@ -43,13 +43,7 @@ pub fn task_deploy(testcase: &Testcase) -> Result { Ok(json) } "gfmul" => { - let poly1_text: String = serde_json::from_value(args["a"].clone())?; - let poly_a = BASE64_STANDARD.decode(poly1_text)?; - - let poly2_text: String = serde_json::from_value(args["b"].clone())?; - let poly_b = BASE64_STANDARD.decode(poly2_text)?; - - let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b)?); + let result = BASE64_STANDARD.encode(gfmul_task(args)?); let json = json!({"product" : result}); Ok(json) } diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index 44a032e..58e5afb 100644 --- a/src/tasks/tasks01/gfmul.rs +++ b/src/tasks/tasks01/gfmul.rs @@ -1,49 +1,24 @@ -use anyhow::Result; -use base64::prelude::*; -//use num_bigint::{BigUint, ToBigUint}; -use serde_json::Value; - use crate::utils::{ math::ByteArray, - poly::{b64_2_num, coefficient_to_binary}, + poly::{b64_2_num, coefficient_to_binary, gfmul}, }; -pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000; +use anyhow::Result; +use base64::prelude::*; +use serde_json::Value; -pub fn gfmul(poly_a: Vec, poly_b: Vec) -> Result> { - let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec()); - red_poly_bytes.0.push(0x01); +pub fn gfmul_task(args: &Value) -> Result> { + let poly1_text: String = serde_json::from_value(args["a"].clone())?; + let poly_a = BASE64_STANDARD.decode(poly1_text)?; - let mut poly1: ByteArray = ByteArray(poly_a); - poly1.0.push(0x00); + let poly2_text: String = serde_json::from_value(args["b"].clone())?; + let poly_b = BASE64_STANDARD.decode(poly2_text)?; - let mut poly2: ByteArray = ByteArray(poly_b); - poly2.0.push(0x00); + let semantic: String = serde_json::from_value(args["semantic"].clone())?; - let mut result: ByteArray = ByteArray(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); + let result = gfmul(poly_a, poly_b, &semantic)?; - if poly2.LSB_is_one() { - result.xor_byte_arrays(&poly1); - poly2.right_shift(); - } else { - poly2.right_shift(); - } - - while !poly2.is_empty() { - if poly2.LSB_is_one() { - poly1.left_shift(); - poly1.xor_byte_arrays(&red_poly_bytes); - result.xor_byte_arrays(&poly1); - } else { - poly1.left_shift(); - poly1.xor_byte_arrays(&red_poly_bytes); - } - poly2.right_shift(); - } - - result.0.remove(16); - - Ok(result.0) + Ok(result) } #[cfg(test)] @@ -64,7 +39,7 @@ mod tests { let poly2_text: String = serde_json::from_value(args["b"].clone())?; let poly_b = BASE64_STANDARD.decode(poly2_text)?; - let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b)?); + let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "xex")?); assert_eq!( result, "hSQAAAAAAAAAAAAAAAAAAA==", diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index ec1b467..6ffa52a 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -83,7 +83,7 @@ pub fn xex_encrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result let cypher_block_intermediate = sea_128_encrypt(&key, &plaintext_intermediate)?; let mut cypher_block = xor_bytes(&tweak_block.0, cypher_block_intermediate)?; output.append(cypher_block.as_mut()); - tweak_block.left_shift_reduce(); + tweak_block.left_shift_reduce("xex"); } Ok(output) @@ -116,7 +116,7 @@ pub fn xex_decrypt(mut key: Vec, tweak: &Vec, input: &Vec) -> Result let plaintext_block_intermediate = sea_128_decrypt(&key, &cyphertext_intermediate)?; let mut cypher_block = xor_bytes(&tweak_block.0, plaintext_block_intermediate)?; output.append(cypher_block.as_mut()); - tweak_block.left_shift_reduce(); + tweak_block.left_shift_reduce("xex"); } Ok(output) diff --git a/src/utils/math.rs b/src/utils/math.rs index 82b2c61..5fb6a35 100644 --- a/src/utils/math.rs +++ b/src/utils/math.rs @@ -1,7 +1,7 @@ -use anyhow::{Ok, Result}; +use anyhow::{anyhow, Ok, Result}; use base64::Engine; -use crate::tasks::tasks01::gfmul::gfmul; +use super::poly::gfmul; pub fn xor_bytes(vec1: &Vec, mut vec2: Vec) -> Result> { for (byte1, byte2) in vec1.iter().zip(vec2.iter_mut()) { @@ -25,21 +25,46 @@ impl ByteArray { carry } - pub fn left_shift_reduce(&mut self) { - let alpha_poly: Vec = base64::prelude::BASE64_STANDARD - .decode("AgAAAAAAAAAAAAAAAAAAAA==") - .expect("Decode failed"); - self.0 = gfmul(self.0.clone(), alpha_poly).unwrap(); + 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) -> u8 { - 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; + 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")), } - carry } pub fn xor_byte_arrays(&mut self, vec2: &ByteArray) { @@ -94,7 +119,7 @@ mod tests { 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(); + byte_array.right_shift("xex"); assert_eq!( byte_array.0, shifted_array.0, diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 3c14e76..74233ed 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,7 +1,45 @@ +use crate::utils::math::ByteArray; use anyhow::Result; use base64::prelude::*; - +use serde_json::Value; use std::{str::FromStr, u128, u8, usize}; +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 poly1: ByteArray = ByteArray(poly_a); + poly1.0.push(0x00); + + let mut poly2: ByteArray = ByteArray(poly_b); + poly2.0.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]); + + if poly2.LSB_is_one() { + result.xor_byte_arrays(&poly1); + poly2.right_shift(semantic); + } else { + poly2.right_shift(semantic); + } + + while !poly2.is_empty() { + if poly2.LSB_is_one() { + poly1.left_shift(); + poly1.xor_byte_arrays(&red_poly_bytes); + result.xor_byte_arrays(&poly1); + } else { + poly1.left_shift(); + poly1.xor_byte_arrays(&red_poly_bytes); + } + poly2.right_shift(semantic); + } + + result.0.remove(16); + + Ok(result.0) +} pub fn get_alpha_rep(num: u128) -> String { let powers: Vec = get_coefficients(num);