Skip to content

Commit

Permalink
feat(sig): add insecure_sig (#1458)
Browse files Browse the repository at this point in the history
  • Loading branch information
folex committed Feb 13, 2023
1 parent b7c3427 commit 9727c3f
Show file tree
Hide file tree
Showing 2 changed files with 149 additions and 41 deletions.
58 changes: 57 additions & 1 deletion crates/particle-node-tests/tests/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ use std::str::FromStr;
use std::time::Duration;

use eyre::{Report, WrapErr};
use fluence_keypair::{KeyPair, Signature};
use fluence_keypair::{KeyFormat, KeyPair, Signature};
use itertools::Itertools;
use libp2p::core::Multiaddr;
use libp2p::kad::kbucket::Key;
Expand Down Expand Up @@ -1629,6 +1629,62 @@ fn json_builtins() {
}
}

#[test]
fn insecure_sign_verify() {
let kp = KeyPair::from_secret_key((0..32).collect(), KeyFormat::Ed25519).unwrap();
let swarms = make_swarms_with_builtins(
1,
"tests/builtins/services".as_ref(),
Some(kp.clone()),
None,
);

let mut client = ConnectedClient::connect_to(swarms[0].multiaddr.clone())
.wrap_err("connect client")
.unwrap();

client.send_particle(
r#"
(seq
(seq
(call relay ("registry" "get_record_bytes") ["key_id" "" [] [] 1 []] data)
(seq
(call relay ("insecure_sig" "sign") [data] sig_result)
(call relay ("insecure_sig" "verify") [sig_result.$.signature.[0]! data] result)
)
)
(call %init_peer_id% ("op" "return") [data sig_result result])
)
"#,
hashmap! {
"relay" => json!(client.node.to_string()),
},
);

use serde_json::Value::Array;
use serde_json::Value::Bool;
use serde_json::Value::Object;

if let [Array(data), Object(sig_result), Bool(result)] =
client.receive_args().unwrap().as_slice()
{
let data: Vec<_> = data.iter().map(|n| n.as_u64().unwrap() as u8).collect();

assert!(sig_result["success"].as_bool().unwrap());
let signature = sig_result["signature"].as_array().unwrap()[0]
.as_array()
.unwrap()
.iter()
.map(|n| n.as_u64().unwrap() as u8)
.collect();
let signature = Signature::from_bytes(kp.public().get_key_format(), signature);
assert!(result);
assert!(kp.public().verify(&data, &signature).is_ok());
} else {
panic!("incorrect args: expected three arguments")
}
}

fn binary(
service: &str,
func: &str,
Expand Down
132 changes: 92 additions & 40 deletions particle-builtins/src/builtins.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use std::str::FromStr;
use std::time::{Duration, Instant};

use derivative::Derivative;
use fluence_keypair::{KeyPair, Signature};
use fluence_keypair::{KeyFormat, KeyPair, Signature};
use futures::stream::FuturesUnordered;
use futures::StreamExt;
use humantime_serde::re::humantime::format_duration as pretty;
Expand Down Expand Up @@ -83,6 +83,9 @@ pub struct Builtins<C> {
pub custom_services: RwLock<HashMap<String, CustomService>>,

particles_vault_dir: path::PathBuf,

#[derivative(Debug = "ignore")]
insecure_keypair: KeyPair,
}

impl<C> Builtins<C>
Expand Down Expand Up @@ -125,6 +128,8 @@ where
node_info,
particles_vault_dir,
custom_services: <_>::default(),
insecure_keypair: KeyPair::from_secret_key((0..32).collect(), KeyFormat::Ed25519)
.expect("error creating insecure keypair"),
}
}

Expand Down Expand Up @@ -220,45 +225,49 @@ where

("debug", "stringify") => self.stringify(args.function_args),

("stat", "service_memory") => wrap(self.service_mem_stats(args, particle)),
("stat", "service_stat") => wrap(self.service_stat(args, particle)),

("math", "add") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::add(x, y) }),
("math", "sub") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::sub(x, y) }),
("math", "mul") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::mul(x, y) }),
("math", "fmul") => binary(args, |x: f64, y: f64| -> R<i64, _> { math::fmul_floor(x, y) }),
("math", "div") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::div(x, y) }),
("math", "rem") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::rem(x, y) }),
("math", "pow") => binary(args, |x: i64, y: u32| -> R<i64, _> { math::pow(x, y) }),
("math", "log") => binary(args, |x: i64, y: i64| -> R<u32, _> { math::log(x, y) }),

("cmp", "gt") => binary(args, |x: i64, y: i64| -> R<bool, _> { math::gt(x, y) }),
("cmp", "gte") => binary(args, |x: i64, y: i64| -> R<bool, _> { math::gte(x, y) }),
("cmp", "lt") => binary(args, |x: i64, y: i64| -> R<bool, _> { math::lt(x, y) }),
("cmp", "lte") => binary(args, |x: i64, y: i64| -> R<bool, _> { math::lte(x, y) }),
("cmp", "cmp") => binary(args, |x: i64, y: i64| -> R<i8, _> { math::cmp(x, y) }),

("array", "sum") => unary(args, |xs: Vec<i64> | -> R<i64, _> { math::array_sum(xs) }),
("array", "dedup") => unary(args, |xs: Vec<String>| -> R<Vec<String>, _> { math::dedup(xs) }),
("array", "intersect") => binary(args, |xs: HashSet<String>, ys: HashSet<String>| -> R<Vec<String>, _> { math::intersect(xs, ys) }),
("array", "diff") => binary(args, |xs: HashSet<String>, ys: HashSet<String>| -> R<Vec<String>, _> { math::diff(xs, ys) }),
("array", "sdiff") => binary(args, |xs: HashSet<String>, ys: HashSet<String>| -> R<Vec<String>, _> { math::sdiff(xs, ys) }),
("array", "slice") => wrap(self.array_slice(args.function_args)),
("array", "length") => wrap(self.array_length(args.function_args)),

("sig", "sign") => wrap(self.sign(args)),
("sig", "verify") => wrap(self.verify(args)),
("sig", "get_peer_id") => wrap(self.get_peer_id()),

("json", "obj") => wrap(json::obj(args)),
("json", "put") => wrap(json::put(args)),
("json", "puts") => wrap(json::puts(args)),
("json", "parse") => unary(args, |s: String| -> R<JValue, _> { json::parse(&s) }),
("json", "stringify") => unary(args, |v: JValue| -> R<String, _> { Ok(json::stringify(v)) }),
("json", "obj_pairs") => unary(args, |vs: Vec<(String, JValue)>| -> R<JValue, _> { json::obj_from_pairs(vs) }),
("json", "puts_pairs") => binary(args, |obj: JValue, vs: Vec<(String, JValue)>| -> R<JValue, _> { json::puts_from_pairs(obj, vs) }),

("run-console", "print") => wrap_unit(Ok(log::debug!(target: "run-console", "{}", json!(args.function_args)))),
("stat", "service_memory") => wrap(self.service_mem_stats(args, particle)),
("stat", "service_stat") => wrap(self.service_stat(args, particle)),

("math", "add") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::add(x, y) }),
("math", "sub") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::sub(x, y) }),
("math", "mul") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::mul(x, y) }),
("math", "fmul") => binary(args, |x: f64, y: f64| -> R<i64, _> { math::fmul_floor(x, y) }),
("math", "div") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::div(x, y) }),
("math", "rem") => binary(args, |x: i64, y: i64| -> R<i64, _> { math::rem(x, y) }),
("math", "pow") => binary(args, |x: i64, y: u32| -> R<i64, _> { math::pow(x, y) }),
("math", "log") => binary(args, |x: i64, y: i64| -> R<u32, _> { math::log(x, y) }),

("cmp", "gt") => binary(args, |x: i64, y: i64| -> R<bool, _> { math::gt(x, y) }),
("cmp", "gte") => binary(args, |x: i64, y: i64| -> R<bool, _> { math::gte(x, y) }),
("cmp", "lt") => binary(args, |x: i64, y: i64| -> R<bool, _> { math::lt(x, y) }),
("cmp", "lte") => binary(args, |x: i64, y: i64| -> R<bool, _> { math::lte(x, y) }),
("cmp", "cmp") => binary(args, |x: i64, y: i64| -> R<i8, _> { math::cmp(x, y) }),

