feat: Add ddf algorithm
This commit is contained in:
parent
6856420ff9
commit
341b22e184
5 changed files with 193 additions and 13 deletions
|
|
@ -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<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)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<FieldElement> = vec![];
|
||||
let c_array: Vec<String> = 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(),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue