Compare commits

...
Sign in to create a new pull request.

5 commits

Author SHA1 Message Date
0xalivecow
b2b068b150
Merge branch 'feat_gcm' into feat_polynomial_gcm 2024-11-02 18:05:31 +01:00
0xalivecow
28216d2e2f
WIP: feat: start on gcm 2024-11-02 17:58:53 +01:00
0xalivecow
1e51015a14
WIP: feat: working on gfmul gcm 2024-11-02 16:12:51 +01:00
0xalivecow
1ce30e1cea
refactor: Apply cargo reccomended cleanups 2024-11-02 14:19:21 +01:00
0xalivecow
26ca12b419
feat: Add more tests to b2p edge cases 2024-11-02 14:18:10 +01:00
11 changed files with 271 additions and 122 deletions

View file

@ -1,5 +1,5 @@
use std::{ use std::{
env::{self, args}, env::{self},
fs, fs,
}; };

View file

@ -4,11 +4,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_task, poly2block::poly2block, sea128::sea128, xex::fde_xex,
gfmul::gfmul_task,
poly2block::poly2block,
sea128::sea128,
xex::{self, fde_xex},
}; };
use anyhow::{anyhow, Result}; use anyhow::{anyhow, Result};

View file

@ -1,4 +1,4 @@
use crate::utils::poly::{b64_2_num, block_2_polynomial, get_coefficients}; use crate::utils::poly::block_2_polynomial;
use anyhow::Result; use anyhow::Result;
use base64::prelude::*; use base64::prelude::*;
use serde_json::Value; use serde_json::Value;
@ -19,7 +19,7 @@ pub fn block2poly(val: &Value) -> Result<Vec<u8>> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json::json; use serde_json::json;
use std::str::FromStr;
// Note this useful idiom: importing names from outer (for mod tests) scope. // Note this useful idiom: importing names from outer (for mod tests) scope.
use super::*; use super::*;
@ -51,4 +51,46 @@ mod tests {
Ok(()) Ok(())
} }
#[test]
fn block2poly_task03() -> Result<()> {
let block: Value = json!({"block" : "AAAAAAAAAAAAAAAAAAAAAA==", "semantic" : "gcm"});
let coefficients: Vec<u8> = vec![];
assert_eq!(
block2poly(&block)?,
coefficients,
"Coefficients were: {:?}",
block2poly(&block)?
);
Ok(())
}
#[test]
fn block2poly_task04() -> Result<()> {
let block: Value = json!({"block" : "", "semantic" : "gcm"});
let coefficients: Vec<u8> = vec![];
assert_eq!(
block2poly(&block)?,
coefficients,
"Coefficients were: {:?}",
block2poly(&block)?
);
Ok(())
}
#[test]
fn block2poly_task_empty_xex() -> Result<()> {
let block: Value = json!({"block" : "", "semantic" : "xex"});
let coefficients: Vec<u8> = vec![];
assert_eq!(
block2poly(&block)?,
coefficients,
"Coefficients were: {:?}",
block2poly(&block)?
);
Ok(())
}
} }

View file

@ -1,7 +1,4 @@
use crate::utils::{ use crate::utils::poly::gfmul;
field::ByteArray,
poly::{b64_2_num, coefficient_to_binary, gfmul},
};
use anyhow::Result; use anyhow::Result;
use base64::prelude::*; use base64::prelude::*;
@ -24,7 +21,8 @@ pub fn gfmul_task(args: &Value) -> Result<Vec<u8>> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use serde_json::json; use serde_json::json;
use std::str::FromStr;
use crate::utils::math::reverse_bits_in_bytevec;
// Note this useful idiom: importing names from outer (for mod tests) scope. // Note this useful idiom: importing names from outer (for mod tests) scope.
use super::*; use super::*;
@ -108,4 +106,26 @@ mod tests {
); );
Ok(()) Ok(())
} }
#[test]
fn gfmul_task_gcm01() -> Result<()> {
let args: Value = json!({"a": "ARIAAAAAAAAAAAAAAAAAgA==", "b": "AgAAAAAAAAAAAAAAAAAAAA=="});
let poly1_text: String = serde_json::from_value(args["a"].clone())?;
let poly_a = reverse_bits_in_bytevec(BASE64_STANDARD.decode(poly1_text)?);
let poly2_text: String = serde_json::from_value(args["b"].clone())?;
let poly_b = reverse_bits_in_bytevec(BASE64_STANDARD.decode(poly2_text)?);
let result = BASE64_STANDARD.encode(gfmul(poly_a, poly_b, "gcm")?);
assert_eq!(
result,
BASE64_STANDARD.encode(reverse_bits_in_bytevec(
BASE64_STANDARD.decode("hSQAAAAAAAAAAAAAAAAAAA==")?
)),
"Failure. Calulated result was: {}",
result
);
Ok(())
}
} }

