A toy implementation of an (s-t)Detectable Hash Function
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

85 lines
2.1 KiB

use std::fmt::{Display, Formatter, Result};
use std::ops::{Add, Mul, Sub};
/// Did I really implement an awfully hacky prime order field to play with this
/// Yes...yes I did...
#[derive(Clone, Copy, Debug)]
pub struct PrimeOrderDomain<const ORDER: u64> {
val: u64,
}
impl<const ORDER: u64> Display for PrimeOrderDomain<{ ORDER }> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result {
write!(f, "{:20}", self.val)
}
}
impl<const ORDER: u64> PrimeOrderDomain<{ ORDER }> {
pub fn new(val: u64) -> PrimeOrderDomain<{ ORDER }> {
PrimeOrderDomain { val }
}
pub fn is_zero(&self) -> bool {
self.val == 0
}
pub fn gt(&self, rhs: &Self) -> bool {
self.val > rhs.val
}
pub fn inverse(&self) -> Self {
self.pow(ORDER - 2) // at least it is faster an iterating...
}
// exponentiation by squaring
pub fn pow(&self, exp: u64) -> Self {
if exp == 0 {
return PrimeOrderDomain::new(1);
}
if exp == 1 {
return self.clone();
}
if exp % 2 == 0 {
(*self * *self).pow(exp / 2)
} else {
*self * self.pow(2).pow((exp - 1) / 2)
}
}
}
impl<const ORDER: u64> Add for PrimeOrderDomain<{ ORDER }> {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
PrimeOrderDomain {
val: ((self.val as u128 + rhs.val as u128) % ORDER as u128) as u64,
}
}
}
impl<const ORDER: u64> Sub for PrimeOrderDomain<{ ORDER }> {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
if rhs.val > self.val {
return PrimeOrderDomain {
val: ((ORDER - rhs.val) + self.val) % ORDER,
};
}
PrimeOrderDomain {
val: (self.val - rhs.val) % ORDER,
}
}
}
impl<const ORDER: u64> Mul for PrimeOrderDomain<{ ORDER }> {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
PrimeOrderDomain {
val: ((self.val as u128 * rhs.val as u128) % ORDER as u128) as u64,
}
}
}