Add key schedule / info changes in TripleDH computation (#69)
This commit is contained in:
+112
-46
@@ -9,6 +9,7 @@ use crate::{
|
||||
hash::Hash,
|
||||
key_exchange::traits::{KeyExchange, ToBytes},
|
||||
keypair::{KeyPair, SizedBytes},
|
||||
serialization::serialize,
|
||||
};
|
||||
use digest::{Digest, FixedOutput};
|
||||
use generic_array::{
|
||||
@@ -27,6 +28,11 @@ pub(crate) type NonceLen = U32;
|
||||
const KE1_STATE_LEN: usize = KEY_LEN + KEY_LEN + NONCE_LEN;
|
||||
|
||||
static STR_3DH: &[u8] = b"3DH keys";
|
||||
static STR_CLIENT_MAC: &[u8] = b"client mac";
|
||||
static STR_HANDSHAKE_SECRET: &[u8] = b"handshake secret";
|
||||
static STR_SERVER_MAC: &[u8] = b"server mac";
|
||||
static STR_SESSION_SECRET: &[u8] = b"session secret";
|
||||
static STR_OPAQUE: &[u8] = b"OPAQUE ";
|
||||
|
||||
/// The Triple Diffie-Hellman key exchange implementation
|
||||
pub struct TripleDH;
|
||||
@@ -84,7 +90,7 @@ impl<D: Hash, KeyFormat: KeyPair> KeyExchange<D, KeyFormat> for TripleDH {
|
||||
server_nonce_bytes.into()
|
||||
};
|
||||
|
||||
let (shared_secret, km2, km3) = derive_3dh_keys::<KeyFormat, D>(
|
||||
let (session_secret, km2, km3) = derive_3dh_keys::<KeyFormat, D>(
|
||||
TripleDHComponents {
|
||||
pk1: ke1_message.client_e_pk.clone(),
|
||||
sk1: server_e_kp.private().clone(),
|
||||
@@ -122,7 +128,7 @@ impl<D: Hash, KeyFormat: KeyPair> KeyExchange<D, KeyFormat> for TripleDH {
|
||||
KE2State {
|
||||
km3,
|
||||
hashed_transcript,
|
||||
shared_secret,
|
||||
session_secret,
|
||||
},
|
||||
KE2Message {
|
||||
server_nonce,
|
||||
@@ -139,7 +145,7 @@ impl<D: Hash, KeyFormat: KeyPair> KeyExchange<D, KeyFormat> for TripleDH {
|
||||
server_s_pk: KeyFormat::Repr,
|
||||
client_s_sk: KeyFormat::Repr,
|
||||
) -> Result<(Vec<u8>, Self::KE3Message), ProtocolError> {
|
||||
let (shared_secret, km2, km3) = derive_3dh_keys::<KeyFormat, D>(
|
||||
let (session_secret, km2, km3) = derive_3dh_keys::<KeyFormat, D>(
|
||||
TripleDHComponents {
|
||||
pk1: ke2_message.server_e_pk.clone(),
|
||||
sk1: ke1_state.client_e_sk.clone(),
|
||||
@@ -181,7 +187,7 @@ impl<D: Hash, KeyFormat: KeyPair> KeyExchange<D, KeyFormat> for TripleDH {
|
||||
client_mac.update(&hashed_transcript);
|
||||
|
||||
Ok((
|
||||
shared_secret.to_vec(),
|
||||
session_secret.to_vec(),
|
||||
KE3Message {
|
||||
mac: client_mac.finalize().into_bytes(),
|
||||
},
|
||||
@@ -202,7 +208,7 @@ impl<D: Hash, KeyFormat: KeyPair> KeyExchange<D, KeyFormat> for TripleDH {
|
||||
));
|
||||
}
|
||||
|
||||
Ok(ke2_state.shared_secret.to_vec())
|
||||
Ok(ke2_state.session_secret.to_vec())
|
||||
}
|
||||
|
||||
fn ke1_state_size() -> usize {
|
||||
@@ -285,7 +291,7 @@ impl<KeyFormat: KeyPair> TryFrom<&[u8]> for KE1Message<KeyFormat> {
|
||||
pub struct KE2State<HashLen: ArrayLength<u8>> {
|
||||
km3: GenericArray<u8, HashLen>,
|
||||
hashed_transcript: GenericArray<u8, HashLen>,
|
||||
shared_secret: GenericArray<u8, HashLen>,
|
||||
session_secret: GenericArray<u8, HashLen>,
|
||||
}
|
||||
|
||||
/// The second key exchange message
|
||||
@@ -300,7 +306,7 @@ impl<HashLen: ArrayLength<u8>> ToBytes for KE2State<HashLen> {
|
||||
let output: Vec<u8> = [
|
||||
&self.km3[..],
|
||||
&self.hashed_transcript[..],
|
||||
&self.shared_secret[..],
|
||||
&self.session_secret[..],
|
||||
]
|
||||
.concat();
|
||||
output
|
||||
@@ -316,7 +322,7 @@ impl<HashLen: ArrayLength<u8>> TryFrom<&[u8]> for KE2State<HashLen> {
|
||||
Ok(Self {
|
||||
km3: GenericArray::clone_from_slice(&checked_bytes[..KEY_LEN]),
|
||||
hashed_transcript: GenericArray::clone_from_slice(&checked_bytes[KEY_LEN..2 * KEY_LEN]),
|
||||
shared_secret: GenericArray::clone_from_slice(&checked_bytes[2 * KEY_LEN..]),
|
||||
session_secret: GenericArray::clone_from_slice(&checked_bytes[2 * KEY_LEN..]),
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -362,50 +368,13 @@ struct TripleDHComponents<KeyFormat: KeyPair> {
|
||||
sk3: KeyFormat::Repr,
|
||||
}
|
||||
|
||||
// Consists of a shared secret, followed by two mac keys
|
||||
// Consists of a shared secret, followed by two mac keys: (session_secret, km2, km3)
|
||||
type TripleDHDerivationResult<D> = (
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
GenericArray<u8, <D as FixedOutput>::OutputSize>,
|
||||
);
|
||||
|
||||
// Internal function which takes the public and private components of the client and server keypairs, along
|
||||
// with some auxiliary metadata, to produce the shared secret and two MAC keys
|
||||
fn derive_3dh_keys<KeyFormat: KeyPair, D: Hash>(
|
||||
dh: TripleDHComponents<KeyFormat>,
|
||||
client_nonce: &GenericArray<u8, NonceLen>,
|
||||
server_nonce: &GenericArray<u8, NonceLen>,
|
||||
client_s_pk: KeyFormat::Repr,
|
||||
server_s_pk: KeyFormat::Repr,
|
||||
) -> Result<TripleDHDerivationResult<D>, ProtocolError> {
|
||||
let ikm: Vec<u8> = [
|
||||
&KeyFormat::diffie_hellman(dh.pk1, dh.sk1)[..],
|
||||
&KeyFormat::diffie_hellman(dh.pk2, dh.sk2)[..],
|
||||
&KeyFormat::diffie_hellman(dh.pk3, dh.sk3)[..],
|
||||
]
|
||||
.concat();
|
||||
|
||||
let info: Vec<u8> = [
|
||||
STR_3DH,
|
||||
&client_nonce,
|
||||
&server_nonce,
|
||||
&client_s_pk.to_arr(),
|
||||
&server_s_pk.to_arr(),
|
||||
]
|
||||
.concat();
|
||||
|
||||
const OUTPUT_SIZE: usize = 32;
|
||||
let mut okm = [0u8; 3 * OUTPUT_SIZE];
|
||||
let h = Hkdf::<D>::new(None, &ikm);
|
||||
h.expand(&info, &mut okm)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
||||
Ok((
|
||||
GenericArray::clone_from_slice(&okm[..OUTPUT_SIZE]),
|
||||
GenericArray::clone_from_slice(&okm[OUTPUT_SIZE..2 * OUTPUT_SIZE]),
|
||||
GenericArray::clone_from_slice(&okm[2 * OUTPUT_SIZE..]),
|
||||
))
|
||||
}
|
||||
|
||||
/// The third key exchange message
|
||||
pub struct KE3Message<HashLen: ArrayLength<u8>> {
|
||||
mac: GenericArray<u8, HashLen>,
|
||||
@@ -428,3 +397,100 @@ impl<HashLen: ArrayLength<u8>> TryFrom<&[u8]> for KE3Message<HashLen> {
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// Helper functions
|
||||
|
||||
// Internal function which takes the public and private components of the client and server keypairs, along
|
||||
// with some auxiliary metadata, to produce the shared secret and two MAC keys
|
||||
fn derive_3dh_keys<KeyFormat: KeyPair, D: Hash>(
|
||||
dh: TripleDHComponents<KeyFormat>,
|
||||
client_nonce: &GenericArray<u8, NonceLen>,
|
||||
server_nonce: &GenericArray<u8, NonceLen>,
|
||||
client_s_pk: KeyFormat::Repr,
|
||||
server_s_pk: KeyFormat::Repr,
|
||||
) -> Result<TripleDHDerivationResult<D>, ProtocolError> {
|
||||
let ikm: Vec<u8> = [
|
||||
&KeyFormat::diffie_hellman(dh.pk1, dh.sk1)[..],
|
||||
&KeyFormat::diffie_hellman(dh.pk2, dh.sk2)[..],
|
||||
&KeyFormat::diffie_hellman(dh.pk3, dh.sk3)[..],
|
||||
]
|
||||
.concat();
|
||||
|
||||
let info: Vec<u8> = [
|
||||
STR_3DH,
|
||||
&serialize(&client_nonce, 2),
|
||||
&serialize(&server_nonce, 2),
|
||||
&serialize(&client_s_pk.to_arr(), 2),
|
||||
&serialize(&server_s_pk.to_arr(), 2),
|
||||
]
|
||||
.concat();
|
||||
|
||||
let extracted_ikm = Hkdf::<D>::new(None, &ikm);
|
||||
let handshake_secret = derive_secrets::<D>(&extracted_ikm, &STR_HANDSHAKE_SECRET, &info)?;
|
||||
let session_secret = derive_secrets::<D>(&extracted_ikm, &STR_SESSION_SECRET, &info)?;
|
||||
let km2 = hkdf_expand_label::<D>(
|
||||
&handshake_secret,
|
||||
&STR_SERVER_MAC,
|
||||
b"",
|
||||
<D as Digest>::OutputSize::to_usize(),
|
||||
)?;
|
||||
let km3 = hkdf_expand_label::<D>(
|
||||
&handshake_secret,
|
||||
&STR_CLIENT_MAC,
|
||||
b"",
|
||||
<D as Digest>::OutputSize::to_usize(),
|
||||
)?;
|
||||
|
||||
Ok((
|
||||
GenericArray::clone_from_slice(&session_secret),
|
||||
GenericArray::clone_from_slice(&km2),
|
||||
GenericArray::clone_from_slice(&km3),
|
||||
))
|
||||
}
|
||||
|
||||
fn hkdf_expand_label<D: Hash>(
|
||||
secret: &[u8],
|
||||
label: &[u8],
|
||||
context: &[u8],
|
||||
length: usize,
|
||||
) -> Result<Vec<u8>, ProtocolError> {
|
||||
let h = Hkdf::<D>::new(None, secret);
|
||||
hkdf_expand_label_extracted(&h, label, context, length)
|
||||
}
|
||||
|
||||
fn hkdf_expand_label_extracted<D: Hash>(
|
||||
hkdf: &Hkdf<D>,
|
||||
label: &[u8],
|
||||
context: &[u8],
|
||||
length: usize,
|
||||
) -> Result<Vec<u8>, ProtocolError> {
|
||||
let mut okm = vec![0u8; length];
|
||||
|
||||
let mut hkdf_label: Vec<u8> = Vec::new();
|
||||
hkdf_label.extend_from_slice(&length.to_be_bytes()[6..]);
|
||||
|
||||
let mut opaque_label: Vec<u8> = Vec::new();
|
||||
opaque_label.extend_from_slice(&STR_OPAQUE);
|
||||
opaque_label.extend_from_slice(&label);
|
||||
hkdf_label.extend_from_slice(&serialize(&opaque_label, 1));
|
||||
|
||||
hkdf_label.extend_from_slice(&serialize(&context, 1));
|
||||
|
||||
hkdf.expand(&hkdf_label, &mut okm)
|
||||
.map_err(|_| InternalPakeError::HkdfError)?;
|
||||
Ok(okm)
|
||||
}
|
||||
|
||||
fn derive_secrets<D: Hash>(
|
||||
hkdf: &Hkdf<D>,
|
||||
label: &[u8],
|
||||
transcript: &[u8],
|
||||
) -> Result<Vec<u8>, ProtocolError> {
|
||||
let hashed_transcript = D::digest(transcript);
|
||||
hkdf_expand_label_extracted::<D>(
|
||||
hkdf,
|
||||
label,
|
||||
&hashed_transcript,
|
||||
<D as Digest>::OutputSize::to_usize(),
|
||||
)
|
||||
}
|
||||
|
||||
+27
-27
@@ -64,35 +64,35 @@ pub struct TestVectorParameters {
|
||||
|
||||
static TEST_VECTOR: &str = r#"
|
||||
{
|
||||
"client_s_pk": "6c3f4c134a1697cda1d494cef349e99117aaedecb6792c3aeab06fc1da5f463d",
|
||||
"client_s_sk": "98f628dfaed00892809f1ff24f44eddb933ca593eeb88c532827249c3fdae56d",
|
||||
"client_e_pk": "b20d78da45e7d91fb9185be968ba20c680bfb735e5dbdec36c2aefdb261d6903",
|
||||
"client_e_sk": "88f058f4de21fc364603318edce30931a60fe78f7953722e3214203c02d52a79",
|
||||
"server_s_pk": "511b18e0a82493d9b0d7988f5a7e2d05fe6886cb26e9813d476e3fe6d3ca1349",
|
||||
"server_s_sk": "e00d089a96b19c74f77dcc6079277ba18b2dd1f603d0bc5c46664d4fe5c2867a",
|
||||
"server_e_pk": "98e12670ffd22a9a827d74bfa5ac44c9f83cb52b477b1ab201a589a8fd643674",
|
||||
"server_e_sk": "080f051060d51c9f1406e7cf5d9ac3212d8ba3829ca94fdd7c8f43e80fa8b278",
|
||||
"client_s_pk": "8ede26558ada44c55f44a39b3e4811bb71533b52c8331799349f5bf579b0063b",
|
||||
"client_s_sk": "e0937ce386f57ba61303f56851c6c1c338535ef30a046090c211fbae2b925575",
|
||||
"client_e_pk": "b2c126715667420809d14b6056d9492051dc31c77cbb39cd61e9d76736118e46",
|
||||
"client_e_sk": "481a41606adc0d8aa358cee44e36e5cb02f80d445e42551a90f15e1be59bf450",
|
||||
"server_s_pk": "da106c3619e8c17c2356f4827b33f6f869ab6f99badc8002324925458fecbd0d",
|
||||
"server_s_sk": "50cc8c336756b9c91badaa42df728c0a06033eca4770a7912f9f2924742f4356",
|
||||
"server_e_pk": "1848442db55ef8301a28b078317be3c40590fc40b3a356f704ced8c552f59349",
|
||||
"server_e_sk": "b8d7358f35d79cfa5e288e8ca8356bc806d4463710144767caf65eb9b4f77973",
|
||||
"password": "70617373776f7264",
|
||||
"blinding_factor_raw": "3def40a264b30c15dfcafc8d52cbe309d2d08e015d516b515f17cf98443bb39d6d164e9bd391303d890697b38dc59ee7e9ec196682528a078d51983ab18c227b",
|
||||
"blinding_factor": "d315d7e6c81d5398c015af3d55ded87f0979dfdb28b6f222ee8699905fd41e0a",
|
||||
"blinding_factor_raw": "6e5823f7d820cf6996a2cac80e239f58a9d7e8fcbf9588c07dde69dff3c330785bb85a9b1269f079bbcf4b1f428fbc3a977c324120867b9e918c97dad44576f2",
|
||||
"blinding_factor": "033a794ce47e3fb19206b8e1f2d74e54c874efcf5b5055d2a31d2164efd41a07",
|
||||
"pepper": "706570706572",
|
||||
"oprf_key": "75e559c8cc7a81642e61b77651bc61b71d3eb7d8b6cd9ca13d8532cb684d5405",
|
||||
"envelope_nonce": "3048ea382aa7357dbcd480047c884b717c4fea3ca627f2c498001b2a46e015da",
|
||||
"client_nonce": "47b20166a022bb319ba9a09d5c328b6e2d6cc5813018f7dd5b53f380f914e79f",
|
||||
"server_nonce": "1bf2cc47738524a83c995122a44c7832be18b48b606897d71fc942e8ec6d9b2e",
|
||||
"r1": "01000024000000204df6277df3ee67e084af0d24e27a6567b75589dc887d5acbe5e5830dc8dc7eb0",
|
||||
"r2": "0200002800208d04d78807ed18542f65707f964d96089a322a8bb06dad269cb7a4bee8c20b57000001010103",
|
||||
"r3": "030000ae3048ea382aa7357dbcd480047c884b717c4fea3ca627f2c498001b2a46e015da0023469a6c15d59bc2b9cf07e4e37138292e58070a34eb76f8cb5e3015c542b8e96346482f0023030020511b18e0a82493d9b0d7988f5a7e2d05fe6886cb26e9813d476e3fe6d3ca13490020b3fc2eb3ffc0ddfa3b9d94a33874d297263cb768077f128e7ec798b03c5c7ba300206c3f4c134a1697cda1d494cef349e99117aaedecb6792c3aeab06fc1da5f463d",
|
||||
"l1": "04000024000000204df6277df3ee67e084af0d24e27a6567b75589dc887d5acbe5e5830dc8dc7eb047b20166a022bb319ba9a09d5c328b6e2d6cc5813018f7dd5b53f380f914e79fb20d78da45e7d91fb9185be968ba20c680bfb735e5dbdec36c2aefdb261d6903",
|
||||
"l2": "050000ae00208d04d78807ed18542f65707f964d96089a322a8bb06dad269cb7a4bee8c20b573048ea382aa7357dbcd480047c884b717c4fea3ca627f2c498001b2a46e015da0023469a6c15d59bc2b9cf07e4e37138292e58070a34eb76f8cb5e3015c542b8e96346482f0023030020511b18e0a82493d9b0d7988f5a7e2d05fe6886cb26e9813d476e3fe6d3ca13490020b3fc2eb3ffc0ddfa3b9d94a33874d297263cb768077f128e7ec798b03c5c7ba3080f051060d51c9f1406e7cf5d9ac3212d8ba3829ca94fdd7c8f43e80fa8b27898e12670ffd22a9a827d74bfa5ac44c9f83cb52b477b1ab201a589a8fd64367476b2f0458ade73668e3aaab6e1cd7d48dacc702b9a49147d8431a18e649f814e",
|
||||
"l3": "ed9d2f5af8d30d7927458a6d10f309ae6f49792d5e86d12f5e163a980f49c7ff",
|
||||
"client_registration_state": "00000000d315d7e6c81d5398c015af3d55ded87f0979dfdb28b6f222ee8699905fd41e0a70617373776f7264",
|
||||
"client_login_state": "00000000d315d7e6c81d5398c015af3d55ded87f0979dfdb28b6f222ee8699905fd41e0a88f058f4de21fc364603318edce30931a60fe78f7953722e3214203c02d52a7947b20166a022bb319ba9a09d5c328b6e2d6cc5813018f7dd5b53f380f914e79f2e9c4b0c4bc9bdd4fca317dab50240fb32c31f9ec3742ec610a7e5016ad88de570617373776f7264",
|
||||
"server_registration_state": "75e559c8cc7a81642e61b77651bc61b71d3eb7d8b6cd9ca13d8532cb684d5405",
|
||||
"server_login_state": "54a3c257ad6e5406be86e9f983bcb25a50dcdaf8c8bd6928f17ea8b001db400c02b16899d3fe648ef86fb914dba9892d09df4a449f6f077e3ad903c01e309d6fd8e21fc482f3d3a396b8c1f5587e00806c860e5a2b82f0da989333ce870ee1ee",
|
||||
"password_file": "75e559c8cc7a81642e61b77651bc61b71d3eb7d8b6cd9ca13d8532cb684d54056c3f4c134a1697cda1d494cef349e99117aaedecb6792c3aeab06fc1da5f463d3048ea382aa7357dbcd480047c884b717c4fea3ca627f2c498001b2a46e015da0023469a6c15d59bc2b9cf07e4e37138292e58070a34eb76f8cb5e3015c542b8e96346482f0023030020511b18e0a82493d9b0d7988f5a7e2d05fe6886cb26e9813d476e3fe6d3ca13490020b3fc2eb3ffc0ddfa3b9d94a33874d297263cb768077f128e7ec798b03c5c7ba3",
|
||||
"export_key": "90f9b6ec1edd53a60a9be4f744950befecf5bbfbd973702082fa031aa192bb5a",
|
||||
"shared_secret": "d8e21fc482f3d3a396b8c1f5587e00806c860e5a2b82f0da989333ce870ee1ee"
|
||||
"oprf_key": "fd76f0e1cfa9f971bc5dada4caa87dcba1d69d7ace0064d56107ca1932d36300",
|
||||
"envelope_nonce": "b25a32f7d33a1225675a8ea65dd4ca0b1a09845ce1f917f66ccc62a695c79f20",
|
||||
"client_nonce": "e29650629c1463124cb2283068557ba10d35637876b131040b4f8702276e1900",
|
||||
"server_nonce": "b32c16a32fe0cbb926a4926ff29bcfae2a96fe6e92b45f5ca27de3b6e413d413",
|
||||
"r1": "01000024000000200e0a8b356d7c81a331dddd6987a888943892863b23e14202895eb27b69da691e",
|
||||
"r2": "020000280020d63f9afe21e3246534cbfbd230b4497255e0a7bb68c3ad6e2dd9b3f4283c8382000001010103",
|
||||
"r3": "030000aeb25a32f7d33a1225675a8ea65dd4ca0b1a09845ce1f917f66ccc62a695c79f200023b73a7e011120604ac7d44a5ae7f65102ee79a4f6cc4b544d64b5dc064318cfb35230a70023030020da106c3619e8c17c2356f4827b33f6f869ab6f99badc8002324925458fecbd0d002016ba53f6b3b80db59717025c3a9246d5256bef434ce5f7d2c53b961cb5afe44000208ede26558ada44c55f44a39b3e4811bb71533b52c8331799349f5bf579b0063b",
|
||||
"l1": "04000024000000200e0a8b356d7c81a331dddd6987a888943892863b23e14202895eb27b69da691ee29650629c1463124cb2283068557ba10d35637876b131040b4f8702276e1900b2c126715667420809d14b6056d9492051dc31c77cbb39cd61e9d76736118e46",
|
||||
"l2": "050000ae0020d63f9afe21e3246534cbfbd230b4497255e0a7bb68c3ad6e2dd9b3f4283c8382b25a32f7d33a1225675a8ea65dd4ca0b1a09845ce1f917f66ccc62a695c79f200023b73a7e011120604ac7d44a5ae7f65102ee79a4f6cc4b544d64b5dc064318cfb35230a70023030020da106c3619e8c17c2356f4827b33f6f869ab6f99badc8002324925458fecbd0d002016ba53f6b3b80db59717025c3a9246d5256bef434ce5f7d2c53b961cb5afe440b8d7358f35d79cfa5e288e8ca8356bc806d4463710144767caf65eb9b4f779731848442db55ef8301a28b078317be3c40590fc40b3a356f704ced8c552f59349732f8a81df2e21f59afd20155576e6191439e4fc4212b78a74a1198cfca92184",
|
||||
"l3": "512fa64c0540a5fa5d8ee82910fc91bfff98d6272b9070e37e79832e55916ce5",
|
||||
"client_registration_state": "00000000033a794ce47e3fb19206b8e1f2d74e54c874efcf5b5055d2a31d2164efd41a0770617373776f7264",
|
||||
"client_login_state": "00000000033a794ce47e3fb19206b8e1f2d74e54c874efcf5b5055d2a31d2164efd41a07481a41606adc0d8aa358cee44e36e5cb02f80d445e42551a90f15e1be59bf450e29650629c1463124cb2283068557ba10d35637876b131040b4f8702276e190062259ed12ff91ba92d2cb43c7433e73e79c4d6d1536ae77cc9ca808bdffc190b70617373776f7264",
|
||||
"server_registration_state": "fd76f0e1cfa9f971bc5dada4caa87dcba1d69d7ace0064d56107ca1932d36300",
|
||||
"server_login_state": "7a78a3ce25b39e78d65c9e648f13f6dbe08b3f91b0ef16565b780d42ca61c6d51a66199867f777c671a8e5fa6e8faf1e1047a26f64adea97b16b7a831204d4bdbc293cebd5bc7f82054b142b10617ee8f2e30f2e39fbcacb3566167fc2021589",
|
||||
"password_file": "fd76f0e1cfa9f971bc5dada4caa87dcba1d69d7ace0064d56107ca1932d363008ede26558ada44c55f44a39b3e4811bb71533b52c8331799349f5bf579b0063bb25a32f7d33a1225675a8ea65dd4ca0b1a09845ce1f917f66ccc62a695c79f200023b73a7e011120604ac7d44a5ae7f65102ee79a4f6cc4b544d64b5dc064318cfb35230a70023030020da106c3619e8c17c2356f4827b33f6f869ab6f99badc8002324925458fecbd0d002016ba53f6b3b80db59717025c3a9246d5256bef434ce5f7d2c53b961cb5afe440",
|
||||
"export_key": "57da80dc58057781bf65a4f4b1ea0d77d7eb69fbb2786e26dfdfa0c440ea3611",
|
||||
"shared_secret": "bc293cebd5bc7f82054b142b10617ee8f2e30f2e39fbcacb3566167fc2021589"
|
||||
}
|
||||
"#;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user