From 22c8a8b514d242bd647ace70522fc983e00e5840 Mon Sep 17 00:00:00 2001 From: Masato Imai Date: Thu, 21 Apr 2022 12:19:03 +0900 Subject: [PATCH] =?UTF-8?q?=E9=80=94=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/common/finite_field.rs | 23 ++++++++++----- src/common/math.rs | 60 ++++++++++++++++++++++++++++++++++++++ src/common/mod.rs | 3 +- src/main.rs | 8 +++++ 4 files changed, 85 insertions(+), 9 deletions(-) create mode 100644 src/common/math.rs diff --git a/src/common/finite_field.rs b/src/common/finite_field.rs index 6fc57fd..640563f 100644 --- a/src/common/finite_field.rs +++ b/src/common/finite_field.rs @@ -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; diff --git a/src/common/math.rs b/src/common/math.rs new file mode 100644 index 0000000..e17b16b --- /dev/null +++ b/src/common/math.rs @@ -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; +} \ No newline at end of file diff --git a/src/common/mod.rs b/src/common/mod.rs index 31e2632..d960ed3 100644 --- a/src/common/mod.rs +++ b/src/common/mod.rs @@ -1 +1,2 @@ -pub mod finite_field; \ No newline at end of file +pub mod finite_field; +pub mod math; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 71679ea..24c0e50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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())); }