1use crate::{Error, Result};
4use blake2::VarBlake2b;
5use rand::{CryptoRng, Rng};
6use std::fmt::{self, Debug};
7
8#[derive(Copy, Clone, PartialEq, Eq)]
10pub struct Hash([u8; HASH_LEN]);
11
12impl From<[u8; HASH_LEN]> for Hash {
13 fn from(bytes: [u8; HASH_LEN]) -> Self {
14 Self(bytes)
15 }
16}
17
18impl AsRef<[u8]> for Hash {
19 fn as_ref(&self) -> &[u8] {
20 &self.0
21 }
22}
23
24impl Debug for Hash {
25 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
26 write!(fmt, "{}", hex::encode(self.0))
27 }
28}
29
30#[derive(Copy, Clone)]
32pub struct Mac([u8; MAC_LEN]);
33
34impl From<[u8; MAC_LEN]> for Mac {
35 fn from(bytes: [u8; MAC_LEN]) -> Self {
36 Self(bytes)
37 }
38}
39
40impl AsRef<[u8]> for Mac {
41 fn as_ref(&self) -> &[u8] {
42 &self.0
43 }
44}
45
46impl Debug for Mac {
47 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
48 write!(fmt, "{}", hex::encode(self.0))
49 }
50}
51
52impl Mac {
53 pub fn verify(&self, other: &Mac) -> Result<()> {
55 use subtle::ConstantTimeEq;
56
57 if self.0.ct_eq(&other.0).into() {
58 Ok(())
59 } else {
60 Err(Error::InvalidMac)
61 }
62 }
63}
64
65#[derive(Copy, Clone, Debug, PartialEq, Eq)]
67pub struct KeyPair {
68 secret: SecretKey,
69 public: PublicKey,
70}
71
72impl KeyPair {
73 pub fn generate<R: Rng + CryptoRng>(rng: &mut R) -> Self {
75 let sk = SecretKey::generate(rng);
76 Self {
77 secret: sk,
78 public: sk.public_key(),
79 }
80 }
81
82 pub fn secret(&self) -> &SecretKey {
84 &self.secret
85 }
86
87 pub fn public(&self) -> &PublicKey {
89 &self.public
90 }
91}
92
93impl From<SecretKey> for KeyPair {
94 fn from(sk: SecretKey) -> Self {
95 let pk = sk.public_key();
96 Self {
97 secret: sk,
98 public: pk,
99 }
100 }
101}
102
103#[derive(Copy, Clone, PartialEq, Eq)]
105pub struct SecretKey([u8; KEY_LEN]);
106
107impl From<[u8; KEY_LEN]> for SecretKey {
108 fn from(bytes: [u8; KEY_LEN]) -> Self {
109 Self(bytes)
110 }
111}
112
113impl AsRef<[u8]> for SecretKey {
114 fn as_ref(&self) -> &[u8] {
115 &self.0
116 }
117}
118
119impl Debug for SecretKey {
120 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
121 write!(fmt, "{}", hex::encode(self.0))
122 }
123}
124
125#[derive(Copy, Clone, PartialEq, Eq)]
127pub struct PublicKey([u8; KEY_LEN]);
128
129impl From<[u8; KEY_LEN]> for PublicKey {
130 fn from(bytes: [u8; KEY_LEN]) -> Self {
131 Self(bytes)
132 }
133}
134
135impl AsRef<[u8]> for PublicKey {
136 fn as_ref(&self) -> &[u8] {
137 &self.0
138 }
139}
140
141impl Debug for PublicKey {
142 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
143 write!(fmt, "{}", hex::encode(self.0))
144 }
145}
146
147impl SecretKey {
148 fn generate<R: Rng + CryptoRng>(rng: &mut R) -> Self {
149 let mut buf = [0u8; KEY_LEN];
150 rng.fill(&mut buf);
151 Self(buf)
152 }
153
154 fn public_key(&self) -> PublicKey {
155 let pk =
156 x25519_dalek::PublicKey::from(&x25519_dalek::StaticSecret::from(self.0)).to_bytes();
157 PublicKey(pk)
158 }
159}
160
161#[derive(Copy, Clone, PartialEq, Eq)]
163pub struct SymmetricKey([u8; KEY_LEN]);
164
165impl From<[u8; KEY_LEN]> for SymmetricKey {
166 fn from(bytes: [u8; KEY_LEN]) -> Self {
167 Self(bytes)
168 }
169}
170
171impl From<Hash> for SymmetricKey {
172 fn from(hash: Hash) -> Self {
173 Self(hash.0)
174 }
175}
176
177impl AsRef<[u8]> for SymmetricKey {
178 fn as_ref(&self) -> &[u8] {
179 &self.0
180 }
181}
182
183impl Debug for SymmetricKey {
184 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
185 write!(fmt, "{}", hex::encode(self.0))
186 }
187}
188
189impl SymmetricKey {
190 pub fn generate<R: Rng + CryptoRng>(rng: &mut R) -> Self {
192 let mut buf = [0u8; KEY_LEN];
193 rng.fill(&mut buf);
194 Self(buf)
195 }
196}
197
198#[derive(Copy, Clone, PartialEq, Eq)]
200pub struct Nonce([u8; NONCE_LEN]);
201
202impl From<[u8; NONCE_LEN]> for Nonce {
203 fn from(bytes: [u8; NONCE_LEN]) -> Self {
204 Self(bytes)
205 }
206}
207
208impl AsRef<[u8]> for Nonce {
209 fn as_ref(&self) -> &[u8] {
210 &self.0
211 }
212}
213
214impl Debug for Nonce {
215 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
216 write!(fmt, "{}", hex::encode(self.0))
217 }
218}
219
220impl Nonce {
221 pub fn new<R>(rng: &mut R) -> Self
223 where
224 R: Rng + CryptoRng,
225 {
226 let mut buf = [0u8; NONCE_LEN];
227 rng.fill(&mut buf);
228 Self(buf)
229 }
230}
231
232struct TupleHasher(VarBlake2b);
233
234impl TupleHasher {
235 pub fn new(label: &'static [u8]) -> Self {
236 use blake2::digest::VariableOutput;
237
238 Self(VarBlake2b::new(HASH_LEN).unwrap()).chain(label)
239 }
240
241 pub fn new_keyed(label: &'static [u8], key: &SymmetricKey) -> Self {
242 Self(VarBlake2b::new_keyed(&key.0, HASH_LEN)).chain(label)
243 }
244
245 pub fn new_exchange(
246 label: &'static [u8],
247 our_sk: &SecretKey,
248 their_pk: &PublicKey,
249 ) -> Result<Self> {
250 let key = dh(our_sk, their_pk);
251 if key.as_ref() == [0u8; KEY_LEN] {
252 return Err(Error::FailedKeyExchange);
253 }
254 Ok(Self::new(label).chain(&key))
255 }
256
257 pub fn update(&mut self, data: impl AsRef<[u8]>) {
258 use blake2::digest::Update;
259
260 let data = data.as_ref();
261 let l = data.len() as u32;
262 self.0.update(&l.to_be_bytes());
263 self.0.update(data);
264 }
265
266 pub fn chain(mut self, data: impl AsRef<[u8]>) -> Self {
267 self.update(data);
268 self
269 }
270
271 pub fn finalize(mut self) -> [u8; HASH_LEN] {
272 use blake2::digest::VariableOutput;
273
274 let mut buf = [0u8; HASH_LEN];
275 self.0
276 .finalize_variable_reset(|res| buf.copy_from_slice(res));
277 buf
278 }
279}
280
281pub fn hash(label: &'static [u8], messages: &[&[u8]]) -> Hash {
283 let mut hasher = TupleHasher::new(label);
284 for m in messages {
285 hasher.update(m);
286 }
287 Hash(hasher.finalize())
288}
289
290pub fn mac(label: &'static [u8], key: &SymmetricKey, messages: &[&[u8]]) -> Mac {
292 let mut hasher = TupleHasher::new_keyed(label, key);
293 for m in messages {
294 hasher.update(m);
295 }
296 Mac(hasher.finalize())
297}
298
299pub fn kdf(label: &'static [u8], key: &SymmetricKey, messages: &[&[u8]]) -> SymmetricKey {
301 let mut hasher = TupleHasher::new_keyed(label, key);
302 for m in messages {
303 hasher.update(m);
304 }
305 SymmetricKey(hasher.finalize())
306}
307
308pub fn kex(
310 label: &'static [u8],
311 our_sk: &SecretKey,
312 their_pk: &PublicKey,
313 messages: &[&[u8]],
314) -> Result<SymmetricKey> {
315 let mut hasher = TupleHasher::new_exchange(label, our_sk, their_pk)?;
316 for m in messages {
317 hasher.update(m);
318 }
319 Ok(SymmetricKey(hasher.finalize()))
320}
321
322pub fn dh(our_sk: &SecretKey, their_pk: &PublicKey) -> SymmetricKey {
324 use x25519_dalek::{PublicKey, StaticSecret as SecretKey};
325
326 SymmetricKey(
327 SecretKey::from(our_sk.0)
328 .diffie_hellman(&PublicKey::from(their_pk.0))
329 .to_bytes(),
330 )
331}
332
333pub fn stream(key: &SymmetricKey, buf: &mut [u8]) {
335 use salsa20::{
336 cipher::{NewCipher, StreamCipher},
337 Salsa20,
338 };
339 let mut cipher =
340 Salsa20::new_from_slices(key.as_ref(), &[0u8; 8]).expect("invalid key/nonce sizes");
341 buf.fill(0);
342 cipher.apply_keystream(buf)
343}
344
345pub fn prf(key: &SymmetricKey, message: &[u8]) -> [u8; PRF_LEN] {
347 use blake2::digest::Update;
348 use blake2::digest::VariableOutput;
349
350 let mut buf = [0u8; HASH_LEN];
351 VarBlake2b::new_keyed(&key.0, HASH_LEN)
352 .chain(message)
353 .finalize_variable_reset(|res| buf.copy_from_slice(res));
354 buf
355}
356
357pub fn enc(key: &SymmetricKey, nonce: &Nonce, buf: &mut [u8], auth: &mut [u8]) {
359 use xsalsa20poly1305::{
360 aead::{AeadInPlace, NewAead},
361 XSalsa20Poly1305,
362 };
363 assert!(auth.len() == AUTH_LEN);
364 let aead = XSalsa20Poly1305::new_from_slice(key.as_ref()).expect("invalid key size");
365 let nonce = xsalsa20poly1305::Nonce::from_slice(nonce.as_ref());
366 let tag = aead
367 .encrypt_in_place_detached(nonce, &[], buf)
368 .expect("encryption failed");
369 auth.copy_from_slice(&tag);
370}
371
372pub fn dec(key: &SymmetricKey, nonce: &Nonce, buf: &mut [u8], auth: &[u8]) -> Result<()> {
374 use xsalsa20poly1305::{
375 aead::{AeadInPlace, NewAead},
376 XSalsa20Poly1305,
377 };
378 assert!(auth.len() == AUTH_LEN);
379 let aead = XSalsa20Poly1305::new_from_slice(key.as_ref()).expect("invalid key size");
380 let nonce = xsalsa20poly1305::Nonce::from_slice(nonce.as_ref());
381 let tag = xsalsa20poly1305::Tag::from_slice(auth);
382 aead.decrypt_in_place_detached(nonce, &[], buf, tag)?;
383 Ok(())
384}
385
386pub const HASH_LEN: usize = 32;
388pub const MAC_LEN: usize = HASH_LEN;
390pub const KEY_LEN: usize = MAC_LEN;
392pub const PRF_LEN: usize = KEY_LEN;
394pub const AUTH_LEN: usize = 16;
396pub const NONCE_LEN: usize = 24;
398
399#[cfg(test)]
400mod test {
401 use super::{dh, hash, kdf, kex, Hash, PublicKey, SecretKey, SymmetricKey, KEY_LEN};
402 use hex_literal::hex;
403
404 #[test]
405 fn hash_reference_values() {
406 for (m1, m2, m3, expected1, expected2) in HASH_TEST_VECTORS {
407 let hash1 = hash(b"test1", &[&m1, &m2, &m3]);
408 let hash2 = hash(b"test2", &[&m1, &m2, &m3]);
409 assert_eq!(hash1, expected1);
410 assert_eq!(hash2, expected2);
411 }
412 }
413
414 #[test]
415 fn hash_identical_inputs_produce_identical_outputs() {
416 let label = b"test";
417 let m1 = random_bytes(123);
418 let m2 = random_bytes(123);
419 let m3 = random_bytes(123);
420 let hash1 = hash(label, &[&m1, &m2, &m3]);
421 let hash2 = hash(label, &[&m1, &m2, &m3]);
422 assert_eq!(hash1, hash2);
423 }
424
425 #[test]
426 fn hash_different_labels_produce_different_outputs() {
427 let label1 = b"test1";
428 let label2 = b"test2";
429 let m1 = random_bytes(123);
430 let m2 = random_bytes(123);
431 let m3 = random_bytes(123);
432 let hash1 = hash(label1, &[&m1, &m2, &m3]);
433 let hash2 = hash(label2, &[&m1, &m2, &m3]);
434 assert_ne!(hash1, hash2);
435 }
436
437 #[test]
438 fn hash_different_inputs_produce_different_outputs() {
439 let label = b"test";
440 let m1 = random_bytes(123);
441 let m2 = random_bytes(123);
442 let m3 = random_bytes(123);
443 let hash1 = hash(label, &[&m1, &m2, &m3]);
444 let hash2 = hash(label, &[&m3, &m2, &m1]);
445 assert_ne!(hash1, hash2);
446 }
447
448 #[test]
449 fn kdf_reference_values() {
450 for (key, m1, m2, m3, expected1, expected2) in KDF_TEST_VECTORS {
451 let mac1 = kdf(b"test1", &key, &[&m1, &m2, &m3]);
452 let mac2 = kdf(b"test2", &key, &[&m1, &m2, &m3]);
453 assert_eq!(mac1, expected1);
454 assert!(expected1 == mac1);
455 assert_eq!(mac2, expected2);
456 assert!(expected2 == mac2);
457 }
458 }
459
460 #[test]
461 fn kdf_identical_keys_and_inputs_produce_identical_outputs() {
462 let label = b"test";
463 let key = random_key();
464 let m1 = random_bytes(123);
465 let m2 = random_bytes(123);
466 let m3 = random_bytes(123);
467 let mac1 = kdf(label, &key, &[&m1, &m2, &m3]);
468 let mac2 = kdf(label, &key, &[&m1, &m2, &m3]);
469 assert_eq!(mac1, mac2);
470 assert!(mac1 == mac2);
471 }
472
473 #[test]
474 fn kdf_different_labels_produce_different_outputs() {
475 let label1 = b"test1";
476 let label2 = b"test2";
477 let key = random_key();
478 let m1 = random_bytes(123);
479 let m2 = random_bytes(123);
480 let m3 = random_bytes(123);
481 let mac1 = kdf(label1, &key, &[&m1, &m2, &m3]);
482 let mac2 = kdf(label2, &key, &[&m1, &m2, &m3]);
483 assert_ne!(mac1, mac2);
484 assert!(mac1 != mac2);
485 assert!(mac2 != mac1);
486 }
487
488 #[test]
489 fn kdf_different_keys_produce_different_outputs() {
490 let label = b"test";
491 let key1 = random_key();
492 let key2 = random_key();
493 let m1 = random_bytes(123);
494 let m2 = random_bytes(123);
495 let m3 = random_bytes(123);
496 let mac1 = kdf(label, &key1, &[&m1, &m2, &m3]);
497 let mac2 = kdf(label, &key2, &[&m1, &m2, &m3]);
498 assert_ne!(mac1, mac2);
499 assert!(mac1 != mac2);
500 assert!(mac2 != mac1);
501 }
502
503 #[test]
504 fn kdf_different_inputs_produce_different_outputs() {
505 let label = b"test";
506 let key = random_key();
507 let m1 = random_bytes(123);
508 let m2 = random_bytes(123);
509 let m3 = random_bytes(123);
510 let mac1 = kdf(label, &key, &[&m1, &m2, &m3]);
511 let mac2 = kdf(label, &key, &[&m3, &m2, &m1]);
512 assert_ne!(mac1, mac2);
513 assert!(mac1 != mac2);
514 assert!(mac2 != mac1);
515 }
516
517 #[test]
518 fn dh_reference_values() {
519 let ss1 = dh(&ALICE_PRIVATE, &BOB_PUBLIC);
520 let ss2 = dh(&BOB_PRIVATE, &ALICE_PUBLIC);
521 assert_eq!(ss1, ss2);
522 assert_eq!(ss1, SHARED_SECRET);
523 assert_eq!(ss2, SHARED_SECRET);
524 }
525
526 #[test]
527 fn dh_derives_same_shared_secret_from_equivalent_public_key() {
528 let mut equiv = ALICE_PUBLIC;
529 equiv.0[31] ^= 0x80;
530 assert_ne!(equiv, ALICE_PUBLIC);
531 let ss1 = dh(&BOB_PRIVATE, &ALICE_PUBLIC);
532 let ss2 = dh(&BOB_PRIVATE, &equiv);
533 assert_eq!(ss1, SHARED_SECRET);
534 assert_eq!(ss2, SHARED_SECRET);
535 }
536
537 #[test]
538 fn kex_derives_shared_secret() {
539 let (sk1, pk1) = random_key_pair();
540 let (sk2, pk2) = random_key_pair();
541 let m1 = random_bytes(123);
542 let m2 = random_bytes(123);
543 let m3 = random_bytes(123);
544 let ss1 = kex(b"test", &sk1, &pk2, &[&m1, &m2, &m3]);
545 let ss2 = kex(b"test", &sk2, &pk1, &[&m1, &m2, &m3]);
546 assert_eq!(ss1.unwrap(), ss2.unwrap());
547 }
548
549 #[test]
550 fn kex_rejects_invalid_public_key() {
551 let (sk1, _) = random_key_pair();
552 let invalid = PublicKey([0u8; KEY_LEN]);
553 let m1 = random_bytes(123);
554 let m2 = random_bytes(123);
555 let m3 = random_bytes(123);
556 assert!(kex(b"test", &sk1, &invalid, &[&m1, &m2, &m3]).is_err());
557 }
558
559 #[test]
560 fn kex_derive_same_shared_secret_from_equivalent_public_keys_without_hashing_in() {
561 let (_, pk1) = random_key_pair();
562 let (sk2, _) = random_key_pair();
563 let mut equiv = pk1;
564 equiv.0[31] ^= 0x80;
565 let m1 = random_bytes(123);
566 let m2 = random_bytes(123);
567 let m3 = random_bytes(123);
568 let ss1 = kex(b"test", &sk2, &pk1, &[&m1, &m2, &m3]);
569 let ss2 = kex(b"test", &sk2, &equiv, &[&m1, &m2, &m3]);
570 assert_eq!(ss1.unwrap(), ss2.unwrap());
571 }
572
573 #[test]
574 fn kex_derive_same_shared_secret_from_equivalent_public_keys_with_hashing_in() {
575 let (_, pk1) = random_key_pair();
576 let (sk2, pk2) = random_key_pair();
577 let mut equiv = pk1;
578 equiv.0[31] ^= 0x80;
579 let m1 = random_bytes(123);
580 let m2 = random_bytes(123);
581 let m3 = random_bytes(123);
582 let ss1 = kex(
583 b"test",
584 &sk2,
585 &pk1,
586 &[pk1.as_ref(), pk2.as_ref(), &m1, &m2, &m3],
587 );
588 let ss2 = kex(
589 b"test",
590 &sk2,
591 &equiv,
592 &[equiv.as_ref(), pk2.as_ref(), &m1, &m2, &m3],
593 );
594 assert_ne!(ss1.unwrap(), ss2.unwrap());
595 }
596
597 fn random_bytes(n: usize) -> Vec<u8> {
598 use rand::distributions::Standard;
599 use rand::{thread_rng, Rng};
600
601 let rng = thread_rng();
602 rng.sample_iter(Standard).take(n).collect()
603 }
604
605 fn random_key() -> SymmetricKey {
606 use rand::{thread_rng, Rng};
607
608 let mut buf = [0u8; KEY_LEN];
609 let mut rng = thread_rng();
610 rng.fill(&mut buf);
611 SymmetricKey(buf)
612 }
613
614 fn random_key_pair() -> (SecretKey, PublicKey) {
615 let sk = random_key();
616 let pk = x25519_dalek::PublicKey::from(&x25519_dalek::StaticSecret::from(sk.0)).to_bytes();
617 (SecretKey(sk.0), PublicKey(pk))
618 }
619
620 const ALICE_PRIVATE: SecretKey = SecretKey(hex!(
621 "77076D0A7318A57D3C16C17251B26645DF4C2F87EBC0992AB177FBA51DB92C2A"
622 ));
623 const ALICE_PUBLIC: PublicKey = PublicKey(hex!(
624 "8520F0098930A754748B7DDCB43EF75A0DBF3A0D26381AF4EBA4A98EAA9B4E6A"
625 ));
626 const BOB_PRIVATE: SecretKey = SecretKey(hex!(
627 "5DAB087E624A8A4B79E17F8B83800EE66F3BB1292618B6FD1C2F8B27FF88E0EB"
628 ));
629 const BOB_PUBLIC: PublicKey = PublicKey(hex!(
630 "DE9EDB7D7B7DC1B4D35B61C2ECE435373F8343C85B78674DADFC7E146F882B4F"
631 ));
632 const SHARED_SECRET: SymmetricKey = SymmetricKey(hex!(
633 "4A5D9D5BA4CE2DE1728E3BF480350F25E07E21C947D19E3376F09B3C1E161742"
634 ));
635
636 const HASH_TEST_VECTORS: [([u8; 64], [u8; 64], [u8; 64], Hash, Hash); 16]= [
637 (
638 hex!("44EE2E7DCD5C33C19FE601C1B38C1C3068409D96E49BACD0E093A2091EB5C734B9D0290092E4CDB0EC9BC81F30E0489916631EA66BCAB1A4679845738BE7B580"),
639 hex!("A2E238EFDE50E694CFBE2F1C3B16148880AD49DBAD459521E09B44D24FCAED47DE5884EB984EB34839A131AFAA1BA80735314A155B9E25EC3E6925961A9C8BA7"),
640 hex!("CEFAE5AEDB84593E40D5D6A3A98410BA87B624479B4EC82BDB695D2D33E42F4DD66E2F95742795A09F8D085438A380360E51C65185F41962F28D19B7F370001A"),
641 Hash(hex!("8BB5C31F5A540872FD3E8E3874E7CB2C4B3D6C5DDA969195D7B285A4EEDF5713")),
642 Hash(hex!("5D095D88F1013E6F72BC6DED575F285B3A87323E4CB5F7D12C11BD887EED06D1"))
643 ),
644 (
645 hex!("DBFC6A076B5FA5DC82AC0AAB28B5908F6C7788827C5CE554F4065989331C11F7344F33BB69A2B7152DE0436F2C2CBD6244BBC00CFF7C5DD44BEB9E624A8D4ECE"),
646 hex!("63ED19DE0182B65080E3D28207BD8683561D71C216752545F4D20F8F3615787B6184256004F74ADFEA6322A35BB06F710D0DEDF61E745F5421A0EA9836BFA83A"),
647 hex!("2ABB8212FB0599027CC274F3A12367A7171085DD683CA1EEE4FE9AF59B64A07D40EF1F019F01EAC36D642183A34F3710E8C6D12DB80DF0BFB73DAB064ADB3F31"),
648 Hash(hex!("0257D05D007BC15A80A3EE8C9B02888BE0654484F678968D8D2E786A8C87B6B0")),
649 Hash(hex!("A11D3ED4F623AFBD9F03468E39B07DA732A9732101F7423F90263F025474412C"))
650 ),
651 (
652 hex!("EA30E266DDCFF498F7EE84DFB314E2A57EE23C72C06CDCF25EC47C3F02CA743C950AEDC47185E521306BCD877B8295697E16ED2DC68BF01A9751FC9E3ADF506A"),
653 hex!("B962AA68A422AE5A09E32283770F3A9FB91502D56D5B840DA8EAAF7A1B8D5779EB62EA39B6D68543EA37F279968E4645F6793EE33DBCED637C6996DCEF4143EC"),
654 hex!("44A6C3051ABE4EE363027C401C251147C162E210339BD287642DE47E930FA012E265F64BF5D4CADAA6D23EA420C1FFDEE9E9C4E9408CAA4D95E30074F909FD67"),
655 Hash(hex!("AF612B99B64F509183F472AFF082342A708E224F1F0A1F5E97BD61982639B33E")),
656 Hash(hex!("461918BA348D96997721FF83D5D7C4030A9F0CE7796CC8C37D3717297DDC5932"))
657 ),
658 (
659 hex!("75CFDDDE303F4E0E840E640627A52633DE48A66923861B9E1204FF9E3546124037720A6FE2CF964737950BB3FD3FFE7A1F3024741FC8813EBB3A70BAD26C2A57"),
660 hex!("DB4BE8EFAE9FDB4CE5C8E1F8F8A27D04A02D5AE67C73F00F647DE1D4BF765C401177CA08BFAE83DB7387F344D389618D064206006EDC0197376EF36ED2FB7AFA"),
661 hex!("8E0775C7F49B79D66BF9DDA31FD0156E37737F631FADE2A03E80BE3DF55C39CB8CA679125E4735727BC2E7F7BE1702FADEB0EF712B304331EAAF7EF1A5520C34"),
662 Hash(hex!("8BE489F466D789F32BC407A5DEC414EEF0606CA774F6B30237FF3B761CA17B86")),
663 Hash(hex!("B1E97A6EADA81E43E1ED9B716588E8655A82AE1B14E66B9508EA6EE3B27EDABB"))
664 ),
665 (
666 hex!("81BBCAB8241EB0155163E3C12C29C6B3116C61110A091019E54BAE3A881A6E28FECF8E4729660D4FA77E6ED7E5500E294742FBD7DB1476C289BCE8B319767C64"),
667 hex!("09D9E8C4B69AE63736C95692C8B206D1480F8BE3018453577AB47D7AF6C510CFEEC688D063D7E3E8E0D594A8DE81B29A13E70DA0DD90527F9C5E2E9E01C200A8"),
668 hex!("7E1A62E8F957F882ABA5FC9E812EA76E6B724E8143E5FD0438925D03AE600A9D8EF1F306F8CA4AD541C84735E13C8F3E574351E8FD94CBBE7A7BCB6788951DBD"),
669 Hash(hex!("B67C87EA7B93AC2780F998D4052B360E39FEA686B09C55D496B97E523F8D11FE")),
670 Hash(hex!("A77777FB5A711565218A42D8E91EAACF704776F5BFCACE2DD3D05C6AFC4F61D3"))
671 ),
672 (
673 hex!("986D1D67AE1E581EACC0B1B5BC2926C05EF7B7AA51F67CFA14ABE67E4D28F046D0AF687466E0B5608883F8EC3A5EE5155A65D6EAC10FA8F4B8BE5B752E71FFB0"),
674 hex!("0439A9F289AB98DC41A4618F7B7D9697B04731442EF925B89A63B0612BD376FD9F23F8679AB1145B33132D6A54F0ECF139E231B7A6F58038DBFD6310B04CE67B"),
675 hex!("0DC20AD1CF95C59B61E25DDC6CCA1A6D15AD1A9A28A163427E09976940E01BB93F1B1810926F5F80F255B7F9BFD06365281978052B9B271EECB2F802F08250AE"),
676 Hash(hex!("99FF047DCA092824F7E83993A25A5C748643DD2A4801999A4649644251DBEE9C")),
677 Hash(hex!("1FC2F1CFCC75F0870027C58B271CF23ECD86739D0EE46661C1BF1176B0959DAA"))
678 ),
679 (
680 hex!("47FBCF0D756529708588ED3EA74383D6517FC7AEC5B8A204BC858B4EE94D14F51557D927ED6B92B4083F5996574B51A381FF1F010B8B2F7F63B6DE1EC3DF12D0"),
681 hex!("93801D48A7F132C2EE99A24679F2C1701C265A872A0E1C8F5CB4FB9EDA60AE05C6802FFC90E8395D917FDE1B2BC6850D59F353875C60B10885BD1EFAAA6CCEA8"),
682 hex!("39503B53CCD5D4246E3BB7A4E2BBF7CF324BA5294EB2B03C1E2328D640B8D20578C3FAA73284F3A2A97E1E49E5675AA2E829A7ECA0A18FD14AD29D79BC30DD07"),
683 Hash(hex!("610C80BAE7A922BC0FBB021A5C943581CF931A513AE7F89D2B54F37C8477EE2B")),
684 Hash(hex!("12649D9C636378ACC43E0A3F6346133A5054FB870F353A4A9849A24437C16EBD"))
685 ),
686 (
687 hex!("A22E18B8578B514DF14EBF6811C5AD293991517CAABEC25E61F0F83D575C63DF3C4C068BC77CEE1BF71EE9D56D03710226443B91E7D62E3E88F117419B74CF0F"),
688 hex!("FEA19B0DC47556B94BED048C7CAF105094AB76FB8FC6C2F0BC6137B516F115BD0A5C8C2827832F22C21E9EDD2999A4B99580EC6687093E9213E9B10DCB90D3F9"),
689 hex!("855D24B67F36D6AED75020933406D0F8821F3328A6B7AD8B8BCEFABED69111A1179D7DDF8E089EE0284AC0F5B118037D742C7EFF398F40878370553FE4FFA690"),
690 Hash(hex!("B46CFAF84D30B021FBB6033AAF496E7CBCC20B7A436B2D5847D356DE2BA78451")),
691 Hash(hex!("FFFBE623632C26DEC80D8EBE8EDB43B7149EAB2CC6AA68E58850C8FE9438652B"))
692 ),
693 (
694 hex!("BDAD3373E36EB230A90DA1B3F09A9FECABD2F22B34E3E4806A9BDA94A25C8AFF36EE5234314FA18D4B8753E8FE960AE47AC3AFD8F9DA4B008C72B71F1289B1B5"),
695 hex!("94740051495B857608F8392E154EE9FE648A9954ECB772DF9783F970026BBEC09334A15C72C56FB4B4BBAD4C6A213CE4D705390E1F86A9325F61A0C3869BBACC"),
696 hex!("75B0D0BB2606670244CA793D8B45DBF007874972174787611D59586742E8E00E7FC5CA4294EE2D1454983CF8D758D6B56BE6A2594BACFF27EBDA49AAF0D1CF80"),
697 Hash(hex!("FFF6BBFAA68236E2F863F6507552371B3FE5309FCED0FC59AD7B6D681E341066")),
698 Hash(hex!("F01C5DCC21625B8314E40D54F216FF521394E81567CEEBECC6632CF4A3BA2C09"))
699 ),
700 (
701 hex!("333268EEDED5D6498BE79F87918E2148FF30BF4E10A80479A14E16666D252650FB1B606F1A3965E89B85FD9863A98A27F1094CCDD6FFBA57B45BE5C293E231B9"),
702 hex!("27CC2CACD2E18222FACDF212260101A49C357ED043A33E4431EA16C65A10477191126E093AE2E1EAF77B1615DD06C0A84A94455C151137FA28E87C5A5F084822"),
703 hex!("153517A73724753683DA56E862AC88098B589802FBE6952A8DA93794535E3322152CBE2BE52B8883B594D62ADE2AF9C8B28B29B11A4C5833B840BFE17E8EA14F"),
704 Hash(hex!("B58741E3E6A2330A38B445390E1B86D14C1D9C41AB714F65432FDDDCBE9A5E6F")),
705 Hash(hex!("185D7BF10CD25418E4B0E29BA4423314E19A8E3F089A3D45C8DF79BFE7EEBB3E"))
706 ),
707 (
708 hex!("A1D09520C0DE7752167C26A412D3F5B4D02081FFDA3E0CA0B5F437EB6D40196603ECCF44A6CB0942A51477E6452EE3DBC34F3D4C89E801B9ACEAD30421C8E28C"),
709 hex!("8DA0B8D9B036180A9A70E6036682441B900017DC8BDEC326B1092914E9C2778BB41E81477B7CD7164003F22AC6FE2D24DE614F01C9A4CE0E90FBF1626F61CDA6"),
710 hex!("72046749DA32DBC80453F7F707517E9E19E44E5DA0D71B287B0B15B4F0639C6EC3095BD7549B08B6F8B94D7DA29BC834EF2DBA646146B931856EC9F1BEF86338"),
711 Hash(hex!("204494CA7BFCAF12407F8B99684EFA6D685AD953515535FB3827998F6E9C02BE")),
712 Hash(hex!("6CBB199BA1E1C8BE18CABF326291D3457610EAE9BF5A093C2BF33B244F54E832"))
713 ),
714 (
715 hex!("2950F9CB3642D9ECEFCA1D92E7E23DDA7FED194BA66243DCBA360DE7EB1F8294CC732B50B0C48655CAEF84872577BFB26B385A5D0FFCD7D30204E3E6D167E7E7"),
716 hex!("1F45FA53661604FA8592F200E24F7097574EA05A2D8E02F7A17547DD139A2F74B349DD57E5F8BE8AE826907B3B39603BC6683EF093E4124C9F41DFDAE50445C6"),
717 hex!("1D7C0B986B987B035C4720A21FCBBB2B80025A48CAAC9EEEEA8A01AD922B0F2B7768ABD369AE6BFA6F65D790D28FA2170F3CB184CF40D853D1199B9EF7D4F40A"),
718 Hash(hex!("DD4FC490E3C5E32156262FEB6DE7F3ED8D9D303A593B040888D4AAF0F140C383")),
719 Hash(hex!("1CE8DC7A69756F681DC1FBC1DAB3BCAFB8195DCFA2FA7A2A06727BDAAE9C4497"))
720 ),
721 (
722 hex!("F291FC88A06482E560A7720758AD114DAF18C1887A01182EA6A75E2145A4A711589F880A41D035F58FF690D3D690C3AB29A21E3DDDBECA59A94E03504C8CDB3A"),
723 hex!("3BB0BF9A2E3E1B4FFCEAE4E57939CE134ED176D288AEA3AB70EC62584BC87DEFC703C5895E9F50BC6C31C7E8A91EDFF2FB1634E53CD6CE89C083BAC0813A9268"),
724 hex!("AD65C638FA5060C3C440E16E2121D6C7D53449A02EB7C2EFC1DFD7F1C6EFFBDEA3BAA713E2EE869C8EFA06BE72E1A1FDC211B9A086C8003E7EBC1C88025E3836"),
725 Hash(hex!("046A6A69C032C3472A65B155D772E04999372F6EF7CCD9EF7A2CC25DDE38D350")),
726 Hash(hex!("F179B2CBE004B5C65466C33406E741A9A424A932F46B3065D6E122161ED94A4C"))
727 ),
728 (
729 hex!("A408334992371AF6D6BB4D4DFF137EA3C7C920C7D0B5667BD37FF4136CF171BCAE18CE401C1AB9D11C208FBBFFF0CC3A828516B457FC8B4578DF46E450A2818C"),
730 hex!("C4D2579474ADDF556419BB645D3ECE0194DA2EE06FED52FEF2F2EF5E9BD0FAF32F04C7AF7D8C3C80EDB5FC9A4E5DA844B90D6DB3846B2121413AA2A61999BBD3"),
731 hex!("3C2EDEDDCC8FA59A99019458D80583C7F0D3D8C5F73DCE0E4AE9C4A5AD8861FCBC8204272E5056D66F96B2D059CD43D4FC969A179D3B357D5400B9DCCC0AB8AB"),
732 Hash(hex!("DBEF9E5AF1C30098BBA277B16BB0809ADD34F9360BA58E304FA8C194084F15FD")),
733 Hash(hex!("36733C9CC5F84229CD8F13395CE917C79F1ECB20FF001CE29517C14F094F6040"))
734 ),
735 (
736 hex!("EE3FE00355EB6B02611D8C144DB8603A754D8DF71710A95C82E8549F659445A3573FB3F434AF5469BEFEA4E29C736A81BCE4B50E58C00F2DAA74CDEB2E0ECDE3"),
737 hex!("9FFFC9CE58B71440C51867BF97BA705B8DB9AA64A753122FDCFFCE03210CB89CAC20AB660E739FB0B0F3B428BE46A185FEF0F3689CDB0C10D5A7CF2217BC356B"),
738 hex!("E72DFE29DA303541DCD8A4D5E465E9DCEC4F5FC443883AAEB4B991737D51A9AABD0A04BCF25024AB4D532248B1B02CEF75EF42939D82473B7DBA8C40D6A30545"),
739 Hash(hex!("66ED10E4935150D14BD8731BCFCEE098C62B91740501DC5D658ECD47ADEDCB23")),
740 Hash(hex!("16C5C00FB0015C7AD4E79719661061E68D75DE87CF22C664D3CD89114876344C"))
741 ),
742 (
743 hex!("0274A6756670DA3B366F46B60319D7D228A5D5FC30B0AF1654D7E913CAF85646E02FDAE732AFC08E67D321807CA8016165CBDBCCAF20E0375E417A3D4BD11E26"),
744 hex!("3663592E2EE415BA4D43664E81E4B7D8612B2EEF6CBEAD6E4B37A0A78E7F5BE504351D01932DC47A9DC9B6BC607DAA691047E3AAABCC4F7A13855609F7489494"),
745 hex!("50FF862C4FFA985BB285F1C838456D6AA97F9BEDA4B6F8AB92315D54005E637FA32BAAB187ECD216091C18A47B1682D6273A3C3F059A4F76097768ACB7A8B8B4"),
746 Hash(hex!("B878EEC15288593F91F2DE899061D26DAFD8FACEC4570D1BF70B251B5C77FA04")),
747 Hash(hex!("CEA2750E11D569DA1D5DE8C549646A5CC608207321A84D29A198324DE6E2A087"))
748 ),
749 ];
750
751 const KDF_TEST_VECTORS: [(SymmetricKey, [u8; 64], [u8; 64], [u8; 64], SymmetricKey, SymmetricKey); 16] = [
752 (
753 SymmetricKey(hex!("011591346B2B0239A076F8F66784C0571624ABB4A4F0412EFE39B9B962B6E6D0")),
754 hex!("76F4050C3EDC2E34FF137D27966CEB31DE03A60ADB02214367689A2713ED64A0DB6531AF22292B0CB74460158DE45304B0268543D3B6BE3DAED7B8B494E160CE"),
755 hex!("7C7883AD1B4733FD125DFDA107CF994B9C0EB5CD286AC621AF813605CA21687D4D4B1ADA006CDD19A083306BB6ADCF5296232F1A8E349C45CC927ACFD15591CC"),
756 hex!("64DDEEFBFE9481C7B335DDFDBE0BCCB7F60BD3464996EAB56AB64B6877D269A57B6E9BFB139D636CE4DB108C38B84DEFF89462DCB476C7C2727337B6BEFB1282"),
757 SymmetricKey(hex!("528FCBB00BD7D3EC03EC27C2290E42730A9ABEF834DC2D6BD4DC8C44AEA3757F")),
758 SymmetricKey(hex!("356C1D3D4106ED4066FFB6550A0E77E323ECBCD336075407CC7E34FF3EC0C9D4"))
759 ),
760 (
761 SymmetricKey(hex!("6F6F5D7293A399C78C6E33D8B1D07CC23D2BE2DBBB720A74D198D8A25D77B9F3")),
762 hex!("C3023590A7C2E8AF4C2AF802A89B92A649E35F4D607BAEFBF8B9CEA0402FD0CC1E0D4469C91512A48554002E1333B25E0312630039C4587E5CBB78250424B915"),
763 hex!("C8D5CEDC4A104AACE10F6271DBFE3B8F37758634F0015FB3F76EC4057C0FC65D31378072CD23D489C84085765BFF25C917ECFE6EC2F8E6EEC540A57D2FD7BA8D"),
764 hex!("6B5FD3BCC9B6FC16EC810827E5E7221BB6BF10D8015BF92148F3034AD7CE3B1CAB20C5090A6BEB06BE28A0423D09A2658C7BB51992F7A13D056C39A5E3CAD167"),
765 SymmetricKey(hex!("9EB06394F343E046D75D94BA8D5986FF7C3A8FA8C98FB4E264BEE7E48BF7D2EC")),
766 SymmetricKey(hex!("68C106D4FE6D9F97E46F9B0C4DB6B7F44A49D6E25CF8087BBA9DE9469509C155"))
767 ),
768 (
769 SymmetricKey(hex!("CCD12E6D30B407EAF659215B1C0CF285F555F4DE7038772F05906626F6026E05")),
770 hex!("CBBE6C7A2EBEE9780F2E2BAAAE7B10ECB128AFC127F1225F55303B7C66C497054C293255CCA311ADC8E51F701420F05566F9E5AA597DC62D8606FEBBBDF4AD8D"),
771 hex!("14D9AC1B26F5DE1BA42E6010E328403A1912B3673D2F54792DC1E7853C64E6A58D3C5A0E2C8E825D6B77FAEAA427FEE3B9A9817B1B0E388F6420239053F0F4C7"),
772 hex!("4519304420BDE406A754400852DA5C5F941C4106D1E4E94A482204422A76848D6FCCFA2B1AB9B9E228F5F306DFC5C91FE0B496EB51A04256793F48E91C95EBD8"),
773 SymmetricKey(hex!("5BB3797B7DB0B7B0F59E92AD311E8EF6C426210A50CF7FF3EBF91C90941EA891")),
774 SymmetricKey(hex!("52FE75CEBEEAD67369F25C7BF062D08F2BC345550BC18E695440A519C5EFBD07"))
775 ),
776 (
777 SymmetricKey(hex!("601B139687683EA380A6FF61AFA01BB63403504621FEAEA29DB771BB3641C7F5")),
778 hex!("1394CD83A677573B8869E90E1A8D33050CC79799D98A993BDCED8F45BC25657AA67D45840ABF0C6BD99674AAEE239B224867AF1FA8F0A58365D50625A5D72726"),
779 hex!("DB5865F81BFA9AD0549323E5EC4EE977ADFA2E0CD09597C7E86D27E41AD84E9498F04E3294CD95FC9B948BA547F3F7C862E00D96268BFDD21B50AB9DFB66CC5D"),
780 hex!("67FA8406061ED49C9575AC62286C347A75E8F52393CAFDDB364A659A5A251330F646780F54B620CFEE9ABE8C2CD594D1540CA30395C5D9AC760CB974FD870572"),
781 SymmetricKey(hex!("ECC1364E68A666A16DB6EA3EA3C5E0FF2D35DF7FEBC300F1828B1E679302BA62")),
782 SymmetricKey(hex!("2729F34F8D21EEEC33AED8DCA5BBEB28268775A0553D61627FFFC2859BF1D3AE"))
783 ),
784 (
785 SymmetricKey(hex!("98825A96363EE91194E72877E424FCF354B751ABBE43066B9DE5AB6DE019714B")),
786 hex!("C38558CEB68065163BC1901A531717102E9F7DA23491F0BC708FA087B18EBF4690359ED1B502F1ECDA24363274E8FB7E7D2C73D530FDCA58380B10AB53A5C74F"),
787 hex!("3FF4C59967E990A12CCB0DACB2DE16A2417375457FA8FA37428ED1915BDAE785B0A195FFD330E063305D4B1F6EA52DED5EBB7ABD04A400C45F7EC37596EAD432"),
788 hex!("EA2B2BA85432DCC2AAB84D017D7783DA1E99C171345FF852657EE7878125C63A97AFFAA71A7B4B5AA0441F9DA719687EAB95C03698660533AB8A4305CF8FE985"),
789 SymmetricKey(hex!("700C011046CA0481CEC14B55387B536B2D901D3FDE4D2DC1BE4A375E8F3C6EAC")),
790 SymmetricKey(hex!("74555D7AD903304D604669B6311C1A59DDC0F9EC35ED26A7A6EF78491B114DC9"))
791 ),
792 (
793 SymmetricKey(hex!("8628408EAAF2B88CDD55FC6529A5BB0E9667324A4F724A5591251A57E7D54936")),
794 hex!("29B2C67D5A513D8A71A39119342231FA53BB407F89C44362F6934B0C640E90F8155827F2D6E690F12ECBE44A6CF2591ABA8B0FFD0DD89EA2C029F2A1934C4B61"),
795 hex!("8476E1D29EB01FCE2DE6185B690BC422880A2BA5B45EE9B058A68B01F802A813D6AAEE7F85C01993482D81993901B5AEDC189AA5EB8FB1592BA14153C935C161"),
796 hex!("0B54B49533F3B9F89DADB340DCE04B36BA4F97B035C7F1682A062343717DF5314BA37440A4F63C4E110D8E4AC7DA13C38B9832D2A772E1644AA260200FD9E937"),
797 SymmetricKey(hex!("195F0471A8CA586906EC9C238A926E0E9FF89AD86A8C651D0421868457E5070E")),
798 SymmetricKey(hex!("FB335CB495AFDEF0E3B5957E42C39EC53D183177376EA27974005E6D6478398B"))
799 ),
800 (
801 SymmetricKey(hex!("5E3CA119A8A042E8CA5E5EA162BD51739B555DE26B51855F05C0DE4DF55024FB")),
802 hex!("3466B1B3619593D0B407A2088A3F96BA9A1A23203D029919D8D3AD53296968B85FCB5D2BC73D85C1FEB20C340F1B5FD51CF51099F1E1ABAAC3383C81E7633FE6"),
803 hex!("94CA634F270E76C49A56C9E737F7D01419450D9EEB398BC3CCFC52781C5456082E573232A01C1C80C04727A93A23D47E6D2522ADA5BE53697CBD2F29EDFF9B88"),
804 hex!("AB692243A507A0606B5F257BC3201EBE5964FCE52C5EC4B860944DC02E9348802D001D5F7E2CBE48DA2E8D5E75FEF184000C2155A45EACDA8913AFC6EC2139B6"),
805 SymmetricKey(hex!("8ECB6605E812672F9049F0678D4106152E208BDA35DDBCCB1BE2FB2C7DC457B1")),
806 SymmetricKey(hex!("2C91D48E7CDCC192FEF9E582A0356503D8B0574BCAE15F56DE09459F6E901599"))
807 ),
808 (
809 SymmetricKey(hex!("F9AED0A2C62D6868114490D16482A154EB7A1B20C0CC8ED30D52BB3DE4FA489B")),
810 hex!("FBC0D82AEEC9A02A567E195798241913860C26E34A3AD541840800D009CA92B841E87758B9018CE9B47244228ED900F7A1510F5FA1CC2B6F8BBD6A48028BC3D6"),
811 hex!("7C7EC8A3BE8EED3C7BE0AC5EB6AC3B1AEFD85DEC369BE0524402CB61A94BE9208255847EEAA98F44BE358832F62AD0718A87F4060E5E6044D4BEAFA88DBE67A8"),
812 hex!("CE17C64CFB214C45D323BB83259D83016D81B9AB436C2A26E48EF199719DFCFAFE38660306C2B14CD7435DBD9112B2E0F9A10130830AD6C2212E7C60CBDBFDEE"),
813 SymmetricKey(hex!("733868886319C986D13AD1FEE05F54751EC5C8E8DBBDC30ED84E0A39C3ED107C")),
814 SymmetricKey(hex!("A8E27921FD3A372AF337E646001B5953A9B869F9A2E6E370615920406581FAA0"))
815 ),
816 (
817 SymmetricKey(hex!("5476D58DF107805427CB5C4F7A3B2D0D7184C2B08F0903EFBDF4289546A93B65")),
818 hex!("36E796B7F92A738CE84F346694132C187D1CCD35BDB44FC4EB63BC2B40443083AF9DBBF72E721A06819DE464895C9570ABDE922B7710AEF266C258484C9C67D3"),
819 hex!("EBD60127F2DAB2FB1C99A4FF75E82E6DE97837E4BA68B2B6EBC8F710B2C448CDBFBB79DB7E0F40502836F97168B47B400D1BF166982FB57CBA5EBDAEEA36AB80"),
820 hex!("1EB1D1DE5DAD5DB4D97A272FE8D252AF4D4FF9F2B62BE2991966359B25E5E184A538ACF6EFDB8210A79432986C2679BAC7629041CFF68ECDD198CE05C41C26D6"),
821 SymmetricKey(hex!("87B782BE12D27200F64704860FAD745ECB9B3C26F163833691CCDCEE42679162")),
822 SymmetricKey(hex!("C37666B9C23C4D82CC632D156ACD19C37B124A9040C15F73157C18E4B1F15DA1"))
823 ),
824 (
825 SymmetricKey(hex!("1061A100E832B272CBFCD7B6E2EBC76AFA5DD5C02FCC726EAF742496DE388CFF")),
826 hex!("C2C6CD35CEF0CFC2C5AC3BB92915AA964B8D74B738A799400438EA0FBF24ECCA422411447E8118EED96236EE9873FAC682996E7FE1B12CF226EE886563AE67B3"),
827 hex!("B8725ECDA754710F8CF6774E76B28C584A307ACC31036A26ED8BC296FFA87882749ABFC74D048E572CBDEF327F21EB96B43CC240C9AD65C7361CEC5079DFB0D2"),
828 hex!("68B3EE2A48CB231D46FE2CB5664F13D4B4AF0269581E6E1064FC90A6EBD695AEA9D5A652C24BA58A2E78A95A4D743B70A3D8459724CA2D64DA28915C24614225"),
829 SymmetricKey(hex!("4862F235EB4FEED6EC8CEF9D149A9CAD57373FCB817AA498C055223B36020D2D")),
830 SymmetricKey(hex!("8DDEE6A05669559D5EEC9B385187922272C5186712F4DEE6ED2701CF69823360"))
831 ),
832 (
833 SymmetricKey(hex!("F2790E7FBDA540D47AF42F184EACEA5BBB4DC4F9882DE48A82990C3B26FFB779")),
834 hex!("206ADDE68BDD19BE87ECD06EF601EEDD9E64A9B9701A506649AEAD88A9130A85B74120E15492FB7FF33D1760C448F44DD03ABEE3DE562582A0AB245797E5CCFE"),
835 hex!("5B7EBBC69304F8C021EF6E3BAFC7DA03384E3D5B698B2729FD46E68F8E7272A25820104E996CB47AB803F0D29DB3F4F2A3A5501DB98144D058437FC061117F93"),
836 hex!("1CDB634D09A158112461FF79ED79D7474189FCA90CB347BAAE1D0F7E97E4BFF5B7D5EE025A0D5DD214C3774CEEDA75E626CB787DB42601B082C9BBD7EB1CED69"),
837 SymmetricKey(hex!("48649FC12281CB1A2D44D9EF3BBD00B44886DAC60A4BB9052F8D5251C4C3E29D")),
838 SymmetricKey(hex!("456E268BA37FCEA40250D504FC2BB2F9C58CD94F3993D363AE9E0B03A6371706"))
839 ),
840 (
841 SymmetricKey(hex!("62FBB03B59F8B059FABF4CA165D493D5CA9F3A2397A0F989577D30B8CA0B6202")),
842 hex!("F5DB70F4A41AF3118EDDD9370B5CDD7B8A063192AE1F0E12378F7946D805D54E6E1C865A2F85B6214BB54FA30DEA291225C2F52F86AC8C742F61CF4E6B153951"),
843 hex!("71775164C3D70D9DF128F1B38BD3B6D53FE1F40EC277AC11D05D227C0E7D3389C34D84937AC7D6BF01A7122219756254E1D6CCB996487B01B0047AB3000ACFC6"),
844 hex!("CEC699D545F57F4A447F0D8B402D32A4F72269244E3B9A05E7067932B3365720218123E1661443D8454799E4FE26AD76D18A9929C5CF63F59373982A4D1D853A"),
845 SymmetricKey(hex!("9C935A745728ED8FA999EB52EE5C642218C29A7B89505B0BCC8DE3F0805FD7DE")),
846 SymmetricKey(hex!("45E35694EED05E2D405AE3C53A0FB8DE4C17DDD1CA0384E1B8891691C921AF10"))
847 ),
848 (
849 SymmetricKey(hex!("EDD2CBE0F6600D2BD24E3DE742F4D5BFA2E12752EE4755EA54F4EB722A3A680D")),
850 hex!("889A2FB7606690F67F24CC9471F8CC170461AE804F56D593D019819257FEB473EE9EF1A8E41535A9222A1BECE4A265157391B083811CB22230B8ABD51932631D"),
851 hex!("3B80A9C4152DEB0E5839680F6779389FCDC2B87DB279F02DA153D1586527C6F1323890F25CEC0E6FFF571F9FBCF2FB97D8147C8922A9C6CBD59C85F365BC8888"),
852 hex!("B92A0C30721DDFF3BA7CF2CE16212E5ABC0F47FEA930DCDA7FFD09B7F92D37245BC67E1DEA693DBF716375C79F2C592E85CC343F301F2921DB34824333BA4084"),
853 SymmetricKey(hex!("26B31776AEE6E241BC3A904E9A6CE722B0C54B192F8BBCA1DF6A2FEB1536175E")),
854 SymmetricKey(hex!("47690A25891F3B96F5F5A9160776DF84A2406DE32A98F11B98B9475F365AEEB0"))
855 ),
856 (
857 SymmetricKey(hex!("C5B4F5AEA501B30DCE71AF3AF29D7C46A2ADF20D339B0E772304708FDA129BF7")),
858 hex!("499BA1825B91F32DC0AB55AEA17865D069A712F046C182AE1BEB47DDE89F71545E6B341A198958E0FCB79EE2B025FF5F91182E548DD2694786F430830C928ADC"),
859 hex!("1D4389F6BDB20EE777F4E2E8182EE749B6325BCA42B3764BAE9241D929C54BA1C6DD375F7C18F02CED9A7AF145C5CD85D8F2B6D132B92CDDE08BCB1AD57289AD"),
860 hex!("3994F5715D3B44EE5EF58B9499236D57DCA9057340CADC1EEDF68847DBB488167EEDE5EFBC99E0BB8BA2BB5DE7B0214C0A15AC1EE1CAB717AB47BC19B9D7DF18"),
861 SymmetricKey(hex!("D726E36DCC8CF5E4CD1DEEEC85D92C11095CA7BC8A84957DA21071888D72B02D")),
862 SymmetricKey(hex!("B785AB54F3524F64B92189C1269ACBBFD6142668716979C4104C14E5D76D7EA4"))
863 ),
864 (
865 SymmetricKey(hex!("3DBF3C21C88563067DEAF0AEF8FE6C128D06830A9F5C5026726B95F6237D1E91")),
866 hex!("46DED311044C831CFF22A0A20994ED4FF69D479A97EC2561A0F56D567E8E67730B5F965BCAA9AB2C1F244D724B8595E1BA10AA33FA1113FF155CAE8266FF6660"),
867 hex!("2166E3ADC39363E7B1CC370A62E129E1AF023D3D8F3CB982B8436EAF28604D19C3884A43704C35D5CC9664DFE7EA5462936EC7ED2FB343EDF0DC21674840BB5F"),
868 hex!("4FBD4381A5CA12504A3C73D1E622D518851EBBFF48E21BAE2B50E6F6FD60C6C1C6DBC40F087070554C6BF5DD612393008AB4D1525BFA685E5A3A3F0AB0B782ED"),
869 SymmetricKey(hex!("E6080B8B02C39D665F6148C06BE501759C58BD46BC8F830AA19CF1385E4FBA27")),
870 SymmetricKey(hex!("5F87F0949E6348DDD35C6621A253B1EDA4E5DE87CC85220DF38AED9178E7CF02"))
871 ),
872 (
873 SymmetricKey(hex!("50AED6D0960F9013B58A37AFCA49A8AF094312047FDE7498733957ED8140B96A")),
874 hex!("B6918B421F44B629AA8EAD9C8D31A0314F75C18ADB625064EE8815FDC2A0B604E7A5F9FFC516441018DD758784FE7E2A0C48FEF62FDB50C449AE9AA47A995BC1"),
875 hex!("738E1A4881F5EE022E42A41981775687D5510D854CF940E58435F6E7E349D9FD13C3B2AB9EF99014DEF44653C8F07331A09B945697FB5E57A67D27E4EC41C32C"),
876 hex!("1F70A2453C7E4BC961AB57FC910671104A094A498B2B827E3695BBDCB76461BC16E7412BCE06F6B0B0BF0A878A27B1261452D69034AC0119C2269A671C9B6BDF"),
877 SymmetricKey(hex!("12864AA0913865829F8EC2DA9ABAC54D638F6A923A4F5B91B38782594486F736")),
878 SymmetricKey(hex!("9B2256F60DD687D26739F0DC41EB809B9A063260CE107C53ED11F0C8CEF96AC8"))
879 ),
880 ];
881}
882
883