From 341b22e18422c847affd2bf9f8063cadd6a55480 Mon Sep 17 00:00:00 2001 From: Alivecow Date: Tue, 26 Nov 2024 13:19:07 +0100 Subject: [PATCH] feat: Add ddf algorithm --- Cargo.toml | 1 + src/tasks/mod.rs | 11 ++++- src/tasks/tasks01/pfmath.rs | 32 ++++++++++++-- src/utils/dff.rs | 85 ++++++++++++++++++++++++++++++++++--- src/utils/poly.rs | 77 +++++++++++++++++++++++++++++++++ 5 files changed, 193 insertions(+), 13 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e127c7e..8582eed 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ base64 = "0.22" openssl = "0.10" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" +num = "0.4" [source.crates-io] replace-with = "vendored-sources" diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 2c3a428..a129f04 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -9,8 +9,9 @@ use tasks01::{ gfmul::gfmul_task, pad_oracle::padding_oracle, pfmath::{ - gfdiv, gfpoly_add, gfpoly_diff, gfpoly_divmod, gfpoly_factor_sff, gfpoly_gcd, - gfpoly_make_monic, gfpoly_mul, gfpoly_pow, gfpoly_powmod, gfpoly_sort, gfpoly_sqrt, + gfdiv, gfpoly_add, gfpoly_diff, gfpoly_divmod, gfpoly_factor_ddf, gfpoly_factor_sff, + gfpoly_gcd, gfpoly_make_monic, gfpoly_mul, gfpoly_pow, gfpoly_powmod, gfpoly_sort, + gfpoly_sqrt, }, poly2block::poly2block, sea128::sea128, @@ -163,6 +164,12 @@ pub fn task_deploy(testcase: &Testcase) -> Result { Ok(json) } + "gfpoly_factor_ddf" => { + let result = gfpoly_factor_ddf(args)?; + let json = json!({"factors" : result}); + + Ok(json) + } _ => Err(anyhow!( "Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}", diff --git a/src/tasks/tasks01/pfmath.rs b/src/tasks/tasks01/pfmath.rs index b9067cc..dec3b6e 100644 --- a/src/tasks/tasks01/pfmath.rs +++ b/src/tasks/tasks01/pfmath.rs @@ -1,11 +1,18 @@ +use std::usize; + use anyhow::Result; use base64::{prelude::BASE64_STANDARD, Engine}; use serde_json::Value; -use crate::utils::{ - field::FieldElement, - poly::{gcd, Polynomial}, - sff::{sff, Factors}, +use crate::{ + tasks, + utils::{ + self, + dff::ddf, + field::FieldElement, + poly::{gcd, Polynomial}, + sff::{sff, Factors}, + }, }; pub fn gfpoly_add(args: &Value) -> Result { @@ -135,6 +142,23 @@ pub fn gfpoly_factor_sff(arsg: &Value) -> Result> { Ok(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); + factors.sort(); + let mut result: Vec = vec![]; + + for (factor, degree) in factors { + result.push(utils::dff::Factors { + factor: factor.to_c_array(), + degree: degree as u32, + }); + } + + Ok(result) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src/utils/dff.rs b/src/utils/dff.rs index 575d9de..6335d27 100644 --- a/src/utils/dff.rs +++ b/src/utils/dff.rs @@ -1,10 +1,81 @@ -use super::poly::Polynomial; +use std::usize; -pub fn dff(f: Polynomial) { - let q = 2u128.pow(128); - let z: Vec<(Polynomial, u32)> = vec![]; - let d = 1; - let f_start = f.clone(); +use num::{pow::Pow, traits::ToBytes, BigUint, FromPrimitive}; +use serde::{Deserialize, Serialize}; - while f_start.degree() >= 2 * d {} +use super::poly::{gcd, Polynomial}; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Factors { + pub factor: Vec, + pub degree: u32, +} + +pub fn ddf(f: Polynomial) -> Vec<(Polynomial, usize)> { + let q = BigUint::pow(&BigUint::from_u8(2).unwrap(), 128); + eprintln!("q: {:?}", q); + + let mut z: Vec<(Polynomial, usize)> = vec![]; + let mut d: u32 = 1; + let mut f_star = f.clone(); + + let one_cmp = Polynomial::one(); + while f_star.degree() >= (2 * d) as usize { + let h = Polynomial::x().bpow_mod(q.clone().pow(d), f_star.clone()) + + Polynomial::x().div(&f_star).1; + + let g = gcd(&h, &f_star); + if g != one_cmp { + z.push((g.clone(), d as usize)); + f_star = f_star.div(&g).0; + } + + d += 1; + } + if f_star != one_cmp { + z.push((f_star.clone(), f_star.degree())); + } else if z.len() == 0 { + z.push((f.clone(), 1)); + } + + z +} + +#[cfg(test)] +mod tests { + + use serde_json::json; + + // Note this useful idiom: importing names from outer (for mod tests) scope. + use super::*; + + #[test] + fn test_dff_sheet() { + let json_f = json!([ + "tpkgAAAAAAAAAAAAAAAAAA==", + "m6MQAAAAAAAAAAAAAAAAAA==", + "8roAAAAAAAAAAAAAAAAAAA==", + "3dUAAAAAAAAAAAAAAAAAAA==", + "FwAAAAAAAAAAAAAAAAAAAA==", + "/kAAAAAAAAAAAAAAAAAAAA==", + "a4AAAAAAAAAAAAAAAAAAAA==", + "gAAAAAAAAAAAAAAAAAAAAA==" + ]); + let poly_f = Polynomial::from_c_array(&json_f); + + let mut factors = ddf(poly_f); + factors.sort(); + let mut result: Vec = vec![]; + + for (factor, degree) in factors { + result.push(Factors { + factor: factor.to_c_array(), + degree: degree as u32, + }); + } + + println!("Result: {:?}", result); + let bit_indices: Vec = vec![0]; + assert!(false) + } } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 786c67a..42e6916 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -1,5 +1,7 @@ use crate::utils::field::ByteArray; +use base64::alphabet::BIN_HEX; use base64::prelude::*; +use num::{BigInt, BigUint, One, Zero}; use std::{str::FromStr, u128, u8, usize}; use std::{ @@ -26,6 +28,23 @@ impl Polynomial { self.polynomial.len() } + pub fn one() -> Self { + Polynomial::new(vec![FieldElement::new( + polynomial_2_block(vec![0], "gcm").unwrap(), + )]) + } + + pub fn x() -> Self { + Polynomial::new(vec![ + FieldElement::new(vec![0; 16]), + FieldElement::new(polynomial_2_block(vec![0], "gcm").unwrap()), + ]) + } + + pub fn zero() -> Self { + Polynomial::new(vec![FieldElement::new(vec![0; 16])]) + } + pub fn from_c_array(array: &Value) -> Self { let mut polynomial: Vec = vec![]; let c_array: Vec = array @@ -122,6 +141,64 @@ impl Polynomial { result } + pub fn bpow_mod(mut self, mut exponent: BigUint, modulus: Polynomial) -> Polynomial { + let mut result: Polynomial = Polynomial::new(vec![FieldElement::new( + polynomial_2_block(vec![0], "gcm").unwrap(), + )]); + + if exponent == BigUint::one() { + eprintln!("special case 1: {:02X?}", self.clone().div(&modulus).1); + + return self.div(&modulus).1; + } + + if exponent == BigUint::zero() { + let result = Polynomial::new(vec![FieldElement::new( + polynomial_2_block(vec![0], "gcm").unwrap(), + )]); + + eprintln!("Returned value is: {:02X?}", result); + 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; + } + + eprintln!("result in powmod before reduction: {:02X?}", result); + + while !result.polynomial.is_empty() + && result + .polynomial + .last() + .unwrap() + .as_ref() + .iter() + .all(|&x| x == 0) + { + result.polynomial.pop(); + } + + eprintln!("result in powmod after reduction: {:02X?}", result); + + if result.is_empty() { + result = Polynomial::new(vec![FieldElement::new(vec![0; 16])]); + } + + result + } pub fn pow_mod(mut self, mut exponent: u128, modulus: Polynomial) -> Polynomial { let mut result: Polynomial = Polynomial::new(vec![FieldElement::new( polynomial_2_block(vec![0], "gcm").unwrap(), -- 2.49.1