From 1d871fb2d23f9cb56cb26d394e3f352538920c81 Mon Sep 17 00:00:00 2001 From: Masato Imai Date: Fri, 18 Feb 2022 09:44:14 +0900 Subject: [PATCH] add FiniteField --- .gitignore | 1 + .vscode/launch.json | 45 +++++++++++++++++++++++++++++++++++ Cargo.lock | 57 +++++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 9 +++++++ src/finite_field.rs | 40 +++++++++++++++++++++++++++++++ src/lib.rs | 1 + src/main.rs | 20 ++++++++++++++++ 7 files changed, 173 insertions(+) create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 Cargo.lock create mode 100644 Cargo.toml create mode 100644 src/finite_field.rs create mode 100644 src/lib.rs create mode 100644 src/main.rs diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..16be673 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,45 @@ +{ + // 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/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..8516dfa --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,57 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "autocfg" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" + +[[package]] +name = "bigdecimal" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6aaf33151a6429fe9211d1b276eafdf70cdff28b071e76c0b0e1503221ea3744" +dependencies = [ + "num-bigint", + "num-integer", + "num-traits", +] + +[[package]] +name = "encrypt" +version = "0.1.0" +dependencies = [ + "bigdecimal", +] + +[[package]] +name = "num-bigint" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f93ab6289c7b344a8a9f60f88d80aa20032336fe78da341afc91c8a2341fc75f" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-integer" +version = "0.1.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290" +dependencies = [ + "autocfg", +] diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..32330ea --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,9 @@ +[package] +name = "encrypt" +version = "0.1.0" +edition = "2021" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +bigdecimal = "0.3.0" \ No newline at end of file diff --git a/src/finite_field.rs b/src/finite_field.rs new file mode 100644 index 0000000..4ba84e8 --- /dev/null +++ b/src/finite_field.rs @@ -0,0 +1,40 @@ +use std::{ops::Add, fmt::{self, Display}}; + +use bigdecimal::{BigDecimal, Zero}; + +#[derive(Debug, Clone)] +pub struct FiniteFieldElement { + pub value: BigDecimal, + p: BigDecimal +} + +fn pmod(x: BigDecimal, y: BigDecimal) -> BigDecimal { + if x < BigDecimal::zero() { + (y.clone() - (-x % y.clone())) % y + } else { + x % y + } +} + +impl FiniteFieldElement { + pub fn new(value: BigDecimal, p: BigDecimal) -> Self { + Self { value: pmod(value, p.clone()), p } + } +} + +impl Display for FiniteFieldElement { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + write!(f, "{} mod {}", self.value, self.p) + } +} + +impl Add for FiniteFieldElement { + type Output = Self; + + fn add(self, rhs: Self) -> Self::Output { + if self.p != rhs.p { + panic!("p doesn't match: {} != {}", self.p, rhs.p); + } + Self::new(self.value + rhs.value, self.p) + } +} diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..31e2632 --- /dev/null +++ b/src/lib.rs @@ -0,0 +1 @@ +pub mod finite_field; \ No newline at end of file diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..4335ce3 --- /dev/null +++ b/src/main.rs @@ -0,0 +1,20 @@ +use bigdecimal::{BigDecimal, FromPrimitive}; +use encrypt::finite_field::FiniteFieldElement; + +macro_rules! b { + ( $x: expr ) => { + BigDecimal::from_i64($x).unwrap() + }; +} + +macro_rules! ffe { + ( $value: expr, $p: expr ) => { + FiniteFieldElement::new(b!($value), b!($p)) + }; +} + +fn main() { + let a = ffe!(4, 5); + let b = ffe!(3, 5); + println!("{}", a + b); +}