Add basic pfmath functionality #13
8 changed files with 841 additions and 37 deletions
|
|
@ -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::{gfdiv, gfpoly_add, gfpoly_divmod, gfpoly_mul, gfpoly_pow, gfpoly_powmod},
|
||||||
poly2block::poly2block,
|
poly2block::poly2block,
|
||||||
sea128::sea128,
|
sea128::sea128,
|
||||||
xex::{self, fde_xex},
|
xex::{self, fde_xex},
|
||||||
|
|
@ -83,6 +84,44 @@ pub fn task_deploy(testcase: &Testcase) -> Result<Value> {
|
||||||
|
|
||||||
Ok(json)
|
Ok(json)
|
||||||
}
|
}
|
||||||
|
"gfpoly_add" => {
|
||||||
|
let result = gfpoly_add(args)?;
|
||||||
|
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!(
|
_ => Err(anyhow!(
|
||||||
"Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}",
|
"Fatal. No compatible action found. Json data was {:?}. Arguments were; {:?}",
|
||||||
testcase,
|
testcase,
|
||||||
|
|
@ -272,4 +311,22 @@ mod tests {
|
||||||
|
|
||||||
Ok(())
|
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(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ pub fn gfmul_task(args: &Value) -> Result<Vec<u8>> {
|
||||||
|
|
||||||
let semantic: String = serde_json::from_value(args["semantic"].clone())?;
|
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)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
@ -39,7 +39,7 @@ mod tests {
|
||||||
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
|
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
|
||||||
let poly_b = BASE64_STANDARD.decode(poly2_text)?;
|
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!(
|
assert_eq!(
|
||||||
result, "hSQAAAAAAAAAAAAAAAAAAA==",
|
result, "hSQAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
|
@ -59,7 +59,7 @@ mod tests {
|
||||||
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
|
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
|
||||||
let poly_b = BASE64_STANDARD.decode(poly2_text)?;
|
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!(
|
assert_eq!(
|
||||||
result, "QKgUAAAAAAAAAAAAAAAAAA==",
|
result, "QKgUAAAAAAAAAAAAAAAAAA==",
|
||||||
|
|
@ -79,7 +79,7 @@ mod tests {
|
||||||
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
|
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
|
||||||
let poly_b = BASE64_STANDARD.decode(poly2_text)?;
|
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!(
|
assert_eq!(
|
||||||
result, "UIAUAAAAAAAAAAAAAAAAAA==",
|
result, "UIAUAAAAAAAAAAAAAAAAAA==",
|
||||||
|
|
@ -99,27 +99,7 @@ mod tests {
|
||||||
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
|
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
|
||||||
let poly_b = BASE64_STANDARD.decode(poly2_text)?;
|
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==",
|
|
||||||
"Failure. Calulated result was: {}",
|
|
||||||
result
|
|
||||||
);
|
|
||||||
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!(
|
assert_eq!(
|
||||||
result, "hSQAAAAAAAAAAAAAAAAAAA==",
|
result, "hSQAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
69
src/tasks/tasks01/pfmath.rs
Normal file
69
src/tasks/tasks01/pfmath.rs
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
use anyhow::Result;
|
||||||
|
use base64::{prelude::BASE64_STANDARD, Engine};
|
||||||
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use crate::utils::field::{FieldElement, 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)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gfpoly_mul(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)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn gfpoly_pow(args: &Value) -> Result<Polynomial> {
|
||||||
|
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<FieldElement> {
|
||||||
|
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<Polynomial> {
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
@ -340,25 +340,25 @@ pub fn ghash(
|
||||||
eprintln!("Ad chunks before first next {:001X?}", ad_chunks);
|
eprintln!("Ad chunks before first next {:001X?}", ad_chunks);
|
||||||
|
|
||||||
let inter1 = xor_bytes(&output, ad_chunks.next().unwrap().to_vec())?;
|
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);
|
eprintln!("Ad chunks after first next {:001X?}", ad_chunks);
|
||||||
|
|
||||||
for chunk in ad_chunks {
|
for chunk in ad_chunks {
|
||||||
eprintln!("Inside ad chunk loop");
|
eprintln!("Inside ad chunk loop");
|
||||||
eprintln!("Ad chunk in loop {:001X?}", chunk);
|
eprintln!("Ad chunk in loop {:001X?}", chunk);
|
||||||
let inter2 = xor_bytes(&inter_loop, chunk.to_vec())?;
|
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);
|
let cipher_chunks = ciphertext.chunks(16);
|
||||||
|
|
||||||
for chunk in cipher_chunks {
|
for chunk in cipher_chunks {
|
||||||
let inter3 = xor_bytes(&inter_loop, chunk.to_vec())?;
|
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)?;
|
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);
|
eprintln!("GHASH auth tag: {:001X?}", inter_loop);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,424 @@
|
||||||
use anyhow::{anyhow, Ok, Result};
|
use std::{
|
||||||
use base64::Engine;
|
env::args,
|
||||||
|
ops::{Add, BitXor, Div, Mul, Rem, Sub},
|
||||||
|
result,
|
||||||
|
};
|
||||||
|
|
||||||
use super::poly::gfmul;
|
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)]
|
||||||
|
pub struct Polynomial {
|
||||||
|
polynomial: Vec<FieldElement>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Polynomial {
|
||||||
|
pub const fn new(polynomial: Vec<FieldElement>) -> Self {
|
||||||
|
Self { polynomial }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn from_c_array(array: &Value) -> Self {
|
||||||
|
let mut polynomial: Vec<FieldElement> = vec![];
|
||||||
|
let c_array: Vec<String> = 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<String> {
|
||||||
|
let mut output: Vec<String> = vec![];
|
||||||
|
for coeff in self.polynomial {
|
||||||
|
output.push(BASE64_STANDARD.encode(coeff));
|
||||||
|
}
|
||||||
|
|
||||||
|
output
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pow(&self, mut exponent: u128) -> Polynomial {
|
||||||
|
if exponent == 0 {
|
||||||
|
return Polynomial::new(vec![FieldElement::new(vec![0])]);
|
||||||
|
}
|
||||||
|
|
||||||
|
let base = self.clone();
|
||||||
|
let mut result = base.clone();
|
||||||
|
exponent -= 1;
|
||||||
|
while exponent > 0 {
|
||||||
|
result = result * base.clone();
|
||||||
|
exponent -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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(),
|
||||||
|
)]);
|
||||||
|
|
||||||
|
//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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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 {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
Polynomial {
|
||||||
|
polynomial: self.polynomial.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Mul for Polynomial {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, rhs: Self) -> Self::Output {
|
||||||
|
let mut polynomial: Vec<FieldElement> =
|
||||||
|
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 Mul for &Polynomial {
|
||||||
|
type Output = Polynomial;
|
||||||
|
fn mul(self, rhs: Self) -> Self::Output {
|
||||||
|
let mut polynomial: Vec<FieldElement> =
|
||||||
|
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 {
|
||||||
|
let mut polynomial: Vec<FieldElement>;
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct FieldElement {
|
||||||
|
field_element: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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(field_element: Vec<u8>) -> Self {
|
||||||
|
Self { field_element }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn mul(&self, poly_a: Vec<u8>, poly_b: Vec<u8>) -> Result<Vec<u8>> {
|
||||||
|
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<u8> = 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 {
|
||||||
|
type Output = Self;
|
||||||
|
|
||||||
|
fn mul(self, rhs: Self) -> Self::Output {
|
||||||
|
FieldElement::new(
|
||||||
|
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, &rhs.field_element, "gcm")
|
||||||
|
.expect("Error during multiplication"),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Add for FieldElement {
|
||||||
|
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 &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.field_element.as_ref()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Clone for FieldElement {
|
||||||
|
fn clone(&self) -> Self {
|
||||||
|
FieldElement {
|
||||||
|
field_element: self.field_element.clone(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl BitXor for FieldElement {
|
||||||
|
type Output = Self;
|
||||||
|
fn bitxor(self, rhs: Self) -> Self::Output {
|
||||||
|
let result: Vec<u8> = self
|
||||||
|
.field_element
|
||||||
|
.iter()
|
||||||
|
.zip(rhs.field_element.iter())
|
||||||
|
.map(|(&x1, &x2)| x1 ^ x2)
|
||||||
|
.collect();
|
||||||
|
FieldElement::new(result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
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 {
|
||||||
|
FieldElement
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
impl From<Vec<u8>> for FieldElement {
|
||||||
|
fn from(item: Vec<u8>) -> Self {
|
||||||
|
FieldElement { bytes: item }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct ByteArray(pub Vec<u8>);
|
pub struct ByteArray(pub Vec<u8>);
|
||||||
|
|
@ -37,13 +454,13 @@ impl ByteArray {
|
||||||
let alpha_poly: Vec<u8> = base64::prelude::BASE64_STANDARD
|
let alpha_poly: Vec<u8> = base64::prelude::BASE64_STANDARD
|
||||||
.decode("AgAAAAAAAAAAAAAAAAAAAA==")
|
.decode("AgAAAAAAAAAAAAAAAAAAAA==")
|
||||||
.expect("Decode failed");
|
.expect("Decode failed");
|
||||||
self.0 = gfmul(self.0.clone(), alpha_poly, "xex").unwrap();
|
self.0 = gfmul(&self.0, &alpha_poly, "xex").unwrap();
|
||||||
}
|
}
|
||||||
"gcm" => {
|
"gcm" => {
|
||||||
let alpha_poly: Vec<u8> = base64::prelude::BASE64_STANDARD
|
let alpha_poly: Vec<u8> = base64::prelude::BASE64_STANDARD
|
||||||
.decode("AgAAAAAAAAAAAAAAAAAAAA==")
|
.decode("AgAAAAAAAAAAAAAAAAAAAA==")
|
||||||
.expect("Decode failed");
|
.expect("Decode failed");
|
||||||
self.0 = gfmul(self.0.clone(), alpha_poly, "gcm").unwrap();
|
self.0 = gfmul(&self.0, &alpha_poly, "gcm").unwrap();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -105,6 +522,8 @@ impl ByteArray {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use base64::prelude::*;
|
||||||
|
use serde_json::json;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -199,4 +618,184 @@ mod tests {
|
||||||
|
|
||||||
assert_eq!(byte_array.0, vec![0x55, 0x55]);
|
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==");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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!(
|
||||||
|
sum.to_c_array(),
|
||||||
|
vec![
|
||||||
|
"H1d3GuyA9/0OxeYouUpAAA==",
|
||||||
|
"OZuIncPAGEp4tYouDownAA==",
|
||||||
|
"NeverGonnaRunAroundAAA==",
|
||||||
|
"AndDesertYouAAAAAAAAAA=="
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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;
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
result.to_c_array(),
|
||||||
|
vec![
|
||||||
|
"MoAAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"sUgAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"MbQAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
"AAhAAAAAAAAAAAAAAAAAAA=="
|
||||||
|
]
|
||||||
|
);
|
||||||
|
//assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA==");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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==");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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 =
|
||||||
|
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==");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[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=="]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,14 +7,14 @@ use std::{str::FromStr, u128, u8, usize};
|
||||||
use super::{field, math::reverse_bits_in_bytevec};
|
use super::{field, math::reverse_bits_in_bytevec};
|
||||||
pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000;
|
pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000;
|
||||||
|
|
||||||
pub fn gfmul(poly_a: Vec<u8>, poly_b: Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
|
pub fn gfmul(poly_a: &Vec<u8>, poly_b: &Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
|
||||||
let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec());
|
let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec());
|
||||||
red_poly_bytes.0.push(0x01);
|
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);
|
poly1.0.push(0x00);
|
||||||
|
|
||||||
let mut poly2: ByteArray = ByteArray(poly_b);
|
let mut poly2: ByteArray = ByteArray(poly_b.to_owned());
|
||||||
poly2.0.push(0x00);
|
poly2.0.push(0x00);
|
||||||
|
|
||||||
if semantic == "gcm" {
|
if semantic == "gcm" {
|
||||||
|
|
|
||||||
98
test_json/pfmath_tests.json
Normal file
98
test_json/pfmath_tests.json
Normal file
|
|
@ -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=="
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue