refactor: externalise gfmul to make it more accessible and semantic support

This commit is contained in:
0xalivecow 2024-10-29 13:53:10 +01:00
parent 31050ea696
commit f4c49a9137
No known key found for this signature in database
5 changed files with 96 additions and 64 deletions

View file

@ -5,7 +5,7 @@ use std::collections::HashMap;
use crate::utils::parse::{Responses, Testcase, Testcases}; use crate::utils::parse::{Responses, Testcase, Testcases};
use tasks01::{ use tasks01::{
block2poly::block2poly, block2poly::block2poly,
gfmul::gfmul, gfmul::gfmul_task,
poly2block::poly2block, poly2block::poly2block,
sea128::sea128, sea128::sea128,
xex::{self, fde_xex}, xex::{self, fde_xex},
@ -43,13 +43,7 @@ pub fn task_deploy(testcase: &Testcase) -> Result<Value> {
Ok(json) Ok(json)
} }
"gfmul" => { "gfmul" => {
let poly1_text: String = serde_json::from_value(args["a"].clone())?; let result = BASE64_STANDARD.encode(gfmul_task(args)?);
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)?);
let json = json!({"product" : result}); let json = json!({"product" : result});
Ok(json) Ok(json)
} }

View file

@ -1,49 +1,24 @@
use anyhow::Result;
use base64::prelude::*;
//use num_bigint::{BigUint, ToBigUint};
use serde_json::Value;
use crate::utils::{ use crate::utils::{
math::ByteArray, math::ByteArray,
poly::{b64_2_num, coefficient_to_binary}, poly::{b64_2_num, coefficient_to_binary, gfmul},
}; };
pub const RED_POLY: u128 = 0x87000000_00000000_00000000_00000000; use anyhow::Result;
use base64::prelude::*;
use serde_json::Value;
pub fn gfmul(poly_a: Vec<u8>, poly_b: Vec<u8>) -> Result<Vec<u8>> { pub fn gfmul_task(args: &Value) -> Result<Vec<u8>> {
let mut red_poly_bytes: ByteArray = ByteArray(RED_POLY.to_be_bytes().to_vec()); let poly1_text: String = serde_json::from_value(args["a"].clone())?;
red_poly_bytes.0.push(0x01); let poly_a = BASE64_STANDARD.decode(poly1_text)?;
let mut poly1: ByteArray = ByteArray(poly_a); let poly2_text: String = serde_json::from_value(args["b"].clone())?;
poly1.0.push(0x00); let poly_b = BASE64_STANDARD.decode(poly2_text)?;
let mut poly2: ByteArray = ByteArray(poly_b); let semantic: String = serde_json::from_value(args["semantic"].clone())?;
poly2.0.push(0x00);
let mut result: ByteArray = ByteArray(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); let result = gfmul(poly_a, poly_b, &semantic)?;
if poly2.LSB_is_one() { Ok(result)
result.xor_byte_arrays(&poly1);
poly2.right_shift();
} else {
poly2.right_shift();
}
while !poly2.is_empty() {
if poly2.LSB_is_one() {
poly1.left_shift();
poly1.xor_byte_arrays(&red_poly_bytes);
result.xor_byte_arrays(&poly1);
} else {
poly1.left_shift();
poly1.xor_byte_arrays(&red_poly_bytes);
}
poly2.right_shift();
}
result.0.remove(16);
Ok(result.0)
} }
#[cfg(test)] #[cfg(test)]
@ -64,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)?); let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "xex")?);
assert_eq!( assert_eq!(
result, "hSQAAAAAAAAAAAAAAAAAAA==", result, "hSQAAAAAAAAAAAAAAAAAAA==",

View file

@ -83,7 +83,7 @@ pub fn xex_encrypt(mut key: Vec<u8>, tweak: &Vec<u8>, input: &Vec<u8>) -> Result
let cypher_block_intermediate = sea_128_encrypt(&key, &plaintext_intermediate)?; let cypher_block_intermediate = sea_128_encrypt(&key, &plaintext_intermediate)?;
let mut cypher_block = xor_bytes(&tweak_block.0, cypher_block_intermediate)?; let mut cypher_block = xor_bytes(&tweak_block.0, cypher_block_intermediate)?;
output.append(cypher_block.as_mut()); output.append(cypher_block.as_mut());
tweak_block.left_shift_reduce(); tweak_block.left_shift_reduce("xex");
} }
Ok(output) Ok(output)
@ -116,7 +116,7 @@ pub fn xex_decrypt(mut key: Vec<u8>, tweak: &Vec<u8>, input: &Vec<u8>) -> Result
let plaintext_block_intermediate = sea_128_decrypt(&key, &cyphertext_intermediate)?; let plaintext_block_intermediate = sea_128_decrypt(&key, &cyphertext_intermediate)?;
let mut cypher_block = xor_bytes(&tweak_block.0, plaintext_block_intermediate)?; let mut cypher_block = xor_bytes(&tweak_block.0, plaintext_block_intermediate)?;
output.append(cypher_block.as_mut()); output.append(cypher_block.as_mut());
tweak_block.left_shift_reduce(); tweak_block.left_shift_reduce("xex");
} }
Ok(output) Ok(output)

