Generic PublicKey and PrivateKey
This commit is contained in:
+4
-4
@@ -32,9 +32,9 @@ const NONCE_LEN: usize = 32;
|
|||||||
fn build_inner_envelope_internal<CS: CipherSuite>(
|
fn build_inner_envelope_internal<CS: CipherSuite>(
|
||||||
random_pwd: &[u8],
|
random_pwd: &[u8],
|
||||||
nonce: &[u8],
|
nonce: &[u8],
|
||||||
) -> Result<PublicKey, InternalPakeError> {
|
) -> Result<PublicKey<CS::Group>, InternalPakeError> {
|
||||||
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
||||||
let mut keypair_seed = vec![0u8; <PrivateKey as SizedBytes>::Len::to_usize()];
|
let mut keypair_seed = vec![0u8; <PrivateKey<CS::Group> as SizedBytes>::Len::to_usize()];
|
||||||
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalPakeError::HkdfError)?;
|
||||||
let client_static_keypair =
|
let client_static_keypair =
|
||||||
@@ -50,7 +50,7 @@ fn recover_keys_internal<CS: CipherSuite>(
|
|||||||
nonce: &[u8],
|
nonce: &[u8],
|
||||||
) -> Result<KeyPair<CS::Group>, InternalPakeError> {
|
) -> Result<KeyPair<CS::Group>, InternalPakeError> {
|
||||||
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
let h = Hkdf::<CS::Hash>::new(None, random_pwd);
|
||||||
let mut keypair_seed = vec![0u8; <PrivateKey as SizedBytes>::Len::to_usize()];
|
let mut keypair_seed = vec![0u8; <PrivateKey<CS::Group> as SizedBytes>::Len::to_usize()];
|
||||||
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
h.expand(&[nonce, STR_PRIVATE_KEY].concat(), &mut keypair_seed)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
.map_err(|_| InternalPakeError::HkdfError)?;
|
||||||
let client_static_keypair =
|
let client_static_keypair =
|
||||||
@@ -185,7 +185,7 @@ impl<CS: CipherSuite> Envelope<CS> {
|
|||||||
) -> Result<
|
) -> Result<
|
||||||
(
|
(
|
||||||
Self,
|
Self,
|
||||||
PublicKey,
|
PublicKey<CS::Group>,
|
||||||
GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||||
),
|
),
|
||||||
InternalPakeError,
|
InternalPakeError,
|
||||||
|
|||||||
+2
-2
@@ -30,7 +30,7 @@ pub trait Group: Copy + Sized + for<'a> Mul<&'a <Self as Group>::Scalar, Output
|
|||||||
/// The type of base field scalars
|
/// The type of base field scalars
|
||||||
type Scalar: Zeroize + Clone;
|
type Scalar: Zeroize + Clone;
|
||||||
/// The byte length necessary to represent scalars
|
/// The byte length necessary to represent scalars
|
||||||
type ScalarLen: ArrayLength<u8>;
|
type ScalarLen: ArrayLength<u8> + 'static;
|
||||||
/// Return a scalar from its fixed-length bytes representation
|
/// Return a scalar from its fixed-length bytes representation
|
||||||
fn from_scalar_slice(
|
fn from_scalar_slice(
|
||||||
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
scalar_bits: &GenericArray<u8, Self::ScalarLen>,
|
||||||
@@ -43,7 +43,7 @@ pub trait Group: Copy + Sized + for<'a> Mul<&'a <Self as Group>::Scalar, Output
|
|||||||
fn scalar_invert(scalar: &Self::Scalar) -> Self::Scalar;
|
fn scalar_invert(scalar: &Self::Scalar) -> Self::Scalar;
|
||||||
|
|
||||||
/// The byte length necessary to represent group elements
|
/// The byte length necessary to represent group elements
|
||||||
type ElemLen: ArrayLength<u8>;
|
type ElemLen: ArrayLength<u8> + 'static;
|
||||||
/// Return an element from its fixed-length bytes representation
|
/// Return an element from its fixed-length bytes representation
|
||||||
fn from_element_slice(
|
fn from_element_slice(
|
||||||
element_bits: &GenericArray<u8, Self::ElemLen>,
|
element_bits: &GenericArray<u8, Self::ElemLen>,
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ pub trait KeyExchange<D: Hash, G: Group> {
|
|||||||
l1_bytes: Vec<u8>,
|
l1_bytes: Vec<u8>,
|
||||||
l2_bytes: Vec<u8>,
|
l2_bytes: Vec<u8>,
|
||||||
ke1_message: Self::KE1Message,
|
ke1_message: Self::KE1Message,
|
||||||
client_s_pk: PublicKey,
|
client_s_pk: PublicKey<G>,
|
||||||
server_s_sk: PrivateKey,
|
server_s_sk: PrivateKey<G>,
|
||||||
id_u: Vec<u8>,
|
id_u: Vec<u8>,
|
||||||
id_s: Vec<u8>,
|
id_s: Vec<u8>,
|
||||||
context: Vec<u8>,
|
context: Vec<u8>,
|
||||||
@@ -43,8 +43,8 @@ pub trait KeyExchange<D: Hash, G: Group> {
|
|||||||
ke2_message: Self::KE2Message,
|
ke2_message: Self::KE2Message,
|
||||||
ke1_state: &Self::KE1State,
|
ke1_state: &Self::KE1State,
|
||||||
serialized_credential_request: &[u8],
|
serialized_credential_request: &[u8],
|
||||||
server_s_pk: PublicKey,
|
server_s_pk: PublicKey<G>,
|
||||||
client_s_sk: PrivateKey,
|
client_s_sk: PrivateKey<G>,
|
||||||
id_u: Vec<u8>,
|
id_u: Vec<u8>,
|
||||||
id_s: Vec<u8>,
|
id_s: Vec<u8>,
|
||||||
context: Vec<u8>,
|
context: Vec<u8>,
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ static STR_OPAQUE: &[u8] = b"OPAQUE-";
|
|||||||
pub struct TripleDH;
|
pub struct TripleDH;
|
||||||
|
|
||||||
impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
||||||
type KE1State = Ke1State;
|
type KE1State = Ke1State<G>;
|
||||||
type KE2State = Ke2State<<D as FixedOutput>::OutputSize>;
|
type KE2State = Ke2State<<D as FixedOutput>::OutputSize>;
|
||||||
type KE1Message = Ke1Message;
|
type KE1Message = Ke1Message<G>;
|
||||||
type KE2Message = Ke2Message<<D as FixedOutput>::OutputSize>;
|
type KE2Message = Ke2Message<G, <D as FixedOutput>::OutputSize>;
|
||||||
type KE3Message = Ke3Message<<D as FixedOutput>::OutputSize>;
|
type KE3Message = Ke3Message<<D as FixedOutput>::OutputSize>;
|
||||||
|
|
||||||
fn generate_ke1<R: RngCore + CryptoRng>(
|
fn generate_ke1<R: RngCore + CryptoRng>(
|
||||||
@@ -75,8 +75,8 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
|||||||
serialized_credential_request: Vec<u8>,
|
serialized_credential_request: Vec<u8>,
|
||||||
l2_bytes: Vec<u8>,
|
l2_bytes: Vec<u8>,
|
||||||
ke1_message: Self::KE1Message,
|
ke1_message: Self::KE1Message,
|
||||||
client_s_pk: PublicKey,
|
client_s_pk: PublicKey<G>,
|
||||||
server_s_sk: PrivateKey,
|
server_s_sk: PrivateKey<G>,
|
||||||
id_u: Vec<u8>,
|
id_u: Vec<u8>,
|
||||||
id_s: Vec<u8>,
|
id_s: Vec<u8>,
|
||||||
context: Vec<u8>,
|
context: Vec<u8>,
|
||||||
@@ -133,8 +133,8 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
|||||||
ke2_message: Self::KE2Message,
|
ke2_message: Self::KE2Message,
|
||||||
ke1_state: &Self::KE1State,
|
ke1_state: &Self::KE1State,
|
||||||
serialized_credential_request: &[u8],
|
serialized_credential_request: &[u8],
|
||||||
server_s_pk: PublicKey,
|
server_s_pk: PublicKey<G>,
|
||||||
client_s_sk: PrivateKey,
|
client_s_sk: PrivateKey<G>,
|
||||||
id_u: Vec<u8>,
|
id_u: Vec<u8>,
|
||||||
id_s: Vec<u8>,
|
id_s: Vec<u8>,
|
||||||
context: Vec<u8>,
|
context: Vec<u8>,
|
||||||
@@ -208,23 +208,44 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// The client state produced after the first key exchange message
|
/// The client state produced after the first key exchange message
|
||||||
#[derive(PartialEq, Eq, Debug, Hash, Zeroize, Clone)]
|
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[zeroize(drop)]
|
pub struct Ke1State<G> {
|
||||||
pub struct Ke1State {
|
client_e_sk: PrivateKey<G>,
|
||||||
client_e_sk: PrivateKey,
|
|
||||||
client_nonce: GenericArray<u8, NonceLen>,
|
client_nonce: GenericArray<u8, NonceLen>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl_clone_for!(
|
||||||
|
struct Ke1State<G>,
|
||||||
|
[client_e_sk, client_nonce],
|
||||||
|
);
|
||||||
|
impl_debug_eq_hash_for!(
|
||||||
|
struct Ke1State<G>,
|
||||||
|
[client_e_sk, client_nonce],
|
||||||
|
);
|
||||||
|
|
||||||
|
// This can't be derived because of the use of a generic parameter
|
||||||
|
impl<G> Zeroize for Ke1State<G> {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
self.client_e_sk.zeroize();
|
||||||
|
self.client_nonce.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G> Drop for Ke1State<G> {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// The first key exchange message
|
/// The first key exchange message
|
||||||
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
|
#[derive(PartialEq, Eq, Debug, Hash, Clone)]
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||||
pub struct Ke1Message {
|
pub struct Ke1Message<G> {
|
||||||
pub(crate) client_nonce: GenericArray<u8, NonceLen>,
|
pub(crate) client_nonce: GenericArray<u8, NonceLen>,
|
||||||
pub(crate) client_e_pk: PublicKey,
|
pub(crate) client_e_pk: PublicKey<G>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromBytes for Ke1State {
|
impl<G: Group> FromBytes for Ke1State<G> {
|
||||||
fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, PakeError> {
|
fn from_bytes<CS: CipherSuite>(bytes: &[u8]) -> Result<Self, PakeError> {
|
||||||
let nonce_len = NonceLen::to_usize();
|
let nonce_len = NonceLen::to_usize();
|
||||||
let checked_bytes = check_slice_size_atleast(bytes, KEY_LEN + nonce_len, "ke1_state")?;
|
let checked_bytes = check_slice_size_atleast(bytes, KEY_LEN + nonce_len, "ke1_state")?;
|
||||||
@@ -238,7 +259,7 @@ impl FromBytes for Ke1State {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToBytesWithPointers for Ke1State {
|
impl<G: Group> ToBytesWithPointers for Ke1State<G> {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
let output: Vec<u8> = [&self.client_e_sk.to_arr(), &self.client_nonce[..]].concat();
|
let output: Vec<u8> = [&self.client_e_sk.to_arr(), &self.client_nonce[..]].concat();
|
||||||
output
|
output
|
||||||
@@ -249,20 +270,20 @@ impl ToBytesWithPointers for Ke1State {
|
|||||||
vec![
|
vec![
|
||||||
(
|
(
|
||||||
self.client_e_sk.as_ptr(),
|
self.client_e_sk.as_ptr(),
|
||||||
<PrivateKey as SizedBytes>::Len::to_usize(),
|
<PrivateKey<G> as SizedBytes>::Len::to_usize(),
|
||||||
),
|
),
|
||||||
(self.client_nonce.as_ptr(), NonceLen::to_usize()),
|
(self.client_nonce.as_ptr(), NonceLen::to_usize()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ToBytes for Ke1Message {
|
impl<G: Group> ToBytes for Ke1Message<G> {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
[&self.client_nonce[..], &self.client_e_pk.to_arr()].concat()
|
[&self.client_nonce[..], &self.client_e_pk.to_arr()].concat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromBytes for Ke1Message {
|
impl<G: Group> FromBytes for Ke1Message<G> {
|
||||||
fn from_bytes<CS: CipherSuite>(ke1_message_bytes: &[u8]) -> Result<Self, PakeError> {
|
fn from_bytes<CS: CipherSuite>(ke1_message_bytes: &[u8]) -> Result<Self, PakeError> {
|
||||||
let nonce_len = NonceLen::to_usize();
|
let nonce_len = NonceLen::to_usize();
|
||||||
let checked_nonce =
|
let checked_nonce =
|
||||||
@@ -323,9 +344,9 @@ impl<HashLen: ArrayLength<u8>> ToBytesWithPointers for Ke2State<HashLen> {
|
|||||||
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
#[derive(Clone, Debug, Eq, Hash, PartialEq)]
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||||
#[cfg_attr(feature = "serialize", serde(bound = ""))]
|
#[cfg_attr(feature = "serialize", serde(bound = ""))]
|
||||||
pub struct Ke2Message<HashLen: ArrayLength<u8>> {
|
pub struct Ke2Message<G, HashLen: ArrayLength<u8>> {
|
||||||
server_nonce: GenericArray<u8, NonceLen>,
|
server_nonce: GenericArray<u8, NonceLen>,
|
||||||
server_e_pk: PublicKey,
|
server_e_pk: PublicKey<G>,
|
||||||
mac: GenericArray<u8, HashLen>,
|
mac: GenericArray<u8, HashLen>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -344,19 +365,19 @@ impl<HashLen: ArrayLength<u8>> FromBytes for Ke2State<HashLen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<HashLen: ArrayLength<u8>> ToBytes for Ke2Message<HashLen> {
|
impl<G: Group, HashLen: ArrayLength<u8>> ToBytes for Ke2Message<G, HashLen> {
|
||||||
fn to_bytes(&self) -> Vec<u8> {
|
fn to_bytes(&self) -> Vec<u8> {
|
||||||
[&self.to_bytes_without_info_or_mac(), &self.mac[..]].concat()
|
[&self.to_bytes_without_info_or_mac(), &self.mac[..]].concat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<HashLen: ArrayLength<u8>> Ke2Message<HashLen> {
|
impl<G: Group, HashLen: ArrayLength<u8>> Ke2Message<G, HashLen> {
|
||||||
fn to_bytes_without_info_or_mac(&self) -> Vec<u8> {
|
fn to_bytes_without_info_or_mac(&self) -> Vec<u8> {
|
||||||
[&self.server_nonce[..], &self.server_e_pk.to_arr()].concat()
|
[&self.server_nonce[..], &self.server_e_pk.to_arr()].concat()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<HashLen: ArrayLength<u8>> FromBytes for Ke2Message<HashLen> {
|
impl<G: Group, HashLen: ArrayLength<u8>> FromBytes for Ke2Message<G, HashLen> {
|
||||||
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError> {
|
fn from_bytes<CS: CipherSuite>(input: &[u8]) -> Result<Self, PakeError> {
|
||||||
let nonce_len = NonceLen::to_usize();
|
let nonce_len = NonceLen::to_usize();
|
||||||
let checked_nonce = check_slice_size_atleast(input, nonce_len, "ke2_message nonce")?;
|
let checked_nonce = check_slice_size_atleast(input, nonce_len, "ke2_message nonce")?;
|
||||||
@@ -387,13 +408,13 @@ impl<HashLen: ArrayLength<u8>> FromBytes for Ke2Message<HashLen> {
|
|||||||
|
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
// The triple of public and private components used in the 3DH computation
|
// The triple of public and private components used in the 3DH computation
|
||||||
struct TripleDHComponents {
|
struct TripleDHComponents<G> {
|
||||||
pk1: PublicKey,
|
pk1: PublicKey<G>,
|
||||||
sk1: PrivateKey,
|
sk1: PrivateKey<G>,
|
||||||
pk2: PublicKey,
|
pk2: PublicKey<G>,
|
||||||
sk2: PrivateKey,
|
sk2: PrivateKey<G>,
|
||||||
pk3: PublicKey,
|
pk3: PublicKey<G>,
|
||||||
sk3: PrivateKey,
|
sk3: PrivateKey<G>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::upper_case_acronyms)]
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
@@ -433,7 +454,7 @@ impl<HashLen: ArrayLength<u8>> FromBytes for Ke3Message<HashLen> {
|
|||||||
// Internal function which takes the public and private components of the client and server keypairs, along
|
// Internal function which takes the public and private components of the client and server keypairs, along
|
||||||
// with some auxiliary metadata, to produce the session key and two MAC keys
|
// with some auxiliary metadata, to produce the session key and two MAC keys
|
||||||
fn derive_3dh_keys<D: Hash, G: Group>(
|
fn derive_3dh_keys<D: Hash, G: Group>(
|
||||||
dh: TripleDHComponents,
|
dh: TripleDHComponents<G>,
|
||||||
hashed_derivation_transcript: &[u8],
|
hashed_derivation_transcript: &[u8],
|
||||||
) -> Result<TripleDHDerivationResult<D>, ProtocolError> {
|
) -> Result<TripleDHDerivationResult<D>, ProtocolError> {
|
||||||
let ikm: Vec<u8> = [
|
let ikm: Vec<u8> = [
|
||||||
|
|||||||
+107
-50
@@ -11,7 +11,7 @@ use crate::errors::InternalPakeError;
|
|||||||
use crate::group::Group;
|
use crate::group::Group;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use generic_array::typenum::Unsigned;
|
use generic_array::typenum::Unsigned;
|
||||||
use generic_array::{typenum::U32, GenericArray};
|
use generic_array::{ArrayLength, GenericArray};
|
||||||
use generic_bytes::{SizedBytes, TryFromSizedBytesError};
|
use generic_bytes::{SizedBytes, TryFromSizedBytesError};
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
use proptest::prelude::*;
|
use proptest::prelude::*;
|
||||||
@@ -35,20 +35,19 @@ pub trait SizedBytesExt: SizedBytes {
|
|||||||
impl<T> SizedBytesExt for T where T: SizedBytes {}
|
impl<T> SizedBytesExt for T where T: SizedBytes {}
|
||||||
|
|
||||||
/// A Keypair trait with public-private verification
|
/// A Keypair trait with public-private verification
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize), serde(bound = ""))]
|
||||||
pub struct KeyPair<G> {
|
pub struct KeyPair<G> {
|
||||||
pk: PublicKey,
|
pk: PublicKey<G>,
|
||||||
sk: PrivateKey,
|
sk: PrivateKey<G>,
|
||||||
_g: PhantomData<G>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_clone_for!(
|
impl_clone_for!(
|
||||||
struct KeyPair<G>,
|
struct KeyPair<G>,
|
||||||
[pk, sk, _g],
|
[pk, sk],
|
||||||
);
|
);
|
||||||
impl_debug_eq_hash_for!(
|
impl_debug_eq_hash_for!(
|
||||||
struct KeyPair<G>,
|
struct KeyPair<G>,
|
||||||
[pk, sk, _g],
|
[pk, sk],
|
||||||
);
|
);
|
||||||
|
|
||||||
// This can't be derived because of the use of a phantom parameter
|
// This can't be derived because of the use of a phantom parameter
|
||||||
@@ -67,12 +66,12 @@ impl<G> Drop for KeyPair<G> {
|
|||||||
|
|
||||||
impl<G: Group> KeyPair<G> {
|
impl<G: Group> KeyPair<G> {
|
||||||
/// The public key component
|
/// The public key component
|
||||||
pub fn public(&self) -> &PublicKey {
|
pub fn public(&self) -> &PublicKey<G> {
|
||||||
&self.pk
|
&self.pk
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The private key component
|
/// The private key component
|
||||||
pub fn private(&self) -> &PrivateKey {
|
pub fn private(&self) -> &PrivateKey<G> {
|
||||||
&self.sk
|
&self.sk
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -82,17 +81,16 @@ impl<G: Group> KeyPair<G> {
|
|||||||
let sk_bytes = G::scalar_as_bytes(&sk);
|
let sk_bytes = G::scalar_as_bytes(&sk);
|
||||||
let pk = G::base_point().mult_by_slice(sk_bytes);
|
let pk = G::base_point().mult_by_slice(sk_bytes);
|
||||||
Self {
|
Self {
|
||||||
pk: PublicKey(Key(pk.to_arr().to_vec())),
|
pk: PublicKey::new(Key(pk.to_arr().to_vec())),
|
||||||
sk: PrivateKey(Key(sk_bytes.to_vec())),
|
sk: PrivateKey::new(Key(sk_bytes.to_vec())),
|
||||||
_g: PhantomData,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtaining a public key from secret bytes. At all times, we should have
|
/// Obtaining a public key from secret bytes. At all times, we should have
|
||||||
/// &public_from_private(self.private()) == self.public()
|
/// &public_from_private(self.private()) == self.public()
|
||||||
pub(crate) fn public_from_private(bytes: &PrivateKey) -> PublicKey {
|
pub(crate) fn public_from_private(bytes: &PrivateKey<G>) -> PublicKey<G> {
|
||||||
let bytes_data = GenericArray::<u8, G::ScalarLen>::from_slice(&bytes.0[..]);
|
let bytes_data = GenericArray::<u8, G::ScalarLen>::from_slice(&bytes.0[..]);
|
||||||
PublicKey(Key(G::base_point()
|
PublicKey::new(Key(G::base_point()
|
||||||
.mult_by_slice(bytes_data)
|
.mult_by_slice(bytes_data)
|
||||||
.to_arr()
|
.to_arr()
|
||||||
.to_vec()))
|
.to_vec()))
|
||||||
@@ -102,14 +100,14 @@ impl<G: Group> KeyPair<G> {
|
|||||||
/// material provided through the network which fits the key
|
/// material provided through the network which fits the key
|
||||||
/// representation (i.e. can be mapped to a curve point), but presents
|
/// representation (i.e. can be mapped to a curve point), but presents
|
||||||
/// some risk - e.g. small subgroup check
|
/// some risk - e.g. small subgroup check
|
||||||
pub(crate) fn check_public_key(key: PublicKey) -> Result<PublicKey, InternalPakeError> {
|
pub(crate) fn check_public_key(key: PublicKey<G>) -> Result<PublicKey<G>, InternalPakeError> {
|
||||||
G::from_element_slice(GenericArray::from_slice(&key.0)).map(|_| key)
|
G::from_element_slice(GenericArray::from_slice(&key.0)).map(|_| key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the diffie hellman function on a public key and private key
|
/// Computes the diffie hellman function on a public key and private key
|
||||||
pub(crate) fn diffie_hellman(
|
pub(crate) fn diffie_hellman(
|
||||||
pk: PublicKey,
|
pk: PublicKey<G>,
|
||||||
sk: PrivateKey,
|
sk: PrivateKey<G>,
|
||||||
) -> Result<Vec<u8>, InternalPakeError> {
|
) -> Result<Vec<u8>, InternalPakeError> {
|
||||||
let pk_data = GenericArray::<u8, G::ElemLen>::from_slice(&pk.0[..]);
|
let pk_data = GenericArray::<u8, G::ElemLen>::from_slice(&pk.0[..]);
|
||||||
let point = G::from_element_slice(pk_data)?;
|
let point = G::from_element_slice(pk_data)?;
|
||||||
@@ -119,20 +117,19 @@ impl<G: Group> KeyPair<G> {
|
|||||||
|
|
||||||
/// Obtains a KeyPair from a slice representing the private key
|
/// Obtains a KeyPair from a slice representing the private key
|
||||||
pub fn from_private_key_slice(input: &[u8]) -> Result<Self, InternalPakeError> {
|
pub fn from_private_key_slice(input: &[u8]) -> Result<Self, InternalPakeError> {
|
||||||
let sk = PrivateKey(Key::from_arr(GenericArray::from_slice(input))?);
|
let sk = PrivateKey::new(Key::from_arr::<G::ScalarLen>(GenericArray::from_slice(input))?);
|
||||||
let pk = Self::public_from_private(&sk);
|
let pk = Self::public_from_private(&sk);
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
pk,
|
pk,
|
||||||
sk,
|
sk,
|
||||||
_g: PhantomData,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn as_byte_ptrs(&self) -> Vec<(*const u8, usize)> {
|
pub fn as_byte_ptrs(&self) -> Vec<(*const u8, usize)> {
|
||||||
vec![
|
vec![
|
||||||
(self.pk.as_ptr(), KeyLen::to_usize()),
|
(self.pk.as_ptr(), G::ElemLen::to_usize()),
|
||||||
(self.sk.as_ptr(), KeyLen::to_usize()),
|
(self.sk.as_ptr(), G::ScalarLen::to_usize()),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,8 +151,6 @@ impl<G: Group + Debug> KeyPair<G> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type KeyLen = U32;
|
|
||||||
|
|
||||||
/// A minimalist key type built around a \[u8; 32\]
|
/// A minimalist key type built around a \[u8; 32\]
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Zeroize)]
|
#[derive(Debug, PartialEq, Eq, Clone, Hash, Zeroize)]
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||||
@@ -174,69 +169,131 @@ impl Deref for Key {
|
|||||||
|
|
||||||
// Don't make it implement SizedBytes so that it's not constructible outside of this module.
|
// Don't make it implement SizedBytes so that it's not constructible outside of this module.
|
||||||
impl Key {
|
impl Key {
|
||||||
fn to_arr(&self) -> GenericArray<u8, KeyLen> {
|
fn to_arr<L: ArrayLength<u8>>(&self) -> GenericArray<u8, L> {
|
||||||
GenericArray::clone_from_slice(&self.0[..])
|
GenericArray::clone_from_slice(&self.0[..])
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
fn from_arr(key_bytes: &GenericArray<u8, KeyLen>) -> Result<Self, TryFromSizedBytesError> {
|
fn from_arr<L: ArrayLength<u8>>(key_bytes: &GenericArray<u8, L>) -> Result<Self, TryFromSizedBytesError> {
|
||||||
Ok(Key(key_bytes.to_vec()))
|
Ok(Key(key_bytes.to_vec()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper around a Key to enforce that it's a private one.
|
/// Wrapper around a Key to enforce that it's a private one.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Zeroize)]
|
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||||
// Ensure Key material is zeroed after use.
|
|
||||||
#[zeroize(drop)]
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PrivateKey(Key);
|
pub struct PrivateKey<G> {
|
||||||
|
key: Key,
|
||||||
|
_g: PhantomData<G>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for PrivateKey {
|
impl_clone_for!(
|
||||||
type Target = Key;
|
struct PrivateKey<G>,
|
||||||
|
[key, _g],
|
||||||
|
);
|
||||||
|
impl_debug_eq_hash_for!(
|
||||||
|
struct PrivateKey<G>,
|
||||||
|
[key, _g],
|
||||||
|
);
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
// This can't be derived because of the use of a phantom parameter
|
||||||
&self.0
|
impl<G> Zeroize for PrivateKey<G> {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
self.key.zeroize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SizedBytes for PrivateKey {
|
impl<G> Drop for PrivateKey<G> {
|
||||||
type Len = KeyLen;
|
fn drop(&mut self) {
|
||||||
|
self.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G> Deref for PrivateKey<G> {
|
||||||
|
type Target = Key;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G> PrivateKey<G> {
|
||||||
|
fn new(key: Key) -> Self {
|
||||||
|
Self {
|
||||||
|
key,
|
||||||
|
_g: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G: Group> SizedBytes for PrivateKey<G> {
|
||||||
|
type Len = G::ScalarLen;
|
||||||
|
|
||||||
fn to_arr(&self) -> GenericArray<u8, Self::Len> {
|
fn to_arr(&self) -> GenericArray<u8, Self::Len> {
|
||||||
self.0.to_arr()
|
self.key.to_arr()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_arr(key_bytes: &GenericArray<u8, Self::Len>) -> Result<Self, TryFromSizedBytesError> {
|
fn from_arr(key_bytes: &GenericArray<u8, Self::Len>) -> Result<Self, TryFromSizedBytesError> {
|
||||||
Ok(PrivateKey(Key::from_arr(key_bytes)?))
|
Ok(PrivateKey::new(Key::from_arr(key_bytes)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper around a Key to enforce that it's a public one.
|
/// Wrapper around a Key to enforce that it's a public one.
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Hash, Zeroize)]
|
|
||||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||||
// Ensure Key material is zeroed after use.
|
|
||||||
#[zeroize(drop)]
|
|
||||||
#[repr(transparent)]
|
#[repr(transparent)]
|
||||||
pub struct PublicKey(Key);
|
pub struct PublicKey<G> {
|
||||||
|
key: Key,
|
||||||
|
_g: PhantomData<G>,
|
||||||
|
}
|
||||||
|
|
||||||
impl Deref for PublicKey {
|
impl_clone_for!(
|
||||||
type Target = Key;
|
struct PublicKey<G>,
|
||||||
|
[key, _g],
|
||||||
|
);
|
||||||
|
impl_debug_eq_hash_for!(
|
||||||
|
struct PublicKey<G>,
|
||||||
|
[key, _g],
|
||||||
|
);
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
// This can't be derived because of the use of a phantom parameter
|
||||||
&self.0
|
impl<G> Zeroize for PublicKey<G> {
|
||||||
|
fn zeroize(&mut self) {
|
||||||
|
self.key.zeroize();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SizedBytes for PublicKey {
|
impl<G> Drop for PublicKey<G> {
|
||||||
type Len = KeyLen;
|
fn drop(&mut self) {
|
||||||
|
self.zeroize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G> Deref for PublicKey<G> {
|
||||||
|
type Target = Key;
|
||||||
|
|
||||||
|
fn deref(&self) -> &Self::Target {
|
||||||
|
&self.key
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G> PublicKey<G> {
|
||||||
|
fn new(key: Key) -> Self {
|
||||||
|
Self {
|
||||||
|
key,
|
||||||
|
_g: PhantomData,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<G: Group> SizedBytes for PublicKey<G> {
|
||||||
|
type Len = G::ElemLen;
|
||||||
|
|
||||||
fn to_arr(&self) -> GenericArray<u8, Self::Len> {
|
fn to_arr(&self) -> GenericArray<u8, Self::Len> {
|
||||||
self.0.to_arr()
|
self.key.to_arr()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn from_arr(key_bytes: &GenericArray<u8, Self::Len>) -> Result<Self, TryFromSizedBytesError> {
|
fn from_arr(key_bytes: &GenericArray<u8, Self::Len>) -> Result<Self, TryFromSizedBytesError> {
|
||||||
Ok(PublicKey(Key::from_arr(key_bytes)?))
|
Ok(PublicKey::new(Key::from_arr(key_bytes)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -251,7 +308,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_zeroize_key() -> Result<(), ProtocolError> {
|
fn test_zeroize_key() -> Result<(), ProtocolError> {
|
||||||
let key_len = KeyLen::to_usize();
|
let key_len = <RistrettoPoint as Group>::ElemLen::to_usize();
|
||||||
let mut key = Key(vec![1u8; key_len]);
|
let mut key = Key(vec![1u8; key_len]);
|
||||||
let ptr = key.as_ptr();
|
let ptr = key.as_ptr();
|
||||||
|
|
||||||
|
|||||||
+5
-5
@@ -79,7 +79,7 @@ pub struct RegistrationResponse<CS: CipherSuite> {
|
|||||||
/// The server's oprf output
|
/// The server's oprf output
|
||||||
pub(crate) beta: CS::Group,
|
pub(crate) beta: CS::Group,
|
||||||
/// Server's static public key
|
/// Server's static public key
|
||||||
pub(crate) server_s_pk: PublicKey,
|
pub(crate) server_s_pk: PublicKey<CS::Group>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cannot be derived because it would require for CS to be Clone.
|
// Cannot be derived because it would require for CS to be Clone.
|
||||||
@@ -107,7 +107,7 @@ impl<CS: CipherSuite> RegistrationResponse<CS> {
|
|||||||
/// Deserialization from bytes
|
/// Deserialization from bytes
|
||||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let elem_len = <CS::Group as Group>::ElemLen::to_usize();
|
let elem_len = <CS::Group as Group>::ElemLen::to_usize();
|
||||||
let key_len = <PublicKey as SizedBytes>::Len::to_usize();
|
let key_len = <PublicKey<CS::Group> as SizedBytes>::Len::to_usize();
|
||||||
let checked_slice =
|
let checked_slice =
|
||||||
check_slice_size(input, elem_len + key_len, "registration_response_bytes")?;
|
check_slice_size(input, elem_len + key_len, "registration_response_bytes")?;
|
||||||
|
|
||||||
@@ -141,7 +141,7 @@ pub struct RegistrationUpload<CS: CipherSuite> {
|
|||||||
/// The masking key used to mask the envelope
|
/// The masking key used to mask the envelope
|
||||||
pub(crate) masking_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
pub(crate) masking_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||||
/// The user's public key
|
/// The user's public key
|
||||||
pub(crate) client_s_pk: PublicKey,
|
pub(crate) client_s_pk: PublicKey<CS::Group>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl_clone_for!(
|
impl_clone_for!(
|
||||||
@@ -166,7 +166,7 @@ impl<CS: CipherSuite> RegistrationUpload<CS> {
|
|||||||
|
|
||||||
/// Deserialization from bytes
|
/// Deserialization from bytes
|
||||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let key_len = <PublicKey as SizedBytes>::Len::to_usize();
|
let key_len = <PublicKey<CS::Group> as SizedBytes>::Len::to_usize();
|
||||||
let hash_len = <CS::Hash as Digest>::OutputSize::to_usize();
|
let hash_len = <CS::Hash as Digest>::OutputSize::to_usize();
|
||||||
let checked_slice =
|
let checked_slice =
|
||||||
check_slice_size_atleast(input, key_len + hash_len, "registration_upload_bytes")?;
|
check_slice_size_atleast(input, key_len + hash_len, "registration_upload_bytes")?;
|
||||||
@@ -311,7 +311,7 @@ impl<CS: CipherSuite> CredentialResponse<CS> {
|
|||||||
/// Deserialization from bytes
|
/// Deserialization from bytes
|
||||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let elem_len = <CS::Group as Group>::ElemLen::to_usize();
|
let elem_len = <CS::Group as Group>::ElemLen::to_usize();
|
||||||
let key_len = <PublicKey as SizedBytes>::Len::to_usize();
|
let key_len = <PublicKey<CS::Group> as SizedBytes>::Len::to_usize();
|
||||||
let nonce_len: usize = 32;
|
let nonce_len: usize = 32;
|
||||||
let envelope_len = Envelope::<CS>::len();
|
let envelope_len = Envelope::<CS>::len();
|
||||||
let masked_response_len = key_len + envelope_len;
|
let masked_response_len = key_len + envelope_len;
|
||||||
|
|||||||
+9
-9
@@ -69,7 +69,7 @@ impl<CS: CipherSuite> ServerSetup<CS> {
|
|||||||
/// Deserialization from bytes
|
/// Deserialization from bytes
|
||||||
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
pub fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||||
let seed_len = <CS::Hash as Digest>::OutputSize::to_usize();
|
let seed_len = <CS::Hash as Digest>::OutputSize::to_usize();
|
||||||
let key_len = <PrivateKey as SizedBytes>::Len::to_usize();
|
let key_len = <PrivateKey<CS::Group> as SizedBytes>::Len::to_usize();
|
||||||
let checked_slice = check_slice_size(input, seed_len + key_len + key_len, "server_setup")?;
|
let checked_slice = check_slice_size(input, seed_len + key_len + key_len, "server_setup")?;
|
||||||
|
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
@@ -242,7 +242,7 @@ pub struct ClientRegistrationFinishResult<CS: CipherSuite> {
|
|||||||
/// The export key output by client registration
|
/// The export key output by client registration
|
||||||
pub export_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
pub export_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||||
/// The server's static public key
|
/// The server's static public key
|
||||||
pub server_s_pk: PublicKey,
|
pub server_s_pk: PublicKey<CS::Group>,
|
||||||
/// Instance of the ClientRegistration, only used in tests for checking zeroize
|
/// Instance of the ClientRegistration, only used in tests for checking zeroize
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub state: ClientRegistration<CS>,
|
pub state: ClientRegistration<CS>,
|
||||||
@@ -517,7 +517,7 @@ pub struct ClientLoginFinishResult<CS: CipherSuite> {
|
|||||||
/// The client-side export key
|
/// The client-side export key
|
||||||
pub export_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
pub export_key: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||||
/// The server's static public key
|
/// The server's static public key
|
||||||
pub server_s_pk: PublicKey,
|
pub server_s_pk: PublicKey<CS::Group>,
|
||||||
/// Instance of the ClientLogin, only used in tests for checking zeroize
|
/// Instance of the ClientLogin, only used in tests for checking zeroize
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub state: ClientLogin<CS>,
|
pub state: ClientLogin<CS>,
|
||||||
@@ -915,7 +915,7 @@ fn oprf_key_from_seed<G: GroupWithMapToCurve, D: Hash>(
|
|||||||
oprf_seed: &GenericArray<u8, D::OutputSize>,
|
oprf_seed: &GenericArray<u8, D::OutputSize>,
|
||||||
credential_identifier: &[u8],
|
credential_identifier: &[u8],
|
||||||
) -> Result<G::Scalar, InternalPakeError> {
|
) -> Result<G::Scalar, InternalPakeError> {
|
||||||
let mut oprf_key_bytes = vec![0u8; <PrivateKey as SizedBytes>::Len::to_usize()];
|
let mut oprf_key_bytes = vec![0u8; <PrivateKey<G> as SizedBytes>::Len::to_usize()];
|
||||||
Hkdf::<D>::from_prk(oprf_seed)
|
Hkdf::<D>::from_prk(oprf_seed)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?
|
.map_err(|_| InternalPakeError::HkdfError)?
|
||||||
.expand(
|
.expand(
|
||||||
@@ -929,10 +929,10 @@ fn oprf_key_from_seed<G: GroupWithMapToCurve, D: Hash>(
|
|||||||
fn mask_response<CS: CipherSuite>(
|
fn mask_response<CS: CipherSuite>(
|
||||||
masking_key: &[u8],
|
masking_key: &[u8],
|
||||||
masking_nonce: &[u8],
|
masking_nonce: &[u8],
|
||||||
server_s_pk: &PublicKey,
|
server_s_pk: &PublicKey<CS::Group>,
|
||||||
envelope: &Envelope<CS>,
|
envelope: &Envelope<CS>,
|
||||||
) -> Result<Vec<u8>, ProtocolError> {
|
) -> Result<Vec<u8>, ProtocolError> {
|
||||||
let mut xor_pad = vec![0u8; <PublicKey as SizedBytes>::Len::to_usize() + Envelope::<CS>::len()];
|
let mut xor_pad = vec![0u8; <PublicKey<CS::Group> as SizedBytes>::Len::to_usize() + Envelope::<CS>::len()];
|
||||||
Hkdf::<CS::Hash>::from_prk(masking_key)
|
Hkdf::<CS::Hash>::from_prk(masking_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?
|
.map_err(|_| InternalPakeError::HkdfError)?
|
||||||
.expand(
|
.expand(
|
||||||
@@ -954,8 +954,8 @@ fn unmask_response<CS: CipherSuite>(
|
|||||||
masking_key: &[u8],
|
masking_key: &[u8],
|
||||||
masking_nonce: &[u8],
|
masking_nonce: &[u8],
|
||||||
masked_response: &[u8],
|
masked_response: &[u8],
|
||||||
) -> Result<(PublicKey, Envelope<CS>), ProtocolError> {
|
) -> Result<(PublicKey<CS::Group>, Envelope<CS>), ProtocolError> {
|
||||||
let mut xor_pad = vec![0u8; <PublicKey as SizedBytes>::Len::to_usize() + Envelope::<CS>::len()];
|
let mut xor_pad = vec![0u8; <PublicKey<CS::Group> as SizedBytes>::Len::to_usize() + Envelope::<CS>::len()];
|
||||||
Hkdf::<CS::Hash>::from_prk(masking_key)
|
Hkdf::<CS::Hash>::from_prk(masking_key)
|
||||||
.map_err(|_| InternalPakeError::HkdfError)?
|
.map_err(|_| InternalPakeError::HkdfError)?
|
||||||
.expand(
|
.expand(
|
||||||
@@ -968,7 +968,7 @@ fn unmask_response<CS: CipherSuite>(
|
|||||||
.zip(masked_response.iter())
|
.zip(masked_response.iter())
|
||||||
.map(|(&x1, &x2)| x1 ^ x2)
|
.map(|(&x1, &x2)| x1 ^ x2)
|
||||||
.collect();
|
.collect();
|
||||||
let key_len = <PublicKey as SizedBytes>::Len::to_usize();
|
let key_len = <PublicKey<CS::Group> as SizedBytes>::Len::to_usize();
|
||||||
let unchecked_server_s_pk =
|
let unchecked_server_s_pk =
|
||||||
PublicKey::from_arr(&GenericArray::clone_from_slice(&plaintext[..key_len]))?;
|
PublicKey::from_arr(&GenericArray::clone_from_slice(&plaintext[..key_len]))?;
|
||||||
let envelope = Envelope::deserialize(&plaintext[key_len..])?;
|
let envelope = Envelope::deserialize(&plaintext[key_len..])?;
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ fn credential_response_roundtrip() {
|
|||||||
rng.fill_bytes(&mut masking_nonce);
|
rng.fill_bytes(&mut masking_nonce);
|
||||||
|
|
||||||
let mut masked_response =
|
let mut masked_response =
|
||||||
vec![0u8; <PublicKey as SizedBytes>::Len::to_usize() + Envelope::<Default>::len()];
|
vec![0u8; <PublicKey<RistrettoPoint> as SizedBytes>::Len::to_usize() + Envelope::<Default>::len()];
|
||||||
rng.fill_bytes(&mut masked_response);
|
rng.fill_bytes(&mut masked_response);
|
||||||
|
|
||||||
let server_e_kp = KeyPair::<<Default as CipherSuite>::Group>::generate_random(&mut rng);
|
let server_e_kp = KeyPair::<<Default as CipherSuite>::Group>::generate_random(&mut rng);
|
||||||
|
|||||||
@@ -445,7 +445,7 @@ fn populate_test_vectors(values: &Value) -> TestVectorParameters {
|
|||||||
dummy_private_key: parse_default!(
|
dummy_private_key: parse_default!(
|
||||||
values,
|
values,
|
||||||
"client_private_key",
|
"client_private_key",
|
||||||
vec![0u8; <PrivateKey as SizedBytes>::Len::to_usize()]
|
vec![0u8; <PrivateKey<RistrettoPoint> as SizedBytes>::Len::to_usize()]
|
||||||
),
|
),
|
||||||
dummy_masking_key: parse_default!(values, "masking_key", vec![0u8; 64]),
|
dummy_masking_key: parse_default!(values, "masking_key", vec![0u8; 64]),
|
||||||
context: parse!(values, "Context"),
|
context: parse!(values, "Context"),
|
||||||
|
|||||||
Reference in New Issue
Block a user