Introduce PrivateKey associated type to CipherSuite

This commit is contained in:
daxpedda
2021-07-23 15:23:10 -07:00
committed by Kevin Lewi
parent 990acf67e3
commit d61e2d0b5c
11 changed files with 165 additions and 82 deletions
+2
View File
@@ -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 {
+6 -4
View File
@@ -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
View File
@@ -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>;
}
+3 -3
View File
@@ -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>,
+12 -12
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+2 -1
View File
@@ -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
+2 -1
View File
@@ -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 {
+1
View File
@@ -21,6 +21,7 @@ impl CipherSuite for Ristretto255Sha512NoSlowHash {
type KeyExchange = TripleDH;
type Hash = sha2::Sha512;
type SlowHash = NoOpHash;
type PrivateKey = PrivateKey<RistrettoPoint>;
}
#[derive(PartialEq)]