refactor: Change implementation to only switch semantic once
This commit is contained in:
parent
679c0223af
commit
12254744d4
2 changed files with 59 additions and 63 deletions
|
|
@ -28,18 +28,24 @@ impl FieldElement {
|
||||||
|
|
||||||
pub fn rand() -> Self {
|
pub fn rand() -> Self {
|
||||||
let rand_field: [u8; 16] = rand::random();
|
let rand_field: [u8; 16] = rand::random();
|
||||||
FieldElement::new(rand_field.to_vec())
|
FieldElement::new_no_convert(rand_field.to_vec())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zero() -> Self {
|
pub fn zero() -> Self {
|
||||||
FieldElement::new(vec![0])
|
FieldElement::new_no_convert(vec![0; 16])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn one() -> Self {
|
pub fn one() -> Self {
|
||||||
FieldElement::new(vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
FieldElement::new_no_convert(vec![0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn new(field_element: Vec<u8>) -> Self {
|
pub fn new(field_element: Vec<u8>) -> Self {
|
||||||
|
Self {
|
||||||
|
field_element: reverse_bits_in_bytevec(field_element),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn new_no_convert(field_element: Vec<u8>) -> Self {
|
||||||
Self { field_element }
|
Self { field_element }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,7 +54,7 @@ impl FieldElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_b64(&self) -> String {
|
pub fn to_b64(&self) -> String {
|
||||||
BASE64_STANDARD.encode(&self.field_element)
|
BASE64_STANDARD.encode(reverse_bits_in_bytevec(self.field_element.to_owned()))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pow(mut self, mut exponent: u128) -> FieldElement {
|
pub fn pow(mut self, mut exponent: u128) -> FieldElement {
|
||||||
|
|
@ -97,20 +103,20 @@ impl FieldElement {
|
||||||
const INVERSER_START: u128 = 0xfffffffffffffffffffffffffffffffe;
|
const INVERSER_START: u128 = 0xfffffffffffffffffffffffffffffffe;
|
||||||
|
|
||||||
let mut inverser = INVERSER_START;
|
let mut inverser = INVERSER_START;
|
||||||
let mut inverse: Vec<u8> = vec![0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
let mut inverse: Vec<u8> = vec![0x01, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
|
||||||
//eprintln!("Inverse start {:02X?}", inverse);
|
//eprintln!("Inverse start {:02X?}", inverse);
|
||||||
|
|
||||||
while inverser > 0 {
|
while inverser > 0 {
|
||||||
//eprintln!("{:02X}", inverser);
|
//eprintln!("{:02X}", inverser);
|
||||||
if inverser & 1 == 1 {
|
if inverser & 1 == 1 {
|
||||||
inverse = gfmul(&self.field_element, &inverse, "gcm").unwrap();
|
inverse = gfmul(&self.field_element, &inverse, "xex").unwrap();
|
||||||
}
|
}
|
||||||
inverser >>= 1;
|
inverser >>= 1;
|
||||||
self.field_element = gfmul(&self.field_element, &self.field_element, "gcm")
|
self.field_element = gfmul(&self.field_element, &self.field_element, "xex")
|
||||||
.expect("Error in sqrmul sqr");
|
.expect("Error in sqrmul sqr");
|
||||||
}
|
}
|
||||||
//eprintln!("Inverse rhs {:?}", inverse);
|
//eprintln!("Inverse rhs {:?}", inverse);
|
||||||
FieldElement::new(inverse)
|
FieldElement::new_no_convert(inverse)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_zero(&self) -> bool {
|
pub fn is_zero(&self) -> bool {
|
||||||
|
|
@ -118,7 +124,7 @@ impl FieldElement {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn reverse_bits(&self) -> Self {
|
pub fn reverse_bits(&self) -> Self {
|
||||||
FieldElement::new(reverse_bits_in_bytevec(self.field_element.clone()))
|
FieldElement::new_no_convert(reverse_bits_in_bytevec(self.field_element.clone()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -126,8 +132,8 @@ impl Mul for FieldElement {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
|
|
||||||
fn mul(self, rhs: Self) -> Self::Output {
|
fn mul(self, rhs: Self) -> Self::Output {
|
||||||
FieldElement::new(
|
FieldElement::new_no_convert(
|
||||||
gfmul(&self.field_element, &rhs.field_element, "gcm")
|
gfmul(&self.field_element, &rhs.field_element, "xex")
|
||||||
.expect("Error during multiplication"),
|
.expect("Error during multiplication"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -137,8 +143,8 @@ impl Mul for &FieldElement {
|
||||||
type Output = FieldElement;
|
type Output = FieldElement;
|
||||||
|
|
||||||
fn mul(self, rhs: &FieldElement) -> FieldElement {
|
fn mul(self, rhs: &FieldElement) -> FieldElement {
|
||||||
FieldElement::new(
|
FieldElement::new_no_convert(
|
||||||
gfmul(&self.field_element, &rhs.field_element, "gcm")
|
gfmul(&self.field_element, &rhs.field_element, "xex")
|
||||||
.expect("Error during multiplication"),
|
.expect("Error during multiplication"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -147,7 +153,7 @@ impl Mul for &FieldElement {
|
||||||
impl Add for FieldElement {
|
impl Add for FieldElement {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn add(self, rhs: Self) -> Self::Output {
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
FieldElement::new(
|
FieldElement::new_no_convert(
|
||||||
xor_bytes(&self.field_element, rhs.field_element).expect("Error in poly add"),
|
xor_bytes(&self.field_element, rhs.field_element).expect("Error in poly add"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -156,7 +162,7 @@ impl Add for FieldElement {
|
||||||
impl Add for &FieldElement {
|
impl Add for &FieldElement {
|
||||||
type Output = FieldElement;
|
type Output = FieldElement;
|
||||||
fn add(self, rhs: Self) -> Self::Output {
|
fn add(self, rhs: Self) -> Self::Output {
|
||||||
FieldElement::new(
|
FieldElement::new_no_convert(
|
||||||
xor_bytes(&self.field_element, rhs.field_element.clone()).expect("Error in poly add"),
|
xor_bytes(&self.field_element, rhs.field_element.clone()).expect("Error in poly add"),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
@ -185,7 +191,7 @@ impl BitXor for FieldElement {
|
||||||
.zip(rhs.field_element.iter())
|
.zip(rhs.field_element.iter())
|
||||||
.map(|(&x1, &x2)| x1 ^ x2)
|
.map(|(&x1, &x2)| x1 ^ x2)
|
||||||
.collect();
|
.collect();
|
||||||
FieldElement::new(result)
|
FieldElement::new_no_convert(result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -450,7 +456,7 @@ mod tests {
|
||||||
FieldElement::new(BASE64_STANDARD.decode("KryptoanalyseAAAAAAAAA==").unwrap());
|
FieldElement::new(BASE64_STANDARD.decode("KryptoanalyseAAAAAAAAA==").unwrap());
|
||||||
let sum = element2 + element1;
|
let sum = element2 + element1;
|
||||||
|
|
||||||
assert_eq!(BASE64_STANDARD.encode(sum), "H1d3GuyA9/0OxeYouUpAAA==");
|
assert_eq!(sum.to_b64(), "H1d3GuyA9/0OxeYouUpAAA==");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -461,6 +467,19 @@ mod tests {
|
||||||
FieldElement::new(BASE64_STANDARD.decode("DHBWMannheimAAAAAAAAAA==").unwrap());
|
FieldElement::new(BASE64_STANDARD.decode("DHBWMannheimAAAAAAAAAA==").unwrap());
|
||||||
let sum = element2 + element1;
|
let sum = element2 + element1;
|
||||||
|
|
||||||
assert_eq!(BASE64_STANDARD.encode(sum), "OZuIncPAGEp4tYouDownAA==");
|
assert_eq!(sum.to_b64(), "OZuIncPAGEp4tYouDownAA==");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_field_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!(result.to_b64(), "OAAAAAAAAAAAAAAAAAAAAA==");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,15 +32,13 @@ impl Polynomial {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn one() -> Self {
|
pub fn one() -> Self {
|
||||||
Polynomial::new(vec![FieldElement::new(
|
Polynomial::new(vec![FieldElement::one()])
|
||||||
polynomial_2_block(vec![0], "gcm").unwrap(),
|
|
||||||
)])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x() -> Self {
|
pub fn x() -> Self {
|
||||||
Polynomial::new(vec![
|
Polynomial::new(vec![
|
||||||
FieldElement::new(vec![0; 16]),
|
FieldElement::new(vec![0; 16]),
|
||||||
FieldElement::new(polynomial_2_block(vec![0], "gcm").unwrap()),
|
FieldElement::new(polynomial_2_block(vec![0], "xex").unwrap()),
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -54,7 +52,7 @@ impl Polynomial {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zero() -> Self {
|
pub fn zero() -> Self {
|
||||||
Polynomial::new(vec![FieldElement::new(vec![0; 16])])
|
Polynomial::new(vec![FieldElement::zero()])
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_c_array(array: &Value) -> Self {
|
pub fn from_c_array(array: &Value) -> Self {
|
||||||
|
|
@ -85,7 +83,7 @@ impl Polynomial {
|
||||||
pub fn to_c_array(self) -> Vec<String> {
|
pub fn to_c_array(self) -> Vec<String> {
|
||||||
let mut output: Vec<String> = vec![];
|
let mut output: Vec<String> = vec![];
|
||||||
for coeff in self.polynomial {
|
for coeff in self.polynomial {
|
||||||
output.push(BASE64_STANDARD.encode(coeff));
|
output.push(coeff.to_b64());
|
||||||
}
|
}
|
||||||
|
|
||||||
output
|
output
|
||||||
|
|
@ -219,9 +217,7 @@ impl Polynomial {
|
||||||
}
|
}
|
||||||
|
|
||||||
if exponent == 0 {
|
if exponent == 0 {
|
||||||
let result = Polynomial::new(vec![FieldElement::new(
|
let result = Polynomial::new(vec![FieldElement::one()]);
|
||||||
polynomial_2_block(vec![0], "gcm").unwrap(),
|
|
||||||
)]);
|
|
||||||
|
|
||||||
eprintln!("Returned value is: {:02X?}", result);
|
eprintln!("Returned value is: {:02X?}", result);
|
||||||
return result;
|
return result;
|
||||||
|
|
@ -273,10 +269,7 @@ impl Polynomial {
|
||||||
//eprintln!("{:?}, {:?}", self.polynomial.len(), rhs.polynomial.len());
|
//eprintln!("{:?}, {:?}", self.polynomial.len(), rhs.polynomial.len());
|
||||||
|
|
||||||
if self.polynomial.len() < rhs.polynomial.len() {
|
if self.polynomial.len() < rhs.polynomial.len() {
|
||||||
return (
|
return (Polynomial::new(vec![FieldElement::zero()]), self.clone());
|
||||||
Polynomial::new(vec![FieldElement::new(vec![0; 16])]),
|
|
||||||
self.clone(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut remainder = self.clone();
|
let mut remainder = self.clone();
|
||||||
|
|
@ -285,16 +278,10 @@ impl Polynomial {
|
||||||
let divisor_deg = divisor.polynomial.len() - 1;
|
let divisor_deg = divisor.polynomial.len() - 1;
|
||||||
|
|
||||||
if dividend_deg < divisor_deg {
|
if dividend_deg < divisor_deg {
|
||||||
return (
|
return (Polynomial::new(vec![FieldElement::zero()]), remainder);
|
||||||
Polynomial::new(vec![FieldElement::new(
|
|
||||||
polynomial_2_block(vec![0; 16], "gcm").unwrap(),
|
|
||||||
)]),
|
|
||||||
remainder,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut quotient_coeffs =
|
let mut quotient_coeffs = vec![FieldElement::zero(); dividend_deg - divisor_deg + 1];
|
||||||
vec![FieldElement::new(vec![0; 16]); dividend_deg - divisor_deg + 1];
|
|
||||||
|
|
||||||
while remainder.polynomial.len() >= divisor.polynomial.len() {
|
while remainder.polynomial.len() >= divisor.polynomial.len() {
|
||||||
let deg_diff = remainder.polynomial.len() - divisor.polynomial.len();
|
let deg_diff = remainder.polynomial.len() - divisor.polynomial.len();
|
||||||
|
|
@ -305,7 +292,7 @@ impl Polynomial {
|
||||||
|
|
||||||
quotient_coeffs[deg_diff] = quot_coeff.clone();
|
quotient_coeffs[deg_diff] = quot_coeff.clone();
|
||||||
|
|
||||||
let mut subtrahend = vec![FieldElement::new(vec![0; 16]); deg_diff];
|
let mut subtrahend = vec![FieldElement::zero(); deg_diff];
|
||||||
subtrahend.extend(
|
subtrahend.extend(
|
||||||
divisor
|
divisor
|
||||||
.polynomial
|
.polynomial
|
||||||
|
|
@ -330,7 +317,7 @@ impl Polynomial {
|
||||||
}
|
}
|
||||||
|
|
||||||
if remainder.is_empty() {
|
if remainder.is_empty() {
|
||||||
remainder = Polynomial::new(vec![FieldElement::new(vec![0; 16])]);
|
remainder = Polynomial::new(vec![FieldElement::zero()]);
|
||||||
}
|
}
|
||||||
(Polynomial::new(quotient_coeffs), remainder)
|
(Polynomial::new(quotient_coeffs), remainder)
|
||||||
}
|
}
|
||||||
|
|
@ -431,10 +418,10 @@ impl Mul for Polynomial {
|
||||||
type Output = Self;
|
type Output = Self;
|
||||||
fn mul(self, rhs: Self) -> Self::Output {
|
fn mul(self, rhs: Self) -> Self::Output {
|
||||||
if self.is_zero() || rhs.is_zero() {
|
if self.is_zero() || rhs.is_zero() {
|
||||||
return Polynomial::new(vec![FieldElement::new(vec![0; 16])]);
|
return Polynomial::zero();
|
||||||
}
|
}
|
||||||
let mut polynomial: Vec<FieldElement> =
|
let mut polynomial: Vec<FieldElement> =
|
||||||
vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1];
|
vec![FieldElement::zero(); 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]
|
||||||
|
|
@ -449,10 +436,10 @@ impl Mul for &Polynomial {
|
||||||
type Output = Polynomial;
|
type Output = Polynomial;
|
||||||
fn mul(self, rhs: Self) -> Self::Output {
|
fn mul(self, rhs: Self) -> Self::Output {
|
||||||
if self.is_zero() || rhs.is_zero() {
|
if self.is_zero() || rhs.is_zero() {
|
||||||
return Polynomial::new(vec![FieldElement::new(vec![0])]);
|
return Polynomial::zero();
|
||||||
}
|
}
|
||||||
let mut polynomial: Vec<FieldElement> =
|
let mut polynomial: Vec<FieldElement> =
|
||||||
vec![FieldElement::new(vec![0; 16]); self.polynomial.len() + rhs.polynomial.len() - 1];
|
vec![FieldElement::zero(); 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]
|
||||||
|
|
@ -486,7 +473,7 @@ impl Add for Polynomial {
|
||||||
}
|
}
|
||||||
|
|
||||||
if polynomial.is_empty() {
|
if polynomial.is_empty() {
|
||||||
return Polynomial::new(vec![FieldElement::new(vec![0; 16])]);
|
return Polynomial::new(vec![FieldElement::zero()]);
|
||||||
}
|
}
|
||||||
|
|
||||||
Polynomial::new(polynomial)
|
Polynomial::new(polynomial)
|
||||||
|
|
@ -535,8 +522,8 @@ impl PartialOrd for Polynomial {
|
||||||
);
|
);
|
||||||
|
|
||||||
match field_a
|
match field_a
|
||||||
.reverse_bits()
|
//.reverse_bits()
|
||||||
.partial_cmp(&field_b.reverse_bits())
|
.partial_cmp(&field_b)
|
||||||
.unwrap()
|
.unwrap()
|
||||||
{
|
{
|
||||||
Ordering::Equal => continue,
|
Ordering::Equal => continue,
|
||||||
|
|
@ -559,7 +546,10 @@ impl Ord for Polynomial {
|
||||||
for (field_a, field_b) in
|
for (field_a, field_b) in
|
||||||
self.as_ref().iter().rev().zip(other.as_ref().iter().rev())
|
self.as_ref().iter().rev().zip(other.as_ref().iter().rev())
|
||||||
{
|
{
|
||||||
match field_a.reverse_bits().cmp(&field_b.reverse_bits()) {
|
match field_a
|
||||||
|
//.reverse_bits()
|
||||||
|
.cmp(&field_b)
|
||||||
|
{
|
||||||
Ordering::Equal => continue,
|
Ordering::Equal => continue,
|
||||||
other => return other,
|
other => return other,
|
||||||
}
|
}
|
||||||
|
|
@ -1136,19 +1126,6 @@ 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==");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_field_poly_div_01() {
|
fn test_field_poly_div_01() {
|
||||||
let json1 = json!([
|
let json1 = json!([
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue