From a9666a9058fae981e2e8424cc6d0ef39c90d243a Mon Sep 17 00:00:00 2001 From: Cassandra Heart Date: Wed, 18 Dec 2024 23:43:56 -0600 Subject: [PATCH] pre-stage state for milestone 2 merge --- Cargo.lock | 15 +- Cargo.toml | 1 + crates/channel-wasm/Cargo.lock | 7 + crates/channel-wasm/Cargo.toml | 15 ++ crates/channel-wasm/src/lib.rs | 154 ++++++++++++++++++ crates/channel/src/lib.rs | 37 +++-- crates/channel/src/protocols/doubleratchet.rs | 1 + 7 files changed, 211 insertions(+), 19 deletions(-) create mode 100644 crates/channel-wasm/Cargo.lock create mode 100644 crates/channel-wasm/Cargo.toml create mode 100644 crates/channel-wasm/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index 8cc1928..583f3d1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aead" @@ -354,6 +354,17 @@ dependencies = [ "uniffi", ] +[[package]] +name = "channelwasm" +version = "0.1.0" +dependencies = [ + "channel", + "getrandom", + "serde", + "serde_json", + "wasm-bindgen", +] + [[package]] name = "ciborium" version = "0.2.2" @@ -774,8 +785,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" dependencies = [ "cfg-if", + "js-sys", "libc", "wasi", + "wasm-bindgen", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b4ca0ee..a4c8196 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ members = [ "crates/vdf", "crates/channel", + "crates/channel-wasm", "crates/classgroup", "crates/bls48581", "crates/rpm", diff --git a/crates/channel-wasm/Cargo.lock b/crates/channel-wasm/Cargo.lock new file mode 100644 index 0000000..cadec0d --- /dev/null +++ b/crates/channel-wasm/Cargo.lock @@ -0,0 +1,7 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +version = 3 + +[[package]] +name = "channel" +version = "0.1.0" diff --git a/crates/channel-wasm/Cargo.toml b/crates/channel-wasm/Cargo.toml new file mode 100644 index 0000000..14fed50 --- /dev/null +++ b/crates/channel-wasm/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "channelwasm" +version = "0.1.0" +edition = "2021" + +[lib] +crate-type = ["cdylib"] +name = "channelwasm" + +[dependencies] +wasm-bindgen = "0.2" +channel = { path = "../channel", version = "^0.1.0" } +getrandom = { version = "0.2", features = ["js"] } +serde = "1.0.208" +serde_json = "1.0.117" diff --git a/crates/channel-wasm/src/lib.rs b/crates/channel-wasm/src/lib.rs new file mode 100644 index 0000000..b705f19 --- /dev/null +++ b/crates/channel-wasm/src/lib.rs @@ -0,0 +1,154 @@ +use wasm_bindgen::prelude::*; +use channel::*; +use serde::{Deserialize, Serialize}; + +#[derive(Clone, PartialEq, Serialize, Deserialize)] +pub struct NewDoubleRatchetParameters { + pub session_key: Vec, + pub sending_header_key: Vec, + pub next_receiving_header_key: Vec, + pub is_sender: bool, + pub sending_ephemeral_private_key: Vec, + pub receiving_ephemeral_key: Vec +} + +#[derive(Clone, PartialEq, Serialize, Deserialize)] +pub struct NewTripleRatchetParameters { + pub peers: Vec>, + pub peer_key: Vec, + pub identity_key: Vec, + pub signed_pre_key: Vec, + pub threshold: u64, + pub async_dkg_ratchet: bool +} + +#[wasm_bindgen] +pub fn js_new_double_ratchet(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(inputs) => { + return new_double_ratchet(&inputs.session_key, &inputs.sending_header_key, &inputs.next_receiving_header_key, inputs.is_sender, &inputs.sending_ephemeral_private_key, &inputs.receiving_ephemeral_key); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_double_ratchet_encrypt(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(ratchet_state_and_message) => { + return serde_json::to_string(&double_ratchet_encrypt(ratchet_state_and_message)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_double_ratchet_decrypt(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(ratchet_state_and_envelope) => { + return serde_json::to_string(&double_ratchet_decrypt(ratchet_state_and_envelope)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_new_triple_ratchet(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(input) => { + return serde_json::to_string(&new_triple_ratchet(&input.peers, &input.peer_key, &input.identity_key, &input.signed_pre_key, input.threshold, input.async_dkg_ratchet)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_triple_ratchet_init_round_1(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(ratchet_state_and_metadata) => { + return serde_json::to_string(&triple_ratchet_init_round_1(ratchet_state_and_metadata)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_triple_ratchet_init_round_2(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(ratchet_state_and_metadata) => { + return serde_json::to_string(&triple_ratchet_init_round_2(ratchet_state_and_metadata)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_triple_ratchet_init_round_3(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(ratchet_state_and_metadata) => { + return serde_json::to_string(&triple_ratchet_init_round_3(ratchet_state_and_metadata)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_triple_ratchet_init_round_4(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(ratchet_state_and_metadata) => { + return serde_json::to_string(&triple_ratchet_init_round_4(ratchet_state_and_metadata)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_triple_ratchet_encrypt(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(ratchet_state_and_message) => { + return serde_json::to_string(&triple_ratchet_encrypt(ratchet_state_and_message)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + +#[wasm_bindgen] +pub fn js_triple_ratchet_decrypt(params: &str) -> String { + let json: Result = serde_json::from_str(params); + match json { + Ok(ratchet_state_and_envelope) => { + return serde_json::to_string(&triple_ratchet_decrypt(ratchet_state_and_envelope)).unwrap_or_else(|e| e.to_string()); + } + Err(e) => { + return e.to_string(); + } + } +} + diff --git a/crates/channel/src/lib.rs b/crates/channel/src/lib.rs index 00f9740..682eb5c 100644 --- a/crates/channel/src/lib.rs +++ b/crates/channel/src/lib.rs @@ -1,4 +1,5 @@ use base64::prelude::*; +use serde::{Deserialize, Serialize}; use std::collections::HashMap; use ed448_goldilocks_plus::{elliptic_curve::group::GroupEncoding, EdwardsPoint, Scalar}; @@ -8,31 +9,31 @@ pub(crate) mod protocols; uniffi::include_scaffolding!("lib"); -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Serialize, Deserialize)] pub struct DoubleRatchetStateAndEnvelope { pub ratchet_state: String, pub envelope: String, } -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Serialize, Deserialize)] pub struct DoubleRatchetStateAndMessage { pub ratchet_state: String, pub message: Vec, } -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Serialize, Deserialize)] pub struct TripleRatchetStateAndMetadata { pub ratchet_state: String, pub metadata: HashMap, } -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Serialize, Deserialize)] pub struct TripleRatchetStateAndEnvelope { pub ratchet_state: String, pub envelope: String, } -#[derive(Clone, PartialEq)] +#[derive(Clone, PartialEq, Serialize, Deserialize)] pub struct TripleRatchetStateAndMessage { pub ratchet_state: String, pub message: Vec, @@ -40,11 +41,11 @@ pub struct TripleRatchetStateAndMessage { pub fn new_double_ratchet(session_key: &Vec, sending_header_key: &Vec, next_receiving_header_key: &Vec, is_sender: bool, sending_ephemeral_private_key: &Vec, receiving_ephemeral_key: &Vec) -> String { if sending_ephemeral_private_key.len() != 56 { - return "".to_string(); + return "invalid private key length".to_string(); } if receiving_ephemeral_key.len() != 57 { - return "".to_string(); + return "invalid public key length".to_string(); } let mut sending_ephemeral_private_key_bytes = [0u8; 56]; @@ -56,7 +57,7 @@ pub fn new_double_ratchet(session_key: &Vec, sending_header_key: &Vec, n let sending_key = Scalar::from_bytes(&sending_ephemeral_private_key_bytes.into()); let receiving_key = EdwardsPoint::from_bytes(&receiving_ephemeral_key_bytes.into()).into_option(); if receiving_key.is_none() { - return "".to_string(); + return "invalid receiving key".to_string(); } let participant = DoubleRatchetParticipant::new( @@ -69,12 +70,12 @@ pub fn new_double_ratchet(session_key: &Vec, sending_header_key: &Vec, n ); if participant.is_err() { - return "".to_string(); + return participant.unwrap_err().to_string(); } let json = participant.unwrap().to_json(); if json.is_err() { - return "".to_string(); + return json.unwrap_err().to_string(); } return json.unwrap(); @@ -86,7 +87,7 @@ pub fn double_ratchet_encrypt(ratchet_state_and_message: DoubleRatchetStateAndMe if participant.is_err() { return DoubleRatchetStateAndEnvelope{ - ratchet_state: ratchet_state, + ratchet_state: participant.unwrap_err().to_string(), envelope: "".to_string(), }; } @@ -97,7 +98,7 @@ pub fn double_ratchet_encrypt(ratchet_state_and_message: DoubleRatchetStateAndMe if envelope.is_err() { return DoubleRatchetStateAndEnvelope{ ratchet_state: ratchet_state, - envelope: "".to_string(), + envelope: envelope.unwrap_err().to_string(), }; } @@ -105,7 +106,7 @@ pub fn double_ratchet_encrypt(ratchet_state_and_message: DoubleRatchetStateAndMe let participant_json = dr.to_json(); if participant_json.is_err() { return DoubleRatchetStateAndEnvelope{ - ratchet_state: ratchet_state, + ratchet_state: participant_json.unwrap_err().to_string(), envelope: "".to_string(), }; } @@ -114,7 +115,7 @@ pub fn double_ratchet_encrypt(ratchet_state_and_message: DoubleRatchetStateAndMe if envelope_json.is_err() { return DoubleRatchetStateAndEnvelope{ ratchet_state: ratchet_state, - envelope: "".to_string(), + envelope: envelope_json.unwrap_err().to_string(), }; } @@ -142,14 +143,14 @@ pub fn double_ratchet_decrypt(ratchet_state_and_envelope: DoubleRatchetStateAndE if message.is_err() { return DoubleRatchetStateAndMessage{ ratchet_state: ratchet_state, - message: vec![], + message: message.unwrap_err().to_string().as_bytes().to_vec(), }; } let participant_json = dr.to_json(); if participant_json.is_err() { return DoubleRatchetStateAndMessage{ - ratchet_state: ratchet_state, + ratchet_state: participant_json.unwrap_err().to_string(), message: vec![], }; } @@ -170,14 +171,14 @@ pub fn new_triple_ratchet(peers: &Vec>, peer_key: &Vec, identity_key if identity_key.len() != 56 { return TripleRatchetStateAndMetadata{ - ratchet_state: "invalid idk".to_string(), + ratchet_state: "invalid identity key".to_string(), metadata: HashMap::new(), }; } if signed_pre_key.len() != 56 { return TripleRatchetStateAndMetadata{ - ratchet_state: "invalid spk".to_string(), + ratchet_state: "invalid signed pre key".to_string(), metadata: HashMap::new(), }; } diff --git a/crates/channel/src/protocols/doubleratchet.rs b/crates/channel/src/protocols/doubleratchet.rs index a828305..9ad2fcf 100644 --- a/crates/channel/src/protocols/doubleratchet.rs +++ b/crates/channel/src/protocols/doubleratchet.rs @@ -20,6 +20,7 @@ const CHAIN_KEY: u8 = 0x01; const MESSAGE_KEY: u8 = 0x02; const AEAD_KEY: u8 = 0x03; +#[derive(Debug)] pub struct DoubleRatchetParticipant { sending_ephemeral_private_key: Scalar, receiving_ephemeral_key: EdwardsPoint,