feat: Add edf calculation #27

Merged
0xalivecow merged 2 commits from dev into main 2024-11-28 12:22:17 +00:00
4 changed files with 131 additions and 1 deletions

View file

@ -19,6 +19,7 @@ pub fn ddf(f: Polynomial) -> Vec<(Polynomial, u128)> {
let mut f_star = f.clone(); let mut f_star = f.clone();
let one_cmp = Polynomial::one(); let one_cmp = Polynomial::one();
while f_star.degree() as u128 >= (2 * d) { while f_star.degree() as u128 >= (2 * 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.clone()) + Polynomial::x();

View file

@ -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<Polynomial> {
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<Polynomial> = 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<String>> = 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=="
]
]
)
}
}

View file

@ -1,4 +1,5 @@
use base64::prelude::*; use base64::prelude::*;
use rand::{random, Rng, RngCore};
use std::{u128, u8, usize}; use std::{u128, u8, usize};
use std::{ 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, 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 { pub fn zero(self) -> Self {
FieldElement::new(vec![0]) FieldElement::new(vec![0])
} }

View file

@ -41,6 +41,15 @@ impl Polynomial {
]) ])
} }
pub fn rand(rng_cap: &usize) -> Self {
let mut rand_poly: Vec<FieldElement> = 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 { pub fn zero() -> Self {
Polynomial::new(vec![FieldElement::new(vec![0; 16])]) Polynomial::new(vec![FieldElement::new(vec![0; 16])])
} }
@ -141,7 +150,7 @@ impl Polynomial {
result 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( let mut result: Polynomial = Polynomial::new(vec![FieldElement::new(
polynomial_2_block(vec![0], "gcm").unwrap(), polynomial_2_block(vec![0], "gcm").unwrap(),
)]); )]);
@ -572,6 +581,15 @@ pub fn gcd(a: &Polynomial, b: &Polynomial) -> Polynomial {
return gcd(&monic_b, a); 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<Polynomial>) -> Result<Vec<Polynomial>> { pub fn sort_polynomial_array(mut polys: Vec<Polynomial>) -> Result<Vec<Polynomial>> {
// Algorithm to sort polynomials // Algorithm to sort polynomials
// First sorting round // First sorting round