Add basic pfmath functionality #13

Merged
0xalivecow merged 7 commits from dev into main 2024-11-14 22:12:02 +00:00
2 changed files with 135 additions and 26 deletions
Showing only changes of commit 11916e29f0 - Show all commits

View file

@ -108,24 +108,4 @@ mod tests {
); );
Ok(()) 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(())
}
} }

View file

@ -52,6 +52,42 @@ impl Polynomial {
output 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<String> = 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 { impl Mul for Polynomial {
@ -70,9 +106,11 @@ impl Mul for Polynomial {
} }
} }
impl Add for Polynomial { impl Mul for &Polynomial {
type Output = Self; type Output = Polynomial;
fn add(self, rhs: Self) -> Self::Output { 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 i in 0..self.polynomial.len() {
for j in 0..rhs.polynomial.len() { for j in 0..rhs.polynomial.len() {
polynomial[i + j] = &polynomial[i + j] 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<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)
}
}
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 { impl Add for Polynomial {
type Output = Self; type Output = Self;
@ -117,6 +189,10 @@ 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 {
BASE64_STANDARD.encode(&self.field_element)
}
} }
impl Mul for FieldElement { 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<u8> = self
.field_element
.iter()
.zip(rhs.field_element.iter())
.map(|(&x1, &x2)| x1 ^ x2)
.collect();
FieldElement::new(result)
}
}
/* /*
impl BitXor for FieldElement { impl BitXor for FieldElement {
fn bitxor(self, rhs: Self) -> Self::Output { fn bitxor(self, rhs: Self) -> Self::Output {
@ -424,7 +513,15 @@ mod tests {
let sum = element2 + element1; let sum = element2 + element1;
assert_eq!(BASE64_STANDARD.encode(sum), "OZuIncPAGEp4tYouDownAA=="); assert_eq!(
sum.to_c_array(),
vec![
"H1d3GuyA9/0OxeYouUpAAA==",
"OZuIncPAGEp4tYouDownAA==",
"NeverGonnaRunAroundAAA==",
"AndDesertYouAAAAAAAAAA=="
]
);
} }
#[test] #[test]
@ -442,9 +539,41 @@ mod tests {
let result = element1 * element2; 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=="); //assert_eq!(BASE64_STANDARD.encode(product), "MoAAAAAAAAAAAAAAAAAAAA==");
} }
} }