diff --git a/src/utils/dff.rs b/src/utils/dff.rs index a4ebda8..da41e33 100644 --- a/src/utils/dff.rs +++ b/src/utils/dff.rs @@ -20,7 +20,7 @@ pub fn ddf(f: Polynomial) -> Vec<(Polynomial, u128)> { let one_cmp = Polynomial::one(); while f_star.degree() as u128 >= (d) { - let h = Polynomial::x().bpow_mod(q.clone().pow(d), f_star.clone()) + Polynomial::x(); + let h = Polynomial::x().bpow_mod(q.clone().pow(d), &f_star) + Polynomial::x(); let g = gcd(&h, &f_star); if g != one_cmp { diff --git a/src/utils/edf.rs b/src/utils/edf.rs index e69de29..134a743 100644 --- a/src/utils/edf.rs +++ b/src/utils/edf.rs @@ -0,0 +1,105 @@ +use base64::{prelude::BASE64_STANDARD, Engine}; +use num::{BigUint, FromPrimitive, Integer, One}; +use rand::Rng; + +use crate::utils::{field::FieldElement, poly::non_monic_gcd}; + +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()]; + 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(0..f.degree())); + //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); + + //eprintln!("z before for {:0X?}", z); + + for i in 0..z.len() { + if z[i].degree() as u32 > d { + //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()); + z.push(intemediate); + } + } + } + + //eprintln!("z after for {:0X?}", z); + } + + 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_edf_sheet() { + let json_f = json!([ + "mmAAAAAAAAAAAAAAAAAAAA==", + "AbAAAAAAAAAAAAAAAAAAAA==", + "zgAAAAAAAAAAAAAAAAAAAA==", + "FwAAAAAAAAAAAAAAAAAAAA==", + "AAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "gAAAAAAAAAAAAAAAAAAAAA==" + ]); + let d = 3; + let poly_f = Polynomial::from_c_array(&json_f); + + let mut factors = edf(poly_f, d); + factors.sort(); + + let mut result: Vec> = vec![]; + + for factor in factors { + result.push(factor.to_c_array()) + } + + println!("Result: {:?}", result); + + assert_eq!( + result, + vec![ + [ + "iwAAAAAAAAAAAAAAAAAAAA==", + "CAAAAAAAAAAAAAAAAAAAAA==", + "AAAAAAAAAAAAAAAAAAAAAA==", + "gAAAAAAAAAAAAAAAAAAAAA==" + ], + [ + "kAAAAAAAAAAAAAAAAAAAAA==", + "CAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "gAAAAAAAAAAAAAAAAAAAAA==" + ] + ] + ) + } +} diff --git a/src/utils/field.rs b/src/utils/field.rs index bbdfa91..2dea48b 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -1,4 +1,5 @@ use base64::prelude::*; +use rand::{random, Rng, RngCore}; use std::{u128, u8, usize}; use std::{ @@ -24,6 +25,11 @@ impl FieldElement { 87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, ]; + pub fn rand() -> Self { + let rand_field: [u8; 16] = rand::random(); + FieldElement::new(rand_field.to_vec()) + } + pub fn zero(self) -> Self { FieldElement::new(vec![0]) } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index ef625ce..84194cd 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -41,6 +41,15 @@ impl Polynomial { ]) } + pub fn rand(rng_cap: &usize) -> Self { + let mut rand_poly: Vec = Vec::with_capacity(rng_cap.to_owned()); + for _i in 0..rng_cap.to_owned() { + rand_poly.push(FieldElement::rand()); + } + + Polynomial::new(rand_poly) + } + pub fn zero() -> Self { Polynomial::new(vec![FieldElement::new(vec![0; 16])]) } @@ -141,7 +150,7 @@ impl Polynomial { result } - pub fn bpow_mod(mut self, mut exponent: BigUint, modulus: Polynomial) -> Polynomial { + 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(), )]); @@ -572,6 +581,15 @@ pub fn gcd(a: &Polynomial, b: &Polynomial) -> Polynomial { return gcd(&monic_b, a); } +pub fn non_monic_gcd(a: &Polynomial, b: &Polynomial) -> Polynomial { + if a.is_zero() { + return b.clone(); + } + + let b = b.div(&a).1; + return non_monic_gcd(&b, a); +} + pub fn sort_polynomial_array(mut polys: Vec) -> Result> { // Algorithm to sort polynomials // First sorting round