Skip to content

Commit

Permalink
Experimental mmpke feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Marta Mularczyk committed Feb 5, 2024
1 parent 3c57e91 commit bc2b38b
Show file tree
Hide file tree
Showing 21 changed files with 684 additions and 272 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/fuzz.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
run: cargo fmt --all -- --check
- name: Clippy on fuzz targets
working-directory: mls-rs/fuzz
run: cargo clippy --all-targets --all-features --workspace -- -D warnings
run: cargo clippy --all-targets -- -D warnings
- name: Run Fuzz Targets
working-directory: mls-rs
run: |
Expand Down
8 changes: 4 additions & 4 deletions .github/workflows/native_build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,21 +31,21 @@ jobs:
- name: Rust Fmt
run: cargo fmt --all -- --check
- name: Clippy Full RFC Compliance
run: cargo clippy --all-targets --all-features --workspace -- -D warnings
run: cargo clippy --all-targets --features external_client,grease --workspace -- -D warnings
- name: Clippy Bare Bones
run: cargo clippy --all-targets --no-default-features --features std,test_util --workspace -- -D warnings
- name: Test Full RFC Compliance
run: cargo test --all-features --verbose --workspace
run: cargo test --features external_client,grease --verbose --workspace
- name: Test Bare Bones
run: cargo test --no-default-features --features std,test_util --verbose --workspace
- name: Test Async Full RFC
run: cargo test --lib --test '*' --verbose --features test_util -p mls-rs
env:
RUSTFLAGS: '--cfg mls_build_async'
RUSTFLAGS: "--cfg mls_build_async"
- name: Test Async Bare Bones
run: cargo test --no-default-features --lib --test '*' --features std,test_util --verbose -p mls-rs
env:
RUSTFLAGS: '--cfg mls_build_async'
RUSTFLAGS: "--cfg mls_build_async"
- name: Examples
working-directory: mls-rs
run: cargo run --example basic_usage
Expand Down
6 changes: 4 additions & 2 deletions mls-rs-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,16 @@ keywords = ["mls", "mls-rs"]
license = "Apache-2.0 OR MIT"
exclude = ["test_data"]


[features]
default = ["std", "rfc_compliant", "fast_serialize"]
default = ["std", "rfc_compliant", "fast_serialize", "rayon"]
arbitrary = ["std", "dep:arbitrary"]
fast_serialize = ["mls-rs-codec/preallocate"]
std = ["mls-rs-codec/std", "zeroize/std", "safer-ffi-gen?/std", "dep:thiserror"]
rfc_compliant = ["x509"]
ffi = ["dep:safer-ffi", "dep:safer-ffi-gen"]
x509 = []
test_suite = ["dep:serde", "dep:serde_json", "dep:hex", "dep:itertools"]
rayon = ["std", "dep:rayon"]

[dependencies]
mls-rs-codec = { version = "0.5.0", path = "../mls-rs-codec", default-features = false}
Expand All @@ -28,6 +28,8 @@ thiserror = { version = "1.0.40", optional = true }
safer-ffi = { version = "0.1.3", default-features = false, optional = true }
safer-ffi-gen = { version = "0.9.2", default-features = false, optional = true }
maybe-async = "0.2.7"
# TODO: https://github.com/GoogleChromeLabs/wasm-bindgen-rayon
rayon = { version = "1", optional = true }

serde = { version = "1.0", default-features = false, features = ["alloc", "derive"], optional = true }
serde_json = { version = "^1.0", optional = true }
Expand Down
32 changes: 28 additions & 4 deletions mls-rs-core/src/crypto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,14 @@ use mls_rs_codec::{MlsDecode, MlsEncode, MlsSize};
use zeroize::{ZeroizeOnDrop, Zeroizing};

mod cipher_suite;
pub use self::cipher_suite::*;
mod mm_hpke;

#[cfg(feature = "test_suite")]
pub mod test_suite;

pub use self::cipher_suite::*;
use self::mm_hpke::{mm_hpke_open, mm_hpke_seal};

