From 6d808aef548ab629c63f652ae5535131cdadc338 Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Tue, 29 Oct 2024 20:22:02 +0100 Subject: [PATCH 1/8] chore: debug official ci --- src/main.rs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main.rs b/src/main.rs index 5816ecb..59e561b 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,6 +3,8 @@ use std::{ fs, }; +// TESTING + use anyhow::Result; fn main() -> Result<()> { -- 2.49.1 From 811e2b21f65169d70f360d94b644cfabb7ff99f0 Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Fri, 8 Nov 2024 13:09:12 +0100 Subject: [PATCH 2/8] feat: Implement field object and addition Starting work on proper field object Polynomial addition working --- src/utils/field.rs | 70 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 3 deletions(-) diff --git a/src/utils/field.rs b/src/utils/field.rs index 5645b04..37ceb74 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -1,7 +1,59 @@ -use anyhow::{anyhow, Ok, Result}; -use base64::Engine; +use std::ops::{Add, Mul}; -use super::poly::gfmul; +use anyhow::{anyhow, Ok, Result}; +use base64::prelude::*; + +use super::{math::xor_bytes, poly::gfmul}; + +#[derive(Debug)] +pub struct FieldElement { + polynomial: Vec, +} + +impl FieldElement { + pub const IRREDUCIBLE_POLYNOMIAL: [u8; 17] = [ + 87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, + ]; + + pub const fn new(polynomial: Vec) -> Self { + Self { polynomial } + } + + pub fn mul(&self, poly_a: Vec, poly_b: Vec) -> Result> { + gfmul(poly_a, poly_b, "gcm") + } +} + +impl Mul for FieldElement { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + FieldElement::new( + gfmul(self.polynomial, rhs.polynomial, "gcm").expect("Error during multiplication"), + ) + } +} + +impl Add for FieldElement { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + FieldElement::new(xor_bytes(&self.polynomial, rhs.polynomial).expect("Error in poly add")) + } +} + +impl AsRef<[u8]> for FieldElement { + fn as_ref(&self) -> &[u8] { + &self.polynomial.as_ref() + } +} + +/* +impl From> for FieldElement { + fn from(item: Vec) -> Self { + FieldElement { bytes: item } + } +} +*/ #[derive(Debug)] pub struct ByteArray(pub Vec); @@ -105,6 +157,7 @@ impl ByteArray { #[cfg(test)] mod tests { use super::*; + use base64::prelude::*; use std::fs; #[test] @@ -199,4 +252,15 @@ mod tests { assert_eq!(byte_array.0, vec![0x55, 0x55]); } + + #[test] + fn test_field_add_01() { + let element1: FieldElement = + FieldElement::new(BASE64_STANDARD.decode("NeverGonnaGiveYouUpAAA==").unwrap()); + let element2: FieldElement = + FieldElement::new(BASE64_STANDARD.decode("KryptoanalyseAAAAAAAAA==").unwrap()); + let sum = element2 + element1; + + assert_eq!(BASE64_STANDARD.encode(sum), "H1d3GuyA9/0OxeYouUpAAA=="); + } } -- 2.49.1 From 6e33e2e44c0b3f5592409c633de4a0fd793d2342 Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Sun, 10 Nov 2024 18:30:41 +0100 Subject: [PATCH 3/8] feat: Initial multiplication working --- src/utils/field.rs | 186 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 179 insertions(+), 7 deletions(-) diff --git a/src/utils/field.rs b/src/utils/field.rs index 37ceb74..f0da8f0 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -1,13 +1,104 @@ -use std::ops::{Add, Mul}; +use std::{ + env::args, + ops::{Add, Mul}, +}; use anyhow::{anyhow, Ok, Result}; use base64::prelude::*; +use serde_json::Value; use super::{math::xor_bytes, poly::gfmul}; +#[derive(Debug)] +pub struct Polynomial { + polynomial: Vec, +} + +impl Polynomial { + pub const fn new(polynomial: Vec) -> Self { + Self { polynomial } + } + + pub fn from_c_array(array: &Value) -> Self { + let mut polynomial: Vec = vec![]; + let c_array: Vec = array + .as_array() + .expect("Input is not an array") + .iter() + .map(|x| { + x.as_str() + .expect("Array element is not a string") + .to_string() + }) + .collect(); + + eprintln!("{:?}", c_array); + + for coefficient in c_array { + polynomial.push(FieldElement::new( + BASE64_STANDARD + .decode(coefficient) + .expect("Error on poly decode:"), + )); + } + Self { polynomial } + } + + pub fn to_c_array(self) -> Vec { + let mut output: Vec = vec![]; + for coeff in self.polynomial { + output.push(BASE64_STANDARD.encode(coeff)); + } + + output + } +} + +impl Mul for Polynomial { + type Output = Self; + + fn mul(self, rhs: Self) -> Self::Output { + let mut polynomial: Vec = + vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1]; + for i in 0..self.polynomial.len() { + for j in 0..rhs.polynomial.len() { + polynomial[i + j] = &polynomial[i + j] + + &(self.polynomial.get(i).unwrap() * rhs.polynomial.get(j).unwrap()); + } + } + Polynomial::new(polynomial) + } +} + +impl Add for Polynomial { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + FieldElement::new( + xor_bytes(&self.field_element, rhs.field_element).expect("Error in poly add"), + ) + } +} + +/* +impl Add for Polynomial { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + FieldElement::new( + xor_bytes(&self.field_element, rhs.field_element).expect("Error in poly add"), + ) + } +} + +impl AsRef<[u8]> for Polynomial { + fn as_ref(&self) -> &[u8] { + &self.field_element.as_ref() + } +} +*/ + #[derive(Debug)] pub struct FieldElement { - polynomial: Vec, + field_element: Vec, } impl FieldElement { @@ -15,8 +106,8 @@ impl FieldElement { 87, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 01, ]; - pub const fn new(polynomial: Vec) -> Self { - Self { polynomial } + pub const fn new(field_element: Vec) -> Self { + Self { field_element } } pub fn mul(&self, poly_a: Vec, poly_b: Vec) -> Result> { @@ -29,7 +120,19 @@ impl Mul for FieldElement { fn mul(self, rhs: Self) -> Self::Output { FieldElement::new( - gfmul(self.polynomial, rhs.polynomial, "gcm").expect("Error during multiplication"), + gfmul(self.field_element, rhs.field_element, "gcm") + .expect("Error during multiplication"), + ) + } +} + +impl Mul for &FieldElement { + type Output = FieldElement; + + fn mul(self, rhs: &FieldElement) -> FieldElement { + FieldElement::new( + gfmul(self.field_element.clone(), rhs.field_element.clone(), "gcm") + .expect("Error during multiplication"), ) } } @@ -37,13 +140,32 @@ impl Mul for FieldElement { impl Add for FieldElement { type Output = Self; fn add(self, rhs: Self) -> Self::Output { - FieldElement::new(xor_bytes(&self.polynomial, rhs.polynomial).expect("Error in poly add")) + FieldElement::new( + xor_bytes(&self.field_element, rhs.field_element).expect("Error in poly add"), + ) + } +} + +impl Add for &FieldElement { + type Output = FieldElement; + fn add(self, rhs: Self) -> Self::Output { + FieldElement::new( + xor_bytes(&self.field_element, rhs.field_element.clone()).expect("Error in poly add"), + ) } } impl AsRef<[u8]> for FieldElement { fn as_ref(&self) -> &[u8] { - &self.polynomial.as_ref() + &self.field_element.as_ref() + } +} + +impl Clone for FieldElement { + fn clone(&self) -> Self { + FieldElement { + field_element: self.field_element.clone(), + } } } @@ -158,6 +280,7 @@ impl ByteArray { mod tests { use super::*; use base64::prelude::*; + use serde_json::json; use std::fs; #[test] @@ -263,4 +386,53 @@ mod tests { assert_eq!(BASE64_STANDARD.encode(sum), "H1d3GuyA9/0OxeYouUpAAA=="); } + + #[test] + fn test_field_add_02() { + let element1: FieldElement = + FieldElement::new(BASE64_STANDARD.decode("NeverGonnaLetYouDownAA==").unwrap()); + let element2: FieldElement = + FieldElement::new(BASE64_STANDARD.decode("DHBWMannheimAAAAAAAAAA==").unwrap()); + let sum = element2 + element1; + + assert_eq!(BASE64_STANDARD.encode(sum), "OZuIncPAGEp4tYouDownAA=="); + } + + #[test] + fn test_field_add_03() { + let json1 = json!([ + "NeverGonnaGiveYouUpAAA==", + "NeverGonnaLetYouDownAA==", + "NeverGonnaRunAroundAAA==", + "AndDesertYouAAAAAAAAAA==" + ]); + let json2 = json!(["KryptoanalyseAAAAAAAAA==", "DHBWMannheimAAAAAAAAAA=="]); + let element1: Polynomial = Polynomial::from_c_array(&json1); + let element2: Polynomial = Polynomial::from_c_array(&json2); + + let sum = element2 + element1; + + assert_eq!(BASE64_STANDARD.encode(sum), "OZuIncPAGEp4tYouDownAA=="); + } + + #[test] + fn test_field_mul_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); + + let result = element1 * element2; + + eprintln!("Result = {:?}", result.to_c_array()); + + assert!(false); + //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); + } } -- 2.49.1 From 6431a6636ed777e190355b36d81d850946b98244 Mon Sep 17 00:00:00 2001 From: 0xalivecow Date: Mon, 11 Nov 2024 10:31:59 +0100 Subject: [PATCH 4/8] feat: start working on add for polynomial --- src/utils/field.rs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/src/utils/field.rs b/src/utils/field.rs index f0da8f0..63e2230 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -1,6 +1,6 @@ use std::{ env::args, - ops::{Add, Mul}, + ops::{Add, BitXor, Mul}, }; use anyhow::{anyhow, Ok, Result}; @@ -73,9 +73,13 @@ impl Mul for Polynomial { impl Add for Polynomial { type Output = Self; fn add(self, rhs: Self) -> Self::Output { - FieldElement::new( - xor_bytes(&self.field_element, rhs.field_element).expect("Error in poly add"), - ) + for i in 0..self.polynomial.len() { + for j in 0..rhs.polynomial.len() { + polynomial[i + j] = &polynomial[i + j] + + &(self.polynomial.get(i).unwrap() * rhs.polynomial.get(j).unwrap()); + } + } + Polynomial::new(polynomial) } } @@ -169,6 +173,14 @@ impl Clone for FieldElement { } } +/* +impl BitXor for FieldElement { + fn bitxor(self, rhs: Self) -> Self::Output { + FieldElement + } +} +*/ + /* impl From> for FieldElement { fn from(item: Vec) -> Self { -- 2.49.1 From 11916e29f0bbd361d39d7e4c18a8e68325f7c9f7 Mon Sep 17 00:00:00 2001 From: alivecow Date: Tue, 12 Nov 2024 18:58:20 +0100 Subject: [PATCH 5/8] feat: initial pow support working --- src/tasks/tasks01/gfmul.rs | 20 ------ src/utils/field.rs | 141 +++++++++++++++++++++++++++++++++++-- 2 files changed, 135 insertions(+), 26 deletions(-) diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index 01731f6..c4acefe 100644 --- a/src/tasks/tasks01/gfmul.rs +++ b/src/tasks/tasks01/gfmul.rs @@ -108,24 +108,4 @@ mod tests { ); Ok(()) } - - #[test] - fn gfmul_task01_gcm() -> Result<()> { - let args: Value = json!({"a": "AAAAAAAAAAAAAAAQBAAAAA==", "b": "IAAAAAAAAACAAAAAAAAAAA=="}); - - let poly1_text: String = serde_json::from_value(args["a"].clone())?; - let poly_a = BASE64_STANDARD.decode(poly1_text)?; - - let poly2_text: String = serde_json::from_value(args["b"].clone())?; - let poly_b = BASE64_STANDARD.decode(poly2_text)?; - - let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "gcm")?); - - assert_eq!( - result, "hSQAAAAAAAAAAAAAAAAAAA==", - "Failure. Calulated result was: {}", - result - ); - Ok(()) - } } diff --git a/src/utils/field.rs b/src/utils/field.rs index 63e2230..25088cf 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -52,6 +52,42 @@ impl Polynomial { output } + + pub fn pow(&self, mut exponent: u128) -> Polynomial { + if exponent == 0 { + // Return polynomial with coefficient 1 + return Polynomial::new(vec![FieldElement::new(vec![1])]); + } + + let base = self.clone(); + let mut result = base.clone(); + exponent -= 1; // Subtract 1 because we already set result to base + + while exponent > 0 { + result = result * base.clone(); + exponent -= 1; + } + + result + } + /* + pub fn to_b64(&self) -> String { + let mut output: Vec = vec![]; + for coeff in self.polynomial { + output.push(BASE64_STANDARD.encode(coeff)); + } + + output + } + */ +} + +impl Clone for Polynomial { + fn clone(&self) -> Self { + Polynomial { + polynomial: self.polynomial.clone(), + } + } } impl Mul for Polynomial { @@ -70,9 +106,11 @@ impl Mul for Polynomial { } } -impl Add for Polynomial { - type Output = Self; - fn add(self, rhs: Self) -> Self::Output { +impl Mul for &Polynomial { + type Output = Polynomial; + fn mul(self, rhs: Self) -> Self::Output { + let mut polynomial: Vec = + vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1]; for i in 0..self.polynomial.len() { for j in 0..rhs.polynomial.len() { polynomial[i + j] = &polynomial[i + j] @@ -83,6 +121,40 @@ impl Add for Polynomial { } } +impl Add for Polynomial { + type Output = Self; + fn add(self, rhs: Self) -> Self::Output { + let mut polynomial: Vec; + + if self.polynomial.len() > rhs.polynomial.len() { + polynomial = self.polynomial.clone(); + for i in 0..rhs.polynomial.len() { + polynomial[i] = polynomial[i].clone() + rhs.polynomial[i].clone(); + } + } else { + polynomial = rhs.polynomial.clone(); + for i in 0..self.polynomial.len() { + polynomial[i] = polynomial[i].clone() + self.polynomial[i].clone(); + } + } + + Polynomial::new(polynomial) + } +} + +impl AsRef<[FieldElement]> for Polynomial { + fn as_ref(&self) -> &[FieldElement] { + &self.polynomial + } +} + +/* +impl AsRef<[u8]> for Polynomial { + fn as_ref(&self) -> &[u8] { + &self.polynomial + } +} +*/ /* impl Add for Polynomial { type Output = Self; @@ -117,6 +189,10 @@ impl FieldElement { pub fn mul(&self, poly_a: Vec, poly_b: Vec) -> Result> { gfmul(poly_a, poly_b, "gcm") } + + pub fn to_b64(&self) -> String { + BASE64_STANDARD.encode(&self.field_element) + } } impl Mul for FieldElement { @@ -173,6 +249,19 @@ impl Clone for FieldElement { } } +impl BitXor for FieldElement { + type Output = Self; + fn bitxor(self, rhs: Self) -> Self::Output { + let result: Vec = self + .field_element + .iter() + .zip(rhs.field_element.iter()) + .map(|(&x1, &x2)| x1 ^ x2) + .collect(); + FieldElement::new(result) + } +} + /* impl BitXor for FieldElement { fn bitxor(self, rhs: Self) -> Self::Output { @@ -424,7 +513,15 @@ mod tests { let sum = element2 + element1; - assert_eq!(BASE64_STANDARD.encode(sum), "OZuIncPAGEp4tYouDownAA=="); + assert_eq!( + sum.to_c_array(), + vec![ + "H1d3GuyA9/0OxeYouUpAAA==", + "OZuIncPAGEp4tYouDownAA==", + "NeverGonnaRunAroundAAA==", + "AndDesertYouAAAAAAAAAA==" + ] + ); } #[test] @@ -442,9 +539,41 @@ mod tests { let result = element1 * element2; - eprintln!("Result = {:?}", result.to_c_array()); + assert_eq!( + result.to_c_array(), + vec![ + "MoAAAAAAAAAAAAAAAAAAAA==", + "sUgAAAAAAAAAAAAAAAAAAA==", + "MbQAAAAAAAAAAAAAAAAAAA==", + "AAhAAAAAAAAAAAAAAAAAAA==" + ] + ); + //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); + } - assert!(false); + #[test] + fn test_field_pow_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=="); } } -- 2.49.1 From a05f2f02b678c21968ecf94675ac5a73dfe27ef6 Mon Sep 17 00:00:00 2001 From: alivecow Date: Wed, 13 Nov 2024 20:27:20 +0100 Subject: [PATCH 6/8] feat/refactor: Change gfmul to take references and add field div --- src/tasks/tasks01/gfmul.rs | 10 +-- src/utils/ciphers.rs | 8 +-- src/utils/field.rs | 138 +++++++++++++++++++++++++++++-------- src/utils/poly.rs | 6 +- 4 files changed, 120 insertions(+), 42 deletions(-) diff --git a/src/tasks/tasks01/gfmul.rs b/src/tasks/tasks01/gfmul.rs index c4acefe..2c1d6b8 100644 --- a/src/tasks/tasks01/gfmul.rs +++ b/src/tasks/tasks01/gfmul.rs @@ -16,7 +16,7 @@ pub fn gfmul_task(args: &Value) -> Result> { let semantic: String = serde_json::from_value(args["semantic"].clone())?; - let result = gfmul(poly_a, poly_b, &semantic)?; + let result = gfmul(&poly_a, &poly_b, &semantic)?; Ok(result) } @@ -39,7 +39,7 @@ mod tests { let poly2_text: String = serde_json::from_value(args["b"].clone())?; let poly_b = BASE64_STANDARD.decode(poly2_text)?; - let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "xex")?); + let result = BASE64_STANDARD.encode(gfmul(&poly_a, &poly_b, "xex")?); assert_eq!( result, "hSQAAAAAAAAAAAAAAAAAAA==", @@ -59,7 +59,7 @@ mod tests { let poly2_text: String = serde_json::from_value(args["b"].clone())?; let poly_b = BASE64_STANDARD.decode(poly2_text)?; - let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "xex")?); + let result = BASE64_STANDARD.encode(gfmul(&poly_a, &poly_b, "xex")?); assert_eq!( result, "QKgUAAAAAAAAAAAAAAAAAA==", @@ -79,7 +79,7 @@ mod tests { let poly2_text: String = serde_json::from_value(args["b"].clone())?; let poly_b = BASE64_STANDARD.decode(poly2_text)?; - let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "xex")?); + let result = BASE64_STANDARD.encode(gfmul(&poly_a, &poly_b, "xex")?); assert_eq!( result, "UIAUAAAAAAAAAAAAAAAAAA==", @@ -99,7 +99,7 @@ mod tests { let poly2_text: String = serde_json::from_value(args["b"].clone())?; let poly_b = BASE64_STANDARD.decode(poly2_text)?; - let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "xex")?); + let result = BASE64_STANDARD.encode(gfmul(&poly_a, &poly_b, "xex")?); assert_eq!( result, "hSQAAAAAAAAAAAAAAAAAAA==", diff --git a/src/utils/ciphers.rs b/src/utils/ciphers.rs index 917a1c7..333ec13 100644 --- a/src/utils/ciphers.rs +++ b/src/utils/ciphers.rs @@ -340,25 +340,25 @@ pub fn ghash( eprintln!("Ad chunks before first next {:001X?}", ad_chunks); let inter1 = xor_bytes(&output, ad_chunks.next().unwrap().to_vec())?; - let mut inter_loop = gfmul(inter1, auth_key_h.clone(), "gcm")?; + let mut inter_loop = gfmul(&inter1, &auth_key_h, "gcm")?; eprintln!("Ad chunks after first next {:001X?}", ad_chunks); for chunk in ad_chunks { eprintln!("Inside ad chunk loop"); eprintln!("Ad chunk in loop {:001X?}", chunk); let inter2 = xor_bytes(&inter_loop, chunk.to_vec())?; - inter_loop = gfmul(inter2, auth_key_h.clone(), "gcm")?; + inter_loop = gfmul(&inter2, &auth_key_h, "gcm")?; } let cipher_chunks = ciphertext.chunks(16); for chunk in cipher_chunks { let inter3 = xor_bytes(&inter_loop, chunk.to_vec())?; - inter_loop = gfmul(inter3, auth_key_h.clone(), "gcm")?; + inter_loop = gfmul(&inter3, &auth_key_h, "gcm")?; } let inter4 = xor_bytes(&inter_loop, l_field)?; - inter_loop = gfmul(inter4, auth_key_h.clone(), "gcm")?; + inter_loop = gfmul(&inter4, &auth_key_h, "gcm")?; eprintln!("GHASH auth tag: {:001X?}", inter_loop); diff --git a/src/utils/field.rs b/src/utils/field.rs index 25088cf..c8de249 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -1,12 +1,15 @@ use std::{ env::args, - ops::{Add, BitXor, Mul}, + ops::{Add, BitXor, Div, Mul, Rem, Sub}, + result, }; use anyhow::{anyhow, Ok, Result}; use base64::prelude::*; use serde_json::Value; +use crate::{tasks::tasks01::poly2block::poly2block, utils::poly::polynomial_2_block}; + use super::{math::xor_bytes, poly::gfmul}; #[derive(Debug)] @@ -142,36 +145,32 @@ impl Add for Polynomial { } } +// Helper implementation for subtraction +impl Sub for &FieldElement { + type Output = FieldElement; + + fn sub(self, rhs: Self) -> FieldElement { + // In a field of characteristic 2, addition and subtraction are the same operation (XOR) + self + rhs + } +} + +// Helper trait for checking emptiness +trait IsEmpty { + fn is_empty(&self) -> bool; +} + +impl IsEmpty for Polynomial { + fn is_empty(&self) -> bool { + self.polynomial.is_empty() + } +} impl AsRef<[FieldElement]> for Polynomial { fn as_ref(&self) -> &[FieldElement] { &self.polynomial } } -/* -impl AsRef<[u8]> for Polynomial { - fn as_ref(&self) -> &[u8] { - &self.polynomial - } -} -*/ -/* -impl Add for Polynomial { - type Output = Self; - fn add(self, rhs: Self) -> Self::Output { - FieldElement::new( - xor_bytes(&self.field_element, rhs.field_element).expect("Error in poly add"), - ) - } -} - -impl AsRef<[u8]> for Polynomial { - fn as_ref(&self) -> &[u8] { - &self.field_element.as_ref() - } -} -*/ - #[derive(Debug)] pub struct FieldElement { field_element: Vec, @@ -187,12 +186,48 @@ impl FieldElement { } pub fn mul(&self, poly_a: Vec, poly_b: Vec) -> Result> { - gfmul(poly_a, poly_b, "gcm") + gfmul(&poly_a, &poly_b, "gcm") } pub fn to_b64(&self) -> String { BASE64_STANDARD.encode(&self.field_element) } + + pub fn pow(&self, mut exponent: u128) -> FieldElement { + if exponent == 0 { + // Return polynomial with coefficient 1 + return FieldElement::new(vec![1]); + } + + let base = self.clone(); + let mut result = base.clone(); + exponent -= 1; // Subtract 1 because we already set result to base + + while exponent > 0 { + result = result * base.clone(); + exponent -= 1; + } + + result + } + + pub fn inv(mut self) -> Self { + let mut inverser: u128 = 0xfffffffffffffffffffffffffffffffe; + let mut inverse: Vec = polynomial_2_block(vec![0], "gcm").unwrap(); + eprintln!("Inverse start {:02X?}", inverse); + + while inverser > 0 { + //eprintln!("{:02X}", inverser); + if inverser & 1 == 1 { + inverse = gfmul(&self.field_element, &inverse, "gcm").unwrap(); + } + inverser >>= 1; + self.field_element = gfmul(&self.field_element, &self.field_element, "gcm") + .expect("Error in sqrmul sqr"); + } + eprintln!("Inverse rhs {:?}", inverse); + FieldElement::new(inverse) + } } impl Mul for FieldElement { @@ -200,7 +235,7 @@ impl Mul for FieldElement { fn mul(self, rhs: Self) -> Self::Output { FieldElement::new( - gfmul(self.field_element, rhs.field_element, "gcm") + gfmul(&self.field_element, &rhs.field_element, "gcm") .expect("Error during multiplication"), ) } @@ -211,7 +246,7 @@ impl Mul for &FieldElement { fn mul(self, rhs: &FieldElement) -> FieldElement { FieldElement::new( - gfmul(self.field_element.clone(), rhs.field_element.clone(), "gcm") + gfmul(&self.field_element, &rhs.field_element, "gcm") .expect("Error during multiplication"), ) } @@ -262,6 +297,36 @@ impl BitXor for FieldElement { } } +impl Div for FieldElement { + type Output = Self; + fn div(self, rhs: Self) -> Self::Output { + eprintln!("RHS in div{:02X?}", &rhs); + + let inverse = rhs.inv(); + eprintln!("Inverse in div{:02X?}", inverse); + self.clone() * inverse + } +} + +impl Div for &FieldElement { + type Output = FieldElement; + + fn div(self, rhs: Self) -> Self::Output { + // First clone and invert the divisor (rhs) + let rhs_inv = rhs.clone().inv(); + // Multiply original number by the inverse + self.clone() * rhs_inv + } +} +/* +//TODO: Not yet ready + impl Rem for FieldElement { + fn rem(self, rhs: Self) -> Self::Output { + + } +} +*/ + /* impl BitXor for FieldElement { fn bitxor(self, rhs: Self) -> Self::Output { @@ -312,13 +377,13 @@ impl ByteArray { let alpha_poly: Vec = base64::prelude::BASE64_STANDARD .decode("AgAAAAAAAAAAAAAAAAAAAA==") .expect("Decode failed"); - self.0 = gfmul(self.0.clone(), alpha_poly, "xex").unwrap(); + self.0 = gfmul(&self.0, &alpha_poly, "xex").unwrap(); } "gcm" => { let alpha_poly: Vec = base64::prelude::BASE64_STANDARD .decode("AgAAAAAAAAAAAAAAAAAAAA==") .expect("Decode failed"); - self.0 = gfmul(self.0.clone(), alpha_poly, "gcm").unwrap(); + self.0 = gfmul(&self.0, &alpha_poly, "gcm").unwrap(); } _ => {} } @@ -576,4 +641,17 @@ mod tests { ); //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA=="); } + + #[test] + fn test_poly_div_01() { + let element1 = + FieldElement::new(BASE64_STANDARD.decode("JAAAAAAAAAAAAAAAAAAAAA==").unwrap()); + + let element2 = + FieldElement::new(BASE64_STANDARD.decode("wAAAAAAAAAAAAAAAAAAAAA==").unwrap()); + + let result = element1 / element2; + + assert_eq!(BASE64_STANDARD.encode(result), "OAAAAAAAAAAAAAAAAAAAAA=="); + } } diff --git a/src/utils/poly.rs b/src/utils/poly.rs index 78889c8..6425577 100644 --- a/src/utils/poly.rs +++ b/src/utils/poly.rs @@ -7,14 +7,14 @@ use std::{str::FromStr, u128, u8, usize}; use super::{field, math::reverse_bits_in_bytevec}; pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000; -pub fn gfmul(poly_a: Vec, poly_b: Vec, semantic: &str) -> Result> { +pub fn gfmul(poly_a: &Vec, poly_b: &Vec, semantic: &str) -> Result> { let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec()); red_poly_bytes.0.push(0x01); - let mut poly1: ByteArray = ByteArray(poly_a); + let mut poly1: ByteArray = ByteArray(poly_a.to_owned()); poly1.0.push(0x00); - let mut poly2: ByteArray = ByteArray(poly_b); + let mut poly2: ByteArray = ByteArray(poly_b.to_owned()); poly2.0.push(0x00); if semantic == "gcm" { -- 2.49.1 From deb426112106e13bd5f2d3fc1e684d4438d2490c Mon Sep 17 00:00:00 2001 From: alivecow Date: Thu, 14 Nov 2024 22:30:55 +0100 Subject: [PATCH 7/8] feat: add division and powmod (WIP) and start adapting task runner --- src/tasks/mod.rs | 7 ++ src/tasks/tasks01/mod.rs | 1 + src/tasks/tasks01/pfmath.rs | 15 +++ src/utils/field.rs | 176 ++++++++++++++++++++++++++++++++---- 4 files changed, 183 insertions(+), 16 deletions(-) create mode 100644 src/tasks/tasks01/pfmath.rs diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index 0fa72d6..f7475be 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -11,6 +11,7 @@ use tasks01::{ gcm::{gcm_decrypt, gcm_encrypt}, gfmul::gfmul_task, pad_oracle::padding_oracle, + pfmath::gfpoly_add, poly2block::poly2block, sea128::sea128, xex::{self, fde_xex}, @@ -83,6 +84,12 @@ pub fn task_deploy(testcase: &Testcase) -> Result { Ok(json) } + "gfpoly_add" => { + let result = gfpoly_add(args)?; + let json = json!({"plaintext" : result.to_c_array()}); + + Ok(json) + } _ => Err(anyhow!( "Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}", testcase, diff --git a/src/tasks/tasks01/mod.rs b/src/tasks/tasks01/mod.rs index 479fe47..8200de5 100644 --- a/src/tasks/tasks01/mod.rs +++ b/src/tasks/tasks01/mod.rs @@ -2,6 +2,7 @@ pub mod block2poly; pub mod gcm; pub mod gfmul; pub mod pad_oracle; +pub mod pfmath; pub mod poly2block; pub mod sea128; pub mod xex; diff --git a/src/tasks/tasks01/pfmath.rs b/src/tasks/tasks01/pfmath.rs new file mode 100644 index 0000000..b0c978e --- /dev/null +++ b/src/tasks/tasks01/pfmath.rs @@ -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 { + 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) +} diff --git a/src/utils/field.rs b/src/utils/field.rs index c8de249..59ffc18 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -58,14 +58,12 @@ impl Polynomial { pub fn pow(&self, mut exponent: u128) -> Polynomial { if exponent == 0 { - // Return polynomial with coefficient 1 - return Polynomial::new(vec![FieldElement::new(vec![1])]); + return Polynomial::new(vec![FieldElement::new(vec![0])]); } let base = self.clone(); let mut result = base.clone(); - exponent -= 1; // Subtract 1 because we already set result to base - + exponent -= 1; while exponent > 0 { result = result * base.clone(); exponent -= 1; @@ -73,16 +71,90 @@ impl Polynomial { result } - /* - pub fn to_b64(&self) -> String { - let mut output: Vec = vec![]; - for coeff in self.polynomial { - output.push(BASE64_STANDARD.encode(coeff)); + + 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(), + )]); + + 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 { @@ -318,15 +390,20 @@ impl Div for &FieldElement { 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 { fn bitxor(self, rhs: Self) -> Self::Output { @@ -642,6 +719,32 @@ mod tests { //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] fn test_poly_div_01() { let element1 = @@ -654,4 +757,45 @@ mod tests { 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=="]); + } } -- 2.49.1 From 68d9f13a3dd05dbf96c898a19f4a165ffdae1073 Mon Sep 17 00:00:00 2001 From: alivecow Date: Thu, 14 Nov 2024 23:08:20 +0100 Subject: [PATCH 8/8] feat: finialise test runner and add testing json --- src/tasks/mod.rs | 54 +++++++++++++++++++- src/tasks/tasks01/pfmath.rs | 56 ++++++++++++++++++++- src/utils/field.rs | 16 +++--- test_json/pfmath_tests.json | 98 +++++++++++++++++++++++++++++++++++++ 4 files changed, 213 insertions(+), 11 deletions(-) create mode 100644 test_json/pfmath_tests.json diff --git a/src/tasks/mod.rs b/src/tasks/mod.rs index f7475be..b024471 100644 --- a/src/tasks/mod.rs +++ b/src/tasks/mod.rs @@ -11,7 +11,7 @@ use tasks01::{ gcm::{gcm_decrypt, gcm_encrypt}, gfmul::gfmul_task, pad_oracle::padding_oracle, - pfmath::gfpoly_add, + pfmath::{gfdiv, gfpoly_add, gfpoly_divmod, gfpoly_mul, gfpoly_pow, gfpoly_powmod}, poly2block::poly2block, sea128::sea128, xex::{self, fde_xex}, @@ -86,10 +86,42 @@ pub fn task_deploy(testcase: &Testcase) -> Result { } "gfpoly_add" => { let result = gfpoly_add(args)?; - let json = json!({"plaintext" : result.to_c_array()}); + let json = json!({"S" : result.to_c_array()}); Ok(json) } + "gfpoly_mul" => { + let result = gfpoly_mul(args)?; + let json = json!({"P" : result.to_c_array()}); + + Ok(json) + } + "gfpoly_pow" => { + let result = gfpoly_pow(args)?; + let json = json!({"Z" : result.to_c_array()}); + + Ok(json) + } + "gfdiv" => { + let result = gfdiv(args)?; + let out = BASE64_STANDARD.encode(result); + let json = json!({"q" : out}); + + Ok(json) + } + "gfpoly_divmod" => { + let result = gfpoly_divmod(args)?; + let json = json!({"Q" : result.0.to_c_array(), "R" : result.1.to_c_array()}); + + Ok(json) + } + "gfpoly_powmod" => { + let result = gfpoly_powmod(args)?; + let json = json!({"Z" : result.to_c_array()}); + + Ok(json) + } + _ => Err(anyhow!( "Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}", testcase, @@ -279,4 +311,22 @@ mod tests { Ok(()) } + + #[test] + fn test_task_gcm_gfpoly_add() -> Result<()> { + let json = fs::read_to_string("test_json/gcm_decrypt_sea.json").unwrap(); + let parsed = parse_json(json).unwrap(); + + let expected = json!({ "responses" : { "b856d760-023d-4b00-bad2-15d2b6da22fe" : { + "plaintext": "RGFzIGlzdCBlaW4gVGVzdA==", + "authentic": true, + }}}); + + assert_eq!( + serde_json::to_value(task_distrubute(&parsed)?).unwrap(), + serde_json::to_value(expected).unwrap() + ); + + Ok(()) + } } diff --git a/src/tasks/tasks01/pfmath.rs b/src/tasks/tasks01/pfmath.rs index b0c978e..4ad3ac7 100644 --- a/src/tasks/tasks01/pfmath.rs +++ b/src/tasks/tasks01/pfmath.rs @@ -2,7 +2,7 @@ use anyhow::Result; use base64::{prelude::BASE64_STANDARD, Engine}; use serde_json::Value; -use crate::utils::field::Polynomial; +use crate::utils::field::{FieldElement, Polynomial}; pub fn gfpoly_add(args: &Value) -> Result { let poly_a = Polynomial::from_c_array(&args["A"].clone()); @@ -13,3 +13,57 @@ pub fn gfpoly_add(args: &Value) -> Result { Ok(result) } + +pub fn gfpoly_mul(args: &Value) -> Result { + 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) +} + +pub fn gfpoly_pow(args: &Value) -> Result { + let poly_a = Polynomial::from_c_array(&args["A"].clone()); + + let k: u128 = serde_json::from_value(args["k"].clone())?; + + let result = poly_a.pow(k); + + Ok(result) +} + +pub fn gfdiv(args: &Value) -> Result { + let f1_text: String = serde_json::from_value(args["a"].clone())?; + let f_a = FieldElement::new(BASE64_STANDARD.decode(f1_text)?); + + let f2_text: String = serde_json::from_value(args["b"].clone())?; + let f_b = FieldElement::new(BASE64_STANDARD.decode(f2_text)?); + + let result = f_a / f_b; + + Ok(result) +} + +pub fn gfpoly_divmod(args: &Value) -> Result<(Polynomial, 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.div(&poly_b); + + Ok(result) +} + +pub fn gfpoly_powmod(args: &Value) -> Result { + let poly_a = Polynomial::from_c_array(&args["A"].clone()); + + let poly_m = Polynomial::from_c_array(&args["M"].clone()); + + let k: u128 = serde_json::from_value(args["k"].clone())?; + + let result = poly_a.pow_mod(k, poly_m); + + Ok(result) +} diff --git a/src/utils/field.rs b/src/utils/field.rs index 59ffc18..fac51f2 100644 --- a/src/utils/field.rs +++ b/src/utils/field.rs @@ -77,19 +77,19 @@ impl Polynomial { polynomial_2_block(vec![0], "gcm").unwrap(), )]); - eprintln!("Initial result: {:?}", result); + //eprintln!("Initial result: {:?}", result); while exponent > 0 { - eprintln!("Current exponent: {:02X}", exponent); + //eprintln!("Current exponent: {:02X}", exponent); if exponent & 1 == 1 { let temp = &self * &result; - eprintln!("After multiplication: {:?}", temp); + //eprintln!("After multiplication: {:?}", temp); result = temp.div(&modulus).1; - eprintln!("After mod: {:?}", result); + //eprintln!("After mod: {:?}", result); } let temp_square = &self * &self; - eprintln!("After squaring: {:?}", temp_square); + //eprintln!("After squaring: {:?}", temp_square); self = temp_square.div(&modulus).1; - eprintln!("After mod: {:?}", self); + //eprintln!("After mod: {:?}", self); exponent >>= 1; } result @@ -286,7 +286,7 @@ impl FieldElement { pub fn inv(mut self) -> Self { let mut inverser: u128 = 0xfffffffffffffffffffffffffffffffe; let mut inverse: Vec = polynomial_2_block(vec![0], "gcm").unwrap(); - eprintln!("Inverse start {:02X?}", inverse); + //eprintln!("Inverse start {:02X?}", inverse); while inverser > 0 { //eprintln!("{:02X}", inverser); @@ -297,7 +297,7 @@ impl FieldElement { self.field_element = gfmul(&self.field_element, &self.field_element, "gcm") .expect("Error in sqrmul sqr"); } - eprintln!("Inverse rhs {:?}", inverse); + //eprintln!("Inverse rhs {:?}", inverse); FieldElement::new(inverse) } } diff --git a/test_json/pfmath_tests.json b/test_json/pfmath_tests.json new file mode 100644 index 0000000..b9cc6e0 --- /dev/null +++ b/test_json/pfmath_tests.json @@ -0,0 +1,98 @@ +{ + "testcases": { + "gfpoly_add": { + "action": "gfpoly_add", + "arguments": { + "A": [ + "NeverGonnaGiveYouUpAAA==", + "NeverGonnaLetYouDownAA==", + "NeverGonnaRunAroundAAA==", + "AndDesertYouAAAAAAAAAA==" + ], + "B": [ + "KryptoanalyseAAAAAAAAA==", + "DHBWMannheimAAAAAAAAAA==" + ] + } + }, + "gfpoly_mul": { + "action": "gfpoly_mul", + "arguments": { + "A": [ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ], + "B": [ + "0AAAAAAAAAAAAAAAAAAAAA==", + "IQAAAAAAAAAAAAAAAAAAAA==" + ] + } + }, + "gfpoly_mul_10": { + "action": "gfpoly_mul", + "arguments": { + "A": [ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ], + "B": [ + "AAAAAAAAAAAAAAAAAAAAAA==" + ] + } + }, + "gfpoly_mul_01": { + "action": "gfpoly_mul", + "arguments": { + "A": [ + "AAAAAAAAAAAAAAAAAAAAAA==" + ], + "B": [ + "0AAAAAAAAAAAAAAAAAAAAA==", + "IQAAAAAAAAAAAAAAAAAAAA==" + ] + } + }, + "gfpoly_pow": { + "action": "gfpoly_pow", + "arguments": { + "A": [ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ], + "k": 3 + } + }, + "gfpoly_pow_k0": { + "action": "gfpoly_pow", + "arguments": { + "A": [ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ], + "k": 0 + } + }, + "gfpoly_pow_k1": { + "action": "gfpoly_pow", + "arguments": { + "A": [ + "JAAAAAAAAAAAAAAAAAAAAA==", + "wAAAAAAAAAAAAAAAAAAAAA==", + "ACAAAAAAAAAAAAAAAAAAAA==" + ], + "k": 1 + } + }, + "gfdiv": { + "action": "gfdiv", + "arguments": { + "a": "JAAAAAAAAAAAAAAAAAAAAA==", + "b": "wAAAAAAAAAAAAAAAAAAAAA==" + } + } + } +} -- 2.49.1