View file

@ -1,6 +1,5 @@
use crate::utils::poly::{self, polynomial_2_block}; use crate::utils::poly::{polynomial_2_block};
use anyhow::{Ok, Result}; use anyhow::{Ok, Result};
use base64::prelude::*;
use serde_json::Value; use serde_json::Value;
pub fn poly2block(args: &Value) -> Result<Vec<u8>> { pub fn poly2block(args: &Value) -> Result<Vec<u8>> {

View file

@ -34,7 +34,7 @@ pub fn sea128(args: &Value) -> Result<String> {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use std::fs;
use anyhow::Result; use anyhow::Result;
use serde_json::json; use serde_json::json;

View file

@ -1,4 +1,3 @@
use std::io::BufRead;
use anyhow::Result; use anyhow::Result;
use openssl::symm::{Cipher, Crypter, Mode}; use openssl::symm::{Cipher, Crypter, Mode};
@ -65,12 +64,12 @@ pub fn xex_encrypt(mut key: Vec<u8>, tweak: &Vec<u8>, input: &Vec<u8>) -> Result
let mut output: Vec<u8> = vec![]; let mut output: Vec<u8> = vec![];
//assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len());
//assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len());
let mut tweak_block: ByteArray = ByteArray(sea_128_encrypt(&key2, tweak)?); let mut tweak_block: ByteArray = ByteArray::from(sea_128_encrypt(&key2, tweak)?);
//dbg!("input_chunks: {:001X?}", &input_chunks); //dbg!("input_chunks: {:001X?}", &input_chunks);
for chunk in input_chunks { for chunk in input_chunks {
let plaintext_intermediate = xor_bytes(&tweak_block.0, chunk)?; let plaintext_intermediate = xor_bytes(&tweak_block.vector, chunk)?;
/* /*
assert!( assert!(
plaintext_intermediate.len() % 16 == 0, plaintext_intermediate.len() % 16 == 0,
@ -81,7 +80,7 @@ pub fn xex_encrypt(mut key: Vec<u8>, tweak: &Vec<u8>, input: &Vec<u8>) -> Result
//assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len());
//assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len());
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.vector, cypher_block_intermediate)?;
output.append(cypher_block.as_mut()); output.append(cypher_block.as_mut());
tweak_block.left_shift_reduce("xex"); tweak_block.left_shift_reduce("xex");
} }
@ -99,10 +98,10 @@ pub fn xex_decrypt(mut key: Vec<u8>, tweak: &Vec<u8>, input: &Vec<u8>) -> Result
let mut output: Vec<u8> = vec![]; let mut output: Vec<u8> = vec![];
//assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len()); //assert!(key.len() % 16 == 0, "Failure: Key len {}", key.len());
//assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); //assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len());
let mut tweak_block: ByteArray = ByteArray(sea_128_encrypt(&key2, tweak)?); let mut tweak_block: ByteArray = ByteArray::from(sea_128_encrypt(&key2, tweak)?);
for chunk in input_chunks { for chunk in input_chunks {
let cyphertext_intermediate = xor_bytes(&tweak_block.0, chunk)?; let cyphertext_intermediate = xor_bytes(&tweak_block.vector, chunk)?;
/* /*
assert!( assert!(
@ -114,7 +113,7 @@ pub fn xex_decrypt(mut key: Vec<u8>, tweak: &Vec<u8>, input: &Vec<u8>) -> Result
assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len()); assert!(key2.len() % 16 == 0, "Failure: Key2 len {}", key2.len());
*/ */
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.vector, plaintext_block_intermediate)?;
output.append(cypher_block.as_mut()); output.append(cypher_block.as_mut());
tweak_block.left_shift_reduce("xex"); tweak_block.left_shift_reduce("xex");
} }
@ -122,6 +121,42 @@ pub fn xex_decrypt(mut key: Vec<u8>, tweak: &Vec<u8>, input: &Vec<u8>) -> Result
Ok(output) Ok(output)
} }
pub fn gcm_aes_encrypt(
action: &str,
mut nonce: Vec<u8>,
key: Vec<u8>,
plaintext: Vec<u8>,
ad: ByteArray,
) -> Result<Vec<u8>> {
nonce.append(vec![0x01].as_mut());
let auth_text_xor_block = aes_128_encrypt(&key, &nonce);
let auth_key_h = aes_128_encrypt(&key, &vec![0]);
let plaintext: Vec<Vec<u8>> = plaintext.chunks(16).map(|x| x.to_vec()).collect();
let mut output: Vec<Vec<u8>> = vec![];
for (ctr, chunk) in plaintext.iter().enumerate() {
nonce.pop();
nonce.push(ctr as u8);
let intermediate = aes_128_encrypt(&key, &nonce)?;
let intermediate2 = xor_bytes(chunk, intermediate)?;
output.push(intermediate2);
}
todo!();
}
pub fn ghash(auth_key_h: Vec<u8>, ad: Vec<u8>, ciphertext: Vec<Vec<u8>>) {
let output: Vec<u8> = vec![0, 16];
let inter1 = xor_bytes(&output, ad);
}
/* /*
* let mut bytes: [u8; 16] = [0u8; 16]; * let mut bytes: [u8; 16] = [0u8; 16];
bytes.copy_from_slice(&ciphertext); bytes.copy_from_slice(&ciphertext);

View file

@ -4,14 +4,16 @@ use base64::Engine;
use super::poly::gfmul; use super::poly::gfmul;
#[derive(Debug)] #[derive(Debug)]
pub struct ByteArray(pub Vec<u8>); pub struct ByteArray {
pub vector: Vec<u8>,
}
impl ByteArray { impl ByteArray {
pub fn left_shift(&mut self, semantic: &str) -> Result<u8> { pub fn left_shift(&mut self, semantic: &str) -> Result<u8> {
match semantic { match semantic {
"xex" => { "xex" => {
let mut carry = 0u8; let mut carry = 0u8;
for byte in self.0.iter_mut() { for byte in self.vector.iter_mut() {
let new_carry = *byte >> 7; let new_carry = *byte >> 7;
*byte = (*byte << 1) | carry; *byte = (*byte << 1) | carry;
carry = new_carry; carry = new_carry;
@ -20,14 +22,56 @@ impl ByteArray {
} }
"gcm" => { "gcm" => {
let mut carry = 0u8; let mut carry = 0u8;
for byte in self.0.iter_mut() { for byte in self.vector.iter_mut() {
let new_carry = *byte & 1;
*byte = (*byte >> 1) | carry << 7;
carry = new_carry;
}
Ok(carry)
}
_ => Err(anyhow!("Failure in lsh. No compatible action found")),
}
}
pub fn left_shift_reduce(&mut self, semantic: &str) {
match semantic {
"xex" => {
let alpha_poly: Vec<u8> = base64::prelude::BASE64_STANDARD
.decode("AgAAAAAAAAAAAAAAAAAAAA==")
.expect("Decode failed");
self.vector = gfmul(self.vector.clone(), alpha_poly, "xex").unwrap();
}
"gcm" => {
let alpha_poly: Vec<u8> = base64::prelude::BASE64_STANDARD
.decode("AgAAAAAAAAAAAAAAAAAAAA==")
.expect("Decode failed");
self.vector = gfmul(self.vector.clone(), alpha_poly, "gcm").unwrap();
}
_ => {}
}
}
pub fn right_shift(&mut self, semantic: &str) -> Result<u8> {
match semantic {
"xex" => {
let mut carry = 0u8;
for byte in self.vector.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;
} }
Ok(carry) Ok(carry)
} }
_ => Err(anyhow!("Failure in lsh. No compatible action found")), "gcm" => {
let mut carry = 0u8;
for byte in self.vector.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")),
} }
} }
@ -49,150 +93,139 @@ impl ByteArray {
} }
} }
pub fn right_shift(&mut self, semantic: &str) -> Result<u8> {
match semantic {
"xex" => {
let mut carry = 0u8;
for byte in self.0.iter_mut().rev() {
let new_carry = *byte & 1;
*byte = (*byte >> 1) | (carry << 7);
carry = new_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) {
self.0 self.vector
.iter_mut() .iter_mut()
.zip(vec2.0.iter()) .zip(vec2.vector.iter())
.for_each(|(x1, x2)| *x1 ^= *x2); .for_each(|(x1, x2)| *x1 ^= *x2);
} }
pub fn LSB_is_one(&self) -> bool { pub fn lsb_is_one(&self) -> bool {
(self.0.first().unwrap() & 1) == 1 (self.0.first().unwrap() & 1) == 1
} }
pub fn msb_is_one(&self) -> bool { pub fn msb_is_one(&self) -> bool {
(self.0.last().unwrap() & 1) == 1 (self.vector.last().unwrap() & 1) == 1
} }
pub fn is_empty(&self) -> bool { pub fn is_empty(&self) -> bool {
for i in self.0.iter() { for i in self.vector.iter() {
if *i != 0 { if *i != 0 {
return false; return false;
} }
} }
true true
} }
pub fn reverse_bits_in_bytevec(&mut self) {
self.0 = self.0.iter_mut().map(|byte| byte.reverse_bits()).collect();
}
pub fn append_vec(&mut self, mut other: Vec<u8>) {
self.vector.append(other.as_mut());
}
}
impl From<Vec<u8>> for ByteArray {
fn from(item: Vec<u8>) -> Self {
ByteArray { vector: item }
}
} }
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use std::fs;
#[test] #[test]
fn test_byte_array_shift1() { fn test_byte_array_shift1() {
let mut byte_array: ByteArray = ByteArray(vec![0x00, 0x01]); let mut byte_array: ByteArray = ByteArray::from(vec![0x00, 0x01]);
let shifted_array: ByteArray = ByteArray(vec![0x00, 0x02]); let shifted_array: ByteArray = ByteArray::from(vec![0x00, 0x02]);
byte_array.left_shift("xex"); byte_array.left_shift("xex");
assert_eq!(byte_array.0, shifted_array.0); assert_eq!(byte_array.vector, shifted_array.vector);
} }
#[test] #[test]
fn test_byte_array_shift2() { fn test_byte_array_shift2() {
let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]);
let shifted_array: ByteArray = ByteArray(vec![0xFE, 0x01]); let shifted_array: ByteArray = ByteArray::from(vec![0xFE, 0x01]);
byte_array.left_shift("xex"); byte_array.left_shift("xex");
assert_eq!( assert_eq!(
byte_array.0, shifted_array.0, byte_array.vector, shifted_array.vector,
"Failure: Shifted array was: {:?}", "Failure: Shifted array was: {:?}",
byte_array.0 byte_array.vector
); );
} }
#[test] #[test]
fn test_byte_array_shift1_gcm() { fn test_byte_array_shift1_gcm() {
let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]);
let shifted_array: ByteArray = ByteArray(vec![0x7F, 0x80]); let shifted_array: ByteArray = ByteArray::from(vec![0x7F, 0x80]);
byte_array.left_shift("gcm"); byte_array.left_shift("gcm");
assert_eq!( assert_eq!(
byte_array.0, shifted_array.0, byte_array.vector, shifted_array.vector,
"Failure: Shifted array was: {:02X?}", "Failure: Shifted array was: {:02X?}",
byte_array.0 byte_array.vector
); );
} }
#[test] #[test]
fn test_byte_array_shift1_right_gcm() { fn test_byte_array_shift1_right_gcm() {
let mut byte_array: ByteArray = ByteArray(vec![0xFF, 0x00]); let mut byte_array: ByteArray = ByteArray::from(vec![0xFF, 0x00]);
let shifted_array: ByteArray = ByteArray(vec![0xFE, 0x00]); let shifted_array: ByteArray = ByteArray::from(vec![0xFE, 0x00]);
byte_array.right_shift("gcm"); byte_array.right_shift("gcm");
assert_eq!( assert_eq!(
byte_array.0, shifted_array.0, byte_array.vector, shifted_array.vector,
"Failure: Shifted array was: {:02X?}", "Failure: Shifted array was: {:02X?}",
byte_array.0 byte_array.vector
); );
} }
#[test] #[test]
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::from(vec![0x02]);
let shifted_array: ByteArray = ByteArray(vec![0x01]); let shifted_array: ByteArray = ByteArray::from(vec![0x01]);
byte_array.right_shift("xex"); byte_array.right_shift("xex");
assert_eq!( assert_eq!(
byte_array.0, shifted_array.0, byte_array.vector, shifted_array.vector,
"Failure: Shifted array was: {:?}", "Failure: Shifted array was: {:?}",
byte_array.0 byte_array.vector
); );
} }
#[test] #[test]
fn test_lsb_one() { fn test_lsb_one() {
let byte_array: ByteArray = ByteArray(vec![0x00, 0xFF]); let byte_array: ByteArray = ByteArray(vec![0x00, 0xFF]);
assert!(!byte_array.LSB_is_one()); assert!(!byte_array.lsb_is_one());
let byte_array2: ByteArray = ByteArray(vec![0x02, 0xFF]); let byte_array2: ByteArray = ByteArray(vec![0x02, 0xFF]);
assert!(!byte_array2.LSB_is_one()); assert!(!byte_array2.lsb_is_one());
let byte_array3: ByteArray = ByteArray(vec![0xFF, 0x00]); let byte_array3: ByteArray = ByteArray(vec![0xFF, 0x00]);
assert!(byte_array3.LSB_is_one()); assert!(byte_array3.lsb_is_one());
} }
#[test] #[test]
fn test_byte_xor() { fn test_byte_xor() {
let mut byte_array: ByteArray = ByteArray(vec![0x25, 0x25]); let mut byte_array: ByteArray = ByteArray::from(vec![0x25, 0x25]);
let byte_array2: ByteArray = ByteArray(vec![0x55, 0x55]); let byte_array2: ByteArray = ByteArray::from(vec![0x55, 0x55]);
byte_array.xor_byte_arrays(&byte_array2); byte_array.xor_byte_arrays(&byte_array2);
assert_eq!(byte_array.0, vec![0x70, 0x70]); assert_eq!(byte_array.vector, vec![0x70, 0x70]);
} }
#[test] #[test]
fn test_byte_xor2() { fn test_byte_xor2() {
let mut byte_array: ByteArray = ByteArray(vec![0x00, 0x00]); let mut byte_array: ByteArray = ByteArray::from(vec![0x00, 0x00]);
let byte_array2: ByteArray = ByteArray(vec![0x55, 0x55]); let byte_array2: ByteArray = ByteArray::from(vec![0x55, 0x55]);
byte_array.xor_byte_arrays(&byte_array2); byte_array.xor_byte_arrays(&byte_array2);
assert_eq!(byte_array.0, vec![0x55, 0x55]); assert_eq!(byte_array.vector, vec![0x55, 0x55]);
} }
} }

View file

@ -1,7 +1,4 @@
use anyhow::{anyhow, Ok, Result}; use anyhow::{Ok, Result};
use base64::Engine;
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()) {
@ -10,3 +7,9 @@ pub fn xor_bytes(vec1: &Vec<u8>, mut vec2: Vec<u8>) -> Result<Vec<u8>> {
Ok(vec2) Ok(vec2)
} }
pub fn reverse_bits_in_bytevec(mut vec: Vec<u8>) -> Vec<u8> {
vec = vec.iter_mut().map(|byte| byte.reverse_bits()).collect();
vec
}

View file

@ -28,7 +28,7 @@ pub fn parse_json(json: String) -> Result<Testcases> {
mod tests { mod tests {
use std::fs; use std::fs;
use serde_json::json;
// Note this useful idiom: importing names from outer (for mod tests) scope. // Note this useful idiom: importing names from outer (for mod tests) scope.
use super::*; use super::*;

View file

@ -1,46 +1,63 @@
use crate::utils::field::ByteArray; use crate::utils::field::ByteArray;
use anyhow::{anyhow, Result}; use anyhow::{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};
use super::field;
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::from(RED_POLY.to_be_bytes().to_vec());
red_poly_bytes.0.push(0x01); red_poly_bytes.vector.push(0x01);
let mut poly1: ByteArray = ByteArray(poly_a); red_poly_bytes.reverse_bits_in_bytevec();
poly1.0.push(0x00);
let mut poly2: ByteArray = ByteArray(poly_b); let mut poly1: ByteArray = ByteArray::from(poly_a);
poly2.0.push(0x00); poly1.vector.push(0x00);
let mut poly2: ByteArray = ByteArray::from(poly_b);
poly2.vector.push(0x00);
eprintln!(
"poly1 is: {:001X?} \n poly2 is: {:001X?} \n gen poly is: {:001X?} \n",
poly1, poly2, red_poly_bytes
);
let mut result: ByteArray = ByteArray(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]); let mut result: ByteArray = ByteArray(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
let mut result: ByteArray =
ByteArray::from(vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]);
if poly2.LSB_is_one() { if poly2.msb_is_one() {
result.xor_byte_arrays(&poly1); result.xor_byte_arrays(&poly1);
} }
poly2.right_shift(semantic)?; poly2.right_shift(semantic)?;
eprintln!(
"poly1 is: {:001X?} \n poly2 is: {:001X?} \n gen poly is: {:001X?} \n result is: {:001X?} \n ",
poly1, poly2, red_poly_bytes, result
);
while !poly2.is_empty() { while !poly2.is_empty() {
eprintln!(
"poly1 is: {:001X?} \n poly2 is: {:001X?} \n gen poly is: {:001X?} \n result is: {:001X?} \n ",
poly1, poly2, red_poly_bytes, result
);
poly1.left_shift(semantic)?; poly1.left_shift(semantic)?;
if poly1.msb_is_one() { if poly1.lsb_is_one() {
poly1.xor_byte_arrays(&red_poly_bytes); poly1.xor_byte_arrays(&red_poly_bytes);
} }
if poly2.LSB_is_one() { if poly2.msb_is_one() {
eprintln!("poly write to result");
result.xor_byte_arrays(&poly1); result.xor_byte_arrays(&poly1);
} }
poly2.right_shift(semantic)?; poly2.right_shift(semantic)?;
} }
result.0.remove(16); result.vector.remove(16);
Ok(result.0) Ok(result.vector)
} }
pub fn convert_gcm_to_xex(gcm_poly: Vec<u8>) -> Result<Vec<u8>> { pub fn convert_gcm_to_xex(gcm_poly: Vec<u8>) -> Result<Vec<u8>> {
@ -104,13 +121,16 @@ pub fn get_bit_indices_from_byte(byte: u8) -> Vec<u8> {
} }
pub fn block_2_polynomial(block: Vec<u8>, semantic: &str) -> Result<Vec<u8>> { pub fn block_2_polynomial(block: Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
if block.len() == 0 {
Ok(Vec::new())
} else {
let mut output: Vec<u8> = vec![]; let mut output: Vec<u8> = vec![];
match semantic { match semantic {
"xex" => { "xex" => {
for i in 0u8..=15 { for byte in 0u8..=15 {
for j in 0u8..=7 { for bit in 0u8..=7 {
if (block[i as usize] >> j) & 1 == 1 { if (block[byte as usize] >> bit) & 1 == 1 {
output.push(8 * i + j); output.push(8 * byte + bit);
} }
} }
} }
@ -118,10 +138,10 @@ pub fn block_2_polynomial(block: Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
Ok(output) Ok(output)
} }
"gcm" => { "gcm" => {
for i in 0u8..=15 { for byte in 0u8..=15 {
for j in 0u8..=7 { for bit in 0u8..=7 {
if (block[i as usize] >> j) & 1 == 1 { if (block[byte as usize] >> bit) & 1 == 1 {
output.push(8 * i + 7 - j); output.push(8 * byte + 7 - bit);
} }
} }
} }
@ -131,6 +151,7 @@ pub fn block_2_polynomial(block: Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
_ => Err(anyhow!("Error in b2p")), _ => Err(anyhow!("Error in b2p")),
} }
} }
}
pub fn polynomial_2_block(coefficients: Vec<u8>, semantic: &str) -> Result<Vec<u8>> { pub fn polynomial_2_block(coefficients: Vec<u8>, semantic: &str) -> Result<Vec<u8>> {
let mut output: Vec<u8> = Vec::with_capacity(16); let mut output: Vec<u8> = Vec::with_capacity(16);
@ -163,7 +184,7 @@ pub fn coefficients_to_byte_arr_xex(coeffs: Vec<u8>) -> Vec<u8> {
let mut byte_array: Vec<u8> = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; let mut byte_array: Vec<u8> = vec![0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
for coeff in coeffs { for coeff in coeffs {
let block_num = coeff / 8; let block_num = coeff / 8;
byte_array[usize::from(block_num)] |= (1 << (coeff % 7)); byte_array[usize::from(block_num)] |= 1 << (coeff % 7);
} }
byte_array byte_array