This commit is contained in:
mii8080
2022-05-27 08:01:34 +00:00
committed by GitHub
parent 58a6e27743
commit e1c0dca87d
2 changed files with 65 additions and 89 deletions

View File

@ -1,48 +1,40 @@
use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div, Rem}, fmt::Debug};
use primitive_types::U512;
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct FiniteFieldElement<T>
where
T: PartialEq + Copy
{
pub value: T,
pub p: T,
pub one: T
pub struct FiniteFieldElement {
pub value: U512,
pub p: U512
}
impl<T> FiniteFieldElement<T>
where
T: PartialEq + Copy
{
pub fn new(value: T, p: T, one: T) -> Self {
Self { value, p, one }
impl FiniteFieldElement {
pub fn new(value: U512, p: U512) -> Self {
Self { value, p }
}
}
impl<T> FiniteFieldElement<T>
where
T: Rem<Output = T> + Add<Output = T> + Sub<Output = T> + Div<Output = T> + PartialEq + PartialOrd + Copy + Debug
{
fn pow(self, e: T) -> Self {
let one = self.one;
let two = one + one;
let mut r = Self::new(one, self.p, self.one);
let mut i = e;
let zero = self.value - self.value;
while i > zero {
if i % two != zero {
r = r * self;
impl FiniteFieldElement {
fn pow(self, e: U512) -> Self {
let k = e.bits();
let mut a1 = self.value;
let mut a2 = self.value * self.value;
let mut i = (k - 2) as i64;
while i >= 0 {
if e.bit(i as usize) {
a1 = (a1 * a2) % self.p;
} else {
a2 = (a1 * a2) % self.p;
a1 = (a1 * a1) % self.p;
}
i = i / two;
i -= 1;
}
r * self
Self::new(a1, self.p)
}
}
impl<T> Add for FiniteFieldElement<T>
where
T: Add<Output = T> + Sub<Output = T> + PartialEq + PartialOrd + Copy
{
impl Add for FiniteFieldElement {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
@ -51,26 +43,20 @@ where
}
let sum = self.value + rhs.value;
if sum >= self.p {
Self::new(sum - self.p, self.p, self.one)
Self::new(sum - self.p, self.p)
} else {
Self::new(sum, self.p, self.one)
Self::new(sum, self.p)
}
}
}
impl<T> AddAssign for FiniteFieldElement<T>
where
T: Add<Output = T> + Sub<Output = T> + PartialEq + PartialOrd + Copy
{
impl AddAssign for FiniteFieldElement {
fn add_assign(&mut self, rhs: Self) {
*self = (*self) + rhs
}
}
impl<T> Sub for FiniteFieldElement<T>
where
T: Add<Output = T> + Sub<Output = T> + PartialEq + PartialOrd + Copy
{
impl Sub for FiniteFieldElement {
type Output = Self;
fn sub(self, rhs: Self) -> Self::Output {
@ -78,58 +64,47 @@ where
panic!("Cannot sub different field value.");
}
if self.value < rhs.value {
Self::new(self.p - rhs.value + self.value , self.p, self.one)
Self::new(self.p - rhs.value + self.value , self.p)
} else {
Self::new(self.value - rhs.value, self.p, self.one)
Self::new(self.value - rhs.value, self.p)
}
}
}
impl<T> SubAssign for FiniteFieldElement<T>
where
T: Add<Output = T> + Sub<Output = T> + PartialEq + PartialOrd + Copy
{
impl SubAssign for FiniteFieldElement {
fn sub_assign(&mut self, rhs: Self) {
*self = (*self) - rhs
}
}
impl<T> Mul for FiniteFieldElement<T>
where
T: Add<Output = T> + Sub<Output = T> + Div<Output = T> + Rem<Output = T> + PartialEq + PartialOrd + Copy + Debug
{
impl Mul for FiniteFieldElement {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
if self.p != rhs.p {
panic!("Cannot mul different field value.");
}
let one = self.one;
let two = one + one;
let zero = self.value - self.value;
let mut tmp = self;
let mut i = rhs.value;
let mut r = Self::new(zero, self.p, self.one);
while i > zero {
if i % two != zero {
let mut r = Self::new(U512::from(0), self.p);
while i > U512::from(0) {
if i & U512::from(1) == U512::from(1) {
r += tmp;
}
i = i / two;
i = i >> 1;
tmp = tmp + tmp;
}
r
}
}
impl<T> Div for FiniteFieldElement<T>
where
T: Add<Output = T> + Sub<Output = T> + Rem<Output = T> + Div<Output = T> + PartialEq + PartialOrd + Copy + Debug
{
impl Div for FiniteFieldElement {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
let one = self.one;
self * rhs.pow(self.p - one - one)
let rhs = rhs.pow(self.p - U512::from(2));
println!("{:?} * {:?}", self, rhs);
self * rhs
}
}
@ -141,40 +116,42 @@ mod tests {
#[test]
fn add() {
let a = FiniteFieldElement::new(U512::from(2), U512::from(7), U512::from(1));
let b = FiniteFieldElement::new(U512::from(1), U512::from(7), U512::from(1));
let c = FiniteFieldElement::new(U512::from(3), U512::from(7), U512::from(1));
let a = FiniteFieldElement::new(U512::from(2u8), U512::from(7u8));
let b = FiniteFieldElement::new(U512::from(1u8), U512::from(7u8));
let c = FiniteFieldElement::new(U512::from(3u8), U512::from(7u8));
assert_eq!(a + b, c);
}
#[test]
fn sub() {
let a = FiniteFieldElement::new(U512::from(6), U512::from(7), U512::from(1));
let b = FiniteFieldElement::new(U512::from(4), U512::from(7), U512::from(1));
let c = FiniteFieldElement::new(U512::from(2), U512::from(7), U512::from(1));
let a = FiniteFieldElement::new(U512::from(6u8), U512::from(7u8));
let b = FiniteFieldElement::new(U512::from(4u8), U512::from(7u8));
let c = FiniteFieldElement::new(U512::from(2u8), U512::from(7u8));
assert_eq!(a - b, c);
}
#[test]
fn mul() {
let a = FiniteFieldElement::new(U512::from(3), U512::from(13), U512::from(1));
let b = FiniteFieldElement::new(U512::from(12), U512::from(13), U512::from(1));
let c = FiniteFieldElement::new(U512::from(10), U512::from(13), U512::from(1));
let a = FiniteFieldElement::new(U512::from(3u8), U512::from(13u8));
let b = FiniteFieldElement::new(U512::from(12u8), U512::from(13u8));
let c = FiniteFieldElement::new(U512::from(10u8), U512::from(13u8));
assert_eq!(a * b, c);
}
#[test]
fn pow() {
let a = FiniteFieldElement::new(U512::from(3), U512::from(13), U512::from(1));
let b = FiniteFieldElement::new(U512::from(1), U512::from(13), U512::from(1));
let a = FiniteFieldElement::new(U512::from(3u8), U512::from(13u8));
let b = FiniteFieldElement::new(U512::from(1u8), U512::from(13u8));
assert_eq!(a.pow(U512::from(3)), b);
println!("{:?}", FiniteFieldElement::new(U512::from(5u8), U512::from(19u8)).pow(U512::from(17)));
}
#[test]
fn div() {
let a = FiniteFieldElement::new(U512::from(7), U512::from(19), U512::from(1));
let b = FiniteFieldElement::new(U512::from(5), U512::from(19), U512::from(1));
let c = FiniteFieldElement::new(U512::from(9), U512::from(19), U512::from(1));
let a = FiniteFieldElement::new(U512::from(7u8), U512::from(19u8));
let b = FiniteFieldElement::new(U512::from(5u8), U512::from(19u8));
let c = FiniteFieldElement::new(U512::from(9u8), U512::from(19u8));
assert_eq!(a / b, c);
}
}
}

View File

@ -3,7 +3,7 @@ use primitive_types::U512;
// 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141
fn main() {
println!("Encryption Library");
/*
let p = U512::from_str_radix("115792089237316195423570985008687907853269984665640564039457584007908834671663", 10).unwrap();
let secp256_k1_a = FiniteFieldElement::new(U512::from(0u8), p);
@ -12,16 +12,15 @@ fn main() {
let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("32670510020758816978083085130507043184471273380659243275938904335757337482424", 10).unwrap(), p);
let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("115792089237316195423570985008687907852837564279074904382605163141518161494337", 10).unwrap(), p);
*/
/*
let p = U512::from_str_radix("5", 10).unwrap();
let one = U512::from(1u8);
let secp256_k1_a = FiniteFieldElement::new(U512::from(1u8), p, one);
let secp256_k1_b = FiniteFieldElement::new(U512::from(1u8), p, one);
let secp256_k1_base_x = FiniteFieldElement::new(U512::from_str_radix("0", 10).unwrap(), p, one);
let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("1", 10).unwrap(), p, one);
let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("2", 10).unwrap(), p, one);
let secp256_k1_a = FiniteFieldElement::new(U512::from(1u8), p);
let secp256_k1_b = FiniteFieldElement::new(U512::from(1u8), p);
let secp256_k1_base_x = FiniteFieldElement::new(U512::from_str_radix("0", 10).unwrap(), p);
let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("1", 10).unwrap(), p);
let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("2", 10).unwrap(), p);
*/
let ec = EllipticCurve {
a: secp256_k1_a,
b: secp256_k1_b