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() {
let a = encrypt(16)
println("a: " + a)
let b = encrypt(60)
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))
let a = encrypt(3);
let b = encrypt2(2);
println(decrypt_pair(a * b));
}

BIN
gpsl_conf

Binary file not shown.

View File

@ -17,4 +17,7 @@ pub struct Args {
#[clap(short, long, takes_value = false)]
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)));
}
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(
Some(functions),
@ -143,7 +151,9 @@ pub fn start_client(args: Args) {
Some(servers),
encryption.clone(),
config.private_key,
config.private_key2,
config.public_key,
config.public_key2,
vec![STD_FUNC],
);
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)]
pub struct ConfigFile {
pub private_key: Option<String>,
pub private_key2: Option<String>,
pub public_key: Option<String>,
pub public_key2: Option<String>,
}
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 = {
if let Some(public_key) = config.public_key {
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 {
private_key,
private_key2,
public_key,
public_key2,
}
}
}
@ -49,19 +73,24 @@ impl ConfigFile {
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct Config {
pub private_key: Option<U512>,
pub private_key2: Option<U512>,
pub public_key: Option<EllipticCurvePoint>,
pub public_key2: Option<EllipticCurvePoint>,
}
impl Config {
pub fn read_or_create() -> Self {
let encryption = Encryption::secp256k1();
pub fn read_or_create(encryption: Option<Encryption>) -> Self {
let encryption = encryption.unwrap_or(Encryption::secp256k1());
if Path::new("gpsl_conf").exists() {
Config::from_file("gpsl_conf")
} else {
let private_key = Encryption::get_private_key();
let private_key2 = Encryption::get_private_key();
let config = Config {
private_key: Some(private_key),
private_key2: Some(private_key2),
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();
@ -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 = {
if let Some(public_key) = config.public_key {
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 {
private_key,
private_key2,
public_key,
public_key2,
}
}
}

View File

@ -20,6 +20,8 @@ use super::elliptic_curve::{EllipticCurve, EllipticCurvePoint};
pub struct Encryption {
pub ellictic_curve: EllipticCurve,
pub base_point: EllipticCurvePoint,
pub base_point2: Option<EllipticCurvePoint>,
pub r: Option<U512>,
pub order: FiniteFieldElement,
pub plain_mapping: Vec<EllipticCurvePoint>,
}
@ -94,6 +96,52 @@ impl Mul<U512> for EncryptedEllipticCurvePoint {
}
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 {
let p = U512::from_str_radix(
"115792089237316195423570985008687907853269984665640564039457584007908834671663",
@ -135,11 +183,49 @@ impl Encryption {
Self {
ellictic_curve: ec,
base_point: ec.point(secp256_k1_base_x, secp256_k1_base_y),
base_point2: None,
r: None,
order: secp256_k1_order,
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 {
match point {
EllipticCurvePoint::Infinity => return U512::from(0u8),
@ -219,6 +305,14 @@ impl Encryption {
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 {
let rq = ecc_p.rp * private_key;
ecc_p.data + (-rq)

View File

@ -25,7 +25,9 @@ pub struct ExternalFuncReturn {
pub struct ExternalFunctionCallData {
pub encryption: Encryption,
pub private_key: Option<U512>,
pub private_key2: Option<U512>,
pub public_key: Option<EllipticCurvePoint>,
pub public_key2: Option<EllipticCurvePoint>,
}
#[allow(dead_code)]
@ -135,6 +137,20 @@ pub const STD_FUNC: fn(
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" => {
let encryption = data.encryption;
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" => {
let num = match args[0].clone() {
Variable::Number { value } => value,
@ -219,7 +256,9 @@ pub const STD_FUNC: fn(
Variable::Number { value } => println!("{}", value),
Variable::U512 { value } => println!("{:x}", 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 } => {
STD_FUNC(
"print".to_string(),
@ -232,7 +271,9 @@ pub const STD_FUNC: fn(
ExternalFunctionCallData {
encryption: data.encryption.clone(),
private_key: data.private_key.clone(),
private_key2: data.private_key2.clone(),
public_key: data.public_key.clone(),
public_key2: data.public_key2.clone(),
},
);
println!("");
@ -257,7 +298,9 @@ pub const STD_FUNC: fn(
Variable::Number { value } => print!("{}", value),
Variable::U512 { value } => print!("{:x}", 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, .. } => {
print!("[");
let mut f = false;
@ -275,7 +318,9 @@ pub const STD_FUNC: fn(
ExternalFunctionCallData {
encryption: data.encryption.clone(),
private_key: data.private_key,
private_key2: data.private_key2,
public_key: data.public_key,
public_key2: data.public_key2,
},
);
}

View File

@ -22,7 +22,10 @@ pub enum Variable {
value: EncryptedEllipticCurvePoint,
},
PairedEncrypted {
value: FiniteFieldElement,
a: FiniteFieldElement,
b: FiniteFieldElement,
c: FiniteFieldElement,
d: FiniteFieldElement,
},
U512 {
value: U512,
@ -60,7 +63,10 @@ impl Variable {
Variable::Text { value } => Some(value.clone()),
Variable::Number { 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::Vec { value, .. } => {
let mut result = String::new();

View File

@ -31,7 +31,9 @@ pub struct GPSL {
pub servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>,
pub encryption: Encryption,
pub private_key: Option<U512>,
pub private_key2: Option<U512>,
pub public_key: Option<EllipticCurvePoint>,
pub public_key2: Option<EllipticCurvePoint>,
pub global_variables: Vec<Variable>,
pub blocks: VecDeque<Block>,
pub external_func: Vec<
@ -76,7 +78,9 @@ impl GPSL {
servers: Option<HashMap<String, Arc<Mutex<TcpStream>>>>,
encryption: Encryption,
private_key: Option<U512>,
private_key2: Option<U512>,
public_key: Option<EllipticCurvePoint>,
public_key2: Option<EllipticCurvePoint>,
external_func: Vec<
fn(
String,
@ -93,7 +97,9 @@ impl GPSL {
servers,
encryption,
private_key,
private_key2,
public_key,
public_key2,
global_variables: vec![],
blocks: VecDeque::new(),
external_func,
@ -295,7 +301,9 @@ impl GPSL {
ExternalFunctionCallData {
encryption: self.encryption.clone(),
private_key: self.private_key,
private_key2: self.private_key2,
public_key: self.public_key,
public_key2: self.public_key2,
},
);
if res.status == ExternalFuncStatus::SUCCESS {
@ -435,6 +443,10 @@ impl GPSL {
Variable::U512 { value: 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_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();
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(
Some(functions),
Some(HashMap::new()),
Some(HashMap::new()),
Encryption::secp256k1(),
encryption,
None,
None,
None,
None,
vec![STD_FUNC],