暗号化実装

This commit is contained in:
mii
2022-05-29 23:14:47 +09:00
parent 6d2dc6df2f
commit 790209c646
6 changed files with 181 additions and 43 deletions

72
Cargo.lock generated
View File

@ -67,6 +67,8 @@ version = "0.1.0"
dependencies = [
"bigdecimal",
"primitive-types",
"rand 0.7.3",
"rand_chacha 0.3.1",
]
[[package]]
@ -76,7 +78,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfcf0ed7fe52a17a03854ec54a9f76d6d84508d1c0e66bc1793301c73fc8493c"
dependencies = [
"byteorder",
"rand",
"rand 0.8.5",
"rustc-hex",
"static_assertions",
]
@ -87,6 +89,17 @@ version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c"
[[package]]
name = "getrandom"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8fc3cb4d91f53b50155bdcfd23f6a4c39ae1969c2ae85982b135750cccaf5fce"
dependencies = [
"cfg-if",
"libc",
"wasi 0.9.0+wasi-snapshot-preview1",
]
[[package]]
name = "getrandom"
version = "0.2.6"
@ -95,7 +108,7 @@ checksum = "9be70c98951c83b8d2f8f60d7065fa6d5146873094452a1008da8c2f1e4205ad"
dependencies = [
"cfg-if",
"libc",
"wasi",
"wasi 0.10.2+wasi-snapshot-preview1",
]
[[package]]
@ -237,6 +250,19 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09"
[[package]]
name = "rand"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
dependencies = [
"getrandom 0.1.16",
"libc",
"rand_chacha 0.2.2",
"rand_core 0.5.1",
"rand_hc",
]
[[package]]
name = "rand"
version = "0.8.5"
@ -244,8 +270,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.3",
]
[[package]]
name = "rand_chacha"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
dependencies = [
"ppv-lite86",
"rand_core 0.5.1",
]
[[package]]
@ -255,7 +291,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.3",
]
[[package]]
name = "rand_core"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "90bde5296fc891b0cef12a6d03ddccc162ce7b2aff54160af9338f8d40df6d19"
dependencies = [
"getrandom 0.1.16",
]
[[package]]
@ -264,7 +309,16 @@ version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
dependencies = [
"getrandom",
"getrandom 0.2.6",
]
[[package]]
name = "rand_hc"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
dependencies = [
"rand_core 0.5.1",
]
[[package]]
@ -349,6 +403,12 @@ version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d22af068fba1eb5edcb4aea19d382b2a3deb4c8f9d475c589b6ada9e0fd493ee"
[[package]]
name = "wasi"
version = "0.9.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519"
[[package]]
name = "wasi"
version = "0.10.2+wasi-snapshot-preview1"

View File

@ -7,4 +7,6 @@ edition = "2021"
[dependencies]
bigdecimal = "0.3.0"
primitive-types = "0.11.1"
primitive-types = "0.11.1"
rand = {version = "0.7.3"}
rand_chacha = "*"

View File

