// Copyright (c) Meta Platforms, Inc. and affiliates. // // This source code is dual-licensed under either the MIT license found in the // LICENSE-MIT file in the root directory of this source tree or the Apache // License, Version 2.0 found in the LICENSE-APACHE file in the root directory // of this source tree. You may select, at your option, one of the above-listed // licenses. #![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": "26716bbe69e8a0f5af491ee125ebcf1ba570fded8429a5efe3a411572046f168", "client_s_sk": "f4a4b1f3c2c54257b91a0d87db527505428cbee4b6139e653160d44418f2110c", "client_e_pk": "6ef6b77b5640a9edc6f70c51498008113d616abcaecb93665184f960d109fe52", "client_e_sk": "e2ea723e5c50da359eb157b61305ceba76e782def7900f49c4d6710255dab502", "server_s_pk": "88a0a8d7d4af520eed596ed1ba0f559ef3938e0760ba4dc0edda61516f786c34", "server_s_sk": "119d9d4d6a0d346b32bd098545374bb13d3c62292ee46244ad198388e33d7d0c", "server_e_pk": "bc7cc5a25ae069bda90f1c7dd1171025ab795f27e45b78839f6991f29a56e052", "server_e_sk": "5b7e3196121b14d54f326ad51849264aeaeef95ea4f4bfde96b31266df92200b", "fake_sk": "45caf0bf77b445fedbac477bde6b4302122c29c572b8a4b0760e25c7ae992d0a", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "4c590eff6854bda8024117051aa86c838b5d37bf408714a6004c671e7f72fb03", "oprf_seed": "77b3fa30df8c1a6cf848a3cd747f5e28dae23b522e80b9ed67d4d06f09f53136dbc44bbb511b56fec4de8780572bac59b2647c1a71f080e42e70e573f10c6e8a", "masking_nonce": "586157850ffa2085e7f857a27b5c942f5419331ca8f9d7467dfd2825e1ec6a3cf85ec715b14eeaadc89615d07c8d49d6859940ff84649df740f97ecaef168f9b", "envelope_nonce": "21946497a938b40c9bdeb84d286fc7e9b3ef1e6d150660bd2330e400eac5c5bc", "client_nonce": "d49d84dcfdde7c09eecf7b6ddaab79c3269a9d2511ba72d01d363fae862b5a83", "server_nonce": "1e5a5cc267d99866ea30678c1ee43c53400b78e4a27b7dcf2b4521667b78c3b3", "context": "636f6e74657874", "registration_request": "70815fce02606dcb4a45ac1b3e312e201501d5cada02691953297e982e1f9b32", "registration_response": "9e2ae845f8f4bd555c4c8df2b5bcff75fa6d1f0650011c422ad349b8d16edc3788a0a8d7d4af520eed596ed1ba0f559ef3938e0760ba4dc0edda61516f786c34", "registration_upload": "66723c5c39695106d654570842a1edab79711a36ea4f34f65078b8c35731ea494d10c64e8239e9ed8a476faf6a4df44dd60a58fb0036ef65d5241541c7ca87aa050a7ea198c68d490d02f23419d0e002c7819805f8c9a6517a062d67a2de8b4df4a4b1f3c2c54257b91a0d87db527505428cbee4b6139e653160d44418f2110cedf21caa38e4cfbef0a7e5254082231d0b0dd056ff9014f2fa313e2107925dd8e69e45c126b8dae8c00567da34d09c8658aa7acab6e2fcb43359b263b4642773", "credential_request": "70815fce02606dcb4a45ac1b3e312e201501d5cada02691953297e982e1f9b32d49d84dcfdde7c09eecf7b6ddaab79c3269a9d2511ba72d01d363fae862b5a83306781008374dd7ae51f6ea634f742c5db39774daed51d781e1a2e155a804666", "credential_response": "9e2ae845f8f4bd555c4c8df2b5bcff75fa6d1f0650011c422ad349b8d16edc37586157850ffa2085e7f857a27b5c942f5419331ca8f9d7467dfd2825e1ec6a3c0e282fab682070fe5f5eaac1c4c01607c753263d6089bec28cf159483d9d8d3bae87a9ae56d6234b34187cd59740eb5e1cbcfe14e048f04ddd020b223365877b175ec2778d8cb0b427ea592751b1456d7f0c7295bc35bc70803e1a69e9ef0039b805f52c349b47ac42896152b738cd2babd230633a30d005fbfdae4a62b168f55b7e3196121b14d54f326ad51849264aeaeef95ea4f4bfde96b31266df92200bfe12195f75aa85845eb390e4eec3ee3594370f9fde7f3864dac00fb5c967dd00f198994831bc346a4b558e0570302b653436f9ecba165dc1f2ac3137f0a0df68aa209353dbf8539a39a4f9d7ff289195b2df5c5e84cb8ff02bbe552c384009f1", "credential_finalization": "5f944d84bb4b92fa2a2ae5719eb7f3c486f4dc3c9622d8b23b8512383b2e9be96ecf3540c7a343a519a447ddd74bf651602dbaa54e6b41e44d24fbe00e4888d3", "client_registration_state": "4c590eff6854bda8024117051aa86c838b5d37bf408714a6004c671e7f72fb0370815fce02606dcb4a45ac1b3e312e201501d5cada02691953297e982e1f9b32", "client_login_state": "4c590eff6854bda8024117051aa86c838b5d37bf408714a6004c671e7f72fb0370815fce02606dcb4a45ac1b3e312e201501d5cada02691953297e982e1f9b32d49d84dcfdde7c09eecf7b6ddaab79c3269a9d2511ba72d01d363fae862b5a83306781008374dd7ae51f6ea634f742c5db39774daed51d781e1a2e155a8046668d4d5de82f0c234b84eb97934b87f2d43960fae1b6bd5d3d6944caf5154d6308d49d84dcfdde7c09eecf7b6ddaab79c3269a9d2511ba72d01d363fae862b5a83", "server_login_state": "30234f3b8cead1e011aa7dfeaae19b64913115daaa46f3cfd033c2a64fdd0a3959e62584463cf961b0471a6aff255eb0537edafef843dd59145ae1a96536b42476799bfed1b5332d0547740d550554fdf83b2fa13ef9850c8664a6932e7da165b629fb87a8993b3dca588a96199e5e5d5454e4597d60482390925ecece9f62fd87a6422c13f1ed7bc5b844ebb29f7b35a2230d9a4d798763d91feb7f2be228b6c46277fd8d9589066c3c656d7daf75c71ce257ff9c7b7c8d017cc5dc766858c1", "password_file": "66723c5c39695106d654570842a1edab79711a36ea4f34f65078b8c35731ea494d10c64e8239e9ed8a476faf6a4df44dd60a58fb0036ef65d5241541c7ca87aa050a7ea198c68d490d02f23419d0e002c7819805f8c9a6517a062d67a2de8b4df4a4b1f3c2c54257b91a0d87db527505428cbee4b6139e653160d44418f2110cedf21caa38e4cfbef0a7e5254082231d0b0dd056ff9014f2fa313e2107925dd8e69e45c126b8dae8c00567da34d09c8658aa7acab6e2fcb43359b263b4642773", "export_key": "f529f81953f783863c758dc677dc5673d39e3b17508c5ccff96a3bb8dc29b3d09966c6b8cb11afe53ac1784b3768d8789d47c85a300ec2431a4b48b63d0724fc", "session_key": "87a6422c13f1ed7bc5b844ebb29f7b35a2230d9a4d798763d91feb7f2be228b6c46277fd8d9589066c3c656d7daf75c71ce257ff9c7b7c8d017cc5dc766858c1" } "#; #[cfg(feature = "ristretto255")] static TEST_VECTOR_RISTRETTO255_P256: &str = r#" { "client_s_pk": "96860d1458e14e8724abc569401bcd1b6bcfeddf09742103d760a6014804cc73", "client_s_sk": "0daf879c98ee31788e0014af07cebe6ff594ea3c4f6e308abcc2bb878b8fa605", "client_e_pk": "5a049d36bf732157b108dbfc9230a9e67fea0020f16035856c10ca81d8930f07", "client_e_sk": "b1683ccba5ced8986407ca6f6047749a239418ebe1bde10c793db752e6980c06", "server_s_pk": "12396a13fddef61cf0134aa4c2a6aaf3d1be57cb13ea4f4b9838d71fc54ee80c", "server_s_sk": "0f383b8fc12a075e1625771cb0e5dbe415f11f5bf1782b890c72c079214db30d", "server_e_pk": "922dc5a69f7cad85dd41191458f4964176c47dd563d02bfd49c3023329b3ec6c", "server_e_sk": "02ea163c9f6e9178774981e0c1e85f15279bfedc3dda8e6d61d29a3a6cb7100c", "fake_sk": "85dd0108f49dfba87cc20ddbf26e50fa2f75617eadd79f981166918dd46d0b07", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "0c4bce66bf65a8546ef873df3753d1d7be8b03c7117e4db915db6c39e8e2ba3c", "oprf_seed": "189debd660e17b3e4bf4e867d341715e9106d1c8fe50f1c7494b844f84581520", "masking_nonce": "cf06408b0fb43754f84212958c57c9f1f80ee9c286f09f4a8abb0df17a34f5c7fb0678eb323d4c08bf48261066876c41e552f0fa0597bcf72723745084074c33", "envelope_nonce": "48485d8f1020b7a37c39b1d30b32a8e1627f090602bc6d252210feced34f5380", "client_nonce": "2299b1cbada1e9f1aab6ae243db020674b38e3c3d9d48c09a77e68cb5a3dbc89", "server_nonce": "e930041050fbfe8ee81dc9769d9b70ef4bc1aa214fcc816566a94c216dd25a1b", "context": "636f6e74657874", "registration_request": "03bd2e315c39a7f0262844c53d8474cf45ff0eb1702b583f190b902b80dd636211", "registration_response": "0295b6e042acf53567b5e0c33f6ef78867387f97be9cfa032d63dd59b0a3bbe69612396a13fddef61cf0134aa4c2a6aaf3d1be57cb13ea4f4b9838d71fc54ee80c", "registration_upload": "1cbf711b9e1dff7c2aaf72a2b6f1539575829b8810bfe226e24fbbefbcd2894dc919828b717bfe9b990b34447ae288e858d92188d447aeed5e567d22145b3d4c0daf879c98ee31788e0014af07cebe6ff594ea3c4f6e308abcc2bb878b8fa6052b8c9a902bbc1e1ebc7ddfe5bc8d8f0373643ebc8aa14068cfd59023c08a9c2b", "credential_request": "03bd2e315c39a7f0262844c53d8474cf45ff0eb1702b583f190b902b80dd6362112299b1cbada1e9f1aab6ae243db020674b38e3c3d9d48c09a77e68cb5a3dbc898e49984d760ede86d52699fa452d5297c4939007ce7aa197374e1048a6035d46", "credential_response": "0295b6e042acf53567b5e0c33f6ef78867387f97be9cfa032d63dd59b0a3bbe696cf06408b0fb43754f84212958c57c9f1f80ee9c286f09f4a8abb0df17a34f5c7537e2b0fddecff2140a12fff250cf71dc909d80397aef7ef4b127762dcfcc718c7023064997840e593afea87022470bdee8954a0640992403f8ec4a14b7c845d49010dae5bf99c6db15c34fb354c3c385c7dc45853ec9b1dcf9afab48281a8cb02ea163c9f6e9178774981e0c1e85f15279bfedc3dda8e6d61d29a3a6cb7100caa4daad8755b1ffb28695e317278215428bd4d1ecd969e62059a93fba1af40018caf3978ca1456277ec344116a4f189a32c91fd28c1d23cc7be0e80e10a57422", "credential_finalization": "4db5e4b91877f7bcee7d63b015793559fc788e7196b3c53f34b63ff8bf9bb91d", "client_registration_state": "0c4bce66bf65a8546ef873df3753d1d7be8b03c7117e4db915db6c39e8e2ba3c03bd2e315c39a7f0262844c53d8474cf45ff0eb1702b583f190b902b80dd636211", "client_login_state": "0c4bce66bf65a8546ef873df3753d1d7be8b03c7117e4db915db6c39e8e2ba3c03bd2e315c39a7f0262844c53d8474cf45ff0eb1702b583f190b902b80dd6362112299b1cbada1e9f1aab6ae243db020674b38e3c3d9d48c09a77e68cb5a3dbc898e49984d760ede86d52699fa452d5297c4939007ce7aa197374e1048a6035d46f62b5e93fa459dcdf3ee17e3e2447f0809e85f15b17e46d06f8894baa3c0e20a2299b1cbada1e9f1aab6ae243db020674b38e3c3d9d48c09a77e68cb5a3dbc89", "server_login_state": "3a31ecc4fdee405375e58df2e9f4fe25965859cb6173d7e6709fb24fd2698d53933d8bc443c8860da1d4096d8b2ea2a5c651d744a22da9b2c9f73ff0ad17fc0b5c0df6a11fedcc36dcd1173ab7e55f3f2627d399e464ec29671cee7566d6d912", "password_file": "1cbf711b9e1dff7c2aaf72a2b6f1539575829b8810bfe226e24fbbefbcd2894dc919828b717bfe9b990b34447ae288e858d92188d447aeed5e567d22145b3d4c0daf879c98ee31788e0014af07cebe6ff594ea3c4f6e308abcc2bb878b8fa6052b8c9a902bbc1e1ebc7ddfe5bc8d8f0373643ebc8aa14068cfd59023c08a9c2b", "export_key": "e785a045278a7fa931ef1f8910d0ba85dc3d6c7537dfe5a9f4bd7bfa317e1762", "session_key": "5c0df6a11fedcc36dcd1173ab7e55f3f2627d399e464ec29671cee7566d6d912" } "#; #[cfg(feature = "ristretto255")] static TEST_VECTOR_RISTRETTO255_P384: &str = r#" { "client_s_pk": "4e2c60441878e85783c9800406ebd5e7e881dff80616d03b567947b82e5c7a57", "client_s_sk": "dce2e0634b405f06caf29c1265fe223cb534535bb7c27cdf2e12f6291b39c00a", "client_e_pk": "5e49aef294f9dce3c6522d66805d864337dc0fadfe88fe2e0f037c32c105a82d", "client_e_sk": "dfb45d06440e1cbcdda340d9582de46237c44413f05b40339a6187115bfcc404", "server_s_pk": "543f5a039f83eacc40c62fc5c5acecfd4650873dce4d6dbceb04a327baf86f2f", "server_s_sk": "0c0d7c18c7ff0860f5d6648d5ebea2fec4a3cff45d436f3be5aa680608e7f605", "server_e_pk": "e063a148282a82945d5ea35b9bcbc4fdacc175f73bee2ba4d0f72e7b3aec1338", "server_e_sk": "a50f4953424642bcfc681fd4b6f8f9c71bd4a052bbc5f46047d22727da26af0b", "fake_sk": "4305d00aa1b28f5fa20a4c939c97ce51150b948f87307191d5febc66ea2ea606", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "ebb318997438ae2f5e3238f03b75b975c15574221dc5366b28fd9f3401230420fbdaea1919df12380f986f7c6dcaee4d", "oprf_seed": "f28b12958dfe452b0819cc0df743666cb27c9f7d5b07818de0c79b21bbc8a3987257a81a1c57c21bccebd2af0e6fbe94", "masking_nonce": "cbe822a5e60816a19d6b707308876147e4c0be5436e0658802c88d257f9523f873c3c248f599aa0854a047ff227676b2ef036e847aad26113df99cf494ada455", "envelope_nonce": "f5af3d4e880da0abaf85dfb4da5b7b23549c83c90bffbce20fc84d8a22014b00", "client_nonce": "97cb195111c2bd433a1d1cafed854d9039936ae9559942cc701dafcb9dd51524", "server_nonce": "4b15d916d5fb9bfc3e0a110dfcade484e4c98f6bebd9860f7b7956880a806efe", "context": "636f6e74657874", "registration_request": "0335ded8e0d44b32ef46a01d530365171b4a0656bc97362c731e5228c8d82cc66a7be5bbb4af2df2c69fab5946951bddba", "registration_response": "037afbd911baaeaf20b8f81a323b9394b0483b622b92a02d19c6956b229264f645b2c82d42207a43c14445c9b77d5812d1543f5a039f83eacc40c62fc5c5acecfd4650873dce4d6dbceb04a327baf86f2f", "registration_upload": "f0009445fd1d418db028788a28b21992786ad8b697a2a8baebe30547733f9143bdb7d21117484fed96d101d15e148c5a63623687e4844834c2d22a48913aaf0feeeb831dfb5ca91a91be5d2d7d46680fdce2e0634b405f06caf29c1265fe223cb534535bb7c27cdf2e12f6291b39c00a659cfc677db765aa62682b8095a1ab39dcd73ddbe49b668eb63f7bd5f4396f6e6b40ad646ebbb1af13b3589b73d69371", "credential_request": "0335ded8e0d44b32ef46a01d530365171b4a0656bc97362c731e5228c8d82cc66a7be5bbb4af2df2c69fab5946951bddba97cb195111c2bd433a1d1cafed854d9039936ae9559942cc701dafcb9dd51524962707435be9a80153f6e4ec9ebc2440163ba73c232a418c958e25e77aa85863", "credential_response": "037afbd911baaeaf20b8f81a323b9394b0483b622b92a02d19c6956b229264f645b2c82d42207a43c14445c9b77d5812d1cbe822a5e60816a19d6b707308876147e4c0be5436e0658802c88d257f9523f8020480a4ed9d375068b49232966147564a442f1dfe5cab652453c60a29d384863194bfb106012b50ca488869460200f16360b01a1337cfe3f03e118eb48bbba6ccd4c56eb181539277bc2b72f1dc15afabecd59885ca66fe42595382d085692bbd0278b83759deb8230883bf2c3181eea50f4953424642bcfc681fd4b6f8f9c71bd4a052bbc5f46047d22727da26af0b3405b452e6d6dabfe98ba19092987ebbfae106116b40a0f65dacbd709ac4f7756c3e6d1965246cca600fc88be6abd548299f728d756bc966b3021c2fb1a8c43a0b53a886a9594c93b3975536e59c71e1", "credential_finalization": "4adf8d88cfd65aeec5b01e53cb0c791fba6239a7140994105b2d43c30d1921e9f3510d03c6f097f1d170cb7ae665e7cf", "client_registration_state": "ebb318997438ae2f5e3238f03b75b975c15574221dc5366b28fd9f3401230420fbdaea1919df12380f986f7c6dcaee4d0335ded8e0d44b32ef46a01d530365171b4a0656bc97362c731e5228c8d82cc66a7be5bbb4af2df2c69fab5946951bddba", "client_login_state": "ebb318997438ae2f5e3238f03b75b975c15574221dc5366b28fd9f3401230420fbdaea1919df12380f986f7c6dcaee4d0335ded8e0d44b32ef46a01d530365171b4a0656bc97362c731e5228c8d82cc66a7be5bbb4af2df2c69fab5946951bddba97cb195111c2bd433a1d1cafed854d9039936ae9559942cc701dafcb9dd51524962707435be9a80153f6e4ec9ebc2440163ba73c232a418c958e25e77aa85863dea54ac07a062a89450b947cd563d9b3c7bbec1460212b78c21d509f45f1310997cb195111c2bd433a1d1cafed854d9039936ae9559942cc701dafcb9dd51524", "server_login_state": "ed32e9f19429767a8297ece379a7f2ca317543fa601f9d575577c4004a22240814814df482a466fb9456f2a8ea175f61d589b838e49246593d6fa7e2f41335961f0d890be0ff0f196d6c54b0ea909e9833cce7f57c20cdde215c23d0107bb32173700ee1021612393ecb5a619d95774b74ac82c7a2243ea01091aa34059bb6b93763af9e3270d17e15d31e2c36a22c1d", "password_file": "f0009445fd1d418db028788a28b21992786ad8b697a2a8baebe30547733f9143bdb7d21117484fed96d101d15e148c5a63623687e4844834c2d22a48913aaf0feeeb831dfb5ca91a91be5d2d7d46680fdce2e0634b405f06caf29c1265fe223cb534535bb7c27cdf2e12f6291b39c00a659cfc677db765aa62682b8095a1ab39dcd73ddbe49b668eb63f7bd5f4396f6e6b40ad646ebbb1af13b3589b73d69371", "export_key": "d610a300a933f98e70927f01cd97b7aead44e98b1405c40b42c15e25e20dc0ce237eca5cc623d2f7f185aa3db7846cf1", "session_key": "73700ee1021612393ecb5a619d95774b74ac82c7a2243ea01091aa34059bb6b93763af9e3270d17e15d31e2c36a22c1d" } "#; static TEST_VECTOR_P256: &str = r#" { "client_s_pk": "02c2e8f49855c9f783a851dcefbd8987ce90d8e85cf191c7aa475950c771a1a392", "client_s_sk": "5ae546ad6e00e6434492285305f0a087a2c0fd4c70d867c87e59aa18df7168d1", "client_e_pk": "039f4ec8755bb55f7b815f08fdda9da51a05edbc22025a3d4f5ff7b6ddcdecf847", "client_e_sk": "efaaaad9104f1eaf18014d70ac70a61073cb1cf471b02b89dc16f6a338c9aac5", "server_s_pk": "03923edfe871973dc0e549692526eeed3967fec567cd4ccba30ea3696614e5c9d6", "server_s_sk": "21cbcff4c92ceb1acade2eccf301c7defe655f55d7354d1326a1259de4f6afc9", "server_e_pk": "037ae15922e04a5e1d288494176932c8b4defae649eae82dd40876e9bc5afe7236", "server_e_sk": "6162bef0095725abad6b72a7e3e64599fc1b5df9064e7ce40766fb0ac7e7964e", "fake_sk": "da212727cf2f6f38c536014c883c22c35cb9efc4a27228563d364ab4d12ec5fa", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "9d781bd63f99a84b819c99c7ce497e6288f9122834048945997f2d76147efde4", "oprf_seed": "b09d533d8960cb471b05a36882927adbcbe7ef600ba74e1af31d1486230e8adf", "masking_nonce": "2590367466a06ccc880d11398181d1c302144c05e4ac5a0528ef3336fc26e4f13e45edf9d43d0d4e9c6ec08536895968111c4d23f6f9ecc6734999e7466ae9c5", "envelope_nonce": "aacb6bb400ab28256d2e54d9eca742857f6d5e29c92b7b0044c95215b6db4892", "client_nonce": "27e8fe90451e2934e8dc358fe30ba07d15175e2c70a6fda88b1bab732e80c140", "server_nonce": "fefe1c85ec03f03f8ab66d4037a661f677954cda1695765381fe56ee553275bf", "context": "636f6e74657874", "registration_request": "03493e2bda2f5ce79408178469ddb1424bd6880b796945caf97eca254091493c4f", "registration_response": "03f66c48699b84e856f2110cb770c46c59fd75831d5fe0a4b1c164a2b13272798503923edfe871973dc0e549692526eeed3967fec567cd4ccba30ea3696614e5c9d6", "registration_upload": "033975e189b8c31851993d7b38abf30c0fc666ab8fb93e5ad8581a035fbeb60283bf546c8d3d8f1759d16dd4db3653c45248c8420703beba195304e1f5600cded75ae546ad6e00e6434492285305f0a087a2c0fd4c70d867c87e59aa18df7168d107ed74db82d4ef8d7268bc2dbcb146681347aafd7ed9bb8e78399766d753688f", "credential_request": "03493e2bda2f5ce79408178469ddb1424bd6880b796945caf97eca254091493c4f27e8fe90451e2934e8dc358fe30ba07d15175e2c70a6fda88b1bab732e80c140026a65dd93748b6d545fe24839cdcba11db412e3649d704e88a0a24b3600671a77", "credential_response": "03f66c48699b84e856f2110cb770c46c59fd75831d5fe0a4b1c164a2b1327279852590367466a06ccc880d11398181d1c302144c05e4ac5a0528ef3336fc26e4f1fc2abe70c70551c2922019c4e8aa092a32492dd50e0be8aaa44913d2c7253c8255ffec37fd5612b651b7ac26e5f2aeebb0caeddae68e8dd49aa0ee522dce90900da3537d718ae15954a5b5c2678d6efa31c846f6bd46605b56fdf70a448c3143c46162bef0095725abad6b72a7e3e64599fc1b5df9064e7ce40766fb0ac7e7964e03f609f0b7575cf87465a11900d2ac4e91f8097f34c5668b974e55af50ae1ddf4895d3f8760cfd8699c9bf6ea54fdaaa7af049e2ec205505ab33fad7c0ce680c14", "credential_finalization": "e6aa42333906d3294b5f6f153c746974bfbb3f9d6eee94fabff2757994ae0828", "client_registration_state": "9d781bd63f99a84b819c99c7ce497e6288f9122834048945997f2d76147efde403493e2bda2f5ce79408178469ddb1424bd6880b796945caf97eca254091493c4f", "client_login_state": "9d781bd63f99a84b819c99c7ce497e6288f9122834048945997f2d76147efde403493e2bda2f5ce79408178469ddb1424bd6880b796945caf97eca254091493c4f27e8fe90451e2934e8dc358fe30ba07d15175e2c70a6fda88b1bab732e80c140026a65dd93748b6d545fe24839cdcba11db412e3649d704e88a0a24b3600671a77d406726833e0a9451751dbb50af5764e45187906840cdfe814282d5aa0efa95527e8fe90451e2934e8dc358fe30ba07d15175e2c70a6fda88b1bab732e80c140", "server_login_state": "dab1a874a0f1db74fa0c9526e6b55b2c4843f26d181b410278b76f1a5a65b0b960e1c6fa8b17cca50f4dc45d53a7f5ef975e31406b31418b87d2d9cab0991e2326ca86363e475842c54ce152c8075b5d633ce3d44f3123bccfbb9a444833f6ed", "password_file": "033975e189b8c31851993d7b38abf30c0fc666ab8fb93e5ad8581a035fbeb60283bf546c8d3d8f1759d16dd4db3653c45248c8420703beba195304e1f5600cded75ae546ad6e00e6434492285305f0a087a2c0fd4c70d867c87e59aa18df7168d107ed74db82d4ef8d7268bc2dbcb146681347aafd7ed9bb8e78399766d753688f", "export_key": "5b8816c59a360431bf7afe5d93644136617c2d25bd67673785cc593cc40b1e35", "session_key": "26ca86363e475842c54ce152c8075b5d633ce3d44f3123bccfbb9a444833f6ed" } "#; static TEST_VECTOR_P256_P384: &str = r#" { "client_s_pk": "0300ffa27e9e1c07e726f3446303fd6e169a824e938be7142c5d57c966c41f48cd", "client_s_sk": "63bcffa26f32783271d78d3b84dbdefda3a4533bc11d7ce73de145c6a80ea659", "client_e_pk": "03f46e7129db840987843f76ec3c1521c7c753740bcb22f00b37b2cf52a9dc5974", "client_e_sk": "502bd0e6474522e6c0572f81e4d7ba6cb87430aa34bad5eb7509d0dd5f2aa01e", "server_s_pk": "02ec3bb6cdaa17e7e0872a57e2c89e2647983bced0b86ffd0d7fcdfa304f90e03f", "server_s_sk": "47965063ae881466b08ba9e96cf1fc48d6bfb7e23d0a6bac30498b114dfc5a54", "server_e_pk": "0304fc747fa5640c258d4846be2f6529ad35d61782f3e45a48efd6d6dbd1cedf07", "server_e_sk": "1bdbabc050b6f5d59d01b02a03d187b0954c8a9341b696cb60c49a8511ab9712", "fake_sk": "cf19797c598f15e3cddc5e01388999e85ca49ef729dc2e8ac10d8f10ff59d2c7", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "ef8bb36f1ad0921181910a8a1a497e18c1192264c5389f4e2cdc270d322e0a0c9b74284ee2af3d476cc7893fe7597d01", "oprf_seed": "1f9b1338fb64584fdd2ef104c15a15a75cd9b922dedcdc4037409c4dd69c5aee2ecada1652d380f3335352baf92974c0", "masking_nonce": "889e0b260347814b97b922fca5c96f89e3974776f2d6486399d17f7634d90d3a7fe5cecf435269a054b3b24d968c20c586ead3fe3b529b7a129f2cd75bb11645", "envelope_nonce": "df7b5518d79f0c5748cbe6ba671786680e895ab470e8a8399018ab4a245e308d", "client_nonce": "ed8e76fe71017d89879ec9580cbee48e1dff47f05d52e4e7655ea65a813897a5", "server_nonce": "92fd03780d2b4035ebe83915fe37fa650477ac7d20a8d83b553d43a569beb584", "context": "636f6e74657874", "registration_request": "03f98a111741a24c1ad90f15985ac345636e631cddde1d05dd8d7f5fc00e57483c5504f390e8bda613345aa89d3493bed0", "registration_response": "029daa00653cd0b4f9ac0b9e5640e6c6b608543e02955a40de853bcc530f3180bdd52991e528e570e650a6c50d6ed06b5602ec3bb6cdaa17e7e0872a57e2c89e2647983bced0b86ffd0d7fcdfa304f90e03f", "registration_upload": "020b1901303ffe1ea63379d6e310d39712521ca43609a8bcfa4db28866411355862282ab14133a5a1c095c9af7b4ffc61aa5371b3ed762a24f94448e6ca0bb87b7c0ce558dce762c73aeb6ba1f4b56681363bcffa26f32783271d78d3b84dbdefda3a4533bc11d7ce73de145c6a80ea659033f437455f7be8b3ed47fd871057beb6e30785364bb586c074c0c4b475d17129383f531042647448933a17914cc2b61", "credential_request": "03f98a111741a24c1ad90f15985ac345636e631cddde1d05dd8d7f5fc00e57483c5504f390e8bda613345aa89d3493bed0ed8e76fe71017d89879ec9580cbee48e1dff47f05d52e4e7655ea65a813897a5027204ea166787e2d7766ae8101143be5283f79ba8107b33f8db03339d72970597", "credential_response": "029daa00653cd0b4f9ac0b9e5640e6c6b608543e02955a40de853bcc530f3180bdd52991e528e570e650a6c50d6ed06b56889e0b260347814b97b922fca5c96f89e3974776f2d6486399d17f7634d90d3a68490a295fd49a787786c1db2bb1e31e38b56e8151e958f8770041746fb5496696be499beb470f04a2ea7074502918277c024cd785b534de8ced805918a2a0bce17eded3cf11e6fc2e54d67d641632fe1d2fb56bf641540c34a023d32913fa9eddfad0aadd9fddfbe1c9af4a96da04887b1bdbabc050b6f5d59d01b02a03d187b0954c8a9341b696cb60c49a8511ab971202d56b40e364d4947215d3befb46b114cedd8ae3f75f9d38767a7cc87315e3473d94ca79a51b45a5bdc935be80d9bf697d384ded48d5d5b9bdb85432e3d85ee5aba8729d55ec530313d28ca3208090ce11", "credential_finalization": "6ab06573cb9bb92a5e4ae2c6623bffc5463f94b81c2d38c1416e4dce35c32e49d2225ac5957a9913e1badcab819f35af", "client_registration_state": "ef8bb36f1ad0921181910a8a1a497e18c1192264c5389f4e2cdc270d322e0a0c9b74284ee2af3d476cc7893fe7597d0103f98a111741a24c1ad90f15985ac345636e631cddde1d05dd8d7f5fc00e57483c5504f390e8bda613345aa89d3493bed0", "client_login_state": "ef8bb36f1ad0921181910a8a1a497e18c1192264c5389f4e2cdc270d322e0a0c9b74284ee2af3d476cc7893fe7597d0103f98a111741a24c1ad90f15985ac345636e631cddde1d05dd8d7f5fc00e57483c5504f390e8bda613345aa89d3493bed0ed8e76fe71017d89879ec9580cbee48e1dff47f05d52e4e7655ea65a813897a5027204ea166787e2d7766ae8101143be5283f79ba8107b33f8db03339d72970597de1f1c0591eaeacea4eaddf441e4f78007347895f79775d836aeef03269ef260ed8e76fe71017d89879ec9580cbee48e1dff47f05d52e4e7655ea65a813897a5", "server_login_state": "4af2c9dc93a9681293550723eccabed75aec6fc72b688bca2c68d8bdd8fe21c66b94753b04b4f9b9d1dfb3661397ca712f8990baea7679888d3045640cf0f17c98a6704146f5e4f6cfa2c764532fa1bfe78bfdbda526213af50d2c6b8dbd83eeb78c21b07ad43485cacaa2bb6743962ea4d450fab27f9d3848b4d4f5a50ecea2ce3fcf3007867d8e708182d76f97ba2a", "password_file": "020b1901303ffe1ea63379d6e310d39712521ca43609a8bcfa4db28866411355862282ab14133a5a1c095c9af7b4ffc61aa5371b3ed762a24f94448e6ca0bb87b7c0ce558dce762c73aeb6ba1f4b56681363bcffa26f32783271d78d3b84dbdefda3a4533bc11d7ce73de145c6a80ea659033f437455f7be8b3ed47fd871057beb6e30785364bb586c074c0c4b475d17129383f531042647448933a17914cc2b61", "export_key": "f79bdebcf6534e9fbb727a295edb160e952a8bda27b0e1d3f2379ece6bde6fc5d0d4486e2a37ef41d2fd1d0fe1719fc9", "session_key": "b78c21b07ad43485cacaa2bb6743962ea4d450fab27f9d3848b4d4f5a50ecea2ce3fcf3007867d8e708182d76f97ba2a" } "#; #[cfg(feature = "ristretto255")] static TEST_VECTOR_P256_RISTRETTO255: &str = r#" { "client_s_pk": "026a80b08688346c0a5d884119239af863b0729ef14bf8b86b285b5751b6e2b067", "client_s_sk": "8ea03094d56fdfd7937b9a4b8b89e2b09f8a2a493d6409d39dfec1f4612a4fdf", "client_e_pk": "0326c437e32e7a5604807b24f92385cd732e6b70f70793fd59022d9470e6579622", "client_e_sk": "4fe1d7f5159e429d35bb4d3c66ca20f50b133893f1e1712e89d9edd34c044612", "server_s_pk": "02267105ddf0f2a9531a0875ab315f1c831766134af1b7e4ad9c4f298ce0536eea", "server_s_sk": "8871c04d141df9881e3ef15210660112c164cc32867f3ec0bd67d68cbbd87424", "server_e_pk": "03315305fc11f61944bc790a112f01e1020df7a830479618e7a42dd2204d30075b", "server_e_sk": "225599a7b01f047bee6fba835c86f271410b786b3933cd7542abc8c58afb10f8", "fake_sk": "61ea20ed0bde67756fe11072c5a8aa3103085a293d60bcbb0b5c5e09920d07d8", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "269627e7fb86bc28052c4538cd8a4a8cf30ed530196e0e2d99a8382a78c21f00", "oprf_seed": "3abaf808e5435b5fb9929d98dc3060827fe627bbaefdaeb9205b9cdf2037a625ce8a687ab3f85c0a70629f94c1f23212f8d67b3dd0fc422c5f65a600350267b2", "masking_nonce": "093ba9502b07a9a838f28bd2bfb9699315549db299ef6196fa32233acdfaabf9b97a0dd265db7ff52ca1b1f3fadedfa9dca26751b166972e6ab6569ff08ff5b5", "envelope_nonce": "d7e0137e8adf2de3b00cd9e0c888f36ecba2ee18f92e51b7298fbaa654d286ba", "client_nonce": "1186e18b135739cd36cde4a2dd72ce5d1c4a92a96da279ead6f54813f84d9d86", "server_nonce": "9589f0bbec5cc2c68b98684158b8ef40f81f7f0fb8b2197e90d8e3666cfd1682", "context": "636f6e74657874", "registration_request": "f28816d64e1d4f17a0f36830ed92349d29de1e0444f21147a23d1952a4355573", "registration_response": "7c734fdd7907d3aeef3fd17a8bb1d08642ab04f36c1eca4d8e6b10147c8a505f02267105ddf0f2a9531a0875ab315f1c831766134af1b7e4ad9c4f298ce0536eea", "registration_upload": "03ce990fb3f9331bccd12eeadcf92f938dcf3acb07ec660c2936f8adc34554d7c7ecb4d45aa36908729dc4ca3e7c6e0a4a605fef0e7aa9c84de814e304a27dae2b8738f10785f2a1005d906a37f12b259b83a9f8406b6d6783180ba471e27393858ea03094d56fdfd7937b9a4b8b89e2b09f8a2a493d6409d39dfec1f4612a4fdfaa6224b035117cd28adba5aeba7c4733b66b44fa47052f2f50fd68b02360a769157fbd7e00af377f755d2ae0d1f6042eeb8e45c0c870eb7a985c8cd867aad53e", "credential_request": "f28816d64e1d4f17a0f36830ed92349d29de1e0444f21147a23d1952a43555731186e18b135739cd36cde4a2dd72ce5d1c4a92a96da279ead6f54813f84d9d8603eb66e9a64dd24d6aa1a89dc0002e3e12f01b3dc6d9005bd72a03ef934377f23b", "credential_response": "7c734fdd7907d3aeef3fd17a8bb1d08642ab04f36c1eca4d8e6b10147c8a505f093ba9502b07a9a838f28bd2bfb9699315549db299ef6196fa32233acdfaabf92bdd08e08a4ac46f690d1dc4ad05eb4323770753adbf0c354f7fe215200c3091b4342949f456fb3d0e2d6a59ce9da891930dde787b9b6943446bebf9b029a82e878e2ca9412df818403c9a8b817985f9697219d1319bd90b57793a64472995b72b0f15551d35c1f90db203b8dbfc3448fe35982b350349255b4d1a8bc100d0f280225599a7b01f047bee6fba835c86f271410b786b3933cd7542abc8c58afb10f8027a0c4c39a84d38b39f2b54c62c20b312fd37090e841337483b27047c143b94a1d57a81fed7757d80845053b83cb02890e60ec0f48d241965f752dbc826b88753d2d256b76e8c181f48d7c24351da7b2bad1c41790c20776db86c654bf48cb9ae", "credential_finalization": "643a6547dc003d7caa81adadfb74be774853e0a422bf58fc61e5918a3dff35e9854b4150c73ddea93283deb6aa4216437fad406fdea480ec229fcdae3c83d6da", "client_registration_state": "269627e7fb86bc28052c4538cd8a4a8cf30ed530196e0e2d99a8382a78c21f00f28816d64e1d4f17a0f36830ed92349d29de1e0444f21147a23d1952a4355573", "client_login_state": "269627e7fb86bc28052c4538cd8a4a8cf30ed530196e0e2d99a8382a78c21f00f28816d64e1d4f17a0f36830ed92349d29de1e0444f21147a23d1952a43555731186e18b135739cd36cde4a2dd72ce5d1c4a92a96da279ead6f54813f84d9d8603eb66e9a64dd24d6aa1a89dc0002e3e12f01b3dc6d9005bd72a03ef934377f23bd8fabb81cc58414997e3c76aba160146183de4cc966657e5b1def258df81ff6b1186e18b135739cd36cde4a2dd72ce5d1c4a92a96da279ead6f54813f84d9d86", "server_login_state": "13bab355577815ab29a0571bc571f6911d88f92cc64d6e930872674364b7400cacb5cab973263ca4da8687f36f894c06fb8939e96a7c6d1d4bed17dc1e00a12878b01cb72645993a5186b124808b8604a24b63aa3d934424dc78f9e56d02b506941b0af906d06edec7ab2eed07847fa424b5881e71282aa306d223902b37c354ed6f8a57a79a4433771a1b3aec9ab490df027ac3383a42cf7d09bed5c35e1dd1e092354e18d809935e1c19929906398286669f2603153de7026674823149fed0", "password_file": "03ce990fb3f9331bccd12eeadcf92f938dcf3acb07ec660c2936f8adc34554d7c7ecb4d45aa36908729dc4ca3e7c6e0a4a605fef0e7aa9c84de814e304a27dae2b8738f10785f2a1005d906a37f12b259b83a9f8406b6d6783180ba471e27393858ea03094d56fdfd7937b9a4b8b89e2b09f8a2a493d6409d39dfec1f4612a4fdfaa6224b035117cd28adba5aeba7c4733b66b44fa47052f2f50fd68b02360a769157fbd7e00af377f755d2ae0d1f6042eeb8e45c0c870eb7a985c8cd867aad53e", "export_key": "2fe20c906ff2656ba5c9c4bb313788f88395ef86281e4448462d5b1f5438d4afc91d2ccf9b8f340c0434db96a1996bc90cfa8a378c349c18e4291e793277e31f", "session_key": "ed6f8a57a79a4433771a1b3aec9ab490df027ac3383a42cf7d09bed5c35e1dd1e092354e18d809935e1c19929906398286669f2603153de7026674823149fed0" } "#; static TEST_VECTOR_P384: &str = r#" { "client_s_pk": "027ad019b16564c074d6f2ae68bdf20a738d7d2e9839a0abfa438a760d0c06c16048fcb8fd4f1dd115a7dfc3fea5f09b58", "client_s_sk": "834a110fe6c0e7b6cea98c3bc534a928d6a842116774a1e01b513584405cd2e31970f765d7bf0db0ade9bf27fcd9cd0c", "client_e_pk": "036a8b6a879e4b771b980f60263761fe7fe8ea7caf25f72093e4e7becaaea14a11a6acdc9ff156f0f9663623e17738a541", "client_e_sk": "44760cfc351b43df634d788300fe8a21d3a1045654421a0c7db0e4def8a4f95f78900b61e9ceeff021f381270cdb5418", "server_s_pk": "02f66681149226426db92504e9c0604e8f9fdbfc5f36f399e77d2a9b1383a00d693a04e3549bf909acbbd700162cefbca9", "server_s_sk": "5dc037810ae1265de50fe0262b18f9f494866dfd9e8b10d7cd9126e513de0f3248510c8af60e8e61d875eb702610a010", "server_e_pk": "0345d90f8c96cdec81eaaeb147250f54e25824b5fa9df6a333fa932cc73e3768228f3ba8b81a1480c1c8cd705775ea9761", "server_e_sk": "c82bf9be4884f55e97240bb1fddf2c21cb9d44ea208a6448dcd0dfa25b4500b60990c58e8de1041a10068c8b1390353c", "fake_sk": "c75ce826bfcfaa3328fbf6ca2060c5f80313048082da3bbe9b81654c4f6bdf87374e15ad49594315e973e0cd289c6bf9", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "bc8fd9384462ca535b97649453851e7d053165c1d813f88f168e91deadbd58ff2f1ce08628948d75db1ae9ddca1d5b97", "oprf_seed": "b06de4f6d4a0dd8efe8afb46f51d197a3e098d0af21b52b4a5117d4980ca8fcd90c629400a43476271e89291d6618096", "masking_nonce": "5469703e134b2b70a9ad0aad851cdd22038fce9291147198b87d5731ec1ab5000ebf49eacbb3b90e6ea84bc1ec0032b233b9edf505289298db7ef65720e1f2aa", "envelope_nonce": "f4320d83faae12c799f3ceca6a84c4aabc9bc1896b11b217087a9b820c6ff075", "client_nonce": "4edb4057671642bb7630028923812954abdd34f57bf6f62ad4f24568680bc0be", "server_nonce": "aa49c4593ad1ff89776852ab9f555a68eba4b5d86c7ec7f39577cdb04684e24f", "context": "636f6e74657874", "registration_request": "0305632a043103148c0c50187844d031dc33aa81ab6b9d13919469b317703774ee3eea7c7b4b63445fb446ce2c4bde9173", "registration_response": "03f878aaf28a28fbce8805a11b0feccf82233c46a75f7c8513c47a23bba92bced8f95d97c795c70a7755ac3c5b290a14a302f66681149226426db92504e9c0604e8f9fdbfc5f36f399e77d2a9b1383a00d693a04e3549bf909acbbd700162cefbca9", "registration_upload": "03499599951aa81858e10fd6394610cdceee52195ca2f5eab241fb8a30d24f4f6ce3f33839c025bf5ebbc056d489e55797cab6175299333799ad308b718815a97d3326c82311f380dbc3d3f3bbb1c9922fa75b4eb2125fa386b75b610a07c2f639834a110fe6c0e7b6cea98c3bc534a928d6a842116774a1e01b513584405cd2e360093806a0701ac9820c29ac81ab66b91d12243b036b20309c2dab1a473869c03efadc490a20af8f3e5dec0f5643a621", "credential_request": "0305632a043103148c0c50187844d031dc33aa81ab6b9d13919469b317703774ee3eea7c7b4b63445fb446ce2c4bde91734edb4057671642bb7630028923812954abdd34f57bf6f62ad4f24568680bc0be025cbaa73207a363589d904f9ccc29197ddad82e32580db1e4fcc26eaee9e202cb40e8b0a08b5d1f1240e835f9da08d0e2", "credential_response": "03f878aaf28a28fbce8805a11b0feccf82233c46a75f7c8513c47a23bba92bced8f95d97c795c70a7755ac3c5b290a14a35469703e134b2b70a9ad0aad851cdd22038fce9291147198b87d5731ec1ab5003eff2203d3b86ee028fe1889fd24b6459a3ed00fda3cf90bfbb9508ce62367a185609ec407a7765a2cdfb9d4558c984bc3c235451a584c133ca70c57ef5573f3dcf29dfdce332106e53d4778331e8dcf4f807f3f13c41748fd251c5af002f64efc48cfbd7243d78ab451b9c9cc0dad4fca77583abe51538f2f42cb198cb698b7fccb9d44ea208a6448dcd0dfa25b4500b60990c58e8de1041a10068c8b1390353c021e31dcaffe65a256f1b32c8e91fda21d475a4b4fe06c961a6e23a7aca49214846a5d999db011e5de464859ee8d023cf96d3c35ef24a969602bc8b9346dc55a5a4fcb14aa9f42932986885a79317945d277e9601dc4ccdb5fee028f17fb33f14e", "credential_finalization": "4d9dd316ad4c575ef6c6a26f90e72f26672d8740e03c9d8808c95449f3279ec8709c5d2f1fc1cf14270d3919ee952e86", "client_registration_state": "bc8fd9384462ca535b97649453851e7d053165c1d813f88f168e91deadbd58ff2f1ce08628948d75db1ae9ddca1d5b970305632a043103148c0c50187844d031dc33aa81ab6b9d13919469b317703774ee3eea7c7b4b63445fb446ce2c4bde9173", "client_login_state": "bc8fd9384462ca535b97649453851e7d053165c1d813f88f168e91deadbd58ff2f1ce08628948d75db1ae9ddca1d5b970305632a043103148c0c50187844d031dc33aa81ab6b9d13919469b317703774ee3eea7c7b4b63445fb446ce2c4bde91734edb4057671642bb7630028923812954abdd34f57bf6f62ad4f24568680bc0be025cbaa73207a363589d904f9ccc29197ddad82e32580db1e4fcc26eaee9e202cb40e8b0a08b5d1f1240e835f9da08d0e2e546cb8ed99c8d3ad4c1f32c4cf19ce4da1e2a13700df0a0a1eed43f251261f6e7edb92cb124f652241186604c5f1cdb4edb4057671642bb7630028923812954abdd34f57bf6f62ad4f24568680bc0be", "server_login_state": "2e33ed0981c481b9141212ab38ca6e8ed1cbc132f8b96c70c2268b6b10aca88c38411cae2cf819b786922785bb2b7019e20c7da8c330d03e251b1fb4555995389964ad78cda9a6ea30c9b0e5b3733656c40cdf92f31ad08331baddf5c98a4ff6641618b739a79bd6a29f917505c30ca462b3d43b762fd7cfc8181fe439055f4f151e5ea1796bcc0f146305e9712c6376", "password_file": "03499599951aa81858e10fd6394610cdceee52195ca2f5eab241fb8a30d24f4f6ce3f33839c025bf5ebbc056d489e55797cab6175299333799ad308b718815a97d3326c82311f380dbc3d3f3bbb1c9922fa75b4eb2125fa386b75b610a07c2f639834a110fe6c0e7b6cea98c3bc534a928d6a842116774a1e01b513584405cd2e360093806a0701ac9820c29ac81ab66b91d12243b036b20309c2dab1a473869c03efadc490a20af8f3e5dec0f5643a621", "export_key": "4e00ea96339443ec9427a94d5ffc38faf7abfe49bc45f33a2b8893ca05266eb7c3d9dda533244384656e3595e589d4d0", "session_key": "641618b739a79bd6a29f917505c30ca462b3d43b762fd7cfc8181fe439055f4f151e5ea1796bcc0f146305e9712c6376" } "#; static TEST_VECTOR_P384_P256: &str = r#" { "client_s_pk": "03aa7fcc3a2b13ed9080a84f4c73ef1e8431cb0f981911d8e9b1bbf6d1b13a97c6b4230bfeb638d960f2deea221c699e80", "client_s_sk": "e465935788fc3d6f16cdef00c912f9e032a6aa4d9452c86cbbf2549217f390b0a81faffdca2b752ec7bfdee0dbcda7a5", "client_e_pk": "020c105b40758cf0d0c596644d387eaf598dc215652fb8c7ae3f9cab07b72ca87feb3385ede83ca6792df13959ca866650", "client_e_sk": "a5c0e6f2080c4952fefdb7e50753942e8f46ed5dcd16925d976a6919d601721e7d2bd75f89b07e4a48cb7e9a5afdd450", "server_s_pk": "0295c88cdbfefcacbab08754dd36b58abc72026e761a6e0337b4feee1392dd4dd0f2ac6817bb1e12df2c6020a790343695", "server_s_sk": "82aaee1871a785361798e2b78179a333ae3c4da7fb8d537534e244f889c2bbc51f92c4505b24bef69dbb5028cf87653e", "server_e_pk": "03363da7ae2f5ebf0ae9e3d98fe6c7ecc41fec55afa834959e71a61d848d850cf50f2636c877f78e8a7a3d525408dd79ef", "server_e_sk": "a271eb33e9b9ec5f8bc797a66596bf477cbf8d4b7fbe69b18509dfe633f4159cbd3a5e92d3bd0fd2de81a7d9bb6499f5", "fake_sk": "90574e2a941462615a8958064f02cfd2070ee0c2f12761eb77e70d6b5f5eb8417843b6812c89b6841ff7bdbbd2db33cc", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "48408a664deda29200696fdb750224da0210d17f45a0b59de34162e63b57b994", "oprf_seed": "94b2ded5dc7b7bf787234c8deaa2107d2522b51125d2e58b331e36b6329ad4c1", "masking_nonce": "2b7d2d7e3e856bb56a1b52b0e2caf2b166b72f3542dd96913979eec031ffe9dacce0484db3069adde7e122d145a993c31bb0f6f663c178e1f95fafc7a0be8a58", "envelope_nonce": "e2476436fb2d0a4fbb17821008da5e16650a8fa03f68138b733a5d200e6c2983", "client_nonce": "3bd63f9517a75441ea79144e4f6b050b815cb05211737902a074ae83c6aeb2f8", "server_nonce": "cbbb2b55ef928799ec4007730505e0cf2189d5e60c5d914948d32e4a02ca4488", "context": "636f6e74657874", "registration_request": "0350999de8c8a3dfb259b5ce85966712c2989449758ac6ac14076c93c8abf3e656", "registration_response": "03138b9a92582ac291858e1954b2dff11098c89fae57c2ff137400ba95b901a39a0295c88cdbfefcacbab08754dd36b58abc72026e761a6e0337b4feee1392dd4dd0f2ac6817bb1e12df2c6020a790343695", "registration_upload": "03808b6fa408dc690f92e06196131aad15dff9164e10e11991d1cdcc763f979cfb4577cf766164fa6ffc75a67b13ac2a910b878ac6b600b274baa71d8eb97323ccf45443577c62faf1222bf0fe017d983ae465935788fc3d6f16cdef00c912f9e032a6aa4d9452c86cbbf2549217f390b0d55fc01d6e91ea395a9233165418b5584f38f31175083cccfae69578e85758b1", "credential_request": "0350999de8c8a3dfb259b5ce85966712c2989449758ac6ac14076c93c8abf3e6563bd63f9517a75441ea79144e4f6b050b815cb05211737902a074ae83c6aeb2f802386993c958a9a14fc3a788d73f89fc932930a077c86d3222d9c40f07e3f0795d9f5c7191118978242bb722f72a082ac7", "credential_response": "03138b9a92582ac291858e1954b2dff11098c89fae57c2ff137400ba95b901a39a2b7d2d7e3e856bb56a1b52b0e2caf2b166b72f3542dd96913979eec031ffe9da93db2760bead8c6834ed76bade81fe8cb849f92f957991ff9f41d1ecb7fa4eeb82acab5ba32fdbeff970a50986e16c069a230989b18a6d2488f096a52949a6e4c824f25e803253cd8498991c3707cb1ee9edc14c5b4b8b4d2e03b4059c075a785bcba61873a9d3994029e98580a55437d67cbf8d4b7fbe69b18509dfe633f4159cbd3a5e92d3bd0fd2de81a7d9bb6499f5039cf64cf96647d66faf21348683a4d80ee69fcbd8cb6545dc8a13aa52e226c77389c0f1a7bb2396bee9a6807ec566835041259eb94980ac4c5634dde99c9d0f5124e2653102170a34626f32907745e5c3", "credential_finalization": "4fe1618a77247445239c7733cb0d25380fc728d86f5785fd08bbe13419fd94f5", "client_registration_state": "48408a664deda29200696fdb750224da0210d17f45a0b59de34162e63b57b9940350999de8c8a3dfb259b5ce85966712c2989449758ac6ac14076c93c8abf3e656", "client_login_state": "48408a664deda29200696fdb750224da0210d17f45a0b59de34162e63b57b9940350999de8c8a3dfb259b5ce85966712c2989449758ac6ac14076c93c8abf3e6563bd63f9517a75441ea79144e4f6b050b815cb05211737902a074ae83c6aeb2f802386993c958a9a14fc3a788d73f89fc932930a077c86d3222d9c40f07e3f0795d9f5c7191118978242bb722f72a082ac76bcd42cbe5150c7632326bf7b038ac8fd5cb09530c144cdfe798847035a7f14c82849c114e13883295de509a7a9a15d73bd63f9517a75441ea79144e4f6b050b815cb05211737902a074ae83c6aeb2f8", "server_login_state": "882a3c1a309a19a32907ed72540b465f308380cb9adcb3e1d906d6e0c255f91de5ff8b87edbe0af9daa50908efb34a9a8da444ced5f1b0e2bfce8ffd4947e1e64d169ed4727febf302256f84ee462e2219c5217236da8749c8e3aec996eedf2e", "password_file": "03808b6fa408dc690f92e06196131aad15dff9164e10e11991d1cdcc763f979cfb4577cf766164fa6ffc75a67b13ac2a910b878ac6b600b274baa71d8eb97323ccf45443577c62faf1222bf0fe017d983ae465935788fc3d6f16cdef00c912f9e032a6aa4d9452c86cbbf2549217f390b0d55fc01d6e91ea395a9233165418b5584f38f31175083cccfae69578e85758b1", "export_key": "7c242005347a90ed8a263e0963f554d1c0fc2d0df3b3bdb4a818e94569da2cfa", "session_key": "4d169ed4727febf302256f84ee462e2219c5217236da8749c8e3aec996eedf2e" } "#; #[cfg(feature = "ristretto255")] static TEST_VECTOR_P384_RISTRETTO255: &str = r#" { "client_s_pk": "02c1d4d7d66aeb737564a1b854dd415b93cdc77c09652783d62947bac97d501bbb6a9fae15244f06b38f0f1c82a5585e5a", "client_s_sk": "a0563c18fa5e065414411f2b7a05a42ccafffe6c3f820a453fdc5ec4bcbf75164646c3dda5ad48424c33342cd7e7e4df", "client_e_pk": "02cfab78104a87ec00bbb5a59b9da3a2e8007ccf2b280129594f61f38702bdb9431f770201bda3cab38a583e907b686c16", "client_e_sk": "5254f4ded1c5274d284bd01dd1eed07ec23ae9748857606282c6170d5a722058763367284abe9caf9389d942a523db5b", "server_s_pk": "038b01c3863136ab24e59be966b61516c622bb2cbe4d615d598b692aec4584ccf03617949fa2eb768890b50f91316997f0", "server_s_sk": "6dd0f63b233b2bd25288bce7b7c4128e595d7e7ae14a502151f17496d821b976f2ffc636ad02dab23786054c943a5248", "server_e_pk": "0243dc3cd7669109cbe9dcd71c10c0df3c571603c90cb8f836471851c8c4e59b2b33df99a83e5f82b9997509b0937c5af7", "server_e_sk": "0c6514cb587895583f71bea545cd793eb5c6c3a7b47af02bf7eec36995013ff5e62d020aebaa8584cd0c09db2a57c394", "fake_sk": "bd88b0857965e266c8b9c070af374335ceed0a2588081b338128985d8e6d9ac5cf7dd28a4eab2ed92a8d1c5e40586667", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "945e750cc030ea56fb69fd959b1c869bbbd11598a55cca1c344680bb3af39e0c", "oprf_seed": "6ede60508d189654155ebdf35e3e1f9ffac1b0a3a7c3af5623a16f0db771341826aed1298ce0a2c9458d810d0db29fb91d2220c58e5a4866ce8d26449d2ca5dd", "masking_nonce": "581e546cc899d1aefb99c2b7444b66702b7e810f863303b3ae542cacee4e5fabf1b048c70e198d7f4ff92d9ef651e462ae64813d2a61dfb76834ab41ada048d4", "envelope_nonce": "c1711624ac043ceaefff11d3e7cd8d0968ce5cd737edccffdf981b6e550eda63", "client_nonce": "c45770702f6a169965cdc6bde6bd684ae0cca88beff84a10a10531c44881a251", "server_nonce": "e22873960b1dce985b72c7aceca1211b0d62901a12ec24d5836bee01d0fa3069", "context": "636f6e74657874", "registration_request": "38f651deae743ceb93947f3b29c0b6a8bdca06cd2ddbf8bf4034f188eb21a341", "registration_response": "9a35389a31de25ffdb70f4c76630c55089acf2b4f4de9543f59ece5ebe3a4626038b01c3863136ab24e59be966b61516c622bb2cbe4d615d598b692aec4584ccf03617949fa2eb768890b50f91316997f0", "registration_upload": "037243f014bbdfa0dbbc3caa7333fcad50be492f2c08233f81a798fed8fabef6b4b400920800531dc9eb25d3af5d9f20a1ac1cb96ceb4f40c0dc2a86f9b3fd0cb869b697b95cef3ceb267219df86f74d143102a91ea5499b1beb4d184964722caef65d052c9527104424e0320809928391a0563c18fa5e065414411f2b7a05a42ccafffe6c3f820a453fdc5ec4bcbf75161189765050d2b8e8e288f7e7d4dae5a4d864e39de8dfe6b56d4ecd2f7aa1d73b970ef1d89e00dd468e92465676f11fcbb3ce89dfa165700034942a4120ac8c14", "credential_request": "38f651deae743ceb93947f3b29c0b6a8bdca06cd2ddbf8bf4034f188eb21a341c45770702f6a169965cdc6bde6bd684ae0cca88beff84a10a10531c44881a25102ff65f91c0f286b9469d0f33463b70868e2693f8c511c92dba2e55689bbd298a440c2c6b0c831fe87dfb8ad6286460d1b", "credential_response": "9a35389a31de25ffdb70f4c76630c55089acf2b4f4de9543f59ece5ebe3a4626581e546cc899d1aefb99c2b7444b66702b7e810f863303b3ae542cacee4e5fab6a5aae2fee1f37a48874d26eda94d6285d5002bcc0c070fccf0c7731f55ceca1b678e1c355d4d933992866bee7f9f28b43359b348e63292bc9ffbd5d41ff8f14d5398384c86920b882e92476b954d4481234fbc01021b0c5e78327bc170aa0278eec426b7cedddd0d6b3d807bc3d9f52f3fc3a40a425f5514200f16eb92e0d7c67530fb4f215bc3e6b14e95cd4f03cbd7eb5c6c3a7b47af02bf7eec36995013ff5e62d020aebaa8584cd0c09db2a57c3940241e8e3ea63ecb7374164f8713b915f2d563a18f99c13e855a82d8f2af5af048835e4146f56612b9fd4e67f823a70e48a19df97488e6d1b7ff3a0a1e949ed25aa4835d88ea7a44f5028e8ad58ca0203c0087439e22dd7aea4ce64d8fae6432bfcb601acd244fe9e44b392c69cfc116ad4", "credential_finalization": "50f417b52847e0af257a96f03ec433bc1b202528727cd0d768247c7584d0e14879d9eff7a4a61c1b954f923c64b0c2fffb328cdba031b7be95b3dc49e23042d6", "client_registration_state": "945e750cc030ea56fb69fd959b1c869bbbd11598a55cca1c344680bb3af39e0c38f651deae743ceb93947f3b29c0b6a8bdca06cd2ddbf8bf4034f188eb21a341", "client_login_state": "945e750cc030ea56fb69fd959b1c869bbbd11598a55cca1c344680bb3af39e0c38f651deae743ceb93947f3b29c0b6a8bdca06cd2ddbf8bf4034f188eb21a341c45770702f6a169965cdc6bde6bd684ae0cca88beff84a10a10531c44881a25102ff65f91c0f286b9469d0f33463b70868e2693f8c511c92dba2e55689bbd298a440c2c6b0c831fe87dfb8ad6286460d1bd089e7b04a5bddab582c56c919ed4972e43ec70695d516b48b3d54f3a98a5c4b47e663fbc0691f3eaf2d33d7c6e951acc45770702f6a169965cdc6bde6bd684ae0cca88beff84a10a10531c44881a251", "server_login_state": "ab1b5088cc404142917da8cb9f0460800e222acd0abb20a0411824bbb3a33530caa46508d6a4d6778394fa3a1c7dc7c922241761e84567b0900365479ca10cdcae0c9adf368396b41a0c857c52274c3705ea4cc35b3dce1c83cd6b17b75723a0a93996c25c33f2fd1d2367416c40743ca0019db466d62c64cf832670a5e4e2e0526b13f76de824546a13c404d9545a6d401c13d0034c9e4b748854eaf316b74c5df9c3dc2caa274f196b9bd5c0e2ebf9036ec462f72da000d8e9631490aa19e0", "password_file": "037243f014bbdfa0dbbc3caa7333fcad50be492f2c08233f81a798fed8fabef6b4b400920800531dc9eb25d3af5d9f20a1ac1cb96ceb4f40c0dc2a86f9b3fd0cb869b697b95cef3ceb267219df86f74d143102a91ea5499b1beb4d184964722caef65d052c9527104424e0320809928391a0563c18fa5e065414411f2b7a05a42ccafffe6c3f820a453fdc5ec4bcbf75161189765050d2b8e8e288f7e7d4dae5a4d864e39de8dfe6b56d4ecd2f7aa1d73b970ef1d89e00dd468e92465676f11fcbb3ce89dfa165700034942a4120ac8c14", "export_key": "9763c031678a1b0398640298c9b2ab1651c580ca573e77279fb8e5869fd2d728faf4eff799ff9f6da74452935afe513da1dbaee132514c79529cd48680fa9df7", "session_key": "526b13f76de824546a13c404d9545a6d401c13d0034c9e4b748854eaf316b74c5df9c3dc2caa274f196b9bd5c0e2ebf9036ec462f72da000d8e9631490aa19e0" } "#; #[cfg(feature = "curve25519")] static TEST_VECTOR_CURVE25519_P256: &str = r#" { "client_s_pk": "356d33885c60c90a4bca2ca9e758c72842016738cb29114efe5b363a77e60e18", "client_s_sk": "98e74559a5af2af21de2f4caf01dd88232ee6a542e6bd2ed68b9dfa9ddf65e6f", "client_e_pk": "d9a367a4aa1f2822a5e50d3616f8763bda41a0882f2d29d78e25db36594dd44a", "client_e_sk": "f8ca80bc3fc0301986545adc309928a756d2aa1e79c6c617386a2ce9bc31da5c", "server_s_pk": "fd69aa024b1896f5911c50d2990ec5075738a5a86a9722b9779eb3032eb74838", "server_s_sk": "b06d35d129927c7427b2532656d7b33db7e6ff0070c630ab37a5022af8899b6d", "server_e_pk": "05369b574ab94ef297688d377c4fb4693b80898733128ebce44ad6614290aa64", "server_e_sk": "a02c5c8d35a1924823bd9ece4a67906211a29674355896061f2c72b63a806959", "fake_sk": "48faf5b2e5852fa92c7e431eee79383886885e9b2fa0e5957728614af670c964", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "afde4969d9abad215bc2d476b968a4113ce39c8736da16e107e067abbb9343c9", "oprf_seed": "1b55db8ba8bed7c6dffee2682971f938ae43f91898698c5f34a6c6dd64e69a19", "masking_nonce": "da87388c66103598f4b49a44abc7ac2ebf6caad4db2e32e19fb59d845e9d9b820f7afe413703648d03501421f9d2e25bd38bf35bd0a5b7167927cebe237c3dad", "envelope_nonce": "3c9f900ce6674b8ea3ee734678bd1e9397a1842392f2c79b3400434bee6934f4", "client_nonce": "e1b52de2ccb8b8b9175bca18cac32ac5138717d2bdea57dd1e8182f71e98af8e", "server_nonce": "d26610cea1112c2c57955b5e24242be031632dfd8ce1a018cc62ee653e5a8e33", "context": "636f6e74657874", "registration_request": "035741c014e89d5a10fd6f2b81e2cfc9f35e53222c619fb6fd20608843530b74ae", "registration_response": "0264db058e5010d658021d7c1b972d626fa353712c83bf7a7500d4a9bc22e85358fd69aa024b1896f5911c50d2990ec5075738a5a86a9722b9779eb3032eb74838", "registration_upload": "9dc1380a44873401d0dc181baecf898e9bc1f4bbcd75e7de3e28ef9f6b570479e059b27ad6ed0f9b240d9dde050aedbf30a5684e23dfe1af47f6bb75b240c74a98e74559a5af2af21de2f4caf01dd88232ee6a542e6bd2ed68b9dfa9ddf65e6f85396cff1f5d230d09bd9e662bd5a4d9594a32d2ab2b2f8a581542db82467f5e", "credential_request": "035741c014e89d5a10fd6f2b81e2cfc9f35e53222c619fb6fd20608843530b74aee1b52de2ccb8b8b9175bca18cac32ac5138717d2bdea57dd1e8182f71e98af8ed9a367a4aa1f2822a5e50d3616f8763bda41a0882f2d29d78e25db36594dd44a", "credential_response": "0264db058e5010d658021d7c1b972d626fa353712c83bf7a7500d4a9bc22e85358da87388c66103598f4b49a44abc7ac2ebf6caad4db2e32e19fb59d845e9d9b82aac713b4beab61312d2d57d98249f1a6e5e7c8bd435d704149679a381fe3c8da8b9b682af290e93422d1c52fa5cb94135823f8587b3c2a9056ab36845659ff2cad86ca029fd836b316471f1a42ee1a928331a4f7c1ec7aefc6429a13008c88bea02c5c8d35a1924823bd9ece4a67906211a29674355896061f2c72b63a806959606d4e3a19bfa8f940c87e5dc9e63ddf6c083d7406942c8c32e6bf7b35c504231d00490013365017c87b0c786f7d58e0bbe69c3c7f22f75e67c4a2ebf716c595", "credential_finalization": "e9e0ec963e9096dcfcbed47fdf6ac5c0fa43103a11753d7f82652ea3d64a2657", "client_registration_state": "afde4969d9abad215bc2d476b968a4113ce39c8736da16e107e067abbb9343c9035741c014e89d5a10fd6f2b81e2cfc9f35e53222c619fb6fd20608843530b74ae", "client_login_state": "afde4969d9abad215bc2d476b968a4113ce39c8736da16e107e067abbb9343c9035741c014e89d5a10fd6f2b81e2cfc9f35e53222c619fb6fd20608843530b74aee1b52de2ccb8b8b9175bca18cac32ac5138717d2bdea57dd1e8182f71e98af8ed9a367a4aa1f2822a5e50d3616f8763bda41a0882f2d29d78e25db36594dd44af8ca80bc3fc0301986545adc309928a756d2aa1e79c6c617386a2ce9bc31da5ce1b52de2ccb8b8b9175bca18cac32ac5138717d2bdea57dd1e8182f71e98af8e", "server_login_state": "f34318b0b8512ad4aed925465f80e25f3ca18b6ac57f0341beeaeda4ce944580d541e1e80e929cd4f2ce6e91c71a816e09833176a3a3e48801e9583b7da585535266262802364c33b9f4ebbf1e5fafe05b4beb6871bd197c5c3110d22404dd5b", "password_file": "9dc1380a44873401d0dc181baecf898e9bc1f4bbcd75e7de3e28ef9f6b570479e059b27ad6ed0f9b240d9dde050aedbf30a5684e23dfe1af47f6bb75b240c74a98e74559a5af2af21de2f4caf01dd88232ee6a542e6bd2ed68b9dfa9ddf65e6f85396cff1f5d230d09bd9e662bd5a4d9594a32d2ab2b2f8a581542db82467f5e", "export_key": "644446d460267013ccc320a626484f6d8b4fa773f1558c43eb0ddce656a53570", "session_key": "5266262802364c33b9f4ebbf1e5fafe05b4beb6871bd197c5c3110d22404dd5b" } "#; #[cfg(feature = "curve25519")] static TEST_VECTOR_CURVE25519_P384: &str = r#" { "client_s_pk": "f94d2f4ed06a99e5dc09edb4ed4566a29cb6706243ad0665019b559932a93375", "client_s_sk": "8034c5724cb6345b3534de5b1e44f6e4e97f5a98c3f5c7203f84aa370f00dd54", "client_e_pk": "3a8ec2f554673ecf8c706759d6f24a3a068594f49e22769c763a3f712e289a22", "client_e_sk": "60dac79209e340f068112840c69c681f458d55916af81521e3aac61058aed542", "server_s_pk": "70dafba720cf8ed7c5001107f1679974c8dd53f51bb12c6362024bd46d294e6a", "server_s_sk": "b0beb05237a893edeefad4bfb87d8a56d79120e2ef71ccf335fb36719822bf54", "server_e_pk": "7e5ac26d2eece1e95a7db76a2c9b0f63119c59755bde71baa153b700d10afa09", "server_e_sk": "004fb840dc8e2b4bf44cbce8bc9fb2439439ea8c81bf9299fe62a6a7eb133572", "fake_sk": "a8b7f29cc8faa909eccd741c8a9c043adf30b76ceb29979015e4905aa8c98975", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "b448ff1079b9bb899acb01f271303e43a1db682c515780cff8ede88795ab7aae65af947df67425dacce97080a82d63ee", "oprf_seed": "453a628c1033f01a8a7e289afd6a0701249eb387115e68dda5e9762815acc3c6890201190623466deb6ebcfa8d348c97", "masking_nonce": "043b357b425f2fa9a3bcd694f4599838ade3d2a565f3debb64549400922f698bee9d14b0246b92eecf22aee99d9267643e33bf2e6d1985da0b12fb06a1acf102", "envelope_nonce": "872593dc9342df3095eabdd5f238c27874e6bfdac3f7f2b413f396aa878dcc30", "client_nonce": "5b11f9c0204aa46756eb81a3929a54e3723294459cb82b37694cf7c1b8c130c0", "server_nonce": "2ed607c5c0d2cf6babe59b07b175eb2daca2c7b7f4f18ab8109edde08a2467db", "context": "636f6e74657874", "registration_request": "03840be924a75bf138c7d6ae38a34cee612df596e2e375482cdec3416bcee6e18ced4de0fb21325b54695724bcb2f6fb4b", "registration_response": "037179bd08a76c2e668c9665df3a6b47d2753a6cd0d3cc84ceaccc8719f538a603a4704e4cc1e8c04dcb3e1f30fb69badd70dafba720cf8ed7c5001107f1679974c8dd53f51bb12c6362024bd46d294e6a", "registration_upload": "036855719f79f2e7431c00616260933a2ead332dddc0d6a431945095f3abc62da8d6f332c5d8508850d33745ef81d4a87c7c684c6546aa31ce1084a279bbdc6d76b7c58c398d438e046e1e2b60ae9c9a8034c5724cb6345b3534de5b1e44f6e4e97f5a98c3f5c7203f84aa370f00dd5432cae335c0d7f1dd6abcce898bc8a7c7fe2ccc1e8b37accacd9f28f8a236f71979e28d47fe3ccaadb292fff9d4cc4c67", "credential_request": "03840be924a75bf138c7d6ae38a34cee612df596e2e375482cdec3416bcee6e18ced4de0fb21325b54695724bcb2f6fb4b5b11f9c0204aa46756eb81a3929a54e3723294459cb82b37694cf7c1b8c130c03a8ec2f554673ecf8c706759d6f24a3a068594f49e22769c763a3f712e289a22", "credential_response": "037179bd08a76c2e668c9665df3a6b47d2753a6cd0d3cc84ceaccc8719f538a603a4704e4cc1e8c04dcb3e1f30fb69badd043b357b425f2fa9a3bcd694f4599838ade3d2a565f3debb64549400922f698b817494112f8b8547a859357085e26d06cdb5cf3fc1d815fc35c158d0fd079bcee961df7356749be2fd54f310f89260a7cf67de23b12ef4b3a1f4f39f9454279602f6c32842f7618aa41cb16cd94c58490e2174641dcc05134e3d7806c5a0af9eacc7c53bf8aea591bb25a7ac9ae6307d004fb840dc8e2b4bf44cbce8bc9fb2439439ea8c81bf9299fe62a6a7eb133572891c828f84395e2fa18bddf2779342d51d87a6cc0382ff7b4f792ec1d25dc9110c60c54343806bb3fabf01c74cd948cb089a4f5841b43f85335ccfea5c6bac71b282f1fda62f6c49d11fc7da20ff4f08", "credential_finalization": "e85722888bbf3939cee3510febedb204e6768dcdfb99d258754e5a9bbd7f8ea1a0d65a6dd28af223e94f334c5801a06c", "client_registration_state": "b448ff1079b9bb899acb01f271303e43a1db682c515780cff8ede88795ab7aae65af947df67425dacce97080a82d63ee03840be924a75bf138c7d6ae38a34cee612df596e2e375482cdec3416bcee6e18ced4de0fb21325b54695724bcb2f6fb4b", "client_login_state": "b448ff1079b9bb899acb01f271303e43a1db682c515780cff8ede88795ab7aae65af947df67425dacce97080a82d63ee03840be924a75bf138c7d6ae38a34cee612df596e2e375482cdec3416bcee6e18ced4de0fb21325b54695724bcb2f6fb4b5b11f9c0204aa46756eb81a3929a54e3723294459cb82b37694cf7c1b8c130c03a8ec2f554673ecf8c706759d6f24a3a068594f49e22769c763a3f712e289a2260dac79209e340f068112840c69c681f458d55916af81521e3aac61058aed5425b11f9c0204aa46756eb81a3929a54e3723294459cb82b37694cf7c1b8c130c0", "server_login_state": "92be6961dc5d248b0724bd3f428e036d968756f0b7e0e551c5f4100294b1c8dffa147894e74b1e0229d8fdca0971a529d85fe7c10eba397a9499c59e8513c72df6687652590a36cf7bf3cc4a06d9ab452431ee154bf2a41542c6ec5c4f5de94db19f799a9ab8cf49cc4ecd52b35f6b7a01d454a8f5bc0f3853e43278463da212a614bb4a32b3c3bbb8ee2e9e284a5749", "password_file": "036855719f79f2e7431c00616260933a2ead332dddc0d6a431945095f3abc62da8d6f332c5d8508850d33745ef81d4a87c7c684c6546aa31ce1084a279bbdc6d76b7c58c398d438e046e1e2b60ae9c9a8034c5724cb6345b3534de5b1e44f6e4e97f5a98c3f5c7203f84aa370f00dd5432cae335c0d7f1dd6abcce898bc8a7c7fe2ccc1e8b37accacd9f28f8a236f71979e28d47fe3ccaadb292fff9d4cc4c67", "export_key": "7175fbd9eed61a7cb5b723faafec8c945733622a90c75a72ec262599cff1afeb0ddc1f30eadb69c71def535001ef5e99", "session_key": "b19f799a9ab8cf49cc4ecd52b35f6b7a01d454a8f5bc0f3853e43278463da212a614bb4a32b3c3bbb8ee2e9e284a5749" } "#; #[cfg(all(feature = "curve25519", feature = "ristretto255"))] static TEST_VECTOR_CURVE25519_RISTRETTO255: &str = r#" { "client_s_pk": "6f00b5a7c3400e5b3480e4ff963affa27a2e894bfc246da63404ab5dfcb12861", "client_s_sk": "402429cb18f30b6e5e6c3c4a9fb95480d31e9490c96ec09038bad2a2bba70378", "client_e_pk": "e5571e70f949d095f6f8385e0056abdf4182175d61f466a80d9ed8cbeb6da42d", "client_e_sk": "68d89ca14f80c9cf0cbe905ccc3573999c5eefacde6a2373591f6316828e9c65", "server_s_pk": "deafeb091131b492b8ad5af1aa10a3e95f503cc27f156daa5d612cf917b7512e", "server_s_sk": "40e5d55900e9402b0bf311e604fc6574cfc1786a9024132fd617b5e1015b9d7e", "server_e_pk": "40c97d16c9e95f8f7c7db8c9057afea8b3fccc06890e002ba36834e5271c3352", "server_e_sk": "480173d0dc1d7cc60382fb0c3fca5814acac964ae0e4984f31d9f3aac2a62850", "fake_sk": "50e9872b44d1595ab4478ce74d0e3b00666fd713ed5e1e5f172ef0bbf3014a6b", "credential_identifier": "637265644964656e746966696572", "id_u": "696455", "id_s": "696453", "password": "70617373776f7264", "blinding_factor": "8a6a055fcb9a6b7d2ba698bbec4099dbbc6a35766b63b16c04731399657faa05", "oprf_seed": "acd7d6bb5cbc48e3a5002158e14292e10fd0bbe27084b2ff2b917e8ae4cfe6901cbcc8eaffd83229cea4895e3aefb0456f14b887bd2077a5743cce5e86304c5c", "masking_nonce": "8e287233c7add7f2d3b3faa6aece0bd88274c45431d1f20302bba6f281a75c5db416d615c291a870f6b2350d872543df723d719144fd5282f853711d1430f348", "envelope_nonce": "32a0ece9a749a9982968975690b8cff5853da742018ddca972f5b2a64b368558", "client_nonce": "e6763553592f4f197b5411ccc02eae73f45480f2695169b07477d7fa953d384a", "server_nonce": "dc3e7e45e29129c8ce05ae2bbfde44c41ab01b976724f5e1fddc432d812390d4", "context": "636f6e74657874", "registration_request": "184bb0c06beba0eb813d28339db050e46b1d78ef51e0f715e246435b1f387030", "registration_response": "c23d5b2943f63db89b026e555cd40be4e42679d748d6b773154b9734eb17f65ddeafeb091131b492b8ad5af1aa10a3e95f503cc27f156daa5d612cf917b7512e", "registration_upload": "e44f23560d80e1ad23fcd321329069f44c7ecadbf5cd382642b9ab8d4660213ba69f7c5367f5e2662a2576b2c1c0284ba19da7de6db380081d6fb00126d69d143054ac49ac14a8a4422f72c205abee5f58917dcfb92932adbb7e1da5fa729278402429cb18f30b6e5e6c3c4a9fb95480d31e9490c96ec09038bad2a2bba7037886ea885ea9a847da454f4c1778e2d3cf693bed5995fcb60ea884675dd9acd5bbc5042fa6df3b87e7ea739fa8a9028097c5801348dba62a33b88b337030303639", "credential_request": "184bb0c06beba0eb813d28339db050e46b1d78ef51e0f715e246435b1f387030e6763553592f4f197b5411ccc02eae73f45480f2695169b07477d7fa953d384ae5571e70f949d095f6f8385e0056abdf4182175d61f466a80d9ed8cbeb6da42d", "credential_response": "c23d5b2943f63db89b026e555cd40be4e42679d748d6b773154b9734eb17f65d8e287233c7add7f2d3b3faa6aece0bd88274c45431d1f20302bba6f281a75c5decb46e775794d8612374cc354c24bb650bec4bae29d5ee748314a317a650176f02a606fbbd9565d62d0d82c8b989ed3c6cdca843b2c900591e661b76de3df23652ecea5aed831de1f3e68ee6a71953ada0ee5a0349f7a8469f0ea58113cc82e9a5f293cb03a74d05eb14d57ffe14b5a8dccc5b1fe8b5e31e8eec756ce7418d18480173d0dc1d7cc60382fb0c3fca5814acac964ae0e4984f31d9f3aac2a62850976c2d5a50e59e96708446af04c477438782bd8ab1be69ed331deb0f17a24c1ee2bdc5fedb0ecd1c2a842ace5d81b4ed0e93c89d883e7b8c59a3a3ca5f9c868eadb3d9835e09fd6bbbb45d91543c061cde3e3d94df2cc61f80993946065bc032", "credential_finalization": "45929de91f8996598dbe7c65db1f445a62510e8a27ddcef0ae1bcb033f4b74d03f4beb4f83f46602a20152adf0aad3afa465d5b2346f31be62bcc9adac4b5aab", "client_registration_state": "8a6a055fcb9a6b7d2ba698bbec4099dbbc6a35766b63b16c04731399657faa05184bb0c06beba0eb813d28339db050e46b1d78ef51e0f715e246435b1f387030", "client_login_state": "8a6a055fcb9a6b7d2ba698bbec4099dbbc6a35766b63b16c04731399657faa05184bb0c06beba0eb813d28339db050e46b1d78ef51e0f715e246435b1f387030e6763553592f4f197b5411ccc02eae73f45480f2695169b07477d7fa953d384ae5571e70f949d095f6f8385e0056abdf4182175d61f466a80d9ed8cbeb6da42d68d89ca14f80c9cf0cbe905ccc3573999c5eefacde6a2373591f6316828e9c65e6763553592f4f197b5411ccc02eae73f45480f2695169b07477d7fa953d384a", "server_login_state": "56f1f25910e0eca4e3d2d604b9cf8d3878138b4d89ef4966ae001cb5847f658f81850a6ee1aad03cf3864fa652ca9a7b04f02669d5a3e46f49641b8f188af27c06540e830a2f68264f3c7cb533f623b3fbef2ba87777f6909c20c42e911f26c92abdf474b4b1c9d591864a59b508a820b53ba819a0b14189e28b94302707cfe4164a6e3ec2dcba09aa66b70ee18c83ebbc9338aa0092d130051ad98a4bb931dd7bbc6ec93018ee8087435ac9f7171bb1b1b9fe022170963e39681129e2fe104b", "password_file": "e44f23560d80e1ad23fcd321329069f44c7ecadbf5cd382642b9ab8d4660213ba69f7c5367f5e2662a2576b2c1c0284ba19da7de6db380081d6fb00126d69d143054ac49ac14a8a4422f72c205abee5f58917dcfb92932adbb7e1da5fa729278402429cb18f30b6e5e6c3c4a9fb95480d31e9490c96ec09038bad2a2bba7037886ea885ea9a847da454f4c1778e2d3cf693bed5995fcb60ea884675dd9acd5bbc5042fa6df3b87e7ea739fa8a9028097c5801348dba62a33b88b337030303639", "export_key": "931b2394c380c1ae3a7e9cedaa9fc438fbc19e920fe74965813a7d4ee2c5cec8c13b144c826b259dd67a2507b3cf2e84f95d8e52dc2111050e7a91ee9d72be99", "session_key": "164a6e3ec2dcba09aa66b70ee18c83ebbc9338aa0092d130051ad98a4bb931dd7bbc6ec93018ee8087435ac9f7171bb1b1b9fe022170963e39681129e2fe104b" } "#; 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(()) }