Add basic pfmath functionality #13
4 changed files with 120 additions and 42 deletions
|
|
@ -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,7 +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!(
|
assert_eq!(
|
||||||
result, "hSQAAAAAAAAAAAAAAAAAAA==",
|
result, "hSQAAAAAAAAAAAAAAAAAAA==",
|
||||||
|
|
|
||||||
|
|
@ -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,12 +1,15 @@
|
||||||
use std::{
|
use std::{
|
||||||
env::args,
|
env::args,
|
||||||
ops::{Add, BitXor, Mul},
|
ops::{Add, BitXor, Div, Mul, Rem, Sub},
|
||||||
|
result,
|
||||||
};
|
};
|
||||||
|
|
||||||
use anyhow::{anyhow, Ok, Result};
|
use anyhow::{anyhow, Ok, Result};
|
||||||
use base64::prelude::*;
|
use base64::prelude::*;
|
||||||
use serde_json::Value;
|
use serde_json::Value;
|
||||||
|
|
||||||
|
use crate::{tasks::tasks01::poly2block::poly2block, utils::poly::polynomial_2_block};
|
||||||
|
|
||||||
use super::{math::xor_bytes, poly::gfmul};
|
use super::{math::xor_bytes, poly::gfmul};
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[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 {
|
impl AsRef<[FieldElement]> for Polynomial {
|
||||||
fn as_ref(&self) -> &[FieldElement] {
|
fn as_ref(&self) -> &[FieldElement] {
|
||||||
&self.polynomial
|
&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)]
|
#[derive(Debug)]
|
||||||
pub struct FieldElement {
|
pub struct FieldElement {
|
||||||
field_element: Vec<u8>,
|
field_element: Vec<u8>,
|
||||||
|
|
@ -187,12 +186,48 @@ impl FieldElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn mul(&self, poly_a: Vec<u8>, poly_b: Vec<u8>) -> Result<Vec<u8>> {
|
pub fn mul(&self, poly_a: Vec<u8>, poly_b: Vec<u8>) -> Result<Vec<u8>> {
|
||||||
gfmul(poly_a, poly_b, "gcm")
|
gfmul(&poly_a, &poly_b, "gcm")
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_b64(&self) -> String {
|
pub fn to_b64(&self) -> String {
|
||||||
BASE64_STANDARD.encode(&self.field_element)
|
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 {
|
impl Mul for FieldElement {
|
||||||
|
|
@ -200,7 +235,7 @@ impl Mul for FieldElement {
|
||||||
|
|
||||||
fn mul(self, rhs: Self) -> Self::Output {
|
fn mul(self, rhs: Self) -> Self::Output {
|
||||||
FieldElement::new(
|
FieldElement::new(
|
||||||
gfmul(self.field_element, rhs.field_element, "gcm")
|
gfmul(&self.field_element, &rhs.field_element, "gcm")
|
||||||
.expect("Error during multiplication"),
|
.expect("Error during multiplication"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -211,7 +246,7 @@ impl Mul for &FieldElement {
|
||||||
|
|
||||||
fn mul(self, rhs: &FieldElement) -> FieldElement {
|
fn mul(self, rhs: &FieldElement) -> FieldElement {
|
||||||
FieldElement::new(
|
FieldElement::new(
|
||||||
gfmul(self.field_element.clone(), rhs.field_element.clone(), "gcm")
|
gfmul(&self.field_element, &rhs.field_element, "gcm")
|
||||||
.expect("Error during multiplication"),
|
.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 {
|
impl BitXor for FieldElement {
|
||||||
fn bitxor(self, rhs: Self) -> Self::Output {
|
fn bitxor(self, rhs: Self) -> Self::Output {
|
||||||
|
|
@ -312,13 +377,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();
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
|
@ -576,4 +641,17 @@ mod tests {
|
||||||
);
|
);
|
||||||
//assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA==");
|
//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==");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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" {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue