有限体実装終わり

This commit is contained in:
mii
2022-05-29 15:10:27 +09:00
parent 03237952a7
commit 6d2dc6df2f
7 changed files with 58 additions and 60 deletions

45
.vscode/launch.json vendored
View File

@ -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}"
}
]
}

View File

@ -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)
}
}

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

@ -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)
}

View File

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

View File

@ -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.");

View File

@ -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 {

View File

@ -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() {