From 4dc6cdfef8835f245f33f99cd9222b8028a14719 Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Sat, 26 Oct 2024 13:04:26 +0200 Subject: [PATCH] WIP: feat: gfmul working but LSB check is broken --- Cargo.lock | 35 +++++++++++++ Cargo.toml | 1 + src/tasks/tasks01/gfmul.rs | 83 ++++++++++++++++++++++------- src/utils/math.rs | 104 ++++++++++++++++++++++++++++++++++++- src/utils/poly.rs | 30 ++++++++++- 5 files changed, 231 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fa8324c..2997a36 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8,6 +8,12 @@ version = "1.0.90" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37bf3594c4c988a53154954629820791dde498571819ae4ca50ca811e060cc95" +[[package]] +name = "autocfg" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" + [[package]] name = "base64" version = "0.22.1" @@ -62,6 +68,7 @@ version = "0.1.0" dependencies = [ "anyhow", "base64", + "num-bigint", "openssl", "serde", "serde_json", @@ -79,6 +86,34 @@ version = "2.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3" +[[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.46" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" +dependencies = [ + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" version = "1.20.2" diff --git a/Cargo.toml b/Cargo.toml index e360829..f62f21e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,6 +7,7 @@ rust = "1.75" [dependencies] anyhow = "1.0.90" base64 = "0.22.1" +num-bigint = "0.4.6" openssl = "0.10.68" serde = { version = "1.0.210", features = ["derive"] } serde_json = "1.0" diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index fda7a24..9104114 100644 --- a/src/tasks/tasks01/gfmul.rs +++ b/src/tasks/tasks01/gfmul.rs @@ -1,20 +1,38 @@ use anyhow::Result; use base64::prelude::*; +//use num_bigint::{BigUint, ToBigUint}; use serde_json::Value; -use crate::utils::poly::{b64_2_num, coefficient_to_binary}; +use crate::utils::{ + math::ByteArray, + poly::{b64_2_num, coefficient_to_binary}, +}; + +pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000; pub fn gfmul(args: &Value) -> Result { eprintln!("{args}"); // Generate reduction polynomial - let reduction_polynomial_coeffs: Vec = vec![7, 2, 1, 0]; - let red_poly_num: u128 = 340282366920938463463374607431768211591; //coefficient_to_binary(reduction_polynomial_coeffs); - //eprintln!("{:?}", serde_json::from_value(args["a"].clone())?); + let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec()); + eprintln!("Before push {:01X?}", red_poly_bytes); + red_poly_bytes.0.push(0x01); + //red_poly_bytes.0.reverse(); + eprintln!("After push {:01X?}", red_poly_bytes); + //let red_poly_num = ; //coefficient_to_binary(reduction_polynomial_coeffs); + //eprintln!("{:?}", serde_json::from_value(args["a"].clone())?); - let mut poly1: u128 = b64_2_num(&serde_json::from_value(args["a"].clone())?)?; - let poly2: u128 = b64_2_num(&serde_json::from_value(args["b"].clone())?)?; - eprintln!("poly1 is: {}", poly1); - eprintln!("poly2 is: {}", poly2); + let poly1_text: String = serde_json::from_value(args["a"].clone())?; + let mut poly1: ByteArray = ByteArray(BASE64_STANDARD.decode(poly1_text)?); + poly1.0.push(0x00); + //poly1.0.reverse(); + + let poly2_text: String = serde_json::from_value(args["b"].clone())?; + let mut poly2: ByteArray = ByteArray(BASE64_STANDARD.decode(poly2_text)?); + poly2.0.push(0x00); + //poly2.0.reverse(); + + eprintln!("poly1 is: {:01X?}", poly1); + eprintln!("poly2 is: {:01X?}", poly2); /* Begin of magic algorithm * poly1 = a = X = V ??? @@ -22,26 +40,51 @@ pub fn gfmul(args: &Value) -> Result { * result = Z */ - let mut result: u128 = 0; + 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 >> 1) & 1) == 1 { - eprintln!("ALHIGLIWhlighliwfhlihliawfhliawfhli"); - result ^= poly1; + if poly2.LSB_is_one() { + result.xor_byte_arrays(&poly1); } - for i in 2..128 { - if ((poly2 >> i) & 1) == 1 { - poly1 = (poly1 << 1) ^ red_poly_num; - result ^= poly1; + while !poly2.is_empty() { + if !poly2.LSB_is_one() { + poly1.left_shift(); + poly1.xor_byte_arrays(&red_poly_bytes); + eprintln!("Poly1 after reduction: {:01X?}", poly1); + result.xor_byte_arrays(&poly1); + eprintln!( + "LSB was one; \n + poly1 is {:01X?}; \n + poly2 is {:01X?}; \n + result is: {:01X?}", + poly1.0, poly2.0, result.0 + ) } else { - poly1 = (poly1 << 1) ^ red_poly_num; + poly1.left_shift(); + poly1.xor_byte_arrays(&red_poly_bytes); + eprintln!( + "LSB was 0; \n + poly1 is {:01X?}; \n + poly2 is {:01X?}; \n + result is: {:01X?}", + poly1.0, poly2.0, result.0 + ) } + poly2.right_shift(); } + //result.xor_byte_arrays(&red_poly_bytes); + //result.xor_byte_arrays(&red_poly_bytes); + eprintln!("Result after last red {:01X?}", &result.0); - poly1 = (poly1 << 1) ^ red_poly_num; - result ^= poly1; + eprintln!( + "Should be: {:01X?}", + ByteArray(BASE64_STANDARD.decode("hSQAAAAAAAAAAAAAAAAAAA==")?) + ); + result.0.remove(16); + let mut bytes: [u8; 16] = [0u8; 16]; + bytes.copy_from_slice(&result.0); - Ok(BASE64_STANDARD.encode(result.to_ne_bytes())) + Ok(BASE64_STANDARD.encode(bytes)) } #[cfg(test)] diff --git a/src/utils/math.rs b/src/utils/math.rs index b9c8f84..4392b86 100644 --- a/src/utils/math.rs +++ b/src/utils/math.rs @@ -1,4 +1,4 @@ -use anyhow::Result; +use anyhow::{Ok, Result}; pub fn xor_bytes(vec1: &Vec, mut vec2: Vec) -> Result> { for (byte1, byte2) in vec1.iter().zip(vec2.iter_mut()) { @@ -7,3 +7,105 @@ 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) -> u8 { + let mut carry = 0u8; + for byte in self.0.iter_mut() { + let new_carry = *byte >> 7; + *byte = (*byte << 1) | carry; + carry = new_carry; + } + carry + } + + 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; + } + carry + } + + 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 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(); + + assert_eq!(byte_array.0, shifted_array.0); + } + + #[test] + fn test_byte_array_shift2() { + let mut byte_array: ByteArray = ByteArray(vec![0x00, 0xFF]); + let shifted_array: ByteArray = ByteArray(vec![0x01, 0xFE]); + byte_array.left_shift(); + + assert_eq!( + byte_array.0, shifted_array.0, + "Failure: Shifted array was: {:?}", + byte_array.0 + ); + } + + #[test] + fn test_lsb_one() { + let mut byte_array: ByteArray = ByteArray(vec![0x00, 0xFF]); + assert!(byte_array.LSB_is_one()); + + let mut byte_array2: ByteArray = ByteArray(vec![0x00, 0x02]); + assert!(!byte_array2.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/poly.rs b/src/utils/poly.rs index 5e3efec..5ee7181 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,7 +1,7 @@ use anyhow::Result; use base64::prelude::*; -use std::{str::FromStr, u128, u8}; +use std::{str::FromStr, u128, u8, usize}; pub fn get_alpha_rep(num: u128) -> String { let powers: Vec = get_coefficients(num); @@ -55,6 +55,16 @@ pub fn get_bit_indices_from_byte(byte: u8) -> Vec { coefficients } +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 +} + pub fn coefficient_to_binary(coefficients: Vec) -> u128 { let mut binary_number: u128 = 0; for coeff in coefficients { @@ -71,6 +81,24 @@ mod tests { // Note this useful idiom: importing names from outer (for mod tests) scope. use super::*; + #[test] + fn coefficients_to_byte_arr_xex_test1() { + let coefficients: Vec = vec![0]; + let byte_array = vec![ + 01, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, + ]; + assert_eq!(coefficients_to_byte_arr_xex(coefficients), byte_array) + } + + #[test] + fn coefficients_to_byte_arr_xex_test2() { + let coefficients: Vec = vec![127, 12, 9, 0]; + let byte_array = vec![ + 01, 12, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 80, + ]; + assert_eq!(coefficients_to_byte_arr_xex(coefficients), byte_array) + } + #[test] fn byte_indices_0x01() { let byte: u8 = 0x01;