add elliptic add support

This commit is contained in:
Masato Imai
2022-07-22 13:40:20 +09:00
parent 9eb9176a60
commit c0bc083589
9 changed files with 127 additions and 50 deletions

10
Cargo.lock generated
View File

@ -237,6 +237,15 @@ dependencies = [
"parity-scale-codec", "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]] [[package]]
name = "impl-trait-for-tuples" name = "impl-trait-for-tuples"
version = "0.2.2" version = "0.2.2"
@ -367,6 +376,7 @@ checksum = "e28720988bff275df1f51b171e1b2a18c30d194c4d2b61defdacecd625a5d94a"
dependencies = [ dependencies = [
"fixed-hash", "fixed-hash",
"impl-codec", "impl-codec",
"impl-serde",
"uint", "uint",
] ]

View File

@ -7,7 +7,7 @@ edition = "2021"
[dependencies] [dependencies]
bigdecimal = "0.3.0" bigdecimal = "0.3.0"
primitive-types = "0.11.1" primitive-types = { version = "0.11.1", features = ["serde"] }
rand = {version = "0.7.3"} rand = {version = "0.7.3"}
rand_chacha = "*" rand_chacha = "*"
clap = { version = "3.2.8", features = ["derive"] } clap = { version = "3.2.8", features = ["derive"] }

View File

@ -1,10 +1,10 @@
#[server(ip = "localhost:8080")] #[server(ip = "172.25.5.104:8080")]
fn add(a: num, b: num) { fn add(a: num, b: num) {
return a + b; return a + b;
} }
#[server(ip = "localhost:8080")] #[server(ip = "172.25.5.189:8080")]
fn mul(a: num, b: num) { fn mul(a: num, b: num) {
return a * b; return a * b;
} }

View File

@ -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 bigdecimal::{num_bigint::BigInt, Num};
use primitive_types::U512; use primitive_types::U512;
use serde::{Deserialize, Serialize};
use super::math::{mod_inv, plus_mod}; use super::math::{mod_inv, plus_mod};
#[derive(PartialEq, Debug, Copy, Clone)] #[derive(PartialEq, PartialOrd, Debug, Copy, Clone, Deserialize, Serialize)]
pub struct FiniteFieldElement { pub struct FiniteFieldElement {
pub value: U512, pub value: U512,
pub p: U512 pub p: U512,
} }
impl FiniteFieldElement { impl FiniteFieldElement {
@ -19,7 +23,10 @@ impl FiniteFieldElement {
pub fn inverse(&self) -> Self { pub fn inverse(&self) -> Self {
let left = BigInt::from_str_radix(&format!("{}", self.value), 10).unwrap(); let left = BigInt::from_str_radix(&format!("{}", self.value), 10).unwrap();
let right = BigInt::from_str_radix(&format!("{}", self.p), 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."); panic!("Cannot sub different field value.");
} }
if self.value < rhs.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 { } else {
Self::new(self.value - rhs.value, self.p) 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 value = -BigInt::from_str_radix(&format!("{}", self.value), 10).unwrap();
let p = BigInt::from_str_radix(&format!("{}", self.p), 10).unwrap(); let p = BigInt::from_str_radix(&format!("{}", self.p), 10).unwrap();
let plus_mod = plus_mod(value, p); 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,
)
} }
} }

View File

@ -4,10 +4,11 @@ use std::{
}; };
use primitive_types::U512; use primitive_types::U512;
use serde::{Deserialize, Serialize};
use crate::common::finite_field::FiniteFieldElement; use crate::common::finite_field::FiniteFieldElement;
#[derive(Debug, Clone, Copy, PartialEq)] #[derive(Debug, Clone, Copy, PartialEq, PartialOrd, Deserialize, Serialize)]
pub struct EllipticCurve { pub struct EllipticCurve {
pub a: FiniteFieldElement, pub a: FiniteFieldElement,
pub b: 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 { pub enum EllipticCurvePoint {
Point { Point {
x: FiniteFieldElement, x: FiniteFieldElement,

View File

@ -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 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}; use super::elliptic_curve::{EllipticCurve, EllipticCurvePoint};
@ -12,13 +20,13 @@ pub struct Encryption {
pub ellictic_curve: EllipticCurve, pub ellictic_curve: EllipticCurve,
pub base_point: EllipticCurvePoint, pub base_point: EllipticCurvePoint,
pub order: FiniteFieldElement, pub order: FiniteFieldElement,
pub plain_mapping: Vec<EllipticCurvePoint> pub plain_mapping: Vec<EllipticCurvePoint>,
} }
#[derive(Debug, Clone, Copy)] #[derive(PartialEq, PartialOrd, Clone, Copy, Debug, Deserialize, Serialize)]
pub struct EncryptedEllipticCurvePoint { pub struct EncryptedEllipticCurvePoint {
pub data: EllipticCurvePoint, pub data: EllipticCurvePoint,
pub rp: EllipticCurvePoint pub rp: EllipticCurvePoint,
} }
impl Add for EncryptedEllipticCurvePoint { impl Add for EncryptedEllipticCurvePoint {
@ -27,7 +35,7 @@ impl Add for EncryptedEllipticCurvePoint {
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
Self { Self {
data: self.data + rhs.data, data: self.data + rhs.data,
rp: self.rp + rhs.rp rp: self.rp + rhs.rp,
} }
} }
} }
@ -38,7 +46,7 @@ impl Sub for EncryptedEllipticCurvePoint {
fn sub(self, rhs: Self) -> Self::Output { fn sub(self, rhs: Self) -> Self::Output {
Self { Self {
data: self.data + (-rhs.data), data: self.data + (-rhs.data),
rp: self.rp + (-rhs.rp) rp: self.rp + (-rhs.rp),
} }
} }
} }
@ -46,9 +54,7 @@ impl Sub for EncryptedEllipticCurvePoint {
impl Encryption { impl Encryption {
pub fn ec_point_to_plain(&self, point: EllipticCurvePoint) -> U512 { pub fn ec_point_to_plain(&self, point: EllipticCurvePoint) -> U512 {
match point { match point {
EllipticCurvePoint::Infinity => { EllipticCurvePoint::Infinity => return U512::from(0u8),
return U512::from(0u8)
}
_ => {} _ => {}
} }
@ -56,15 +62,23 @@ impl Encryption {
for p in &self.plain_mapping { for p in &self.plain_mapping {
match p { match p {
EllipticCurvePoint::Point { x: px, y: py, a: _, b: _ } => { EllipticCurvePoint::Point {
match point { x: px,
EllipticCurvePoint::Point { x: ppx, y, a: _, b: _ } => { y: py,
a: _,
b: _,
} => match point {
EllipticCurvePoint::Point {
x: ppx,
y,
a: _,
b: _,
} => {
if *px == ppx && *py == y { if *px == ppx && *py == y {
return U512::from(x) + U512::from(1u8); return U512::from(x) + U512::from(1u8);
} }
},
_ => {}
} }
_ => {}
}, },
_ => {} _ => {}
} }
@ -80,16 +94,28 @@ impl Encryption {
self.plain_mapping[x as usize] self.plain_mapping[x as usize]
}; };
while x < i64::MAX && !(match tmp { while x < i64::MAX
EllipticCurvePoint::Point { x: tx, y: ty, a: _, b: _ } => match point { && !(match tmp {
EllipticCurvePoint::Point { x: px, y: py, a: _, b: _ } => tx == px && ty == py, EllipticCurvePoint::Point {
_ => false 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 => match point {
EllipticCurvePoint::Infinity => true, EllipticCurvePoint::Infinity => true,
_ => false _ => false,
}, },
}) { })
{
x += 1; x += 1;
tmp = tmp + self.base_point; tmp = tmp + self.base_point;
} }
@ -99,7 +125,7 @@ impl Encryption {
pub fn plain_to_ec_point(&self, m: U512) -> EllipticCurvePoint { pub fn plain_to_ec_point(&self, m: U512) -> EllipticCurvePoint {
if m == U512::from(0u8) { if m == U512::from(0u8) {
return EllipticCurvePoint::Infinity return EllipticCurvePoint::Infinity;
} }
return self.base_point * m; return self.base_point * m;
@ -110,12 +136,13 @@ impl Encryption {
ecc_p.data + (-rq) ecc_p.data + (-rq)
} }
pub fn encrypt(&self, message: EllipticCurvePoint, public_key: EllipticCurvePoint, r: Option<U512>) -> EncryptedEllipticCurvePoint { pub fn encrypt(
let ra = if let Some(ra) = r { &self,
ra message: EllipticCurvePoint,
} else { public_key: EllipticCurvePoint,
Self::random() r: Option<U512>,
}; ) -> EncryptedEllipticCurvePoint {
let ra = if let Some(ra) = r { ra } else { Self::random() };
let (data_tx, data_rx) = mpsc::channel(); let (data_tx, data_rx) = mpsc::channel();
let (rp_tx, rp_rx) = mpsc::channel(); let (rp_tx, rp_rx) = mpsc::channel();
@ -134,7 +161,10 @@ impl Encryption {
let data_received = data_rx.recv().unwrap(); let data_received = data_rx.recv().unwrap();
let rp_received = rp_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 { pub fn get_public_key(&self, private_key: U512) -> EllipticCurvePoint {

View File

@ -1,8 +1,15 @@
use crate::{
common::finite_field::FiniteFieldElement,
elliptic_curve::encryption::EncryptedEllipticCurvePoint,
};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)] #[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
pub enum Variable { pub enum Variable {
Number { value: i64 }, Number { value: i64 },
Text { value: String }, Text { value: String },
Return { value: Box<Variable> }, Return { value: Box<Variable> },
PureEncrypted { value: EncryptedEllipticCurvePoint },
PairedEncrypted { value: FiniteFieldElement },
None {}, None {},
} }

View File

@ -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::external_function::{ExternalFuncReturn, ExternalFuncStatus};
use crate::gpsl::node::*; use crate::gpsl::node::*;
use crate::gpsl::permission::Permission; use crate::gpsl::permission::Permission;
@ -113,6 +115,13 @@ impl GPSL {
} }
} }
pub fn extract_eep(node: Variable) -> Result<EncryptedEllipticCurvePoint, String> {
match node {
Variable::PureEncrypted { value } => Ok(value),
_ => Err(String::from("Not an encrypted point")),
}
}
pub fn evaluate(&mut self, node: Box<Node>) -> Result<Option<Variable>, String> { pub fn evaluate(&mut self, node: Box<Node>) -> Result<Option<Variable>, String> {
match *node { match *node {
Node::Call { name, args } => { Node::Call { name, args } => {
@ -267,8 +276,16 @@ impl GPSL {
Ok(rhs) => Ok(Some(Variable::Number { value: lhs + rhs })), 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),
}, },
Err(err) => Err(err),
},
},
NodeKind::DIV => match GPSL::extract_number(lhs) { NodeKind::DIV => match GPSL::extract_number(lhs) {
Ok(lhs) => match GPSL::extract_number(rhs) { Ok(lhs) => match GPSL::extract_number(rhs) {
Ok(rhs) => Ok(Some(Variable::Number { value: lhs / rhs })), Ok(rhs) => Ok(Some(Variable::Number { value: lhs / rhs })),

View File

@ -1,3 +1,5 @@
mod common;
mod elliptic_curve;
mod gpsl; mod gpsl;
use gpsl::external_function::ExternalFuncReturn; use gpsl::external_function::ExternalFuncReturn;
use gpsl::external_function::ExternalFuncStatus; use gpsl::external_function::ExternalFuncStatus;