("array", "sum") => unary(args, |xs: Vec<i64> | -> R<i64, _> { math::array_sum(xs) }),
("array", "dedup") => unary(args, |xs: Vec<String>| -> R<Vec<String>, _> { math::dedup(xs) }),
("array", "intersect") => binary(args, |xs: HashSet<String>, ys: HashSet<String>| -> R<Vec<String>, _> { math::intersect(xs, ys) }),
("array", "diff") => binary(args, |xs: HashSet<String>, ys: HashSet<String>| -> R<Vec<String>, _> { math::diff(xs, ys) }),
("array", "sdiff") => binary(args, |xs: HashSet<String>, ys: HashSet<String>| -> R<Vec<String>, _> { math::sdiff(xs, ys) }),
("array", "slice") => wrap(self.array_slice(args.function_args)),
("array", "length") => wrap(self.array_length(args.function_args)),

("sig", "sign") => wrap(self.sign(args)),
("sig", "verify") => wrap(self.verify(args)),
("sig", "get_peer_id") => wrap(self.get_peer_id()),

("insecure_sig", "sign") => wrap(self.insecure_sign(args)),
("insecure_sig", "verify") => wrap(self.insecure_verify(args)),
("insecure_sig", "get_peer_id") => wrap(self.insecure_get_peer_id()),

("json", "obj") => wrap(json::obj(args)),
("json", "put") => wrap(json::put(args)),
("json", "puts") => wrap(json::puts(args)),
("json", "parse") => unary(args, |s: String| -> R<JValue, _> { json::parse(&s) }),
("json", "stringify") => unary(args, |v: JValue| -> R<String, _> { Ok(json::stringify(v)) }),
("json", "obj_pairs") => unary(args, |vs: Vec<(String, JValue)>| -> R<JValue, _> { json::obj_from_pairs(vs) }),
("json", "puts_pairs") => binary(args, |obj: JValue, vs: Vec<(String, JValue)>| -> R<JValue, _> { json::puts_from_pairs(obj, vs) }),

("run-console", "print") => wrap_unit(Ok(log::debug!(target: "run-console", "{}", json!(args.function_args)))),

_ => FunctionOutcome::NotDefined { args, params: particle },
}
Expand Down Expand Up @@ -943,6 +952,49 @@ where
fn get_peer_id(&self) -> Result<JValue, JError> {
Ok(JValue::String(self.root_keypair.get_peer_id().to_base58()))
}

fn insecure_sign(&self, args: Args) -> Result<JValue, JError> {
let mut args = args.function_args.into_iter();
let result: Result<JValue, JError> = try {
let data: Vec<u8> = Args::next("data", &mut args)?;
json!(self.insecure_keypair.sign(&data)?.to_vec())
};

match result {
Ok(sig) => Ok(json!({
"success": true,
"error": [],
"signature": vec![sig]
})),

Err(error) => Ok(json!({
"success": false,
"error": vec![JValue::from(error)],
"signature": []
})),
}
}

fn insecure_verify(&self, args: Args) -> Result<JValue, JError> {
let mut args = args.function_args.into_iter();
let signature: Vec<u8> = Args::next("signature", &mut args)?;
let data: Vec<u8> = Args::next("data", &mut args)?;
let signature =
Signature::from_bytes(self.insecure_keypair.public().get_key_format(), signature);

Ok(JValue::Bool(
self.insecure_keypair
.public()
.verify(&data, &signature)
.is_ok(),
))
}

fn insecure_get_peer_id(&self) -> Result<JValue, JError> {
Ok(JValue::String(
self.insecure_keypair.get_peer_id().to_base58(),
))
}
}

fn make_module_config(args: Args) -> Result<JValue, JError> {
Expand Down

0 comments on commit 9727c3f

Please sign in to comment.