Add better parsing for RFC test vectors (#247)

This commit is contained in:
Kevin Lewi
2021-10-09 18:17:07 -07:00
committed by GitHub
parent 77fbdb29f8
commit f1f4184400
6 changed files with 1221 additions and 1123 deletions
+2
View File
@@ -51,11 +51,13 @@ bincode = "1"
chacha20poly1305 = "0.8"
criterion = "0.3"
hex = "0.4"
json = "0.12"
lazy_static = "1"
opaque-ke = { path = "", default-features = false, features = ["std"] }
serde_json = "1"
sha2 = "0.9"
proptest = "1"
regex = "1"
rustyline = "8"
[[bench]]
+3 -1
View File
@@ -5,5 +5,7 @@
mod full_test;
pub mod mock_rng;
mod opaque_test_vectors;
mod opaque_vectors;
mod parser;
mod test_opaque_vectors;
mod voprf_test_vectors;
File diff suppressed because it is too large Load Diff
+593
View File
@@ -0,0 +1,593 @@
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
//! The OPAQUE test vectors taken from:
//! https://github.com/cfrg/draft-irtf-cfrg-opaque/blob/master/draft-irtf-cfrg-opaque.md
pub(crate) static VECTORS: &str = r#"
## Real Test Vectors {#real-vectors}
### OPAQUE-3DH Real Test Vector 1
#### Configuration
~~~
OPRF: 0001
Hash: SHA512
MHF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: ristretto255
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
~~~
#### Input Values
~~~
oprf_seed: 5c4f99877d253be5817b4b03f37b6da680b0d5671d1ec5351fa61c5d82
eab28b9de4c4e170f27e433ba377c71c49aa62ad26391ee1cac17011d8a7e9406657c
8
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: 71b8f14b7a1059cdadc414c409064a22cf9e970b0ffc6f1fc6fdd
539c4676775
masking_nonce: 54f9341ca183700f6b6acf28dbfe4a86afad788805de49f2d680ab
86ff39ed7f
server_private_key: 16eb9dc74a3df2033cd738bf2cfb7a3670c569d7749f284b2
b241cb237e7d10f
server_public_key: 18d5035fd0a9c1d6412226df037125901a43f4dff660c0549d
402f672bcc0933
server_nonce: f9c5ec75a8cd571370add249e99cb8a8c43f6ef05610ac6e354642b
f4fedbf69
client_nonce: 804133133e7ee6836c8515752e24bb44d323fef4ead34cde967798f
2e9784f69
server_keyshare: 6e77d4749eb304c4d74be9457c597546bc22aed699225499910f
c913b3e90712
client_keyshare: f67926bd036c5dc4971816b9376e9f64737f361ef8269c18f69f
1ab555e96d4a
server_private_keyshare: f8e3e31543dd6fc86833296726773d51158291ab9afd
666bb55dce83474c1101
client_private_keyshare: 4230d62ea740b13e178185fc517cf2c313e6908c4cd9
fb42154870ff3490c608
blind_registration: c62937d17dc9aa213c9038f84fe8c5bf3d953356db01c4d48
acb7cae48e6a504
blind_login: b5f458822ea11c900ad776e38e29d7be361f75b4d79b55ad74923299
bf8d6503
~~~
#### Intermediate Values
~~~
client_public_key: a2ba5f0b3c7d340f33852c354ba36983230abbcb78a2ae2219
6f6d6272faba00
auth_key: bfe5696d23897e60acd8d8df3b458983bebf8c7322982b0de6f56311367
887bef0bbaecc2c4a6de3528851030a0d5256288b902e37798e129988814faa5aad33
randomized_pwd: 8bdf54a171e0c0bcbad3a821e0954fe5e758a3c1c07df697e5532
265cc06687b295ca98e1f635a7f31ac78af483a9d272e8ee763dd3b567f9a5dc9f4e7
05a36b
envelope: 71b8f14b7a1059cdadc414c409064a22cf9e970b0ffc6f1fc6fdd539c46
76775749f7c447c49605d117f4cea49637ae644f2fee8a9c5eeb44dc78c60f1fc7a31
caec487e7117b4fa948042615525820f0dce8c763b4859db56fef87816b106e0
handshake_secret: 3847f696cc538d008e5e2d54f5b92a18404022ec7c3fc6f16c5
1cec65cff678dc1fdee81e3e001d282dabb9be877aa15de1d425f7612a94af864d00e
6d84350f
server_mac_key: 8b8ed457decef90f8864aec84f5d3716ab2091a8013d377976a32
073007b1685b851539a04cbfeaeedf63565f441ca840479a84d9e6dc2b264278c4913
08947c
client_mac_key: 9e891f73fabfce6a232ac10c2191fa9fc7ee9421cb39bcab5e376
a24b5c89a8f7d8589ba5f110298ef209a40676af9cf53a31f16fac47a97440597544b
036a07
oprf_key: 3f76113135e6ca7e51ac5bb3e8774eb84709ad36b8907ec8f7bc3537828
71906
~~~
#### Output Values
~~~
registration_request: 76cc85628d5ac0e01de4ede72479d607490e7f58b94578d
b7a0606d74bc58b03
registration_response: 865f3305ff73be7388313e7a74b5fc277a165ff2895f92
60391057b84c7bc72718d5035fd0a9c1d6412226df037125901a43f4dff660c0549d4
02f672bcc0933
registration_upload: a2ba5f0b3c7d340f33852c354ba36983230abbcb78a2ae22
196f6d6272faba0079a983ebe317141ee594ffd03535c1efce5411da15a92f92981bb
c1c02c292a5e472eb7d953cdecd10691aff451364b3eb67578758184c89830c420d0e
bee4ad71b8f14b7a1059cdadc414c409064a22cf9e970b0ffc6f1fc6fdd539c467677
5749f7c447c49605d117f4cea49637ae644f2fee8a9c5eeb44dc78c60f1fc7a31caec
487e7117b4fa948042615525820f0dce8c763b4859db56fef87816b106e0
KE1: e47c1c5e5eed1910a1cbb6420c5edf26ea3c099aaaedcb03599fc311a724d84f
804133133e7ee6836c8515752e24bb44d323fef4ead34cde967798f2e9784f69f6792
6bd036c5dc4971816b9376e9f64737f361ef8269c18f69f1ab555e96d4a
KE2: 9692d473e0bde7a1fbb6d2c0e4001ccc58902102857d0e67e5fa44f4b902b17f
54f9341ca183700f6b6acf28dbfe4a86afad788805de49f2d680ab86ff39ed7fbd513
832aba2b4ce0057dad8a9264cba31eee4713745b502b741bb8255c500dc16f1e5a57c
347bca59229cf4ed4e65abd59529fcaa0fd25ec20a777895785c1dba58c6a2517e5db
5e2940109fd2bf77d7db86b65a2032519b89559775dca96a0e8ea76fafacab0fff0de
09e1e8fecca1b835d6759b51cce90120391b3aa0bd6ff9c5ec75a8cd571370add249e
99cb8a8c43f6ef05610ac6e354642bf4fedbf696e77d4749eb304c4d74be9457c5975
46bc22aed699225499910fc913b3e9071235c693acb2f588a9ff4a7d1eb9ae3bc7f97
c2b29d939c405cd9f010a53ee5c20400c605ee4b85bccb2523d8a00b62a160a7ad6f5
45950e92e21802c73a1e3fa3
KE3: 5bab0d8fdabe655eb370d81c0233588b2c3e1519ed82aa8c6faf747db4a3210b
3db5b8b7807fd1f9fb5f4304f369bab081a4fce002aa3a55bc1a45239956e3ea
export_key: 5b622c41b12add9bd88da466777d2b34ba09c975164b573280340495f
26f17d3a7dbbe163a069d54bf10e95750e86ea4f4c3a4eaa78c435bc26ef3f9058439
a9
session_key: 32cfd43d68402222c9ee4ba93a266aca15c0e57a9fc728d03b557be9
ac1f8222d1c083b49988c34575ba4b2c972c5da728f3d8e8d78b2f99e62c74398c299
881
~~~
### OPAQUE-3DH Real Test Vector 2
#### Configuration
~~~
OPRF: 0001
Hash: SHA512
MHF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: ristretto255
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
~~~
#### Input Values
~~~
client_identity: 616c696365
server_identity: 626f62
oprf_seed: db5c1c16e264b8933d5da56439e7cfed23ab7287b474fe3cdcd58df089
a365a426ea849258d9f4bc13573601f2e727c90ecc19d448cf3145a662e0065f157ba
5
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: d0c7b0f0047682bd87a87e0c3553b9bcdce7e1ae3348570df20bf
2747829b2d2
masking_nonce: 30635396b708ddb7fc10fb73c4e3a9258cd9c3f6f761b2c227853b
5def228c85
server_private_key: eeb2fcc794f98501b16139771720a0713a2750b9e528adfd3
662ad56a7e19b04
server_public_key: 8aa90cb321a38759fc253c444f317782962ca18d33101eab2c
8cda04405a181f
server_nonce: 3fa57f7ef652185f89114109f5a61cc8c9216fdd7398246bb7a0c20
e2fbca2d8
client_nonce: a6bcd29b5aecc3507fc1f8f7631af3d2f5105155222e48099e5e608
5d8c1187a
server_keyshare: ae070cdffe5bb4b1c373e71be8e7d8f356ee5de37881533f1039
7bcd84d35445
client_keyshare: 642e7eecf19b804a62817486663d6c6c239396f709b663a4350c
da67d025687a
server_private_keyshare: 0974010a8528b813f5b33ae0d791df88516c8839c152
b030697637878b2d8b0a
client_private_keyshare: 03b52f066898929f4aca48014b2b97365205ce691ee3
444b0a7cecec3c7efb01
blind_registration: a66ffb41ccf1194a8d7dda900f8b6b0652e4c7fac4610066f
e0489a804d3bb05
blind_login: e6f161ac189e6873a19a54efca4baa0719e801e336d929d35ca28b5b
4f60560e
~~~
#### Intermediate Values
~~~
client_public_key: 4e54972ea754782f53c77c027ee2d39a12ec1c8821047fc7c9
5bd286cbc9c279
auth_key: 0ffb3201ca1ee9cb60e18a952ad6f178cc9944f54c7b6e7ad29fef8e7f8
95dfc4446ab9e26f150b7e4a710853d4a63616d4c4c7cd5e95d2fbc706c16d5d8e846
randomized_pwd: 6f0250970339fbf8dae7950e3010fe30eb7eb4e83bfadf428983c
451f310f3765cfcfd1d6ed0c8929cb9df59443adbdc6b554f5c636f9d08ac545e84b1
9921dc
envelope: d0c7b0f0047682bd87a87e0c3553b9bcdce7e1ae3348570df20bf274782
9b2d2906f10d832323d9a2a32a9f785e53cdb4a8534069409ab58e1886fa3e22de6b2
9476314d24fdb01a4ea80e358babe708a237ac17474b858a59482a58430c11ce
handshake_secret: b404a36e7d92890dbee76e443a86a0c2868569e81b5cfc7e16c
e60dfe1614d0707e875dcc65a9447b5ba00b9b0b97fcf4e6af7c47fc6199ec7122feb
9138c3e3
server_mac_key: 23ed6e15617061e9d7fdae661c1b746139ebb84f53bef5f6c29cc
e312c60fa36719aea50a338d7b02871da291ec44d0f5087c582c9147ac272c62f1244
6bd0bb
client_mac_key: 13750671047d8d0b7f119b222b6b33b7dd63d4e128a766f2cc76e
49792055232a58d5919117e2b91a5afd5756f93e3cb68ac2c9424651b05d30c282a59
e70f6c
oprf_key: 531b0c7b0a3f90060c28d3d96ef5fecf56e25b8e4bf71c14bc770804c3f
b4507
~~~
#### Output Values
~~~
registration_request: ec2927a03ced1220168b6d5a54f0372f813ced8ad3673d5
1dee92d2cbfee500c
registration_response: f6e244e131f8cd14bc37a856a933c91128b2498c06540d
2dba3a197ed7d8bd778aa90cb321a38759fc253c444f317782962ca18d33101eab2c8
cda04405a181f
registration_upload: 4e54972ea754782f53c77c027ee2d39a12ec1c8821047fc7
c95bd286cbc9c2793d81743982004acf05243d6c5405be93c137a8015727f59a4128d
db373cae8ffcef5db11460df6cbcc2c8d3ce0bb48fc58712a32de8dea7ac746671413
f9eeaad0c7b0f0047682bd87a87e0c3553b9bcdce7e1ae3348570df20bf2747829b2d
2906f10d832323d9a2a32a9f785e53cdb4a8534069409ab58e1886fa3e22de6b29476
314d24fdb01a4ea80e358babe708a237ac17474b858a59482a58430c11ce
KE1: d0a498e621d3ff7a011b37166a63ef40fe268f93c7d75a467eea42a98c0a490d
a6bcd29b5aecc3507fc1f8f7631af3d2f5105155222e48099e5e6085d8c1187a642e7
eecf19b804a62817486663d6c6c239396f709b663a4350cda67d025687a
KE2: e6d0c01cdc14f7bfdb38effbd63394f6304b47c2dc26fd510ecdbf471486b972
30635396b708ddb7fc10fb73c4e3a9258cd9c3f6f761b2c227853b5def228c8563f8f
17910f13eee01e10947637da13dc9a31c07c9dd324a8a59b22b4b58546a073d289b82
0b9658dcd6c387032248c1eae07ecf16eb63ea49c39cb3e9973d619e2e41299f00e42
defca71d240e72062c4466b4cd8b69b05ba4b3692e63f5ae15f08f142ae96fb245c48
4610d4a169fd99911bebae28dbb14a622452e7372b823fa57f7ef652185f89114109f
5a61cc8c9216fdd7398246bb7a0c20e2fbca2d8ae070cdffe5bb4b1c373e71be8e7d8
f356ee5de37881533f10397bcd84d354454fa8a9e5f63ce02d024dc602e2f61be2d7d
454ca88550af0851f3ee5e4de05e6e255c6b3bde1a47d808ca920783d5409040312d2
b3ee35f1fd8e24d009ed37ca
KE3: ea093c79f3d9d7718f3f632ed9c2e9004d069dea13ba7f08cd33de0f3042886e
bf6c4dc9cc9898a96f4b539b5b735f440005d07c9a636b6c5f76f2e78582ddc1
export_key: 987da0b1086098b5e11fcd74e9232515f2545779865cab6d911d78b4f
d4c9a464e9df1864419c26d7eb8708edf95a2a17b76ebbeb2979d30d6c2b4a3f26345
64
session_key: 5c2f66f5e3602b3150af772515ffb7cdfc9ace8626b319659f86f6c2
a01fe437d12a0c3f72f216bbaef007a35273bfa0d8d1220fb54e53a70f3fb9ae39345
064
~~~
### OPAQUE-3DH Real Test Vector 3
#### Configuration
~~~
OPRF: 0003
Hash: SHA256
MHF: Identity
KDF: HKDF-SHA256
MAC: HMAC-SHA256
Group: P256_XMD:SHA-256_SSWU_RO_
Context: 4f50415155452d504f43
Nh: 32
Npk: 33
Nsk: 32
Nm: 32
Nx: 32
Nok: 32
~~~
#### Input Values
~~~
oprf_seed: 77bfc065218c9a5593c952161b93193f025b3474102519e6984fa64831
0dd1bf
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: 2527e48c983deeb54c9c6337fdd9e120de85343dc7887f00248f1
acacc4a8319
masking_nonce: cb792f3657240ce5296dd5633e7333531009c11ee6ab46b6111f15
6d96a160b2
server_private_key: 87ef09986545b295e8f5bbbaa7ad3dce15eb299eb2a5b3487
5ff421b1d63d7a3
server_public_key: 025b95a6add1f2f3d038811b5ad3494bed73b1e2500d8dadec
592d88406e25c2f2
server_nonce: 8018e88ecfc53891529278c47239f8fe6f1be88972721898ef81cc0
a76a0b550
client_nonce: 967fcded96ed46986e60fcbdf985232639f537377ca3fcf07ad4899
56b2e9019
server_keyshare: 0242bc29993976185dacf6be815cbfa923aac80fad8b7f020c9d
4f18e0b6867a17
client_keyshare: 03358b4eae039953116889466bfddeb40168e39ed83809fd5f0d
5f2de9c5234398
server_private_keyshare: b1c0063e442238bdd89cd62b4c3ad31f016b68085d25
f85613f5838cd7c6b16a
client_private_keyshare: 10256ab078bc1edbaf79bee4cd28dd9db89179dcc921
9bc8f388b533f5439099
blind_registration: d50e29b581d716c3c05c4a0d6110b510cb5c9959bee817fde
b1eabd7ccd74fee
blind_login: 503d8495c6d04efaee8370c45fa1dfad70201edd140cec8ed6c73b5f
cd15c478
~~~
#### Intermediate Values
~~~
client_public_key: 0286913c9cdffc7a71c54cc5b32a3faa62cfba0180f0b76351
096409c9e19cd72e
auth_key: 91ec5a156946628872502569eee2a1a3d9deaa3320a11175ea462bfa607
98af5
randomized_pwd: 10706a06fc4c1c9101c655e0bc1fe9cf6fecdf38d8d0c15219bd2
4fc6d738214
envelope: 2527e48c983deeb54c9c6337fdd9e120de85343dc7887f00248f1acacc4
a831981a30154a6b4305a0d6906b704a148673ec0266683850abe9a2a91971eaa53b9
handshake_secret: 742560ea50065a0af34e458d98ef78f935bedf880437bc73164
15324dbab525c
server_mac_key: c3299b1ed28d5b8cb3e37ab09ef31a2a0406c0521d0faf2320a20
d7fdbb53ddc
client_mac_key: f96f80d13370635c3822fe6eba028ae3e05c1b8c298e05b32c669
83663cdb3a3
oprf_key: d153d662a1e7dd4383837aa7125685d2be6f8041472ecbfd610e46952a6
a24f1
~~~
#### Output Values
~~~
registration_request: 0325768a660df0c15f6f2a1dcbb7efd4f1c92702401edf3
e2f0742c8dce85d5fa8
registration_response: 0244211a4d2a067f7a61ed88dff6764856d347465f330d
0e15502700afd1865911025b95a6add1f2f3d038811b5ad3494bed73b1e2500d8dade
c592d88406e25c2f2
registration_upload: 0286913c9cdffc7a71c54cc5b32a3faa62cfba0180f0b763
51096409c9e19cd72e2dd8b5c51a4689c469f067e2766b987fa6c4ee4353b19f2974f
2407e2dc07fd92527e48c983deeb54c9c6337fdd9e120de85343dc7887f00248f1aca
cc4a831981a30154a6b4305a0d6906b704a148673ec0266683850abe9a2a91971eaa5
3b9
KE1: 03884e56429f1ee53559f2e244392eb8f994fd46c8fd9ffdd24ac5a7af963a66
3b967fcded96ed46986e60fcbdf985232639f537377ca3fcf07ad489956b2e9019033
58b4eae039953116889466bfddeb40168e39ed83809fd5f0d5f2de9c5234398
KE2: 0383fff1b3e8003723dff1b1f90a7934a036bd6691aca0366b07a100bf2bb3dc
2acb792f3657240ce5296dd5633e7333531009c11ee6ab46b6111f156d96a160b2977
de9d90759e8c525469d291422e8f4d66751b4b8d01fa9f62d142e46b78e672b8212b2
9d7d6d5d6884efd48a34827c7699d92e6dea7a8b608735f6bae399b1840c3f2eb0901
da4a2468467677abc843ec7d12e0dcc6359b74d145506fa79aebf8018e88ecfc53891
529278c47239f8fe6f1be88972721898ef81cc0a76a0b5500242bc29993976185dacf
6be815cbfa923aac80fad8b7f020c9d4f18e0b6867a175e6476d88558e5c2035530b5
3ce13597a06d22b9586040847b6d1e6f24a5ab90
KE3: a3dbf3ba53af908306d649ff0f7ff8db80311143d340356d0c817d02632e5e23
export_key: 4cd8130ebe797e83bb86a60dc100923349180d1da9c2f880791097111
c18aa96
session_key: 049948e93acc746a961a1efeec71af938957281a640623670f6f7a86
f5a3539b
~~~
### OPAQUE-3DH Real Test Vector 4
#### Configuration
~~~
OPRF: 0003
Hash: SHA256
MHF: Identity
KDF: HKDF-SHA256
MAC: HMAC-SHA256
Group: P256_XMD:SHA-256_SSWU_RO_
Context: 4f50415155452d504f43
Nh: 32
Npk: 33
Nsk: 32
Nm: 32
Nx: 32
Nok: 32
~~~
#### Input Values
~~~
client_identity: 616c696365
server_identity: 626f62
oprf_seed: 482123652ea37c7e4a0f9f1984ff1f2a310fe428d9de5819bf63b3942d
be09f9
credential_identifier: 31323334
password: 436f7272656374486f72736542617474657279537461706c65
envelope_nonce: 75c245690f9669a9af5699e8b23d6d1fa9e697aeb4526267d942b
842e4426e42
masking_nonce: 5947586f69259e0708bdfab794f689eec14c7deb7edde68c816451
56cf278f21
server_private_key: c728ebf47b1c65594d77dab871872dba848bdf20ed725f0fa
3b58e7d8f3eab2b
server_public_key: 029a2c6097fbbcf3457fe3ff7d4ef8e89dab585a67dfed0905
c9f104d909138bae
server_nonce: 581ac468101aee528cc6b69daac7a90de8837d49708e76310767cbe
4af18594d
client_nonce: 46498f95ec7986f0602019b3fbb646db87a2fdbc12176d4f7ab74fa
5fadace60
server_keyshare: 022aa8746ab4329d591296652d44f6dfb04470103311bacd7ad5
1060ef5abac41b
client_keyshare: 02a9f857ad3eabe09047049e8b8cee72feea2acb7fc487777c0b
22d3add6a0e0c0
server_private_keyshare: 48a5baa24274d5acc5e007a44f2147549ac8dd675564
2638f1029631944beed4
client_private_keyshare: 161e3aaa50f50e33344022969d17d9cf4c88b7a9eec4
c36bf64de079abb6dc7b
blind_registration: 9280e203ef27d9ef0d1d189bb3c02a66ef9a72d48cca6c1f9
afc1fedea22567c
blind_login: 4308682dc1bdab92ff91bb1a5fc5bc084223fe4369beddca3f1640a6
645455ad
~~~
#### Intermediate Values
~~~
client_public_key: 035d5fedb78e26e301de5b93bf181fba61f6407d8df3da212d
fdcfea66ef271f55
auth_key: 3bd6e6627f0f880f290fb77904f39ed2699e90b80440ba26f5eeb1bf30f
5f565
randomized_pwd: 59ae24f1bcf649d009bf972845e0aab0b37951c5201b6f2699707
2c79d84e104
envelope: 75c245690f9669a9af5699e8b23d6d1fa9e697aeb4526267d942b842e44
26e42e05c3e55ce81561193b699bd0981f86cda079361b1864b332335e239c707fa67
handshake_secret: 208f53119e80ea03007ab521ccad95a90fafb815551a6b0996c
0c96620415176
server_mac_key: d246f0371736ce72116f88cd15b59a87a7d3fe25a1b09d34a3f88
56bcb1b5785
client_mac_key: 2fc9858f5e228e9e344a790ff5157e96dbfa3b5ed2cfd050073cf
9ca4b49ee9f
oprf_key: f14e1fc34ba1218bfd3f7373f036889bf4f35a8fbc9e8c9c07ccf2d2388
79d9c
~~~
#### Output Values
~~~
registration_request: 02792b0f4670aced5970a68b01bb951004ccad962159be4
b6783170c9ad68f6052
registration_response: 03cc3491b4bcb3e4804f3eadbc6a04c8fff18cc9ca5a4f
eeb577fdfebd71f5060f029a2c6097fbbcf3457fe3ff7d4ef8e89dab585a67dfed090
5c9f104d909138bae
registration_upload: 035d5fedb78e26e301de5b93bf181fba61f6407d8df3da21
2dfdcfea66ef271f55f83490fc11b3ceccad8e302f5d7e98661dc91191f6fb742e05f
3278095a9741875c245690f9669a9af5699e8b23d6d1fa9e697aeb4526267d942b842
e4426e42e05c3e55ce81561193b699bd0981f86cda079361b1864b332335e239c707f
a67
KE1: 02fe96fc48d9fc921edd8e92ada581cbcc2a65e30962d0002ea5242f5baf627f
f646498f95ec7986f0602019b3fbb646db87a2fdbc12176d4f7ab74fa5fadace6002a
9f857ad3eabe09047049e8b8cee72feea2acb7fc487777c0b22d3add6a0e0c0
KE2: 035115b21dde0992cb812926d65c7dccd5e0f8ffff573da4a7c1e603e0e40827
895947586f69259e0708bdfab794f689eec14c7deb7edde68c81645156cf278f219d6
6e0743f1106cd46a10f249f404071bc798a39273d3cc3d2f4b88bb34e3b0df9488d32
72d42be1fddf60ee63c0628015aaefb8f4fa3ca2365e70041a1014c9dff4014550cd0
dd29a9b476f699b3a6d9528f98c27f471054f4883c875be99a0ed581ac468101aee52
8cc6b69daac7a90de8837d49708e76310767cbe4af18594d022aa8746ab4329d59129
6652d44f6dfb04470103311bacd7ad51060ef5abac41bb37b28686cee6592632e4dba
19c914f418da2f9b79a4f0783edb013d189fe9b8
KE3: 342b1213e0b0ab4101decbae6a6759e174cfbaf916ebe304e07128ae3ebf6076
export_key: 446f5a94d53f60823f27547118f7b499636617a81c9bbcd28e0ddacb8
5bdce59
session_key: 6d15cde32da560bf0d2363066e66028515d9117348cf78d205bca58b
e35550b0
~~~
## Fake Test Vectors {#fake-vectors}
### OPAQUE-3DH Fake Test Vector 1
#### Configuration
~~~
OPRF: 0001
Hash: SHA512
MHF: Identity
KDF: HKDF-SHA512
MAC: HMAC-SHA512
Group: ristretto255
Context: 4f50415155452d504f43
Nh: 64
Npk: 32
Nsk: 32
Nm: 64
Nx: 64
Nok: 32
~~~
#### Input Values
~~~
client_identity: 616c696365
server_identity: 626f62
oprf_seed: 98ee70b2c51d3e89d9c08b00889a1fa8f3947a48dac9ad994e946f408a
2c31250ee34f9d04a7d85661bab11c67048ecfb7a68c657a3df87cff3d09c6af9912a
1
credential_identifier: 31323334
masking_nonce: 7cb33db5ba8082e4f4bfb830e8e3f525b0ddcb70469b34224758d7
25ce53ac76
client_private_key: 21c97ffc56be5d93f86441023b7c8a4b629399933b3f845f5
852e8c716a60408
client_public_key: 5cc46fdc0337a684e126f8663deacc67872a7daffc75312a1d
6377783935f932
server_private_key: 030c7634ae24b9c6d4e2c07176719e7a246850b8e019f1c71
a23af6bdb847b0b
server_public_key: 1ac449e9cdd633788069cca1aaea36ea359d7c2d493b254e5f
fe8d64212dcc59
server_nonce: cae1f4fee4ee4ba509fda550ea0421a85762305b1db20e37f4539b2
327d37b80
server_keyshare: 5e5c0ac2904c7d9bf38f99e0050594e484b4d8ded8038ef6e0c1
41a985fa6b35
server_private_keyshare: a4abffe3bef8082b78323ea4507fbb0ce8105ca62b38
1919a35767deaa699709
masking_key: 077adba76f768fd0979f8dc006ca297e7954ebf0e81a893021ee24ac
c35e1a3f4b5e0366c15771133082ec21035ae0ef0d8bcd0e59d26775ae953b9552fdf
bf2
KE1: 1ef5fc13fa7695e81b5fcadf57eb49a579b10e4f51bbee11afb278608592456b
8837b6c0709160251cbebe0d55e4423554c45da7a8952367cf336eb623379e80dae2f
1e0cd79b733131d499fb9e77efe0f235d73c1f920bdc5816259ad3a7429
~~~
#### Output Values
~~~
KE2: 2e1bb024ff255d0f35eb7b1f11174b3e60d8aaabb11ea347a6da0c1964594f4f
7cb33db5ba8082e4f4bfb830e8e3f525b0ddcb70469b34224758d725ce53ac76094c0
aa800d9a0884392e4efbc0479e3cb84a38c9ead879f1ff755ad762c06812b9858f82c
9722acc61b8eb1d156bc994839bf9ed8a760615258d23e0f94fa2cffadc655ed0d6ff
6914066427366019d4e6989b65d13e38e8edc5ae6f82aa1b6a46bfe6ca0256c64d0cf
db50a3eb7676e1d212e155e152e3bbc9d1fae3c679aacae1f4fee4ee4ba509fda550e
a0421a85762305b1db20e37f4539b2327d37b805e5c0ac2904c7d9bf38f99e0050594
e484b4d8ded8038ef6e0c141a985fa6b3528ef79e28dbd3783322ab69900a43be8919
a840cfcc5aa31a8f42b6f2a0c1ce1f9fa50c58dc5787a957af588580117b70d304639
dc68851224301bbbae9cd654
~~~
### OPAQUE-3DH Fake Test Vector 2
#### Configuration
~~~
OPRF: 0003
Hash: SHA256
MHF: Identity
KDF: HKDF-SHA256
MAC: HMAC-SHA256
Group: P256_XMD:SHA-256_SSWU_RO_
Context: 4f50415155452d504f43
Nh: 32
Npk: 33
Nsk: 32
Nm: 32
Nx: 32
Nok: 32
~~~
#### Input Values
~~~
client_identity: 616c696365
server_identity: 626f62
oprf_seed: f7664fae89be455ee3350b04a85eab390b2dc63256fbd311d8de944b45
b859e6
credential_identifier: 31323334
masking_nonce: 21cd364318a92b2afbfccea5d80d337f07defe40d92673a52f3844
058f5d949a
client_private_key: 41ffab7c86e2b0916361fb6a69f9a097e3ef2f83f8fd5f95c
c79432eabf3e020
client_public_key: 0251bc2a7e0cb7c043eec5ee7d1b769b69f85b0fa19d1ae907
5416e93fa01689de
server_private_key: 61764783412278e6ce3c6c66f1995a2a30b5824be6a6d31ca
d35a578ec3d9353
server_public_key: 03727dd31712275905b1a3cca3bbb33bc71034a1d0c3801be0
20541933dd497f18
server_nonce: 2b772c1eb569cc2b57741bf3be630e377c8245b11d0b6ad1fe1d606
490c27208
server_keyshare: 02a59205c836a2ab86e19dbd9a417818052179e9a5c99221e2d1
d8a780dfe4734d
server_private_keyshare: e8c25741b201c2ba00abe390e5a3933a75efdb71b50e
1e0087cc7235f6f9448a
masking_key: 5bb4d884375d7dcbd562a62190cc569ccc809cff9d5aa5e176d48e96
46b558eb
KE1: 031ac7e5c8099fcb7de5ad5b6cf33ff53078dbee1da64f15f6cd53b2afe6e332
06a91c9485d74c9010185f462ce1eec52f588a8e392f36915849b6bfcb6bd5b904037
6a35db8f7e582569dba2e573c4af1462f91c59a9bdee253ed13f60108746252
~~~
#### Output Values
~~~
KE2: 02200f91b03819f6a4b0957216fc94a2230d75d0e1be1fe0ced9434b0ec9d23a
5621cd364318a92b2afbfccea5d80d337f07defe40d92673a52f3844058f5d949a604
39294e7567fc29643e0d5c8799d0dffbbfc8609558b982012fa90aef2ce52b1ffdd8f
96bda49f5306ae346cd745812d3a953ff94712e4ed0acc67c99b432860e337fe3234b
ba88415ac55368b938106cca4049b5c13496fe167d3a092bd990e2b772c1eb569cc2b
57741bf3be630e377c8245b11d0b6ad1fe1d606490c2720802a59205c836a2ab86e19
dbd9a417818052179e9a5c99221e2d1d8a780dfe4734d7325a81225091665460460ec
37fcf0431f738ba6cb80b63756ee70c6e43aeae5
~~~
"#;
+100
View File
@@ -0,0 +1,100 @@
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
use alloc::string::String;
pub(crate) fn rfc_to_json(input: &str) -> String {
format!("{{\n{}\n}}", parse_vector_types(input))
}
fn parse_vector_types(input: &str) -> String {
let re = regex::Regex::new(r" (?P<type>.+?) Test Vectors").unwrap();
let mut vector_types = vec![];
let chunks: Vec<&str> = re.split(input).collect();
println!("{:?}", chunks.len());
let mut count = 1;
for caps in re.captures_iter(input) {
println!("{:?}", caps["type"].to_string());
let vector_type = format!(
"\"{}\": [\n {} \n]",
caps["type"].to_string(),
parse_ciphersuites(chunks[count])
);
vector_types.push(vector_type);
count += 1;
}
vector_types.join(",\n")
}
fn parse_ciphersuites(input: &str) -> String {
let re = regex::Regex::new(
r"# Configuration(.|\n)+?Hash: (?P<hash>.*?)\n(.|\n)*?Group: (?P<group>.*?)\n",
)
.unwrap();
let mut ciphersuites = vec![];
let chunks: Vec<&str> = re.split(input).collect();
let mut count = 1;
for caps in re.captures_iter(input) {
let ciphersuite = format!(
"{{ \"{}, {}\": {{ {} }} }}",
caps["group"].to_string(),
caps["hash"].to_string(),
parse_params(chunks[count])
);
ciphersuites.push(ciphersuite);
count += 1;
}
ciphersuites.join(",\n")
}
fn parse_params(input: &str) -> String {
let mut params = vec![];
let mut param = String::new();
let mut lines = input.lines();
loop {
match lines.next() {
None => {
// Clear out any existing string and flush to params
param += "\"";
params.push(param);
return params.join(",\n");
}
Some(line) => {
// If line contains :, then
if line.contains(':') {
// Clear out any existing string and flush to params
if !param.is_empty() {
param += "\"";
params.push(param);
}
let mut iter = line.split(':');
let key = iter.next().unwrap().split_whitespace().next().unwrap();
let val = iter.next().unwrap().split_whitespace().next().unwrap();
param = format!(" \"{}\": \"{}", key, val);
} else {
let s = line.trim().to_string();
if s.contains('~') || s.contains('#') {
// Ignore comment lines
continue;
}
if !s.is_empty() {
param += &s;
}
}
}
}
}
}
+523
View File
@@ -0,0 +1,523 @@
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
use crate::{
ciphersuite::CipherSuite, errors::*, key_exchange::tripledh::TripleDH, opaque::*,
slow_hash::NoOpHash, tests::mock_rng::CycleRng, *,
};
use alloc::{string::ToString, vec, vec::Vec};
use json::JsonValue;
#[allow(non_snake_case)]
pub struct OpaqueTestVectorParameters {
pub dummy_private_key: Vec<u8>,
pub dummy_masking_key: Vec<u8>,
pub context: Vec<u8>,
pub client_private_key: Option<Vec<u8>>,
pub client_keyshare: Vec<u8>,
pub client_private_keyshare: Vec<u8>,
pub server_public_key: Vec<u8>,
pub server_private_key: Vec<u8>,
pub server_keyshare: Vec<u8>,
pub server_private_keyshare: Vec<u8>,
pub client_identity: Option<Vec<u8>>,
pub server_identity: Option<Vec<u8>>,
pub credential_identifier: Vec<u8>,
pub password: Vec<u8>,
pub blind_registration: Vec<u8>,
pub oprf_seed: Vec<u8>,
pub masking_nonce: Vec<u8>,
pub envelope_nonce: Vec<u8>,
pub client_nonce: Vec<u8>,
pub server_nonce: Vec<u8>,
pub client_info: Vec<u8>,
pub server_info: Vec<u8>,
pub registration_request: Vec<u8>,
pub registration_response: Vec<u8>,
pub registration_upload: Vec<u8>,
pub KE1: Vec<u8>,
pub blind_login: Vec<u8>,
pub KE2: Vec<u8>,
pub KE3: Vec<u8>,
pub export_key: Vec<u8>,
pub session_key: Vec<u8>,
pub auth_key: Vec<u8>,
pub randomized_pwd: Vec<u8>,
pub handshake_secret: Vec<u8>,
pub server_mac_key: Vec<u8>,
pub client_mac_key: Vec<u8>,
pub oprf_key: Vec<u8>,
}
macro_rules! parse {
( $v:ident, $s:expr ) => {
parse_default!($v, $s, vec![])
};
}
macro_rules! parse_default {
( $v:ident, $s:expr, $d:expr ) => {
match decode(&$v, $s) {
Some(x) => x,
None => $d,
}
};
}
fn decode(values: &JsonValue, key: &str) -> Option<Vec<u8>> {
values[key]
.as_str()
.and_then(|s| hex::decode(&s.to_string()).ok())
}
fn populate_test_vectors(values: &JsonValue) -> OpaqueTestVectorParameters {
OpaqueTestVectorParameters {
dummy_private_key: parse_default!(values, "client_private_key", vec![0u8; 32]),
dummy_masking_key: parse_default!(values, "masking_key", vec![0u8; 64]),
context: parse!(values, "Context"),
client_private_key: decode(values, "client_private_key"),
client_keyshare: parse!(values, "client_keyshare"),
client_private_keyshare: parse!(values, "client_private_keyshare"),
server_public_key: parse!(values, "server_public_key"),
server_private_key: parse!(values, "server_private_key"),
server_keyshare: parse!(values, "server_keyshare"),
server_private_keyshare: parse!(values, "server_private_keyshare"),
client_identity: decode(values, "client_identity"),
server_identity: decode(values, "server_identity"),
credential_identifier: parse!(values, "credential_identifier"),
password: parse!(values, "password"),
blind_registration: parse!(values, "blind_registration"),
oprf_seed: parse!(values, "oprf_seed"),
masking_nonce: parse!(values, "masking_nonce"),
envelope_nonce: parse!(values, "envelope_nonce"),
client_nonce: parse!(values, "client_nonce"),
server_nonce: parse!(values, "server_nonce"),
client_info: parse!(values, "client_info"),
server_info: parse!(values, "server_info"),
registration_request: parse!(values, "registration_request"),
registration_response: parse!(values, "registration_response"),
registration_upload: parse!(values, "registration_upload"),
KE1: parse!(values, "KE1"),
KE2: parse!(values, "KE2"),
KE3: parse!(values, "KE3"),
blind_login: parse!(values, "blind_login"),
export_key: parse!(values, "export_key"),
session_key: parse!(values, "session_key"),
auth_key: parse!(values, "auth_key"),
randomized_pwd: parse!(values, "randomized_pwd"),
handshake_secret: parse!(values, "handshake_secret"),
server_mac_key: parse!(values, "server_mac_key"),
client_mac_key: parse!(values, "client_mac_key"),
oprf_key: parse!(values, "oprf_key"),
}
}
fn get_password_file_bytes<CS: CipherSuite>(
parameters: &OpaqueTestVectorParameters,
) -> Result<Vec<u8>, ProtocolError> {
let password_file = ServerRegistration::<CS>::finish(
RegistrationUpload::deserialize(&parameters.registration_upload[..]).unwrap(),
);
Ok(password_file.serialize())
}
fn parse_identifiers(
client_identity: &Option<Vec<u8>>,
server_identity: &Option<Vec<u8>>,
) -> Option<Identifiers> {
match (client_identity, server_identity) {
(None, None) => None,
(Some(x), None) => Some(Identifiers::ClientIdentifier(x.clone())),
(None, Some(y)) => Some(Identifiers::ServerIdentifier(y.clone())),
(Some(x), Some(y)) => Some(Identifiers::ClientAndServerIdentifiers(
x.clone(),
y.clone(),
)),
}
}
macro_rules! json_to_test_vectors {
( $v:ident, $vector_type:expr, $cs:expr, ) => {
$v[$vector_type][$cs]
.members()
.map(|x| populate_test_vectors(&x))
.collect::<Vec<OpaqueTestVectorParameters>>()
};
}
#[test]
fn tests() -> Result<(), ProtocolError> {
let rfc = json::parse(super::parser::rfc_to_json(super::opaque_vectors::VECTORS).as_str())
.expect("Could not parse json");
let ristretto_real_tvs = json_to_test_vectors!(
rfc,
String::from("Real"),
String::from("ristretto255, SHA512"),
);
let ristretto_fake_tvs = json_to_test_vectors!(
rfc,
String::from("Fake"),
String::from("ristretto255, SHA512"),
);
struct Ristretto255Sha512NoSlowHash;
impl CipherSuite for Ristretto255Sha512NoSlowHash {
type OprfGroup = curve25519_dalek::ristretto::RistrettoPoint;
type KeGroup = curve25519_dalek::ristretto::RistrettoPoint;
type KeyExchange = TripleDH;
type Hash = sha2::Sha512;
type SlowHash = NoOpHash;
}
test_registration_request::<Ristretto255Sha512NoSlowHash>(&ristretto_real_tvs)?;
test_registration_response::<Ristretto255Sha512NoSlowHash>(&ristretto_real_tvs)?;
test_registration_upload::<Ristretto255Sha512NoSlowHash>(&ristretto_real_tvs)?;
test_ke1::<Ristretto255Sha512NoSlowHash>(&ristretto_real_tvs)?;
test_ke2::<Ristretto255Sha512NoSlowHash>(&ristretto_real_tvs)?;
test_ke3::<Ristretto255Sha512NoSlowHash>(&ristretto_real_tvs)?;
test_server_login_finish::<Ristretto255Sha512NoSlowHash>(&ristretto_real_tvs)?;
test_fake_vectors::<Ristretto255Sha512NoSlowHash>(&ristretto_fake_tvs)?;
#[cfg(feature = "p256")]
{
let p256_real_tvs = json_to_test_vectors!(
rfc,
String::from("Real"),
String::from("P256_XMD:SHA-256_SSWU_RO_, SHA256"),
);
let p256_fake_tvs = json_to_test_vectors!(
rfc,
String::from("Fake"),
String::from("P256_XMD:SHA-256_SSWU_RO_, SHA256"),
);
struct P256Sha256NoSlowHash;
impl CipherSuite for P256Sha256NoSlowHash {
type OprfGroup = p256_::ProjectivePoint;
type KeGroup = p256_::ProjectivePoint;
type KeyExchange = TripleDH;
type Hash = sha2::Sha256;
type SlowHash = NoOpHash;
}
test_registration_request::<P256Sha256NoSlowHash>(&p256_real_tvs)?;
test_registration_response::<P256Sha256NoSlowHash>(&p256_real_tvs)?;
test_registration_upload::<P256Sha256NoSlowHash>(&p256_real_tvs)?;
test_ke1::<P256Sha256NoSlowHash>(&p256_real_tvs)?;
test_ke2::<P256Sha256NoSlowHash>(&p256_real_tvs)?;
test_ke3::<P256Sha256NoSlowHash>(&p256_real_tvs)?;
test_server_login_finish::<P256Sha256NoSlowHash>(&p256_real_tvs)?;
test_fake_vectors::<P256Sha256NoSlowHash>(&p256_fake_tvs)?;
}
Ok(())
}
fn test_registration_request<CS: CipherSuite>(
tvs: &[OpaqueTestVectorParameters],
) -> Result<(), ProtocolError> {
for parameters in tvs {
let mut rng = CycleRng::new(parameters.blind_registration.to_vec());
let client_registration_start_result =
ClientRegistration::<CS>::start(&mut rng, &parameters.password)?;
assert_eq!(
hex::encode(&parameters.registration_request),
hex::encode(client_registration_start_result.message.serialize())
);
}
Ok(())
}
fn test_registration_response<CS: CipherSuite>(
tvs: &[OpaqueTestVectorParameters],
) -> Result<(), ProtocolError> {
for parameters in tvs {
let server_setup = ServerSetup::<CS>::deserialize(
&[
&parameters.oprf_seed[..],
&parameters.server_private_key[..],
&parameters.dummy_private_key[..],
]
.concat(),
)?;
let server_registration_start_result = ServerRegistration::<CS>::start(
&server_setup,
RegistrationRequest::deserialize(&parameters.registration_request[..]).unwrap(),
&parameters.credential_identifier,
)?;
assert_eq!(
hex::encode(&parameters.oprf_key),
hex::encode(server_registration_start_result.oprf_key)
);
assert_eq!(
hex::encode(&parameters.registration_response),
hex::encode(server_registration_start_result.message.serialize())
);
}
Ok(())
}
fn test_registration_upload<CS: CipherSuite>(
tvs: &[OpaqueTestVectorParameters],
) -> Result<(), ProtocolError> {
for parameters in tvs {
let mut rng = CycleRng::new(parameters.blind_registration.to_vec());
let client_registration_start_result =
ClientRegistration::<CS>::start(&mut rng, &parameters.password)?;
let mut finish_registration_rng = CycleRng::new(parameters.envelope_nonce.to_vec());
let result = client_registration_start_result.state.finish(
&mut finish_registration_rng,
RegistrationResponse::deserialize(&parameters.registration_response[..]).unwrap(),
match parse_identifiers(&parameters.client_identity, &parameters.server_identity) {
None => ClientRegistrationFinishParameters::default(),
Some(ids) => ClientRegistrationFinishParameters::new(Some(ids), None),
},
)?;
assert_eq!(
hex::encode(&parameters.auth_key),
hex::encode(result.auth_key)
);
assert_eq!(
hex::encode(&parameters.randomized_pwd),
hex::encode(result.randomized_pwd)
);
assert_eq!(
hex::encode(&parameters.registration_upload),
hex::encode(result.message.serialize())
);
assert_eq!(
hex::encode(&parameters.export_key),
hex::encode(result.export_key.to_vec())
);
}
Ok(())
}
fn test_ke1<CS: CipherSuite>(tvs: &[OpaqueTestVectorParameters]) -> Result<(), ProtocolError> {
for parameters in tvs {
let client_login_start = [
&parameters.blind_login[..],
&parameters.client_private_keyshare[..],
&parameters.client_nonce[..],
]
.concat();
let mut client_login_start_rng = CycleRng::new(client_login_start);
let client_login_start_result =
ClientLogin::<CS>::start(&mut client_login_start_rng, &parameters.password)?;
assert_eq!(
hex::encode(&parameters.KE1),
hex::encode(client_login_start_result.message.serialize())
);
}
Ok(())
}
fn test_ke2<CS: CipherSuite>(tvs: &[OpaqueTestVectorParameters]) -> Result<(), ProtocolError> {
for parameters in tvs {
let server_setup = ServerSetup::<CS>::deserialize(
&[
&parameters.oprf_seed[..],
&parameters.server_private_key[..],
&parameters.dummy_private_key[..],
]
.concat(),
)?;
let record = ServerRegistration::<CS>::deserialize(
&get_password_file_bytes::<CS>(&parameters)?[..],
)?;
let mut server_private_keyshare_and_nonce_rng = CycleRng::new(
[
&parameters.masking_nonce[..],
&parameters.server_private_keyshare[..],
&parameters.server_nonce[..],
]
.concat(),
);
let server_login_start_result = ServerLogin::<CS>::start(
&mut server_private_keyshare_and_nonce_rng,
&server_setup,
Some(record),
CredentialRequest::<CS>::deserialize(&parameters.KE1[..]).unwrap(),
&parameters.credential_identifier,
match parse_identifiers(&parameters.client_identity, &parameters.server_identity) {
None => ServerLoginStartParameters::WithContext(parameters.context.to_vec()),
Some(ids) => ServerLoginStartParameters::WithContextAndIdentifiers(
parameters.context.to_vec(),
ids,
),
},
)?;
assert_eq!(
hex::encode(&parameters.handshake_secret),
hex::encode(server_login_start_result.handshake_secret)
);
assert_eq!(
hex::encode(&parameters.server_mac_key),
hex::encode(server_login_start_result.server_mac_key)
);
assert_eq!(
hex::encode(&parameters.oprf_key),
hex::encode(server_login_start_result.oprf_key)
);
assert_eq!(
hex::encode(&parameters.KE2),
hex::encode(server_login_start_result.message.serialize())
);
}
Ok(())
}
fn test_ke3<CS: CipherSuite>(tvs: &[OpaqueTestVectorParameters]) -> Result<(), ProtocolError> {
for parameters in tvs {
let client_login_start = [
&parameters.blind_login[..],
&parameters.client_private_keyshare[..],
&parameters.client_nonce[..],
]
.concat();
let mut client_login_start_rng = CycleRng::new(client_login_start);
let client_login_start_result =
ClientLogin::<CS>::start(&mut client_login_start_rng, &parameters.password)?;
let client_login_finish_result = client_login_start_result.state.finish(
CredentialResponse::<CS>::deserialize(&parameters.KE2[..])?,
match parse_identifiers(&parameters.client_identity, &parameters.server_identity) {
None => {
ClientLoginFinishParameters::new(Some(parameters.context.clone()), None, None)
}
Some(ids) => ClientLoginFinishParameters::new(
Some(parameters.context.clone()),
Some(ids),
None,
),
},
)?;
assert_eq!(
hex::encode(&parameters.session_key),
hex::encode(&client_login_finish_result.session_key)
);
assert_eq!(
hex::encode(&parameters.handshake_secret),
hex::encode(&client_login_finish_result.handshake_secret)
);
assert_eq!(
hex::encode(&parameters.client_mac_key),
hex::encode(&client_login_finish_result.client_mac_key)
);
assert_eq!(
hex::encode(&parameters.KE3),
hex::encode(client_login_finish_result.message.serialize())
);
assert_eq!(
hex::encode(&parameters.export_key),
hex::encode(client_login_finish_result.export_key)
);
}
Ok(())
}
fn test_server_login_finish<CS: CipherSuite>(
tvs: &[OpaqueTestVectorParameters],
) -> Result<(), ProtocolError> {
for parameters in tvs {
let server_setup = ServerSetup::<CS>::deserialize(
&[
&parameters.oprf_seed[..],
&parameters.server_private_key[..],
&parameters.dummy_private_key[..],
]
.concat(),
)?;
let record = ServerRegistration::<CS>::deserialize(
&get_password_file_bytes::<CS>(&parameters)?[..],
)?;
let mut server_private_keyshare_and_nonce_rng = CycleRng::new(
[
&parameters.masking_nonce[..],
&parameters.server_private_keyshare[..],
&parameters.server_nonce[..],
]
.concat(),
);
let server_login_start_result = ServerLogin::<CS>::start(
&mut server_private_keyshare_and_nonce_rng,
&server_setup,
Some(record),
CredentialRequest::<CS>::deserialize(&parameters.KE1[..]).unwrap(),
&parameters.credential_identifier,
match parse_identifiers(&parameters.client_identity, &parameters.server_identity) {
None => ServerLoginStartParameters::WithContext(parameters.context.to_vec()),
Some(ids) => ServerLoginStartParameters::WithContextAndIdentifiers(
parameters.context.to_vec(),
ids,
),
},
)?;
let server_login_result = server_login_start_result
.state
.finish(CredentialFinalization::deserialize(&parameters.KE3[..])?)?;
assert_eq!(
hex::encode(&parameters.session_key),
hex::encode(&server_login_result.session_key)
);
}
Ok(())
}
fn test_fake_vectors<CS: CipherSuite>(
tvs: &[OpaqueTestVectorParameters],
) -> Result<(), ProtocolError> {
for parameters in tvs {
let server_setup = ServerSetup::<CS>::deserialize(
&[
&parameters.oprf_seed[..],
&parameters.server_private_key[..],
&parameters.dummy_private_key[..],
]
.concat(),
)?;
let mut server_private_keyshare_and_nonce_rng = CycleRng::new(
[
&parameters.dummy_masking_key[..],
&parameters.masking_nonce[..],
&parameters.server_private_keyshare[..],
&parameters.server_nonce[..],
]
.concat(),
);
let server_login_start_result = ServerLogin::<CS>::start(
&mut server_private_keyshare_and_nonce_rng,
&server_setup,
None,
CredentialRequest::<CS>::deserialize(&parameters.KE1[..]).unwrap(),
&parameters.credential_identifier,
match parse_identifiers(&parameters.client_identity, &parameters.server_identity) {
None => ServerLoginStartParameters::WithContext(parameters.context.to_vec()),
Some(ids) => ServerLoginStartParameters::WithContextAndIdentifiers(
parameters.context.to_vec(),
ids,
),
},
)?;
assert_eq!(
hex::encode(&parameters.KE2),
hex::encode(server_login_start_result.message.serialize())
);
}
Ok(())
}