feat: Add ddf algorithm #25

Merged
0xalivecow merged 1 commit from dev into main 2024-11-26 12:21:49 +00:00
5 changed files with 193 additions and 13 deletions

View file

@ -10,6 +10,7 @@ base64 = "0.22"
openssl = "0.10" openssl = "0.10"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0"
num = "0.4"
[source.crates-io] [source.crates-io]
replace-with = "vendored-sources" replace-with = "vendored-sources"

View file

@ -9,8 +9,9 @@ use tasks01::{
gfmul::gfmul_task, gfmul::gfmul_task,
pad_oracle::padding_oracle, pad_oracle::padding_oracle,
pfmath::{ pfmath::{
gfdiv, gfpoly_add, gfpoly_diff, gfpoly_divmod, gfpoly_factor_sff, gfpoly_gcd, gfdiv, gfpoly_add, gfpoly_diff, gfpoly_divmod, gfpoly_factor_ddf, gfpoly_factor_sff,
gfpoly_make_monic, gfpoly_mul, gfpoly_pow, gfpoly_powmod, gfpoly_sort, gfpoly_sqrt, gfpoly_gcd, gfpoly_make_monic, gfpoly_mul, gfpoly_pow, gfpoly_powmod, gfpoly_sort,
gfpoly_sqrt,
}, },
poly2block::poly2block, poly2block::poly2block,
sea128::sea128, sea128::sea128,
@ -163,6 +164,12 @@ pub fn task_deploy(testcase: &Testcase) -> Result<Value> {
Ok(json) Ok(json)
} }
"gfpoly_factor_ddf" => {
let result = gfpoly_factor_ddf(args)?;
let json = json!({"factors" : result});
Ok(json)
}
_ => Err(anyhow!( _ => Err(anyhow!(
"Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}", "Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}",

View file

@ -1,11 +1,18 @@
use std::usize;
use anyhow::Result; use anyhow::Result;
use base64::{prelude::BASE64_STANDARD, Engine}; use base64::{prelude::BASE64_STANDARD, Engine};
use serde_json::Value; use serde_json::Value;
use crate::utils::{ use crate::{
field::FieldElement, tasks,
poly::{gcd, Polynomial}, utils::{
sff::{sff, Factors}, self,
dff::ddf,
field::FieldElement,
poly::{gcd, Polynomial},
sff::{sff, Factors},
},
}; };
pub fn gfpoly_add(args: &Value) -> Result<Polynomial> { pub fn gfpoly_add(args: &Value) -> Result<Polynomial> {
@ -135,6 +142,23 @@ pub fn gfpoly_factor_sff(arsg: &Value) -> Result<Vec<(Factors)>> {
Ok(result) Ok(result)
} }
pub fn gfpoly_factor_ddf(arsg: &Value) -> Result<Vec<(utils::dff::Factors)>> {
let poly_f = Polynomial::from_c_array(&arsg["F"].clone());
let mut factors = ddf(poly_f);
factors.sort();
let mut result: Vec<utils::dff::Factors> = vec![];
for (factor, degree) in factors {
result.push(utils::dff::Factors {
factor: factor.to_c_array(),
degree: degree as u32,
});
}
Ok(result)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;

View file

@ -1,10 +1,81 @@
use super::poly::Polynomial; use std::usize;
pub fn dff(f: Polynomial) { use num::{pow::Pow, traits::ToBytes, BigUint, FromPrimitive};
let q = 2u128.pow(128); use serde::{Deserialize, Serialize};
let z: Vec<(Polynomial, u32)> = vec![];
let d = 1;
let f_start = f.clone();
while f_start.degree() >= 2 * d {} use super::poly::{gcd, Polynomial};
#[derive(Debug, Serialize, Deserialize)]
pub struct Factors {
pub factor: Vec<String>,
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<Factors> = 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<u8> = vec![0];
assert!(false)
}
} }

View file

@ -1,5 +1,7 @@
use crate::utils::field::ByteArray; use crate::utils::field::ByteArray;
use base64::alphabet::BIN_HEX;
use base64::prelude::*; use base64::prelude::*;
use num::{BigInt, BigUint, One, Zero};
use std::{str::FromStr, u128, u8, usize}; use std::{str::FromStr, u128, u8, usize};
use std::{ use std::{
@ -26,6 +28,23 @@ impl Polynomial {
self.polynomial.len() 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 { pub fn from_c_array(array: &Value) -> Self {
let mut polynomial: Vec<FieldElement> = vec![]; let mut polynomial: Vec<FieldElement> = vec![];
let c_array: Vec<String> = array let c_array: Vec<String> = array
@ -122,6 +141,64 @@ impl Polynomial {
result 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 { pub fn pow_mod(mut self, mut exponent: u128, modulus: Polynomial) -> Polynomial {
let mut result: Polynomial = Polynomial::new(vec![FieldElement::new( let mut result: Polynomial = Polynomial::new(vec![FieldElement::new(
polynomial_2_block(vec![0], "gcm").unwrap(), polynomial_2_block(vec![0], "gcm").unwrap(),