Voprf update (#255)
* Update to latest voprf * Upgrade to Rust edition 2021 * Fix Clippy * Remove all allocations * Remove unnecessary `allow(type_alias_bounds)` * Make all serialization infallible * Remove self-dependency * Update rustyline
This commit is contained in:
@@ -19,10 +19,7 @@ jobs:
|
||||
- x25519_u64,ristretto255_u64
|
||||
toolchain:
|
||||
- stable
|
||||
- 1.51.0
|
||||
exclude:
|
||||
- backend_feature: p256
|
||||
toolchain: 1.51.0
|
||||
- 1.56.1
|
||||
name: test
|
||||
steps:
|
||||
- name: Checkout sources
|
||||
@@ -102,7 +99,7 @@ jobs:
|
||||
matrix:
|
||||
toolchain:
|
||||
- stable
|
||||
- 1.51.0
|
||||
- 1.56.1
|
||||
name: test simple_login command-line example
|
||||
steps:
|
||||
- name: install expect
|
||||
@@ -125,7 +122,7 @@ jobs:
|
||||
matrix:
|
||||
toolchain:
|
||||
- stable
|
||||
- 1.51.0
|
||||
- 1.56.1
|
||||
name: test digital_locker command-line example
|
||||
steps:
|
||||
- name: install expect
|
||||
|
||||
+9
-12
@@ -7,10 +7,9 @@ categories = ["no-std"]
|
||||
description = "An implementation of the OPAQUE password-authenticated key exchange protocol"
|
||||
authors = ["Kevin Lewi <[email protected]>", "François Garillot <[email protected]>"]
|
||||
license = "Apache-2.0 OR MIT"
|
||||
edition = "2018"
|
||||
edition = "2021"
|
||||
readme = "README.md"
|
||||
resolver = "2"
|
||||
rust-version = "1.51"
|
||||
rust-version = "1.56"
|
||||
|
||||
[features]
|
||||
default = ["ristretto255_u64", "serde"]
|
||||
@@ -37,17 +36,17 @@ argon2 = { version = "0.3", default-features = false, features = ["alloc"], opti
|
||||
constant_time_eq = "0.1"
|
||||
curve25519-dalek = { version = "3", default-features = false, optional = true }
|
||||
derive-where = { version = "1.0.0-rc.1", features = ["zeroize"] }
|
||||
digest = "0.9"
|
||||
digest = "0.10"
|
||||
displaydoc = { version = "0.2", default-features = false }
|
||||
generic-array = "0.14"
|
||||
getrandom = { version = "0.2", optional = true }
|
||||
hkdf = "0.11"
|
||||
hmac = "0.11"
|
||||
p256_ = { package = "p256", version = "0.9", default-features = false, features = ["arithmetic", "zeroize"], 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/khonsulabs/voprf", rev = "f8c19eab4ecc9e7a2a5ae26c59661ce797229566", default-features = false, features = ["danger"] }
|
||||
voprf = { git = "https://github.com/novifinancial/voprf", rev = "55ef981a3f9a12eddd8c372ffdf51818011343ee", default-features = false, features = ["danger"] }
|
||||
x25519-dalek = { version = "1", default-features = false, optional = true }
|
||||
zeroize = { version = "1", features = ["zeroize_derive"] }
|
||||
|
||||
@@ -62,13 +61,11 @@ criterion = "0.3"
|
||||
hex = "0.4"
|
||||
json = "0.12"
|
||||
lazy_static = "1"
|
||||
opaque-ke = { path = "", default-features = false, features = ["std"] }
|
||||
serde_json = "1"
|
||||
sha2 = "0.9"
|
||||
sha2 = "0.10"
|
||||
proptest = "1"
|
||||
regex = "1"
|
||||
# Version 9.1 requires an MSRV of 1.56
|
||||
rustyline = "~9.0"
|
||||
rustyline = "9"
|
||||
|
||||
[[bench]]
|
||||
name = "opaque"
|
||||
|
||||
@@ -27,7 +27,7 @@ opaque-ke = "0.6.0"
|
||||
|
||||
### Minimum Supported Rust Version
|
||||
|
||||
Rust **1.51** or higher.
|
||||
Rust **1.56** or higher.
|
||||
|
||||
Audit
|
||||
-----
|
||||
|
||||
@@ -113,6 +113,7 @@ fn client_registration_finish(c: &mut Criterion) {
|
||||
.state
|
||||
.finish(
|
||||
&mut rng,
|
||||
password,
|
||||
server_registration_start_result.message.clone(),
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
@@ -139,6 +140,7 @@ fn server_registration_finish(c: &mut Criterion) {
|
||||
.state
|
||||
.finish(
|
||||
&mut rng,
|
||||
password,
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
@@ -182,6 +184,7 @@ fn server_login_start_real(c: &mut Criterion) {
|
||||
.state
|
||||
.finish(
|
||||
&mut rng,
|
||||
password,
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
@@ -249,6 +252,7 @@ fn client_login_finish(c: &mut Criterion) {
|
||||
.state
|
||||
.finish(
|
||||
&mut rng,
|
||||
password,
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
@@ -271,6 +275,7 @@ fn client_login_finish(c: &mut Criterion) {
|
||||
.clone()
|
||||
.state
|
||||
.finish(
|
||||
password,
|
||||
server_login_start.clone().message,
|
||||
ClientLoginFinishParameters::default(),
|
||||
)
|
||||
@@ -296,6 +301,7 @@ fn server_login_finish(c: &mut Criterion) {
|
||||
.state
|
||||
.finish(
|
||||
&mut rng,
|
||||
password,
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
@@ -314,6 +320,7 @@ fn server_login_finish(c: &mut Criterion) {
|
||||
let client_login_finish_result = client_login_start_result
|
||||
.state
|
||||
.finish(
|
||||
password,
|
||||
server_login_start_result.clone().message,
|
||||
ClientLoginFinishParameters::default(),
|
||||
)
|
||||
|
||||
@@ -122,6 +122,7 @@ fn register_locker(
|
||||
.state
|
||||
.finish(
|
||||
&mut client_rng,
|
||||
password.as_bytes(),
|
||||
RegistrationResponse::deserialize(®istration_response_bytes).unwrap(),
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
@@ -176,6 +177,7 @@ fn open_locker(
|
||||
// Server sends credential_response_bytes to client
|
||||
|
||||
let result = client_login_start_result.state.finish(
|
||||
password.as_bytes(),
|
||||
CredentialResponse::deserialize(&credential_response_bytes).unwrap(),
|
||||
ClientLoginFinishParameters::default(),
|
||||
);
|
||||
|
||||
@@ -86,6 +86,7 @@ fn account_registration(
|
||||
.state
|
||||
.finish(
|
||||
&mut client_rng,
|
||||
password.as_bytes(),
|
||||
RegistrationResponse::deserialize(®istration_response_bytes).unwrap(),
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
@@ -130,6 +131,7 @@ fn account_login(
|
||||
// Server sends credential_response_bytes to client
|
||||
|
||||
let result = client_login_start_result.state.finish(
|
||||
password.as_bytes(),
|
||||
CredentialResponse::deserialize(&credential_response_bytes).unwrap(),
|
||||
ClientLoginFinishParameters::default(),
|
||||
);
|
||||
|
||||
+10
-2
@@ -7,9 +7,12 @@
|
||||
|
||||
//! Defines the CipherSuite trait to specify the underlying primitives for OPAQUE
|
||||
|
||||
use crate::hash::ProxyHash;
|
||||
use crate::key_exchange::group::KeGroup;
|
||||
use crate::{hash::Hash, key_exchange::traits::KeyExchange, slow_hash::SlowHash};
|
||||
use voprf::group::Group as OprfGroup;
|
||||
use digest::core_api::{BlockSizeUser, CoreProxy};
|
||||
use generic_array::typenum::{IsLess, Le, NonZero, U256};
|
||||
use voprf::Group as OprfGroup;
|
||||
|
||||
/// Configures the underlying primitives used in OPAQUE
|
||||
/// * `OprfGroup`: a finite cyclic group along with a point representation, along
|
||||
@@ -19,7 +22,12 @@ use voprf::group::Group as OprfGroup;
|
||||
/// * `KeyExchange`: The key exchange protocol to use in the login step
|
||||
/// * `Hash`: The main hashing function to use
|
||||
/// * `SlowHash`: A slow hashing function, typically used for password hashing
|
||||
pub trait CipherSuite {
|
||||
pub trait CipherSuite
|
||||
where
|
||||
<Self::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<Self::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<Self::Hash 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`.
|
||||
|
||||
+63
-44
@@ -8,7 +8,7 @@
|
||||
use crate::{
|
||||
ciphersuite::CipherSuite,
|
||||
errors::{utils::check_slice_size, InternalError, ProtocolError},
|
||||
hash::Hash,
|
||||
hash::{Hash, OutputSize, ProxyHash},
|
||||
key_exchange::group::KeGroup,
|
||||
keypair::{KeyPair, PublicKey},
|
||||
opaque::{bytestrings_from_identifiers, Identifiers},
|
||||
@@ -17,16 +17,17 @@ use crate::{
|
||||
use core::convert::TryFrom;
|
||||
use core::ops::Add;
|
||||
use derive_where::DeriveWhere;
|
||||
use digest::{Digest, FixedOutput};
|
||||
use digest::core_api::{BlockSizeUser, CoreProxy};
|
||||
use digest::Output;
|
||||
use generic_array::{
|
||||
sequence::Concat,
|
||||
typenum::{Sum, Unsigned, U2, U32},
|
||||
typenum::{IsLess, Le, NonZero, Sum, Unsigned, U2, U256, U32},
|
||||
ArrayLength, GenericArray,
|
||||
};
|
||||
use hkdf::Hkdf;
|
||||
use hmac::{Hmac, Mac, NewMac};
|
||||
use hmac::{Hmac, Mac};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use voprf::group::Group;
|
||||
use voprf::Group;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
// Constant string used as salt for HKDF computation
|
||||
@@ -65,55 +66,63 @@ impl TryFrom<u8> for InnerEnvelopeMode {
|
||||
/// the confusion around the implementation of an RKR-secure encryption.
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize(drop))]
|
||||
pub(crate) struct Envelope<CS: CipherSuite> {
|
||||
pub(crate) struct Envelope<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
mode: InnerEnvelopeMode,
|
||||
nonce: GenericArray<u8, NonceLen>,
|
||||
hmac: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
hmac: Output<CS::Hash>,
|
||||
}
|
||||
|
||||
// Note that this struct represents an envelope that has been "opened" with the asssociated
|
||||
// key. This key is also used to derive the export_key parameter, which is technically
|
||||
// unrelated to the envelope's encrypted and authenticated contents.
|
||||
pub(crate) struct OpenedEnvelope<'a, CS: CipherSuite> {
|
||||
pub(crate) struct OpenedEnvelope<'a, CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
pub(crate) client_static_keypair: KeyPair<CS::KeGroup>,
|
||||
pub(crate) export_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub(crate) export_key: Output<CS::Hash>,
|
||||
pub(crate) id_u: Serialize<'a, U2, <CS::KeGroup as KeGroup>::PkLen>,
|
||||
pub(crate) id_s: Serialize<'a, U2, <CS::KeGroup as KeGroup>::PkLen>,
|
||||
}
|
||||
|
||||
pub(crate) struct OpenedInnerEnvelope<D: Hash> {
|
||||
pub(crate) export_key: GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
pub(crate) struct OpenedInnerEnvelope<D: Hash>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
pub(crate) export_key: Output<D>,
|
||||
}
|
||||
|
||||
#[cfg(not(test))]
|
||||
type SealRawResult<CS> = (
|
||||
Envelope<CS>,
|
||||
GenericArray<u8, <<CS as CipherSuite>::Hash as Digest>::OutputSize>,
|
||||
);
|
||||
type SealRawResult<CS: CipherSuite> = (Envelope<CS>, Output<CS::Hash>);
|
||||
#[cfg(test)]
|
||||
type SealRawResult<CS> = (
|
||||
Envelope<CS>,
|
||||
GenericArray<u8, <<CS as CipherSuite>::Hash as Digest>::OutputSize>,
|
||||
GenericArray<u8, <<CS as CipherSuite>::Hash as Digest>::OutputSize>,
|
||||
);
|
||||
type SealRawResult<CS: CipherSuite> = (Envelope<CS>, Output<CS::Hash>, Output<CS::Hash>);
|
||||
#[cfg(not(test))]
|
||||
type SealResult<CS> = (
|
||||
Envelope<CS>,
|
||||
PublicKey<<CS as CipherSuite>::KeGroup>,
|
||||
GenericArray<u8, <<CS as CipherSuite>::Hash as Digest>::OutputSize>,
|
||||
);
|
||||
type SealResult<CS: CipherSuite> = (Envelope<CS>, PublicKey<CS::KeGroup>, Output<CS::Hash>);
|
||||
#[cfg(test)]
|
||||
type SealResult<CS> = (
|
||||
type SealResult<CS: CipherSuite> = (
|
||||
Envelope<CS>,
|
||||
PublicKey<<CS as CipherSuite>::KeGroup>,
|
||||
GenericArray<u8, <<CS as CipherSuite>::Hash as Digest>::OutputSize>,
|
||||
GenericArray<u8, <<CS as CipherSuite>::Hash as Digest>::OutputSize>,
|
||||
PublicKey<CS::KeGroup>,
|
||||
Output<CS::Hash>,
|
||||
Output<CS::Hash>,
|
||||
);
|
||||
|
||||
#[allow(type_alias_bounds)]
|
||||
pub(crate) type EnvelopeLen<CS: CipherSuite> = Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>;
|
||||
pub(crate) type EnvelopeLen<CS: CipherSuite> = Sum<NonceLen, OutputSize<CS::Hash>>;
|
||||
|
||||
impl<CS: CipherSuite> Envelope<CS> {
|
||||
impl<CS: CipherSuite> Envelope<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub(crate) fn seal<R: RngCore + CryptoRng>(
|
||||
rng: &mut R,
|
||||
@@ -155,8 +164,8 @@ impl<CS: CipherSuite> Envelope<CS> {
|
||||
aad: impl Iterator<Item = &'a [u8]>,
|
||||
mode: InnerEnvelopeMode,
|
||||
) -> Result<SealRawResult<CS>, InternalError> {
|
||||
let mut hmac_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut export_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut hmac_key = Output::<CS::Hash>::default();
|
||||
let mut export_key = Output::<CS::Hash>::default();
|
||||
|
||||
randomized_pwd_hasher
|
||||
.expand_multi_info(&[&nonce, &STR_AUTH_KEY], &mut hmac_key)
|
||||
@@ -223,8 +232,8 @@ impl<CS: CipherSuite> Envelope<CS> {
|
||||
randomized_pwd_hasher: Hkdf<CS::Hash>,
|
||||
aad: impl Iterator<Item = &'a [u8]>,
|
||||
) -> Result<OpenedInnerEnvelope<CS::Hash>, InternalError> {
|
||||
let mut hmac_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut export_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut hmac_key = Output::<CS::Hash>::default();
|
||||
let mut export_key = Output::<CS::Hash>::default();
|
||||
|
||||
randomized_pwd_hasher
|
||||
.expand(&self.nonce.concat(STR_AUTH_KEY.into()), &mut hmac_key)
|
||||
@@ -253,17 +262,17 @@ impl<CS: CipherSuite> Envelope<CS> {
|
||||
}
|
||||
|
||||
fn hmac_key_size() -> usize {
|
||||
<CS::Hash as Digest>::OutputSize::USIZE
|
||||
OutputSize::<CS::Hash>::USIZE
|
||||
}
|
||||
|
||||
pub(crate) fn len() -> usize {
|
||||
<CS::Hash as Digest>::OutputSize::USIZE + NonceLen::USIZE
|
||||
OutputSize::<CS::Hash>::USIZE + NonceLen::USIZE
|
||||
}
|
||||
|
||||
pub(crate) fn serialize(&self) -> GenericArray<u8, EnvelopeLen<CS>>
|
||||
where
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
self.nonce.concat(self.hmac.clone())
|
||||
@@ -300,14 +309,19 @@ impl<CS: CipherSuite> Envelope<CS> {
|
||||
fn build_inner_envelope_internal<CS: CipherSuite>(
|
||||
randomized_pwd_hasher: Hkdf<CS::Hash>,
|
||||
nonce: GenericArray<u8, NonceLen>,
|
||||
) -> Result<PublicKey<CS::KeGroup>, ProtocolError> {
|
||||
) -> Result<PublicKey<CS::KeGroup>, ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut keypair_seed = GenericArray::<_, <CS::KeGroup as KeGroup>::SkLen>::default();
|
||||
randomized_pwd_hasher
|
||||
.expand(&nonce.concat(STR_PRIVATE_KEY.into()), &mut keypair_seed)
|
||||
.map_err(|_| InternalError::HkdfError)?;
|
||||
let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
|
||||
&CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash, _, _>(
|
||||
Some(keypair_seed.as_slice()),
|
||||
[keypair_seed.as_slice()],
|
||||
GenericArray::from(STR_OPAQUE_DERIVE_AUTH_KEY_PAIR),
|
||||
)?),
|
||||
)?;
|
||||
@@ -318,14 +332,19 @@ fn build_inner_envelope_internal<CS: CipherSuite>(
|
||||
fn recover_keys_internal<CS: CipherSuite>(
|
||||
randomized_pwd_hasher: Hkdf<CS::Hash>,
|
||||
nonce: GenericArray<u8, NonceLen>,
|
||||
) -> Result<KeyPair<CS::KeGroup>, ProtocolError> {
|
||||
) -> Result<KeyPair<CS::KeGroup>, ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut keypair_seed = GenericArray::<_, <CS::KeGroup as KeGroup>::SkLen>::default();
|
||||
randomized_pwd_hasher
|
||||
.expand(&nonce.concat(STR_PRIVATE_KEY.into()), &mut keypair_seed)
|
||||
.map_err(|_| InternalError::HkdfError)?;
|
||||
let client_static_keypair = KeyPair::<CS::KeGroup>::from_private_key_slice(
|
||||
&CS::OprfGroup::scalar_as_bytes(CS::OprfGroup::hash_to_scalar::<CS::Hash, _, _>(
|
||||
Some(keypair_seed.as_slice()),
|
||||
[keypair_seed.as_slice()],
|
||||
GenericArray::from(STR_OPAQUE_DERIVE_AUTH_KEY_PAIR),
|
||||
)?),
|
||||
)?;
|
||||
@@ -338,5 +357,5 @@ fn construct_aad<'a>(
|
||||
id_s: impl Iterator<Item = &'a [u8]>,
|
||||
server_s_pk: &'a [u8],
|
||||
) -> impl Iterator<Item = &'a [u8]> {
|
||||
chain!(Some(server_s_pk).into_iter(), id_s, id_u)
|
||||
[server_s_pk].into_iter().chain(id_s).chain(id_u)
|
||||
}
|
||||
|
||||
+8
-8
@@ -8,7 +8,7 @@
|
||||
//! A list of error types which are produced during an execution of the protocol
|
||||
use core::convert::Infallible;
|
||||
use core::fmt::Debug;
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(any(feature = "std", test))]
|
||||
use std::error::Error;
|
||||
|
||||
use displaydoc::Display;
|
||||
@@ -48,7 +48,7 @@ pub enum InternalError<T = Infallible> {
|
||||
/// This error occurs when the inner envelope is malformed
|
||||
InvalidInnerEnvelopeError,
|
||||
/// Error from the OPRF evaluation
|
||||
OprfError(voprf::errors::InternalError),
|
||||
OprfError(voprf::Error),
|
||||
/// Error encountered when attempting to produce a keypair
|
||||
InvalidKeypairError,
|
||||
}
|
||||
@@ -84,7 +84,7 @@ impl<T: Debug> Debug for InternalError<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Error> Error for InternalError<T> {}
|
||||
|
||||
impl InternalError {
|
||||
@@ -116,14 +116,14 @@ impl InternalError {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<voprf::errors::InternalError> for InternalError {
|
||||
fn from(voprf_error: voprf::errors::InternalError) -> Self {
|
||||
impl From<voprf::Error> for InternalError {
|
||||
fn from(voprf_error: voprf::Error) -> Self {
|
||||
Self::OprfError(voprf_error)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<voprf::errors::InternalError> for ProtocolError {
|
||||
fn from(voprf_error: voprf::errors::InternalError) -> Self {
|
||||
impl From<voprf::Error> for ProtocolError {
|
||||
fn from(voprf_error: voprf::Error) -> Self {
|
||||
Self::LibraryError(InternalError::OprfError(voprf_error))
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ impl<T: Debug> Debug for ProtocolError<T> {
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "std")]
|
||||
#[cfg(any(feature = "std", test))]
|
||||
impl<T: Error> Error for ProtocolError<T> {}
|
||||
|
||||
// This is meant to express future(ly) non-trivial ways of converting the
|
||||
|
||||
+50
-3
@@ -7,11 +7,58 @@
|
||||
|
||||
//! A convenience trait for digest bounds used throughout the library
|
||||
|
||||
use digest::{BlockInput, FixedOutput, Reset, Update};
|
||||
use digest::block_buffer::Eager;
|
||||
use digest::core_api::{BlockSizeUser, BufferKindUser, CoreProxy, FixedOutputCore};
|
||||
use digest::{Digest, FixedOutputReset, HashMarker, OutputSizeUser};
|
||||
use generic_array::typenum::{IsLess, Le, NonZero, U256};
|
||||
|
||||
pub(crate) type OutputSize<D> = <<D as CoreProxy>::Core as OutputSizeUser>::OutputSize;
|
||||
|
||||
/// Trait to simplify requirements for [`Hash`].
|
||||
pub trait ProxyHash:
|
||||
HashMarker + FixedOutputCore + BufferKindUser<BufferKind = Eager> + Default + Clone
|
||||
where
|
||||
<Self as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<Self as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: HashMarker + FixedOutputCore + BufferKindUser<BufferKind = Eager> + Default + Clone>
|
||||
ProxyHash for T
|
||||
where
|
||||
<Self as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<Self as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
}
|
||||
|
||||
/// Trait inheriting the requirements from digest::Digest for compatibility with HKDF and HMAC
|
||||
// Associated types could be simplified when they are made as defaults:
|
||||
// https://github.com/rust-lang/rust/issues/29661
|
||||
pub trait Hash: Update + BlockInput + FixedOutput + Reset + Default + Clone {}
|
||||
pub trait Hash:
|
||||
Digest
|
||||
+ OutputSizeUser<OutputSize = OutputSize<Self>>
|
||||
+ BlockSizeUser
|
||||
+ FixedOutputReset
|
||||
+ CoreProxy
|
||||
+ Clone
|
||||
where
|
||||
<Self as CoreProxy>::Core: ProxyHash,
|
||||
<<Self as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<Self as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
}
|
||||
|
||||
impl<T: Update + BlockInput + FixedOutput + Reset + Default + Clone> Hash for T {}
|
||||
impl<
|
||||
T: Digest
|
||||
+ OutputSizeUser<OutputSize = OutputSize<Self>>
|
||||
+ BlockSizeUser
|
||||
+ FixedOutputReset
|
||||
+ CoreProxy
|
||||
+ Clone,
|
||||
> Hash for T
|
||||
where
|
||||
<Self as CoreProxy>::Core: ProxyHash,
|
||||
<<Self as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<Self as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
}
|
||||
|
||||
+20
-6
@@ -7,23 +7,29 @@
|
||||
|
||||
/// Macro used for deriving `serde`'s `Serialize` and `Deserialize` traits.
|
||||
macro_rules! impl_serialize_and_deserialize_for {
|
||||
($item:ident$( where $($path:ty: $bound1:path $(| $bound2:path)*),+$(,)?)?$(; $error:expr)?) => {
|
||||
($item:ident$( where $($path:ty: $bound1:path $(| $bound2:path)*),+$(,)?)?) => {
|
||||
#[cfg(feature = "serde")]
|
||||
impl<CS: CipherSuite> serde_::Serialize for $item<CS>
|
||||
$(where
|
||||
$($path: $bound1 $(+ $bound2)*),+
|
||||
)?
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
$($($path: $bound1 $(+ $bound2)*),+)?
|
||||
{
|
||||
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
|
||||
where
|
||||
S: serde_::Serializer,
|
||||
{
|
||||
serializer.serialize_bytes(&self.serialize()$(.map_err($error)?)?)
|
||||
serializer.serialize_bytes(&self.serialize())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "serde")]
|
||||
impl<'de, CS: CipherSuite> serde_::Deserialize<'de> for $item<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
@@ -31,9 +37,17 @@ macro_rules! impl_serialize_and_deserialize_for {
|
||||
{
|
||||
use serde_::de::Error;
|
||||
|
||||
struct ByteVisitor<CS: CipherSuite>(core::marker::PhantomData<CS>);
|
||||
struct ByteVisitor<CS: CipherSuite>(core::marker::PhantomData<CS>)
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero;
|
||||
|
||||
impl<'de, CS: CipherSuite> serde_::de::Visitor<'de> for ByteVisitor<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
type Value = $item<CS>;
|
||||
|
||||
|
||||
@@ -26,11 +26,13 @@ impl KeGroup for PublicKey<NistP256> {
|
||||
}
|
||||
|
||||
fn random_sk<R: RngCore + CryptoRng>(rng: &mut R) -> GenericArray<u8, Self::SkLen> {
|
||||
SecretKey::<NistP256>::random(rng).to_bytes()
|
||||
SecretKey::<NistP256>::random(rng).to_be_bytes()
|
||||
}
|
||||
|
||||
fn public_key(sk: &GenericArray<u8, Self::SkLen>) -> Self {
|
||||
SecretKey::<NistP256>::from_bytes(sk).unwrap().public_key()
|
||||
SecretKey::<NistP256>::from_be_bytes(sk)
|
||||
.unwrap()
|
||||
.public_key()
|
||||
}
|
||||
|
||||
fn to_arr(&self) -> GenericArray<u8, Self::PkLen> {
|
||||
@@ -39,9 +41,9 @@ impl KeGroup for PublicKey<NistP256> {
|
||||
|
||||
fn diffie_hellman(&self, sk: &GenericArray<u8, Self::SkLen>) -> GenericArray<u8, Self::PkLen> {
|
||||
(self.to_projective()
|
||||
* SecretKey::<NistP256>::from_bytes(sk)
|
||||
* SecretKey::<NistP256>::from_be_bytes(sk)
|
||||
.unwrap()
|
||||
.to_secret_scalar()
|
||||
.to_nonzero_scalar()
|
||||
.as_ref())
|
||||
.to_affine()
|
||||
.to_bytes()
|
||||
|
||||
+18
-18
@@ -5,6 +5,7 @@
|
||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
// of this source tree.
|
||||
|
||||
use crate::hash::ProxyHash;
|
||||
use crate::key_exchange::group::KeGroup;
|
||||
use crate::{
|
||||
ciphersuite::CipherSuite,
|
||||
@@ -12,7 +13,9 @@ use crate::{
|
||||
hash::Hash,
|
||||
keypair::{PrivateKey, PublicKey, SecretKey},
|
||||
};
|
||||
use digest::Digest;
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::Output;
|
||||
use generic_array::typenum::{IsLess, Le, NonZero, U256};
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use zeroize::Zeroize;
|
||||
@@ -26,23 +29,25 @@ pub type GenerateKe2Result<K, D, G> = (
|
||||
pub type GenerateKe2Result<K, D, G> = (
|
||||
<K as KeyExchange<D, G>>::KE2State,
|
||||
<K as KeyExchange<D, G>>::KE2Message,
|
||||
GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
Output<D>,
|
||||
Output<D>,
|
||||
);
|
||||
#[cfg(not(test))]
|
||||
pub type GenerateKe3Result<K, D, G> = (
|
||||
GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
<K as KeyExchange<D, G>>::KE3Message,
|
||||
);
|
||||
pub type GenerateKe3Result<K, D, G> = (Output<D>, <K as KeyExchange<D, G>>::KE3Message);
|
||||
#[cfg(test)]
|
||||
pub type GenerateKe3Result<K, D, G> = (
|
||||
GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
Output<D>,
|
||||
<K as KeyExchange<D, G>>::KE3Message,
|
||||
GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
Output<D>,
|
||||
Output<D>,
|
||||
);
|
||||
|
||||
pub trait KeyExchange<D: Hash, G: KeGroup> {
|
||||
pub trait KeyExchange<D: Hash, G: KeGroup>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
type KE1State: FromBytes + ToBytes + Zeroize + Clone;
|
||||
type KE2State: FromBytes + ToBytes + Zeroize + Clone;
|
||||
type KE1Message: FromBytes + ToBytes + Zeroize + Clone;
|
||||
@@ -83,7 +88,7 @@ pub trait KeyExchange<D: Hash, G: KeGroup> {
|
||||
fn finish_ke(
|
||||
ke3_message: Self::KE3Message,
|
||||
ke2_state: &Self::KE2State,
|
||||
) -> Result<GenericArray<u8, D::OutputSize>, ProtocolError>;
|
||||
) -> Result<Output<D>, ProtocolError>;
|
||||
|
||||
fn ke2_message_size() -> usize;
|
||||
}
|
||||
@@ -98,19 +103,14 @@ pub trait ToBytes {
|
||||
fn to_bytes(&self) -> GenericArray<u8, Self::Len>;
|
||||
}
|
||||
|
||||
#[allow(dead_code, type_alias_bounds)]
|
||||
#[allow(dead_code)]
|
||||
pub type Ke1StateLen<CS: CipherSuite> =
|
||||
<<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE1State as ToBytes>::Len;
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type Ke1MessageLen<CS: CipherSuite> =
|
||||
<<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE1Message as ToBytes>::Len;
|
||||
#[allow(type_alias_bounds)]
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type Ke2StateLen<CS: CipherSuite> =
|
||||
<<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE2State as ToBytes>::Len;
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type Ke2MessageLen<CS: CipherSuite> =
|
||||
<<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE2Message as ToBytes>::Len;
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type Ke3MessageLen<CS: CipherSuite> =
|
||||
<<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE3Message as ToBytes>::Len;
|
||||
|
||||
+115
-57
@@ -11,7 +11,7 @@ use crate::{
|
||||
utils::{check_slice_size, check_slice_size_atleast},
|
||||
InternalError, ProtocolError,
|
||||
},
|
||||
hash::Hash,
|
||||
hash::{Hash, OutputSize, ProxyHash},
|
||||
key_exchange::{
|
||||
group::KeGroup,
|
||||
traits::{FromBytes, GenerateKe2Result, GenerateKe3Result, KeyExchange, ToBytes},
|
||||
@@ -19,18 +19,19 @@ use crate::{
|
||||
keypair::{KeyPair, PrivateKey, PublicKey, SecretKey},
|
||||
serialization::{Serialize, UpdateExt},
|
||||
};
|
||||
use core::array::IntoIter;
|
||||
use core::convert::TryFrom;
|
||||
use core::ops::Add;
|
||||
use derive_where::DeriveWhere;
|
||||
use digest::{Digest, FixedOutput};
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::{Digest, Output};
|
||||
use generic_array::sequence::Concat;
|
||||
use generic_array::typenum::{IsLess, Le, NonZero, U256};
|
||||
use generic_array::{
|
||||
typenum::{Sum, Unsigned, U1, U2, U32},
|
||||
ArrayLength, GenericArray,
|
||||
};
|
||||
use hkdf::{Hkdf, HkdfExtract};
|
||||
use hmac::{Hmac, Mac, NewMac};
|
||||
use hmac::{Hmac, Mac};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
///////////////
|
||||
@@ -89,10 +90,15 @@ pub struct Ke1Message<KG: KeGroup> {
|
||||
)]
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize(drop))]
|
||||
pub struct Ke2State<D: Hash> {
|
||||
km3: GenericArray<u8, D::OutputSize>,
|
||||
hashed_transcript: GenericArray<u8, D::OutputSize>,
|
||||
session_key: GenericArray<u8, D::OutputSize>,
|
||||
pub struct Ke2State<D: Hash>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
km3: Output<D>,
|
||||
hashed_transcript: Output<D>,
|
||||
session_key: Output<D>,
|
||||
}
|
||||
|
||||
/// The second key exchange message
|
||||
@@ -103,10 +109,15 @@ pub struct Ke2State<D: Hash> {
|
||||
)]
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub struct Ke2Message<D: Hash, KG: KeGroup> {
|
||||
pub struct Ke2Message<D: Hash, KG: KeGroup>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
server_nonce: GenericArray<u8, NonceLen>,
|
||||
server_e_pk: PublicKey<KG>,
|
||||
mac: GenericArray<u8, D::OutputSize>,
|
||||
mac: Output<D>,
|
||||
}
|
||||
|
||||
/// The third key exchange message
|
||||
@@ -117,8 +128,13 @@ pub struct Ke2Message<D: Hash, KG: KeGroup> {
|
||||
)]
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
|
||||
pub struct Ke3Message<D: Hash> {
|
||||
mac: GenericArray<u8, D::OutputSize>,
|
||||
pub struct Ke3Message<D: Hash>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
mac: Output<D>,
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
@@ -128,6 +144,9 @@ pub struct Ke3Message<D: Hash> {
|
||||
|
||||
impl<D: Hash, KG: KeGroup> KeyExchange<D, KG> for TripleDH
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Ke1State: KeSk + Nonce
|
||||
KG::SkLen: Add<NonceLen>,
|
||||
Sum<KG::SkLen, NonceLen>: ArrayLength<u8>,
|
||||
@@ -135,13 +154,13 @@ where
|
||||
NonceLen: Add<KG::PkLen>,
|
||||
Sum<NonceLen, KG::PkLen>: ArrayLength<u8>,
|
||||
// Ke2State: (Hash + Hash) + Hash
|
||||
D::OutputSize: Add<D::OutputSize>,
|
||||
Sum<D::OutputSize, D::OutputSize>: ArrayLength<u8> + Add<D::OutputSize>,
|
||||
Sum<Sum<D::OutputSize, D::OutputSize>, D::OutputSize>: ArrayLength<u8>,
|
||||
OutputSize<D>: Add<OutputSize<D>>,
|
||||
Sum<OutputSize<D>, OutputSize<D>>: ArrayLength<u8> + Add<OutputSize<D>>,
|
||||
Sum<Sum<OutputSize<D>, OutputSize<D>>, OutputSize<D>>: ArrayLength<u8>,
|
||||
// Ke2Message: (Nonce + KePk) + Hash
|
||||
NonceLen: Add<KG::PkLen>,
|
||||
Sum<NonceLen, KG::PkLen>: ArrayLength<u8> + Add<D::OutputSize>,
|
||||
Sum<Sum<NonceLen, KG::PkLen>, D::OutputSize>: ArrayLength<u8>,
|
||||
Sum<NonceLen, KG::PkLen>: ArrayLength<u8> + Add<OutputSize<D>>,
|
||||
Sum<Sum<NonceLen, KG::PkLen>, OutputSize<D>>: ArrayLength<u8>,
|
||||
{
|
||||
type KE1State = Ke1State<KG>;
|
||||
type KE2State = Ke2State<D>;
|
||||
@@ -215,7 +234,7 @@ where
|
||||
mac_hasher.update(&transcript_hasher.clone().finalize());
|
||||
let mac = mac_hasher.finalize().into_bytes();
|
||||
|
||||
transcript_hasher.update(&mac);
|
||||
Digest::update(&mut transcript_hasher, &mac);
|
||||
|
||||
Ok((
|
||||
Ke2State {
|
||||
@@ -276,7 +295,7 @@ where
|
||||
.verify(&ke2_message.mac)
|
||||
.map_err(|_| ProtocolError::InvalidLoginError)?;
|
||||
|
||||
transcript_hasher.update(&ke2_message.mac);
|
||||
Digest::update(&mut transcript_hasher, &ke2_message.mac);
|
||||
|
||||
let mut client_mac =
|
||||
Hmac::<D>::new_from_slice(&result.2).map_err(|_| InternalError::HmacError)?;
|
||||
@@ -294,11 +313,10 @@ where
|
||||
))
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn finish_ke(
|
||||
ke3_message: Self::KE3Message,
|
||||
ke2_state: &Self::KE2State,
|
||||
) -> Result<GenericArray<u8, D::OutputSize>, ProtocolError> {
|
||||
) -> Result<Output<D>, ProtocolError> {
|
||||
let mut client_mac =
|
||||
Hmac::<D>::new_from_slice(&ke2_state.km3).map_err(|_| InternalError::HmacError)?;
|
||||
client_mac.update(&ke2_state.hashed_transcript);
|
||||
@@ -311,7 +329,7 @@ where
|
||||
}
|
||||
|
||||
fn ke2_message_size() -> usize {
|
||||
NonceLen::USIZE + <KG as KeGroup>::PkLen::USIZE + <D as FixedOutput>::OutputSize::USIZE
|
||||
NonceLen::USIZE + <KG as KeGroup>::PkLen::USIZE + OutputSize::<D>::USIZE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -334,18 +352,9 @@ struct TripleDHComponents<KG: KeGroup, S: SecretKey<KG>> {
|
||||
// Consists of a session key, followed by two mac keys: (session_key, km2, km3)
|
||||
#[cfg(not(test))]
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
type TripleDHDerivationResult<D> = (
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
);
|
||||
type TripleDHDerivationResult<D> = (Output<D>, Output<D>, Output<D>);
|
||||
#[cfg(test)]
|
||||
type TripleDHDerivationResult<D> = (
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
);
|
||||
type TripleDHDerivationResult<D> = (Output<D>, Output<D>, Output<D>, Output<D>);
|
||||
|
||||
////////////////////////////////////////////////
|
||||
// Helper functions and Trait Implementations //
|
||||
@@ -359,7 +368,12 @@ type TripleDHDerivationResult<D> = (
|
||||
fn derive_3dh_keys<D: Hash, KG: KeGroup, S: SecretKey<KG>>(
|
||||
dh: TripleDHComponents<KG, S>,
|
||||
hashed_derivation_transcript: &[u8],
|
||||
) -> Result<TripleDHDerivationResult<D>, ProtocolError<S::Error>> {
|
||||
) -> Result<TripleDHDerivationResult<D>, ProtocolError<S::Error>>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut hkdf = HkdfExtract::<D>::new(None);
|
||||
|
||||
hkdf.input_ikm(
|
||||
@@ -406,7 +420,12 @@ fn hkdf_expand_label<D: Hash>(
|
||||
secret: &[u8],
|
||||
label: &[u8],
|
||||
context: &[u8],
|
||||
) -> Result<GenericArray<u8, D::OutputSize>, ProtocolError> {
|
||||
) -> Result<Output<D>, ProtocolError>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let h = Hkdf::<D>::from_prk(secret).map_err(|_| InternalError::HkdfError)?;
|
||||
hkdf_expand_label_extracted(&h, label, context)
|
||||
}
|
||||
@@ -415,11 +434,16 @@ fn hkdf_expand_label_extracted<D: Hash>(
|
||||
hkdf: &Hkdf<D>,
|
||||
label: &[u8],
|
||||
context: &[u8],
|
||||
) -> Result<GenericArray<u8, D::OutputSize>, ProtocolError> {
|
||||
) -> Result<Output<D>, ProtocolError>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut okm = GenericArray::default();
|
||||
|
||||
let length_u16: u16 =
|
||||
u16::try_from(D::OutputSize::USIZE).map_err(|_| ProtocolError::SerializationError)?;
|
||||
u16::try_from(OutputSize::<D>::USIZE).map_err(|_| ProtocolError::SerializationError)?;
|
||||
let label = Serialize::<U1>::from_label(STR_OPAQUE, label)?;
|
||||
let label = label.to_array_3();
|
||||
let context = Serialize::<U1>::from(context)?;
|
||||
@@ -443,7 +467,12 @@ fn derive_secrets<D: Hash>(
|
||||
hkdf: &Hkdf<D>,
|
||||
label: &[u8],
|
||||
hashed_derivation_transcript: &[u8],
|
||||
) -> Result<GenericArray<u8, D::OutputSize>, ProtocolError> {
|
||||
) -> Result<Output<D>, ProtocolError>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
hkdf_expand_label_extracted::<D>(hkdf, label, hashed_derivation_transcript)
|
||||
}
|
||||
|
||||
@@ -514,9 +543,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Hash> FromBytes for Ke2State<D> {
|
||||
impl<D: Hash> FromBytes for Ke2State<D>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
fn from_bytes(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let hash_len = D::OutputSize::USIZE;
|
||||
let hash_len = OutputSize::<D>::USIZE;
|
||||
let checked_bytes = check_slice_size(input, 3 * hash_len, "ke2_state")?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -531,12 +565,15 @@ impl<D: Hash> FromBytes for Ke2State<D> {
|
||||
|
||||
impl<D: Hash> ToBytes for Ke2State<D>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Ke2State: (Hash + Hash) + Hash
|
||||
D::OutputSize: Add<D::OutputSize>,
|
||||
Sum<D::OutputSize, D::OutputSize>: ArrayLength<u8> + Add<D::OutputSize>,
|
||||
Sum<Sum<D::OutputSize, D::OutputSize>, D::OutputSize>: ArrayLength<u8>,
|
||||
OutputSize<D>: Add<OutputSize<D>>,
|
||||
Sum<OutputSize<D>, OutputSize<D>>: ArrayLength<u8> + Add<OutputSize<D>>,
|
||||
Sum<Sum<OutputSize<D>, OutputSize<D>>, OutputSize<D>>: ArrayLength<u8>,
|
||||
{
|
||||
type Len = Sum<Sum<D::OutputSize, D::OutputSize>, D::OutputSize>;
|
||||
type Len = Sum<Sum<OutputSize<D>, OutputSize<D>>, OutputSize<D>>;
|
||||
|
||||
fn to_bytes(&self) -> GenericArray<u8, Self::Len> {
|
||||
self.km3
|
||||
@@ -546,7 +583,12 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<KG: KeGroup, D: Hash> FromBytes for Ke2Message<D, KG> {
|
||||
impl<KG: KeGroup, D: Hash> FromBytes for Ke2Message<D, KG>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
fn from_bytes(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let key_len = <KG as KeGroup>::PkLen::USIZE;
|
||||
let nonce_len = NonceLen::USIZE;
|
||||
@@ -559,7 +601,7 @@ impl<KG: KeGroup, D: Hash> FromBytes for Ke2Message<D, KG> {
|
||||
)?;
|
||||
let checked_mac = check_slice_size(
|
||||
&unchecked_server_e_pk[key_len..],
|
||||
D::OutputSize::USIZE,
|
||||
OutputSize::<D>::USIZE,
|
||||
"ke1_message mac",
|
||||
)?;
|
||||
|
||||
@@ -578,12 +620,15 @@ impl<KG: KeGroup, D: Hash> FromBytes for Ke2Message<D, KG> {
|
||||
|
||||
impl<D: Hash, KG: KeGroup> ToBytes for Ke2Message<D, KG>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Ke2Message: (Nonce + KePk) + Hash
|
||||
NonceLen: Add<KG::PkLen>,
|
||||
Sum<NonceLen, KG::PkLen>: ArrayLength<u8> + Add<D::OutputSize>,
|
||||
Sum<Sum<NonceLen, KG::PkLen>, D::OutputSize>: ArrayLength<u8>,
|
||||
Sum<NonceLen, KG::PkLen>: ArrayLength<u8> + Add<OutputSize<D>>,
|
||||
Sum<Sum<NonceLen, KG::PkLen>, OutputSize<D>>: ArrayLength<u8>,
|
||||
{
|
||||
type Len = Sum<Sum<NonceLen, KG::PkLen>, D::OutputSize>;
|
||||
type Len = Sum<Sum<NonceLen, KG::PkLen>, OutputSize<D>>;
|
||||
|
||||
fn to_bytes(&self) -> GenericArray<u8, Self::Len> {
|
||||
self.server_nonce
|
||||
@@ -592,17 +637,25 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Hash, KG: KeGroup> Ke2Message<D, KG> {
|
||||
impl<D: Hash, KG: KeGroup> Ke2Message<D, KG>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
fn to_bytes_without_info_or_mac(&self) -> impl Iterator<Item = &[u8]> {
|
||||
// MSRV: array `into_iter` isn't available in 1.51
|
||||
#[allow(deprecated)]
|
||||
IntoIter::new([self.server_nonce.as_slice(), self.server_e_pk.as_slice()])
|
||||
[self.server_nonce.as_slice(), self.server_e_pk.as_slice()].into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Hash> FromBytes for Ke3Message<D> {
|
||||
impl<D: Hash> FromBytes for Ke3Message<D>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
fn from_bytes(bytes: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let checked_bytes = check_slice_size(bytes, D::OutputSize::USIZE, "ke3_message")?;
|
||||
let checked_bytes = check_slice_size(bytes, OutputSize::<D>::USIZE, "ke3_message")?;
|
||||
|
||||
Ok(Self {
|
||||
mac: GenericArray::clone_from_slice(checked_bytes),
|
||||
@@ -610,8 +663,13 @@ impl<D: Hash> FromBytes for Ke3Message<D> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<D: Hash> ToBytes for Ke3Message<D> {
|
||||
type Len = D::OutputSize;
|
||||
impl<D: Hash> ToBytes for Ke3Message<D>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
type Len = OutputSize<D>;
|
||||
|
||||
fn to_bytes(&self) -> GenericArray<u8, Self::Len> {
|
||||
self.mac.clone()
|
||||
|
||||
+9
-5
@@ -251,15 +251,13 @@ mod tests {
|
||||
use core::slice::from_raw_parts;
|
||||
use generic_array::typenum::Unsigned;
|
||||
use rand::rngs::OsRng;
|
||||
use std::vec;
|
||||
|
||||
#[test]
|
||||
fn test_zeroize_key() -> Result<(), ProtocolError> {
|
||||
fn inner<G: KeGroup>() -> Result<(), ProtocolError> {
|
||||
let key_len = G::PkLen::USIZE;
|
||||
let mut key = Key::<G::PkLen>(GenericArray::clone_from_slice(&alloc::vec![
|
||||
1u8;
|
||||
key_len
|
||||
]));
|
||||
let mut key = Key::<G::PkLen>(GenericArray::clone_from_slice(&vec![1u8; key_len]));
|
||||
let ptr = key.as_ptr();
|
||||
|
||||
Zeroize::zeroize(&mut key);
|
||||
@@ -308,6 +306,7 @@ mod tests {
|
||||
mod $mod {
|
||||
use super::*;
|
||||
use proptest::prelude::*;
|
||||
use std::format;
|
||||
|
||||
proptest! {
|
||||
#[test]
|
||||
@@ -428,6 +427,7 @@ mod tests {
|
||||
let ClientRegistrationFinishResult { message, .. } = client
|
||||
.finish(
|
||||
&mut OsRng,
|
||||
PASSWORD.as_bytes(),
|
||||
message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)
|
||||
@@ -452,7 +452,11 @@ mod tests {
|
||||
)
|
||||
.unwrap();
|
||||
let ClientLoginFinishResult { message, .. } = client
|
||||
.finish(message, ClientLoginFinishParameters::default())
|
||||
.finish(
|
||||
PASSWORD.as_bytes(),
|
||||
message,
|
||||
ClientLoginFinishParameters::default(),
|
||||
)
|
||||
.unwrap();
|
||||
server.finish(message).unwrap();
|
||||
}
|
||||
|
||||
+21
-12
@@ -12,7 +12,7 @@
|
||||
//!
|
||||
//! ### Minimum Supported Rust Version
|
||||
//!
|
||||
//! Rust **1.51** or higher.
|
||||
//! Rust **1.56** or higher.
|
||||
//!
|
||||
//! # Overview
|
||||
//!
|
||||
@@ -207,6 +207,7 @@
|
||||
//! # let server_registration_start_result = ServerRegistration::<Default>::start(&server_setup, client_registration_start_result.message, b"[email protected]")?;
|
||||
//! let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
//! &mut client_rng,
|
||||
//! b"password",
|
||||
//! server_registration_start_result.message,
|
||||
//! ClientRegistrationFinishParameters::default(),
|
||||
//! )?;
|
||||
@@ -253,7 +254,7 @@
|
||||
//! # let mut server_rng = OsRng;
|
||||
//! # let server_setup = ServerSetup::<Default>::new(&mut server_rng);
|
||||
//! # let server_registration_start_result = ServerRegistration::<Default>::start(&server_setup, client_registration_start_result.message, b"[email protected]")?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, b"password", server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
|
||||
//! let password_file = ServerRegistration::<Default>::finish(
|
||||
//! client_registration_finish_result.message,
|
||||
//! );
|
||||
@@ -348,7 +349,7 @@
|
||||
//! # let mut server_rng = OsRng;
|
||||
//! # let server_setup = ServerSetup::<Default>::new(&mut server_rng);
|
||||
//! # let server_registration_start_result = ServerRegistration::<Default>::start(&server_setup, client_registration_start_result.message, b"[email protected]")?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, b"password", server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
|
||||
//! # let password_file_bytes = ServerRegistration::<Default>::finish(client_registration_finish_result.message).serialize();
|
||||
//! # let client_login_start_result = ClientLogin::<Default>::start(
|
||||
//! # &mut client_rng,
|
||||
@@ -411,7 +412,7 @@
|
||||
//! # let mut server_rng = OsRng;
|
||||
//! # let server_setup = ServerSetup::<Default>::new(&mut server_rng);
|
||||
//! # let server_registration_start_result = ServerRegistration::<Default>::start(&server_setup, client_registration_start_result.message, b"[email protected]")?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, b"password", server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
|
||||
//! # let password_file_bytes = ServerRegistration::<Default>::finish(client_registration_finish_result.message).serialize();
|
||||
//! # let client_login_start_result = ClientLogin::<Default>::start(
|
||||
//! # &mut client_rng,
|
||||
@@ -424,6 +425,7 @@
|
||||
//! # let server_login_start_result =
|
||||
//! # ServerLogin::start(&mut server_rng, &server_setup, Some(password_file), client_login_start_result.message, b"[email protected]", ServerLoginStartParameters::default())?;
|
||||
//! let client_login_finish_result = client_login_start_result.state.finish(
|
||||
//! b"password",
|
||||
//! server_login_start_result.message,
|
||||
//! ClientLoginFinishParameters::default(),
|
||||
//! )?;
|
||||
@@ -466,7 +468,7 @@
|
||||
//! # let mut server_rng = OsRng;
|
||||
//! # let server_setup = ServerSetup::<Default>::new(&mut server_rng);
|
||||
//! # let server_registration_start_result = ServerRegistration::<Default>::start(&server_setup, client_registration_start_result.message, b"[email protected]")?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, b"password", server_registration_start_result.message, ClientRegistrationFinishParameters::default())?;
|
||||
//! # let password_file_bytes = ServerRegistration::<Default>::finish(client_registration_finish_result.message).serialize();
|
||||
//! # let client_login_start_result = ClientLogin::<Default>::start(
|
||||
//! # &mut client_rng,
|
||||
@@ -479,6 +481,7 @@
|
||||
//! # let server_login_start_result =
|
||||
//! # ServerLogin::start(&mut server_rng, &server_setup, Some(password_file), client_login_start_result.message, b"[email protected]", ServerLoginStartParameters::default())?;
|
||||
//! # let client_login_finish_result = client_login_start_result.state.finish(
|
||||
//! # b"password",
|
||||
//! # server_login_start_result.message,
|
||||
//! # ClientLoginFinishParameters::default(),
|
||||
//! # )?;
|
||||
@@ -555,6 +558,7 @@
|
||||
//! // a server_s_pk field
|
||||
//! let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
//! &mut client_rng,
|
||||
//! b"password",
|
||||
//! server_registration_start_result.message,
|
||||
//! ClientRegistrationFinishParameters::default(),
|
||||
//! )?;
|
||||
@@ -572,6 +576,7 @@
|
||||
//!
|
||||
//! // And then later, during login...
|
||||
//! let client_login_finish_result = client_login_start_result.state.finish(
|
||||
//! b"password",
|
||||
//! server_login_start_result.message,
|
||||
//! ClientLoginFinishParameters::default(),
|
||||
//! )?;
|
||||
@@ -641,6 +646,7 @@
|
||||
//! // During registration...
|
||||
//! let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
//! &mut client_rng,
|
||||
//! b"password",
|
||||
//! server_registration_start_result.message,
|
||||
//! ClientRegistrationFinishParameters::default()
|
||||
//! )?;
|
||||
@@ -658,6 +664,7 @@
|
||||
//!
|
||||
//! // And then later, during login...
|
||||
//! let client_login_finish_result = client_login_start_result.state.finish(
|
||||
//! b"password",
|
||||
//! server_login_start_result.message,
|
||||
//! ClientLoginFinishParameters::default(),
|
||||
//! )?;
|
||||
@@ -715,6 +722,7 @@
|
||||
//! # let server_registration_start_result = ServerRegistration::<Default>::start(&server_setup, client_registration_start_result.message, b"[email protected]")?;
|
||||
//! let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
//! &mut client_rng,
|
||||
//! b"password",
|
||||
//! server_registration_start_result.message,
|
||||
//! ClientRegistrationFinishParameters::new(
|
||||
//! Identifiers {
|
||||
@@ -761,7 +769,7 @@
|
||||
//! # let mut server_rng = OsRng;
|
||||
//! # let server_setup = ServerSetup::<Default>::new(&mut server_rng);
|
||||
//! # let server_registration_start_result = ServerRegistration::<Default>::start(&server_setup, client_registration_start_result.message, b"[email protected]")?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::new(Identifiers { client: Some(b"Alice_the_Cryptographer"), server: Some(b"Facebook") }, None))?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, b"password", server_registration_start_result.message, ClientRegistrationFinishParameters::new(Identifiers { client: Some(b"Alice_the_Cryptographer"), server: Some(b"Facebook") }, None))?;
|
||||
//! # let password_file_bytes = ServerRegistration::<Default>::finish(client_registration_finish_result.message).serialize();
|
||||
//! # let client_login_start_result = ClientLogin::<Default>::start(
|
||||
//! # &mut client_rng,
|
||||
@@ -821,7 +829,7 @@
|
||||
//! # let mut server_rng = OsRng;
|
||||
//! # let server_setup = ServerSetup::<Default>::new(&mut server_rng);
|
||||
//! # let server_registration_start_result = ServerRegistration::<Default>::start(&server_setup, client_registration_start_result.message, b"[email protected]")?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, server_registration_start_result.message, ClientRegistrationFinishParameters::new(Identifiers { client: Some(b"Alice_the_Cryptographer"), server: Some(b"Facebook") }, None))?;
|
||||
//! # let client_registration_finish_result = client_registration_start_result.state.finish(&mut client_rng, b"password", server_registration_start_result.message, ClientRegistrationFinishParameters::new(Identifiers { client: Some(b"Alice_the_Cryptographer"), server: Some(b"Facebook") }, None))?;
|
||||
//! # let password_file_bytes = ServerRegistration::<Default>::finish(client_registration_finish_result.message).serialize();
|
||||
//! # let client_login_start_result = ClientLogin::<Default>::start(
|
||||
//! # &mut client_rng,
|
||||
@@ -834,6 +842,7 @@
|
||||
//! # let server_login_start_result =
|
||||
//! # ServerLogin::start(&mut server_rng, &server_setup, Some(password_file), client_login_start_result.message, b"[email protected]", ServerLoginStartParameters { context: None, identifiers: Identifiers { client: Some(b"Alice_the_Cryptographer"), server: Some(b"Facebook") } })?;
|
||||
//! let client_login_finish_result = client_login_start_result.state.finish(
|
||||
//! b"password",
|
||||
//! server_login_start_result.message,
|
||||
//! ClientLoginFinishParameters::new(
|
||||
//! None,
|
||||
@@ -975,19 +984,18 @@
|
||||
//!
|
||||
|
||||
#![deny(unsafe_code)]
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
#![no_std]
|
||||
#![warn(clippy::cargo, missing_docs)]
|
||||
#![allow(clippy::multiple_crate_versions)]
|
||||
#![allow(clippy::multiple_crate_versions, type_alias_bounds)]
|
||||
|
||||
extern crate alloc;
|
||||
#[cfg(any(feature = "std", test))]
|
||||
extern crate std;
|
||||
|
||||
// Error types
|
||||
pub mod errors;
|
||||
|
||||
#[macro_use]
|
||||
mod impls;
|
||||
#[macro_use]
|
||||
mod serialization;
|
||||
pub mod ciphersuite;
|
||||
mod envelope;
|
||||
pub mod hash;
|
||||
@@ -995,6 +1003,7 @@ pub mod key_exchange;
|
||||
pub mod keypair;
|
||||
mod messages;
|
||||
mod opaque;
|
||||
mod serialization;
|
||||
pub mod slow_hash;
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
+94
-47
@@ -14,6 +14,7 @@ use crate::{
|
||||
utils::{check_slice_size, check_slice_size_atleast},
|
||||
ProtocolError,
|
||||
},
|
||||
hash::{OutputSize, ProxyHash},
|
||||
key_exchange::{
|
||||
group::KeGroup,
|
||||
traits::{FromBytes, Ke1MessageLen, Ke2MessageLen, Ke3MessageLen, KeyExchange, ToBytes},
|
||||
@@ -22,17 +23,17 @@ use crate::{
|
||||
keypair::{KeyPair, PublicKey, SecretKey},
|
||||
opaque::{MaskedResponse, MaskedResponseLen, ServerSetup},
|
||||
};
|
||||
use core::array::IntoIter;
|
||||
use core::ops::Add;
|
||||
use derive_where::DeriveWhere;
|
||||
use digest::{Digest, FixedOutput};
|
||||
use digest::core_api::{BlockSizeUser, CoreProxy};
|
||||
use digest::Output;
|
||||
use generic_array::sequence::Concat;
|
||||
use generic_array::{
|
||||
typenum::{Sum, Unsigned},
|
||||
typenum::{IsLess, Le, NonZero, Sum, Unsigned, U256},
|
||||
ArrayLength, GenericArray,
|
||||
};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use voprf::group::Group;
|
||||
use voprf::Group;
|
||||
|
||||
////////////////////////////
|
||||
// High-level API Structs //
|
||||
@@ -43,7 +44,12 @@ use voprf::group::Group;
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone)]
|
||||
#[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; CS::OprfGroup)]
|
||||
pub struct RegistrationRequest<CS: CipherSuite> {
|
||||
pub struct RegistrationRequest<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// blinded password information
|
||||
pub(crate) blinded_element: voprf::BlindedElement<CS::OprfGroup, CS::Hash>,
|
||||
}
|
||||
@@ -55,7 +61,12 @@ impl_serialize_and_deserialize_for!(RegistrationRequest);
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone)]
|
||||
#[derive_where(Debug, Eq, Hash, Ord, PartialEq, PartialOrd; CS::OprfGroup)]
|
||||
pub struct RegistrationResponse<CS: CipherSuite> {
|
||||
pub struct RegistrationResponse<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The server's oprf output
|
||||
pub(crate) evaluation_element: voprf::EvaluationElement<CS::OprfGroup, CS::Hash>,
|
||||
/// Server's static public key
|
||||
@@ -74,12 +85,17 @@ impl_serialize_and_deserialize_for!(
|
||||
/// identifiers
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize(drop))]
|
||||
pub struct RegistrationUpload<CS: CipherSuite> {
|
||||
pub struct RegistrationUpload<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The "envelope" generated by the user, containing sealed
|
||||
/// cryptographic identifiers
|
||||
pub(crate) envelope: Envelope<CS>,
|
||||
/// The masking key used to mask the envelope
|
||||
pub(crate) masking_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub(crate) masking_key: Output<CS::Hash>,
|
||||
/// The user's public key
|
||||
pub(crate) client_s_pk: PublicKey<CS::KeGroup>,
|
||||
}
|
||||
@@ -88,11 +104,11 @@ impl_serialize_and_deserialize_for!(
|
||||
RegistrationUpload
|
||||
where
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> | Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
);
|
||||
@@ -105,7 +121,12 @@ impl_serialize_and_deserialize_for!(
|
||||
CS::OprfGroup,
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE1Message,
|
||||
)]
|
||||
pub struct CredentialRequest<CS: CipherSuite> {
|
||||
pub struct CredentialRequest<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
pub(crate) blinded_element: voprf::BlindedElement<CS::OprfGroup, CS::Hash>,
|
||||
pub(crate) ke1_message: <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE1Message,
|
||||
}
|
||||
@@ -127,7 +148,12 @@ impl_serialize_and_deserialize_for!(
|
||||
CS::OprfGroup,
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE2Message,
|
||||
)]
|
||||
pub struct CredentialResponse<CS: CipherSuite> {
|
||||
pub struct CredentialResponse<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// the server's oprf output
|
||||
pub(crate) evaluation_element: voprf::EvaluationElement<CS::OprfGroup, CS::Hash>,
|
||||
pub(crate) masking_nonce: GenericArray<u8, NonceLen>,
|
||||
@@ -144,8 +170,8 @@ impl_serialize_and_deserialize_for!(
|
||||
ArrayLength<u8> | Add<MaskedResponseLen<CS>>,
|
||||
CredentialResponseWithoutKeLen<CS>: ArrayLength<u8>,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> | Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message
|
||||
@@ -161,7 +187,12 @@ impl_serialize_and_deserialize_for!(
|
||||
Debug, Eq, Hash, PartialEq;
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE3Message,
|
||||
)]
|
||||
pub struct CredentialFinalization<CS: CipherSuite> {
|
||||
pub struct CredentialFinalization<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
pub(crate) ke3_message: <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE3Message,
|
||||
}
|
||||
|
||||
@@ -173,10 +204,14 @@ impl_serialize_and_deserialize_for!(CredentialFinalization);
|
||||
////////////////////////////////
|
||||
|
||||
/// Length of [`RegistrationRequest`] in bytes for serialization.
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type RegistrationRequestLen<CS: CipherSuite> = <CS::OprfGroup as Group>::ElemLen;
|
||||
|
||||
impl<CS: CipherSuite> RegistrationRequest<CS> {
|
||||
impl<CS: CipherSuite> RegistrationRequest<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Only used for testing purposes
|
||||
#[cfg(test)]
|
||||
pub fn get_blinded_element_for_testing(
|
||||
@@ -199,11 +234,15 @@ impl<CS: CipherSuite> RegistrationRequest<CS> {
|
||||
}
|
||||
|
||||
/// Length of [`RegistrationResponse`] in bytes for serialization.
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type RegistrationResponseLen<CS: CipherSuite> =
|
||||
Sum<<CS::OprfGroup as Group>::ElemLen, <CS::KeGroup as KeGroup>::PkLen>;
|
||||
|
||||
impl<CS: CipherSuite> RegistrationResponse<CS> {
|
||||
impl<CS: CipherSuite> RegistrationResponse<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, RegistrationResponseLen<CS>>
|
||||
where
|
||||
@@ -247,22 +286,24 @@ impl<CS: CipherSuite> RegistrationResponse<CS> {
|
||||
}
|
||||
|
||||
/// Length of [`RegistrationUpload`] in bytes for serialization.
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type RegistrationUploadLen<CS: CipherSuite> = Sum<
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>,
|
||||
EnvelopeLen<CS>,
|
||||
>;
|
||||
pub type RegistrationUploadLen<CS: CipherSuite> =
|
||||
Sum<Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>, EnvelopeLen<CS>>;
|
||||
|
||||
impl<CS: CipherSuite> RegistrationUpload<CS> {
|
||||
impl<CS: CipherSuite> RegistrationUpload<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, RegistrationUploadLen<CS>>
|
||||
where
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
@@ -275,7 +316,7 @@ impl<CS: CipherSuite> RegistrationUpload<CS> {
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let key_len = <CS::KeGroup as KeGroup>::PkLen::USIZE;
|
||||
let hash_len = <CS::Hash as Digest>::OutputSize::USIZE;
|
||||
let hash_len = OutputSize::<CS::Hash>::USIZE;
|
||||
let checked_slice =
|
||||
check_slice_size_atleast(input, key_len + hash_len, "registration_upload_bytes")?;
|
||||
let envelope = Envelope::<CS>::deserialize(&checked_slice[key_len + hash_len..])?;
|
||||
@@ -295,7 +336,7 @@ impl<CS: CipherSuite> RegistrationUpload<CS> {
|
||||
rng: &mut R,
|
||||
server_setup: &ServerSetup<CS, S>,
|
||||
) -> Self {
|
||||
let mut masking_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut masking_key = Output::<CS::Hash>::default();
|
||||
rng.fill_bytes(&mut masking_key);
|
||||
|
||||
Self {
|
||||
@@ -307,11 +348,15 @@ impl<CS: CipherSuite> RegistrationUpload<CS> {
|
||||
}
|
||||
|
||||
/// Length of [`CredentialRequest`] in bytes for serialization.
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type CredentialRequestLen<CS: CipherSuite> =
|
||||
Sum<<CS::OprfGroup as Group>::ElemLen, Ke1MessageLen<CS>>;
|
||||
|
||||
impl<CS: CipherSuite> CredentialRequest<CS> {
|
||||
impl<CS: CipherSuite> CredentialRequest<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, CredentialRequestLen<CS>>
|
||||
where
|
||||
@@ -329,9 +374,7 @@ impl<CS: CipherSuite> CredentialRequest<CS> {
|
||||
blinded_element: &'a GenericArray<u8, <CS::OprfGroup as Group>::ElemLen>,
|
||||
ke1_message: &'a GenericArray<u8, Ke1MessageLen<CS>>,
|
||||
) -> impl Iterator<Item = &'a [u8]> {
|
||||
// MSRV: array `into_iter` isn't available in 1.51
|
||||
#[allow(deprecated)]
|
||||
IntoIter::new([blinded_element.as_slice(), ke1_message])
|
||||
[blinded_element.as_slice(), ke1_message].into_iter()
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
@@ -372,15 +415,18 @@ impl<CS: CipherSuite> CredentialRequest<CS> {
|
||||
}
|
||||
|
||||
/// Length of [`CredentialResponse`] in bytes for serialization.
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type CredentialResponseLen<CS: CipherSuite> =
|
||||
Sum<CredentialResponseWithoutKeLen<CS>, Ke2MessageLen<CS>>;
|
||||
|
||||
#[allow(type_alias_bounds)]
|
||||
pub(crate) type CredentialResponseWithoutKeLen<CS: CipherSuite> =
|
||||
Sum<Sum<<CS::OprfGroup as Group>::ElemLen, NonceLen>, MaskedResponseLen<CS>>;
|
||||
|
||||
impl<CS: CipherSuite> CredentialResponse<CS> {
|
||||
impl<CS: CipherSuite> CredentialResponse<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, CredentialResponseLen<CS>>
|
||||
where
|
||||
@@ -390,9 +436,8 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
|
||||
ArrayLength<u8> + Add<MaskedResponseLen<CS>>,
|
||||
CredentialResponseWithoutKeLen<CS>: ArrayLength<u8>,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message
|
||||
CredentialResponseWithoutKeLen<CS>: Add<Ke2MessageLen<CS>>,
|
||||
@@ -411,9 +456,7 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
|
||||
masking_nonce: &'a GenericArray<u8, NonceLen>,
|
||||
masked_response: &'a MaskedResponse<CS>,
|
||||
) -> impl Iterator<Item = &'a [u8]> {
|
||||
// MSRV: array `into_iter` isn't available in 1.51
|
||||
#[allow(deprecated)]
|
||||
IntoIter::new([beta.as_slice(), masking_nonce.as_slice()])
|
||||
[beta.as_slice(), masking_nonce.as_slice()]
|
||||
.into_iter()
|
||||
.chain(masked_response.iter())
|
||||
}
|
||||
@@ -476,10 +519,14 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
|
||||
}
|
||||
|
||||
/// Length of [`CredentialFinalization`] in bytes for serialization.
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type CredentialFinalizationLen<CS: CipherSuite> = Ke3MessageLen<CS>;
|
||||
|
||||
impl<CS: CipherSuite> CredentialFinalization<CS> {
|
||||
impl<CS: CipherSuite> CredentialFinalization<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, CredentialFinalizationLen<CS>> {
|
||||
self.ke3_message.to_bytes()
|
||||
|
||||
+290
-145
@@ -11,34 +11,33 @@ use crate::{
|
||||
ciphersuite::CipherSuite,
|
||||
envelope::{Envelope, EnvelopeLen},
|
||||
errors::{utils::check_slice_size, InternalError, ProtocolError},
|
||||
hash::Hash,
|
||||
hash::{Hash, OutputSize, ProxyHash},
|
||||
key_exchange::{
|
||||
group::KeGroup,
|
||||
traits::{FromBytes, Ke1MessageLen, Ke2StateLen, KeyExchange, ToBytes},
|
||||
traits::{FromBytes, Ke1MessageLen, Ke1StateLen, Ke2StateLen, KeyExchange, ToBytes},
|
||||
tripledh::NonceLen,
|
||||
},
|
||||
keypair::{KeyPair, PrivateKey, PublicKey, SecretKey},
|
||||
messages::{CredentialRequestLen, RegistrationUploadLen},
|
||||
serialization::{tokenize, Serialize},
|
||||
serialization::Serialize,
|
||||
slow_hash::SlowHash,
|
||||
CredentialFinalization, CredentialRequest, CredentialResponse, RegistrationRequest,
|
||||
RegistrationResponse, RegistrationUpload,
|
||||
};
|
||||
use alloc::vec::Vec;
|
||||
use core::array::IntoIter;
|
||||
use core::marker::PhantomData;
|
||||
use core::ops::Add;
|
||||
use derive_where::DeriveWhere;
|
||||
use digest::{Digest, FixedOutput};
|
||||
use digest::core_api::{BlockSizeUser, CoreProxy};
|
||||
use digest::Output;
|
||||
use generic_array::sequence::Concat;
|
||||
use generic_array::{
|
||||
typenum::{Sum, Unsigned, U2},
|
||||
typenum::{IsLess, Le, NonZero, Sum, Unsigned, U2, U256},
|
||||
ArrayLength, GenericArray,
|
||||
};
|
||||
use hkdf::{Hkdf, HkdfExtract};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use subtle::ConstantTimeEq;
|
||||
use voprf::group::Group;
|
||||
use voprf::Group;
|
||||
|
||||
///////////////
|
||||
// Constants //
|
||||
@@ -73,8 +72,12 @@ const STR_OPAQUE_DERIVE_KEY_PAIR: &[u8; 20] = b"OPAQUE-DeriveKeyPair";
|
||||
pub struct ServerSetup<
|
||||
CS: CipherSuite,
|
||||
S: SecretKey<CS::KeGroup> = PrivateKey<<CS as CipherSuite>::KeGroup>,
|
||||
> {
|
||||
oprf_seed: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
> where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
oprf_seed: Output<CS::Hash>,
|
||||
keypair: KeyPair<CS::KeGroup, S>,
|
||||
pub(crate) fake_keypair: KeyPair<CS::KeGroup>,
|
||||
}
|
||||
@@ -87,27 +90,42 @@ pub struct ServerSetup<
|
||||
voprf::NonVerifiableClient<CS::OprfGroup, CS::Hash>,
|
||||
voprf::BlindedElement<CS::OprfGroup, CS::Hash>,
|
||||
)]
|
||||
pub struct ClientRegistration<CS: CipherSuite> {
|
||||
pub struct ClientRegistration<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
pub(crate) oprf_client: voprf::NonVerifiableClient<CS::OprfGroup, CS::Hash>,
|
||||
pub(crate) blinded_element: voprf::BlindedElement<CS::OprfGroup, CS::Hash>,
|
||||
}
|
||||
|
||||
impl_serialize_and_deserialize_for!(ClientRegistration; serde_::ser::Error::custom);
|
||||
impl_serialize_and_deserialize_for!(
|
||||
ClientRegistration
|
||||
where
|
||||
// ClientRegistration: KgSk + KgPk
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<<CS::OprfGroup as Group>::ElemLen>,
|
||||
ClientRegistrationLen<CS>: ArrayLength<u8>,
|
||||
);
|
||||
|
||||
/// The state elements the server holds to record a registration
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Zeroize(drop))]
|
||||
pub struct ServerRegistration<CS: CipherSuite>(RegistrationUpload<CS>);
|
||||
pub struct ServerRegistration<CS: CipherSuite>(RegistrationUpload<CS>)
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero;
|
||||
|
||||
impl_serialize_and_deserialize_for!(
|
||||
ServerRegistration
|
||||
where
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> | Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
@@ -122,7 +140,12 @@ impl_serialize_and_deserialize_for!(
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE1State,
|
||||
CredentialRequest<CS>,
|
||||
)]
|
||||
pub struct ClientLogin<CS: CipherSuite> {
|
||||
pub struct ClientLogin<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
oprf_client: voprf::NonVerifiableClient<CS::OprfGroup, CS::Hash>,
|
||||
ke1_state: <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE1State,
|
||||
credential_request: CredentialRequest<CS>,
|
||||
@@ -133,8 +156,12 @@ impl_serialize_and_deserialize_for!(
|
||||
where
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>;
|
||||
serde_::ser::Error::custom
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
// ClientLogin: KgSk + CredentialRequest + Ke1State
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<CredentialRequestLen<CS>>,
|
||||
Sum<<CS::OprfGroup as Group>::ScalarLen, CredentialRequestLen<CS>>:
|
||||
ArrayLength<u8> | Add<Ke1StateLen<CS>>,
|
||||
ClientLoginLen<CS>: ArrayLength<u8>,
|
||||
);
|
||||
|
||||
/// The state elements the server holds to record a login
|
||||
@@ -144,7 +171,12 @@ impl_serialize_and_deserialize_for!(
|
||||
Debug, Eq, Hash, PartialEq;
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE2State,
|
||||
)]
|
||||
pub struct ServerLogin<CS: CipherSuite> {
|
||||
pub struct ServerLogin<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
ke2_state: <CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE2State,
|
||||
#[derive_where(skip(Zeroize))]
|
||||
_cs: PhantomData<CS>,
|
||||
@@ -160,7 +192,12 @@ impl_serialize_and_deserialize_for!(ServerLogin);
|
||||
// Server Setup
|
||||
// ============
|
||||
|
||||
impl<CS: CipherSuite> ServerSetup<CS, PrivateKey<CS::KeGroup>> {
|
||||
impl<CS: CipherSuite> ServerSetup<CS, PrivateKey<CS::KeGroup>>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Generate a new instance of server setup
|
||||
pub fn new<R: CryptoRng + RngCore>(rng: &mut R) -> Self {
|
||||
let keypair = KeyPair::generate_random(rng);
|
||||
@@ -169,11 +206,15 @@ impl<CS: CipherSuite> ServerSetup<CS, PrivateKey<CS::KeGroup>> {
|
||||
}
|
||||
|
||||
/// Length of [`ServerSetup`] in bytes for serialization.
|
||||
#[allow(type_alias_bounds)]
|
||||
pub type ServerSetupLen<CS: CipherSuite, S: SecretKey<CS::KeGroup>> =
|
||||
Sum<Sum<<CS::Hash as FixedOutput>::OutputSize, S::Len>, <CS::KeGroup as KeGroup>::SkLen>;
|
||||
Sum<Sum<OutputSize<CS::Hash>, S::Len>, <CS::KeGroup as KeGroup>::SkLen>;
|
||||
|
||||
impl<CS: CipherSuite, S: SecretKey<CS::KeGroup>> ServerSetup<CS, S> {
|
||||
impl<CS: CipherSuite, S: SecretKey<CS::KeGroup>> ServerSetup<CS, S>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Create [`ServerSetup`] with the given keypair
|
||||
pub fn new_with_key<R: CryptoRng + RngCore>(
|
||||
rng: &mut R,
|
||||
@@ -193,9 +234,8 @@ impl<CS: CipherSuite, S: SecretKey<CS::KeGroup>> ServerSetup<CS, S> {
|
||||
pub fn serialize(&self) -> GenericArray<u8, ServerSetupLen<CS, S>>
|
||||
where
|
||||
// ServerSetup: Hash + KeSk + KeSk
|
||||
<CS::Hash as FixedOutput>::OutputSize: Add<S::Len>,
|
||||
Sum<<CS::Hash as FixedOutput>::OutputSize, S::Len>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::SkLen>,
|
||||
OutputSize<CS::Hash>: Add<S::Len>,
|
||||
Sum<OutputSize<CS::Hash>, S::Len>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::SkLen>,
|
||||
ServerSetupLen<CS, S>: ArrayLength<u8>,
|
||||
{
|
||||
self.oprf_seed
|
||||
@@ -206,7 +246,7 @@ impl<CS: CipherSuite, S: SecretKey<CS::KeGroup>> ServerSetup<CS, S> {
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError<S::Error>> {
|
||||
let seed_len = <CS::Hash as Digest>::OutputSize::USIZE;
|
||||
let seed_len = OutputSize::<CS::Hash>::USIZE;
|
||||
let key_len = <CS::KeGroup as KeGroup>::SkLen::USIZE;
|
||||
let checked_slice = check_slice_size(input, seed_len + key_len + key_len, "server_setup")?;
|
||||
|
||||
@@ -227,39 +267,46 @@ impl<CS: CipherSuite, S: SecretKey<CS::KeGroup>> ServerSetup<CS, S> {
|
||||
// Registration
|
||||
// ============
|
||||
|
||||
impl<CS: CipherSuite> ClientRegistration<CS> {
|
||||
pub(crate) type ClientRegistrationLen<CS: CipherSuite> =
|
||||
Sum<<CS::OprfGroup as Group>::ScalarLen, <CS::OprfGroup as Group>::ElemLen>;
|
||||
|
||||
impl<CS: CipherSuite> ClientRegistration<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Result<Vec<u8>, ProtocolError> {
|
||||
Ok(chain!(
|
||||
Serialize::<U2>::from(&self.oprf_client.serialize())?.iter(),
|
||||
Serialize::<U2>::from(&self.blinded_element.serialize())?.iter(),
|
||||
)
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect())
|
||||
pub fn serialize(&self) -> GenericArray<u8, ClientRegistrationLen<CS>>
|
||||
where
|
||||
// ClientRegistration: KgSk + KgPk
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<<CS::OprfGroup as Group>::ElemLen>,
|
||||
ClientRegistrationLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
self.oprf_client
|
||||
.serialize()
|
||||
.concat(self.blinded_element.serialize())
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let (serialized_oprf_client, remainder) = tokenize(input, 2)?;
|
||||
let (serialized_blinded_element, remainder) = tokenize(remainder, 2)?;
|
||||
|
||||
if !remainder.is_empty() {
|
||||
return Err(ProtocolError::SerializationError);
|
||||
}
|
||||
let client_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
|
||||
let element_len = <CS::OprfGroup as Group>::ElemLen::USIZE;
|
||||
let checked_slice =
|
||||
check_slice_size(input, client_len + element_len, "client_registration")?;
|
||||
|
||||
Ok(Self {
|
||||
oprf_client: voprf::NonVerifiableClient::deserialize(serialized_oprf_client)?,
|
||||
blinded_element: voprf::BlindedElement::deserialize(serialized_blinded_element)?,
|
||||
oprf_client: voprf::NonVerifiableClient::deserialize(&checked_slice[..client_len])?,
|
||||
blinded_element: voprf::BlindedElement::deserialize(&checked_slice[client_len..])?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Only used for testing zeroize
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_vec(&self) -> Vec<u8> {
|
||||
pub(crate) fn to_vec(&self) -> std::vec::Vec<u8> {
|
||||
[
|
||||
self.oprf_client.serialize(),
|
||||
self.blinded_element.serialize(),
|
||||
self.oprf_client.serialize().to_vec(),
|
||||
self.blinded_element.serialize().to_vec(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
@@ -287,6 +334,7 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
|
||||
pub fn finish<R: CryptoRng + RngCore>(
|
||||
self,
|
||||
rng: &mut R,
|
||||
password: &[u8],
|
||||
registration_response: RegistrationResponse<CS>,
|
||||
params: ClientRegistrationFinishParameters<CS>,
|
||||
) -> Result<ClientRegistrationFinishResult<CS>, ProtocolError> {
|
||||
@@ -302,12 +350,13 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
|
||||
|
||||
#[cfg_attr(not(test), allow(unused_variables))]
|
||||
let (randomized_pwd, randomized_pwd_hasher) = get_password_derived_key::<CS>(
|
||||
password,
|
||||
self.oprf_client.clone(),
|
||||
registration_response.evaluation_element,
|
||||
params.slow_hash,
|
||||
)?;
|
||||
|
||||
let mut masking_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut masking_key = Output::<CS::Hash>::default();
|
||||
randomized_pwd_hasher
|
||||
.expand(STR_MASKING_KEY, &mut masking_key)
|
||||
.map_err(|_| InternalError::HkdfError)?;
|
||||
@@ -340,16 +389,21 @@ impl<CS: CipherSuite> ClientRegistration<CS> {
|
||||
/// Length of [`ServerRegistration`] in bytes for serialization.
|
||||
pub type ServerRegistrationLen<CS> = RegistrationUploadLen<CS>;
|
||||
|
||||
impl<CS: CipherSuite> ServerRegistration<CS> {
|
||||
impl<CS: CipherSuite> ServerRegistration<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, ServerRegistrationLen<CS>>
|
||||
where
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
@@ -375,7 +429,7 @@ impl<CS: CipherSuite> ServerRegistration<CS> {
|
||||
)?;
|
||||
|
||||
let server = voprf::NonVerifiableServer::new_with_key(&oprf_key)?;
|
||||
let evaluate_result = server.evaluate(message.blinded_element, None)?;
|
||||
let evaluate_result = server.evaluate(&message.blinded_element, None)?;
|
||||
|
||||
Ok(ServerRegistrationStartResult {
|
||||
message: RegistrationResponse {
|
||||
@@ -405,55 +459,64 @@ impl<CS: CipherSuite> ServerRegistration<CS> {
|
||||
// Login
|
||||
// =====
|
||||
|
||||
impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
pub(crate) type ClientLoginLen<CS: CipherSuite> =
|
||||
Sum<Sum<<CS::OprfGroup as Group>::ScalarLen, CredentialRequestLen<CS>>, Ke1StateLen<CS>>;
|
||||
|
||||
impl<CS: CipherSuite> ClientLogin<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Result<Vec<u8>, ProtocolError>
|
||||
pub fn serialize(&self) -> GenericArray<u8, ClientLoginLen<CS>>
|
||||
where
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
// ClientLogin: KgSk + CredentialRequest + Ke1State
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<CredentialRequestLen<CS>>,
|
||||
Sum<<CS::OprfGroup as Group>::ScalarLen, CredentialRequestLen<CS>>:
|
||||
ArrayLength<u8> + Add<Ke1StateLen<CS>>,
|
||||
ClientLoginLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
Ok(chain!(
|
||||
Serialize::<U2>::from(&self.oprf_client.serialize())?.iter(),
|
||||
Serialize::<U2>::from(&self.credential_request.serialize())?.iter(),
|
||||
Serialize::<U2>::from(&self.ke1_state.to_bytes())?.iter(),
|
||||
)
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect())
|
||||
self.oprf_client
|
||||
.serialize()
|
||||
.concat(self.credential_request.serialize())
|
||||
.concat(self.ke1_state.to_bytes())
|
||||
}
|
||||
|
||||
/// Deserialization from bytes
|
||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let (serialized_oprf_client, remainder) = tokenize(input, 2)?;
|
||||
let (serialized_credential_request, remainder) = tokenize(remainder, 2)?;
|
||||
let (ke1_state_bytes, remainder) = tokenize(remainder, 2)?;
|
||||
|
||||
if !remainder.is_empty() {
|
||||
return Err(ProtocolError::SerializationError);
|
||||
}
|
||||
let client_len = <CS::OprfGroup as Group>::ScalarLen::USIZE;
|
||||
let request_len = <CS::OprfGroup as Group>::ElemLen::USIZE + Ke1MessageLen::<CS>::USIZE;
|
||||
let state_len = Ke1StateLen::<CS>::USIZE;
|
||||
let checked_slice =
|
||||
check_slice_size(input, client_len + request_len + state_len, "client_login")?;
|
||||
|
||||
let ke1_state =
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE1State::from_bytes(
|
||||
ke1_state_bytes,
|
||||
&checked_slice[client_len + request_len..],
|
||||
)?;
|
||||
Ok(Self {
|
||||
oprf_client: voprf::NonVerifiableClient::deserialize(serialized_oprf_client)?,
|
||||
oprf_client: voprf::NonVerifiableClient::deserialize(&checked_slice[..client_len])?,
|
||||
credential_request: CredentialRequest::deserialize(
|
||||
&checked_slice[client_len..client_len + request_len],
|
||||
)?,
|
||||
ke1_state,
|
||||
credential_request: CredentialRequest::deserialize(serialized_credential_request)?,
|
||||
})
|
||||
}
|
||||
|
||||
/// Only used for testing zeroize
|
||||
#[cfg(test)]
|
||||
pub(crate) fn to_vec(&self) -> Vec<u8>
|
||||
pub(crate) fn to_vec(&self) -> std::vec::Vec<u8>
|
||||
where
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
[
|
||||
self.oprf_client.serialize(),
|
||||
self.oprf_client.serialize().to_vec(),
|
||||
self.credential_request.serialize().to_vec(),
|
||||
self.ke1_state.to_bytes().to_vec(),
|
||||
]
|
||||
@@ -461,7 +524,12 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
impl<CS: CipherSuite> ClientLogin<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Returns an initial "blinded" password request to send to the server, as well as a ClientLogin
|
||||
pub fn start<R: RngCore + CryptoRng>(
|
||||
rng: &mut R,
|
||||
@@ -489,14 +557,14 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
/// the server
|
||||
pub fn finish(
|
||||
self,
|
||||
password: &[u8],
|
||||
credential_response: CredentialResponse<CS>,
|
||||
params: ClientLoginFinishParameters<CS>,
|
||||
) -> Result<ClientLoginFinishResult<CS>, ProtocolError>
|
||||
where
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
// Check if beta value from server is equal to alpha value from client
|
||||
@@ -511,12 +579,13 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
}
|
||||
|
||||
let (_, randomized_pwd_hasher) = get_password_derived_key::<CS>(
|
||||
password,
|
||||
self.oprf_client.clone(),
|
||||
credential_response.evaluation_element.clone(),
|
||||
params.slow_hash,
|
||||
)?;
|
||||
|
||||
let mut masking_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut masking_key = Output::<CS::Hash>::default();
|
||||
randomized_pwd_hasher
|
||||
.expand(STR_MASKING_KEY, &mut masking_key)
|
||||
.map_err(|_| InternalError::HkdfError)?;
|
||||
@@ -585,7 +654,12 @@ impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> ServerLogin<CS> {
|
||||
impl<CS: CipherSuite> ServerLogin<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> GenericArray<u8, Ke2StateLen<CS>> {
|
||||
self.ke2_state.to_bytes()
|
||||
@@ -617,9 +691,8 @@ impl<CS: CipherSuite> ServerLogin<CS> {
|
||||
) -> Result<ServerLoginStartResult<CS>, ProtocolError<S::Error>>
|
||||
where
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let record = match password_file {
|
||||
@@ -669,7 +742,7 @@ impl<CS: CipherSuite> ServerLogin<CS> {
|
||||
let server = voprf::NonVerifiableServer::new_with_key(&oprf_key)
|
||||
.map_err(|e| ProtocolError::into_custom(e.into()))?;
|
||||
let evaluate_result = server
|
||||
.evaluate(credential_request.blinded_element, None)
|
||||
.evaluate(&credential_request.blinded_element, None)
|
||||
.map_err(|e| ProtocolError::into_custom(e.into()))?;
|
||||
let evaluation_element = evaluate_result.message;
|
||||
|
||||
@@ -748,14 +821,24 @@ pub struct Identifiers<'a> {
|
||||
/// Optional parameters for client registration finish
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone, Default)]
|
||||
pub struct ClientRegistrationFinishParameters<'i, 'h, CS: CipherSuite> {
|
||||
pub struct ClientRegistrationFinishParameters<'i, 'h, CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Specifying the identifiers idU and idS
|
||||
pub identifiers: Identifiers<'i>,
|
||||
/// Specifying a configuration for the slow hash
|
||||
pub slow_hash: Option<&'h CS::SlowHash>,
|
||||
}
|
||||
|
||||
impl<'i, 'h, CS: CipherSuite> ClientRegistrationFinishParameters<'i, 'h, CS> {
|
||||
impl<'i, 'h, CS: CipherSuite> ClientRegistrationFinishParameters<'i, 'h, CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash 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 {
|
||||
Self {
|
||||
@@ -768,7 +851,12 @@ impl<'i, 'h, CS: CipherSuite> ClientRegistrationFinishParameters<'i, 'h, CS> {
|
||||
/// Contains the fields that are returned by a client registration start
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone)]
|
||||
pub struct ClientRegistrationStartResult<CS: CipherSuite> {
|
||||
pub struct ClientRegistrationStartResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The registration request message to be sent to the server
|
||||
pub message: RegistrationRequest<CS>,
|
||||
/// The client state that must be persisted in order to complete registration
|
||||
@@ -778,11 +866,16 @@ pub struct ClientRegistrationStartResult<CS: CipherSuite> {
|
||||
/// Contains the fields that are returned by a client registration finish
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone)]
|
||||
pub struct ClientRegistrationFinishResult<CS: CipherSuite> {
|
||||
pub struct ClientRegistrationFinishResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The registration upload message to be sent to the server
|
||||
pub message: RegistrationUpload<CS>,
|
||||
/// The export key output by client registration
|
||||
pub export_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub export_key: Output<CS::Hash>,
|
||||
/// The server's static public key
|
||||
pub server_s_pk: PublicKey<CS::KeGroup>,
|
||||
/// Instance of the ClientRegistration, only used in tests for checking zeroize
|
||||
@@ -790,17 +883,22 @@ pub struct ClientRegistrationFinishResult<CS: CipherSuite> {
|
||||
pub state: ClientRegistration<CS>,
|
||||
/// AuthKey, only used in tests
|
||||
#[cfg(test)]
|
||||
pub auth_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub auth_key: Output<CS::Hash>,
|
||||
/// Password derived key, only used in tests
|
||||
#[cfg(test)]
|
||||
pub randomized_pwd: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub randomized_pwd: Output<CS::Hash>,
|
||||
}
|
||||
|
||||
/// 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<CS: CipherSuite> {
|
||||
pub struct ServerRegistrationStartResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The registration resposne message to send to the client
|
||||
pub message: RegistrationResponse<CS>,
|
||||
/// OPRF key, only used in tests
|
||||
@@ -811,7 +909,12 @@ pub struct ServerRegistrationStartResult<CS: CipherSuite> {
|
||||
/// Contains the fields that are returned by a client login start
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone)]
|
||||
pub struct ClientLoginStartResult<CS: CipherSuite> {
|
||||
pub struct ClientLoginStartResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The message to send to the server to begin the login protocol
|
||||
pub message: CredentialRequest<CS>,
|
||||
/// The state that the client must keep in order to complete the protocol
|
||||
@@ -821,7 +924,12 @@ pub struct ClientLoginStartResult<CS: CipherSuite> {
|
||||
/// Optional parameters for client login finish
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone, Default)]
|
||||
pub struct ClientLoginFinishParameters<'c, 'i, 'h, CS: CipherSuite> {
|
||||
pub struct ClientLoginFinishParameters<'c, 'i, 'h, CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Specifying a context field that the server must agree on
|
||||
pub context: Option<&'c [u8]>,
|
||||
/// Specifying a user identifier and server identifier that will be matched against the server
|
||||
@@ -830,7 +938,12 @@ pub struct ClientLoginFinishParameters<'c, 'i, 'h, CS: CipherSuite> {
|
||||
pub slow_hash: Option<&'h CS::SlowHash>,
|
||||
}
|
||||
|
||||
impl<'c, 'i, 'h, CS: CipherSuite> ClientLoginFinishParameters<'c, 'i, 'h, CS> {
|
||||
impl<'c, 'i, 'h, CS: CipherSuite> ClientLoginFinishParameters<'c, 'i, 'h, CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Create a new [`ClientLoginFinishParameters`]
|
||||
pub fn new(
|
||||
context: Option<&'c [u8]>,
|
||||
@@ -848,13 +961,18 @@ impl<'c, 'i, 'h, CS: CipherSuite> ClientLoginFinishParameters<'c, 'i, 'h, CS> {
|
||||
/// Contains the fields that are returned by a client login finish
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone)]
|
||||
pub struct ClientLoginFinishResult<CS: CipherSuite> {
|
||||
pub struct ClientLoginFinishResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The message to send to the server to complete the protocol
|
||||
pub message: CredentialFinalization<CS>,
|
||||
/// The session key
|
||||
pub session_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub session_key: Output<CS::Hash>,
|
||||
/// The client-side export key
|
||||
pub export_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub export_key: Output<CS::Hash>,
|
||||
/// The server's static public key
|
||||
pub server_s_pk: PublicKey<CS::KeGroup>,
|
||||
/// Instance of the ClientLogin, only used in tests for checking zeroize
|
||||
@@ -862,10 +980,10 @@ pub struct ClientLoginFinishResult<CS: CipherSuite> {
|
||||
pub state: ClientLogin<CS>,
|
||||
/// Handshake secret, only used in tests
|
||||
#[cfg(test)]
|
||||
pub handshake_secret: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub handshake_secret: Output<CS::Hash>,
|
||||
/// Client MAC key, only used in tests
|
||||
#[cfg(test)]
|
||||
pub client_mac_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub client_mac_key: Output<CS::Hash>,
|
||||
}
|
||||
|
||||
/// Contains the fields that are returned by a server login finish
|
||||
@@ -873,9 +991,14 @@ pub struct ClientLoginFinishResult<CS: CipherSuite> {
|
||||
#[derive_where(Clone)]
|
||||
#[cfg_attr(not(test), derive_where(Debug))]
|
||||
#[cfg_attr(test, derive_where(Debug; ServerLogin<CS>))]
|
||||
pub struct ServerLoginFinishResult<CS: CipherSuite> {
|
||||
pub struct ServerLoginFinishResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The session key between client and server
|
||||
pub session_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub session_key: Output<CS::Hash>,
|
||||
_cs: PhantomData<CS>,
|
||||
/// Instance of the ClientRegistration, only used in tests for checking zeroize
|
||||
#[cfg(test)]
|
||||
@@ -900,17 +1023,22 @@ pub struct ServerLoginStartParameters<'c, 'i> {
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE2Message,
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::KeGroup>>::KE2State,
|
||||
)]
|
||||
pub struct ServerLoginStartResult<CS: CipherSuite> {
|
||||
pub struct ServerLoginStartResult<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// The message to send back to the client
|
||||
pub message: CredentialResponse<CS>,
|
||||
/// The state that the server must keep in order to finish the protocl
|
||||
pub state: ServerLogin<CS>,
|
||||
/// Handshake secret, only used in tests
|
||||
#[cfg(test)]
|
||||
pub handshake_secret: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub handshake_secret: Output<CS::Hash>,
|
||||
/// Server MAC key, only used in tests
|
||||
#[cfg(test)]
|
||||
pub server_mac_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
pub server_mac_key: Output<CS::Hash>,
|
||||
/// OPRF key, only used in tests
|
||||
#[cfg(test)]
|
||||
pub oprf_key: GenericArray<u8, <CS::OprfGroup as Group>::ScalarLen>,
|
||||
@@ -922,20 +1050,19 @@ pub struct ServerLoginStartResult<CS: CipherSuite> {
|
||||
////////////////////////////////////////////////
|
||||
|
||||
// Helper functions
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn get_password_derived_key<CS: CipherSuite>(
|
||||
input: &[u8],
|
||||
oprf_client: voprf::NonVerifiableClient<CS::OprfGroup, CS::Hash>,
|
||||
evaluation_element: voprf::EvaluationElement<CS::OprfGroup, CS::Hash>,
|
||||
slow_hash: Option<&CS::SlowHash>,
|
||||
) -> Result<
|
||||
(
|
||||
GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
Hkdf<CS::Hash>,
|
||||
),
|
||||
ProtocolError,
|
||||
> {
|
||||
let oprf_output = oprf_client.finalize(evaluation_element, None)?;
|
||||
) -> Result<(Output<CS::Hash>, Hkdf<CS::Hash>), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let oprf_output = oprf_client.finalize(input, &evaluation_element, None)?;
|
||||
|
||||
let hardened_output = if let Some(slow_hash) = slow_hash {
|
||||
slow_hash.hash(oprf_output.clone())
|
||||
@@ -951,9 +1078,14 @@ fn get_password_derived_key<CS: CipherSuite>(
|
||||
}
|
||||
|
||||
fn oprf_key_from_seed<G: Group, D: Hash>(
|
||||
oprf_seed: &GenericArray<u8, D::OutputSize>,
|
||||
oprf_seed: &Output<D>,
|
||||
credential_identifier: &[u8],
|
||||
) -> Result<GenericArray<u8, G::ScalarLen>, ProtocolError> {
|
||||
) -> Result<GenericArray<u8, G::ScalarLen>, ProtocolError>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut ikm = GenericArray::<_, G::ScalarLen>::default();
|
||||
Hkdf::<D>::from_prk(oprf_seed)
|
||||
.ok()
|
||||
@@ -963,7 +1095,7 @@ fn oprf_key_from_seed<G: Group, D: Hash>(
|
||||
})
|
||||
.ok_or(InternalError::HkdfError)?;
|
||||
Ok(G::scalar_as_bytes(G::hash_to_scalar::<D, _, _>(
|
||||
Some(ikm.as_slice()),
|
||||
[ikm.as_slice()],
|
||||
GenericArray::from(*STR_OPAQUE_DERIVE_KEY_PAIR),
|
||||
)?))
|
||||
}
|
||||
@@ -971,23 +1103,31 @@ fn oprf_key_from_seed<G: Group, D: Hash>(
|
||||
#[derive(DeriveWhere)]
|
||||
#[derive_where(Clone)]
|
||||
#[derive_where(Debug, Eq, Hash, PartialEq)]
|
||||
pub(crate) struct MaskedResponse<CS: CipherSuite> {
|
||||
pub(crate) struct MaskedResponse<CS: CipherSuite>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
pub(crate) nonce: GenericArray<u8, NonceLen>,
|
||||
pub(crate) hash: GenericArray<u8, <CS::Hash as FixedOutput>::OutputSize>,
|
||||
pub(crate) hash: Output<CS::Hash>,
|
||||
pub(crate) pk: GenericArray<u8, <CS::KeGroup as KeGroup>::PkLen>,
|
||||
}
|
||||
|
||||
#[allow(type_alias_bounds)]
|
||||
pub(crate) type MaskedResponseLen<CS: CipherSuite> =
|
||||
Sum<Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>, <CS::KeGroup as KeGroup>::PkLen>;
|
||||
Sum<Sum<NonceLen, OutputSize<CS::Hash>>, <CS::KeGroup as KeGroup>::PkLen>;
|
||||
|
||||
impl<CS: CipherSuite> MaskedResponse<CS> {
|
||||
impl<CS: CipherSuite> MaskedResponse<CS>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
pub(crate) fn serialize(&self) -> GenericArray<u8, MaskedResponseLen<CS>>
|
||||
where
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
self.nonce.concat(self.hash.clone()).concat(self.pk.clone())
|
||||
@@ -995,7 +1135,7 @@ impl<CS: CipherSuite> MaskedResponse<CS> {
|
||||
|
||||
pub(crate) fn deserialize(bytes: &[u8]) -> Self {
|
||||
let nonce = NonceLen::USIZE;
|
||||
let hash = nonce + <CS::Hash as FixedOutput>::OutputSize::USIZE;
|
||||
let hash = nonce + OutputSize::<CS::Hash>::USIZE;
|
||||
let pk = hash + <CS::KeGroup as KeGroup>::PkLen::USIZE;
|
||||
|
||||
Self {
|
||||
@@ -1006,9 +1146,7 @@ impl<CS: CipherSuite> MaskedResponse<CS> {
|
||||
}
|
||||
|
||||
pub(crate) fn iter(&self) -> impl Iterator<Item = &[u8]> {
|
||||
// MSRV: array `into_iter` isn't available in 1.51
|
||||
#[allow(deprecated)]
|
||||
IntoIter::new([self.nonce.as_slice(), &self.hash, &self.pk])
|
||||
[self.nonce.as_slice(), &self.hash, &self.pk].into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1019,10 +1157,13 @@ fn mask_response<CS: CipherSuite>(
|
||||
envelope: &Envelope<CS>,
|
||||
) -> Result<MaskedResponse<CS>, ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let mut xor_pad = GenericArray::<_, MaskedResponseLen<CS>>::default();
|
||||
@@ -1051,10 +1192,12 @@ fn unmask_response<CS: CipherSuite>(
|
||||
masked_response: &MaskedResponse<CS>,
|
||||
) -> Result<(PublicKey<CS::KeGroup>, Envelope<CS>), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let mut xor_pad = GenericArray::<_, MaskedResponseLen<CS>>::default();
|
||||
@@ -1086,12 +1229,12 @@ pub(crate) fn bytestrings_from_identifiers<KG: KeGroup>(
|
||||
server_s_pk: GenericArray<u8, KG::PkLen>,
|
||||
) -> Result<(Serialize<U2, KG::PkLen>, Serialize<U2, KG::PkLen>), ProtocolError> {
|
||||
let client_identity = if let Some(client) = ids.client {
|
||||
Serialize::<U2, KG::PkLen>::from(client)?
|
||||
Serialize::<U2, _>::from(client)?
|
||||
} else {
|
||||
Serialize::<U2, _>::from_owned(client_s_pk)?
|
||||
};
|
||||
let server_identity = if let Some(server) = ids.server {
|
||||
Serialize::<U2, KG::PkLen>::from(server)?
|
||||
Serialize::<U2, _>::from(server)?
|
||||
} else {
|
||||
Serialize::<U2, _>::from_owned(server_s_pk)?
|
||||
};
|
||||
@@ -1106,12 +1249,14 @@ pub(crate) fn bytestrings_from_identifiers<KG: KeGroup>(
|
||||
fn blind<CS: CipherSuite, R: RngCore + CryptoRng>(
|
||||
rng: &mut R,
|
||||
password: &[u8],
|
||||
) -> Result<
|
||||
voprf::NonVerifiableClientBlindResult<CS::OprfGroup, CS::Hash>,
|
||||
voprf::errors::InternalError,
|
||||
> {
|
||||
) -> Result<voprf::NonVerifiableClientBlindResult<CS::OprfGroup, CS::Hash>, voprf::Error>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
#[cfg(not(test))]
|
||||
let result = voprf::NonVerifiableClient::blind(password.to_vec(), rng)?;
|
||||
let result = voprf::NonVerifiableClient::blind(password, rng)?;
|
||||
|
||||
#[cfg(test)]
|
||||
let result = {
|
||||
@@ -1127,7 +1272,7 @@ fn blind<CS: CipherSuite, R: RngCore + CryptoRng>(
|
||||
true => (),
|
||||
}
|
||||
};
|
||||
voprf::NonVerifiableClient::deterministic_blind_unchecked(password.to_vec(), blind)?
|
||||
voprf::NonVerifiableClient::deterministic_blind_unchecked(password, blind)?
|
||||
};
|
||||
|
||||
Ok(result)
|
||||
|
||||
+10
-43
@@ -20,23 +20,19 @@ pub(crate) fn i2osp<L: ArrayLength<u8>>(
|
||||
) -> Result<GenericArray<u8, L>, ProtocolError> {
|
||||
const SIZEOF_USIZE: usize = core::mem::size_of::<usize>();
|
||||
|
||||
// Check if input >= 256^length
|
||||
// Make sure input fits in output.
|
||||
if (SIZEOF_USIZE as u32 - input.leading_zeros() / 8) > L::U32 {
|
||||
return Err(ProtocolError::SerializationError);
|
||||
}
|
||||
|
||||
if L::USIZE <= SIZEOF_USIZE {
|
||||
return Ok(GenericArray::clone_from_slice(
|
||||
&input.to_be_bytes()[SIZEOF_USIZE - L::USIZE..],
|
||||
));
|
||||
}
|
||||
|
||||
let mut output = GenericArray::default();
|
||||
output[L::USIZE - SIZEOF_USIZE..L::USIZE].copy_from_slice(&input.to_be_bytes());
|
||||
output[L::USIZE.saturating_sub(SIZEOF_USIZE)..]
|
||||
.copy_from_slice(&input.to_be_bytes()[SIZEOF_USIZE.saturating_sub(L::USIZE)..]);
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
// Corresponds to the OS2IP() function from RFC8017
|
||||
#[cfg(test)]
|
||||
pub(crate) fn os2ip(input: &[u8]) -> Result<usize, ProtocolError> {
|
||||
if input.len() > core::mem::size_of::<usize>() {
|
||||
return Err(ProtocolError::SerializationError);
|
||||
@@ -96,17 +92,17 @@ impl<'a, L1: ArrayLength<u8>, L2: ArrayLength<u8>, L3: ArrayLength<u8>> Serializ
|
||||
|
||||
pub(crate) fn iter(&self) -> impl Iterator<Item = &[u8]> {
|
||||
// Some magic to make it output the same type in all branches.
|
||||
Some(self.octet.as_slice())
|
||||
[self.octet.as_slice()]
|
||||
.into_iter()
|
||||
.chain(match &self.input {
|
||||
Input::Owned(bytes) => Some(bytes.as_slice()),
|
||||
Input::Borrowed(bytes) => Some(*bytes),
|
||||
Input::Label(_) => None,
|
||||
Input::Owned(bytes) => [bytes.as_slice()],
|
||||
Input::Borrowed(bytes) => [*bytes],
|
||||
Input::Label((iter, _)) => [iter[0]],
|
||||
})
|
||||
.chain(if let Input::Label((iter, _)) = &self.input {
|
||||
Some(iter[0]).into_iter().chain(Some(iter[1]).into_iter())
|
||||
Some(iter[1])
|
||||
} else {
|
||||
None.into_iter().chain(None)
|
||||
None
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -132,24 +128,6 @@ impl<'a, L1: ArrayLength<u8>, L2: ArrayLength<u8>> Serialize<'a, L1, L2, U2> {
|
||||
}
|
||||
}
|
||||
|
||||
// Tokenizes an input of the format I2OSP(len(input), max_bytes) || input, outputting
|
||||
// (input, remainder)
|
||||
pub(crate) fn tokenize(input: &[u8], size_bytes: usize) -> Result<(&[u8], &[u8]), ProtocolError> {
|
||||
if size_bytes > core::mem::size_of::<usize>() || input.len() < size_bytes {
|
||||
return Err(ProtocolError::SerializationError);
|
||||
}
|
||||
|
||||
let size = os2ip(&input[..size_bytes])?;
|
||||
if size_bytes + size > input.len() {
|
||||
return Err(ProtocolError::SerializationError);
|
||||
}
|
||||
|
||||
Ok((
|
||||
&input[size_bytes..size_bytes + size],
|
||||
&input[size_bytes + size..],
|
||||
))
|
||||
}
|
||||
|
||||
pub(crate) trait UpdateExt {
|
||||
fn chain_iter<'a>(self, iter: impl Iterator<Item = &'a [u8]>) -> Self;
|
||||
}
|
||||
@@ -178,17 +156,6 @@ impl<T: Mac> MacExt for T {
|
||||
}
|
||||
}
|
||||
|
||||
/// The purpose of this macro is to simplify [`concat`](alloc::slice::Concat::concat)ing
|
||||
/// slices into an [`Iterator`] to avoid allocation
|
||||
macro_rules! chain {
|
||||
(
|
||||
$item1:expr,
|
||||
$($item2:expr),+$(,)?
|
||||
) => {
|
||||
$item1$(.chain($item2))+
|
||||
};
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
|
||||
+120
-63
@@ -9,9 +9,10 @@ use crate::{
|
||||
ciphersuite::CipherSuite,
|
||||
envelope::{Envelope, EnvelopeLen, InnerEnvelopeMode},
|
||||
errors::*,
|
||||
hash::{OutputSize, ProxyHash},
|
||||
key_exchange::{
|
||||
group::KeGroup,
|
||||
traits::{Ke1MessageLen, Ke2MessageLen},
|
||||
traits::{Ke1MessageLen, Ke1StateLen, Ke2MessageLen},
|
||||
},
|
||||
key_exchange::{
|
||||
traits::{FromBytes, KeyExchange, ToBytes},
|
||||
@@ -19,26 +20,23 @@ use crate::{
|
||||
},
|
||||
keypair::KeyPair,
|
||||
messages::CredentialResponseWithoutKeLen,
|
||||
opaque::MaskedResponseLen,
|
||||
serialization::{i2osp, os2ip, Serialize},
|
||||
opaque::{ClientLoginLen, ClientRegistrationLen, MaskedResponseLen},
|
||||
serialization::{i2osp, os2ip},
|
||||
*,
|
||||
};
|
||||
#[cfg(test)]
|
||||
use alloc::vec;
|
||||
#[cfg(test)]
|
||||
use alloc::vec::Vec;
|
||||
use core::ops::Add;
|
||||
use std::vec;
|
||||
use std::vec::Vec;
|
||||
|
||||
use digest::FixedOutput;
|
||||
use digest::core_api::{BlockSizeUser, CoreProxy};
|
||||
use digest::Output;
|
||||
use generic_array::{
|
||||
typenum::{Sum, Unsigned, U2},
|
||||
ArrayLength, GenericArray,
|
||||
typenum::{IsLess, Le, NonZero, Sum, Unsigned, U256},
|
||||
ArrayLength,
|
||||
};
|
||||
use proptest::{collection::vec, prelude::*};
|
||||
use rand::{rngs::OsRng, RngCore};
|
||||
use voprf::group::Group;
|
||||
|
||||
use sha2::Digest;
|
||||
use voprf::Group;
|
||||
|
||||
#[cfg(feature = "ristretto255")]
|
||||
struct Ristretto255;
|
||||
@@ -62,7 +60,12 @@ impl CipherSuite for P256 {
|
||||
type SlowHash = crate::slow_hash::NoOpHash;
|
||||
}
|
||||
|
||||
fn random_point<CS: CipherSuite>() -> CS::KeGroup {
|
||||
fn random_point<CS: CipherSuite>() -> CS::KeGroup
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut rng = OsRng;
|
||||
let sk = CS::KeGroup::random_sk(&mut rng);
|
||||
CS::KeGroup::public_key(&sk)
|
||||
@@ -70,24 +73,32 @@ fn random_point<CS: CipherSuite>() -> CS::KeGroup {
|
||||
|
||||
#[test]
|
||||
fn client_registration_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// ClientRegistration: KgSk + KgPk
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<<CS::OprfGroup as Group>::ElemLen>,
|
||||
ClientRegistrationLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let pw = b"hunter2";
|
||||
let mut rng = OsRng;
|
||||
|
||||
let blind_result =
|
||||
&voprf::NonVerifiableClient::<CS::OprfGroup, CS::Hash>::blind(pw.to_vec(), &mut rng)?;
|
||||
&voprf::NonVerifiableClient::<CS::OprfGroup, CS::Hash>::blind(pw, &mut rng)?;
|
||||
|
||||
let bytes: Vec<u8> = chain!(
|
||||
Serialize::<U2>::from(&blind_result.state.serialize())?.iter(),
|
||||
Serialize::<U2>::from(&blind_result.message.serialize())?.iter(),
|
||||
)
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect();
|
||||
let bytes: Vec<u8> = blind_result
|
||||
.state
|
||||
.serialize()
|
||||
.iter()
|
||||
.chain(blind_result.message.serialize().iter())
|
||||
.cloned()
|
||||
.collect();
|
||||
|
||||
let reg = ClientRegistration::<CS>::deserialize(&bytes)?;
|
||||
let reg_bytes = reg.serialize()?;
|
||||
assert_eq!(reg_bytes, bytes);
|
||||
let reg_bytes = reg.serialize();
|
||||
assert_eq!(*reg_bytes, bytes);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -103,12 +114,15 @@ fn client_registration_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn server_registration_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
@@ -116,15 +130,14 @@ fn server_registration_roundtrip() -> Result<(), ProtocolError> {
|
||||
// If we don't have envelope and client_pk, the server registration just
|
||||
// contains the prf key
|
||||
let mut rng = OsRng;
|
||||
let mut masking_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut masking_key = Output::<CS::Hash>::default();
|
||||
rng.fill_bytes(&mut masking_key);
|
||||
|
||||
// Construct a mock envelope
|
||||
let mut mock_envelope_bytes = Vec::new();
|
||||
mock_envelope_bytes.extend_from_slice(&[0; NonceLen::USIZE]); // empty nonce
|
||||
// mock_envelope_bytes.extend_from_slice(&ciphertext); // ciphertext which is an encrypted private key
|
||||
mock_envelope_bytes
|
||||
.extend_from_slice(&GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default()); // length-MAC_SIZE hmac
|
||||
mock_envelope_bytes.extend_from_slice(&Output::<CS::Hash>::default()); // length-MAC_SIZE hmac
|
||||
|
||||
let mock_client_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
|
||||
// serialization order: oprf_key, public key, envelope
|
||||
@@ -148,7 +161,12 @@ fn server_registration_roundtrip() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn registration_request_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let pt = random_point::<CS>();
|
||||
let pt_bytes = pt.to_arr().to_vec();
|
||||
|
||||
@@ -166,7 +184,7 @@ fn registration_request_roundtrip() -> Result<(), ProtocolError> {
|
||||
assert!(matches!(
|
||||
RegistrationRequest::<CS>::deserialize(&identity_bytes),
|
||||
Err(ProtocolError::LibraryError(InternalError::OprfError(
|
||||
voprf::errors::InternalError::PointError,
|
||||
voprf::Error::PointError,
|
||||
)))
|
||||
));
|
||||
|
||||
@@ -185,6 +203,9 @@ fn registration_request_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn registration_response_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// RegistrationResponse: KgPk + KePk
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
RegistrationResponseLen<CS>: ArrayLength<u8>,
|
||||
@@ -212,7 +233,7 @@ fn registration_response_roundtrip() -> Result<(), ProtocolError> {
|
||||
&[identity_bytes, pubkey_bytes.to_vec()].concat()
|
||||
),
|
||||
Err(ProtocolError::LibraryError(InternalError::OprfError(
|
||||
voprf::errors::InternalError::PointError,
|
||||
voprf::Error::PointError,
|
||||
)))
|
||||
));
|
||||
|
||||
@@ -231,12 +252,15 @@ fn registration_response_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn registration_upload_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
@@ -249,7 +273,7 @@ fn registration_upload_roundtrip() -> Result<(), ProtocolError> {
|
||||
let mut nonce = [0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut nonce);
|
||||
|
||||
let mut masking_key = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut masking_key = Output::<CS::Hash>::default();
|
||||
rng.fill_bytes(&mut masking_key);
|
||||
|
||||
let randomized_pwd_hasher = hkdf::Hkdf::new(None, &key);
|
||||
@@ -257,7 +281,7 @@ fn registration_upload_roundtrip() -> Result<(), ProtocolError> {
|
||||
let (envelope, _, _) = Envelope::<CS>::seal_raw(
|
||||
randomized_pwd_hasher,
|
||||
nonce.into(),
|
||||
Some(pubkey_bytes.as_slice()).into_iter(),
|
||||
[pubkey_bytes.as_slice()].into_iter(),
|
||||
InnerEnvelopeMode::Internal,
|
||||
)
|
||||
.unwrap();
|
||||
@@ -287,6 +311,9 @@ fn registration_upload_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn credential_request_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
@@ -316,7 +343,7 @@ fn credential_request_roundtrip() -> Result<(), ProtocolError> {
|
||||
assert!(matches!(
|
||||
CredentialRequest::<CS>::deserialize(&[identity_bytes, ke1m.to_vec()].concat()),
|
||||
Err(ProtocolError::LibraryError(InternalError::OprfError(
|
||||
voprf::errors::InternalError::PointError,
|
||||
voprf::Error::PointError,
|
||||
)))
|
||||
));
|
||||
|
||||
@@ -335,15 +362,17 @@ fn credential_request_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn credential_response_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<NonceLen>,
|
||||
Sum<<CS::OprfGroup as Group>::ElemLen, NonceLen>:
|
||||
ArrayLength<u8> + Add<MaskedResponseLen<CS>>,
|
||||
CredentialResponseWithoutKeLen<CS>: ArrayLength<u8>,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message
|
||||
CredentialResponseWithoutKeLen<CS>: Add<Ke2MessageLen<CS>>,
|
||||
@@ -362,7 +391,7 @@ fn credential_response_roundtrip() -> Result<(), ProtocolError> {
|
||||
rng.fill_bytes(&mut masked_response);
|
||||
|
||||
let server_e_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
|
||||
let mut mac = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut mac = Output::<CS::Hash>::default();
|
||||
rng.fill_bytes(&mut mac);
|
||||
let mut server_nonce = [0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut server_nonce);
|
||||
@@ -394,7 +423,7 @@ fn credential_response_roundtrip() -> Result<(), ProtocolError> {
|
||||
.concat()
|
||||
),
|
||||
Err(ProtocolError::LibraryError(InternalError::OprfError(
|
||||
voprf::errors::InternalError::PointError,
|
||||
voprf::Error::PointError,
|
||||
)))
|
||||
));
|
||||
|
||||
@@ -411,9 +440,14 @@ fn credential_response_roundtrip() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn credential_finalization_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut rng = OsRng;
|
||||
let mut mac = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut mac = Output::<CS::Hash>::default();
|
||||
rng.fill_bytes(&mut mac);
|
||||
|
||||
let input = mac;
|
||||
@@ -437,9 +471,17 @@ fn credential_finalization_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn client_login_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
// ClientLogin: KgSk + CredentialRequest + Ke1State
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<CredentialRequestLen<CS>>,
|
||||
Sum<<CS::OprfGroup as Group>::ScalarLen, CredentialRequestLen<CS>>:
|
||||
ArrayLength<u8> + Add<Ke1StateLen<CS>>,
|
||||
ClientLoginLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let pw = b"hunter2";
|
||||
let mut rng = OsRng;
|
||||
@@ -455,7 +497,7 @@ fn client_login_roundtrip() -> Result<(), ProtocolError> {
|
||||
.concat();
|
||||
|
||||
let blind_result =
|
||||
voprf::NonVerifiableClient::<CS::OprfGroup, CS::Hash>::blind(pw.to_vec(), &mut rng)?;
|
||||
voprf::NonVerifiableClient::<CS::OprfGroup, CS::Hash>::blind(pw, &mut rng)?;
|
||||
|
||||
let credential_request = CredentialRequest::<CS> {
|
||||
blinded_element: blind_result.message,
|
||||
@@ -465,17 +507,17 @@ fn client_login_roundtrip() -> Result<(), ProtocolError> {
|
||||
)?,
|
||||
};
|
||||
|
||||
let bytes: Vec<u8> = chain!(
|
||||
Serialize::<U2>::from(&blind_result.state.serialize())?.iter(),
|
||||
Serialize::<U2>::from(&credential_request.serialize())?.iter(),
|
||||
Serialize::<U2>::from(&l1_data)?.iter(),
|
||||
)
|
||||
.flatten()
|
||||
.cloned()
|
||||
.collect();
|
||||
let bytes: Vec<u8> = blind_result
|
||||
.state
|
||||
.serialize()
|
||||
.iter()
|
||||
.chain(credential_request.serialize().iter())
|
||||
.chain(l1_data.iter())
|
||||
.cloned()
|
||||
.collect();
|
||||
let reg = ClientLogin::<CS>::deserialize(&bytes)?;
|
||||
let reg_bytes = reg.serialize()?;
|
||||
assert_eq!(reg_bytes, bytes);
|
||||
let reg_bytes = reg.serialize();
|
||||
assert_eq!(*reg_bytes, bytes);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -489,7 +531,12 @@ fn client_login_roundtrip() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn ke1_message_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut rng = OsRng;
|
||||
|
||||
let client_e_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
|
||||
@@ -515,11 +562,16 @@ fn ke1_message_roundtrip() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn ke2_message_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut rng = OsRng;
|
||||
|
||||
let server_e_kp = KeyPair::<CS::KeGroup>::generate_random(&mut rng);
|
||||
let mut mac = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut mac = Output::<CS::Hash>::default();
|
||||
rng.fill_bytes(&mut mac);
|
||||
let mut server_nonce = vec![0u8; NonceLen::USIZE];
|
||||
rng.fill_bytes(&mut server_nonce);
|
||||
@@ -544,9 +596,14 @@ fn ke2_message_roundtrip() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn ke3_message_roundtrip() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut rng = OsRng;
|
||||
let mut mac = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut mac = Output::<CS::Hash>::default();
|
||||
rng.fill_bytes(&mut mac);
|
||||
|
||||
let ke3m: Vec<u8> = [mac].concat();
|
||||
|
||||
+29
-19
@@ -7,39 +7,49 @@
|
||||
|
||||
//! Trait specifying a slow hashing function
|
||||
|
||||
use crate::{errors::InternalError, hash::Hash};
|
||||
use digest::Digest;
|
||||
use generic_array::GenericArray;
|
||||
use crate::{
|
||||
errors::InternalError,
|
||||
hash::{Hash, ProxyHash},
|
||||
};
|
||||
use digest::core_api::BlockSizeUser;
|
||||
use digest::Output;
|
||||
use generic_array::typenum::{IsLess, Le, NonZero, U256};
|
||||
|
||||
/// Used for the slow hashing function in OPAQUE
|
||||
pub trait SlowHash<D: Hash>: Default {
|
||||
pub trait SlowHash<D: Hash>: Default
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
/// Computes the slow hashing function
|
||||
fn hash(
|
||||
&self,
|
||||
input: GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
) -> Result<GenericArray<u8, <D as Digest>::OutputSize>, InternalError>;
|
||||
fn hash(&self, input: Output<D>) -> Result<Output<D>, InternalError>;
|
||||
}
|
||||
|
||||
/// A no-op hash which simply returns its input
|
||||
#[derive(Default)]
|
||||
pub struct NoOpHash;
|
||||
|
||||
impl<D: Hash> SlowHash<D> for NoOpHash {
|
||||
fn hash(
|
||||
&self,
|
||||
input: GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
) -> Result<GenericArray<u8, <D as Digest>::OutputSize>, InternalError> {
|
||||
impl<D: Hash> SlowHash<D> for NoOpHash
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
fn hash(&self, input: Output<D>) -> Result<Output<D>, InternalError> {
|
||||
Ok(input)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "slow-hash")]
|
||||
impl<D: Hash> SlowHash<D> for argon2::Argon2<'_> {
|
||||
fn hash(
|
||||
&self,
|
||||
input: GenericArray<u8, <D as Digest>::OutputSize>,
|
||||
) -> Result<GenericArray<u8, <D as Digest>::OutputSize>, InternalError> {
|
||||
let mut output = GenericArray::default();
|
||||
impl<D: Hash> SlowHash<D> for argon2::Argon2<'_>
|
||||
where
|
||||
D::Core: ProxyHash,
|
||||
<D::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<D::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
fn hash(&self, input: Output<D>) -> Result<Output<D>, InternalError> {
|
||||
let mut output = Output::<D>::default();
|
||||
self.hash_password_into(&input, &[0; argon2::MIN_SALT_LEN], &mut output)
|
||||
.map_err(|_| InternalError::SlowHashError)?;
|
||||
Ok(output)
|
||||
|
||||
+271
-172
@@ -11,9 +11,10 @@ use crate::{
|
||||
ciphersuite::CipherSuite,
|
||||
envelope::EnvelopeLen,
|
||||
errors::*,
|
||||
hash::{OutputSize, ProxyHash},
|
||||
key_exchange::{
|
||||
group::KeGroup,
|
||||
traits::{Ke1MessageLen, Ke2MessageLen},
|
||||
traits::{Ke1MessageLen, Ke1StateLen, Ke2MessageLen},
|
||||
tripledh::{NonceLen, TripleDH},
|
||||
},
|
||||
messages::{
|
||||
@@ -25,16 +26,18 @@ use crate::{
|
||||
tests::mock_rng::CycleRng,
|
||||
*,
|
||||
};
|
||||
use alloc::string::ToString;
|
||||
use alloc::vec::Vec;
|
||||
use core::ops::Add;
|
||||
use digest::{Digest, FixedOutput};
|
||||
use generic_array::typenum::{Sum, Unsigned};
|
||||
use generic_array::{ArrayLength, GenericArray};
|
||||
use digest::core_api::{BlockSizeUser, CoreProxy};
|
||||
use digest::Output;
|
||||
use generic_array::typenum::{IsLess, Le, NonZero, Sum, Unsigned, U256};
|
||||
use generic_array::ArrayLength;
|
||||
use rand::rngs::OsRng;
|
||||
use serde_json::Value;
|
||||
use std::string::{String, ToString};
|
||||
use std::vec::Vec;
|
||||
use std::{format, println, vec};
|
||||
use subtle::ConstantTimeEq;
|
||||
use voprf::group::Group;
|
||||
use voprf::Group;
|
||||
use zeroize::Zeroize;
|
||||
|
||||
// Tests
|
||||
@@ -126,152 +129,152 @@ static STR_CREDENTIAL_IDENTIFIER: &str = "credential_identifier";
|
||||
#[cfg(feature = "ristretto255")]
|
||||
static TEST_VECTOR_RISTRETTO255: &str = r#"
|
||||
{
|
||||
"client_s_pk": "181bbea01a5e444390c4b335f8bcb9a846a1c60042669ce6d731af4587960c06",
|
||||
"client_s_sk": "2f21529b9fb27c8c12770b765dc36750c4a51c5ccaf2f83d0182504a85a22c0b",
|
||||
"client_e_pk": "58a16b672e100b18069d0716715a9a8d9a643954bb24c0887e46d542eab9e417",
|
||||
"client_e_sk": "c1a4db9d650ce1700e05fbd472d30c13e0a4c6926b114e7ca11e2e9f397c5005",
|
||||
"server_s_pk": "dc8c66b6dcf4731836a0cdb336985c77a6321ffb75db6bb1aef20974c141dd3c",
|
||||
"server_s_sk": "410ef173f972994eeabb2cb39fd5db907e39a1abd6b36c9f514ab903d9d16305",
|
||||
"server_e_pk": "68630597c4593cb8158f398ab6ff956a1d87232be4300be1f96a6860663d9461",
|
||||
"server_e_sk": "155452c6b08b889b31d5a810925136adfb2d363eee4ccaed0ef15b594fb88b04",
|
||||
"fake_sk": "b009e67b83c418f0ae271b8790d6c5e06ea3874fa5a9e66752b5ebdbec953b04",
|
||||
"client_s_pk": "8cc7c9eb1d0f5803fd02f13ffc91175bd2a4ea0395913c7d6414431a05dda94c",
|
||||
"client_s_sk": "b30044efeb2c90127e35389c2d025dccbe90c03c102ea38388e362320c6e570f",
|
||||
"client_e_pk": "5ac74ef87ac50c960c56fdcd46daf12ef7d88739c8654937e7a4d8996d60ed22",
|
||||
"client_e_sk": "1d78d5ffe9b3ad5bb467da13232805cbbdff0473ed47da7738f7a05d2f35c603",
|
||||
"server_s_pk": "34dacc7158463c3d29aa780baab28624b1c71df0468e134bde085cdc8f4e941b",
|
||||
"server_s_sk": "966ee3f6f3ece48d37ca5394f113dad2fc3afe2923fc20f769a185de1bea9905",
|
||||
"server_e_pk": "387e1dff8d671ac91665bb0268478ec518d2db28d0cf71041696e65c14c04562",
|
||||
"server_e_sk": "5f7bed95ef1efd306e3144f30381593a85adb98e632552b0e87644d46cbcc002",
|
||||
"fake_sk": "a85ac8f4eee6bb688c3ae7d7b6d995da2038645ba34ceadf8467e56d175bc008",
|
||||
"credential_identifier": "637265644964656e746966696572",
|
||||
"id_u": "696455",
|
||||
"id_s": "696453",
|
||||
"password": "70617373776f7264",
|
||||
"blinding_factor": "544ce97b02dff0201282a44cf73171a62a76e2a113d40dce8950f31bf4339403",
|
||||
"oprf_seed": "f929fa161a065bec163bea6dbab6d6eccd960666951fc7fd3da7cf2b6baf20a2763598aba89a4e5bcaa57096c66cfded26d683e07ab1a3b37a7c82706dfaee81",
|
||||
"masking_nonce": "4c0099b7067c7c243ed804def0fd490babd577abcd7b05a1f24a05d2d1cc344e079a75936ed36b89a3056661a2dc981a6628edde6a86da2714cce71659d84f8d",
|
||||
"envelope_nonce": "9888ba54ffc1e1be5deb23a2efa5432f318f9a17d681d1273e909ca3bf1b2fea",
|
||||
"client_nonce": "652a39daf155cc9b5a005b67951f19c2ccdf4667cf7bcd39f941a87565ed4c29",
|
||||
"server_nonce": "5e2f19069ea9791d6b346b676d8d8aaf45536148ca0357a595f330c7aed107d2",
|
||||
"blinding_factor": "ae7bd2be7bcbeafcf4c26f92e4ab37b174c93126cdb0b6321a511c92f3cecb0f",
|
||||
"oprf_seed": "4f31cd5f5ddbc39da5d354b0d5bdae1c0f57aa549aaca4eba8138156c387473ed050329b97631d9fca895c60afb1855e30f2426043cd2dd242707bf664082c87",
|
||||
"masking_nonce": "97a321a4a2946fcacbae9d80d78ac1c06d9f7e39e426b367be57398957938bbc5a18264ee75b6976b2abc8fccc702010196cb1c90fbfcab60363acc3d503c968",
|
||||
"envelope_nonce": "4745c52d41faa7c697d3fb3374c087966b8e44da7519e0f7c561a0ee0f3a6180",
|
||||
"client_nonce": "781fbdffc567af01253fb0d53839842a7255fd36371dde1b05979691c0bca067",
|
||||
"server_nonce": "1f5fc6d4f55c092245bdb150c2db4189ad8fca9c8df5218a0876cb11c8114a39",
|
||||
"context": "636f6e74657874",
|
||||
"registration_request": "f05048bb39f3f5a3a414f50254c425b36f842162a630bf73456df453351cb33d",
|
||||
"registration_response": "2c6f5ba3de9af2719529e9a993097e8c0ecd5110a24471414e4225950189cc46dc8c66b6dcf4731836a0cdb336985c77a6321ffb75db6bb1aef20974c141dd3c",
|
||||
"registration_upload": "08a51d9973140af4f911f235d4910e9536503157bfaffefaeaa11f69d723cc54d35d9ae50d6a0a7ab38614e571a81821cfbfec36ed9fd46e397e173252d02ff623287035e190153e9fb88509da1c225765bb200ed59249cbfd6201656d1672db2f21529b9fb27c8c12770b765dc36750c4a51c5ccaf2f83d0182504a85a22c0b19e07582aea6c5e782b15ff18f6188203f54ea62dfb1efb77d641f030b86062c9f0d1bc3c39b7f824fe81df456c702ea4fa084eba803fea7e5a80d2284c2ff15",
|
||||
"credential_request": "f05048bb39f3f5a3a414f50254c425b36f842162a630bf73456df453351cb33d652a39daf155cc9b5a005b67951f19c2ccdf4667cf7bcd39f941a87565ed4c2958a16b672e100b18069d0716715a9a8d9a643954bb24c0887e46d542eab9e417",
|
||||
"credential_response": "2c6f5ba3de9af2719529e9a993097e8c0ecd5110a24471414e4225950189cc464c0099b7067c7c243ed804def0fd490babd577abcd7b05a1f24a05d2d1cc344e4100aea1aa461bed485d0e441c275d0d04388e1b6b739379cd9ebabe6a53ca025375487ea73cc17ea884fb3fd91d05a8970628459ab7996e9e20aacdc613a669a687c95479814b866c43cde2ca225f43a44035ba921b5986877589013acd8eba3f4e00bd4c5e83756651c5faa0319487e4b80bcedfef82b9e46c3cace5b4aa8e155452c6b08b889b31d5a810925136adfb2d363eee4ccaed0ef15b594fb88b04605c82fb3bb14125d8274619e5ceef90151b6309610aa35c2c0a004337c44b50162d27726ed40aca064e88cff1413d7098f81b16567919ca8d9c425b8b3445684e2ad7e7d8d14475c2ca1ace56a5949199fb836f9f343d46994098955bb9f129",
|
||||
"credential_finalization": "e13284ada3e78eed48047934115ce7e6c2cdff0c3012e9ba2d423759c4000ddf11ecd186dd7f0740ee3413ff0d253e2437eced56f3717e45c071b170d12db1dd",
|
||||
"client_registration_state": "0028544ce97b02dff0201282a44cf73171a62a76e2a113d40dce8950f31bf433940370617373776f72640020f05048bb39f3f5a3a414f50254c425b36f842162a630bf73456df453351cb33d",
|
||||
"client_login_state": "0028544ce97b02dff0201282a44cf73171a62a76e2a113d40dce8950f31bf433940370617373776f72640060f05048bb39f3f5a3a414f50254c425b36f842162a630bf73456df453351cb33d652a39daf155cc9b5a005b67951f19c2ccdf4667cf7bcd39f941a87565ed4c2958a16b672e100b18069d0716715a9a8d9a643954bb24c0887e46d542eab9e4170040c1a4db9d650ce1700e05fbd472d30c13e0a4c6926b114e7ca11e2e9f397c5005652a39daf155cc9b5a005b67951f19c2ccdf4667cf7bcd39f941a87565ed4c29",
|
||||
"server_login_state": "2a009e5881454a2b42fb8c039762f78828c5b4ba7008d2e57b16ffdc937ee846b56461f9cda751b2a1c2b03793d72d5ca8c482adf8009880779323e64e12eb1d4c0cf45ec665be918cb9d655f9eca974494f0f4c0f6e714c6ddcca37b547c122cf7419984e123fa4c7981212e5171b01bfd6f8ac88e7964c8da4a88b5df4f2c85da5318465cef76fbddd389ff36be66c693cfc6feecbcf43bf16a22c97de8430e824b2812449934d13fb666b24de78a007f1fc06064304b0abfae3fc5caba7f6",
|
||||
"password_file": "08a51d9973140af4f911f235d4910e9536503157bfaffefaeaa11f69d723cc54d35d9ae50d6a0a7ab38614e571a81821cfbfec36ed9fd46e397e173252d02ff623287035e190153e9fb88509da1c225765bb200ed59249cbfd6201656d1672db2f21529b9fb27c8c12770b765dc36750c4a51c5ccaf2f83d0182504a85a22c0b19e07582aea6c5e782b15ff18f6188203f54ea62dfb1efb77d641f030b86062c9f0d1bc3c39b7f824fe81df456c702ea4fa084eba803fea7e5a80d2284c2ff15",
|
||||
"export_key": "ea8d1f871a3c8ad5d2a7a2d647e020105a33f8b8534055c56ab4bae2b8467d22806968159f918d9c31098602790fcad3e5969f1d8ff0b90b48c26b4132877ed4",
|
||||
"session_key": "5da5318465cef76fbddd389ff36be66c693cfc6feecbcf43bf16a22c97de8430e824b2812449934d13fb666b24de78a007f1fc06064304b0abfae3fc5caba7f6"
|
||||
"registration_request": "083b7dfada0e53c78f9d32ddcb88ec50144cf361fd202d73581eeeb944113715",
|
||||
"registration_response": "760fdf28216493a9a9b9f268c33d7a22f059f16ab6f3b9559f3165874453414834dacc7158463c3d29aa780baab28624b1c71df0468e134bde085cdc8f4e941b",
|
||||
"registration_upload": "5c60129a5003992493977306a309188b373fb806a9f0668279ca21806081cc7d21a180fba338aa1477038a9b41623dc5feb69445f9f48e342a63eb7a45b6522fa4f1555d1729fcb15fb2d1e761c7583c0b5ce704c032e3804aa3c2ca16e6bd26b30044efeb2c90127e35389c2d025dccbe90c03c102ea38388e362320c6e570f4992b64df766073034f49e77eddf22f6a6418408cc29a11357871e9c41663ee71958443f36fa81c3ff2d487dcfcdd28695e2f0dfbb84201e968a8f9111a68a28",
|
||||
"credential_request": "083b7dfada0e53c78f9d32ddcb88ec50144cf361fd202d73581eeeb944113715781fbdffc567af01253fb0d53839842a7255fd36371dde1b05979691c0bca0675ac74ef87ac50c960c56fdcd46daf12ef7d88739c8654937e7a4d8996d60ed22",
|
||||
"credential_response": "760fdf28216493a9a9b9f268c33d7a22f059f16ab6f3b9559f3165874453414897a321a4a2946fcacbae9d80d78ac1c06d9f7e39e426b367be57398957938bbcb095ee31bf57672fab06716b53c69cbfefc2907064a8fbf284cd02adda3add3c43706e059634ea372ecb2718103ca2fc83a7b060194a804dc2b4339ee5d5d228d38d21e16c61424bbc3ff8fd599e5f1e928935983ee3b0226a1beeb182777a0c0053859554b5bde0f9f52f5a8c82831e866891cfa1907f2906b55d0432f0c30b5f7bed95ef1efd306e3144f30381593a85adb98e632552b0e87644d46cbcc002d023f69a86ba2b2ec3d6e75350f2ac1f780a899e6eb658a41dd773c440dc2b4a4f4281f8a049d3ed483db43274d30e89220e693e4027259ab1b037ff543935d973772ca255fc128d114c338100c49a86906c8deed99fd49a9c481beeb689154d",
|
||||
"credential_finalization": "90861a832ee7aa11c865d37c011443fb0bc66852484d41f7ee712ceb4a61a580b368c08b7a3d1b133f63a54db5368b47e28e59740697336d9855da3b72d26e83",
|
||||
"client_registration_state": "ae7bd2be7bcbeafcf4c26f92e4ab37b174c93126cdb0b6321a511c92f3cecb0f083b7dfada0e53c78f9d32ddcb88ec50144cf361fd202d73581eeeb944113715",
|
||||
"client_login_state": "ae7bd2be7bcbeafcf4c26f92e4ab37b174c93126cdb0b6321a511c92f3cecb0f083b7dfada0e53c78f9d32ddcb88ec50144cf361fd202d73581eeeb944113715781fbdffc567af01253fb0d53839842a7255fd36371dde1b05979691c0bca0675ac74ef87ac50c960c56fdcd46daf12ef7d88739c8654937e7a4d8996d60ed221d78d5ffe9b3ad5bb467da13232805cbbdff0473ed47da7738f7a05d2f35c603781fbdffc567af01253fb0d53839842a7255fd36371dde1b05979691c0bca067",
|
||||
"server_login_state": "877f235cde56f884c971e137dbfec8dc6fbb00656cbf6e20d032f6fba598ed0ad6ff7fc2d52b76e57eb72037c6976491ee045472b35204513b909cafc3ac5e3bac4fab5f4dce3c8de85481d899ee644fd8af2c30b8756746ef97bdfb82d9a081bad64d83fa726404f7af042b49ba79049e6ed825e40180ac08407ff18d44f11d828933d78f17e6360881ec80e8696507892dd1072958b8e1566ea2a68b0ed227593a19f2c5266d5c456338d7142126543bfb38bfe7209e84778eda944774832b",
|
||||
"password_file": "5c60129a5003992493977306a309188b373fb806a9f0668279ca21806081cc7d21a180fba338aa1477038a9b41623dc5feb69445f9f48e342a63eb7a45b6522fa4f1555d1729fcb15fb2d1e761c7583c0b5ce704c032e3804aa3c2ca16e6bd26b30044efeb2c90127e35389c2d025dccbe90c03c102ea38388e362320c6e570f4992b64df766073034f49e77eddf22f6a6418408cc29a11357871e9c41663ee71958443f36fa81c3ff2d487dcfcdd28695e2f0dfbb84201e968a8f9111a68a28",
|
||||
"export_key": "c37b2ce98f5822c578236405dba3b17d42e3ae452ec2bb667442bbfc39774827bfeff20ec0c98c4b2d131880425455f0e12cd09b5112dc6e8609eb3be07bb396",
|
||||
"session_key": "828933d78f17e6360881ec80e8696507892dd1072958b8e1566ea2a68b0ed227593a19f2c5266d5c456338d7142126543bfb38bfe7209e84778eda944774832b"
|
||||
}
|
||||
"#;
|
||||
|
||||
#[cfg(feature = "p256")]
|
||||
static TEST_VECTOR_P256: &str = r#"
|
||||
{
|
||||
"client_s_pk": "022bb70342affe88f4f3c5d5fc4991bfc1f4758651d59d50c25815ffc4d13eeae3",
|
||||
"client_s_sk": "ee7beaaed8110b155efac3af2bb97a7a45262fa5702de4721c90ebcfb098b596",
|
||||
"client_e_pk": "02faf2a785a7de0d59c240b235ab7559820f682a7930fb546ecabddee2de091043",
|
||||
"client_e_sk": "755577ce43627c5201af2bd35bc17bb7a4c9945acbadbb08962a0236a860ce80",
|
||||
"server_s_pk": "025e6c524abf252eadf812d3ef46dd7afbeb2f65d76269d1a1288fb0be82b378cb",
|
||||
"server_s_sk": "5f044f77db085dd5ebeb0ffbe69166057c586719f5ff277a4488b3202c720258",
|
||||
"server_e_pk": "039e7fc9dcf8e9f50405d228a70c1d9bf5eb283b7e156774125b876819d0349630",
|
||||
"server_e_sk": "5158264e39bd1234ab785701b47d697b07db92eb4f5dc0f206607edf69f66476",
|
||||
"fake_sk": "402eaf9bf6d4b1501a2eae8ebb76d4970060decd43944c4bd601602c23a23093",
|
||||
"client_s_pk": "02ec5dd688a3aa66022860d4bfed2dcb01a5da07a0b4ff0c84d9f8749bd478c293",
|
||||
"client_s_sk": "4982f91037e2e498ea3b7fe8f72c35d00a9b952c8ce4fb0563a49071d599390c",
|
||||
"client_e_pk": "027f8c859ded40011655cd5314f5dc3b42ed95c11da3ad181a70d911fadb818415",
|
||||
"client_e_sk": "efeb2242f4068b651e29917611a295033e8369ee14c1091678f0327383997289",
|
||||
"server_s_pk": "0231a120b62158db8b182afba15361f32870c17d09675fb2b751fab99a55b7f29b",
|
||||
"server_s_sk": "04a0d9eae979c3e0a7be44d723fdabafd4a2c2bd0d2bef4d1134a61358e1d3d6",
|
||||
"server_e_pk": "022ef1078479c8d69e08d94d682aca2c63a293193ef8d45d0508cc13d64d5dc3b4",
|
||||
"server_e_sk": "304ada96918e021ec1595981ac41711853bd7a271bf3aa6c01e57ebdd18b50ed",
|
||||
"fake_sk": "668017c4eb69093ca24e877fb258df8de386a136af9a08fb5c3c52c52267a03c",
|
||||
"credential_identifier": "637265644964656e746966696572",
|
||||
"id_u": "696455",
|
||||
"id_s": "696453",
|
||||
"password": "70617373776f7264",
|
||||
"blinding_factor": "a383673cc3fc95652d0fd6fdfaaff8c2db97c0cb55706499a7e719a28f93ba49",
|
||||
"oprf_seed": "84618864bc307f9c178cb5c156865094c8f3737e6ea4e46dc965ddbd4b2332f2",
|
||||
"masking_nonce": "ec5bb47a34e050136fb97a513ddf182ccc498ffb7d70d94954cc013db934c2716f35c5a1adb5c220194bbb1e8159bbfbcabeb7d94215476bdf29e5dad3919b2c",
|
||||
"envelope_nonce": "a9a9de9d77fae996ffa597928b12c83ff44e56b2e7d4f79dd561132800d63a2c",
|
||||
"client_nonce": "51710b892007ef555ffd08452d9f9078165c2e7fd3695ad8020d74a8c20bb8b1",
|
||||
"server_nonce": "68f4bc84db8af9940f41e8e91a5d39800e1eacdecd124918d24dc5eb8d5ed840",
|
||||
"blinding_factor": "7c4a996eaac89d9cea984623277a142b52b63c6546ef426227922dec19d00a87",
|
||||
"oprf_seed": "cdeef0e45c5c592bcc00d9ac8f094d43463165f886c4102f5a293ef8aa319de8",
|
||||
"masking_nonce": "1d8e692fc6911170cfa00dbe665fa0d5db76a672245d111432b2fe35733d04f86b3d1ba79b08430b7fcad140a0d3067bcb2dd90fb3c3376cfc50660477454ae4",
|
||||
"envelope_nonce": "18774499e68269ff9cc98e6b74438d00378b11886e93b34dfe61fb0912be6faa",
|
||||
"client_nonce": "4a66273ed0c375274d59eb5d29f2f579c282dce9853401c9c7bdefe4018ed016",
|
||||
"server_nonce": "e11586209869eb4ac351ebc8c1e348a7f7bdd4cccf747b8ccd6b7028a57a1692",
|
||||
"context": "636f6e74657874",
|
||||
"registration_request": "0397d002bed42dfd7a104348c29e82c0bab8a5871846d8c6159e511d3c681fc2be",
|
||||
"registration_response": "0357c5ca3794429f3111026c79925ffa597c7e518ac787ed49fe152d083d07c846025e6c524abf252eadf812d3ef46dd7afbeb2f65d76269d1a1288fb0be82b378cb",
|
||||
"registration_upload": "03dd5bbddab150cf7cd793d6702741e529ee13ab4ce4cfad731dd77fc13c2310e5d82ca5e29fa03deff3ed1d8eb1353389b02a78bd48fa256915314dac55cf5e74ee7beaaed8110b155efac3af2bb97a7a45262fa5702de4721c90ebcfb098b5964788cdaf2a92a5a161a819c2aa84985f5a8ea6fbedf01c87ddaa8be23fc16721",
|
||||
"credential_request": "0397d002bed42dfd7a104348c29e82c0bab8a5871846d8c6159e511d3c681fc2be51710b892007ef555ffd08452d9f9078165c2e7fd3695ad8020d74a8c20bb8b102faf2a785a7de0d59c240b235ab7559820f682a7930fb546ecabddee2de091043",
|
||||
"credential_response": "0357c5ca3794429f3111026c79925ffa597c7e518ac787ed49fe152d083d07c846ec5bb47a34e050136fb97a513ddf182ccc498ffb7d70d94954cc013db934c27117a3467e180aa4144edd4122e53e2f9fe4d1c1363796e5820d92489e94c5fcabda33f5e886cfee0da967b28cc2a06674cf5d050125ac1136a44284520fcde7f7de6af0ab5f26f57d682c5d389298d5ebd38e7ca7f8bf5456ed0ac9f9ac6f4b7cbe5158264e39bd1234ab785701b47d697b07db92eb4f5dc0f206607edf69f66476039cb032462240ab63f406935a398ef593655ed0617147a952a249ca81bfda7d4ad872b9829967987a74514454b1ee3776debcae819c526ac33f838a81edb234b3",
|
||||
"credential_finalization": "35395199a2e317c5f08f55f67f9f5565d1d0c856572876b1b4e447925a36eb60",
|
||||
"client_registration_state": "0028a383673cc3fc95652d0fd6fdfaaff8c2db97c0cb55706499a7e719a28f93ba4970617373776f726400210397d002bed42dfd7a104348c29e82c0bab8a5871846d8c6159e511d3c681fc2be",
|
||||
"client_login_state": "0028a383673cc3fc95652d0fd6fdfaaff8c2db97c0cb55706499a7e719a28f93ba4970617373776f726400620397d002bed42dfd7a104348c29e82c0bab8a5871846d8c6159e511d3c681fc2be51710b892007ef555ffd08452d9f9078165c2e7fd3695ad8020d74a8c20bb8b102faf2a785a7de0d59c240b235ab7559820f682a7930fb546ecabddee2de0910430040755577ce43627c5201af2bd35bc17bb7a4c9945acbadbb08962a0236a860ce8051710b892007ef555ffd08452d9f9078165c2e7fd3695ad8020d74a8c20bb8b1",
|
||||
"server_login_state": "5c2ec839d40694328ed6133cc12b8da7ec4300589849eb193eb673d35e4645c8bce86cbd880012967dae7c0f1ac2a90a4d6ea9f3ee5c521c77a20600de4528ee89699ffdb9e8ba62442184bd4a696c6c5832801a425446869aefa2544260d618",
|
||||
"password_file": "03dd5bbddab150cf7cd793d6702741e529ee13ab4ce4cfad731dd77fc13c2310e5d82ca5e29fa03deff3ed1d8eb1353389b02a78bd48fa256915314dac55cf5e74ee7beaaed8110b155efac3af2bb97a7a45262fa5702de4721c90ebcfb098b5964788cdaf2a92a5a161a819c2aa84985f5a8ea6fbedf01c87ddaa8be23fc16721",
|
||||
"export_key": "35a93c215dc618dc3acbacc08d16e4879bf2054349facf2a33bc061dee57d787",
|
||||
"session_key": "89699ffdb9e8ba62442184bd4a696c6c5832801a425446869aefa2544260d618"
|
||||
"registration_request": "0240132c056e840d76432376499866bc24cbcc421352f97876e3db730eaf93c9a3",
|
||||
"registration_response": "02aaf5d179cbd839043f1a5bb0b9d548240f83ba04fdf20bde2c4eb6c8cbd9af190231a120b62158db8b182afba15361f32870c17d09675fb2b751fab99a55b7f29b",
|
||||
"registration_upload": "02d4231d770ef9ae965843a1675ad74199326c45903ba01740fb78802b3c513a94dadfe6d48822c9afb0180a8c153d05ec8165f12a65c5a4cdc4dd3319d1771d014982f91037e2e498ea3b7fe8f72c35d00a9b952c8ce4fb0563a49071d599390c13dd1bc302ed8244f467ae4efeffed774664d64a23e3be0526ca1a97bd0e184d",
|
||||
"credential_request": "0240132c056e840d76432376499866bc24cbcc421352f97876e3db730eaf93c9a34a66273ed0c375274d59eb5d29f2f579c282dce9853401c9c7bdefe4018ed016027f8c859ded40011655cd5314f5dc3b42ed95c11da3ad181a70d911fadb818415",
|
||||
"credential_response": "02aaf5d179cbd839043f1a5bb0b9d548240f83ba04fdf20bde2c4eb6c8cbd9af191d8e692fc6911170cfa00dbe665fa0d5db76a672245d111432b2fe35733d04f82b04c06b790ba4255130b98aff3a2f1fd6a0527cd9c8013b21eaf416292ce31f7f0cc1265563c461b5b201321c9aff0e33ebcbb3c378d44abe339070ee98d9c4273424602fe6defccedf46622f024f9d43569cb168ffde5f83ce2627e4b3033502304ada96918e021ec1595981ac41711853bd7a271bf3aa6c01e57ebdd18b50ed03a2fc14b586b9875732238ef1c8964ca168781c3002a0dd1b301aa692525cb86023db579c0d130a7272e9e43f0ae71cc585146f0c547f4d903b0e85fb5c855dc0",
|
||||
"credential_finalization": "d721a8860a39f2f0b454a1721c3edef13bd9d2d1dc850624b4375e9824ab04ce",
|
||||
"client_registration_state": "7c4a996eaac89d9cea984623277a142b52b63c6546ef426227922dec19d00a870240132c056e840d76432376499866bc24cbcc421352f97876e3db730eaf93c9a3",
|
||||
"client_login_state": "7c4a996eaac89d9cea984623277a142b52b63c6546ef426227922dec19d00a870240132c056e840d76432376499866bc24cbcc421352f97876e3db730eaf93c9a34a66273ed0c375274d59eb5d29f2f579c282dce9853401c9c7bdefe4018ed016027f8c859ded40011655cd5314f5dc3b42ed95c11da3ad181a70d911fadb818415efeb2242f4068b651e29917611a295033e8369ee14c1091678f03273839972894a66273ed0c375274d59eb5d29f2f579c282dce9853401c9c7bdefe4018ed016",
|
||||
"server_login_state": "b652d371e96e1b4afc79137d6f6fbdb7c98a254f2547f3fab2423ea2213a188c2884cb33441cb38a5d0d63e3d914de117781df0573022dd326766effb07e3cce5b812234056fefc56980a25a8d0a2614cd638594fae2b25cd17b456f2046c724",
|
||||
"password_file": "02d4231d770ef9ae965843a1675ad74199326c45903ba01740fb78802b3c513a94dadfe6d48822c9afb0180a8c153d05ec8165f12a65c5a4cdc4dd3319d1771d014982f91037e2e498ea3b7fe8f72c35d00a9b952c8ce4fb0563a49071d599390c13dd1bc302ed8244f467ae4efeffed774664d64a23e3be0526ca1a97bd0e184d",
|
||||
"export_key": "bcb1ed54d1baebf8c0ee5542623b1867cd3f9257a67fac4a456af55a9fd9e02a",
|
||||
"session_key": "5b812234056fefc56980a25a8d0a2614cd638594fae2b25cd17b456f2046c724"
|
||||
}
|
||||
"#;
|
||||
|
||||
#[cfg(all(feature = "x25519", feature = "ristretto255"))]
|
||||
static TEST_VECTOR_X25519_RISTRETTO255: &str = r#"
|
||||
{
|
||||
"client_s_pk": "9b1f31c4e1a456d140ea5ae0f683c13785b4ecf473019aca643461afa09ccf1b",
|
||||
"client_s_sk": "88e61aca2e4715cbbfa2bc3058c9ff388fc9c5a89178624d28ff14ce232e495c",
|
||||
"client_e_pk": "3e532c63ccb8aabb87b1a724eda76b94083d7cb15174acda91635245618cde3d",
|
||||
"client_e_sk": "18e9a925e2a1dd150f20322783a935bdfccb488478c6befcc31cce1a27643164",
|
||||
"server_s_pk": "afe934c6742742e4f1389e42722ce080bb4c4963b1eeaeb8829ea22a11162941",
|
||||
"server_s_sk": "f0f1348721d891985a3a92236fab57593fc3d997a649c6ce8858e8c20d7c1944",
|
||||
"server_e_pk": "9a579563f40948693645f490ee3fb0b7ec3fd5de1331858fe95927f71a59a971",
|
||||
"server_e_sk": "b81c82d7219bf318b75160dd010e96e83e0e080709c61edfbce206d6ec101a4a",
|
||||
"fake_sk": "90f850aae07d8365e8d28d31ff87bbef1d50c9928c49a5b4ec7aabd4d69ddf75",
|
||||
"client_s_pk": "d6ea34b61fa4625c1197f8f9fd51bc7023d4dfb0e17a95cf0ec38488ffff072c",
|
||||
"client_s_sk": "f8fe7d4c525bd238c501c78a7b6ab26e076bb22c6b409ca08e34875ee4055850",
|
||||
"client_e_pk": "7b0d1002539befa86f0cdf2a281f538842ec685bad21e9057a92390846ca0047",
|
||||
"client_e_sk": "30e51bf7c5734fd3d1465b20affb65dc342f06513df999822832aa464aa29c5a",
|
||||
"server_s_pk": "b6791c7cad7775b6cbc0bfa580319a1de159981771c59b0b86afeeff2767365a",
|
||||
"server_s_sk": "68bfdb4e00e93059fb35e90db641ae1ef7af0fc8a7e013e2990431cf4c708563",
|
||||
"server_e_pk": "c68d13eacc23578e731d78d2ccc37e2ff8e7cfdac3f76ee54d9ae40dd1167325",
|
||||
"server_e_sk": "68b6d213f11d303e61929d299ca2424947e136d5a56b1400dda6286eaf5e4278",
|
||||
"fake_sk": "c8f71d7e7864a25ee4e786744c5059ca268b7cf7a7610b4b3d763f368fae6972",
|
||||
"credential_identifier": "637265644964656e746966696572",
|
||||
"id_u": "696455",
|
||||
"id_s": "696453",
|
||||
"password": "70617373776f7264",
|
||||
"blinding_factor": "5aa31e7d500431691fa3eb16a8a2e416b769ec3df66ace2c199e6b1cfb8a7e0e",
|
||||
"oprf_seed": "ee0813a196ccc90a12de74c2d680eed39d6f6f16e55012881b32b4c02367f205fa5d7374a6c7119b28a586d59e9ea45760c011a3a81f064f07f80ffa23155e77",
|
||||
"masking_nonce": "e3a3aecff193e9fbdd6677aeb1078bbf6d78f1893fd6f7acd77e9e05c4d6b35f9b267571d52e74a5b159e5ff55f93f31fa278e549802eb36b66f1ec8b77aa3be",
|
||||
"envelope_nonce": "e2bd93bfcae01cc59e5e0d928923002682a291577b6e0e214c3a67c1ba94fd15",
|
||||
"client_nonce": "e130bdb7b59020cd43a39fc588d5f05d33967c48b3e2a87488788897470797d5",
|
||||
"server_nonce": "f1238020af1207007652c734b023758168c2156cc81b76a4f628f30a042e248f",
|
||||
"blinding_factor": "fa0bbeb200bef1802f3317c0e6b92590d9431fb6f5cb7f579d0865950172e40f",
|
||||
"oprf_seed": "8bbe6e550d125d9169342b5683b085be3aee7e6414fe2a4f6db2aa3493b16a9b75f109725d6d92c13f3f2814dec17f83e2fd20cf8b922ca1d928e8bf476f8154",
|
||||
"masking_nonce": "885aa518b13d78757415f8839e1505a4ae8b5f04b6904ce9aff6de6d156d94756f3cb40352bbdafe521da49bf9a57bcde3597114161b023cfbf3b79051d2ee0d",
|
||||
"envelope_nonce": "e5c5bb34123bb9b08eb961c6f3a94c6b627f1c5bcd3527d46a1652f662e078ac",
|
||||
"client_nonce": "7fb4b8f81eefe57a8b1cf5d75465d557e04b21ed7800356713ecc63b0ebbfca5",
|
||||
"server_nonce": "9e3f8ceb7174fdd7ceb2f1e37d4cd483e28e18fa60457416d2d5c468ae7501e7",
|
||||
"context": "636f6e74657874",
|
||||
"registration_request": "9ef8b4a7817e4932f4e9837dd54b31ce9209cad61d7ea4003283158e5566620d",
|
||||
"registration_response": "823eb375fcea47b3b1023848dc7b159ea4b9925f725a45f9e7da0f28c04f717eafe934c6742742e4f1389e42722ce080bb4c4963b1eeaeb8829ea22a11162941",
|
||||
"registration_upload": "fe576ba51ba994ef0cac45a5fd55f663b2fcb9377d5ea1141d24f6c1a840b71890bf61e8066f25e3ea4148a685aaa2345cfdf3cd9157765c104659fcf695cb76b43f34a46ca41f5e78ae4ac857d98c6f105902305e695bcdec10dc4eda526fac88e61aca2e4715cbbfa2bc3058c9ff388fc9c5a89178624d28ff14ce232e495c90ea3a5efe3b34d84610f458759a7864eed0773290f7a5e5115eef6e5a81164f6e6fc5d026bcbfe55195dfdaa55b13b3d7f177ab8e5e318ffcd7d2ac5daf42c4",
|
||||
"credential_request": "9ef8b4a7817e4932f4e9837dd54b31ce9209cad61d7ea4003283158e5566620de130bdb7b59020cd43a39fc588d5f05d33967c48b3e2a87488788897470797d53e532c63ccb8aabb87b1a724eda76b94083d7cb15174acda91635245618cde3d",
|
||||
"credential_response": "823eb375fcea47b3b1023848dc7b159ea4b9925f725a45f9e7da0f28c04f717ee3a3aecff193e9fbdd6677aeb1078bbf6d78f1893fd6f7acd77e9e05c4d6b35fc05b4023afa48dba2a9c78abfb9c93353be3ce2adabe0d4cc4f69d9c0b635cc2e5b14ccec2a9bbabb4ad3f1591a3ac3c92dd989322ad7753e7f5834186a67c94ab65c6a446dcf06f13cf5ef0502f265c3be9e03770c54fe2cee1486cddbf292fa0f44b6173faefe0c093a7797bee2b04927c009f3653b42c3319bbb817920fbdb81c82d7219bf318b75160dd010e96e83e0e080709c61edfbce206d6ec101a4ae21bc06da818572e3a7e77f0eb74bbf7375379771dd7ada27c0b9bdd584f5f142eb61b7fb2c5f7d164597ec148f74a6a168ec0d93b06fb45d48d0a0c3e92e1da80cfe439fccde489c74b801de4401fadf4dcbd61cfe559ad2cf38e83662e2b06",
|
||||
"credential_finalization": "fd18bc8aa8d789e6d954f962b52cb700296e88efd3a26f0761ff3e367d12b94ef187b2cc250519a2193fbd3c78247d3e0121aacdcdc5b22dcc818cd964c25754",
|
||||
"client_registration_state": "00285aa31e7d500431691fa3eb16a8a2e416b769ec3df66ace2c199e6b1cfb8a7e0e70617373776f726400209ef8b4a7817e4932f4e9837dd54b31ce9209cad61d7ea4003283158e5566620d",
|
||||
"client_login_state": "00285aa31e7d500431691fa3eb16a8a2e416b769ec3df66ace2c199e6b1cfb8a7e0e70617373776f726400609ef8b4a7817e4932f4e9837dd54b31ce9209cad61d7ea4003283158e5566620de130bdb7b59020cd43a39fc588d5f05d33967c48b3e2a87488788897470797d53e532c63ccb8aabb87b1a724eda76b94083d7cb15174acda91635245618cde3d004018e9a925e2a1dd150f20322783a935bdfccb488478c6befcc31cce1a27643164e130bdb7b59020cd43a39fc588d5f05d33967c48b3e2a87488788897470797d5",
|
||||
"server_login_state": "b8bb1a1ff45040bf016aeab52aceec195109233f4c0e2589d4370658bb07f1d57f65d5e3007d94ed36d974c298f21184041c08c3298c9d16fa33591c19b07b45bdaaaee9c95f286dc4ce250b684bf3c5248ca0382f682d9eddeb5bf8fa16488696f7df7dec0d5090c57153aa1b3da588469ca6be7dc25954147ad3c08367f1bb2d2e6bd1a311eb2f3960b80a72e77158fc7b072c85f134695735ffed8206d465029c3ce886fee4665e05dfca5ef778dfe851bc31a8980dae67f15672d8e3f1dd",
|
||||
"password_file": "fe576ba51ba994ef0cac45a5fd55f663b2fcb9377d5ea1141d24f6c1a840b71890bf61e8066f25e3ea4148a685aaa2345cfdf3cd9157765c104659fcf695cb76b43f34a46ca41f5e78ae4ac857d98c6f105902305e695bcdec10dc4eda526fac88e61aca2e4715cbbfa2bc3058c9ff388fc9c5a89178624d28ff14ce232e495c90ea3a5efe3b34d84610f458759a7864eed0773290f7a5e5115eef6e5a81164f6e6fc5d026bcbfe55195dfdaa55b13b3d7f177ab8e5e318ffcd7d2ac5daf42c4",
|
||||
"export_key": "aafb0c3bc3694314180212233e811fa44cd35896420d3f65c3696e305c177fca6850bb1b36ed5b6fa3fdca9483dd2013ad30bb84f2a94979fc1fec2e461c1515",
|
||||
"session_key": "2d2e6bd1a311eb2f3960b80a72e77158fc7b072c85f134695735ffed8206d465029c3ce886fee4665e05dfca5ef778dfe851bc31a8980dae67f15672d8e3f1dd"
|
||||
"registration_request": "8eda5caa002e6574e677636eeba5967ec25505a125ea12d9857c0d8c3beb3551",
|
||||
"registration_response": "ecf14ba8fb208a8d5b263170ffd84a9d21751810f52e539938ed22e71f66cb02b6791c7cad7775b6cbc0bfa580319a1de159981771c59b0b86afeeff2767365a",
|
||||
"registration_upload": "020689ce9ffba0f198d9e63e23902ff1600656fdd604aa47c289d5d073cc472354e891e7c4f89058fd270813d320e0cb97a745722eb8038eec062e5aed5e6b40b88148d43e68b7f457c352c3b6523e0bc79795f651487d007574cbaf7dba317ff8fe7d4c525bd238c501c78a7b6ab26e076bb22c6b409ca08e34875ee4055850ea0fcb59720fdb42fcbddbccbaed60a0aec01d72403c63075468e8a03c9efc25206776154291cbce05d7567a82a10d8303f991b8689643c5727b1886c478a9b8",
|
||||
"credential_request": "8eda5caa002e6574e677636eeba5967ec25505a125ea12d9857c0d8c3beb35517fb4b8f81eefe57a8b1cf5d75465d557e04b21ed7800356713ecc63b0ebbfca57b0d1002539befa86f0cdf2a281f538842ec685bad21e9057a92390846ca0047",
|
||||
"credential_response": "ecf14ba8fb208a8d5b263170ffd84a9d21751810f52e539938ed22e71f66cb02885aa518b13d78757415f8839e1505a4ae8b5f04b6904ce9aff6de6d156d94756060ede0b8a8d061eaa376b4578fd39ec064f9f36c7a0602894690da72727b427148a2970ce50d06d93ed74dde1143f7d092f19541e8738c509dd5d34f4411d753959bc295083bc96a0b6e1d9a12a369c83fc2a50fab84276f83a2a63e5d5ba6dbb0b23752b7819c238123f0e69cbccc777fa6c35484608f324a3c30b307ad6068b6d213f11d303e61929d299ca2424947e136d5a56b1400dda6286eaf5e4278549bc184dd7a99b0749dfb1acb8ca862b649567d04b056c0530755d453e4c466d5728608562883eea4c922c313455999720cbbf3c6511d3666365132e39c1b6f094d05e73a75e15fb0869661337c3569fcfca75a9373d8fac9ff29c61be49a0d",
|
||||
"credential_finalization": "6061b34bc847481034908047ded2b7e08450793091f96b9a425e4e4e24e65810596b2556e1ea1ae57e3f6bf234ba33fc393fe4fa98de984760df870a454fcdc9",
|
||||
"client_registration_state": "fa0bbeb200bef1802f3317c0e6b92590d9431fb6f5cb7f579d0865950172e40f8eda5caa002e6574e677636eeba5967ec25505a125ea12d9857c0d8c3beb3551",
|
||||
"client_login_state": "fa0bbeb200bef1802f3317c0e6b92590d9431fb6f5cb7f579d0865950172e40f8eda5caa002e6574e677636eeba5967ec25505a125ea12d9857c0d8c3beb35517fb4b8f81eefe57a8b1cf5d75465d557e04b21ed7800356713ecc63b0ebbfca57b0d1002539befa86f0cdf2a281f538842ec685bad21e9057a92390846ca004730e51bf7c5734fd3d1465b20affb65dc342f06513df999822832aa464aa29c5a7fb4b8f81eefe57a8b1cf5d75465d557e04b21ed7800356713ecc63b0ebbfca5",
|
||||
"server_login_state": "d58815ef0bd83afafea536fe17c23f5292a5484d5748e7164b678bb4edbbfd99a31fc1b8e78ce8aab0908db29832e2c9644b4af4e3a167ab9a4f5e82c0a068eb8df23068244e4c7256c48abb28bc02529c3fbc2217c042fcc7f54e50f1516dde8f9f25c694e34604c9bea4b94090c3c911c22db5c74a79abbecf0354dc8d475575d17a1f85b7efdc2dd8b6e2fa9529bfe49d7cfa2563451fe6b9d5cd7344377c3730e197b550030c012b01466b142c9022b869fe5ea7c59412e5b6685db19997",
|
||||
"password_file": "020689ce9ffba0f198d9e63e23902ff1600656fdd604aa47c289d5d073cc472354e891e7c4f89058fd270813d320e0cb97a745722eb8038eec062e5aed5e6b40b88148d43e68b7f457c352c3b6523e0bc79795f651487d007574cbaf7dba317ff8fe7d4c525bd238c501c78a7b6ab26e076bb22c6b409ca08e34875ee4055850ea0fcb59720fdb42fcbddbccbaed60a0aec01d72403c63075468e8a03c9efc25206776154291cbce05d7567a82a10d8303f991b8689643c5727b1886c478a9b8",
|
||||
"export_key": "0527421cb5c31aeba8fddff1af3a673e94cbd7af57999eaed47e23ea3562d68362416d69afb3bcf450db76b4fea504d5d065e0a104d9a1848f20e64ff04f3cfd",
|
||||
"session_key": "75d17a1f85b7efdc2dd8b6e2fa9529bfe49d7cfa2563451fe6b9d5cd7344377c3730e197b550030c012b01466b142c9022b869fe5ea7c59412e5b6685db19997"
|
||||
}
|
||||
"#;
|
||||
|
||||
#[cfg(all(feature = "x25519", feature = "p256"))]
|
||||
static TEST_VECTOR_X25519_P256: &str = r#"
|
||||
{
|
||||
"client_s_pk": "515850c2fb8fcf90378ba5baa2e5b05fd5244f90f49e4a4e8ded4553a696835a",
|
||||
"client_s_sk": "2894850bbca99009c3a50e648011a57edda65bf88177197fff52378bde705878",
|
||||
"client_e_pk": "8570fc35b68cf59e9c2d3d08a2452e9eaa9089b6d4cbee4053aedcd8eb4d3555",
|
||||
"client_e_sk": "9001cb4337b57ca2a72e1a837ab72c5ee6f41348a4c77b5720a3fc6cd6f75561",
|
||||
"server_s_pk": "583ef921ee685fe1a9d25492ed7221bf429dd8f3093cd78bf3de4b4822f11b56",
|
||||
"server_s_sk": "f8c0872b11bebf21c83b300dedf222340c034a9831a3d21feaf7cb51c6f7805a",
|
||||
"server_e_pk": "303d1d7ad0d6d466ee5a98a1407b1a05a891511cbdaa38695c63f9fb47a61c6a",
|
||||
"server_e_sk": "c8ffba68071b11cabaae1f28bc5c816132dd2e1fc2d11ecf6286855f76e4b37f",
|
||||
"fake_sk": "48aecca7847d09a5ba8ea1243d9a3527c16dc79852fd04eeb93083ef52e8f075",
|
||||
"client_s_pk": "ee6282a908e24291fcd1e7ce0a6fc244cf9b6371889e31a908d1919cdd756776",
|
||||
"client_s_sk": "785f65307f77f78cc4b20565a42c1954a30763d881528749f376b90a13ca2b73",
|
||||
"client_e_pk": "c6e0310d186d3c869b384418a6574cd9fff826e3a91ac46d05ce0ab56e25b978",
|
||||
"client_e_sk": "e889400a32d355cd203d6a1ee195a787217db28075de794d0c39ca29c44f1776",
|
||||
"server_s_pk": "1c840f081ecaa88b6eff81536d28b3220cc7101e6e90b998461cc80ead285808",
|
||||
"server_s_sk": "10138ce9d5660b1b23aaf520e1ec948bd1f318b571356aa3f9becf3db34daf7a",
|
||||
"server_e_pk": "152d47f6ac15e7c2c11f29bd513d182db4eed09ef3974a6e4438b72ec9aa2d0c",
|
||||
"server_e_sk": "589db8b32e957d97134b10f8b2fa107b908f88eb2a4620f2ae25d61107bf9e6f",
|
||||
"fake_sk": "088a857c0f23ea4896cb067420a5264e8ea22f13d6b471cc4518cdf520de817b",
|
||||
"credential_identifier": "637265644964656e746966696572",
|
||||
"id_u": "696455",
|
||||
"id_s": "696453",
|
||||
"password": "70617373776f7264",
|
||||
"blinding_factor": "0e2fe2a1a193da4c6739a1265cd9a2df297ac7312f2770afa9c8d6de37ead907",
|
||||
"oprf_seed": "048e281519d6d7548d03dccc8684d91e22025fc573e076c1c5885839cf42b8ad",
|
||||
"masking_nonce": "59ded518f0215d108d4b0ba8a34911c1d4178318816ab964e67d8315c6803c1fe403684d504bdcbbde77fb90d3824390dd7d3f04b9203636c23399ffdacf9e62",
|
||||
"envelope_nonce": "119acabcfa0d808d0ce82b7d3de2193deb5b0e71dc111d456c8ad4ee32fa7306",
|
||||
"client_nonce": "9e34fd4a6900a3dcb0bfcf8b6df799871bb0a11178ee0d7dad6c0fb74921f302",
|
||||
"server_nonce": "d62fbaec787648da7900d89fd007822e79407016d98a62333239892d49375a7d",
|
||||
"blinding_factor": "40b461844231f2f890fc68aa0da838e25f40af01ec1b212fdf6bad07db170757",
|
||||
"oprf_seed": "b25a0265e824656034824b935d49d7f844d26acf1a7d8c6c40d635543a2e6d33",
|
||||
"masking_nonce": "005cf982b3ddbb28ee252d729c83c4b9d74a54ac72f25325f7f21824530649fbf165383559cce8a4734d6fcd56e45f866828008d3d4c56dd57659c80bc3e094f",
|
||||
"envelope_nonce": "0c9954390a2bac0bf09c083a2152bfce397281e7a5408c08b0b18d56c0ec686c",
|
||||
"client_nonce": "b389ed08bf4bfbf895ea6706c3d967b5ec7c4af96c207ebe816c50b9615ab06e",
|
||||
"server_nonce": "a920b7dbb1607caea2a3d7577531fb30173d0123a2353cf4151bea9e71caaab2",
|
||||
"context": "636f6e74657874",
|
||||
"registration_request": "03cc7a78723430cbfa6f337c25d3ad586e5d20e2f8e9c2126a28c08f76493088f7",
|
||||
"registration_response": "0247b0d70311fb623ee21236536cb5df543100b44abaacc3bf2627cca77ee80185583ef921ee685fe1a9d25492ed7221bf429dd8f3093cd78bf3de4b4822f11b56",
|
||||
"registration_upload": "e3969807b3496f7a07afa9f2288e706f71125bbe1bc659e40f9c83eb3e428e430d9dc301ff73d3b95bf0fceab01ce66dc4c2f84dbea61526e6c1ee7c4adb8c912894850bbca99009c3a50e648011a57edda65bf88177197fff52378bde705878a6ede2210483b94ff0ca04b1eda09b841a735170f79d1674aacfbd3550bba356",
|
||||
"credential_request": "03cc7a78723430cbfa6f337c25d3ad586e5d20e2f8e9c2126a28c08f76493088f79e34fd4a6900a3dcb0bfcf8b6df799871bb0a11178ee0d7dad6c0fb74921f3028570fc35b68cf59e9c2d3d08a2452e9eaa9089b6d4cbee4053aedcd8eb4d3555",
|
||||
"credential_response": "0247b0d70311fb623ee21236536cb5df543100b44abaacc3bf2627cca77ee8018559ded518f0215d108d4b0ba8a34911c1d4178318816ab964e67d8315c6803c1fd513bf2f3cea8283a7ba98973d1f160213586e42a5e6ae5d6ac73f5deebc609e7481e84cd4f61b844db7457a5dc18121a0a6d8776d4e29d98cdf4892c18189439a3a7692a2be2910e0ba9fd8f7a28c10733ff781c4e36dabe86a819d35ce4745c8ffba68071b11cabaae1f28bc5c816132dd2e1fc2d11ecf6286855f76e4b37f2c2ffc6b9b2f6342231d5d3a9ea28023f543c7ccf3852413e411ab011b0c06523163f82d3cf9abb5e8517d0d47ef13071ac1001c6a1e39f2cbfe7440257d4db2",
|
||||
"credential_finalization": "de00d81621b2394b201a0c9d731b6b96e9cdab29fedb14c749c51029446da74a",
|
||||
"client_registration_state": "00280e2fe2a1a193da4c6739a1265cd9a2df297ac7312f2770afa9c8d6de37ead90770617373776f7264002103cc7a78723430cbfa6f337c25d3ad586e5d20e2f8e9c2126a28c08f76493088f7",
|
||||
"client_login_state": "00280e2fe2a1a193da4c6739a1265cd9a2df297ac7312f2770afa9c8d6de37ead90770617373776f7264006103cc7a78723430cbfa6f337c25d3ad586e5d20e2f8e9c2126a28c08f76493088f79e34fd4a6900a3dcb0bfcf8b6df799871bb0a11178ee0d7dad6c0fb74921f3028570fc35b68cf59e9c2d3d08a2452e9eaa9089b6d4cbee4053aedcd8eb4d355500409001cb4337b57ca2a72e1a837ab72c5ee6f41348a4c77b5720a3fc6cd6f755619e34fd4a6900a3dcb0bfcf8b6df799871bb0a11178ee0d7dad6c0fb74921f302",
|
||||
"server_login_state": "df965dfa291f57cfead138a43802798c270c481a35b2fbf3d6d0c1860ab73a8e5f9874bbe6a329b51e9015a551a7b49809de26f74ba2ff496782d94ae01468fc63b02cf977a143ebe1a1231a28367d1be1065d5c0273f959e1e97a08a74bf6f1",
|
||||
"password_file": "e3969807b3496f7a07afa9f2288e706f71125bbe1bc659e40f9c83eb3e428e430d9dc301ff73d3b95bf0fceab01ce66dc4c2f84dbea61526e6c1ee7c4adb8c912894850bbca99009c3a50e648011a57edda65bf88177197fff52378bde705878a6ede2210483b94ff0ca04b1eda09b841a735170f79d1674aacfbd3550bba356",
|
||||
"export_key": "6168b6786fbded7a888067b58e62035f0f1940c0fb6448fc69093d62597f365a",
|
||||
"session_key": "63b02cf977a143ebe1a1231a28367d1be1065d5c0273f959e1e97a08a74bf6f1"
|
||||
"registration_request": "02c1f758572663d7bb1fa5dbc8cf426b867a9936bc741e9acc8a31b18bf0e5bd33",
|
||||
"registration_response": "03068d5d3fe0d6b3361c2c728b85dce104df42d3d11c2079392ab894ace50ff4001c840f081ecaa88b6eff81536d28b3220cc7101e6e90b998461cc80ead285808",
|
||||
"registration_upload": "f49b790e8f2e36ca511957263868d1ee897b2936b1ae4922ac2ad0b7a0e38f3c2606360d0008b6ed33e4ca48d31f3992875445e3a53f42e4eee661aad96e2c50785f65307f77f78cc4b20565a42c1954a30763d881528749f376b90a13ca2b7374d474b4232682bf9033067a42d35f2b9936822372cd9ea4f9b8c38b14948ff5",
|
||||
"credential_request": "02c1f758572663d7bb1fa5dbc8cf426b867a9936bc741e9acc8a31b18bf0e5bd33b389ed08bf4bfbf895ea6706c3d967b5ec7c4af96c207ebe816c50b9615ab06ec6e0310d186d3c869b384418a6574cd9fff826e3a91ac46d05ce0ab56e25b978",
|
||||
"credential_response": "03068d5d3fe0d6b3361c2c728b85dce104df42d3d11c2079392ab894ace50ff400005cf982b3ddbb28ee252d729c83c4b9d74a54ac72f25325f7f21824530649fbed3e1ab6eb243095958829896b0286515a108213900d019d88d8578eb7919aec225c95400fd737bdfa72a8dfcfc12958fb794383b8da8f49d13cd554569097e0f9ed325ae363061f593e3cf7a2d28ac87e5e0d2a2f344e7286cf7f38e006908b589db8b32e957d97134b10f8b2fa107b908f88eb2a4620f2ae25d61107bf9e6f3691d795831920a6728252782da676dc34b5d069d92af4d306f8b13a81185b5e8f648ff448ba49b2fbe98d0cac15fce9f60b965e79e0903bdee7528549d4241b",
|
||||
"credential_finalization": "1e7f17932a85f0d16ca1a40c1233695dd23a087f17f470df4eb51e9ff24cbe43",
|
||||
"client_registration_state": "40b461844231f2f890fc68aa0da838e25f40af01ec1b212fdf6bad07db17075702c1f758572663d7bb1fa5dbc8cf426b867a9936bc741e9acc8a31b18bf0e5bd33",
|
||||
"client_login_state": "40b461844231f2f890fc68aa0da838e25f40af01ec1b212fdf6bad07db17075702c1f758572663d7bb1fa5dbc8cf426b867a9936bc741e9acc8a31b18bf0e5bd33b389ed08bf4bfbf895ea6706c3d967b5ec7c4af96c207ebe816c50b9615ab06ec6e0310d186d3c869b384418a6574cd9fff826e3a91ac46d05ce0ab56e25b978e889400a32d355cd203d6a1ee195a787217db28075de794d0c39ca29c44f1776b389ed08bf4bfbf895ea6706c3d967b5ec7c4af96c207ebe816c50b9615ab06e",
|
||||
"server_login_state": "9a2ccb3a4690792ee4c290ae12a84049b941ac7d6c5288c300f3af40b34fef6dc40347b218e9f65fe3c67d07173dcc9d73b7bcd5e2a128e7565e4c2fcaada2c631b54a2472ce398831783222437e916804e19a67771d900cde8733e890305ce3",
|
||||
"password_file": "f49b790e8f2e36ca511957263868d1ee897b2936b1ae4922ac2ad0b7a0e38f3c2606360d0008b6ed33e4ca48d31f3992875445e3a53f42e4eee661aad96e2c50785f65307f77f78cc4b20565a42c1954a30763d881528749f376b90a13ca2b7374d474b4232682bf9033067a42d35f2b9936822372cd9ea4f9b8c38b14948ff5",
|
||||
"export_key": "2b867ad9909d31946cb3c3738fb1c1e51ba09d768e83d6b03eb909e0e4298003",
|
||||
"session_key": "31b54a2472ce398831783222437e916804e19a67771d900cde8733e890305ce3"
|
||||
}
|
||||
"#;
|
||||
|
||||
@@ -318,8 +321,8 @@ fn populate_test_vectors(values: &Value) -> TestVectorParameters {
|
||||
}
|
||||
}
|
||||
|
||||
fn stringify_test_vectors(p: &TestVectorParameters) -> alloc::string::String {
|
||||
let mut s = alloc::string::String::new();
|
||||
fn stringify_test_vectors(p: &TestVectorParameters) -> String {
|
||||
let mut s = String::new();
|
||||
s.push_str("{\n");
|
||||
s.push_str(format!("\"client_s_pk\": \"{}\",\n", hex::encode(&p.client_s_pk)).as_str());
|
||||
s.push_str(format!("\"client_s_sk\": \"{}\",\n", hex::encode(&p.client_s_sk)).as_str());
|
||||
@@ -443,15 +446,21 @@ fn stringify_test_vectors(p: &TestVectorParameters) -> alloc::string::String {
|
||||
|
||||
fn generate_parameters<CS: CipherSuite>() -> Result<TestVectorParameters, ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// ClientRegistration: KgSk + KgPk
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<<CS::OprfGroup as Group>::ElemLen>,
|
||||
ClientRegistrationLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationResponse: KgPk + KePk
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
RegistrationResponseLen<CS>: ArrayLength<u8>,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
@@ -461,10 +470,14 @@ where
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
// ClientLogin: KgSk + CredentialRequest + Ke1State
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<CredentialRequestLen<CS>>,
|
||||
Sum<<CS::OprfGroup as Group>::ScalarLen, CredentialRequestLen<CS>>:
|
||||
ArrayLength<u8> + Add<Ke1StateLen<CS>>,
|
||||
ClientLoginLen<CS>: ArrayLength<u8>,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<NonceLen>,
|
||||
@@ -472,8 +485,7 @@ where
|
||||
CredentialResponseWithoutKeLen<CS>: ArrayLength<u8>,
|
||||
// Ke2Message: (Nonce + KePk) + Hash
|
||||
NonceLen: Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
Sum<NonceLen, <CS::KeGroup as KeGroup>::PkLen>:
|
||||
ArrayLength<u8> + Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::KeGroup as KeGroup>::PkLen>: ArrayLength<u8> + Add<OutputSize<CS::Hash>>,
|
||||
Ke2MessageLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message
|
||||
CredentialResponseWithoutKeLen<CS>: Add<Ke2MessageLen<CS>>,
|
||||
@@ -495,7 +507,7 @@ where
|
||||
let id_s = b"idS";
|
||||
let password = b"password";
|
||||
let context = b"context";
|
||||
let mut oprf_seed = GenericArray::<_, <CS::Hash as Digest>::OutputSize>::default();
|
||||
let mut oprf_seed = Output::<CS::Hash>::default();
|
||||
rng.fill_bytes(&mut oprf_seed);
|
||||
let mut masking_nonce = [0u8; 64];
|
||||
rng.fill_bytes(&mut masking_nonce);
|
||||
@@ -535,7 +547,7 @@ where
|
||||
);
|
||||
|
||||
let registration_request_bytes = client_registration_start_result.message.serialize();
|
||||
let client_registration_state = client_registration_start_result.state.serialize()?;
|
||||
let client_registration_state = client_registration_start_result.state.serialize();
|
||||
|
||||
let server_registration_start_result = ServerRegistration::<CS>::start(
|
||||
&server_setup,
|
||||
@@ -554,6 +566,7 @@ where
|
||||
.state
|
||||
.finish(
|
||||
&mut finish_registration_rng,
|
||||
password,
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::new(
|
||||
Identifiers {
|
||||
@@ -578,11 +591,7 @@ where
|
||||
let client_login_start_result =
|
||||
ClientLogin::<CS>::start(&mut client_login_start_rng, password).unwrap();
|
||||
let credential_request_bytes = client_login_start_result.message.serialize();
|
||||
let client_login_state = client_login_start_result
|
||||
.state
|
||||
.serialize()
|
||||
.unwrap()
|
||||
.to_vec();
|
||||
let client_login_state = client_login_start_result.state.serialize().to_vec();
|
||||
|
||||
let mut server_e_sk_and_nonce_rng = CycleRng::new(
|
||||
[
|
||||
@@ -613,6 +622,7 @@ where
|
||||
let client_login_finish_result = client_login_start_result
|
||||
.state
|
||||
.finish(
|
||||
password,
|
||||
server_login_start_result.message,
|
||||
ClientLoginFinishParameters::new(
|
||||
Some(context),
|
||||
@@ -654,7 +664,7 @@ where
|
||||
credential_response: credential_response_bytes.to_vec(),
|
||||
credential_finalization: credential_finalization_bytes.to_vec(),
|
||||
password_file: password_file_bytes.to_vec(),
|
||||
client_registration_state,
|
||||
client_registration_state: client_registration_state.to_vec(),
|
||||
client_login_state,
|
||||
server_login_state: server_login_state.to_vec(),
|
||||
session_key: client_login_finish_result.session_key.to_vec(),
|
||||
@@ -693,7 +703,15 @@ fn generate_test_vectors() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn test_registration_request() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// ClientRegistration: KgSk + KgPk
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<<CS::OprfGroup as Group>::ElemLen>,
|
||||
ClientRegistrationLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap());
|
||||
let mut rng = CycleRng::new(parameters.blinding_factor.to_vec());
|
||||
let client_registration_start_result =
|
||||
@@ -704,7 +722,7 @@ fn test_registration_request() -> Result<(), ProtocolError> {
|
||||
);
|
||||
assert_eq!(
|
||||
hex::encode(¶meters.client_registration_state),
|
||||
hex::encode(client_registration_start_result.state.serialize()?)
|
||||
hex::encode(client_registration_start_result.state.serialize())
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
@@ -726,7 +744,12 @@ fn test_registration_request() -> Result<(), ProtocolError> {
|
||||
fn test_serialization() -> Result<(), ProtocolError> {
|
||||
use core::mem;
|
||||
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap());
|
||||
let mut rng = CycleRng::new(parameters.blinding_factor.to_vec());
|
||||
let client_registration_start_result =
|
||||
@@ -765,6 +788,9 @@ fn test_serialization() -> Result<(), ProtocolError> {
|
||||
fn test_registration_response() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// RegistrationResponse: KgPk + KePk
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
RegistrationResponseLen<CS>: ArrayLength<u8>,
|
||||
@@ -810,12 +836,15 @@ fn test_registration_response() -> Result<(), ProtocolError> {
|
||||
fn test_registration_upload() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
@@ -829,6 +858,7 @@ fn test_registration_upload() -> Result<(), ProtocolError> {
|
||||
let result = ClientRegistration::<CS>::deserialize(¶meters.client_registration_state)?
|
||||
.finish(
|
||||
&mut finish_registration_rng,
|
||||
¶meters.password,
|
||||
RegistrationResponse::deserialize(¶meters.registration_response)?,
|
||||
ClientRegistrationFinishParameters::new(
|
||||
Identifiers {
|
||||
@@ -867,12 +897,15 @@ fn test_registration_upload() -> Result<(), ProtocolError> {
|
||||
fn test_password_file() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
@@ -906,9 +939,17 @@ fn test_password_file() -> Result<(), ProtocolError> {
|
||||
fn test_credential_request() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
// ClientLogin: KgSk + CredentialRequest + Ke1State
|
||||
<CS::OprfGroup as Group>::ScalarLen: Add<CredentialRequestLen<CS>>,
|
||||
Sum<<CS::OprfGroup as Group>::ScalarLen, CredentialRequestLen<CS>>:
|
||||
ArrayLength<u8> + Add<Ke1StateLen<CS>>,
|
||||
ClientLoginLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap());
|
||||
|
||||
@@ -927,7 +968,7 @@ fn test_credential_request() -> Result<(), ProtocolError> {
|
||||
);
|
||||
assert_eq!(
|
||||
hex::encode(¶meters.client_login_state),
|
||||
hex::encode(client_login_start_result.state.serialize()?)
|
||||
hex::encode(client_login_start_result.state.serialize())
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
@@ -948,10 +989,12 @@ fn test_credential_request() -> Result<(), ProtocolError> {
|
||||
fn test_credential_response() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<NonceLen>,
|
||||
@@ -1022,16 +1065,19 @@ fn test_credential_response() -> Result<(), ProtocolError> {
|
||||
fn test_credential_finalization() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap());
|
||||
|
||||
let client_login_finish_result =
|
||||
ClientLogin::<CS>::deserialize(¶meters.client_login_state)?.finish(
|
||||
¶meters.password,
|
||||
CredentialResponse::<CS>::deserialize(¶meters.credential_response)?,
|
||||
ClientLoginFinishParameters::new(
|
||||
Some(¶meters.context),
|
||||
@@ -1077,7 +1123,12 @@ fn test_credential_finalization() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn test_server_login_finish() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>(test_vector: &str) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap());
|
||||
|
||||
let server_login_result = ServerLogin::<CS>::deserialize(¶meters.server_login_state)?
|
||||
@@ -1110,10 +1161,12 @@ fn test_complete_flow<CS: CipherSuite>(
|
||||
login_password: &[u8],
|
||||
) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let credential_identifier = b"credentialIdentifier";
|
||||
@@ -1129,6 +1182,7 @@ where
|
||||
)?;
|
||||
let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
&mut client_rng,
|
||||
registration_password,
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1144,6 +1198,7 @@ where
|
||||
)?;
|
||||
|
||||
let client_login_result = client_login_start_result.state.finish(
|
||||
login_password,
|
||||
server_login_start_result.message,
|
||||
ClientLoginFinishParameters::default(),
|
||||
);
|
||||
@@ -1204,7 +1259,12 @@ fn test_complete_flow_fail() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn test_zeroize_client_registration_start() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut client_rng = OsRng;
|
||||
let client_registration_start_result =
|
||||
ClientRegistration::<CS>::start(&mut client_rng, STR_PASSWORD.as_bytes())?;
|
||||
@@ -1232,7 +1292,12 @@ fn test_zeroize_client_registration_start() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let mut client_rng = OsRng;
|
||||
let mut server_rng = OsRng;
|
||||
let server_setup = ServerSetup::<CS>::new(&mut server_rng);
|
||||
@@ -1245,6 +1310,7 @@ fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> {
|
||||
)?;
|
||||
let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
&mut client_rng,
|
||||
STR_PASSWORD.as_bytes(),
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1274,12 +1340,15 @@ fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> {
|
||||
fn test_zeroize_server_registration_finish() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
@@ -1296,6 +1365,7 @@ fn test_zeroize_server_registration_finish() -> Result<(), ProtocolError> {
|
||||
)?;
|
||||
let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
&mut client_rng,
|
||||
STR_PASSWORD.as_bytes(),
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1326,6 +1396,9 @@ fn test_zeroize_server_registration_finish() -> Result<(), ProtocolError> {
|
||||
fn test_zeroize_client_login_start() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
@@ -1359,10 +1432,12 @@ fn test_zeroize_client_login_start() -> Result<(), ProtocolError> {
|
||||
fn test_zeroize_server_login_start() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let mut client_rng = OsRng;
|
||||
@@ -1377,6 +1452,7 @@ fn test_zeroize_server_login_start() -> Result<(), ProtocolError> {
|
||||
)?;
|
||||
let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
&mut client_rng,
|
||||
STR_PASSWORD.as_bytes(),
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1417,10 +1493,12 @@ fn test_zeroize_server_login_start() -> Result<(), ProtocolError> {
|
||||
fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
@@ -1438,6 +1516,7 @@ fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
|
||||
)?;
|
||||
let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
&mut client_rng,
|
||||
STR_PASSWORD.as_bytes(),
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1453,6 +1532,7 @@ fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
|
||||
ServerLoginStartParameters::default(),
|
||||
)?;
|
||||
let client_login_finish_result = client_login_start_result.state.finish(
|
||||
STR_PASSWORD.as_bytes(),
|
||||
server_login_start_result.message,
|
||||
ClientLoginFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1482,10 +1562,12 @@ fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
|
||||
fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let mut client_rng = OsRng;
|
||||
@@ -1500,6 +1582,7 @@ fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> {
|
||||
)?;
|
||||
let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
&mut client_rng,
|
||||
STR_PASSWORD.as_bytes(),
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1515,6 +1598,7 @@ fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> {
|
||||
ServerLoginStartParameters::default(),
|
||||
)?;
|
||||
let client_login_finish_result = client_login_start_result.state.finish(
|
||||
STR_PASSWORD.as_bytes(),
|
||||
server_login_start_result.message,
|
||||
ClientLoginFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1545,7 +1629,12 @@ fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn test_scalar_always_nonzero() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
// Start out with a bunch of zeros to force resampling of scalar
|
||||
let mut client_registration_rng = CycleRng::new([vec![0u8; 128], vec![1u8; 128]].concat());
|
||||
let client_registration_start_result =
|
||||
@@ -1591,7 +1680,12 @@ fn test_scalar_always_nonzero() -> Result<(), ProtocolError> {
|
||||
|
||||
#[test]
|
||||
fn test_reflected_value_error_registration() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
let credential_identifier = b"credentialIdentifier";
|
||||
let password = b"password";
|
||||
let mut client_rng = OsRng;
|
||||
@@ -1615,6 +1709,7 @@ fn test_reflected_value_error_registration() -> Result<(), ProtocolError> {
|
||||
|
||||
let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
&mut client_rng,
|
||||
password,
|
||||
reflected_registration_response,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
);
|
||||
@@ -1643,10 +1738,12 @@ fn test_reflected_value_error_registration() -> Result<(), ProtocolError> {
|
||||
fn test_reflected_value_error_login() -> Result<(), ProtocolError> {
|
||||
fn inner<CS: CipherSuite>() -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
let credential_identifier = b"credentialIdentifier";
|
||||
@@ -1663,6 +1760,7 @@ fn test_reflected_value_error_login() -> Result<(), ProtocolError> {
|
||||
)?;
|
||||
let client_registration_finish_result = client_registration_start_result.state.finish(
|
||||
&mut client_rng,
|
||||
password,
|
||||
server_registration_start_result.message,
|
||||
ClientRegistrationFinishParameters::default(),
|
||||
)?;
|
||||
@@ -1686,6 +1784,7 @@ fn test_reflected_value_error_login() -> Result<(), ProtocolError> {
|
||||
.set_evaluation_element_for_testing(alpha);
|
||||
|
||||
let client_login_result = client_login_start_result.state.finish(
|
||||
password,
|
||||
reflected_credential_response,
|
||||
ClientLoginFinishParameters::default(),
|
||||
);
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
// of this source tree.
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::cmp::min;
|
||||
use rand::{CryptoRng, Error, RngCore};
|
||||
use std::vec::Vec;
|
||||
|
||||
/// A simple implementation of `RngCore` for testing purposes.
|
||||
///
|
||||
|
||||
+175
-175
@@ -68,25 +68,25 @@ bf8d6503
|
||||
#### Intermediate Values
|
||||
|
||||
~~~
|
||||
client_public_key: 3ea81ee30a44d65ca6db8f42a9c125277898ead7fe1604da98
|
||||
70ad4542044a56
|
||||
auth_key: 7816871e2ab2d039dc0d8a07ce94081dfd975de003ea1b7ff2b120cc74c
|
||||
f18c32e11d2ed730fae9040f87be5c11cfc90cdf3393557c47065d7127ece8ca2b09c
|
||||
randomized_pwd: c9c8c47dece13aed16b80ca049cedc86e984177d98b549ba40390
|
||||
eb77981f954537e743ca3ec854fce472981714aadb3a280f4b2c15040d97653c64b7e
|
||||
5c265e
|
||||
client_public_key: 60c9b59f46e93a2dc8c5dd0dd101fad1838f4c4c026691e9d1
|
||||
8d3de8f2b3940d
|
||||
auth_key: 72c837a116b444f86229d432ea48221327339704fd2451704766bb3d42d
|
||||
10796a2be4083998a78f31f52f3d2fff6ace6b9c2fa9dae1ce64ee36cc867f6cc9e48
|
||||
randomized_pwd: 024d0bc2c5e95421951227ee87d8c5488e6dc537b2bf014452edb
|
||||
714bb98f0ef9590b1cca3345f2a1d0afff79967875306e07326b311662d5975b24e82
|
||||
07594e
|
||||
envelope: 71b8f14b7a1059cdadc414c409064a22cf9e970b0ffc6f1fc6fdd539c46
|
||||
76775eca8b48680e4973b26f754fbe0865af5135b284b00afce879c285db39b2ef0a9
|
||||
c1bd2f847c3f2139556b34885691be2d1917be4de9d2f50ef198950964142256
|
||||
handshake_secret: 706bae252489cd38228083790e3ead93f6b5b41682468741508
|
||||
124a58185fbb5fc2ee23850dd5285095d6e18dd133f16ecda7e35837429efdf71455e
|
||||
a6642cf6
|
||||
server_mac_key: b63f98de411d2b008abaee6699ed14fa2834986f9fc2f9ae59af2
|
||||
292fe8aa5e125d0ab0d5e5954cb8de5966da7994d798c800062c17fc167c598aa0d86
|
||||
071685
|
||||
client_mac_key: 187335e3edd777cb419d055e54001325cb19ebac8d43cf736f101
|
||||
127bb19c932717960b2401699b0d5029cd3637a3175248048f1eba202eada9428b475
|
||||
f2867a
|
||||
767750a343dd3f683692f4ed987ff286a4ece0813a4942e23477920608f261e1ab6f8
|
||||
727f532c9fd0cde8ec492cb76efdc855da76d0b6ccbe8a4dc0ba2709d63c4517
|
||||
handshake_secret: 01d81a6ba7c31a2c7c7ff4dab19db55d1f0290905645004bc2b
|
||||
b8d703f00e486a34c15095df96d6524901eeac1d6c46d94a2ee390dcc5625c6b0baba
|
||||
fe40e504
|
||||
server_mac_key: 5ee8f006713979257342d86a1541545b59e4e628b8be4b2f01438
|
||||
83cb9ce2cd9b6caded5733919739bd889b9426a03ad7c23db8b26ad13d2ad179e56dd
|
||||
cfe76d
|
||||
client_mac_key: 5b14da362ce9eaf3492ad315997911d9db3264f0e22e2a4cfb501
|
||||
f6f336c4e5e3d448f4c1b558101563c55a31e992aab92459c67231ca68de19ab12470
|
||||
4ca0f9
|
||||
oprf_key: 3f76113135e6ca7e51ac5bb3e8774eb84709ad36b8907ec8f7bc3537828
|
||||
71906
|
||||
~~~
|
||||
@@ -94,38 +94,38 @@ oprf_key: 3f76113135e6ca7e51ac5bb3e8774eb84709ad36b8907ec8f7bc3537828
|
||||
#### Output Values
|
||||
|
||||
~~~
|
||||
registration_request: 76cc85628d5ac0e01de4ede72479d607490e7f58b94578d
|
||||
b7a0606d74bc58b03
|
||||
registration_response: 583fd26fd3130386b1a1a970e4617d45dc21c7a6f07052
|
||||
8f0175985570b4ea2018d5035fd0a9c1d6412226df037125901a43f4dff660c0549d4
|
||||
registration_request: ac7a6330f91d1e5c87365630c7be58641885d59ffe4d3f8
|
||||
a49c094271993331d
|
||||
registration_response: 5c7d3c70cf7478ead859bb879b37cce78baef3b9d81e04
|
||||
f4c790ce25f2830e2e18d5035fd0a9c1d6412226df037125901a43f4dff660c0549d4
|
||||
02f672bcc0933
|
||||
registration_upload: 3ea81ee30a44d65ca6db8f42a9c125277898ead7fe1604da
|
||||
9870ad4542044a56dde0af371300d8b13f4dc7039ae643560c279c0e67be6086bfbe2
|
||||
188a65480689c9044a36b844b3f137a1fb594caff5e79002232a877aba39da085ce62
|
||||
e1a59f71b8f14b7a1059cdadc414c409064a22cf9e970b0ffc6f1fc6fdd539c467677
|
||||
5eca8b48680e4973b26f754fbe0865af5135b284b00afce879c285db39b2ef0a9c1bd
|
||||
2f847c3f2139556b34885691be2d1917be4de9d2f50ef198950964142256
|
||||
KE1: e47c1c5e5eed1910a1cbb6420c5edf26ea3c099aaaedcb03599fc311a724d84f
|
||||
registration_upload: 60c9b59f46e93a2dc8c5dd0dd101fad1838f4c4c026691e9
|
||||
d18d3de8f2b3940d7981498360f8f276df1dfb852a93ec4f4a0189dec5a96363296a6
|
||||
93fc8a51fb052ae8318dac48be7e3c3cd290f7b8c12b807617b7f9399417deed00158
|
||||
281ac771b8f14b7a1059cdadc414c409064a22cf9e970b0ffc6f1fc6fdd539c467677
|
||||
50a343dd3f683692f4ed987ff286a4ece0813a4942e23477920608f261e1ab6f8727f
|
||||
532c9fd0cde8ec492cb76efdc855da76d0b6ccbe8a4dc0ba2709d63c4517
|
||||
KE1: e4e7ce5bf96ddb2924faf816774b26a0ec7a6dd9d3a5bced1f4a3675c3cfd14c
|
||||
804133133e7ee6836c8515752e24bb44d323fef4ead34cde967798f2e9784f69f6792
|
||||
6bd036c5dc4971816b9376e9f64737f361ef8269c18f69f1ab555e96d4a
|
||||
KE2: b01355438b21dc20aaa46a5dea61d5b60f81b81f347f80e8ee3addc12f62be05
|
||||
54f9341ca183700f6b6acf28dbfe4a86afad788805de49f2d680ab86ff39ed7f98431
|
||||
127a277d18a821887ef0e23d92d73000161f14a3437d5fa6e028e4b33edad12212183
|
||||
73ef515b13f023d4a17ed5f62201416b4ae07f56605093eda407390f83457ce80c4ad
|
||||
48e25a7875deacb41fa9ee9c3fb9895407733ef147a97fb0eee9b47abd930777b6599
|
||||
1c53b126f9f5aae3307a111a85107fe2229f93db8fe0f9c5ec75a8cd571370add249e
|
||||
KE2: 1af11be29a90322dc16462d0861b1eb617611fe2f05e5e9860c164592d4f7f62
|
||||
54f9341ca183700f6b6acf28dbfe4a86afad788805de49f2d680ab86ff39ed7f76011
|
||||
9ed2f12f6ec4983f2c598068057af146fd09133c75b229145b7580d53cac4ba581155
|
||||
2e6786837a3e03d9f7971df0dad4a04fd6a6d4164101c91137a87f4afde7dae72daf2
|
||||
620082f46413bbb3071767d549833bcc523acc645b571a66318b0b1f8bf4b23de3542
|
||||
8373aa1d3a45c1e89eff88f03f9446e5dfc23b6f8394f9c5ec75a8cd571370add249e
|
||||
99cb8a8c43f6ef05610ac6e354642bf4fedbf696e77d4749eb304c4d74be9457c5975
|
||||
46bc22aed699225499910fc913b3e907125ff3ab1b935c6740b10dd4441074507761b
|
||||
1d955aba1296ba52061dfec49c5e003bf84a354d30f2a1f00fb320256002b781da075
|
||||
e838cc535ece42b26d6043af
|
||||
KE3: 19624915863ad577d4c6c15d56207fe0dfd96a8ec489b4bc25a7b79cc33c1d75
|
||||
717c0ba4db2cc5bb95d275ba5a5bcd39ad17459fb162d83455658acd20a4b4e4
|
||||
export_key: 252cfa49d8fd722663fe16ef7451d8cc25345f05f4967859e7500763f
|
||||
42b18b036fb1c4e7f0ad0110c71fb87f80da9ab53724976c4f8fa368d1c4cb6b9c6cd
|
||||
e4
|
||||
session_key: f31b89ce77171a51e6da037ad77f634184406844057f7875f04c7c4d
|
||||
e08aa26d2f3bf9ab78e1e8a5faa6f625b12008d98da5e00d8aa36f9e097890337ac9c
|
||||
005
|
||||
46bc22aed699225499910fc913b3e907120638f222a1a08460f4e40d0686830d3d608
|
||||
ce89789489161438bf6809dbbce3a6ddb0ce8702576843b58465d6cedd4e965f3f81b
|
||||
92992ecec0e2137b66eff0b4
|
||||
KE3: 1c0c743ff88f1a4ff07350eef61e899ae25d7fb23d555926b218bac4c1963071
|
||||
5038c56cca247630be8a8e66f3ff18b89c1bc97e1e2192fd7f14f2f60ed084a3
|
||||
export_key: 8408f92d282c7f4b0f5462e5206bd92937a4d53b0dcdef90afffd015c
|
||||
5dee44dc4dc5ad35d1681c97e2b66de09203ac359a69f1d45f8c97dbc907589177ccc
|
||||
24
|
||||
session_key: 05d03f4143e5866844f7ae921d3b48f3d611e930a6c4be0993a98290
|
||||
085110c5a27a2e5f92aeed861b90de068a51a952aa75bf97589be7c7104a4c30cc357
|
||||
506
|
||||
~~~
|
||||
|
||||
### OPAQUE-3DH Real Test Vector 2
|
||||
@@ -187,25 +187,25 @@ blind_login: e6f161ac189e6873a19a54efca4baa0719e801e336d929d35ca28b5b
|
||||
#### Intermediate Values
|
||||
|
||||
~~~
|
||||
client_public_key: 003e4b5cd9124a026302a223cd2187fb62285d33d987155c4a
|
||||
3307aa55f60c5e
|
||||
auth_key: c34629e50ddce1db7aa01edb9cf6979890c40f0e55d8abfc388dae762a6
|
||||
5300955344d1e273be49a1a513dbadeb045163b8882809f885dd46e978797484da85b
|
||||
randomized_pwd: 2d0285e5872af71e6b6f3e76e1605de56ee229d1436563988aab1
|
||||
13b2f8104a7a14377b71158451988bb4ec11a235fbac2063dad136cffd0b1f76019d4
|
||||
123199
|
||||
client_public_key: 3036af4744effe59eb7ee5db0ebcb653bd4a1c7ad0c56c78af
|
||||
1288f1e8538d1c
|
||||
auth_key: 8820ff275662bf91d4ebcca74c9b90913eb3ee8151047926ad754da823e
|
||||
98800db56a79c68b44d76ad906d26ed8b9e25d8ea862cfc6c2f0da86c623f6a24961a
|
||||
randomized_pwd: 16decdbba6912903b7ae38de7040a79ebc59c9fbbac04add8a710
|
||||
0ff8aedbb9530c4e664bd08b2689a607e99923e80563a8379ddfdb37801718ed043fb
|
||||
7bca07
|
||||
envelope: d0c7b0f0047682bd87a87e0c3553b9bcdce7e1ae3348570df20bf274782
|
||||
9b2d2d20f701d2571da6f0fe29687724db96371b552df07e06c6cf3a2534147161ba4
|
||||
5e543a6d4a15eda6af8ec5aab229abbaac2af81b48c1737a419a524bb618a48d
|
||||
handshake_secret: b7cab8367758393c3a7c72b38accaa91e164d77be82d4c01364
|
||||
0b8d2d6e1750f5ce1b77dcaf4173d07deeefc67895ad2d9ae6c6be8bdb384a9f54c7d
|
||||
946ad85e
|
||||
server_mac_key: aa959f4338f440f08dbaee86a576aae1ba65ee348f51e339feeda
|
||||
8ce93ab0673904c1bb3de591689613f489705de68ae9e96146b0f54c7e0333fa50855
|
||||
587fd5
|
||||
client_mac_key: 3a3ca98df30379ac1cf59f3508b3daa60ea644c28f1e9de5a4911
|
||||
f641514db7df1f46ec850ed2f9a2053f5a7cccd77f0a9b14e0e7c570319b8080c4484
|
||||
cecf74
|
||||
9b2d24117867ef8aa569ed6fa8ad1b3749b0df472d431ce92da7775e44623d6c36f7e
|
||||
9396d16ac58060704e9d42b37f09642ed7ee49008b4b81dc65d282ddcec0ab97
|
||||
handshake_secret: eef528fc4e46c387ef2bd68c06eb135ea18d743bcb632233594
|
||||
b213eb4eefaa4010b0f00785a204c77456f9007d8f7645fdc0c6795f486150a53fe17
|
||||
e6608179
|
||||
server_mac_key: ff6eeffbe0e88a966bdb39fa4fc933a488c0b802f913a7a6950d1
|
||||
c2eda0fc6acce6fdf7b060aa0be02efddb5a127e4dd893d3666e9b54d6fd6c85f52c9
|
||||
13138e
|
||||
client_mac_key: 4babec778469dfed06cd89c6673b8511f337e27ce565a2fd68cb6
|
||||
2a04df035fabc2097ba33018a4cd858dc399a0563950d7ce8ffe26c223328023e4c70
|
||||
a16c8e
|
||||
oprf_key: 531b0c7b0a3f90060c28d3d96ef5fecf56e25b8e4bf71c14bc770804c3f
|
||||
b4507
|
||||
~~~
|
||||
@@ -213,38 +213,38 @@ b4507
|
||||
#### Output Values
|
||||
|
||||
~~~
|
||||
registration_request: ec2927a03ced1220168b6d5a54f0372f813ced8ad3673d5
|
||||
1dee92d2cbfee500c
|
||||
registration_response: 588b259785af29c162958ebfdc4ca3b1fcf46bd1894c81
|
||||
854db7d2d41bf1933c8aa90cb321a38759fc253c444f317782962ca18d33101eab2c8
|
||||
registration_request: d81b76a8a78b8b0758f7ceffaa5c3cb4ac76c0517759ad8
|
||||
077ed87857e585f79
|
||||
registration_response: a48835aa277db6d7d501addbd431100a548867e3f1ee6f
|
||||
d6ae4aacd817a66e4c8aa90cb321a38759fc253c444f317782962ca18d33101eab2c8
|
||||
cda04405a181f
|
||||
registration_upload: 003e4b5cd9124a026302a223cd2187fb62285d33d987155c
|
||||
4a3307aa55f60c5e3114123a82551b4851bbc26b4a6a25444a60c501bb3e8eae95f2a
|
||||
eae7971f1358c5fe0cfa3cbf7f493be05418740bc884c1a20ad220c43ea30a7af1e92
|
||||
3e81b7d0c7b0f0047682bd87a87e0c3553b9bcdce7e1ae3348570df20bf2747829b2d
|
||||
2d20f701d2571da6f0fe29687724db96371b552df07e06c6cf3a2534147161ba45e54
|
||||
3a6d4a15eda6af8ec5aab229abbaac2af81b48c1737a419a524bb618a48d
|
||||
KE1: d0a498e621d3ff7a011b37166a63ef40fe268f93c7d75a467eea42a98c0a490d
|
||||
registration_upload: 3036af4744effe59eb7ee5db0ebcb653bd4a1c7ad0c56c78
|
||||
af1288f1e8538d1cedbc931daab2331b192808768f149499a04c6dffa4eae66a6e0d3
|
||||
399547c8b9e9a743a3cd20f08ce07adf84b27c9ca879d730bcc41823cbd60411fbde6
|
||||
c7faf2d0c7b0f0047682bd87a87e0c3553b9bcdce7e1ae3348570df20bf2747829b2d
|
||||
24117867ef8aa569ed6fa8ad1b3749b0df472d431ce92da7775e44623d6c36f7e9396
|
||||
d16ac58060704e9d42b37f09642ed7ee49008b4b81dc65d282ddcec0ab97
|
||||
KE1: 8a32b2985d824b0e42b7d3c5091774acd64386f8a762678422f0b5cbabeda12b
|
||||
a6bcd29b5aecc3507fc1f8f7631af3d2f5105155222e48099e5e6085d8c1187a642e7
|
||||
eecf19b804a62817486663d6c6c239396f709b663a4350cda67d025687a
|
||||
KE2: 6810ba4cf3049dab416529542385d194eddf0105ad6480ea0c92f872cab6af46
|
||||
30635396b708ddb7fc10fb73c4e3a9258cd9c3f6f761b2c227853b5def228c854aa9f
|
||||
c9066d61f2a64d5890ed79ff8e4a200444dc2e180ae57d6e78bdb594722d57283a3ff
|
||||
9a6600f61341f9ad49c32be9054ad8a26837d8ccea6de753520b1eb836c85faa907a4
|
||||
428828fb5ad362ff1b5327afdd1d1c300e03db05f9d55c1535bac50d76b4e5f19dcd7
|
||||
0ee043d2254ffcae31bffaf426f0b862f5fd311649723fa57f7ef652185f89114109f
|
||||
KE2: da642966461f20090d1e8d6b1f63ea70dc94fc6e0ea0bad46d011e906cc03c03
|
||||
30635396b708ddb7fc10fb73c4e3a9258cd9c3f6f761b2c227853b5def228c8594543
|
||||
768891810f779604eb9e07dcd37635def358e2f4531f464a4e0b3726c150d7872785c
|
||||
9b6a22f00fe3527d9e938d4b503047484723585ee390925ab9d97e30f0860caef1243
|
||||
0459d8ca24e5ff1a2029c363ed00f2f3cd09ead304f217290d8915183c2667959d420
|
||||
175bfca3bbec3d603844ca0d5b5892888f0de19dc3b83fa57f7ef652185f89114109f
|
||||
5a61cc8c9216fdd7398246bb7a0c20e2fbca2d8ae070cdffe5bb4b1c373e71be8e7d8
|
||||
f356ee5de37881533f10397bcd84d35445a04e7e9047091f5b371582b6f7eb8f8f665
|
||||
6f800f2ad2491122a28fb5623987c28cd9d8fae45e0ab205cff7635c83fe993a83b0f
|
||||
b2c1c85e599f0a33bd65a7ef
|
||||
KE3: 37de6eb166462dd8d36a6f0c75bbe826856cf6f7f067935aaf5fddaeb6e56935
|
||||
e8f1b53af96d5194dd49cb2438801745597affd3af7508f260746573d42144bd
|
||||
export_key: cb43c5c131fc4ee3c72a9c5a664a0137d46088c58cf24de4408e838d8
|
||||
1b743f6e1b9516cdc307775c45d3c70d3a446180782cb4a7dea4be5777b1934a78c11
|
||||
e1
|
||||
session_key: a40fa034f8220e18c1991f981655e8255009d62a596a579f08fd476a
|
||||
08cca7d66189a19e68f180e520de10ee841ab4e4f1a61291468429f093776f0bc8663
|
||||
528
|
||||
f356ee5de37881533f10397bcd84d354454f08b6c37449cf70cac0babb85d5302dc59
|
||||
a0ae16b2e54865642b8bb985f48444d49ad89a6a0707dd46c2d53b8b73dff46ac7176
|
||||
a6167f39818f605e3c39d22c
|
||||
KE3: b9487ca4b1308ce593d765739992e19c10d63c47f4f2d3eb4bfd0ffa101b6959
|
||||
114b4f6051305652e0f48ad219a696f3f12fad685f8d6e371dddc10fda2ec87e
|
||||
export_key: 258d525e93a07c17dd9e41afc4fbfe316152afad02c54a6d3d201fd77
|
||||
487903143ca2ef27718a1e48b2ade5dc614b027b8a46fd334b701df5d385aaef2b1bd
|
||||
16
|
||||
session_key: 021c0c3f15940f3e898f2925949aa8bc262248fae7b9ed7d33a2900e
|
||||
866548ed24760c2244a2c14bfc196a00ffd66ebf54839850b101bc5e617c37ccad45a
|
||||
68a
|
||||
~~~
|
||||
|
||||
### OPAQUE-3DH Real Test Vector 3
|
||||
@@ -303,20 +303,20 @@ cd15c478
|
||||
#### Intermediate Values
|
||||
|
||||
~~~
|
||||
client_public_key: 03c84a1dc96d2b896f20b390e75ae7e5ebedbb4db6c6cc9a78
|
||||
96e3c5d5f280e7ab
|
||||
auth_key: 9a6ce467dca8841cb0f706bfd83f39cc8e855d000d982554af799acc33d
|
||||
8354e
|
||||
randomized_pwd: d8a0060fa0d6118cf89fe9df92a9b65dd1b0dd86cccbdee067926
|
||||
7dce6f50e3a
|
||||
client_public_key: 030f9b896400f6efd57c69a41b05ffedc456f041cb54a2ab56
|
||||
8f5595c586070708
|
||||
auth_key: 4e01ca008eb4f84b8cee1b84b3abfaeb4f2c7fb41d2c8ad0f4fe89d74e6
|
||||
f0fc5
|
||||
randomized_pwd: c741d0a042e653ee4ccf24648aee4e3b4c500cc28feb3a72eea0f
|
||||
24f69006693
|
||||
envelope: 2527e48c983deeb54c9c6337fdd9e120de85343dc7887f00248f1acacc4
|
||||
a8319bb19ce6d364d86bd95a1516a49e288e0e013a197609e1de0b4e9e5950ade9c13
|
||||
handshake_secret: 3f11e9bb0233a88d5c00f236485058ebcbfd24180d0b8f7f078
|
||||
e8b88fa8a1c04
|
||||
server_mac_key: 7d82030842afc175e1a0fbddceba0e0e53102bf170ee394419d2b
|
||||
fdefefda358
|
||||
client_mac_key: a605eb6d2e72308f29fc1d1709a683aaa5d09e775134bded0deae
|
||||
e17dccaa9a1
|
||||
a83190f798f947d61d060cb102e5eeb9bd698bec5d1e1b6788860ec7c2d2e590121b0
|
||||
handshake_secret: 78bedd3ee950e1795ddeca4e0d4f4267a971ace52e6f876d9b2
|
||||
c8a349ec2be2a
|
||||
server_mac_key: c8e62b9aee6ae6e2199db70f16631a302e9269f27d5f6ef954572
|
||||
f8ca05f8d01
|
||||
client_mac_key: 31e3581fcfbb7d6b10b5cf78399fb844ab7afe42cf94f8b72178a
|
||||
1618711bb25
|
||||
oprf_key: d153d662a1e7dd4383837aa7125685d2be6f8041472ecbfd610e46952a6
|
||||
a24f1
|
||||
~~~
|
||||
@@ -324,32 +324,32 @@ a24f1
|
||||
#### Output Values
|
||||
|
||||
~~~
|
||||
registration_request: 0325768a660df0c15f6f2a1dcbb7efd4f1c92702401edf3
|
||||
e2f0742c8dce85d5fa8
|
||||
registration_response: 03de5c8f7d8ea7fd9590b0c8321b5f508bb8f49bbff83c
|
||||
5449ef50d66bf3e93892025b95a6add1f2f3d038811b5ad3494bed73b1e2500d8dade
|
||||
registration_request: 037aa042e317344246ebb94c38fe9989e01f7265413ade1
|
||||
f7ffaa706a81f58cf19
|
||||
registration_response: 03c0b3e621cadf1a56aa48305e3101efedb6248157708c
|
||||
7ba70af396fa62d29bf7025b95a6add1f2f3d038811b5ad3494bed73b1e2500d8dade
|
||||
c592d88406e25c2f2
|
||||
registration_upload: 03c84a1dc96d2b896f20b390e75ae7e5ebedbb4db6c6cc9a
|
||||
7896e3c5d5f280e7aba453596f5b719f2cf3c0982ebd2466a8442f3a98d9dcfe420b3
|
||||
5acb7cd8d0e592527e48c983deeb54c9c6337fdd9e120de85343dc7887f00248f1aca
|
||||
cc4a8319bb19ce6d364d86bd95a1516a49e288e0e013a197609e1de0b4e9e5950ade9
|
||||
c13
|
||||
KE1: 03884e56429f1ee53559f2e244392eb8f994fd46c8fd9ffdd24ac5a7af963a66
|
||||
3b967fcded96ed46986e60fcbdf985232639f537377ca3fcf07ad489956b2e9019033
|
||||
registration_upload: 030f9b896400f6efd57c69a41b05ffedc456f041cb54a2ab
|
||||
568f5595c5860707085e76cb3c849637cfd386d9cc762050a476a58da7c24b8a39084
|
||||
4689d8d6482bd2527e48c983deeb54c9c6337fdd9e120de85343dc7887f00248f1aca
|
||||
cc4a83190f798f947d61d060cb102e5eeb9bd698bec5d1e1b6788860ec7c2d2e59012
|
||||
1b0
|
||||
KE1: 0320fee3e9c08dfd30d00ce524cee6595d9bd7387629efa0cb9eba1ba82ec465
|
||||
13967fcded96ed46986e60fcbdf985232639f537377ca3fcf07ad489956b2e9019033
|
||||
58b4eae039953116889466bfddeb40168e39ed83809fd5f0d5f2de9c5234398
|
||||
KE2: 0225dbce19cf48eb908d66d0e955d0fe7d0f67d09bb0362154c7316d69700e23
|
||||
29cb792f3657240ce5296dd5633e7333531009c11ee6ab46b6111f156d96a160b268f
|
||||
4a82c2b61a752672a3e322b6b8580c1a2c76fad4563d06c12a27146f73dbb5267ca8b
|
||||
b86a83d0b902b97ac14d12501697300815c5d5fdc262830a351bb4416baceb16938e6
|
||||
cfd021f43dee80b9bc400304a4398480e195bc51b3bcc186ff0bf8018e88ecfc53891
|
||||
KE2: 03f629c1a3a5a3dc83af63c52d3bd58bbd78d5054caee7731381e967a7c381fa
|
||||
20cb792f3657240ce5296dd5633e7333531009c11ee6ab46b6111f156d96a160b22c1
|
||||
7f819537c821604229b8c07798c56f14b5104729a1336f153510f58ea921758f8a486
|
||||
13ec4ee3e5675dc8be14776c0bb6458bf0d3f76dd24af8b43b49c8fbfcb5229c0bbe3
|
||||
a37c440bdca76ce404b215ceb8842e95e81138416e161ea02c2648018e88ecfc53891
|
||||
529278c47239f8fe6f1be88972721898ef81cc0a76a0b5500242bc29993976185dacf
|
||||
6be815cbfa923aac80fad8b7f020c9d4f18e0b6867a17c4af032f0221800fec352a2b
|
||||
ec9ddb2dd8b91a087aa51c7fbbaf5efcbbea52fe
|
||||
KE3: eb86a68c5e8812293d1da4a60e499236ffdffb34b29f6f8f0ac46979f07b1ef4
|
||||
export_key: b755602f5d0a8c2118f38608a98cf08f20adadf5ef759cea8e246e5ed
|
||||
5bf95c3
|
||||
session_key: 08b539a036c888da87a25205c9c386f382bc53b098dae42f88f2320c
|
||||
48f1a3dd
|
||||
6be815cbfa923aac80fad8b7f020c9d4f18e0b6867a1764573de6cf3b1b7737e7e56a
|
||||
181fe0ec8754940adce33c4712bd35e7e9e08e7c
|
||||
KE3: d9108b70e4ff4955911162ed1cec6df65c880aad120bbf10fd7f32eea71b1a04
|
||||
export_key: 086cd26a64f469f2d22ab0b5f0c524b10321c4019018b004d0f8383c0
|
||||
24059be
|
||||
session_key: 36d1125dbf5ea45568e586645841efb6c5f53d357cdffb79edf1bb8d
|
||||
b0b843a9
|
||||
~~~
|
||||
|
||||
### OPAQUE-3DH Real Test Vector 4
|
||||
@@ -410,20 +410,20 @@ blind_login: 4308682dc1bdab92ff91bb1a5fc5bc084223fe4369beddca3f1640a6
|
||||
#### Intermediate Values
|
||||
|
||||
~~~
|
||||
client_public_key: 03a12f7047c8a1774a745520b2eaac995687fbb6212a418f9c
|
||||
1696d4186278eaa3
|
||||
auth_key: 2461460e02dde8a10c98e2911d4d5a3be0bd85f095064ade2f3a0ae79a4
|
||||
89b07
|
||||
randomized_pwd: 3d990218aab34ca0137bbbb298adcf585d4495ae843eddcbe3ca8
|
||||
f969b690676
|
||||
client_public_key: 03ce71710d0d366e44e4a7e92cb111fc41353d4244cac1ce4d
|
||||
8a622acaab9effc6
|
||||
auth_key: b894fa35f63413029fcc70e80a0d1b59d1c90c3c255bfb11cf7b58fb136
|
||||
d2aee
|
||||
randomized_pwd: 0588794becaf8f5fee7921cb467e4ce8b3c048e7b42d815ed306d
|
||||
ef278c231d3
|
||||
envelope: 75c245690f9669a9af5699e8b23d6d1fa9e697aeb4526267d942b842e44
|
||||
26e423d452786ba80be94bd8ebe643394d1a07e745a07e97b37a88b585b8afd6ce3cb
|
||||
handshake_secret: 586e927091452c797e0eb69fc90840f4c1923a6852834644c5f
|
||||
47cc8b5810d55
|
||||
server_mac_key: 09f90fb15227c185ba6102b797251d32f6bfaec56b218743ba4bb
|
||||
c64696f9734
|
||||
client_mac_key: 7612361b97d074852344ee92ecfe154b93241e696808438745d4c
|
||||
b4f5b8513fb
|
||||
26e42cb65c94629db9811649cd4f3ff92e5d2c67f7486203ea5e471f2655f363f9f19
|
||||
handshake_secret: 8a2547abef351fc1f94fb19a886c2e5ca16aba3b2bfe0b4a8cc
|
||||
086dd47b62c08
|
||||
server_mac_key: fa7c99e15ca1036738b9b48799515be78e471a2d06c3c3920d6a3
|
||||
703d11c0360
|
||||
client_mac_key: d480fde6de5e91a08179d9780bf6db0d1b959ae2fa394c09acdc6
|
||||
07b993410c2
|
||||
oprf_key: f14e1fc34ba1218bfd3f7373f036889bf4f35a8fbc9e8c9c07ccf2d2388
|
||||
79d9c
|
||||
~~~
|
||||
@@ -431,32 +431,32 @@ oprf_key: f14e1fc34ba1218bfd3f7373f036889bf4f35a8fbc9e8c9c07ccf2d2388
|
||||
#### Output Values
|
||||
|
||||
~~~
|
||||
registration_request: 02792b0f4670aced5970a68b01bb951004ccad962159be4
|
||||
b6783170c9ad68f6052
|
||||
registration_response: 02101f7b9999e363b44dfa946eaad9930fda88d53632aa
|
||||
701778747b6a411a071c029a2c6097fbbcf3457fe3ff7d4ef8e89dab585a67dfed090
|
||||
registration_request: 02baa002c856f4b0d49542dcb1391f240f836178702f835
|
||||
819fd221bcf9b6e9eec
|
||||
registration_response: 03864f4590c09b4c4155f0cbb731c5aab554ab1bc930c3
|
||||
28e7a58bd6227933d54f029a2c6097fbbcf3457fe3ff7d4ef8e89dab585a67dfed090
|
||||
5c9f104d909138bae
|
||||
registration_upload: 03a12f7047c8a1774a745520b2eaac995687fbb6212a418f
|
||||
9c1696d4186278eaa37b6e2a7531d9ca9a324ac5c1a02303f00175c41646a873441a5
|
||||
eb69dcbec4ea975c245690f9669a9af5699e8b23d6d1fa9e697aeb4526267d942b842
|
||||
e4426e423d452786ba80be94bd8ebe643394d1a07e745a07e97b37a88b585b8afd6ce
|
||||
3cb
|
||||
KE1: 02fe96fc48d9fc921edd8e92ada581cbcc2a65e30962d0002ea5242f5baf627f
|
||||
f646498f95ec7986f0602019b3fbb646db87a2fdbc12176d4f7ab74fa5fadace6002a
|
||||
registration_upload: 03ce71710d0d366e44e4a7e92cb111fc41353d4244cac1ce
|
||||
4d8a622acaab9effc66c5d2844e32ed930c56080fa523c15ec6d85f7db1bbd02c4692
|
||||
14b31e27f6c5775c245690f9669a9af5699e8b23d6d1fa9e697aeb4526267d942b842
|
||||
e4426e42cb65c94629db9811649cd4f3ff92e5d2c67f7486203ea5e471f2655f363f9
|
||||
f19
|
||||
KE1: 038469dadcb23317fa577317079c82bad1e20be41c783cd0ecad6bef3de1b16b
|
||||
1446498f95ec7986f0602019b3fbb646db87a2fdbc12176d4f7ab74fa5fadace6002a
|
||||
9f857ad3eabe09047049e8b8cee72feea2acb7fc487777c0b22d3add6a0e0c0
|
||||
KE2: 03463f69fc22bfa666c55bd38319addcf5816f063ec5ae9fdeb7e572603c6698
|
||||
025947586f69259e0708bdfab794f689eec14c7deb7edde68c81645156cf278f219cb
|
||||
3882d08a0617909c1a9f545dace3d56b5034d8025220e0280d5d541eb22ade140fa11
|
||||
663bd0a4c787203b93e423f431b3702ffcc635919dcf0d22520d90596fccdef52f3ca
|
||||
c75d2804a96d1521b78205c47c998cdb4aafcb7cce4c174671423581ac468101aee52
|
||||
KE2: 036297ebd0b53dabaae6377cb1c3ba1bdd942a67a5ce019b363f26cd11ae3707
|
||||
ac5947586f69259e0708bdfab794f689eec14c7deb7edde68c81645156cf278f21308
|
||||
4ce22d007db399a17af864b5ea826f4086f3d477ce236cacf7867de174692940b103b
|
||||
367ccb8b5aee6ef352079bf95c5961442cf400432de4d904815d1a8a20f64f3e8447b
|
||||
82c27f4c9b798769db0fb5ab8d29ea0ee54c1e371105388a7ae7c581ac468101aee52
|
||||
8cc6b69daac7a90de8837d49708e76310767cbe4af18594d022aa8746ab4329d59129
|
||||
6652d44f6dfb04470103311bacd7ad51060ef5abac41ba38a2e46ce2cfd59c6dfdd1e
|
||||
77758505d944b28e753a7254bac79302947dc7d0
|
||||
KE3: 2ae94c682a2bc4c89eb16c395dc09d2b14d216dee0e59f34c317f5a6d8bbc717
|
||||
export_key: 04f3100265180b083abbd84109f5ed963481eb78a5d377e888810217f
|
||||
fb8af04
|
||||
session_key: 7a0a42051497621e659270552be01baadddd1ee829f802891535a3fb
|
||||
ac2a33ec
|
||||
6652d44f6dfb04470103311bacd7ad51060ef5abac41bfa6b8e732462d3de6bdb3ef3
|
||||
edcf4595b478a6704d578fde4eaf922e1c1e8504
|
||||
KE3: cd11b70f1ed59d101ec20a73745d3d654c3772236ed2c365a730ef8ee51da6d2
|
||||
export_key: 8e1eb57bcde2d58d805b16fa045811679c68b0ec2817b9ac61786786a
|
||||
9032837
|
||||
session_key: b1f3da97388d6171719c3e2281e88da75b68d6945189f460db841cc6
|
||||
92f7e164
|
||||
~~~
|
||||
|
||||
## Fake Test Vectors {#fake-vectors}
|
||||
@@ -509,7 +509,7 @@ server_private_keyshare: a4abffe3bef8082b78323ea4507fbb0ce8105ca62b38
|
||||
masking_key: 077adba76f768fd0979f8dc006ca297e7954ebf0e81a893021ee24ac
|
||||
c35e1a3f4b5e0366c15771133082ec21035ae0ef0d8bcd0e59d26775ae953b9552fdf
|
||||
bf2
|
||||
KE1: 1ef5fc13fa7695e81b5fcadf57eb49a579b10e4f51bbee11afb278608592456b
|
||||
KE1: 88303c5318f93d39bb8afde6df62593869ba4eec265b980e3843c013401e6c5a
|
||||
8837b6c0709160251cbebe0d55e4423554c45da7a8952367cf336eb623379e80dae2f
|
||||
1e0cd79b733131d499fb9e77efe0f235d73c1f920bdc5816259ad3a7429
|
||||
~~~
|
||||
@@ -517,16 +517,16 @@ KE1: 1ef5fc13fa7695e81b5fcadf57eb49a579b10e4f51bbee11afb278608592456b
|
||||
#### Output Values
|
||||
|
||||
~~~
|
||||
KE2: 02648d7558231b92265efe08ec0b3dec70e596e36ea6c70ceae961411bf8f328
|
||||
KE2: 8a003351892efcf8615128a241e2bf091433fab5a080d7512b156f53e8602a20
|
||||
7cb33db5ba8082e4f4bfb830e8e3f525b0ddcb70469b34224758d725ce53ac76094c0
|
||||
aa800d9a0884392e4efbc0479e3cb84a38c9ead879f1ff755ad762c06812b9858f82c
|
||||
9722acc61b8eb1d156bc994839bf9ed8a760615258d23e0f94fa2cffadc655ed0d6ff
|
||||
6914066427366019d4e6989b65d13e38e8edc5ae6f82aa1b6a46bfe6ca0256c64d0cf
|
||||
db50a3eb7676e1d212e155e152e3bbc9d1fae3c679aacae1f4fee4ee4ba509fda550e
|
||||
a0421a85762305b1db20e37f4539b2327d37b805e5c0ac2904c7d9bf38f99e0050594
|
||||
e484b4d8ded8038ef6e0c141a985fa6b35afc0c330be0512ba1eace7c1cae0b807f01
|
||||
6f2a67b604008b270f3e41a8fb3d54084b62510495baa0309a993a48cf2110cfe2555
|
||||
33047291134a010c13509ba1
|
||||
e484b4d8ded8038ef6e0c141a985fa6b35ad4627117ba6a8cfe2a7c9d100800a62c84
|
||||
aacc83ed786d722921ee7037abf71b4af7381cdc3d40c4d9e4fc9f6dc2bb2fc15c8e3
|
||||
aa9eca8a83332841dda4524f
|
||||
~~~
|
||||
|
||||
### OPAQUE-3DH Fake Test Vector 2
|
||||
@@ -575,21 +575,21 @@ server_private_keyshare: e8c25741b201c2ba00abe390e5a3933a75efdb71b50e
|
||||
1e0087cc7235f6f9448a
|
||||
masking_key: 5bb4d884375d7dcbd562a62190cc569ccc809cff9d5aa5e176d48e96
|
||||
46b558eb
|
||||
KE1: 031ac7e5c8099fcb7de5ad5b6cf33ff53078dbee1da64f15f6cd53b2afe6e332
|
||||
06a91c9485d74c9010185f462ce1eec52f588a8e392f36915849b6bfcb6bd5b904037
|
||||
KE1: 0320dd7cff999858fb63be5d11db9c3fafbacbedb775303324d8859bfb31f6dc
|
||||
dba91c9485d74c9010185f462ce1eec52f588a8e392f36915849b6bfcb6bd5b904037
|
||||
6a35db8f7e582569dba2e573c4af1462f91c59a9bdee253ed13f60108746252
|
||||
~~~
|
||||
|
||||
#### Output Values
|
||||
|
||||
~~~
|
||||
KE2: 02ed3cb4182cb2c2659d6c1d88014e821ea4fc00de1aca987fae5483f5f8aa59
|
||||
d021cd364318a92b2afbfccea5d80d337f07defe40d92673a52f3844058f5d949a604
|
||||
KE2: 03cac8c1654bba83a122227e503e5e5d1a094def98d6835be289421cdc08d549
|
||||
a121cd364318a92b2afbfccea5d80d337f07defe40d92673a52f3844058f5d949a604
|
||||
39294e7567fc29643e0d5c8799d0dffbbfc8609558b982012fa90aef2ce52b1ffdd8f
|
||||
96bda49f5306ae346cd745812d3a953ff94712e4ed0acc67c99b432860e337fe3234b
|
||||
ba88415ac55368b938106cca4049b5c13496fe167d3a092bd990e2b772c1eb569cc2b
|
||||
57741bf3be630e377c8245b11d0b6ad1fe1d606490c2720802a59205c836a2ab86e19
|
||||
dbd9a417818052179e9a5c99221e2d1d8a780dfe4734dc9b9b3f64e5b3572a8f05f68
|
||||
93b0fa4dd12fba85ea99c8760b8011321bc37263
|
||||
dbd9a417818052179e9a5c99221e2d1d8a780dfe4734d04a0d4911decc97ece7f24af
|
||||
58f767090bf16677af9468a4026efbab99877399
|
||||
~~~
|
||||
"#;
|
||||
|
||||
+3
-1
@@ -5,7 +5,9 @@
|
||||
// License, Version 2.0 found in the LICENSE-APACHE file in the root directory
|
||||
// of this source tree.
|
||||
|
||||
use alloc::string::String;
|
||||
use std::string::{String, ToString};
|
||||
use std::vec::Vec;
|
||||
use std::{format, vec};
|
||||
|
||||
pub(crate) fn rfc_to_json(input: &str) -> String {
|
||||
format!("{{\n{}\n}}", parse_vector_types(input))
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::{
|
||||
ciphersuite::CipherSuite,
|
||||
envelope::EnvelopeLen,
|
||||
errors::*,
|
||||
hash::{OutputSize, ProxyHash},
|
||||
key_exchange::{
|
||||
group::KeGroup,
|
||||
traits::{Ke1MessageLen, Ke2MessageLen},
|
||||
@@ -23,12 +24,15 @@ use crate::{
|
||||
tests::mock_rng::CycleRng,
|
||||
*,
|
||||
};
|
||||
use alloc::{string::ToString, vec, vec::Vec};
|
||||
use core::ops::Add;
|
||||
use digest::FixedOutput;
|
||||
use generic_array::{typenum::Sum, ArrayLength};
|
||||
use digest::core_api::{BlockSizeUser, CoreProxy};
|
||||
use generic_array::{
|
||||
typenum::{IsLess, Le, NonZero, Sum, U256},
|
||||
ArrayLength,
|
||||
};
|
||||
use json::JsonValue;
|
||||
use voprf::group::Group;
|
||||
use std::{println, string::ToString, vec, vec::Vec};
|
||||
use voprf::Group;
|
||||
|
||||
#[allow(non_snake_case)]
|
||||
#[derive(Debug)]
|
||||
@@ -150,12 +154,15 @@ fn populate_test_vectors(values: &JsonValue) -> OpaqueTestVectorParameters {
|
||||
|
||||
fn get_password_file_bytes<CS: CipherSuite>(parameters: &OpaqueTestVectorParameters) -> Vec<u8>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
@@ -253,7 +260,12 @@ fn tests() -> Result<(), ProtocolError> {
|
||||
|
||||
fn test_registration_request<CS: CipherSuite>(
|
||||
tvs: &[OpaqueTestVectorParameters],
|
||||
) -> Result<(), ProtocolError> {
|
||||
) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
{
|
||||
for parameters in tvs {
|
||||
let mut rng = CycleRng::new(parameters.blind_registration.to_vec());
|
||||
let client_registration_start_result =
|
||||
@@ -270,6 +282,9 @@ fn test_registration_response<CS: CipherSuite>(
|
||||
tvs: &[OpaqueTestVectorParameters],
|
||||
) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// RegistrationResponse: KgPk + KePk
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
RegistrationResponseLen<CS>: ArrayLength<u8>,
|
||||
@@ -304,12 +319,15 @@ fn test_registration_upload<CS: CipherSuite>(
|
||||
tvs: &[OpaqueTestVectorParameters],
|
||||
) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
@@ -321,6 +339,7 @@ where
|
||||
let mut finish_registration_rng = CycleRng::new(parameters.envelope_nonce.to_vec());
|
||||
let result = client_registration_start_result.state.finish(
|
||||
&mut finish_registration_rng,
|
||||
¶meters.password,
|
||||
RegistrationResponse::deserialize(¶meters.registration_response).unwrap(),
|
||||
ClientRegistrationFinishParameters::new(
|
||||
Identifiers {
|
||||
@@ -353,6 +372,9 @@ where
|
||||
|
||||
fn test_ke1<CS: CipherSuite>(tvs: &[OpaqueTestVectorParameters]) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// CredentialRequest: KgPk + Ke1Message
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<Ke1MessageLen<CS>>,
|
||||
CredentialRequestLen<CS>: ArrayLength<u8>,
|
||||
@@ -383,28 +405,29 @@ where
|
||||
|
||||
fn test_ke2<CS: CipherSuite>(tvs: &[OpaqueTestVectorParameters]) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<NonceLen>,
|
||||
Sum<<CS::OprfGroup as Group>::ElemLen, NonceLen>: ArrayLength<u8> + Add<MaskedResponseLen<CS>>,
|
||||
CredentialResponseWithoutKeLen<CS>: ArrayLength<u8>,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message
|
||||
CredentialResponseWithoutKeLen<CS>: Add<Ke2MessageLen<CS>>,
|
||||
@@ -467,10 +490,12 @@ where
|
||||
|
||||
fn test_ke3<CS: CipherSuite>(tvs: &[OpaqueTestVectorParameters]) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
for parameters in tvs {
|
||||
@@ -485,6 +510,7 @@ where
|
||||
ClientLogin::<CS>::start(&mut client_login_start_rng, ¶meters.password)?;
|
||||
|
||||
let client_login_finish_result = client_login_start_result.state.finish(
|
||||
¶meters.password,
|
||||
CredentialResponse::<CS>::deserialize(¶meters.KE2)?,
|
||||
ClientLoginFinishParameters::new(
|
||||
Some(¶meters.context.clone()),
|
||||
@@ -524,19 +550,21 @@ fn test_server_login_finish<CS: CipherSuite>(
|
||||
tvs: &[OpaqueTestVectorParameters],
|
||||
) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// Envelope: Nonce + Hash
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
EnvelopeLen<CS>: ArrayLength<u8>,
|
||||
// RegistrationUpload: (KePk + Hash) + Envelope
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
<CS::KeGroup as KeGroup>::PkLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<<CS::KeGroup as KeGroup>::PkLen, OutputSize<CS::Hash>>:
|
||||
ArrayLength<u8> + Add<EnvelopeLen<CS>>,
|
||||
RegistrationUploadLen<CS>: ArrayLength<u8>,
|
||||
// ServerRegistration = RegistrationUpload
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
{
|
||||
for parameters in tvs {
|
||||
@@ -591,10 +619,12 @@ fn test_fake_vectors<CS: CipherSuite>(
|
||||
tvs: &[OpaqueTestVectorParameters],
|
||||
) -> Result<(), ProtocolError>
|
||||
where
|
||||
<CS::Hash as CoreProxy>::Core: ProxyHash,
|
||||
<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess<U256>,
|
||||
Le<<<CS::Hash as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero,
|
||||
// MaskedResponse: (Nonce + Hash) + KePk
|
||||
NonceLen: Add<<CS::Hash as FixedOutput>::OutputSize>,
|
||||
Sum<NonceLen, <CS::Hash as FixedOutput>::OutputSize>:
|
||||
ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
NonceLen: Add<OutputSize<CS::Hash>>,
|
||||
Sum<NonceLen, OutputSize<CS::Hash>>: ArrayLength<u8> + Add<<CS::KeGroup as KeGroup>::PkLen>,
|
||||
MaskedResponseLen<CS>: ArrayLength<u8>,
|
||||
// CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse
|
||||
<CS::OprfGroup as Group>::ElemLen: Add<NonceLen>,
|
||||
|
||||
Reference in New Issue
Block a user