From 6d2dc6df2fed2addee40a93edce3c7b47d28d5b0 Mon Sep 17 00:00:00 2001 From: mii Date: Sun, 29 May 2022 15:10:27 +0900 Subject: [PATCH] =?UTF-8?q?=E6=9C=89=E9=99=90=E4=BD=93=E5=AE=9F=E8=A3=85?= =?UTF-8?q?=E7=B5=82=E3=82=8F=E3=82=8A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .vscode/launch.json | 45 ---------------------------- src/common/finite_field.rs | 17 +++++++---- src/common/math.rs | 37 +++++++++++++++++++++++ src/common/mod.rs | 3 +- src/elliptic_curve/elliptic_curve.rs | 4 +-- src/elliptic_curve/encryption.rs | 10 +++---- src/main.rs | 2 +- 7 files changed, 58 insertions(+), 60 deletions(-) delete mode 100644 .vscode/launch.json create mode 100644 src/common/math.rs diff --git a/.vscode/launch.json b/.vscode/launch.json deleted file mode 100644 index 16be673..0000000 --- a/.vscode/launch.json +++ /dev/null @@ -1,45 +0,0 @@ -{ - // IntelliSense を使用して利用可能な属性を学べます。 - // 既存の属性の説明をホバーして表示します。 - // 詳細情報は次を確認してください: https://go.microsoft.com/fwlink/?linkid=830387 - "version": "0.2.0", - "configurations": [ - { - "type": "lldb", - "request": "launch", - "name": "Debug executable 'encrypt'", - "cargo": { - "args": [ - "build", - "--bin=encrypt", - "--package=encrypt" - ], - "filter": { - "name": "encrypt", - "kind": "bin" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - }, - { - "type": "lldb", - "request": "launch", - "name": "Debug unit tests in executable 'encrypt'", - "cargo": { - "args": [ - "test", - "--no-run", - "--bin=encrypt", - "--package=encrypt" - ], - "filter": { - "name": "encrypt", - "kind": "bin" - } - }, - "args": [], - "cwd": "${workspaceFolder}" - } - ] -} \ No newline at end of file diff --git a/src/common/finite_field.rs b/src/common/finite_field.rs index af1b386..4e70ec4 100644 --- a/src/common/finite_field.rs +++ b/src/common/finite_field.rs @@ -1,11 +1,14 @@ -use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div, Rem}, fmt::Debug}; +use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div}, fmt::Debug}; +use bigdecimal::{num_bigint::BigInt, Num}; use primitive_types::U512; +use super::math::mod_inv; + #[derive(PartialEq, Debug, Copy, Clone)] pub struct FiniteFieldElement { pub value: U512, - pub p: U512 + pub p: U512 } impl FiniteFieldElement { @@ -15,7 +18,7 @@ impl FiniteFieldElement { } impl FiniteFieldElement { - fn pow(self, e: U512) -> Self { + pub fn pow(self, e: U512) -> Self { let k = e.bits(); let mut a1 = self; let mut a2 = self * self; @@ -102,8 +105,12 @@ impl Div for FiniteFieldElement { type Output = Self; fn div(self, rhs: Self) -> Self::Output { - let rhs = rhs.pow(self.p - U512::from(2)); - self * rhs + let left = BigInt::from_str_radix(&format!("{}", rhs.value), 10).unwrap(); + let right = BigInt::from_str_radix(&format!("{}", rhs.p), 10).unwrap(); + let mod_inv = mod_inv(left, right); + println!("mod_inv: {:?}", mod_inv); + let mod_inv = U512::from_str_radix(&format!("{}", mod_inv), 10).unwrap(); + self * FiniteFieldElement::new(mod_inv, rhs.p) } } diff --git a/src/common/math.rs b/src/common/math.rs new file mode 100644 index 0000000..74553a0 --- /dev/null +++ b/src/common/math.rs @@ -0,0 +1,37 @@ +use bigdecimal::{num_bigint::BigInt, Zero, One}; + +pub fn plus_mod(a: BigInt, m: BigInt) -> BigInt { + (a.clone() % m.clone() + m.clone()) % m +} + +pub fn mod_inv(a: BigInt, m: BigInt) -> BigInt { + let mut a = a; + if a < BigInt::zero() { + a = a.modpow(&BigInt::one(), &m); + } + + let mut x = BigInt::zero(); + let mut y = BigInt::one(); + let mut gcd = m.clone(); + let mut px = BigInt::one(); + let mut py = BigInt::zero(); + let mut pgcd = a; + + while gcd.clone() > BigInt::zero() { + let q = pgcd.clone() / gcd.clone(); + + let tmp = x.clone(); + x = px.clone() - q.clone() * tmp.clone(); + px = tmp.clone(); + + let tmp = y.clone(); + y = py.clone() - q.clone() * tmp.clone(); + py = tmp.clone(); + + let tmp = gcd.clone(); + gcd = pgcd.clone() - q.clone() * tmp.clone(); + pgcd = tmp.clone(); + } + + plus_mod(px, m) +} 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/elliptic_curve/elliptic_curve.rs b/src/elliptic_curve/elliptic_curve.rs index adc1f3f..76afad6 100644 --- a/src/elliptic_curve/elliptic_curve.rs +++ b/src/elliptic_curve/elliptic_curve.rs @@ -1,4 +1,4 @@ -use std::ops::{Div, Add, Sub, Mul}; +use std::ops::{Add, Mul}; use primitive_types::U512; @@ -47,7 +47,7 @@ impl Add for EllipticCurvePoint { match rhs { EllipticCurvePoint::Point { x: x2, y: y2, a: a2, b: b2 } => { println!("default plus"); - + let p = x1.p; if a != a2 || b != b2 { panic!("Cannot add different curve point."); diff --git a/src/elliptic_curve/encryption.rs b/src/elliptic_curve/encryption.rs index 086ff48..57fc5ee 100644 --- a/src/elliptic_curve/encryption.rs +++ b/src/elliptic_curve/encryption.rs @@ -1,5 +1,3 @@ -use std::ops::{Mul, Add, Sub, Div}; - use primitive_types::U512; use crate::common::finite_field::FiniteFieldElement; @@ -29,9 +27,9 @@ impl Encryption { println!("get plain mapping"); for p in &self.plain_mapping { match p { - EllipticCurvePoint::Point { x: px, y: py, a, b } => { + EllipticCurvePoint::Point { x: px, y: py, a: _, b: _ } => { match point { - EllipticCurvePoint::Point { x: ppx, y, a, b } => { + EllipticCurvePoint::Point { x: ppx, y, a: _, b: _ } => { if *px == ppx && *py == y { return U512::from(x) + U512::from(1u8); } @@ -55,8 +53,8 @@ impl Encryption { println!("calc mapping"); while x < i64::MAX && !(match tmp { - EllipticCurvePoint::Point { x: tx, y: ty, a, b } => match point { - EllipticCurvePoint::Point { x: px, y: py, a, b } => tx == px && ty == py, + EllipticCurvePoint::Point { x: tx, y: ty, a: _, b: _ } => match point { + EllipticCurvePoint::Point { x: px, y: py, a: _, b: _ } => tx == px && ty == py, _ => false }, EllipticCurvePoint::Infinity => match point { diff --git a/src/main.rs b/src/main.rs index 643048c..114691e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -use encrypt::{elliptic_curve::{elliptic_curve::{EllipticCurve, EllipticCurvePoint}, encryption::Encryption}, common::finite_field::FiniteFieldElement}; +use encrypt::{elliptic_curve::{elliptic_curve::EllipticCurve, encryption::Encryption}, common::finite_field::FiniteFieldElement}; use primitive_types::U512; fn main() {