// Copyright (c) Facebook, Inc. and its affiliates. // // This source code is licensed under both the MIT license found in the // LICENSE-MIT file in the root directory of this source tree and the Apache // License, Version 2.0 found in the LICENSE-APACHE file in the root directory // of this source tree. #![allow(unsafe_code)] use core::ops::Add; use std::string::String; use std::vec::Vec; use std::{format, println, ptr, vec}; use digest::core_api::{BlockSizeUser, CoreProxy}; use digest::{Output, OutputSizeUser}; use generic_array::typenum::{IsLess, IsLessOrEqual, Le, NonZero, Sum, Unsigned, U256}; use generic_array::ArrayLength; use rand::rngs::OsRng; use serde_json::Value; use subtle::ConstantTimeEq; use voprf::Group; use crate::ciphersuite::{CipherSuite, OprfGroup, OprfHash}; use crate::envelope::EnvelopeLen; use crate::errors::*; use crate::hash::{Hash, OutputSize, ProxyHash}; use crate::key_exchange::group::KeGroup; use crate::key_exchange::traits::{Ke1MessageLen, Ke1StateLen, Ke2MessageLen}; use crate::key_exchange::tripledh::{NonceLen, TripleDh}; use crate::keypair::SecretKey; use crate::ksf::Identity; use crate::messages::{ CredentialRequestLen, CredentialResponseLen, CredentialResponseWithoutKeLen, RegistrationResponseLen, RegistrationUploadLen, }; use crate::opaque::*; use crate::tests::mock_rng::CycleRng; use crate::*; // Tests // ===== #[cfg(feature = "ristretto255")] struct Ristretto255; #[cfg(feature = "ristretto255")] impl CipherSuite for Ristretto255 { type OprfCs = crate::Ristretto255; type KeGroup = crate::Ristretto255; type KeyExchange = TripleDh; type Ksf = Identity; } #[cfg(feature = "ristretto255")] struct Ristretto255P256; #[cfg(feature = "ristretto255")] impl CipherSuite for Ristretto255P256 { type OprfCs = p256::NistP256; type KeGroup = crate::Ristretto255; type KeyExchange = TripleDh; type Ksf = Identity; } #[cfg(feature = "ristretto255")] struct Ristretto255P384; #[cfg(feature = "ristretto255")] impl CipherSuite for Ristretto255P384 { type OprfCs = p384::NistP384; type KeGroup = crate::Ristretto255; type KeyExchange = TripleDh; type Ksf = Identity; } struct P256; impl CipherSuite for P256 { type OprfCs = p256::NistP256; type KeGroup = p256::NistP256; type KeyExchange = TripleDh; type Ksf = Identity; } struct P256P384; impl CipherSuite for P256P384 { type OprfCs = p384::NistP384; type KeGroup = p256::NistP256; type KeyExchange = TripleDh; type Ksf = Identity; } #[cfg(feature = "ristretto255")] struct P256Ristretto255; #[cfg(feature = "ristretto255")] impl CipherSuite for P256Ristretto255 { type OprfCs = crate::Ristretto255; type KeGroup = p256::NistP256; type KeyExchange = TripleDh; type Ksf = Identity; } struct P384; impl CipherSuite for P384 { type OprfCs = p384::NistP384; type KeGroup = p384::NistP384; type KeyExchange = TripleDh; type Ksf = Identity; } struct P384P256; impl CipherSuite for P384P256 { type OprfCs = p256::NistP256; type KeGroup = p384::NistP384; type KeyExchange = TripleDh; type Ksf = Identity; } #[cfg(feature = "ristretto255")] struct P384Ristretto255; #[cfg(feature = "ristretto255")] impl CipherSuite for P384Ristretto255 { type OprfCs = crate::Ristretto255; type KeGroup = p384::NistP384; type KeyExchange = TripleDh; type Ksf = Identity; } #[cfg(all(feature = "curve25519", feature = "ristretto255"))] struct Curve25519Ristretto255; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] impl CipherSuite for Curve25519Ristretto255 { type OprfCs = crate::Ristretto255; type KeGroup = crate::Curve25519; type KeyExchange = TripleDh; type Ksf = Identity; } #[cfg(feature = "curve25519")] struct Curve25519P256; #[cfg(feature = "curve25519")] impl CipherSuite for Curve25519P256 { type OprfCs = p256::NistP256; type KeGroup = crate::Curve25519; type KeyExchange = TripleDh; type Ksf = Identity; } #[cfg(feature = "curve25519")] struct Curve25519P384; #[cfg(feature = "curve25519")] impl CipherSuite for Curve25519P384 { type OprfCs = p384::NistP384; type KeGroup = crate::Curve25519; type KeyExchange = TripleDh; type Ksf = Identity; } pub struct TestVectorParameters { pub client_s_pk: Vec, pub client_s_sk: Vec, pub client_e_pk: Vec, pub client_e_sk: Vec, pub server_s_pk: Vec, pub server_s_sk: Vec, pub server_e_pk: Vec, pub server_e_sk: Vec, pub fake_sk: Vec, pub credential_identifier: Vec, pub id_u: Vec, pub id_s: Vec, pub password: Vec, pub blinding_factor: Vec, pub oprf_seed: Vec, pub masking_nonce: Vec, pub envelope_nonce: Vec, pub client_nonce: Vec, pub server_nonce: Vec, pub context: Vec, pub registration_request: Vec, pub registration_response: Vec, pub registration_upload: Vec, pub credential_request: Vec, pub credential_response: Vec, pub credential_finalization: Vec, client_registration_state: Vec, client_login_state: Vec, server_login_state: Vec, pub password_file: Vec, pub export_key: Vec, pub session_key: Vec, } static STR_PASSWORD: &str = "password"; static STR_CREDENTIAL_IDENTIFIER: &str = "credential_identifier"; // To regenerate these test vectors, run: // cargo test --features curve25519 -- --nocapture generate_test_vectors #[cfg(feature = "ristretto255")] static TEST_VECTOR_RISTRETTO255: &str = r#" { "client_s_pk": "58f84ab1de6d6baed997b8622a7340470a2e321778cf15a6a349f57143181b6d", "client_s_sk": "ca1860c537f99dce6da9d0bf674f7c5c483c7e12c07487821d0fc60b78702a03", "client_e_pk": "5898671746f581bbaa9019ea3e5dc5809612960e38f3fd3569237e8d0cf14a23", "client_e_sk": "bd61a18173fe09b88529b4c04424637ce066fabc0f077985713ae12457d7b601", "server_s_pk": "32033f92bfd82242f7dc9b2574f6916a53aa4ef83ecab4f4d912aad9957d8027", "server_s_sk": "ab8f8598cb4166fb5ee1d437b6f5b563b59e4b699ded8e176c25ee77358bac01", "server_e_pk": "f4ac5c4ef8dfae76705ddc1dd6c64b916680f69975cad5733ba7a4570bdd5629", "server_e_sk": "7bf9ca648ab766269eeed497f640264cc248caaf94498b3aba2324395d061308", "fake_sk": "23c51f2bd15324bbc088313184ff2daf81454c24002887b8abd8dc1d78f35000", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "16d9379d74dd857d97ed7470bc022290f0aed9d14c8de873c03139360d7c2203", "oprf_seed": "089519f6ab43cb90f6c37abe2f4d6ef7928106fd5920c9856d717c6db229d6887b98ea296e8c48f962065e8c224ee1d687b5e9ea9be5c9fd66a1d5edf4326aa3", "masking_nonce": "ff24215c44990ee27982e667ed57e1fefe21a38ecae3cf8dad951237ba6166cfef780945009e3cfc031f59552a8d7b84571c7c13722d88a52f2b7d279e27ff84", "envelope_nonce": "add2e39416fb5917d1328dd9987b9e8e2ee30c04eb4f4a8ae5c52e63b719846a", "client_nonce": "db1f9c4b2e3f4f307d35490a2d9ace7ccd2e124c5a08655bfb97597f24d5da55", "server_nonce": "00285d1b30f04f84f020dc60d702581cf36fc8f683b75b1efd21e01056a1a102", "context": "636f6e74657874", "registration_request": "3025151fce8a32a8961aaf77031402a3d0cf70370052b22b6131c78de82e8366", "registration_response": "1a566c5cb551027e996788ad999b14ecd8bc0f230348aef90674e733d946cd6332033f92bfd82242f7dc9b2574f6916a53aa4ef83ecab4f4d912aad9957d8027", "registration_upload": "90c46263e6709e038ffd12d5e97eca652800edc492b942a798951da8af74ef289e8fe0c9fef7a8f785445c82f6185f1e8682ae907197ce97ae0521c0f5ce4f636781ad5b5c3f9df7c4af0dfdd0f77ce98846d019cf4189b8f0a793cd59e2b42aca1860c537f99dce6da9d0bf674f7c5c483c7e12c07487821d0fc60b78702a039923ef46ae4f5b0240484250d690a6b1533bc8d5cd89e5b5bb78ebe4cb40d4439275e924b80683c6b8833cb503059bd3bcb083aa72bf70d1d2cb4e6d40cd61d7", "credential_request": "3025151fce8a32a8961aaf77031402a3d0cf70370052b22b6131c78de82e8366db1f9c4b2e3f4f307d35490a2d9ace7ccd2e124c5a08655bfb97597f24d5da555898671746f581bbaa9019ea3e5dc5809612960e38f3fd3569237e8d0cf14a23", "credential_response": "1a566c5cb551027e996788ad999b14ecd8bc0f230348aef90674e733d946cd63ff24215c44990ee27982e667ed57e1fefe21a38ecae3cf8dad951237ba6166cfd7635651e5f867c08c02e7564b86a03d1b1b198dec5b9b54f998d3bfba0f4fe956d3e795c672c275ac2fb0a5ce38920bc17f532348243f79db5aaf34db507ce41096d9a326ee453f02ab1d1c9b738507fbe87197b13c65720e4f16737f9da173613b90bd5b2ee6812c0462299a7c3b179e439e88af08abf607796e4e9d23e17f7bf9ca648ab766269eeed497f640264cc248caaf94498b3aba2324395d061308a0c9863142b43845b16e9bf9e1d236038a0cf8a470a7291c60e8579dae1e2128d7919f28f7a4ff9fdd915f00b42007aa1de6f9a0bded2cbbf297e923bcef57f42fb06bcfca035fbc66cf74300c54daec3738dbaca2ba470bb81330efab584256", "credential_finalization": "6a3f177d73886db031e081e116a1eb7c13ef763a60a0ae8b7477f4fcf6c7d22618651402f3ab7bd501f42442a010a185253c87bb051cca80686b54ceb5c410d3", "client_registration_state": "16d9379d74dd857d97ed7470bc022290f0aed9d14c8de873c03139360d7c22033025151fce8a32a8961aaf77031402a3d0cf70370052b22b6131c78de82e8366", "client_login_state": "16d9379d74dd857d97ed7470bc022290f0aed9d14c8de873c03139360d7c22033025151fce8a32a8961aaf77031402a3d0cf70370052b22b6131c78de82e8366db1f9c4b2e3f4f307d35490a2d9ace7ccd2e124c5a08655bfb97597f24d5da555898671746f581bbaa9019ea3e5dc5809612960e38f3fd3569237e8d0cf14a23bd61a18173fe09b88529b4c04424637ce066fabc0f077985713ae12457d7b601db1f9c4b2e3f4f307d35490a2d9ace7ccd2e124c5a08655bfb97597f24d5da55", "server_login_state": "01410c086ece65443dcbca42c6703d08bae0d293f4b9b78449df626f7f8b04d8cada3f693670e74683f4ec6f9df9d1773fa4212a6ddc52343874bcfb0a87dd82cd25afdbb29dd431c859b337de3123e325d9aa9c99e9a59fd98858c6835e8c34d0945a251261f456ffa67399c8745e478c7377a3774930a49f0b7c351ed654e38d62e93a5ec5cd0305521bcce9695b3ce23b4713a699bd9e1e102049652bc407fc6579cf4c7f8e5e3dcfaadb73a36c49bc2084b82246c01c630dde63a5bbfb40", "password_file": "90c46263e6709e038ffd12d5e97eca652800edc492b942a798951da8af74ef289e8fe0c9fef7a8f785445c82f6185f1e8682ae907197ce97ae0521c0f5ce4f636781ad5b5c3f9df7c4af0dfdd0f77ce98846d019cf4189b8f0a793cd59e2b42aca1860c537f99dce6da9d0bf674f7c5c483c7e12c07487821d0fc60b78702a039923ef46ae4f5b0240484250d690a6b1533bc8d5cd89e5b5bb78ebe4cb40d4439275e924b80683c6b8833cb503059bd3bcb083aa72bf70d1d2cb4e6d40cd61d7", "export_key": "55833fcf856af07df1ec4d98a2180ca90227edddf53bca6787cb86f40337290491dec6dbc95efd56e15e7f2bb9bea2c2e683b956b1f85b2f9abce2a87cf61e4b", "session_key": "8d62e93a5ec5cd0305521bcce9695b3ce23b4713a699bd9e1e102049652bc407fc6579cf4c7f8e5e3dcfaadb73a36c49bc2084b82246c01c630dde63a5bbfb40" } "#; #[cfg(feature = "ristretto255")] static TEST_VECTOR_RISTRETTO255_P256: &str = r#" { "client_s_pk": "f88bd648ec3275a06d2f64f7f2e35f9b79cef7d6ead6ba05945b700658643e2f", "client_s_sk": "04e1b7f9448b6913ff7de5e0b4ccc2f6e88eb6ef80963c75f89db0f634cb000b", "client_e_pk": "907bd6c4d780c85415ce1b9e8cff2a6c10bec716d6eab80cf3f9646469033a3c", "client_e_sk": "8c0e7d7310db05a12a418c0616c8969855008946702d7d0e2b0b1f10dd24c402", "server_s_pk": "681525049da7bedd96b863b95f13859b616aa9729b752676dde32513acfb7611", "server_s_sk": "30aa1bf8df6bf6ed30e7c9579e3bda2804dad268ea2d3bc793173a35e895ad00", "server_e_pk": "68732765fd7a76511f7c2a50bf7df6efe54efa15b0bfce2ba162ee922c4e0452", "server_e_sk": "4961b6b17fef0eb216c13c97e5a2c28db78feddbbbdcfe9eaea937c6fb625d05", "fake_sk": "d3fd635217181a826cb07eaad0d6c722e73731a3c719f26322ccef9d2130990d", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "ce2a220c656632c5bb630351bf2bc9258631acd226c5ecb1686aa82ea5baf308", "oprf_seed": "3d108c5667216961a69098fc9a94294cd8761aa4af76c51ea35df3a06f2139f6", "masking_nonce": "ef9aebb14f7f965ac8fcba0418a83340646747cb00d056b57f7ba2671945728ce3648bf46c6d2b21890ad09c25142e57360cea1300ed7d74dc0580e61fa5b5e7", "envelope_nonce": "23abd8c07fec3913673426fd49f4d2832c29855b5846fea5ffa6d91ede58f6ac", "client_nonce": "dff3b604d150842e692aa20fd0621ba8718581fd6fa4a3409108bba35d5f7bdc", "server_nonce": "e3d70b5657db6fa047f106843a746091c602d2c2e8280d9ac8994cf39bf93d30", "context": "636f6e74657874", "registration_request": "03ae0926f45e0b5efab9e15e6acddd7dd4bdbf15b1accccbae1927d5450532229a", "registration_response": "03f2a9e0737a10e41a5501f853d2401a89a7c8c626926e6899205357a7d971c238681525049da7bedd96b863b95f13859b616aa9729b752676dde32513acfb7611", "registration_upload": "7e7ea08bc8cceb5d89b7ceb8e91deadb721a2ad684272510e85570acb9563451ad667e253cfd587092cfc3a788aec8b0cf3e248d84cc7ff98e7d5488736deb3704e1b7f9448b6913ff7de5e0b4ccc2f6e88eb6ef80963c75f89db0f634cb000bfc47ba0ccf49efab4a706d72cf038a01c6f32fa4fa10a30c6ce94df37a86504f", "credential_request": "03ae0926f45e0b5efab9e15e6acddd7dd4bdbf15b1accccbae1927d5450532229adff3b604d150842e692aa20fd0621ba8718581fd6fa4a3409108bba35d5f7bdc907bd6c4d780c85415ce1b9e8cff2a6c10bec716d6eab80cf3f9646469033a3c", "credential_response": "03f2a9e0737a10e41a5501f853d2401a89a7c8c626926e6899205357a7d971c238ef9aebb14f7f965ac8fcba0418a83340646747cb00d056b57f7ba2671945728cb166cbc26eadb074abec8888288bb157ba6e995e4983277dde3a8b164e78efcf261a0a2ae4dcbb379a1e651b128bf356108a2be9e10f5e0d95f5e51c748b890b96e6304f8380ee71f623e3bfde447ee58bb60e40281e44f8496e5a799c24506f4961b6b17fef0eb216c13c97e5a2c28db78feddbbbdcfe9eaea937c6fb625d05c0b7b235a518f55c3026b2bc375841f35c3b2e1fc381c3963b721a97d34d887ea4dfb155d59da8ad912aac17df06e6a21b118cac0cfd15903f0c20658fa717b4", "credential_finalization": "10653ec75b594a7401ffcde895d463002c3eac839f0343ac779fa9210e4782dc", "client_registration_state": "ce2a220c656632c5bb630351bf2bc9258631acd226c5ecb1686aa82ea5baf30803ae0926f45e0b5efab9e15e6acddd7dd4bdbf15b1accccbae1927d5450532229a", "client_login_state": "ce2a220c656632c5bb630351bf2bc9258631acd226c5ecb1686aa82ea5baf30803ae0926f45e0b5efab9e15e6acddd7dd4bdbf15b1accccbae1927d5450532229adff3b604d150842e692aa20fd0621ba8718581fd6fa4a3409108bba35d5f7bdc907bd6c4d780c85415ce1b9e8cff2a6c10bec716d6eab80cf3f9646469033a3c8c0e7d7310db05a12a418c0616c8969855008946702d7d0e2b0b1f10dd24c402dff3b604d150842e692aa20fd0621ba8718581fd6fa4a3409108bba35d5f7bdc", "server_login_state": "2b6792d84ae19d64f39ae233b54ce79ab8793f9648c24f4bd22df7b4f9e4e6e77fe5ead3ce6faf1d05cbc64518cfe259cfe522b381eadc79019c0c81f613233d91910ea0c4c286eeec89dd2ceec93478f936454f4f41206c75407862150cdf3a", "password_file": "7e7ea08bc8cceb5d89b7ceb8e91deadb721a2ad684272510e85570acb9563451ad667e253cfd587092cfc3a788aec8b0cf3e248d84cc7ff98e7d5488736deb3704e1b7f9448b6913ff7de5e0b4ccc2f6e88eb6ef80963c75f89db0f634cb000bfc47ba0ccf49efab4a706d72cf038a01c6f32fa4fa10a30c6ce94df37a86504f", "export_key": "b776d68ad88a7534f571625727ce09a13ff203b9c26e16da9aaa1b7698cd1645", "session_key": "91910ea0c4c286eeec89dd2ceec93478f936454f4f41206c75407862150cdf3a" } "#; #[cfg(feature = "ristretto255")] static TEST_VECTOR_RISTRETTO255_P384: &str = r#" { "client_s_pk": "86a1adb5a45e87b1cb92f082a5bf5890e9e21e2d78d4773ab7f0d021664b7b69", "client_s_sk": "950ac3b5fcca8fbcc740e24a9f0a0703bf06c1e345459cb662bed0ae91f10904", "client_e_pk": "d697f15ff9e34fd51a2a8980995503d17bd11cbb0407d51502138f384f908112", "client_e_sk": "c320ee0eb5eef9e6e00872cef1196e362d20712ae9da185e7466397324a72907", "server_s_pk": "d0433b254df7a9952f281f10b86d9c4cc14faef3a3c67943a01b208782da620e", "server_s_sk": "94985ed3d85392c7957c53b9f24ab138acbdbba80357c79eeccea19602434b0d", "server_e_pk": "00ea32a0e605deb301bc73b4df661100d7de331c6e4548b9e5dbf02872fe7529", "server_e_sk": "e4d2a0ea0adf9edb4a8d7e0d236ea9022bdcae7d7c24665928c7c9e765ffe700", "fake_sk": "26e8e0bf9739b54dafab24a3454cceef1b3c61b0b6e521dc5cba404722517101", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "454092e5dcb20854d987421466835f4a270bcaffeae8e094a0cd1c4f636946b90bb5d8d0cc2bddfcde1bc97042021043", "oprf_seed": "e4d402280ebe5718f2b2887ef5595a6b2020f6fb983b5f117ab7db986e2fdca9675b4bc94ff4db6cd249810ff08bb760", "masking_nonce": "ed6dd7938ad35abd1088e892d55706ea3394d88351e18b6574b7b2931210e5b6320a60040a96d8a68f8ca197dc77c9072964e0a267eb4d51bf6327d40ec3091f", "envelope_nonce": "866f1e43f59ab3076f7ffa80e3d180d74dfe472a4399378477927ac88e99483c", "client_nonce": "c4eb516c8f385cabe449e30bd55975cb8c73b8cd4121e392202c95dc1ca58ff6", "server_nonce": "7eba5738ead262ae3288e908cc31126d8755b79471e34a0fed7bda22abdf830b", "context": "636f6e74657874", "registration_request": "031032c75bd6d20572956af17c27c8a628f493993903e8a2dbd4db1b069f2dacbf05767428f0e4c58150af7d6577c42cc1", "registration_response": "024fbffd6d812d62d98009ac0277c0740e3245e98bf3c62a8dda34152b350b8a74f34fb5677b848b45e982d663ee7ae522d0433b254df7a9952f281f10b86d9c4cc14faef3a3c67943a01b208782da620e", "registration_upload": "82961e5ba6f42e3dede98b0eb333668f768df6e28335896e1d1c764d45b26101937f31c8f82cda4be30080d8edeefdce8d43a11a8dc089111f48d173d9a057fa35dc0dfe0a59457a6bfec84298d5e4d8950ac3b5fcca8fbcc740e24a9f0a0703bf06c1e345459cb662bed0ae91f1090468008a29cf8f061e01bdc0940a04bee4a49391c2eb3a10552254f3904e2b374a2018fd6153e948d7bb74e47de4b3765e", "credential_request": "031032c75bd6d20572956af17c27c8a628f493993903e8a2dbd4db1b069f2dacbf05767428f0e4c58150af7d6577c42cc1c4eb516c8f385cabe449e30bd55975cb8c73b8cd4121e392202c95dc1ca58ff6d697f15ff9e34fd51a2a8980995503d17bd11cbb0407d51502138f384f908112", "credential_response": "024fbffd6d812d62d98009ac0277c0740e3245e98bf3c62a8dda34152b350b8a74f34fb5677b848b45e982d663ee7ae522ed6dd7938ad35abd1088e892d55706ea3394d88351e18b6574b7b2931210e5b631a1b6b837aa901a6016382e5174dc0afe05c4c382066c68a4712a9472382b22e0f41eec742cfb4fb44606388b40c4460b87996048768e54f2d130cabead02de5e564ca78adb2f72c45c966cf8feadeecbbefbdab76b21474a1513c098a61e2fb00c6b3e23b248d9d95740d44b81e54ae4d2a0ea0adf9edb4a8d7e0d236ea9022bdcae7d7c24665928c7c9e765ffe700bac9e8a7cec2359871b91d1f87d975888ff28262c2520d729a48f27e6c8f722b7b778392ded7de3648a63e312aaca0dfdac3177583b016d64ee3735f983e2b1dbe622fa1f92d9a38fe55550948416592", "credential_finalization": "17a0cf86d1021759062b89f802a798b5d2492f7373462e1b75d6197a21d599e1f16b0fafad97ba72b0ad69683e69a145", "client_registration_state": "454092e5dcb20854d987421466835f4a270bcaffeae8e094a0cd1c4f636946b90bb5d8d0cc2bddfcde1bc97042021043031032c75bd6d20572956af17c27c8a628f493993903e8a2dbd4db1b069f2dacbf05767428f0e4c58150af7d6577c42cc1", "client_login_state": "454092e5dcb20854d987421466835f4a270bcaffeae8e094a0cd1c4f636946b90bb5d8d0cc2bddfcde1bc97042021043031032c75bd6d20572956af17c27c8a628f493993903e8a2dbd4db1b069f2dacbf05767428f0e4c58150af7d6577c42cc1c4eb516c8f385cabe449e30bd55975cb8c73b8cd4121e392202c95dc1ca58ff6d697f15ff9e34fd51a2a8980995503d17bd11cbb0407d51502138f384f908112c320ee0eb5eef9e6e00872cef1196e362d20712ae9da185e7466397324a72907c4eb516c8f385cabe449e30bd55975cb8c73b8cd4121e392202c95dc1ca58ff6", "server_login_state": "1ac407a2442a2b126afd56a7790d790c1dcbd16b3d9d89963267f26c798a0266d896e8c1daa912d5933be902cfa301e42f1fe785b8429087cc492f9e8731139628530254e4524a0df9a6840748dc8bd12b65bf3141f09a696b55760bd4f65fc3e952e42d4d61618bd93459e43b4ee699eba8d9d3ed3c0c31bd605b654e9fc289a87799c43267570e7644c16436463fd0", "password_file": "82961e5ba6f42e3dede98b0eb333668f768df6e28335896e1d1c764d45b26101937f31c8f82cda4be30080d8edeefdce8d43a11a8dc089111f48d173d9a057fa35dc0dfe0a59457a6bfec84298d5e4d8950ac3b5fcca8fbcc740e24a9f0a0703bf06c1e345459cb662bed0ae91f1090468008a29cf8f061e01bdc0940a04bee4a49391c2eb3a10552254f3904e2b374a2018fd6153e948d7bb74e47de4b3765e", "export_key": "6507d9329bb8fb8468d7fbf89781f02e3d56e887aa8cd0e56b622bb9b2cf78e079000936c0cbacdf3acbae65b929f143", "session_key": "e952e42d4d61618bd93459e43b4ee699eba8d9d3ed3c0c31bd605b654e9fc289a87799c43267570e7644c16436463fd0" } "#; static TEST_VECTOR_P256: &str = r#" { "client_s_pk": "032d82f5e7db19c5f87db1cb296d5f847315e98aa4ae2f14cb94fe9fefae5b23a1", "client_s_sk": "4c2bd02fd037cfe6aa8aa243bbf0419c6f4196565470192554bdf3da966ae1d5", "client_e_pk": "03b2ee310f831c43b6ecf8683ab3a0f903f4c54d42b5851652667d24a051805e54", "client_e_sk": "11fd841fa4c27ed5849632ce256a242c526f1f828e170a68800fa4a7a9c93047", "server_s_pk": "022cc9aadeaed45bdae85464af1512614edde6adf97c1407d6721e5cd1a985734a", "server_s_sk": "e6334d73a9a34212886d4c4b7368df72f06a90b2887e5632f0eadad4cc8c9d3d", "server_e_pk": "03ca02f4d31f1e66624dc21864e410876f2dc8fdcfff031090f170736d73060a10", "server_e_sk": "6a6b22ac2bc7bd6401cc2e42f588a4550651cbd30d9529b69ebb88d7b073e6a2", "fake_sk": "8362d70183ab78942b21ae3cba95f1edb5d314fb2f2afa49a452222a02f6dcc4", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "87700138241d25149a2ca6fd9a27e7f9d71a8e718fe1c411862a975cdb17a413", "oprf_seed": "8b10b0445efce9c59e6e5a39f89961722fba14a809068620b9d77433bafb254e", "masking_nonce": "52b2cf34ba108ffd2ef1e516585d845b90e34af198f379b6465744f5812274680c5dc1dca7e6a73a4dd48159cbd4b35913ff51bac2605a63563602e681aeb171", "envelope_nonce": "f97a0c9a7de14b073531d24ba6d7893191a2724fffa6fe242099c17c6640e210", "client_nonce": "4c5dbddfb063ecba7fd528c0caec52893ef206bf86362dafb27fe13d96e0b538", "server_nonce": "fab1f9fa3f0356fc5d9b766ea3bdd53884ab38bac8371842d047a3b815c79428", "context": "636f6e74657874", "registration_request": "030e9bc97e025d9b5eacf7e76b16ada9a568401c509d2d1c507914c56d820be7ea", "registration_response": "03dc5d4ba61011266879896966f26fde5e188a5d30df17deca56d5e227efbc8102022cc9aadeaed45bdae85464af1512614edde6adf97c1407d6721e5cd1a985734a", "registration_upload": "035153b60a0f66ddf3d45d00c6bf6506a0898e6d438f1f73fbec916d538f6b43b042eaa5fe4bb07b55cce02bdc53225886bff138edf3a57a7f28d256d52b1755c84c2bd02fd037cfe6aa8aa243bbf0419c6f4196565470192554bdf3da966ae1d5489d88b7908412724d6c28f209a1c45ff7d509cbdb67b017c08802a4532e04d5", "credential_request": "030e9bc97e025d9b5eacf7e76b16ada9a568401c509d2d1c507914c56d820be7ea4c5dbddfb063ecba7fd528c0caec52893ef206bf86362dafb27fe13d96e0b53803b2ee310f831c43b6ecf8683ab3a0f903f4c54d42b5851652667d24a051805e54", "credential_response": "03dc5d4ba61011266879896966f26fde5e188a5d30df17deca56d5e227efbc810252b2cf34ba108ffd2ef1e516585d845b90e34af198f379b6465744f5812274682cc3c3b734abf18e0ee058a9983f91017022b220d76a7bea6a99e7a7ca8bce9dfe0d670272cdfe25136f9bf00b4607a79133c37f367da3e8b9ead9059f40a2bca60b7d99ba5a2557de3be49de1b62e5771a2855d1fbce37ffbf403ca5fa3a37c3b6a6b22ac2bc7bd6401cc2e42f588a4550651cbd30d9529b69ebb88d7b073e6a203e0f0020d7d9a024e799db237b7dedc4faa8a4a8ce17e93ff490ea66ebc654ba67c17359620d1e627a528c40c961d55d77de2882a9c510ea920974f1ddc97f3c5", "credential_finalization": "a6836d9d17ed9a5e7c562002058f0a68e1c41925f7736e959965811b6e3e0783", "client_registration_state": "87700138241d25149a2ca6fd9a27e7f9d71a8e718fe1c411862a975cdb17a413030e9bc97e025d9b5eacf7e76b16ada9a568401c509d2d1c507914c56d820be7ea", "client_login_state": "87700138241d25149a2ca6fd9a27e7f9d71a8e718fe1c411862a975cdb17a413030e9bc97e025d9b5eacf7e76b16ada9a568401c509d2d1c507914c56d820be7ea4c5dbddfb063ecba7fd528c0caec52893ef206bf86362dafb27fe13d96e0b53803b2ee310f831c43b6ecf8683ab3a0f903f4c54d42b5851652667d24a051805e5411fd841fa4c27ed5849632ce256a242c526f1f828e170a68800fa4a7a9c930474c5dbddfb063ecba7fd528c0caec52893ef206bf86362dafb27fe13d96e0b538", "server_login_state": "f7954aa457f509c7695b9e3313a7a445086cb7c0340f75249544d638fe2faba161395f0bfaeb1f56bfb8c93b56b5cb77e5e63c15d328e7e5bb4310e92cb2cdd867e4fa4ba1fdae0282a7b8dadb9bb30081ff2fd351c3ff24dac160d46e3192cb", "password_file": "035153b60a0f66ddf3d45d00c6bf6506a0898e6d438f1f73fbec916d538f6b43b042eaa5fe4bb07b55cce02bdc53225886bff138edf3a57a7f28d256d52b1755c84c2bd02fd037cfe6aa8aa243bbf0419c6f4196565470192554bdf3da966ae1d5489d88b7908412724d6c28f209a1c45ff7d509cbdb67b017c08802a4532e04d5", "export_key": "dfaad05e13c091a4cd11d9342bbf361111bfd7ae0b09866175a6c76403afef15", "session_key": "67e4fa4ba1fdae0282a7b8dadb9bb30081ff2fd351c3ff24dac160d46e3192cb" } "#; static TEST_VECTOR_P256_P384: &str = r#" { "client_s_pk": "02ffaa7a9ad8d8fbdf51462333be3baf795e927626afc30a825299b2738be56e64", "client_s_sk": "867143397117121b3cf8bbbdbb577e7a3ec3de33a5d052e6ea5e736d8da5243a", "client_e_pk": "02d71ac13b7c461a0aff3ffcf6fb43961f3cc78d159a88190e11814cf8c1c47e63", "client_e_sk": "e48b752d3f498fbd8e605e95a076f342574b6d6717483fe11a8f8bb1f7f404a9", "server_s_pk": "03b0c19cb4a9c38a4f8dfd3108d346153612258eda0a918a66898ead514a087484", "server_s_sk": "799ec708dff22260a940b1daab1bf246f7dc0b3ef36edf5e325e4783ed580b15", "server_e_pk": "0266a3ee38dd097628288b9f12ddcd8ba2d581dd3f390bc82c88019fb6da84b4ab", "server_e_sk": "2d40040888e6eabc3ef1192abe45de7e72de591e88f9cb85624f6fe69a829abe", "fake_sk": "1f63b1381351cdee56bb69a649210a0e401946033210a1d1abb310ee84b057be", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "898b728c633b5f335da29527ae279122049cc0a48adde3de699707f9008e58808383b39014554696359c1ff9198092cf", "oprf_seed": "a681bb60cbc5f65264fbdd29b487fb7eff1bc1b1fad69ba6dad7d802714251fcadd91cbddb9d203be691c99be04dd3a9", "masking_nonce": "596d13dbdaf0a67f38ab3560f1a8ad539f6879365d2499c35c61822ab457656b5d3102a21c019920324671b47f0c86e6d573179babcd8b87980804a0cec8655c", "envelope_nonce": "027b3fe224cd45ea4a88125341fb12f903c36665fcfd9f86e20e91b094e935b3", "client_nonce": "86c1a1f3bf1872e0f19ce42ca68f4e69c0c7fa2bcd0f9728af650b849f35995d", "server_nonce": "f649bf73c6e0625c8c204a300b6da5f9efcd182634df70175e6cfeb74bbde7ed", "context": "636f6e74657874", "registration_request": "03b9f9c8b76887dd8c74246c02bf77a29af14cb5ba2b02e13992db2c8c87f48068c040a9898dca0d4122e42ccf65219522", "registration_response": "038fe2c1e3b7d968e312b48077edd6545550fcabfdfa25b9420c78c8331dc413028fe973e15270b96673c101ce98c944c303b0c19cb4a9c38a4f8dfd3108d346153612258eda0a918a66898ead514a087484", "registration_upload": "02e07f9bd7377e8275dd95713f4a8de1a13699f61359b69095cfcada7efbb1ab72b8ff9db6b14b4f8bcb1bf6978cf1b02ce7c75af8d63433d6a75caa620ad851cde67df132e8e71a92c2f6cc137c09ddfd867143397117121b3cf8bbbdbb577e7a3ec3de33a5d052e6ea5e736d8da5243a4f30fd6be311843b3b8309d41a0a11f5f1d42eadc5539959457a6eed12d4adfb599fe45a546effd7dca5dcac5b5ff498", "credential_request": "03b9f9c8b76887dd8c74246c02bf77a29af14cb5ba2b02e13992db2c8c87f48068c040a9898dca0d4122e42ccf6521952286c1a1f3bf1872e0f19ce42ca68f4e69c0c7fa2bcd0f9728af650b849f35995d02d71ac13b7c461a0aff3ffcf6fb43961f3cc78d159a88190e11814cf8c1c47e63", "credential_response": "038fe2c1e3b7d968e312b48077edd6545550fcabfdfa25b9420c78c8331dc413028fe973e15270b96673c101ce98c944c3596d13dbdaf0a67f38ab3560f1a8ad539f6879365d2499c35c61822ab457656b967df0a08fb74ca0bbbb915587e55808699b877c9d9f7370e0ba290f3d95e175d66fb98adf8f3aff5b9c06a5dd2a7b5d20a2a76a4f2dc6ef5a67113461a85a03174b585c78445c7a6b1438edd882f75cb56e380f4447e3d366430ca3f2ef372e439b5bb7ac2e1f9dc5b3487232e60a1ddf2d40040888e6eabc3ef1192abe45de7e72de591e88f9cb85624f6fe69a829abe033f366e71bf3f7573a431bac0b35aa60db23b40d2003af7d8eb5f55940b75af3e62ea7b191b1f5b9fae34bb92f0c10b06b95918e784f4afb06c846c254113bdfb3a5b5ca81890dc601dfdb80fabb3865d", "credential_finalization": "188fe8130fab154ddf481a80349f50685d160e6e1db4d11acdff51e1b5d617032e8a62b39e43116f2ffc3651df61995b", "client_registration_state": "898b728c633b5f335da29527ae279122049cc0a48adde3de699707f9008e58808383b39014554696359c1ff9198092cf03b9f9c8b76887dd8c74246c02bf77a29af14cb5ba2b02e13992db2c8c87f48068c040a9898dca0d4122e42ccf65219522", "client_login_state": "898b728c633b5f335da29527ae279122049cc0a48adde3de699707f9008e58808383b39014554696359c1ff9198092cf03b9f9c8b76887dd8c74246c02bf77a29af14cb5ba2b02e13992db2c8c87f48068c040a9898dca0d4122e42ccf6521952286c1a1f3bf1872e0f19ce42ca68f4e69c0c7fa2bcd0f9728af650b849f35995d02d71ac13b7c461a0aff3ffcf6fb43961f3cc78d159a88190e11814cf8c1c47e63e48b752d3f498fbd8e605e95a076f342574b6d6717483fe11a8f8bb1f7f404a986c1a1f3bf1872e0f19ce42ca68f4e69c0c7fa2bcd0f9728af650b849f35995d", "server_login_state": "6c196b4c6cd855c215852c5c11fd1590038eb9d7c69adc062777e3fed1464526d6a8aafd04e9a5845b32bc92bab852520200c994e54b7c3a8844c75c7952d1c0d2cf5232bd3fe6fa24d7b74e6373ccf66d48ead98331257efc320a16864908f4fce34bf2c26ec5f73072d3522d3b42306dfde8ce0b6827dff1202bd1ca11e767d758b4237c30e30d8878db1ebd4bb595", "password_file": "02e07f9bd7377e8275dd95713f4a8de1a13699f61359b69095cfcada7efbb1ab72b8ff9db6b14b4f8bcb1bf6978cf1b02ce7c75af8d63433d6a75caa620ad851cde67df132e8e71a92c2f6cc137c09ddfd867143397117121b3cf8bbbdbb577e7a3ec3de33a5d052e6ea5e736d8da5243a4f30fd6be311843b3b8309d41a0a11f5f1d42eadc5539959457a6eed12d4adfb599fe45a546effd7dca5dcac5b5ff498", "export_key": "431c7293c534c3a555c36ac8b665130066c667b26f86403b3b3e1f06c5e941447f52976265a234fcb0edf4bdef99aaff", "session_key": "fce34bf2c26ec5f73072d3522d3b42306dfde8ce0b6827dff1202bd1ca11e767d758b4237c30e30d8878db1ebd4bb595" } "#; #[cfg(feature = "ristretto255")] static TEST_VECTOR_P256_RISTRETTO255: &str = r#" { "client_s_pk": "027e83df2e0b7380bb430352afc9326a63cd53d6bf6955b60114ae56a9ada8a005", "client_s_sk": "125dee3f99fd11e6dfc10f3269010644abbe1676856c1fd28c3f1c11fb12e8a9", "client_e_pk": "02e1a67fc34629e5d0bc6c7d2873673e873514114e15a72a27e71fde337351ab79", "client_e_sk": "3ba3bfd9cf3b5970a7557260fbd9c1f5480ad2434f3ca788bf0e298e3adb1728", "server_s_pk": "0363418a22f5e2d041a3cc49ac195bb72c484fe2422756874eea2502b1f37265f2", "server_s_sk": "9ca7d0b89c84808c6a3a234383f2a400171d0362fd9cd66874a812b29309aea7", "server_e_pk": "02d3da0962e20af7c63624aff08fcf98f622cdc75d1c475bdec059064cb176da41", "server_e_sk": "7c7aea17291d0c297fc2685c2876b0b57a67b91dfa7d20edce1872341c86a74c", "fake_sk": "2fb1ab3f8edf772701cc7c2a4773ac7441fc17157c00132d0bc4df63703953c3", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "5b4e8ccffa209c8df0ec71d0d1092de288ae05e472e71f9f95ff8d4b34a45a0f", "oprf_seed": "a519f2078900c38d7764481978296720f9b02b472e5aa5e08a32ec1d72c23dc2e3fbd680d367668ce032f45c214aa4efe76b4722f487732aed6c4063a5ab067b", "masking_nonce": "4e3843835669dac4e6875c1627391e2a5589d4f4a3cfb507f0956c16566feb62692db88b2fbaf002a729a31afecbc016e06b004b11c8f9f53d10430c51db1c9f", "envelope_nonce": "d9d3327bd827540d1e5f267605c222cd154c5da6dadd43845d8498c58420fc06", "client_nonce": "246142ff274fe7c3385f6268e7e9c0c1ae2804c664308cec59d2cd0e5af683a4", "server_nonce": "4f9277be8c0deeccb8c67c5312332ea8fc268360c9a46603c2f5f06f94e45f37", "context": "636f6e74657874", "registration_request": "0ca151ef38b3b82f1b2166b6627671943ae8371b207dadfc4c4ccbc93db0fc51", "registration_response": "ca2757e756faaed5e3956fff22ed9d7f5e7114856b11753b3f84f904831d8c290363418a22f5e2d041a3cc49ac195bb72c484fe2422756874eea2502b1f37265f2", "registration_upload": "0273a4a83ef4a4c014623a59d3188370e4592b0c1d2d695dda98a07339a1536e77c5aab89c3434cfb25289d087d3f35680d82a3eaf34b539317a82a219652e2bc1b151f423e945eab65a598624a9328265f91a8e69f5975c7517905db6091894b2125dee3f99fd11e6dfc10f3269010644abbe1676856c1fd28c3f1c11fb12e8a90944628ebe4b83026cca4f2b719ab0e836c01f42bc854a2262f7f0cfcf83b026426371c91a3a3f6ebc47225e092b76fb54636aec37618815f2ba0f9da6290def", "credential_request": "0ca151ef38b3b82f1b2166b6627671943ae8371b207dadfc4c4ccbc93db0fc51246142ff274fe7c3385f6268e7e9c0c1ae2804c664308cec59d2cd0e5af683a402e1a67fc34629e5d0bc6c7d2873673e873514114e15a72a27e71fde337351ab79", "credential_response": "ca2757e756faaed5e3956fff22ed9d7f5e7114856b11753b3f84f904831d8c294e3843835669dac4e6875c1627391e2a5589d4f4a3cfb507f0956c16566feb624c697ec15f81508a6d26927d6240ec09672cc5c6afefba3e6ad828b722c2f13ad1814ee338fbe739ce915c8c77e65a0c1c6baf42e96474997c9eaf8a3c828bf609f60be9d98b30e4d86b14717b16929839e77583d990205a05689ac46773e83e6b35f95770c9c5919484c4e9bed34a85d1ee7db3f9914329f9f559bbed677f8a457c7aea17291d0c297fc2685c2876b0b57a67b91dfa7d20edce1872341c86a74c02c44f9047c059de10dc36ce904b3f1754dbee6b1e0657a194d563db45348198b3448dc365a3112a25c17fd5d02837cb4cb342ca831ba383b61ca684f9afdad1dab235ecd48f3c093bce9ca95449a1b26f7f2cb51b882ee5757ab3b99a078e0670", "credential_finalization": "156511d3bed0e04bb931e21d4e01203ecb8035c8f2a13203a6d7c76156bd98c70161ec4dd434a0da576d7841483d2d6468e2d2df6b046a132a13a148be9f2ed9", "client_registration_state": "5b4e8ccffa209c8df0ec71d0d1092de288ae05e472e71f9f95ff8d4b34a45a0f0ca151ef38b3b82f1b2166b6627671943ae8371b207dadfc4c4ccbc93db0fc51", "client_login_state": "5b4e8ccffa209c8df0ec71d0d1092de288ae05e472e71f9f95ff8d4b34a45a0f0ca151ef38b3b82f1b2166b6627671943ae8371b207dadfc4c4ccbc93db0fc51246142ff274fe7c3385f6268e7e9c0c1ae2804c664308cec59d2cd0e5af683a402e1a67fc34629e5d0bc6c7d2873673e873514114e15a72a27e71fde337351ab793ba3bfd9cf3b5970a7557260fbd9c1f5480ad2434f3ca788bf0e298e3adb1728246142ff274fe7c3385f6268e7e9c0c1ae2804c664308cec59d2cd0e5af683a4", "server_login_state": "00f0c2c254202ccf13ae33839e39a895a23778a8063334ba699cc4157646951fac5da2dc3363fc5cf051157b5f092c1d662ebe258211b02a051335aed2372387e8de8436dcd35b59eed28f6ca2cd4a0e969456e435393fabd0aa6b5e437018c49697c130b7075c7bc3deedb60ead5dd3b4b1f1cd8a86586f26fb1fca907bf27c9c97cc96869f519d4139e5ed967f4b82cee172a06c72702699d194ee49424bf11f73bf6ea75fe40712b3e9c7ae85328a02dacb453f7a95820836026f20dd4815", "password_file": "0273a4a83ef4a4c014623a59d3188370e4592b0c1d2d695dda98a07339a1536e77c5aab89c3434cfb25289d087d3f35680d82a3eaf34b539317a82a219652e2bc1b151f423e945eab65a598624a9328265f91a8e69f5975c7517905db6091894b2125dee3f99fd11e6dfc10f3269010644abbe1676856c1fd28c3f1c11fb12e8a90944628ebe4b83026cca4f2b719ab0e836c01f42bc854a2262f7f0cfcf83b026426371c91a3a3f6ebc47225e092b76fb54636aec37618815f2ba0f9da6290def", "export_key": "47c8aeb7e4b5fcb65728f8b2b07e7d0112496c3e72e5ecb17f00794e90d00fb4e4a9f8f2dccfdd19df8302e3c38d2b7f819ff373c3c829e34705e54dd95fcb09", "session_key": "9c97cc96869f519d4139e5ed967f4b82cee172a06c72702699d194ee49424bf11f73bf6ea75fe40712b3e9c7ae85328a02dacb453f7a95820836026f20dd4815" } "#; static TEST_VECTOR_P384: &str = r#" { "client_s_pk": "02d30caa7523fe782794a4dafdc34b236b3ef01a887ed6f705ff4644cb06df4140cfeaeeeb123d8a4394c485cf6c930fab", "client_s_sk": "26f4f688d5c314da59d08a7672d444ff48c3580fd02ed9998a3906d507c506bf7059f166bec930032afc7fa59fdc6455", "client_e_pk": "022d5b9d95e3686a8274435bf61414a0a371bd1351760fed07da6b281a419aef32c1b9b1eab59222111198d30ed63c7cbd", "client_e_sk": "319076296bb7ce07bd9d383d7bfc6544222b99938e0ec627e7e284391f55e6a98b076a7843f383cbe802a907584fd271", "server_s_pk": "03801a686045ee201b54f8367fc5a3ce577a5310b6431eadbf4abbf2f87213cf8b3853875f7f7badb10d029fe0c6f1cad4", "server_s_sk": "209af74445ade701f4a99011c8e7304e3914ef9101fd92ea8b62d8ae6220a446cf544ca0eaf22552a21b149fc5e12008", "server_e_pk": "021fdb138cd5b99a905285673be1b62085de588b4921ea35f3188aa6d4a57159d072ebda60a163996641473cd82e917633", "server_e_sk": "061bc6ed455e852e8ad7eaf6836bbf061642043e48aef18416575071dc976577296eca9902af72c0d59e324e96abf34e", "fake_sk": "3232e916073a895b65040efcec1a4038bf2fc4c41f8ae2e66bbccc5cf9ce8e31ca84e609b29af7207556452a4ebcf023", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "6522c4e1432f30cdf2d3ad20ddb2677ef444a9447ccb643992a545ed1c9a8c255af28ec952ff87046256a0d942c4be48", "oprf_seed": "0b2ab841c8c79a53710e424a768939d9a36fc5baffc4fad5e8731736c831b3750f61010140ef62708b58dbc0734c4228", "masking_nonce": "3df9ef31bbf2e58364690728a86862b5bb9b6cfb874631006b3fc8da98e13c4a196cf0ae225742a918be575c1f98c5c54ccaa679c55693834d2d7e0ad7374f29", "envelope_nonce": "b358bd034c790212f83b8b9d2f1373a5067314392e244606292856afc9020405", "client_nonce": "c14909f325841eed32aae25899d84c7044c2223e58a18f715977df310e2c2e7d", "server_nonce": "8c4e71dab0435f22238d5e1ae8686d694ca8f6f0131ad5e106b6a909a53de050", "context": "636f6e74657874", "registration_request": "03182483430a1dcccd138466a63f05f523e44f2d0078fd9f21d0c3e145137437ca75f187d38d0d2b806b0c1f21fde2207f", "registration_response": "0256a3f872e6307d2b7c93aee4573a3d18a61ac0cff31d5e2de354f36728663d4f491a040d1b88f2abd7594f2e5cd130fa03801a686045ee201b54f8367fc5a3ce577a5310b6431eadbf4abbf2f87213cf8b3853875f7f7badb10d029fe0c6f1cad4", "registration_upload": "03c8c502f79257e6d92cbfe79767b539fd4e0dbec4fc6543bf9191587986a6e205b899f38ee12a383420488a69d6ce104478ee84a8c4031e77d13a8a8d42041d78ff48e67a970e399d4333812ae0579fa18b2eebcdf6c6fd3f1d180bca053c941726f4f688d5c314da59d08a7672d444ff48c3580fd02ed9998a3906d507c506bf915bdbf6215beb014ea81a290fa38804957f72f2b7473bf33d7e7cecf84f3edf5c67aeebae6b538c6a629a9046719966", "credential_request": "03182483430a1dcccd138466a63f05f523e44f2d0078fd9f21d0c3e145137437ca75f187d38d0d2b806b0c1f21fde2207fc14909f325841eed32aae25899d84c7044c2223e58a18f715977df310e2c2e7d022d5b9d95e3686a8274435bf61414a0a371bd1351760fed07da6b281a419aef32c1b9b1eab59222111198d30ed63c7cbd", "credential_response": "0256a3f872e6307d2b7c93aee4573a3d18a61ac0cff31d5e2de354f36728663d4f491a040d1b88f2abd7594f2e5cd130fa3df9ef31bbf2e58364690728a86862b5bb9b6cfb874631006b3fc8da98e13c4a42035f0afefe847d522d37a6a7e40965f1c81ebfda02b4632df08d7f8136ed222dcf9c723cefa9deb7fb60a4df1682bf9ff2906db5af47728b8ca3815ce820c4677787e631a39e6912ba7705a634c251bf420771a9cac8436a2b53b524b60f9e0047d97bad37d741e5abaf710b9c81bff8ed6d84a319c62dcbab952221e0e9d9511642043e48aef18416575071dc976577296eca9902af72c0d59e324e96abf34e025a82f2ecec7de30ae500fe0efc1b9b6bf925d0ec00b2e21e8a446acc37f063f5f77703d6cc87c3c688f4430fd8c6875a8abe86e344e263b4a450dd7a4684f26052c244defcec09768c6d305b73e09d8e9135228d98c8b84cc586d8cff97bb675", "credential_finalization": "8c0e0cf31d1490a4678994bc4f47e8a5e1b4380d770881d000370ad8c5ef3ffd2e8d7f6101e9411e453a367a65ff146d", "client_registration_state": "6522c4e1432f30cdf2d3ad20ddb2677ef444a9447ccb643992a545ed1c9a8c255af28ec952ff87046256a0d942c4be4803182483430a1dcccd138466a63f05f523e44f2d0078fd9f21d0c3e145137437ca75f187d38d0d2b806b0c1f21fde2207f", "client_login_state": "6522c4e1432f30cdf2d3ad20ddb2677ef444a9447ccb643992a545ed1c9a8c255af28ec952ff87046256a0d942c4be4803182483430a1dcccd138466a63f05f523e44f2d0078fd9f21d0c3e145137437ca75f187d38d0d2b806b0c1f21fde2207fc14909f325841eed32aae25899d84c7044c2223e58a18f715977df310e2c2e7d022d5b9d95e3686a8274435bf61414a0a371bd1351760fed07da6b281a419aef32c1b9b1eab59222111198d30ed63c7cbd319076296bb7ce07bd9d383d7bfc6544222b99938e0ec627e7e284391f55e6a98b076a7843f383cbe802a907584fd271c14909f325841eed32aae25899d84c7044c2223e58a18f715977df310e2c2e7d", "server_login_state": "79814d2b3ba60f503d5ac2a71cf10e66ef8f0d3af2cfcb20898415721147c48458b752bbd88d86c3399addfe7e1adca52f32055b893d59fb1b4c16b8bca49a6c425cb713061ea35d73472b9a70059f9007e0e881d934ae2d2f8b2cfd2a2ea2607aa2592bc9b387e4776df01efd287465a729a66b17550afd9a540536c437e89084d101d66afbf0be092f4b0ab1167ac4", "password_file": "03c8c502f79257e6d92cbfe79767b539fd4e0dbec4fc6543bf9191587986a6e205b899f38ee12a383420488a69d6ce104478ee84a8c4031e77d13a8a8d42041d78ff48e67a970e399d4333812ae0579fa18b2eebcdf6c6fd3f1d180bca053c941726f4f688d5c314da59d08a7672d444ff48c3580fd02ed9998a3906d507c506bf915bdbf6215beb014ea81a290fa38804957f72f2b7473bf33d7e7cecf84f3edf5c67aeebae6b538c6a629a9046719966", "export_key": "b05096e7ff9666fb3845c8ef552b69332b96d3ee63ad46c3da497d0ea85bbe8ee866f7fd606f958ecd08a2100adaa8fa", "session_key": "7aa2592bc9b387e4776df01efd287465a729a66b17550afd9a540536c437e89084d101d66afbf0be092f4b0ab1167ac4" } "#; static TEST_VECTOR_P384_P256: &str = r#" { "client_s_pk": "0254911f1d17aee72f5b891cfaeb8d0b0e68e9db9fb25f2dc42d672382f45b01e559639dc93a21a294461318be76144819", "client_s_sk": "526e10a69a7f9c7ae685defcd8dc4f23f2b668f63cf558c9d76cdb83bbb5b216ef9e91763fa2e015c66ec827316131cc", "client_e_pk": "03a01066dccb456e0e4a238d7afd1dcc788283154f0f7936295b950b316c66d0f52376b26e64585da98308c1ceea732c93", "client_e_sk": "6de338c62147b2f5cd9579109b40584768e7dc1ae451f7d566fb28011bc13c180f3f1001a700c59488716b45011ad5e6", "server_s_pk": "03df5ea7a932ff02124130743543236f3b8de290a1f27c8b9d518112beb72c527a8818a13914cf27c2375f75f832a23093", "server_s_sk": "fd59eb004849e24eb70cd7d6e1ddcd87afae0743b82f2921c0bfe093831db2f17d031c4d63af482c778002394e3cb9ae", "server_e_pk": "033b51d2ec7c6d8db890b5dbc0eaf13298ff25eb516249c2f367d84cb45d1717ed55f1b46f8b142ca899d480cc8a493e86", "server_e_sk": "81443e69a1cc93d7a779235de18be512a0bfc4a2288b16e5323092e54ef4139dac21ed831d34e78e7d03dff908cae373", "fake_sk": "05ef5e97565fa9fc1f485e4aad8516ad9104533397b2bac011aec371c2e98938a9b09b66fed328d4c9ca7bd1c941792c", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "3f3ff410cb7927e1ffe1d1c0f0d2360f49ef04effc2242782f155c858b50c4d6", "oprf_seed": "9c98df8aaf13048694099325ff6bea1ddee273bf632e192c25fdf4a748d95a91", "masking_nonce": "e4315a82379378b7d190c95a24d62871ec68b6b47f206d03a9ae0c27e6397556f50ecae65da56ee71155638cfdc932e8ec1997c16a96be1f55631977618c0b09", "envelope_nonce": "26c52be641cd24569f0b566bb6fc3a8f6490229bac9ffef3345170be8d1135e4", "client_nonce": "0f0f56edf27a8591093e280f79f6b304a003a4aab3565a59d4c4f6ea1e27e76b", "server_nonce": "42679ba32e3301bab082c2d9580ea367cd8b737f422315329213c8b0dd5c2254", "context": "636f6e74657874", "registration_request": "030d2425e25d95ca6380beac64813feb5b127681fc2d3d37814a453f3815fb28dd", "registration_response": "02c4610c2be8d4e308b8a31d9f4ea07686631b8237adfd7bbebd8c8c3be951d7d603df5ea7a932ff02124130743543236f3b8de290a1f27c8b9d518112beb72c527a8818a13914cf27c2375f75f832a23093", "registration_upload": "02120a5aada0251e2a005bddd90a69003b97b8343467a25010e5a5f444c3cfb74ad562c4b4dcb66dc4083a81516e99cf0f4b77b4a187e359ada76ffcc29ba6e895aa3e2b1386be6eed16ad865b92d4f130526e10a69a7f9c7ae685defcd8dc4f23f2b668f63cf558c9d76cdb83bbb5b2162335ec8cc8815e9d4e604a48e1248be2bd92015103fe0396a167d7f5e031c640", "credential_request": "030d2425e25d95ca6380beac64813feb5b127681fc2d3d37814a453f3815fb28dd0f0f56edf27a8591093e280f79f6b304a003a4aab3565a59d4c4f6ea1e27e76b03a01066dccb456e0e4a238d7afd1dcc788283154f0f7936295b950b316c66d0f52376b26e64585da98308c1ceea732c93", "credential_response": "02c4610c2be8d4e308b8a31d9f4ea07686631b8237adfd7bbebd8c8c3be951d7d6e4315a82379378b7d190c95a24d62871ec68b6b47f206d03a9ae0c27e6397556e9aa0bfbbab92e92dd3a8e20799eba9ca690e2a7178256c394d413e9ea29321322ca32d89b4988835bc56366def8916684bdf2a06198f9535f898e35736ac1679925faffb6584c2ddf7d38185a095c5a471073142df269826c8a7baadf69ed8a3923d7b2a7073dfb2aeb780b75ab8cc991a0bfc4a2288b16e5323092e54ef4139dac21ed831d34e78e7d03dff908cae3730304fd477b4439cd862643630c4c141dccb9794d02228624d7fe1394c388fbdcdcfc6d522119b53354745e51e114f9ea1d25057b52c5403716ccf21ff0c3c22a946d65d3272add1236b8c8c0d01f801282", "credential_finalization": "aad107b4b6396ef9ce3233c46992276908c3490026164817aec4b3ee301821a6", "client_registration_state": "3f3ff410cb7927e1ffe1d1c0f0d2360f49ef04effc2242782f155c858b50c4d6030d2425e25d95ca6380beac64813feb5b127681fc2d3d37814a453f3815fb28dd", "client_login_state": "3f3ff410cb7927e1ffe1d1c0f0d2360f49ef04effc2242782f155c858b50c4d6030d2425e25d95ca6380beac64813feb5b127681fc2d3d37814a453f3815fb28dd0f0f56edf27a8591093e280f79f6b304a003a4aab3565a59d4c4f6ea1e27e76b03a01066dccb456e0e4a238d7afd1dcc788283154f0f7936295b950b316c66d0f52376b26e64585da98308c1ceea732c936de338c62147b2f5cd9579109b40584768e7dc1ae451f7d566fb28011bc13c180f3f1001a700c59488716b45011ad5e60f0f56edf27a8591093e280f79f6b304a003a4aab3565a59d4c4f6ea1e27e76b", "server_login_state": "2bee3adc9a7db1e964fd11f6b0a4cc87286762fa7548ab5d3393966f19da7cc5ca72928b4ad955a857ead83fe4a375afb7bb050f8c09c755823d7062e52c37bca3853ad81a963f92049b08f96b940e17cd5f2a8767714c5e28be1c5fa95a8d26", "password_file": "02120a5aada0251e2a005bddd90a69003b97b8343467a25010e5a5f444c3cfb74ad562c4b4dcb66dc4083a81516e99cf0f4b77b4a187e359ada76ffcc29ba6e895aa3e2b1386be6eed16ad865b92d4f130526e10a69a7f9c7ae685defcd8dc4f23f2b668f63cf558c9d76cdb83bbb5b2162335ec8cc8815e9d4e604a48e1248be2bd92015103fe0396a167d7f5e031c640", "export_key": "3cf2a36cb8f9df152f797718fbdead0dac400eb45300e6c93fa40c0b42713795", "session_key": "a3853ad81a963f92049b08f96b940e17cd5f2a8767714c5e28be1c5fa95a8d26" } "#; #[cfg(feature = "ristretto255")] static TEST_VECTOR_P384_RISTRETTO255: &str = r#" { "client_s_pk": "02cc4db2cf4cd01a188ad2d24f37c13d542253202a15c1967fbc01ff3c67ec3976a09d950be6e61fd331ceee6c73afe071", "client_s_sk": "90a2c638013427e671591d125152921d0d18a84a6de44fd7b2b58e139b295628c137d26fc8e4b31e3d23e0a886aa70e2", "client_e_pk": "031c9d7101bd543a64537944c7ffbef579852d03e109386d1cb7d40438a494a3f466daf8ce56866ff94cca71e4c8a4baf4", "client_e_sk": "6e84980c5aaa6d78d3d634668b9a8427219ebf3da0dbc364d41cf29549c8dbecdcf55c91794b1147ed1f80b3f21aab9a", "server_s_pk": "0330a19238b845ed798b626d991645d5454b35bdf78c1aaaa8370ca1ee90839bdfeb3022f0967103a9bf7dd65f0bd764e7", "server_s_sk": "c947228ef3e8f98e14dcf8d44209508133425fa3ecd5b5dea57271b34619ec78503954df1c0d8a17067fdea51568feb0", "server_e_pk": "035ec4661b6d7d838d34438a683e2260be53e49adf362f7e68e366d4eada87a475c98898f57b38f89777f470f33056a5f5", "server_e_sk": "91d5f270837a3109f011a0fb1dc05fb26cb6c312dbaf5258d9c731a581e9398134cb0c5cadad0b09aeb1bbb1856973ac", "fake_sk": "440fc2ef4f616072e5cc984cb49a0a6100d8ba22a002b4a7e88baf000da81acf26399e0cb1277cd55e4cbf0d595714d6", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "18b3146671040f5e23f8df4e40411af98c64f356f34d4abdf8e7023c173a130e", "oprf_seed": "d79e4976efa4866928d3e4fe7e463ec9e1ed756b67a2b156a991ce8c08b7a5d351d42f6e79416d30cae9032afbdedd4e46a360d3a67a2c088cc4f17f23cf548a", "masking_nonce": "f28da85667feea48ee90660484e463b5a3e9c26d78ee966919413e28e5e3298314a233fe33720e72f2086e9adafa8f3ed4b994271e764a836572492e0706b6c5", "envelope_nonce": "b33217f0bfca84df0f5c0e06944d7099ae657138e093e8b8fbd06886ca704f1b", "client_nonce": "6d6547ddbb040af90fd6fcd961e605ed2eec4c2dee24ae729f5145eaab8c3867", "server_nonce": "90901fa0e77d2e184ea1cde30eecd25e7c076245fb9ed40dcf2e64249d58c0be", "context": "636f6e74657874", "registration_request": "b4ab9b7315e3a66face7d81f24d8e2d538e6a09acb929fa3990d8fe3f5cdc665", "registration_response": "aa9159f5472d0f32d06205095eeca6cf2bfb402e2174120b1bb2d42719c5f93b0330a19238b845ed798b626d991645d5454b35bdf78c1aaaa8370ca1ee90839bdfeb3022f0967103a9bf7dd65f0bd764e7", "registration_upload": "02c1c9a0f2a01152ca24c81449e4d86c9d88f2709fc5e8c03c368b8952eae9ef9485a9dc65cf9cee71991266a9c339122601b02d1deee0df0ae3d4cd90cd0ee7b775cecaf73519fa7b1744344dd8f667f566c7fff174152c539fa0e276135862cb2581154db6ce754b594f13c4cdc7649d90a2c638013427e671591d125152921d0d18a84a6de44fd7b2b58e139b2956288a1c235698eb9f64a9b3ff2392a2f927c724a4bd9eac605f445d744614ccd15ed9222d0d0c6a4ba5c3edfa58b2ba386b9cfdb23229c2baf9cd01d30cc6a4267d", "credential_request": "b4ab9b7315e3a66face7d81f24d8e2d538e6a09acb929fa3990d8fe3f5cdc6656d6547ddbb040af90fd6fcd961e605ed2eec4c2dee24ae729f5145eaab8c3867031c9d7101bd543a64537944c7ffbef579852d03e109386d1cb7d40438a494a3f466daf8ce56866ff94cca71e4c8a4baf4", "credential_response": "aa9159f5472d0f32d06205095eeca6cf2bfb402e2174120b1bb2d42719c5f93bf28da85667feea48ee90660484e463b5a3e9c26d78ee966919413e28e5e329838f55cc8db1b7a3159515f4f8659424bec2003f52ddc1cacf3375ebc99ce25796776206afc2336e9eac2526801f3dc865ea4f41312342de7f0380a3dbf19d07fca963efbd55279d227397bdd4061f0d6018f8e921568a13a48ead1841adb79e6fccca36e58c831e08ba390d374b54d2ea57872867e522510a5b5acd6e8db6eea17728d8193047d15a92c6b7ccc21f731a286cb6c312dbaf5258d9c731a581e9398134cb0c5cadad0b09aeb1bbb1856973ac02a333fd1a99cd9efdc223198828ceb73535ad7583f8b2d1a660e9111fb90e7d59699c6a59b7222ffef86be508701cfb16327891268981272101c472e0018e8f685976e9fc02a760a05c4260477400092cfb9e57f91c487194cbb6eee9abe2d99957151a0f11bcfee0fe3862012119847c", "credential_finalization": "4a6ecd34b51d45a77f34f8a959dbac7e507c749ec869eb936d6c591691f74c13c8906a9e02071768eb28f6f0244e9a673c42bdbf326319c5ae93a8837fad2a5b", "client_registration_state": "18b3146671040f5e23f8df4e40411af98c64f356f34d4abdf8e7023c173a130eb4ab9b7315e3a66face7d81f24d8e2d538e6a09acb929fa3990d8fe3f5cdc665", "client_login_state": "18b3146671040f5e23f8df4e40411af98c64f356f34d4abdf8e7023c173a130eb4ab9b7315e3a66face7d81f24d8e2d538e6a09acb929fa3990d8fe3f5cdc6656d6547ddbb040af90fd6fcd961e605ed2eec4c2dee24ae729f5145eaab8c3867031c9d7101bd543a64537944c7ffbef579852d03e109386d1cb7d40438a494a3f466daf8ce56866ff94cca71e4c8a4baf46e84980c5aaa6d78d3d634668b9a8427219ebf3da0dbc364d41cf29549c8dbecdcf55c91794b1147ed1f80b3f21aab9a6d6547ddbb040af90fd6fcd961e605ed2eec4c2dee24ae729f5145eaab8c3867", "server_login_state": "2e28f843e78b3a64e90d4fe4e69e6c905a6f0dc88ec4da004cc6aa83709f5f62631c0359489957187f9bbc1e188a9577cd839e20210ae14da99c921d779a7e7b05542f09b2fa76e5ab43a73b14f3b4be10d14c56271eb1a5a1ee01ef781d220321ca21deaf632855aa442d91f32b6f4d89c5b87cadaf158b93cf71c0c84b7f7ec26fc66b9419dbf492de4a2e9874ef8002c792726b7dc1db770453a5eb1dc94fe245885e7d3aa33ed6e262db3b9344624a5d92b97521a169c78f837d8e5a4f7b", "password_file": "02c1c9a0f2a01152ca24c81449e4d86c9d88f2709fc5e8c03c368b8952eae9ef9485a9dc65cf9cee71991266a9c339122601b02d1deee0df0ae3d4cd90cd0ee7b775cecaf73519fa7b1744344dd8f667f566c7fff174152c539fa0e276135862cb2581154db6ce754b594f13c4cdc7649d90a2c638013427e671591d125152921d0d18a84a6de44fd7b2b58e139b2956288a1c235698eb9f64a9b3ff2392a2f927c724a4bd9eac605f445d744614ccd15ed9222d0d0c6a4ba5c3edfa58b2ba386b9cfdb23229c2baf9cd01d30cc6a4267d", "export_key": "d22fbb27898c9d010471f75d5c914cc96543a381e895660e9650f718bbd410c3d1fdee25d251af597cd21bd1b4165861e19bc424dc9cd9c9381cc278fa812b38", "session_key": "c26fc66b9419dbf492de4a2e9874ef8002c792726b7dc1db770453a5eb1dc94fe245885e7d3aa33ed6e262db3b9344624a5d92b97521a169c78f837d8e5a4f7b" } "#; #[cfg(feature = "curve25519")] static TEST_VECTOR_CURVE25519_P256: &str = r#" { "client_s_pk": "e109acb05ead255b0ddef3b1b2a04161149fdbcf9d1a1583cf3bb39dd43f3d6f", "client_s_sk": "88e628927240f786517e00a5b77ed2fb383e11361c0d4b3324ffb6b927aef373", "client_e_pk": "334dff6942070b0b1395835e54dc7531699fd5ceed7f197f81d5d28090316b21", "client_e_sk": "78ab0d232c8231d1a84ad3cfb4d27226d432954ba9a422a825baac4ac4ee3257", "server_s_pk": "b005c8dca395f0ecd2b6355d600d46199e2f9f389aa84e719d75424b4b8b2b44", "server_s_sk": "88193c55d0a16c2c833be2a0004ebba32ed63019d94b1a498cdfc04310a9a563", "server_e_pk": "20303db181367b52118c89bd7e0d4d97d1c6382bd65ca166cd9876c9b6fc9f1d", "server_e_sk": "58bbac2fd1ee62043eb05631a361b71abfede72530899129035a0ea5454e8042", "fake_sk": "08f3aeac6bd5d6a30cd59e0c74e0ec90254828a3ff8b18a622a3e8bc6a31be73", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "6b68b1711d94273abfec09e6a747b8d5f9b3b42250dc867d9a69808ddde97602", "oprf_seed": "a1ebc0d9b741fbe1b4d3d5b97a89eeca2e3f42ea54afad209e3462d9d8c2f5c3", "masking_nonce": "653f38d85dd789596c39617ef7a54d33b20dc40bab5b1acfc8deef215c14322ab9d7801cd27ac622bcd31f62cf0d739a1e296a2ca8b2f8be854290e0aad33068", "envelope_nonce": "aa76064915e29d00600b6a2b694c0da826a9388bf58fa39fb41fa22b3e6083f0", "client_nonce": "be19d2540482db6096279c55970711cda737c4cc1695a8e417d1ebf19691f223", "server_nonce": "1eaa5da8f04d0b707e147ff78af9aa56f9d9b6042205063c24579d10048cb06e", "context": "636f6e74657874", "registration_request": "02efc05fc89c30469d017160a3ac0630a3546b19dd20193a7cbea801482e4d0f00", "registration_response": "02120dbe7291cf53739fef3955f49956147f518e9f2ee9f17e4c061fefe09c3cccb005c8dca395f0ecd2b6355d600d46199e2f9f389aa84e719d75424b4b8b2b44", "registration_upload": "ba486310fcc3cbacf1b3835bcd06aa33d302a8cff11874a34f10d2ed3940f81d547dc06cd2faa5afe8fe75880c1e6ebca4b4734f8a9e95a8ff29e19db3d5d99e88e628927240f786517e00a5b77ed2fb383e11361c0d4b3324ffb6b927aef373ef4454dd53eedad0082f2dafb2ef474394d8a15dfc4a907f5fbf75403b399a9e", "credential_request": "02efc05fc89c30469d017160a3ac0630a3546b19dd20193a7cbea801482e4d0f00be19d2540482db6096279c55970711cda737c4cc1695a8e417d1ebf19691f223334dff6942070b0b1395835e54dc7531699fd5ceed7f197f81d5d28090316b21", "credential_response": "02120dbe7291cf53739fef3955f49956147f518e9f2ee9f17e4c061fefe09c3ccc653f38d85dd789596c39617ef7a54d33b20dc40bab5b1acfc8deef215c14322a25ceb12702124627c855cd281b4bedb24821ddee72fac2ff840343772ebb3145b9062e1b6804a9b48782be7194cf1092b0f0873ca01a56c04612b8070602e1a361731d0a51df56d9badcb8dfae739c71d640cd5fc49a53d40d109c261a587b9158bbac2fd1ee62043eb05631a361b71abfede72530899129035a0ea5454e80424a84ce00257ddfcfa70d36591f2c2db293276114660134be94d3f5dad10c312ccdc54d5a631789a6d39697a35e12a4900ff7f356b3aa97773f225d32dc901b21", "credential_finalization": "e1ac3b00c834a871e3163ea28b4611810e530b57c9e0e698b5fe6353c9f7ebba", "client_registration_state": "6b68b1711d94273abfec09e6a747b8d5f9b3b42250dc867d9a69808ddde9760202efc05fc89c30469d017160a3ac0630a3546b19dd20193a7cbea801482e4d0f00", "client_login_state": "6b68b1711d94273abfec09e6a747b8d5f9b3b42250dc867d9a69808ddde9760202efc05fc89c30469d017160a3ac0630a3546b19dd20193a7cbea801482e4d0f00be19d2540482db6096279c55970711cda737c4cc1695a8e417d1ebf19691f223334dff6942070b0b1395835e54dc7531699fd5ceed7f197f81d5d28090316b2178ab0d232c8231d1a84ad3cfb4d27226d432954ba9a422a825baac4ac4ee3257be19d2540482db6096279c55970711cda737c4cc1695a8e417d1ebf19691f223", "server_login_state": "6c744915f5aba566f8cc9c601e3a0388c679a07da549905f0350ec3fbc2bbecf8b62a285aa728a8a124d9b30b986745e334143e0fdd1b112fcfb7f87c412da6b405910d03caf6cb3ec6b21c3c7095f136ff050f3c294ee268c537116b90c8c18", "password_file": "ba486310fcc3cbacf1b3835bcd06aa33d302a8cff11874a34f10d2ed3940f81d547dc06cd2faa5afe8fe75880c1e6ebca4b4734f8a9e95a8ff29e19db3d5d99e88e628927240f786517e00a5b77ed2fb383e11361c0d4b3324ffb6b927aef373ef4454dd53eedad0082f2dafb2ef474394d8a15dfc4a907f5fbf75403b399a9e", "export_key": "c8d95a7b0a2c3baa488949effc399d39e64ee09cae26e26ee0ded26e295d9f0b", "session_key": "405910d03caf6cb3ec6b21c3c7095f136ff050f3c294ee268c537116b90c8c18" } "#; #[cfg(feature = "curve25519")] static TEST_VECTOR_CURVE25519_P384: &str = r#" { "client_s_pk": "47bf6620ef1793404dedc4b92516e8633b3580d8e9ab7d38f4664a9cc4308e3c", "client_s_sk": "7051dd78600860b1c96bfd4729fc792111c06b7653057ab9dd32efe03052a564", "client_e_pk": "741bb246da7c5b1361038e78d25006c3d8388b7361e9ca082e5a9770edfd7e42", "client_e_sk": "68ea700379d9f0d73594cd3edcd2096a8ce99af9faf736c11262d15b91584f51", "server_s_pk": "cef452814c8d96e7187efdc6f39b4cf3b9af79a3303fdc1ff06d73fcdfa9fc09", "server_s_sk": "40265c6e7b69c63b1dd77b0a5b55736ed5a3a3e1ef4d6a2be5d84a2b8c9f4078", "server_e_pk": "95f2ea9503fae836c029d7a85229eb537b6a82c9f0362802e488878eaef5655f", "server_e_sk": "f0209a74b6f09e05d3214bbdbbd4d1c3386a7d47213746876e8d840a56299f65", "fake_sk": "8865f09f0d9270e951c7fb723922095ace2febd5a673fd2bfe85456140afb97e", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "23b19816e290cafe9796db34c4922211de1498df4bab2e5ce0c318e533658771d117e9a9eae9d016d7433d3400b4d99c", "oprf_seed": "b29c73aa3651b3eda0cd7e327c0c60693c2b667707d4d7825f862ccca1e319ab0ca5de2f6fa89829cc73c1340fcff00b", "masking_nonce": "25431b6a925130d744101b95fd1ddd822173d97a945b3a7f721cff33c4d3afd4fd93c70914553bde5d50144117cd601449bcdc15f2606a38402aea3ba404a8b1", "envelope_nonce": "f7a5c2edad92af2dc4d0901e54090341a66cd925d0b487f92a64c8cf0aaefe2d", "client_nonce": "48b90f2c8909576edc61743b84d66ce93ae5432d60bb29eadb076e027a163731", "server_nonce": "b4e8004b2f78bd47a132a9ae1640984990066856553ec12e6d409c55af0f93db", "context": "636f6e74657874", "registration_request": "036da1da44ad100ce9c80f074b98e8564e131d6d9186c666e44e2f2ac74822a86aa9af120bc2ebbba3f81dddea21fb418e", "registration_response": "02faff596ac44ab490917a3153c50d67f46bfd12877c2d42d9ae855af3160461aa055ba4900a7c2df6b89acee908376b09cef452814c8d96e7187efdc6f39b4cf3b9af79a3303fdc1ff06d73fcdfa9fc09", "registration_upload": "4f6f6c4b7d2dce29897218c5c609aea30288112ed8c33d8cd67f2b19c3fd1928fb65782af6070e84bb7a542813fff00fb7f71a7797089072babfe06ba01d1845e0c8b6a9b17b65f6b992c00ce34f115b7051dd78600860b1c96bfd4729fc792111c06b7653057ab9dd32efe03052a564d02881210e8c7e043f278032e691a23e8451377624aebcbf7364155158c8cc0a3df1f2c3e669785b81f17016ba7a7acd", "credential_request": "036da1da44ad100ce9c80f074b98e8564e131d6d9186c666e44e2f2ac74822a86aa9af120bc2ebbba3f81dddea21fb418e48b90f2c8909576edc61743b84d66ce93ae5432d60bb29eadb076e027a163731741bb246da7c5b1361038e78d25006c3d8388b7361e9ca082e5a9770edfd7e42", "credential_response": "02faff596ac44ab490917a3153c50d67f46bfd12877c2d42d9ae855af3160461aa055ba4900a7c2df6b89acee908376b0925431b6a925130d744101b95fd1ddd822173d97a945b3a7f721cff33c4d3afd4ef3e8ead079f059d604ce87722708a50b49fd35ab475d7bad69d507e5a7f1bc499ac79e68265a5a89ee3ef56e250e3b724113ba179d07bf846ff2c068e0e46e2c57c5d98571d169bef75148c2adad3e4d6a927b53763fa8fd197ab6b73500a6dcbc6718556f48a74e87e737802d08c9df0209a74b6f09e05d3214bbdbbd4d1c3386a7d47213746876e8d840a56299f65f7bc99ca5350019cc62b759ddacbb55172e13b762614ebe959987840db244c7f548798cdd6a3354f79d58c1fd39715cc31b7ab7feb1702aec24da864500831fb39a83920b1e2e32ef23e73987fde2e24", "credential_finalization": "554a499b045b2c94d68f0bddeb41f76c32f7b357000eadbfea0487ba8dc0b146491f4ff614619e955686d64d4575f564", "client_registration_state": "23b19816e290cafe9796db34c4922211de1498df4bab2e5ce0c318e533658771d117e9a9eae9d016d7433d3400b4d99c036da1da44ad100ce9c80f074b98e8564e131d6d9186c666e44e2f2ac74822a86aa9af120bc2ebbba3f81dddea21fb418e", "client_login_state": "23b19816e290cafe9796db34c4922211de1498df4bab2e5ce0c318e533658771d117e9a9eae9d016d7433d3400b4d99c036da1da44ad100ce9c80f074b98e8564e131d6d9186c666e44e2f2ac74822a86aa9af120bc2ebbba3f81dddea21fb418e48b90f2c8909576edc61743b84d66ce93ae5432d60bb29eadb076e027a163731741bb246da7c5b1361038e78d25006c3d8388b7361e9ca082e5a9770edfd7e4268ea700379d9f0d73594cd3edcd2096a8ce99af9faf736c11262d15b91584f5148b90f2c8909576edc61743b84d66ce93ae5432d60bb29eadb076e027a163731", "server_login_state": "ef411e8209facbabbeb99d7b73600d6f6c54df43969048381619b7e2c448eff411a67be3f782d9e7a64fb86434cf4923976f0526ff3ddb232492982e34b85e22ca4d6ce6d77608e69966e6ee946df1895483da7e27974d8013f668aab235376d0fc20aa7385934f47c498b804483c436514ac31e3817067615464a89afb46ffff7cc2bd52e05cbee3a23c6ec9a43705e", "password_file": "4f6f6c4b7d2dce29897218c5c609aea30288112ed8c33d8cd67f2b19c3fd1928fb65782af6070e84bb7a542813fff00fb7f71a7797089072babfe06ba01d1845e0c8b6a9b17b65f6b992c00ce34f115b7051dd78600860b1c96bfd4729fc792111c06b7653057ab9dd32efe03052a564d02881210e8c7e043f278032e691a23e8451377624aebcbf7364155158c8cc0a3df1f2c3e669785b81f17016ba7a7acd", "export_key": "c90f604c28e60aa7b386ae9b37fc1d9d2f9aabf9c4e6ead8eb2b132667121f19bc6e99afdfc287aff26224fc451a9328", "session_key": "0fc20aa7385934f47c498b804483c436514ac31e3817067615464a89afb46ffff7cc2bd52e05cbee3a23c6ec9a43705e" } "#; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] static TEST_VECTOR_CURVE25519_RISTRETTO255: &str = r#" { "client_s_pk": "425d9690de8c494cf18020f0b8977aa02d2701e20ae22f7e9a22396b219bdd09", "client_s_sk": "48064fdc57a4f75dd1e07013c7123cc9f63bcc7cc812fd4d6785b10d323b2549", "client_e_pk": "643a85ac2e212108b822e2ed22705aa1da98db515cc010ea5f803a227be1c919", "client_e_sk": "70662c87da47502582f94edcc41babaf50eff95125ac666a9ff02f06c852276a", "server_s_pk": "a4fac053abfb5d79def37a3ea1d19d85d34b84a0ac4cbfc4cea1f368cd99553c", "server_s_sk": "50e025031678aea84429d14259ab2d7e2d95f552e7a694d58d00e1ed4517b14f", "server_e_pk": "957eb70736694ad3058275fae43bb48204d88d65b80b7b197192f78c0942d013", "server_e_sk": "6802638853a41e9773fe51a9ab442465176e2ccef3eb3855a343a411ac35e952", "fake_sk": "881be0fdc6ba406b4725daf16cf0dd6cef20c8e401db26c6827fb93f30906c69", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "7dbc12dd8b1280bc76567b32f150e1c96a7d88d8dbb7083eae67c85990905e01", "oprf_seed": "4c335f4d75f53e9bf593fbbb4971763fc27caed1151ea054aa582178794a95b11ce9fbead333205f705cb9dc717ed643fa743ddfa606f7d7e02fcb750d70294c", "masking_nonce": "4df6e5189bce92a87ade075e4bfb5aba25e1a215c9da97bfefe3751abbd516f74e65aa7f5571e603936e8aba0d60a317fe991478e12e97e5303ddac6b5eed135", "envelope_nonce": "bc787b112a62e219225fb7b157a7455014726c9ef4176551526615511d2b08c1", "client_nonce": "1e930824df3cd0e4d0423a87371ad1d903770fed134a2ff5839493ea29d4ac5f", "server_nonce": "6d41b975cd7106c6db6e1d89af45e3e7f1635cd0c1c866be96d517314d04b585", "context": "636f6e74657874", "registration_request": "ac14c0042d20a0feb27ef3215db82e66786872cddc0568508318526477cc1830", "registration_response": "3243003d14d0d29621c4136f9ce9a09d4fc24e77fccffeb9619134a26d14c226a4fac053abfb5d79def37a3ea1d19d85d34b84a0ac4cbfc4cea1f368cd99553c", "registration_upload": "3b7ccbd3e9aba6b0e1b04e2fe7a5a1e7a9e1d4c2ab66e87e2626ab585c50fb3d8f6ce5c600adf8bb328211944c9ff00135fafad3b3552806bda433db0ea2be69f9abc83d572dfefa4d0062dd98f73a51cf9398621fd7398584488614f611ed3748064fdc57a4f75dd1e07013c7123cc9f63bcc7cc812fd4d6785b10d323b254917976677c28c001c43665f9709975a5c403a2fbbaf2fe853b80497ca5bb0e8300c671775ced7247fe6304c34c4f1f96ddcab1323682741cf899a9d208d392ce0", "credential_request": "ac14c0042d20a0feb27ef3215db82e66786872cddc0568508318526477cc18301e930824df3cd0e4d0423a87371ad1d903770fed134a2ff5839493ea29d4ac5f643a85ac2e212108b822e2ed22705aa1da98db515cc010ea5f803a227be1c919", "credential_response": "3243003d14d0d29621c4136f9ce9a09d4fc24e77fccffeb9619134a26d14c2264df6e5189bce92a87ade075e4bfb5aba25e1a215c9da97bfefe3751abbd516f77933211492cc397232556fd7092e998fb80ef2d5fb351cec4ab89864fc6822dcb7c88065773da1f9f89df37a18e012c60a90a8464242bd0b627dfd62a435f2ae4ddb54d57b3fb76f625cdb71b1e1927558c3e378503dd17251997c9d19dba8bb0331f474eb49035edc30b4cb8eec75ad261c6ef789ce1dd24d1dc1c1a4004cb36802638853a41e9773fe51a9ab442465176e2ccef3eb3855a343a411ac35e952925e2d2267d597d6f6a672cd95f6ea7ec152ea4d47d4cc7806ae406910627c2f2e8511ea4a4440a7538f7a964f7e789c8041e7a7bafb60c9c07bf9748a435da4a0b6cd195136427cca4414894202913585e488eb1f3406d3e272415827ddc137", "credential_finalization": "f3b767aeabf8fccbabee31baae90ccb95f0aff73824f8832e1ef91d988f873d4c1c92c6dd47cc3b6cf3d9ba3d74d2111e7709060da1ad17eda5697ad5bdf1523", "client_registration_state": "7dbc12dd8b1280bc76567b32f150e1c96a7d88d8dbb7083eae67c85990905e01ac14c0042d20a0feb27ef3215db82e66786872cddc0568508318526477cc1830", "client_login_state": "7dbc12dd8b1280bc76567b32f150e1c96a7d88d8dbb7083eae67c85990905e01ac14c0042d20a0feb27ef3215db82e66786872cddc0568508318526477cc18301e930824df3cd0e4d0423a87371ad1d903770fed134a2ff5839493ea29d4ac5f643a85ac2e212108b822e2ed22705aa1da98db515cc010ea5f803a227be1c91970662c87da47502582f94edcc41babaf50eff95125ac666a9ff02f06c852276a1e930824df3cd0e4d0423a87371ad1d903770fed134a2ff5839493ea29d4ac5f", "server_login_state": "74116bce8ba020be04b87f65f0cc7687f01538ba573c931ce11b761dd032e7112a2da04f92adda01a33682e425fda5ec0d473f8fabf9bf5f35ccf226e05dd89399de8bb7f84e9ff90a9e0090c98cd3fcfa930da647db50ccea008d44810297c92e0a27400591aabfe0878c2c7040b6a67da760c0d88fba2443b5f0840afe274edd42475990df27dfd26d3823e429e7092664f5cc3e12e9ca4854f44e8d589d79a1a9b796137c2e72e3ff79aceeaf34aa885f1986b849ddee8d3b8635a79a5e41", "password_file": "3b7ccbd3e9aba6b0e1b04e2fe7a5a1e7a9e1d4c2ab66e87e2626ab585c50fb3d8f6ce5c600adf8bb328211944c9ff00135fafad3b3552806bda433db0ea2be69f9abc83d572dfefa4d0062dd98f73a51cf9398621fd7398584488614f611ed3748064fdc57a4f75dd1e07013c7123cc9f63bcc7cc812fd4d6785b10d323b254917976677c28c001c43665f9709975a5c403a2fbbaf2fe853b80497ca5bb0e8300c671775ced7247fe6304c34c4f1f96ddcab1323682741cf899a9d208d392ce0", "export_key": "2bd139ff06ca5fe9897640fefbd00380b080239efb84d796df997c235306c9829e52694193f0d0e2bb69235e42276fffa933b436ebd6132a59d7062f3a74b83d", "session_key": "dd42475990df27dfd26d3823e429e7092664f5cc3e12e9ca4854f44e8d589d79a1a9b796137c2e72e3ff79aceeaf34aa885f1986b849ddee8d3b8635a79a5e41" } "#; fn decode(values: &Value, key: &str) -> Option> { values[key].as_str().and_then(|s| hex::decode(s).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(), fake_sk: decode(values, "fake_sk").unwrap(), credential_identifier: decode(values, "credential_identifier").unwrap(), id_u: decode(values, "id_u").unwrap(), id_s: decode(values, "id_s").unwrap(), password: decode(values, "password").unwrap(), blinding_factor: decode(values, "blinding_factor").unwrap(), oprf_seed: decode(values, "oprf_seed").unwrap(), masking_nonce: decode(values, "masking_nonce").unwrap(), envelope_nonce: decode(values, "envelope_nonce").unwrap(), client_nonce: decode(values, "client_nonce").unwrap(), server_nonce: decode(values, "server_nonce").unwrap(), context: decode(values, "context").unwrap(), registration_request: decode(values, "registration_request").unwrap(), registration_response: decode(values, "registration_response").unwrap(), registration_upload: decode(values, "registration_upload").unwrap(), credential_request: decode(values, "credential_request").unwrap(), credential_response: decode(values, "credential_response").unwrap(), credential_finalization: decode(values, "credential_finalization").unwrap(), 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(), export_key: decode(values, "export_key").unwrap(), session_key: decode(values, "session_key").unwrap(), } } 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()); s.push_str(format!("\"fake_sk\": \"{}\",\n", hex::encode(&p.fake_sk)).as_str()); s.push_str( format!( "\"credential_identifier\": \"{}\",\n", hex::encode(&p.credential_identifier) ) .as_str(), ); 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()); 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(), ); 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(), ); 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()); s.push_str(format!("\"context\": \"{}\",\n", hex::encode(&p.context)).as_str()); 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(), ); s.push_str( format!( "\"registration_upload\": \"{}\",\n", hex::encode(&p.registration_upload) ) .as_str(), ); 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(), ); s.push_str( format!( "\"credential_finalization\": \"{}\",\n", hex::encode(&p.credential_finalization) ) .as_str(), ); 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(), ); s.push_str(format!("\"export_key\": \"{}\",\n", hex::encode(&p.export_key)).as_str()); s.push_str(format!("\"session_key\": \"{}\"\n", hex::encode(&p.session_key)).as_str()); s.push_str("}\n"); s } fn generate_parameters() -> Result where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // ClientRegistration: KgSk + KgPk as Group>::ScalarLen: Add< as Group>::ElemLen>, ClientRegistrationLen: ArrayLength, // RegistrationResponse: KgPk + KePk as Group>::ElemLen: Add<::PkLen>, RegistrationResponseLen: ArrayLength, // Envelope: Nonce + Hash NonceLen: Add>>, EnvelopeLen: ArrayLength, // RegistrationUpload: (KePk + Hash) + Envelope ::PkLen: Add>>, Sum<::PkLen, OutputSize>>: ArrayLength + Add>, RegistrationUploadLen: ArrayLength, // ServerRegistration = RegistrationUpload // Ke1Message: Nonce + KePk NonceLen: Add<::PkLen>, Ke1MessageLen: ArrayLength, // CredentialRequest: KgPk + Ke1Message as Group>::ElemLen: Add>, CredentialRequestLen: ArrayLength, // ClientLogin: KgSk + CredentialRequest + Ke1State as Group>::ScalarLen: Add>, Sum< as Group>::ScalarLen, CredentialRequestLen>: ArrayLength + Add>, ClientLoginLen: ArrayLength, // MaskedResponse: (Nonce + Hash) + KePk NonceLen: Add>>, Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, // CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse as Group>::ElemLen: Add, Sum< as Group>::ElemLen, NonceLen>: ArrayLength + Add>, CredentialResponseWithoutKeLen: ArrayLength, // Ke2Message: (Nonce + KePk) + Hash NonceLen: Add<::PkLen>, Sum::PkLen>: ArrayLength + Add>>, Ke2MessageLen: ArrayLength, // CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message CredentialResponseWithoutKeLen: Add>, CredentialResponseLen: ArrayLength, { use rand::RngCore; use crate::keypair::KeyPair; let mut rng = OsRng; // Inputs let server_s_kp = KeyPair::::generate_random(&mut rng); let server_e_kp = KeyPair::::generate_random(&mut rng); let client_s_kp = KeyPair::::generate_random(&mut rng); let client_e_kp = KeyPair::::generate_random(&mut rng); let fake_kp = KeyPair::::generate_random(&mut rng); let credential_identifier = b"credIdentifier"; let id_u = b"idU"; let id_s = b"idS"; let password = b"password"; let context = b"context"; let mut oprf_seed = Output::>::default(); rng.fill_bytes(&mut oprf_seed); let mut masking_nonce = [0u8; 64]; rng.fill_bytes(&mut masking_nonce); let mut envelope_nonce = [0u8; 32]; rng.fill_bytes(&mut envelope_nonce); let mut client_nonce = [0u8; NonceLen::USIZE]; rng.fill_bytes(&mut client_nonce); let mut server_nonce = [0u8; NonceLen::USIZE]; rng.fill_bytes(&mut server_nonce); let fake_sk: Vec = fake_kp.private().serialize().to_vec(); let server_setup = ServerSetup::::deserialize( &[ oprf_seed.as_ref(), &server_s_kp.private().serialize(), &fake_sk, ] .concat(), ) .unwrap(); let blinding_factor = as Group>::random_scalar(&mut rng); let blinding_factor_bytes = OprfGroup::::serialize_scalar(blinding_factor); let mut blinding_factor_registration_rng = CycleRng::new(blinding_factor_bytes.to_vec()); let client_registration_start_result = ClientRegistration::::start(&mut blinding_factor_registration_rng, password).unwrap(); let blinding_factor_bytes_returned = OprfGroup::::serialize_scalar( client_registration_start_result .state .oprf_client .get_blind(), ); assert_eq!( hex::encode(&blinding_factor_bytes), hex::encode(&blinding_factor_bytes_returned) ); let registration_request_bytes = client_registration_start_result.message.serialize(); let client_registration_state = client_registration_start_result.state.serialize(); let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, credential_identifier, ) .unwrap(); let registration_response_bytes = server_registration_start_result.message.serialize(); let mut client_s_sk_and_nonce: Vec = Vec::new(); client_s_sk_and_nonce.extend_from_slice(&client_s_kp.private().serialize()); client_s_sk_and_nonce.extend_from_slice(&envelope_nonce); let mut finish_registration_rng = CycleRng::new(client_s_sk_and_nonce); let client_registration_finish_result = client_registration_start_result .state .finish( &mut finish_registration_rng, password, server_registration_start_result.message, ClientRegistrationFinishParameters::new( Identifiers { client: Some(id_u), server: Some(id_s), }, None, ), ) .unwrap(); let registration_upload_bytes = client_registration_finish_result.message.serialize(); let password_file = ServerRegistration::finish(client_registration_finish_result.message); let password_file_bytes = password_file.serialize(); let mut client_login_start: Vec = Vec::new(); client_login_start.extend_from_slice(&blinding_factor_bytes); client_login_start.extend_from_slice(&client_e_kp.private().serialize()); client_login_start.extend_from_slice(&client_nonce); let mut client_login_start_rng = CycleRng::new(client_login_start); let client_login_start_result = ClientLogin::::start(&mut client_login_start_rng, password).unwrap(); let credential_request_bytes = client_login_start_result.message.serialize(); let client_login_state = client_login_start_result.state.serialize().to_vec(); let mut server_e_sk_and_nonce_rng = CycleRng::new( [ masking_nonce.to_vec(), server_e_kp.private().serialize().to_vec(), server_nonce.to_vec(), ] .concat(), ); let server_login_start_result = ServerLogin::::start( &mut server_e_sk_and_nonce_rng, &server_setup, Some(password_file), client_login_start_result.message, credential_identifier, ServerLoginStartParameters { context: Some(context), identifiers: Identifiers { client: Some(id_u), server: Some(id_s), }, }, ) .unwrap(); let credential_response_bytes = server_login_start_result.message.serialize(); let server_login_state = server_login_start_result.state.serialize(); let client_login_finish_result = client_login_start_result .state .finish( password, server_login_start_result.message, ClientLoginFinishParameters::new( Some(context), Identifiers { client: Some(id_u), server: Some(id_s), }, None, ), ) .unwrap(); let credential_finalization_bytes = client_login_finish_result.message.serialize(); Ok(TestVectorParameters { client_s_pk: client_s_kp.public().serialize().to_vec(), client_s_sk: client_s_kp.private().serialize().to_vec(), client_e_pk: client_e_kp.public().serialize().to_vec(), client_e_sk: client_e_kp.private().serialize().to_vec(), server_s_pk: server_s_kp.public().serialize().to_vec(), server_s_sk: server_s_kp.private().serialize().to_vec(), server_e_pk: server_e_kp.public().serialize().to_vec(), server_e_sk: server_e_kp.private().serialize().to_vec(), fake_sk, credential_identifier: credential_identifier.to_vec(), id_u: id_u.to_vec(), id_s: id_s.to_vec(), password: password.to_vec(), blinding_factor: blinding_factor_bytes.to_vec(), oprf_seed: oprf_seed.to_vec(), masking_nonce: masking_nonce.to_vec(), envelope_nonce: envelope_nonce.to_vec(), client_nonce: client_nonce.to_vec(), server_nonce: server_nonce.to_vec(), context: context.to_vec(), registration_request: registration_request_bytes.to_vec(), registration_response: registration_response_bytes.to_vec(), registration_upload: registration_upload_bytes.to_vec(), credential_request: credential_request_bytes.to_vec(), credential_response: credential_response_bytes.to_vec(), credential_finalization: credential_finalization_bytes.to_vec(), password_file: password_file_bytes.to_vec(), client_registration_state: client_registration_state.to_vec(), client_login_state, server_login_state: server_login_state.to_vec(), session_key: client_login_finish_result.session_key.to_vec(), export_key: client_registration_finish_result.export_key.to_vec(), }) } #[test] fn generate_test_vectors() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] { let parameters = generate_parameters::()?; println!("Ristretto255: {}", stringify_test_vectors(¶meters)); let parameters = generate_parameters::()?; println!( "Ristretto255 P-256: {}", stringify_test_vectors(¶meters) ); let parameters = generate_parameters::()?; println!( "Ristretto255 P-384: {}", stringify_test_vectors(¶meters) ); } let parameters = generate_parameters::()?; println!("P-256: {}", stringify_test_vectors(¶meters)); let parameters = generate_parameters::()?; println!("P-256 P-384: {}", stringify_test_vectors(¶meters)); #[cfg(feature = "ristretto255")] { let parameters = generate_parameters::()?; println!( "P-256 Ristretto255: {}", stringify_test_vectors(¶meters) ); } let parameters = generate_parameters::()?; println!("P-384: {}", stringify_test_vectors(¶meters)); let parameters = generate_parameters::()?; println!("P-384 P-256: {}", stringify_test_vectors(¶meters)); #[cfg(feature = "ristretto255")] { let parameters = generate_parameters::()?; println!( "P-384 Ristretto255: {}", stringify_test_vectors(¶meters) ); } #[cfg(feature = "curve25519")] { let parameters = generate_parameters::()?; println!("Curve25519 P-256: {}", stringify_test_vectors(¶meters)); let parameters = generate_parameters::()?; println!("Curve25519 P-384: {}", stringify_test_vectors(¶meters)); } #[cfg(all(feature = "curve25519", feature = "ristretto255"))] { let parameters = generate_parameters::()?; println!( "Curve25519 Ristretto255: {}", stringify_test_vectors(¶meters) ); } Ok(()) } #[test] fn test_registration_request() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // ClientRegistration: KgSk + KgPk as Group>::ScalarLen: Add< as Group>::ElemLen>, ClientRegistrationLen: ArrayLength, { 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::::start(&mut rng, ¶meters.password)?; assert_eq!( hex::encode(¶meters.registration_request), hex::encode(client_registration_start_result.message.serialize()) ); assert_eq!( hex::encode(¶meters.client_registration_state), hex::encode(client_registration_start_result.state.serialize()) ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } #[cfg(feature = "serde")] #[test] fn test_serialization() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { 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::::start(&mut rng, ¶meters.password)?; // Test the bincode serialization (binary). let registration_request = bincode::serialize(&client_registration_start_result.message).unwrap(); assert_eq!( registration_request.len(), RegistrationRequestLen::::USIZE ); let registration_request: RegistrationRequest = bincode::deserialize(®istration_request).unwrap(); assert_eq!( hex::encode(client_registration_start_result.message.serialize()), hex::encode(registration_request.serialize()), ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } #[test] fn test_registration_response() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // RegistrationResponse: KgPk + KePk as Group>::ElemLen: Add<::PkLen>, RegistrationResponseLen: ArrayLength, { let parameters = populate_test_vectors( &serde_json::from_str(test_vector).map_err(|_| ProtocolError::SerializationError)?, ); let server_setup = ServerSetup::::deserialize( &[ parameters.oprf_seed, parameters.server_s_sk, parameters.fake_sk, ] .concat(), )?; let server_registration_start_result = ServerRegistration::::start( &server_setup, RegistrationRequest::deserialize(¶meters.registration_request)?, ¶meters.credential_identifier, )?; assert_eq!( hex::encode(parameters.registration_response), hex::encode(server_registration_start_result.message.serialize()) ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } #[test] fn test_registration_upload() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // Envelope: Nonce + Hash NonceLen: Add>>, EnvelopeLen: ArrayLength, // RegistrationUpload: (KePk + Hash) + Envelope ::PkLen: Add>>, Sum<::PkLen, OutputSize>>: ArrayLength + Add>, RegistrationUploadLen: ArrayLength, { let parameters = populate_test_vectors( &serde_json::from_str(test_vector).map_err(|_| ProtocolError::SerializationError)?, ); let client_s_sk_and_nonce: Vec = [parameters.client_s_sk, parameters.envelope_nonce].concat(); let mut finish_registration_rng = CycleRng::new(client_s_sk_and_nonce); let result = ClientRegistration::::deserialize(¶meters.client_registration_state)? .finish( &mut finish_registration_rng, ¶meters.password, RegistrationResponse::deserialize(¶meters.registration_response)?, ClientRegistrationFinishParameters::new( Identifiers { client: Some(¶meters.id_u), server: Some(¶meters.id_s), }, None, ), )?; assert_eq!( hex::encode(parameters.registration_upload), hex::encode(result.message.serialize()) ); assert_eq!( hex::encode(parameters.export_key), hex::encode(result.export_key) ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } #[test] fn test_password_file() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // Envelope: Nonce + Hash NonceLen: Add>>, EnvelopeLen: ArrayLength, // RegistrationUpload: (KePk + Hash) + Envelope ::PkLen: Add>>, Sum<::PkLen, OutputSize>>: ArrayLength + Add>, RegistrationUploadLen: ArrayLength, // ServerRegistration = RegistrationUpload { let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap()); let password_file = ServerRegistration::finish(RegistrationUpload::::deserialize( ¶meters.registration_upload, )?); assert_eq!( hex::encode(parameters.password_file), hex::encode(password_file.serialize()) ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } #[test] fn test_credential_request() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // CredentialRequest: KgPk + Ke1Message as Group>::ElemLen: Add>, CredentialRequestLen: ArrayLength, // ClientLogin: KgSk + CredentialRequest + Ke1State as Group>::ScalarLen: Add>, Sum< as Group>::ScalarLen, CredentialRequestLen>: ArrayLength + Add>, ClientLoginLen: ArrayLength, { let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap()); let client_login_start_rng = [ parameters.blinding_factor, parameters.client_e_sk, parameters.client_nonce, ] .concat(); let mut client_login_start_rng = CycleRng::new(client_login_start_rng); let client_login_start_result = ClientLogin::::start(&mut client_login_start_rng, ¶meters.password)?; assert_eq!( hex::encode(¶meters.credential_request), hex::encode(client_login_start_result.message.serialize()) ); assert_eq!( hex::encode(¶meters.client_login_state), hex::encode(client_login_start_result.state.serialize()) ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } #[test] fn test_credential_response() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk NonceLen: Add>>, Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, // CredentialResponseWithoutKeLen: (KgPk + Nonce) + MaskedResponse as Group>::ElemLen: Add, Sum< as Group>::ElemLen, NonceLen>: ArrayLength + Add>, CredentialResponseWithoutKeLen: ArrayLength, // CredentialResponse: CredentialResponseWithoutKeLen + Ke2Message CredentialResponseWithoutKeLen: Add>, CredentialResponseLen: ArrayLength, { let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap()); let server_setup = ServerSetup::::deserialize( &[ parameters.oprf_seed, parameters.server_s_sk, parameters.fake_sk, ] .concat(), )?; let mut server_e_sk_and_nonce_rng = CycleRng::new( [ parameters.masking_nonce, parameters.server_e_sk, parameters.server_nonce, ] .concat(), ); let server_login_start_result = ServerLogin::::start( &mut server_e_sk_and_nonce_rng, &server_setup, Some(ServerRegistration::deserialize(¶meters.password_file)?), CredentialRequest::::deserialize(¶meters.credential_request)?, ¶meters.credential_identifier, ServerLoginStartParameters { context: Some(¶meters.context), identifiers: Identifiers { client: Some(¶meters.id_u), server: Some(¶meters.id_s), }, }, )?; assert_eq!( hex::encode(¶meters.credential_response), hex::encode(server_login_start_result.message.serialize()) ); assert_eq!( hex::encode(¶meters.server_login_state), hex::encode(server_login_start_result.state.serialize()) ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } #[test] fn test_credential_finalization() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk NonceLen: Add>>, Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap()); let client_login_finish_result = ClientLogin::::deserialize(¶meters.client_login_state)?.finish( ¶meters.password, CredentialResponse::::deserialize(¶meters.credential_response)?, ClientLoginFinishParameters::new( Some(¶meters.context), Identifiers { client: Some(¶meters.id_u), server: Some(¶meters.id_s), }, None, ), )?; assert_eq!( hex::encode(¶meters.server_s_pk), hex::encode(&client_login_finish_result.server_s_pk.serialize()) ); assert_eq!( hex::encode(¶meters.session_key), hex::encode(&client_login_finish_result.session_key) ); assert_eq!( hex::encode(¶meters.credential_finalization), hex::encode(client_login_finish_result.message.serialize()) ); assert_eq!( hex::encode(¶meters.export_key), hex::encode(client_login_finish_result.export_key) ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } #[test] fn test_server_login_finish() -> Result<(), ProtocolError> { fn inner(test_vector: &str) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { let parameters = populate_test_vectors(&serde_json::from_str(test_vector).unwrap()); let server_login_result = ServerLogin::::deserialize(¶meters.server_login_state)? .finish(CredentialFinalization::deserialize( ¶meters.credential_finalization, )?)?; assert_eq!( hex::encode(parameters.session_key), hex::encode(&server_login_result.session_key) ); Ok(()) } #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_RISTRETTO255_P384)?; inner::(TEST_VECTOR_P256)?; inner::(TEST_VECTOR_P256_P384)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P256_RISTRETTO255)?; inner::(TEST_VECTOR_P384)?; inner::(TEST_VECTOR_P384_P256)?; #[cfg(feature = "ristretto255")] inner::(TEST_VECTOR_P384_RISTRETTO255)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P256)?; #[cfg(feature = "curve25519")] inner::(TEST_VECTOR_CURVE25519_P384)?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::(TEST_VECTOR_CURVE25519_RISTRETTO255)?; Ok(()) } fn test_complete_flow( registration_password: &[u8], login_password: &[u8], ) -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk NonceLen: Add>>, Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { let credential_identifier = b"credentialIdentifier"; let mut client_rng = OsRng; let mut server_rng = OsRng; let server_setup = ServerSetup::::new(&mut server_rng); let client_registration_start_result = ClientRegistration::::start(&mut client_rng, registration_password)?; let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, credential_identifier, )?; let client_registration_finish_result = client_registration_start_result.state.finish( &mut client_rng, registration_password, server_registration_start_result.message, ClientRegistrationFinishParameters::default(), )?; let p_file = ServerRegistration::finish(client_registration_finish_result.message); let client_login_start_result = ClientLogin::::start(&mut client_rng, login_password)?; let server_login_start_result = ServerLogin::::start( &mut server_rng, &server_setup, Some(p_file), client_login_start_result.message, credential_identifier, ServerLoginStartParameters::default(), )?; let client_login_result = client_login_start_result.state.finish( login_password, server_login_start_result.message, ClientLoginFinishParameters::default(), ); if hex::encode(registration_password) == hex::encode(login_password) { let client_login_finish_result = client_login_result?; let server_login_finish_result = server_login_start_result .state .finish(client_login_finish_result.message)?; assert_eq!( hex::encode(&server_login_finish_result.session_key), hex::encode(&client_login_finish_result.session_key) ); assert_eq!( hex::encode(client_registration_finish_result.export_key), hex::encode(client_login_finish_result.export_key) ); } else { assert!(matches!( client_login_result, Err(ProtocolError::InvalidLoginError) )); } Ok(()) } #[test] fn test_complete_flow_success() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"good password")?; #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"good password")?; #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"good password")?; test_complete_flow::(b"good password", b"good password")?; test_complete_flow::(b"good password", b"good password")?; #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"good password")?; test_complete_flow::(b"good password", b"good password")?; test_complete_flow::(b"good password", b"good password")?; #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"good password")?; #[cfg(feature = "curve25519")] test_complete_flow::(b"good password", b"good password")?; #[cfg(feature = "curve25519")] test_complete_flow::(b"good password", b"good password")?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] test_complete_flow::(b"good password", b"good password")?; Ok(()) } #[test] fn test_complete_flow_fail() -> Result<(), ProtocolError> { #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"bad password")?; #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"bad password")?; #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"bad password")?; test_complete_flow::(b"good password", b"bad password")?; test_complete_flow::(b"good password", b"bad password")?; #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"bad password")?; test_complete_flow::(b"good password", b"bad password")?; test_complete_flow::(b"good password", b"bad password")?; #[cfg(feature = "ristretto255")] test_complete_flow::(b"good password", b"bad password")?; #[cfg(feature = "curve25519")] test_complete_flow::(b"good password", b"bad password")?; #[cfg(feature = "curve25519")] test_complete_flow::(b"good password", b"bad password")?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] test_complete_flow::(b"good password", b"bad password")?; Ok(()) } // Zeroize tests #[test] fn test_zeroize_client_registration_start() -> Result<(), ProtocolError> { fn inner() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { let mut client_rng = OsRng; let client_registration_start_result = ClientRegistration::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let mut state = client_registration_start_result.state; unsafe { ptr::drop_in_place(&mut state) }; for byte in state.to_vec() { assert_eq!(byte, 0); } Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> { fn inner() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { let mut client_rng = OsRng; let mut server_rng = OsRng; let server_setup = ServerSetup::::new(&mut server_rng); let client_registration_start_result = ClientRegistration::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, STR_CREDENTIAL_IDENTIFIER.as_bytes(), )?; let client_registration_finish_result = client_registration_start_result.state.finish( &mut client_rng, STR_PASSWORD.as_bytes(), server_registration_start_result.message, ClientRegistrationFinishParameters::default(), )?; let mut state = client_registration_finish_result.state; unsafe { ptr::drop_in_place(&mut state) }; for byte in state.to_vec() { assert_eq!(byte, 0); } Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_zeroize_server_registration_finish() -> Result<(), ProtocolError> { fn inner() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // Envelope: Nonce + Hash NonceLen: Add>>, EnvelopeLen: ArrayLength, // RegistrationUpload: (KePk + Hash) + Envelope ::PkLen: Add>>, Sum<::PkLen, OutputSize>>: ArrayLength + Add>, RegistrationUploadLen: ArrayLength, // ServerRegistration = RegistrationUpload { let mut client_rng = OsRng; let mut server_rng = OsRng; let server_setup = ServerSetup::::new(&mut server_rng); let client_registration_start_result = ClientRegistration::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, STR_CREDENTIAL_IDENTIFIER.as_bytes(), )?; let client_registration_finish_result = client_registration_start_result.state.finish( &mut client_rng, STR_PASSWORD.as_bytes(), server_registration_start_result.message, ClientRegistrationFinishParameters::default(), )?; let p_file = ServerRegistration::finish(client_registration_finish_result.message); let mut state = p_file; util::drop_manually(&mut state); util::test_zeroized(&mut state.0.envelope.mode); util::test_zeroized(&mut state.0.masking_key); Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_zeroize_client_login_start() -> Result<(), ProtocolError> { fn inner>() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // CredentialRequest: KgPk + Ke1Message as Group>::ElemLen: Add::PkLen>>, CredentialRequestLen: ArrayLength, // Ke1State: KeSk + Nonce ::SkLen: Add, Sum<::SkLen, NonceLen>: ArrayLength, // Ke1Message: Nonce + KePk NonceLen: Add<::PkLen>, Sum::PkLen>: ArrayLength, // Ke2State: (Hash + Hash) + Hash OutputSize>: Add>>, Sum>, OutputSize>>: ArrayLength + Add>>, Sum>, OutputSize>>, OutputSize>>: ArrayLength, // Ke2Message: (Nonce + KePk) + Hash NonceLen: Add<::PkLen>, Sum::PkLen>: ArrayLength + Add>>, Sum::PkLen>, OutputSize>>: ArrayLength, { let mut client_rng = OsRng; let client_login_start_result = ClientLogin::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let mut state = client_login_start_result.state; util::drop_manually(&mut state); util::test_zeroized(&mut state.oprf_client); util::test_zeroized(&mut state.ke1_state); util::test_zeroized(&mut state.credential_request.ke1_message.client_nonce); Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_zeroize_server_login_start() -> Result<(), ProtocolError> { fn inner() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk NonceLen: Add>>, Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { let mut client_rng = OsRng; let mut server_rng = OsRng; let server_setup = ServerSetup::::new(&mut server_rng); let client_registration_start_result = ClientRegistration::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, STR_CREDENTIAL_IDENTIFIER.as_bytes(), )?; let client_registration_finish_result = client_registration_start_result.state.finish( &mut client_rng, STR_PASSWORD.as_bytes(), server_registration_start_result.message, ClientRegistrationFinishParameters::default(), )?; let p_file = ServerRegistration::finish(client_registration_finish_result.message); let client_login_start_result = ClientLogin::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let server_login_start_result = ServerLogin::::start( &mut server_rng, &server_setup, Some(p_file), client_login_start_result.message, STR_CREDENTIAL_IDENTIFIER.as_bytes(), ServerLoginStartParameters::default(), )?; let mut state = server_login_start_result.state; unsafe { ptr::drop_in_place(&mut state) }; for byte in state.serialize() { assert_eq!(byte, 0); } Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> { fn inner>() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk NonceLen: Add>>, Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, // CredentialRequest: KgPk + Ke1Message as Group>::ElemLen: Add::PkLen>>, CredentialRequestLen: ArrayLength, // Ke1State: KeSk + Nonce ::SkLen: Add, Sum<::SkLen, NonceLen>: ArrayLength, // Ke1Message: Nonce + KePk NonceLen: Add<::PkLen>, Sum::PkLen>: ArrayLength, // Ke2State: (Hash + Hash) + Hash OutputSize>: Add>>, Sum>, OutputSize>>: ArrayLength + Add>>, Sum>, OutputSize>>, OutputSize>>: ArrayLength, // Ke2Message: (Nonce + KePk) + Hash NonceLen: Add<::PkLen>, Sum::PkLen>: ArrayLength + Add>>, Sum::PkLen>, OutputSize>>: ArrayLength, { let mut client_rng = OsRng; let mut server_rng = OsRng; let server_setup = ServerSetup::::new(&mut server_rng); let client_registration_start_result = ClientRegistration::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, STR_CREDENTIAL_IDENTIFIER.as_bytes(), )?; let client_registration_finish_result = client_registration_start_result.state.finish( &mut client_rng, STR_PASSWORD.as_bytes(), server_registration_start_result.message, ClientRegistrationFinishParameters::default(), )?; let p_file = ServerRegistration::finish(client_registration_finish_result.message); let client_login_start_result = ClientLogin::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let server_login_start_result = ServerLogin::::start( &mut server_rng, &server_setup, Some(p_file), client_login_start_result.message, STR_CREDENTIAL_IDENTIFIER.as_bytes(), ServerLoginStartParameters::default(), )?; let client_login_finish_result = client_login_start_result.state.finish( STR_PASSWORD.as_bytes(), server_login_start_result.message, ClientLoginFinishParameters::default(), )?; let mut state = client_login_finish_result.state; util::drop_manually(&mut state); util::test_zeroized(&mut state.oprf_client); util::test_zeroized(&mut state.ke1_state); util::test_zeroized(&mut state.credential_request.ke1_message.client_nonce); Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> { fn inner() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk NonceLen: Add>>, Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { let mut client_rng = OsRng; let mut server_rng = OsRng; let server_setup = ServerSetup::::new(&mut server_rng); let client_registration_start_result = ClientRegistration::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, STR_CREDENTIAL_IDENTIFIER.as_bytes(), )?; let client_registration_finish_result = client_registration_start_result.state.finish( &mut client_rng, STR_PASSWORD.as_bytes(), server_registration_start_result.message, ClientRegistrationFinishParameters::default(), )?; let p_file = ServerRegistration::finish(client_registration_finish_result.message); let client_login_start_result = ClientLogin::::start(&mut client_rng, STR_PASSWORD.as_bytes())?; let server_login_start_result = ServerLogin::::start( &mut server_rng, &server_setup, Some(p_file), client_login_start_result.message, STR_CREDENTIAL_IDENTIFIER.as_bytes(), ServerLoginStartParameters::default(), )?; let client_login_finish_result = client_login_start_result.state.finish( STR_PASSWORD.as_bytes(), 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; unsafe { ptr::drop_in_place(&mut state) }; for byte in state.serialize() { assert_eq!(byte, 0); } Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_scalar_always_nonzero() -> Result<(), ProtocolError> { fn inner() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { // 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::::start(&mut client_registration_rng, STR_PASSWORD.as_bytes())?; assert!(!bool::from( OprfGroup::::identity_elem().ct_eq( &client_registration_start_result .message .get_blinded_element_for_testing() .value(), ) )); // Start out with a bunch of zeros to force resampling of scalar let mut client_login_rng = CycleRng::new([vec![0u8; 128], vec![1u8; 128]].concat()); let client_login_start_result = ClientLogin::::start(&mut client_login_rng, STR_PASSWORD.as_bytes())?; assert!(!bool::from( OprfGroup::::identity_elem().ct_eq( &client_login_start_result .message .get_blinded_element_for_testing() .value(), ) )); Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_reflected_value_error_registration() -> Result<(), ProtocolError> { fn inner() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, { let credential_identifier = b"credentialIdentifier"; let password = b"password"; let mut client_rng = OsRng; let mut server_rng = OsRng; let server_setup = ServerSetup::::new(&mut server_rng); let client_registration_start_result = ClientRegistration::::start(&mut client_rng, password)?; let alpha = client_registration_start_result .message .get_blinded_element_for_testing() .value(); let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, credential_identifier, )?; let reflected_registration_response = server_registration_start_result .message .set_evaluation_element_for_testing(alpha); let client_registration_finish_result = client_registration_start_result.state.finish( &mut client_rng, password, reflected_registration_response, ClientRegistrationFinishParameters::default(), ); assert!(matches!( client_registration_finish_result, Err(ProtocolError::ReflectedValueError) )); Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) } #[test] fn test_reflected_value_error_login() -> Result<(), ProtocolError> { fn inner() -> Result<(), ProtocolError> where as OutputSizeUser>::OutputSize: IsLess + IsLessOrEqual< as BlockSizeUser>::BlockSize>, OprfHash: Hash, as CoreProxy>::Core: ProxyHash, < as CoreProxy>::Core as BlockSizeUser>::BlockSize: IsLess, Le<< as CoreProxy>::Core as BlockSizeUser>::BlockSize, U256>: NonZero, // MaskedResponse: (Nonce + Hash) + KePk NonceLen: Add>>, Sum>>: ArrayLength + Add<::PkLen>, MaskedResponseLen: ArrayLength, { let credential_identifier = b"credentialIdentifier"; let password = b"password"; let mut client_rng = OsRng; let mut server_rng = OsRng; let server_setup = ServerSetup::::new(&mut server_rng); let client_registration_start_result = ClientRegistration::::start(&mut client_rng, password)?; let server_registration_start_result = ServerRegistration::::start( &server_setup, client_registration_start_result.message, credential_identifier, )?; let client_registration_finish_result = client_registration_start_result.state.finish( &mut client_rng, password, server_registration_start_result.message, ClientRegistrationFinishParameters::default(), )?; let p_file = ServerRegistration::finish(client_registration_finish_result.message); let client_login_start_result = ClientLogin::::start(&mut client_rng, password)?; let alpha = client_login_start_result .message .get_blinded_element_for_testing() .value(); let server_login_start_result = ServerLogin::::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_evaluation_element_for_testing(alpha); let client_login_result = client_login_start_result.state.finish( password, reflected_credential_response, ClientLoginFinishParameters::default(), ); assert!(matches!( client_login_result, Err(ProtocolError::ReflectedValueError) )); Ok(()) } #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; inner::()?; inner::()?; #[cfg(feature = "ristretto255")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(feature = "curve25519")] inner::()?; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] inner::()?; Ok(()) }