diff --git a/Cargo.lock b/Cargo.lock index 0932d25..0f8153e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -465,18 +465,11 @@ dependencies = [ "hybrid-array", "ml-kem", "rand_core", - "wharrgarbl-core", "wharrgarbl-strobe", + "wharrgarbl-utils", "zeroize", ] -[[package]] -name = "wharrgarbl-core" -version = "0.1.0" -dependencies = [ - "aead", -] - [[package]] name = "wharrgarbl-strobe" version = "0.1.0" @@ -489,10 +482,17 @@ dependencies = [ "serde", "serde-big-array", "serde_json", - "wharrgarbl-core", + "wharrgarbl-utils", "zeroize", ] +[[package]] +name = "wharrgarbl-utils" +version = "0.1.0" +dependencies = [ + "aead", +] + [[package]] name = "wit-bindgen" version = "0.51.0" diff --git a/Cargo.toml b/Cargo.toml index 2367dca..c6c7b19 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "3" -members = ["wharrgarbl-core", "wharrgarbl-strobe"] +members = ["wharrgarbl-utils", "wharrgarbl-strobe"] [workspace.package] authors = ["Sachy.dev "] @@ -27,7 +27,7 @@ authors.workspace = true parallel = ["wharrgarbl-strobe/parallel"] [dependencies] -wharrgarbl-core = { path = "./wharrgarbl-core", version = "0.1" } +wharrgarbl-utils = { path = "./wharrgarbl-utils", version = "0.1" } wharrgarbl-strobe = { path = "./wharrgarbl-strobe", version = "0.1" } ctutils.workspace = true zeroize.workspace = true diff --git a/src/handshake.rs b/src/handshake.rs index 0fa49db..a7e9b8f 100644 --- a/src/handshake.rs +++ b/src/handshake.rs @@ -1,8 +1,7 @@ use aead::Buffer; use hybrid_array::typenum::Unsigned; use rand_core::CryptoRng; -use wharrgarbl_core::Role; -use wharrgarbl_strobe::{StrobeSecurity, StrobeState}; +use wharrgarbl_strobe::{StrobeRole, StrobeSecurity, StrobeState}; use crate::{ WHARRGHARBL_PROTO, @@ -19,7 +18,8 @@ pub struct ClientHandshake { impl ClientHandshake { pub fn new(kem_sec: KemSecurity, sec_param: StrobeSecurity, psk: Option<&[u8; 32]>) -> Self { - let mut strobe = StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), sec_param, Role::Sender); + let mut strobe = + StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), sec_param, StrobeRole::Sender); if let Some(psk) = psk { strobe.key(psk); @@ -87,7 +87,7 @@ impl ClientHandshake { self.strobe.prf(&mut inbound); self.strobe.prf(&mut outbound); - AeadState::new(key, self.sec_param, outbound, inbound, Role::Sender) + AeadState::new(key, self.sec_param, outbound, inbound, StrobeRole::Sender) } } @@ -99,7 +99,11 @@ pub struct ServerHandshake { impl ServerHandshake { pub fn new(kem_sec: KemSecurity, sec_param: StrobeSecurity, psk: Option<&[u8; 32]>) -> Self { - let mut strobe = StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), sec_param, Role::Receiver); + let mut strobe = StrobeState::new( + WHARRGHARBL_PROTO.as_bytes(), + sec_param, + StrobeRole::Receiver, + ); if let Some(psk) = psk { strobe.key(psk); @@ -162,13 +166,13 @@ impl ServerHandshake { self.strobe.prf(&mut inbound); self.strobe.prf(&mut outbound); - AeadState::new(key, self.sec_param, outbound, inbound, Role::Receiver) + AeadState::new(key, self.sec_param, outbound, inbound, StrobeRole::Receiver) } } #[cfg(test)] mod tests { - use wharrgarbl_core::BufferSlice; + use crate::utils::BufferSlice; use super::*; diff --git a/src/lib.rs b/src/lib.rs index da78c80..7b9f08f 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -7,6 +7,9 @@ pub mod transport; extern crate alloc; -/// Version of Strobe that this crate implements. -pub static STROBE_VERSION: &str = "1.0.2"; +/// Version of WHARRGARBL that this crate implements. pub static WHARRGHARBL_PROTO: &str = "WGBL-v0.0-STv1.0.2"; + +pub mod utils { + pub use wharrgarbl_utils::BufferSlice; +} diff --git a/src/transport.rs b/src/transport.rs index ce0f3cd..a8ef2c2 100644 --- a/src/transport.rs +++ b/src/transport.rs @@ -3,8 +3,7 @@ use aead::{ consts::{U16, U32}, }; use ctutils::{CtEq, CtSelect}; -use wharrgarbl_core::Role; -use wharrgarbl_strobe::{StrobeSecurity, StrobeState}; +use wharrgarbl_strobe::{StrobeRole, StrobeSecurity, StrobeState}; use crate::WHARRGHARBL_PROTO; @@ -31,7 +30,8 @@ impl aead::AeadInOut for AeadStrobe { mut buffer: aead::inout::InOutBuf<'_, '_, u8>, ) -> aead::Result> { let mut tag: aead::Tag = Default::default(); - let mut strobe = StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), self.param, Role::Sender); + let mut strobe = + StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), self.param, StrobeRole::Sender); strobe.key(&self.key); strobe.meta_ad(&self.param.to_bytes()); @@ -51,7 +51,11 @@ impl aead::AeadInOut for AeadStrobe { mut buffer: aead::inout::InOutBuf<'_, '_, u8>, tag: &aead::Tag, ) -> aead::Result<()> { - let mut strobe = StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), self.param, Role::Receiver); + let mut strobe = StrobeState::new( + WHARRGHARBL_PROTO.as_bytes(), + self.param, + StrobeRole::Receiver, + ); strobe.key(&self.key); strobe.meta_ad(&self.param.to_bytes()); @@ -73,7 +77,7 @@ pub struct AeadState { pub(crate) aead: AeadStrobe, pub(crate) epstein: aead::Nonce, pub(crate) trump: aead::Nonce, - role: Role, + handshake_role: StrobeRole, } impl zeroize::Zeroize for AeadState { @@ -98,7 +102,7 @@ impl AeadState { sec: StrobeSecurity, outbound: aead::Nonce, inbound: aead::Nonce, - role: Role, + role: StrobeRole, ) -> Self { assert_ne!( &inbound, &outbound, @@ -109,18 +113,18 @@ impl AeadState { aead: AeadStrobe { key, param: sec }, epstein: outbound, trump: inbound, - role, + handshake_role: role, } } - fn select_nonce(&self, role: Role) -> aead::Nonce { - let role_context = self.role ^ role; + fn select_nonce(&self, sending_role: StrobeRole) -> aead::Nonce { + let role_context = self.handshake_role ^ sending_role; self.epstein.ct_select(&self.trump, role_context.ct_eq(&1)) } - fn mix_nonce(&self, position: [u8; 8], role: Role) -> aead::Nonce { - let mut nonce = self.select_nonce(role); + fn mix_nonce(&self, position: [u8; 8], sending_role: StrobeRole) -> aead::Nonce { + let mut nonce = self.select_nonce(sending_role); let mid = nonce.len() - position.len(); @@ -160,7 +164,7 @@ impl SendState<'_> { let encryption_result = self.transport.aead.encrypt_in_place( &self .transport - .mix_nonce(self.counter.to_be_bytes(), Role::Sender), + .mix_nonce(self.counter.to_be_bytes(), StrobeRole::Sender), ad, buffer, ); @@ -186,7 +190,7 @@ impl RecvState<'_> { let decryption_result = self.transport.aead.decrypt_in_place( &self .transport - .mix_nonce(self.counter.to_be_bytes(), Role::Receiver), + .mix_nonce(self.counter.to_be_bytes(), StrobeRole::Receiver), ad, buffer, ); @@ -217,14 +221,14 @@ mod tests { StrobeSecurity::B128, outbound.into(), inbound.into(), - Role::Sender, + StrobeRole::Sender, ); let bob = AeadState::new( shared_secret.into(), StrobeSecurity::B128, outbound.into(), inbound.into(), - Role::Receiver, + StrobeRole::Receiver, ); let (mut alice_send, mut alice_recv) = alice.split(); @@ -292,14 +296,14 @@ mod tests { StrobeSecurity::B128, outbound.into(), inbound.into(), - Role::Sender, + StrobeRole::Sender, ); let bob = AeadState::new( shared_secret.into(), StrobeSecurity::B256, outbound.into(), inbound.into(), - Role::Receiver, + StrobeRole::Receiver, ); let (mut alice_send, mut _alice_recv) = alice.split(); diff --git a/wharrgarbl-strobe/Cargo.toml b/wharrgarbl-strobe/Cargo.toml index 48b4541..d22f4bf 100644 --- a/wharrgarbl-strobe/Cargo.toml +++ b/wharrgarbl-strobe/Cargo.toml @@ -11,7 +11,7 @@ license.workspace = true parallel = ["keccak/parallel"] [dependencies] -wharrgarbl-core = { path = "../wharrgarbl-core", version = "0.1" } +wharrgarbl-utils = { path = "../wharrgarbl-utils", version = "0.1" } aead.workspace = true zeroize.workspace = true ctutils.workspace = true diff --git a/wharrgarbl-strobe/src/basic_kats.rs b/wharrgarbl-strobe/src/basic_kats.rs index 8d404a6..0e5409c 100644 --- a/wharrgarbl-strobe/src/basic_kats.rs +++ b/wharrgarbl-strobe/src/basic_kats.rs @@ -6,15 +6,14 @@ use aead::consts::{U16, U65}; use hybrid_array::Array; -use wharrgarbl_core::Role; -use crate::{StrobeSecurity, keccakf::KECCAK_BUFFER_SIZE, strobe::StrobeState}; +use crate::{StrobeRole, StrobeSecurity, keccakf::KECCAK_BUFFER_SIZE, strobe::StrobeState}; extern crate std; #[test] fn test_init_128() { - let s = StrobeState::new(b"", StrobeSecurity::B128, Role::Sender); + let s = StrobeState::new(b"", StrobeSecurity::B128, StrobeRole::Sender); let expected_st: [u8; KECCAK_BUFFER_SIZE] = [ 0x9c, 0x7f, 0x16, 0x8f, 0xf8, 0xfd, 0x55, 0xda, 0x2a, 0xa7, 0x3c, 0x23, 0x55, 0x65, 0x35, @@ -38,7 +37,7 @@ fn test_init_128() { #[test] fn test_init_256() { - let s = StrobeState::new(b"", StrobeSecurity::B256, Role::Sender); + let s = StrobeState::new(b"", StrobeSecurity::B256, StrobeRole::Sender); let expected_st: [u8; KECCAK_BUFFER_SIZE] = [ 0x37, 0xc1, 0x15, 0x06, 0xed, 0x61, 0xe7, 0xda, 0x7c, 0x1a, 0x2f, 0x2c, 0x1f, 0x49, 0x74, @@ -63,7 +62,7 @@ fn test_init_256() { #[test] fn test_metadata() { // We will accumulate output over 3 operations and 3 meta-operations - let mut s = StrobeState::new(b"metadatatest", StrobeSecurity::B256, Role::Sender); + let mut s = StrobeState::new(b"metadatatest", StrobeSecurity::B256, StrobeRole::Sender); let mut output = std::vec::Vec::new(); let buf = b"meta1"; @@ -117,7 +116,7 @@ fn test_metadata() { #[test] fn test_seq() { - let mut s = StrobeState::new(b"seqtest", StrobeSecurity::B256, Role::Sender); + let mut s = StrobeState::new(b"seqtest", StrobeSecurity::B256, StrobeRole::Sender); let mut buf = [0u8; 10]; s.prf(&mut buf[..]); @@ -173,8 +172,16 @@ fn test_seq() { #[test] fn test_enc_correctness() { let orig_msg = b"Hello there"; - let mut tx = StrobeState::new(b"enccorrectnesstest", StrobeSecurity::B256, Role::Sender); - let mut rx = StrobeState::new(b"enccorrectnesstest", StrobeSecurity::B256, Role::Receiver); + let mut tx = StrobeState::new( + b"enccorrectnesstest", + StrobeSecurity::B256, + StrobeRole::Sender, + ); + let mut rx = StrobeState::new( + b"enccorrectnesstest", + StrobeSecurity::B256, + StrobeRole::Receiver, + ); tx.key(b"the-combination-on-my-luggage"); rx.key(b"the-combination-on-my-luggage"); @@ -189,8 +196,8 @@ fn test_enc_correctness() { #[test] fn test_mac_correctness_and_soundness() { - let mut tx = StrobeState::new(b"mactest", StrobeSecurity::B256, Role::Sender); - let mut rx = StrobeState::new(b"mactest", StrobeSecurity::B256, Role::Receiver); + let mut tx = StrobeState::new(b"mactest", StrobeSecurity::B256, StrobeRole::Sender); + let mut rx = StrobeState::new(b"mactest", StrobeSecurity::B256, StrobeRole::Receiver); // Just do some stuff with the state @@ -218,7 +225,7 @@ fn test_mac_correctness_and_soundness() { #[test] fn test_long_inputs() { - let mut s = StrobeState::new(b"bigtest", StrobeSecurity::B256, Role::Sender); + let mut s = StrobeState::new(b"bigtest", StrobeSecurity::B256, StrobeRole::Sender); const BIG_N: usize = 9823; const SMALL_N: usize = 65; let big_data = [0x34u8; BIG_N]; @@ -275,7 +282,7 @@ fn test_long_inputs() { fn test_streaming_correctness() { // Compute a few things without breaking up their inputs let one_shot_st: std::vec::Vec = { - let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, Role::Receiver); + let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, StrobeRole::Receiver); s.ad(b"mynonce"); @@ -291,7 +298,7 @@ fn test_streaming_correctness() { }; // Now do the same thing but stream the inputs let streamed_st: std::vec::Vec = { - let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, Role::Receiver); + let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, StrobeRole::Receiver); s.ad(b"my"); s.ad(b"nonce"); diff --git a/wharrgarbl-strobe/src/herding_kats/harness.rs b/wharrgarbl-strobe/src/herding_kats/harness.rs index 6a86ae0..99c6b2e 100644 --- a/wharrgarbl-strobe/src/herding_kats/harness.rs +++ b/wharrgarbl-strobe/src/herding_kats/harness.rs @@ -4,9 +4,8 @@ use std::{string::String, vec::Vec}; use aead::consts::U14; use serde::{Deserialize, Deserializer, de}; -use wharrgarbl_core::Role; -use crate::{StrobeSecurity, strobe::StrobeState}; +use crate::{StrobeRole, StrobeSecurity, strobe::StrobeState}; /// The harness we will put on our KATs so we can herd them and make them do tests. /// (This is the top-level structure of the JSON we find in the test vectors) @@ -115,7 +114,7 @@ pub fn test_against_kat>(filename: P) { operations, } = serde_json::from_reader(file).unwrap(); - let mut strobe = StrobeState::new(proto_string.as_bytes(), security, Role::Sender); + let mut strobe = StrobeState::new(proto_string.as_bytes(), security, StrobeRole::Sender); operations.into_iter().for_each( |KatOperation { diff --git a/wharrgarbl-strobe/src/lib.rs b/wharrgarbl-strobe/src/lib.rs index 65c9206..2df7215 100644 --- a/wharrgarbl-strobe/src/lib.rs +++ b/wharrgarbl-strobe/src/lib.rs @@ -8,6 +8,8 @@ mod basic_kats; #[cfg(test)] mod herding_kats; +use core::ops::BitXor; + pub use strobe::StrobeState; /// Version of Strobe that this crate implements. @@ -29,3 +31,18 @@ impl StrobeSecurity { (self as u16).to_le_bytes() } } + +#[derive(Debug, Clone, Copy, PartialEq, Eq)] +#[repr(u8)] +pub enum StrobeRole { + Sender = 0, + Receiver = 1, +} + +impl BitXor for StrobeRole { + fn bitxor(self, rhs: Self) -> Self::Output { + (self as u8) ^ (rhs as u8) + } + + type Output = u8; +} diff --git a/wharrgarbl-strobe/src/strobe.rs b/wharrgarbl-strobe/src/strobe.rs index 3a11fe9..ac64a4e 100644 --- a/wharrgarbl-strobe/src/strobe.rs +++ b/wharrgarbl-strobe/src/strobe.rs @@ -1,10 +1,9 @@ use ctutils::{Choice, CtAssign, CtEq, CtLt, CtSelect}; use hybrid_array::{Array, ArraySize}; -use wharrgarbl_core::Role; use zeroize::Zeroize; use crate::{ - STROBE_VERSION, StrobeSecurity, + STROBE_VERSION, StrobeRole, StrobeSecurity, keccakf::{KECCAK_BUFFER_SIZE, KeccakF1600}, opflags::OpFlags, ops, @@ -110,7 +109,7 @@ impl core::fmt::Debug for StrobeState { impl StrobeState { /// Makes a new `StrobeState` object with a given protocol byte string and security parameter. - pub fn new(protocol: &[u8], sec: StrobeSecurity, role: Role) -> Self { + pub fn new(protocol: &[u8], sec: StrobeSecurity, role: StrobeRole) -> Self { let rate = KECCAK_BUFFER_SIZE - (sec as usize) / 4 - 2; assert!((1..254).contains(&rate)); @@ -458,7 +457,7 @@ mod tests { #[test] fn version_formatting() { - let s = StrobeState::new(b"", StrobeSecurity::B128, Role::Sender); + let s = StrobeState::new(b"", StrobeSecurity::B128, StrobeRole::Sender); let display = std::format!("{s}"); let debug = std::format!("{s:?}"); diff --git a/wharrgarbl-core/Cargo.toml b/wharrgarbl-utils/Cargo.toml similarity index 69% rename from wharrgarbl-core/Cargo.toml rename to wharrgarbl-utils/Cargo.toml index d1bef5c..b1cb173 100644 --- a/wharrgarbl-core/Cargo.toml +++ b/wharrgarbl-utils/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "wharrgarbl-core" -description = "Whimsical core types for WHARRGARBL" +name = "wharrgarbl-utils" +description = "Whimsical utils for WHARRGARBL" authors.workspace = true edition.workspace = true repository.workspace = true diff --git a/wharrgarbl-core/src/lib.rs b/wharrgarbl-utils/src/lib.rs similarity index 89% rename from wharrgarbl-core/src/lib.rs rename to wharrgarbl-utils/src/lib.rs index 4bd4269..36f1e01 100644 --- a/wharrgarbl-core/src/lib.rs +++ b/wharrgarbl-utils/src/lib.rs @@ -1,23 +1,5 @@ #![no_std] -use core::ops::BitXor; - -// Public API for passing in Role -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -#[repr(u8)] -pub enum Role { - Sender = 0, - Receiver = 1, -} - -impl BitXor for Role { - fn bitxor(self, rhs: Self) -> Self::Output { - (self as u8) ^ (rhs as u8) - } - - type Output = u8; -} - #[derive(Debug)] pub struct BufferSlice<'slice> { buffer: &'slice mut [u8],