diff --git a/src/main.rs b/src/main.rs index 59e561b..f546561 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 b024471..bdb2fb0 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -1,11 +1,8 @@ use base64::prelude::*; -use std::{collections::HashMap, env::args}; +use std::collections::HashMap; -use crate::utils::{ - ciphers::gcm_encrypt_aes, - parse::{Responses, Testcase, Testcases}, -}; +use crate::utils::parse::{Responses, Testcase, Testcases}; use tasks01::{ block2poly::block2poly, gcm::{gcm_decrypt, gcm_encrypt}, @@ -14,7 +11,7 @@ use tasks01::{ pfmath::{gfdiv, gfpoly_add, gfpoly_divmod, gfpoly_mul, gfpoly_pow, gfpoly_powmod}, 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 dbdaf66..3e636eb 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; diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index 2c1d6b8..70ab788 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::*; diff --git a/src/tasks/tasks01/pad_oracle.rs b/src/tasks/tasks01/pad_oracle.rs index 64eb2d1..90e4295 100644 --- a/src/tasks/tasks01/pad_oracle.rs +++ b/src/tasks/tasks01/pad_oracle.rs @@ -3,8 +3,8 @@ use base64::prelude::*; use serde_json::Value; use std::io::prelude::*; use std::net::TcpStream; -use std::time::{Duration, Instant}; -use std::{thread, usize}; +use std::time::Instant; +use std::usize; pub fn padding_oracle(args: &Value) -> Result> { let hostname: String = serde_json::from_value(args["hostname"].clone())?; @@ -29,8 +29,6 @@ pub fn padding_oracle(args: &Value) -> Result> { let mut chunk_counter = 0; for chunk in &cipher_chunks { - let start = Instant::now(); - let mut stream = TcpStream::connect(format!("{}:{}", hostname, port))?; stream.set_nonblocking(false)?; @@ -111,12 +109,12 @@ pub fn padding_oracle(args: &Value) -> Result> { } else { //eprintln!("Invalid padding"); // Search for second hit - let valid_val = (255 + let valid_val = 255 - server_q_resp .iter() .rev() .position(|&r| r == 0x01) - .unwrap_or(0x00) as u8); + .unwrap_or(0x00) as u8; if valid_val == 0x00 { eprintln!("No valid found"); } 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..6d76909 100644 --- a/src/tasks/tasks01/sea128.rs +++ b/src/tasks/tasks01/sea128.rs @@ -12,7 +12,6 @@ pub fn sea128(args: &Value) -> Result { let input_string: String = serde_json::from_value(args["input"].clone())?; //let plaintexts: &[u8] = &b64_2_num(plaintexts_string)?.to_ne_bytes(); let input = BASE64_STANDARD.decode(input_string)?; - let xor_val: u128 = 0xc0ffeec0ffeec0ffeec0ffeec0ffee11; let mode: String = serde_json::from_value(args["mode"].clone())?; match mode.as_str() { @@ -34,7 +33,6 @@ 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 333ec13..35181a5 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -1,6 +1,4 @@ -use std::{io::BufRead, process::Output}; - -use crate::utils::{field::ByteArray, math::reverse_bits_in_bytevec, poly::gfmul}; +use crate::utils::{field::ByteArray, poly::gfmul}; use anyhow::Result; use base64::prelude::*; use openssl::symm::{Cipher, Crypter, Mode}; @@ -40,7 +38,6 @@ pub fn aes_128_decrypt(key: &Vec, input: &Vec) -> Result> { let mut bytes: [u8; 16] = [0u8; 16]; bytes.copy_from_slice(&plaintext); - let number: u128 = ::from_be_bytes(bytes); Ok(plaintext) } diff --git a/src/utils/field.rs b/src/utils/field.rs index fac51f2..3bd1c89 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -1,14 +1,10 @@ -use std::{ - env::args, - ops::{Add, BitXor, Div, Mul, Rem, Sub}, - result, -}; +use std::ops::{Add, BitXor, Div, Mul, Sub}; use anyhow::{anyhow, Ok, Result}; use base64::prelude::*; use serde_json::Value; -use crate::{tasks::tasks01::poly2block::poly2block, utils::poly::polynomial_2_block}; +use crate::utils::poly::polynomial_2_block; use super::{math::xor_bytes, poly::gfmul}; @@ -58,7 +54,9 @@ impl Polynomial { pub fn pow(&self, mut exponent: u128) -> Polynomial { if exponent == 0 { - return Polynomial::new(vec![FieldElement::new(vec![0])]); + return Polynomial::new(vec![FieldElement::new( + polynomial_2_block(vec![0], "gcm").unwrap(), + )]); } let base = self.clone(); @@ -73,6 +71,12 @@ impl Polynomial { } pub fn pow_mod(mut self, mut exponent: u128, modulus: Polynomial) -> Polynomial { + if exponent == 0 { + return Polynomial::new(vec![FieldElement::new( + polynomial_2_block(vec![0], "gcm").unwrap(), + )]); + } + let mut result: Polynomial = Polynomial::new(vec![FieldElement::new( polynomial_2_block(vec![0], "gcm").unwrap(), )]); @@ -99,6 +103,12 @@ impl Polynomial { pub fn div(self, rhs: &Self) -> (Self, Self) { // Div by zero check ommitted since data is guaranteed to be non 0 + eprintln!("{:?}, {:?}", self.polynomial.len(), rhs.polynomial.len()); + + if self.polynomial.len() < rhs.polynomial.len() { + return (Polynomial::new(vec![FieldElement::new(vec![0; 16])]), self); + } + let mut remainder = self.clone(); let divisor = rhs; let dividend_deg = remainder.polynomial.len() - 1; @@ -155,6 +165,15 @@ impl Polynomial { (Polynomial::new(quotient_coeffs), remainder) } + + fn is_zero(&self) -> bool { + for field_element in &self.polynomial { + if !field_element.is_zero() { + return false; + } + } + true + } } impl Clone for Polynomial { @@ -167,8 +186,10 @@ impl Clone for Polynomial { impl Mul for Polynomial { type Output = Self; - fn mul(self, rhs: Self) -> Self::Output { + if self.is_zero() || rhs.is_zero() { + return Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + } let mut polynomial: Vec = vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1]; for i in 0..self.polynomial.len() { @@ -184,6 +205,9 @@ impl Mul for Polynomial { impl Mul for &Polynomial { type Output = Polynomial; fn mul(self, rhs: Self) -> Self::Output { + if self.is_zero() || rhs.is_zero() { + return Polynomial::new(vec![FieldElement::new(vec![0])]); + } let mut polynomial: Vec = vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1]; for i in 0..self.polynomial.len() { @@ -300,6 +324,10 @@ impl FieldElement { //eprintln!("Inverse rhs {:?}", inverse); FieldElement::new(inverse) } + + fn is_zero(&self) -> bool { + self.field_element.iter().all(|&x| x == 0x00) + } } impl Mul for FieldElement { @@ -522,15 +550,13 @@ impl ByteArray { #[cfg(test)] mod tests { use super::*; - use base64::prelude::*; use serde_json::json; - 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"); + byte_array.left_shift("xex").unwrap(); assert_eq!(byte_array.0, shifted_array.0); } @@ -539,7 +565,7 @@ mod tests { 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"); + byte_array.left_shift("xex").unwrap(); assert_eq!( byte_array.0, shifted_array.0, @@ -552,7 +578,7 @@ mod tests { 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"); + byte_array.left_shift("gcm").unwrap(); assert_eq!( byte_array.0, shifted_array.0, @@ -565,7 +591,7 @@ mod tests { 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"); + byte_array.right_shift("gcm").unwrap(); assert_eq!( byte_array.0, shifted_array.0, @@ -578,7 +604,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("xex"); + byte_array.right_shift("xex").unwrap(); assert_eq!( byte_array.0, shifted_array.0, @@ -666,6 +692,68 @@ mod tests { ); } + #[test] + fn test_field_add_zero() { + let json1 = json!([ + "NeverGonnaGiveYouUpAAA==", + "NeverGonnaLetYouDownAA==", + "NeverGonnaRunAroundAAA==", + "AndDesertYouAAAAAAAAAA==" + ]); + let json2 = json!(["AAAAAAAAAAAAAAAAAAAAAA=="]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + let element2: Polynomial = Polynomial::from_c_array(&json2); + + let sum = element2 + element1; + + assert_eq!( + sum.to_c_array(), + vec![ + "NeverGonnaGiveYouUpAAA==", + "NeverGonnaLetYouDownAA==", + "NeverGonnaRunAroundAAA==", + "AndDesertYouAAAAAAAAAA==" + ] + ); + } + + #[test] + fn test_field_add_zero_to_zero() { + let json1 = json!(["AAAAAAAAAAAAAAAAAAAAAA=="]); + let json2 = json!(["AAAAAAAAAAAAAAAAAAAAAA=="]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + let element2: Polynomial = Polynomial::from_c_array(&json2); + + let sum = element2 + element1; + + assert_eq!(sum.to_c_array(), vec!["AAAAAAAAAAAAAAAAAAAAAA=="]); + } + + #[test] + fn test_field_add_short_to_long() { + let json1 = json!(["AAAAAAAAAAAAAAAAAAAAAA=="]); + let json2 = json!([ + "NeverGonnaGiveYouUpAAA==", + "NeverGonnaLetYouDownAA==", + "NeverGonnaRunAroundAAA==", + "AndDesertYouAAAAAAAAAA==" + ]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + let element2: Polynomial = Polynomial::from_c_array(&json2); + + let sum = element2 + element1; + + assert_eq!( + sum.to_c_array(), + vec![ + "NeverGonnaGiveYouUpAAA==", + "NeverGonnaLetYouDownAA==", + "NeverGonnaRunAroundAAA==", + "AndDesertYouAAAAAAAAAA==" + ] + ); + } + #[test] fn test_field_mul_01() { let json1 = json!([ @@ -694,7 +782,26 @@ mod tests { } #[test] - fn test_field_pow_01() { + fn test_poly_mul_with_zero() { + let json1 = json!([ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ]); + let json2 = json!(["AAAAAAAAAAAAAAAAAAAAAA=="]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + let element2: Polynomial = Polynomial::from_c_array(&json2); + + //eprintln!("{:?}", element1); + + let result = element1 * element2; + + assert_eq!(result.to_c_array(), vec!["AAAAAAAAAAAAAAAAAAAAAA=="]); + //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); + } + + #[test] + fn test_poly_pow_01() { let json1 = json!([ "JAAAAAAAAAAAAAAAAAAAAA==", "wAAAAAAAAAAAAAAAAAAAAA==", @@ -719,6 +826,21 @@ mod tests { //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); } + #[test] + fn test_poly_pow_with_zero() { + let json1 = json!([ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + + let result = element1.pow(0); + + assert_eq!(result.to_c_array(), vec!["gAAAAAAAAAAAAAAAAAAAAA=="]); + //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); + } + #[test] fn test_field_pow_mod_01() { let json1 = json!([ @@ -745,6 +867,38 @@ mod tests { //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); } + #[test] + fn test_field_pow_mod_with_zero() { + let json1 = json!([ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + + let result = element1.pow(0); + + assert_eq!(result.to_c_array(), vec!["gAAAAAAAAAAAAAAAAAAAAA=="]); + //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); + } + + #[test] + fn test_field_pow_mod_10mill() { + let json1 = json!([ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ]); + let json2 = json!(["KryptoanalyseAAAAAAAAA==", "DHBWMannheimAAAAAAAAAA=="]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + let modulus: Polynomial = Polynomial::from_c_array(&json2); + + let result = element1.pow_mod(10000000, modulus); + + assert!(!result.is_zero()) + //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); + } + #[test] fn test_poly_div_01() { let element1 = @@ -782,6 +936,29 @@ mod tests { //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); } + #[test] + fn test_field_poly_div_larger_div() { + let json1 = json!([ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ]); + let json2 = json!(["0AAAAAAAAAAAAAAAAAAAAA==", "IQAAAAAAAAAAAAAAAAAAAA=="]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + let element2: Polynomial = Polynomial::from_c_array(&json2); + + //eprintln!("{:?}", element1); + + println!("Beginning the new division"); + let (result, remainder) = element2.div(&element1); + + assert_eq!(result.to_c_array(), vec!["AAAAAAAAAAAAAAAAAAAAAA=="]); + assert_eq!( + remainder.to_c_array(), + vec!["0AAAAAAAAAAAAAAAAAAAAA==", "IQAAAAAAAAAAAAAAAAAAAA=="] + ); + //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); + } #[test] fn test_field_poly_powmod_01() { let json1 = json!([ @@ -796,6 +973,6 @@ mod tests { let result = element1.pow_mod(1000, modulus); eprintln!("Result is: {:02X?}", result); - assert_eq!(result.to_c_array(), vec!["XrEhmKuat+Glt5zZWtMo6g=="]); + assert_eq!(result.to_c_array(), vec!["oNXl5P8xq2WpUTP92u25zg=="]); } } diff --git a/src/utils/math.rs b/src/utils/math.rs index cf87e0c..c1809e2 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..6e5d2dd 100644 --- a/src/utils/parse.rs +++ b/src/utils/parse.rs @@ -28,8 +28,6 @@ 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 6425577..3866e49 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, math::reverse_bits_in_bytevec}; pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000; pub fn gfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result> { @@ -172,7 +170,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