2020-06-05 09:35:14 -07:00
|
|
|
// Copyright (c) Facebook, Inc. and its affiliates.
|
|
|
|
|
//
|
|
|
|
|
// This source code is licensed under the MIT license found in the
|
|
|
|
|
// LICENSE file in the root directory of this source tree.
|
|
|
|
|
|
2021-06-04 16:29:58 -07:00
|
|
|
#![allow(unsafe_code)]
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
use crate::{
|
2020-06-14 23:25:31 -07:00
|
|
|
ciphersuite::CipherSuite,
|
2020-06-05 09:35:14 -07:00
|
|
|
errors::*,
|
|
|
|
|
group::Group,
|
2021-02-02 12:12:20 -08:00
|
|
|
key_exchange::tripledh::{NonceLen, TripleDH},
|
2021-07-16 14:31:44 +02:00
|
|
|
keypair::KeyPair,
|
2020-06-05 09:35:14 -07:00
|
|
|
opaque::*,
|
2020-07-02 12:24:53 -07:00
|
|
|
slow_hash::NoOpHash,
|
2020-06-05 09:35:14 -07:00
|
|
|
tests::mock_rng::CycleRng,
|
2020-11-16 14:05:43 -08:00
|
|
|
*,
|
2020-06-05 09:35:14 -07:00
|
|
|
};
|
2021-06-15 17:31:12 -07:00
|
|
|
use curve25519_dalek::{ristretto::RistrettoPoint, traits::Identity};
|
2021-02-02 12:12:20 -08:00
|
|
|
use generic_array::typenum::Unsigned;
|
2020-11-03 21:44:00 +00:00
|
|
|
use generic_bytes::SizedBytes;
|
2021-02-11 18:10:48 -08:00
|
|
|
use rand::{rngs::OsRng, RngCore};
|
2020-06-05 09:35:14 -07:00
|
|
|
use serde_json::Value;
|
2021-06-04 16:29:58 -07:00
|
|
|
use std::slice::from_raw_parts;
|
|
|
|
|
use zeroize::Zeroize;
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
// Tests
|
|
|
|
|
// =====
|
|
|
|
|
|
2021-01-25 13:20:36 -08:00
|
|
|
struct RistrettoSha5123dhNoSlowHash;
|
|
|
|
|
impl CipherSuite for RistrettoSha5123dhNoSlowHash {
|
2021-08-04 21:24:46 +02:00
|
|
|
type OprfGroup = RistrettoPoint;
|
|
|
|
|
type KeGroup = RistrettoPoint;
|
2020-07-13 15:23:29 -07:00
|
|
|
type KeyExchange = TripleDH;
|
2021-01-25 13:20:36 -08:00
|
|
|
type Hash = sha2::Sha512;
|
2020-07-02 12:24:53 -07:00
|
|
|
type SlowHash = NoOpHash;
|
2020-06-14 23:25:31 -07:00
|
|
|
}
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
pub struct TestVectorParameters {
|
|
|
|
|
pub client_s_pk: Vec<u8>,
|
|
|
|
|
pub client_s_sk: Vec<u8>,
|
|
|
|
|
pub client_e_pk: Vec<u8>,
|
|
|
|
|
pub client_e_sk: Vec<u8>,
|
|
|
|
|
pub server_s_pk: Vec<u8>,
|
|
|
|
|
pub server_s_sk: Vec<u8>,
|
|
|
|
|
pub server_e_pk: Vec<u8>,
|
|
|
|
|
pub server_e_sk: Vec<u8>,
|
2021-04-30 15:56:51 -07:00
|
|
|
pub fake_sk: Vec<u8>,
|
2021-04-16 01:07:07 -07:00
|
|
|
pub credential_identifier: Vec<u8>,
|
2020-11-02 13:51:43 -08:00
|
|
|
pub id_u: Vec<u8>,
|
|
|
|
|
pub id_s: Vec<u8>,
|
2020-06-05 09:35:14 -07:00
|
|
|
pub password: Vec<u8>,
|
|
|
|
|
pub blinding_factor: Vec<u8>,
|
2021-04-16 01:07:07 -07:00
|
|
|
pub oprf_seed: Vec<u8>,
|
|
|
|
|
pub masking_nonce: Vec<u8>,
|
2020-06-05 09:35:14 -07:00
|
|
|
pub envelope_nonce: Vec<u8>,
|
|
|
|
|
pub client_nonce: Vec<u8>,
|
|
|
|
|
pub server_nonce: Vec<u8>,
|
2021-04-30 15:56:51 -07:00
|
|
|
pub context: Vec<u8>,
|
2020-12-12 21:53:33 -08:00
|
|
|
pub registration_request: Vec<u8>,
|
|
|
|
|
pub registration_response: Vec<u8>,
|
2020-12-17 14:00:32 -08:00
|
|
|
pub registration_upload: Vec<u8>,
|
2020-12-12 21:53:33 -08:00
|
|
|
pub credential_request: Vec<u8>,
|
|
|
|
|
pub credential_response: Vec<u8>,
|
2021-01-26 09:27:30 -08:00
|
|
|
pub credential_finalization: Vec<u8>,
|
2020-06-05 09:35:14 -07:00
|
|
|
client_registration_state: Vec<u8>,
|
|
|
|
|
client_login_state: Vec<u8>,
|
|
|
|
|
server_login_state: Vec<u8>,
|
|
|
|
|
pub password_file: Vec<u8>,
|
2020-09-01 11:23:00 -07:00
|
|
|
pub export_key: Vec<u8>,
|
2021-02-08 11:19:06 -08:00
|
|
|
pub session_key: Vec<u8>,
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
2021-06-04 16:29:58 -07:00
|
|
|
static STR_PASSWORD: &str = "password";
|
2021-04-16 01:07:07 -07:00
|
|
|
static STR_CREDENTIAL_IDENTIFIER: &str = "credential_identifier";
|
2021-06-04 16:29:58 -07:00
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
static TEST_VECTOR: &str = r#"
|
|
|
|
|
{
|
2021-07-12 12:33:19 -07:00
|
|
|
"client_s_pk": "e4a2b9e3aee013bf72f35a00847861631c61f5b1f02e3b8e191fcd14f53a1436",
|
|
|
|
|
"client_s_sk": "fa12397b47d1b9cac12902a6d5aa751839e7d2eb97338718936724ef5a867106",
|
|
|
|
|
"client_e_pk": "50a57787f5cebc6be96834eb2ea4ef35556c1c4c7780161b65724e4a1057d32a",
|
|
|
|
|
"client_e_sk": "4d113729710988d19529ab39447726d615e179bf9bcff6c09febe7e18518aa02",
|
|
|
|
|
"server_s_pk": "6c381cb5a5c7c8718537793886053f9ffb4e0a6944efc036384344caf16c174e",
|
|
|
|
|
"server_s_sk": "df4aace3a5b6b02f54584a5cdfc280b7f381d44f57f25ce4b0008ed92a7c270f",
|
|
|
|
|
"server_e_pk": "24f9d4f69de78834757ad9f16b08997a205249e125ad151f979f63380950cb19",
|
|
|
|
|
"server_e_sk": "6dc1d8525660605c3abcd86ec8a690f8af3d5bece6ea76d860a0de644d9d6508",
|
|
|
|
|
"fake_sk": "db40438a3dea4ee7dde5840af0050fbade18bc2b231b4469b2bf4ce0ebd25206",
|
2021-04-16 01:07:07 -07:00
|
|
|
"credential_identifier": "637265644964656e746966696572",
|
2020-11-02 13:51:43 -08:00
|
|
|
"id_u": "696455",
|
|
|
|
|
"id_s": "696453",
|
2020-06-05 09:35:14 -07:00
|
|
|
"password": "70617373776f7264",
|
2021-07-12 12:33:19 -07:00
|
|
|
"blinding_factor": "c8fa84eba32048544608f67a0ab43aebe21ab78ebbddf32e8210b9b7dbc50002",
|
|
|
|
|
"oprf_seed": "e6403df8aa116b9b1bc0010506110422ca462bd763fcd9e2dbc2258613acdf0d431e5bb53097f1d4cd35aa5725a4375fa7ff8bdd81b59b4da74782e9c98781e1",
|
|
|
|
|
"masking_nonce": "0ab98ae7b94c33c362f9bc47e56ced702a5e118fd7d71c148642c1df3ee95ef0aeab6c5bce7313f86d8b68067d0d6788ff5405c17c230d3c348cb1f1b9af66f0",
|
|
|
|
|
"envelope_nonce": "0512216114d8fd3157cc148adc77985aee1868a79181abf1c88fc4b38e972dc8",
|
|
|
|
|
"client_nonce": "8f752fbb35518786eb32a951a8d1dc5fb591b0ca752d18d71e8cc05c52d5a199",
|
|
|
|
|
"server_nonce": "9f790dea5a443cf4a3b0215f676e733cbfa3eb8d20a95fd1494466f568882bd4",
|
2021-04-30 15:56:51 -07:00
|
|
|
"context": "636f6e74657874",
|
2021-07-12 12:33:19 -07:00
|
|
|
"registration_request": "c4d73dc3087bab36dd9cf0dd6b405e0474d8d12b41a7bd7317ff8ae04416696e",
|
|
|
|
|
"registration_response": "9e024b7621ad17a1809d25a3ca47c42eb12cf67e052a453c38ab119f4344ae026c381cb5a5c7c8718537793886053f9ffb4e0a6944efc036384344caf16c174e",
|
|
|
|
|
"registration_upload": "a8f448f10d547cd8186cfd7ab33ec055a5bc9f05306fafd6816c84356fb0f8672f0991ad6d648a22b937055e4db6a5fd381cf5e9fa3ed4128338202039b292cdad8ebc3b1bbd332230e4914c7d4c910642f8c22f4494e2e56c99aff79a698759fa12397b47d1b9cac12902a6d5aa751839e7d2eb97338718936724ef5a8671067c616a828ff31a550e31d5fc178d3ac8171b2213967b504513d982ce66c9e93159cc7fe10e845060fcb721b6e681b60f6bb981c12d14ba39d6f3c1a33afe71da",
|
|
|
|
|
"credential_request": "c4d73dc3087bab36dd9cf0dd6b405e0474d8d12b41a7bd7317ff8ae04416696e8f752fbb35518786eb32a951a8d1dc5fb591b0ca752d18d71e8cc05c52d5a19950a57787f5cebc6be96834eb2ea4ef35556c1c4c7780161b65724e4a1057d32a",
|
|
|
|
|
"credential_response": "9e024b7621ad17a1809d25a3ca47c42eb12cf67e052a453c38ab119f4344ae020ab98ae7b94c33c362f9bc47e56ced702a5e118fd7d71c148642c1df3ee95ef086ce2acd2daf1d9528991d88e4baaa43cf6b93527ba08b1a734471ab11f85b469785dd0b2f144131370c169e81fcffae8febdd7543303f6f6de974274f6018904dde8dc42044718430f2c986266d93f7a56109a7ea85318481ee51f1098ee4de4d260c4b41172ddce3f3d10c1193c972eedfa6cb807c6a198a06620adb5945d66dc1d8525660605c3abcd86ec8a690f8af3d5bece6ea76d860a0de644d9d65089cee765b7149cad46e928a79a294d410fe63f8e4be824dfc00d9a233fc2c4378199ff3e47a208757018a0084f65fb76f9645c10a687a1421a634e8a3fbadb10d49fca58e37e00c4e1963b67798a4577014422b316c0621d5c25584f1a00d8dd3",
|
|
|
|
|
"credential_finalization": "6398492ae387d8816552721723fdf602da8d30e39a489a6f373f6a012ae3b27e7f2b9a739f64de3faa1409596cec67cb916d510fbc2bdf2dd48db56bbdd354ee",
|
|
|
|
|
"client_registration_state": "c4d73dc3087bab36dd9cf0dd6b405e0474d8d12b41a7bd7317ff8ae04416696ec8fa84eba32048544608f67a0ab43aebe21ab78ebbddf32e8210b9b7dbc5000270617373776f7264",
|
|
|
|
|
"client_login_state": "c8fa84eba32048544608f67a0ab43aebe21ab78ebbddf32e8210b9b7dbc500020060c4d73dc3087bab36dd9cf0dd6b405e0474d8d12b41a7bd7317ff8ae04416696e8f752fbb35518786eb32a951a8d1dc5fb591b0ca752d18d71e8cc05c52d5a19950a57787f5cebc6be96834eb2ea4ef35556c1c4c7780161b65724e4a1057d32a00404d113729710988d19529ab39447726d615e179bf9bcff6c09febe7e18518aa028f752fbb35518786eb32a951a8d1dc5fb591b0ca752d18d71e8cc05c52d5a19970617373776f7264",
|
|
|
|
|
"server_login_state": "a6e54e3c6f8c98dbcaddcc67bf9835afb398a922a516a854a96342037a4931c46ff55ce773b85a70aa09c89c15c77beb8df0fa528b2b091ce30e88ae3b29306ab476323aac7cc3fe9ef8793c6cea8e1d54d9ea2d663729a3095494572e952ac61180e42793c167951787b3bda61bce732c76dd9a7a11a7c835cbad8b19bdc75bdde7a653389faca8ad458f03faea5d130b374259940f0183f3b666c930c6c7947a0c0cc48d3848da0e2d4be117a3dfb8837f76528bb4ed40ba9412db51fe14eb",
|
|
|
|
|
"password_file": "a8f448f10d547cd8186cfd7ab33ec055a5bc9f05306fafd6816c84356fb0f8672f0991ad6d648a22b937055e4db6a5fd381cf5e9fa3ed4128338202039b292cdad8ebc3b1bbd332230e4914c7d4c910642f8c22f4494e2e56c99aff79a698759fa12397b47d1b9cac12902a6d5aa751839e7d2eb97338718936724ef5a8671067c616a828ff31a550e31d5fc178d3ac8171b2213967b504513d982ce66c9e93159cc7fe10e845060fcb721b6e681b60f6bb981c12d14ba39d6f3c1a33afe71da",
|
|
|
|
|
"export_key": "d2884167b7fb2a9aca88f606438d2d2c3b99ed086f916f982efe041a8b1d57ddbc6f04f9fd0d4fa2537b0bc645f3280335a9bcc9b99bab12cd301480a7e85a07",
|
|
|
|
|
"session_key": "dde7a653389faca8ad458f03faea5d130b374259940f0183f3b666c930c6c7947a0c0cc48d3848da0e2d4be117a3dfb8837f76528bb4ed40ba9412db51fe14eb"
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
fn decode(values: &Value, key: &str) -> Option<Vec<u8>> {
|
|
|
|
|
values[key]
|
|
|
|
|
.as_str()
|
|
|
|
|
.and_then(|s| hex::decode(&s.to_string()).ok())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn populate_test_vectors(values: &Value) -> TestVectorParameters {
|
|
|
|
|
TestVectorParameters {
|
|
|
|
|
client_s_pk: decode(&values, "client_s_pk").unwrap(),
|
|
|
|
|
client_s_sk: decode(&values, "client_s_sk").unwrap(),
|
|
|
|
|
client_e_pk: decode(&values, "client_e_pk").unwrap(),
|
|
|
|
|
client_e_sk: decode(&values, "client_e_sk").unwrap(),
|
|
|
|
|
server_s_pk: decode(&values, "server_s_pk").unwrap(),
|
|
|
|
|
server_s_sk: decode(&values, "server_s_sk").unwrap(),
|
|
|
|
|
server_e_pk: decode(&values, "server_e_pk").unwrap(),
|
|
|
|
|
server_e_sk: decode(&values, "server_e_sk").unwrap(),
|
2021-04-30 15:56:51 -07:00
|
|
|
fake_sk: decode(&values, "fake_sk").unwrap(),
|
2021-04-16 01:07:07 -07:00
|
|
|
credential_identifier: decode(&values, "credential_identifier").unwrap(),
|
2020-11-02 13:51:43 -08:00
|
|
|
id_u: decode(&values, "id_u").unwrap(),
|
|
|
|
|
id_s: decode(&values, "id_s").unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
password: decode(&values, "password").unwrap(),
|
|
|
|
|
blinding_factor: decode(&values, "blinding_factor").unwrap(),
|
2021-04-16 01:07:07 -07:00
|
|
|
oprf_seed: decode(&values, "oprf_seed").unwrap(),
|
|
|
|
|
masking_nonce: decode(&values, "masking_nonce").unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
envelope_nonce: decode(&values, "envelope_nonce").unwrap(),
|
|
|
|
|
client_nonce: decode(&values, "client_nonce").unwrap(),
|
|
|
|
|
server_nonce: decode(&values, "server_nonce").unwrap(),
|
2021-04-30 15:56:51 -07:00
|
|
|
context: decode(&values, "context").unwrap(),
|
2020-12-12 21:53:33 -08:00
|
|
|
registration_request: decode(&values, "registration_request").unwrap(),
|
|
|
|
|
registration_response: decode(&values, "registration_response").unwrap(),
|
2020-12-17 14:00:32 -08:00
|
|
|
registration_upload: decode(&values, "registration_upload").unwrap(),
|
2020-12-12 21:53:33 -08:00
|
|
|
credential_request: decode(&values, "credential_request").unwrap(),
|
|
|
|
|
credential_response: decode(&values, "credential_response").unwrap(),
|
2021-01-26 09:27:30 -08:00
|
|
|
credential_finalization: decode(&values, "credential_finalization").unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
client_registration_state: decode(&values, "client_registration_state").unwrap(),
|
|
|
|
|
client_login_state: decode(&values, "client_login_state").unwrap(),
|
|
|
|
|
server_login_state: decode(&values, "server_login_state").unwrap(),
|
|
|
|
|
password_file: decode(&values, "password_file").unwrap(),
|
2020-09-01 11:23:00 -07:00
|
|
|
export_key: decode(&values, "export_key").unwrap(),
|
2021-02-08 11:19:06 -08:00
|
|
|
session_key: decode(&values, "session_key").unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn stringify_test_vectors(p: &TestVectorParameters) -> String {
|
|
|
|
|
let mut s = String::new();
|
|
|
|
|
s.push_str("{\n");
|
|
|
|
|
s.push_str(format!("\"client_s_pk\": \"{}\",\n", hex::encode(&p.client_s_pk)).as_str());
|
|
|
|
|
s.push_str(format!("\"client_s_sk\": \"{}\",\n", hex::encode(&p.client_s_sk)).as_str());
|
|
|
|
|
s.push_str(format!("\"client_e_pk\": \"{}\",\n", hex::encode(&p.client_e_pk)).as_str());
|
|
|
|
|
s.push_str(format!("\"client_e_sk\": \"{}\",\n", hex::encode(&p.client_e_sk)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_s_pk\": \"{}\",\n", hex::encode(&p.server_s_pk)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_s_sk\": \"{}\",\n", hex::encode(&p.server_s_sk)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_e_pk\": \"{}\",\n", hex::encode(&p.server_e_pk)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_e_sk\": \"{}\",\n", hex::encode(&p.server_e_sk)).as_str());
|
2021-07-12 15:07:29 -07:00
|
|
|
s.push_str(format!("\"fake_sk\": \"{}\",\n", hex::encode(&p.fake_sk)).as_str());
|
2021-04-16 01:07:07 -07:00
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"credential_identifier\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.credential_identifier)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2020-11-02 13:51:43 -08:00
|
|
|
s.push_str(format!("\"id_u\": \"{}\",\n", hex::encode(&p.id_u)).as_str());
|
|
|
|
|
s.push_str(format!("\"id_s\": \"{}\",\n", hex::encode(&p.id_s)).as_str());
|
2020-06-05 09:35:14 -07:00
|
|
|
s.push_str(format!("\"password\": \"{}\",\n", hex::encode(&p.password)).as_str());
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"blinding_factor\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.blinding_factor)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2021-04-16 01:07:07 -07:00
|
|
|
s.push_str(format!("\"oprf_seed\": \"{}\",\n", hex::encode(&p.oprf_seed)).as_str());
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"masking_nonce\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.masking_nonce)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"envelope_nonce\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.envelope_nonce)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(format!("\"client_nonce\": \"{}\",\n", hex::encode(&p.client_nonce)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_nonce\": \"{}\",\n", hex::encode(&p.server_nonce)).as_str());
|
2021-04-30 15:56:51 -07:00
|
|
|
s.push_str(format!("\"context\": \"{}\",\n", hex::encode(&p.context)).as_str());
|
2020-12-12 21:53:33 -08:00
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"registration_request\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.registration_request)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"registration_response\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.registration_response)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2020-12-17 14:00:32 -08:00
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"registration_upload\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.registration_upload)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2020-12-12 21:53:33 -08:00
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"credential_request\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.credential_request)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"credential_response\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.credential_response)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2021-01-26 09:27:30 -08:00
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"credential_finalization\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.credential_finalization)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"client_registration_state\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.client_registration_state)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"client_login_state\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.client_login_state)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"server_login_state\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.server_login_state)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"password_file\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.password_file)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2020-09-01 11:23:00 -07:00
|
|
|
s.push_str(format!("\"export_key\": \"{}\",\n", hex::encode(&p.export_key)).as_str());
|
2021-02-08 11:19:06 -08:00
|
|
|
s.push_str(format!("\"session_key\": \"{}\"\n", hex::encode(&p.session_key)).as_str());
|
2020-06-05 09:35:14 -07:00
|
|
|
s.push_str("}\n");
|
|
|
|
|
s
|
|
|
|
|
}
|
|
|
|
|
|
2021-01-25 13:20:36 -08:00
|
|
|
fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
|
2020-06-05 09:35:14 -07:00
|
|
|
let mut rng = OsRng;
|
|
|
|
|
|
|
|
|
|
// Inputs
|
2021-08-04 21:24:46 +02:00
|
|
|
let server_s_kp = KeyPair::<CS::OprfGroup>::generate_random(&mut rng);
|
|
|
|
|
let server_e_kp = KeyPair::<CS::OprfGroup>::generate_random(&mut rng);
|
|
|
|
|
let client_s_kp = KeyPair::<CS::OprfGroup>::generate_random(&mut rng);
|
|
|
|
|
let client_e_kp = KeyPair::<CS::OprfGroup>::generate_random(&mut rng);
|
|
|
|
|
let fake_kp = KeyPair::<CS::OprfGroup>::generate_random(&mut rng);
|
2021-04-16 01:07:07 -07:00
|
|
|
let credential_identifier = b"credIdentifier";
|
2020-11-02 13:51:43 -08:00
|
|
|
let id_u = b"idU";
|
|
|
|
|
let id_s = b"idS";
|
2020-06-05 09:35:14 -07:00
|
|
|
let password = b"password";
|
2021-04-30 15:56:51 -07:00
|
|
|
let context = b"context";
|
2021-04-16 01:07:07 -07:00
|
|
|
let mut oprf_seed = [0u8; 64];
|
|
|
|
|
rng.fill_bytes(&mut oprf_seed);
|
|
|
|
|
let mut masking_nonce = [0u8; 64];
|
|
|
|
|
rng.fill_bytes(&mut masking_nonce);
|
2020-09-01 11:23:00 -07:00
|
|
|
let mut envelope_nonce = [0u8; 32];
|
2020-06-05 09:35:14 -07:00
|
|
|
rng.fill_bytes(&mut envelope_nonce);
|
2021-02-02 12:12:20 -08:00
|
|
|
let mut client_nonce = vec![0u8; NonceLen::to_usize()];
|
2020-06-05 09:35:14 -07:00
|
|
|
rng.fill_bytes(&mut client_nonce);
|
2021-02-02 12:12:20 -08:00
|
|
|
let mut server_nonce = vec![0u8; NonceLen::to_usize()];
|
2020-06-05 09:35:14 -07:00
|
|
|
rng.fill_bytes(&mut server_nonce);
|
|
|
|
|
|
2021-04-30 15:56:51 -07:00
|
|
|
let fake_sk: Vec<u8> = fake_kp.private().to_vec();
|
|
|
|
|
let server_setup = ServerSetup::<CS>::deserialize(
|
|
|
|
|
&[&oprf_seed, &server_s_kp.private().to_arr()[..], &fake_sk].concat(),
|
|
|
|
|
)
|
|
|
|
|
.unwrap();
|
2021-04-16 01:07:07 -07:00
|
|
|
|
2021-08-04 21:24:46 +02:00
|
|
|
let blinding_factor = CS::OprfGroup::random_nonzero_scalar(&mut rng);
|
|
|
|
|
let blinding_factor_bytes = CS::OprfGroup::scalar_as_bytes(blinding_factor);
|
2021-01-25 13:20:36 -08:00
|
|
|
|
|
|
|
|
let mut blinding_factor_registration_rng = CycleRng::new(blinding_factor_bytes.to_vec());
|
|
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<CS>::start(&mut blinding_factor_registration_rng, password).unwrap();
|
|
|
|
|
let blinding_factor_bytes_returned =
|
2021-08-04 21:24:46 +02:00
|
|
|
CS::OprfGroup::scalar_as_bytes(client_registration_start_result.state.token.blind);
|
2021-01-25 13:20:36 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(&blinding_factor_bytes),
|
|
|
|
|
hex::encode(&blinding_factor_bytes_returned)
|
|
|
|
|
);
|
|
|
|
|
|
2020-12-12 21:53:33 -08:00
|
|
|
let registration_request_bytes = client_registration_start_result
|
|
|
|
|
.message
|
|
|
|
|
.serialize()
|
|
|
|
|
.to_vec();
|
2021-02-17 02:47:00 -08:00
|
|
|
let client_registration_state = client_registration_start_result.state.serialize().to_vec();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
2020-12-12 21:53:33 -08:00
|
|
|
let server_registration_start_result = ServerRegistration::<CS>::start(
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
2020-12-12 21:53:33 -08:00
|
|
|
client_registration_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
&credential_identifier[..],
|
2020-12-12 21:53:33 -08:00
|
|
|
)
|
|
|
|
|
.unwrap();
|
|
|
|
|
let registration_response_bytes = server_registration_start_result
|
|
|
|
|
.message
|
|
|
|
|
.serialize()
|
|
|
|
|
.to_vec();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
let mut client_s_sk_and_nonce: Vec<u8> = Vec::new();
|
2020-09-22 08:50:39 -04:00
|
|
|
client_s_sk_and_nonce.extend_from_slice(&client_s_kp.private().to_arr());
|
2020-06-05 09:35:14 -07:00
|
|
|
client_s_sk_and_nonce.extend_from_slice(&envelope_nonce);
|
|
|
|
|
|
|
|
|
|
let mut finish_registration_rng = CycleRng::new(client_s_sk_and_nonce);
|
2020-12-12 21:53:33 -08:00
|
|
|
let client_registration_finish_result = client_registration_start_result
|
|
|
|
|
.state
|
|
|
|
|
.finish(
|
|
|
|
|
&mut finish_registration_rng,
|
|
|
|
|
server_registration_start_result.message,
|
2021-04-30 15:56:51 -07:00
|
|
|
ClientRegistrationFinishParameters::WithIdentifiers(
|
|
|
|
|
Identifiers::ClientAndServerIdentifiers(id_u.to_vec(), id_s.to_vec()),
|
|
|
|
|
),
|
2020-12-12 21:53:33 -08:00
|
|
|
)
|
2020-06-05 09:35:14 -07:00
|
|
|
.unwrap();
|
2020-12-17 14:00:32 -08:00
|
|
|
let registration_upload_bytes = client_registration_finish_result
|
2020-12-12 21:53:33 -08:00
|
|
|
.message
|
|
|
|
|
.serialize()
|
|
|
|
|
.to_vec();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
2021-04-16 01:07:07 -07:00
|
|
|
let password_file = ServerRegistration::finish(client_registration_finish_result.message);
|
2021-02-17 02:47:00 -08:00
|
|
|
let password_file_bytes = password_file.serialize();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
let mut client_login_start: Vec<u8> = Vec::new();
|
2021-01-25 13:20:36 -08:00
|
|
|
client_login_start.extend_from_slice(&blinding_factor_bytes);
|
2020-09-22 08:50:39 -04:00
|
|
|
client_login_start.extend_from_slice(&client_e_kp.private().to_arr());
|
2020-06-05 09:35:14 -07:00
|
|
|
client_login_start.extend_from_slice(&client_nonce);
|
|
|
|
|
|
|
|
|
|
let mut client_login_start_rng = CycleRng::new(client_login_start);
|
2021-04-30 15:56:51 -07:00
|
|
|
let client_login_start_result =
|
|
|
|
|
ClientLogin::<CS>::start(&mut client_login_start_rng, password).unwrap();
|
2020-12-12 21:53:33 -08:00
|
|
|
let credential_request_bytes = client_login_start_result.message.serialize().to_vec();
|
2021-07-08 11:04:32 -07:00
|
|
|
let client_login_state = client_login_start_result
|
|
|
|
|
.state
|
|
|
|
|
.serialize()
|
|
|
|
|
.unwrap()
|
|
|
|
|
.to_vec();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
2021-01-26 09:27:30 -08:00
|
|
|
let mut server_e_sk_and_nonce_rng = CycleRng::new(
|
|
|
|
|
[
|
2021-04-16 01:07:07 -07:00
|
|
|
masking_nonce.to_vec(),
|
2021-01-26 09:27:30 -08:00
|
|
|
server_e_kp.private().to_arr().to_vec(),
|
|
|
|
|
server_nonce.to_vec(),
|
|
|
|
|
]
|
|
|
|
|
.concat(),
|
|
|
|
|
);
|
2020-11-16 14:05:43 -08:00
|
|
|
let server_login_start_result = ServerLogin::<CS>::start(
|
2021-01-26 09:27:30 -08:00
|
|
|
&mut server_e_sk_and_nonce_rng,
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
|
|
|
|
Some(password_file),
|
2020-12-12 21:53:33 -08:00
|
|
|
client_login_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
credential_identifier,
|
2021-04-30 15:56:51 -07:00
|
|
|
ServerLoginStartParameters::WithContextAndIdentifiers(
|
|
|
|
|
context.to_vec(),
|
|
|
|
|
Identifiers::ClientAndServerIdentifiers(id_u.to_vec(), id_s.to_vec()),
|
2021-01-04 14:27:20 -08:00
|
|
|
),
|
2020-06-05 09:35:14 -07:00
|
|
|
)
|
|
|
|
|
.unwrap();
|
2020-12-12 21:53:33 -08:00
|
|
|
let credential_response_bytes = server_login_start_result.message.serialize().to_vec();
|
2021-02-17 02:47:00 -08:00
|
|
|
let server_login_state = server_login_start_result.state.serialize().to_vec();
|
2020-11-16 14:05:43 -08:00
|
|
|
|
|
|
|
|
let client_login_finish_result = client_login_start_result
|
2020-12-12 21:53:33 -08:00
|
|
|
.state
|
2020-11-16 14:05:43 -08:00
|
|
|
.finish(
|
2020-12-12 21:53:33 -08:00
|
|
|
server_login_start_result.message,
|
2021-04-30 15:56:51 -07:00
|
|
|
ClientLoginFinishParameters::WithContextAndIdentifiers(
|
|
|
|
|
context.to_vec(),
|
|
|
|
|
Identifiers::ClientAndServerIdentifiers(id_u.to_vec(), id_s.to_vec()),
|
|
|
|
|
),
|
2020-11-16 14:05:43 -08:00
|
|
|
)
|
2020-06-05 09:35:14 -07:00
|
|
|
.unwrap();
|
2021-02-17 02:47:00 -08:00
|
|
|
let credential_finalization_bytes = client_login_finish_result.message.serialize();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
TestVectorParameters {
|
2020-09-22 08:50:39 -04:00
|
|
|
client_s_pk: client_s_kp.public().to_arr().to_vec(),
|
|
|
|
|
client_s_sk: client_s_kp.private().to_arr().to_vec(),
|
|
|
|
|
client_e_pk: client_e_kp.public().to_arr().to_vec(),
|
|
|
|
|
client_e_sk: client_e_kp.private().to_arr().to_vec(),
|
|
|
|
|
server_s_pk: server_s_kp.public().to_arr().to_vec(),
|
|
|
|
|
server_s_sk: server_s_kp.private().to_arr().to_vec(),
|
|
|
|
|
server_e_pk: server_e_kp.public().to_arr().to_vec(),
|
|
|
|
|
server_e_sk: server_e_kp.private().to_arr().to_vec(),
|
2021-04-30 15:56:51 -07:00
|
|
|
fake_sk,
|
2021-04-16 01:07:07 -07:00
|
|
|
credential_identifier: credential_identifier.to_vec(),
|
2020-11-02 13:51:43 -08:00
|
|
|
id_u: id_u.to_vec(),
|
|
|
|
|
id_s: id_s.to_vec(),
|
2020-06-05 09:35:14 -07:00
|
|
|
password: password.to_vec(),
|
|
|
|
|
blinding_factor: blinding_factor_bytes.to_vec(),
|
2021-04-16 01:07:07 -07:00
|
|
|
oprf_seed: oprf_seed.to_vec(),
|
|
|
|
|
masking_nonce: masking_nonce.to_vec(),
|
2020-06-05 09:35:14 -07:00
|
|
|
envelope_nonce: envelope_nonce.to_vec(),
|
|
|
|
|
client_nonce: client_nonce.to_vec(),
|
|
|
|
|
server_nonce: server_nonce.to_vec(),
|
2021-04-30 15:56:51 -07:00
|
|
|
context: context.to_vec(),
|
2020-12-12 21:53:33 -08:00
|
|
|
registration_request: registration_request_bytes,
|
|
|
|
|
registration_response: registration_response_bytes,
|
2020-12-17 14:00:32 -08:00
|
|
|
registration_upload: registration_upload_bytes,
|
2020-12-12 21:53:33 -08:00
|
|
|
credential_request: credential_request_bytes,
|
|
|
|
|
credential_response: credential_response_bytes,
|
2021-01-26 09:27:30 -08:00
|
|
|
credential_finalization: credential_finalization_bytes,
|
2020-06-05 09:35:14 -07:00
|
|
|
password_file: password_file_bytes,
|
|
|
|
|
client_registration_state,
|
|
|
|
|
client_login_state,
|
|
|
|
|
server_login_state,
|
2021-06-15 10:52:51 +02:00
|
|
|
session_key: client_login_finish_result.session_key,
|
2020-12-12 21:53:33 -08:00
|
|
|
export_key: client_registration_finish_result.export_key.to_vec(),
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn generate_test_vectors() {
|
2021-01-25 13:20:36 -08:00
|
|
|
let parameters = generate_parameters::<RistrettoSha5123dhNoSlowHash>();
|
2020-06-05 09:35:14 -07:00
|
|
|
println!("{}", stringify_test_vectors(¶meters));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-12 21:53:33 -08:00
|
|
|
fn test_registration_request() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
2021-01-25 13:20:36 -08:00
|
|
|
let mut rng = CycleRng::new(parameters.blinding_factor.to_vec());
|
|
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(&mut rng, ¶meters.password)?;
|
2020-12-12 21:53:33 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.registration_request),
|
|
|
|
|
hex::encode(client_registration_start_result.message.serialize())
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.client_registration_state),
|
2021-02-17 02:47:00 -08:00
|
|
|
hex::encode(client_registration_start_result.state.serialize())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
2021-06-10 21:48:38 +02:00
|
|
|
#[cfg(feature = "serialize")]
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_serialization() -> Result<(), ProtocolError> {
|
|
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
let mut rng = CycleRng::new(parameters.blinding_factor.to_vec());
|
|
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(&mut rng, ¶meters.password)?;
|
|
|
|
|
{
|
|
|
|
|
// Test the json serialization (human-readable, base64).
|
|
|
|
|
let registration_request_json =
|
|
|
|
|
serde_json::to_string(&client_registration_start_result.message).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
registration_request_json,
|
2021-07-12 12:33:19 -07:00
|
|
|
r#""xNc9wwh7qzbdnPDda0BeBHTY0StBp71zF/+K4EQWaW4=""#
|
2021-06-10 21:48:38 +02:00
|
|
|
);
|
|
|
|
|
let registration_request: RegistrationRequest<RistrettoSha5123dhNoSlowHash> =
|
|
|
|
|
serde_json::from_str(®istration_request_json).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(client_registration_start_result.message.serialize()),
|
|
|
|
|
hex::encode(registration_request.serialize()),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
{
|
|
|
|
|
// Test the bincode serialization (binary).
|
|
|
|
|
let registration_request_bin =
|
|
|
|
|
bincode::serialize(&client_registration_start_result.message).unwrap();
|
|
|
|
|
assert_eq!(registration_request_bin.len(), 40);
|
|
|
|
|
let registration_request: RegistrationRequest<RistrettoSha5123dhNoSlowHash> =
|
|
|
|
|
bincode::deserialize(®istration_request_bin).unwrap();
|
|
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(client_registration_start_result.message.serialize()),
|
|
|
|
|
hex::encode(registration_request.serialize()),
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2020-06-05 09:35:14 -07:00
|
|
|
#[test]
|
2020-12-12 21:53:33 -08:00
|
|
|
fn test_registration_response() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
2021-04-16 01:07:07 -07:00
|
|
|
|
|
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::deserialize(
|
2021-04-30 15:56:51 -07:00
|
|
|
&[
|
|
|
|
|
¶meters.oprf_seed[..],
|
|
|
|
|
¶meters.server_s_sk[..],
|
|
|
|
|
¶meters.fake_sk[..],
|
|
|
|
|
]
|
|
|
|
|
.concat(),
|
2021-04-16 01:07:07 -07:00
|
|
|
)?;
|
|
|
|
|
|
2021-01-25 13:20:36 -08:00
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
2021-02-02 12:12:20 -08:00
|
|
|
RegistrationRequest::deserialize(¶meters.registration_request[..])?,
|
2021-04-16 01:07:07 -07:00
|
|
|
¶meters.credential_identifier,
|
2021-01-25 13:20:36 -08:00
|
|
|
)?;
|
2020-12-12 21:53:33 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(parameters.registration_response),
|
|
|
|
|
hex::encode(server_registration_start_result.message.serialize())
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-17 14:00:32 -08:00
|
|
|
fn test_registration_upload() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
|
|
|
|
let client_s_sk_and_nonce: Vec<u8> =
|
|
|
|
|
[parameters.client_s_sk, parameters.envelope_nonce].concat();
|
|
|
|
|
let mut finish_registration_rng = CycleRng::new(client_s_sk_and_nonce);
|
2021-02-17 02:47:00 -08:00
|
|
|
let result = ClientRegistration::<RistrettoSha5123dhNoSlowHash>::deserialize(
|
2020-06-05 09:35:14 -07:00
|
|
|
¶meters.client_registration_state[..],
|
2020-12-09 12:49:59 -08:00
|
|
|
)?
|
2020-06-14 23:25:31 -07:00
|
|
|
.finish(
|
2020-06-05 09:35:14 -07:00
|
|
|
&mut finish_registration_rng,
|
2021-02-02 12:12:20 -08:00
|
|
|
RegistrationResponse::deserialize(¶meters.registration_response[..])?,
|
2021-04-30 15:56:51 -07:00
|
|
|
ClientRegistrationFinishParameters::WithIdentifiers(
|
|
|
|
|
Identifiers::ClientAndServerIdentifiers(parameters.id_u, parameters.id_s),
|
|
|
|
|
),
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-12-12 21:53:33 -08:00
|
|
|
|
|
|
|
|
assert_eq!(
|
2020-12-17 14:00:32 -08:00
|
|
|
hex::encode(parameters.registration_upload),
|
2020-12-12 21:53:33 -08:00
|
|
|
hex::encode(result.message.serialize())
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
2020-09-01 11:23:00 -07:00
|
|
|
hex::encode(parameters.export_key),
|
2020-12-12 21:53:33 -08:00
|
|
|
hex::encode(result.export_key.to_vec())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-09 12:49:59 -08:00
|
|
|
fn test_password_file() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
2021-04-16 01:07:07 -07:00
|
|
|
let password_file = ServerRegistration::finish(RegistrationUpload::<
|
|
|
|
|
RistrettoSha5123dhNoSlowHash,
|
|
|
|
|
>::deserialize(
|
|
|
|
|
¶meters.registration_upload[..]
|
|
|
|
|
)?);
|
2020-12-12 21:53:33 -08:00
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(parameters.password_file),
|
2021-02-17 02:47:00 -08:00
|
|
|
hex::encode(password_file.serialize())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-12 21:53:33 -08:00
|
|
|
fn test_credential_request() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
2021-01-25 13:20:36 -08:00
|
|
|
let client_login_start_rng = [
|
|
|
|
|
parameters.blinding_factor,
|
2020-06-05 09:35:14 -07:00
|
|
|
parameters.client_e_sk,
|
|
|
|
|
parameters.client_nonce,
|
|
|
|
|
]
|
|
|
|
|
.concat();
|
2021-01-25 13:20:36 -08:00
|
|
|
let mut client_login_start_rng = CycleRng::new(client_login_start_rng);
|
|
|
|
|
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
2020-11-04 11:33:58 -05:00
|
|
|
&mut client_login_start_rng,
|
2020-12-12 21:53:33 -08:00
|
|
|
¶meters.password,
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-11-16 14:05:43 -08:00
|
|
|
assert_eq!(
|
2020-12-12 21:53:33 -08:00
|
|
|
hex::encode(¶meters.credential_request),
|
|
|
|
|
hex::encode(client_login_start_result.message.serialize())
|
2020-11-16 14:05:43 -08:00
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.client_login_state),
|
2021-07-08 11:04:32 -07:00
|
|
|
hex::encode(client_login_start_result.state.serialize()?)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-12 21:53:33 -08:00
|
|
|
fn test_credential_response() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
2021-04-16 01:07:07 -07:00
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::deserialize(
|
2021-04-30 15:56:51 -07:00
|
|
|
&[
|
|
|
|
|
¶meters.oprf_seed[..],
|
|
|
|
|
¶meters.server_s_sk[..],
|
|
|
|
|
¶meters.fake_sk[..],
|
|
|
|
|
]
|
|
|
|
|
.concat(),
|
2021-04-16 01:07:07 -07:00
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let mut server_e_sk_and_nonce_rng = CycleRng::new(
|
|
|
|
|
[
|
|
|
|
|
parameters.masking_nonce,
|
|
|
|
|
parameters.server_e_sk,
|
|
|
|
|
parameters.server_nonce,
|
|
|
|
|
]
|
|
|
|
|
.concat(),
|
|
|
|
|
);
|
2021-01-25 13:20:36 -08:00
|
|
|
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
2021-01-26 09:27:30 -08:00
|
|
|
&mut server_e_sk_and_nonce_rng,
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
|
|
|
|
Some(ServerRegistration::deserialize(
|
|
|
|
|
¶meters.password_file[..],
|
|
|
|
|
)?),
|
2021-01-25 13:20:36 -08:00
|
|
|
CredentialRequest::<RistrettoSha5123dhNoSlowHash>::deserialize(
|
|
|
|
|
¶meters.credential_request[..],
|
2021-02-02 12:12:20 -08:00
|
|
|
)?,
|
2021-04-16 01:07:07 -07:00
|
|
|
¶meters.credential_identifier,
|
2021-04-30 15:56:51 -07:00
|
|
|
ServerLoginStartParameters::WithContextAndIdentifiers(
|
|
|
|
|
parameters.context,
|
|
|
|
|
Identifiers::ClientAndServerIdentifiers(parameters.id_u, parameters.id_s),
|
2021-01-04 14:27:20 -08:00
|
|
|
),
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-11-16 14:05:43 -08:00
|
|
|
assert_eq!(
|
2020-12-12 21:53:33 -08:00
|
|
|
hex::encode(¶meters.credential_response),
|
|
|
|
|
hex::encode(server_login_start_result.message.serialize())
|
2020-11-16 14:05:43 -08:00
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.server_login_state),
|
2021-02-17 02:47:00 -08:00
|
|
|
hex::encode(server_login_start_result.state.serialize())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2021-01-26 09:27:30 -08:00
|
|
|
fn test_credential_finalization() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
2021-02-17 02:47:00 -08:00
|
|
|
let client_login_finish_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::deserialize(
|
|
|
|
|
¶meters.client_login_state[..],
|
|
|
|
|
)?
|
|
|
|
|
.finish(
|
|
|
|
|
CredentialResponse::<RistrettoSha5123dhNoSlowHash>::deserialize(
|
|
|
|
|
¶meters.credential_response[..],
|
|
|
|
|
)?,
|
2021-04-30 15:56:51 -07:00
|
|
|
ClientLoginFinishParameters::WithContextAndIdentifiers(
|
|
|
|
|
parameters.context,
|
|
|
|
|
Identifiers::ClientAndServerIdentifiers(parameters.id_u, parameters.id_s),
|
|
|
|
|
),
|
2021-02-17 02:47:00 -08:00
|
|
|
)?;
|
2020-12-12 21:53:33 -08:00
|
|
|
|
2020-11-29 23:06:55 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.server_s_pk),
|
2021-01-05 10:13:00 -08:00
|
|
|
hex::encode(&client_login_finish_result.server_s_pk.to_arr().to_vec())
|
2020-11-29 23:06:55 -08:00
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
2021-02-08 11:19:06 -08:00
|
|
|
hex::encode(¶meters.session_key),
|
|
|
|
|
hex::encode(&client_login_finish_result.session_key)
|
2020-11-16 14:05:43 -08:00
|
|
|
);
|
|
|
|
|
assert_eq!(
|
2021-01-26 09:27:30 -08:00
|
|
|
hex::encode(¶meters.credential_finalization),
|
2021-02-17 02:47:00 -08:00
|
|
|
hex::encode(client_login_finish_result.message.serialize())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
assert_eq!(
|
2020-09-01 11:23:00 -07:00
|
|
|
hex::encode(¶meters.export_key),
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(client_login_finish_result.export_key)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_server_login_finish() -> Result<(), ProtocolError> {
|
|
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
2021-02-17 02:47:00 -08:00
|
|
|
let server_login_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::deserialize(
|
|
|
|
|
¶meters.server_login_state[..],
|
|
|
|
|
)?
|
|
|
|
|
.finish(CredentialFinalization::deserialize(
|
|
|
|
|
¶meters.credential_finalization[..],
|
|
|
|
|
)?)?;
|
2020-12-12 21:53:33 -08:00
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
2021-02-08 11:19:06 -08:00
|
|
|
hex::encode(parameters.session_key),
|
2021-06-04 16:29:58 -07:00
|
|
|
hex::encode(&server_login_result.session_key)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn test_complete_flow(
|
|
|
|
|
registration_password: &[u8],
|
|
|
|
|
login_password: &[u8],
|
|
|
|
|
) -> Result<(), ProtocolError> {
|
2021-04-16 01:07:07 -07:00
|
|
|
let credential_identifier = b"credentialIdentifier";
|
2020-06-05 09:35:14 -07:00
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
2021-04-16 01:07:07 -07:00
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
|
2021-01-25 13:20:36 -08:00
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
registration_password,
|
|
|
|
|
)?;
|
|
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
2021-01-25 13:20:36 -08:00
|
|
|
client_registration_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
credential_identifier,
|
2021-01-25 13:20:36 -08:00
|
|
|
)?;
|
2020-12-17 14:00:32 -08:00
|
|
|
let client_registration_finish_result = client_registration_start_result.state.finish(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
server_registration_start_result.message,
|
|
|
|
|
ClientRegistrationFinishParameters::default(),
|
|
|
|
|
)?;
|
2021-04-16 01:07:07 -07:00
|
|
|
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
|
2021-04-30 15:56:51 -07:00
|
|
|
let client_login_start_result =
|
|
|
|
|
ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(&mut client_rng, login_password)?;
|
2021-01-25 13:20:36 -08:00
|
|
|
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
2020-12-12 21:53:33 -08:00
|
|
|
&mut server_rng,
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
|
|
|
|
Some(p_file),
|
2020-12-12 21:53:33 -08:00
|
|
|
client_login_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
credential_identifier,
|
2020-11-16 14:05:43 -08:00
|
|
|
ServerLoginStartParameters::default(),
|
2020-07-13 15:23:29 -07:00
|
|
|
)?;
|
2020-06-05 09:35:14 -07:00
|
|
|
|
2020-12-12 21:53:33 -08:00
|
|
|
let client_login_result = client_login_start_result.state.finish(
|
|
|
|
|
server_login_start_result.message,
|
2020-11-16 14:05:43 -08:00
|
|
|
ClientLoginFinishParameters::default(),
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
if hex::encode(registration_password) == hex::encode(login_password) {
|
2020-11-16 14:05:43 -08:00
|
|
|
let client_login_finish_result = client_login_result?;
|
|
|
|
|
let server_login_finish_result = server_login_start_result
|
2020-12-12 21:53:33 -08:00
|
|
|
.state
|
|
|
|
|
.finish(client_login_finish_result.message)?;
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
assert_eq!(
|
2021-06-04 16:29:58 -07:00
|
|
|
hex::encode(&server_login_finish_result.session_key),
|
|
|
|
|
hex::encode(&client_login_finish_result.session_key)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
assert_eq!(
|
2020-12-12 21:53:33 -08:00
|
|
|
hex::encode(client_registration_finish_result.export_key),
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(client_login_finish_result.export_key)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
} else {
|
2021-03-01 19:23:09 -08:00
|
|
|
assert!(match client_login_result {
|
|
|
|
|
Err(ProtocolError::VerificationError(PakeError::InvalidLoginError)) => true,
|
|
|
|
|
_ => false,
|
|
|
|
|
});
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_complete_flow_success() -> Result<(), ProtocolError> {
|
|
|
|
|
test_complete_flow(b"good password", b"good password")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_complete_flow_fail() -> Result<(), ProtocolError> {
|
|
|
|
|
test_complete_flow(b"good password", b"bad password")
|
|
|
|
|
}
|
2021-06-04 16:29:58 -07:00
|
|
|
|
|
|
|
|
// Zeroize tests
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_zeroize_client_registration_start() -> Result<(), ProtocolError> {
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let mut state = client_registration_start_result.state;
|
|
|
|
|
let ptrs = state.as_byte_ptrs();
|
|
|
|
|
state.zeroize();
|
|
|
|
|
|
|
|
|
|
for (ptr, len) in ptrs {
|
|
|
|
|
let bytes = unsafe { from_raw_parts(ptr, len) };
|
|
|
|
|
assert!(bytes.iter().all(|&x| x == 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> {
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
2021-04-16 01:07:07 -07:00
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
|
2021-06-04 16:29:58 -07:00
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
2021-06-04 16:29:58 -07:00
|
|
|
client_registration_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
|
2021-06-04 16:29:58 -07:00
|
|
|
)?;
|
|
|
|
|
let client_registration_finish_result = client_registration_start_result.state.finish(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
server_registration_start_result.message,
|
|
|
|
|
ClientRegistrationFinishParameters::default(),
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let mut state = client_registration_finish_result.state;
|
|
|
|
|
let ptrs = state.as_byte_ptrs();
|
|
|
|
|
state.zeroize();
|
|
|
|
|
|
|
|
|
|
for (ptr, len) in ptrs {
|
|
|
|
|
let bytes = unsafe { from_raw_parts(ptr, len) };
|
|
|
|
|
assert!(bytes.iter().all(|&x| x == 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_zeroize_server_registration_finish() -> Result<(), ProtocolError> {
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
2021-04-16 01:07:07 -07:00
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
|
2021-06-04 16:29:58 -07:00
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
2021-06-04 16:29:58 -07:00
|
|
|
client_registration_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
|
2021-06-04 16:29:58 -07:00
|
|
|
)?;
|
|
|
|
|
let client_registration_finish_result = client_registration_start_result.state.finish(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
server_registration_start_result.message,
|
|
|
|
|
ClientRegistrationFinishParameters::default(),
|
|
|
|
|
)?;
|
2021-04-16 01:07:07 -07:00
|
|
|
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
|
2021-06-04 16:29:58 -07:00
|
|
|
|
|
|
|
|
let mut state = p_file;
|
|
|
|
|
let ptrs = state.as_byte_ptrs();
|
|
|
|
|
state.zeroize();
|
|
|
|
|
|
|
|
|
|
for (ptr, len) in ptrs {
|
|
|
|
|
let bytes = unsafe { from_raw_parts(ptr, len) };
|
|
|
|
|
assert!(bytes.iter().all(|&x| x == 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_zeroize_client_login_start() -> Result<(), ProtocolError> {
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let mut state = client_login_start_result.state;
|
|
|
|
|
let ptrs = state.as_byte_ptrs();
|
|
|
|
|
state.zeroize();
|
|
|
|
|
|
|
|
|
|
for (ptr, len) in ptrs {
|
|
|
|
|
let bytes = unsafe { from_raw_parts(ptr, len) };
|
|
|
|
|
assert!(bytes.iter().all(|&x| x == 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_zeroize_server_login_start() -> Result<(), ProtocolError> {
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
2021-04-16 01:07:07 -07:00
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
|
2021-06-04 16:29:58 -07:00
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
2021-06-04 16:29:58 -07:00
|
|
|
client_registration_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
|
2021-06-04 16:29:58 -07:00
|
|
|
)?;
|
|
|
|
|
let client_registration_finish_result = client_registration_start_result.state.finish(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
server_registration_start_result.message,
|
|
|
|
|
ClientRegistrationFinishParameters::default(),
|
|
|
|
|
)?;
|
2021-04-16 01:07:07 -07:00
|
|
|
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
|
2021-06-04 16:29:58 -07:00
|
|
|
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut server_rng,
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
|
|
|
|
Some(p_file),
|
2021-06-04 16:29:58 -07:00
|
|
|
client_login_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
|
2021-06-04 16:29:58 -07:00
|
|
|
ServerLoginStartParameters::default(),
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let mut state = server_login_start_result.state;
|
|
|
|
|
let ptrs = state.as_byte_ptrs();
|
|
|
|
|
state.zeroize();
|
|
|
|
|
|
|
|
|
|
for (ptr, len) in ptrs {
|
|
|
|
|
let bytes = unsafe { from_raw_parts(ptr, len) };
|
|
|
|
|
assert!(bytes.iter().all(|&x| x == 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
2021-04-16 01:07:07 -07:00
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
|
2021-06-04 16:29:58 -07:00
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
2021-06-04 16:29:58 -07:00
|
|
|
client_registration_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
|
2021-06-04 16:29:58 -07:00
|
|
|
)?;
|
|
|
|
|
let client_registration_finish_result = client_registration_start_result.state.finish(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
server_registration_start_result.message,
|
|
|
|
|
ClientRegistrationFinishParameters::default(),
|
|
|
|
|
)?;
|
2021-04-16 01:07:07 -07:00
|
|
|
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
|
2021-06-04 16:29:58 -07:00
|
|
|
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut server_rng,
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
|
|
|
|
Some(p_file),
|
2021-06-04 16:29:58 -07:00
|
|
|
client_login_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
|
2021-06-04 16:29:58 -07:00
|
|
|
ServerLoginStartParameters::default(),
|
|
|
|
|
)?;
|
|
|
|
|
let client_login_finish_result = client_login_start_result.state.finish(
|
|
|
|
|
server_login_start_result.message,
|
|
|
|
|
ClientLoginFinishParameters::default(),
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let mut state = client_login_finish_result.state;
|
|
|
|
|
let ptrs = state.as_byte_ptrs();
|
|
|
|
|
state.zeroize();
|
|
|
|
|
|
|
|
|
|
for (ptr, len) in ptrs {
|
|
|
|
|
let bytes = unsafe { from_raw_parts(ptr, len) };
|
|
|
|
|
assert!(bytes.iter().all(|&x| x == 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> {
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
2021-04-16 01:07:07 -07:00
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
|
2021-06-04 16:29:58 -07:00
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
2021-06-04 16:29:58 -07:00
|
|
|
client_registration_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
|
2021-06-04 16:29:58 -07:00
|
|
|
)?;
|
|
|
|
|
let client_registration_finish_result = client_registration_start_result.state.finish(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
server_registration_start_result.message,
|
|
|
|
|
ClientRegistrationFinishParameters::default(),
|
|
|
|
|
)?;
|
2021-04-16 01:07:07 -07:00
|
|
|
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
|
2021-06-04 16:29:58 -07:00
|
|
|
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut server_rng,
|
2021-04-16 01:07:07 -07:00
|
|
|
&server_setup,
|
|
|
|
|
Some(p_file),
|
2021-06-04 16:29:58 -07:00
|
|
|
client_login_start_result.message,
|
2021-04-16 01:07:07 -07:00
|
|
|
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
|
2021-06-04 16:29:58 -07:00
|
|
|
ServerLoginStartParameters::default(),
|
|
|
|
|
)?;
|
|
|
|
|
let client_login_finish_result = client_login_start_result.state.finish(
|
|
|
|
|
server_login_start_result.message,
|
|
|
|
|
ClientLoginFinishParameters::default(),
|
|
|
|
|
)?;
|
|
|
|
|
let server_login_finish_result = server_login_start_result
|
|
|
|
|
.state
|
|
|
|
|
.finish(client_login_finish_result.message)?;
|
|
|
|
|
|
|
|
|
|
let mut state = server_login_finish_result.state;
|
|
|
|
|
let ptrs = state.as_byte_ptrs();
|
|
|
|
|
state.zeroize();
|
|
|
|
|
|
|
|
|
|
for (ptr, len) in ptrs {
|
|
|
|
|
let bytes = unsafe { from_raw_parts(ptr, len) };
|
|
|
|
|
assert!(bytes.iter().all(|&x| x == 0));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2021-06-15 17:31:12 -07:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_scalar_always_nonzero() -> Result<(), ProtocolError> {
|
|
|
|
|
// Start out with a bunch of zeros to force resampling of scalar
|
|
|
|
|
let mut client_registration_rng = CycleRng::new([vec![0u8; 128], vec![1u8; 128]].concat());
|
|
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut client_registration_rng,
|
|
|
|
|
STR_PASSWORD.as_bytes(),
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
assert_ne!(
|
|
|
|
|
RistrettoPoint::identity(),
|
|
|
|
|
client_registration_start_result
|
|
|
|
|
.message
|
|
|
|
|
.get_alpha_for_testing()
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
2021-07-12 12:33:19 -07:00
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_reflected_value_error_registration() -> Result<(), ProtocolError> {
|
|
|
|
|
let credential_identifier = b"credentialIdentifier";
|
|
|
|
|
let password = b"password";
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
|
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
|
|
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(&mut client_rng, password)?;
|
|
|
|
|
let alpha = client_registration_start_result
|
|
|
|
|
.message
|
|
|
|
|
.get_alpha_for_testing();
|
|
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&server_setup,
|
|
|
|
|
client_registration_start_result.message,
|
|
|
|
|
credential_identifier,
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let reflected_registration_response = server_registration_start_result
|
|
|
|
|
.message
|
|
|
|
|
.set_beta_for_testing(alpha);
|
|
|
|
|
|
|
|
|
|
let client_registration_finish_result = client_registration_start_result.state.finish(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
reflected_registration_response,
|
|
|
|
|
ClientRegistrationFinishParameters::default(),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assert!(match client_registration_finish_result {
|
|
|
|
|
Err(ProtocolError::ReflectedValueError) => true,
|
|
|
|
|
_ => false,
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_reflected_value_error_login() -> Result<(), ProtocolError> {
|
|
|
|
|
let credential_identifier = b"credentialIdentifier";
|
|
|
|
|
let password = b"password";
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
|
|
|
|
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
|
|
|
|
|
let client_registration_start_result =
|
|
|
|
|
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(&mut client_rng, password)?;
|
|
|
|
|
let server_registration_start_result =
|
|
|
|
|
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&server_setup,
|
|
|
|
|
client_registration_start_result.message,
|
|
|
|
|
credential_identifier,
|
|
|
|
|
)?;
|
|
|
|
|
let client_registration_finish_result = client_registration_start_result.state.finish(
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
server_registration_start_result.message,
|
|
|
|
|
ClientRegistrationFinishParameters::default(),
|
|
|
|
|
)?;
|
|
|
|
|
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
|
|
|
|
|
let client_login_start_result =
|
|
|
|
|
ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(&mut client_rng, password)?;
|
|
|
|
|
let alpha = client_login_start_result.message.get_alpha_for_testing();
|
|
|
|
|
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
|
|
|
|
|
&mut server_rng,
|
|
|
|
|
&server_setup,
|
|
|
|
|
Some(p_file),
|
|
|
|
|
client_login_start_result.message,
|
|
|
|
|
credential_identifier,
|
|
|
|
|
ServerLoginStartParameters::default(),
|
|
|
|
|
)?;
|
|
|
|
|
|
|
|
|
|
let reflected_credential_response = server_login_start_result
|
|
|
|
|
.message
|
|
|
|
|
.set_beta_for_testing(alpha);
|
|
|
|
|
|
|
|
|
|
let client_login_result = client_login_start_result.state.finish(
|
|
|
|
|
reflected_credential_response,
|
|
|
|
|
ClientLoginFinishParameters::default(),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
assert!(match client_login_result {
|
|
|
|
|
Err(ProtocolError::ReflectedValueError) => true,
|
|
|
|
|
_ => false,
|
|
|
|
|
});
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|