Add polynomial sorting #16
4 changed files with 220 additions and 33 deletions
|
|
@ -8,10 +8,12 @@ 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::{gfdiv, gfpoly_add, gfpoly_divmod, gfpoly_mul, gfpoly_pow, gfpoly_powmod},
|
pfmath::{
|
||||||
|
gfdiv, gfpoly_add, gfpoly_divmod, gfpoly_mul, gfpoly_pow, gfpoly_powmod, gfpoly_sort,
|
||||||
|
},
|
||||||
poly2block::poly2block,
|
poly2block::poly2block,
|
||||||
sea128::sea128,
|
sea128::sea128,
|
||||||
xex::{fde_xex},
|
xex::fde_xex,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{anyhow, Result};
|
use anyhow::{anyhow, Result};
|
||||||
|
|
@ -118,6 +120,18 @@ pub fn task_deploy(testcase: &Testcase) -> Result<Value> {
|
||||||
|
|
||||||
Ok(json)
|
Ok(json)
|
||||||
}
|
}
|
||||||
|
"gfpoly_sort" => {
|
||||||
|
let sorted_array = gfpoly_sort(args)?;
|
||||||
|
let mut result: Vec<Vec<String>> = vec![];
|
||||||
|
|
||||||
|
for poly in sorted_array {
|
||||||
|
result.push(poly.to_c_array());
|
||||||
|
}
|
||||||
|
|
||||||
|
let json = json!({"sorted_polys" : json!(result)});
|
||||||
|
|
||||||
|
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; {:?}",
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use anyhow::Result;
|
||||||
use base64::{prelude::BASE64_STANDARD, Engine};
|
use base64::{prelude::BASE64_STANDARD, Engine};
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
use crate::utils::field::{FieldElement, Polynomial};
|
use crate::utils::field::{sort_polynomial_array, FieldElement, Polynomial};
|
||||||
|
|
||||||
pub fn gfpoly_add(args: &Value) -> Result<Polynomial> {
|
pub fn gfpoly_add(args: &Value) -> Result<Polynomial> {
|
||||||
let poly_a = Polynomial::from_c_array(&args["A"].clone());
|
let poly_a = Polynomial::from_c_array(&args["A"].clone());
|
||||||
|
|
@ -67,3 +67,75 @@ pub fn gfpoly_powmod(args: &Value) -> Result<Polynomial> {
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn gfpoly_sort(args: &Value) -> Result<Vec<Polynomial>> {
|
||||||
|
let poly_arrays: Vec<Value> = serde_json::from_value(args["polys"].clone())?;
|
||||||
|
let mut polys: Vec<Polynomial> = vec![];
|
||||||
|
|
||||||
|
for array in poly_arrays {
|
||||||
|
polys.push(Polynomial::from_c_array(&array));
|
||||||
|
}
|
||||||
|
|
||||||
|
polys.sort();
|
||||||
|
//polys.sort();
|
||||||
|
Ok(polys)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use serde_json::json;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_poly_sorting() {
|
||||||
|
let json1 = json!(
|
||||||
|
{"polys": [
|
||||||
|
[
|
||||||
|
"NeverGonnaGiveYouUpAAA==",
|
||||||
|
"NeverGonnaLetYouDownAA==",
|
||||||
|
"NeverGonnaRunAroundAAA==",
|
||||||
|
"AndDesertYouAAAAAAAAAA=="
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"WereNoStrangersToLoveA==",
|
||||||
|
"YouKnowTheRulesAAAAAAA==",
|
||||||
|
"AndSoDoIAAAAAAAAAAAAAA=="
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"NeverGonnaMakeYouCryAA==",
|
||||||
|
"NeverGonnaSayGoodbyeAA==",
|
||||||
|
"NeverGonnaTellALieAAAA==",
|
||||||
|
"AndHurtYouAAAAAAAAAAAA=="
|
||||||
|
]
|
||||||
|
]});
|
||||||
|
|
||||||
|
let expected = json!([
|
||||||
|
[
|
||||||
|
"WereNoStrangersToLoveA==",
|
||||||
|
"YouKnowTheRulesAAAAAAA==",
|
||||||
|
"AndSoDoIAAAAAAAAAAAAAA=="
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"NeverGonnaMakeYouCryAA==",
|
||||||
|
"NeverGonnaSayGoodbyeAA==",
|
||||||
|
"NeverGonnaTellALieAAAA==",
|
||||||
|
"AndHurtYouAAAAAAAAAAAA=="
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"NeverGonnaGiveYouUpAAA==",
|
||||||
|
"NeverGonnaLetYouDownAA==",
|
||||||
|
"NeverGonnaRunAroundAAA==",
|
||||||
|
"AndDesertYouAAAAAAAAAA=="
|
||||||
|
]
|
||||||
|
]);
|
||||||
|
|
||||||
|
let sorted_array = gfpoly_sort(&json1).unwrap();
|
||||||
|
let mut result: Vec<Vec<String>> = vec![];
|
||||||
|
for poly in sorted_array {
|
||||||
|
result.push(poly.to_c_array());
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_eq!(json!(result), expected);
|
||||||
|
//assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA==");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,7 @@
|
||||||
use std::ops::{Add, BitXor, Div, Mul, Sub};
|
use std::{
|
||||||
|
cmp::Ordering,
|
||||||
|
ops::{Add, BitXor, Div, Mul, Sub},
|
||||||
|
};
|
||||||
|
|
||||||
use anyhow::{anyhow, Ok, Result};
|
use anyhow::{anyhow, Ok, Result};
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
|
|
@ -8,7 +11,7 @@ use crate::utils::poly::polynomial_2_block;
|
||||||
|
|
||||||
use super::{math::xor_bytes, poly::gfmul};
|
use super::{math::xor_bytes, poly::gfmul};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, serde::Serialize)]
|
||||||
pub struct Polynomial {
|
pub struct Polynomial {
|
||||||
polynomial: Vec<FieldElement>,
|
polynomial: Vec<FieldElement>,
|
||||||
}
|
}
|
||||||
|
|
@ -284,17 +287,14 @@ impl Add for Polynomial {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper implementation for subtraction
|
|
||||||
impl Sub for &FieldElement {
|
impl Sub for &FieldElement {
|
||||||
type Output = FieldElement;
|
type Output = FieldElement;
|
||||||
|
|
||||||
fn sub(self, rhs: Self) -> FieldElement {
|
fn sub(self, rhs: Self) -> FieldElement {
|
||||||
// In a field of characteristic 2, addition and subtraction are the same operation (XOR)
|
|
||||||
self + rhs
|
self + rhs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper trait for checking emptiness
|
|
||||||
trait IsEmpty {
|
trait IsEmpty {
|
||||||
fn is_empty(&self) -> bool;
|
fn is_empty(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
@ -310,7 +310,66 @@ impl AsRef<[FieldElement]> for Polynomial {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
impl PartialEq for Polynomial {
|
||||||
|
fn eq(&self, other: &Self) -> bool {
|
||||||
|
if self.polynomial.len() != other.polynomial.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// Compare each coefficient
|
||||||
|
self.polynomial
|
||||||
|
.iter()
|
||||||
|
.zip(other.polynomial.iter())
|
||||||
|
.all(|(a, b)| a == b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PartialOrd for Polynomial {
|
||||||
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
|
if self.polynomial.len() != other.polynomial.len() {
|
||||||
|
return Some(self.polynomial.len().cmp(&other.polynomial.len()));
|
||||||
|
} else {
|
||||||
|
for (field_a, field_b) in self.as_ref().iter().rev().zip(other.as_ref().iter().rev()) {
|
||||||
|
match field_a.cmp(field_b) {
|
||||||
|
std::cmp::Ordering::Equal => continue,
|
||||||
|
other => return Some(other.reverse()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Some(Ordering::Equal)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for Polynomial {}
|
||||||
|
|
||||||
|
impl Ord for Polynomial {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
match self.polynomial.len().cmp(&other.polynomial.len()) {
|
||||||
|
Ordering::Equal => {
|
||||||
|
for (field_a, field_b) in
|
||||||
|
self.as_ref().iter().rev().zip(other.as_ref().iter().rev())
|
||||||
|
{
|
||||||
|
match field_a.cmp(field_b) {
|
||||||
|
std::cmp::Ordering::Equal => continue,
|
||||||
|
other => return other.reverse(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ordering::Equal
|
||||||
|
}
|
||||||
|
other => other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn sort_polynomial_array(mut polys: Vec<Polynomial>) -> Result<Vec<Polynomial>> {
|
||||||
|
// Algorithm to sort polynomials
|
||||||
|
// First sorting round
|
||||||
|
// Sorting by degree of polynomial
|
||||||
|
polys.sort();
|
||||||
|
|
||||||
|
Ok(polys)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, serde::Serialize)]
|
||||||
pub struct FieldElement {
|
pub struct FieldElement {
|
||||||
field_element: Vec<u8>,
|
field_element: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
@ -462,34 +521,39 @@ impl Div for &FieldElement {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
impl PartialOrd for FieldElement {
|
||||||
impl Rem for FieldElement {
|
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
|
||||||
type Output = Self;
|
for (byte_a, byte_b) in self.as_ref().iter().rev().zip(other.as_ref().iter().rev()) {
|
||||||
fn rem(self, rhs: Self) -> Self::Output {
|
match byte_a.reverse_bits().cmp(&byte_b.reverse_bits()) {
|
||||||
let result: FieldElement = self.field_element;
|
std::cmp::Ordering::Equal => continue,
|
||||||
|
other => return Some(other),
|
||||||
while self.field_element[15] != 0x00 {
|
}
|
||||||
self.field_element
|
|
||||||
}
|
}
|
||||||
todo!();
|
Some(Ordering::Equal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
/*
|
|
||||||
impl BitXor for FieldElement {
|
|
||||||
fn bitxor(self, rhs: Self) -> Self::Output {
|
|
||||||
FieldElement
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
impl PartialEq for FieldElement {
|
||||||
impl From<Vec<u8>> for FieldElement {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
fn from(item: Vec<u8>) -> Self {
|
self.field_element == other.field_element
|
||||||
FieldElement { bytes: item }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Eq for FieldElement {
|
||||||
|
// add code here
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Ord for FieldElement {
|
||||||
|
fn cmp(&self, other: &Self) -> Ordering {
|
||||||
|
for (byte_a, byte_b) in self.as_ref().iter().zip(other.as_ref().iter()) {
|
||||||
|
match byte_a.reverse_bits().cmp(&byte_b.reverse_bits()) {
|
||||||
|
std::cmp::Ordering::Equal => continue,
|
||||||
|
other => return other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ordering::Equal
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ByteArray(pub Vec<u8>);
|
pub struct ByteArray(pub Vec<u8>);
|
||||||
|
|
@ -1110,8 +1174,16 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_field_poly_powmod_kn_eqdeg() {
|
fn test_field_poly_powmod_kn_eqdeg() {
|
||||||
let json1 = json!(["JAAAAAAAAAAAAAAAAAAAAA==", "JAAAAAAAAAAAAAAAAAAAAA=="]);
|
let json1 = json!([
|
||||||
let json2 = json!(["KryptoanalyseAAAAAAAAA==", "KryptoanalyseAAAAAAAAA=="]);
|
"JAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"JAAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"KryptoanalyseAAAAAAAAA=="
|
||||||
|
]);
|
||||||
|
let json2 = json!([
|
||||||
|
"KryptoanalyseAAAAAAAAA==",
|
||||||
|
"KryptoanalyseAAAAAAAAA==",
|
||||||
|
"JAAAAAAAAABBAAAAAAAAAA=="
|
||||||
|
]);
|
||||||
let element1: Polynomial = Polynomial::from_c_array(&json1);
|
let element1: Polynomial = Polynomial::from_c_array(&json1);
|
||||||
let modulus: Polynomial = Polynomial::from_c_array(&json2);
|
let modulus: Polynomial = Polynomial::from_c_array(&json2);
|
||||||
|
|
||||||
|
|
|
||||||
29
test_json/poly_algs.json
Normal file
29
test_json/poly_algs.json
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
{
|
||||||
|
"testcases": {
|
||||||
|
"b856d760-023d-4b00-bad2-15d2b6da22fe": {
|
||||||
|
|
||||||
|
"action": "gfpoly_sort",
|
||||||
|
"arguments": {
|
||||||
|
"polys": [
|
||||||
|
[
|
||||||
|
"NeverGonnaGiveYouUpAAA==",
|
||||||
|
"NeverGonnaLetYouDownAA==",
|
||||||
|
"NeverGonnaRunAroundAAA==",
|
||||||
|
"AndDesertYouAAAAAAAAAA=="
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"WereNoStrangersToLoveA==",
|
||||||
|
"YouKnowTheRulesAAAAAAA==",
|
||||||
|
"AndSoDoIAAAAAAAAAAAAAA=="
|
||||||
|
],
|
||||||
|
[
|
||||||
|
"NeverGonnaMakeYouCryAA==",
|
||||||
|
"NeverGonnaSayGoodbyeAA==",
|
||||||
|
"NeverGonnaTellALieAAAA==",
|
||||||
|
"AndHurtYouAAAAAAAAAAAA=="
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue