add encrypted calc in gpsl

This commit is contained in:
Masato Imai
2022-07-22 15:20:08 +09:00
parent c0bc083589
commit 6856108c3f
7 changed files with 215 additions and 26 deletions

View File

@ -1,20 +1,24 @@
#[server(ip = "172.25.5.104:8080")]
fn add(a: num, b: num) {
#[server(ip = "localhost:8080")]
fn encrypt_add(a: eep, b: eep) {
print("a: ");
println(a);
print("b: ");
println(b);
return a + b;
}
#[server(ip = "172.25.5.189:8080")]
fn mul(a: num, b: num) {
return a * b;
}
fn main() {
println(add(1, 2));
println(mul(2, 2));
let i: num;
for (i = 0; i < 2000; i += 1) {
println(mul(i, i));
}
}
let enc_a: eep;
let enc_b: eep;
enc_a = encrypt(10);
enc_b = encrypt(4);
let enc_res: eep;
enc_res = encrypt_add(enc_a, enc_b);
println(decrypt(enc_res));
}

View File

@ -9,7 +9,7 @@ use serde::{Deserialize, Serialize};
use super::math::{mod_inv, plus_mod};
#[derive(PartialEq, PartialOrd, Debug, Copy, Clone, Deserialize, Serialize)]
#[derive(PartialEq, Debug, Copy, Clone, PartialOrd, Deserialize, Serialize)]
pub struct FiniteFieldElement {
pub value: U512,
pub p: U512,

View File

@ -1,4 +1,5 @@
use std::{
fmt::Display,
ops::{Add, Sub},
sync::mpsc,
thread,
@ -15,7 +16,7 @@ use rand_chacha::{
use super::elliptic_curve::{EllipticCurve, EllipticCurvePoint};
#[derive(Debug, Clone)]
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Encryption {
pub ellictic_curve: EllipticCurve,
pub base_point: EllipticCurvePoint,
@ -29,6 +30,24 @@ pub struct EncryptedEllipticCurvePoint {
pub rp: EllipticCurvePoint,
}
impl EncryptedEllipticCurvePoint {
pub fn default() -> Self {
Self {
data: EllipticCurvePoint::Infinity,
rp: EllipticCurvePoint::Infinity,
}
}
}
impl Display for EncryptedEllipticCurvePoint {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.data {
EllipticCurvePoint::Infinity => write!(f, "Infinity"),
EllipticCurvePoint::Point { x, y, .. } => write!(f, "{:x}{:x}", x.value, y.value),
}
}
}
impl Add for EncryptedEllipticCurvePoint {
type Output = Self;

View File

@ -1,6 +1,10 @@
use primitive_types::U512;
use serde::{Deserialize, Serialize};
use crate::gpsl::{permission::Permission, variable::Variable};
use crate::{
elliptic_curve::{elliptic_curve::EllipticCurvePoint, encryption::Encryption},
gpsl::{permission::Permission, variable::Variable},
};
#[derive(PartialEq, Debug, Serialize, Deserialize)]
pub enum ExternalFuncStatus {
@ -16,20 +20,84 @@ pub struct ExternalFuncReturn {
pub value: Option<Variable>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ExternalFunctionCallData {
pub encryption: Encryption,
pub private_key: Option<U512>,
pub public_key: Option<EllipticCurvePoint>,
}
#[allow(dead_code)]
pub const STD_FUNC: fn(
String,
Vec<Variable>,
Vec<Permission>,
Vec<Permission>,
) -> ExternalFuncReturn = |name, args, accept, reject| {
ExternalFunctionCallData,
) -> ExternalFuncReturn = |name, args, accept, reject, data| {
let name = name.as_str();
match name {
"encrypt" => {
let encryption = data.encryption;
let plain = match args[0] {
Variable::Number { value } => U512::from(value),
_ => panic!("encrypt: first argument must be a number"),
};
let ec = encryption.plain_to_ec_point(plain);
let eep = encryption.encrypt(ec, data.public_key.unwrap(), None);
ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: Some(Variable::PureEncrypted { value: eep }),
}
}
"decrypt" => {
let encryption = data.encryption;
let eep = match args[0] {
Variable::PureEncrypted { value } => value,
_ => panic!("decrypt: first argument must be a pure encrypted point"),
};
let plain = Encryption::decrypt(eep, data.private_key.unwrap());
let plain = encryption.ec_point_to_plain(plain);
ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: Some(Variable::Number {
value: plain.as_u64() as i64,
}),
}
}
"to_u512" => {
if args.len() != 1 {
return ExternalFuncReturn {
status: ExternalFuncStatus::ERROR,
value: None,
};
}
let arg = args[0].clone();
match arg {
Variable::Number { value } => {
return ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: Some(Variable::U512 {
value: value.into(),
}),
};
}
_ => {
return ExternalFuncReturn {
status: ExternalFuncStatus::ERROR,
value: None,
};
}
}
}
"println" => {
if accept.contains(&Permission::StdIo) && !reject.contains(&Permission::StdIo) {
match &args[0] {
Variable::Text { value } => println!("{}", value),
Variable::Number { value } => println!("{}", value),
Variable::U512 { value } => println!("{:x}", value),
Variable::PureEncrypted { value } => println!("{}", value),
Variable::PairedEncrypted { value } => println!("{:x}", value.value),
_ => {}
}
ExternalFuncReturn {
@ -48,6 +116,9 @@ pub const STD_FUNC: fn(
match &args[0] {
Variable::Text { value } => print!("{}", value),
Variable::Number { value } => print!("{}", value),
Variable::U512 { value } => print!("{:x}", value),
Variable::PureEncrypted { value } => print!("{}", value),
Variable::PairedEncrypted { value } => print!("{:x}", value.value),
_ => {}
}
ExternalFuncReturn {

View File

@ -2,6 +2,7 @@ use crate::{
common::finite_field::FiniteFieldElement,
elliptic_curve::encryption::EncryptedEllipticCurvePoint,
};
use primitive_types::U512;
use serde::{Deserialize, Serialize};
#[derive(Clone, PartialEq, Debug, Serialize, Deserialize)]
@ -11,5 +12,6 @@ pub enum Variable {
Return { value: Box<Variable> },
PureEncrypted { value: EncryptedEllipticCurvePoint },
PairedEncrypted { value: FiniteFieldElement },
U512 { value: U512 },
None {},
}

View File

@ -1,11 +1,14 @@
use crate::elliptic_curve::encryption::EncryptedEllipticCurvePoint;
use crate::elliptic_curve::encryption::EncryptedEllipticCurvePoint;
use crate::gpsl::external_function::{ExternalFuncReturn, ExternalFuncStatus};
use crate::elliptic_curve::elliptic_curve::EllipticCurvePoint;
use crate::elliptic_curve::encryption::{EncryptedEllipticCurvePoint, Encryption};
use crate::gpsl::external_function::{
ExternalFuncReturn, ExternalFuncStatus, ExternalFunctionCallData,
};
use crate::gpsl::node::*;
use crate::gpsl::permission::Permission;
use crate::gpsl::source::Source;
use crate::gpsl::variable::*;
use log::*;
use primitive_types::U512;
use serde::{Deserialize, Serialize};
use std::collections::{HashMap, VecDeque};
use std::io::{BufRead, BufReader, Write};
@ -26,11 +29,21 @@ pub struct GPSL {
pub functions: Option<HashMap<String, Box<Node>>>,
pub server_functions: Option<HashMap<String, HashMap<String, Box<Node>>>>,
pub servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>,
pub encryption: Encryption,
pub private_key: Option<U512>,
pub public_key: Option<EllipticCurvePoint>,
pub global_variables: Vec<Variable>,
pub source: Source,
pub blocks: VecDeque<Block>,
pub external_func:
Vec<fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn>,
pub external_func: Vec<
fn(
String,
Vec<Variable>,
Vec<Permission>,
Vec<Permission>,
ExternalFunctionCallData,
) -> ExternalFuncReturn,
>,
}
#[derive(Clone, Debug)]
@ -63,8 +76,17 @@ impl GPSL {
functions: Option<HashMap<String, Box<Node>>>,
server_functions: Option<HashMap<String, HashMap<String, Box<Node>>>>,
servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>,
encryption: Encryption,
private_key: Option<U512>,
public_key: Option<EllipticCurvePoint>,
external_func: Vec<
fn(String, Vec<Variable>, Vec<Permission>, Vec<Permission>) -> ExternalFuncReturn,
fn(
String,
Vec<Variable>,
Vec<Permission>,
Vec<Permission>,
ExternalFunctionCallData,
) -> ExternalFuncReturn,
>,
) -> GPSL {
GPSL {
@ -72,6 +94,9 @@ impl GPSL {
functions,
server_functions,
servers,
encryption,
private_key,
public_key,
global_variables: vec![],
blocks: VecDeque::new(),
external_func,
@ -234,6 +259,11 @@ impl GPSL {
args_value.clone(),
block.accept.clone(),
block.reject.clone(),
ExternalFunctionCallData {
encryption: self.encryption.clone(),
private_key: self.private_key,
public_key: self.public_key,
},
);
if res.status == ExternalFuncStatus::SUCCESS {
return Ok(res.value);
@ -268,15 +298,15 @@ impl GPSL {
let lhs = self.evaluate(lhs).expect("Cannot evaluate lhs.");
let rhs = self.evaluate(rhs).expect("Cannot evaluate rhs.");
if let Some(lhs) = lhs {
if let Some(lhs) = lhs.clone() {
if let Some(rhs) = rhs {
match kind {
NodeKind::ADD => match GPSL::extract_number(lhs) {
NodeKind::ADD => match GPSL::extract_number(lhs.clone()) {
Ok(lhs) => match GPSL::extract_number(rhs) {
Ok(rhs) => Ok(Some(Variable::Number { value: lhs + rhs })),
Err(err) => Err(err),
},
Err(err) => match GPSL::extract_eep(lhs) {
Err(_) => match GPSL::extract_eep(lhs) {
Ok(lhs) => match GPSL::extract_eep(rhs) {
Ok(rhs) => {
Ok(Some(Variable::PureEncrypted { value: lhs + rhs }))
@ -532,6 +562,10 @@ impl GPSL {
Variable::Text {
value: String::default(),
}
} else if var_type == "eep" {
Variable::PureEncrypted {
value: EncryptedEllipticCurvePoint::default(),
}
} else {
return Err(format!("{}: 未知の型です。", var_type));
};

View File

@ -1,6 +1,9 @@
mod common;
mod elliptic_curve;
mod gpsl;
use common::finite_field::FiniteFieldElement;
use elliptic_curve::elliptic_curve::EllipticCurve;
use elliptic_curve::encryption::Encryption;
use gpsl::external_function::ExternalFuncReturn;
use gpsl::external_function::ExternalFuncStatus;
use gpsl::node::Node;
@ -8,6 +11,7 @@ use gpsl::node::NodeKind;
use gpsl::vm::gpsl::ServerFunctionCall;
use gpsl::{external_function::STD_FUNC, source::*, tokenizer::*, vm::gpsl::*};
use log::*;
use primitive_types::U512;
use std::env;
use std::io::BufRead;
use std::io::BufReader;
@ -89,6 +93,52 @@ fn listen_tcp_server(port: u16) -> TcpStream {
panic!("Cannot connect to client");
}
fn generate_encryption() -> Encryption {
let p = U512::from_str_radix(
"115792089237316195423570985008687907853269984665640564039457584007908834671663",
10,
)
.unwrap();
let secp256_k1_a = FiniteFieldElement::new(U512::from(0u8), p);
let secp256_k1_b = FiniteFieldElement::new(U512::from(7u8), p);
let secp256_k1_base_x = FiniteFieldElement::new(
U512::from_str_radix(
"55066263022277343669578718895168534326250603453777594175500187360389116729240",
10,
)
.unwrap(),
p,
);
let secp256_k1_base_y = FiniteFieldElement::new(
U512::from_str_radix(
"32670510020758816978083085130507043184471273380659243275938904335757337482424",
10,
)
.unwrap(),
p,
);
let secp256_k1_order = FiniteFieldElement::new(
U512::from_str_radix(
"115792089237316195423570985008687907852837564279074904382605163141518161494337",
10,
)
.unwrap(),
p,
);
let ec = EllipticCurve {
a: secp256_k1_a,
b: secp256_k1_b,
};
Encryption {
ellictic_curve: ec,
base_point: ec.point(secp256_k1_base_x, secp256_k1_base_y),
order: secp256_k1_order,
plain_mapping: vec![],
}
}
fn main() {
env::set_var("RUST_LOG", "info");
env_logger::init();
@ -126,6 +176,9 @@ fn server(args: Args) {
Some(functions),
Some(HashMap::new()),
Some(HashMap::new()),
generate_encryption(),
None,
None,
vec![STD_FUNC],
);
@ -240,11 +293,17 @@ fn client(args: Args) {
servers.insert(ip, Arc::new(Mutex::new(stream)));
}
let encryption = generate_encryption();
let private_key = Encryption::get_private_key();
let mut gpsl = GPSL::new(
source,
Some(functions),
Some(server_functions),
Some(servers),
encryption.clone(),
Some(private_key),
Some(encryption.get_public_key(private_key)),
vec![STD_FUNC],
);
let res = gpsl.run("main".to_string(), HashMap::new());