View file

@ -1,7 +1,7 @@
use anyhow::{Ok, Result}; use anyhow::{anyhow, Ok, Result};
use base64::Engine; use base64::Engine;
use crate::tasks::tasks01::gfmul::gfmul; use super::poly::gfmul;
pub fn xor_bytes(vec1: &Vec<u8>, mut vec2: Vec<u8>) -> Result<Vec<u8>> { pub fn xor_bytes(vec1: &Vec<u8>, mut vec2: Vec<u8>) -> Result<Vec<u8>> {
for (byte1, byte2) in vec1.iter().zip(vec2.iter_mut()) { for (byte1, byte2) in vec1.iter().zip(vec2.iter_mut()) {
@ -25,21 +25,46 @@ impl ByteArray {
carry carry
} }
pub fn left_shift_reduce(&mut self) { pub fn left_shift_reduce(&mut self, semantic: &str) {
match semantic {
"xex" => {
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).unwrap(); self.0 = gfmul(self.0.clone(), alpha_poly, "xex").unwrap();
}
"gcm" => {
let alpha_poly: Vec<u8> = base64::prelude::BASE64_STANDARD
.decode("AgAAAAAAAAAAAAAAAAAAAA==")
.expect("Decode failed");
self.0 = gfmul(self.0.clone(), alpha_poly, "gcm").unwrap();
}
_ => {}
}
} }
pub fn right_shift(&mut self) -> u8 { pub fn right_shift(&mut self, semantic: &str) -> Result<u8> {
match semantic {
"xex" => {
let mut carry = 0u8; let mut carry = 0u8;
for byte in self.0.iter_mut().rev() { for byte in self.0.iter_mut().rev() {
let new_carry = *byte & 1; let new_carry = *byte & 1;
*byte = (*byte >> 1) | (carry << 7); *byte = (*byte >> 1) | (carry << 7);
carry = new_carry; carry = new_carry;
} }
carry Ok(carry)
}
"gcm" => {
let mut carry = 0u8;
for byte in self.0.iter_mut().rev() {
let new_carry = *byte & 1;
*byte = (*byte << 1) | carry;
carry = new_carry;
}
Ok(carry)
}
_ => Err(anyhow!("Failure in rsh. No valid semantic found")),
}
} }
pub fn xor_byte_arrays(&mut self, vec2: &ByteArray) { pub fn xor_byte_arrays(&mut self, vec2: &ByteArray) {
@ -94,7 +119,7 @@ mod tests {
fn test_byte_array_shift_right() { fn test_byte_array_shift_right() {
let mut byte_array: ByteArray = ByteArray(vec![0x02]); let mut byte_array: ByteArray = ByteArray(vec![0x02]);
let shifted_array: ByteArray = ByteArray(vec![0x01]); let shifted_array: ByteArray = ByteArray(vec![0x01]);
byte_array.right_shift(); byte_array.right_shift("xex");
assert_eq!( assert_eq!(
byte_array.0, shifted_array.0, byte_array.0, shifted_array.0,

View file

@ -1,7 +1,45 @@
use crate::utils::math::ByteArray;
use anyhow::Result; use anyhow::Result;
use base64::prelude::*; use base64::prelude::*;
use serde_json::Value;
use std::{str::FromStr, u128, u8, usize}; use std::{str::FromStr, u128, u8, usize};
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>> {
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);
poly1.0.push(0x00);
let mut poly2: ByteArray = ByteArray(poly_b);
poly2.0.push(0x00);
let mut result: ByteArray = ByteArray(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
if poly2.LSB_is_one() {
result.xor_byte_arrays(&poly1);
poly2.right_shift(semantic);
} else {
poly2.right_shift(semantic);
}
while !poly2.is_empty() {
if poly2.LSB_is_one() {
poly1.left_shift();
poly1.xor_byte_arrays(&red_poly_bytes);
result.xor_byte_arrays(&poly1);
} else {
poly1.left_shift();
poly1.xor_byte_arrays(&red_poly_bytes);
}
poly2.right_shift(semantic);
}
result.0.remove(16);
Ok(result.0)
}
pub fn get_alpha_rep(num: u128) -> String { pub fn get_alpha_rep(num: u128) -> String {
let powers: Vec<u8> = get_coefficients(num); let powers: Vec<u8> = get_coefficients(num);