@ -1,9 +1,9 @@
use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div}, fmt::Debug};
use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div, Neg}, fmt::Debug};
use bigdecimal::{num_bigint::BigInt, Num};
use primitive_types::U512;
use super::math::mod_inv;
use super::math::{mod_inv, plus_mod};
#[derive(PartialEq, Debug, Copy, Clone)]
pub struct FiniteFieldElement {
@ -107,13 +107,22 @@ impl Div for FiniteFieldElement {
fn div(self, rhs: Self) -> Self::Output {
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();
let mod_inv = U512::from_str_radix(&format!("{}", mod_inv(left, right)), 10).unwrap();
self * FiniteFieldElement::new(mod_inv, rhs.p)
}
}
impl Neg for FiniteFieldElement {
type Output = Self;
fn neg(self) -> Self::Output {
let value = -BigInt::from_str_radix(&format!("{}", self.value), 10).unwrap();
let p = BigInt::from_str_radix(&format!("{}", self.p), 10).unwrap();
let plus_mod = plus_mod(value, p);
FiniteFieldElement::new(U512::from_str_radix(&format!("{}", plus_mod), 10).unwrap(), self.p)
}
}
#[cfg(test)]
mod tests {
use primitive_types::U512;

View File

@ -1,4 +1,4 @@
use std::ops::{Add, Mul};
use std::ops::{Add, Mul, Neg};
use primitive_types::U512;
@ -38,6 +38,18 @@ impl EllipticCurvePoint {
}
}
impl Neg for EllipticCurvePoint {
type Output = Self;
fn neg(self) -> Self::Output {
if let EllipticCurvePoint::Point { x, y, a, b } = self {
EllipticCurvePoint::Point { x, y: -y, a, b }
} else {
return self
}
}
}
impl Add for EllipticCurvePoint {
type Output = Self;
@ -46,8 +58,6 @@ impl Add for EllipticCurvePoint {
EllipticCurvePoint::Point { x: x1, y: y1, a, b } => {
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.");
@ -58,14 +68,11 @@ impl Add for EllipticCurvePoint {
}
let l = if x1 == x2 && y1 == y2 {
println!("twice");
let t = x1 * x1 * FiniteFieldElement::new(U512::from(3), p) + a;
let u = y1 * FiniteFieldElement::new(U512::from(2), p);
let a = t / u;
println!("t: {:?}\nu: {:?}\na: {:?}", t, u, a);
a
} else {
println!("plus");
(y2 - y1) / (x2 - x1)
};
let x = l * l - x1 - x2;
@ -85,13 +92,17 @@ impl Mul<U512> for EllipticCurvePoint {
type Output = Self;
fn mul(self, rhs: U512) -> Self::Output {
let mut tmp = self;
let mut point = EllipticCurvePoint::Infinity;
let mut n = rhs;
let mut r: EllipticCurvePoint = EllipticCurvePoint::Infinity;
while n > U512::from(0) {
r = r + self;
n = n - U512::from(1);
}
while n > U512::zero() {
if n & U512::one() == U512::one() {
point = point + tmp;
}
r
n = n >> 1;
tmp = tmp + tmp;
}
point
}
}

View File

@ -1,6 +1,9 @@
use primitive_types::U512;
use std::ops::Add;
use primitive_types::{U512, U256};
use crate::common::finite_field::FiniteFieldElement;
use rand_chacha::{ChaCha20Rng, rand_core::{SeedableRng, RngCore}};
use super::elliptic_curve::{EllipticCurve, EllipticCurvePoint};
@ -12,9 +15,25 @@ pub struct Encryption {
pub plain_mapping: Vec<EllipticCurvePoint>
}
#[derive(Debug)]
pub struct EncryptedEllipticCurvePoint {
pub data: EllipticCurvePoint,
pub rp: EllipticCurvePoint
}
impl Add for EncryptedEllipticCurvePoint {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
data: self.data + rhs.data,
rp: self.rp + rhs.rp
}
}
}
impl Encryption {
pub fn ec_point_to_plain(&self, point: EllipticCurvePoint) -> U512 {
println!("ec point to plain");
match point {
EllipticCurvePoint::Infinity => {
return U512::from(0u8)
@ -24,7 +43,6 @@ impl Encryption {
let mut x = 0i64;
println!("get plain mapping");
for p in &self.plain_mapping {
match p {
EllipticCurvePoint::Point { x: px, y: py, a: _, b: _ } => {
@ -51,7 +69,6 @@ impl Encryption {
self.plain_mapping[x as usize]
};
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,
@ -76,4 +93,36 @@ impl Encryption {
return self.base_point * m;
}
pub fn decrypt(ecc_p: EncryptedEllipticCurvePoint, private_key: U512) -> EllipticCurvePoint {
let rq = ecc_p.rp * private_key;
ecc_p.data + (-rq)
}
pub fn encrypt(&self, message: EllipticCurvePoint, public_key: EllipticCurvePoint, r: Option<U512>) -> EncryptedEllipticCurvePoint {
let ra = if let Some(ra) = r {
ra
} else {
Self::random()
};
EncryptedEllipticCurvePoint { data: message + public_key * ra, rp: self.base_point * ra }
}
pub fn get_public_key(&self, private_key: U512) -> EllipticCurvePoint {
self.base_point * private_key
}
pub fn get_private_key() -> U512 {
Self::random()
}
pub fn random() -> U512 {
let mut csprng = ChaCha20Rng::from_entropy();
let mut data = [0u8; 32];
csprng.fill_bytes(&mut data);
U512::from(U256::from(data))
}
}

View File

@ -19,7 +19,7 @@ fn main() {
let secp256_k1_b = FiniteFieldElement::new(U512::from(1u8), p);
let secp256_k1_base_x = FiniteFieldElement::new(U512::from_str_radix("0", 10).unwrap(), p);
let secp256_k1_base_y = FiniteFieldElement::new(U512::from_str_radix("1", 10).unwrap(), p);
let secp256_k1_order = FiniteFieldElement::new(U512::from_str_radix("2", 10).unwrap(), p);
let secp256_k1_order = FiniteFieldElement::nimage.pngew(U512::from_str_radix("2", 10).unwrap(), p);
*/
let ec = EllipticCurve {
a: secp256_k1_a,
@ -36,19 +36,26 @@ fn main() {
plain_mapping: vec![]
};
//let twenty = encryption.plain_to_ec_point(U512::from(12u8));
//let ten = encryption.plain_to_ec_point(U512::from(10u8));
//let two = encryption.plain_to_ec_point(U512::from(2u8));
//println!("{:?}", twenty);
//println!("{:?}", ten + two);
//println!("{:?}", encryption.ec_point_to_plain(ten));
let p = encryption.base_point + encryption.base_point;
println!("{:?}", p);
println!("{}", p.check());
println!("{}", encryption.base_point.check());
/*
let t = encryption.base_point + encryption.base_point;
println!("{:?}", t);
println!("{:?}", encryption.base_point);
let private_key = Encryption::get_private_key();
println!("private_key: {:?}", private_key);
let public_key = encryption.get_public_key(private_key);
println!("public_key: {:?}", public_key);
let ten = encryption.plain_to_ec_point(U512::from(13u32));
let e_ten = encryption.encrypt(ten, public_key, None);
let two = encryption.plain_to_ec_point(U512::from(27000u32));
let e_two = encryption.encrypt(two, public_key, None);
println!("{:?}", encryption.ec_point_to_plain(Encryption::decrypt(e_ten + e_two, private_key)));
/*
let twenty = encryption.plain_to_ec_point(U512::from(12u8));
let ten = encryption.plain_to_ec_point(U512::from(10u8));
let two = encryption.plain_to_ec_point(U512::from(2u8));
println!("{:?}", twenty);
println!("{:?}", encryption.ec_point_to_plain(twenty));
println!("{:?}", ten + two);
println!("{:?}", encryption.ec_point_to_plain(ten + two));
*/
}