A whimsical STROBE based encryption protocol
0
fork

Configure Feed

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

Generification of Wharrgarbl

authored by

Sachymetsu and committed by
Tangled
04e1b5d2 7d3f18c9

+266 -361
+2 -2
.tangled/workflows/test.yml
··· 15 15 - name: Format check 16 16 command: cargo fmt --all --check 17 17 - name: Clippy 18 - command: cargo clippy --locked --no-deps 18 + command: cargo clippy --workspace --locked --no-deps 19 19 - name: Tests 20 - command: cargo test --locked --no-fail-fast 20 + command: cargo test --workspace --locked --no-fail-fast
+75 -70
src/handshake.rs
··· 1 + use core::marker::PhantomData; 2 + 1 3 use aead::Buffer; 2 - use hybrid_array::typenum::Unsigned; 4 + use hybrid_array::{Array, typenum::Unsigned}; 5 + use ml_kem::{Encapsulate, Kem, KeyExport, ParameterSet, TryKeyInit, kem::Decapsulate}; 3 6 use rand_core::CryptoRng; 4 - use wharrgarbl_strobe::{StrobeRole, StrobeSecurity, StrobeState}; 7 + use wharrgarbl_strobe::{StrobeRole, StrobeState, traits::StrobeSecurity}; 5 8 6 9 use crate::{ 7 10 WHARRGHARBL_PROTO, 8 - kem::{KemEncap, KemSecurity}, 9 11 transport::{AeadState, AeadStrobe}, 10 12 }; 11 13 12 - pub struct ClientHandshake { 13 - kem_sec: KemSecurity, 14 - sec_param: StrobeSecurity, 15 - strobe: StrobeState, 16 - decap: Option<crate::kem::KemDecap>, 14 + pub struct ClientHandshake<S: StrobeSecurity, K: Kem + ParameterSet> { 15 + kem_sec: PhantomData<K>, 16 + strobe: StrobeState<S>, 17 + decap: Option<K::DecapsulationKey>, 17 18 } 18 19 19 - impl ClientHandshake { 20 - pub fn new(kem_sec: KemSecurity, sec_param: StrobeSecurity, psk: Option<&[u8; 32]>) -> Self { 21 - let mut strobe = 22 - StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), sec_param, StrobeRole::Sender); 20 + impl<S: StrobeSecurity, K: Kem + ParameterSet> ClientHandshake<S, K> 21 + where 22 + K::DecapsulationKey: Decapsulate, 23 + { 24 + pub fn new(psk: Option<&[u8; 32]>) -> Self { 25 + let mut strobe = StrobeState::<S>::new(WHARRGHARBL_PROTO.as_bytes(), StrobeRole::Sender); 23 26 24 27 if let Some(psk) = psk { 25 28 strobe.key(psk); 26 29 } 27 30 28 - strobe.meta_ad(&kem_sec.to_bytes()); 29 - strobe.meta_ad(&sec_param.to_bytes()); 31 + strobe.meta_ad(&K::K::to_u16().to_le_bytes()); 32 + strobe.meta_ad(&S::to_bytes()); 30 33 31 34 Self { 32 - kem_sec, 33 - sec_param, 35 + kem_sec: PhantomData, 34 36 strobe, 35 37 decap: None, 36 38 } 37 39 } 38 40 39 41 pub fn send(&mut self, rng: &mut impl CryptoRng, buf: &mut dyn Buffer) -> aead::Result<()> { 40 - let mut tag: aead::Tag<AeadStrobe> = Default::default(); 41 - let (decap, encap) = self.kem_sec.generate_with_rng(rng); 42 + let mut tag: aead::Tag<AeadStrobe<S>> = Default::default(); 43 + let (decap, encap) = K::generate_keypair_from_rng(rng); 42 44 43 - let written = encap.serialize(buf.as_mut())?; 45 + buf.extend_from_slice(&encap.to_bytes())?; 44 46 45 - buf.truncate(written); 47 + let rachet_bytes = S::to_usize() >> 3; 46 48 47 49 self.strobe.send_clr(buf.as_ref()); 48 50 self.strobe.send_mac(&mut tag); 49 - self.strobe.ratchet(self.sec_param.rachet_bytes()); 51 + self.strobe.ratchet(rachet_bytes); 50 52 51 53 buf.extend_from_slice(&tag)?; 52 54 ··· 55 57 Ok(()) 56 58 } 57 59 58 - pub fn receive(&mut self, ciphertext: &[u8]) -> aead::Result<AeadState> { 59 - let decap = self.decap.as_mut().ok_or(aead::Error)?; 60 + pub fn receive(&mut self, ciphertext: &[u8]) -> aead::Result<AeadState<S>> { 61 + let decap = self.decap.as_ref().ok_or(aead::Error)?; 60 62 61 63 let tag = ciphertext 62 64 .len() 63 - .checked_sub(<AeadStrobe as aead::AeadCore>::TagSize::to_usize()) 65 + .checked_sub(<AeadStrobe<S> as aead::AeadCore>::TagSize::to_usize()) 64 66 .ok_or(aead::Error)?; 65 67 66 68 let (ciphertext, tag) = ciphertext.split_at(tag); 67 69 68 - let tag: aead::Tag<AeadStrobe> = tag.try_into().unwrap(); 70 + let tag: aead::Tag<AeadStrobe<S>> = tag.try_into().unwrap(); 71 + let rachet_bytes = S::to_usize() >> 3; 69 72 70 73 self.strobe.recv_clr(ciphertext); 71 74 self.strobe.recv_mac(&tag)?; 72 - self.strobe.ratchet(self.sec_param.rachet_bytes()); 75 + self.strobe.ratchet(rachet_bytes); 73 76 74 - let shared = decap.decapsulate(ciphertext)?; 77 + let shared = decap 78 + .decapsulate_slice(ciphertext) 79 + .map_err(|_| aead::Error)?; 75 80 76 81 Ok(self.finish(shared)) 77 82 } 78 83 79 - fn finish(&mut self, shared: ml_kem::SharedKey) -> AeadState { 84 + fn finish(&mut self, shared: Array<u8, K::SharedKeySize>) -> AeadState<S> { 80 85 self.strobe.ad(&shared); 81 86 82 - let mut key: aead::Key<AeadStrobe> = Default::default(); 83 - let mut inbound: aead::Nonce<AeadStrobe> = Default::default(); 84 - let mut outbound: aead::Nonce<AeadStrobe> = Default::default(); 87 + let mut key: aead::Key<AeadStrobe<S>> = Default::default(); 88 + let mut inbound: aead::Nonce<AeadStrobe<S>> = Default::default(); 89 + let mut outbound: aead::Nonce<AeadStrobe<S>> = Default::default(); 85 90 86 91 self.strobe.prf(&mut key); 87 92 self.strobe.prf(&mut inbound); 88 93 self.strobe.prf(&mut outbound); 89 94 90 - AeadState::new(key, self.sec_param, outbound, inbound, StrobeRole::Sender) 95 + AeadState::new(key, outbound, inbound, StrobeRole::Sender) 91 96 } 92 97 } 93 98 94 - pub struct ServerHandshake { 95 - kem_sec: KemSecurity, 96 - sec_param: StrobeSecurity, 97 - strobe: StrobeState, 99 + pub struct ServerHandshake<S: StrobeSecurity, K: Kem + ParameterSet> { 100 + kem_sec: PhantomData<K>, 101 + strobe: StrobeState<S>, 98 102 } 99 103 100 - impl ServerHandshake { 101 - pub fn new(kem_sec: KemSecurity, sec_param: StrobeSecurity, psk: Option<&[u8; 32]>) -> Self { 102 - let mut strobe = StrobeState::new( 103 - WHARRGHARBL_PROTO.as_bytes(), 104 - sec_param, 105 - StrobeRole::Receiver, 106 - ); 104 + impl<S: StrobeSecurity, K: Kem + ParameterSet> ServerHandshake<S, K> { 105 + pub fn new(psk: Option<&[u8; 32]>) -> Self { 106 + let mut strobe = StrobeState::<S>::new(WHARRGHARBL_PROTO.as_bytes(), StrobeRole::Receiver); 107 107 108 108 if let Some(psk) = psk { 109 109 strobe.key(psk); 110 110 } 111 111 112 - strobe.meta_ad(&kem_sec.to_bytes()); 113 - strobe.meta_ad(&sec_param.to_bytes()); 112 + strobe.meta_ad(&K::K::to_u16().to_le_bytes()); 113 + strobe.meta_ad(&S::to_bytes()); 114 114 115 115 Self { 116 - kem_sec, 117 - sec_param, 116 + kem_sec: PhantomData, 118 117 strobe, 119 118 } 120 119 } ··· 123 122 &mut self, 124 123 rng: &mut impl CryptoRng, 125 124 buf: &mut dyn Buffer, 126 - ) -> aead::Result<AeadState> { 125 + ) -> aead::Result<AeadState<S>> { 127 126 let slice = buf.as_ref(); 128 127 129 128 let tag = slice 130 129 .len() 131 - .checked_sub(<AeadStrobe as aead::AeadCore>::TagSize::to_usize()) 130 + .checked_sub(<AeadStrobe<S> as aead::AeadCore>::TagSize::to_usize()) 132 131 .ok_or(aead::Error)?; 133 132 134 133 let (encap, tag) = buf.as_ref().split_at(tag); 135 134 136 - let tag: aead::Tag<AeadStrobe> = tag.try_into().unwrap(); 135 + let tag: aead::Tag<AeadStrobe<S>> = tag.try_into().unwrap(); 136 + let rachet_bytes = S::to_usize() >> 3; 137 137 138 138 self.strobe.recv_clr(encap); 139 139 self.strobe.recv_mac(&tag)?; 140 - self.strobe.ratchet(self.sec_param.rachet_bytes()); 140 + self.strobe.ratchet(rachet_bytes); 141 + 142 + let encap = K::EncapsulationKey::new_from_slice(encap).map_err(|_| aead::Error)?; 141 143 142 - let (cipher, shared) = KemEncap::encapsulate_from_slice(self.kem_sec, encap, rng)?; 144 + let (cipher, shared) = encap.encapsulate_with_rng(rng); 143 145 144 - let mut tag: aead::Tag<AeadStrobe> = Default::default(); 146 + let mut tag: aead::Tag<AeadStrobe<S>> = Default::default(); 145 147 146 148 buf.truncate(0); 147 149 148 150 self.strobe.send_clr(cipher.as_ref()); 149 151 self.strobe.send_mac(&mut tag); 150 - self.strobe.ratchet(self.sec_param.rachet_bytes()); 152 + self.strobe.ratchet(rachet_bytes); 151 153 152 154 buf.extend_from_slice(cipher.as_ref())?; 153 155 buf.extend_from_slice(&tag)?; ··· 155 157 Ok(self.finish(shared)) 156 158 } 157 159 158 - fn finish(&mut self, shared: ml_kem::SharedKey) -> AeadState { 160 + fn finish(&mut self, shared: Array<u8, K::SharedKeySize>) -> AeadState<S> { 159 161 self.strobe.ad(&shared); 160 162 161 - let mut key: aead::Key<AeadStrobe> = Default::default(); 162 - let mut inbound: aead::Nonce<AeadStrobe> = Default::default(); 163 - let mut outbound: aead::Nonce<AeadStrobe> = Default::default(); 163 + let mut key: aead::Key<AeadStrobe<S>> = Default::default(); 164 + let mut inbound: aead::Nonce<AeadStrobe<S>> = Default::default(); 165 + let mut outbound: aead::Nonce<AeadStrobe<S>> = Default::default(); 164 166 165 167 self.strobe.prf(&mut key); 166 168 self.strobe.prf(&mut inbound); 167 169 self.strobe.prf(&mut outbound); 168 170 169 - AeadState::new(key, self.sec_param, outbound, inbound, StrobeRole::Receiver) 171 + AeadState::new(key, outbound, inbound, StrobeRole::Receiver) 170 172 } 171 173 } 172 174 173 175 #[cfg(test)] 174 176 mod tests { 177 + use ml_kem::{MlKem512, MlKem768}; 178 + use wharrgarbl_strobe::{Sec128, Sec256}; 179 + 175 180 use crate::utils::BufferSlice; 176 181 177 182 use super::*; ··· 183 188 132, 45, 174, 183, 65, 89, 73, 107, 177, 77, 90, 164, 251, 184 189 ]; 185 190 186 - let mut alice = ClientHandshake::new(KemSecurity::Level1, StrobeSecurity::B128, Some(&psk)); 187 - let mut bob = ServerHandshake::new(KemSecurity::Level1, StrobeSecurity::B128, Some(&psk)); 191 + let mut alice = ClientHandshake::<Sec128, MlKem512>::new(Some(&psk)); 192 + let mut bob = ServerHandshake::<Sec128, MlKem512>::new(Some(&psk)); 188 193 189 194 // BufferSlice acts as our transport across the webz 190 195 let mut buf = alloc::vec![0u8; 2048]; ··· 192 197 193 198 let mut rng = rand_core::UnwrapErr(getrandom::SysRng); 194 199 195 - alice.send(&mut rng, &mut buf)?; 200 + alice.send(&mut rng, &mut buf).unwrap(); 196 201 197 202 // Pretend to send ek across the webz: client -> server 198 - let bob = bob.respond(&mut rng, &mut buf)?; 203 + let bob = bob.respond(&mut rng, &mut buf).unwrap(); 199 204 200 205 // Pretend to send ciphertext across the webz: server -> client 201 - let alice = alice.receive(buf.as_ref())?; 206 + let alice = alice.receive(buf.as_ref()).unwrap(); 202 207 203 208 assert_eq!(alice.aead.key, bob.aead.key); 204 209 ··· 220 225 132, 45, 174, 183, 65, 89, 73, 107, 177, 77, 90, 164, 251, 221 226 ]; 222 227 223 - let mut alice = ClientHandshake::new(KemSecurity::Level1, StrobeSecurity::B128, Some(&psk)); 224 - let mut bob = ServerHandshake::new(KemSecurity::Level1, StrobeSecurity::B256, Some(&psk)); 228 + let mut alice = ClientHandshake::<Sec128, MlKem512>::new(Some(&psk)); 229 + let mut bob = ServerHandshake::<Sec256, MlKem512>::new(Some(&psk)); 225 230 226 231 // BufferSlice acts as our transport across the webz 227 232 let mut buf = alloc::vec![0u8; 2048]; ··· 243 248 132, 45, 174, 183, 65, 89, 73, 107, 177, 77, 90, 164, 251, 244 249 ]; 245 250 246 - let mut alice = ClientHandshake::new(KemSecurity::Level1, StrobeSecurity::B128, Some(&psk)); 247 - let mut bob = ServerHandshake::new(KemSecurity::Level3, StrobeSecurity::B128, Some(&psk)); 251 + let mut alice = ClientHandshake::<Sec128, MlKem512>::new(Some(&psk)); 252 + let mut bob = ServerHandshake::<Sec128, MlKem768>::new(Some(&psk)); 248 253 249 254 // BufferSlice acts as our transport across the webz 250 255 let mut buf = alloc::vec![0u8; 2048]; ··· 266 271 132, 45, 174, 183, 65, 89, 73, 107, 177, 77, 90, 164, 251, 267 272 ]; 268 273 269 - let mut alice = ClientHandshake::new(KemSecurity::Level1, StrobeSecurity::B128, None); 270 - let mut bob = ServerHandshake::new(KemSecurity::Level1, StrobeSecurity::B128, Some(&psk)); 274 + let mut alice = ClientHandshake::<Sec128, MlKem512>::new(None); 275 + let mut bob = ServerHandshake::<Sec128, MlKem512>::new(Some(&psk)); 271 276 272 277 // BufferSlice acts as our transport across the webz 273 278 let mut buf = alloc::vec![0u8; 2048];
-137
src/kem.rs
··· 1 - use alloc::boxed::Box; 2 - use ml_kem::{Decapsulate, Encapsulate, Kem, KeyExport, SharedKey, TryKeyInit}; 3 - use rand_core::CryptoRng; 4 - use zeroize::Zeroize; 5 - 6 - #[derive(Debug, Clone, Copy, PartialEq, Eq)] 7 - #[repr(u8)] 8 - pub enum KemSecurity { 9 - Level1 = 0, 10 - Level3 = 1, 11 - } 12 - 13 - pub enum KemEncap { 14 - Level1(Box<ml_kem::EncapsulationKey512>), 15 - Level3(Box<ml_kem::EncapsulationKey768>), 16 - } 17 - 18 - pub struct KemCipher(Box<[u8]>); 19 - 20 - pub enum KemDecap { 21 - Level1(Box<ml_kem::DecapsulationKey512>), 22 - Level3(Box<ml_kem::DecapsulationKey768>), 23 - } 24 - 25 - impl KemSecurity { 26 - pub fn generate_with_rng(&self, rng: &mut impl CryptoRng) -> (KemDecap, KemEncap) { 27 - match self { 28 - Self::Level1 => { 29 - let (decap, encap) = ml_kem::MlKem512::generate_keypair_from_rng(rng); 30 - 31 - ( 32 - KemDecap::Level1(Box::new(decap)), 33 - KemEncap::Level1(Box::new(encap)), 34 - ) 35 - } 36 - Self::Level3 => { 37 - let (decap, encap) = ml_kem::MlKem768::generate_keypair_from_rng(rng); 38 - 39 - ( 40 - KemDecap::Level3(Box::new(decap)), 41 - KemEncap::Level3(Box::new(encap)), 42 - ) 43 - } 44 - } 45 - } 46 - 47 - pub const fn to_bytes(self) -> [u8; 1] { 48 - (self as u8).to_le_bytes() 49 - } 50 - } 51 - 52 - impl KemEncap { 53 - pub fn encapsulate_from_slice( 54 - sec: KemSecurity, 55 - buf: &[u8], 56 - rng: &mut impl CryptoRng, 57 - ) -> Result<(KemCipher, ml_kem::SharedKey), aead::Error> { 58 - match sec { 59 - KemSecurity::Level1 => { 60 - let encap = 61 - ml_kem::EncapsulationKey512::new_from_slice(buf).map_err(|_| aead::Error)?; 62 - 63 - let (ct, shared) = encap.encapsulate_with_rng(rng); 64 - 65 - Ok((KemCipher(ct.into()), shared)) 66 - } 67 - KemSecurity::Level3 => { 68 - let encap = 69 - ml_kem::EncapsulationKey768::new_from_slice(buf).map_err(|_| aead::Error)?; 70 - 71 - let (ct, shared) = encap.encapsulate_with_rng(rng); 72 - 73 - Ok((KemCipher(ct.into()), shared)) 74 - } 75 - } 76 - } 77 - 78 - pub fn serialize(&self, buf: &mut [u8]) -> Result<usize, aead::Error> { 79 - match self { 80 - Self::Level1(encap) => { 81 - let data = encap.to_bytes(); 82 - let (slice, _) = buf.split_at_mut_checked(data.len()).ok_or(aead::Error)?; 83 - 84 - slice.copy_from_slice(&data); 85 - 86 - Ok(data.len()) 87 - } 88 - Self::Level3(encap) => { 89 - let data = encap.to_bytes(); 90 - let (slice, _) = buf.split_at_mut_checked(data.len()).ok_or(aead::Error)?; 91 - 92 - slice.copy_from_slice(&data); 93 - 94 - Ok(data.len()) 95 - } 96 - } 97 - } 98 - } 99 - 100 - impl AsRef<[u8]> for KemCipher { 101 - fn as_ref(&self) -> &[u8] { 102 - self.0.as_ref() 103 - } 104 - } 105 - 106 - impl KemCipher { 107 - pub const fn len(&self) -> usize { 108 - self.0.len() 109 - } 110 - 111 - pub const fn is_empty(&self) -> bool { 112 - self.0.is_empty() 113 - } 114 - } 115 - 116 - impl Zeroize for KemCipher { 117 - fn zeroize(&mut self) { 118 - self.0.zeroize(); 119 - } 120 - } 121 - 122 - impl Drop for KemCipher { 123 - fn drop(&mut self) { 124 - self.zeroize(); 125 - } 126 - } 127 - 128 - impl KemDecap { 129 - pub fn decapsulate(&mut self, ciphertext: &[u8]) -> Result<SharedKey, aead::Error> { 130 - let key = match self { 131 - Self::Level1(decap) => decap.decapsulate_slice(ciphertext), 132 - Self::Level3(decap) => decap.decapsulate_slice(ciphertext), 133 - }; 134 - 135 - key.map_err(|_| aead::Error) 136 - } 137 - }
+8 -1
src/lib.rs
··· 1 1 #![no_std] 2 2 #![forbid(unsafe_code)] 3 3 4 + use ml_kem::{MlKem512, MlKem768}; 5 + use wharrgarbl_strobe::{Sec128, Sec256}; 6 + 4 7 pub mod handshake; 5 - mod kem; 6 8 pub mod transport; 7 9 8 10 extern crate alloc; ··· 13 15 pub mod utils { 14 16 pub use wharrgarbl_utils::BufferSlice; 15 17 } 18 + 19 + pub type ClientHandshake128L1 = handshake::ClientHandshake<Sec128, MlKem512>; 20 + pub type ServerHandshake128L1 = handshake::ServerHandshake<Sec128, MlKem512>; 21 + pub type ClientHandshake256L3 = handshake::ClientHandshake<Sec256, MlKem768>; 22 + pub type ServerHandshake256L3 = handshake::ServerHandshake<Sec256, MlKem768>;
+43 -46
src/transport.rs
··· 1 + use core::marker::PhantomData; 2 + 1 3 use aead::{ 2 4 AeadInOut, Buffer, Key, TagPosition, 3 5 consts::{U16, U32}, 4 6 }; 5 7 use ctutils::{CtEq, CtSelect}; 6 - use wharrgarbl_strobe::{StrobeRole, StrobeSecurity, StrobeState}; 8 + use wharrgarbl_strobe::{StrobeRole, StrobeState, traits::StrobeSecurity}; 7 9 8 10 use crate::WHARRGHARBL_PROTO; 9 11 10 - pub struct AeadStrobe { 12 + pub struct AeadStrobe<S: StrobeSecurity> { 11 13 pub(crate) key: Key<Self>, 12 - param: StrobeSecurity, 14 + param: PhantomData<S>, 13 15 } 14 16 15 - impl aead::AeadCore for AeadStrobe { 17 + impl<S: StrobeSecurity> aead::AeadCore for AeadStrobe<S> { 16 18 type NonceSize = U16; 17 19 type TagSize = U16; 18 20 const TAG_POSITION: TagPosition = TagPosition::Postfix; 19 21 } 20 22 21 - impl aead::KeySizeUser for AeadStrobe { 23 + impl<S: StrobeSecurity> aead::KeySizeUser for AeadStrobe<S> { 22 24 type KeySize = U32; 23 25 } 24 26 25 - impl aead::AeadInOut for AeadStrobe { 27 + impl<S: StrobeSecurity> aead::AeadInOut for AeadStrobe<S> { 26 28 fn encrypt_inout_detached( 27 29 &self, 28 30 nonce: &aead::Nonce<Self>, ··· 30 32 mut buffer: aead::inout::InOutBuf<'_, '_, u8>, 31 33 ) -> aead::Result<aead::Tag<Self>> { 32 34 let mut tag: aead::Tag<Self> = Default::default(); 33 - let mut strobe = 34 - StrobeState::new(WHARRGHARBL_PROTO.as_bytes(), self.param, StrobeRole::Sender); 35 + let mut strobe = StrobeState::<S>::new(WHARRGHARBL_PROTO.as_bytes(), StrobeRole::Sender); 35 36 36 37 strobe.key(&self.key); 37 - strobe.meta_ad(&self.param.to_bytes()); 38 + strobe.meta_ad(&S::to_bytes()); 38 39 strobe.meta_ad(nonce); 39 40 strobe.ad(associated_data); 40 41 strobe.send_enc(buffer.get_out()); ··· 51 52 mut buffer: aead::inout::InOutBuf<'_, '_, u8>, 52 53 tag: &aead::Tag<Self>, 53 54 ) -> aead::Result<()> { 54 - let mut strobe = StrobeState::new( 55 - WHARRGHARBL_PROTO.as_bytes(), 56 - self.param, 57 - StrobeRole::Receiver, 58 - ); 55 + let mut strobe = StrobeState::<S>::new(WHARRGHARBL_PROTO.as_bytes(), StrobeRole::Receiver); 59 56 60 57 strobe.key(&self.key); 61 - strobe.meta_ad(&self.param.to_bytes()); 58 + strobe.meta_ad(&S::to_bytes()); 62 59 strobe.meta_ad(nonce); 63 60 strobe.ad(associated_data); 64 61 strobe.recv_enc(buffer.get_out()); ··· 67 64 } 68 65 } 69 66 70 - impl zeroize::Zeroize for AeadStrobe { 67 + impl<S: StrobeSecurity> zeroize::Zeroize for AeadStrobe<S> { 71 68 fn zeroize(&mut self) { 72 69 self.key.zeroize(); 73 70 } 74 71 } 75 72 76 - pub struct AeadState { 77 - pub(crate) aead: AeadStrobe, 78 - pub(crate) epstein: aead::Nonce<AeadStrobe>, 79 - pub(crate) trump: aead::Nonce<AeadStrobe>, 73 + pub struct AeadState<S: StrobeSecurity> { 74 + pub(crate) aead: AeadStrobe<S>, 75 + pub(crate) epstein: aead::Nonce<AeadStrobe<S>>, 76 + pub(crate) trump: aead::Nonce<AeadStrobe<S>>, 80 77 handshake_role: StrobeRole, 81 78 } 82 79 83 - impl zeroize::Zeroize for AeadState { 80 + impl<S: StrobeSecurity> zeroize::Zeroize for AeadState<S> { 84 81 fn zeroize(&mut self) { 85 82 self.aead.zeroize(); 86 83 self.epstein.zeroize(); ··· 88 85 } 89 86 } 90 87 91 - impl zeroize::ZeroizeOnDrop for AeadState {} 88 + impl<S: StrobeSecurity> zeroize::ZeroizeOnDrop for AeadState<S> {} 92 89 93 - impl Drop for AeadState { 90 + impl<S: StrobeSecurity> Drop for AeadState<S> { 94 91 fn drop(&mut self) { 95 92 zeroize::Zeroize::zeroize(self); 96 93 } 97 94 } 98 95 99 - impl AeadState { 96 + impl<S: StrobeSecurity> AeadState<S> { 100 97 pub(crate) fn new( 101 - key: Key<AeadStrobe>, 102 - sec: StrobeSecurity, 103 - outbound: aead::Nonce<AeadStrobe>, 104 - inbound: aead::Nonce<AeadStrobe>, 98 + key: Key<AeadStrobe<S>>, 99 + outbound: aead::Nonce<AeadStrobe<S>>, 100 + inbound: aead::Nonce<AeadStrobe<S>>, 105 101 role: StrobeRole, 106 102 ) -> Self { 107 103 assert_ne!( ··· 110 106 ); 111 107 112 108 Self { 113 - aead: AeadStrobe { key, param: sec }, 109 + aead: AeadStrobe { 110 + key, 111 + param: PhantomData, 112 + }, 114 113 epstein: outbound, 115 114 trump: inbound, 116 115 handshake_role: role, 117 116 } 118 117 } 119 118 120 - fn select_nonce(&self, sending_role: StrobeRole) -> aead::Nonce<AeadStrobe> { 119 + fn select_nonce(&self, sending_role: StrobeRole) -> aead::Nonce<AeadStrobe<S>> { 121 120 let role_context = self.handshake_role ^ sending_role; 122 121 123 122 self.epstein.ct_select(&self.trump, role_context.ct_eq(&1)) 124 123 } 125 124 126 - fn mix_nonce(&self, position: [u8; 8], sending_role: StrobeRole) -> aead::Nonce<AeadStrobe> { 125 + fn mix_nonce(&self, position: [u8; 8], sending_role: StrobeRole) -> aead::Nonce<AeadStrobe<S>> { 127 126 let mut nonce = self.select_nonce(sending_role); 128 127 129 128 let mid = nonce.len() - position.len(); ··· 136 135 nonce 137 136 } 138 137 139 - pub fn split(&self) -> (SendState<'_>, RecvState<'_>) { 138 + pub fn split(&self) -> (SendState<'_, S>, RecvState<'_, S>) { 140 139 ( 141 140 SendState { 142 141 transport: self, ··· 150 149 } 151 150 } 152 151 153 - pub struct SendState<'a> { 154 - transport: &'a AeadState, 152 + pub struct SendState<'a, S: StrobeSecurity> { 153 + transport: &'a AeadState<S>, 155 154 counter: u64, 156 155 } 157 156 158 - impl SendState<'_> { 157 + impl<S: StrobeSecurity> SendState<'_, S> { 159 158 pub fn encrypt(&mut self, buffer: &mut dyn Buffer, ad: &[u8]) -> aead::Result<()> { 160 159 if self.counter.ct_eq(&u64::MAX).into() { 161 160 return Err(aead::Error); ··· 175 174 } 176 175 } 177 176 178 - pub struct RecvState<'a> { 179 - transport: &'a AeadState, 177 + pub struct RecvState<'a, S: StrobeSecurity> { 178 + transport: &'a AeadState<S>, 180 179 counter: u64, 181 180 } 182 181 183 - impl RecvState<'_> { 182 + impl<S: StrobeSecurity> RecvState<'_, S> { 184 183 pub fn decrypt(&mut self, buffer: &mut dyn Buffer, ad: &[u8]) -> aead::Result<()> { 185 184 if self.counter.ct_eq(&u64::MAX).into() { 186 185 return Err(aead::Error); ··· 203 202 204 203 #[cfg(test)] 205 204 mod tests { 205 + use wharrgarbl_strobe::{Sec128, Sec256}; 206 + 206 207 use super::*; 207 208 208 209 #[test] ··· 216 217 let outbound = 123u128.to_ne_bytes(); 217 218 let inbound = 234u128.to_ne_bytes(); 218 219 219 - let alice = AeadState::new( 220 + let alice = AeadState::<Sec128>::new( 220 221 shared_secret.into(), 221 - StrobeSecurity::B128, 222 222 outbound.into(), 223 223 inbound.into(), 224 224 StrobeRole::Sender, 225 225 ); 226 - let bob = AeadState::new( 226 + let bob = AeadState::<Sec128>::new( 227 227 shared_secret.into(), 228 - StrobeSecurity::B128, 229 228 outbound.into(), 230 229 inbound.into(), 231 230 StrobeRole::Receiver, ··· 291 290 let outbound = 123u128.to_ne_bytes(); 292 291 let inbound = 234u128.to_ne_bytes(); 293 292 294 - let alice = AeadState::new( 293 + let alice = AeadState::<Sec128>::new( 295 294 shared_secret.into(), 296 - StrobeSecurity::B128, 297 295 outbound.into(), 298 296 inbound.into(), 299 297 StrobeRole::Sender, 300 298 ); 301 - let bob = AeadState::new( 299 + let bob = AeadState::<Sec256>::new( 302 300 shared_secret.into(), 303 - StrobeSecurity::B256, 304 301 outbound.into(), 305 302 inbound.into(), 306 303 StrobeRole::Receiver,
+12 -20
wharrgarbl-strobe/src/basic_kats.rs
··· 7 7 use aead::consts::{U16, U65}; 8 8 use hybrid_array::Array; 9 9 10 - use crate::{StrobeRole, StrobeSecurity, keccakf::KECCAK_BUFFER_SIZE, strobe::StrobeState}; 10 + use crate::{Sec128, Sec256, StrobeRole, keccakf::KECCAK_BUFFER_SIZE, strobe::StrobeState}; 11 11 12 12 extern crate std; 13 13 14 14 #[test] 15 15 fn test_init_128() { 16 - let s = StrobeState::new(b"", StrobeSecurity::B128, StrobeRole::Sender); 16 + let s = StrobeState::<Sec128>::new(b"", StrobeRole::Sender); 17 17 18 18 let expected_st: [u8; KECCAK_BUFFER_SIZE] = [ 19 19 0x9c, 0x7f, 0x16, 0x8f, 0xf8, 0xfd, 0x55, 0xda, 0x2a, 0xa7, 0x3c, 0x23, 0x55, 0x65, 0x35, ··· 37 37 38 38 #[test] 39 39 fn test_init_256() { 40 - let s = StrobeState::new(b"", StrobeSecurity::B256, StrobeRole::Sender); 40 + let s = StrobeState::<Sec256>::new(b"", StrobeRole::Sender); 41 41 42 42 let expected_st: [u8; KECCAK_BUFFER_SIZE] = [ 43 43 0x37, 0xc1, 0x15, 0x06, 0xed, 0x61, 0xe7, 0xda, 0x7c, 0x1a, 0x2f, 0x2c, 0x1f, 0x49, 0x74, ··· 62 62 #[test] 63 63 fn test_metadata() { 64 64 // We will accumulate output over 3 operations and 3 meta-operations 65 - let mut s = StrobeState::new(b"metadatatest", StrobeSecurity::B256, StrobeRole::Sender); 65 + let mut s = StrobeState::<Sec256>::new(b"metadatatest", StrobeRole::Sender); 66 66 let mut output = std::vec::Vec::new(); 67 67 68 68 let buf = b"meta1"; ··· 116 116 117 117 #[test] 118 118 fn test_seq() { 119 - let mut s = StrobeState::new(b"seqtest", StrobeSecurity::B256, StrobeRole::Sender); 119 + let mut s = StrobeState::<Sec256>::new(b"seqtest", StrobeRole::Sender); 120 120 121 121 let mut buf = [0u8; 10]; 122 122 s.prf(&mut buf[..]); ··· 172 172 #[test] 173 173 fn test_enc_correctness() { 174 174 let orig_msg = b"Hello there"; 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 - ); 175 + let mut tx = StrobeState::<Sec256>::new(b"enccorrectnesstest", StrobeRole::Sender); 176 + let mut rx = StrobeState::<Sec256>::new(b"enccorrectnesstest", StrobeRole::Receiver); 185 177 186 178 tx.key(b"the-combination-on-my-luggage"); 187 179 rx.key(b"the-combination-on-my-luggage"); ··· 196 188 197 189 #[test] 198 190 fn test_mac_correctness_and_soundness() { 199 - let mut tx = StrobeState::new(b"mactest", StrobeSecurity::B256, StrobeRole::Sender); 200 - let mut rx = StrobeState::new(b"mactest", StrobeSecurity::B256, StrobeRole::Receiver); 191 + let mut tx = StrobeState::<Sec256>::new(b"mactest", StrobeRole::Sender); 192 + let mut rx = StrobeState::<Sec256>::new(b"mactest", StrobeRole::Receiver); 201 193 202 194 // Just do some stuff with the state 203 195 ··· 225 217 226 218 #[test] 227 219 fn test_long_inputs() { 228 - let mut s = StrobeState::new(b"bigtest", StrobeSecurity::B256, StrobeRole::Sender); 220 + let mut s = StrobeState::<Sec256>::new(b"bigtest", StrobeRole::Sender); 229 221 const BIG_N: usize = 9823; 230 222 const SMALL_N: usize = 65; 231 223 let big_data = [0x34u8; BIG_N]; ··· 282 274 fn test_streaming_correctness() { 283 275 // Compute a few things without breaking up their inputs 284 276 let one_shot_st: std::vec::Vec<u8> = { 285 - let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, StrobeRole::Receiver); 277 + let mut s = StrobeState::<Sec256>::new(b"streamingtest", StrobeRole::Receiver); 286 278 287 279 s.ad(b"mynonce"); 288 280 ··· 298 290 }; 299 291 // Now do the same thing but stream the inputs 300 292 let streamed_st: std::vec::Vec<u8> = { 301 - let mut s = StrobeState::new(b"streamingtest", StrobeSecurity::B256, StrobeRole::Receiver); 293 + let mut s = StrobeState::<Sec256>::new(b"streamingtest", StrobeRole::Receiver); 302 294 303 295 s.ad(b"my"); 304 296 s.ad(b"nonce");
+54 -23
wharrgarbl-strobe/src/herding_kats/harness.rs
··· 2 2 3 3 use std::{string::String, vec::Vec}; 4 4 5 - use aead::consts::U14; 5 + use aead::consts::{U14, U128, U256}; 6 6 use serde::{Deserialize, Deserializer, de}; 7 7 8 - use crate::{StrobeRole, StrobeSecurity, strobe::StrobeState}; 8 + use crate::{StrobeRole, strobe::StrobeState, traits::StrobeSecurity}; 9 9 10 10 /// The harness we will put on our KATs so we can herd them and make them do tests. 11 11 /// (This is the top-level structure of the JSON we find in the test vectors) 12 12 #[derive(Deserialize)] 13 13 struct KatHarness { 14 14 proto_string: String, 15 - #[serde(deserialize_with = "security_param_from_bits")] 16 - security: StrobeSecurity, 15 + security: u64, 17 16 operations: Vec<KatOperation>, 18 17 } 19 18 ··· 38 37 Length(usize), 39 38 } 40 39 41 - // Given the name of the operation and its required parameters, run the STROBE operation. 42 - fn run_kat_operation( 40 + enum StrobeKinds { 41 + U128(StrobeState<U128>), 42 + U256(StrobeState<U256>), 43 + } 44 + 45 + impl StrobeKinds { 46 + fn new(protocol: &[u8], security: u64) -> Self { 47 + match security { 48 + 128 => Self::U128(StrobeState::new(protocol, StrobeRole::Sender)), 49 + 256 => Self::U256(StrobeState::new(protocol, StrobeRole::Sender)), 50 + _ => panic!("Invalid Security parameter"), 51 + } 52 + } 53 + 54 + fn get_state(&self) -> &[u8] { 55 + match self { 56 + Self::U128(s) => &s.state.0, 57 + Self::U256(s) => &s.state.0, 58 + } 59 + } 60 + 61 + fn run_kat_operation(&mut self, op_name: &str, meta: bool, dol: DataOrLength, more: bool) { 62 + match self { 63 + Self::U128(s) => { 64 + exec_kat(s, op_name, meta, dol, more); 65 + } 66 + Self::U256(s) => { 67 + exec_kat(s, op_name, meta, dol, more); 68 + } 69 + } 70 + } 71 + } 72 + 73 + fn exec_kat<S: StrobeSecurity>( 74 + s: &mut StrobeState<S>, 43 75 op_name: &str, 44 76 meta: bool, 45 - s: &mut StrobeState, 46 77 dol: DataOrLength, 47 78 more: bool, 48 79 ) { ··· 114 145 operations, 115 146 } = serde_json::from_reader(file).unwrap(); 116 147 117 - let mut strobe = StrobeState::new(proto_string.as_bytes(), security, StrobeRole::Sender); 148 + let mut strobe = StrobeKinds::new(proto_string.as_bytes(), security); 118 149 119 150 operations.into_iter().for_each( 120 151 |KatOperation { ··· 127 158 }| match name.as_str() { 128 159 "init" => { 129 160 // Check that the initial state matches what is expected in the KAT operation. 130 - assert_eq!(&strobe.state.0[..], expected_state_after.as_slice()); 161 + assert_eq!(strobe.get_state(), expected_state_after.as_slice()); 131 162 } 132 163 name => { 133 164 // RATCHET inputs are given as strings of zeros instead of lengths. So just take the ··· 138 169 DataOrLength::Data(input_data.as_mut_slice()) 139 170 }; 140 171 141 - run_kat_operation(name, meta, &mut strobe, input, stream); 172 + strobe.run_kat_operation(name, meta, input, stream); 142 173 143 - assert_eq!(&strobe.state.0[..], expected_state_after.as_slice()); 174 + assert_eq!(strobe.get_state(), expected_state_after.as_slice()); 144 175 145 176 // Only test expected output if the test vector has output to test against. 146 177 if let Some(expected) = expected_output { ··· 152 183 ); 153 184 } 154 185 155 - fn security_param_from_bits<'de, D: Deserializer<'de>>( 156 - deserializer: D, 157 - ) -> Result<StrobeSecurity, D::Error> { 158 - match u64::deserialize(deserializer)? { 159 - 128 => Ok(StrobeSecurity::B128), 160 - 256 => Ok(StrobeSecurity::B256), 161 - n => Err(de::Error::custom(std::format!( 162 - "Invalid security parameter: {}", 163 - n 164 - ))), 165 - } 166 - } 186 + // fn security_param_from_bits<'de, D: Deserializer<'de>>( 187 + // deserializer: D, 188 + // ) -> Result<StrobeSecurity, D::Error> { 189 + // match u64::deserialize(deserializer)? { 190 + // 128 => Ok(StrobeSecurity::B128), 191 + // 256 => Ok(StrobeSecurity::B256), 192 + // n => Err(de::Error::custom(std::format!( 193 + // "Invalid security parameter: {}", 194 + // n 195 + // ))), 196 + // } 197 + // } 167 198 168 199 fn bytes_from_hex<'de, D>(deserializer: D) -> Result<Vec<u8>, D::Error> 169 200 where
+4 -16
wharrgarbl-strobe/src/lib.rs
··· 7 7 mod basic_kats; 8 8 #[cfg(test)] 9 9 mod herding_kats; 10 + pub mod traits; 10 11 11 12 use core::ops::BitXor; 12 13 14 + use aead::consts::{U128, U256}; 13 15 pub use strobe::StrobeState; 14 16 15 17 /// Version of Strobe that this crate implements. 16 18 pub static STROBE_VERSION: &str = "1.0.2"; 17 19 18 - #[derive(Debug, Clone, Copy)] 19 - #[repr(u16)] 20 - pub enum StrobeSecurity { 21 - B128 = 128, 22 - B256 = 256, 23 - } 24 - 25 - impl StrobeSecurity { 26 - pub const fn rachet_bytes(self) -> usize { 27 - (self as usize) >> 3 28 - } 29 - 30 - pub const fn to_bytes(self) -> [u8; 2] { 31 - (self as u16).to_le_bytes() 32 - } 33 - } 20 + pub type Sec128 = U128; 21 + pub type Sec256 = U256; 34 22 35 23 #[derive(Debug, Clone, Copy, PartialEq, Eq)] 36 24 #[repr(u8)]
+25 -25
wharrgarbl-strobe/src/strobe.rs
··· 1 + use core::marker::PhantomData; 2 + 1 3 use ctutils::{Choice, CtAssign, CtEq, CtLt, CtSelect}; 2 4 use hybrid_array::{Array, ArraySize}; 3 5 use zeroize::Zeroize; 4 6 5 7 use crate::{ 6 - STROBE_VERSION, StrobeRole, StrobeSecurity, 8 + STROBE_VERSION, StrobeRole, 7 9 keccakf::{KECCAK_BUFFER_SIZE, KeccakF1600}, 8 10 opflags::OpFlags, 9 11 ops, 12 + traits::StrobeSecurity, 10 13 }; 11 14 12 15 /// Private integer representations for Role, to allow for better constant time compat. ··· 16 19 } 17 20 18 21 #[derive(Clone)] 19 - pub struct StrobeState { 22 + pub struct StrobeState<Sec: StrobeSecurity> { 20 23 /// Internal Keccak state 21 24 pub(crate) state: KeccakF1600, 22 25 /// Security parameter (128 or 256 bits) 23 - sec: StrobeSecurity, 26 + sec: PhantomData<Sec>, 24 27 /// This is the `R` parameter in the Strobe spec 25 28 rate: usize, 26 29 /// Index into `state` ··· 66 69 }; 67 70 } 68 71 69 - impl Zeroize for StrobeState { 72 + impl<S: StrobeSecurity> Zeroize for StrobeState<S> { 70 73 fn zeroize(&mut self) { 71 74 self.state.zeroize(); 72 75 self.rate.zeroize(); ··· 77 80 } 78 81 } 79 82 80 - impl zeroize::ZeroizeOnDrop for StrobeState {} 83 + impl<S: StrobeSecurity> zeroize::ZeroizeOnDrop for StrobeState<S> {} 81 84 82 - impl Drop for StrobeState { 85 + impl<S: StrobeSecurity> Drop for StrobeState<S> { 83 86 fn drop(&mut self) { 84 87 self.zeroize(); 85 88 } 86 89 } 87 90 88 - impl core::fmt::Display for StrobeState { 91 + impl<S: StrobeSecurity> core::fmt::Display for StrobeState<S> { 89 92 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 90 93 f.write_str("Strobe-Keccak-")?; 91 - match self.sec { 92 - StrobeSecurity::B128 => f.write_str("128")?, 93 - StrobeSecurity::B256 => f.write_str("256")?, 94 - } 94 + write!(f, "{}", S::to_usize())?; 95 95 f.write_str("/1600-v")?; 96 96 f.write_str(STROBE_VERSION) 97 97 } 98 98 } 99 99 100 - impl core::fmt::Debug for StrobeState { 100 + impl<S: StrobeSecurity> core::fmt::Debug for StrobeState<S> { 101 101 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { 102 102 // Do not reveal internal state of StrobeState, other than its security level 103 103 f.debug_struct("StrobeState") 104 - .field("sec", &self.sec) 104 + .field("sec", &S::to_usize()) 105 105 .field("version", &STROBE_VERSION) 106 106 .finish_non_exhaustive() 107 107 } 108 108 } 109 109 110 - impl StrobeState { 110 + impl<S: StrobeSecurity> StrobeState<S> { 111 111 /// Makes a new `StrobeState` object with a given protocol byte string and security parameter. 112 - pub fn new(protocol: &[u8], sec: StrobeSecurity, role: StrobeRole) -> Self { 113 - let rate = KECCAK_BUFFER_SIZE - (sec as usize) / 4 - 2; 114 - assert!((1..254).contains(&rate)); 112 + pub fn new(protocol: &[u8], role: StrobeRole) -> Self { 113 + let rate = S::rate(); 115 114 116 115 // Initialize state: st = F([0x01, R+2, 0x01, 0x00, 0x01, 0x60] + b"STROBEvX.Y.Z") 117 116 let mut state_buffer = [0u8; KECCAK_BUFFER_SIZE]; ··· 125 124 126 125 let mut strobe = Self { 127 126 state, 128 - sec, 127 + sec: PhantomData, 129 128 rate, 130 129 position: 0, 131 130 start: 0, ··· 311 310 debug_assert!(flags != ops::KEY && flags.contains(OpFlags::CIPHER).to_bool()); 312 311 313 312 static SPECIAL_CASES: [OpFlags; 3] = [ops::PRF, ops::SEND_MAC, ops::SEND_ENC]; 314 - static OPS: [fn(&mut StrobeState, data: &mut [u8]); 4] = [ 313 + let ops: [fn(&mut Self, data: &mut [u8]); 4] = [ 315 314 StrobeState::squeeze, 316 315 StrobeState::copy_state, 317 316 StrobeState::absorb_and_set, ··· 329 328 }) 330 329 & 0b11; 331 330 332 - OPS[index](self, data); 331 + ops[index](self, data); 333 332 } 334 333 335 334 /// Performs the state transformation that corresponds to the given flags. If `more` is given, ··· 350 349 // RATCHET is special cased to never call operate/operate_no_mutate directly 351 350 debug_assert!(flags == ops::KEY || !flags.contains(OpFlags::CIPHER).to_bool()); 352 351 353 - static OPS: [fn(&mut StrobeState, data: &[u8]); 2] = 354 - [StrobeState::absorb, StrobeState::overwrite]; 352 + let ops: [fn(&mut Self, data: &[u8]); 2] = [StrobeState::absorb, StrobeState::overwrite]; 355 353 356 354 let index = (flags.ct_eq(&ops::KEY).to_u8() & 1) as usize; 357 355 358 - OPS[index](self, data); 356 + ops[index](self, data); 359 357 } 360 358 361 359 fn recv_mac_inner(&mut self, flags: OpFlags, mac_copy: &mut [u8]) -> Result<(), aead::Error> { ··· 451 449 452 450 #[cfg(test)] 453 451 mod tests { 452 + use aead::consts::U128; 453 + 454 454 use super::*; 455 455 456 456 extern crate std; 457 457 458 458 #[test] 459 459 fn version_formatting() { 460 - let s = StrobeState::new(b"", StrobeSecurity::B128, StrobeRole::Sender); 460 + let s = StrobeState::<U128>::new(b"", StrobeRole::Sender); 461 461 462 462 let display = std::format!("{s}"); 463 463 let debug = std::format!("{s:?}"); 464 464 465 465 assert_eq!(&display, "Strobe-Keccak-128/1600-v1.0.2"); 466 - assert_eq!(&debug, "StrobeState { sec: B128, version: \"1.0.2\", .. }"); 466 + assert_eq!(&debug, "StrobeState { sec: 128, version: \"1.0.2\", .. }"); 467 467 } 468 468 }
+29
wharrgarbl-strobe/src/traits.rs
··· 1 + use aead::consts::{U128, U256}; 2 + use hybrid_array::typenum::Unsigned; 3 + 4 + use crate::keccakf::KECCAK_BUFFER_SIZE; 5 + 6 + pub trait StrobeSecurity: Unsigned { 7 + fn to_bytes() -> [u8; 2]; 8 + fn rate() -> usize; 9 + } 10 + 11 + impl StrobeSecurity for U128 { 12 + fn to_bytes() -> [u8; 2] { 13 + Self::to_u16().to_le_bytes() 14 + } 15 + 16 + fn rate() -> usize { 17 + KECCAK_BUFFER_SIZE - (Self::to_usize()) / 4 - 2 18 + } 19 + } 20 + 21 + impl StrobeSecurity for U256 { 22 + fn to_bytes() -> [u8; 2] { 23 + Self::to_u16().to_le_bytes() 24 + } 25 + 26 + fn rate() -> usize { 27 + KECCAK_BUFFER_SIZE - (Self::to_usize()) / 4 - 2 28 + } 29 + }
+14 -21
wharrgarbl-utils/src/lib.rs
··· 8 8 9 9 impl<'slice> BufferSlice<'slice> { 10 10 pub const fn new(buffer: &'slice mut [u8]) -> Self { 11 - Self { 12 - end: buffer.len(), 13 - buffer, 14 - } 11 + Self { end: 0, buffer } 15 12 } 16 13 17 - pub const fn reset(&mut self) { 14 + pub const fn fill(&mut self) { 18 15 self.end = self.buffer.len(); 19 16 } 20 17 } ··· 47 44 } 48 45 49 46 fn truncate(&mut self, len: usize) { 50 - self.end = len.min(self.buffer.len()); 47 + self.end = len.min(self.end); 51 48 } 52 49 } 53 50 ··· 59 56 extern crate alloc; 60 57 61 58 #[test] 62 - fn defaults_to_full_buffer_size() { 59 + fn defaults_to_empty_buffer_size() { 63 60 let mut buf = alloc::vec![0u8; 128]; 64 61 65 62 let buf_slice = BufferSlice::new(&mut buf); 66 63 67 - assert_eq!(buf_slice.len(), 128); 64 + assert_eq!(buf_slice.len(), 0); 68 65 } 69 66 70 67 #[test] ··· 73 70 74 71 let mut buf_slice = BufferSlice::new(&mut buf); 75 72 73 + buf_slice.extend_from_slice(&[0; 70]).unwrap(); 74 + 76 75 buf_slice.truncate(64); 77 76 78 77 assert_eq!(buf_slice.len(), 64); 79 78 80 79 buf_slice.truncate(256); 81 80 82 - assert_eq!(buf_slice.len(), 128); 81 + assert_eq!(buf_slice.len(), 64); 83 82 } 84 83 85 84 #[test] ··· 88 87 89 88 let mut buf_slice = BufferSlice::new(&mut buf); 90 89 91 - assert_eq!(buf_slice.len(), 128); 92 - assert_eq!(buf_slice.extend_from_slice(&[0, 0, 0]), Err(aead::Error)); 93 - 94 - buf_slice.truncate(64); 90 + assert_eq!(buf_slice.len(), 0); 91 + assert_eq!(buf_slice.extend_from_slice(&[0; 129]), Err(aead::Error)); 95 92 96 93 assert_eq!(buf_slice.extend_from_slice(&[0, 0, 0, 0, 0, 0]), Ok(())); 97 - assert_eq!(buf_slice.len(), 70); 94 + assert_eq!(buf_slice.len(), 6); 98 95 } 99 96 100 97 #[test] 101 - fn reset_sets_length_to_buffer_max_length() { 98 + fn fill_sets_length_to_buffer_max_length() { 102 99 let mut buf = alloc::vec![0u8; 128]; 103 100 104 101 let mut buf_slice = BufferSlice::new(&mut buf); 105 102 106 - assert_eq!(buf_slice.len(), 128); 107 - 108 - buf_slice.truncate(64); 109 - 110 - assert_eq!(buf_slice.len(), 64); 103 + assert_eq!(buf_slice.len(), 0); 111 104 112 - buf_slice.reset(); 105 + buf_slice.fill(); 113 106 114 107 assert_eq!(buf_slice.len(), 128); 115 108 }