A whimsical STROBE based encryption protocol
2
fork

Configure Feed

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

CT transport role selection & opflag setting

+25 -20
+13 -5
src/opflags.rs
··· 29 29 (*self & other).ct_ne(&OpFlags::EMPTY) 30 30 } 31 31 32 + fn insert(&mut self, flags: OpFlags) { 33 + *self |= flags; 34 + } 35 + 36 + fn remove(&mut self, flags: OpFlags) { 37 + *self &= !flags; 38 + } 39 + 32 40 pub fn set(&mut self, flags: OpFlags, cond: Choice) { 33 - if cond.into() { 34 - *self |= flags; 35 - } else { 36 - *self &= !flags; 37 - } 41 + const OPS: [fn(&mut OpFlags, OpFlags); 2] = [OpFlags::remove, OpFlags::insert]; 42 + 43 + let index = (cond.to_u8() & 1) as usize; 44 + 45 + OPS[index](self, flags); 38 46 } 39 47 40 48 #[inline(always)]
+12 -15
src/strobe.rs
··· 7 7 ops, 8 8 }; 9 9 10 + /// Private integer representations for Role, to allow for better constant time compat. 11 + mod role { 12 + pub const SENDER: u8 = 0; 13 + pub const RECEIVER: u8 = 1; 14 + } 15 + 16 + /// Public API for passing in Role 10 17 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 11 18 #[repr(u8)] 12 19 pub enum Role { 13 20 Sender, 14 21 Receiver, 15 - } 16 - 17 - impl CtEq for Role { 18 - fn ct_eq(&self, other: &Self) -> Choice { 19 - (*self as u8).ct_eq(&(*other as u8)) 20 - } 21 22 } 22 23 23 24 #[derive(Debug, Clone, Copy)] ··· 40 41 /// Index into `state` 41 42 start: usize, 42 43 /// Represents whether we're a sender or a receiver 43 - role: Role, 44 + role: u8, 44 45 /// The last operation performed. This is to verify that the `more` flag is only used across 45 46 /// identical operations. 46 47 prev_flags: OpFlags, ··· 122 123 rate, 123 124 position: 0, 124 125 start: 0, 125 - role, 126 + role: role as u8, 126 127 prev_flags: OpFlags::EMPTY, 127 128 }; 128 129 ··· 264 265 /// sending or receiving 265 266 fn begin_op(&mut self, mut flags: OpFlags) { 266 267 if flags.contains(OpFlags::TRANSPORT).to_bool() { 267 - let op_role = if flags.contains(OpFlags::INBOUND).to_bool() { 268 - Role::Receiver 269 - } else { 270 - Role::Sender 271 - }; 268 + let op_role = role::SENDER.ct_select(&role::RECEIVER, flags.contains(OpFlags::INBOUND)); 272 269 273 270 // So that the sender and receiver agree, toggle the I flag as necessary 274 271 flags.set(OpFlags::INBOUND, self.role.ct_ne(&op_role)); ··· 305 302 // Flags that don't pass this assertion should normally call `absorb`, but `absorb` does not mutate, 306 303 // so the implementor should have used operate_no_mutate instead 307 304 // RATCHET is special-cased to never call operate directly 308 - debug_assert!(flags != ops::KEY && bool::from(flags.contains(OpFlags::CIPHER))); 305 + debug_assert!(flags != ops::KEY && flags.contains(OpFlags::CIPHER).to_bool()); 309 306 310 307 const SPECIAL_CASES: [OpFlags; 3] = [ops::PRF, ops::SEND_MAC, ops::SEND_ENC]; 311 308 const OPS: [fn(&mut StrobeState, data: &mut [u8]); 4] = [ ··· 343 340 344 341 // Flags that trigger the assertion to fail are mutating operations. 345 342 // RATCHET is special cased to never call operate/operate_no_mutate directly 346 - debug_assert!(flags == ops::KEY || !bool::from(flags.contains(OpFlags::CIPHER))); 343 + debug_assert!(flags == ops::KEY || !flags.contains(OpFlags::CIPHER).to_bool()); 347 344 348 345 const OPS: [fn(&mut StrobeState, data: &[u8]); 2] = 349 346 [StrobeState::absorb, StrobeState::overwrite];