support pairing multiply

This commit is contained in:
Masato Imai
2022-08-25 13:49:57 +09:00
parent c4c475714a
commit d2dbefe505
10 changed files with 246 additions and 22 deletions

View File

@ -1,15 +1,5 @@
fn main() { fn main() {
let a = encrypt(16) let a = encrypt(3);
println("a: " + a) let b = encrypt2(2);
let b = encrypt(60) println(decrypt_pair(a * b));
println("b: " + b)
let c = encrypt(48)
println("c: " + c)
let d = encrypt(2)
println("d: " + d)
let e = encrypt(24)
println("e: " + e)
let f = encrypt(15)
let r = a + b + c + d + e - f
println("(a + b + c + d + e - f) * 2 = " + decrypt(r * 2))
} }

BIN
gpsl_conf

Binary file not shown.

View File

@ -17,4 +17,7 @@ pub struct Args {
#[clap(short, long, takes_value = false)] #[clap(short, long, takes_value = false)]
pub compile: bool, pub compile: bool,
#[clap(short, long, value_parser)]
pub curve: Option<String>,
} }

View File

@ -133,9 +133,17 @@ pub fn start_client(args: Args) {
servers.insert(ip, Arc::new(Mutex::new(stream))); servers.insert(ip, Arc::new(Mutex::new(stream)));
} }
let encryption = Encryption::secp256k1(); let encryption = if let Some(curve) = args.curve {
if curve == String::from("pairing") {
Encryption::pairing_friendly()
} else {
panic!("Unknown curve");
}
} else {
Encryption::secp256k1()
};
let config = Config::read_or_create(); let config = Config::read_or_create(Some(encryption.clone()));
let mut gpsl = GPSL::new( let mut gpsl = GPSL::new(
Some(functions), Some(functions),
@ -143,7 +151,9 @@ pub fn start_client(args: Args) {
Some(servers), Some(servers),
encryption.clone(), encryption.clone(),
config.private_key, config.private_key,
config.private_key2,
config.public_key, config.public_key,
config.public_key2,
vec![STD_FUNC], vec![STD_FUNC],
); );
let res = gpsl.run("main".to_string(), HashMap::new()); let res = gpsl.run("main".to_string(), HashMap::new());

View File

@ -14,7 +14,9 @@ use crate::elliptic_curve::encryption::Encryption;
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct ConfigFile { pub struct ConfigFile {
pub private_key: Option<String>, pub private_key: Option<String>,
pub private_key2: Option<String>,
pub public_key: Option<String>, pub public_key: Option<String>,
pub public_key2: Option<String>,
} }
impl ConfigFile { impl ConfigFile {
@ -29,6 +31,16 @@ impl ConfigFile {
} }
}; };
let private_key2 = {
if let Some(private_key2) = config.private_key2 {
let s = private_key2.to_string();
let encode = base64::encode(&s);
Some(encode)
} else {
None
}
};
let public_key = { let public_key = {
if let Some(public_key) = config.public_key { if let Some(public_key) = config.public_key {
let s = serde_json::to_string(&public_key).unwrap(); let s = serde_json::to_string(&public_key).unwrap();
@ -39,9 +51,21 @@ impl ConfigFile {
} }
}; };
let public_key2 = {
if let Some(public_key2) = config.public_key2 {
let s = serde_json::to_string(&public_key2).unwrap();
let encode = base64::encode(&s);
Some(encode)
} else {
None
}
};
Self { Self {
private_key, private_key,
private_key2,
public_key, public_key,
public_key2,
} }
} }
} }
@ -49,19 +73,24 @@ impl ConfigFile {
#[derive(Clone, Debug, Serialize, Deserialize)] #[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Config { pub struct Config {
pub private_key: Option<U512>, pub private_key: Option<U512>,
pub private_key2: Option<U512>,
pub public_key: Option<EllipticCurvePoint>, pub public_key: Option<EllipticCurvePoint>,
pub public_key2: Option<EllipticCurvePoint>,
} }
impl Config { impl Config {
pub fn read_or_create() -> Self { pub fn read_or_create(encryption: Option<Encryption>) -> Self {
let encryption = Encryption::secp256k1(); let encryption = encryption.unwrap_or(Encryption::secp256k1());
if Path::new("gpsl_conf").exists() { if Path::new("gpsl_conf").exists() {
Config::from_file("gpsl_conf") Config::from_file("gpsl_conf")
} else { } else {
let private_key = Encryption::get_private_key(); let private_key = Encryption::get_private_key();
let private_key2 = Encryption::get_private_key();
let config = Config { let config = Config {
private_key: Some(private_key), private_key: Some(private_key),
private_key2: Some(private_key2),
public_key: Some(encryption.get_public_key(private_key)), public_key: Some(encryption.get_public_key(private_key)),
public_key2: Some(encryption.get_public_key(private_key2)),
}; };
let mut file = File::create("gpsl_conf").unwrap(); let mut file = File::create("gpsl_conf").unwrap();
@ -99,6 +128,16 @@ impl Config {
} }
}; };
let private_key2 = {
if let Some(private_key2) = config.private_key2 {
let decoded = base64::decode(&private_key2).unwrap();
let s = std::str::from_utf8(&decoded).unwrap();
Some(U512::from_str_radix(s, 10).unwrap())
} else {
None
}
};
let public_key = { let public_key = {
if let Some(public_key) = config.public_key { if let Some(public_key) = config.public_key {
let decoded = base64::decode(&public_key).unwrap(); let decoded = base64::decode(&public_key).unwrap();
@ -110,9 +149,22 @@ impl Config {
} }
}; };
let public_key2 = {
if let Some(public_key2) = config.public_key2 {
let decoded = base64::decode(&public_key2).unwrap();
let s = std::str::from_utf8(&decoded).unwrap();
let r = EllipticCurvePoint::from_str(s).unwrap();
Some(r)
} else {
None
}
};
Config { Config {
private_key, private_key,
private_key2,
public_key, public_key,
public_key2,
} }
} }
} }

