A whimsical STROBE based encryption protocol
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Further reorg

+93 -78
+9 -9
Cargo.lock
··· 465 465 "hybrid-array", 466 466 "ml-kem", 467 467 "rand_core", 468 - "wharrgarbl-core", 469 468 "wharrgarbl-strobe", 469 + "wharrgarbl-utils", 470 470 "zeroize", 471 - ] 472 - 473 - [[package]] 474 - name = "wharrgarbl-core" 475 - version = "0.1.0" 476 - dependencies = [ 477 - "aead", 478 471 ] 479 472 480 473 [[package]] ··· 489 482 "serde", 490 483 "serde-big-array", 491 484 "serde_json", 492 - "wharrgarbl-core", 485 + "wharrgarbl-utils", 493 486 "zeroize", 487 + ] 488 + 489 + [[package]] 490 + name = "wharrgarbl-utils" 491 + version = "0.1.0" 492 + dependencies = [ 493 + "aead", 494 494 ] 495 495 496 496 [[package]]
+2 -2
Cargo.toml
··· 1 1 [workspace] 2 2 resolver = "3" 3 - members = ["wharrgarbl-core", "wharrgarbl-strobe"] 3 + members = ["wharrgarbl-utils", "wharrgarbl-strobe"] 4 4 5 5 [workspace.package] 6 6 authors = ["Sachy.dev <sachymetsu@tutamail.com>"] ··· 27 27 parallel = ["wharrgarbl-strobe/parallel"] 28 28 29 29 [dependencies] 30 - wharrgarbl-core = { path = "./wharrgarbl-core", version = "0.1" } 30 + wharrgarbl-utils = { path = "./wharrgarbl-utils", version = "0.1" } 31 31 wharrgarbl-strobe = { path = "./wharrgarbl-strobe", version = "0.1" } 32 32 ctutils.workspace = true 33 33 zeroize.workspace = true
+11 -7
src/handshake.rs
··· 1 1 use aead::Buffer; 2 2 use hybrid_array::typenum::Unsigned; 3 3 use rand_core::CryptoRng; 4 - use wharrgarbl_core::Role; 5 - use wharrgarbl_strobe::{StrobeSecurity, StrobeState}; 4 + use wharrgarbl_strobe::{StrobeRole, StrobeSecurity, StrobeState}; 6 5 7 6 use crate::{ 8 7 WHARRGHARBL_PROTO, ··· 19 18 20 19 impl ClientHandshake { 21 20 pub fn new(kem_sec: KemSecurity, sec_param: StrobeSecurity, psk: Option<&[u8; 32]>) -> Self { 22 - let mut strobe = StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), sec_param, Role::Sender); 21 + let mut strobe = 22 + StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), sec_param, StrobeRole::Sender); 23 23 24 24 if let Some(psk) = psk { 25 25 strobe.key(psk); ··· 87 87 self.strobe.prf(&mut inbound); 88 88 self.strobe.prf(&mut outbound); 89 89 90 - AeadState::new(key, self.sec_param, outbound, inbound, Role::Sender) 90 + AeadState::new(key, self.sec_param, outbound, inbound, StrobeRole::Sender) 91 91 } 92 92 } 93 93 ··· 99 99 100 100 impl ServerHandshake { 101 101 pub fn new(kem_sec: KemSecurity, sec_param: StrobeSecurity, psk: Option<&[u8; 32]>) -> Self { 102 - let mut strobe = StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), sec_param, Role::Receiver); 102 + let mut strobe = StrobeState::new( 103 + WHARRGHARBL_PROTO.as_bytes(), 104 + sec_param, 105 + StrobeRole::Receiver, 106 + ); 103 107 104 108 if let Some(psk) = psk { 105 109 strobe.key(psk); ··· 162 166 self.strobe.prf(&mut inbound); 163 167 self.strobe.prf(&mut outbound); 164 168 165 - AeadState::new(key, self.sec_param, outbound, inbound, Role::Receiver) 169 + AeadState::new(key, self.sec_param, outbound, inbound, StrobeRole::Receiver) 166 170 } 167 171 } 168 172 169 173 #[cfg(test)] 170 174 mod tests { 171 - use wharrgarbl_core::BufferSlice; 175 + use crate::utils::BufferSlice; 172 176 173 177 use super::*; 174 178
+5 -2
src/lib.rs
··· 7 7 8 8 extern crate alloc; 9 9 10 - /// Version of Strobe that this crate implements. 11 - pub static STROBE_VERSION: &str = "1.0.2"; 10 + /// Version of WHARRGARBL that this crate implements. 12 11 pub static WHARRGHARBL_PROTO: &str = "WGBL-v0.0-STv1.0.2"; 12 + 13 + pub mod utils { 14 + pub use wharrgarbl_utils::BufferSlice; 15 + }
+21 -17
src/transport.rs
··· 3 3 consts::{U16, U32}, 4 4 }; 5 5 use ctutils::{CtEq, CtSelect}; 6 - use wharrgarbl_core::Role; 7 - use wharrgarbl_strobe::{StrobeSecurity, StrobeState}; 6 + use wharrgarbl_strobe::{StrobeRole, StrobeSecurity, StrobeState}; 8 7 9 8 use crate::WHARRGHARBL_PROTO; 10 9 ··· 31 30 mut buffer: aead::inout::InOutBuf<'_, '_, u8>, 32 31 ) -> aead::Result<aead::Tag<Self>> { 33 32 let mut tag: aead::Tag<Self> = Default::default(); 34 - let mut strobe = StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), self.param, Role::Sender); 33 + let mut strobe = 34 + StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), self.param, StrobeRole::Sender); 35 35 36 36 strobe.key(&self.key); 37 37 strobe.meta_ad(&self.param.to_bytes()); ··· 51 51 mut buffer: aead::inout::InOutBuf<'_, '_, u8>, 52 52 tag: &aead::Tag<Self>, 53 53 ) -> aead::Result<()> { 54 - let mut strobe = StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), self.param, Role::Receiver); 54 + let mut strobe = StrobeState::new( 55 + WHARRGHARBL_PROTO.as_bytes(), 56 + self.param, 57 + StrobeRole::Receiver, 58 + ); 55 59 56 60 strobe.key(&self.key); 57 61 strobe.meta_ad(&self.param.to_bytes()); ··· 73 77 pub(crate) aead: AeadStrobe, 74 78 pub(crate) epstein: aead::Nonce<AeadStrobe>, 75 79 pub(crate) trump: aead::Nonce<AeadStrobe>, 76 - role: Role, 80 + handshake_role: StrobeRole, 77 81 } 78 82 79 83 impl zeroize::Zeroize for AeadState { ··· 98 102 sec: StrobeSecurity, 99 103 outbound: aead::Nonce<AeadStrobe>, 100 104 inbound: aead::Nonce<AeadStrobe>, 101 - role: Role, 105 + role: StrobeRole, 102 106 ) -> Self { 103 107 assert_ne!( 104 108 &inbound, &outbound, ··· 109 113 aead: AeadStrobe { key, param: sec }, 110 114 epstein: outbound, 111 115 trump: inbound, 112 - role, 116 + handshake_role: role, 113 117 } 114 118 } 115 119 116 - fn select_nonce(&self, role: Role) -> aead::Nonce<AeadStrobe> { 117 - let role_context = self.role ^ role; 120 + fn select_nonce(&self, sending_role: StrobeRole) -> aead::Nonce<AeadStrobe> { 121 + let role_context = self.handshake_role ^ sending_role; 118 122 119 123 self.epstein.ct_select(&self.trump, role_context.ct_eq(&1)) 120 124 } 121 125 122 - fn mix_nonce(&self, position: [u8; 8], role: Role) -> aead::Nonce<AeadStrobe> { 123 - let mut nonce = self.select_nonce(role); 126 + fn mix_nonce(&self, position: [u8; 8], sending_role: StrobeRole) -> aead::Nonce<AeadStrobe> { 127 + let mut nonce = self.select_nonce(sending_role); 124 128 125 129 let mid = nonce.len() - position.len(); 126 130 ··· 160 164 let encryption_result = self.transport.aead.encrypt_in_place( 161 165 &self 162 166 .transport 163 - .mix_nonce(self.counter.to_be_bytes(), Role::Sender), 167 + .mix_nonce(self.counter.to_be_bytes(), StrobeRole::Sender), 164 168 ad, 165 169 buffer, 166 170 ); ··· 186 190 let decryption_result = self.transport.aead.decrypt_in_place( 187 191 &self 188 192 .transport 189 - .mix_nonce(self.counter.to_be_bytes(), Role::Receiver), 193 + .mix_nonce(self.counter.to_be_bytes(), StrobeRole::Receiver), 190 194 ad, 191 195 buffer, 192 196 ); ··· 217 221 StrobeSecurity::B128, 218 222 outbound.into(), 219 223 inbound.into(), 220 - Role::Sender, 224 + StrobeRole::Sender, 221 225 ); 222 226 let bob = AeadState::new( 223 227 shared_secret.into(), 224 228 StrobeSecurity::B128, 225 229 outbound.into(), 226 230 inbound.into(), 227 - Role::Receiver, 231 + StrobeRole::Receiver, 228 232 ); 229 233 230 234 let (mut alice_send, mut alice_recv) = alice.split(); ··· 292 296 StrobeSecurity::B128, 293 297 outbound.into(), 294 298 inbound.into(), 295 - Role::Sender, 299 + StrobeRole::Sender, 296 300 ); 297 301 let bob = AeadState::new( 298 302 shared_secret.into(), 299 303 StrobeSecurity::B256, 300 304 outbound.into(), 301 305 inbound.into(), 302 - Role::Receiver, 306 + StrobeRole::Receiver, 303 307 ); 304 308 305 309 let (mut alice_send, mut _alice_recv) = alice.split();
+2 -2
wharrgarbl-core/Cargo.toml wharrgarbl-utils/Cargo.toml
··· 1 1 [package] 2 - name = "wharrgarbl-core" 3 - description = "Whimsical core types for WHARRGARBL" 2 + name = "wharrgarbl-utils" 3 + description = "Whimsical utils for WHARRGARBL" 4 4 authors.workspace = true 5 5 edition.workspace = true 6 6 repository.workspace = true
-18
wharrgarbl-core/src/lib.rs wharrgarbl-utils/src/lib.rs
··· 1 1 #![no_std] 2 2 3 - use core::ops::BitXor; 4 - 5 - // Public API for passing in Role 6 - #[derive(Debug, Clone, Copy, PartialEq, Eq)] 7 - #[repr(u8)] 8 - pub enum Role { 9 - Sender = 0, 10 - Receiver = 1, 11 - } 12 - 13 - impl BitXor for Role { 14 - fn bitxor(self, rhs: Self) -> Self::Output { 15 - (self as u8) ^ (rhs as u8) 16 - } 17 - 18 - type Output = u8; 19 - } 20 - 21 3 #[derive(Debug)] 22 4 pub struct BufferSlice<'slice> { 23 5 buffer: &'slice mut [u8],
+1 -1
wharrgarbl-strobe/Cargo.toml
··· 11 11 parallel = ["keccak/parallel"] 12 12 13 13 [dependencies] 14 - wharrgarbl-core = { path = "../wharrgarbl-core", version = "0.1" } 14 + wharrgarbl-utils = { path = "../wharrgarbl-utils", version = "0.1" } 15 15 aead.workspace = true 16 16 zeroize.workspace = true 17 17 ctutils.workspace = true
+20 -13
wharrgarbl-strobe/src/basic_kats.rs
··· 6 6 7 7 use aead::consts::{U16, U65}; 8 8 use hybrid_array::Array; 9 - use wharrgarbl_core::Role; 10 9 11 - use crate::{StrobeSecurity, keccakf::KECCAK_BUFFER_SIZE, strobe::StrobeState}; 10 + use crate::{StrobeRole, StrobeSecurity, keccakf::KECCAK_BUFFER_SIZE, strobe::StrobeState}; 12 11 13 12 extern crate std; 14 13 15 14 #[test] 16 15 fn test_init_128() { 17 - let s = StrobeState::new(b"", StrobeSecurity::B128, Role::Sender); 16 + let s = StrobeState::new(b"", StrobeSecurity::B128, StrobeRole::Sender); 18 17 19 18 let expected_st: [u8; KECCAK_BUFFER_SIZE] = [ 20 19 0x9c, 0x7f, 0x16, 0x8f, 0xf8, 0xfd, 0x55, 0xda, 0x2a, 0xa7, 0x3c, 0x23, 0x55, 0x65, 0x35, ··· 38 37 39 38 #[test] 40 39 fn test_init_256() { 41 - let s = StrobeState::new(b"", StrobeSecurity::B256, Role::Sender); 40 + let s = StrobeState::new(b"", StrobeSecurity::B256, StrobeRole::Sender); 42 41 43 42 let expected_st: [u8; KECCAK_BUFFER_SIZE] = [ 44 43 0x37, 0xc1, 0x15, 0x06, 0xed, 0x61, 0xe7, 0xda, 0x7c, 0x1a, 0x2f, 0x2c, 0x1f, 0x49, 0x74, ··· 63 62 #[test] 64 63 fn test_metadata() { 65 64 // We will accumulate output over 3 operations and 3 meta-operations 66 - let mut s = StrobeState::new(b"metadatatest", StrobeSecurity::B256, Role::Sender); 65 + let mut s = StrobeState::new(b"metadatatest", StrobeSecurity::B256, StrobeRole::Sender); 67 66 let mut output = std::vec::Vec::new(); 68 67 69 68 let buf = b"meta1"; ··· 117 116 118 117 #[test] 119 118 fn test_seq() { 120 - let mut s = StrobeState::new(b"seqtest", StrobeSecurity::B256, Role::Sender); 119 + let mut s = StrobeState::new(b"seqtest", StrobeSecurity::B256, StrobeRole::Sender); 121 120 122 121 let mut buf = [0u8; 10]; 123 122 s.prf(&mut buf[..]); ··· 173 172 #[test] 174 173 fn test_enc_correctness() { 175 174 let orig_msg = b"Hello there"; 176 - let mut tx = StrobeState::new(b"enccorrectnesstest", StrobeSecurity::B256, Role::Sender); 177 - let mut rx = StrobeState::new(b"enccorrectnesstest", StrobeSecurity::B256, Role::Receiver); 175 + let mut tx = StrobeState::new( 176 + b"enccorrectnesstest", 177 + StrobeSecurity::B256, 178 + StrobeRole::Sender, 179 + ); 180 + let mut rx = StrobeState::new( 181 + b"enccorrectnesstest", 182 + StrobeSecurity::B256, 183 + StrobeRole::Receiver, 184 + ); 178 185 179 186 tx.key(b"the-combination-on-my-luggage"); 180 187 rx.key(b"the-combination-on-my-luggage"); ··· 189 196 190 197 #[test] 191 198 fn test_mac_correctness_and_soundness() { 192 - let mut tx = StrobeState::new(b"mactest", StrobeSecurity::B256, Role::Sender); 193 - let mut rx = StrobeState::new(b"mactest", StrobeSecurity::B256, Role::Receiver); 199 + let mut tx = StrobeState::new(b"mactest", StrobeSecurity::B256, StrobeRole::Sender); 200 + let mut rx = StrobeState::new(b"mactest", StrobeSecurity::B256, StrobeRole::Receiver); 194 201 195 202 // Just do some stuff with the state 196 203 ··· 218 225 219 226 #[test] 220 227 fn test_long_inputs() { 221 - let mut s = StrobeState::new(b"bigtest", StrobeSecurity::B256, Role::Sender); 228 + let mut s = StrobeState::new(b"bigtest", StrobeSecurity::B256, StrobeRole::Sender); 222 229 const BIG_N: usize = 9823; 223 230 const SMALL_N: usize = 65; 224 231 let big_data = [0x34u8; BIG_N]; ··· 275 282 fn test_streaming_correctness() { 276 283 // Compute a few things without breaking up their inputs 277 284 let one_shot_st: std::vec::Vec<u8> = { 278 - let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, Role::Receiver); 285 + let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, StrobeRole::Receiver); 279 286 280 287 s.ad(b"mynonce"); 281 288 ··· 291 298 }; 292 299 // Now do the same thing but stream the inputs 293 300 let streamed_st: std::vec::Vec<u8> = { 294 - let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, Role::Receiver); 301 + let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, StrobeRole::Receiver); 295 302 296 303 s.ad(b"my"); 297 304 s.ad(b"nonce");
+2 -3
wharrgarbl-strobe/src/herding_kats/harness.rs
··· 4 4 5 5 use aead::consts::U14; 6 6 use serde::{Deserialize, Deserializer, de}; 7 - use wharrgarbl_core::Role; 8 7 9 - use crate::{StrobeSecurity, strobe::StrobeState}; 8 + use crate::{StrobeRole, StrobeSecurity, strobe::StrobeState}; 10 9 11 10 /// The harness we will put on our KATs so we can herd them and make them do tests. 12 11 /// (This is the top-level structure of the JSON we find in the test vectors) ··· 115 114 operations, 116 115 } = serde_json::from_reader(file).unwrap(); 117 116 118 - let mut strobe = StrobeState::new(proto_string.as_bytes(), security, Role::Sender); 117 + let mut strobe = StrobeState::new(proto_string.as_bytes(), security, StrobeRole::Sender); 119 118 120 119 operations.into_iter().for_each( 121 120 |KatOperation {
+17
wharrgarbl-strobe/src/lib.rs
··· 8 8 #[cfg(test)] 9 9 mod herding_kats; 10 10 11 + use core::ops::BitXor; 12 + 11 13 pub use strobe::StrobeState; 12 14 13 15 /// Version of Strobe that this crate implements. ··· 29 31 (self as u16).to_le_bytes() 30 32 } 31 33 } 34 + 35 + #[derive(Debug, Clone, Copy, PartialEq, Eq)] 36 + #[repr(u8)] 37 + pub enum StrobeRole { 38 + Sender = 0, 39 + Receiver = 1, 40 + } 41 + 42 + impl BitXor for StrobeRole { 43 + fn bitxor(self, rhs: Self) -> Self::Output { 44 + (self as u8) ^ (rhs as u8) 45 + } 46 + 47 + type Output = u8; 48 + }
+3 -4
wharrgarbl-strobe/src/strobe.rs
··· 1 1 use ctutils::{Choice, CtAssign, CtEq, CtLt, CtSelect}; 2 2 use hybrid_array::{Array, ArraySize}; 3 - use wharrgarbl_core::Role; 4 3 use zeroize::Zeroize; 5 4 6 5 use crate::{ 7 - STROBE_VERSION, StrobeSecurity, 6 + STROBE_VERSION, StrobeRole, StrobeSecurity, 8 7 keccakf::{KECCAK_BUFFER_SIZE, KeccakF1600}, 9 8 opflags::OpFlags, 10 9 ops, ··· 110 109 111 110 impl StrobeState { 112 111 /// Makes a new `StrobeState` object with a given protocol byte string and security parameter. 113 - pub fn new(protocol: &[u8], sec: StrobeSecurity, role: Role) -> Self { 112 + pub fn new(protocol: &[u8], sec: StrobeSecurity, role: StrobeRole) -> Self { 114 113 let rate = KECCAK_BUFFER_SIZE - (sec as usize) / 4 - 2; 115 114 assert!((1..254).contains(&rate)); 116 115 ··· 458 457 459 458 #[test] 460 459 fn version_formatting() { 461 - let s = StrobeState::new(b"", StrobeSecurity::B128, Role::Sender); 460 + let s = StrobeState::new(b"", StrobeSecurity::B128, StrobeRole::Sender); 462 461 463 462 let display = std::format!("{s}"); 464 463 let debug = std::format!("{s:?}");