feat: add division and powmod (WIP) and start adapting task runner

This commit is contained in:
alivecow 2024-11-14 22:30:55 +01:00
parent a05f2f02b6
commit deb4261121
4 changed files with 183 additions and 16 deletions

View file

@ -11,6 +11,7 @@ use tasks01::{
gcm::{gcm_decrypt, gcm_encrypt}, gcm::{gcm_decrypt, gcm_encrypt},
gfmul::gfmul_task, gfmul::gfmul_task,
pad_oracle::padding_oracle, pad_oracle::padding_oracle,
pfmath::gfpoly_add,
poly2block::poly2block, poly2block::poly2block,
sea128::sea128, sea128::sea128,
xex::{self, fde_xex}, xex::{self, fde_xex},
@ -83,6 +84,12 @@ pub fn task_deploy(testcase: &Testcase) -> Result<Value> {
Ok(json) Ok(json)
} }
"gfpoly_add" => {
let result = gfpoly_add(args)?;
let json = json!({"plaintext" : result.to_c_array()});
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; {:?}",
testcase, testcase,

View file

@ -2,6 +2,7 @@ pub mod block2poly;
pub mod gcm; pub mod gcm;
pub mod gfmul; pub mod gfmul;
pub mod pad_oracle; pub mod pad_oracle;
pub mod pfmath;
pub mod poly2block; pub mod poly2block;
pub mod sea128; pub mod sea128;
pub mod xex; pub mod xex;

View file

@ -0,0 +1,15 @@
use anyhow::Result;
use base64::{prelude::BASE64_STANDARD, Engine};
use serde_json::Value;
use crate::utils::field::Polynomial;
pub fn gfpoly_add(args: &Value) -> Result<Polynomial> {
let poly_a = Polynomial::from_c_array(&args["A"].clone());
let poly_b = Polynomial::from_c_array(&args["B"].clone());
let result = poly_a + poly_b;
Ok(result)
}

View file

@ -58,14 +58,12 @@ impl Polynomial {
pub fn pow(&self, mut exponent: u128) -> Polynomial { pub fn pow(&self, mut exponent: u128) -> Polynomial {
if exponent == 0 { if exponent == 0 {
// Return polynomial with coefficient 1 return Polynomial::new(vec![FieldElement::new(vec![0])]);
return Polynomial::new(vec![FieldElement::new(vec![1])]);
} }
let base = self.clone(); let base = self.clone();
let mut result = base.clone(); let mut result = base.clone();
exponent -= 1; // Subtract 1 because we already set result to base exponent -= 1;
while exponent > 0 { while exponent > 0 {
result = result * base.clone(); result = result * base.clone();
exponent -= 1; exponent -= 1;
@ -73,16 +71,90 @@ impl Polynomial {
result result
} }
/*
pub fn to_b64(&self) -> String { pub fn pow_mod(mut self, mut exponent: u128, modulus: Polynomial) -> Polynomial {
let mut output: Vec<String> = vec![]; let mut result: Polynomial = Polynomial::new(vec![FieldElement::new(
for coeff in self.polynomial { polynomial_2_block(vec![0], "gcm").unwrap(),
output.push(BASE64_STANDARD.encode(coeff)); )]);
eprintln!("Initial result: {:?}", result);
while exponent > 0 {
eprintln!("Current exponent: {:02X}", exponent);
if exponent & 1 == 1 {
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;
}
result
}
// Returns (quotient, remainder)
pub fn div(self, rhs: &Self) -> (Self, Self) {
// Div by zero check ommitted since data is guaranteed to be non 0
let mut remainder = self.clone();
let divisor = rhs;
let dividend_deg = remainder.polynomial.len() - 1;
let divisor_deg = divisor.polynomial.len() - 1;
if dividend_deg < divisor_deg {
return (
Polynomial::new(vec![FieldElement::new(
polynomial_2_block(vec![0; 16], "gcm").unwrap(),
)]),
remainder,
);
} }
output let mut quotient_coeffs =
vec![
FieldElement::new(polynomial_2_block(vec![0; 16], "gcm").unwrap());
dividend_deg - divisor_deg + 1
];
while remainder.polynomial.len() >= divisor.polynomial.len() {
let deg_diff = remainder.polynomial.len() - divisor.polynomial.len();
let leading_dividend = remainder.polynomial.last().unwrap();
let leading_divisor = divisor.polynomial.last().unwrap();
let quot_coeff = leading_dividend / leading_divisor;
quotient_coeffs[deg_diff] = quot_coeff.clone();
let mut subtrahend =
vec![FieldElement::new(polynomial_2_block(vec![0; 16], "gcm").unwrap()); deg_diff];
subtrahend.extend(
divisor
.polynomial
.iter()
.map(|x| x.clone() * quot_coeff.clone()),
);
let subtrahend_poly = Polynomial::new(subtrahend);
remainder = remainder + subtrahend_poly;
while !remainder.polynomial.is_empty()
&& remainder
.polynomial
.last()
.unwrap()
.as_ref()
.iter()
.all(|&x| x == 0)
{
remainder.polynomial.pop();
}
}
(Polynomial::new(quotient_coeffs), remainder)
} }
*/
} }
impl Clone for Polynomial { impl Clone for Polynomial {
@ -318,15 +390,20 @@ impl Div for &FieldElement {
self.clone() * rhs_inv self.clone() * rhs_inv
} }
} }
/*
//TODO: Not yet ready
impl Rem for FieldElement {
fn rem(self, rhs: Self) -> Self::Output {
/*
impl Rem for FieldElement {
type Output = Self;
fn rem(self, rhs: Self) -> Self::Output {
let result: FieldElement = self.field_element;
while self.field_element[15] != 0x00 {
self.field_element
}
todo!();
} }
} }
*/ */
/* /*
impl BitXor for FieldElement { impl BitXor for FieldElement {
fn bitxor(self, rhs: Self) -> Self::Output { fn bitxor(self, rhs: Self) -> Self::Output {
@ -642,6 +719,32 @@ mod tests {
//assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA==");
} }
#[test]
fn test_field_pow_mod_01() {
let json1 = json!([
"JAAAAAAAAAAAAAAAAAAAAA==",
"wAAAAAAAAAAAAAAAAAAAAA==",
"ACAAAAAAAAAAAAAAAAAAAA=="
]);
let element1: Polynomial = Polynomial::from_c_array(&json1);
let result = element1.pow(3);
assert_eq!(
result.to_c_array(),
vec![
"AkkAAAAAAAAAAAAAAAAAAA==",
"DDAAAAAAAAAAAAAAAAAAAA==",
"LQIIAAAAAAAAAAAAAAAAAA==",
"8AAAAAAAAAAAAAAAAAAAAA==",
"ACgCQAAAAAAAAAAAAAAAAA==",
"AAAMAAAAAAAAAAAAAAAAAA==",
"AAAAAgAAAAAAAAAAAAAAAA=="
]
);
//assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA==");
}
#[test] #[test]
fn test_poly_div_01() { fn test_poly_div_01() {
let element1 = let element1 =
@ -654,4 +757,45 @@ mod tests {
assert_eq!(BASE64_STANDARD.encode(result), "OAAAAAAAAAAAAAAAAAAAAA=="); assert_eq!(BASE64_STANDARD.encode(result), "OAAAAAAAAAAAAAAAAAAAAA==");
} }
#[test]
fn test_field_poly_div_01() {
let json1 = json!([
"JAAAAAAAAAAAAAAAAAAAAA==",
"wAAAAAAAAAAAAAAAAAAAAA==",
"ACAAAAAAAAAAAAAAAAAAAA=="
]);
let json2 = json!(["0AAAAAAAAAAAAAAAAAAAAA==", "IQAAAAAAAAAAAAAAAAAAAA=="]);
let element1: Polynomial = Polynomial::from_c_array(&json1);
let element2: Polynomial = Polynomial::from_c_array(&json2);
//eprintln!("{:?}", element1);
println!("Beginning the new division");
let (result, remainder) = element1.div(&element2);
assert_eq!(
result.to_c_array(),
vec!["nAIAgCAIAgCAIAgCAIAgCg==", "m85znOc5znOc5znOc5znOQ=="]
);
assert_eq!(remainder.to_c_array(), vec!["lQNA0DQNA0DQNA0DQNA0Dg=="]);
//assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA==");
}
#[test]
fn test_field_poly_powmod_01() {
let json1 = json!([
"JAAAAAAAAAAAAAAAAAAAAA==",
"wAAAAAAAAAAAAAAAAAAAAA==",
"ACAAAAAAAAAAAAAAAAAAAA=="
]);
let json2 = json!(["KryptoanalyseAAAAAAAAA==", "DHBWMannheimAAAAAAAAAA=="]);
let element1: Polynomial = Polynomial::from_c_array(&json1);
let modulus: Polynomial = Polynomial::from_c_array(&json2);
let result = element1.pow_mod(1000, modulus);
eprintln!("Result is: {:02X?}", result);
assert_eq!(result.to_c_array(), vec!["XrEhmKuat+Glt5zZWtMo6g=="]);
}
} }