From c0bc083589682a58e71f4941f9f821623c563d33 Mon Sep 17 00:00:00 2001 From: Masato Imai Date: Fri, 22 Jul 2022 13:40:20 +0900 Subject: [PATCH] add elliptic add support --- Cargo.lock | 10 +++ Cargo.toml | 2 +- client.gpsl | 4 +- src/common/finite_field.rs | 22 ++++-- src/elliptic_curve/elliptic_curve.rs | 5 +- src/elliptic_curve/encryption.rs | 106 +++++++++++++++++---------- src/gpsl/variable.rs | 7 ++ src/gpsl/vm/gpsl.rs | 19 ++++- src/main.rs | 2 + 9 files changed, 127 insertions(+), 50 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 77834f0..44050d6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -237,6 +237,15 @@ dependencies = [ "parity-scale-codec", ] +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + [[package]] name = "impl-trait-for-tuples" version = "0.2.2" @@ -367,6 +376,7 @@ checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a" dependencies = [ "fixed-hash", "impl-codec", + "impl-serde", "uint", ] diff --git a/Cargo.toml b/Cargo.toml index e8dbe06..720115f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -7,7 +7,7 @@ edition = "2021" [dependencies] bigdecimal = "0.3.0" -primitive-types = "0.11.1" +primitive-types = { version = "0.11.1", features = ["serde"] } rand = {version = "0.7.3"} rand_chacha = "*" clap = { version = "3.2.8", features = ["derive"] } diff --git a/client.gpsl b/client.gpsl index 77edaa7..9e1b4ac 100644 --- a/client.gpsl +++ b/client.gpsl @@ -1,10 +1,10 @@ -#[server(ip = "localhost:8080")] +#[server(ip = "172.25.5.104:8080")] fn add(a: num, b: num) { return a + b; } -#[server(ip = "localhost:8080")] +#[server(ip = "172.25.5.189:8080")] fn mul(a: num, b: num) { return a * b; } diff --git a/src/common/finite_field.rs b/src/common/finite_field.rs index c1d9f72..12513d8 100644 --- a/src/common/finite_field.rs +++ b/src/common/finite_field.rs @@ -1,14 +1,18 @@ -use std::{ops::{Add, Sub, Mul, AddAssign, SubAssign, Div, Neg}, fmt::{Debug, Display}}; +use std::{ + fmt::{Debug, Display}, + ops::{Add, AddAssign, Div, Mul, Neg, Sub, SubAssign}, +}; use bigdecimal::{num_bigint::BigInt, Num}; use primitive_types::U512; +use serde::{Deserialize, Serialize}; use super::math::{mod_inv, plus_mod}; -#[derive(PartialEq, Debug, Copy, Clone)] +#[derive(PartialEq, PartialOrd, Debug, Copy, Clone, Deserialize, Serialize)] pub struct FiniteFieldElement { pub value: U512, - pub p: U512 + pub p: U512, } impl FiniteFieldElement { @@ -19,7 +23,10 @@ impl FiniteFieldElement { pub fn inverse(&self) -> Self { let left = BigInt::from_str_radix(&format!("{}", self.value), 10).unwrap(); let right = BigInt::from_str_radix(&format!("{}", self.p), 10).unwrap(); - Self::new(U512::from_str_radix(&format!("{}", mod_inv(left, right)), 10).unwrap(), self.p) + Self::new( + U512::from_str_radix(&format!("{}", mod_inv(left, right)), 10).unwrap(), + self.p, + ) } } @@ -79,7 +86,7 @@ impl Sub for FiniteFieldElement { panic!("Cannot sub different field value."); } if self.value < rhs.value { - Self::new(self.p - rhs.value + self.value , self.p) + Self::new(self.p - rhs.value + self.value, self.p) } else { Self::new(self.value - rhs.value, self.p) } @@ -131,7 +138,10 @@ impl Neg for FiniteFieldElement { 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) + FiniteFieldElement::new( + U512::from_str_radix(&format!("{}", plus_mod), 10).unwrap(), + self.p, + ) } } diff --git a/src/elliptic_curve/elliptic_curve.rs b/src/elliptic_curve/elliptic_curve.rs index 9d64d97..6e39dc4 100644 --- a/src/elliptic_curve/elliptic_curve.rs +++ b/src/elliptic_curve/elliptic_curve.rs @@ -4,10 +4,11 @@ use std::{ }; use primitive_types::U512; +use serde::{Deserialize, Serialize}; use crate::common::finite_field::FiniteFieldElement; -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Deserialize, Serialize)] pub struct EllipticCurve { pub a: FiniteFieldElement, pub b: FiniteFieldElement, @@ -24,7 +25,7 @@ impl EllipticCurve { } } -#[derive(Debug, Clone, Copy, PartialEq)] +#[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Deserialize, Serialize)] pub enum EllipticCurvePoint { Point { x: FiniteFieldElement, diff --git a/src/elliptic_curve/encryption.rs b/src/elliptic_curve/encryption.rs index a475be4..551d322 100644 --- a/src/elliptic_curve/encryption.rs +++ b/src/elliptic_curve/encryption.rs @@ -1,9 +1,17 @@ -use std::{ops::{Add, Sub}, sync::mpsc, thread}; +use std::{ + ops::{Add, Sub}, + sync::mpsc, + thread, +}; -use primitive_types::{U512, U256}; +use primitive_types::{U256, U512}; +use serde::{Deserialize, Serialize}; use crate::common::finite_field::FiniteFieldElement; -use rand_chacha::{ChaCha20Rng, rand_core::{SeedableRng, RngCore}}; +use rand_chacha::{ + rand_core::{RngCore, SeedableRng}, + ChaCha20Rng, +}; use super::elliptic_curve::{EllipticCurve, EllipticCurvePoint}; @@ -12,13 +20,13 @@ pub struct Encryption { pub ellictic_curve: EllipticCurve, pub base_point: EllipticCurvePoint, pub order: FiniteFieldElement, - pub plain_mapping: Vec + pub plain_mapping: Vec, } -#[derive(Debug, Clone, Copy)] +#[derive(PartialEq, PartialOrd, Clone, Copy, Debug, Deserialize, Serialize)] pub struct EncryptedEllipticCurvePoint { pub data: EllipticCurvePoint, - pub rp: EllipticCurvePoint + pub rp: EllipticCurvePoint, } impl Add for EncryptedEllipticCurvePoint { @@ -27,7 +35,7 @@ impl Add for EncryptedEllipticCurvePoint { fn add(self, rhs: Self) -> Self::Output { Self { data: self.data + rhs.data, - rp: self.rp + rhs.rp + rp: self.rp + rhs.rp, } } } @@ -37,8 +45,8 @@ impl Sub for EncryptedEllipticCurvePoint { fn sub(self, rhs: Self) -> Self::Output { Self { - data: self.data + (-rhs.data), - rp: self.rp + (-rhs.rp) + data: self.data + (-rhs.data), + rp: self.rp + (-rhs.rp), } } } @@ -46,9 +54,7 @@ impl Sub for EncryptedEllipticCurvePoint { impl Encryption { pub fn ec_point_to_plain(&self, point: EllipticCurvePoint) -> U512 { match point { - EllipticCurvePoint::Infinity => { - return U512::from(0u8) - } + EllipticCurvePoint::Infinity => return U512::from(0u8), _ => {} } @@ -56,15 +62,23 @@ impl Encryption { for p in &self.plain_mapping { match p { - EllipticCurvePoint::Point { x: px, y: py, a: _, b: _ } => { - match point { - EllipticCurvePoint::Point { x: ppx, y, a: _, b: _ } => { - if *px == ppx && *py == y { - return U512::from(x) + U512::from(1u8); - } - }, - _ => {} + EllipticCurvePoint::Point { + x: px, + y: py, + a: _, + b: _, + } => match point { + EllipticCurvePoint::Point { + x: ppx, + y, + a: _, + b: _, + } => { + if *px == ppx && *py == y { + return U512::from(x) + U512::from(1u8); + } } + _ => {} }, _ => {} } @@ -80,16 +94,28 @@ impl Encryption { self.plain_mapping[x as usize] }; - 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, - _ => false - }, - EllipticCurvePoint::Infinity => match point { - EllipticCurvePoint::Infinity => true, - _ => false - }, - }) { + 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, + _ => false, + }, + EllipticCurvePoint::Infinity => match point { + EllipticCurvePoint::Infinity => true, + _ => false, + }, + }) + { x += 1; tmp = tmp + self.base_point; } @@ -99,7 +125,7 @@ impl Encryption { pub fn plain_to_ec_point(&self, m: U512) -> EllipticCurvePoint { if m == U512::from(0u8) { - return EllipticCurvePoint::Infinity + return EllipticCurvePoint::Infinity; } return self.base_point * m; @@ -110,12 +136,13 @@ impl Encryption { ecc_p.data + (-rq) } - pub fn encrypt(&self, message: EllipticCurvePoint, public_key: EllipticCurvePoint, r: Option) -> EncryptedEllipticCurvePoint { - let ra = if let Some(ra) = r { - ra - } else { - Self::random() - }; + pub fn encrypt( + &self, + message: EllipticCurvePoint, + public_key: EllipticCurvePoint, + r: Option, + ) -> EncryptedEllipticCurvePoint { + let ra = if let Some(ra) = r { ra } else { Self::random() }; let (data_tx, data_rx) = mpsc::channel(); let (rp_tx, rp_rx) = mpsc::channel(); @@ -134,7 +161,10 @@ impl Encryption { let data_received = data_rx.recv().unwrap(); let rp_received = rp_rx.recv().unwrap(); - EncryptedEllipticCurvePoint { data: data_received, rp: rp_received } + EncryptedEllipticCurvePoint { + data: data_received, + rp: rp_received, + } } pub fn get_public_key(&self, private_key: U512) -> EllipticCurvePoint { diff --git a/src/gpsl/variable.rs b/src/gpsl/variable.rs index 7a3add6..24af70f 100644 --- a/src/gpsl/variable.rs +++ b/src/gpsl/variable.rs @@ -1,8 +1,15 @@ +use crate::{ + common::finite_field::FiniteFieldElement, + elliptic_curve::encryption::EncryptedEllipticCurvePoint, +}; use serde::{Deserialize, Serialize}; + #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] pub enum Variable { Number { value: i64 }, Text { value: String }, Return { value: Box }, + PureEncrypted { value: EncryptedEllipticCurvePoint }, + PairedEncrypted { value: FiniteFieldElement }, None {}, } diff --git a/src/gpsl/vm/gpsl.rs b/src/gpsl/vm/gpsl.rs index e88f3e5..8672cb5 100644 --- a/src/gpsl/vm/gpsl.rs +++ b/src/gpsl/vm/gpsl.rs @@ -1,3 +1,5 @@ +use crate::elliptic_curve::encryption::EncryptedEllipticCurvePoint; +use crate::elliptic_curve::encryption::EncryptedEllipticCurvePoint; use crate::gpsl::external_function::{ExternalFuncReturn, ExternalFuncStatus}; use crate::gpsl::node::*; use crate::gpsl::permission::Permission; @@ -113,6 +115,13 @@ impl GPSL { } } + pub fn extract_eep(node: Variable) -> Result { + match node { + Variable::PureEncrypted { value } => Ok(value), + _ => Err(String::from("Not an encrypted point")), + } + } + pub fn evaluate(&mut self, node: Box) -> Result, String> { match *node { Node::Call { name, args } => { @@ -267,7 +276,15 @@ impl GPSL { Ok(rhs) => Ok(Some(Variable::Number { value: lhs + rhs })), Err(err) => Err(err), }, - Err(err) => Err(err), + Err(err) => match GPSL::extract_eep(lhs) { + Ok(lhs) => match GPSL::extract_eep(rhs) { + Ok(rhs) => { + Ok(Some(Variable::PureEncrypted { value: lhs + rhs })) + } + Err(err) => Err(err), + }, + Err(err) => Err(err), + }, }, NodeKind::DIV => match GPSL::extract_number(lhs) { Ok(lhs) => match GPSL::extract_number(rhs) { diff --git a/src/main.rs b/src/main.rs index ea2f9d8..5d1398c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,5 @@ +mod common; +mod elliptic_curve; mod gpsl; use gpsl::external_function::ExternalFuncReturn; use gpsl::external_function::ExternalFuncStatus;