diff --git a/src/elligator/mod.rs b/src/elligator/mod.rs index 2df11f7..164020d 100644 --- a/src/elligator/mod.rs +++ b/src/elligator/mod.rs @@ -58,6 +58,7 @@ pub fn hash_to_point(bytes: &[u8]) -> EdwardsPoint { #[cfg(test)] mod tests { use super::*; + use std::convert::TryInto; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // Signal tests from // @@ -73,8 +74,8 @@ mod tests { #[test] fn elligator_correct() { let bytes: Vec = (0u8..32u8).collect(); - let mut bits_in = [0u8; 32]; - bits_in.copy_from_slice(&bytes); + let bits_in: [u8; 32] = (&bytes[..]).try_into().expect("Range invariant broken"); + let fe = FieldElement51::from_bytes(&bits_in); let eg = elligator_signal(&fe); assert_eq!(eg.to_bytes(), ELLIGATOR_CORRECT_OUTPUT); diff --git a/src/group.rs b/src/group.rs index 551403c..732260f 100644 --- a/src/group.rs +++ b/src/group.rs @@ -19,6 +19,7 @@ use generic_array::{ ArrayLength, GenericArray, }; use rand_core::{CryptoRng, RngCore}; +use std::convert::TryInto; use std::ops::Mul; use zeroize::Zeroize; @@ -86,7 +87,8 @@ impl Group for RistrettoPoint { element_bits: &GenericArray, ) -> Result { CompressedRistretto::from_slice(element_bits) - .decompress().ok_or(InternalPakeError::PointError) + .decompress() + .ok_or(InternalPakeError::PointError) } // serialization of a group element fn to_arr(&self) -> GenericArray { @@ -96,8 +98,9 @@ impl Group for RistrettoPoint { type UniformBytesLen = U64; fn hash_to_curve(uniform_bytes: &GenericArray) -> Self { - let mut bits = [0u8; 64]; - bits.copy_from_slice(&uniform_bytes); + let bits: [u8; 64] = (&uniform_bytes[..]) + .try_into() + .expect("GenericArray has a type-level length"); RistrettoPoint::from_uniform_bytes(&bits) } @@ -130,7 +133,8 @@ impl Group for EdwardsPoint { element_bits: &GenericArray, ) -> Result { let point = CompressedEdwardsY::from_slice(element_bits) - .decompress().ok_or(InternalPakeError::PointError)?; + .decompress() + .ok_or(InternalPakeError::PointError)?; if point.is_small_order() { return Err(InternalPakeError::SubGroupError); @@ -190,8 +194,9 @@ mod tests { ]; fn deserialize_point(pt: &[u8]) -> Result { - let mut bytes = [0u8; 32]; - bytes.copy_from_slice(&pt[..32]); + let bytes: [u8; 32] = (&pt[..32]) + .try_into() + .expect("Slice pattern invariant broken"); curve25519_dalek::edwards::CompressedEdwardsY(bytes) .decompress() diff --git a/src/keypair.rs b/src/keypair.rs index a425808..0c6bd8b 100644 --- a/src/keypair.rs +++ b/src/keypair.rs @@ -16,6 +16,7 @@ use proptest::prelude::*; #[cfg(test)] use rand::{rngs::StdRng, SeedableRng}; use rand_core::{CryptoRng, RngCore}; +use std::convert::TryInto; use std::fmt::Debug; use x25519_dalek::{PublicKey, StaticSecret}; @@ -216,15 +217,15 @@ impl KeyPair for X25519KeyPair { } fn public_from_private(secret: &Self::Repr) -> Self::Repr { - let mut secret_data = [0u8; 32]; - secret_data.copy_from_slice(&secret.0[..]); + let secret_data: [u8; 32] = (&secret.0[..]) + .try_into() + .expect("Keypair::Repr invariant broken"); let base_data = ::x25519_dalek::X25519_BASEPOINT_BYTES; Key(::x25519_dalek::x25519(secret_data, base_data).to_vec()) } fn check_public_key(key: Self::Repr) -> Result { - let mut key_bytes = [0u8; 32]; - key_bytes.copy_from_slice(&key); + let key_bytes: [u8; 32] = (&key[..]).try_into().expect("Key invariant broken"); let point = ::curve25519_dalek::montgomery::MontgomeryPoint(key_bytes) .to_edwards(1) .ok_or(InternalPakeError::PointError)?; diff --git a/src/opaque.rs b/src/opaque.rs index d98eacb..f65efb4 100644 --- a/src/opaque.rs +++ b/src/opaque.rs @@ -533,14 +533,12 @@ where /// byte representation for the server's registration state pub fn to_bytes(&self) -> Vec { let mut output: Vec = CS::Group::scalar_as_bytes(&self.oprf_key).to_vec(); - match &self.client_s_pk { - Some(v) => output.extend_from_slice(&v.to_arr()), - None => {} - }; - match &self.envelope { - Some(v) => output.extend_from_slice(&v.to_bytes()), - None => {} - }; + self.client_s_pk + .iter() + .for_each(|v| output.extend_from_slice(&v)); + self.envelope + .iter() + .for_each(|v| output.extend_from_slice(&v.to_bytes())); output } @@ -641,8 +639,6 @@ where /// The state elements the client holds to perform a login pub struct ClientLogin { - /// A choice of the keypair type - _key_format: PhantomData, /// A blinding factor, which is used to mask (and unmask) secret /// information before transmission blinding_factor: ::Scalar, @@ -675,7 +671,6 @@ impl TryFrom<&[u8]> for ClientLogin { )?; let password = bytes[scalar_len + ke1_state_size..].to_vec(); Ok(Self { - _key_format: PhantomData, blinding_factor, password, ke1_state, @@ -745,7 +740,6 @@ impl ClientLogin { Ok(( l1, Self { - _key_format: PhantomData, blinding_factor, password: password.to_vec(), ke1_state, @@ -986,7 +980,6 @@ impl ServerLogin { } // Helper functions - fn get_password_derived_key, D: Hash>( password: Vec, beta: G, diff --git a/src/tests/opaque_ke_test.rs b/src/tests/opaque_ke_test.rs index a79d23b..c13988d 100644 --- a/src/tests/opaque_ke_test.rs +++ b/src/tests/opaque_ke_test.rs @@ -558,7 +558,12 @@ fn test_complete_flow( hex::encode(login_export_key) ); } else { - let res = matches!(client_login_result, Err(ProtocolError::VerificationError(PakeError::InvalidLoginError))); + let res = matches!( + client_login_result, + Err(ProtocolError::VerificationError( + PakeError::InvalidLoginError + )) + ); assert!(res); }