Implement common traits
This commit is contained in:
+2
-2
@@ -15,7 +15,7 @@ slow-hash = ["argon2"]
|
||||
bench = []
|
||||
u64_backend = ["curve25519-dalek/u64_backend"]
|
||||
u32_backend = ["curve25519-dalek/u32_backend"]
|
||||
serialize = ["serde", "base64"]
|
||||
serialize = ["serde", "base64", "generic-array/serde", "curve25519-dalek/serde"]
|
||||
|
||||
[dependencies]
|
||||
argon2 = { version = "0.2", optional = true }
|
||||
@@ -28,7 +28,7 @@ generic-bytes = { version = "0.1.0" }
|
||||
hkdf = "0.11.0"
|
||||
hmac = "0.11.0"
|
||||
rand = "0.8"
|
||||
serde = { version = "1", optional = true }
|
||||
serde = { version = "1", features = ["derive"], optional = true }
|
||||
subtle = { version = "2.3.0", default-features = false }
|
||||
thiserror = "1.0.22"
|
||||
zeroize = { version = "1.1.1", features = ["zeroize_derive"] }
|
||||
|
||||
+3
-1
@@ -61,7 +61,7 @@ fn recover_keys_internal<CS: CipherSuite>(
|
||||
Ok(client_static_keypair)
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, PartialEq, Zeroize)]
|
||||
#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq, Zeroize)]
|
||||
#[zeroize(drop)]
|
||||
pub(crate) enum InnerEnvelopeMode {
|
||||
Zero = 0,
|
||||
@@ -105,6 +105,8 @@ impl<CS: CipherSuite> Clone for Envelope<CS> {
|
||||
}
|
||||
}
|
||||
|
||||
impl_debug_eq_hash_for!(struct Envelope<CS: CipherSuite>, [mode, nonce, hmac]);
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -0,0 +1,97 @@
|
||||
macro_rules! impl_debug_eq_hash_for {
|
||||
(struct $name:ident$(<$($gen:ident$(: $bound:tt)?),+$(,)?>)?, [$field1:ident$(, $field2:ident)*$(,)?]$(, )?$([$($type:ty),+$(,)?]$(,)?)?) => {
|
||||
impl$(<$($gen$(: $bound)?),+>)? std::fmt::Debug for $name$(<$($gen),+>)?
|
||||
$(where $($type: std::fmt::Debug,)+)?
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("$name")
|
||||
.field("$field1", &self.$field1)
|
||||
$(.field("$field2", &self.$field2))*
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl$(<$($gen$(: $bound)?),+>)? Eq for $name$(<$($gen),+>)?
|
||||
$(where $($type: Eq,)+)?
|
||||
{}
|
||||
|
||||
impl$(<$($gen$(: $bound)?),+>)? PartialEq for $name$(<$($gen),+>)?
|
||||
$(where $($type: PartialEq,)+)?
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
PartialEq::eq(&self.$field1, &other.$field1)
|
||||
$(&& PartialEq::eq(&self.$field2, &other.$field2))*
|
||||
}
|
||||
}
|
||||
|
||||
impl$(<$($gen$(: $bound)?),+>)? std::hash::Hash for $name$(<$($gen),+>)?
|
||||
$(where $($type: std::hash::Hash,)+)?
|
||||
{
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
std::hash::Hash::hash(&self.$field1, state);
|
||||
$(std::hash::Hash::hash(&self.$field2, state);)*
|
||||
}
|
||||
}
|
||||
};
|
||||
(tuple $name:ident$(<$($gen:ident$(: $bound:tt)?),+$(,)?>)?, [$field1:tt$(, $field2:tt)*$(,)?]$(, )?$([$($type:ty),+$(,)?]$(,)?)?) => {
|
||||
impl$(<$($gen$(: $bound)?),+>)? std::fmt::Debug for $name$(<$($gen),+>)?
|
||||
$(where $($type: std::fmt::Debug,)+)?
|
||||
{
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_tuple("$name")
|
||||
.field(&self.$field1)
|
||||
$(.field(&self.$field2))*
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl$(<$($gen$(: $bound)?),+>)? Eq for $name$(<$($gen),+>)?
|
||||
$(where $($type: Eq,)+)?
|
||||
{}
|
||||
|
||||
impl$(<$($gen$(: $bound)?),+>)? PartialEq for $name$(<$($gen),+>)?
|
||||
$(where $($type: PartialEq,)+)?
|
||||
{
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
PartialEq::eq(&self.$field1, &other.$field1)
|
||||
$(&& PartialEq::eq(&self.$field2, &other.$field2))*
|
||||
}
|
||||
}
|
||||
|
||||
impl$(<$($gen$(: $bound)?),+>)? std::hash::Hash for $name$(<$($gen),+>)?
|
||||
$(where $($type: std::hash::Hash,)+)?
|
||||
{
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
std::hash::Hash::hash(&self.$field1, state);
|
||||
$(std::hash::Hash::hash(&self.$field2, state);)*
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! impl_clone_for {
|
||||
(struct $name:ident$(<$($gen:ident$(: $bound:tt)?),+$(,)?>)?, [$field1:ident$(, $field2:ident)*$(,)?]$(, )?$([$($type:ty),+$(,)?]$(,)?)?) => {
|
||||
impl$(<$($gen$(: $bound)?),+>)? Clone for $name$(<$($gen),+>)?
|
||||
$(where $($type: Clone,)+)?
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
$field1: self.$field1.clone(),
|
||||
$($field2: self.$field2.clone(),)*
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
(tuple $name:ident$(<$($gen:ident$(: $bound:tt)?),+$(,)?>)?, [$field1:tt$(, $field2:tt)*$(,)?]$(, )?$([$($type:ty),+$(,)?]$(,)?)?) => {
|
||||
impl$(<$($gen$(: $bound)?),+>)? Clone for $name$(<$($gen),+>)?
|
||||
$(where $($type: Clone,)+)?
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self(
|
||||
self.$field1.clone(),
|
||||
$(self.$field2.clone(),)*
|
||||
)
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -207,7 +207,8 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
||||
}
|
||||
|
||||
/// The client state produced after the first key exchange message
|
||||
#[derive(PartialEq, Eq, Zeroize, Clone)]
|
||||
#[derive(PartialEq, Eq, Debug, Hash, Zeroize, Clone)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[zeroize(drop)]
|
||||
pub struct Ke1State {
|
||||
client_e_sk: PrivateKey,
|
||||
@@ -215,7 +216,8 @@ pub struct Ke1State {
|
||||
}
|
||||
|
||||
/// The first key exchange message
|
||||
#[derive(PartialEq, Eq, Clone)]
|
||||
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct Ke1Message {
|
||||
pub(crate) client_nonce: GenericArray<u8, NonceLen>,
|
||||
pub(crate) client_e_pk: PublicKey,
|
||||
@@ -272,7 +274,9 @@ impl FromBytes for Ke1Message {
|
||||
}
|
||||
}
|
||||
/// The server state produced after the second key exchange message
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serialize", serde(bound = ""))]
|
||||
pub struct Ke2State<HashLen: ArrayLength<u8>> {
|
||||
km3: GenericArray<u8, HashLen>,
|
||||
hashed_transcript: GenericArray<u8, HashLen>,
|
||||
@@ -315,7 +319,9 @@ impl<HashLen: ArrayLength<u8>> ToBytesWithPointers for Ke2State<HashLen> {
|
||||
}
|
||||
|
||||
/// The second key exchange message
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serialize", serde(bound = ""))]
|
||||
pub struct Ke2Message<HashLen: ArrayLength<u8>> {
|
||||
server_nonce: GenericArray<u8, NonceLen>,
|
||||
server_e_pk: PublicKey,
|
||||
@@ -398,7 +404,9 @@ type TripleDHDerivationResult<D> = (
|
||||
);
|
||||
|
||||
/// The third key exchange message
|
||||
#[derive(Clone)]
|
||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(feature = "serialize", serde(bound = ""))]
|
||||
pub struct Ke3Message<HashLen: ArrayLength<u8>> {
|
||||
mac: GenericArray<u8, HashLen>,
|
||||
}
|
||||
|
||||
+16
-4
@@ -35,13 +35,22 @@ pub trait SizedBytesExt: SizedBytes {
|
||||
impl<T> SizedBytesExt for T where T: SizedBytes {}
|
||||
|
||||
/// A Keypair trait with public-private verification
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct KeyPair<G> {
|
||||
pk: PublicKey,
|
||||
sk: PrivateKey,
|
||||
_g: PhantomData<G>,
|
||||
}
|
||||
|
||||
impl_clone_for!(
|
||||
struct KeyPair<G>,
|
||||
[pk, sk, _g],
|
||||
);
|
||||
impl_debug_eq_hash_for!(
|
||||
struct KeyPair<G>,
|
||||
[pk, sk, _g],
|
||||
);
|
||||
|
||||
// This can't be derived because of the use of a phantom parameter
|
||||
impl<G> Zeroize for KeyPair<G> {
|
||||
fn zeroize(&mut self) {
|
||||
@@ -154,7 +163,8 @@ impl<G: Group + Debug> KeyPair<G> {
|
||||
type KeyLen = U32;
|
||||
|
||||
/// A minimalist key type built around a \[u8; 32\]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Zeroize)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Zeroize)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
// Ensure Key material is zeroed after use.
|
||||
#[zeroize(drop)]
|
||||
#[repr(transparent)]
|
||||
@@ -181,7 +191,8 @@ impl Key {
|
||||
}
|
||||
|
||||
/// Wrapper around a Key to enforce that it's a private one.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Zeroize)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Zeroize)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
// Ensure Key material is zeroed after use.
|
||||
#[zeroize(drop)]
|
||||
#[repr(transparent)]
|
||||
@@ -208,7 +219,8 @@ impl SizedBytes for PrivateKey {
|
||||
}
|
||||
|
||||
/// Wrapper around a Key to enforce that it's a public one.
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Zeroize)]
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Zeroize)]
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
// Ensure Key material is zeroed after use.
|
||||
#[zeroize(drop)]
|
||||
#[repr(transparent)]
|
||||
|
||||
@@ -747,6 +747,8 @@ compile_error!(
|
||||
// Error types
|
||||
pub mod errors;
|
||||
|
||||
#[macro_use]
|
||||
mod impls;
|
||||
#[macro_use]
|
||||
mod serialization;
|
||||
|
||||
|
||||
+40
-18
@@ -46,6 +46,8 @@ impl<CS: CipherSuite> Clone for RegistrationRequest<CS> {
|
||||
}
|
||||
}
|
||||
|
||||
impl_debug_eq_hash_for!(struct RegistrationRequest<CS: CipherSuite>, [alpha], [CS::Group]);
|
||||
|
||||
impl<CS: CipherSuite> RegistrationRequest<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
@@ -90,6 +92,12 @@ impl<CS: CipherSuite> Clone for RegistrationResponse<CS> {
|
||||
}
|
||||
}
|
||||
|
||||
impl_debug_eq_hash_for!(
|
||||
struct RegistrationResponse<CS: CipherSuite>,
|
||||
[beta, server_s_pk],
|
||||
[CS::Group],
|
||||
);
|
||||
|
||||
impl<CS: CipherSuite> RegistrationResponse<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
@@ -136,16 +144,14 @@ pub struct RegistrationUpload<CS: CipherSuite> {
|
||||
pub(crate) client_s_pk: PublicKey,
|
||||
}
|
||||
|
||||
// Cannot be derived because it would require for CS to be Clone.
|
||||
impl<CS: CipherSuite> Clone for RegistrationUpload<CS> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
envelope: self.envelope.clone(),
|
||||
masking_key: self.masking_key.clone(),
|
||||
client_s_pk: self.client_s_pk.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_clone_for!(
|
||||
struct RegistrationUpload<CS: CipherSuite>,
|
||||
[envelope, masking_key, client_s_pk],
|
||||
);
|
||||
impl_debug_eq_hash_for!(
|
||||
struct RegistrationUpload<CS: CipherSuite>,
|
||||
[envelope, masking_key, client_s_pk],
|
||||
);
|
||||
|
||||
impl<CS: CipherSuite> RegistrationUpload<CS> {
|
||||
/// Serialization into bytes
|
||||
@@ -211,6 +217,15 @@ impl<CS: CipherSuite> Clone for CredentialRequest<CS> {
|
||||
}
|
||||
}
|
||||
|
||||
impl_debug_eq_hash_for!(
|
||||
struct CredentialRequest<CS: CipherSuite>,
|
||||
[alpha, ke1_message],
|
||||
[
|
||||
CS::Group,
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE1Message
|
||||
],
|
||||
);
|
||||
|
||||
impl<CS: CipherSuite> CredentialRequest<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
@@ -266,6 +281,15 @@ impl<CS: CipherSuite> Clone for CredentialResponse<CS> {
|
||||
}
|
||||
}
|
||||
|
||||
impl_debug_eq_hash_for!(
|
||||
struct CredentialResponse<CS: CipherSuite>,
|
||||
[beta, masking_nonce, masked_response, ke2_message],
|
||||
[
|
||||
CS::Group,
|
||||
<CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE2Message,
|
||||
],
|
||||
);
|
||||
|
||||
impl<CS: CipherSuite> CredentialResponse<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
@@ -336,14 +360,12 @@ pub struct CredentialFinalization<CS: CipherSuite> {
|
||||
pub(crate) ke3_message: <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE3Message,
|
||||
}
|
||||
|
||||
// Cannot be derived because it would require for CS to be Clone.
|
||||
impl<CS: CipherSuite> Clone for CredentialFinalization<CS> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
ke3_message: self.ke3_message.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_clone_for!(struct CredentialFinalization<CS: CipherSuite>, [ke3_message]);
|
||||
impl_debug_eq_hash_for!(
|
||||
struct CredentialFinalization<CS: CipherSuite>,
|
||||
[ke3_message],
|
||||
[<CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE3Message],
|
||||
);
|
||||
|
||||
impl<CS: CipherSuite> CredentialFinalization<CS> {
|
||||
/// Serialization into bytes
|
||||
|
||||
+42
-33
@@ -36,6 +36,7 @@ const STR_OPRF_KEY: &[u8] = b"OprfKey";
|
||||
// ============
|
||||
|
||||
/// The state elements the server holds upon setup
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
pub struct ServerSetup<CS: CipherSuite> {
|
||||
oprf_seed: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
keypair: KeyPair<CS::Group>,
|
||||
@@ -84,6 +85,16 @@ impl<CS: CipherSuite> ServerSetup<CS> {
|
||||
}
|
||||
}
|
||||
|
||||
// Cannot be derived because it would require for CS to be bound.
|
||||
impl_clone_for!(
|
||||
struct ServerSetup<CS: CipherSuite>,
|
||||
[oprf_seed, keypair, fake_keypair],
|
||||
);
|
||||
impl_debug_eq_hash_for!(
|
||||
struct ServerSetup<CS: CipherSuite>,
|
||||
[oprf_seed, oprf_seed, fake_keypair],
|
||||
);
|
||||
|
||||
// Registration
|
||||
// ============
|
||||
|
||||
@@ -93,14 +104,12 @@ pub struct ClientRegistration<CS: CipherSuite> {
|
||||
pub(crate) token: oprf::Token<CS::Group>,
|
||||
}
|
||||
|
||||
// Cannot be derived because it would require for CS to be Clone.
|
||||
impl<CS: CipherSuite> Clone for ClientRegistration<CS> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
token: self.token.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_clone_for!(struct ClientRegistration<CS: CipherSuite>, [token]);
|
||||
impl_debug_eq_hash_for!(
|
||||
struct ClientRegistration<CS: CipherSuite>,
|
||||
[token],
|
||||
[oprf::Token<CS::Group>],
|
||||
);
|
||||
|
||||
impl<CS: CipherSuite> ClientRegistration<CS> {
|
||||
/// Serialization into bytes
|
||||
@@ -306,12 +315,11 @@ impl<CS: CipherSuite> Clone for ServerRegistrationStartResult<CS> {
|
||||
/// The state elements the server holds to record a registration
|
||||
pub struct ServerRegistration<CS: CipherSuite>(RegistrationUpload<CS>);
|
||||
|
||||
// Cannot be derived because it would require for CS to be Clone.
|
||||
impl<CS: CipherSuite> Clone for ServerRegistration<CS> {
|
||||
fn clone(&self) -> Self {
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
impl_clone_for!(tuple ServerRegistration<CS: CipherSuite>, [0]);
|
||||
impl_debug_eq_hash_for!(
|
||||
tuple ServerRegistration<CS: CipherSuite>,
|
||||
[0],
|
||||
);
|
||||
|
||||
impl<CS: CipherSuite> ServerRegistration<CS> {
|
||||
/// Serialization into bytes
|
||||
@@ -377,6 +385,14 @@ impl_serialize_and_deserialize_for!(ServerRegistration);
|
||||
// =====
|
||||
|
||||
/// The state elements the client holds to perform a login
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
serde(bound(
|
||||
deserialize = "oprf::Token<CS::Group>: serde::Deserialize<'de>, <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE1State: serde::Deserialize<'de>",
|
||||
serialize = "oprf::Token<CS::Group>: serde::Serialize, <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE1State: serde::Serialize"
|
||||
))
|
||||
)]
|
||||
pub struct ClientLogin<CS: CipherSuite> {
|
||||
/// token containing the client's password and the blinding factor
|
||||
token: oprf::Token<CS::Group>,
|
||||
@@ -384,16 +400,12 @@ pub struct ClientLogin<CS: CipherSuite> {
|
||||
serialized_credential_request: Vec<u8>,
|
||||
}
|
||||
|
||||
// Cannot be derived because it would require for CS to be Clone.
|
||||
impl<CS: CipherSuite> Clone for ClientLogin<CS> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
token: self.token.clone(),
|
||||
ke1_state: self.ke1_state.clone(),
|
||||
serialized_credential_request: self.serialized_credential_request.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_clone_for!(struct ClientLogin<CS: CipherSuite>, [token, ke1_state, serialized_credential_request]);
|
||||
impl_debug_eq_hash_for!(
|
||||
struct ClientLogin<CS: CipherSuite>,
|
||||
[token, ke1_state, serialized_credential_request],
|
||||
[oprf::Token<CS::Group>, <CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE1State],
|
||||
);
|
||||
|
||||
impl<CS: CipherSuite> ClientLogin<CS> {
|
||||
/// Serialization into bytes
|
||||
@@ -627,15 +639,12 @@ pub struct ServerLogin<CS: CipherSuite> {
|
||||
_cs: PhantomData<CS>,
|
||||
}
|
||||
|
||||
// Cannot be derived because it would require for CS to be Clone.
|
||||
impl<CS: CipherSuite> Clone for ServerLogin<CS> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
ke2_state: self.ke2_state.clone(),
|
||||
_cs: PhantomData,
|
||||
}
|
||||
}
|
||||
}
|
||||
impl_clone_for!(struct ServerLogin<CS: CipherSuite>, [ke2_state, _cs]);
|
||||
impl_debug_eq_hash_for!(
|
||||
struct ServerLogin<CS: CipherSuite>,
|
||||
[ke2_state, _cs],
|
||||
[<CS::KeyExchange as KeyExchange<CS::Hash, CS::Group>>::KE2State],
|
||||
);
|
||||
|
||||
/// Optional parameters for server login start
|
||||
#[derive(Clone)]
|
||||
|
||||
+3
-1
@@ -12,12 +12,14 @@ use generic_array::GenericArray;
|
||||
use rand::{CryptoRng, RngCore};
|
||||
|
||||
/// Used to store the OPRF input and blinding factor
|
||||
#[derive(Clone)]
|
||||
pub struct Token<Grp: Group> {
|
||||
pub(crate) data: Vec<u8>,
|
||||
pub(crate) blind: Grp::Scalar,
|
||||
}
|
||||
|
||||
impl_clone_for!(struct Token<Grp: Group>, [data, blind]);
|
||||
impl_debug_eq_hash_for!(struct Token<Grp: Group>, [data, blind], [Grp::Scalar]);
|
||||
|
||||
static STR_VOPRF: &[u8] = b"VOPRF06-HashToGroup-";
|
||||
static STR_VOPRF_FINALIZE: &[u8] = b"VOPRF06-Finalize-";
|
||||
static MODE_BASE: u8 = 0x00;
|
||||
|
||||
Reference in New Issue
Block a user