Introduce PrivateKey associated type to CipherSuite
This commit is contained in:
@@ -32,6 +32,7 @@ use std::process::exit;
|
||||
|
||||
use opaque_ke::{
|
||||
ciphersuite::CipherSuite,
|
||||
keypair::PrivateKey,
|
||||
rand::{rngs::OsRng, RngCore},
|
||||
ClientLogin, ClientLoginFinishParameters, ClientRegistration,
|
||||
ClientRegistrationFinishParameters, CredentialFinalization, CredentialRequest,
|
||||
@@ -48,6 +49,7 @@ impl CipherSuite for Default {
|
||||
type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
type Hash = sha2::Sha512;
|
||||
type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
type PrivateKey = PrivateKey<Self::Group>;
|
||||
}
|
||||
|
||||
struct Locker {
|
||||
|
||||
@@ -26,10 +26,11 @@ use std::collections::HashMap;
|
||||
use std::process::exit;
|
||||
|
||||
use opaque_ke::{
|
||||
ciphersuite::CipherSuite, rand::rngs::OsRng, ClientLogin, ClientLoginFinishParameters,
|
||||
ClientRegistration, ClientRegistrationFinishParameters, CredentialFinalization,
|
||||
CredentialRequest, CredentialResponse, RegistrationRequest, RegistrationResponse,
|
||||
RegistrationUpload, ServerLogin, ServerLoginStartParameters, ServerRegistration, ServerSetup,
|
||||
ciphersuite::CipherSuite, keypair::PrivateKey, rand::rngs::OsRng, ClientLogin,
|
||||
ClientLoginFinishParameters, ClientRegistration, ClientRegistrationFinishParameters,
|
||||
CredentialFinalization, CredentialRequest, CredentialResponse, RegistrationRequest,
|
||||
RegistrationResponse, RegistrationUpload, ServerLogin, ServerLoginStartParameters,
|
||||
ServerRegistration, ServerSetup,
|
||||
};
|
||||
|
||||
// The ciphersuite trait allows to specify the underlying primitives
|
||||
@@ -41,6 +42,7 @@ impl CipherSuite for Default {
|
||||
type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
type Hash = sha2::Sha512;
|
||||
type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
type PrivateKey = PrivateKey<Self::Group>;
|
||||
}
|
||||
|
||||
// Password-based registration between a client and server
|
||||
|
||||
+4
-2
@@ -6,8 +6,8 @@
|
||||
//! Defines the CipherSuite trait to specify the underlying primitives for OPAQUE
|
||||
|
||||
use crate::{
|
||||
hash::Hash, key_exchange::traits::KeyExchange, map_to_curve::GroupWithMapToCurve,
|
||||
slow_hash::SlowHash,
|
||||
hash::Hash, key_exchange::traits::KeyExchange, keypair::SecretKey,
|
||||
map_to_curve::GroupWithMapToCurve, slow_hash::SlowHash,
|
||||
};
|
||||
use digest::Digest;
|
||||
|
||||
@@ -31,4 +31,6 @@ pub trait CipherSuite {
|
||||
type Hash: Hash;
|
||||
/// A slow hashing function, typically used for password hashing
|
||||
type SlowHash: SlowHash<Self::Hash>;
|
||||
/// A private key container, allows remote key implementations
|
||||
type PrivateKey: SecretKey<Self::Group>;
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ use crate::{
|
||||
errors::{PakeError, ProtocolError},
|
||||
group::Group,
|
||||
hash::Hash,
|
||||
keypair::{PrivateKey, PublicKey},
|
||||
keypair::{PrivateKey, PublicKey, SecretKey},
|
||||
};
|
||||
use rand::{CryptoRng, RngCore};
|
||||
use zeroize::Zeroize;
|
||||
@@ -25,13 +25,13 @@ pub trait KeyExchange<D: Hash, G: Group> {
|
||||
) -> Result<(Self::KE1State, Self::KE1Message), ProtocolError>;
|
||||
|
||||
#[allow(clippy::too_many_arguments, clippy::type_complexity)]
|
||||
fn generate_ke2<R: RngCore + CryptoRng>(
|
||||
fn generate_ke2<R: RngCore + CryptoRng, S: SecretKey<G>>(
|
||||
rng: &mut R,
|
||||
l1_bytes: Vec<u8>,
|
||||
l2_bytes: Vec<u8>,
|
||||
ke1_message: Self::KE1Message,
|
||||
client_s_pk: PublicKey<G>,
|
||||
server_s_sk: PrivateKey<G>,
|
||||
server_s_sk: S,
|
||||
id_u: Vec<u8>,
|
||||
id_s: Vec<u8>,
|
||||
context: Vec<u8>,
|
||||
|
||||
@@ -13,7 +13,7 @@ use crate::{
|
||||
group::Group,
|
||||
hash::Hash,
|
||||
key_exchange::traits::{FromBytes, KeyExchange, ToBytes, ToBytesWithPointers},
|
||||
keypair::{KeyPair, PrivateKey, PublicKey, SizedBytesExt},
|
||||
keypair::{KeyPair, PrivateKey, PublicKey, SecretKey, SizedBytesExt},
|
||||
serialization::serialize,
|
||||
};
|
||||
use digest::{Digest, FixedOutput};
|
||||
@@ -70,13 +70,13 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
||||
}
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
fn generate_ke2<R: RngCore + CryptoRng>(
|
||||
fn generate_ke2<R: RngCore + CryptoRng, S: SecretKey<G>>(
|
||||
rng: &mut R,
|
||||
serialized_credential_request: Vec<u8>,
|
||||
l2_bytes: Vec<u8>,
|
||||
ke1_message: Self::KE1Message,
|
||||
client_s_pk: PublicKey<G>,
|
||||
server_s_sk: PrivateKey<G>,
|
||||
server_s_sk: S,
|
||||
id_u: Vec<u8>,
|
||||
id_s: Vec<u8>,
|
||||
context: Vec<u8>,
|
||||
@@ -94,7 +94,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
||||
.chain(&server_nonce[..])
|
||||
.chain(&server_e_kp.public().to_arr());
|
||||
|
||||
let (session_key, km2, km3) = derive_3dh_keys::<D, G>(
|
||||
let (session_key, km2, km3) = derive_3dh_keys::<D, G, S>(
|
||||
TripleDHComponents {
|
||||
pk1: ke1_message.client_e_pk.clone(),
|
||||
sk1: server_e_kp.private().clone(),
|
||||
@@ -148,7 +148,7 @@ impl<D: Hash, G: Group> KeyExchange<D, G> for TripleDH {
|
||||
.chain(&l2_component[..])
|
||||
.chain(&ke2_message.to_bytes_without_info_or_mac());
|
||||
|
||||
let (session_key, km2, km3) = derive_3dh_keys::<D, G>(
|
||||
let (session_key, km2, km3) = derive_3dh_keys::<D, G, PrivateKey<G>>(
|
||||
TripleDHComponents {
|
||||
pk1: ke2_message.server_e_pk.clone(),
|
||||
sk1: ke1_state.client_e_sk.clone(),
|
||||
@@ -408,11 +408,11 @@ impl<G: Group, HashLen: ArrayLength<u8>> FromBytes for Ke2Message<G, HashLen> {
|
||||
|
||||
#[allow(clippy::upper_case_acronyms)]
|
||||
// The triple of public and private components used in the 3DH computation
|
||||
struct TripleDHComponents<G: Group> {
|
||||
struct TripleDHComponents<G: Group, S: SecretKey<G>> {
|
||||
pk1: PublicKey<G>,
|
||||
sk1: PrivateKey<G>,
|
||||
pk2: PublicKey<G>,
|
||||
sk2: PrivateKey<G>,
|
||||
sk2: S,
|
||||
pk3: PublicKey<G>,
|
||||
sk3: PrivateKey<G>,
|
||||
}
|
||||
@@ -453,14 +453,14 @@ impl<HashLen: ArrayLength<u8>> FromBytes for Ke3Message<HashLen> {
|
||||
|
||||
// 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
|
||||
fn derive_3dh_keys<D: Hash, G: Group>(
|
||||
dh: TripleDHComponents<G>,
|
||||
fn derive_3dh_keys<D: Hash, G: Group, S: SecretKey<G>>(
|
||||
dh: TripleDHComponents<G, S>,
|
||||
hashed_derivation_transcript: &[u8],
|
||||
) -> Result<TripleDHDerivationResult<D>, ProtocolError> {
|
||||
let ikm: Vec<u8> = [
|
||||
&KeyPair::<G>::diffie_hellman(dh.pk1, dh.sk1)?[..],
|
||||
&KeyPair::<G>::diffie_hellman(dh.pk2, dh.sk2)?[..],
|
||||
&KeyPair::<G>::diffie_hellman(dh.pk3, dh.sk3)?[..],
|
||||
&dh.sk1.diffie_hellman(dh.pk1)?[..],
|
||||
&dh.sk2.diffie_hellman(dh.pk2)?[..],
|
||||
&dh.sk3.diffie_hellman(dh.pk3)?[..],
|
||||
]
|
||||
.concat();
|
||||
|
||||
|
||||
+101
-51
@@ -7,7 +7,7 @@
|
||||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use crate::errors::InternalPakeError;
|
||||
use crate::errors::{InternalPakeError, PakeError, ProtocolError};
|
||||
use crate::group::Group;
|
||||
#[cfg(test)]
|
||||
use generic_array::typenum::Unsigned;
|
||||
@@ -37,65 +37,74 @@ impl<T> SizedBytesExt for T where T: SizedBytes {}
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound = "")
|
||||
serde(bound(
|
||||
deserialize = "S: serde::Deserialize<'de>",
|
||||
serialize = "S: serde::Serialize"
|
||||
))
|
||||
)]
|
||||
pub struct KeyPair<G: Group> {
|
||||
pub struct KeyPair<G: Group, S: SecretKey<G> = PrivateKey<G>> {
|
||||
pk: PublicKey<G>,
|
||||
sk: PrivateKey<G>,
|
||||
sk: S,
|
||||
}
|
||||
|
||||
impl_clone_for!(
|
||||
struct KeyPair<G: Group>,
|
||||
[pk, sk],
|
||||
);
|
||||
impl_debug_eq_hash_for!(
|
||||
struct KeyPair<G: Group>,
|
||||
[pk, sk],
|
||||
);
|
||||
impl<G: Group, S: SecretKey<G>> Clone for KeyPair<G, S> {
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
pk: self.pk.clone(),
|
||||
sk: self.sk.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group, S: SecretKey<G> + Debug> Debug for KeyPair<G, S> {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("KeyPair")
|
||||
.field("pk", &self.pk)
|
||||
.field("sk", &self.sk)
|
||||
.finish()
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group, S: SecretKey<G> + PartialEq> PartialEq for KeyPair<G, S> {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self.pk.eq(&other.pk) && self.sk.eq(&other.sk)
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group, S: SecretKey<G> + Eq> Eq for KeyPair<G, S> {}
|
||||
|
||||
impl<G: Group, S: SecretKey<G> + std::hash::Hash> std::hash::Hash for KeyPair<G, S> {
|
||||
fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
|
||||
self.pk.hash(state);
|
||||
self.sk.hash(state);
|
||||
}
|
||||
}
|
||||
|
||||
// This can't be derived because of the use of a generic parameter
|
||||
impl<G: Group> Zeroize for KeyPair<G> {
|
||||
impl<G: Group, S: SecretKey<G>> Zeroize for KeyPair<G, S> {
|
||||
fn zeroize(&mut self) {
|
||||
self.pk.zeroize();
|
||||
self.sk.zeroize();
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> Drop for KeyPair<G> {
|
||||
impl<G: Group, S: SecretKey<G>> Drop for KeyPair<G, S> {
|
||||
fn drop(&mut self) {
|
||||
self.zeroize();
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> KeyPair<G> {
|
||||
impl<G: Group, S: SecretKey<G>> KeyPair<G, S> {
|
||||
/// The public key component
|
||||
pub fn public(&self) -> &PublicKey<G> {
|
||||
&self.pk
|
||||
}
|
||||
|
||||
/// The private key component
|
||||
pub fn private(&self) -> &PrivateKey<G> {
|
||||
pub fn private(&self) -> &S {
|
||||
&self.sk
|
||||
}
|
||||
|
||||
/// Generating a random key pair given a cryptographic rng
|
||||
pub(crate) fn generate_random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||
let sk = G::random_nonzero_scalar(rng);
|
||||
let sk_bytes = G::scalar_as_bytes(sk);
|
||||
let pk = G::base_point().mult_by_slice(&sk_bytes);
|
||||
Self {
|
||||
pk: PublicKey(Key(pk.to_arr())),
|
||||
sk: PrivateKey(Key(sk_bytes)),
|
||||
}
|
||||
}
|
||||
|
||||
/// Obtaining a public key from secret bytes. At all times, we should have
|
||||
/// &public_from_private(self.private()) == self.public()
|
||||
pub(crate) fn public_from_private(bytes: &PrivateKey<G>) -> PublicKey<G> {
|
||||
let bytes_data = GenericArray::<u8, G::ScalarLen>::from_slice(&bytes.0[..]);
|
||||
PublicKey(Key(G::base_point().mult_by_slice(bytes_data).to_arr()))
|
||||
}
|
||||
|
||||
/// Check whether a public key is valid. This is meant to be applied on
|
||||
/// material provided through the network which fits the key
|
||||
/// representation (i.e. can be mapped to a curve point), but presents
|
||||
@@ -104,23 +113,25 @@ impl<G: Group> KeyPair<G> {
|
||||
G::from_element_slice(GenericArray::from_slice(&key.0)).map(|_| key)
|
||||
}
|
||||
|
||||
/// Computes the diffie hellman function on a public key and private key
|
||||
pub(crate) fn diffie_hellman(
|
||||
pk: PublicKey<G>,
|
||||
sk: PrivateKey<G>,
|
||||
) -> Result<Vec<u8>, InternalPakeError> {
|
||||
let pk_data = GenericArray::<u8, G::ElemLen>::from_slice(&pk.0[..]);
|
||||
let point = G::from_element_slice(pk_data)?;
|
||||
let secret_data = GenericArray::<u8, G::ScalarLen>::from_slice(&sk.0[..]);
|
||||
Ok(G::mult_by_slice(&point, secret_data).to_arr().to_vec())
|
||||
}
|
||||
|
||||
/// Obtains a KeyPair from a slice representing the private key
|
||||
pub fn from_private_key_slice(input: &[u8]) -> Result<Self, InternalPakeError> {
|
||||
let sk = PrivateKey(Key(GenericArray::clone_from_slice(input)));
|
||||
let pk = Self::public_from_private(&sk);
|
||||
pub fn from_private_key_slice(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
let sk = S::deserialize(input)?;
|
||||
let pk = sk.public_key()?;
|
||||
Ok(Self { pk, sk })
|
||||
}
|
||||
}
|
||||
|
||||
impl<G: Group> KeyPair<G> {
|
||||
/// Generating a random key pair given a cryptographic rng
|
||||
pub(crate) fn generate_random<R: RngCore + CryptoRng>(rng: &mut R) -> Self {
|
||||
let sk = G::random_nonzero_scalar(rng);
|
||||
let sk_bytes = G::scalar_as_bytes(sk);
|
||||
let pk = G::base_point().mult_by_slice(&sk_bytes);
|
||||
Self {
|
||||
pk: PublicKey(Key(pk.to_arr())),
|
||||
sk: PrivateKey(Key(sk_bytes)),
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub fn as_byte_ptrs(&self) -> Vec<(*const u8, usize)> {
|
||||
@@ -263,6 +274,45 @@ impl<G: Group> SizedBytes for PrivateKey<G> {
|
||||
}
|
||||
}
|
||||
|
||||
/// A trait specifying the requirements for a private key container
|
||||
pub trait SecretKey<G: Group>: Clone + Sized + Zeroize {
|
||||
/// Diffie-Hellman key exchange implementation
|
||||
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError>;
|
||||
|
||||
/// Returns public key from private key
|
||||
fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError>;
|
||||
|
||||
/// Serialization into bytes
|
||||
fn serialize(&self) -> Vec<u8>;
|
||||
|
||||
/// Deserialization from bytes
|
||||
fn deserialize(input: &[u8]) -> Result<Self, ProtocolError>;
|
||||
}
|
||||
|
||||
impl<G: Group> SecretKey<G> for PrivateKey<G> {
|
||||
fn diffie_hellman(&self, pk: PublicKey<G>) -> Result<Vec<u8>, InternalPakeError> {
|
||||
let pk_data = GenericArray::<u8, G::ElemLen>::from_slice(&pk.0[..]);
|
||||
let point = G::from_element_slice(pk_data)?;
|
||||
let secret_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
|
||||
Ok(G::mult_by_slice(&point, secret_data).to_arr().to_vec())
|
||||
}
|
||||
|
||||
fn public_key(&self) -> Result<PublicKey<G>, InternalPakeError> {
|
||||
let bytes_data = GenericArray::<u8, G::ScalarLen>::from_slice(&self.0[..]);
|
||||
Ok(PublicKey(Key(G::base_point()
|
||||
.mult_by_slice(bytes_data)
|
||||
.to_arr())))
|
||||
}
|
||||
|
||||
fn serialize(&self) -> Vec<u8> {
|
||||
self.to_vec()
|
||||
}
|
||||
|
||||
fn deserialize(input: &[u8]) -> Result<Self, ProtocolError> {
|
||||
PrivateKey::from_bytes(input).map_err(|_| PakeError::SerializationError.into())
|
||||
}
|
||||
}
|
||||
|
||||
/// Wrapper around a Key to enforce that it's a public one.
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[repr(transparent)]
|
||||
@@ -364,15 +414,15 @@ mod tests {
|
||||
fn test_ristretto_pub_from_priv(kp in KeyPair::<RistrettoPoint>::uniform_keypair_strategy()) {
|
||||
let pk = kp.public();
|
||||
let sk = kp.private();
|
||||
prop_assert_eq!(&KeyPair::<RistrettoPoint>::public_from_private(sk), pk);
|
||||
prop_assert_eq!(&sk.public_key()?, pk);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_ristretto_dh(kp1 in KeyPair::<RistrettoPoint>::uniform_keypair_strategy(),
|
||||
kp2 in KeyPair::<RistrettoPoint>::uniform_keypair_strategy()) {
|
||||
|
||||
let dh1 = KeyPair::<RistrettoPoint>::diffie_hellman(kp1.public().clone(), kp2.private().clone())?;
|
||||
let dh2 = KeyPair::<RistrettoPoint>::diffie_hellman(kp2.public().clone(), kp1.private().clone())?;
|
||||
let dh1 = kp2.private().diffie_hellman(kp1.public().clone())?;
|
||||
let dh2 = kp1.private().diffie_hellman(kp2.public().clone())?;
|
||||
|
||||
prop_assert_eq!(dh1, dh2);
|
||||
}
|
||||
|
||||
+15
@@ -26,6 +26,7 @@
|
||||
//! type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! type Hash = sha2::Sha512;
|
||||
//! type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! }
|
||||
//! ```
|
||||
//! See [examples/simple_login.rs](https://github.com/novifinancial/opaque-ke/blob/master/examples/simple_login.rs)
|
||||
@@ -47,6 +48,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! use rand::{rngs::OsRng, RngCore};
|
||||
//! let mut rng = OsRng;
|
||||
@@ -79,6 +81,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! use opaque_ke::ClientRegistration;
|
||||
//! use rand::{rngs::OsRng, RngCore};
|
||||
@@ -109,6 +112,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -146,6 +150,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -184,6 +189,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -226,6 +232,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! use opaque_ke::ClientLogin;
|
||||
@@ -259,6 +266,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -312,6 +320,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -357,6 +366,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -432,6 +442,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -509,6 +520,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -574,6 +586,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -611,6 +624,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
@@ -660,6 +674,7 @@
|
||||
//! # type KeyExchange = opaque_ke::key_exchange::tripledh::TripleDH;
|
||||
//! # type Hash = sha2::Sha512;
|
||||
//! # type SlowHash = opaque_ke::slow_hash::NoOpHash;
|
||||
//! # type PrivateKey = opaque_ke::keypair::PrivateKey<Self::Group>;
|
||||
//! # }
|
||||
//! # use rand::{rngs::OsRng, RngCore};
|
||||
//! # let mut client_rng = OsRng;
|
||||
|
||||
+17
-8
@@ -12,7 +12,7 @@ use crate::{
|
||||
group::Group,
|
||||
hash::Hash,
|
||||
key_exchange::traits::{FromBytes, KeyExchange, ToBytesWithPointers},
|
||||
keypair::{KeyPair, PrivateKey, PublicKey},
|
||||
keypair::{KeyPair, PrivateKey, PublicKey, SecretKey},
|
||||
map_to_curve::GroupWithMapToCurve,
|
||||
oprf,
|
||||
serialization::{serialize, tokenize},
|
||||
@@ -37,14 +37,21 @@ const STR_OPAQUE_DERIVE_KEY_PAIR: &[u8] = b"OPAQUE-DeriveKeyPair";
|
||||
// ============
|
||||
|
||||
/// The state elements the server holds upon setup
|
||||
#[cfg_attr(feature = "serialize", derive(serde::Deserialize, serde::Serialize))]
|
||||
#[cfg_attr(
|
||||
feature = "serialize",
|
||||
derive(serde::Deserialize, serde::Serialize),
|
||||
serde(bound(
|
||||
deserialize = "KeyPair<CS::Group, CS::PrivateKey>: serde::Deserialize<'de>",
|
||||
serialize = "KeyPair<CS::Group, CS::PrivateKey>: serde::Serialize"
|
||||
))
|
||||
)]
|
||||
pub struct ServerSetup<CS: CipherSuite> {
|
||||
oprf_seed: GenericArray<u8, <CS::Hash as Digest>::OutputSize>,
|
||||
keypair: KeyPair<CS::Group>,
|
||||
keypair: KeyPair<CS::Group, CS::PrivateKey>,
|
||||
pub(crate) fake_keypair: KeyPair<CS::Group>,
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> ServerSetup<CS> {
|
||||
impl<CS: CipherSuite<Group = G, PrivateKey = PrivateKey<G>>, G: Group> ServerSetup<CS> {
|
||||
/// Generate a new instance of server setup
|
||||
pub fn new<R: CryptoRng + RngCore>(rng: &mut R) -> Self {
|
||||
let mut seed = vec![0u8; <CS::Hash as Digest>::OutputSize::to_usize()];
|
||||
@@ -56,13 +63,15 @@ impl<CS: CipherSuite> ServerSetup<CS> {
|
||||
fake_keypair: KeyPair::<CS::Group>::generate_random(rng),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<CS: CipherSuite> ServerSetup<CS> {
|
||||
/// Serialization into bytes
|
||||
pub fn serialize(&self) -> Vec<u8> {
|
||||
[
|
||||
self.oprf_seed.to_vec(),
|
||||
self.keypair.private().to_arr().to_vec(),
|
||||
self.fake_keypair.private().to_arr().to_vec(),
|
||||
self.keypair.private().serialize(),
|
||||
self.fake_keypair.private().serialize(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
@@ -81,7 +90,7 @@ impl<CS: CipherSuite> ServerSetup<CS> {
|
||||
}
|
||||
|
||||
/// Returns the keypair
|
||||
pub fn keypair(&self) -> &KeyPair<CS::Group> {
|
||||
pub fn keypair(&self) -> &KeyPair<CS::Group, CS::PrivateKey> {
|
||||
&self.keypair
|
||||
}
|
||||
}
|
||||
@@ -775,7 +784,7 @@ impl<CS: CipherSuite> ServerLogin<CS> {
|
||||
};
|
||||
|
||||
let server_s_sk = server_setup.keypair.private();
|
||||
let server_s_pk = KeyPair::<CS::Group>::public_from_private(server_s_sk);
|
||||
let server_s_pk = server_s_sk.public_key()?;
|
||||
|
||||
let mut masking_nonce = vec![0u8; 32];
|
||||
rng.fill_bytes(&mut masking_nonce);
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::{
|
||||
traits::{FromBytes, KeyExchange, ToBytes},
|
||||
tripledh::{NonceLen, TripleDH},
|
||||
},
|
||||
keypair::{KeyPair, PublicKey},
|
||||
keypair::{KeyPair, PrivateKey, PublicKey},
|
||||
serialization::{i2osp, os2ip, serialize},
|
||||
*,
|
||||
};
|
||||
@@ -31,6 +31,7 @@ impl CipherSuite for Default {
|
||||
type KeyExchange = TripleDH;
|
||||
type Hash = sha2::Sha512;
|
||||
type SlowHash = crate::slow_hash::NoOpHash;
|
||||
type PrivateKey = PrivateKey<RistrettoPoint>;
|
||||
}
|
||||
|
||||
const HASH_SIZE: usize = 64; // Because of SHA512
|
||||
|
||||
@@ -10,7 +10,7 @@ use crate::{
|
||||
errors::*,
|
||||
group::Group,
|
||||
key_exchange::tripledh::{NonceLen, TripleDH},
|
||||
keypair::KeyPair,
|
||||
keypair::{KeyPair, PrivateKey},
|
||||
opaque::*,
|
||||
slow_hash::NoOpHash,
|
||||
tests::mock_rng::CycleRng,
|
||||
@@ -33,6 +33,7 @@ impl CipherSuite for RistrettoSha5123dhNoSlowHash {
|
||||
type KeyExchange = TripleDH;
|
||||
type Hash = sha2::Sha512;
|
||||
type SlowHash = NoOpHash;
|
||||
type PrivateKey = PrivateKey<RistrettoPoint>;
|
||||
}
|
||||
|
||||
pub struct TestVectorParameters {
|
||||
|
||||
@@ -21,6 +21,7 @@ impl CipherSuite for Ristretto255Sha512NoSlowHash {
|
||||
type KeyExchange = TripleDH;
|
||||
type Hash = sha2::Sha512;
|
||||
type SlowHash = NoOpHash;
|
||||
type PrivateKey = PrivateKey<RistrettoPoint>;
|
||||
}
|
||||
|
||||
#[derive(PartialEq)]
|
||||
|
||||
Reference in New Issue
Block a user