This commit is contained in:
Masato Imai
2022-04-21 12:19:03 +09:00
parent b7c37c595b
commit 22c8a8b514
4 changed files with 85 additions and 9 deletions

View File

@ -2,6 +2,8 @@ use std::{ops::{Add, Sub, Mul, Div, Neg}, fmt::{self, Display}};
use bigdecimal::{BigDecimal, Zero};
use super::math::{self, modInv, plusMod};
#[macro_export]
macro_rules! b {
( $x: expr ) => {
@ -41,6 +43,19 @@ impl FiniteFieldElement {
pub fn new(value: BigDecimal, p: BigDecimal) -> Self {
Self { value: pmod(value, p.clone()), p }
}
pub fn floor_div(self, rhs: FiniteFieldElement) -> Self {
self * FiniteFieldElement { value: modInv(rhs.value, self.p.clone()), p: self.p }
}
pub fn rem(self, rhs: FiniteFieldElement) -> FiniteFieldElement {
FiniteFieldElement { value: plusMod(self.value, rhs.value), p: self.p }
}
pub fn pow(self, rhs: FiniteFieldElement) -> FiniteFieldElement {
FiniteFieldElement { value: plusMod(self.value.), p: () }
}
}
impl Display for FiniteFieldElement {
@ -80,14 +95,6 @@ impl Mul for FiniteFieldElement {
}
}
impl Div for FiniteFieldElement {
type Output = Self;
fn div(self, rhs: Self) -> Self::Output {
Self::new(self.value / rhs.value, self.p)
}
}
impl Neg for FiniteFieldElement {
type Output = Self;

60
src/common/math.rs Normal file
View File

@ -0,0 +1,60 @@
use std::ops::Div;
use bigdecimal::{BigDecimal, FromPrimitive, Zero, One};
fn extGCD(a: BigDecimal, b: BigDecimal) -> (BigDecimal, BigDecimal, BigDecimal) {
let mut a = a;
let mut b = b;
let mut x0 = BigDecimal::from_i32(1).unwrap();
let mut y0 = BigDecimal::from_i32(0).unwrap();
let mut x1 = BigDecimal::from_i32(0).unwrap();
let mut y1 = BigDecimal::from_i32(1).unwrap();
while b != BigDecimal::zero() {
let q = down(a.clone() / b.clone());
let at = a.clone();
a = plusMod(at, b.clone());
let x0t = x0.clone();
x0 = x1.clone();
x1 = x0t - q.clone() * x1.clone();
let y0t = y0.clone();
y0 = y1.clone();
y1 = y0t - q.clone() * y1;
}
return (a, x0, y0);
}
pub fn plusMod(a: BigDecimal, b: BigDecimal) -> BigDecimal {
a.clone() - floor(a / b.clone()) * b
}
pub fn modInv(a: BigDecimal, m: BigDecimal) -> BigDecimal {
let r = extGCD(a, m);
if r.0 != BigDecimal::one() {
panic!("Moduler inverse does not exist.");
} else {
return plusMod(r.1, m);
}
}
pub fn down(a: BigDecimal) -> BigDecimal {
return a.clone() - a % BigDecimal::one();
}
pub fn floor(a: BigDecimal) -> BigDecimal {
let m = a.clone() % BigDecimal::one();
if a > BigDecimal::zero() {
return a.clone() - m;
}
if m < BigDecimal::zero() {
return a - m - BigDecimal::one();
}
return a;
}

View File

@ -1 +1,2 @@
pub mod finite_field;
pub mod math;

View File

@ -17,4 +17,12 @@ fn main() {
};
println!("{:?}", ec.add(ecp1.clone(), ecp1));
for x in 1..101 {
for y in 1..101 {
println!("{}, {}: {}", x, y, encrypt::common::math::plusMod(BigDecimal::from_i32(x).unwrap(), BigDecimal::from_i32(y).unwrap()));
}
}
println!("{}", encrypt::common::math::plusMod(BigDecimal::from_i32(100).unwrap(), BigDecimal::from_i32(50).unwrap()));
}