diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 0613d93..2c3a428 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -9,8 +9,8 @@ use tasks01::{ gfmul::gfmul_task, pad_oracle::padding_oracle, pfmath::{ - gfdiv, gfpoly_add, gfpoly_diff, gfpoly_divmod, gfpoly_gcd, gfpoly_make_monic, gfpoly_mul, - gfpoly_pow, gfpoly_powmod, gfpoly_sort, gfpoly_sqrt, + 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, }, poly2block::poly2block, sea128::sea128, @@ -157,6 +157,12 @@ pub fn task_deploy(testcase: &Testcase) -> Result { Ok(json) } + "gfpoly_factor_sff" => { + let result = gfpoly_factor_sff(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 4fc686e..b9067cc 100644 --- a/src/tasks/tasks01/pfmath.rs +++ b/src/tasks/tasks01/pfmath.rs @@ -5,6 +5,7 @@ use serde_json::Value; use crate::utils::{ field::FieldElement, poly::{gcd, Polynomial}, + sff::{sff, Factors}, }; pub fn gfpoly_add(args: &Value) -> Result { @@ -112,7 +113,24 @@ pub fn gfpoly_gcd(args: &Value) -> Result { let poly_a = Polynomial::from_c_array(&args["A"].clone()); let poly_b = Polynomial::from_c_array(&args["B"].clone()); - let result = gcd(poly_a.monic(), poly_b.monic()); + let result = gcd(&poly_a.monic(), &poly_b.monic()); + + Ok(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); + factors.sort(); + let mut result: Vec = vec![]; + + for (factor, exponent) in factors { + result.push(Factors { + factor: factor.to_c_array(), + exponent, + }); + } Ok(result) } diff --git a/src/utils/dff.rs b/src/utils/dff.rs new file mode 100644 index 0000000..575d9de --- /dev/null +++ b/src/utils/dff.rs @@ -0,0 +1,10 @@ +use super::poly::Polynomial; + +pub fn dff(f: Polynomial) { + let q = 2u128.pow(128); + let z: Vec<(Polynomial, u32)> = vec![]; + let d = 1; + let f_start = f.clone(); + + while f_start.degree() >= 2 * d {} +} diff --git a/src/utils/edf.rs b/src/utils/edf.rs new file mode 100644 index 0000000..e69de29 diff --git a/src/utils/field.rs b/src/utils/field.rs index ce0b8a4..626d40d 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -14,7 +14,7 @@ use super::{ poly::gfmul, }; -#[derive(Debug, serde::Serialize)] +#[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct FieldElement { field_element: Vec, } diff --git a/src/utils/mod.rs b/src/utils/mod.rs index 298415b..35fb781 100644 --- a/src/utils/mod.rs +++ b/src/utils/mod.rs @@ -1,6 +1,9 @@ pub mod ciphers; +pub mod dff; +pub mod edf; pub mod field; pub mod math; pub mod net; pub mod parse; pub mod poly; +pub mod sff; diff --git a/src/utils/poly.rs b/src/utils/poly.rs index b820e01..786c67a 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -12,7 +12,7 @@ use serde_json::Value; use super::field::FieldElement; -#[derive(Debug, serde::Serialize)] +#[derive(Debug, serde::Serialize, serde::Deserialize)] pub struct Polynomial { polynomial: Vec, } @@ -22,6 +22,10 @@ impl Polynomial { Self { polynomial } } + pub fn degree(&self) -> usize { + self.polynomial.len() + } + pub fn from_c_array(array: &Value) -> Self { let mut polynomial: Vec = vec![]; let c_array: Vec = array @@ -178,13 +182,16 @@ impl Polynomial { } // Returns (quotient, remainder) - pub fn div(self, rhs: &Self) -> (Self, Self) { + pub fn div(&self, rhs: &Self) -> (Self, Self) { // Div by zero check ommitted since data is guaranteed to be non 0 eprintln!("{:?}, {:?}", self.polynomial.len(), rhs.polynomial.len()); if self.polynomial.len() < rhs.polynomial.len() { - return (Polynomial::new(vec![FieldElement::new(vec![0; 16])]), self); + return ( + Polynomial::new(vec![FieldElement::new(vec![0; 16])]), + self.clone(), + ); } let mut remainder = self.clone(); @@ -483,12 +490,13 @@ impl Ord for Polynomial { } } -pub fn gcd(a: Polynomial, b: Polynomial) -> Polynomial { +pub fn gcd(a: &Polynomial, b: &Polynomial) -> Polynomial { if a.is_zero() { - return b; + return b.clone(); } - return gcd(b.div(&a).1.monic(), a); + let monic_b = b.div(&a).1.monic(); + return gcd(&monic_b, a); } pub fn sort_polynomial_array(mut polys: Vec) -> Result> { @@ -1300,7 +1308,7 @@ mod tests { let a: Polynomial = Polynomial::from_c_array(&a); let b: Polynomial = Polynomial::from_c_array(&b); - let result = gcd(a.monic(), b.monic()); + let result = gcd(&a.monic(), &b.monic()); assert_eq!(json!(result.to_c_array()), expected); } @@ -1314,7 +1322,7 @@ mod tests { let a: Polynomial = Polynomial::from_c_array(&a); let b: Polynomial = Polynomial::from_c_array(&b); - let result = gcd(a.monic(), b.monic()); + let result = gcd(&a.monic(), &b.monic()); assert_eq!(json!(result.to_c_array()), expected); } diff --git a/src/utils/sff.rs b/src/utils/sff.rs new file mode 100644 index 0000000..f8f1358 --- /dev/null +++ b/src/utils/sff.rs @@ -0,0 +1,92 @@ +use serde::{Deserialize, Serialize}; + +use crate::utils::{ + field::FieldElement, + poly::{gcd, polynomial_2_block}, +}; + +use super::poly::Polynomial; + +#[derive(Debug, Serialize, Deserialize)] +pub struct Factors { + pub factor: Vec, + pub exponent: u32, +} + +pub fn sff(mut f: Polynomial) -> Vec<(Polynomial, u32)> { + let mut c = gcd(&f, &f.clone().diff()); + f = f.div(&c).0; + let mut z: Vec<(Polynomial, u32)> = vec![]; + let mut e: u32 = 1; + + let one_element = Polynomial::new(vec![FieldElement::new( + polynomial_2_block(vec![0], "gcm").unwrap(), + )]); + + while f != one_element { + let y = gcd(&f, &c); + if f != y { + z.push(((f.div(&y).0), e)); + } + + f = y.clone(); + c = c.div(&y).0; + e += 1; + } + + if c != one_element { + let r = sff(c.sqrt()); + for (f_star, e_star) in r { + z.push((f_star, 2 * e_star)); + } + } + + 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 byte_indices_0x01() { + let json_f = json!([ + "vL77UwAAAAAAAAAAAAAAAA==", + "mEHchYAAAAAAAAAAAAAAAA==", + "9WJa0MAAAAAAAAAAAAAAAA==", + "akHfwWAAAAAAAAAAAAAAAA==", + "E12o/QAAAAAAAAAAAAAAAA==", + "vKJ/FgAAAAAAAAAAAAAAAA==", + "yctWwAAAAAAAAAAAAAAAAA==", + "c1BXYAAAAAAAAAAAAAAAAA==", + "o0AtAAAAAAAAAAAAAAAAAA==", + "AbP2AAAAAAAAAAAAAAAAAA==", + "k2YAAAAAAAAAAAAAAAAAAA==", + "vBYAAAAAAAAAAAAAAAAAAA==", + "dSAAAAAAAAAAAAAAAAAAAA==", + "69gAAAAAAAAAAAAAAAAAAA==", + "VkAAAAAAAAAAAAAAAAAAAA==", + "a4AAAAAAAAAAAAAAAAAAAA==", + "gAAAAAAAAAAAAAAAAAAAAA==" + ]); + let poly_f = Polynomial::from_c_array(&json_f); + + let mut factors = sff(poly_f); + factors.sort(); + let mut result: Vec = vec![]; + + for (factor, exponent) in factors { + result.push(Factors { + factor: factor.to_c_array(), + exponent, + }); + } + + println!("{:?}", result); + let bit_indices: Vec = vec![0]; + assert!(false) + } +} diff --git a/test_json/sandbox.json b/test_json/sandbox.json index 48d59ed..007d487 100644 --- a/test_json/sandbox.json +++ b/test_json/sandbox.json @@ -1,26 +1,26 @@ { "testcases": { "sandbox": { - "action": "gfpoly_gcd", + "action": "gfpoly_factor_sff", "arguments": { - "A": [ - "DNWpXnnY24XecPa7a8vrEA==", - "I8uYpCbsiPaVvUznuv1IcA==", - "wsbiU432ARWuO93He3vbvA==", - "zp0g3o8iNz7Y+8oUxw1vJw==", - "J0GekE3uendpN6WUAuJ4AA==", - "wACd0e6u1ii4AAAAAAAAAA==", - "ACAAAAAAAAAAAAAAAAAAAA==" - ], - "B": [ - "I20VjJmlSnRSe88gaDiLRQ==", - "0Cw5HxJm/pfybJoQDf7/4w==", - "8ByrMMf+vVj5r3YXUNCJ1g==", - "rEU/f2UZRXqmZ6V7EPKfBA==", - "LfdALhvCrdhhGZWl9l9DSg==", - "KSUKhN0n6/DZmHPozd1prw==", - "DQrRkuA9Zx279wAAAAAAAA==", - "AhCEAAAAAAAAAAAAAAAAAA==" + "F": [ + "vL77UwAAAAAAAAAAAAAAAA==", + "mEHchYAAAAAAAAAAAAAAAA==", + "9WJa0MAAAAAAAAAAAAAAAA==", + "akHfwWAAAAAAAAAAAAAAAA==", + "E12o/QAAAAAAAAAAAAAAAA==", + "vKJ/FgAAAAAAAAAAAAAAAA==", + "yctWwAAAAAAAAAAAAAAAAA==", + "c1BXYAAAAAAAAAAAAAAAAA==", + "o0AtAAAAAAAAAAAAAAAAAA==", + "AbP2AAAAAAAAAAAAAAAAAA==", + "k2YAAAAAAAAAAAAAAAAAAA==", + "vBYAAAAAAAAAAAAAAAAAAA==", + "dSAAAAAAAAAAAAAAAAAAAA==", + "69gAAAAAAAAAAAAAAAAAAA==", + "VkAAAAAAAAAAAAAAAAAAAA==", + "a4AAAAAAAAAAAAAAAAAAAA==", + "gAAAAAAAAAAAAAAAAAAAAA==" ] } }