#[derive(Clone, Debug, PartialEq, Eq, MlsSize, MlsEncode, MlsDecode)]
#[cfg_attr(feature = "arbitrary", derive(arbitrary::Arbitrary))]
/// Ciphertext produced by [`CipherSuiteProvider::hpke_seal`]
Expand Down Expand Up @@ -242,8 +245,8 @@ pub trait CryptoProvider: Send + Sync {
all(not(target_arch = "wasm32"), mls_build_async),
maybe_async::must_be_async
)]
pub trait CipherSuiteProvider: Send + Sync {
type Error: IntoAnyError;
pub trait CipherSuiteProvider: Send + Sync + Sized {
type Error: IntoAnyError + Send + Sync;

type HpkeContextS: HpkeContextS + Send + Sync;
type HpkeContextR: HpkeContextR + Send + Sync;
Expand Down Expand Up @@ -380,7 +383,6 @@ pub trait CipherSuiteProvider: Send + Sync {
kem_output: &[u8],
local_secret: &HpkeSecretKey,
local_public: &HpkePublicKey,

info: &[u8],
) -> Result<Self::HpkeContextR, Self::Error>;

Expand Down Expand Up @@ -436,4 +438,26 @@ pub trait CipherSuiteProvider: Send + Sync {
signature: &[u8],
data: &[u8],
) -> Result<(), Self::Error>;

async fn mm_hpke_seal(
&self,
info: &[u8],
aad: Option<&[u8]>,
pt: &[&[u8]],
remote_keys: &[Vec<&HpkePublicKey>],
) -> Result<Vec<Vec<HpkeCiphertext>>, Self::Error> {
mm_hpke_seal(self, info, aad, pt, remote_keys).await
}

async fn mm_hpke_open(
&self,
ct: &[&[HpkeCiphertext]],
self_index: (usize, usize),
local_secret: &HpkeSecretKey,
local_public: &HpkePublicKey,
info: &[u8],
aad: Option<&[u8]>,
) -> Result<Option<Vec<u8>>, Self::Error> {
mm_hpke_open(self, ct, self_index, local_secret, local_public, info, aad).await
}
}
72 changes: 72 additions & 0 deletions mls-rs-core/src/crypto/mm_hpke.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
use alloc::vec::Vec;

#[cfg(all(not(mls_build_async), feature = "rayon"))]
use rayon::iter::{IntoParallelRefIterator, ParallelIterator};

use super::{CipherSuiteProvider, HpkeCiphertext, HpkePublicKey, HpkeSecretKey};

#[cfg(all(not(mls_build_async), feature = "rayon"))]
pub(crate) fn mm_hpke_seal<P: CipherSuiteProvider>(
cs: &P,
info: &[u8],
aad: Option<&[u8]>,
pt: &[&[u8]],
remote_keys: &[Vec<&HpkePublicKey>],
) -> Result<Vec<Vec<HpkeCiphertext>>, P::Error> {
use rayon::iter::IndexedParallelIterator;

pt.par_iter()
.zip(remote_keys.par_iter())
.map(|(pt, remote_keys)| {
remote_keys
.par_iter()
.map(|remote_pub| cs.hpke_seal(remote_pub, info, aad, pt))
.collect::<Result<_, _>>()
})
.collect()
}

#[cfg(any(mls_build_async, not(feature = "rayon")))]
#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
pub(crate) async fn mm_hpke_seal<P: CipherSuiteProvider>(
cs: &P,
info: &[u8],
aad: Option<&[u8]>,
pt: &[&[u8]],
remote_keys: &[Vec<&HpkePublicKey>],
) -> Result<Vec<Vec<HpkeCiphertext>>, P::Error> {
let mut ct = Vec::new();

for (pt, remote_keys) in pt.iter().zip(remote_keys.iter()) {
ct.push(Vec::new());

for remote_pub in remote_keys {
if let Some(ct) = ct.last_mut() {
ct.push(cs.hpke_seal(remote_pub, info, aad, pt).await?);
}
}
}

Ok(ct)
}

#[cfg_attr(not(mls_build_async), maybe_async::must_be_sync)]
pub(crate) async fn mm_hpke_open<P: CipherSuiteProvider>(
cs: &P,
ct: &[&[HpkeCiphertext]],
self_index: (usize, usize),
local_secret: &HpkeSecretKey,
local_public: &HpkePublicKey,
info: &[u8],
aad: Option<&[u8]>,
) -> Result<Option<Vec<u8>>, P::Error> {
let (i, j) = self_index;

match ct.get(i).and_then(|ct| ct.get(j)) {
Some(ct) => Ok(Some(
cs.hpke_open(ct, local_secret, local_public, info, aad)
.await?,
)),
None => Ok(None),
}
}
11 changes: 8 additions & 3 deletions mls-rs-crypto-awslc/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,17 @@ repository = "https://github.com/awslabs/mls-rs"
keywords = ["mls", "mls-rs", "aws-lc"]
license = "Apache-2.0 OR MIT"

[features]
default = ["rayon"]
rayon = ["mls-rs-crypto-hpke/rayon"]
mmpke = ["mls-rs-crypto-hpke/mmpke"]

[dependencies]
aws-lc-rs = "1.5.1"
aws-lc-sys = { version = "0.12.0" }
mls-rs-core = { path = "../mls-rs-core", version = "0.17.0" }
mls-rs-crypto-hpke = { path = "../mls-rs-crypto-hpke", version = "0.8.0" }
mls-rs-crypto-traits = { path = "../mls-rs-crypto-traits", version = "0.9.0" }
mls-rs-core = { path = "../mls-rs-core", version = "0.17.0", default-features = false }
mls-rs-crypto-hpke = { path = "../mls-rs-crypto-hpke", version = "0.8.0", default-features = false, features = ["std"] }
mls-rs-crypto-traits = { path = "../mls-rs-crypto-traits", version = "0.9.0", default-features = false }
mls-rs-identity-x509 = { path = "../mls-rs-identity-x509", version = "0.10.0" }
thiserror = "1.0.40"
zeroize = { version = "1", features = ["zeroize_derive"] }
Expand Down
27 changes: 27 additions & 0 deletions mls-rs-crypto-awslc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,33 @@ impl CipherSuiteProvider for AwsLcCipherSuite {
) -> Result<(), Self::Error> {
self.signing.verify(public_key, signature, data)
}

#[cfg(feature = "mmpke")]
async fn mm_hpke_seal(
&self,
info: &[u8],
aad: Option<&[u8]>,
pt: &[&[u8]],
remote_keys: &[Vec<&HpkePublicKey>],
) -> Result<Vec<Vec<HpkeCiphertext>>, Self::Error> {
Ok(self.hpke.mm_hpke_seal(info, aad, pt, remote_keys).await?)
}

#[cfg(feature = "mmpke")]
async fn mm_hpke_open(
&self,
ct: &[&[HpkeCiphertext]],
self_index: (usize, usize),
local_secret: &HpkeSecretKey,
local_public: &HpkePublicKey,
info: &[u8],
aad: Option<&[u8]>,
) -> Result<Option<Vec<u8>>, Self::Error> {
Ok(self
.hpke
.mm_hpke_open(ct, self_index, local_secret, local_public, info, aad)
.await?)
}
}

pub fn sha256(data: &[u8]) -> [u8; 32] {
Expand Down
6 changes: 5 additions & 1 deletion mls-rs-crypto-hpke/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,11 @@ categories = ["no-std", "cryptography"]
license = "Apache-2.0 OR MIT"

[features]
default = ["std"]
default = ["std", "rayon"]
std = ["mls-rs-core/std", "mls-rs-crypto-traits/std", "dep:thiserror", "zeroize/std"]
test_utils = ["mls-rs-core/test_suite"]
rayon = ["std", "dep:rayon", "mls-rs-core/rayon"]
mmpke = []

[dependencies]
mls-rs-core = { path = "../mls-rs-core", default-features = false, version = "0.17.0" }
Expand All @@ -21,6 +23,8 @@ thiserror = { version = "1.0.40", optional = true }
zeroize = { version = "1", default-features = false, features = ["alloc", "zeroize_derive"] }
cfg-if = "^1"
maybe-async = "0.2.7"
# TODO: https://github.com/GoogleChromeLabs/wasm-bindgen-rayon
rayon = { version = "1", optional = true }

[dev-dependencies]
serde = { version = "1.0", features = ["derive"] }
Expand Down
Loading

0 comments on commit bc2b38b

Please sign in to comment.