feat/refactor: Change unneded vec initialisations and start on possible new gfmul

This commit is contained in:
Alivecow 2024-11-29 13:49:57 +01:00
parent 270abdb7b7
commit 5b27a4ad9c
2 changed files with 81 additions and 19 deletions

View file

@ -9,6 +9,8 @@ use std::{
use anyhow::{anyhow, Ok, Result}; use anyhow::{anyhow, Ok, Result};
use crate::utils::poly::bgfmul;
use super::poly::polynomial_2_block; use super::poly::polynomial_2_block;
use super::{ use super::{
math::{reverse_bits_in_bytevec, xor_bytes}, math::{reverse_bits_in_bytevec, xor_bytes},
@ -22,7 +24,7 @@ pub struct FieldElement {
impl FieldElement { impl FieldElement {
pub const IRREDUCIBLE_POLYNOMIAL: [u8; 17] = [ pub const IRREDUCIBLE_POLYNOMIAL: [u8; 17] = [
87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, 0x87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01,
]; ];
pub fn rand() -> Self { pub fn rand() -> Self {
@ -30,10 +32,14 @@ impl FieldElement {
FieldElement::new(rand_field.to_vec()) FieldElement::new(rand_field.to_vec())
} }
pub fn zero(self) -> Self { pub fn zero() -> Self {
FieldElement::new(vec![0]) FieldElement::new(vec![0])
} }
pub fn one() -> Self {
FieldElement::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
}
pub const fn new(field_element: Vec<u8>) -> Self { pub const fn new(field_element: Vec<u8>) -> Self {
Self { field_element } Self { field_element }
} }
@ -47,8 +53,7 @@ impl FieldElement {
} }
pub fn pow(mut self, mut exponent: u128) -> FieldElement { pub fn pow(mut self, mut exponent: u128) -> FieldElement {
let mut result: FieldElement = let mut result: FieldElement = FieldElement::one();
FieldElement::new(polynomial_2_block(vec![0], "gcm").unwrap());
if exponent == 1 { if exponent == 1 {
eprintln!("special case 1: {:02X?}", self.clone()); eprintln!("special case 1: {:02X?}", self.clone());
@ -57,7 +62,7 @@ impl FieldElement {
} }
if exponent == 0 { if exponent == 0 {
let result = FieldElement::new(polynomial_2_block(vec![0], "gcm").unwrap()); let result = FieldElement::one();
eprintln!("Returned value is: {:02X?}", result); eprintln!("Returned value is: {:02X?}", result);
return result; return result;
@ -90,8 +95,10 @@ impl FieldElement {
} }
pub fn inv(mut self) -> Self { pub fn inv(mut self) -> Self {
let mut inverser: u128 = 0xfffffffffffffffffffffffffffffffe; const INVERSER_START: u128 = 0xfffffffffffffffffffffffffffffffe;
let mut inverse: Vec<u8> = polynomial_2_block(vec![0], "gcm").unwrap();
let mut inverser = INVERSER_START;
let mut inverse: Vec<u8> = vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
//eprintln!("Inverse start {:02X?}", inverse); //eprintln!("Inverse start {:02X?}", inverse);
while inverser > 0 { while inverser > 0 {
@ -187,7 +194,7 @@ impl Div for FieldElement {
type Output = Self; type Output = Self;
fn div(self, rhs: Self) -> Self::Output { fn div(self, rhs: Self) -> Self::Output {
let inverse = rhs.inv(); let inverse = rhs.inv();
self.clone() * inverse self * inverse
} }
} }
@ -195,10 +202,7 @@ impl Div for &FieldElement {
type Output = FieldElement; type Output = FieldElement;
fn div(self, rhs: Self) -> Self::Output { fn div(self, rhs: Self) -> Self::Output {
// First clone and invert the divisor (rhs) self.clone() * rhs.clone().inv()
let rhs_inv = rhs.clone().inv();
// Multiply original number by the inverse
self.clone() * rhs_inv
} }
} }

View file

@ -1,6 +1,7 @@
use crate::utils::field::ByteArray; use crate::utils::field::ByteArray;
use base64::alphabet::BIN_HEX; use base64::alphabet::BIN_HEX;
use base64::prelude::*; use base64::prelude::*;
use num::traits::FromBytes;
use num::{BigInt, BigUint, One, Zero}; use num::{BigInt, BigUint, One, Zero};
use std::{str::FromStr, u128, u8, usize}; use std::{str::FromStr, u128, u8, usize};
@ -13,6 +14,7 @@ use anyhow::{anyhow, Ok, Result};
use serde_json::Value; use serde_json::Value;
use super::field::FieldElement; use super::field::FieldElement;
use super::math::reverse_bits_in_bytevec;
#[derive(Debug, serde::Serialize, serde::Deserialize)] #[derive(Debug, serde::Serialize, serde::Deserialize)]
pub struct Polynomial { pub struct Polynomial {
@ -291,10 +293,7 @@ impl Polynomial {
} }
let mut quotient_coeffs = let mut quotient_coeffs =
vec![ vec![FieldElement::new(vec![0; 16]); dividend_deg - divisor_deg + 1];
FieldElement::new(polynomial_2_block(vec![0; 16], "gcm").unwrap());
dividend_deg - divisor_deg + 1
];
while remainder.polynomial.len() >= divisor.polynomial.len() { while remainder.polynomial.len() >= divisor.polynomial.len() {
let deg_diff = remainder.polynomial.len() - divisor.polynomial.len(); let deg_diff = remainder.polynomial.len() - divisor.polynomial.len();
@ -305,8 +304,7 @@ impl Polynomial {
quotient_coeffs[deg_diff] = quot_coeff.clone(); quotient_coeffs[deg_diff] = quot_coeff.clone();
let mut subtrahend = let mut subtrahend = vec![FieldElement::new(vec![0; 16]); deg_diff];
vec![FieldElement::new(polynomial_2_block(vec![0; 16], "gcm").unwrap()); deg_diff];
subtrahend.extend( subtrahend.extend(
divisor divisor
.polynomial .polynomial
@ -658,6 +656,53 @@ pub fn gfmul(poly_a: &Vec<u8>, poly_b: &Vec<u8>, semantic: &str) -> Result<Vec<u
Ok(result.0) Ok(result.0)
} }
pub fn bgfmul(poly_a: &Vec<u8>, poly_b: &Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
//TODO: Implement gfmul with bigint
let red_poly_bytes: BigUint = BigUint::from_slice(&[
0x87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 0x01,
]);
let mut poly1: BigUint = BigUint::from_le_bytes(&reverse_bits_in_bytevec(poly_a.to_owned()));
let mut poly2: BigUint = BigUint::from_le_bytes(&reverse_bits_in_bytevec(poly_b.to_owned()));
/*
if semantic == "gcm" {
poly1.re;
poly2.reverse_bits_in_bytevec();
}
*/
let mut result: BigUint = BigUint::zero();
if (&poly2 & (BigUint::one() << 127)) == BigUint::one() {
result = &result ^ &poly1;
}
poly2 = &poly2 >> 1;
while &poly2 != &BigUint::zero() {
poly1 = &poly1 << 1;
if (&poly1 & (BigUint::one() << 127)) == BigUint::one() {
poly1 = &poly1 ^ &red_poly_bytes;
}
if &poly2 & BigUint::one() == BigUint::one() {
result = &result ^ &poly1;
}
poly2 = &poly2 >> 1;
}
/*
if semantic == "gcm" {
result.reverse_bits_in_bytevec();
}
*/
Ok(reverse_bits_in_bytevec(result.to_bytes_le()))
}
pub fn convert_gcm_to_xex(gcm_poly: Vec<u8>) -> Result<Vec<u8>> { pub fn convert_gcm_to_xex(gcm_poly: Vec<u8>) -> Result<Vec<u8>> {
let xex_poly = gcm_poly let xex_poly = gcm_poly
.into_iter() .into_iter()
@ -795,7 +840,7 @@ pub fn coefficient_to_binary(coefficients: Vec<u8>) -> u128 {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use crate::utils::poly::b64_2_num; use crate::utils::poly::{b64_2_num, gcd};
use anyhow::Result; use anyhow::Result;
use serde_json::json; use serde_json::json;
// Note this useful idiom: importing names from outer (for mod tests) scope. // Note this useful idiom: importing names from outer (for mod tests) scope.
@ -1429,4 +1474,17 @@ mod tests {
assert_eq!(json!(result.to_c_array()), expected); assert_eq!(json!(result.to_c_array()), expected);
} }
#[test]
fn test_poly_gcd_stress() {
eprintln!("{:?}", Polynomial::one());
let poly1 = Polynomial::rand(&(500 as usize));
let poly2 = Polynomial::rand(&(500 as usize));
let result = gcd(&poly1.monic(), &poly2.monic());
eprintln!("{:02X?}", result.to_c_array());
assert!(true);
}
} }