From 55fad1bd1ed17801f203c82b5b269c03b113160c Mon Sep 17 00:00:00 2001 From: dAxpeDDa Date: Fri, 18 Feb 2022 23:39:35 +0100 Subject: [PATCH] (broken) Update dependencies --- Cargo.toml | 59 +- benches/opaque.rs | 2 +- src/ciphersuite.rs | 25 +- src/envelope.rs | 149 +++-- src/errors.rs | 12 + src/impls.rs | 36 +- .../group/{p256.rs => elliptic_curve.rs} | 40 +- src/key_exchange/group/mod.rs | 13 +- src/key_exchange/group/ristretto255.rs | 88 ++- src/key_exchange/traits.rs | 20 +- src/key_exchange/tripledh.rs | 53 +- src/keypair.rs | 16 +- src/lib.rs | 3 - src/messages.rs | 293 ++++++---- src/opaque.rs | 524 ++++++++++-------- src/serialization/tests.rs | 17 +- src/slow_hash.rs | 43 +- src/tests/full_test.rs | 88 ++- src/tests/test_opaque_vectors.rs | 49 +- 19 files changed, 881 insertions(+), 649 deletions(-) mode change 100644 => 100755 benches/opaque.rs mode change 100644 => 100755 src/ciphersuite.rs rename src/key_exchange/group/{p256.rs => elliptic_curve.rs} (59%) mode change 100644 => 100755 mode change 100644 => 100755 src/key_exchange/group/mod.rs mode change 100644 => 100755 src/keypair.rs mode change 100644 => 100755 src/lib.rs diff --git a/Cargo.toml b/Cargo.toml index 672707dc..4495a950 100755 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,34 +12,14 @@ rust-version = "1.56" version = "2.0.0-pre.1" [features] -default = ["ristretto255_u64", "serde"] -p256 = ["p256_", "voprf/p256"] -ristretto255 = [] -ristretto255_fiat_u32 = [ - "curve25519-dalek/fiat_u32_backend", - "ristretto255", - "voprf/ristretto255_fiat_u32", -] -ristretto255_fiat_u64 = [ - "curve25519-dalek/fiat_u64_backend", - "ristretto255", - "voprf/ristretto255_fiat_u64", -] -ristretto255_simd = [ - "curve25519-dalek/simd_backend", - "ristretto255", - "voprf/ristretto255_simd", -] -ristretto255_u32 = [ - "curve25519-dalek/u32_backend", - "ristretto255", - "voprf/ristretto255_u32", -] -ristretto255_u64 = [ - "curve25519-dalek/u64_backend", - "ristretto255", - "voprf/ristretto255_u64", -] +default = ["ristretto255_u64", "ristretto255_voprf", "serde"] +ristretto255 = ["voprf/ristretto255"] +ristretto255_fiat_u32 = ["curve25519-dalek/fiat_u32_backend", "ristretto255"] +ristretto255_fiat_u64 = ["curve25519-dalek/fiat_u64_backend", "ristretto255"] +ristretto255_simd = ["curve25519-dalek/simd_backend", "ristretto255"] +ristretto255_u32 = ["curve25519-dalek/u32_backend", "ristretto255"] +ristretto255_u64 = ["curve25519-dalek/u64_backend", "ristretto255"] +ristretto255_voprf = ["ristretto255", "voprf/ristretto255-ciphersuite"] serde = ["serde_", "generic-array/serde", "voprf/serde"] slow-hash = ["argon2"] std = ["getrandom", "rand/std", "rand/std_rng", "voprf/std"] @@ -60,26 +40,24 @@ argon2 = { version = "0.3", default-features = false, features = [ "alloc", ], optional = true } constant_time_eq = "0.1" -curve25519-dalek = { version = "3", default-features = false, optional = true } -derive-where = { version = "1.0.0-rc.1", features = ["zeroize"] } +curve25519-dalek = { version = "=4.0.0-pre.1", default-features = false, optional = true } +derive-where = { version = "=1.0.0-rc.2", features = ["zeroize-on-drop"] } digest = "0.10" displaydoc = { version = "0.2", default-features = false } +elliptic-curve = { version = "0.12.0-pre.1", features = ["sec1"] } generic-array = "0.14" getrandom = { version = "0.2", optional = true } hkdf = "0.12" hmac = "0.12" -p256_ = { package = "p256", version = "0.10", default-features = false, features = [ - "arithmetic", -], optional = true } rand = { version = "0.8", default-features = false } serde_ = { version = "1", package = "serde", default-features = false, features = [ "derive", ], optional = true } subtle = { version = "2.3", default-features = false } -voprf = { git = "https://github.com/novifinancial/voprf", rev = "55ef981a3f9a12eddd8c372ffdf51818011343ee", default-features = false, features = [ +voprf = { version = "0.3", default-features = false, features = [ "danger", ] } -x25519-dalek = { version = "1", default-features = false, optional = true } +x25519-dalek = { version = "=2.0.0-pre.1", default-features = false, optional = true } zeroize = { version = "1", features = ["zeroize_derive"] } [target.'cfg(target_arch = "wasm32")'.dependencies] @@ -93,6 +71,7 @@ criterion = "0.3" hex = "0.4" json = "0.12" lazy_static = "1" +p256 = { version = "=0.11.0-pre.0", default-features = false } proptest = "1" regex = "1" rustyline = "9" @@ -102,3 +81,13 @@ sha2 = "0.10" [[bench]] harness = false name = "opaque" + +[package.metadata.docs.rs] +features = ["std", "slow-hash", "x25519_u64"] +targets = [] + +[patch.crates-io] +chacha20 = { git = "https://github.com/RustCrypto/stream-ciphers" } +chacha20poly1305 = { git = "https://github.com/khonsulabs/aeads", branch = "update-dependencies" } +poly1305 = { git = "https://github.com/RustCrypto/universal-hashes" } +voprf = { git = "https://github.com/khonsulabs/voprf", branch = "v08" } diff --git a/benches/opaque.rs b/benches/opaque.rs old mode 100644 new mode 100755 index 4cdd64f8..5155df5f --- a/benches/opaque.rs +++ b/benches/opaque.rs @@ -20,7 +20,7 @@ static SUFFIX: &str = "ristretto255_u32"; static SUFFIX: &str = "ristretto255_fiat_u64"; #[cfg(feature = "ristretto255_fiat_u32")] static SUFFIX: &str = "ristretto255_fiat_u32"; -#[cfg(all(not(feature = "ristretto255"), feature = "p256"))] +#[cfg(all(not(feature = "ristretto255")))] static SUFFIX: &str = "p256"; struct Default; diff --git a/src/ciphersuite.rs b/src/ciphersuite.rs old mode 100644 new mode 100755 index 2bbe8687..3f2ad733 --- a/src/ciphersuite.rs +++ b/src/ciphersuite.rs @@ -9,8 +9,8 @@ //! OPAQUE use digest::core_api::{BlockSizeUser, CoreProxy}; -use generic_array::typenum::{IsLess, Le, NonZero, U256}; -use voprf::Group as OprfGroup; +use digest::OutputSizeUser; +use generic_array::typenum::{IsLess, IsLessOrEqual, Le, NonZero, U256}; use crate::hash::{Hash, ProxyHash}; use crate::key_exchange::group::KeGroup; @@ -28,21 +28,24 @@ use crate::slow_hash::SlowHash; /// * `SlowHash`: A slow hashing function, typically used for password hashing pub trait CipherSuite where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// A finite cyclic group along with a point representation along with an /// extension trait PasswordToCurve that allows some customization on how to /// hash a password to a curve point. See `group::Group`. - type OprfGroup: OprfGroup; + type OprfGroup: voprf::CipherSuite; /// A `Group` used for the `KeyExchange`. type KeGroup: KeGroup; /// A key exchange protocol - type KeyExchange: KeyExchange; - /// The main hash function use (for HKDF computations and hashing - /// transcripts) - type Hash: Hash; + type KeyExchange: KeyExchange, Self::KeGroup>; /// A slow hashing function, typically used for password hashing - type SlowHash: SlowHash; + type SlowHash: SlowHash; } + +pub type OprfGroup = <::OprfGroup as voprf::CipherSuite>::Group; +pub type OprfHash = <::OprfGroup as voprf::CipherSuite>::Hash; diff --git a/src/envelope.rs b/src/envelope.rs index 93d8f8eb..aa40a489 100755 --- a/src/envelope.rs +++ b/src/envelope.rs @@ -8,19 +8,19 @@ use core::convert::TryFrom; use core::ops::Add; -use derive_where::DeriveWhere; +use derive_where::derive_where; use digest::core_api::{BlockSizeUser, CoreProxy}; -use digest::Output; +use digest::{Output, OutputSizeUser}; use generic_array::sequence::Concat; -use generic_array::typenum::{IsLess, Le, NonZero, Sum, Unsigned, U2, U256, U32}; +use generic_array::typenum::{IsLess, IsLessOrEqual, Le, NonZero, Sum, Unsigned, U2, U256, U32}; use generic_array::{ArrayLength, GenericArray}; use hkdf::Hkdf; use hmac::{Hmac, Mac}; use rand::{CryptoRng, RngCore}; use voprf::Group; -use zeroize::Zeroize; +use zeroize::{Zeroize, ZeroizeOnDrop}; -use crate::ciphersuite::CipherSuite; +use crate::ciphersuite::{CipherSuite, OprfGroup, OprfHash}; use crate::errors::utils::check_slice_size; use crate::errors::{InternalError, ProtocolError}; use crate::hash::{Hash, OutputSize, ProxyHash}; @@ -66,17 +66,46 @@ impl TryFrom for InnerEnvelopeMode { /// The specification update has simplified this assumption by taking an /// XOR-based approach without compromising on security, and to avoid the /// confusion around the implementation of an RKR-secure encryption. -#[derive(DeriveWhere)] -#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize(drop))] +#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub(crate) struct Envelope where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { pub(crate) mode: InnerEnvelopeMode, nonce: GenericArray, - hmac: Output, + hmac: Output>, +} + +impl Drop for Envelope +where + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + fn drop(&mut self) { + self.mode.zeroize(); + self.nonce.zeroize(); + self.hmac.zeroize(); + } +} + +impl ZeroizeOnDrop for Envelope +where + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ } // Note that this struct represents an envelope that has been "opened" with the @@ -85,12 +114,15 @@ where // contents. pub(crate) struct OpenedEnvelope<'a, CS: CipherSuite> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { pub(crate) client_static_keypair: KeyPair, - pub(crate) export_key: Output, + pub(crate) export_key: Output>, pub(crate) id_u: Serialize<'a, U2, ::PkLen>, pub(crate) id_s: Serialize<'a, U2, ::PkLen>, } @@ -105,31 +137,34 @@ where } #[cfg(not(test))] -type SealRawResult = (Envelope, Output); +type SealRawResult = (Envelope, Output>); #[cfg(test)] -type SealRawResult = (Envelope, Output, Output); +type SealRawResult = (Envelope, Output>, Output>); #[cfg(not(test))] -type SealResult = (Envelope, PublicKey, Output); +type SealResult = (Envelope, PublicKey, Output>); #[cfg(test)] type SealResult = ( Envelope, PublicKey, - Output, - Output, + Output>, + Output>, ); -pub(crate) type EnvelopeLen = Sum>; +pub(crate) type EnvelopeLen = Sum>>; impl Envelope where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { #[allow(clippy::type_complexity)] pub(crate) fn seal( rng: &mut R, - randomized_pwd_hasher: Hkdf, + randomized_pwd_hasher: Hkdf>, server_s_pk: &PublicKey, ids: Identifiers, ) -> Result, ProtocolError> { @@ -163,13 +198,13 @@ where /// the aad field. Note that a new nonce is sampled for each call to seal. #[allow(clippy::type_complexity)] pub(crate) fn seal_raw<'a>( - randomized_pwd_hasher: Hkdf, + randomized_pwd_hasher: Hkdf>, nonce: GenericArray, aad: impl Iterator, mode: InnerEnvelopeMode, ) -> Result, InternalError> { - let mut hmac_key = Output::::default(); - let mut export_key = Output::::default(); + let mut hmac_key = Output::>::default(); + let mut export_key = Output::>::default(); randomized_pwd_hasher .expand_multi_info(&[&nonce, &STR_AUTH_KEY], &mut hmac_key) @@ -178,8 +213,8 @@ where .expand_multi_info(&[&nonce, &STR_EXPORT_KEY], &mut export_key) .map_err(|_| InternalError::HkdfError)?; - let mut hmac = - Hmac::::new_from_slice(&hmac_key).map_err(|_| InternalError::HmacError)?; + let mut hmac = Hmac::>::new_from_slice(&hmac_key) + .map_err(|_| InternalError::HmacError)?; hmac.update(&nonce); hmac.update_iter(aad); @@ -199,7 +234,7 @@ where pub(crate) fn open<'a>( &self, - randomized_pwd_hasher: Hkdf, + randomized_pwd_hasher: Hkdf>, server_s_pk: PublicKey, optional_ids: Identifiers<'a>, ) -> Result, ProtocolError> { @@ -234,11 +269,11 @@ where /// if the key and aad used to construct the envelope are the same. pub(crate) fn open_raw<'a>( &self, - randomized_pwd_hasher: Hkdf, + randomized_pwd_hasher: Hkdf>, aad: impl Iterator, - ) -> Result, InternalError> { - let mut hmac_key = Output::::default(); - let mut export_key = Output::::default(); + ) -> Result>, InternalError> { + let mut hmac_key = Output::>::default(); + let mut export_key = Output::>::default(); randomized_pwd_hasher .expand(&self.nonce.concat(STR_AUTH_KEY.into()), &mut hmac_key) @@ -247,8 +282,8 @@ where .expand(&self.nonce.concat(STR_EXPORT_KEY.into()), &mut export_key) .map_err(|_| InternalError::HkdfError)?; - let mut hmac = - Hmac::::new_from_slice(&hmac_key).map_err(|_| InternalError::HmacError)?; + let mut hmac = Hmac::>::new_from_slice(&hmac_key) + .map_err(|_| InternalError::HmacError)?; hmac.update(&self.nonce); hmac.update_iter(aad); hmac.verify(&self.hmac) @@ -267,17 +302,17 @@ where } fn hmac_key_size() -> usize { - OutputSize::::USIZE + OutputSize::>::USIZE } pub(crate) fn len() -> usize { - OutputSize::::USIZE + NonceLen::USIZE + OutputSize::>::USIZE + NonceLen::USIZE } pub(crate) fn serialize(&self) -> GenericArray> where // Envelope: Nonce + Hash - NonceLen: Add>, + NonceLen: Add>>, EnvelopeLen: ArrayLength, { self.nonce.concat(self.hmac.clone()) @@ -312,13 +347,16 @@ where // Helper functions fn build_inner_envelope_internal( - randomized_pwd_hasher: Hkdf, + randomized_pwd_hasher: Hkdf>, nonce: GenericArray, ) -> Result, ProtocolError> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { let mut keypair_seed = GenericArray::<_, ::SkLen>::default(); randomized_pwd_hasher @@ -326,9 +364,9 @@ where .map_err(|_| InternalError::HkdfError)?; let client_static_keypair = KeyPair::::from_private_key_slice( // TODO: Use `KeGroup` instead of `OprfGroup` here. - &CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::( - [keypair_seed.as_slice()], - GenericArray::from(STR_OPAQUE_DERIVE_AUTH_KEY_PAIR), + &OprfGroup::::serialize_scalar(OprfGroup::::hash_to_scalar::( + &[keypair_seed.as_slice()], + &GenericArray::from(STR_OPAQUE_DERIVE_AUTH_KEY_PAIR), )?), )?; @@ -336,22 +374,25 @@ where } fn recover_keys_internal( - randomized_pwd_hasher: Hkdf, + randomized_pwd_hasher: Hkdf>, nonce: GenericArray, ) -> Result, ProtocolError> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { let mut keypair_seed = GenericArray::<_, ::SkLen>::default(); randomized_pwd_hasher .expand(&nonce.concat(STR_PRIVATE_KEY.into()), &mut keypair_seed) .map_err(|_| InternalError::HkdfError)?; let client_static_keypair = KeyPair::::from_private_key_slice( - &CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::( - [keypair_seed.as_slice()], - GenericArray::from(STR_OPAQUE_DERIVE_AUTH_KEY_PAIR), + &OprfGroup::::serialize_scalar(OprfGroup::::hash_to_scalar::( + &[keypair_seed.as_slice()], + &GenericArray::from(STR_OPAQUE_DERIVE_AUTH_KEY_PAIR), )?), )?; diff --git a/src/errors.rs b/src/errors.rs index e35cd38a..ca5ab688 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -49,6 +49,8 @@ pub enum InternalError { InvalidInnerEnvelopeError, /// Error from the OPRF evaluation OprfError(voprf::Error), + /// Error from the OPRF evaluation + OprfInternalError(voprf::InternalError), /// Error encountered when attempting to produce a keypair InvalidKeypairError, } @@ -79,6 +81,9 @@ impl Debug for InternalError { } Self::InvalidInnerEnvelopeError => f.debug_tuple("InvalidInnerEnvelopeError").finish(), Self::OprfError(error) => f.debug_tuple("OprfError").field(error).finish(), + Self::OprfInternalError(error) => { + f.debug_tuple("OprfInternalError").field(error).finish() + } Self::InvalidKeypairError => f.debug_tuple("InvalidKeypairError").finish(), } } @@ -111,6 +116,7 @@ impl InternalError { Self::IncompatibleEnvelopeModeError => InternalError::IncompatibleEnvelopeModeError, Self::InvalidInnerEnvelopeError => InternalError::InvalidInnerEnvelopeError, Self::OprfError(error) => InternalError::OprfError(error), + Self::OprfInternalError(error) => InternalError::OprfInternalError(error), Self::InvalidKeypairError => InternalError::InvalidKeypairError, } } @@ -128,6 +134,12 @@ impl From for ProtocolError { } } +impl From for ProtocolError { + fn from(voprf_error: voprf::InternalError) -> Self { + Self::LibraryError(InternalError::OprfInternalError(voprf_error)) + } +} + /// Represents an error in protocol handling #[derive(Clone, Copy, Display, Eq, Hash, Ord, PartialEq, PartialOrd)] pub enum ProtocolError { diff --git a/src/impls.rs b/src/impls.rs index a579a767..ccdb6376 100755 --- a/src/impls.rs +++ b/src/impls.rs @@ -11,9 +11,12 @@ macro_rules! impl_serialize_and_deserialize_for { #[cfg(feature = "serde")] impl serde_::Serialize for $item where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, $($($path: $bound1 $(+ $bound2)*),+)? { fn serialize(&self, serializer: S) -> Result @@ -27,9 +30,12 @@ macro_rules! impl_serialize_and_deserialize_for { #[cfg(feature = "serde")] impl<'de, CS: CipherSuite> serde_::Deserialize<'de> for $item where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { fn deserialize(deserializer: D) -> Result where @@ -39,15 +45,21 @@ macro_rules! impl_serialize_and_deserialize_for { struct ByteVisitor(core::marker::PhantomData) where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero; + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero; impl<'de, CS: CipherSuite> serde_::de::Visitor<'de> for ByteVisitor where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { type Value = $item; diff --git a/src/key_exchange/group/p256.rs b/src/key_exchange/group/elliptic_curve.rs old mode 100644 new mode 100755 similarity index 59% rename from src/key_exchange/group/p256.rs rename to src/key_exchange/group/elliptic_curve.rs index 6b43ad47..fb560d71 --- a/src/key_exchange/group/p256.rs +++ b/src/key_exchange/group/elliptic_curve.rs @@ -5,34 +5,40 @@ // License, Version 2.0 found in the LICENSE-APACHE file in the root directory // of this source tree. -//! Key Exchange group implementation for p256 - -use generic_array::typenum::{U32, U33}; +use elliptic_curve::sec1::{FromEncodedPoint, ModulusSize, ToEncodedPoint}; +use elliptic_curve::{ + AffinePoint, Curve, FieldSize, ProjectiveArithmetic, ProjectivePoint, PublicKey, SecretKey, +}; use generic_array::GenericArray; -use p256::elliptic_curve::group::GroupEncoding; -use p256::elliptic_curve::sec1::ToEncodedPoint; -use p256::elliptic_curve::{PublicKey, SecretKey}; -use p256::NistP256; use rand::{CryptoRng, RngCore}; use super::KeGroup; use crate::errors::InternalError; -impl KeGroup for NistP256 { +impl KeGroup for G +where + FieldSize: ModulusSize, + AffinePoint: FromEncodedPoint + ToEncodedPoint, + ProjectivePoint: ToEncodedPoint, +{ type Pk = PublicKey; - type PkLen = U33; + + type PkLen = as ModulusSize>::CompressedPointSize; + type Sk = SecretKey; - type SkLen = U32; + + type SkLen = FieldSize; + fn serialize_pk(pk: &Self::Pk) -> GenericArray { GenericArray::clone_from_slice(pk.to_encoded_point(true).as_bytes()) } fn deserialize_pk(bytes: &GenericArray) -> Result { - Self::Pk::from_sec1_bytes(bytes).map_err(|_| InternalError::PointError) + PublicKey::::from_sec1_bytes(bytes).map_err(|_| InternalError::PointError) } fn random_sk(rng: &mut R) -> Self::Sk { - SecretKey::::random(rng) + SecretKey::::random(rng) } fn public_key(sk: &Self::Sk) -> Self::Pk { @@ -40,12 +46,14 @@ impl KeGroup for NistP256 { } fn diffie_hellman(pk: &Self::Pk, sk: &Self::Sk) -> GenericArray { - (pk.to_projective() * sk.to_nonzero_scalar().as_ref()) - .to_affine() - .to_bytes() + GenericArray::clone_from_slice( + (pk.to_projective() * sk.to_nonzero_scalar().as_ref()) + .to_encoded_point(true) + .as_bytes(), + ) } - fn zeroize_sk_on_drop(_: &mut Self::Sk) {} + fn zeroize_sk_on_drop(_sk: &mut Self::Sk) {} fn serialize_sk(sk: &Self::Sk) -> GenericArray { sk.to_be_bytes() diff --git a/src/key_exchange/group/mod.rs b/src/key_exchange/group/mod.rs old mode 100644 new mode 100755 index db2bc991..2e96e8f9 --- a/src/key_exchange/group/mod.rs +++ b/src/key_exchange/group/mod.rs @@ -7,6 +7,12 @@ //! Includes the KeGroup trait and definitions for the key exchange groups +mod elliptic_curve; +#[cfg(feature = "ristretto255")] +pub mod ristretto255; +#[cfg(feature = "x25519")] +pub mod x25519; + use generic_array::{ArrayLength, GenericArray}; use rand::{CryptoRng, RngCore}; @@ -47,10 +53,3 @@ pub trait KeGroup { /// Return a public key from its fixed-length bytes representation fn deserialize_sk(bytes: &GenericArray) -> Result; } - -#[cfg(feature = "p256")] -pub mod p256; -#[cfg(feature = "ristretto255")] -pub mod ristretto255; -#[cfg(feature = "x25519")] -pub mod x25519; diff --git a/src/key_exchange/group/ristretto255.rs b/src/key_exchange/group/ristretto255.rs index 53598419..1a5ff247 100644 --- a/src/key_exchange/group/ristretto255.rs +++ b/src/key_exchange/group/ristretto255.rs @@ -10,15 +10,20 @@ use curve25519_dalek::constants::RISTRETTO_BASEPOINT_POINT; use curve25519_dalek::ristretto::{CompressedRistretto, RistrettoPoint}; use curve25519_dalek::scalar::Scalar; -use generic_array::typenum::U32; +use digest::core_api::BlockSizeUser; +use digest::OutputSizeUser; +use generic_array::typenum::{IsLess, IsLessOrEqual, U256, U32}; use generic_array::GenericArray; use rand::{CryptoRng, RngCore}; +use voprf::Group; use zeroize::Zeroize; use super::KeGroup; use crate::errors::InternalError; /// Implementation for Ristretto255. +// This is necessary because Rust lacks specialization, otherwise we could +// implement `KeGroup` for `voprf::Ristretto255`. pub struct Ristretto255; impl KeGroup for Ristretto255 { @@ -80,10 +85,83 @@ impl KeGroup for Ristretto255 { } fn deserialize_sk(bytes: &GenericArray) -> Result { - // TODO: When we implement `hash_to_field` we can re-enable this again. - //Scalar::from_canonical_bytes((*bytes).into()).ok_or(InternalError:: - // PointError) + Scalar::from_canonical_bytes((*bytes).into()).ok_or(InternalError::PointError) + } +} + +#[cfg(feature = "ristretto255_voprf")] +impl voprf::CipherSuite for Ristretto255 { + const ID: u16 = voprf::Ristretto255::ID; + + type Group = ::Group; + + type Hash = ::Hash; +} + +impl Group for Ristretto255 { + type Elem = ::Elem; + + type ElemLen = ::ElemLen; + + type Scalar = ::Scalar; + + type ScalarLen = ::ScalarLen; + + fn hash_to_curve( + input: &[&[u8]], + dst: &[u8], + ) -> voprf::Result + where + ::OutputSize: + IsLess + IsLessOrEqual<::BlockSize>, + { + ::hash_to_curve::(input, dst) + } + + fn hash_to_scalar( + input: &[&[u8]], + dst: &[u8], + ) -> voprf::Result + where + ::OutputSize: + IsLess + IsLessOrEqual<::BlockSize>, + { + ::hash_to_scalar::(input, dst) + } + + fn base_elem() -> Self::Elem { + ::base_elem() + } + + fn identity_elem() -> Self::Elem { + ::identity_elem() + } + + fn serialize_elem(elem: Self::Elem) -> GenericArray { + ::serialize_elem(elem) + } + + fn deserialize_elem(element_bits: &[u8]) -> voprf::Result { + ::deserialize_elem(element_bits) + } + + fn random_scalar(rng: &mut R) -> Self::Scalar { + ::random_scalar(rng) + } + + fn invert_scalar(scalar: Self::Scalar) -> Self::Scalar { + ::invert_scalar(scalar) + } + + fn is_zero_scalar(scalar: Self::Scalar) -> subtle::Choice { + ::is_zero_scalar(scalar) + } + + fn serialize_scalar(scalar: Self::Scalar) -> GenericArray { + ::serialize_scalar(scalar) + } - Ok(Scalar::from_bits((*bytes).into())) + fn deserialize_scalar(scalar_bits: &[u8]) -> voprf::Result { + ::deserialize_scalar(scalar_bits) } } diff --git a/src/key_exchange/traits.rs b/src/key_exchange/traits.rs index 4e2bfe8b..6daf7407 100755 --- a/src/key_exchange/traits.rs +++ b/src/key_exchange/traits.rs @@ -10,9 +10,9 @@ use digest::Output; use generic_array::typenum::{IsLess, Le, NonZero, U256}; use generic_array::{ArrayLength, GenericArray}; use rand::{CryptoRng, RngCore}; -use zeroize::Zeroize; +use zeroize::ZeroizeOnDrop; -use crate::ciphersuite::CipherSuite; +use crate::ciphersuite::{CipherSuite, OprfHash}; use crate::errors::ProtocolError; use crate::hash::{Hash, ProxyHash}; use crate::key_exchange::group::KeGroup; @@ -46,9 +46,9 @@ where ::BlockSize: IsLess, Le<::BlockSize, U256>: NonZero, { - type KE1State: FromBytes + ToBytes + Zeroize + Clone; - type KE2State: FromBytes + ToBytes + Zeroize + Clone; - type KE1Message: FromBytes + ToBytes + Zeroize + Clone; + type KE1State: FromBytes + ToBytes + ZeroizeOnDrop + Clone; + type KE2State: FromBytes + ToBytes + ZeroizeOnDrop + Clone; + type KE1Message: FromBytes + ToBytes + ZeroizeOnDrop + Clone; type KE2Message: FromBytes + ToBytes + Clone; type KE3Message: FromBytes + ToBytes + Clone; @@ -103,12 +103,12 @@ pub trait ToBytes { #[allow(dead_code)] pub type Ke1StateLen = - <>::KE1State as ToBytes>::Len; + <, CS::KeGroup>>::KE1State as ToBytes>::Len; pub type Ke1MessageLen = - <>::KE1Message as ToBytes>::Len; + <, CS::KeGroup>>::KE1Message as ToBytes>::Len; pub type Ke2StateLen = - <>::KE2State as ToBytes>::Len; + <, CS::KeGroup>>::KE2State as ToBytes>::Len; pub type Ke2MessageLen = - <>::KE2Message as ToBytes>::Len; + <, CS::KeGroup>>::KE2Message as ToBytes>::Len; pub type Ke3MessageLen = - <>::KE3Message as ToBytes>::Len; + <, CS::KeGroup>>::KE3Message as ToBytes>::Len; diff --git a/src/key_exchange/tripledh.rs b/src/key_exchange/tripledh.rs index 204e379e..b07aafbc 100755 --- a/src/key_exchange/tripledh.rs +++ b/src/key_exchange/tripledh.rs @@ -9,7 +9,7 @@ use core::convert::TryFrom; use core::ops::Add; -use derive_where::DeriveWhere; +use derive_where::derive_where; use digest::core_api::BlockSizeUser; use digest::{Digest, Output}; use generic_array::sequence::Concat; @@ -18,6 +18,7 @@ use generic_array::{ArrayLength, GenericArray}; use hkdf::{Hkdf, HkdfExtract}; use hmac::{Hmac, Mac}; use rand::{CryptoRng, RngCore}; +use zeroize::{Zeroize, ZeroizeOnDrop}; use crate::errors::utils::{check_slice_size, check_slice_size_atleast}; use crate::errors::{InternalError, ProtocolError}; @@ -63,15 +64,21 @@ pub struct TripleDH; crate = "serde_" ) )] -#[derive(DeriveWhere)] -#[derive_where(Clone, Zeroize(drop))] +#[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; KG::Sk)] pub struct Ke1State { - #[derive_where(skip(Zeroize))] client_e_sk: PrivateKey, client_nonce: GenericArray, } +impl Drop for Ke1State { + fn drop(&mut self) { + self.client_nonce.zeroize(); + } +} + +impl ZeroizeOnDrop for Ke1State {} + /// The first key exchange message #[cfg_attr( feature = "serde", @@ -84,23 +91,28 @@ pub struct Ke1State { crate = "serde_" ) )] -#[derive(DeriveWhere)] -#[derive_where(Clone, Zeroize(drop))] +#[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; KG::Pk)] pub struct Ke1Message { pub(crate) client_nonce: GenericArray, - #[derive_where(skip(Zeroize))] pub(crate) client_e_pk: PublicKey, } +impl Drop for Ke1Message { + fn drop(&mut self) { + self.client_nonce.zeroize(); + } +} + +impl ZeroizeOnDrop for Ke1Message {} + /// The server state produced after the second key exchange message #[cfg_attr( feature = "serde", derive(serde_::Deserialize, serde_::Serialize), serde(bound = "", crate = "serde_") )] -#[derive(DeriveWhere)] -#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize(drop))] +#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Ke2State where D::Core: ProxyHash, @@ -112,6 +124,27 @@ where session_key: Output, } +impl Drop for Ke2State +where + D::Core: ProxyHash, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ + fn drop(&mut self) { + self.km3.zeroize(); + self.hashed_transcript.zeroize(); + self.session_key.zeroize(); + } +} + +impl ZeroizeOnDrop for Ke2State +where + D::Core: ProxyHash, + ::BlockSize: IsLess, + Le<::BlockSize, U256>: NonZero, +{ +} + /// The second key exchange message #[cfg_attr( feature = "serde", @@ -124,7 +157,6 @@ where crate = "serde_" ) )] -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; KG::Pk)] pub struct Ke2Message @@ -144,7 +176,6 @@ where derive(serde_::Deserialize, serde_::Serialize), serde(bound = "", crate = "serde_") )] -#[derive(DeriveWhere)] #[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)] pub struct Ke3Message where diff --git a/src/keypair.rs b/src/keypair.rs old mode 100644 new mode 100755 index 19bac6ad..855b6e50 --- a/src/keypair.rs +++ b/src/keypair.rs @@ -9,9 +9,10 @@ #![allow(unsafe_code)] -use derive_where::DeriveWhere; +use derive_where::derive_where; use generic_array::{ArrayLength, GenericArray}; use rand::{CryptoRng, RngCore}; +use zeroize::ZeroizeOnDrop; use crate::errors::{InternalError, ProtocolError}; use crate::key_exchange::group::KeGroup; @@ -29,7 +30,6 @@ use crate::serialization::GenericArrayExt; crate = "serde_" ) )] -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; KG::Pk, S)] pub struct KeyPair = PrivateKey> { @@ -109,7 +109,6 @@ where crate = "serde_" ) )] -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; KG::Sk)] pub struct PrivateKey(KG::Sk); @@ -120,6 +119,8 @@ impl Drop for PrivateKey { } } +impl ZeroizeOnDrop for PrivateKey {} + impl PrivateKey { /// Convert from bytes pub fn from_bytes(key_bytes: &GenericArray) -> Result { @@ -186,7 +187,6 @@ impl SecretKey for PrivateKey { crate = "serde_" ) )] -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; KG::Pk)] pub struct PublicKey(KG::Pk); @@ -226,7 +226,6 @@ mod tests { #[cfg(feature = "ristretto255")] inner::(); - #[cfg(feature = "p256")] inner::<::p256::NistP256>(); } @@ -273,7 +272,6 @@ mod tests { #[cfg(feature = "ristretto255")] test!(ristretto, crate::Ristretto255); - #[cfg(feature = "p256")] test!(p256, ::p256::NistP256); #[test] @@ -294,16 +292,12 @@ mod tests { #[cfg(feature = "ristretto255")] type OprfGroup = curve25519_dalek::ristretto::RistrettoPoint; #[cfg(not(feature = "ristretto255"))] - type OprfGroup = ::p256::ProjectivePoint; + type OprfGroup = p256::ProjectivePoint; #[cfg(feature = "ristretto255")] type KeGroup = crate::Ristretto255; #[cfg(not(feature = "ristretto255"))] type KeGroup = ::p256::NistP256; type KeyExchange = crate::key_exchange::tripledh::TripleDH; - #[cfg(feature = "ristretto255")] - type Hash = sha2::Sha512; - #[cfg(not(feature = "ristretto255"))] - type Hash = sha2::Sha256; type SlowHash = crate::slow_hash::NoOpHash; } diff --git a/src/lib.rs b/src/lib.rs old mode 100644 new mode 100755 index 41040647..0bdca4b5 --- a/src/lib.rs +++ b/src/lib.rs @@ -1059,9 +1059,6 @@ #[cfg(any(feature = "std", test))] extern crate std; -#[cfg(feature = "p256")] -extern crate p256_ as p256; - // Error types pub mod errors; diff --git a/src/messages.rs b/src/messages.rs index d94957c6..96213bf3 100755 --- a/src/messages.rs +++ b/src/messages.rs @@ -9,20 +9,22 @@ use core::ops::Add; -use derive_where::DeriveWhere; +use derive_where::derive_where; use digest::core_api::{BlockSizeUser, CoreProxy}; -use digest::Output; +use digest::{Output, OutputSizeUser}; use generic_array::sequence::Concat; -use generic_array::typenum::{IsLess, Le, NonZero, Sum, Unsigned, U256}; +use generic_array::typenum::{IsLess, IsLessOrEqual, Le, NonZero, Sum, Unsigned, U256}; use generic_array::{ArrayLength, GenericArray}; use rand::{CryptoRng, RngCore}; +use subtle::ConstantTimeEq; use voprf::Group; +use zeroize::{Zeroize, ZeroizeOnDrop}; -use crate::ciphersuite::CipherSuite; +use crate::ciphersuite::{CipherSuite, OprfGroup, OprfHash}; use crate::envelope::{Envelope, EnvelopeLen}; use crate::errors::utils::{check_slice_size, check_slice_size_atleast}; use crate::errors::ProtocolError; -use crate::hash::{OutputSize, ProxyHash}; +use crate::hash::{Hash, OutputSize, ProxyHash}; use crate::key_exchange::group::KeGroup; use crate::key_exchange::traits::{ FromBytes, Ke1MessageLen, Ke2MessageLen, Ke3MessageLen, KeyExchange, ToBytes, @@ -37,34 +39,38 @@ use crate::opaque::{MaskedResponse, MaskedResponseLen, ServerSetup}; //////////////////////////// /// The message sent by the client to the server, to initiate registration -#[derive(DeriveWhere)] #[derive_where(Clone)] -#[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; CS::OprfGroup)] +#[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; voprf::BlindedElement)] pub struct RegistrationRequest where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// blinded password information - pub(crate) blinded_element: voprf::BlindedElement, + pub(crate) blinded_element: voprf::BlindedElement, } impl_serialize_and_deserialize_for!(RegistrationRequest); /// The answer sent by the server to the user, upon reception of the /// registration attempt -#[derive(DeriveWhere)] #[derive_where(Clone)] -#[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; CS::OprfGroup, ::Pk)] +#[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; voprf::EvaluationElement, ::Pk)] pub struct RegistrationResponse where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The server's oprf output - pub(crate) evaluation_element: voprf::EvaluationElement, + pub(crate) evaluation_element: voprf::EvaluationElement, /// Server's static public key pub(crate) server_s_pk: PublicKey, } @@ -73,103 +79,133 @@ impl_serialize_and_deserialize_for!( RegistrationResponse where // RegistrationResponse: KgPk + KePk - ::ElemLen: Add<::PkLen>, + as Group>::ElemLen: Add<::PkLen>, RegistrationResponseLen: ArrayLength, ); /// The final message from the client, containing sealed cryptographic /// identifiers -#[derive(DeriveWhere)] -#[derive_where(Clone, Zeroize(drop))] +#[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; ::Pk)] pub struct RegistrationUpload where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The "envelope" generated by the user, containing sealed cryptographic /// identifiers pub(crate) envelope: Envelope, /// The masking key used to mask the envelope - pub(crate) masking_key: Output, + pub(crate) masking_key: Output>, /// The user's public key - #[derive_where(skip(Zeroize))] pub(crate) client_s_pk: PublicKey, } +impl Drop for RegistrationUpload +where + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ + fn drop(&mut self) { + self.masking_key.zeroize(); + } +} + +impl ZeroizeOnDrop for RegistrationUpload +where + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, +{ +} + impl_serialize_and_deserialize_for!( RegistrationUpload where // Envelope: Nonce + Hash - NonceLen: Add>, + NonceLen: Add>>, EnvelopeLen: ArrayLength, // RegistrationUpload: (KePk + Hash) + Envelope - ::PkLen: Add>, - Sum<::PkLen, OutputSize>: + ::PkLen: Add>>, + Sum<::PkLen, OutputSize>>: ArrayLength | Add>, RegistrationUploadLen: ArrayLength, ); /// The message sent by the user to the server, to initiate registration -#[derive(DeriveWhere)] -#[derive_where(Clone, Zeroize(drop))] +#[derive_where(Clone, ZeroizeOnDrop)] #[derive_where( Debug, Eq, Hash, PartialEq; - CS::OprfGroup, - >::KE1Message, + voprf::BlindedElement, + , CS::KeGroup>>::KE1Message, )] pub struct CredentialRequest where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { - pub(crate) blinded_element: voprf::BlindedElement, - pub(crate) ke1_message: >::KE1Message, + pub(crate) blinded_element: voprf::BlindedElement, + pub(crate) ke1_message: , CS::KeGroup>>::KE1Message, } impl_serialize_and_deserialize_for!( CredentialRequest where // CredentialRequest: KgPk + Ke1Message - ::ElemLen: Add>, + as Group>::ElemLen: Add>, CredentialRequestLen: ArrayLength, ); /// The answer sent by the server to the user, upon reception of the login /// attempt -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where( Debug, Eq, Hash, PartialEq; - CS::OprfGroup, - >::KE2Message, + voprf::EvaluationElement, + , CS::KeGroup>>::KE2Message, )] pub struct CredentialResponse where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// the server's oprf output - pub(crate) evaluation_element: voprf::EvaluationElement, + pub(crate) evaluation_element: voprf::EvaluationElement, pub(crate) masking_nonce: GenericArray, pub(crate) masked_response: MaskedResponse, - pub(crate) ke2_message: >::KE2Message, + pub(crate) ke2_message: , CS::KeGroup>>::KE2Message, } impl_serialize_and_deserialize_for!( CredentialResponse where // CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse - ::ElemLen: Add, - Sum<::ElemLen, NonceLen>: + as Group>::ElemLen: Add, + Sum< as Group>::ElemLen, NonceLen>: ArrayLength | Add>, CredentialResponseWithoutKeLen: ArrayLength, // MaskedResponse: (Nonce + Hash) + KePk - NonceLen: Add>, - Sum>: + NonceLen: Add>>, + Sum>>: ArrayLength | Add<::PkLen>, MaskedResponseLen: ArrayLength, // CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message @@ -179,19 +215,21 @@ impl_serialize_and_deserialize_for!( /// The answer sent by the client to the server, upon reception of the sealed /// envelope -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where( Debug, Eq, Hash, PartialEq; - >::KE3Message, + , CS::KeGroup>>::KE3Message, )] pub struct CredentialFinalization where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { - pub(crate) ke3_message: >::KE3Message, + pub(crate) ke3_message: , CS::KeGroup>>::KE3Message, } impl_serialize_and_deserialize_for!(CredentialFinalization); @@ -202,25 +240,26 @@ impl_serialize_and_deserialize_for!(CredentialFinalization); //////////////////////////////// /// Length of [`RegistrationRequest`] in bytes for serialization. -pub type RegistrationRequestLen = ::ElemLen; +pub type RegistrationRequestLen = as Group>::ElemLen; impl RegistrationRequest where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Only used for testing purposes #[cfg(test)] - pub fn get_blinded_element_for_testing( - &self, - ) -> voprf::BlindedElement { + pub fn get_blinded_element_for_testing(&self) -> voprf::BlindedElement { self.blinded_element.clone() } /// Serialization into bytes pub fn serialize(&self) -> GenericArray> { - self.blinded_element.value().to_arr() + as Group>::serialize_elem(self.blinded_element.value()) } /// Deserialization from bytes @@ -233,30 +272,31 @@ where /// Length of [`RegistrationResponse`] in bytes for serialization. pub type RegistrationResponseLen = - Sum<::ElemLen, ::PkLen>; + Sum< as Group>::ElemLen, ::PkLen>; impl RegistrationResponse where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> where // RegistrationResponse: KgPk + KePk - ::ElemLen: Add<::PkLen>, + as Group>::ElemLen: Add<::PkLen>, RegistrationResponseLen: ArrayLength, { - self.evaluation_element - .value() - .to_arr() + as Group>::serialize_elem(self.evaluation_element.value()) .concat(self.server_s_pk.to_bytes()) } /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { - let elem_len = ::ElemLen::USIZE; + let elem_len = as Group>::ElemLen::USIZE; let key_len = ::PkLen::USIZE; let checked_slice = check_slice_size(input, elem_len + key_len, "registration_response_bytes")?; @@ -273,7 +313,7 @@ where #[cfg(test)] /// Only used for tests, where we can set the beta value to test for the /// reflection error case - pub fn set_evaluation_element_for_testing(&self, beta: CS::OprfGroup) -> Self { + pub fn set_evaluation_element_for_testing(&self, beta: OprfGroup) -> Self { Self { evaluation_element: voprf::EvaluationElement::from_value_unchecked(beta), server_s_pk: self.server_s_pk.clone(), @@ -283,23 +323,26 @@ where /// Length of [`RegistrationUpload`] in bytes for serialization. pub type RegistrationUploadLen = - Sum::PkLen, OutputSize>, EnvelopeLen>; + Sum::PkLen, OutputSize>>, EnvelopeLen>; impl RegistrationUpload where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> where // Envelope: Nonce + Hash - NonceLen: Add>, + NonceLen: Add>>, EnvelopeLen: ArrayLength, // RegistrationUpload: (KePk + Hash) + Envelope - ::PkLen: Add>, - Sum<::PkLen, OutputSize>: + ::PkLen: Add>>, + Sum<::PkLen, OutputSize>>: ArrayLength + Add>, RegistrationUploadLen: ArrayLength, { @@ -312,7 +355,7 @@ where /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { let key_len = ::PkLen::USIZE; - let hash_len = OutputSize::::USIZE; + let hash_len = OutputSize::>::USIZE; let checked_slice = check_slice_size_atleast(input, key_len + hash_len, "registration_upload_bytes")?; let envelope = Envelope::::deserialize(&checked_slice[key_len + hash_len..])?; @@ -330,7 +373,7 @@ where rng: &mut R, server_setup: &ServerSetup, ) -> Self { - let mut masking_key = Output::::default(); + let mut masking_key = Output::>::default(); rng.fill_bytes(&mut masking_key); Self { @@ -343,29 +386,30 @@ where /// Length of [`CredentialRequest`] in bytes for serialization. pub type CredentialRequestLen = - Sum<::ElemLen, Ke1MessageLen>; + Sum< as Group>::ElemLen, Ke1MessageLen>; impl CredentialRequest where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> where // CredentialRequest: KgPk + Ke1Message - ::ElemLen: Add>, + as Group>::ElemLen: Add>, CredentialRequestLen: ArrayLength, { - self.blinded_element - .value() - .to_arr() + as Group>::serialize_elem(self.blinded_element.value()) .concat(self.ke1_message.to_bytes()) } pub(crate) fn serialize_iter<'a>( - blinded_element: &'a GenericArray::ElemLen>, + blinded_element: &'a GenericArray as Group>::ElemLen>, ke1_message: &'a GenericArray>, ) -> impl Iterator { [blinded_element.as_slice(), ke1_message].into_iter() @@ -373,23 +417,22 @@ where /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { - let elem_len = ::ElemLen::USIZE; + let elem_len = as Group>::ElemLen::USIZE; let checked_slice = check_slice_size_atleast(input, elem_len, "login_first_message_bytes")?; // Check that the message is actually containing an element of the correct // subgroup - let blinded_element = voprf::BlindedElement::::deserialize( - &checked_slice[..elem_len], - )?; + let blinded_element = + voprf::BlindedElement::::deserialize(&checked_slice[..elem_len])?; // Throw an error if the identity group element is encountered - if blinded_element.value().is_identity() { + if bool::from( as Group>::identity_elem().ct_eq(&blinded_element.value())) { return Err(ProtocolError::IdentityGroupElementError); } let ke1_message = - >::KE1Message::from_bytes( + , CS::KeGroup>>::KE1Message::from_bytes( &checked_slice[elem_len..], )?; @@ -401,9 +444,7 @@ where /// Only used for testing purposes #[cfg(test)] - pub fn get_blinded_element_for_testing( - &self, - ) -> voprf::BlindedElement { + pub fn get_blinded_element_for_testing(&self) -> voprf::BlindedElement { self.blinded_element.clone() } } @@ -413,40 +454,42 @@ pub type CredentialResponseLen = Sum, Ke2MessageLen>; pub(crate) type CredentialResponseWithoutKeLen = - Sum::ElemLen, NonceLen>, MaskedResponseLen>; + Sum as Group>::ElemLen, NonceLen>, MaskedResponseLen>; impl CredentialResponse where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> where // CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse - ::ElemLen: Add, - Sum<::ElemLen, NonceLen>: + as Group>::ElemLen: Add, + Sum< as Group>::ElemLen, NonceLen>: ArrayLength + Add>, CredentialResponseWithoutKeLen: ArrayLength, // MaskedResponse: (Nonce + Hash) + KePk - NonceLen: Add>, - Sum>: ArrayLength + Add<::PkLen>, + NonceLen: Add>>, + Sum>>: + ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, // CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message CredentialResponseWithoutKeLen: Add>, CredentialResponseLen: ArrayLength, { - self.evaluation_element - .value() - .to_arr() + as Group>::serialize_elem(self.evaluation_element.value()) .concat(self.masking_nonce) .concat(self.masked_response.serialize()) .concat(self.ke2_message.to_bytes()) } pub(crate) fn serialize_without_ke<'a>( - beta: &'a GenericArray::ElemLen>, + beta: &'a GenericArray as Group>::ElemLen>, masking_nonce: &'a GenericArray, masked_response: &'a MaskedResponse, ) -> impl Iterator { @@ -457,7 +500,7 @@ where /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { - let elem_len = ::ElemLen::USIZE; + let elem_len = as Group>::ElemLen::USIZE; let key_len = ::PkLen::USIZE; let nonce_len: usize = 32; let envelope_len = Envelope::::len(); @@ -474,10 +517,11 @@ where // subgroup let beta_bytes = &checked_slice[..elem_len]; let evaluation_element = - voprf::EvaluationElement::::deserialize(beta_bytes)?; + voprf::EvaluationElement::::deserialize(beta_bytes)?; // Throw an error if the identity group element is encountered - if evaluation_element.value().is_identity() { + if bool::from( as Group>::identity_elem().ct_eq(&evaluation_element.value())) + { return Err(ProtocolError::IdentityGroupElementError); } @@ -487,7 +531,7 @@ where &checked_slice[elem_len + nonce_len..elem_len + nonce_len + masked_response_len], ); let ke2_message = - >::KE2Message::from_bytes( + , CS::KeGroup>>::KE2Message::from_bytes( &checked_slice[elem_len + nonce_len + masked_response_len..], )?; @@ -502,7 +546,7 @@ where #[cfg(test)] /// Only used for tests, where we can set the beta value to test for the /// reflection error case - pub fn set_evaluation_element_for_testing(&self, beta: CS::OprfGroup) -> Self { + pub fn set_evaluation_element_for_testing(&self, beta: OprfGroup) -> Self { Self { evaluation_element: voprf::EvaluationElement::from_value_unchecked(beta), masking_nonce: self.masking_nonce, @@ -517,9 +561,12 @@ pub type CredentialFinalizationLen = Ke3MessageLen; impl CredentialFinalization where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> { @@ -529,7 +576,9 @@ where /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { let ke3_message = - >::KE3Message::from_bytes(input)?; + , CS::KeGroup>>::KE3Message::from_bytes( + input, + )?; Ok(Self { ke3_message }) } } diff --git a/src/opaque.rs b/src/opaque.rs index 8aef2864..a476c5fa 100755 --- a/src/opaque.rs +++ b/src/opaque.rs @@ -7,21 +7,20 @@ //! Provides the main OPAQUE API -use core::marker::PhantomData; use core::ops::Add; -use derive_where::DeriveWhere; +use derive_where::derive_where; use digest::core_api::{BlockSizeUser, CoreProxy}; -use digest::Output; +use digest::{Output, OutputSizeUser}; use generic_array::sequence::Concat; -use generic_array::typenum::{IsLess, Le, NonZero, Sum, Unsigned, U2, U256}; +use generic_array::typenum::{IsLess, IsLessOrEqual, Le, NonZero, Sum, Unsigned, U2, U256}; use generic_array::{ArrayLength, GenericArray}; use hkdf::{Hkdf, HkdfExtract}; use rand::{CryptoRng, RngCore}; use subtle::ConstantTimeEq; use voprf::Group; -use crate::ciphersuite::CipherSuite; +use crate::ciphersuite::{CipherSuite, OprfGroup, OprfHash}; use crate::envelope::{Envelope, EnvelopeLen}; use crate::errors::utils::check_slice_size; use crate::errors::{InternalError, ProtocolError}; @@ -69,89 +68,97 @@ const STR_OPAQUE_DERIVE_KEY_PAIR: &[u8; 20] = b"OPAQUE-DeriveKeyPair"; crate = "serde_" ) )] -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; ::Pk, ::Sk, S)] pub struct ServerSetup< CS: CipherSuite, S: SecretKey = PrivateKey<::KeGroup>, > where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { - oprf_seed: Output, + oprf_seed: Output>, keypair: KeyPair, pub(crate) fake_keypair: KeyPair, } /// The state elements the client holds to register itself -#[derive(DeriveWhere)] -#[derive_where(Clone, Zeroize(drop))] +#[derive_where(Clone, ZeroizeOnDrop)] #[derive_where( Debug, Eq, Hash, PartialEq; - voprf::NonVerifiableClient, - voprf::BlindedElement, + voprf::NonVerifiableClient, + voprf::BlindedElement, )] pub struct ClientRegistration where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { - pub(crate) oprf_client: voprf::NonVerifiableClient, - pub(crate) blinded_element: voprf::BlindedElement, + pub(crate) oprf_client: voprf::NonVerifiableClient, + pub(crate) blinded_element: voprf::BlindedElement, } impl_serialize_and_deserialize_for!( ClientRegistration where // ClientRegistration: KgSk + KgPk - ::ScalarLen: Add<::ElemLen>, + as Group>::ScalarLen: Add< as Group>::ElemLen>, ClientRegistrationLen: ArrayLength, ); /// The state elements the server holds to record a registration -#[derive(DeriveWhere)] -#[derive_where(Clone, Zeroize(drop))] +#[derive_where(Clone, ZeroizeOnDrop)] #[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; ::Pk)] pub struct ServerRegistration(pub(crate) RegistrationUpload) where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero; + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero; impl_serialize_and_deserialize_for!( ServerRegistration where // Envelope: Nonce + Hash - NonceLen: Add>, + NonceLen: Add>>, EnvelopeLen: ArrayLength, // RegistrationUpload: (KePk + Hash) + Envelope - ::PkLen: Add>, - Sum<::PkLen, OutputSize>: + ::PkLen: Add>>, + Sum<::PkLen, OutputSize>>: ArrayLength | Add>, RegistrationUploadLen: ArrayLength, // ServerRegistration = RegistrationUpload ); /// The state elements the client holds to perform a login -#[derive(DeriveWhere)] -#[derive_where(Clone, Zeroize(drop))] +#[derive_where(Clone, ZeroizeOnDrop)] #[derive_where( Debug, Eq, Hash, PartialEq; - voprf::NonVerifiableClient, - >::KE1State, + voprf::NonVerifiableClient, + , CS::KeGroup>>::KE1State, CredentialRequest, )] pub struct ClientLogin where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { - pub(crate) oprf_client: voprf::NonVerifiableClient, - pub(crate) ke1_state: >::KE1State, + pub(crate) oprf_client: voprf::NonVerifiableClient, + pub(crate) ke1_state: , CS::KeGroup>>::KE1State, pub(crate) credential_request: CredentialRequest, } @@ -159,31 +166,31 @@ impl_serialize_and_deserialize_for!( ClientLogin where // CredentialRequest: KgPk + Ke1Message - ::ElemLen: Add>, + as Group>::ElemLen: Add>, CredentialRequestLen: ArrayLength, // ClientLogin: KgSk + CredentialRequest + Ke1State - ::ScalarLen: Add>, - Sum<::ScalarLen, CredentialRequestLen>: + as Group>::ScalarLen: Add>, + Sum< as Group>::ScalarLen, CredentialRequestLen>: ArrayLength | Add>, ClientLoginLen: ArrayLength, ); /// The state elements the server holds to record a login -#[derive(DeriveWhere)] -#[derive_where(Clone, Zeroize(drop))] +#[derive_where(Clone, ZeroizeOnDrop)] #[derive_where( Debug, Eq, Hash, PartialEq; - >::KE2State, + , CS::KeGroup>>::KE2State, )] pub struct ServerLogin where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { - ke2_state: >::KE2State, - #[derive_where(skip(Zeroize))] - _cs: PhantomData, + ke2_state: , CS::KeGroup>>::KE2State, } impl_serialize_and_deserialize_for!(ServerLogin); @@ -198,9 +205,12 @@ impl_serialize_and_deserialize_for!(ServerLogin); impl ServerSetup> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Generate a new instance of server setup pub fn new(rng: &mut R) -> Self { @@ -211,13 +221,16 @@ where /// Length of [`ServerSetup`] in bytes for serialization. pub type ServerSetupLen> = - Sum, S::Len>, ::SkLen>; + Sum>, S::Len>, ::SkLen>; impl> ServerSetup where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Create [`ServerSetup`] with the given keypair pub fn new_with_key( @@ -238,8 +251,9 @@ where pub fn serialize(&self) -> GenericArray> where // ServerSetup: Hash + KeSk + KeSk - OutputSize: Add, - Sum, S::Len>: ArrayLength + Add<::SkLen>, + OutputSize>: Add, + Sum>, S::Len>: + ArrayLength + Add<::SkLen>, ServerSetupLen: ArrayLength, { self.oprf_seed @@ -250,7 +264,7 @@ where /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result> { - let seed_len = OutputSize::::USIZE; + let seed_len = OutputSize::>::USIZE; let key_len = ::SkLen::USIZE; let checked_slice = check_slice_size(input, seed_len + key_len + key_len, "server_setup")?; @@ -272,19 +286,22 @@ where // ============ pub(crate) type ClientRegistrationLen = - Sum<::ScalarLen, ::ElemLen>; + Sum< as Group>::ScalarLen, as Group>::ElemLen>; impl ClientRegistration where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> where // ClientRegistration: KgSk + KgPk - ::ScalarLen: Add<::ElemLen>, + as Group>::ScalarLen: Add< as Group>::ElemLen>, ClientRegistrationLen: ArrayLength, { self.oprf_client @@ -294,8 +311,8 @@ where /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { - let client_len = ::ScalarLen::USIZE; - let element_len = ::ElemLen::USIZE; + let client_len = as Group>::ScalarLen::USIZE; + let element_len = as Group>::ElemLen::USIZE; let checked_slice = check_slice_size(input, client_len + element_len, "client_registration")?; @@ -362,7 +379,7 @@ where params.slow_hash, )?; - let mut masking_key = Output::::default(); + let mut masking_key = Output::>::default(); randomized_pwd_hasher .expand(STR_MASKING_KEY, &mut masking_key) .map_err(|_| InternalError::HkdfError)?; @@ -397,19 +414,22 @@ pub type ServerRegistrationLen = RegistrationUploadLen; impl ServerRegistration where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> where // Envelope: Nonce + Hash - NonceLen: Add>, + NonceLen: Add>>, EnvelopeLen: ArrayLength, // RegistrationUpload: (KePk + Hash) + Envelope - ::PkLen: Add>, - Sum<::PkLen, OutputSize>: + ::PkLen: Add>>, + Sum<::PkLen, OutputSize>>: ArrayLength + Add>, RegistrationUploadLen: ArrayLength, // ServerRegistration = RegistrationUpload @@ -429,17 +449,15 @@ where message: RegistrationRequest, credential_identifier: &[u8], ) -> Result, ProtocolError> { - let oprf_key = oprf_key_from_seed::( - &server_setup.oprf_seed, - credential_identifier, - )?; + let oprf_key = + oprf_key_from_seed::(&server_setup.oprf_seed, credential_identifier)?; let server = voprf::NonVerifiableServer::new_with_key(&oprf_key)?; - let evaluate_result = server.evaluate(&message.blinded_element, None)?; + let evaluation_element = server.evaluate(&message.blinded_element, None)?; Ok(ServerRegistrationStartResult { message: RegistrationResponse { - evaluation_element: evaluate_result.message, + evaluation_element, server_s_pk: server_setup.keypair.public().clone(), }, #[cfg(test)] @@ -466,23 +484,26 @@ where // ===== pub(crate) type ClientLoginLen = - Sum::ScalarLen, CredentialRequestLen>, Ke1StateLen>; + Sum as Group>::ScalarLen, CredentialRequestLen>, Ke1StateLen>; impl ClientLogin where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> where // CredentialRequest: KgPk + Ke1Message - ::ElemLen: Add>, + as Group>::ElemLen: Add>, CredentialRequestLen: ArrayLength, // ClientLogin: KgSk + CredentialRequest + Ke1State - ::ScalarLen: Add>, - Sum<::ScalarLen, CredentialRequestLen>: + as Group>::ScalarLen: Add>, + Sum< as Group>::ScalarLen, CredentialRequestLen>: ArrayLength + Add>, ClientLoginLen: ArrayLength, { @@ -494,14 +515,14 @@ where /// Deserialization from bytes pub fn deserialize(input: &[u8]) -> Result { - let client_len = ::ScalarLen::USIZE; - let request_len = ::ElemLen::USIZE + Ke1MessageLen::::USIZE; + let client_len = as Group>::ScalarLen::USIZE; + let request_len = as Group>::ElemLen::USIZE + Ke1MessageLen::::USIZE; let state_len = Ke1StateLen::::USIZE; let checked_slice = check_slice_size(input, client_len + request_len + state_len, "client_login")?; let ke1_state = - >::KE1State::from_bytes( + , CS::KeGroup>>::KE1State::from_bytes( &checked_slice[client_len + request_len..], )?; Ok(Self { @@ -516,9 +537,12 @@ where impl ClientLogin where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Returns an initial "blinded" password request to send to the server, as /// well as a ClientLogin @@ -554,8 +578,9 @@ where ) -> Result, ProtocolError> where // MaskedResponse: (Nonce + Hash) + KePk - NonceLen: Add>, - Sum>: ArrayLength + Add<::PkLen>, + NonceLen: Add>>, + Sum>>: + ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { // Check if beta value from server is equal to alpha value from client @@ -576,7 +601,7 @@ where params.slow_hash, )?; - let mut masking_key = Output::::default(); + let mut masking_key = Output::>::default(); randomized_pwd_hasher .expand(STR_MASKING_KEY, &mut masking_key) .map_err(|_| InternalError::HkdfError)?; @@ -604,14 +629,15 @@ where err => err, })?; - let beta = credential_response.evaluation_element.value().to_arr(); + let beta = OprfGroup::::serialize_elem(credential_response.evaluation_element.value()); let credential_response_component = CredentialResponse::::serialize_without_ke( &beta, &credential_response.masking_nonce, &credential_response.masked_response, ); - let blinded_element = self.credential_request.blinded_element.value().to_arr(); + let blinded_element = + OprfGroup::::serialize_elem(self.credential_request.blinded_element.value()); let ke1_message = self.credential_request.ke1_message.to_bytes(); let serialized_credential_request = CredentialRequest::::serialize_iter(&blinded_element, &ke1_message); @@ -647,9 +673,12 @@ where impl ServerLogin where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Serialization into bytes pub fn serialize(&self) -> GenericArray> { @@ -659,9 +688,8 @@ where /// Deserialization from bytes pub fn deserialize(bytes: &[u8]) -> Result { Ok(Self { - _cs: PhantomData, ke2_state: - >::KE2State::from_bytes( + , CS::KeGroup>>::KE2State::from_bytes( bytes, )?, }) @@ -682,8 +710,9 @@ where ) -> Result, ProtocolError> where // MaskedResponse: (Nonce + Hash) + KePk - NonceLen: Add>, - Sum>: ArrayLength + Add<::PkLen>, + NonceLen: Add>>, + Sum>>: + ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { let record = match password_file { @@ -720,24 +749,22 @@ where ) .map_err(ProtocolError::into_custom)?; - let blinded_element = credential_request.blinded_element.value().to_arr(); + let blinded_element = + OprfGroup::::serialize_elem(credential_request.blinded_element.value()); let ke1_message = credential_request.ke1_message.to_bytes(); let credential_request_bytes = CredentialRequest::::serialize_iter(&blinded_element, &ke1_message); - let oprf_key = oprf_key_from_seed::( - &server_setup.oprf_seed, - credential_identifier, - ) - .map_err(ProtocolError::into_custom)?; + let oprf_key = + oprf_key_from_seed::(&server_setup.oprf_seed, credential_identifier) + .map_err(ProtocolError::into_custom)?; let server = voprf::NonVerifiableServer::new_with_key(&oprf_key) .map_err(|e| ProtocolError::into_custom(e.into()))?; - let evaluate_result = server + let evaluation_element = server .evaluate(&credential_request.blinded_element, None) .map_err(|e| ProtocolError::into_custom(e.into()))?; - let evaluation_element = evaluate_result.message; - let beta = evaluation_element.value().to_arr(); + let beta = OprfGroup::::serialize_elem(evaluation_element.value()); let credential_response_component = CredentialResponse::::serialize_without_ke(&beta, &masking_nonce, &masked_response); @@ -763,7 +790,6 @@ where Ok(ServerLoginStartResult { message: credential_response, state: Self { - _cs: PhantomData, ke2_state: result.0, }, #[cfg(test)] @@ -781,14 +807,13 @@ where self, message: CredentialFinalization, ) -> Result, ProtocolError> { - let session_key = >::finish_ke( + let session_key = , CS::KeGroup>>::finish_ke( message.ke3_message, &self.ke2_state, )?; Ok(ServerLoginFinishResult { session_key, - _cs: PhantomData, #[cfg(test)] state: self, }) @@ -810,13 +835,15 @@ pub struct Identifiers<'a> { } /// Optional parameters for client registration finish -#[derive(DeriveWhere)] #[derive_where(Clone, Default)] pub struct ClientRegistrationFinishParameters<'i, 'h, CS: CipherSuite> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Specifying the identifiers idU and idS pub identifiers: Identifiers<'i>, @@ -826,9 +853,12 @@ where impl<'i, 'h, CS: CipherSuite> ClientRegistrationFinishParameters<'i, 'h, CS> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Create a new [`ClientRegistrationFinishParameters`] pub fn new(identifiers: Identifiers<'i>, slow_hash: Option<&'h CS::SlowHash>) -> Self { @@ -840,13 +870,15 @@ where } /// Contains the fields that are returned by a client registration start -#[derive(DeriveWhere)] #[derive_where(Clone)] pub struct ClientRegistrationStartResult where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The registration request message to be sent to the server pub message: RegistrationRequest, @@ -856,18 +888,20 @@ where } /// Contains the fields that are returned by a client registration finish -#[derive(DeriveWhere)] #[derive_where(Clone)] pub struct ClientRegistrationFinishResult where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The registration upload message to be sent to the server pub message: RegistrationUpload, /// The export key output by client registration - pub export_key: Output, + pub export_key: Output>, /// The server's static public key pub server_s_pk: PublicKey, /// Instance of the ClientRegistration, only used in tests for checking @@ -876,37 +910,41 @@ where pub state: ClientRegistration, /// AuthKey, only used in tests #[cfg(test)] - pub auth_key: Output, + pub auth_key: Output>, /// Password derived key, only used in tests #[cfg(test)] - pub randomized_pwd: Output, + pub randomized_pwd: Output>, } /// Contains the fields that are returned by a server registration start. Note /// that there is no state output in this step -#[derive(DeriveWhere)] #[derive_where(Clone)] pub struct ServerRegistrationStartResult where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The registration resposne message to send to the client pub message: RegistrationResponse, /// OPRF key, only used in tests #[cfg(test)] - pub oprf_key: GenericArray::ScalarLen>, + pub oprf_key: GenericArray as Group>::ScalarLen>, } /// Contains the fields that are returned by a client login start -#[derive(DeriveWhere)] #[derive_where(Clone)] pub struct ClientLoginStartResult where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The message to send to the server to begin the login protocol pub message: CredentialRequest, @@ -915,13 +953,15 @@ where } /// Optional parameters for client login finish -#[derive(DeriveWhere)] #[derive_where(Clone, Default)] pub struct ClientLoginFinishParameters<'c, 'i, 'h, CS: CipherSuite> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Specifying a context field that the server must agree on pub context: Option<&'c [u8]>, @@ -934,9 +974,12 @@ where impl<'c, 'i, 'h, CS: CipherSuite> ClientLoginFinishParameters<'c, 'i, 'h, CS> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// Create a new [`ClientLoginFinishParameters`] pub fn new( @@ -953,20 +996,22 @@ where } /// Contains the fields that are returned by a client login finish -#[derive(DeriveWhere)] #[derive_where(Clone)] pub struct ClientLoginFinishResult where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The message to send to the server to complete the protocol pub message: CredentialFinalization, /// The session key - pub session_key: Output, + pub session_key: Output>, /// The client-side export key - pub export_key: Output, + pub export_key: Output>, /// The server's static public key pub server_s_pk: PublicKey, /// Instance of the ClientLogin, only used in tests for checking zeroize @@ -974,26 +1019,27 @@ where pub state: ClientLogin, /// Handshake secret, only used in tests #[cfg(test)] - pub handshake_secret: Output, + pub handshake_secret: Output>, /// Client MAC key, only used in tests #[cfg(test)] - pub client_mac_key: Output, + pub client_mac_key: Output>, } /// Contains the fields that are returned by a server login finish -#[derive(DeriveWhere)] #[derive_where(Clone)] #[cfg_attr(not(test), derive_where(Debug))] #[cfg_attr(test, derive_where(Debug; ServerLogin))] pub struct ServerLoginFinishResult where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The session key between client and server - pub session_key: Output, - _cs: PhantomData, + pub session_key: Output>, /// Instance of the ClientRegistration, only used in tests for checking /// zeroize #[cfg(test)] @@ -1011,19 +1057,21 @@ pub struct ServerLoginStartParameters<'c, 'i> { } /// Contains the fields that are returned by a server login start -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where( Debug; - CS::OprfGroup, - >::KE2Message, - >::KE2State, + voprf::EvaluationElement, + , CS::KeGroup>>::KE2Message, + , CS::KeGroup>>::KE2State, )] pub struct ServerLoginStartResult where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { /// The message to send back to the client pub message: CredentialResponse, @@ -1031,13 +1079,13 @@ where pub state: ServerLogin, /// Handshake secret, only used in tests #[cfg(test)] - pub handshake_secret: Output, + pub handshake_secret: Output>, /// Server MAC key, only used in tests #[cfg(test)] - pub server_mac_key: Output, + pub server_mac_key: Output>, /// OPRF key, only used in tests #[cfg(test)] - pub oprf_key: GenericArray::ScalarLen>, + pub oprf_key: GenericArray as Group>::ScalarLen>, } //////////////////////////////////////////////// @@ -1049,14 +1097,17 @@ where #[allow(clippy::type_complexity)] fn get_password_derived_key( input: &[u8], - oprf_client: voprf::NonVerifiableClient, - evaluation_element: voprf::EvaluationElement, + oprf_client: voprf::NonVerifiableClient, + evaluation_element: voprf::EvaluationElement, slow_hash: Option<&CS::SlowHash>, -) -> Result<(Output, Hkdf), ProtocolError> +) -> Result<(Output>, Hkdf>), ProtocolError> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { let oprf_output = oprf_client.finalize(input, &evaluation_element, None)?; @@ -1067,63 +1118,74 @@ where } .map_err(ProtocolError::from)?; - let mut hkdf = HkdfExtract::::new(None); + let mut hkdf = HkdfExtract::>::new(None); hkdf.input_ikm(&oprf_output); hkdf.input_ikm(&hardened_output); Ok(hkdf.finalize()) } -fn oprf_key_from_seed( - oprf_seed: &Output, +fn oprf_key_from_seed( + oprf_seed: &Output, credential_identifier: &[u8], -) -> Result, ProtocolError> +) -> Result::ScalarLen>, ProtocolError> where - D::Core: ProxyHash, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, + ::OutputSize: + IsLess + IsLessOrEqual<::BlockSize>, + CS::Hash: Hash, + ::Core: ProxyHash, + <::Core as BlockSizeUser>::BlockSize: IsLess, + Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { - let mut ikm = GenericArray::<_, G::ScalarLen>::default(); - Hkdf::::from_prk(oprf_seed) + let mut ikm = GenericArray::<_, ::ScalarLen>::default(); + Hkdf::::from_prk(oprf_seed) .ok() .and_then(|hkdf| { hkdf.expand_multi_info(&[credential_identifier, STR_OPRF_KEY], &mut ikm) .ok() }) .ok_or(InternalError::HkdfError)?; - Ok(G::scalar_as_bytes(G::hash_to_scalar::( - [ikm.as_slice()], - GenericArray::from(*STR_OPAQUE_DERIVE_KEY_PAIR), - )?)) + Ok(CS::Group::serialize_scalar( + CS::Group::hash_to_scalar::( + &[ikm.as_slice()], + &GenericArray::from(*STR_OPAQUE_DERIVE_KEY_PAIR), + )?, + )) } -#[derive(DeriveWhere)] #[derive_where(Clone)] #[derive_where(Debug, Eq, Hash, PartialEq)] pub(crate) struct MaskedResponse where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { pub(crate) nonce: GenericArray, - pub(crate) hash: Output, + pub(crate) hash: Output>, pub(crate) pk: GenericArray::PkLen>, } pub(crate) type MaskedResponseLen = - Sum>, ::PkLen>; + Sum>>, ::PkLen>; impl MaskedResponse where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { pub(crate) fn serialize(&self) -> GenericArray> where // MaskedResponse: (Nonce + Hash) + KePk - NonceLen: Add>, - Sum>: ArrayLength + Add<::PkLen>, + NonceLen: Add>>, + Sum>>: + ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { self.nonce.concat(self.hash.clone()).concat(self.pk.clone()) @@ -1131,7 +1193,7 @@ where pub(crate) fn deserialize(bytes: &[u8]) -> Self { let nonce = NonceLen::USIZE; - let hash = nonce + OutputSize::::USIZE; + let hash = nonce + OutputSize::>::USIZE; let pk = hash + ::PkLen::USIZE; Self { @@ -1153,18 +1215,20 @@ fn mask_response( envelope: &Envelope, ) -> Result, ProtocolError> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, - + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk - NonceLen: Add>, - Sum>: ArrayLength + Add<::PkLen>, + NonceLen: Add>>, + Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { let mut xor_pad = GenericArray::<_, MaskedResponseLen>::default(); - Hkdf::::from_prk(masking_key) + Hkdf::>::from_prk(masking_key) .map_err(|_| InternalError::HkdfError)? .expand_multi_info(&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD], &mut xor_pad) .map_err(|_| InternalError::HkdfError)?; @@ -1188,17 +1252,20 @@ fn unmask_response( masked_response: &MaskedResponse, ) -> Result<(PublicKey, Envelope), ProtocolError> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk - NonceLen: Add>, - Sum>: ArrayLength + Add<::PkLen>, + NonceLen: Add>>, + Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { let mut xor_pad = GenericArray::<_, MaskedResponseLen>::default(); - Hkdf::::from_prk(masking_key) + Hkdf::>::from_prk(masking_key) .map_err(|_| InternalError::HkdfError)? .expand_multi_info(&[masking_nonce, STR_CREDENTIAL_RESPONSE_PAD], &mut xor_pad) .map_err(|_| InternalError::HkdfError)?; @@ -1241,11 +1308,14 @@ pub(crate) fn bytestrings_from_identifiers( fn blind( rng: &mut R, password: &[u8], -) -> Result, voprf::Error> +) -> Result, voprf::Error> where - ::Core: ProxyHash, - <::Core as BlockSizeUser>::BlockSize: IsLess, - Le<<::Core as BlockSizeUser>::BlockSize, U256>: NonZero, + as OutputSizeUser>::OutputSize: + IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, + OprfHash: Hash, + as CoreProxy>::Core: ProxyHash, + < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, + Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { #[cfg(not(test))] let result = voprf::NonVerifiableClient::blind(password, rng)?; @@ -1255,13 +1325,9 @@ where let mut blind_bytes = GenericArray::default(); let blind = loop { rng.fill_bytes(&mut blind_bytes); - let scalar = ::from_scalar_slice_unchecked(&blind_bytes)?; - match scalar - .ct_eq(&::scalar_zero()) - .into() - { - false => break scalar, - true => (), + let scalar = as Group>::deserialize_scalar(&blind_bytes)?; + if !bool::from( as Group>::is_zero_scalar(scalar)) { + break scalar; } }; voprf::NonVerifiableClient::deterministic_blind_unchecked(password, blind)? diff --git a/src/serialization/tests.rs b/src/serialization/tests.rs index 02364ba0..b3f5514c 100755 --- a/src/serialization/tests.rs +++ b/src/serialization/tests.rs @@ -36,6 +36,7 @@ use crate::*; #[cfg(feature = "ristretto255")] struct Ristretto255; + #[cfg(feature = "ristretto255")] impl CipherSuite for Ristretto255 { type OprfGroup = curve25519_dalek::ristretto::RistrettoPoint; @@ -45,9 +46,8 @@ impl CipherSuite for Ristretto255 { type SlowHash = crate::slow_hash::NoOpHash; } -#[cfg(feature = "p256")] struct P256; -#[cfg(feature = "p256")] + impl CipherSuite for P256 { type OprfGroup = ::p256::ProjectivePoint; type KeGroup = ::p256::NistP256; @@ -100,7 +100,6 @@ fn client_registration_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -151,7 +150,6 @@ fn server_registration_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -191,7 +189,6 @@ fn registration_request_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -240,7 +237,6 @@ fn registration_response_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -299,7 +295,6 @@ fn registration_upload_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -354,7 +349,6 @@ fn credential_request_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -439,7 +433,6 @@ fn credential_response_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -468,7 +461,6 @@ fn credential_finalization_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -534,7 +526,6 @@ fn client_login_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -569,7 +560,6 @@ fn ke1_message_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -608,7 +598,6 @@ fn ke2_message_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -638,7 +627,6 @@ fn ke3_message_roundtrip() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; Ok(()) @@ -729,5 +717,4 @@ macro_rules! test { #[cfg(feature = "ristretto255")] test!(ristretto255, Ristretto255); -#[cfg(feature = "p256")] test!(p256, P256); diff --git a/src/slow_hash.rs b/src/slow_hash.rs index 522d923c..7ee63a21 100644 --- a/src/slow_hash.rs +++ b/src/slow_hash.rs @@ -7,48 +7,39 @@ //! Trait specifying a slow hashing function -use digest::core_api::BlockSizeUser; -use digest::Output; -use generic_array::typenum::{IsLess, Le, NonZero, U256}; +use generic_array::{ArrayLength, GenericArray}; use crate::errors::InternalError; -use crate::hash::{Hash, ProxyHash}; /// Used for the slow hashing function in OPAQUE -pub trait SlowHash: Default -where - D::Core: ProxyHash, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ +pub trait SlowHash: Default { /// Computes the slow hashing function - fn hash(&self, input: Output) -> Result, InternalError>; + fn hash>( + &self, + input: GenericArray, + ) -> Result, InternalError>; } /// A no-op hash which simply returns its input #[derive(Default)] pub struct NoOpHash; -impl SlowHash for NoOpHash -where - D::Core: ProxyHash, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ - fn hash(&self, input: Output) -> Result, InternalError> { +impl SlowHash for NoOpHash { + fn hash>( + &self, + input: GenericArray, + ) -> Result, InternalError> { Ok(input) } } #[cfg(feature = "slow-hash")] -impl SlowHash for argon2::Argon2<'_> -where - D::Core: ProxyHash, - ::BlockSize: IsLess, - Le<::BlockSize, U256>: NonZero, -{ - fn hash(&self, input: Output) -> Result, InternalError> { - let mut output = Output::::default(); +impl SlowHash for argon2::Argon2<'_> { + fn hash>( + &self, + input: GenericArray, + ) -> Result, InternalError> { + let mut output = GenericArray::default(); self.hash_password_into(&input, &[0; argon2::MIN_SALT_LEN], &mut output) .map_err(|_| InternalError::SlowHashError)?; Ok(output) diff --git a/src/tests/full_test.rs b/src/tests/full_test.rs index d2206ad3..1a4e99bc 100755 --- a/src/tests/full_test.rs +++ b/src/tests/full_test.rs @@ -44,6 +44,7 @@ use crate::*; #[cfg(feature = "ristretto255")] struct Ristretto255; + #[cfg(feature = "ristretto255")] impl CipherSuite for Ristretto255 { type OprfGroup = curve25519_dalek::ristretto::RistrettoPoint; @@ -53,9 +54,8 @@ impl CipherSuite for Ristretto255 { type SlowHash = NoOpHash; } -#[cfg(feature = "p256")] struct P256; -#[cfg(feature = "p256")] + impl CipherSuite for P256 { type OprfGroup = p256::ProjectivePoint; type KeGroup = p256::NistP256; @@ -66,6 +66,7 @@ impl CipherSuite for P256 { #[cfg(all(feature = "x25519", feature = "ristretto255"))] struct X25519Ristretto255; + #[cfg(all(feature = "x25519", feature = "ristretto255"))] impl CipherSuite for X25519Ristretto255 { type OprfGroup = curve25519_dalek::ristretto::RistrettoPoint; @@ -75,9 +76,10 @@ impl CipherSuite for X25519Ristretto255 { type SlowHash = NoOpHash; } -#[cfg(all(feature = "x25519", feature = "p256"))] +#[cfg(feature = "x25519")] struct X25519P256; -#[cfg(all(feature = "x25519", feature = "p256"))] + +#[cfg(feature = "x25519")] impl CipherSuite for X25519P256 { type OprfGroup = p256::ProjectivePoint; type KeGroup = crate::X25519; @@ -163,7 +165,6 @@ static TEST_VECTOR_RISTRETTO255: &str = r#" } "#; -#[cfg(feature = "p256")] static TEST_VECTOR_P256: &str = r#" { "client_s_pk": "02ec5dd688a3aa66022860d4bfed2dcb01a5da07a0b4ff0c84d9f8749bd478c293", @@ -239,7 +240,7 @@ static TEST_VECTOR_X25519_RISTRETTO255: &str = r#" } "#; -#[cfg(all(feature = "x25519", feature = "p256"))] +#[cfg(feature = "x25519")] static TEST_VECTOR_X25519_P256: &str = r#" { "client_s_pk": "ee6282a908e24291fcd1e7ce0a6fc244cf9b6371889e31a908d1919cdd756776", @@ -679,11 +680,10 @@ fn generate_test_vectors() -> Result<(), ProtocolError> { let parameters = generate_parameters::()?; println!("Ristretto255: {}", stringify_test_vectors(¶meters)); } - #[cfg(feature = "p256")] - { - let parameters = generate_parameters::()?; - println!("P-256: {}", stringify_test_vectors(¶meters)); - } + + let parameters = generate_parameters::()?; + println!("P-256: {}", stringify_test_vectors(¶meters)); + #[cfg(all(feature = "x25519", feature = "ristretto255"))] { let parameters = generate_parameters::()?; @@ -692,7 +692,8 @@ fn generate_test_vectors() -> Result<(), ProtocolError> { stringify_test_vectors(¶meters) ); } - #[cfg(all(feature = "x25519", feature = "p256"))] + + #[cfg(feature = "x25519")] { let parameters = generate_parameters::()?; println!("X25519 P-256: {}", stringify_test_vectors(¶meters)); @@ -729,11 +730,10 @@ fn test_registration_request() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -774,11 +774,10 @@ fn test_serialization() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -822,11 +821,10 @@ fn test_registration_response() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -883,11 +881,10 @@ fn test_registration_upload() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -925,11 +922,10 @@ fn test_password_file() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -975,11 +971,10 @@ fn test_credential_request() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -1051,11 +1046,10 @@ fn test_credential_response() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -1111,11 +1105,10 @@ fn test_credential_finalization() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -1146,11 +1139,10 @@ fn test_server_login_finish() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; - #[cfg(feature = "p256")] inner::(TEST_VECTOR_P256)?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::(TEST_VECTOR_X25519_RISTRETTO255)?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::(TEST_VECTOR_X25519_P256)?; Ok(()) @@ -1231,11 +1223,10 @@ where fn test_complete_flow_success() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"good password")?; - #[cfg(feature = "p256")] test_complete_flow::(b"good password", b"good password")?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] test_complete_flow::(b"good password", b"good password")?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] test_complete_flow::(b"good password", b"good password")?; Ok(()) @@ -1245,11 +1236,10 @@ fn test_complete_flow_success() -> Result<(), ProtocolError> { fn test_complete_flow_fail() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"bad password")?; - #[cfg(feature = "p256")] test_complete_flow::(b"good password", b"bad password")?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] test_complete_flow::(b"good password", b"bad password")?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] test_complete_flow::(b"good password", b"bad password")?; Ok(()) @@ -1280,11 +1270,10 @@ fn test_zeroize_client_registration_start() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1326,11 +1315,10 @@ fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1381,11 +1369,10 @@ fn test_zeroize_server_registration_finish() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1432,11 +1419,10 @@ fn test_zeroize_client_login_start() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1493,11 +1479,10 @@ fn test_zeroize_server_login_start() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1577,11 +1562,10 @@ fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1646,11 +1630,10 @@ fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1697,11 +1680,10 @@ fn test_scalar_always_nonzero() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1753,11 +1735,10 @@ fn test_reflected_value_error_registration() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) @@ -1827,11 +1808,10 @@ fn test_reflected_value_error_login() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] inner::()?; - #[cfg(feature = "p256")] inner::()?; #[cfg(all(feature = "x25519", feature = "ristretto255"))] inner::()?; - #[cfg(all(feature = "x25519", feature = "p256"))] + #[cfg(feature = "x25519")] inner::()?; Ok(()) diff --git a/src/tests/test_opaque_vectors.rs b/src/tests/test_opaque_vectors.rs index de1b882b..736b44cc 100755 --- a/src/tests/test_opaque_vectors.rs +++ b/src/tests/test_opaque_vectors.rs @@ -223,37 +223,32 @@ fn tests() -> Result<(), ProtocolError> { test_fake_vectors::(&ristretto_fake_tvs)?; } - #[cfg(feature = "p256")] - { - let p256_real_tvs = - json_to_test_vectors!(rfc, "Real", "P256_XMD:SHA-256_SSWU_RO_, SHA256",); - let p256_fake_tvs = - json_to_test_vectors!(rfc, "Fake", "P256_XMD:SHA-256_SSWU_RO_, SHA256",); - - assert!( - !(p256_real_tvs.is_empty() || p256_fake_tvs.is_empty()), - "Parsing error" - ); + let p256_real_tvs = json_to_test_vectors!(rfc, "Real", "P256_XMD:SHA-256_SSWU_RO_, SHA256",); + let p256_fake_tvs = json_to_test_vectors!(rfc, "Fake", "P256_XMD:SHA-256_SSWU_RO_, SHA256",); - struct P256Sha256NoSlowHash; - impl CipherSuite for P256Sha256NoSlowHash { - type OprfGroup = p256::ProjectivePoint; - type KeGroup = p256::NistP256; - type KeyExchange = TripleDH; - type Hash = sha2::Sha256; - type SlowHash = NoOpHash; - } + assert!( + !(p256_real_tvs.is_empty() || p256_fake_tvs.is_empty()), + "Parsing error" + ); - test_registration_request::(&p256_real_tvs)?; - test_registration_response::(&p256_real_tvs)?; - test_registration_upload::(&p256_real_tvs)?; - test_ke1::(&p256_real_tvs)?; - test_ke2::(&p256_real_tvs)?; - test_ke3::(&p256_real_tvs)?; - test_server_login_finish::(&p256_real_tvs)?; - test_fake_vectors::(&p256_fake_tvs)?; + struct P256Sha256NoSlowHash; + impl CipherSuite for P256Sha256NoSlowHash { + type OprfGroup = p256::ProjectivePoint; + type KeGroup = p256::NistP256; + type KeyExchange = TripleDH; + type Hash = sha2::Sha256; + type SlowHash = NoOpHash; } + test_registration_request::(&p256_real_tvs)?; + test_registration_response::(&p256_real_tvs)?; + test_registration_upload::(&p256_real_tvs)?; + test_ke1::(&p256_real_tvs)?; + test_ke2::(&p256_real_tvs)?; + test_ke3::(&p256_real_tvs)?; + test_server_login_finish::(&p256_real_tvs)?; + test_fake_vectors::(&p256_fake_tvs)?; + Ok(()) }