diff --git a/src/ciphersuite.rs b/src/ciphersuite.rs index ad7b1ac..63f20dc 100644 --- a/src/ciphersuite.rs +++ b/src/ciphersuite.rs @@ -34,7 +34,7 @@ pub trait CipherSuite { /// A keypair type composed of public and private components type KeyFormat: KeyPair + PartialEq; /// A key exchange protocol - type KeyExchange: KeyExchange; + type KeyExchange: KeyExchange; /// The main hash function use (for HKDF computations and hashing transcripts) type Hash: Hash; /// A slow hashing function, typically used for password hashing diff --git a/src/key_exchange/traits.rs b/src/key_exchange/traits.rs index 543df0f..1786bec 100644 --- a/src/key_exchange/traits.rs +++ b/src/key_exchange/traits.rs @@ -12,19 +12,19 @@ use rand_core::{CryptoRng, RngCore}; use std::convert::TryFrom; -pub trait KeyExchange { +pub trait KeyExchange> { type KE1State: TryFrom, Error = InternalPakeError> + ToBytes; type KE2State: TryFrom, Error = ProtocolError> + ToBytes; type KE1Message: TryFrom, Error = InternalPakeError> + ToBytes; type KE2Message: TryFrom, Error = ProtocolError> + ToBytes; type KE3Message: TryFrom, Error = ProtocolError> + ToBytes; - fn generate_ke1>( + fn generate_ke1( l1_component: Vec, rng: &mut R, ) -> Result<(Self::KE1State, Self::KE1Message), ProtocolError>; - fn generate_ke2>( + fn generate_ke2( rng: &mut R, l1_bytes: Vec, l2_bytes: Vec, @@ -33,7 +33,7 @@ pub trait KeyExchange { server_s_sk: KeyFormat::Repr, ) -> Result<(Self::KE2State, Self::KE2Message), ProtocolError>; - fn generate_ke3>( + fn generate_ke3( l2_component: Vec, ke2_message: Self::KE2Message, ke1_state: &Self::KE1State, diff --git a/src/key_exchange/tripledh.rs b/src/key_exchange/tripledh.rs index 3ddbf5d..ad4ec97 100644 --- a/src/key_exchange/tripledh.rs +++ b/src/key_exchange/tripledh.rs @@ -31,14 +31,14 @@ static STR_3DH: &[u8] = b"3DH keys"; /// The Triple Diffie-Hellman key exchange implementation pub struct TripleDH; -impl KeyExchange for TripleDH { +impl> KeyExchange for TripleDH { type KE1State = KE1State<::OutputSize>; type KE2State = KE2State<::OutputSize>; type KE1Message = KE1Message; type KE2Message = KE2Message<::OutputSize>; type KE3Message = KE3Message<::OutputSize>; - fn generate_ke1>( + fn generate_ke1( l1_component: Vec, rng: &mut R, ) -> Result<(Self::KE1State, Self::KE1Message), ProtocolError> { @@ -69,7 +69,7 @@ impl KeyExchange for TripleDH { )) } - fn generate_ke2>( + fn generate_ke2( rng: &mut R, l1_bytes: Vec, l2_bytes: Vec, @@ -132,7 +132,7 @@ impl KeyExchange for TripleDH { )) } - fn generate_ke3>( + fn generate_ke3( l2_component: Vec, ke2_message: Self::KE2Message, ke1_state: &Self::KE1State, diff --git a/src/opaque.rs b/src/opaque.rs index f65efb4..39b2922 100644 --- a/src/opaque.rs +++ b/src/opaque.rs @@ -141,7 +141,7 @@ where pub struct LoginFirstMessage { /// blinded password information alpha: CS::Group, - ke1_message: >::KE1Message, + ke1_message: >::KE1Message, } impl TryFrom<&[u8]> for LoginFirstMessage { @@ -163,9 +163,10 @@ impl TryFrom<&[u8]> for LoginFirstMessage { let arr = GenericArray::from_slice(&checked_slice[..elem_len]); let alpha = CS::Group::from_element_slice(arr)?; - let ke1_message = >::KE1Message::try_from( - checked_slice[elem_len..].to_vec(), - )?; + let ke1_message = + >::KE1Message::try_from( + checked_slice[elem_len..].to_vec(), + )?; Ok(Self { alpha, ke1_message }) } } @@ -179,28 +180,15 @@ impl LoginFirstMessage { /// The answer sent by the server to the user, upon reception of the /// login attempt. -pub struct LoginSecondMessage -where - KeyFormat: KeyPair, - KE: KeyExchange, - D: Hash, -{ - _key_format: PhantomData, - _key_exchange: PhantomData, +pub struct LoginSecondMessage { /// the server's oprf output - beta: Grp, + beta: CS::Group, /// the user's sealed information, - envelope: Envelope, - ke2_message: KE::KE2Message, + envelope: Envelope, + ke2_message: >::KE2Message, } -impl LoginSecondMessage -where - Grp: Group, - KeyFormat: KeyPair, - KE: KeyExchange, - D: Hash, -{ +impl LoginSecondMessage { /// byte representation for the login response pub fn to_bytes(&self) -> Vec { [ @@ -212,19 +200,13 @@ where } } -impl TryFrom<&[u8]> for LoginSecondMessage -where - Grp: Group, - KeyFormat: KeyPair, - KE: KeyExchange, - D: Hash, -{ +impl TryFrom<&[u8]> for LoginSecondMessage { type Error = ProtocolError; fn try_from(second_message_bytes: &[u8]) -> Result { - let key_len = ::Len::to_usize(); - let envelope_size = key_len + Envelope::::additional_size(); - let elem_len = Grp::ElemLen::to_usize(); - let ke2_message_size = KE::ke2_message_size(); + let key_len = <::Repr as SizedBytes>::Len::to_usize(); + let envelope_size = key_len + Envelope::::additional_size(); + let elem_len = ::ElemLen::to_usize(); + let ke2_message_size = CS::KeyExchange::ke2_message_size(); let checked_slice = check_slice_size( second_message_bytes, elem_len + envelope_size + ke2_message_size, @@ -235,17 +217,17 @@ where // correct subgroup let beta_bytes = &checked_slice[..elem_len]; let arr = GenericArray::from_slice(beta_bytes); - let beta = Grp::from_element_slice(arr)?; + let beta = CS::Group::from_element_slice(arr)?; let envelope = - Envelope::::from_bytes(&checked_slice[elem_len..elem_len + envelope_size])?; + Envelope::::from_bytes(&checked_slice[elem_len..elem_len + envelope_size])?; let ke2_message = - KE::KE2Message::try_from(checked_slice[elem_len + envelope_size..].to_vec())?; + >::KE2Message::try_from( + checked_slice[elem_len + envelope_size..].to_vec(), + )?; Ok(Self { - _key_format: PhantomData, - _key_exchange: PhantomData, beta, envelope, ke2_message, @@ -256,7 +238,7 @@ where /// The answer sent by the client to the server, upon reception of the /// sealed envelope pub struct LoginThirdMessage { - ke3_message: >::KE3Message, + ke3_message: >::KE3Message, } impl TryFrom<&[u8]> for LoginThirdMessage { @@ -264,7 +246,9 @@ impl TryFrom<&[u8]> for LoginThirdMessage { fn try_from(bytes: &[u8]) -> Result { let ke3_message = - >::KE3Message::try_from(bytes.to_vec())?; + >::KE3Message::try_from( + bytes.to_vec(), + )?; Ok(Self { ke3_message }) } } @@ -644,14 +628,15 @@ pub struct ClientLogin { blinding_factor: ::Scalar, /// The user's password password: Vec, - ke1_state: >::KE1State, + ke1_state: >::KE1State, } impl TryFrom<&[u8]> for ClientLogin { type Error = ProtocolError; fn try_from(bytes: &[u8]) -> Result { let scalar_len = ::ScalarLen::to_usize(); - let ke1_state_size = >::ke1_state_size(); + let ke1_state_size = + >::ke1_state_size(); let min_expected_len = scalar_len + ke1_state_size; let checked_slice = (if bytes.len() <= min_expected_len { @@ -666,9 +651,10 @@ impl TryFrom<&[u8]> for ClientLogin { let blinding_factor_bytes = GenericArray::from_slice(&checked_slice[..scalar_len]); let blinding_factor = CS::Group::from_scalar_slice(blinding_factor_bytes)?; - let ke1_state = >::KE1State::try_from( - checked_slice[scalar_len..scalar_len + ke1_state_size].to_vec(), - )?; + let ke1_state = + >::KE1State::try_from( + checked_slice[scalar_len..scalar_len + ke1_state_size].to_vec(), + )?; let password = bytes[scalar_len + ke1_state_size..].to_vec(); Ok(Self { blinding_factor, @@ -732,8 +718,7 @@ impl ClientLogin { blinding_factor, } = oprf::generate_oprf1::(&password, pepper, rng)?; - let (ke1_state, ke1_message) = - CS::KeyExchange::generate_ke1::<_, CS::KeyFormat>(alpha.to_arr().to_vec(), rng)?; + let (ke1_state, ke1_message) = CS::KeyExchange::generate_ke1(alpha.to_arr().to_vec(), rng)?; let l1 = LoginFirstMessage { alpha, ke1_message }; @@ -784,7 +769,7 @@ impl ClientLogin { /// ``` pub fn finish( self, - l2: LoginSecondMessage, + l2: LoginSecondMessage, server_s_pk: &<::KeyFormat as KeyPair>::Repr, _client_e_sk_rng: &mut R, ) -> Result, ProtocolError> { @@ -804,7 +789,7 @@ impl ClientLogin { err => PakeError::from(err), })?; - let (shared_secret, ke3_message) = CS::KeyExchange::generate_ke3::( + let (shared_secret, ke3_message) = CS::KeyExchange::generate_ke3( l2_bytes, l2.ke2_message, &self.ke1_state, @@ -822,7 +807,7 @@ impl ClientLogin { /// The state elements the server holds to record a login pub struct ServerLogin { - ke2_state: >::KE2State, + ke2_state: >::KE2State, _cs: PhantomData, } @@ -831,22 +816,15 @@ impl TryFrom<&[u8]> for ServerLogin { fn try_from(bytes: &[u8]) -> Result { Ok(Self { _cs: PhantomData, - ke2_state: >::KE2State::try_from( - bytes.to_vec(), - )?, + ke2_state: + >::KE2State::try_from( + bytes.to_vec(), + )?, }) } } -type ServerLoginStartResult = ( - LoginSecondMessage< - ::Group, - ::KeyFormat, - ::KeyExchange, - ::Hash, - >, - ServerLogin, -); +type ServerLoginStartResult = (LoginSecondMessage, ServerLogin); impl ServerLogin { /// byte representation for the server's login state @@ -905,7 +883,7 @@ impl ServerLogin { let l2_component: Vec = [&beta.to_arr()[..], &envelope.to_bytes()].concat(); - let (ke2_state, ke2_message) = CS::KeyExchange::generate_ke2::<_, CS::KeyFormat>( + let (ke2_state, ke2_message) = CS::KeyExchange::generate_ke2( rng, l1_bytes.to_vec(), l2_component, @@ -915,8 +893,6 @@ impl ServerLogin { )?; let l2 = LoginSecondMessage { - _key_format: PhantomData, - _key_exchange: PhantomData, beta, envelope, ke2_message, @@ -969,13 +945,16 @@ impl ServerLogin { /// # Ok::<(), ProtocolError>(()) /// ``` pub fn finish(&self, message: LoginThirdMessage) -> Result, ProtocolError> { - >::finish_ke(message.ke3_message, &self.ke2_state) - .map_err(|e| match e { - ProtocolError::VerificationError(PakeError::KeyExchangeMacValidationError) => { - ProtocolError::VerificationError(PakeError::InvalidLoginError) - } - err => err, - }) + >::finish_ke( + message.ke3_message, + &self.ke2_state, + ) + .map_err(|e| match e { + ProtocolError::VerificationError(PakeError::KeyExchangeMacValidationError) => { + ProtocolError::VerificationError(PakeError::InvalidLoginError) + } + err => err, + }) } } diff --git a/src/tests/opaque_ke_test.rs b/src/tests/opaque_ke_test.rs index c13988d..15f66ba 100644 --- a/src/tests/opaque_ke_test.rs +++ b/src/tests/opaque_ke_test.rs @@ -471,19 +471,15 @@ fn test_l3() -> Result<(), PakeError> { let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap()); let mut client_e_sk_rng = CycleRng::new(parameters.client_e_sk.to_vec()); - let (l3, shared_secret, export_key_login) = ClientLogin::::try_from( - ¶meters.client_login_state[..], - ) - .unwrap() - .finish( - LoginSecondMessage::::try_from( - ¶meters.l2[..], - ) - .unwrap(), - &Key::try_from(¶meters.server_s_pk[..])?, - &mut client_e_sk_rng, - ) - .unwrap(); + let (l3, shared_secret, export_key_login) = + ClientLogin::::try_from(¶meters.client_login_state[..]) + .unwrap() + .finish( + LoginSecondMessage::::try_from(¶meters.l2[..]).unwrap(), + &Key::try_from(¶meters.server_s_pk[..])?, + &mut client_e_sk_rng, + ) + .unwrap(); assert_eq!( hex::encode(¶meters.shared_secret), diff --git a/src/tests/serialization.rs b/src/tests/serialization.rs index 47ead1e..9988901 100644 --- a/src/tests/serialization.rs +++ b/src/tests/serialization.rs @@ -167,8 +167,10 @@ fn login_first_message_roundtrip() { rng.fill_bytes(&mut client_nonce); let ke1m: Vec = [&client_nonce[..], &client_e_kp.public()].concat(); - let reg = - >::KE1Message::try_from(ke1m[..].to_vec()).unwrap(); + let reg = >::KE1Message::try_from( + ke1m[..].to_vec(), + ) + .unwrap(); let reg_bytes = reg.to_bytes(); assert_eq!(reg_bytes, ke1m); } @@ -197,7 +199,7 @@ proptest! { #[test] fn test_nocrash_login_second_message(bytes in vec(any::(), 0..500)) { - LoginSecondMessage::::try_from(&bytes[..]).map_or(true, |_| true); + LoginSecondMessage::::try_from(&bytes[..]).map_or(true, |_| true); } #[test]