View File

@ -20,6 +20,8 @@ use super::elliptic_curve::{EllipticCurve, EllipticCurvePoint};
pub struct Encryption { pub struct Encryption {
pub ellictic_curve: EllipticCurve, pub ellictic_curve: EllipticCurve,
pub base_point: EllipticCurvePoint, pub base_point: EllipticCurvePoint,
pub base_point2: Option<EllipticCurvePoint>,
pub r: Option<U512>,
pub order: FiniteFieldElement, pub order: FiniteFieldElement,
pub plain_mapping: Vec<EllipticCurvePoint>, pub plain_mapping: Vec<EllipticCurvePoint>,
} }
@ -94,6 +96,52 @@ impl Mul<U512> for EncryptedEllipticCurvePoint {
} }
impl Encryption { impl Encryption {
pub fn pair_multiply(
&self,
p: EncryptedEllipticCurvePoint,
q: EncryptedEllipticCurvePoint,
) -> (
FiniteFieldElement,
FiniteFieldElement,
FiniteFieldElement,
FiniteFieldElement,
) {
let r = self.r.unwrap();
let a = EllipticCurvePoint::weil(p.data, q.data, r);
let b = EllipticCurvePoint::weil(p.data, q.rp, r);
let c = EllipticCurvePoint::weil(p.rp, q.data, r);
let d = EllipticCurvePoint::weil(p.rp, q.rp, r);
(a, b, c, d)
}
pub fn decrypt_pair(
&self,
a: FiniteFieldElement,
b: FiniteFieldElement,
c: FiniteFieldElement,
d: FiniteFieldElement,
private_key: U512,
private_key2: U512,
) -> U512 {
let f =
EllipticCurvePoint::weil(self.base_point, self.base_point2.unwrap(), self.r.unwrap());
let dec =
a * d.pow(private_key * private_key2) / b.pow(private_key2) / c.pow(private_key) * f;
let mut i = U512::one();
let mut b = f;
while b != dec {
b = b * f;
i += U512::one();
}
if i < U512::from(7u8) {
i
} else {
U512::zero()
}
}
pub fn secp256k1() -> Self { pub fn secp256k1() -> Self {
let p = U512::from_str_radix( let p = U512::from_str_radix(
"115792089237316195423570985008687907853269984665640564039457584007908834671663", "115792089237316195423570985008687907853269984665640564039457584007908834671663",
@ -135,11 +183,49 @@ impl Encryption {
Self { Self {
ellictic_curve: ec, ellictic_curve: ec,
base_point: ec.point(secp256_k1_base_x, secp256_k1_base_y), base_point: ec.point(secp256_k1_base_x, secp256_k1_base_y),
base_point2: None,
r: None,
order: secp256_k1_order, order: secp256_k1_order,
plain_mapping: vec![], plain_mapping: vec![],
} }
} }
pub fn pairing_friendly() -> Self {
let p = U512::from_str_radix("1009", 10).unwrap();
let ec_a = FiniteFieldElement::new(U512::from(37u8), p);
let ec_b = FiniteFieldElement::new(U512::from_str_radix("0", 10).unwrap(), p);
let pp = {
let x = FiniteFieldElement::new(U512::from_str_radix("417", 10).unwrap(), p);
let y = FiniteFieldElement::new(U512::from_str_radix("952", 10).unwrap(), p);
EllipticCurvePoint::Point {
x,
y,
a: ec_a,
b: ec_b,
}
};
let pd = {
let x = FiniteFieldElement::new(U512::from_str_radix("561", 10).unwrap(), p);
let y = FiniteFieldElement::new(U512::from_str_radix("153", 10).unwrap(), p);
EllipticCurvePoint::Point {
x,
y,
a: ec_a,
b: ec_b,
}
};
let ec = EllipticCurve { a: ec_a, b: ec_b };
Self {
ellictic_curve: ec,
base_point: pp,
base_point2: Some(pd),
r: Some(U512::from(7u8)),
order: FiniteFieldElement::new(U512::from_str_radix("7", 10).unwrap(), p),
plain_mapping: vec![],
}
}
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 => return U512::from(0u8), EllipticCurvePoint::Infinity => return U512::from(0u8),
@ -219,6 +305,14 @@ impl Encryption {
return self.base_point * m; return self.base_point * m;
} }
pub fn plain_to_ec_point_sub(&self, m: U512) -> EllipticCurvePoint {
if m == U512::from(0u8) {
return EllipticCurvePoint::Infinity;
}
return self.base_point2.unwrap() * m;
}
pub fn decrypt(ecc_p: EncryptedEllipticCurvePoint, private_key: U512) -> EllipticCurvePoint { pub fn decrypt(ecc_p: EncryptedEllipticCurvePoint, private_key: U512) -> EllipticCurvePoint {
let rq = ecc_p.rp * private_key; let rq = ecc_p.rp * private_key;
ecc_p.data + (-rq) ecc_p.data + (-rq)

View File

@ -25,7 +25,9 @@ pub struct ExternalFuncReturn {
pub struct ExternalFunctionCallData { pub struct ExternalFunctionCallData {
pub encryption: Encryption, pub encryption: Encryption,
pub private_key: Option<U512>, pub private_key: Option<U512>,
pub private_key2: Option<U512>,
pub public_key: Option<EllipticCurvePoint>, pub public_key: Option<EllipticCurvePoint>,
pub public_key2: Option<EllipticCurvePoint>,
} }
#[allow(dead_code)] #[allow(dead_code)]
@ -135,6 +137,20 @@ pub const STD_FUNC: fn(
value: Some(Variable::PureEncrypted { value: eep }), value: Some(Variable::PureEncrypted { value: eep }),
} }
} }
"encrypt2" => {
let encryption = data.encryption;
let plain = match args[0] {
Variable::Number { value } => U512::from(value),
Variable::U512 { value } => value,
_ => panic!("encrypt: first argument must be a number"),
};
let ec = encryption.plain_to_ec_point_sub(plain);
let eep = encryption.encrypt(ec, data.public_key.unwrap(), None);
ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: Some(Variable::PureEncrypted { value: eep }),
}
}
"decrypt" => { "decrypt" => {
let encryption = data.encryption; let encryption = data.encryption;
let eep = match args[0] { let eep = match args[0] {
@ -150,6 +166,27 @@ pub const STD_FUNC: fn(
}), }),
} }
} }
"decrypt_pair" => {
let encryption = data.encryption;
let (a, b, c, d) = match args[0] {
Variable::PairedEncrypted { a, b, c, d } => (a, b, c, d),
_ => panic!("decrypt: first argument must be a pure encrypted point"),
};
let plain = encryption.decrypt_pair(
a,
b,
c,
d,
data.private_key.unwrap(),
data.private_key2.unwrap(),
);
ExternalFuncReturn {
status: ExternalFuncStatus::SUCCESS,
value: Some(Variable::U512 { value: plain }),
}
}
"to_num" => { "to_num" => {
let num = match args[0].clone() { let num = match args[0].clone() {
Variable::Number { value } => value, Variable::Number { value } => value,
@ -219,7 +256,9 @@ pub const STD_FUNC: fn(
Variable::Number { value } => println!("{}", value), Variable::Number { value } => println!("{}", value),
Variable::U512 { value } => println!("{:x}", value), Variable::U512 { value } => println!("{:x}", value),
Variable::PureEncrypted { value } => println!("{}", value), Variable::PureEncrypted { value } => println!("{}", value),
Variable::PairedEncrypted { value } => println!("{:x}", value.value), Variable::PairedEncrypted { a, b, c, d } => {
println!("{:x}{:x}{:x}{:x}", a.value, b.value, c.value, d.value)
}
Variable::Vec { value, gpsl_type } => { Variable::Vec { value, gpsl_type } => {
STD_FUNC( STD_FUNC(
"print".to_string(), "print".to_string(),
@ -232,7 +271,9 @@ pub const STD_FUNC: fn(
ExternalFunctionCallData { ExternalFunctionCallData {
encryption: data.encryption.clone(), encryption: data.encryption.clone(),
private_key: data.private_key.clone(), private_key: data.private_key.clone(),
private_key2: data.private_key2.clone(),
public_key: data.public_key.clone(), public_key: data.public_key.clone(),
public_key2: data.public_key2.clone(),
}, },
); );
println!(""); println!("");
@ -257,7 +298,9 @@ pub const STD_FUNC: fn(
Variable::Number { value } => print!("{}", value), Variable::Number { value } => print!("{}", value),
Variable::U512 { value } => print!("{:x}", value), Variable::U512 { value } => print!("{:x}", value),
Variable::PureEncrypted { value } => print!("{}", value), Variable::PureEncrypted { value } => print!("{}", value),
Variable::PairedEncrypted { value } => print!("{:x}", value.value), Variable::PairedEncrypted { a, b, c, d } => {
print!("{:x}{:x}{:x}{:x}", a.value, b.value, c.value, d.value)
}
Variable::Vec { value, .. } => { Variable::Vec { value, .. } => {
print!("["); print!("[");
let mut f = false; let mut f = false;
@ -275,7 +318,9 @@ pub const STD_FUNC: fn(
ExternalFunctionCallData { ExternalFunctionCallData {
encryption: data.encryption.clone(), encryption: data.encryption.clone(),
private_key: data.private_key, private_key: data.private_key,
private_key2: data.private_key2,
public_key: data.public_key, public_key: data.public_key,
public_key2: data.public_key2,
}, },
); );
} }

View File

@ -22,7 +22,10 @@ pub enum Variable {
value: EncryptedEllipticCurvePoint, value: EncryptedEllipticCurvePoint,
}, },
PairedEncrypted { PairedEncrypted {
value: FiniteFieldElement, a: FiniteFieldElement,
b: FiniteFieldElement,
c: FiniteFieldElement,
d: FiniteFieldElement,
}, },
U512 { U512 {
value: U512, value: U512,
@ -60,7 +63,10 @@ impl Variable {
Variable::Text { value } => Some(value.clone()), Variable::Text { value } => Some(value.clone()),
Variable::Number { value } => Some(value.to_string()), Variable::Number { value } => Some(value.to_string()),
Variable::PureEncrypted { value } => Some(value.to_string()), Variable::PureEncrypted { value } => Some(value.to_string()),
Variable::PairedEncrypted { value } => Some(value.to_string()), Variable::PairedEncrypted { a, b, c, d } => Some(format!(
"{:x}{:x}{:x}{:x}",
a.value, b.value, c.value, d.value
)),
Variable::U512 { value } => Some(value.to_string()), Variable::U512 { value } => Some(value.to_string()),
Variable::Vec { value, .. } => { Variable::Vec { value, .. } => {
let mut result = String::new(); let mut result = String::new();

View File

@ -31,7 +31,9 @@ pub struct GPSL {
pub servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>, pub servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>,
pub encryption: Encryption, pub encryption: Encryption,
pub private_key: Option<U512>, pub private_key: Option<U512>,
pub private_key2: Option<U512>,
pub public_key: Option<EllipticCurvePoint>, pub public_key: Option<EllipticCurvePoint>,
pub public_key2: Option<EllipticCurvePoint>,
pub global_variables: Vec<Variable>, pub global_variables: Vec<Variable>,
pub blocks: VecDeque<Block>, pub blocks: VecDeque<Block>,
pub external_func: Vec< pub external_func: Vec<
@ -76,7 +78,9 @@ impl GPSL {
servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>, servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>,
encryption: Encryption, encryption: Encryption,
private_key: Option<U512>, private_key: Option<U512>,
private_key2: Option<U512>,
public_key: Option<EllipticCurvePoint>, public_key: Option<EllipticCurvePoint>,
public_key2: Option<EllipticCurvePoint>,
external_func: Vec< external_func: Vec<
fn( fn(
String, String,
@ -93,7 +97,9 @@ impl GPSL {
servers, servers,
encryption, encryption,
private_key, private_key,
private_key2,
public_key, public_key,
public_key2,
global_variables: vec![], global_variables: vec![],
blocks: VecDeque::new(), blocks: VecDeque::new(),
external_func, external_func,
@ -295,7 +301,9 @@ impl GPSL {
ExternalFunctionCallData { ExternalFunctionCallData {
encryption: self.encryption.clone(), encryption: self.encryption.clone(),
private_key: self.private_key, private_key: self.private_key,
private_key2: self.private_key2,
public_key: self.public_key, public_key: self.public_key,
public_key2: self.public_key2,
}, },
); );
if res.status == ExternalFuncStatus::SUCCESS { if res.status == ExternalFuncStatus::SUCCESS {
@ -435,6 +443,10 @@ impl GPSL {
Variable::U512 { value: rhs } => { Variable::U512 { value: rhs } => {
Ok(Some(Variable::PureEncrypted { value: lhs * rhs })) Ok(Some(Variable::PureEncrypted { value: lhs * rhs }))
} }
Variable::PureEncrypted { value: rhs } => {
let (a, b, c, d) = self.encryption.pair_multiply(lhs, rhs);
Ok(Some(Variable::PairedEncrypted { a, b, c, d }))
}
_ => Err("Cannot multiply non-number to ppe.".to_string()), _ => Err("Cannot multiply non-number to ppe.".to_string()),
}, },
_ => Err("Cannot multiply non-number.".to_string()), _ => Err("Cannot multiply non-number.".to_string()),

View File

@ -39,11 +39,23 @@ pub fn start_server(args: Args) {
let functions: HashMap<String, Box<Node>> = serde_json::from_str(&buf).unwrap(); let functions: HashMap<String, Box<Node>> = serde_json::from_str(&buf).unwrap();
debug!("Received: {:?}", functions); debug!("Received: {:?}", functions);
let encryption = if let Some(curve) = args.curve.clone() {
if curve == "pairing".to_string() {
Encryption::pairing_friendly()
} else {
panic!("Unknown curve: {}", curve);
}
} else {
Encryption::secp256k1()
};
let mut gpsl = GPSL::new( let mut gpsl = GPSL::new(
Some(functions), Some(functions),
Some(HashMap::new()), Some(HashMap::new()),
Some(HashMap::new()), Some(HashMap::new()),
Encryption::secp256k1(), encryption,
None,
None,
None, None,
None, None,
vec![STD_FUNC], vec![STD_FUNC],