From dd19c90ae12045774321d3d369874cc92e2cb2d7 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Thu, 28 Nov 2024 15:10:02 +0100 Subject: [PATCH 01/28] refactor: Apply cargo recommended refactoring --- src/tasks/tasks01/pfmath.rs | 12 ++++-------- src/utils/dff.rs | 2 +- src/utils/edf.rs | 4 +--- src/utils/field.rs | 1 - src/utils/poly.rs | 3 +-- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/src/tasks/tasks01/pfmath.rs b/src/tasks/tasks01/pfmath.rs index 0f5d134..6830e1a 100644 --- a/src/tasks/tasks01/pfmath.rs +++ b/src/tasks/tasks01/pfmath.rs @@ -1,20 +1,16 @@ -use std::usize; use anyhow::Result; use base64::{prelude::BASE64_STANDARD, Engine}; use serde_json::Value; -use crate::{ - tasks, - utils::{ +use crate::utils::{ self, dff::ddf, edf::edf, field::FieldElement, poly::{gcd, Polynomial}, sff::{sff, Factors}, - }, -}; + }; pub fn gfpoly_add(args: &Value) -> Result { let poly_a = Polynomial::from_c_array(&args["A"].clone()); @@ -126,7 +122,7 @@ pub fn gfpoly_gcd(args: &Value) -> Result { Ok(result) } -pub fn gfpoly_factor_sff(arsg: &Value) -> Result> { +pub fn gfpoly_factor_sff(arsg: &Value) -> Result> { let poly_f = Polynomial::from_c_array(&arsg["F"].clone()); let mut factors = sff(poly_f); @@ -143,7 +139,7 @@ pub fn gfpoly_factor_sff(arsg: &Value) -> Result> { Ok(result) } -pub fn gfpoly_factor_ddf(arsg: &Value) -> Result> { +pub fn gfpoly_factor_ddf(arsg: &Value) -> Result> { let poly_f = Polynomial::from_c_array(&arsg["F"].clone()); let mut factors = ddf(poly_f); diff --git a/src/utils/dff.rs b/src/utils/dff.rs index be63040..bcd1ca0 100644 --- a/src/utils/dff.rs +++ b/src/utils/dff.rs @@ -1,6 +1,6 @@ use std::usize; -use num::{cast::AsPrimitive, pow::Pow, traits::ToBytes, BigUint, FromPrimitive}; +use num::{pow::Pow, BigUint, FromPrimitive}; use serde::{Deserialize, Serialize}; use super::poly::{gcd, Polynomial}; diff --git a/src/utils/edf.rs b/src/utils/edf.rs index 134a743..80f552c 100644 --- a/src/utils/edf.rs +++ b/src/utils/edf.rs @@ -1,8 +1,6 @@ -use base64::{prelude::BASE64_STANDARD, Engine}; -use num::{BigUint, FromPrimitive, Integer, One}; +use num::{BigUint, FromPrimitive, One}; use rand::Rng; -use crate::utils::{field::FieldElement, poly::non_monic_gcd}; use super::poly::{gcd, Polynomial}; diff --git a/src/utils/field.rs b/src/utils/field.rs index 2dea48b..dd2e982 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -1,5 +1,4 @@ use base64::prelude::*; -use rand::{random, Rng, RngCore}; use std::{u128, u8, usize}; use std::{ diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 48242ab..ac2b756 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,7 +1,6 @@ use crate::utils::field::ByteArray; -use base64::alphabet::BIN_HEX; use base64::prelude::*; -use num::{BigInt, BigUint, One, Zero}; +use num::{BigUint, One, Zero}; use std::{str::FromStr, u128, u8, usize}; use std::{ From 270abdb7b726ad37166da7b5a5685e53fe16d756 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Thu, 28 Nov 2024 17:45:10 +0100 Subject: [PATCH 02/28] refactor: Change gcd implementation to attempt faster calc --- src/utils/poly.rs | 16 ++++++++++++++-- test_json/sandbox.json | 16 ++++++++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 48242ab..5b4d86f 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -576,9 +576,21 @@ pub fn gcd(a: &Polynomial, b: &Polynomial) -> Polynomial { if a.is_zero() { return b.clone(); } + if b.is_zero() { + return a.clone(); + } - let monic_b = b.div(&a).1.monic(); - return gcd(&monic_b, a); + if a.degree() > b.degree() { + return gcd(b, a); + } + + let (_, remainder) = b.div(a); + + if remainder.is_zero() { + return a.clone().monic(); + } + + gcd(&remainder, a) } pub fn non_monic_gcd(a: &Polynomial, b: &Polynomial) -> Polynomial { diff --git a/test_json/sandbox.json b/test_json/sandbox.json index d0a0f3c..836b3c8 100644 --- a/test_json/sandbox.json +++ b/test_json/sandbox.json @@ -1,18 +1,18 @@ { "testcases": { "sandbox": { - "action": "gfpoly_factor_ddf", + "action": "gfpoly_factor_edf", "arguments": { "F": [ - "tpkgAAAAAAAAAAAAAAAAAA==", - "m6MQAAAAAAAAAAAAAAAAAA==", - "8roAAAAAAAAAAAAAAAAAAA==", - "3dUAAAAAAAAAAAAAAAAAAA==", + "mmAAAAAAAAAAAAAAAAAAAA==", + "AbAAAAAAAAAAAAAAAAAAAA==", + "zgAAAAAAAAAAAAAAAAAAAA==", "FwAAAAAAAAAAAAAAAAAAAA==", - "/kAAAAAAAAAAAAAAAAAAAA==", - "a4AAAAAAAAAAAAAAAAAAAA==", + "AAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", "gAAAAAAAAAAAAAAAAAAAAA==" - ] + ], + "d": 3 } } } From 5b27a4ad9c9b1dad0ea34e94c03e4578c98243d9 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Fri, 29 Nov 2024 13:49:57 +0100 Subject: [PATCH 03/28] feat/refactor: Change unneded vec initialisations and start on possible new gfmul --- src/utils/field.rs | 28 ++++++++++-------- src/utils/poly.rs | 72 +++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 81 insertions(+), 19 deletions(-) diff --git a/src/utils/field.rs b/src/utils/field.rs index 2dea48b..7b4059c 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -9,6 +9,8 @@ use std::{ use anyhow::{anyhow, Ok, Result}; +use crate::utils::poly::bgfmul; + use super::poly::polynomial_2_block; use super::{ math::{reverse_bits_in_bytevec, xor_bytes}, @@ -22,7 +24,7 @@ pub struct FieldElement { impl FieldElement { pub const IRREDUCIBLE_POLYNOMIAL: [u8; 17] = [ - 87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, + 0x87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01, ]; pub fn rand() -> Self { @@ -30,10 +32,14 @@ impl FieldElement { FieldElement::new(rand_field.to_vec()) } - pub fn zero(self) -> Self { + pub fn zero() -> Self { FieldElement::new(vec![0]) } + pub fn one() -> Self { + FieldElement::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + } + pub const fn new(field_element: Vec) -> Self { Self { field_element } } @@ -47,8 +53,7 @@ impl FieldElement { } pub fn pow(mut self, mut exponent: u128) -> FieldElement { - let mut result: FieldElement = - FieldElement::new(polynomial_2_block(vec![0], "gcm").unwrap()); + let mut result: FieldElement = FieldElement::one(); if exponent == 1 { eprintln!("special case 1: {:02X?}", self.clone()); @@ -57,7 +62,7 @@ impl FieldElement { } if exponent == 0 { - let result = FieldElement::new(polynomial_2_block(vec![0], "gcm").unwrap()); + let result = FieldElement::one(); eprintln!("Returned value is: {:02X?}", result); return result; @@ -90,8 +95,10 @@ impl FieldElement { } pub fn inv(mut self) -> Self { - let mut inverser: u128 = 0xfffffffffffffffffffffffffffffffe; - let mut inverse: Vec = polynomial_2_block(vec![0], "gcm").unwrap(); + const INVERSER_START: u128 = 0xfffffffffffffffffffffffffffffffe; + + let mut inverser = INVERSER_START; + let mut inverse: Vec = vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //eprintln!("Inverse start {:02X?}", inverse); while inverser > 0 { @@ -187,7 +194,7 @@ impl Div for FieldElement { type Output = Self; fn div(self, rhs: Self) -> Self::Output { let inverse = rhs.inv(); - self.clone() * inverse + self * inverse } } @@ -195,10 +202,7 @@ impl Div for &FieldElement { type Output = FieldElement; fn div(self, rhs: Self) -> Self::Output { - // First clone and invert the divisor (rhs) - let rhs_inv = rhs.clone().inv(); - // Multiply original number by the inverse - self.clone() * rhs_inv + self.clone() * rhs.clone().inv() } } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 5b4d86f..82e991a 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,6 +1,7 @@ use crate::utils::field::ByteArray; use base64::alphabet::BIN_HEX; use base64::prelude::*; +use num::traits::FromBytes; use num::{BigInt, BigUint, One, Zero}; use std::{str::FromStr, u128, u8, usize}; @@ -13,6 +14,7 @@ use anyhow::{anyhow, Ok, Result}; use serde_json::Value; use super::field::FieldElement; +use super::math::reverse_bits_in_bytevec; #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct Polynomial { @@ -291,10 +293,7 @@ impl Polynomial { } let mut quotient_coeffs = - vec![ - FieldElement::new(polynomial_2_block(vec![0; 16], "gcm").unwrap()); - dividend_deg - divisor_deg + 1 - ]; + vec![FieldElement::new(vec![0; 16]); dividend_deg - divisor_deg + 1]; while remainder.polynomial.len() >= divisor.polynomial.len() { let deg_diff = remainder.polynomial.len() - divisor.polynomial.len(); @@ -305,8 +304,7 @@ impl Polynomial { quotient_coeffs[deg_diff] = quot_coeff.clone(); - let mut subtrahend = - vec![FieldElement::new(polynomial_2_block(vec![0; 16], "gcm").unwrap()); deg_diff]; + let mut subtrahend = vec![FieldElement::new(vec![0; 16]); deg_diff]; subtrahend.extend( divisor .polynomial @@ -658,6 +656,53 @@ pub fn gfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result, poly_b: &Vec, semantic: &str) -> Result> { + //TODO: Implement gfmul with bigint + let red_poly_bytes: BigUint = BigUint::from_slice(&[ + 0x87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01, + ]); + + let mut poly1: BigUint = BigUint::from_le_bytes(&reverse_bits_in_bytevec(poly_a.to_owned())); + + let mut poly2: BigUint = BigUint::from_le_bytes(&reverse_bits_in_bytevec(poly_b.to_owned())); + + /* + if semantic == "gcm" { + poly1.re; + poly2.reverse_bits_in_bytevec(); + } + */ + + let mut result: BigUint = BigUint::zero(); + + if (&poly2 & (BigUint::one() << 127)) == BigUint::one() { + result = &result ^ &poly1; + } + poly2 = &poly2 >> 1; + + while &poly2 != &BigUint::zero() { + poly1 = &poly1 << 1; + + if (&poly1 & (BigUint::one() << 127)) == BigUint::one() { + poly1 = &poly1 ^ &red_poly_bytes; + } + + if &poly2 & BigUint::one() == BigUint::one() { + result = &result ^ &poly1; + } + + poly2 = &poly2 >> 1; + } + + /* + if semantic == "gcm" { + result.reverse_bits_in_bytevec(); + } + */ + + Ok(reverse_bits_in_bytevec(result.to_bytes_le())) +} + pub fn convert_gcm_to_xex(gcm_poly: Vec) -> Result> { let xex_poly = gcm_poly .into_iter() @@ -795,7 +840,7 @@ pub fn coefficient_to_binary(coefficients: Vec) -> u128 { #[cfg(test)] mod tests { - use crate::utils::poly::b64_2_num; + use crate::utils::poly::{b64_2_num, gcd}; use anyhow::Result; use serde_json::json; // Note this useful idiom: importing names from outer (for mod tests) scope. @@ -1429,4 +1474,17 @@ mod tests { assert_eq!(json!(result.to_c_array()), expected); } + + #[test] + fn test_poly_gcd_stress() { + eprintln!("{:?}", Polynomial::one()); + + let poly1 = Polynomial::rand(&(500 as usize)); + let poly2 = Polynomial::rand(&(500 as usize)); + + let result = gcd(&poly1.monic(), &poly2.monic()); + + eprintln!("{:02X?}", result.to_c_array()); + assert!(true); + } } From e8c9cb1ade5853862f2bf63c5902580f2e61b51a Mon Sep 17 00:00:00 2001 From: Alivecow Date: Fri, 29 Nov 2024 14:31:52 +0100 Subject: [PATCH 04/28] refactor: Imrpove gfmul to remove unneded vec manipulation and imporve performanve --- src/utils/poly.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 82e991a..eeffc34 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -613,20 +613,20 @@ 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); + //red_poly_bytes.0.push(0x01); let mut poly1: ByteArray = ByteArray(poly_a.to_owned()); - poly1.0.push(0x00); + //poly1.0.push(0x00); let mut poly2: ByteArray = ByteArray(poly_b.to_owned()); - poly2.0.push(0x00); + //poly2.0.push(0x00); if semantic == "gcm" { poly1.reverse_bits_in_bytevec(); poly2.reverse_bits_in_bytevec(); } - 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(vec![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); @@ -634,9 +634,9 @@ pub fn gfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result, poly_b: &Vec, semantic: &str) -> Result Date: Fri, 29 Nov 2024 16:50:19 +0100 Subject: [PATCH 05/28] refactor: Change implementation to only switch semantic once --- src/utils/field.rs | 57 ++++++++++++++++++++++++++-------------- src/utils/poly.rs | 65 +++++++++++++++------------------------------- 2 files changed, 59 insertions(+), 63 deletions(-) diff --git a/src/utils/field.rs b/src/utils/field.rs index 9b9876b..7d40732 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -28,18 +28,24 @@ impl FieldElement { pub fn rand() -> Self { let rand_field: [u8; 16] = rand::random(); - FieldElement::new(rand_field.to_vec()) + FieldElement::new_no_convert(rand_field.to_vec()) } pub fn zero() -> Self { - FieldElement::new(vec![0]) + FieldElement::new_no_convert(vec![0; 16]) } pub fn one() -> Self { - FieldElement::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) + FieldElement::new_no_convert(vec![0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) } - pub const fn new(field_element: Vec) -> Self { + pub fn new(field_element: Vec) -> Self { + Self { + field_element: reverse_bits_in_bytevec(field_element), + } + } + + pub fn new_no_convert(field_element: Vec) -> Self { Self { field_element } } @@ -48,7 +54,7 @@ impl FieldElement { } pub fn to_b64(&self) -> String { - BASE64_STANDARD.encode(&self.field_element) + BASE64_STANDARD.encode(reverse_bits_in_bytevec(self.field_element.to_owned())) } pub fn pow(mut self, mut exponent: u128) -> FieldElement { @@ -97,20 +103,20 @@ impl FieldElement { const INVERSER_START: u128 = 0xfffffffffffffffffffffffffffffffe; let mut inverser = INVERSER_START; - let mut inverse: Vec = vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + let mut inverse: Vec = vec![0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; //eprintln!("Inverse start {:02X?}", inverse); while inverser > 0 { //eprintln!("{:02X}", inverser); if inverser & 1 == 1 { - inverse = gfmul(&self.field_element, &inverse, "gcm").unwrap(); + inverse = gfmul(&self.field_element, &inverse, "xex").unwrap(); } inverser >>= 1; - self.field_element = gfmul(&self.field_element, &self.field_element, "gcm") + self.field_element = gfmul(&self.field_element, &self.field_element, "xex") .expect("Error in sqrmul sqr"); } //eprintln!("Inverse rhs {:?}", inverse); - FieldElement::new(inverse) + FieldElement::new_no_convert(inverse) } pub fn is_zero(&self) -> bool { @@ -118,7 +124,7 @@ impl FieldElement { } pub fn reverse_bits(&self) -> Self { - FieldElement::new(reverse_bits_in_bytevec(self.field_element.clone())) + FieldElement::new_no_convert(reverse_bits_in_bytevec(self.field_element.clone())) } } @@ -126,8 +132,8 @@ impl Mul for FieldElement { type Output = Self; fn mul(self, rhs: Self) -> Self::Output { - FieldElement::new( - gfmul(&self.field_element, &rhs.field_element, "gcm") + FieldElement::new_no_convert( + gfmul(&self.field_element, &rhs.field_element, "xex") .expect("Error during multiplication"), ) } @@ -137,8 +143,8 @@ impl Mul for &FieldElement { type Output = FieldElement; fn mul(self, rhs: &FieldElement) -> FieldElement { - FieldElement::new( - gfmul(&self.field_element, &rhs.field_element, "gcm") + FieldElement::new_no_convert( + gfmul(&self.field_element, &rhs.field_element, "xex") .expect("Error during multiplication"), ) } @@ -147,7 +153,7 @@ impl Mul for &FieldElement { impl Add for FieldElement { type Output = Self; fn add(self, rhs: Self) -> Self::Output { - FieldElement::new( + FieldElement::new_no_convert( xor_bytes(&self.field_element, rhs.field_element).expect("Error in poly add"), ) } @@ -156,7 +162,7 @@ impl Add for FieldElement { impl Add for &FieldElement { type Output = FieldElement; fn add(self, rhs: Self) -> Self::Output { - FieldElement::new( + FieldElement::new_no_convert( xor_bytes(&self.field_element, rhs.field_element.clone()).expect("Error in poly add"), ) } @@ -185,7 +191,7 @@ impl BitXor for FieldElement { .zip(rhs.field_element.iter()) .map(|(&x1, &x2)| x1 ^ x2) .collect(); - FieldElement::new(result) + FieldElement::new_no_convert(result) } } @@ -450,7 +456,7 @@ mod tests { FieldElement::new(BASE64_STANDARD.decode("KryptoanalyseAAAAAAAAA==").unwrap()); let sum = element2 + element1; - assert_eq!(BASE64_STANDARD.encode(sum), "H1d3GuyA9/0OxeYouUpAAA=="); + assert_eq!(sum.to_b64(), "H1d3GuyA9/0OxeYouUpAAA=="); } #[test] @@ -461,6 +467,19 @@ mod tests { FieldElement::new(BASE64_STANDARD.decode("DHBWMannheimAAAAAAAAAA==").unwrap()); let sum = element2 + element1; - assert_eq!(BASE64_STANDARD.encode(sum), "OZuIncPAGEp4tYouDownAA=="); + assert_eq!(sum.to_b64(), "OZuIncPAGEp4tYouDownAA=="); + } + + #[test] + fn test_field_div_01() { + let element1 = + FieldElement::new(BASE64_STANDARD.decode("JAAAAAAAAAAAAAAAAAAAAA==").unwrap()); + + let element2 = + FieldElement::new(BASE64_STANDARD.decode("wAAAAAAAAAAAAAAAAAAAAA==").unwrap()); + + let result = element1 / element2; + + assert_eq!(result.to_b64(), "OAAAAAAAAAAAAAAAAAAAAA=="); } } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 68edb82..0d7b122 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -32,15 +32,13 @@ impl Polynomial { } pub fn one() -> Self { - Polynomial::new(vec![FieldElement::new( - polynomial_2_block(vec![0], "gcm").unwrap(), - )]) + Polynomial::new(vec![FieldElement::one()]) } pub fn x() -> Self { Polynomial::new(vec![ FieldElement::new(vec![0; 16]), - FieldElement::new(polynomial_2_block(vec![0], "gcm").unwrap()), + FieldElement::new(polynomial_2_block(vec![0], "xex").unwrap()), ]) } @@ -54,7 +52,7 @@ impl Polynomial { } pub fn zero() -> Self { - Polynomial::new(vec![FieldElement::new(vec![0; 16])]) + Polynomial::new(vec![FieldElement::zero()]) } pub fn from_c_array(array: &Value) -> Self { @@ -85,7 +83,7 @@ impl Polynomial { pub fn to_c_array(self) -> Vec { let mut output: Vec = vec![]; for coeff in self.polynomial { - output.push(BASE64_STANDARD.encode(coeff)); + output.push(coeff.to_b64()); } output @@ -219,9 +217,7 @@ impl Polynomial { } if exponent == 0 { - let result = Polynomial::new(vec![FieldElement::new( - polynomial_2_block(vec![0], "gcm").unwrap(), - )]); + let result = Polynomial::new(vec![FieldElement::one()]); eprintln!("Returned value is: {:02X?}", result); return result; @@ -273,10 +269,7 @@ impl Polynomial { //eprintln!("{:?}, {:?}", self.polynomial.len(), rhs.polynomial.len()); if self.polynomial.len() < rhs.polynomial.len() { - return ( - Polynomial::new(vec![FieldElement::new(vec![0; 16])]), - self.clone(), - ); + return (Polynomial::new(vec![FieldElement::zero()]), self.clone()); } let mut remainder = self.clone(); @@ -285,16 +278,10 @@ impl Polynomial { let divisor_deg = divisor.polynomial.len() - 1; if dividend_deg < divisor_deg { - return ( - Polynomial::new(vec![FieldElement::new( - polynomial_2_block(vec![0; 16], "gcm").unwrap(), - )]), - remainder, - ); + return (Polynomial::new(vec![FieldElement::zero()]), remainder); } - let mut quotient_coeffs = - vec![FieldElement::new(vec![0; 16]); dividend_deg - divisor_deg + 1]; + let mut quotient_coeffs = vec![FieldElement::zero(); dividend_deg - divisor_deg + 1]; while remainder.polynomial.len() >= divisor.polynomial.len() { let deg_diff = remainder.polynomial.len() - divisor.polynomial.len(); @@ -305,7 +292,7 @@ impl Polynomial { quotient_coeffs[deg_diff] = quot_coeff.clone(); - let mut subtrahend = vec![FieldElement::new(vec![0; 16]); deg_diff]; + let mut subtrahend = vec![FieldElement::zero(); deg_diff]; subtrahend.extend( divisor .polynomial @@ -330,7 +317,7 @@ impl Polynomial { } if remainder.is_empty() { - remainder = Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + remainder = Polynomial::new(vec![FieldElement::zero()]); } (Polynomial::new(quotient_coeffs), remainder) } @@ -431,10 +418,10 @@ 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])]); + return Polynomial::zero(); } let mut polynomial: Vec = - vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1]; + vec![FieldElement::zero(); self.polynomial.len() + rhs.polynomial.len() - 1]; for i in 0..self.polynomial.len() { for j in 0..rhs.polynomial.len() { polynomial[i + j] = &polynomial[i + j] @@ -449,10 +436,10 @@ 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])]); + return Polynomial::zero(); } let mut polynomial: Vec = - vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1]; + vec![FieldElement::zero(); self.polynomial.len() + rhs.polynomial.len() - 1]; for i in 0..self.polynomial.len() { for j in 0..rhs.polynomial.len() { polynomial[i + j] = &polynomial[i + j] @@ -486,7 +473,7 @@ impl Add for Polynomial { } if polynomial.is_empty() { - return Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + return Polynomial::new(vec![FieldElement::zero()]); } Polynomial::new(polynomial) @@ -535,8 +522,8 @@ impl PartialOrd for Polynomial { ); match field_a - .reverse_bits() - .partial_cmp(&field_b.reverse_bits()) + //.reverse_bits() + .partial_cmp(&field_b) .unwrap() { Ordering::Equal => continue, @@ -559,7 +546,10 @@ impl Ord for Polynomial { for (field_a, field_b) in self.as_ref().iter().rev().zip(other.as_ref().iter().rev()) { - match field_a.reverse_bits().cmp(&field_b.reverse_bits()) { + match field_a + //.reverse_bits() + .cmp(&field_b) + { Ordering::Equal => continue, other => return other, } @@ -1136,19 +1126,6 @@ mod tests { //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); } - #[test] - fn test_poly_div_01() { - let element1 = - FieldElement::new(BASE64_STANDARD.decode("JAAAAAAAAAAAAAAAAAAAAA==").unwrap()); - - let element2 = - FieldElement::new(BASE64_STANDARD.decode("wAAAAAAAAAAAAAAAAAAAAA==").unwrap()); - - let result = element1 / element2; - - assert_eq!(BASE64_STANDARD.encode(result), "OAAAAAAAAAAAAAAAAAAAAA=="); - } - #[test] fn test_field_poly_div_01() { let json1 = json!([ From 007bbddfcd75532d995909ece70135c026ec36a5 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Fri, 29 Nov 2024 17:22:47 +0100 Subject: [PATCH 06/28] fix: Fix incorrect ouput in gfdiv task --- src/tasks/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 84a4f31..d2c57b7 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -105,7 +105,7 @@ pub fn task_deploy(testcase: &Testcase) -> Result { } "gfdiv" => { let result = gfdiv(args)?; - let out = BASE64_STANDARD.encode(result); + let out = result.to_b64(); let json = json!({"q" : out}); Ok(json) From bf4c3ee4ca71c928e978aafaca2083cdaa7badf7 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Fri, 29 Nov 2024 19:02:37 +0100 Subject: [PATCH 07/28] refactor: Remove unneded prints and change gfmul --- Cargo.toml | 4 ++++ src/utils/ciphers.rs | 37 ------------------------------------- src/utils/edf.rs | 6 ------ src/utils/field.rs | 3 --- src/utils/poly.rs | 31 +++++-------------------------- 5 files changed, 9 insertions(+), 72 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 28fc780..9cf5fa2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -18,3 +18,7 @@ replace-with = "vendored-sources" [source.vendored-sources] directory = "vendor" + +[profile.profiling] +inherits = "release" +debug = true diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index 35181a5..82af34b 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -119,10 +119,8 @@ pub fn gcm_encrypt_aes( let mut counter: u32 = 1; nonce.append(counter.to_be_bytes().to_vec().as_mut()); //nonce.append(0u8.to_le_bytes().to_vec().as_mut()); - eprintln!("{:001X?}", nonce); let auth_tag_xor = aes_128_encrypt(&key, &nonce)?; - eprintln!("Y0 {:001X?}", auth_tag_xor); let auth_key_h = aes_128_encrypt(&key, &0u128.to_be_bytes().to_vec())?; @@ -133,8 +131,6 @@ pub fn gcm_encrypt_aes( nonce.drain(12..); nonce.append(counter.to_be_bytes().to_vec().as_mut()); - eprintln!("{:001X?}", nonce); - let inter1 = aes_128_encrypt(&key, &nonce)?; let mut inter2 = xor_bytes(&inter1, chunk.clone())?; @@ -151,7 +147,6 @@ pub fn gcm_encrypt_aes( &ghash(auth_key_h.clone(), ad, ciphertext.clone(), l_field.clone())?, auth_tag_xor, )?; - eprintln!("aes auth tag: {:001X?}", &auth_tag); Ok((ciphertext, auth_tag, l_field, auth_key_h)) } @@ -168,7 +163,6 @@ pub fn gcm_decrypt_aes( let mut counter: u32 = 1; nonce.append(counter.to_be_bytes().to_vec().as_mut()); //nonce.append(0u8.to_le_bytes().to_vec().as_mut()); - eprintln!("{:001X?}", nonce); let auth_tag_xor = aes_128_encrypt(&key, &nonce)?; @@ -181,8 +175,6 @@ pub fn gcm_decrypt_aes( nonce.drain(12..); nonce.append(counter.to_be_bytes().to_vec().as_mut()); - eprintln!("{:001X?}", nonce); - let inter1 = aes_128_encrypt(&key, &nonce)?; let mut inter2 = xor_bytes(&inter1, chunk.clone())?; @@ -201,7 +193,6 @@ pub fn gcm_decrypt_aes( )?; let valid = auth_tag == tag; - eprintln!("aes auth tag: {:001X?}", auth_tag); Ok((plaintext, valid)) } @@ -217,7 +208,6 @@ pub fn gcm_encrypt_sea( let mut counter: u32 = 1; nonce.append(counter.to_be_bytes().to_vec().as_mut()); //nonce.append(0u8.to_le_bytes().to_vec().as_mut()); - eprintln!("{:001X?}", nonce); let auth_tag_xor = sea_128_encrypt(&key, &nonce)?; @@ -230,8 +220,6 @@ pub fn gcm_encrypt_sea( nonce.drain(12..); nonce.append(counter.to_be_bytes().to_vec().as_mut()); - eprintln!("{:001X?}", nonce); - let inter1 = sea_128_encrypt(&key, &nonce)?; let mut inter2 = xor_bytes(&inter1, chunk.clone())?; @@ -264,7 +252,6 @@ pub fn gcm_decrypt_sea( let mut counter: u32 = 1; nonce.append(counter.to_be_bytes().to_vec().as_mut()); //nonce.append(0u8.to_le_bytes().to_vec().as_mut()); - eprintln!("Nonce 1: {:001X?}", nonce); let auth_tag_xor = sea_128_encrypt(&key, &nonce)?; @@ -272,17 +259,11 @@ pub fn gcm_decrypt_sea( let plaintext_chunks: Vec> = ciphertext.chunks(16).map(|x| x.to_vec()).collect(); - eprintln!("{:?}", plaintext_chunks); - counter = 2; for chunk in plaintext_chunks { - eprintln!("Inside loop"); - nonce.drain(12..); nonce.append(counter.to_be_bytes().to_vec().as_mut()); - eprintln!("Nonce 2: {:001X?}", nonce); - let inter1 = sea_128_encrypt(&key, &nonce)?; let mut inter2 = xor_bytes(&inter1, chunk.clone())?; @@ -295,15 +276,11 @@ pub fn gcm_decrypt_sea( let mut c_len: Vec = ((plaintext.len() * 8) as u64).to_be_bytes().to_vec(); l_field.append(c_len.as_mut()); - eprintln!("Ciphertext: {}", BASE64_STANDARD.encode(&ciphertext)); - let auth_tag = xor_bytes( &ghash(auth_key_h.clone(), ad, ciphertext.clone(), l_field.clone())?, auth_tag_xor, )?; - eprintln!("sea dec auth tag: {}", BASE64_STANDARD.encode(&auth_tag)); - let valid = auth_tag == tag; Ok((plaintext, valid)) @@ -317,10 +294,6 @@ pub fn ghash( ) -> Result> { let output: Vec = vec![0; 16]; - eprintln!("{:?}", ad.len() as u8); - eprintln!("{:?}", (ad.len() % 16) as u8); - eprintln!("{:001X?}", ad); - if ad.len() % 16 != 0 || ad.is_empty() { ad.append(vec![0u8; 16 - (ad.len() % 16)].as_mut()); } @@ -329,20 +302,12 @@ pub fn ghash( ciphertext.append(vec![0u8; 16 - (ciphertext.len() % 16)].as_mut()); } - eprintln!("{:001X?}", ad); - eprintln!("{:001X?}", ciphertext); - let mut ad_chunks = ad.chunks(16); - eprintln!("Ad chunks before first next {:001X?}", ad_chunks); - let inter1 = xor_bytes(&output, ad_chunks.next().unwrap().to_vec())?; let mut inter_loop = gfmul(&inter1, &auth_key_h, "gcm")?; - eprintln!("Ad chunks after first next {:001X?}", ad_chunks); for chunk in ad_chunks { - eprintln!("Inside ad chunk loop"); - eprintln!("Ad chunk in loop {:001X?}", chunk); let inter2 = xor_bytes(&inter_loop, chunk.to_vec())?; inter_loop = gfmul(&inter2, &auth_key_h, "gcm")?; } @@ -357,8 +322,6 @@ pub fn ghash( let inter4 = xor_bytes(&inter_loop, l_field)?; inter_loop = gfmul(&inter4, &auth_key_h, "gcm")?; - eprintln!("GHASH auth tag: {:001X?}", inter_loop); - Ok(inter_loop) } diff --git a/src/utils/edf.rs b/src/utils/edf.rs index 80f552c..72f687d 100644 --- a/src/utils/edf.rs +++ b/src/utils/edf.rs @@ -1,12 +1,9 @@ use num::{BigUint, FromPrimitive, One}; use rand::Rng; - use super::poly::{gcd, Polynomial}; pub fn edf(f: Polynomial, d: u32) -> Vec { - eprintln!("Starting edf"); - let q = BigUint::pow(&BigUint::from_u8(2).unwrap(), 128); let n: u32 = (f.degree() as u32) / (d); let mut z: Vec = vec![f.clone()]; @@ -20,7 +17,6 @@ pub fn edf(f: Polynomial, d: u32) -> Vec { //eprintln!("h: {:02X?}", h); let exponent = (q.pow(d) - BigUint::one()) / BigUint::from_u8(3).unwrap(); - eprintln!("q before for {:0X?}", exponent); let g = h.bpow_mod(exponent, &f) + Polynomial::one(); //eprintln!("g before for {:0X?}", g); @@ -32,9 +28,7 @@ pub fn edf(f: Polynomial, d: u32) -> Vec { //eprintln!("Inside if"); let j = gcd(&z[i], &g); - eprintln!("j: {:02X?}", j); if j != one_cmp && j != z[i] { - eprintln!("Working on Z"); let intemediate = z[i].div(&j).0; z.remove(i); z.push(j.clone()); diff --git a/src/utils/field.rs b/src/utils/field.rs index 9b9876b..4876271 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -55,15 +55,12 @@ impl FieldElement { let mut result: FieldElement = FieldElement::one(); if exponent == 1 { - eprintln!("special case 1: {:02X?}", self.clone()); - return self; } if exponent == 0 { let result = FieldElement::one(); - eprintln!("Returned value is: {:02X?}", result); return result; } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 68edb82..3816dac 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -70,8 +70,6 @@ impl Polynomial { }) .collect(); - eprintln!("{:?}", c_array); - for coefficient in c_array { polynomial.push(FieldElement::new( BASE64_STANDARD @@ -97,8 +95,6 @@ impl Polynomial { )]); if exponent == 1 { - eprintln!("special case 1: {:02X?}", self.clone()); - return self; } @@ -107,7 +103,6 @@ impl Polynomial { polynomial_2_block(vec![0], "gcm").unwrap(), )]); - eprintln!("Returned value is: {:02X?}", result); return result; } @@ -159,8 +154,6 @@ impl Polynomial { )]); if exponent == BigUint::one() { - eprintln!("special case 1: {:02X?}", self.clone().div(&modulus).1); - return self.div(&modulus).1; } @@ -169,7 +162,6 @@ impl Polynomial { polynomial_2_block(vec![0], "gcm").unwrap(), )]); - eprintln!("Returned value is: {:02X?}", result); return result; } @@ -213,8 +205,6 @@ impl Polynomial { )]); if exponent == 1 { - eprintln!("special case 1: {:02X?}", self.clone().div(&modulus).1); - return self.div(&modulus).1; } @@ -223,7 +213,6 @@ impl Polynomial { polynomial_2_block(vec![0], "gcm").unwrap(), )]); - eprintln!("Returned value is: {:02X?}", result); return result; } @@ -243,8 +232,6 @@ impl Polynomial { exponent >>= 1; } - eprintln!("result in powmod before reduction: {:02X?}", result); - while !result.polynomial.is_empty() && result .polynomial @@ -257,8 +244,6 @@ impl Polynomial { result.polynomial.pop(); } - eprintln!("result in powmod after reduction: {:02X?}", result); - if result.is_empty() { result = Polynomial::new(vec![FieldElement::new(vec![0; 16])]); } @@ -528,12 +513,6 @@ impl PartialOrd for Polynomial { for (field_a, field_b) in self.as_ref().iter().rev().zip(other.as_ref().iter().rev()) { - eprintln!( - "Poly partord: {:02X?} {:02X?} ", - self.clone().to_c_array(), - other.clone().to_c_array() - ); - match field_a .reverse_bits() .partial_cmp(&field_b.reverse_bits()) @@ -616,10 +595,10 @@ pub fn gfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result, poly_b: &Vec, semantic: &str) -> Result, poly_b: &Vec, semantic: &str) -> Result) -> Result> { From 2623bd9a8d9807c56c58e2ef7f83e59e000d9e62 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Fri, 29 Nov 2024 19:31:10 +0100 Subject: [PATCH 08/28] refactor: Change initialisations of field elements to be cleaner --- src/utils/poly.rs | 65 +++++++++++++++-------------------------------- 1 file changed, 21 insertions(+), 44 deletions(-) diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 3816dac..969a144 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -32,15 +32,13 @@ impl Polynomial { } pub fn one() -> Self { - Polynomial::new(vec![FieldElement::new( - polynomial_2_block(vec![0], "gcm").unwrap(), - )]) + Polynomial::new(vec![FieldElement::one()]) } pub fn x() -> Self { Polynomial::new(vec![ FieldElement::new(vec![0; 16]), - FieldElement::new(polynomial_2_block(vec![0], "gcm").unwrap()), + FieldElement::new(polynomial_2_block(vec![0], "xex").unwrap()), ]) } @@ -54,7 +52,7 @@ impl Polynomial { } pub fn zero() -> Self { - Polynomial::new(vec![FieldElement::new(vec![0; 16])]) + Polynomial::new(vec![FieldElement::zero()]) } pub fn from_c_array(array: &Value) -> Self { @@ -83,7 +81,7 @@ impl Polynomial { pub fn to_c_array(self) -> Vec { let mut output: Vec = vec![]; for coeff in self.polynomial { - output.push(BASE64_STANDARD.encode(coeff)); + output.push(coeff.to_b64()); } output @@ -209,9 +207,7 @@ impl Polynomial { } if exponent == 0 { - let result = Polynomial::new(vec![FieldElement::new( - polynomial_2_block(vec![0], "gcm").unwrap(), - )]); + let result = Polynomial::new(vec![FieldElement::one()]); return result; } @@ -258,10 +254,7 @@ impl Polynomial { //eprintln!("{:?}, {:?}", self.polynomial.len(), rhs.polynomial.len()); if self.polynomial.len() < rhs.polynomial.len() { - return ( - Polynomial::new(vec![FieldElement::new(vec![0; 16])]), - self.clone(), - ); + return (Polynomial::new(vec![FieldElement::zero()]), self.clone()); } let mut remainder = self.clone(); @@ -270,16 +263,10 @@ impl Polynomial { let divisor_deg = divisor.polynomial.len() - 1; if dividend_deg < divisor_deg { - return ( - Polynomial::new(vec![FieldElement::new( - polynomial_2_block(vec![0; 16], "gcm").unwrap(), - )]), - remainder, - ); + return (Polynomial::new(vec![FieldElement::zero()]), remainder); } - let mut quotient_coeffs = - vec![FieldElement::new(vec![0; 16]); dividend_deg - divisor_deg + 1]; + let mut quotient_coeffs = vec![FieldElement::zero(); dividend_deg - divisor_deg + 1]; while remainder.polynomial.len() >= divisor.polynomial.len() { let deg_diff = remainder.polynomial.len() - divisor.polynomial.len(); @@ -290,7 +277,7 @@ impl Polynomial { quotient_coeffs[deg_diff] = quot_coeff.clone(); - let mut subtrahend = vec![FieldElement::new(vec![0; 16]); deg_diff]; + let mut subtrahend = vec![FieldElement::zero(); deg_diff]; subtrahend.extend( divisor .polynomial @@ -315,7 +302,7 @@ impl Polynomial { } if remainder.is_empty() { - remainder = Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + remainder = Polynomial::new(vec![FieldElement::zero()]); } (Polynomial::new(quotient_coeffs), remainder) } @@ -416,10 +403,10 @@ 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])]); + return Polynomial::zero(); } let mut polynomial: Vec = - vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1]; + vec![FieldElement::zero(); self.polynomial.len() + rhs.polynomial.len() - 1]; for i in 0..self.polynomial.len() { for j in 0..rhs.polynomial.len() { polynomial[i + j] = &polynomial[i + j] @@ -434,10 +421,10 @@ 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])]); + return Polynomial::zero(); } let mut polynomial: Vec = - vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1]; + vec![FieldElement::zero(); self.polynomial.len() + rhs.polynomial.len() - 1]; for i in 0..self.polynomial.len() { for j in 0..rhs.polynomial.len() { polynomial[i + j] = &polynomial[i + j] @@ -471,7 +458,7 @@ impl Add for Polynomial { } if polynomial.is_empty() { - return Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + return Polynomial::new(vec![FieldElement::zero()]); } Polynomial::new(polynomial) @@ -514,8 +501,8 @@ impl PartialOrd for Polynomial { self.as_ref().iter().rev().zip(other.as_ref().iter().rev()) { match field_a - .reverse_bits() - .partial_cmp(&field_b.reverse_bits()) + //.reverse_bits() + .partial_cmp(&field_b) .unwrap() { Ordering::Equal => continue, @@ -538,7 +525,10 @@ impl Ord for Polynomial { for (field_a, field_b) in self.as_ref().iter().rev().zip(other.as_ref().iter().rev()) { - match field_a.reverse_bits().cmp(&field_b.reverse_bits()) { + match field_a + //.reverse_bits() + .cmp(&field_b) + { Ordering::Equal => continue, other => return other, } @@ -1115,19 +1105,6 @@ mod tests { //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); } - #[test] - fn test_poly_div_01() { - let element1 = - FieldElement::new(BASE64_STANDARD.decode("JAAAAAAAAAAAAAAAAAAAAA==").unwrap()); - - let element2 = - FieldElement::new(BASE64_STANDARD.decode("wAAAAAAAAAAAAAAAAAAAAA==").unwrap()); - - let result = element1 / element2; - - assert_eq!(BASE64_STANDARD.encode(result), "OAAAAAAAAAAAAAAAAAAAAA=="); - } - #[test] fn test_field_poly_div_01() { let json1 = json!([ From 7dbcf20891716b64dc653dc5b57b5903c17d1009 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Fri, 29 Nov 2024 21:12:42 +0100 Subject: [PATCH 09/28] feat/fix: add initial MT and remove extend from div for performance --- Cargo.toml | 2 ++ src/main.rs | 2 +- src/tasks/mod.rs | 71 +++++++++++++++++++++++++++++++++++++--------- src/utils/parse.rs | 4 +-- src/utils/poly.rs | 28 ++++++------------ 5 files changed, 71 insertions(+), 36 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 9cf5fa2..0d58d2b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,6 +12,8 @@ serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" num = "0.4" rand = "0.8" +threadpool = "1.8" +num_cpus = "1.16.0" [source.crates-io] replace-with = "vendored-sources" diff --git a/src/main.rs b/src/main.rs index fd69ac4..0bb3127 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ fn main() -> Result<()> { let json = fs::read_to_string(path_to_workload).unwrap(); let workload = kauma::utils::parse::parse_json(json)?; - let response = kauma::tasks::task_distrubute(&workload)?; + let response = kauma::tasks::task_distribute(&workload)?; println!("{}", serde_json::to_string(&response)?); Ok(()) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index d2c57b7..d86e661 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -185,16 +185,61 @@ pub fn task_deploy(testcase: &Testcase) -> Result { } } -pub fn task_distrubute(testcases: &Testcases) -> Result { +fn task_distribute_mt(testcases: &Testcases) -> Result { + eprintln!("USING MULTITHREADED"); + let mut responses: HashMap = HashMap::new(); + let pool = threadpool::ThreadPool::default(); + let (tx, rx) = std::sync::mpsc::channel(); + for (key, testcase) in testcases.testcases.clone() { + let tx = tx.clone(); + let testcase = testcase.clone(); + pool.execute(move || { + tx.send((key, task_deploy(&testcase))) + .expect("could not send return value of thread to main thread") + }); + } + + for _ in 0..testcases.testcases.len() { + let result = match rx.recv_timeout(std::time::Duration::from_secs(60 * 5)) { + Ok(r) => r, + Err(e) => { + eprintln!("! Job timed out: {e}"); + return Err(e.into()); + } + }; + match result.1 { + Ok(v) => { + let _ = responses.insert(result.0, v); + } + Err(e) => { + eprintln!("! failed to solve a challenge: {e:#}"); + continue; + } + } + } + + Ok(Responses { responses }) +} + +pub fn task_distribute_st(testcases: &Testcases) -> Result { + //eprintln!("USING SINGLETHREADED"); let mut responses: HashMap = HashMap::new(); for (id, testcase) in &testcases.testcases { responses.insert(id.to_owned(), task_deploy(testcase).unwrap()); } - Ok(Responses { - responses: responses, - }) + Ok(Responses { responses }) +} + +pub fn task_distribute(testcases: &Testcases) -> Result { + let cpus = num_cpus::get(); + //TODO: Deactivate MT for now + if cpus > 10000000000 { + task_distribute_mt(testcases) + } else { + task_distribute_st(testcases) + } } #[cfg(test)] @@ -227,7 +272,7 @@ mod tests { let expected = json!({ "responses": { "b856d760-023d-4b00-bad2-15d2b6da22fe": {"block": "ARIAAAAAAAAAAAAAAAAAgA=="}}}); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); @@ -251,7 +296,7 @@ mod tests { }); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); @@ -266,7 +311,7 @@ mod tests { let expected = json!({ "responses": { "b856d760-023d-4b00-bad2-15d2b6da22fe": {"product": "hSQAAAAAAAAAAAAAAAAAAA=="}}}); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); @@ -284,7 +329,7 @@ mod tests { }}); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); @@ -304,7 +349,7 @@ mod tests { }}}); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); @@ -324,7 +369,7 @@ mod tests { }}}); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); @@ -342,7 +387,7 @@ mod tests { }}}); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); @@ -360,7 +405,7 @@ mod tests { }}}); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); @@ -378,7 +423,7 @@ mod tests { }}}); assert_eq!( - serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(task_distribute(&parsed)?).unwrap(), serde_json::to_value(expected).unwrap() ); diff --git a/src/utils/parse.rs b/src/utils/parse.rs index 6e5d2dd..4b71b29 100644 --- a/src/utils/parse.rs +++ b/src/utils/parse.rs @@ -8,13 +8,13 @@ pub struct Testcases { pub testcases: HashMap, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct Testcase { pub action: String, pub arguments: Value, } -#[derive(Debug, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize, Clone)] pub struct Responses { pub responses: HashMap, } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 969a144..c294ccb 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -247,12 +247,7 @@ impl Polynomial { result } - // Returns (quotient, remainder) 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::zero()]), self.clone()); } @@ -270,24 +265,20 @@ impl Polynomial { while remainder.polynomial.len() >= divisor.polynomial.len() { let deg_diff = remainder.polynomial.len() - divisor.polynomial.len(); - let leading_dividend = remainder.polynomial.last().unwrap(); let leading_divisor = divisor.polynomial.last().unwrap(); let quot_coeff = leading_dividend / leading_divisor; - quotient_coeffs[deg_diff] = quot_coeff.clone(); - let mut subtrahend = vec![FieldElement::zero(); deg_diff]; - subtrahend.extend( - divisor - .polynomial - .iter() - .map(|x| x.clone() * quot_coeff.clone()), - ); - let subtrahend_poly = Polynomial::new(subtrahend); - - remainder = remainder + subtrahend_poly; + let mut pos; + for (i, divisor_coeff) in divisor.polynomial.iter().enumerate() { + pos = deg_diff + i; + let a: &FieldElement = &remainder.polynomial[pos]; + let c: &FieldElement = "_coeff; + remainder.polynomial[pos] = a + &(divisor_coeff * c); + } + // Remove trailing zeros while !remainder.polynomial.is_empty() && remainder .polynomial @@ -301,9 +292,6 @@ impl Polynomial { } } - if remainder.is_empty() { - remainder = Polynomial::new(vec![FieldElement::zero()]); - } (Polynomial::new(quotient_coeffs), remainder) } From 3687733b7f04cb47300e06dc6f36f5972a35b511 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Sat, 30 Nov 2024 16:07:11 +0100 Subject: [PATCH 10/28] feat: Enable MT --- src/tasks/mod.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index d86e661..a019cfe 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -234,8 +234,7 @@ pub fn task_distribute_st(testcases: &Testcases) -> Result { pub fn task_distribute(testcases: &Testcases) -> Result { let cpus = num_cpus::get(); - //TODO: Deactivate MT for now - if cpus > 10000000000 { + if cpus > 1 { task_distribute_mt(testcases) } else { task_distribute_st(testcases) From 8064dcb9e805c395235c261a3c8cd3bd5ccc5621 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Sat, 30 Nov 2024 16:07:39 +0100 Subject: [PATCH 11/28] fix: Fix incorrect dic output. Remainder could be zero. --- src/utils/poly.rs | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/utils/poly.rs b/src/utils/poly.rs index c294ccb..7f9cbe6 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -140,7 +140,7 @@ impl Polynomial { //eprintln!("result in powmod after reduction: {:02X?}", result); if result.is_empty() { - result = Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + result = Polynomial::zero(); } result @@ -192,7 +192,7 @@ impl Polynomial { } if result.is_empty() { - result = Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + result = Polynomial::zero(); } result @@ -241,7 +241,7 @@ impl Polynomial { } if result.is_empty() { - result = Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + result = Polynomial::zero(); } result @@ -278,20 +278,16 @@ impl Polynomial { remainder.polynomial[pos] = a + &(divisor_coeff * c); } - // Remove trailing zeros - while !remainder.polynomial.is_empty() - && remainder - .polynomial - .last() - .unwrap() - .as_ref() - .iter() - .all(|&x| x == 0) + while !remainder.polynomial.is_empty() && remainder.polynomial.last().unwrap().is_zero() { remainder.polynomial.pop(); } } + if remainder.is_empty() { + remainder = Polynomial::zero(); + } + (Polynomial::new(quotient_coeffs), remainder) } From e2ef29bfd53876afce3df0c8f37de04c6c8b2cab Mon Sep 17 00:00:00 2001 From: Alivecow Date: Sat, 30 Nov 2024 21:16:47 +0100 Subject: [PATCH 12/28] refactor: test with MT disabled --- src/tasks/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index a019cfe..d26cbac 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -234,7 +234,7 @@ pub fn task_distribute_st(testcases: &Testcases) -> Result { pub fn task_distribute(testcases: &Testcases) -> Result { let cpus = num_cpus::get(); - if cpus > 1 { + if cpus > 1000000 { task_distribute_mt(testcases) } else { task_distribute_st(testcases) From e8f4a5873236382d9093e40d0e438deb6ada9308 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Sat, 30 Nov 2024 23:46:59 +0100 Subject: [PATCH 13/28] fix: Fix error in random polynomial generation in edf Upper bound wa incorrect --- src/tasks/mod.rs | 2 +- src/utils/edf.rs | 23 ++++++++++++++--------- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index d26cbac..0b9fce7 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -234,7 +234,7 @@ pub fn task_distribute_st(testcases: &Testcases) -> Result { pub fn task_distribute(testcases: &Testcases) -> Result { let cpus = num_cpus::get(); - if cpus > 1000000 { + if cpus > 100000 { task_distribute_mt(testcases) } else { task_distribute_st(testcases) diff --git a/src/utils/edf.rs b/src/utils/edf.rs index 72f687d..da05db5 100644 --- a/src/utils/edf.rs +++ b/src/utils/edf.rs @@ -4,30 +4,34 @@ use rand::Rng; use super::poly::{gcd, Polynomial}; pub fn edf(f: Polynomial, d: u32) -> Vec { + eprintln!("edf started: {:?}", f.clone().to_c_array()); let q = BigUint::pow(&BigUint::from_u8(2).unwrap(), 128); let n: u32 = (f.degree() as u32) / (d); let mut z: Vec = vec![f.clone()]; let one_cmp = Polynomial::one(); while (z.len() as u32) < n { - //eprintln!("z len {}", z.len()); - //eprintln!("n len {}", n); + eprintln!("z len {}", z.len()); + eprintln!("n len {}", n); - let h = Polynomial::rand(&rand::thread_rng().gen_range(0..f.degree())); - //eprintln!("h: {:02X?}", h); + let h = Polynomial::rand(&rand::thread_rng().gen_range(1..=f.degree())); + eprintln!("h: {:02X?}", h); let exponent = (q.pow(d) - BigUint::one()) / BigUint::from_u8(3).unwrap(); let g = h.bpow_mod(exponent, &f) + Polynomial::one(); - //eprintln!("g before for {:0X?}", g); + eprintln!("g before for {:0X?}", g); - //eprintln!("z before for {:0X?}", z); + eprintln!("z before for {:0X?}", z); - for i in 0..z.len() { + for i in (0..z.len()).rev() { if z[i].degree() as u32 > d { - //eprintln!("Inside if"); + eprintln!("Inside if"); let j = gcd(&z[i], &g); + eprintln!("j != one_cmp {:?}", j != one_cmp); + eprintln!("j != z[i] {:?}", j != z[i]); + eprintln!("Inside if"); if j != one_cmp && j != z[i] { let intemediate = z[i].div(&j).0; z.remove(i); @@ -37,9 +41,10 @@ pub fn edf(f: Polynomial, d: u32) -> Vec { } } - //eprintln!("z after for {:0X?}", z); + eprintln!("z after for {:0X?}", z); } + eprintln!("edf finished"); z } From 16b65b0de485f34f582eeb32f9c2ac8c649254c3 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Sat, 30 Nov 2024 23:47:41 +0100 Subject: [PATCH 14/28] refactor: re-enable multi threading --- src/tasks/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 0b9fce7..a019cfe 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -234,7 +234,7 @@ pub fn task_distribute_st(testcases: &Testcases) -> Result { pub fn task_distribute(testcases: &Testcases) -> Result { let cpus = num_cpus::get(); - if cpus > 100000 { + if cpus > 1 { task_distribute_mt(testcases) } else { task_distribute_st(testcases) From 4c9adb9fdcbeeb1d71cbd70061b35bca53195daf Mon Sep 17 00:00:00 2001 From: Alivecow Date: Tue, 3 Dec 2024 16:52:21 +0100 Subject: [PATCH 15/28] feat: add the gcm crack Example testcase is working --- src/tasks/mod.rs | 9 +- src/tasks/tasks01/gcm_crack.rs | 197 +++++++++++++++++++++++++++++++++ src/tasks/tasks01/mod.rs | 1 + src/utils/dff.rs | 6 - src/utils/field.rs | 12 ++ src/utils/poly.rs | 10 +- test_json/sandbox.json | 42 ++++--- 7 files changed, 253 insertions(+), 24 deletions(-) create mode 100644 src/tasks/tasks01/gcm_crack.rs diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index a019cfe..aeca1c7 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -6,6 +6,7 @@ use crate::utils::parse::{Responses, Testcase, Testcases}; use tasks01::{ block2poly::block2poly, gcm::{gcm_decrypt, gcm_encrypt}, + gcm_crack::gcm_crack, gfmul::gfmul_task, pad_oracle::padding_oracle, pfmath::{ @@ -176,6 +177,12 @@ pub fn task_deploy(testcase: &Testcase) -> Result { Ok(json) } + "gcm_crack" => { + let result = gcm_crack(args)?; + let json = json!({"factors" : result}); + + Ok(json) + } _ => Err(anyhow!( "Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}", @@ -234,7 +241,7 @@ pub fn task_distribute_st(testcases: &Testcases) -> Result { pub fn task_distribute(testcases: &Testcases) -> Result { let cpus = num_cpus::get(); - if cpus > 1 { + if cpus > 1000000 { task_distribute_mt(testcases) } else { task_distribute_st(testcases) diff --git a/src/tasks/tasks01/gcm_crack.rs b/src/tasks/tasks01/gcm_crack.rs new file mode 100644 index 0000000..203b029 --- /dev/null +++ b/src/tasks/tasks01/gcm_crack.rs @@ -0,0 +1,197 @@ +use std::{env::args, fs::canonicalize, slice::Chunks}; + +use anyhow::{Ok, Result}; +use base64::{prelude::BASE64_STANDARD, Engine}; +use openssl::derive; +use serde::{Deserialize, Serialize}; +use serde_json::{map, Value}; + +use crate::utils::{ + self, + ciphers::ghash, + dff::ddf, + edf::edf, + field::FieldElement, + math::{reverse_bits_in_bytevec, xor_bytes}, + poly::Polynomial, + sff::sff, +}; + +#[derive(Debug, Serialize, Deserialize, Clone)] +pub struct CrackAnswer { + tag: String, + H: String, + mask: String, +} + +#[derive(Debug, Serialize, Deserialize, Clone)] +struct Message { + ciphertext: Vec, + ad: Vec, + tag: Vec, + l_field: Vec, +} + +fn parse_message(val: &Value) -> Result<(Message, Polynomial)> { + let ciphertext_text: String = serde_json::from_value(val["ciphertext"].clone())?; + let ciphertext_bytes: Vec = BASE64_STANDARD.decode(ciphertext_text)?; + let mut ciphertext_chunks: Vec = ciphertext_bytes + .chunks(16) + .into_iter() + .map(|chunk| FieldElement::new(chunk.to_vec())) + .collect(); + //ciphertext_chunks; + let ciphertext: Polynomial = Polynomial::new(ciphertext_chunks.clone()); + + let ad_text: String = serde_json::from_value(val["associated_data"].clone())?; + let mut ad_bytes: Vec = BASE64_STANDARD.decode(ad_text)?; + let mut l_field: Vec = ((ad_bytes.len() * 8) as u64).to_be_bytes().to_vec(); + + if ad_bytes.len() % 16 != 0 || ad_bytes.is_empty() { + ad_bytes.append(vec![0u8; 16 - (ad_bytes.len() % 16)].as_mut()); + } + let mut ad_chunks: Vec = ad_bytes + .chunks(16) + .into_iter() + .map(|chunk| FieldElement::new(chunk.to_vec())) + .collect(); + //ad_chunks; + let ad: Polynomial = Polynomial::new(ad_chunks.clone()); + + let tag_text: String = serde_json::from_value(val["tag"].clone()).unwrap_or("".to_string()); + let tag_bytes: Vec = BASE64_STANDARD.decode(tag_text)?; + let tag_field: FieldElement = FieldElement::new(tag_bytes.clone()); + let tag: Polynomial = Polynomial::new(vec![tag_field.clone()]); + + let mut c_len: Vec = ((ciphertext_bytes.len() * 8) as u64).to_be_bytes().to_vec(); + l_field.append(c_len.as_mut()); + + // Combine all data + let mut combined: Vec = + Vec::with_capacity(ad_chunks.len() + ciphertext_chunks.len() + 1); + combined.extend(ad_chunks); + combined.extend(ciphertext_chunks.clone()); + combined.push(FieldElement::new(l_field.clone())); + combined.push(tag_field); + + combined.reverse(); + + let h_poly: Polynomial = Polynomial::new(combined); + + Ok(( + Message { + ciphertext: ciphertext_bytes, + ad: ad_bytes, + tag: tag_bytes, + l_field, + }, + h_poly, + )) +} + +pub fn gcm_crack(args: &Value) -> Result { + let nonce: String = serde_json::from_value(args["nonce"].clone())?; + + let crack_poly: Polynomial = Polynomial::empty(); + + // Prepare first equation + let (m1_data, m1_h_poly) = parse_message(&args["m1"])?; + + let (m2_data, m2_h_poly) = parse_message(&args["m2"])?; + + let (m3_data, m3_h_poly) = parse_message(&args["m3"])?; + + eprintln!("m1 poly: {:?}", m1_h_poly.clone().to_c_array()); + eprintln!("m2 poly: {:?}", m2_h_poly.clone().to_c_array()); + + let combine_poly = m1_h_poly + m2_h_poly; + + eprintln!("combine poly: {:?}", combine_poly.clone().to_c_array()); + + let combine_sff = sff(combine_poly.monic()); + + let mut combine_ddf: Vec<(Polynomial, u128)> = vec![]; + for (factor, _) in combine_sff { + combine_ddf.extend(ddf(factor)); + } + + eprintln!("combine_ddf: {:?}", combine_ddf); + + let mut combine_edf: Vec = vec![]; + for (factor, degree) in combine_ddf { + if degree == 1 { + combine_edf.extend(edf(factor, degree as u32)); + } + } + + eprintln!("combine_edf: {:?}", combine_edf); + + let mut m3_auth_tag: Vec = vec![]; + let mut h_candidate: FieldElement = FieldElement::zero(); + let mut eky0: Vec = vec![]; + for candidate in combine_edf { + if candidate.degree() == 1 { + h_candidate = candidate.extract_component(0); + eprintln!("H candidate: {:02X?}", h_candidate.to_b64()); + let m1_ghash = ghash( + reverse_bits_in_bytevec(h_candidate.to_vec()), + m1_data.ad.clone(), + m1_data.ciphertext.clone(), + m1_data.l_field.clone(), + ) + .unwrap(); + + eky0 = xor_bytes(&m1_data.tag, m1_ghash).unwrap(); + eprintln!("eky0: {:?}", BASE64_STANDARD.encode(eky0.clone())); + + let m3_ghash = ghash( + reverse_bits_in_bytevec(h_candidate.to_vec()), + m3_data.ad.clone(), + m3_data.ciphertext.clone(), + m3_data.l_field.clone(), + ) + .unwrap(); + + m3_auth_tag = xor_bytes(&eky0, m3_ghash).unwrap(); + eprintln!( + "M3 auth tag: {:02X?}", + BASE64_STANDARD.encode(m3_auth_tag.clone()) + ); + + if m3_auth_tag == m3_data.tag { + eprintln!("Candidate valid"); + eprintln!("{:02X?}", m3_auth_tag); + break; + } else { + eprintln!("H candidate not valid"); + } + } + } + + eprintln!( + "M3 Authentication TAG {:02X?}", + BASE64_STANDARD.encode(&m3_auth_tag) + ); + + if m3_auth_tag.is_empty() { + eprintln!("No valid candidate found"); + } + + let (forgery_data, _) = parse_message(&args["forgery"])?; + + let forgery_ghash = ghash( + reverse_bits_in_bytevec(h_candidate.to_vec()), + forgery_data.ad.clone(), + forgery_data.ciphertext.clone(), + forgery_data.l_field.clone(), + ) + .unwrap(); + + let forgery_auth_tag = xor_bytes(&eky0, forgery_ghash).unwrap(); + + Ok(CrackAnswer { + tag: BASE64_STANDARD.encode(forgery_auth_tag), + H: h_candidate.to_b64(), + mask: BASE64_STANDARD.encode(eky0), + }) +} diff --git a/src/tasks/tasks01/mod.rs b/src/tasks/tasks01/mod.rs index 8200de5..64d24da 100644 --- a/src/tasks/tasks01/mod.rs +++ b/src/tasks/tasks01/mod.rs @@ -1,5 +1,6 @@ pub mod block2poly; pub mod gcm; +pub mod gcm_crack; pub mod gfmul; pub mod pad_oracle; pub mod pfmath; diff --git a/src/utils/dff.rs b/src/utils/dff.rs index bcd1ca0..4cd4b39 100644 --- a/src/utils/dff.rs +++ b/src/utils/dff.rs @@ -25,20 +25,14 @@ pub fn ddf(f: Polynomial) -> Vec<(Polynomial, u128)> { let g = gcd(&h, &f_star); if g != one_cmp { - eprintln!("d is: {}", d); - eprintln!("g is: {:?}", &g.clone().to_c_array()); - z.push((g.clone(), d)); f_star = f_star.div(&g).0; } - eprintln!("d outer is: {}", d); - eprintln!("F star degree is {:?}", &f_star.degree()); d += 1; } if f_star != one_cmp { - eprintln!("fstar not one"); z.push((f_star.clone(), f_star.degree() as u128)); } else if z.len() == 0 { z.push((f.clone(), 1)); diff --git a/src/utils/field.rs b/src/utils/field.rs index 7d359c8..13029cd 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -39,6 +39,18 @@ impl FieldElement { FieldElement::new_no_convert(vec![0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) } + pub fn to_vec(&self) -> Vec { + self.field_element.clone() + } + + /* + pub fn padd(&mut self) { + if self.field_element.len() % 16 != 0 || ad.is_empty() { + ad.append(vec![0u8; 16 - (ad.len() % 16)].as_mut()); + } + } + */ + pub fn new(field_element: Vec) -> Self { Self { field_element: reverse_bits_in_bytevec(field_element), diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 7f9cbe6..61109f8 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,7 +1,7 @@ use crate::utils::field::ByteArray; use base64::prelude::*; -use num::traits::FromBytes; +use num::traits::{FromBytes, ToBytes}; use num::{BigInt, BigUint, One, Zero}; use std::{str::FromStr, u128, u8, usize}; @@ -31,6 +31,10 @@ impl Polynomial { self.polynomial.len() - 1 } + pub fn empty() -> Polynomial { + Polynomial::new(vec![]) + } + pub fn one() -> Self { Polynomial::new(vec![FieldElement::one()]) } @@ -373,6 +377,10 @@ impl Polynomial { self } + + pub fn extract_component(&self, i: u32) -> FieldElement { + self.polynomial[i as usize].clone() + } } impl Clone for Polynomial { diff --git a/test_json/sandbox.json b/test_json/sandbox.json index 836b3c8..e3f5e1f 100644 --- a/test_json/sandbox.json +++ b/test_json/sandbox.json @@ -1,19 +1,29 @@ { - "testcases": { - "sandbox": { - "action": "gfpoly_factor_edf", - "arguments": { - "F": [ - "mmAAAAAAAAAAAAAAAAAAAA==", - "AbAAAAAAAAAAAAAAAAAAAA==", - "zgAAAAAAAAAAAAAAAAAAAA==", - "FwAAAAAAAAAAAAAAAAAAAA==", - "AAAAAAAAAAAAAAAAAAAAAA==", - "wAAAAAAAAAAAAAAAAAAAAA==", - "gAAAAAAAAAAAAAAAAAAAAA==" - ], - "d": 3 - } + "testcases": { + "gcm_crack1": { + "action": "gcm_crack", + "arguments": { + "nonce": "4gF+BtR3ku/PUQci", + "m1": { + "ciphertext": "CGOkZDnJEt24aVV8mqQq+P4pouVDWhAYj0SN5MDAgg==", + "associated_data": "TmFjaHJpY2h0IDE=", + "tag": "GC9neV3aZLnmznTIWqCC4A==" + }, + "m2": { + "ciphertext": "FnWyLSTfRrO8Y1MuhLIs6A==", + "associated_data": "", + "tag": "gb2ph1vzwU85/FsUg51t3Q==" + }, + "m3": { + "ciphertext": "CGOkZDnJEt25aV58iaMt6O8+8chKVh0Eg1XFxA==", + "associated_data": "TmFjaHJpY2h0IDM=", + "tag": "+/aDjsAzTseDLuM4jt5Q6Q==" + }, + "forgery": { + "ciphertext": "AXe/ZQ==", + "associated_data": "" + } + } + } } - } } From b632e0c803560b95e9b53f11207c1092797451d7 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Tue, 3 Dec 2024 17:00:23 +0100 Subject: [PATCH 16/28] refactor: clen edf code --- src/utils/edf.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/utils/edf.rs b/src/utils/edf.rs index da05db5..dfb59cf 100644 --- a/src/utils/edf.rs +++ b/src/utils/edf.rs @@ -4,34 +4,21 @@ use rand::Rng; use super::poly::{gcd, Polynomial}; pub fn edf(f: Polynomial, d: u32) -> Vec { - eprintln!("edf started: {:?}", f.clone().to_c_array()); let q = BigUint::pow(&BigUint::from_u8(2).unwrap(), 128); let n: u32 = (f.degree() as u32) / (d); let mut z: Vec = vec![f.clone()]; let one_cmp = Polynomial::one(); while (z.len() as u32) < n { - eprintln!("z len {}", z.len()); - eprintln!("n len {}", n); - let h = Polynomial::rand(&rand::thread_rng().gen_range(1..=f.degree())); - eprintln!("h: {:02X?}", h); let exponent = (q.pow(d) - BigUint::one()) / BigUint::from_u8(3).unwrap(); let g = h.bpow_mod(exponent, &f) + Polynomial::one(); - eprintln!("g before for {:0X?}", g); - - eprintln!("z before for {:0X?}", z); for i in (0..z.len()).rev() { if z[i].degree() as u32 > d { - eprintln!("Inside if"); let j = gcd(&z[i], &g); - eprintln!("j != one_cmp {:?}", j != one_cmp); - eprintln!("j != z[i] {:?}", j != z[i]); - - eprintln!("Inside if"); if j != one_cmp && j != z[i] { let intemediate = z[i].div(&j).0; z.remove(i); @@ -40,11 +27,8 @@ pub fn edf(f: Polynomial, d: u32) -> Vec { } } } - - eprintln!("z after for {:0X?}", z); } - eprintln!("edf finished"); z } From b348c19c6cb6f87cbea3e0e61e48d3436090cac4 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Tue, 3 Dec 2024 17:09:43 +0100 Subject: [PATCH 17/28] refactor: clean up gcm_crack code --- src/tasks/tasks01/gcm_crack.rs | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) diff --git a/src/tasks/tasks01/gcm_crack.rs b/src/tasks/tasks01/gcm_crack.rs index 203b029..d8aab77 100644 --- a/src/tasks/tasks01/gcm_crack.rs +++ b/src/tasks/tasks01/gcm_crack.rs @@ -35,13 +35,11 @@ struct Message { fn parse_message(val: &Value) -> Result<(Message, Polynomial)> { let ciphertext_text: String = serde_json::from_value(val["ciphertext"].clone())?; let ciphertext_bytes: Vec = BASE64_STANDARD.decode(ciphertext_text)?; - let mut ciphertext_chunks: Vec = ciphertext_bytes + let ciphertext_chunks: Vec = ciphertext_bytes .chunks(16) .into_iter() .map(|chunk| FieldElement::new(chunk.to_vec())) .collect(); - //ciphertext_chunks; - let ciphertext: Polynomial = Polynomial::new(ciphertext_chunks.clone()); let ad_text: String = serde_json::from_value(val["associated_data"].clone())?; let mut ad_bytes: Vec = BASE64_STANDARD.decode(ad_text)?; @@ -50,18 +48,15 @@ fn parse_message(val: &Value) -> Result<(Message, Polynomial)> { if ad_bytes.len() % 16 != 0 || ad_bytes.is_empty() { ad_bytes.append(vec![0u8; 16 - (ad_bytes.len() % 16)].as_mut()); } - let mut ad_chunks: Vec = ad_bytes + let ad_chunks: Vec = ad_bytes .chunks(16) .into_iter() .map(|chunk| FieldElement::new(chunk.to_vec())) .collect(); - //ad_chunks; - let ad: Polynomial = Polynomial::new(ad_chunks.clone()); let tag_text: String = serde_json::from_value(val["tag"].clone()).unwrap_or("".to_string()); let tag_bytes: Vec = BASE64_STANDARD.decode(tag_text)?; let tag_field: FieldElement = FieldElement::new(tag_bytes.clone()); - let tag: Polynomial = Polynomial::new(vec![tag_field.clone()]); let mut c_len: Vec = ((ciphertext_bytes.len() * 8) as u64).to_be_bytes().to_vec(); l_field.append(c_len.as_mut()); @@ -90,16 +85,12 @@ fn parse_message(val: &Value) -> Result<(Message, Polynomial)> { } pub fn gcm_crack(args: &Value) -> Result { - let nonce: String = serde_json::from_value(args["nonce"].clone())?; - - let crack_poly: Polynomial = Polynomial::empty(); - // Prepare first equation let (m1_data, m1_h_poly) = parse_message(&args["m1"])?; - let (m2_data, m2_h_poly) = parse_message(&args["m2"])?; + let (_, m2_h_poly) = parse_message(&args["m2"])?; - let (m3_data, m3_h_poly) = parse_message(&args["m3"])?; + let (m3_data, _) = parse_message(&args["m3"])?; eprintln!("m1 poly: {:?}", m1_h_poly.clone().to_c_array()); eprintln!("m2 poly: {:?}", m2_h_poly.clone().to_c_array()); From 6a2f631e4689ab504c354afda5b6ff467ca17db6 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Tue, 3 Dec 2024 17:51:59 +0100 Subject: [PATCH 18/28] fix: Fix the output of mask if mask is empty --- src/tasks/tasks01/gcm_crack.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/tasks/tasks01/gcm_crack.rs b/src/tasks/tasks01/gcm_crack.rs index d8aab77..6cabe38 100644 --- a/src/tasks/tasks01/gcm_crack.rs +++ b/src/tasks/tasks01/gcm_crack.rs @@ -180,6 +180,10 @@ pub fn gcm_crack(args: &Value) -> Result { let forgery_auth_tag = xor_bytes(&eky0, forgery_ghash).unwrap(); + if eky0.is_empty() { + eky0 = vec![0; 16]; + } + Ok(CrackAnswer { tag: BASE64_STANDARD.encode(forgery_auth_tag), H: h_candidate.to_b64(), From 9e31b6cc5b116800d280d23317f8b2eb3a191754 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Tue, 3 Dec 2024 22:58:10 +0100 Subject: [PATCH 19/28] fix: Add ciphertext padding to gcm_crack --- src/tasks/tasks01/gcm_crack.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/tasks/tasks01/gcm_crack.rs b/src/tasks/tasks01/gcm_crack.rs index 6cabe38..5dc2236 100644 --- a/src/tasks/tasks01/gcm_crack.rs +++ b/src/tasks/tasks01/gcm_crack.rs @@ -34,7 +34,10 @@ struct Message { fn parse_message(val: &Value) -> Result<(Message, Polynomial)> { let ciphertext_text: String = serde_json::from_value(val["ciphertext"].clone())?; - let ciphertext_bytes: Vec = BASE64_STANDARD.decode(ciphertext_text)?; + let mut ciphertext_bytes: Vec = BASE64_STANDARD.decode(ciphertext_text)?; + if ciphertext_bytes.len() % 16 != 0 { + ciphertext_bytes.append(vec![0u8; 16 - (ciphertext_bytes.len() % 16)].as_mut()); + } let ciphertext_chunks: Vec = ciphertext_bytes .chunks(16) .into_iter() From 90d61a655ed60e432b40a78cfa8107d090a50fc8 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Tue, 3 Dec 2024 23:15:42 +0100 Subject: [PATCH 20/28] fix: Fix length field implementation in gcm_crack Length field was calculated after padding --- src/tasks/tasks01/gcm_crack.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/tasks/tasks01/gcm_crack.rs b/src/tasks/tasks01/gcm_crack.rs index 5dc2236..05d8886 100644 --- a/src/tasks/tasks01/gcm_crack.rs +++ b/src/tasks/tasks01/gcm_crack.rs @@ -35,9 +35,12 @@ struct Message { fn parse_message(val: &Value) -> Result<(Message, Polynomial)> { let ciphertext_text: String = serde_json::from_value(val["ciphertext"].clone())?; let mut ciphertext_bytes: Vec = BASE64_STANDARD.decode(ciphertext_text)?; + let mut c_len: Vec = ((ciphertext_bytes.len() * 8) as u64).to_be_bytes().to_vec(); + if ciphertext_bytes.len() % 16 != 0 { ciphertext_bytes.append(vec![0u8; 16 - (ciphertext_bytes.len() % 16)].as_mut()); } + let ciphertext_chunks: Vec = ciphertext_bytes .chunks(16) .into_iter() @@ -61,7 +64,6 @@ fn parse_message(val: &Value) -> Result<(Message, Polynomial)> { let tag_bytes: Vec = BASE64_STANDARD.decode(tag_text)?; let tag_field: FieldElement = FieldElement::new(tag_bytes.clone()); - let mut c_len: Vec = ((ciphertext_bytes.len() * 8) as u64).to_be_bytes().to_vec(); l_field.append(c_len.as_mut()); // Combine all data From 7a0d1219f90a2d083da8931c9fcf0977abbba1a3 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Thu, 5 Dec 2024 15:57:18 +0100 Subject: [PATCH 21/28] fix: Fix GCM crack output --- src/tasks/mod.rs | 2 +- src/tasks/tasks01/gcm_crack.rs | 62 +++++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 2 deletions(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index aeca1c7..d48952d 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -179,7 +179,7 @@ pub fn task_deploy(testcase: &Testcase) -> Result { } "gcm_crack" => { let result = gcm_crack(args)?; - let json = json!({"factors" : result}); + let json = json!(result); Ok(json) } diff --git a/src/tasks/tasks01/gcm_crack.rs b/src/tasks/tasks01/gcm_crack.rs index 05d8886..cce3df6 100644 --- a/src/tasks/tasks01/gcm_crack.rs +++ b/src/tasks/tasks01/gcm_crack.rs @@ -54,6 +54,7 @@ fn parse_message(val: &Value) -> Result<(Message, Polynomial)> { if ad_bytes.len() % 16 != 0 || ad_bytes.is_empty() { ad_bytes.append(vec![0u8; 16 - (ad_bytes.len() % 16)].as_mut()); } + let ad_chunks: Vec = ad_bytes .chunks(16) .into_iter() @@ -128,7 +129,6 @@ pub fn gcm_crack(args: &Value) -> Result { for candidate in combine_edf { if candidate.degree() == 1 { h_candidate = candidate.extract_component(0); - eprintln!("H candidate: {:02X?}", h_candidate.to_b64()); let m1_ghash = ghash( reverse_bits_in_bytevec(h_candidate.to_vec()), m1_data.ad.clone(), @@ -170,6 +170,7 @@ pub fn gcm_crack(args: &Value) -> Result { ); if m3_auth_tag.is_empty() { + assert!(false); eprintln!("No valid candidate found"); } @@ -195,3 +196,62 @@ pub fn gcm_crack(args: &Value) -> Result { mask: BASE64_STANDARD.encode(eky0), }) } + +#[cfg(test)] +mod tests { + + use anyhow::Result; + + use rand::Rng; + + use serde_json::json; + use utils::ciphers::{aes_128_encrypt, gcm_encrypt_aes}; + // Note this useful idiom: importing names from outer (for mod tests) scope. + use super::*; + + #[test] + fn test_random() -> Result<()> { + let key = vec![1, 1, 1, 1]; + let nonce = BASE64_STANDARD.decode("4gF+BtR3ku/PUQci")?; + let ad = vec![0]; + + let input: Vec = Vec::with_capacity(rand::thread_rng().gen_range(0..=60)); + let plain1 = gcm_encrypt_aes(nonce.clone(), key.clone(), input, ad.clone())?; + let input: Vec = Vec::with_capacity(rand::thread_rng().gen_range(0..=60)); + let plain2 = gcm_encrypt_aes(nonce.clone(), key.clone(), input, ad.clone())?; + let input: Vec = Vec::with_capacity(rand::thread_rng().gen_range(0..=60)); + let plain3 = gcm_encrypt_aes(nonce.clone(), key.clone(), input, ad.clone())?; + + let crack_input = json!({ + "testcases": { + "gcm_crack46": { + "action": "gcm_crack", + "arguments": { + "nonce": "4gF+BtR3ku/PUQci", + "m1": { + "ciphertext": BASE64_STANDARD.encode(plain1.0), + "associated_data": "", + "tag": BASE64_STANDARD.encode(plain1.1) + }, + "m2": { + "ciphertext": BASE64_STANDARD.encode(plain2.0), + "associated_data": "", + "tag": BASE64_STANDARD.encode(plain2.1) + }, + "m3": { + "ciphertext": BASE64_STANDARD.encode(plain3.0), + "associated_data": "", + "tag": BASE64_STANDARD.encode(plain3.1) + }, + "forgery": { + "ciphertext": "AXe/ZQ==", + "associated_data": "" + } + } + } + } + }); + + todo!(); + } +} From 6d1b735a0ba0aefcb51d3f2df2074cc9d5c158b5 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Thu, 5 Dec 2024 16:37:54 +0100 Subject: [PATCH 22/28] refactor: remove unneded prints and enable mt --- src/tasks/mod.rs | 2 +- src/tasks/tasks01/gcm_crack.rs | 80 ---------------------------------- 2 files changed, 1 insertion(+), 81 deletions(-) diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index d48952d..8a8b782 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -241,7 +241,7 @@ pub fn task_distribute_st(testcases: &Testcases) -> Result { pub fn task_distribute(testcases: &Testcases) -> Result { let cpus = num_cpus::get(); - if cpus > 1000000 { + if cpus > 1 { task_distribute_mt(testcases) } else { task_distribute_st(testcases) diff --git a/src/tasks/tasks01/gcm_crack.rs b/src/tasks/tasks01/gcm_crack.rs index cce3df6..89788c7 100644 --- a/src/tasks/tasks01/gcm_crack.rs +++ b/src/tasks/tasks01/gcm_crack.rs @@ -98,13 +98,8 @@ pub fn gcm_crack(args: &Value) -> Result { let (m3_data, _) = parse_message(&args["m3"])?; - eprintln!("m1 poly: {:?}", m1_h_poly.clone().to_c_array()); - eprintln!("m2 poly: {:?}", m2_h_poly.clone().to_c_array()); - let combine_poly = m1_h_poly + m2_h_poly; - eprintln!("combine poly: {:?}", combine_poly.clone().to_c_array()); - let combine_sff = sff(combine_poly.monic()); let mut combine_ddf: Vec<(Polynomial, u128)> = vec![]; @@ -112,8 +107,6 @@ pub fn gcm_crack(args: &Value) -> Result { combine_ddf.extend(ddf(factor)); } - eprintln!("combine_ddf: {:?}", combine_ddf); - let mut combine_edf: Vec = vec![]; for (factor, degree) in combine_ddf { if degree == 1 { @@ -121,8 +114,6 @@ pub fn gcm_crack(args: &Value) -> Result { } } - eprintln!("combine_edf: {:?}", combine_edf); - let mut m3_auth_tag: Vec = vec![]; let mut h_candidate: FieldElement = FieldElement::zero(); let mut eky0: Vec = vec![]; @@ -155,8 +146,6 @@ pub fn gcm_crack(args: &Value) -> Result { ); if m3_auth_tag == m3_data.tag { - eprintln!("Candidate valid"); - eprintln!("{:02X?}", m3_auth_tag); break; } else { eprintln!("H candidate not valid"); @@ -164,16 +153,6 @@ pub fn gcm_crack(args: &Value) -> Result { } } - eprintln!( - "M3 Authentication TAG {:02X?}", - BASE64_STANDARD.encode(&m3_auth_tag) - ); - - if m3_auth_tag.is_empty() { - assert!(false); - eprintln!("No valid candidate found"); - } - let (forgery_data, _) = parse_message(&args["forgery"])?; let forgery_ghash = ghash( @@ -196,62 +175,3 @@ pub fn gcm_crack(args: &Value) -> Result { mask: BASE64_STANDARD.encode(eky0), }) } - -#[cfg(test)] -mod tests { - - use anyhow::Result; - - use rand::Rng; - - use serde_json::json; - use utils::ciphers::{aes_128_encrypt, gcm_encrypt_aes}; - // Note this useful idiom: importing names from outer (for mod tests) scope. - use super::*; - - #[test] - fn test_random() -> Result<()> { - let key = vec![1, 1, 1, 1]; - let nonce = BASE64_STANDARD.decode("4gF+BtR3ku/PUQci")?; - let ad = vec![0]; - - let input: Vec = Vec::with_capacity(rand::thread_rng().gen_range(0..=60)); - let plain1 = gcm_encrypt_aes(nonce.clone(), key.clone(), input, ad.clone())?; - let input: Vec = Vec::with_capacity(rand::thread_rng().gen_range(0..=60)); - let plain2 = gcm_encrypt_aes(nonce.clone(), key.clone(), input, ad.clone())?; - let input: Vec = Vec::with_capacity(rand::thread_rng().gen_range(0..=60)); - let plain3 = gcm_encrypt_aes(nonce.clone(), key.clone(), input, ad.clone())?; - - let crack_input = json!({ - "testcases": { - "gcm_crack46": { - "action": "gcm_crack", - "arguments": { - "nonce": "4gF+BtR3ku/PUQci", - "m1": { - "ciphertext": BASE64_STANDARD.encode(plain1.0), - "associated_data": "", - "tag": BASE64_STANDARD.encode(plain1.1) - }, - "m2": { - "ciphertext": BASE64_STANDARD.encode(plain2.0), - "associated_data": "", - "tag": BASE64_STANDARD.encode(plain2.1) - }, - "m3": { - "ciphertext": BASE64_STANDARD.encode(plain3.0), - "associated_data": "", - "tag": BASE64_STANDARD.encode(plain3.1) - }, - "forgery": { - "ciphertext": "AXe/ZQ==", - "associated_data": "" - } - } - } - } - }); - - todo!(); - } -} From 0da047110f94996cbb76fc30e2cdeeaf0beb4bac Mon Sep 17 00:00:00 2001 From: Alivecow Date: Thu, 5 Dec 2024 17:48:31 +0100 Subject: [PATCH 23/28] feat: enable tcp no delay option --- src/tasks/tasks01/pad_oracle.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tasks/tasks01/pad_oracle.rs b/src/tasks/tasks01/pad_oracle.rs index 4286e37..6ea7d3e 100644 --- a/src/tasks/tasks01/pad_oracle.rs +++ b/src/tasks/tasks01/pad_oracle.rs @@ -29,6 +29,7 @@ pub fn padding_oracle(args: &Value) -> Result> { for chunk in &cipher_chunks { let mut stream = TcpStream::connect(format!("{}:{}", hostname, port))?; + stream.set_nodelay(true).expect("Error on no delay"); stream.set_nonblocking(false)?; // Track value sent to server From 2f0e265ed69adc1a9a8f684eca5dc22f366f2942 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Thu, 5 Dec 2024 18:12:26 +0100 Subject: [PATCH 24/28] refactor: Change vector init in padding oracle --- src/tasks/tasks01/pad_oracle.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/tasks/tasks01/pad_oracle.rs b/src/tasks/tasks01/pad_oracle.rs index 6ea7d3e..60356b4 100644 --- a/src/tasks/tasks01/pad_oracle.rs +++ b/src/tasks/tasks01/pad_oracle.rs @@ -57,7 +57,8 @@ pub fn padding_oracle(args: &Value) -> Result> { // Generate attack blocks // TODO: Collect all and send in one - let mut payload: Vec = l_msg.to_vec(); + let mut payload: Vec = Vec::with_capacity(2 + 16 * 265); + payload.extend(l_msg.to_vec()); for j in 0..q_block_count { // Next byte //eprintln!("Sending attack block: {:02X?}", attack_counter); From b24c70342900eb3f994dcc3179925bb96506c3a8 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Sun, 22 Dec 2024 18:13:23 +0100 Subject: [PATCH 25/28] refactor: Apply general cargo recommendations --- src/tasks/tasks01/gcm_crack.rs | 5 +---- src/utils/ciphers.rs | 1 - src/utils/field.rs | 2 -- src/utils/poly.rs | 5 ++--- 4 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/tasks/tasks01/gcm_crack.rs b/src/tasks/tasks01/gcm_crack.rs index 89788c7..09ccb2c 100644 --- a/src/tasks/tasks01/gcm_crack.rs +++ b/src/tasks/tasks01/gcm_crack.rs @@ -1,13 +1,10 @@ -use std::{env::args, fs::canonicalize, slice::Chunks}; use anyhow::{Ok, Result}; use base64::{prelude::BASE64_STANDARD, Engine}; -use openssl::derive; use serde::{Deserialize, Serialize}; -use serde_json::{map, Value}; +use serde_json::Value; use crate::utils::{ - self, ciphers::ghash, dff::ddf, edf::edf, diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index 82af34b..f147c5a 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -1,6 +1,5 @@ use crate::utils::{field::ByteArray, poly::gfmul}; use anyhow::Result; -use base64::prelude::*; use openssl::symm::{Cipher, Crypter, Mode}; use super::math::xor_bytes; diff --git a/src/utils/field.rs b/src/utils/field.rs index 13029cd..b5a65dc 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -8,9 +8,7 @@ use std::{ use anyhow::{anyhow, Ok, Result}; -use crate::utils::poly::bgfmul; -use super::poly::polynomial_2_block; use super::{ math::{reverse_bits_in_bytevec, xor_bytes}, poly::gfmul, diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 61109f8..361108e 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -2,7 +2,7 @@ use crate::utils::field::ByteArray; use base64::prelude::*; use num::traits::{FromBytes, ToBytes}; -use num::{BigInt, BigUint, One, Zero}; +use num::{BigUint, One, Zero}; use std::{str::FromStr, u128, u8, usize}; @@ -15,7 +15,6 @@ use anyhow::{anyhow, Ok, Result}; use serde_json::Value; use super::field::FieldElement; -use super::math::reverse_bits_in_bytevec; #[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct Polynomial { @@ -574,7 +573,7 @@ pub fn sort_polynomial_array(mut polys: Vec) -> Result, poly_b: &Vec, semantic: &str) -> Result> { - let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec()); + let 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.to_vec()); From c9c26b39712112381b9237eeb7839f7d74812439 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Mon, 23 Dec 2024 10:27:23 +0100 Subject: [PATCH 26/28] refactor: remove commented code --- src/tasks/tasks01/block2poly.rs | 1 - src/tasks/tasks01/pad_oracle.rs | 37 -------------------------- src/tasks/tasks01/sea128.rs | 5 ---- src/utils/ciphers.rs | 9 ------- src/utils/field.rs | 23 ---------------- src/utils/poly.rs | 47 ++------------------------------- 6 files changed, 2 insertions(+), 120 deletions(-) diff --git a/src/tasks/tasks01/block2poly.rs b/src/tasks/tasks01/block2poly.rs index 3e636eb..3377bf6 100644 --- a/src/tasks/tasks01/block2poly.rs +++ b/src/tasks/tasks01/block2poly.rs @@ -19,7 +19,6 @@ 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/pad_oracle.rs b/src/tasks/tasks01/pad_oracle.rs index 60356b4..067a55f 100644 --- a/src/tasks/tasks01/pad_oracle.rs +++ b/src/tasks/tasks01/pad_oracle.rs @@ -40,7 +40,6 @@ pub fn padding_oracle(args: &Value) -> Result> { let q_block_count: u16 = 256; //Send the first ciphertext chunk - //eprintln!("Sending Ciphertext chunk: {:002X?}", chunk); stream.flush()?; stream.write_all(&chunk)?; stream.flush()?; @@ -50,10 +49,6 @@ pub fn padding_oracle(args: &Value) -> Result> { // FIXME: Assignment is redundant for now // TODO: Goal is to maybe add speed increase in the future let l_msg: [u8; 2] = q_block_count.to_le_bytes(); - //eprintln!("Sending l_msg: {:02X?}", l_msg); - //stream.write_all(&l_msg)?; - //stream.flush()?; - //eprintln!("L_msg sent"); // Generate attack blocks // TODO: Collect all and send in one @@ -61,14 +56,9 @@ pub fn padding_oracle(args: &Value) -> Result> { payload.extend(l_msg.to_vec()); for j in 0..q_block_count { // Next byte - //eprintln!("Sending attack block: {:02X?}", attack_counter); - - //thread::sleep(Duration::from_millis(1000)); payload.extend(&attack_counter); - //eprintln!("I in q builder {}", i); attack_counter[i as usize] += 1; } - //eprintln!("Time for qblocks: {:?}", start.elapsed()); stream.write_all(&payload)?; stream.flush()?; @@ -76,7 +66,6 @@ pub fn padding_oracle(args: &Value) -> Result> { // Read server response let mut server_q_resp = [0u8; 256]; stream.read_exact(&mut server_q_resp)?; - //eprintln!("{:02X?}", buf); // extract valid position let valid_val = server_q_resp @@ -86,7 +75,6 @@ pub fn padding_oracle(args: &Value) -> Result> { if valid_val == 0x00 { eprintln!("No valid found in main loop"); } - //eprintln!("Valid value found: {:02X?}", valid_val); // Craft next attack vector padding; 0x01, 0x02, ... attack_counter[i as usize] = valid_val; @@ -100,15 +88,10 @@ pub fn padding_oracle(args: &Value) -> Result> { l_msg_check.extend(check_q_block.as_slice()); stream.write_all(&l_msg_check)?; - //stream.write_all(&check_q_block)?; let mut buf = [0u8; 0x01]; stream.read(&mut buf)?; - //eprintln!("I = {}", i); - //eprintln!("Buffer from pad check: {:02X?}", buf); if buf == [0x01] { - //eprintln!("Valid padding"); } else { - //eprintln!("Invalid padding"); // Search for second hit let valid_val = 255 - server_q_resp @@ -119,38 +102,21 @@ pub fn padding_oracle(args: &Value) -> Result> { if valid_val == 0x00 { eprintln!("No valid found"); } - //eprintln!("Valid value found: {:02X?}", valid_val); // Craft next attack vector padding; 0x01, 0x02, ... attack_counter[i as usize] = valid_val; } } if chunk_counter + 1 < cipher_chunks.len() { - //eprintln!("XOR Next Ciph block"); plaintext.push( cipher_chunks[chunk_counter + 1][i] ^ (attack_counter[i as usize] ^ (15 - i as u8 + 1)), ); } else { - //seprintln!("XOR IV"); - plaintext.push(iv[i] ^ (attack_counter[i as usize] ^ (15 - i as u8 + 1))); } - //eprintln!("Attack counter after set: {:02X?}", attack_counter); let range = i; for pos in range..=15 { - //eprintln!("i is: {:02X?}", i); - //eprintln!("i + 1 is: {:02X?}", ((16 - i) as u8).to_le()); - /* - eprintln!( - "attack_counter[pos as usize]: {:02X?}", - attack_counter[pos as usize] - ); - eprintln!( - "attack_counter[pos as usize] ^ 0x02 {:02X?}", - attack_counter[pos as usize] ^ (15 - i as u8 + 1) - ); - */ let intermediate = attack_counter[pos as usize] ^ (15 - i as u8 + 1); attack_counter[pos as usize] = intermediate ^ ((15 - i as u8 + 1) + 1); @@ -159,13 +125,10 @@ pub fn padding_oracle(args: &Value) -> Result> { stream.flush()?; // Write plaintext - //eprintln!("{:02X?}", plaintext); } chunk_counter += 1; stream.flush()?; - // break; drop(stream); - //eprintln!("Time rest of calc: {:?}", start.elapsed()); } plaintext.reverse(); diff --git a/src/tasks/tasks01/sea128.rs b/src/tasks/tasks01/sea128.rs index 6d76909..2a6a7e2 100644 --- a/src/tasks/tasks01/sea128.rs +++ b/src/tasks/tasks01/sea128.rs @@ -6,18 +6,13 @@ use crate::utils::ciphers::{sea_128_decrypt, sea_128_encrypt}; pub fn sea128(args: &Value) -> Result { let key_string: String = serde_json::from_value(args["key"].clone())?; - //let key: &[u8] = b64_2_num(key_string)?.to_ne_bytes(); let key = BASE64_STANDARD.decode(key_string)?; - //eprintln!("{:?}", key); 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 mode: String = serde_json::from_value(args["mode"].clone())?; match mode.as_str() { "encrypt" => { - //eprintln!("{:?}", plaintexts); - let output = BASE64_STANDARD.encode(sea_128_encrypt(&key, &input)?); Ok(output) diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index f147c5a..0b558af 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -161,7 +161,6 @@ pub fn gcm_decrypt_aes( let mut counter: u32 = 1; nonce.append(counter.to_be_bytes().to_vec().as_mut()); - //nonce.append(0u8.to_le_bytes().to_vec().as_mut()); let auth_tag_xor = aes_128_encrypt(&key, &nonce)?; @@ -250,7 +249,6 @@ pub fn gcm_decrypt_sea( let mut counter: u32 = 1; nonce.append(counter.to_be_bytes().to_vec().as_mut()); - //nonce.append(0u8.to_le_bytes().to_vec().as_mut()); let auth_tag_xor = sea_128_encrypt(&key, &nonce)?; @@ -324,13 +322,6 @@ pub fn ghash( Ok(inter_loop) } -/* -* let mut bytes: [u8; 16] = [0u8; 16]; - bytes.copy_from_slice(&ciphertext); - let number: u128 = ::from_be_bytes(bytes); - -* */ - #[cfg(test)] mod tests { use super::*; diff --git a/src/utils/field.rs b/src/utils/field.rs index b5a65dc..0a06662 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -8,7 +8,6 @@ use std::{ use anyhow::{anyhow, Ok, Result}; - use super::{ math::{reverse_bits_in_bytevec, xor_bytes}, poly::gfmul, @@ -41,14 +40,6 @@ impl FieldElement { self.field_element.clone() } - /* - pub fn padd(&mut self) { - if self.field_element.len() % 16 != 0 || ad.is_empty() { - ad.append(vec![0u8; 16 - (ad.len() % 16)].as_mut()); - } - } - */ - pub fn new(field_element: Vec) -> Self { Self { field_element: reverse_bits_in_bytevec(field_element), @@ -80,29 +71,18 @@ impl FieldElement { return result; } - //eprintln!("Initial result: {:?}", result); while exponent > 0 { - //eprintln!("Current exponent: {:02X}", exponent); if exponent & 1 == 1 { let temp = &self * &result; - //eprintln!("Mult"); - //eprintln!("After mod: {:?}", temp); result = temp } let temp_square = &self * &self; - // eprintln!("Square"); - // eprintln!("After squaring: {:?}", temp_square); self = temp_square; - //eprintln!("After mod: {:?}", self); exponent >>= 1; } - // eprintln!("result in powmod before reduction: {:02X?}", result); - - // eprintln!("result in powmod after reduction: {:02X?}", result); - result } @@ -111,10 +91,8 @@ impl FieldElement { let mut inverser = INVERSER_START; let mut inverse: Vec = vec![0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; - //eprintln!("Inverse start {:02X?}", inverse); while inverser > 0 { - //eprintln!("{:02X}", inverser); if inverser & 1 == 1 { inverse = gfmul(&self.field_element, &inverse, "xex").unwrap(); } @@ -122,7 +100,6 @@ impl FieldElement { self.field_element = gfmul(&self.field_element, &self.field_element, "xex") .expect("Error in sqrmul sqr"); } - //eprintln!("Inverse rhs {:?}", inverse); FieldElement::new_no_convert(inverse) } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 361108e..90ef5e0 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,14 +1,14 @@ use crate::utils::field::ByteArray; use base64::prelude::*; -use num::traits::{FromBytes, ToBytes}; +use num::traits::FromBytes; use num::{BigUint, One, Zero}; use std::{str::FromStr, u128, u8, usize}; use std::{ cmp::Ordering, - ops::{Add, Div, Mul}, + ops::{Add, Mul}, }; use anyhow::{anyhow, Ok, Result}; @@ -107,27 +107,18 @@ impl Polynomial { return result; } - //eprintln!("Initial result: {:?}", result); while exponent > 0 { - //eprintln!("Current exponent: {:02X}", exponent); if exponent & 1 == 1 { let temp = &self * &result; - //eprintln!("Mult"); - //eprintln!("After mod: {:?}", temp); result = temp } let temp_square = &self * &self; - //eprintln!("Square"); - //eprintln!("After squaring: {:?}", temp_square); self = temp_square; - //eprintln!("After mod: {:?}", self); exponent >>= 1; } - //eprintln!("result in powmod before reduction: {:02X?}", result); - while !result.polynomial.is_empty() && result .polynomial @@ -140,8 +131,6 @@ impl Polynomial { result.polynomial.pop(); } - //eprintln!("result in powmod after reduction: {:02X?}", result); - if result.is_empty() { result = Polynomial::zero(); } @@ -166,19 +155,13 @@ impl Polynomial { return result; } - //eprintln!("Initial result: {:?}", result); while &exponent > &BigUint::zero() { - //eprintln!("Current exponent: {:02X}", exponent); if &exponent & BigUint::one() == BigUint::one() { let temp = &self * &result; - //eprintln!("After multiplication: {:?}", temp); result = temp.div(&modulus).1; - //eprintln!("After mod: {:?}", result); } let temp_square = &self * &self; - //eprintln!("After squaring: {:?}", temp_square); self = temp_square.div(&modulus).1; - //eprintln!("After mod: {:?}", self); exponent >>= 1; } @@ -215,19 +198,13 @@ impl Polynomial { return result; } - //eprintln!("Initial result: {:?}", result); while exponent > 0 { - //eprintln!("Current exponent: {:02X}", exponent); if exponent & 1 == 1 { let temp = &self * &result; - //eprintln!("After multiplication: {:?}", temp); result = temp.div(&modulus).1; - //eprintln!("After mod: {:?}", result); } let temp_square = &self * &self; - //eprintln!("After squaring: {:?}", temp_square); self = temp_square.div(&modulus).1; - //eprintln!("After mod: {:?}", self); exponent >>= 1; } @@ -574,13 +551,10 @@ pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000; pub fn gfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result> { let 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.to_vec()); - //poly1.0.push(0x00); let mut poly2: ByteArray = ByteArray(poly_b.to_vec()); - //poly2.0.push(0x00); if semantic == "gcm" { poly1.reverse_bits_in_bytevec(); @@ -618,7 +592,6 @@ pub fn gfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result, poly_b: &Vec, semantic: &str) -> Result> { - //TODO: Implement gfmul with bigint let red_poly_bytes: BigUint = BigUint::from_slice(&[ 0x87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01, ]); @@ -627,13 +600,6 @@ pub fn bgfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result, poly_b: &Vec, semantic: &str) -> Result> 1; } - /* - if semantic == "gcm" { - result.reverse_bits_in_bytevec(); - } - */ - Ok(result.to_bytes_le()) } @@ -676,8 +636,6 @@ pub fn convert_gcm_to_xex(gcm_poly: Vec) -> Result> { pub fn get_alpha_rep(num: u128) -> String { let powers: Vec = get_coefficients(num); - //println!("{:?}", powers); - let mut alpha_rep = String::new(); if powers.len() == 1 { @@ -704,7 +662,6 @@ pub fn b64_2_num(string: &String) -> Result { pub fn get_coefficients(num: u128) -> Vec { let mut powers: Vec = vec![]; for shift in 0..128 { - //println!("{:?}", ((num >> shift) & 1)); if ((num >> shift) & 1) == 1 { powers.push(shift); } From 848ad15bb8ed531ab246777f76635528b90d2612 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Mon, 23 Dec 2024 10:29:12 +0100 Subject: [PATCH 27/28] refactor: Remove unneded imports --- src/tasks/tasks01/gfmul.rs | 1 - src/tasks/tasks01/pad_oracle.rs | 3 +-- src/tasks/tasks01/poly2block.rs | 2 +- src/utils/dff.rs | 2 +- src/utils/field.rs | 1 - src/utils/poly.rs | 2 +- src/utils/sff.rs | 2 +- 7 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index 70ab788..8bca55f 100644 --- a/src/tasks/tasks01/gfmul.rs +++ b/src/tasks/tasks01/gfmul.rs @@ -21,7 +21,6 @@ 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/pad_oracle.rs b/src/tasks/tasks01/pad_oracle.rs index 067a55f..234babf 100644 --- a/src/tasks/tasks01/pad_oracle.rs +++ b/src/tasks/tasks01/pad_oracle.rs @@ -54,7 +54,7 @@ pub fn padding_oracle(args: &Value) -> Result> { // TODO: Collect all and send in one let mut payload: Vec = Vec::with_capacity(2 + 16 * 265); payload.extend(l_msg.to_vec()); - for j in 0..q_block_count { + for _j in 0..q_block_count { // Next byte payload.extend(&attack_counter); attack_counter[i as usize] += 1; @@ -140,7 +140,6 @@ pub fn padding_oracle(args: &Value) -> Result> { #[cfg(test)] mod tests { use super::*; - use serde_json::json; #[test] fn test_connection() -> Result<()> { diff --git a/src/tasks/tasks01/poly2block.rs b/src/tasks/tasks01/poly2block.rs index 6d5ad95..7557981 100644 --- a/src/tasks/tasks01/poly2block.rs +++ b/src/tasks/tasks01/poly2block.rs @@ -1,4 +1,4 @@ -use crate::utils::poly::{polynomial_2_block}; +use crate::utils::poly::polynomial_2_block; use anyhow::{Ok, Result}; use serde_json::Value; diff --git a/src/utils/dff.rs b/src/utils/dff.rs index 4cd4b39..21dde69 100644 --- a/src/utils/dff.rs +++ b/src/utils/dff.rs @@ -75,7 +75,7 @@ mod tests { } println!("Result: {:?}", result); - let bit_indices: Vec = vec![0]; + let _bit_indices: Vec = vec![0]; assert!(false) } } diff --git a/src/utils/field.rs b/src/utils/field.rs index 0a06662..739b466 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -337,7 +337,6 @@ impl ByteArray { #[cfg(test)] mod tests { use super::*; - use serde_json::json; #[test] fn test_byte_array_shift1() { diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 90ef5e0..f2e7d33 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -788,7 +788,7 @@ mod tests { #[test] fn coeff_to_binary() { let coefficients: Vec = vec![12, 127, 9, 0]; - let b64: &str = "ARIAAAAAAAAAAAAAAAAAgA=="; + let _b64: &str = "ARIAAAAAAAAAAAAAAAAAgA=="; let calculated_num: u128 = coefficient_to_binary(coefficients); assert_eq!( BASE64_STANDARD.encode(calculated_num.to_ne_bytes()), diff --git a/src/utils/sff.rs b/src/utils/sff.rs index e7a154a..de2bef6 100644 --- a/src/utils/sff.rs +++ b/src/utils/sff.rs @@ -86,7 +86,7 @@ mod tests { } println!("{:?}", result); - let bit_indices: Vec = vec![0]; + let _bit_indices: Vec = vec![0]; assert!(false) } } From 0a573d84da8d0984f4ea5d14a04f27c0f7fb14e9 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Mon, 23 Dec 2024 10:30:21 +0100 Subject: [PATCH 28/28] refactor: Remove unused function --- src/utils/poly.rs | 33 --------------------------------- 1 file changed, 33 deletions(-) diff --git a/src/utils/poly.rs b/src/utils/poly.rs index f2e7d33..6a61853 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -591,39 +591,6 @@ pub fn gfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result, poly_b: &Vec, semantic: &str) -> Result> { - let red_poly_bytes: BigUint = BigUint::from_slice(&[ - 0x87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01, - ]); - - let mut poly1: BigUint = BigUint::from_le_bytes(poly_a); - - let mut poly2: BigUint = BigUint::from_le_bytes(poly_b); - - let mut result: BigUint = BigUint::zero(); - - if (&poly2 & (BigUint::one() << 127)) == BigUint::one() { - result = &result ^ &poly1; - } - poly2 = &poly2 >> 1; - - while &poly2 != &BigUint::zero() { - poly1 = &poly1 << 1; - - if (&poly1 & (BigUint::one() << 127)) == BigUint::one() { - poly1 = &poly1 ^ &red_poly_bytes; - } - - if &poly2 & BigUint::one() == BigUint::one() { - result = &result ^ &poly1; - } - - poly2 = &poly2 >> 1; - } - - Ok(result.to_bytes_le()) -} - pub fn convert_gcm_to_xex(gcm_poly: Vec) -> Result> { let xex_poly = gcm_poly .into_iter()