From fe6e641e563c09346c5d4a5fbdd288d7df438009 Mon Sep 17 00:00:00 2001 From: Glenn Gore Date: Wed, 16 Sep 2026 18:12:58 +0200 Subject: [PATCH 1/2] test(tsp-js): move Appendix A vectors to the merged spec (YTSP-AAC) The merged specification (trustoverip/tswg-tsp-specification f5b8668) moved the vectors to YTSP-AAC, changing every message and the control vectors' SAID digests. Replace the pre-merge YTSP-ABA fixture, fix the tests that asserted MINOR 64, and pin one pre-merge ABA message so reading it stays covered. Comment and changelog text only; library behaviour is unchanged. Signed-off-by: Glenn Gore --- packages/tsp-js/CHANGELOG.md | 9 ++ packages/tsp-js/src/cesr/wire.ts | 7 +- packages/tsp-js/src/revision.ts | 7 +- .../tests/fixtures/spec-rev3-vectors.json | 88 +++++++++---------- .../tsp-js/tests/interop.spec-vectors.mjs | 56 +++++++----- packages/tsp-js/tests/message.envelope.mjs | 2 +- packages/tsp-js/tests/revision.dispatch.mjs | 23 ++++- 7 files changed, 118 insertions(+), 74 deletions(-) diff --git a/packages/tsp-js/CHANGELOG.md b/packages/tsp-js/CHANGELOG.md index 2aa569f..5a2830d 100644 --- a/packages/tsp-js/CHANGELOG.md +++ b/packages/tsp-js/CHANGELOG.md @@ -15,6 +15,15 @@ For history before this file, see `git log` on `packages/tsp-js`. only the state, so until now every client had to compare the digests itself or adopt an accept for an invite it never sent. +### Changed + +- The Appendix A test vectors are the merged specification's + ([tswg-tsp-specification@f5b8668](https://github.com/trustoverip/tswg-tsp-specification/commit/f5b8668952aabe8e541b535fcbdf589484ffc4f4)), + which carry `YTSP-AAC` — the marker this package packs — in place of the + pre-merge `YTSP-ABA` set. Every message and the control vectors' digests + changed; all still open and verify. A pre-merge `ABA` message stays pinned in + the tests: reading it is unchanged. Test-only; no library behaviour changed. + ### Fixed - `MAX_HOPS` is 64 (was 10). The specification sets no maximum, and 12-hop diff --git a/packages/tsp-js/src/cesr/wire.ts b/packages/tsp-js/src/cesr/wire.ts index 1004b5b..7353354 100644 --- a/packages/tsp-js/src/cesr/wire.ts +++ b/packages/tsp-js/src/cesr/wire.ts @@ -58,10 +58,11 @@ export const LONG_COUNT_REV3 = DASH; /** TSP version `(major, minor)` this package **packs** — Rev 3, `YTSP-AAC`. * * MAJOR.MINOR, two components rather than three: MINOR occupies the whole - * 12-bit count. The published §9.1 text reads the three characters as MAJOR, - * MINOR, PATCH and gives `YTSP-ABA`; affinidi-tsp deliberately does not follow + * 12-bit count. Pre-merge drafts of §9.1 read the three characters as MAJOR, + * MINOR, PATCH and gave `YTSP-ABA`; affinidi-tsp deliberately does not follow * that reading, and neither do we — see that crate's `TSP_VERSION` for the - * argument. Nothing about interoperating depends on the choice: only MAJOR + * argument. The merged specification's Appendix A vectors carry `YTSP-AAC`, + * the marker packed here. Nothing about interoperating depends on the choice: only MAJOR * gates processability, it is the same character either way, and no * implementation refuses a message on MINOR. */ export const TSP_VERSION = { major: 0, minor: 2 } as const; diff --git a/packages/tsp-js/src/revision.ts b/packages/tsp-js/src/revision.ts index 4a8197a..663a218 100644 --- a/packages/tsp-js/src/revision.ts +++ b/packages/tsp-js/src/revision.ts @@ -19,9 +19,10 @@ // Rev 2 is the only MINOR we match exactly. Everything else at MAJOR 0 is read // as Rev 3, because §9.1 makes MAJOR the field that gates processability and // MINOR one that no implementation may refuse a message on — the ToIP reference -// discards MINOR entirely. Upstream Rev 3 ships `YTSP-ABA`, which is MINOR 64 -// under this (MAJOR.MINOR) reading and MINOR 1 / PATCH 0 under the published -// three-component one; affinidi-tsp emits `AAC` = 2. Both must parse as Rev 3, +// discards MINOR entirely. Pre-merge drafts of Rev 3 shipped `YTSP-ABA`, which +// is MINOR 64 under this (MAJOR.MINOR) reading and MINOR 1 / PATCH 0 under the +// three-component one; the merged specification's Appendix A vectors, like +// affinidi-tsp and this package, carry `AAC` = 2. Both must parse as Rev 3, // and so must whatever the resolution of that argument turns out to be, so // enumerating known-good MINORs would be the wrong shape. See // `KNOWN_MINORS` for what the list is actually for. diff --git a/packages/tsp-js/tests/fixtures/spec-rev3-vectors.json b/packages/tsp-js/tests/fixtures/spec-rev3-vectors.json index d667e5b..ec73718 100644 --- a/packages/tsp-js/tests/fixtures/spec-rev3-vectors.json +++ b/packages/tsp-js/tests/fixtures/spec-rev3-vectors.json @@ -1,92 +1,90 @@ { "_source": { "spec": "trustoverip/tswg-tsp-specification", - "pr": 63, - "commit": "66a158002eb2cc6acf5ac62f9aa23224d433e6cc", + "commit": "f5b8668952aabe8e541b535fcbdf589484ffc4f4", "section": "Appendix A: Test Vectors", - "note": "Generated by the ToIP reference implementation and published in the specification. Extracted from the specification, then checked value by value against tsp_sdk 0.10.0's own tsp_sdk/test_vectors/rev3.json, which is the file the appendix was rendered from. Values are qb64 (CESR text domain), which is a direct base64url transcode of the qb2 binary domain this crate works in. The private keys are published in the spec and must never be used for anything but checking these vectors.", - "reference": "openwallet-foundation-labs/tsp v0.10.0" + "note": "Appendix A as merged, which moved the TSP version to YTSP-AAC. Every message changed with it, and so did the control vectors' SAID digests, which cover the version; keys, ikmE and the direct vectors' printed payloads are unchanged. Supersedes the pre-merge YTSP-ABA vectors of PR #63 (commit 66a158002eb2cc6acf5ac62f9aa23224d433e6cc). Extracted mechanically from the specification (tsp-conformance fixtures/spec-vectors.json, tools/extract_spec_vectors.py); nested-direct and routed additionally carry innerPayload, the plaintext payload frame of the inner message. Values are qb64 (CESR text domain), which is a direct base64url transcode of the qb2 binary domain this package works in. The private keys are published in the spec and must never be used for anything but checking these vectors." }, "identifiers": { "alice": { "id": "did:peer:4zQmUL61Nc1F7ioiKxHNqwnJXX4srhFsKKPo6TrCmhM3dfpq", + "longForm": "did:peer:4zQmUL61Nc1F7ioiKxHNqwnJXX4srhFsKKPo6TrCmhM3dfpq:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUAMspuGDnE6KM7r55U1tmXkDtRRWy97BFdh9HKfA3CPhA3gFdwRRV45CP1kGiaYU2rfwYAncrd1vfsAsZS8CoqbDWBgm7wGQNBXkjE8SuhKA8zv64cwpvbjJZioW7tx6Jo986sMDshig678dSR8whhc1zq4ZeaeDzGB6SbUZrpXXpd4aHy5AQQF7fwmStceXXEsNa4zL8xAhTszp2yFhLF399Q83hTdka8gUWyyQ26LUFDXCUivSfPxFRyUZZEQEK54sZZFP44MQoC4dDRrDqd2tyKMjTkdxVTg1Tvk1k9CNRUoHzdrboeESKmmdN39Ms3xRCVTN7cU6qGFW7Uz9xqhCinaKpzgRLp6ZSvmX4NcCTbruQeb3vMvHvJLCkMghQp", "sigKeyType": "Ed25519", "pkS": "b5DCBaChqWVVGJOsGWcKuKti0SKfm53pTfOwuj-hm9g", "skS": "MqiUK5zsViOi9QxQlyMXvPdraQghVOASyFiAvlFXp4U", "encKeyType": "X25519", "pkE": "4ZKJH0k2hjrBnFa83B8ZWx2dQYjQmbnc2nJW6urQSWg", - "skE": "0G2OObWQl0Nz9fR8LyBvzVGVLezU3wu5Y7payTJY2BE", - "longForm": "did:peer:4zQmUL61Nc1F7ioiKxHNqwnJXX4srhFsKKPo6TrCmhM3dfpq:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUAMspuGDnE6KM7r55U1tmXkDtRRWy97BFdh9HKfA3CPhA3gFdwRRV45CP1kGiaYU2rfwYAncrd1vfsAsZS8CoqbDWBgm7wGQNBXkjE8SuhKA8zv64cwpvbjJZioW7tx6Jo986sMDshig678dSR8whhc1zq4ZeaeDzGB6SbUZrpXXpd4aHy5AQQF7fwmStceXXEsNa4zL8xAhTszp2yFhLF399Q83hTdka8gUWyyQ26LUFDXCUivSfPxFRyUZZEQEK54sZZFP44MQoC4dDRrDqd2tyKMjTkdxVTg1Tvk1k9CNRUoHzdrboeESKmmdN39Ms3xRCVTN7cU6qGFW7Uz9xqhCinaKpzgRLp6ZSvmX4NcCTbruQeb3vMvHvJLCkMghQp" + "skE": "0G2OObWQl0Nz9fR8LyBvzVGVLezU3wu5Y7payTJY2BE" }, "bob": { "id": "did:peer:4zQmZmCAsG7j1ewTjXjtddwujik33CE2cMbYSPagpMiYnt1A", + "longForm": "did:peer:4zQmZmCAsG7j1ewTjXjtddwujik33CE2cMbYSPagpMiYnt1A:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUDuzmWt547vK52UYFjqvYuqeZke48ht1Tn7veKyU9an3DBDEK5iNnMZuTwssYn9WboW5tdbdA3dyKiqwbBwrTUQsaAbpAaMzKCsFouHetYm3r6ft4Ewh5F6sQeWtVzScGmrWr2M9rcyLyRC4nC711Sfh3q6tNeb393SqeLs1uMVD3AJ7mLMWGmaYSuMBewWRcaJZdEiDe4NjZa12WSuZ9hZ9UYigEMByhwiT8WVsgiNEjFwcQLdofowERUKhYYNv1sgDfZ4K7MGRtdkJw3eZRbP1T9NPwyDsiBycnKipqn4MfcnDMWVMSsiQCg1xprkVvtgtgjhYkG1A7w9UGk5497ytKuFMpzwJbu8cAxLqTFZ1phe8cft61Euqj1eoCQ1X5E", "sigKeyType": "Ed25519", "pkS": "-ezxE2yQV7bti34Ofz1Cgy_Ykf3_t6ob2zc4evBKZS4", "skS": "8sDXUkHnFe7exy1sGdCZl9kQQb-Xz-wuMBcGKXkVetw", "encKeyType": "X25519", "pkE": "c2fBIIJWZgJFNKZ0SS7k63Q_73kW1nnwaAf2vIb-mGA", - "skE": "j952DlpES4WEaSrY72PZwOi1j035m9iFxsZh_OKfcOE", - "longForm": "did:peer:4zQmZmCAsG7j1ewTjXjtddwujik33CE2cMbYSPagpMiYnt1A:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUDuzmWt547vK52UYFjqvYuqeZke48ht1Tn7veKyU9an3DBDEK5iNnMZuTwssYn9WboW5tdbdA3dyKiqwbBwrTUQsaAbpAaMzKCsFouHetYm3r6ft4Ewh5F6sQeWtVzScGmrWr2M9rcyLyRC4nC711Sfh3q6tNeb393SqeLs1uMVD3AJ7mLMWGmaYSuMBewWRcaJZdEiDe4NjZa12WSuZ9hZ9UYigEMByhwiT8WVsgiNEjFwcQLdofowERUKhYYNv1sgDfZ4K7MGRtdkJw3eZRbP1T9NPwyDsiBycnKipqn4MfcnDMWVMSsiQCg1xprkVvtgtgjhYkG1A7w9UGk5497ytKuFMpzwJbu8cAxLqTFZ1phe8cft61Euqj1eoCQ1X5E" + "skE": "j952DlpES4WEaSrY72PZwOi1j035m9iFxsZh_OKfcOE" }, "nested_alice": { "id": "did:peer:4zQmehsjMuPkPjzg7WF2tH5X1SGuFMxacJB9RETLFwjgMDqX", + "longForm": "did:peer:4zQmehsjMuPkPjzg7WF2tH5X1SGuFMxacJB9RETLFwjgMDqX:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUDxc1EGZZ8oysc2HpdT4rEuGHZoobGpKmo4XJSoDPKF6CfUWCr2UyzMv8dbCQWeugCqsUqQuASukLHjNPpzRx8cuSRSA7kDNG9civ4UoFrWhgvdSrPgBjeQYQFREA9ctDXCG7QkoYfNrpLhHXZ3LK3C1Jm7hQtmX926LQ75V82SSRPmwXBYXGx153XZuCm98znoU8cWADwCtJ6GhVrUSZPkkaPgrZqE1pFukaCvZf4gstRoZEwGrtDhyDdk5L6SpoLxEYCYfgFGmYpo7a1PojKqFFqp1NLzgfimW8XEuq9sL3BXraAz6kxRXCnbeEmSNHxzgJxe9S17WFsTn2jtFHLQFHgRxzpjhdXeysKxYJSDng8Cjjk8WdZeN5YkmKsve5z", "sigKeyType": "Ed25519", "pkS": "_-E1m_BLThHwhUuYhV0YovargFtQUkox6LnwhHx6Nnc", "skS": "gOpqJhU4I8_MNADm8rODdfaMP4dv61uP8VwY8e0mjNw", "encKeyType": "X25519", "pkE": "NJwm8WK_zTmq60S-bjrbr1OjURO0FBfEjaTlZhmDm0Y", - "skE": "e2EIWSYsqFudoECVTglwKwX_i_t36CGjjDCCRF7uQ7A", - "longForm": "did:peer:4zQmehsjMuPkPjzg7WF2tH5X1SGuFMxacJB9RETLFwjgMDqX:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUDxc1EGZZ8oysc2HpdT4rEuGHZoobGpKmo4XJSoDPKF6CfUWCr2UyzMv8dbCQWeugCqsUqQuASukLHjNPpzRx8cuSRSA7kDNG9civ4UoFrWhgvdSrPgBjeQYQFREA9ctDXCG7QkoYfNrpLhHXZ3LK3C1Jm7hQtmX926LQ75V82SSRPmwXBYXGx153XZuCm98znoU8cWADwCtJ6GhVrUSZPkkaPgrZqE1pFukaCvZf4gstRoZEwGrtDhyDdk5L6SpoLxEYCYfgFGmYpo7a1PojKqFFqp1NLzgfimW8XEuq9sL3BXraAz6kxRXCnbeEmSNHxzgJxe9S17WFsTn2jtFHLQFHgRxzpjhdXeysKxYJSDng8Cjjk8WdZeN5YkmKsve5z" + "skE": "e2EIWSYsqFudoECVTglwKwX_i_t36CGjjDCCRF7uQ7A" }, "nested_bob": { "id": "did:peer:4zQmSMw413keKhgpTpYm1q8jzmpqNYwddVGPubkHNgp3qQei", + "longForm": "did:peer:4zQmSMw413keKhgpTpYm1q8jzmpqNYwddVGPubkHNgp3qQei:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUAgR84nfSphZZkXtF4LsDaKz5V52HNNgWgz1k8aFkjSCzTgyVcS7f2RwomT1HfyLVrW3UqCszF7iJ9vpfMviins6mHyfBkcA3bJbpeKoVTqemLZ9XgkhhGxnszeDAr8HAGrwTysiGmZeJUoweCk2RyP5f1QyWBqcNcRyDRjkShHQgpcVPy2iKceZYQbZsMRVTJveWDuzbAMzAeX2XsXDGE8y6r2dEKLikSRqFFYwGTrNEBjmkfQ9DnkRbQAK3ZoKKT94khAhbw8tZkDK3w48Vjb6XZkEcpWbpwsrAM4RDPcS7UJq3fH3WCoeSDQWoXyxncPoYmNaBK6PtwQe3PhaMoUBwUUFtEsDCuVCrAz6vpvMyZaeMv4EbmBGYwtMunWhxG", "sigKeyType": "Ed25519", "pkS": "eGi5FU5ZXN-kavLZRr_ozjAXFzUPsv14y8CyPCOuR84", "skS": "6X6bCFv20GqJXHcnIBba3cILwFv9eawgwOL2HgOp6ig", "encKeyType": "X25519", "pkE": "5tBNodlJELEWNo9d-rgDxcYf1ldc9fruci9PtWqUgAo", - "skE": "0xi9nim9P3GuGznEHJJFL2JGpuCPqtCYFJ0EvBGj9Qo", - "longForm": "did:peer:4zQmSMw413keKhgpTpYm1q8jzmpqNYwddVGPubkHNgp3qQei:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUAgR84nfSphZZkXtF4LsDaKz5V52HNNgWgz1k8aFkjSCzTgyVcS7f2RwomT1HfyLVrW3UqCszF7iJ9vpfMviins6mHyfBkcA3bJbpeKoVTqemLZ9XgkhhGxnszeDAr8HAGrwTysiGmZeJUoweCk2RyP5f1QyWBqcNcRyDRjkShHQgpcVPy2iKceZYQbZsMRVTJveWDuzbAMzAeX2XsXDGE8y6r2dEKLikSRqFFYwGTrNEBjmkfQ9DnkRbQAK3ZoKKT94khAhbw8tZkDK3w48Vjb6XZkEcpWbpwsrAM4RDPcS7UJq3fH3WCoeSDQWoXyxncPoYmNaBK6PtwQe3PhaMoUBwUUFtEsDCuVCrAz6vpvMyZaeMv4EbmBGYwtMunWhxG" + "skE": "0xi9nim9P3GuGznEHJJFL2JGpuCPqtCYFJ0EvBGj9Qo" }, "p": { "id": "did:peer:4zQmXuYx5quNpAYvu1syaoHpJWxHceBM8PnAS1J84mjEo118", + "longForm": "did:peer:4zQmXuYx5quNpAYvu1syaoHpJWxHceBM8PnAS1J84mjEo118:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUDEQsmpmjBHzq8cijG6sryWW5nVPht6pYsbuY4ccUdfcph7owJRDqYg99MemT1i7k3HvTxvnop9E89WNwWZiDLmJk5tssb7rQSatDkq2kvRhgW8eVyFnsoTdg2h87tsGpE8p6tQNyZpzAnTNVUe886osyyavxqQccEcm8idNnFEXEqtLL1oENMQvaWr8CsYUPy1rUpmv9xFPBay42n54ssn99hEMCahvW1sLFjHwcxGGco6PSMZT5DCw9yhUVSAeYpJ6eC4a2tjXB3tjcFeWifhxkp1u2yLJ1bcdxmJDvbKPghPVeCYYEm7g7RjrdFKKX1534YVEvwgeTi6H6ujmSvvs6xLwDjkmRwYpgPAucS9TMgVGJgDpEXD1brQZUP3PBJ", "sigKeyType": "Ed25519", "pkS": "4aeb8EZ5rJciXQvEjl1LDcZaST67KdYnqvZ2BYWU5Y8", "skS": "WW-aIOkC8AcowW-6H-MmjFoUA92mzz1XYmp5DsLpxE0", "encKeyType": "X25519", "pkE": "ajg137oz_TtbqqxihWdMYGblF9NLtFpDg8mv06leNVQ", - "skE": "ivpbTN8fMgb3oj1S3tQ5SC5UAjDQ5oLuOlmrkbJKy38", - "longForm": "did:peer:4zQmXuYx5quNpAYvu1syaoHpJWxHceBM8PnAS1J84mjEo118:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUDEQsmpmjBHzq8cijG6sryWW5nVPht6pYsbuY4ccUdfcph7owJRDqYg99MemT1i7k3HvTxvnop9E89WNwWZiDLmJk5tssb7rQSatDkq2kvRhgW8eVyFnsoTdg2h87tsGpE8p6tQNyZpzAnTNVUe886osyyavxqQccEcm8idNnFEXEqtLL1oENMQvaWr8CsYUPy1rUpmv9xFPBay42n54ssn99hEMCahvW1sLFjHwcxGGco6PSMZT5DCw9yhUVSAeYpJ6eC4a2tjXB3tjcFeWifhxkp1u2yLJ1bcdxmJDvbKPghPVeCYYEm7g7RjrdFKKX1534YVEvwgeTi6H6ujmSvvs6xLwDjkmRwYpgPAucS9TMgVGJgDpEXD1brQZUP3PBJ" + "skE": "ivpbTN8fMgb3oj1S3tQ5SC5UAjDQ5oLuOlmrkbJKy38" }, "q": { "id": "did:peer:4zQmTKaSRexnzX2ecu1eYRusFNeWbrT5jbjr3YjtfgciZc1Q", + "longForm": "did:peer:4zQmTKaSRexnzX2ecu1eYRusFNeWbrT5jbjr3YjtfgciZc1Q:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUBoRT26HWqurFNeBrp2Z5RXkhxkhyxAnpoB6ZS1CthQZKhEgZz8ubr2Q29a9C2ZYyuCNNuWCCUhfm8AASng7btZiV16P3qyFpbMk1dpwabuguNC2hBAycwQ1pniBp3yDGdTrSDg7Mvd62zkzDJfCXhxTQJQ5SQvAu1bb5ZGonmjMfu3fU877FfvbYL1gqYDKcH7hZ7NnifTQP345XsY2tTav6vR2vUAzDiWwvpVJ9gApPWJExs3A8EBw3wke2m2C9uQpdu4XRaxVzWgtGd1NL3LFwcf34gEksj2VsURD4VNhdjQ4MkKSFy7uxgDSyqTXUdr1GEGeQGAtcFTq5anuPnN9kDHm48WihypUQ48jo3zM5JXE1fhL1Xypi5rWn3tkip", "sigKeyType": "Ed25519", "pkS": "qUfbbaVzKhhddujMaJNSl9C8eGWCOBjA3WT4UGzXNOU", "skS": "GolUele6xQTKisWaDZT9Q6dUNGg93_y__h-J3X_m5aU", "encKeyType": "X25519", "pkE": "M5Qk6RSrDUckHiQlmduCMbu9HW6AZbJCfkQEQqWShSI", - "skE": "GHZ-LhpY_K1f_PvDW6loXWLvFIcc6majVAR8_jWgL4c", - "longForm": "did:peer:4zQmTKaSRexnzX2ecu1eYRusFNeWbrT5jbjr3YjtfgciZc1Q:z25NRJMKpQKwnUm6k9FbTSp1eqANorDtFimHW9nGdLSgAbN1UhsQANFAnhij8VXrrwnDDG5Rb7HGrYpBGZRy3EbgmxirqJi3WuNfiajavps6kAfnvk9ykxGqcxH4u7P2TJohfbvigGMTMGxAhqkU4JDkWYi1sBp266n8tzTzD3DfRUBoRT26HWqurFNeBrp2Z5RXkhxkhyxAnpoB6ZS1CthQZKhEgZz8ubr2Q29a9C2ZYyuCNNuWCCUhfm8AASng7btZiV16P3qyFpbMk1dpwabuguNC2hBAycwQ1pniBp3yDGdTrSDg7Mvd62zkzDJfCXhxTQJQ5SQvAu1bb5ZGonmjMfu3fU877FfvbYL1gqYDKcH7hZ7NnifTQP345XsY2tTav6vR2vUAzDiWwvpVJ9gApPWJExs3A8EBw3wke2m2C9uQpdu4XRaxVzWgtGd1NL3LFwcf34gEksj2VsURD4VNhdjQ4MkKSFy7uxgDSyqTXUdr1GEGeQGAtcFTq5anuPnN9kDHm48WihypUQ48jo3zM5JXE1fhL1Xypi5rWn3tkip" + "skE": "GHZ-LhpY_K1f_PvDW6loXWLvFIcc6majVAR8_jWgL4c" }, "pq_alice": { "id": "did:peer:4zQmbLqu3weZtsnNesBzecCZm5FA6uaGkgCWYR5Wndr6Gzzd", + "longForm": "did:peer:4zQmbLqu3weZtsnNesBzecCZm5FA6uaGkgCWYR5Wndr6Gzzd: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", "sigKeyType": "MlDsa65", "pkS": "-XNPEJoCD0SXNM9Z1Ek_Ah3JXU94GgMiqsGZ9VlhtD-ibb_VSt7Kft0622kvaA7nYI8A1STW6uYfs4EQwElWrjLKUAxyIRGj490atsxFZdlpBJhDzY5GugJfhnT_MTHlM2R1OJHRNVpL7rqAQCFhFMv_s3n_nu6ERT07HE0v4-IV7BzADacxQvizGxUiBMD5_xIBOGFJRsHXyWnxFZkZUlYlMiiA7Czj_ja6qPeNhFQtQJgkCp1hrIteqAXGyBK9ngctYOHypXkwMAG8rO74UW53CHyrCU7FuL13nDmiXxOaEDzZ4e1fbLm_wcmgl7KTCWFsoFyRyZiEHY1IPYXlTlCZjP5s2FzCpoTXO_XvQK-iOcTMesC1-_xkXYJPjjhhyq4aR6Y_gQUBTHG0EROH7NzKRAOCJ0905kxpP5zKv0EYWkMSJcigfgXhREC7Iq6JDyRw0VLpu3czeF4xG0VdojBUJKQChDzkDWC9PzgZKLvktmN9W7-yFw573qgeWY4oWnl4ZPrKoqgcGGcAMMRGG12iEdjvy0kqxg7SUUIho2dUl_lN9FivvNOBGrVfDoL2HBCuEawJA9cVhgNtMxD1OV1QRRrm0MuKzSVOd7M8DH-cRLBb4n_5wSApn53h_5OM6T_uCdrfRjl9FWgiazeXwGb9ivlJR0OjRKQS9aKiU4oP4QK4tzm9IVf7fbmOH66sUh4Cgy2JCjt8Sqhvhp4sySpA_WIUzvhdm52hKFoRx-_FJc35nGMia7tvsgPpc-GlHCdMQXB873Lfrn2yZgIXz1Ji1UIAlqtKFRqVBCRiBlwhAXT9xjrPmpD7PcLXUWe_8pTNI-1t8QqcOl_S9GbQTAnyhkoSaApimo3EzxRyjxoksn0DnX9FKEeguxGEZ0dhXuUT9Et-9FylvkKgd0ZTU_RzMWgdWfS0JEhqUE2uMgJrKYaCzZO5C84o2gSbIyXcyvKukoQ2YVA3qF6qBoj5fiL5atJ2VDxqgg2D2Q2RWL2QUeAbpw50odvjKLQUbW2YLAHuPMnxZCn9MyeXwVjoasyELSemUurKHsxWwnonMAmQ46kxjgv4s5asGxMLrP_-fKtwMEt1epJ3Anicdt4FpD0Rf2EbyCW5KH7jPPz8mq3Tr7Dx5er8jqfT46Zi3Wlx0fIwryB5ON8yQrMTtBRvSMSQndty2JHKoKhylYc4KoVszqx8d8Ia4IkjwNNrvQAQomPUM2s8Wf9HuQwHwwGjhuGQefHiUBnOqbn057HXKuWrFYY-enzKBLaSnwVD0zatyIrkPfocI0PxoCSQIlUrriyAUbOs53drxBdF7bh7urVZjPL2KrPyaC-evLUrFpTl8F1BCUlREpmDSx55LjbcbHQyf9WZY2835gMT096InMv3JrLbuwHyz8hd6oy_FqdJpjrYQK9REajLxmZNVCTPhqxdoUn0cJvnq8uOgn8qVa9AFkxUWT3eLe-IwTo3EnuLxoyvl657a0JsBofp1roFkt0DPlAiNK12ffdclWql6c6S1-W__6um0L_ZcnIMznII7demQ0RQVKBd1ycs9wlJ66GLgxgS40OIZL8OuKp1Ht9vkl5DScgkPt_zKSEdbnEnfXlo70eKAb4fkJaJyTYT4r-wPskiBqUZW8NmJrh8ioK7FyImJYxHXOBgkOD7bReyZJr5kkWD2WWrB-jPr70W_Glk7b7PdwS9Hf3leB8MfZCfOUFbRksbPaz89qOsHcBOM3_F5UthxqUboxREizv41xkN88IHQhmpAyvS3ZXqApr3x2mjkzp7kCUdJFVY2Gk4BX3h7o732Um6UW_TXE1HPvUnqQo2OxfLzw-9xcM0AQbJSrTeC-hD3ZHpJyEHue-4srYvloWjoZqbwcXJUcMiPdNFDfSDiysqwAuN9VUFSCMAzGlyL-sytuTrr1rYEY3KshQ3vjFLxiiiCa6ZBn5Je-s6IHBP-OFTAIylZVLtgq4WDKo9Q1zoulzk6SGHZJ1QF0Q-AxGpiA9We2kq2B040q1jLewPkFLq2dVH45UAzTlvUiUXWg1_sKPhHQHy5gf8S-z6jg5DnDhCik9W2lDMicBYJe1b4_ykBDbPD9Nzabt6L5JcDH-Y9NaYEzHfcx6DqkHy1XDQ6mgxaBLDueY1hAY4YPOuNDoyxhkliEpyc7_Jlogu4RXYWoDft822kyto0vlnyPgEE12Cc2jrpZiixy6_hb8euWXtpznMmHHN44qBCTIpcbmq1_uPbC_oxOSp_Tel90TQev9fyMqFVCBYMgb4Ar9YWKnz2FT1hV7RrGoqFGH6lL62wUelyIa6kQFdBUw31gEXfs3TLyQKL_ZTSh7bXNZS79sfdrh5FekYQS9UpXpnMRq4Gfe_GMdk6Qn7aVRddFrVJviHnTE0cSyEZb8aU3MfTPVVmj5aIDN7TuNG8lI7OzAbZXU-rJpHygn7_6upjNkWJzO88Y2eNuidcrrwtnLL7aGOQsSHIcjIGF3JgB2XJciVmSfxnTSvTtV-ZZRoXwp3mYZsqY3JrfUn-URIo7QTrLO1vlIBCMgxoJeIeDGG4_0wq-YG4202WKVB45US_fgGGhLDcfpsdHm5eZU_pNKYl-uCN89pb1vDrEA", "skS": "-XNPEJoCD0SXNM9Z1Ek_Ah3JXU94GgMiqsGZ9VlhtD_kAdF67qjgAqtaOSUMDFnsYqIrfi6KACV4hnd82xS-9eniQETgp6ws5_-nsj1FHN8IWQMhm1VBcY1xBkejH4s02jxt8376jgka4Uqf0q_QlX_Skzpg9TfQT_FZD1FSGF0QMYGBgYOHU3UWU3NycoN4SIaDKBBCd2QxVAZWggV4coc1RCESNXhEFGF3JWcUURdYMkchhGc4RniHA2IUJmB3YGMINgRIcxgzgYAmYoQTB4MgNzcGAAJVF4BIAFhXVwUTR4YEYXIQVleGdFNDJndVeFdzZDcBZQAWZ4NGJAIAdgiEQGKEEjdQV4OHhCSEEhBndDNFNzeBhSQVMTUGUycFh2QHdwEUIhRlABB1M4UXIgEYeGUhVRVCZlR0ISiIMBNhERIHECYkVydYMIYoYgdWRnaIJGUYJTdlWBIIAggjR3SGhXZyAFZTJgiGVWgCNIhjAmgGBSByUihIUhhidEdQAYgDVoUYgmBgJIcHh1eFcQZ1cEQVEEAQVwBUA0hkYRNVRgUTU3hDYIUoFCdhYBIBQ3NlFUdih2Z2EVZjUTNXU0hQc3BQMlOCY4hwAEczR3ZwOFBXhgQXNINXg2EYgURHIkgCWAZxRGWDESYjV1QRImMxU2QDZSSFZ3NkEVUTBXNCg1gGZRQFdjI2QhUVZTQTVlh2ZDM2g4MIVCCIGFgkAnBkV1FjhYAkV3ATdDYGElSDYRR3NYUBCBdhMWaBJoJydSJDZSMWMIhDVnMhN3IWFlKDaEMnMoEUYHJ3dEM4BnY2c3UBMGiER3AWJVUIZ3IARmEYcXERAYQFg3B0FyI2c0RxMoU3MlWBNDZWIwBnQYYxcCV4RQVoFYBAKGhQIyYWFoZYIyAXJUhwg4N4JAVFaHgnRzVzNXNTEIZWJBU4JIBIZBYDMzd1FkOCMQAAYIiAMDdhBmR4dBGEI0RUGDE0KAcAQTZxUAhwcDFlIggnIBFRQyAVcjYQc4EUZ2RkMnJAJ3hjCHQIY3dRVoODB1MYQGMYJYMHdUY3REZYhHE4MoFUgDNESIclhVg4dFdQJDZjJjAAIWMnOCA3AWRhQShAhkUXMiZGIUJQJhRjI4VxQIUGdhEGZxYAYhYRhkRBEYQVF2dmMQNVJHUYZGgDQ2EkKGJEI3ZQI4M3YFJHKFJ0hHYwhlcoZ1goM4JXcAFIFCRFhwRWRUMkcVZjYXeDNASIIxRIeDchgXQ2MBdEcSYIU1VodCdGRgcRdxOCOIBoQSGAZIh0RQdgNyZUIkAGF2AmY3QTdxKDJIQxKBEHQ0dFZ3UkEkIiZmZRh1gIRXIYAhdVFzEjICECQmgxN1hlUgQGBBVYARBYAXIxZnE2gocTJBYoB3I4BRUzVFMDVSMRNiNIVwOHWFBBdwYEIGh4hzZiFnVHNYhyJIUSQFgDUkhXBVhBIDYQFSNyc3h0CHiAc1dGNmZxCGV4EQYTCHYUWEAiJDAhAXcVM4USEEIYQ1AFYkIVaIUmFUJzdDMzBRN4NRiHgjc4JjYgYjIRFWQnQyg2czZAYIZoBYJSiAODMwJxECRxYTVoVINyYFdYIkBDdCBkNCYgZTcUcxFoJFhwVHU4MjYIY0VlYlE3VocREodUYUgTYHYmdDVYI0ZxNHEjOIYiQiIyZmFSZDMnNiIVeEIhZ2ZVgQQhhVKIcUImUjKIhRQEdUcCMYcwRGJ3AhAzZUVidQZUaHFDAgWCIHYoFkY1gkUVFkcCQXFXiFUkQVMBMzIVWHNxBIUmATUmJgFRgDZoJgdoRWUVgREIMoBhMVEoEociAlaEg3iDFRMwV3A2NQWBASR4hWQxQGEEhBRkdSVURUNCN4ZBQUeHcBBBYxUWQHUwcFJDFIEWcoByhIMlIWM4FYACFGd3VRIYdINgAQRFZEIDUCQTCGhnIxRXBkcVZIESZgRWYjZUVRRYeFN4BEdDVgh3B4YTMkIwF4AHSGIiJTA0VRQQNoU3gBhCRxgXRxFRAHJ1RIEAZRNlBDIXYHFTJlZnZQQIQTAgdzQRNwYXdgEa7MwV9I0hxYbZm1dij9JjeuVueMp9v3iXXJLFSeeNeOEgtx__f5jXsq1bW7PIMuvslJmvvQtJLgB434F_Gmdx7z3zee30OzRQWa257gETLsDtgFwux8KNV43FcDVudsf7jh9C9102AlmOCRmbqE3NR92yGY-PkpHb1zpsK_CKpThiStJtpqGHfrxuF9WWrL_HO7QQhOHIawt-u8_KFDX-x1uTR8PH75PARzDAfvGp8UZOw8pdocNXXYdPrVan4AzRfdKTUMW-XjkKd-TrEhkq1QGkIBosojve_BhJDdHymDtoT7HQPRdzd-pKPNSl6lP4TwQYqdOqvmcoELhKVtAjxAAQIhuhL4AzU8fEarsOvkQq1oC4ewNI81NbSSZ0A5Z7iJGo-pPn0LsS_clkxjAQBD5ht3_XRc3yMT7I1h-AEGYxa_UfzYnlqDaWh-GQMd0hSRTkVf2SGSIsSp4USPHPZR2SURtpBHp659F6Zm5L5j-ROemWvk0PkhArmY71acQFpFAYK6ddoyxZhIWEJm9LDj68cuStJV2p2RTS7MDrLXN6iVSFmV4cyqoOZXLxGeNfrZ5QGRgTJqpRbaxhBC9LrVCLjT-0aodjRoqONUCfj4ADgz8qjrQo9Nkx_UjX7HWU_fDfh0eS2UjUqnGJHY0ATaeQ-7IE_WtU5ayqdK0_wlh6ZABAkFR-ShaY76KKNmTcdrq2cjp9A45cfUhv0fOkJqOBQBD8jDxS-cD_L6SGGt11zcELxObDADc89r_4Deeq9HsLbT36vHvZrZ5wMeZUPsJUVjkGvVbmUTi5544X6WZu2lX1JVuIdfrunzlYc1hWh7M8MNwSSlbqt38ImXtel1c0X993uMnLcHTISrM6FBsEcfFZ3P7t_GT-iImrLKTNBwahPJMFw0XXyz8CUuJjuVIdl1UBNBqs4NO0gp-qxU0A_anAk-ia6jlk440a2EsnB9T99pYFu1yu5ucYtb_171nK1NErw_KKRQqRl9RLbJN32GTR81lSWAyVmhVwP0_3-fhT9HfSALGvYbBu2ZMX7-PmM9_LossI8c-mfH7OngGhO5M55FfMAYnceKZeDUZxgWbijMmH3O-Bw7VUraYPniJQvBpjaqg2TOD1tph41P1SiHsvJ2q-OY_-r8kf8c8wRCWsgUemf2rbLwuWnrKWufcrgQm_AnQG2peAbyCHXXLi4X6hZRy_DogdTcXIdivgvE_0WwDcdVYEy5S9q2WvsY2uKTHvqiabK-h8B_f_v21HszG5TZDFt38zT0GhBt9eeoywR1TOViKxgh_M7cLg6P0UUUehw4jyt8TqC2u6Q-0l4IA8wO4l8Fe3LqKZBAwvkEY1q01ZCOf9cqLLf0Z3KyuudyFs4zco2AFQw9EnWgI5l17V2kcm5ji3AWpieqiXZj5f9YjR5XDX1NbOYcBJ9Zl7XpvS-Ktb4rlgppHy3kCfX3GkvfxYeatevZNvDtvnsPW9Up3zwVcf8N7KzcrAcUNmePUnP2jlaWBXTx2KytqOeqTb5gE6KTi9hXI2YM2JTT7I3oO1hL5QMDdaALseviir5-Vv0UHmWagUmAQZ6azbvDMhXzmRb4AqIX2Si6dZCrHbwZB0qYVIcQ9piXInOamryzIkOnx7A4w2YKD2cCpmdJuL0p-VrbuaMIOg1HFfD6fYugFV2X4l7-vdcC2JDCp6UWWMdbSJdgQW6IcmETG1lYjB8rbvh_5W45lqHwTxbftQNadIU4ep-uyMgu98-ZSsvI2n36yqrObPHTTw2_micQqATm5ejI_W3dOeTt6xbFgAAn-9i3yTeEFGU1N3BDbo7ndnf5KcxeiZGep6vkX2WSKmaITO0TkQmvMXx3FN7u6ATxOO6go-B79O5p9UMI9cG2Tw21A4sp2HQ8ejUyIm6xp1oMQncOv74VlTwmvgmgQHOqC6EUvnZ5E4VKva8ewNDoSVvcSoCiOD6FF5xd7CKKukkgFkPO53y9l_aXvbtgQ4EL76V5FPziJiAVclvDdc0Xh_pmg8JkssVR2IS-fQqhAtG688UwTOWXqeZjS85uGAabOQsvjzy1_Wx4dC7bV6NWHko8VN8-CeTlpdc0iLyHwQ_V2lgTlysCtenAvDQGGAZ2kZ2LWeWVJfg1zFCkKnZ0El5ismIzlloVoPXs_u0q5krVw1tmr3TUdu9kVj69wwvggHe28m9ceQMfoZW42ltQYRDf7Io7pHufW27mCpJdGHmpFUmj3OFm6eJVt2ybHxNWBIybAEQsoDCT853y-Jd-Z2qq-uA1iJ95jtweT38FeUbRq2kLFXN1iKwLoPqSuuUKfudWhzs-2Spb1gYJHlxQ_HqkNfM8I0qtRj3gJY5lOKLZB3pFFgDDWgHH0ALPxgiEI6FbcIMvPcaEJzMBJww1eZ5tssn130LcN0ImDOpG9SHY9WFXocuLYhcCwdpSE91uibnwoVEbJ4oyZNRhn7E5yAPZ3UyA-aSqj4ZhN2MdDdDPFMTIwBxzn6-8FJNYZPo-zD0hL0dcFEBaOTVQpKi_Bm2VQpaNoLva5BVL1g40M5Xkj_R6PL1JMAAjIn5y6gdXu104uWriMmv0x9EUHOb_LlOrXXHe-MPyjoe3jOIZSBKQD7zAtF_qBQFSdpmz63BiIBuG2PK1kjZ117tRSPzIZrgxiY4l-1fqtY1jzBIZzG_kykNC0eLPMB-NuMdQSaUPLvMA0k4PpYWMAzqCVU2JwPha7TTVHGbn77qZSfx4KnOdVQFdj9rQ9U2idFmZY7jMAQnVYHefGJTDghCyTJBRrXyOQS-IVkDbr8af1ZtHKGf2gWYQ3lZS-IBLc3YSb6qlTc-nYOjB6j1k7xj_1BMgv8_P1ZXQKkQg4GyEi-FTG_DfTlo0V0kASIcztDp84tG_iswh9ov_OmJ9MWGq7JH2NPiLZMHPWlKNRuoXcwZJq-ftydxxOZTWO4R41YMlI5n__osufkfEgqwJwZkCGuiTti0qRhPw-eQ_WkOwEVZ5FaK1w1vWmwGnuHw79JA7aCUIY-e4WUsp3oEjvl5jIgmsGfE_TzeawF_OeGZw4P5Ek0NXfVBYDQHKMPoYH58SZ3Jyj0UXNP1ApMPUZFgbxENfpneAwzqnlWXUFYu4dfFs4FLX9zyBDRsdS73qAZZpIe8_vtMdnHyRf0NhFxHXZrWInReuoDbp490SeAPI2lwD19AZSNLEHGfkQ90IJBtHMQYaTw3XBaZjfGvNH8nB8BOGWqnNgeIkjj84oiQGZmfXYOLx8VtNz3-_XrOWwHz47IP67FRHwCPKgPcnty9UL2B6eLpnV_9Dn487pwESVXJW1pUZSOk0C47xuc", - "encKeyType": "X25519MlKem768", + "encKeyType": "MLKEM768-X25519", "pkE": "LDlJhENyVToDWclSyYcaamqm-AMGyZfM04FVB7Gk4UISujKxtGTNJ9IL0EiEy7iGMjai_hFlTfZR-WkJZ5Fyc3SSlndE-MJK5CIpM9sT8aeKetJ60nKzpoMI_xIYSQC_eWlwCgW9qzs019oOUebC6KOJMNhitrRY8QFFOds_TlouG2NxKgLPK1Y5XnaIrZGC9SWEVJW-7WMj-0iWrSEGibxn0RYRR_o8crt0mDMZvZAgGgGaQuRfUueUDtB4HNfBkMgoN3tPhvxwytRXqIQlB-opY5dgk9lgVLpEGXdN5UGkZZJHN-nOU2eD1nMqFHIW5hd6gEUyUwTDRdiX9ppPuwFdCBFbVJE6Gip7qWpK2MZVVJIXt0iRyfB00apPFsQ3ffdE74FQnCIDILhR-OI0zmbA2fNOEviXugeJZdTEyRViJqh8CtsFnjEwASxLxTQQ2kROE0AHwMAbK3Rq-aGciRmjkmFjcIFInAyAPSJxs4B924qV3QEjAeCvPdg7XiWcelC4MymZTsDPoJYMSAFS9vMdL6ksIeGaNUM_07rDh1Bu7FRiCYCO6ncP1Rc1jsYdTftq55uor0OFdoXH0DIuwOdVg5BnixWU4ctSbgM7hORDH5M2AERFFPe4exgcwgKi3BFUicySVrsRrjrAL-JP5GY-n-Km9tByCQRH0xCDDLIVa0pjzYGCi9cdnLkwjJIdy_RhUieIDraW78nAC1kcliWqEPJxVfx3LhyX8ILDocXCTKERjCUAtZFa0sclFvwB__p0Sdu9qZNWyCUj_9g5efxRG4aHO-EVHap608m6J4SZuQLPbBmzDhx_ixdvrIZjXSWNjDVqpPl_J6EdxCKZUWcBfAxOPNqvSHAnsxa5fuFbMLgbcIKXgmPNDRgb5yJJNpBC9ElxPANAQzgSxFJ7mFO6X3cYqPqaAqMDWWgrx9FBdxZjzhKkHKVIRthZM7mUprZsLLCrXeim0Uh-MMwhc9QafKg5I_m7YWYiEZrBFSxyErFg43NpKvQE0CQzBpG3ATYD-eAXfKKmj2wG_9SU3GQrXMTISNRRXDSHFUmOivV-A8QbYFkLZlGZe3EX2EOU4xl_u3WrB2PIn8gIlcCkhSJ7t_d0YUFJQRxw8vWDsLqD39usXJdhLCoI-CYi1Ay3HaKwFahJRuoybPa6tnKx_spngaHGIwOayalmyalRIssG3ll3k3m5NZhQ6nwsSKKj-EnCEAklUnltTPBqSZlmZYU93XKClQdlWxOxFPUetpdgxftsGxxv2QnA3YhkyseyBOBaY3rJagFLooA2a4i4-hNt5KRZveDG4jGqiSQxvjNDDIHBHWMftDonTnFTgbQDIzHMYfVvTWnDDna7pOEJWzK8FJSgBaW88tU8X5sGlYNOxPSD9ZeGZGJzxRAlwjfCjVQ64-aCPjUJWnhFtOKxmscQKqISe1ui_CpTnlauL0Gvh0pHlNzFPxPF6jHLVZE3DPU78FNnRXwVi_COqVM9_ruemamWHZshksI7owuMVYolTmud7uaHENqLAbodwGAvSuQdbRAN18ZMSFKCAwtBcV6TArgCjxMta2YeSPbOuy7Q8p1TRYfghQ3pfur2LLUQb8yYRQDSIsP_hb-ON7AMWQ", - "skE": "U18eGAUfzboX6GC7iBsTD4kOqA9pmCX0DH36kQBZYAA", - "longForm": "did:peer:4zQmbLqu3weZtsnNesBzecCZm5FA6uaGkgCWYR5Wndr6Gzzd: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" + "skE": "U18eGAUfzboX6GC7iBsTD4kOqA9pmCX0DH36kQBZYAA" }, "pq_bob": { "id": "did:peer:4zQmZsKmffnwYVbGLb6ZmZ8gkgyTs8D76YQRBt5YnFNK4Sno", + "longForm": "did:peer:4zQmZsKmffnwYVbGLb6ZmZ8gkgyTs8D76YQRBt5YnFNK4Sno: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", "sigKeyType": "MlDsa65", "pkS": "E3fHwPPFvz4VSA_VgU5wZEsUlBUk8TgMt8NVYFf0MyDTsbWUhMbwZgals8GrGYdy-WRRRc3IUudHYAiZonL7XjueeMzM-WV52zZOLVsCEk-G2ZsPGXSfNBGa1B6tVKV-J_ZvgMq2H7_gBcDSeWEKHNbi8B0Pqwq6eVI_plXTkkb2lnyhzhzt839E5_dUBNvCXlvQvqjgdRlaRV8ttcy8n9XrAWiTk87-79lahLCSP7rrTGulnMbv2V2jffRbwyDbAJb5lb1fnh7J9FFKL-LvbmMUN3TTsQvdcSj5UZsnqb7O5FCCKZDvOpBdG6yk9DVgc0Br3E43PNAIkNHafecpvG3jTphxAO2Vwe0W13Vwq-VcAxdY1Gs1aJJSCROY6j8LeJs26t_gBcgYndNQ7-2ExZlK2nUdUAtHex-73NOvWOf9CS5diU9Zp6xDSN4idQyle5LxgPPp0zzFvckKI1pE5r54S4oUf41sxzzayKkUebhLs4gQuCKDnwI3hg9EFaM4z1t3hXg57lbrk9ZlDeYCEEH-597a-BsnOfxzMpiNuj10FMD0u1XLHA7vHm2n1R8QpLfEc4Vsl0gWTUg4zg747Yk3oyO86-sjh6s4lwJWj-OXIxk9kF7Es_k4Sz9Az8BiPPP7MYo4XKaSchqEDhMUxf3TsuCzLHPLJ1Lmk3AjPphJRVa19T6n8BLLbzimeqTD2Q_1Df0j8LUrL364if98TJuXed7Oxr1ZBFayHJ5P9ci0CXe_tcgDag8ZTVmBhldxMIsY92OGvANEyxqad89tco5-11O69TRIJn1I1jSA1TWfCBYPkQh_uBQWe6llkSDIg1wI_2vd1COJCHkYSO7TdgmASEai_ATmp4ZJ0bG9QafDzphcyjRDuTNA1EOFGQVzN0_ffLaRlZRXmvPoDTvuLzpK2hxqkikzg9r8-GunMiXIlB9RIfuABJu-7iEu2LqXjyDOMXz53ghysFjo4ntpZNlliphGA6Z0-RZBW115ZDUMqJ7n328PWm_hjCmiImHYBc3nOR0MrnVHGTKig1d1DonX5-Qkd81aRpN7_mvvJGs7EWijpsXPjrrpPbarOCJxLbVB7idTUFZ8YeJI-p4uZRGQhnOb18XRcs2i6nzHGAkGlt1w0rbf6wLDXlHUiscE1PVXpzeaG95oTX_fEqTB6SASxd3LFmXhAjio1TS82IJmZtiu9XGGaNpxf6EptCY1H0PCriZ0jXMMXcw7c1dytTmzZzmBzdfse8kqZLOEcOjWn8LYYMCqD_S8u9eLlPOIBEjEkm5KCgatx8l03o-qCiAe18YwlW1HUwaVQHlbDOffLjuuOmfwNEEVZT498PejsmiJ-I3WolWYmELmj1gIOBe1dsFYbTnF5WsB8G6Yeu9ICagcBbRbJNPEmSweL6LIEq-W-dazqGrSF_P8YYdCIM1iB3k7VC_oP70_Zet_tdMeOKzNb-C4fcly3WUMVd_DqiyzzANd4JqO_378znOYZF1XWBdh2-VIA1_NTa_I9CBFgJDZepHJnlOPbskq8qc61ZG_WXz7MmdJe1QK8jBFjarJp7q28h4937gjoppnWSbvQNSwnNK3U3QnyT_HGCCepTfLgHU9mNEQ-Y0lBwtLprrOR7x98LfxQrtAQ8XhsKqrHk-k4o5T6QcmAtWcSmGXwRDIGDKT9hjAWI1JtDer_HDw3_GJDpbxUZuhbVniBaDOjSBH6jHUUUJlEnbujSzOdS__CLwehEkbJ8o8CAUcfE1b2D9netchY7w77Pfdg_DcuI22gWWqqcSVshGhG9aJ_RWG87RaxX0OCkKek1JxSbSH38KdrbxqotlLoxJbRgDxAxViEZYUBesBJgomnFgYTpdroOU_lwWv97s9FDoVa-dU1oTDjfrEDdkeZNvZm5ZRF-5gxx4zBytSdh6favFK8xJPCGGrlQcB9HGMDyl5uIgo8BesLnyj-ITsK39RAbDPUP5GGGCxcKNSalO4kwXDtjvPVegOuOdbu8BIyVi43ye-YcOm6b3fuXD3AQ6w-GuVwlJifBtAInauwP6MKXg3jV_Lr8QCb6oIKNpVCL93dJhE_ldoJoVC06NL4MLNYkkQpmLN-Zxc6DBn0z3x0rdJVrIEUQGXurHMW66c7v-uiIGLexvCd4O9lKm_8ZApB6hYet7MPkAXYBOX6SEnpDuQRghZeKuHOlpoi_RBBGlHcy6qN-w4fu_-P5RZk6A9M7XwE4qu4W1gtMdmZOpZgX9T7KY_L39g9VoRpQv1SqfOAn5uX2ZRM5zatWbtbcgr4ZwHQ97BPwIi2KF_w4JhWB4FfzQufjLkxp-WPecCWr9an98mDhwdPJr1-_QSQPjM-ZOl971L1kVT9WJPQc3ErIHQHZwXPvD7wjLt3cmHVRdaspKt9qqxAWBmyZs4zqahyEgS0Z3Ds8DZXwDT_xKQFvSwR3FVfcMtWLs_xCCmIHKkxp8myRpXS9WOBwWD7am6-isL3EVJXlmyS7IKxQlpWWttniwnMpIw80ujyAb9EZpCUkCFu2DpWzEd44B5RMfFrDNO4uZaiyFxsZJyieKv-zTtQs8BI3WR4qdtV2gTQpM7xn53bzpSbBD63emxl6Nb9mQ", "skS": "E3fHwPPFvz4VSA_VgU5wZEsUlBUk8TgMt8NVYFf0MyCcFajzHL3w3t4tiA8DnPHO_LietFcKL1Rn8dSJriXTTOsJwQ2uNPpvZbnxfxBVfk0x7FhsZIsUCMc-M86km5LsYgBxOAkkR-QtJ7K2LOoiCSPFYTgZzwQD45C7gUlwg7NIhlBiJDFhAVOCVzIXMjZyQnhSYAUBZ3iFOBNSUAMRImYxcHY0RSiERAdCEHgCEBUHg4SEUiAXRmGCSHcDUjYTdWMDcRNDiEVgMohyA3B1hmMgIhV1dgA2YiN0JlRkRWNRBEE1SHMkVBBWQlcRdSRVERdVQRV0SBN1eAJkQYckUYRDEFFYNIdlgBEzFQNlMVGAVgYSOGgmNTIIiCZ3MDVEhncVQjQ2ODVIdoaBF1VoVxIDJCR2EhETBkKHQzZmR4MSFhIhYBIyQVeHNzhWdoIzNkdUModxKFiCMGBUFSZCEhIjMyVlMjMGWIUBQQd1FCiFhFAEdYdHI0gSJBJ1Zoh2ByRBczJFZkg3hDgXMFSAJICHMEgCOFd1V4JEWHdhgBQ3MlJmQkdwRAUkADiCIRImRGV0FUGFcheIIFVTgnFQZmc1NAI0aHU4gDchc3MXeFEUNniGB4FBgzUAZ2EThjNSIRRERSFHcoVHJiBIASiDd0hmgndnWGV1EYdBcAgEM2F4MBgYZCFoUYQVZgBlc2dnVkFRARYDdRFVABUnYSMTRzFRh0MDA3USUIYCNQhwRWVxUkVXF3UUYjAgZzU0dmAQEIOHR4hhOEgxBgMWBDcXUkd1CHMUAHFAVXSFFYF1VmA4hDF3V1B3cgR1FYSAdyhFgWRXSEECETdyNFJFc1WDSEJREBUgMEdEQAGGJDEQVQiBVCJoUAZkMEIXcogVeFEQN4NHNjIneCYEASI3GFIyBXYSBVRVIUZUeIczESVFAiEgUihoUhE0FGBYRVAzhjFngmMDcTM1QlBDZjFkQoKGcIhIR3IQRIMDeFSAGBGIdRJxJXB1UYc4c4ISVFJlBXYQZQOBR1AhEkCAeFJScCQzEmIyNTJHMDAxOGRoI3QkcWYYExNBASGCAEA2VFAxGHJgKDN3gVdiQgJzKBRneEgTFIFXI4VUVjNQJjCHcIdkKHQFdXQBKAYlc2eANGUlBHVoB0QScRJ0YAc3VTBxZ1EEEiWFGAQwNmNUFSUQdiYTJXeGJSQBQWZCCFeFYSgBVGZQUhEXNAN1ExYkdHRjAHUYF2IiMGViBjQTRDF3NQdGU3BDWBd3RSRyYFSDE3F2c4Y0YDgEYXMDJjeHYCURYmgmIQNnSDQwFyZFdgA0AhRhQnIkIUIRSAAQVwUwZ1iCiBJECGRnY0IQQQIGEWAAUCcDaDEWIjZ1hkIHAUiDiDIxYHQHhgZkMyU1iDcBQoCBBVBXB2BGQTYIVmeIaCSINTNTcQFANFETMgKBhShYAoZBZ4WEUxMFJTYRAkYiECIQOCGFYwh4gwiHEjA3EBNGEmVRFTdlWIQIZWYUJARjdxIhM1AzIFQWQWNxaHQWeGFxIWaIYHglElQzNQVIAFIyQyiGaBN0goFDBGcAQIATNjB0V1E4NlQQVxBoZYBAgYgCIDQCNSNyIlYBUCADCHYFFwYzYQIwOHIzNmhVRWA4YDdihDFhZlVVZQgFJGdoiIhVMQQ4ZDNTAggkJAEEKBVwEXSAMWYlRSI1ZTZ2QDVFFkVUcyWDFRUScocxVWBhgIiHhYVwSBMhhwiHhwiIdRIFcVU3h0VRQwKFhGJ4NlGHhDJ1JQIgEiY1GFhxN2AIAEOIcDAFSIJwcmgIYIgXdyNDVXgWBwFhZhF1M2ZFcngAM0aBgReBVkEHh1AjcAiBcBMyeBJCU2JRhWd0UndmiFFwQgRXEIFoJWQXBUZEeAFiQjAjAiJhZGATIyFIJAcYAyIoIYKEQII2MQFkMDQXI0ZSRhhjAUIRRCeGgFOGBGECAmAGJngmQXYTJSN2Y4BhRYdhcjgXKAdWhCIDg4M3CGJRQIRXdBgVEQURFFVmNycCVzJmYhgWE0VSJAVoNnZyhxNWEUcGPwOZJ5PpSe0dmUdmL-i4fNu8uQiOIiTy5QagcmszKyUsQ0wlvrq8XugBfeEBAcTq8C4JxlYHw2gJfKe7xEvIDwN_-0RT9BEZ9ie-Hn4LPnNBD2xPzwGYmflfc4-q2Y1gVPQ6nW16Hyy26dY91s5Pf5v3XWVDlpSKn8pAf7iKKle5o-Vasmtsi_ySIETw6N4Iw-OsWb48vwQdQcQEL09vUUxkGoodnfoA751RtQ7aSkyZix3IOlac08Iw3uMvIyK9oKp1xpL3Z8wN0GJCAKiV-te8p1_B3HgQgMXdm452_wcGehu2ZdYkyWEkgZzql8NALm8qDsn8XElFKhdtMiCTpRLkgk_pq_oQFElY-FolMaLbQq-tEjF9vN0EbqFzg0G30-WbFrEj75kUZoHvslCyn2QVDgCT66AlIEIc8TWIm6L0V3p2pEnSGeR6k27sUT7IDkRl-EmlcHh0KQsnWpZX8cYw--ZOX5iM3RpqMvlyAONuE3A4cmBZBovL2Dh6urXfrf48Er0TTv6k80L52M4tX-s31aq88ExWDSs0BO6ZW-MwI21LcHvE4dlwiKFcWCJrjNl5M8nSe2D57xrCSYWXd-QJ6AER0kacN225v5mbZ2aodUFQnn93yB6kd-nPkceEKjMtpEzz_fz7TliJjDbfD34K9p0QixsbudU5BaKy7NKETjTIp68wdygASUJpNZHhak9immFn6mIp_d9jHZKtkKQ2CuXlDgDnG_CwejxC3iZlg_-Ba0hLFDiKi2vPoO0CueToCnCsdRi3MNpF_FKITvH_mxzZHZJ6kFJ9kzbS11R6ZrAEFkZ18OM5z98X1U5xqmkEVKT5_iJx8Pu8fgn-8o8WkbBl96goiY3RKidnEwKRh8ENFfTocH0qbJHDZGfyUVioZxUpaQ8GVNfsUEUmcr8eqW6MNrDu606y54c5Rw4DHywMEvklG6nLd1G3u30QMmmmQ0u1wJG9TY4iFRUK6NavaudfMRaYXw7zHMj_SKzNBNgV5A4wiOvAsdlQoRo5_AKsDkdTH6uKdaKg8EYbjVIzEmghoO9p3sdW6s9UgnePioFPQE_HeI1wE5XB6xYERaLrMHN41qQvLeqjbis6cIojg1gm_PEdM_W5G815b2Xg8R2psr1bAQlRyz5XJq2QkhxPlyS5WkvkGAcU5DqtUOSt_NTbgdqV1eZ79Tvp9_ZbBzSPDq24a7StrHf7FNfooY8J6_egZvP2TYGtwV4rz_QNxI1Dzrh2ltIlZjjLWyPGCulNsf9_YGacEomwK3wERDYMIvOMWyCb9K8cdi8t9KqpySnzfl2ZdMSFGZ_YW6boipY3LvIjCNUtqEdcMAo76aD-UdG-dRN4kaPpIdbtBTKp4HS9qHNyk3Wznpco2zj5gte9J7RrvOlR9OuVwDOm_cfNSuY6URpnkdYbSy3fKyMUQ1tQWujbSd5_fpyDXbsGmdY-zB_zWEhOXScL2lK7KHgJZxJj_G9jjk8Ro2FmAicUK5Vd2MeVMBlke5bIgYjtUgMX4UkobSSyGMAbid6e-ErTAahWeGxoGdC2LqcgJxKGAhEZqvMM0DeUMS4gZmdEA8TXqAGhodTI9xNFecDZoN82pC-QfNHnb7GZJulCgHXLBC-AE2zqx7PY5y0Zcfl6sPrFYBVTnixewwAXes4K0ORO3SO2UFEi0WSTVkMjj4bzZTwlhQ3VV2c1FjznmOCbNJIJ8TWaivkUmYrLCpTWf5muFQ5nMMj32AZ4WP7vmG4kJSiEShPX9QbeFX8_lc6m8XXpd1-9YTGYSRPukYoXUJg9twdx99d84oH7Sth5jSIfSYs2SDNfYQfu0OzaEkRBhn7pZSPtTR0KaGeRQy7zdXXAVp1dA4aMuk4a3OnjvzDcBaE0h9uYOA8YN0rgHzPzMe07f6zUttgxYyW4Yg5dgCknKlt0ocImI-us22r0guisgLuk7efZnPrQl-Jj0pVVituB4g869_9l7_bD4SVynhJoJynGmtBF3yITp_k5LRbvRysW9pRlYFVchWO-PX17ErA7gChnEiTw1IFPMHZiGv5z1_WLq1nk0I1O9hqCmH59t8yOMMbpDMA8eCvDMY-mdg2f_rk5RRhrUCWSps0L4S2OCLS3Cy5ZS4732itmBmvnRWCIOk9rYQKGjN67xLBqAfl7Q1y0jx_7c_kHMV5xbLE6TEXux6--LyZHWKEF3OCH81cthgcyt0yG1UaTp3NEI_v5aWuwUH4l4UsXCcJAwiL9Ed577GNI1YbC6pwPOPcn_8hPO-BdwMW7sAdPTgeB7lKUTT4unvJT_Ie76CmqhathL67pDD-rFQBUMYjcGISyorczAdb2dKN7-MyvGuDpb9ZfMM283gRNpcPEgYGzTtarIEEVyv9diHaIFKjd5nD4ixAqJKBYv8CUOUpB2tCpXyM_kss_HdO8ovToK3QPuGilavKSOgZH1gT4IQAgECb7dMDJ0AwtHVlmme9Orvs4Ksf8tgmT3R9mKWaGFRqglAuTSyOVELXaPVCpGPBn3mmpjSbZLMWFwS8Q5K3imihRMwgUtoqvurrUy6FwnbKOwaPszKo6hmH_9OhY7HXD57Iefzlpd9nlc8seIcrPBY9mBlFOmqIYZj31hJU3Essq6RtzU4qaTREaZVHMTP53ZJzG-bVpPMjpv4XrBPgxfaWyX7mmhJXZlLTseZAm5bXyJ_SntA4sLzxXWIzExaaef8lN0aqsoLd-lA4mw9W4g911Qin1oWmuXIjr34HoOvGUek53jf6unxmkwc7epNWdxxBhjWmKZzHDglaJjB960hECqDXlKUHGXnhcAdV8d7AF-hg6afLXc_hfi1n5ZLDArmTK29Q6VEz3Jtsq6U6GdGDlPVvG_aZqCUVbFuP9Tj-dROMEXe54Iz3oF5OfYQYoicWTynEPXHvmv48EJq-vtY3tMFutsKNKKSGkv8POR63-zFUlmbNueDjRxhRuZ5VYpK5QCRKWi27D3J0iPP5hD1KznMs5UAm7OzqssAB_x_VDzhaWpDhsVL4xVuNi4Sr0am_deFivikUpoKUZMoKtVH9QuzZ88a4BGneW2Xe3HonCIo-Gjdebo6W6vbKafRVAO9OGKziRhDki4XZhEpcYksCOQQgl7K6dHus-_tsfPVqn0asVptnnE-Jz0_WC23H5rpMfJHFuLbbNEn9-bcWdR3nhgRlIF4RrwLVaf4qzR37Z0GFPX0AJrkr4LPS_B8G9u0Ci1A97y6OfTH8BDknSom7dapD3px8_dzvS-vvJRt0fTMfZ9TauM_DtaDbJ9uO8ahZPIKoFsRte2NtzEVaF0jCPq252OcFRv-fi8HaljZkc", - "encKeyType": "X25519MlKem768", + "encKeyType": "MLKEM768-X25519", "pkE": "CjuwTpSwD7NFkpXPXZdGLPQB4zwvnVYVKXGYnGljHQk0ojR4nLMQFtuS0ncgAiyXUoaHgGAVFIdCnBeLVIuVdlEf0Jy7xXzORRU6cVmq9rF49OtY4YFb1dor56oe5NJhmvWMbGIMK_cZPGGbYAZYe7A_JjKMUjB8eHkDcMql4bal8ialj8EZRNsdlkI7wPlGw1ocvDNgC9sdgaVU3_HLbqRy3cGAjtLGU5keIBFZBRZ3h3WJDiqFtIgyNMHCRFBwV9ULsNey5XiJKItjJFilF8JUCUapMfJwKZg41utgl2pemzBiHUnHcQNyR2A9ljpGc6SAjJpNVmp4LrQXAaEhoeMb1VqK6XMt4cRVlmCiMfWNsyyY5WZDArYMs_aSN5TPDQJWuxUTSHQG-wxD7asfzXSPZTXPdsR7BRIlahKfazuSZGbObICOcsu02mldPsGts5VmDTsNfvFQycjGjMGTfhcdg6OzfFNO0iaFgNxM-xkEdUaYKZOf6TVWxurKOUWExDqDkZavQigMr-imb2dWltsr-nicngYSQkt-ZGx6Z4kbuIVx4nuH9ValTBM03bvIaMEjc1U0aUODWFzGtmVN0gdqxUYwyPS6-xipzGt3LYY4FoCix8IWCTthIxNCK0ys1MtCFSF_BiPLwvbL7koFzQcbpuq79uOgm8eOJzGTiQEmIDS-CPC3izKlvepQbLLPelYoDyUPyKilHzq8NsiunORnD-N0Vpdq70kT4_OysbyKJrxE95i4valbYxoHmLmovtgdudfIebGVjyJbuYRuZWQwFpq6oHNJrOgugwl9IeKwM8U_8FrP8xeLz1dx_8FwSXhcy4VF4agzpeFLlBSCqMwr6Zmg9DIIpZoFfrPEMBkeZ0An0wKGfsWkOlK3BzCgDiBdCwKA7aJgMTpEp7k-apPNYZEnBmiTjnmkPHQuLJPBJHN17qUH15qjWTG7LWGeTKazMHkeh1JkKEC_hlqWDOVht_Bff-Wmw2IWaIBGR0wOkKoepFBJSgdtEVSo2ClCgoaAZayZneGQXDOUpCAz1fKhx6DAMgUs9zyLOfEHD4xh78WDjlGnrDE_swtkYxQQB4NNV-OW97JicwleFvPK40p3ajNKdCJdUExDRXIdjhmDgLML9KS0JOkDBWdacnFqT1dbZaO3r6eYi3UJ32IxukJSCjVnNMhn-5LAyLwjbwwdDoitSRlF9aUE8VcVE9CmGSpP8nrN7ykLpEeSEsE0b2IURvaVvgg_WTQoJ0pamDrAWcidG5ZpMTNOIidpqxawNjiJm9dJ1pF0Xqc7SdSR9RqPhewCB_yK9consyRuznlH_VAQqSEovJSZQxOHtEq4mGhhHdcOk8GZJgOwtuhMm3CPBoOfaUxTeFV3OQwPeAq3GrwSJ2AYd9gLz5IGrGY0hIp2FEg1jOYYuJmxg5A6xCuZG6VhWUKnWbya47kO7seKGdmN8UAZ3bOjw4qQyQMJE8JsgyM5nfwVqLrBF1aGZJJ_5XYok0w2ErgTNLohapmmDGha7EpRBsBiaOLMgnqwXM_m7jARCM0X6ccg8WDwuDxZndFwXZzkIc5zs0HY4usCp2THOwDodeS0VXLTpwYfo7zyF68l8XetCT-GxlxSEw", - "skE": "CDZNS-gKPeJMsblGZC33c-6rrv-JsuuVfitTnkg6wnw", - "longForm": "did:peer:4zQmZsKmffnwYVbGLb6ZmZ8gkgyTs8D76YQRBt5YnFNK4Sno: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" + "skE": "CDZNS-gKPeJMsblGZC33c-6rrv-JsuuVfitTnkg6wnw" } }, "vectors": { @@ -95,75 +93,77 @@ "receiver": "bob", "skEm": "EgVuWV1WsPbu8JDwzSWiCUkkjCeQUl0PkwIY_wtN3RA", "pkEm": "wfprioKR4GMkMcd24cr7B7sM1_iy88nTHbvkED2YVys", - "message": "-EBYYTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4CAtwfprioKR4GMkMcd24cr7B7sM1_iy88nTHbvkED2YVysWC_6GFqzGqxjBQhW05P2nlttvJtG8bu8WM2kZJiLlOeT7b2Wg0URDRYhOFeb4EtB8XpEUW6KqjqW_zwj79vMTAdrf8vq4u27MbDCQpI8qzeiGLN8B-tak3SI1vKAADx68VHVg5TQM-CAX-KAWBAAEBcQdynkYZuKDtCFr96nFQYAYqzFkccyYPS0gtlTpebinrsiEvafy7BI8mzfW-GrzH3zWIVclfElXBm8aB1oP", + "message": "-EBYYTSP-AAC4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4CAtwfprioKR4GMkMcd24cr7B7sM1_iy88nTHbvkED2YVysWC_6GFqzGqxjBQhW05P2nlttvJtG8bu8WM2kZJiLlOeT7b2Wg0URDRYhOFeb4EtB8XpEUW6KqjqW_zwj79vMTAdrf8vq4u27MbDCQpI8qzeiGLN8B-tak3SI1vKAADx68VHVg5TQM-CAX-KAWBADatiGf0keq_Yh5pDYzDpKoicsevHubnS9RNd5rRX8Sn21puLukElsJxroPtCRXFYTcwkJqazpoWpCZAv95sW4M", "payload": "-ZAcXSCS4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BAA-AAF5BAEAGhlbGxvIHdvcmxk" }, "direct-hpke-base": { "sender": "alice", "receiver": "bob", - "pkEm": "1T4oA1pSbehBiIwnoXFGA24kgHowT34VdE95wF9qjSs", "ikmE": "zmfPZS31ZecVid-0CvG0x7YPwxkwy_8TLqggDcwUDJg", - "message": "-EBFYTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FAa1T4oA1pSbehBiIwnoXFGA24kgHowT34VdE95wF9qjStBsok4fIkbu8IKODF2nsZMUAmS5BqxDbbYrvl_TNGpz2omwJgYX4bSYoTeKse4-CAX-KAWBADHuTmj_7jyUCkkalySPOFiy5pTbNtjEODiwwJZlI5DqMk5Wutx4LIOWkAAa3uee2b_0Kh5SXaFq65MedyO5VYJ", + "pkEm": "1T4oA1pSbehBiIwnoXFGA24kgHowT34VdE95wF9qjSs", + "message": "-EBFYTSP-AAC4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FAa1T4oA1pSbehBiIwnoXFGA24kgHowT34VdE95wF9qjStBsok4fIkbu8IKODF2nsZMUAmS5BqxDbbYrvl_TNFj6rHuLymWkvlrkt54-cOq-CAX-KAWBADw48mquyWI0O40nsbcI7jRugSJko0JMZR-4S07YFJq3Mzy6jvAkEsDGAecW9jCUVDdwZScckWUaAzSSGbNunMN", "payload": "-ZAJXSCS4BAA4BAA-AAF5BAEAGhlbGxvIHdvcmxk" }, "direct-signed-only": { "sender": "alice", "receiver": "bob", - "message": "-EA3YTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB-ZAMXSCS4BAA4BAA-AAI5BAHAHB1YmxpYyBhbm5vdW5jZW1lbnQh-CAX-KAWBAD-jhE5h1oMTf-JsSEMVdJ2ntTahc3PFi25mQ6kPvbnPqfuhIQzTKxuTvfYauG95msg_yb2eryo3wvg1YoX7xAP", + "message": "-EA3YTSP-AAC4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB-ZAMXSCS4BAA4BAA-AAI5BAHAHB1YmxpYyBhbm5vdW5jZW1lbnQh-CAX-KAWBACLj6MsdBES31rSLHtwvsl399JiRr8guUU--hauBWZ9zftvcY7LWzfK5JyEOcqb2l1F5c32MNtpDsQjmQgn1m8F", "payload": "-ZAMXSCS4BAA4BAA-AAI5BAHAHB1YmxpYyBhbm5vdW5jZW1lbnQh" }, "control-rfi-direct": { "sender": "alice", "receiver": "bob", - "pkEm": "U9I24IIKCz-mPGP1IZcfMZohp_eBlv-BBlfLm7vbUWk", "ikmE": "ew2j30RF7AyIl6ompEoE-0acQb8yg_Iyk303CTx8HJ8", - "message": "-EBSYTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FAnU9I24IIKCz-mPGP1IZcfMZohp_eBlv-BBlfLm7vbUWlcL29m6RzNgGaA3yIiD3pFzZJXgoeCU1eij4KirnEhlzPGETY8c46grFfA0oxKauyhQSKfn8OxuivWKEaP0_r0j9JfxngveOHpa0A7mCV8dm3taohU-CAX-KAWBAA_tgpqb5e4Vfz2bXZ9ZMrk0K_pw4tSD7xd9PfHv6uPYLhaVLNap-E4pVf2GGLw0qKeadFPDV2WT4gGX2Nww_AF", - "payload": "-ZAWXRFI4BAAIFv8e5p6Z1i2FPunuNF26mSr2AHU5zPJGb7nBuVIPr6e0AARERERERERERERERERERER-JAA-JAA4BAA" + "pkEm": "U9I24IIKCz-mPGP1IZcfMZohp_eBlv-BBlfLm7vbUWk", + "message": "-EBSYTSP-AAC4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FAnU9I24IIKCz-mPGP1IZcfMZohp_eBlv-BBlfLm7vbUWlcL29m6RzNgGaA6llzgwarcJ_sziA26tvIdjNKso7y8wD8jzERbXsSQ_PA0oxKauyhQSKfn8OxuivWKEaP0_r0j9Jfxnh2oanEUeLFG7wJ97xLQfnY-CAX-KAWBACNFhexhFZuxtMYcR0SnzKbkofePpeJJlPsgTyHPUT2YcG2GR5ELoNtquUeu5ltysJtqfDBwXgi2UvPhsSOJrkJ", + "payload": "-ZAWXRFI4BAAIG6HKhYGieW7r7cADGj6gJ0aMB0rNFf6IyDgK_u9jFE60AARERERERERERERERERERER-JAA-JAA4BAA" }, "control-rfa-direct": { "sender": "bob", "receiver": "alice", - "pkEm": "qVZSTmoBq-jrBX8d1pa40Yk5J28FT14vIHOh8-GN6VU", "ikmE": "vU7UpVjzd8nDZDHJ1NKaDdwEzUDHI7PRmK1Udx160J4", - "message": "-EBVYTSP-ABA4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4FAqqVZSTmoBq-jrBX8d1pa40Yk5J28FT14vIHOh8-GN6VXzL1VMQNnLb62gQT0KXkUQj74Jikwx7vUJlxbrJdtnskeHwsE-0heOyQ9hbgVIPjbvbro4DiNE-jSYkdv-xhIF8v7UTyc7OLTwd9ay2_hd6kaXfsa8Ecxv3_3deNYe-CAX-KAWBAB_2tB6-CHdYpaTYbgbvYgRNzQGL_LUn-sy_sga4tWPdHcnH2cUeqvF6r4k9EivaZLLem7S2YfZI2kAsWWTVXYJ", - "payload": "-ZAZXRFA4BAAIFv8e5p6Z1i2FPunuNF26mSr2AHU5zPJGb7nBuVIPr6eIB3iJQFdVqm5fH9RoScnqBs5fIofg9UUDPj8Cm_LkGYS4BAA" + "pkEm": "qVZSTmoBq-jrBX8d1pa40Yk5J28FT14vIHOh8-GN6VU", + "message": "-EBVYTSP-AAC4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4FAqqVZSTmoBq-jrBX8d1pa40Yk5J28FT14vIHOh8-GN6VXzL1VMQNnLb62gdEZb0jn-MrOyxuuFV3ljbqcDOSS01nS9XMYTzOI8JqthJqS9-0Y7fa3YLQvlZmF2VPPfUxxkzmGMFsguP9GFj-Wy2_jbXRvbLGRyd9n5Iu0x6fZY-CAX-KAWBADOiTPO66uSeX7v1x8LVcVGkiJvoRaLemx6g7torYTWAC2fXuVzBxTpBBWUxqHq-feLHLlPF04nQtVvKjwBY88D", + "payload": "-ZAZXRFA4BAAIG6HKhYGieW7r7cADGj6gJ0aMB0rNFf6IyDgK_u9jFE6IFVD0MQtgrqunFx5ALtyRt4RXR8R4umLVKETH2iu5Z4h4BAA" }, "control-rfd": { "sender": "alice", "receiver": "bob", - "pkEm": "OLoHxJkegv3Q68EgUa1HPL_ELnoSkq5XE30aiOOC604", "ikmE": "16WX82PmX4bBjabLDE16md_SNXRJfNa0xPn5_fp6GVE", - "message": "-EBKYTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FAfOLoHxJkegv3Q68EgUa1HPL_ELnoSkq5XE30aiOOC606B3B1YEcvuD4SDsz6TJiaJavy3u83tzf2rlJFV1NsV3QJqO3GwG2gHxOBeTblt_9yZcAaBs9-hgEO9nm-5-CAX-KAWBACH2iTSkMLf5JsDKTu9JUmptveFad52vuynvG5FUwMqSSvDUpAG9QphNBY2CmwZNVQStTjwNWG-NzaiQt_hJw0F", - "payload": "-ZAOXRFD4BAAIFv8e5p6Z1i2FPunuNF26mSr2AHU5zPJGb7nBuVIPr6e4BAA" + "pkEm": "OLoHxJkegv3Q68EgUa1HPL_ELnoSkq5XE30aiOOC604", + "message": "-EBKYTSP-AAC4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FAfOLoHxJkegv3Q68EgUa1HPL_ELnoSkq5XE30aiOOC606B3B1YEcvuD4SDhkXCqlpn1_EM92pZdHHBbSC9yCTGuTFQpXadBZ21K0ReTbkUqjyX4lDkzJyHnFRHC20C-CAX-KAWBAAP0xHZu9aQ3ipUAO_IlZ25t-YZycYCnzDoep-n707EY-MQNqkRqA00M3KvMwBAV_iV9_jzDJ8TXrKiirrrahwK", + "payload": "-ZAOXRFD4BAAIG6HKhYGieW7r7cADGj6gJ0aMB0rNFf6IyDgK_u9jFE64BAA" }, "control-rfi-sealed-box": { "sender": "alice", "receiver": "bob", "skEm": "Z4ALsIFbWmoNYPFkP6mR5CYbOlwk3Oa07reQ9j9BbYo", "pkEm": "DvRIPYQKw_paPzePKdSbkGiRcRNmjYHhx0gYr0S543I", - "message": "-EBlYTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4CA6DvRIPYQKw_paPzePKdSbkGiRcRNmjYHhx0gYr0S543IUTpqE3k4s9HkuJRqrD8LXaYNucbfQLrI9Q_TfieiYffgOvSAPhO5cAisip55K2b2AbuPDV4Zk5EnAMy7-470OWR2mI3ouzQl4meT26JPSyg_rg7X_evwr8ZJy5MbImIzNsXyhokDa-xx64NI2P9EtoAp7jAt2L_c9YW-tI0x9gtg3b53hlA0RJj1GWRop-CAX-KAWBADpDxx2j-GxAdAbAMV57_2ieRHgJniYg9zwHZXVAVS3JLfRDe2y4iEN2rQkFUe2i_iam6ucCwHRUELVXLEOddYG", - "payload": "-ZApXRFI4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBxFAQ__3XiGDTJoRE3D0dX6vL9mIKCqGteryySXu5yNgvW0AARERERERERERERERERERER-JAA-JAA4BAA" + "message": "-EBlYTSP-AAC4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4CA6DvRIPYQKw_paPzePKdSbkGiRcRNmjYHhx0gYr0S543LPuthiS9TykYKBa5GgjpzVaYNucbfQLrI9Q_TfieiYffgOvSAPhO5cAisip55K2b2AbuPDV4Zk5EnAMy7-470OWR2mI3ouzQl4meT26JPSyg_rg5HmXmMJWnalpAWn06Gal8YMCDRbZ0255gZ9Oo_cZ8lsjAt2L_c9YW-tI0x9gtg3b53hlA0RJj1GWRop-CAX-KAWBACZ_SWKSrGs0IJizGHSPHgDFXfwoB4xQFHecjUVbYA8d8jPfVge-5Lj3FW2E9gY1xx4to73eQgj7fc_jiCVuNAA", + "payload": "-ZApXRFI4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBxFCAm2-rAs9Ae4dJYRGoAzEhQMvYDNDqdqfjZW7CD8cjB0AARERERERERERERERERERER-JAA-JAA4BAA" }, "nested-direct": { "sender": "alice", "receiver": "bob", - "pkEm": "2lwtszl6nTuyUHQPcfgHqTOLcllbgMpL5_tD3myO5ko", "ikmE": "wTSnRd6U5rWz-3yO0ngUXXg_6V5WgUjGbGLk0LrLj0g", - "message": "-ECeYTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FBz2lwtszl6nTuyUHQPcfgHqTOLcllbgMpL5_tD3myO5kqpyGOhlgwX9CKraR5Zqsd5gQo7pmzcqtklHmtpSe0VUGRKNk7lkfZ20A6iBtCP1VqpCenjGyAJ53mdytJaBU4yQlfk6_h_qkKkr8jSQoN13rtqJFnFKtSekDzdd8MtUk82fdLHrNnmk8228jNhzbL2mewQhT_V3x1-FikjdZELf5LksMYsRVdiTbIqnVk0Co_EAAO_fNEtKS-g8X2RFjJ4RHAqC-HmTC9rQg-YRasfnB2d9HuK9nLecMZspuUHPEV7Tw6UDpjSHAqwyxLkQ7Lxxgmjc4_5WRW40q8smgcd2coX_MBnjRKhY-7T4Gbo4wQ1g-6KdFgfRPbxU8mK9tN2Ch3HAEgajunFklLWpwyRRJjTYTteYXy4Z8_fYvksFnulwaI14fXVSZw-H5wT4Tiua76wgDGaWUrR-CAX-KAWBAAkhxeb5pP-zAgzjEdQkHMcjb3_U6C5KH-Nan-SU1Mhrog7UzKu1EWq8wqEU_JByX0RbDz_wXMke_SbjOG9JcsC", - "payload": "-ZBiXHOP4BAA-JAA4BAA-EBFYTSP-ABA4BATZGlkOnBlZXI6NHpRbWVoc2pNdVBrUGp6ZzdXRjJ0SDVYMVNHdUZNeGFjSkI5UkVUTEZ3amdNRHFY4BATZGlkOnBlZXI6NHpRbVNNdzQxM2tlS2hncFRwWW0xcThqem1wcU5Zd2RkVkdQdWJrSE5ncDNxUWVp4FAa18xMvIf8fW5FF3cOHHKPlmJY7CNOU4gMdUw06e03UW_1PVt1O92_IkwQWqsgqb--yVFkjJd6aYMUklWFZRedb-1Dges-0k1J6Ci_CRjw-CAX-KAWBADMVJ3ENHk7SRgzuBbzonXVQ2vu4uVtLAu4Icbg1s69jW9RYPw4TaZKFvVR27mf32fuxj1YhrGBaf9hyEfFAJoJ" + "pkEm": "2lwtszl6nTuyUHQPcfgHqTOLcllbgMpL5_tD3myO5ko", + "message": "-ECeYTSP-AAC4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FBz2lwtszl6nTuyUHQPcfgHqTOLcllbgMpL5_tD3myO5kqpyGOhlgwX9CKraR5Zqsd5gQo7pmzcqpslHmtpSe0VUGRKNk7lkfZ20A6iBtCP1VqpCenjGyAJ53mdytJaBU4yQlfk6_h_qkKkr8jSQoN13rtqJFnFKtSekDzdd8MtUk82fdLHrNnmk8228jNhzbL2mewQhT_V3x1-FikjdZELf5LksMYsRVdiTbIqnVk0Co_EAAO_fNEtKS-g8X2RFjJ4RHAqC-HmTC9rQg-YRasfnB2d9HuK9nLecMZspuUHPEV7Tw6UDpjSHAqwyxLkQ7LxxmW98egYKdSiaRxh6Js6BBoX_MBnjRKhY6-kPFnkWJgUA2NhQyzZ4QpYOZwiRT6qkzqB1SWU_hgQ_WLLxr1bMoaVuflEN9Dv2tKRmXJx1LMtWUkeP6Z_e5y0Cnl3d0m10M-GJnvVBBtp-CAX-KAWBAAf8fKbSjXyszjAzBQMtY580wZ_F-rhMqGMYbEGBs4te68JmWebtqW0r4cO_jyf4EQxMSV2wDmc00e0XoUo1N4M", + "payload": "-ZBiXHOP4BAA-JAA4BAA-EBFYTSP-AAC4BATZGlkOnBlZXI6NHpRbWVoc2pNdVBrUGp6ZzdXRjJ0SDVYMVNHdUZNeGFjSkI5UkVUTEZ3amdNRHFY4BATZGlkOnBlZXI6NHpRbVNNdzQxM2tlS2hncFRwWW0xcThqem1wcU5Zd2RkVkdQdWJrSE5ncDNxUWVp4FAa18xMvIf8fW5FF3cOHHKPlmJY7CNOU4gMdUw06e03UW_1PVt1O92_IkwQWqsgqb--yVFkjJd6aYMUklWFZRfxcW8kYJv_yPb6pVojLsUg-CAX-KAWBACNI0H7OMKnaJi-UyGHZNAp6gG7SlaA8JKfZxONWL5MWABhfZ2Jh9BUUC2Twe8ziNrziMbT23NJ4WeK45mWqqgJ", + "innerPayload": "-ZAJXSCS4BAA4BAA-AAF5BAEAGhlbGxvIHdvcmxk" }, "routed": { "sender": "alice", "receiver": "p", - "pkEm": "u3jQxhX4ryavA7_XLCdatfNVJssymR8KjHMqFhCjl1c", "ikmE": "H_LnY626_NNxiT6uU0Cd6029AGyYDUMOKrr3BlRyk4g", - "message": "-EDGYTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVh1WXg1cXVOcEFZdnUxc3lhb0hwSld4SGNlQk04UG5BUzFKODRtakVvMTE44FCbu3jQxhX4ryavA7_XLCdatfNVJssymR8KjHMqFhCjl1fHhCX_UWAqrxNVo7bN-T0MGRTxtZbXHohFBpJBtj56fuw7UmON9OGL5WewM8NS0pCOIVlwvkg3zFasindp0QF9RtKf60Y5ZewPVLKJE6zrYGM2B6fCupmO_qBmBJjXuHWh01-rGzvpFO_-Lldld7PmcFCcTrJDwLb39GhO_MQ8anZkjGz3AOAArmiwDhfVo5PNWj-7OnZ5fsKE5hBbf_2ZGN059sGqofoBGzM3KV9eCcZccBL0gmUCp5pqy_VTzsB19HhzED39WmMiFK67ZwFMmME9yBfMk9hRjyiq7UTulmS6E4X-TJSOhoMq7a3jrDKLzLeFyh6v_Jbu5_aYnz_dohJstsSkhwqCSuQxudCHC9pumoAaO4rE9pg8N1_yMg3bHL7i_SwHELoRSb9zMJy_BDGNeNPqYE7UdwnDanzHVqJ3UHzfkt9mwK4TSkS5YVmYsO2yhFRbK7_PR_J5qlizbUX8oJpm8B7JOrnBT9cUZTCVG2ykcJHrsqNrAlJCHtCl8g9LGpQXjo2PuVqpqF08fFYat_qR3HlZbOPOF13DE9-IoatO88XmFIPoLXd07MA9-CAX-KAWBACFpYywiBN-4IGmaNbJjoMGzmmLRFPtFdZ9Lo6Zhy-skvljp5e3qLMi-5rGYJO0D93U0A_V1O5gTC9LDSUlvjAG", - "payload": "-ZCKXHOP4BAA-JAo4BATZGlkOnBlZXI6NHpRbVRLYVNSZXhuelgyZWN1MWVZUnVzRk5lV2JyVDVqYmpyM1lqdGZnY2laYzFR4BATZGlkOnBlZXI6NHpRbVNNdzQxM2tlS2hncFRwWW0xcThqem1wcU5Zd2RkVkdQdWJrSE5ncDNxUWVp4BAA-EBFYTSP-ABA4BATZGlkOnBlZXI6NHpRbWVoc2pNdVBrUGp6ZzdXRjJ0SDVYMVNHdUZNeGFjSkI5UkVUTEZ3amdNRHFY4BATZGlkOnBlZXI6NHpRbVNNdzQxM2tlS2hncFRwWW0xcThqem1wcU5Zd2RkVkdQdWJrSE5ncDNxUWVp4FAa_Gblg2mbPRmyh5lhWb0A-hzL-Neyd0LKd1gGhh-ILyOsKH7KHRVUqhRWKUcoR8U9j2EogB7xFwucVDU959TAd9Q2QqSjB-jE9i6eegLP-CAX-KAWBADtlMyQTv0kh9azrwhi4zZBRWSjYytoDK1DSDI3ipa5yqU7_YYADFl32dyFqvSZdh_YxLD5EcpCK0Me6sA8aA4J" + "pkEm": "u3jQxhX4ryavA7_XLCdatfNVJssymR8KjHMqFhCjl1c", + "message": "-EDGYTSP-AAC4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVh1WXg1cXVOcEFZdnUxc3lhb0hwSld4SGNlQk04UG5BUzFKODRtakVvMTE44FCbu3jQxhX4ryavA7_XLCdatfNVJssymR8KjHMqFhCjl1fHhCX_UWAqrxNVo7bN-T0MGRTxtZbXHohFBpJBtj56fuw7UmON9OGL5WewM8NS0pCOIVlwvkg3zFasindp0QF9RtKf60Y5ZewPVLKJE6zrYGM2B6fCupmO_qBmBJjXuHWh01-rGzvpFO_-Lldld7PmcFCcTrJDwLb39GhO_MQ8anZkjGz3AOAArmiwDhfVo9HNWj-7OnZ5fsKE5hBbf_2ZGN059sGqofoBGzM3KV9eCcZccBL0gmUCp5pqy_VTzsB19HhzED39WmMiFK67ZwFMmME9yBfMk9hRjyiq7UTulmS6E4X-TJSOhoMq7a3jrDKLzLeFyh6v_Jbu5_aYnz_dohJstsSkhwqCSuQxudCHC9pumoAaO4rE9pg8N1_yMg3bHL7i_SwHELoRSb9zMJy_BDGNeNPqYE7UdwnDanzHVqJ3UHzfkt9mwF1MM_QZdKOvgvfBxE9dxEHPR_J5qlizbf5nGw-4-Nbqt0y1YspyqoHUM7RS8CNS49ihzipCXyaTJQKe8iAamp_Ifkpya_Ufh2-9B0rfUcgRguVt6plFzt_cfp7d8p7yHAIaRGlVeVEi-CAX-KAWBADXtOMgFILitn6czr6D3zzczLT8uAfUBn8x0pBiFu92B-gyI5V8KaYiOvtCqiKVplPFx--C4YAVoNb7mnR2PR4P", + "payload": "-ZCKXHOP4BAA-JAo4BATZGlkOnBlZXI6NHpRbVRLYVNSZXhuelgyZWN1MWVZUnVzRk5lV2JyVDVqYmpyM1lqdGZnY2laYzFR4BATZGlkOnBlZXI6NHpRbVNNdzQxM2tlS2hncFRwWW0xcThqem1wcU5Zd2RkVkdQdWJrSE5ncDNxUWVp4BAA-EBFYTSP-AAC4BATZGlkOnBlZXI6NHpRbWVoc2pNdVBrUGp6ZzdXRjJ0SDVYMVNHdUZNeGFjSkI5UkVUTEZ3amdNRHFY4BATZGlkOnBlZXI6NHpRbVNNdzQxM2tlS2hncFRwWW0xcThqem1wcU5Zd2RkVkdQdWJrSE5ncDNxUWVp4FAa_Gblg2mbPRmyh5lhWb0A-hzL-Neyd0LKd1gGhh-ILyOsKH7KHRVUqhRWKUcoR8U9j2EogB7xFwucVDU959QzKK2G4rFZMNrehW6FfO0x-CAX-KAWBABWD3cFkPXspFtG2yV_hfnwBEx7lavatfw4gv5PitdP_HI2KG60AU1lnhuVcTcxVeThYwBJX0fzY60YST347tMJ", + "innerPayload": "-ZAJXSCS4BAA4BAA-AAF5BAEAGhlbGxvIHdvcmxk" }, "direct-hpke-base-pq": { "sender": "pq_alice", "receiver": "pq_bob", - "message": "-EGwYTSP-ABA4BATZGlkOnBlZXI6NHpRbWJMcXUzd2VadHNuTmVzQnplY0NabTVGQTZ1YUdrZ0NXWVI1V25kcjZHenpk4BATZGlkOnBlZXI6NHpRbVpzS21mZm53WVZiR0xiNlptWjhna2d5VHM4RDc2WVFSQnQ1WW5GTks0U25v5FGFAG_gn35RNoXWKshZoo7uJpjoK4rcKk2jfCWOYB5delcb_W29HoRlEL0dSVeU4hgMITPH3cryDD1lyXErM9gmApU_t3X2VMWTbHMN8i8YqhdzaUnPWWDqRNtFjChapB_euEuUWFXJYvlz7tyudeTDJxbbXFn5s_fzwvfKwPMsvzF0asVGhxKC77xe3cMht126-gHc0xx908WrHrMVUtfLXWQiQmIsnXcbHqPwbHnxDWamgaWPkbwjebDDnJGHwkAg1jBz9_Wo6RYymhGpBGqc2L9IsGfYSzy9PaSb22sg5BtTLO1vf3o_d3KoAks7uHG7RYDQgarMl4pWZUaICod3MK7yZlTR9LOsnXqkn2UXMyNg5Tr0bX6iEIw4bM77HXu2Ic84eF-2DfgXbK2I6DdH-KcH2b2EMmv95kC4WED-jPGoQA2Wd7kBNYlbYouQU4nDmmdVjOVvo2AeD0_aDu3cN2nQyINx34ryTcGjG6sfg6H6FYWT6yET7vpfPpZlx_cs_qq9QC9d5yjZOSzyEmgQE4a0QVGtxdk8a_Bd2O8gGutWbM5fFNLoPEwreECPHIuhuMBXMmIqRS1igha8yN_dvapSle1WrHVy9EADQww4KzR8DHvPVuqbCEKtm5_zA0jYiLtiiCGkfUJnBI5k07acUjSSmWz3idGItf-SmY4latHXAeWF6i18cJZkJjV2MA3s1ufE0xB2QgRMs_zwpDAB94ICwBUcMBuce40rVhamBx4_RPvr-FsX_IUMBOCRf-p_Av3RKqE2KQa83IgWUbgUnvXHsmNOtArVpTD5wtIDB-Pcwq_jvOgyKYupgddkTwo9jY50q4R3u2Nvm47NjurQKJ1jvmVsv-ouSfIYGeUrqWOkbwjfkgenLJHv7ZnXE2bPI-KkkM4n5f2OjCfHuirtQnstKEd4gCbhUSx5BSpjoNLT77emBWb_NjiKdCZ8dugvuu48R9uaAc3PtBQyf1xkyHpUoge7FLHRDC_Kc4mITunie4eC4SjaBpyVwL2PwW-pPr8J1RHOX0KNqxFq_7ZocLPdzAtgaYkLO7kaIBRKH4gGPRsoO4eyk0DrUzIaZBqp4VJRE7EcE48FjtneHHvjPc0eA4v35CWpdPtvEHgeAwsXgfF64Bn_PIMgyMt29Ja-s7Ob4j4TGOBXxxdMUhf67z9nnUARnLej12ARzaz9Wa00fQjfvJQVaxbjeZ9kFDM69vjW997615Oxute1YenKcZqACx9EoghOqj_xwJphXfBIQcy27pYcOPDm5Q1vjLryDv5kyyp0bIni5sIqUQnrJ9InUy2VBtSB0wE_drnoiwQu2_rMb_M0jgnuNZ-N3Y9haW4AMX7a-5uttqK-eyQO0OogmCBr8pLN0ZC7aQz2KbPl_TDxQQgrCn2ra_1VsYn8hl0x_D1FQUeB4y6bA3LnfUuVkYYYoUFQQGy5oCdT-AjqCSqfOoGRjRRBfsOpm67DykdVa1BXIEgfXNPCzfHzPHvAkYdH1aar1fOZINtK9jKJZjz-5RtiE2yvMWqj628njag-IiDxyVRM1-5WD2VR-CRR-KRQ1AAQ7lG6KIMGuSHrKLzGbLDrkCKa1exarWA7Go0792shiM2psZaZuqyfY7fO0V0vY4B4uCOlCWiRxbAR3JzslRQnRzE34f7CseSlcO_Xv-yR1USl0Ad3i9dkdjsqrp8boBA4unSl8IEi5b6syuIORGnQCQZvO1xbHTra_xwdNe9H-yvnaeZe-e9JrvI6wTEXKpwfzj6JhUliPiQiZffpC9aFiaMz4b8s6i37tWRygHFrlCS97tV2fCL9XkGms5vjLzNVBmhBw-NvcgLSrtfXLpvBOmNIphE3kzFAi0vZUa2phQKuFmlviyFrPHPlVAN9Q5WGbst425cS2bIE9meRNnD2i7Y5F74aSPwbow5KDpQQc3Rch3OWWDRjspuxx9zYTkMRIatosRJtXc2dNnGrRoUHKF2-5DKrJ5Gx9J9sFm4f1OQ4IokxmGj-YkjRPiPukYFvUFrobfRx3kyhHzxoHpMgmkN98dh24tlVbVpcsWXwhXkfoGy2fvTMQE3EE7ItA3deCXumiFwHeCFpNOjyEaLj_s9zBI6NF3lvtR0Ex17w-YehP7_zyufpwguCnyxxbHFAbZDOXGc5jMntG2QvosPYirxVoEQUaQg4nZFCikoWbh7KgjXtzLnctKBIRn6DSeNYNdIweq2M3YUJOkk-Au9tTFSO8UvmPiww5oDBT927QrpeyOLVBuHYBC8HFFe7_XbmBC2T-_qCs68f4OqhLbMdK2SM3O36hIXK81QbWR-2_3Zy7qgLRVRiHNIsycmWibYsD_MmSzM7s__J-jzDTISOuj-ZtoKtAcmYndpLZLzkpWoKfxHSfX_PUH1T0My5nhGypx5zSQ2NxOur_PoYERR0bijcAAmzqRm2xtBaGqI6YbPm_88y3hlzU4N1wcFlyoc8R68rHZk25UR5oVi4veVi4_s1itJ1tNVUojKvbYpLOUnVa_A3-G4B6uYBrIW7svDbBzV8cp-ptNGkBrIyh3xNSftImjH641Y49wSfds2RS7K4_QJyJpeRyhLTD3xabL1QkKO2hqNFD0aEtLtCPdpaUvFxrCgL7vXdR86-KnJOP5bedbWNiYGRbUU7JdOQt2pFOqMlW0TWfl7-313tavijKuy4DoSCA_cjlWsc7XWT8zPk0gTSFrN8QH5EF2rAZNt1F7HjZibEDlzC5fb559Y9TB3Kud_LGKfOjqcFQDrRKGpaJTFnBbgBZdk2Mt96QVMUUYJTvHjeUlbFi7MtNrSuGjTItrf2SZWq_c0MJN1T6KX6ZPEVvqTZ31shLhwXW1MysbGdavuF_-Z9ZXwUYeWdmi9mWAfio10dfEKhpjnnxHVaPk7mpKH2883L3GnkzV1GQSJbeykEv-bEgmSEmVNo1QwFcAEBTfndi_vUmSxTtNWUct7Nv7nfvUTmyy6FECGTYaLoT8VfZRPn0hwi5axZM--6lC9qLEWk8PGWQk6FEFoj6jcJS0s69IzasBXE-JyZaKKOORagAjOxYoAv3K0h8N7wSxupoukUwRrYn-4WxAddpfFLTuFGwoqfp4Va0VZXsMZtuXXUkqlPSCfBrvs7m56GDRVCmLGJlI7QlMMjNgde2dxgKo8sqL8mYjZDHAJG732BaGAmGNI31KFy2lCe0ot7JOF5vy8UMBAfHGEprgQpCvRAfzHeJSSRg8ZqfQTCOjKIuGQeKRxYhEXv74-ZaCVNF2qE02ldQ3ugkt642VQXvo-rGSmH17L7P6T3JkU7zUvnO3HMrgI0xSzY1RHRgICCeFi35s7cqliW0jHbuHhQ3VkzY8ZXO8LBLM2nwbor6BetQYmgrhWefqg_QOXyKnnuuwT8sZneNDKpfxPLD_3CKSib56PoRdmZIjM8f1xKcje4ceJktg32XunXWUlDM1ptOLPb7vzniVZycycC_0tqsNk0V_NSbR_wnVsE80t7d0y8uKV7i2-nISibVd6MuQoIVq3dNJ8ebJZkvTNIApOPlPe3KpyZn73C-oROuGINs7I7QDfkrHzsVm-2V7pRYfpdtGNJnXacAdT29Jz20PQBQh11laHcRh-o3JSmzQHRbsHVYi6oBUIi_NUnyLe5lfWXB3BPafxPCVbTBw_WtwEYUBEzpbvNIx_9kaGP068S4Co-qwCRFIS6dsR6d7O_TGsPfddpgESp0XmeWqtsu4x3nTipUVwlDlf9yL4iaOknwejxzdG-CvTlPUCTjXfuE1mv35tptCWjP-64IHPANUHQVfok9otzwWS5Y-y4Ih3yEX9Sriq7WOWp0SVgZNZ7J1r4f3ghHl2zo6W_ec8M5mOLAFJjZQNQzSInA2ZrmtuJ8lXhYht0ydTblDhi1Woprz-hBsmoSVxe2pvjlJSmHgEQUsH__NR-83AP2atgi1MdUqOQWQDCpW6DjYgbOhP4xZiu6jdFqp6AAyUpb6w7NrTqsObzZrwFD72ibmGA3baV1v-z8XSFhYi6FKBf-QLRO_AFzyc0w_vRquM6E_h2X271_SkYSp5A1YtdepapEU6O_e2ivK2lP6ctlv_F2QVFfF-8Lsw-aS9iIJsvrRBXqFct6KkF9XSW7nBcVmKXL-RMZNf2XTtBMta2O2vohS6R1M04g5Ls1w-4dk1jG1XVABNF9o_ECf2ARKMKICbJsQppnJd00Gb5yKpbOwt0D51YOOKF5aPmCl0kX0eB70EHBYa0MIcZuRs5SZooDOVe1sLLrTphX1uHY0TapWKX0_42-434qVgMiSCc7KxJEVDSHHoEof_DVVX9zKdXCbfK5Nykyj8qfDOX21vZP_yNB171nFSpu7kxqrN7q3mC4YMxzPZzFzfgPmWqSDTXBYFxzFmt_wSJSVCjJATRlw8mg1Ay-8xQHWT5K5zikRuNoIgS_cy7kUC8t1EvGN99SHCAvDqN6GMemIv8Av_rCRhlnpVR1XbhutWjrPqoVh4XV7iCBfewlJYIOtocv20tLlbplxC_3WA7goKoKLn1QDrlRuk0lslueye6vIOMNBZv_brPkAilqAkbUVYtiMmnGXOvB3U-rzJ54D9kQkI_zJarhT-wSaMCnoBd2KHyR4rfGnBXCs6xGwvWycET9E8q5ApDjYVAZoOBOl6KwKzCtPz8H2cKmeezVkL3IvTVZsWZEr55WWwioQhPnXpCAgZI0HqEwCfITKh_d_0-Nt3PJdXQygL9Z6EKKxe6fGfs1rx33U86fOiWVftpRWY9WnpreUZQSov3OgtFSeFQbgK2C3WZOgOl6rfzKu9pQjXWHmk-xxWMCIKKSTBmfv2eHzzp8UnBoKSUALNNSMXxA5vUwGDh6iGziC8O0QGex5prNNspjLd99B0TO-NqJVeNd0fwQ5iHWiswfr1Ak3jzYqAyq6mRlUG5mIHNAiDLQb_EizjMQapBSM_QvvZabVHf8EiBNJwvTp0N4ag_XNlf3eOnplLWWRQShRE2nwpZverwNg4AWe7KpvgaHjMNJaj3RzJ5jvYjGdWxd0EreuUE0L_RBDrkXEJVtXo47sys0ykg0i9bJ2GkPyx_TNi8TcrPsKPl4YDbpFG6GZbX0rEJhPwe-MeLAqOriUAPQGblT5RFFTf3Yt5sovMPGkeFy9yybB430UuNm_DcbbrP5_HZqnQ7gp7E5Fws1uBz03IXEUkGlTonBGuRV8s3_FsRpTr3fM7UFr3eK1OYuMNkCbja5tTVXLLTFmGx2F-5EbapDDSFNrVgfr5QQ29qxFc6h9KqN5cKReBQBMMA_LdL74iR2RLMLBltlI8e4PVztX-tXmsvMe6LMFHVAeCcGIHugx48Aaiun-XrAPLG80iRaMBeXNYTYXsnTM7nPk7APJ8FKrbpxKTVKM7fMtddVoYghVpGIPIBo1eGaPRpf1HK1O2XIzR61PoRBGJjRTQlMd4iGlQ6vKA9ss9-3DioRtSrnqws5eoTxN3keYBn-d_jZJws9r4YE3hYyfx-an9jafBQIIwYJ9c1Xi4wd_6KonPhIQig0NLpn4Y_phs4s0Oy8QLGPkTTKHUc3jClCKjoesBbp4WVqb3ffLiZ2rgyYaSKWK2e6Dt57ajcOZuUuGQhTo_CbYTiycGWXNfc_aa7hmA0zM3Aiy1QYN0R4vk0BRGmwJsRuU0uVMRdKD7TbjCNxeKWVnp87Xs4YUyrcCWaj9eW6Vr_e22tPdS32o1sE53D6np0TjdBJHujiUqkaxZQmYRzie92eLlHFqNkuIX5PNGGQUYit0pDJCwx7HQHcVYxcmzhe4CuoEYDGAqt7w7TjI1l8buOk81ZNVHq_IlYf_Q1z8vj9R8qjynQY_CY_ldgMhgq64-F7KvMPrGMWUQJTifjgHEDYeZ97ktz3oIeOUEAxQTfS6ciJmwhyIQ9hJvj9RAWJV1lc57F-i9SWYq5N-R4ecsaQVl8mMoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQ4TFRge", + "message": "-EGwYTSP-AAC4BATZGlkOnBlZXI6NHpRbWJMcXUzd2VadHNuTmVzQnplY0NabTVGQTZ1YUdrZ0NXWVI1V25kcjZHenpk4BATZGlkOnBlZXI6NHpRbVpzS21mZm53WVZiR0xiNlptWjhna2d5VHM4RDc2WVFSQnQ1WW5GTks0U25v5FGFAG_gn35RNoXWKshZoo7uJpjoK4rcKk2jfCWOYB5delcb_W29HoRlEL0dSVeU4hgMITPH3cryDD1lyXErM9gmApU_t3X2VMWTbHMN8i8YqhdzaUnPWWDqRNtFjChapB_euEuUWFXJYvlz7tyudeTDJxbbXFn5s_fzwvfKwPMsvzF0asVGhxKC77xe3cMht126-gHc0xx908WrHrMVUtfLXWQiQmIsnXcbHqPwbHnxDWamgaWPkbwjebDDnJGHwkAg1jBz9_Wo6RYymhGpBGqc2L9IsGfYSzy9PaSb22sg5BtTLO1vf3o_d3KoAks7uHG7RYDQgarMl4pWZUaICod3MK7yZlTR9LOsnXqkn2UXMyNg5Tr0bX6iEIw4bM77HXu2Ic84eF-2DfgXbK2I6DdH-KcH2b2EMmv95kC4WED-jPGoQA2Wd7kBNYlbYouQU4nDmmdVjOVvo2AeD0_aDu3cN2nQyINx34ryTcGjG6sfg6H6FYWT6yET7vpfPpZlx_cs_qq9QC9d5yjZOSzyEmgQE4a0QVGtxdk8a_Bd2O8gGutWbM5fFNLoPEwreECPHIuhuMBXMmIqRS1igha8yN_dvapSle1WrHVy9EADQww4KzR8DHvPVuqbCEKtm5_zA0jYiLtiiCGkfUJnBI5k07acUjSSmWz3idGItf-SmY4latHXAeWF6i18cJZkJjV2MA3s1ufE0xB2QgRMs_zwpDAB94ICwBUcMBuce40rVhamBx4_RPvr-FsX_IUMBOCRf-p_Av3RKqE2KQa83IgWUbgUnvXHsmNOtArVpTD5wtIDB-Pcwq_jvOgyKYupgddkTwo9jY50q4R3u2Nvm47NjurQKJ1jvmVsv-ouSfIYGeUrqWOkbwjfkgenLJHv7ZnXE2bPI-KkkM4n5f2OjCfHuirtQnstKEd4gCbhUSx5BSpjoNLT77emBWb_NjiKdCZ8dugvuu48R9uaAc3PtBQyf1xkyHpUoge7FLHRDC_Kc4mITunie4eC4SjaBpyVwL2PwW-pPr8J1RHOX0KNqxFq_7ZocLPdzAtgaYkLO7kaIBRKH4gGPRsoO4eyk0DrUzIaZBqp4VJRE7EcE48FjtneHHvjPc0eA4v35CWpdPtvEHgeAwsXgfF64Bn_PIMgyMt29Ja-s7Ob4j4TGOBXxxdMUhf67z9nnUARnLej12ARzaz9Wa00fQjfvJQVaxbjeZ9kFDM69vjW997615Oxute1YenKcZqACx9EoghOqj_xwJphXfBIQcy27pYcOPDm5Q1vjLryDv5kyyp0bIni5sIqUQnrJ9InUy2VBtSB0wE_drnoiwQu2_rMb_M0jgnuNZ-N3Y9haW4AMX7a-5uttqK-eyQO0OogmCBr8pLN0ZC7aQz2KbPl_TDxQQgrCn2ra_1VsYn8hl0x_D1FQUeB4y6bA3LnfUuVkYYYoUFQQGy5oCdT-AjqCSqfOoGRjRRBfsOpm67DykdVa1BXIEgfXNPCzfHzPHvAkYdH1aar1fOZINtK9jKJZjz-5RtiE2yvMWqj629LAtbbXg63OW_A6SJ7Y_4N-CRR-KRQ1AAQB4RkRy_co2t-SiuKfXPHlU5es2uIAfVB_WJ8artzk1efysbPS2uf5bdHL7krPJXl1ZV31V-rdxoXv1ESppt27vrwNAd2NnxWkjH9Dnif3SyV8ZY2fxe0X-_hDFVfdst75PK69kAbhCDPaMjczGLVKCFh34fGQVScKIlfsswAuzYPQaTNmt6Zg98lGlWG7oZJ1dXR89NBTYEHk2vJBWS_-qDu28hGUiGpgjK60GNxo0m9JAHvGC_SkURCtRlIydqr1o1sI_ZOIgU43EFYhYrafPrWtx6by6wRSdlRKjKSIDHkuobUsVYruanR6aPdbpjFf31Ez3sFBmn3c1VjqBOl4vBUOBapAVbbj3lnwd6eJC1psRYLgcgqPkLe2sq2i6FhlxDeBX9h9T7qI1hiWmTAwdt3W9CeR00IXIQNE_0OH_THREAv2RE-pBFtg447EwfVpvK1T-3oiPsqrgRq-zoOc5jWqfzY-CLl9lOLE5pO_bAbzzglRNs8oDbfoxSKbhl09GTFbLr5mQ3PGfReVlzL9s-wO4DTYX7zmuVPCEQY5NldKhXHXsPtNrrgedWnpsdIeHsMJ-M_z6gOmhmzctMcf1c8fPluVYmYa6-h5pEIuvmWpkWOVLVZoI7aADx5v1sDXNPokBSo6TY4g8SB2_gcxERbmSp8_BXumw-9RAtwNx0fWkqmJAzZJOLgX-cYOwQyVQvuZv_HhMFtUhhSFEzg6cHQJmbhaTLqVa7iiiJMXU-vPmpro0kf5eKw2nkbrEZ6lnH2-eniGRpycY1PsyRThIkosGwv-9SlMvieR1qMsHxr_p3SfAAvtRupWrFIUZfCECTYx5l9IuV7PEQPxvUiYjAE41NKJ2SX5d_AiX62TYfZDmuRRG5cg7cA6IhD8Uf0sm3_eLErf3dify4uEy7ftvqqQqUHdm-rVaHPp9UdK_7knXvSqXBnfch1ZORlo9e5_nG9KT0zF2Gp6AhcoDYjtXVLVjF_3mmc7SmY6gCNQuqhyrLZLzXOtMmNXM-g_Wg-Wy9KISyfHtOp86HA_mjzGNxOO470A5iQuI-nF_L4kLmhQv1PsVrusUDRNx7dyqBqhIBTetL9uU8a-2dXuBIn-5Qe01XxcnZcmDazq1BPQoeUSgYD30sBAaqEgOZ89nOB7u9nmyB5iirWH9-ejdnx9wkR2wIoB4y9ohwEG3-Gs776uNrTUI73vEHTYrcZNBod432Fnr-iibMsTMa8B_G-EZ4PXIqxzyi7j-SkGK4uVRfsPxhLsC8EvcbtHzyhRczCEhVUFHlikoFUdEoNMze09wq_d8st6OsEobm0WZr6nPlqiJ-gPJWsY0WA7Q_w1Ql5W1M-x0ThkeGxw_RMo_IScHchZ36OodPGm_n0Zjbdh-S_pnlKr8l8YUb6AtIEkOtyhl0ZBHdHTIeJZbSCNNtSaFjKmHwvDdK79CaR4vgN7y2X7aZkVlMwrCmMTydhK_8mvryyhkr6eSQb2A4faz-yzhac09e0abg6_-dXZKr7QWxD3f_3-V42y1AcmemYwKti_RFgE3koDZGY0ghZu851hvRgNzJx0iI6Yz4sdxlzD2GQ_xGKdoZjZLPXeO_Z4PKd6Gb77i-ekutyKDzy3l9g2gaKB8L5T2O9NPWPju3IqFaVzAiwH0qSzxtO6wTk99jVfX6qOBNkgcoJYp1DgQXheDGj5AS7AYWFIrI29uA7PYCEAL_DWT1-nEQFJGZ3vUlsMWRevEg4BnB_64Xw1SvKDpC9dlrot2AWe9Y6K1bcpU2ZObp2kUD7S1hgRGjpjz31Lon4iSdCdhEhXmFU9FQ9zf3K7X_oV8NFYmaUgUk8rFP2jBFG3OmCuMY2lgWN39kh5Vp6KSvvZ4GAcgds5FzUIO3sVfmEWECxnzFPvnJtWaloj2rarXLF50F6FWIJeaJsPks-4D9SB5RiLRE9OT7P-jg9F1asn7D3oE0VfOa1mW1erVL6eHbVV4l_IQCZlRMXzg7V8naaSXXE4mcRC7IA3aq7nHGmTqr2RdzJNpHXebDqL37k7myswdHyX1bHUb--Ku45s9WZwECCXfSfFzKmnGRl_2tOSix5ypPLtJZj4e11usS391NVr7lgUgQBfRAUqrBkx0yhkDc4_ChvfXGdyacRkzmu7kkDZx7PnHGQsvrtSGimxYx9Fa13dRZcW4tH4sFBhc0oUM10yGsjEXhfK0o4zAz94N_Glw5kH-kFtGPkFLTwUEECISWD7xpHVIiNSfM4YtJsNkWXbBtj0UYM57MuGDzbPqDkCnrhHBl2AhHJ5eKz4byR8ouf6i5xQQIG8NU-4cGyiGErUze1QUYQx-10xi1Q8p9Ibz3ejHpSIXmJxUyUMToqTgOA-eQqn073VyLZrc9_AYmSdT9BT1UE56jl7tITcEq0ix_Th0A5zdSoVw5lp_iXrv5V1cy-2Z_rvbjoc6Bw6NikjsKQrX5we9n8hQ-R8ugYW1eIUP-B91inNBWLp8UtY98LE5c8-CulvVJavFjQZXdpC1_Gy8s-GB1QdYfZdoLlbjrojhN-p_HG2L67eakv4hNrgNHJjMs2VvDKuGNZTOF_AFg8QBUWnD5onGwDKt1LhkzCpSgH-qjM79a5AhZPlNrk99jum_TcdKxsBZgjoU3kbs5Nvgb-MHx0tyr35A1r6O18jyBHBH61-KsVu1b3CH6sUVlZ3Vpbl5rGHi02Kv3gf2Z76Oe7rjDmgEtCwp9otovvpBrJxadkdoIOexK45Nw9ZjlArqDxfBAuIeY0VQySHyUQvRJiLC3_1SF8a4d8qnHNlmBEdYnH2bXtnvlBiaF0ZknjCy6IRynUWGYN3kEnE9MjwLWsx1DHdstewkMhq_U5qtxvh6RUmrANXB97GK17vj9E6uCfndQfq_AzSB3WEmWxXHwLDwII7cyN90FwthhxbRM-HfL0Mzj61ljk1fZXtbB9-uRw1S4KqqxJqMxe5giSzZ8A4yhL91ILt5Z6_gvxwCbZEP_BAJut2tCdSu6X6rcCiO0eIyM8MsvXGlBOsY0M_7jvbHJVA86NF8dV6k0uxsN-r1B-0Mg1AOEGt_8gC2YzhN0a6-4PDycJFHsaWFbgoSJZbM_Uy4OEg6QTG4WYaLcjbXES-UzTF1BHsjSO8BEKDHexDlJN_wY2EXJaAoUiPu1JPVjWemHBSNy-HvZGIpdXZ7XSOnBYtCbCVf3khiNNoY6NlhoZtDx5Y92xJlDcVupuq8CBsVZY8ruHd5XVlgFD8QfDKWjzyVqjKQ2yitWOtX6FY443axjZOykFWS_fBwehTV7NVX_yvYiVLFjeJ0XG_9DZqofn8cVg71FBC4AuY1_CdjPnHPlUPPUeEY9NdSyUMDqGDiLTHSWNvhFUbi4La5loNjugGEyvvHmlx6_YFKSJ747WH64AdLSnvNsQ7jgPQtD5rlxUDfdGS_0rE10jfvZGJo_sABL7DIAzi79ecyVCyG0PG3fCfNWHa7iTT6rk8KYRBC4mFhrLmdM3mIe57xu5rMdg1axkXsPOn8heZ-QZyxlSQXXTFEf70S9bgfFT86xs83Cp1k2KaEzlCYnoPxOJOUNdthWv5Skp-OszV5cwUMq5u4Wlei5V1SRzN1ydS27r60I2_JdWg5ymLRlvj5wL1eeaeB7LZF4ROd6uxDmbErX1zPPuSaHMopqEBJOWc-wjFfKF2Hdz4riu6_tYvmbYdrbQVh8ciGOlY4oQX_7EwrCD1fBzDXVtAk59DeyVL6uiFwWRuXTlmYb0yHk4YAnv3pN4BZGX0d6hacYQIbVZFyfRHKE3BmGWamgiLH1-q1OIcpAVfALQcKEjrR666EstrZN_wk2Ydwruu_-Lgj9TPE2eRc-AVYVb-2p29KE1rBkpIkLTHtUqjvIt3YeMv-N2gfVWsPVhr7VtR7vUhzkIASUDBQ3udRiWEQRI2TsFQjgBoNyDCmtBSEJY8eEHd9lA1Jyh2ZLXMVpLNxskklrAz7Xse51jjcbtlHWlHw26pmPHpXfpYxxEQE2JXTbBAvTsa5ei3A7ObX9Cg22ghgv6eMq2zX3-eHurDyZhsSuqd6WSdETenn8HmuEVWybbize-m9AfKQaH5YZN7jUL-nUgbBiOz217AbduaOY9dcnn6-sQPGoik6RxWfHN6r94ox62zRXHxLPwn8A9ycZVAX31Yvi42j435NB5gtwVK3PvykKS0iht2tWkBacQP9R5sFPGgy-mDQ2y8QeRa6rA3Ezyr36wk6OJec9oVd7AqBfXvnI9IiQ3HyeDswRGzukXMncJ0zao4l6hvXP2uE_n6Yhbc1wr_hM2OdQodTirJPaqeS8igmjIeMGhw2RqO1lxI7YII0RswgIDC2SYpsvq-JvP4voJDkFJcXd6kbjd_CcqQFiLEyCS2wAAAAAAAAAAAAAAAAAAAAAABQ4SHSIm", "payload": "-ZAJXSCS4BAA4BAA-AAF5BAEAGhlbGxvIHdvcmxk" } } diff --git a/packages/tsp-js/tests/interop.spec-vectors.mjs b/packages/tsp-js/tests/interop.spec-vectors.mjs index b59fc14..5d20b78 100644 --- a/packages/tsp-js/tests/interop.spec-vectors.mjs +++ b/packages/tsp-js/tests/interop.spec-vectors.mjs @@ -6,9 +6,11 @@ import { unpack, peekRevision } from "../dist/index.js"; // ── The specification's own Appendix A test vectors ── // -// Fixture lifted verbatim from affinidi-tsp's `tests/vectors/rev3.json`, which -// was extracted from spec commit 66a1580 and checked value by value against -// `tsp_sdk` 0.10.0's own copy — the file the appendix was rendered from. +// Fixture extracted from Appendix A of the merged specification +// (trustoverip/tswg-tsp-specification f5b8668), which packs `YTSP-AAC`. It +// replaced the pre-merge `YTSP-ABA` vectors from spec commit 66a1580: the +// version is inside the signed envelope, the AAD and every SAID, so every +// message changed with it. // // These check something neither a round trip nor a two-implementation interop // run can. A round trip passes whenever the encoder and decoder share a @@ -16,11 +18,11 @@ import { unpack, peekRevision } from "../dist/index.js"; // unpacks with the other passes whenever *both* share one. These bytes are // fixed, external, and were produced by neither of us. // -// Three of the ten are runnable here. `direct-sealed-box` and -// `control-rfi-sealed-box` need the libsodium sealed box (§8.3), which we -// deliberately do not implement; `direct-signed-only` is an unencrypted `-E` -// frame we never receive; the three control vectors need the relationship state -// machine; `direct-hpke-base-pq` needs ML-KEM and ML-DSA. Each is skipped by +// Three of the ten are exercised here and the three HPKE-Base control vectors in +// `control.spec-vectors.mjs`. `direct-sealed-box` and `control-rfi-sealed-box` +// need the libsodium sealed box (§8.3), which we deliberately do not implement; +// `direct-signed-only` is an unencrypted `-E` frame we never receive; +// `direct-hpke-base-pq` needs ML-KEM and ML-DSA. Each is skipped by // name below rather than silently absent, so the list says what is missing // instead of looking complete. const VECTORS = JSON.parse( @@ -41,16 +43,20 @@ const openVector = (name) => { }); }; -test("the published vectors declare a revision we read as Rev 3", () => { - // They carry `YTSP-ABA` — MINOR 64 under the MAJOR.MINOR reading this package - // and affinidi-tsp both use, where our own packing emits `AAC` (MINOR 2). - // Both must read as Rev 3, which is the whole reason `peekRevision` matches - // Rev 2 exactly and treats everything else at MAJOR 0 as current. - const peeked = peekRevision(b64u(VECTORS.vectors["direct-hpke-base"].message)); - assert.equal(peeked.revision, "rev3"); - assert.equal(peeked.major, 0); - assert.equal(peeked.minor, 64); - assert.equal(peeked.recognised, true); +test("the published vectors declare Rev 3 as we pack it: YTSP-AAC", () => { + // The merged Appendix A carries `YTSP-AAC` — MINOR 2 under the MAJOR.MINOR + // reading this package and affinidi-tsp both use, the same marker our own + // packing emits. Pre-merge drafts carried `ABA` (MINOR 64), which still reads + // as Rev 3 (see `revision.dispatch.mjs`); `peekRevision` matches Rev 2 exactly + // and treats everything else at MAJOR 0 as current. + for (const [name, v] of Object.entries(VECTORS.vectors)) { + const peeked = peekRevision(b64u(v.message)); + assert.equal(peeked.revision, "rev3", name); + assert.equal(peeked.major, 0, name); + assert.equal(peeked.minor, 2, name); + assert.equal(peeked.recognised, true, name); + assert.equal(v.message.slice(4, 12), "YTSP-AAC", `${name} carries YTSP-AAC in qb64`); + } }); test("direct-hpke-base — opens, verifies, and carries the published payload", async () => { @@ -118,15 +124,21 @@ test("vectors this implementation does not cover are named, not omitted", () => "direct-sealed-box": "libsodium sealed box (§8.3) — deliberately not implemented", "control-rfi-sealed-box": "libsodium sealed box (§8.3)", "direct-signed-only": "unencrypted -E frame; we neither send nor expect one", - "control-rfi-direct": "relationship state machine (§7.2)", - "control-rfa-direct": "relationship state machine (§7.2)", - "control-rfd": "relationship state machine (§7.3)", "direct-hpke-base-pq": "ML-KEM-768/X25519 + ML-DSA-65 (§8.1/§8.2.1)", }; for (const name of Object.keys(uncovered)) { assert.ok(VECTORS.vectors[name], `vector ${name} is in the fixture`); } - const covered = ["direct-hpke-base", "nested-direct", "routed"]; + // The HPKE-Base control vectors are opened, and their digests re-derived, in + // `control.spec-vectors.mjs`. + const covered = [ + "direct-hpke-base", + "nested-direct", + "routed", + "control-rfi-direct", + "control-rfa-direct", + "control-rfd", + ]; assert.deepEqual( new Set([...covered, ...Object.keys(uncovered)]), new Set(Object.keys(VECTORS.vectors)), diff --git a/packages/tsp-js/tests/message.envelope.mjs b/packages/tsp-js/tests/message.envelope.mjs index cbc08a3..71cee86 100644 --- a/packages/tsp-js/tests/message.envelope.mjs +++ b/packages/tsp-js/tests/message.envelope.mjs @@ -91,7 +91,7 @@ test("the public decodeEnvelope dispatches, and reports which revision it read", // Rev 3, from the published vectors. const rev3 = decodeEnvelope(b64u(VECTORS.vectors["direct-hpke-base"].message)); assert.equal(rev3.revision, "rev3"); - assert.equal(rev3.minor, 64); // the vectors carry `ABA` + assert.equal(rev3.minor, 2); // the merged vectors carry `AAC` assert.equal(rev3.envelope.sender, VECTORS.identifiers.alice.id); assert.equal(rev3.envelope.receiver, VECTORS.identifiers.bob.id); diff --git a/packages/tsp-js/tests/revision.dispatch.mjs b/packages/tsp-js/tests/revision.dispatch.mjs index ce45203..3186484 100644 --- a/packages/tsp-js/tests/revision.dispatch.mjs +++ b/packages/tsp-js/tests/revision.dispatch.mjs @@ -73,7 +73,7 @@ test("an unrecognised MINOR at MAJOR 0 still reads as Rev 3", () => { // MINOR a field no implementation may reject on, and the reference discards // it entirely. const frame = Uint8Array.from(b64u(VECTORS.vectors["direct-hpke-base"].message)); - frame[8] = 0x0d; // MINOR 64 → 13, a value nothing has ever shipped + frame[8] = 0x0d; // MINOR 2 → 13, a value nothing has ever shipped const peeked = peekRevision(frame); assert.equal(peeked.revision, "rev3"); assert.equal(peeked.recognised, false, "unrecognised, but not refused"); @@ -106,6 +106,27 @@ test("a Rev 2 message without the sender's X25519 key is refused by name", async ); }); +test("a pre-merge `YTSP-ABA` message still reads as Rev 3, and opens", async () => { + // Appendix A's `direct-hpke-base` as it stood before the specification merged + // (spec commit 66a1580), when the vectors carried `ABA` — MINOR 64 under the + // MAJOR.MINOR reading. The merged vectors moved to `AAC`, so this is pinned + // here: messages packed against the draft exist, and MINOR must never gate + // processing. Same published keys as the current fixture. + const aba = b64u( + "-EBFYTSP-ABA4BATZGlkOnBlZXI6NHpRbVVMNjFOYzFGN2lvaUt4SE5xd25KWFg0c3JoRnNLS1BvNlRyQ21oTTNkZnBx4BATZGlkOnBlZXI6NHpRbVptQ0FzRzdqMWV3VGpYanRkZHd1amlrMzNDRTJjTWJZU1BhZ3BNaVludDFB4FAa1T4oA1pSbehBiIwnoXFGA24kgHowT34VdE95wF9qjStBsok4fIkbu8IKODF2nsZMUAmS5BqxDbbYrvl_TNGpz2omwJgYX4bSYoTeKse4-CAX-KAWBADHuTmj_7jyUCkkalySPOFiy5pTbNtjEODiwwJZlI5DqMk5Wutx4LIOWkAAa3uee2b_0Kh5SXaFq65MedyO5VYJ", + ); + const peeked = peekRevision(aba); + assert.equal(peeked.revision, "rev3"); + assert.equal(peeked.minor, 64); + assert.equal(peeked.recognised, true); + const out = await unpack(aba, { + receiverDecryptionKey: b64u(VECTORS.identifiers.bob.skE), + senderSigningKey: b64u(VECTORS.identifiers.alice.pkS), + }); + assert.equal(out.revision, "rev3"); + assert.equal(dec.decode(out.payload), "hello world"); +}); + test("a Rev 3 message needs no sender encryption key at all", async () => { // The clearest statement that HPKE-Base moved sender authenticity out of the // KEM: the key Rev 2 could not open a message without is simply not passed. From 463672ea7ba4ca0089c43259c26410238d9ddd51 Mon Sep 17 00:00:00 2001 From: Glenn Gore Date: Wed, 16 Sep 2026 18:16:11 +0200 Subject: [PATCH 2/2] feat(tsp-js): re-pack the Appendix A vectors byte for byte Add a test-only ./unsafe-testing subpath whose __unsafeDeterministicPack* functions derive the HPKE-Base ephemeral from a caller-fixed ikmE (RFC 9180 DeriveKeyPair) and can write the NULL VID in the ESSR sender field. The main entry point's packers are unchanged and never forward either knob; a fixed ephemeral key breaks confidentiality, and the subpath exists only to reproduce published vectors. All six HPKE-Base vectors (direct-hpke-base, control-rfi-direct, control-rfa-direct, control-rfd, nested-direct, routed) now re-pack byte for byte, with every input derived from the vector's printed payload. The sealed-box, signed-only and post-quantum vectors are named with the reason they cannot be. Signed-off-by: Glenn Gore --- packages/tsp-js/CHANGELOG.md | 10 + packages/tsp-js/README.md | 18 +- packages/tsp-js/package.json | 4 + packages/tsp-js/src/crypto/hpke-noble.ts | 21 ++ packages/tsp-js/src/rev3/direct.ts | 57 +++- packages/tsp-js/src/unsafe-testing.ts | 122 +++++++++ .../tests/interop.spec-vectors-repack.mjs | 246 ++++++++++++++++++ 7 files changed, 467 insertions(+), 11 deletions(-) create mode 100644 packages/tsp-js/src/unsafe-testing.ts create mode 100644 packages/tsp-js/tests/interop.spec-vectors-repack.mjs diff --git a/packages/tsp-js/CHANGELOG.md b/packages/tsp-js/CHANGELOG.md index 5a2830d..e99e686 100644 --- a/packages/tsp-js/CHANGELOG.md +++ b/packages/tsp-js/CHANGELOG.md @@ -14,6 +14,16 @@ For history before this file, see `git log` on `packages/tsp-js`. accept answers the invite we have outstanding (§7.2.2). `transition` sees only the state, so until now every client had to compare the digests itself or adopt an accept for an invite it never sent. +- `@openvtc/vti-tsp-js/unsafe-testing`, a **test-only** subpath for + byte-reproducible packing: `__unsafeDeterministicPack`, `…PackInvite`, + `…PackAccept`, `…PackCancel`, `…PackNested` and `…PackRouted` take an + `__unsafeIkmE` (RFC 9180 DeriveKeyPair input) for the HPKE-Base ephemeral and + can write the NULL VID in the ESSR sender field. A fixed ephemeral key breaks + confidentiality; the subpath exists so the Appendix A vectors can be + reproduced and is not part of the documented API. The main entry point's + packers are unchanged and never take either knob. With it, all six HPKE-Base + vectors (`direct-hpke-base`, `control-rfi-direct`, `control-rfa-direct`, + `control-rfd`, `nested-direct`, `routed`) re-pack byte for byte. ### Changed diff --git a/packages/tsp-js/README.md b/packages/tsp-js/README.md index 75d386e..f1e1849 100644 --- a/packages/tsp-js/README.md +++ b/packages/tsp-js/README.md @@ -108,15 +108,23 @@ Byte-compatibility is proven in three ways, because a round trip proves none of it — encoder and decoder agree with each other whatever they both get wrong, which is exactly the failure mode Rev 3's one-character changes produce: -- **The specification's own Appendix A vectors** run as a test suite - (`tests/interop.spec-vectors.mjs`), fixed and external and produced by the - ToIP reference implementation. Every published vector is either exercised or - named as uncovered, so the list cannot quietly shrink. +- **The specification's own Appendix A vectors** (`YTSP-AAC`, as merged at + [tswg-tsp-specification@f5b8668](https://github.com/trustoverip/tswg-tsp-specification/commit/f5b8668952aabe8e541b535fcbdf589484ffc4f4)) + run as a test suite, fixed and external and produced by the ToIP reference + implementation. Every HPKE-Base vector both opens + (`tests/interop.spec-vectors.mjs`, `tests/control.spec-vectors.mjs`) and + **re-packs byte for byte** from its published `ikmE` + (`tests/interop.spec-vectors-repack.mjs`). Every published vector is either + exercised or named as uncovered, so the list cannot quietly shrink. - **Both directions against `affinidi-tsp`** — its Rev 2 vector unpacks here (`tests/interop.rust-vector.mjs`), and a message packed here unpacks there, thread digest included. - **Pinned bytes** for the deterministic parts of what we emit, since the sealed - message itself is not reproducible (HPKE draws a fresh ephemeral key). + message itself is not reproducible (HPKE draws a fresh ephemeral key). The + vector re-pack fixes that key through a test-only subpath, + `@openvtc/vti-tsp-js/unsafe-testing`, which is deliberately not part of the + API above: a fixed ephemeral key destroys confidentiality, and nothing but a + test reproducing a published vector has a reason to import it. The HPKE implementation is pinned three ways on every CI run: the official CFRG RFC 9180 `mode_auth` vector asserted in-tree (`tests/crypto.cfrg-vector.mjs` — diff --git a/packages/tsp-js/package.json b/packages/tsp-js/package.json index 015babf..ebac166 100644 --- a/packages/tsp-js/package.json +++ b/packages/tsp-js/package.json @@ -13,6 +13,10 @@ "./hpke": { "types": "./dist/crypto/hpke.d.ts", "import": "./dist/crypto/hpke.js" + }, + "./unsafe-testing": { + "types": "./dist/unsafe-testing.d.ts", + "import": "./dist/unsafe-testing.js" } }, "files": [ diff --git a/packages/tsp-js/src/crypto/hpke-noble.ts b/packages/tsp-js/src/crypto/hpke-noble.ts index 8bd5ce1..d5a7407 100644 --- a/packages/tsp-js/src/crypto/hpke-noble.ts +++ b/packages/tsp-js/src/crypto/hpke-noble.ts @@ -115,6 +115,27 @@ function dh(sk: Uint8Array, pk: Uint8Array): Uint8Array { // public `hpke.ts` wrappers deliberately do not forward it. type UnsafeFixedEphemeral = { __unsafeFixedEphemeralSk?: Uint8Array }; +/** + * §7.1.3 DeriveKeyPair for DHKEM(X25519, HKDF-SHA256): `ikm` → `(skE, pkE)`. + * + * Exported for test-vector verification only. RFC 9180 and TSP Appendix A + * publish the ephemeral as `ikmE`, the input to this function, so a vector's + * `enc` can only be reproduced by running it. X25519 needs no rejection + * sampling: every 32-byte string is a valid scalar (clamped at use). + * + * Nothing on a production path calls this. A random ephemeral is drawn from + * `x25519.utils.randomSecretKey()` directly, and deriving one from caller + * input is exactly the reuse the `__unsafe…` hooks warn about. + */ +export function deriveKeyPair(ikm: Uint8Array): { sk: Uint8Array; pk: Uint8Array } { + if (ikm.length < NX25519) { + throw new Error(`tsp: DeriveKeyPair input must be at least ${NX25519} bytes`); + } + const dkpPrk = labeledExtract(KEM_SUITE_ID, EMPTY, "dkp_prk", ikm); + const sk = labeledExpand(KEM_SUITE_ID, dkpPrk, "sk", EMPTY, NX25519); + return { sk, pk: x25519.getPublicKey(sk) }; +} + /** §4.1 Encap (base mode). Exported for test-vector verification. */ export function encap(recipientPk: Uint8Array, unsafe?: UnsafeFixedEphemeral): { sharedSecret: Uint8Array; diff --git a/packages/tsp-js/src/rev3/direct.ts b/packages/tsp-js/src/rev3/direct.ts index 7aa1924..2d3229a 100644 --- a/packages/tsp-js/src/rev3/direct.ts +++ b/packages/tsp-js/src/rev3/direct.ts @@ -25,6 +25,7 @@ import * as wire from "../cesr/wire.js"; import * as hpke from "../crypto/hpke.js"; +import * as noble from "../crypto/hpke-noble.js"; import * as sign from "../crypto/sign.js"; import { decodeEnvelope, encodeFields, finalizeFrame } from "./envelope.js"; import { @@ -87,6 +88,35 @@ export interface UnpackedMessage { threadDigest: Uint8Array; } +/** + * Test-only knobs that make a pack byte-reproducible. **Never use outside + * tests.** + * + * Internal to the package: reached only through the `./unsafe-testing` subpath, + * and the public wrappers in `message/` deliberately do not forward it — the + * same arrangement as the `__unsafeFixedEphemeralSk` hook in `hpke-noble.ts`. + * + * Fixing the HPKE ephemeral key makes every message packed with it to the same + * recipient share one (key, base_nonce) pair. Under ChaCha20Poly1305 that leaks + * the XOR of the plaintexts and the Poly1305 one-time key: confidentiality and + * integrity both go. It exists so that the specification's Appendix A vectors, + * which publish their ephemeral as `ikmE`, can be reproduced byte for byte. + */ +export interface UnsafeDeterministicPack { + /** RFC 9180 §7.1.3 `DeriveKeyPair` input for the HPKE-Base ephemeral — the + * `ikmE` Appendix A prints. At least 32 bytes. */ + __unsafeIkmE: Uint8Array; + /** Write the NULL VID `4BAA` in the ESSR sender field instead of the sender's + * VID. §9.2 permits it under HPKE-Base, and the published vectors use it; + * this package's own stance is to always write the VID (see `payload.ts`), + * so it is offered only here, for reproducing those vectors. */ + nullPayloadSender?: boolean; +} + +/** The ESSR sender field's content for this pack. */ +const payloadSender = (senderVid: string, unsafe?: UnsafeDeterministicPack): string => + unsafe?.nullPayloadSender === true ? "" : senderVid; + /** Encode the signature attachment: `-C23 -K22 B0 sig(64)`. */ function encodeSignatureFrame(signature: Uint8Array, out: number[]): void { wire.encodeCount(wire.TSP_ATTACH_GRP, ATTACH_GROUP_QUADLETS, out); @@ -129,10 +159,16 @@ async function sealFrame( fields: Uint8Array, frame: Uint8Array, keys: PackKeys, + unsafe?: UnsafeDeterministicPack, ): Promise { // `aad` binds the ciphertext to the version and both VIDs; `info` is the // fixed protocol code. - const sealed = await hpke.sealBase(frame, fields, keys.receiverEncryptionKey, wire.TSP_INFO); + const sealed = + unsafe === undefined + ? await hpke.sealBase(frame, fields, keys.receiverEncryptionKey, wire.TSP_INFO) + : await noble.sealBase(frame, fields, keys.receiverEncryptionKey, wire.TSP_INFO, { + __unsafeFixedEphemeralSk: noble.deriveKeyPair(unsafe.__unsafeIkmE).sk, + }); // Ciphertext field: `enc ‖ ct`, with the AEAD tag inside `ct`. const ciphertext = new Uint8Array(sealed.enc.length + sealed.ciphertext.length); @@ -158,10 +194,11 @@ export async function packWithHops( senderVid: string, receiverVid: string, keys: PackKeys, + unsafe?: UnsafeDeterministicPack, ): Promise { const fields = encodeFields(senderVid, receiverVid); - const { frame, threadDigest } = encodePayloadFrame(body, kind, hops, senderVid); - return { bytes: await sealFrame(fields, frame, keys), threadDigest }; + const { frame, threadDigest } = encodePayloadFrame(body, kind, hops, payloadSender(senderVid, unsafe)); + return { bytes: await sealFrame(fields, frame, keys, unsafe), threadDigest }; } /** @@ -178,10 +215,11 @@ export async function packControl( senderVid: string, receiverVid: string, keys: PackKeys, + unsafe?: UnsafeDeterministicPack, ): Promise { const fields = encodeFields(senderVid, receiverVid); - const { frame, threadDigest } = encodeControlFrame(control, senderVid, fields); - return { bytes: await sealFrame(fields, frame, keys), threadDigest }; + const { frame, threadDigest } = encodeControlFrame(control, payloadSender(senderVid, unsafe), fields); + return { bytes: await sealFrame(fields, frame, keys, unsafe), threadDigest }; } /** @@ -196,6 +234,7 @@ export function packInvite( receiverVid: string, keys: PackKeys, opts: { route?: string[]; nonce?: Uint8Array } = {}, + unsafe?: UnsafeDeterministicPack, ): Promise { return packControl( { @@ -206,6 +245,7 @@ export function packInvite( senderVid, receiverVid, keys, + unsafe, ); } @@ -221,12 +261,14 @@ export function packAccept( senderVid: string, receiverVid: string, keys: PackKeys, + unsafe?: UnsafeDeterministicPack, ): Promise { return packControl( { controlType: "accept", inReplyTo: inviteDigest, route: [] }, senderVid, receiverVid, keys, + unsafe, ); } @@ -239,12 +281,14 @@ export function packCancel( senderVid: string, receiverVid: string, keys: PackKeys, + unsafe?: UnsafeDeterministicPack, ): Promise { return packControl( { controlType: "cancel", inReplyTo: relationshipDigest, route: [] }, senderVid, receiverVid, keys, + unsafe, ); } @@ -254,8 +298,9 @@ export function pack( senderVid: string, receiverVid: string, keys: PackKeys, + unsafe?: UnsafeDeterministicPack, ): Promise { - return packWithHops(body, "direct", [], senderVid, receiverVid, keys); + return packWithHops(body, "direct", [], senderVid, receiverVid, keys, unsafe); } /** Unpack a Rev 3 message. */ diff --git a/packages/tsp-js/src/unsafe-testing.ts b/packages/tsp-js/src/unsafe-testing.ts new file mode 100644 index 0000000..3bed461 --- /dev/null +++ b/packages/tsp-js/src/unsafe-testing.ts @@ -0,0 +1,122 @@ +// @openvtc/vti-tsp-js/unsafe-testing — deterministic packing, for reproducing +// published test vectors. **NOT FOR PRODUCTION USE.** +// +// Every function here packs exactly what its namesake in the main entry point +// packs, except that the HPKE-Base ephemeral key is derived from a caller-fixed +// `ikmE` (RFC 9180 §7.1.3 DeriveKeyPair) instead of drawn at random, and the +// ESSR sender field may be written as the NULL VID. Ed25519 signatures are +// already deterministic, so with those two fixed — and the invite nonce, which +// `packInvite` already takes — the whole message is reproducible byte for byte. +// +// ── Why this is unsafe ── +// +// A fixed ephemeral key repeats the HPKE (key, base_nonce) pair for every +// message sealed with it to the same recipient. Under ChaCha20Poly1305 that +// leaks the XOR of the plaintexts and the Poly1305 one-time key, so both +// confidentiality and integrity are gone. Anyone who learns `ikmE` can also +// derive the ephemeral secret and open the message outright. The only safe +// `ikmE` is one already published next to a test vector. +// +// It is a separate subpath, absent from the main entry point and from the +// documented API, so that it cannot be reached by accident: importing it is a +// statement that the caller is a test. Every export carries the `__unsafe` +// prefix the package already uses for its fixed-ephemeral HPKE hook. + +import { MAX_HOPS } from "./cesr/wire.js"; +import { + pack, + packAccept, + packCancel, + packInvite, + packWithHops, + type PackKeys, + type PackedMessage, + type UnsafeDeterministicPack, +} from "./rev3/direct.js"; + +export type { PackKeys, PackedMessage, UnsafeDeterministicPack }; + +/** `pack` (direct, `XSCS`) with a fixed ephemeral. Test vectors only. */ +export async function __unsafeDeterministicPack( + body: Uint8Array, + senderVid: string, + receiverVid: string, + keys: PackKeys, + unsafe: UnsafeDeterministicPack, +): Promise { + return pack(body, senderVid, receiverVid, keys, requireIkm(unsafe)); +} + +/** `packInvite` (`XRFI`) with a fixed ephemeral and a caller nonce. Test vectors + * only. The nonce is required here: a random one would defeat the point. */ +export async function __unsafeDeterministicPackInvite( + senderVid: string, + receiverVid: string, + keys: PackKeys, + opts: { route?: string[]; nonce: Uint8Array }, + unsafe: UnsafeDeterministicPack, +): Promise { + return packInvite(senderVid, receiverVid, keys, opts, requireIkm(unsafe)); +} + +/** `packAccept` (`XRFA`) with a fixed ephemeral. Test vectors only. */ +export async function __unsafeDeterministicPackAccept( + inviteDigest: Uint8Array, + senderVid: string, + receiverVid: string, + keys: PackKeys, + unsafe: UnsafeDeterministicPack, +): Promise { + return packAccept(inviteDigest, senderVid, receiverVid, keys, requireIkm(unsafe)); +} + +/** `packCancel` (`XRFD`) with a fixed ephemeral. Test vectors only. */ +export async function __unsafeDeterministicPackCancel( + relationshipDigest: Uint8Array, + senderVid: string, + receiverVid: string, + keys: PackKeys, + unsafe: UnsafeDeterministicPack, +): Promise { + return packCancel(relationshipDigest, senderVid, receiverVid, keys, requireIkm(unsafe)); +} + +/** `packNested` (`XHOP`, empty hop list) with a fixed ephemeral. Test vectors + * only. */ +export async function __unsafeDeterministicPackNested( + innerBytes: Uint8Array, + senderVid: string, + intermediaryVid: string, + keys: PackKeys, + unsafe: UnsafeDeterministicPack, +): Promise { + return packWithHops(innerBytes, "nested", [], senderVid, intermediaryVid, keys, requireIkm(unsafe)); +} + +/** `packRouted` (`XHOP`) with a fixed ephemeral. Test vectors only. Same route + * bounds as `packRouted`. */ +export async function __unsafeDeterministicPackRouted( + inner: Uint8Array, + remainingRoute: string[], + senderVid: string, + firstHopVid: string, + keys: PackKeys, + unsafe: UnsafeDeterministicPack, +): Promise { + if (remainingRoute.length === 0) { + throw new Error("tsp: a routed message requires at least one onward hop"); + } + if (remainingRoute.length > MAX_HOPS) { + throw new Error(`tsp: route has ${remainingRoute.length} hops, exceeds max ${MAX_HOPS}`); + } + return packWithHops(inner, "routed", remainingRoute, senderVid, firstHopVid, keys, requireIkm(unsafe)); +} + +/** An absent `ikmE` would silently fall back to a random ephemeral and produce + * bytes that match nothing — refuse it by name instead. */ +function requireIkm(unsafe: UnsafeDeterministicPack): UnsafeDeterministicPack { + if (!(unsafe?.__unsafeIkmE instanceof Uint8Array)) { + throw new Error("tsp: unsafe-testing packers need __unsafeIkmE (a Uint8Array)"); + } + return unsafe; +} diff --git a/packages/tsp-js/tests/interop.spec-vectors-repack.mjs b/packages/tsp-js/tests/interop.spec-vectors-repack.mjs new file mode 100644 index 0000000..4981b78 --- /dev/null +++ b/packages/tsp-js/tests/interop.spec-vectors-repack.mjs @@ -0,0 +1,246 @@ +import { test } from "node:test"; +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; + +import { decodeEnvelope, unpack } from "../dist/index.js"; +import * as wire from "../dist/cesr/wire.js"; +import { deriveKeyPair } from "../dist/crypto/hpke-noble.js"; +import { decodeDigest, decodeNonce, decodeVidList } from "../dist/rev3/fields.js"; +import { + __unsafeDeterministicPack, + __unsafeDeterministicPackAccept, + __unsafeDeterministicPackCancel, + __unsafeDeterministicPackInvite, + __unsafeDeterministicPackNested, + __unsafeDeterministicPackRouted, +} from "../dist/unsafe-testing.js"; + +// ── Re-packing the specification's Appendix A vectors byte for byte ── +// +// `interop.spec-vectors.mjs` proves we can *read* the published messages. This +// proves we *write* them: given the vector's keys, its `ikmE` and the fields its +// printed payload spells out, the packer emits exactly the published bytes. It +// is the stronger claim — a reader tolerates whatever it tolerates, whereas an +// exact writer has had to agree with the reference on every code, count, field +// order, AAD boundary, signature input and HPKE-Base derivation. +// +// Ed25519 is deterministic, so the only randomness is the HPKE ephemeral and the +// invite nonce. Both come from the vector here, through the test-only +// `./unsafe-testing` subpath, whose fixed ephemeral must never be used outside a +// test (see that module). +// +// Every input is derived from the vector, never hard-coded: the NULL-vs-present +// ESSR sender field and the padding from the printed `payload`, the nonce and +// digests and the inner message of a nesting from that same payload. +// +// Of the ten vectors, six are HPKE-Base and all six re-pack. The other four +// cannot, for reasons that are about what this package packs, not about the +// vectors — named below rather than silently skipped. + +const VECTORS = JSON.parse( + readFileSync(new URL("./fixtures/spec-rev3-vectors.json", import.meta.url), "utf8"), +); + +const b64u = (s) => new Uint8Array(Buffer.from(s, "base64url")); +const qb64 = (u8) => Buffer.from(u8).toString("base64url"); +const id = (name) => VECTORS.identifiers[name]; +const eq = (a, b) => a.length === b.length && a.every((x, i) => x === b[i]); + +/** + * Read the printed payload frame far enough to recover what a packer has to be + * told: the type code, whether the ESSR sender field is the NULL VID, the + * type-specific fields, and the padding. Parsed with the wire primitives rather + * than `decodePayloadFrame`, so a mis-reading there cannot hide one here. + */ +function readPrintedPayload(printed) { + const frame = b64u(printed); + const cur = { pos: 0 }; + const quadlets = wire.decodeCount(wire.TSP_PAYLOAD, frame, cur); + assert.equal(cur.pos + quadlets * 3, frame.length, "the -Z count covers the printed payload"); + const typeCode = frame.slice(cur.pos, cur.pos + 3); + cur.pos += 3; + const sender = new TextDecoder().decode(wire.decodeVariableData(wire.TSP_VID, frame, cur)); + const out = { sender }; + const padding = () => wire.decodeVariableData(wire.TSP_PLAINTEXT, frame, cur); + + if (eq(typeCode, wire.XSCS)) { + out.type = "scs"; + out.padding = padding(); + const streamQuadlets = wire.decodeCount(wire.TSP_GENERIC_STREAM, frame, cur); + assert.equal(cur.pos + streamQuadlets * 3, frame.length); + out.body = wire.decodeVariableData(wire.TSP_PLAINTEXT, frame, cur); + } else if (eq(typeCode, wire.XHOP)) { + out.type = "hop"; + out.hops = decodeVidList(frame, cur); + out.padding = padding(); + out.inner = frame.slice(cur.pos); + } else if (eq(typeCode, wire.XRFI)) { + out.type = "rfi"; + out.digest = decodeDigest(frame, cur); + out.nonce = decodeNonce(frame, cur); + out.replyPath = decodeVidList(frame, cur); + out.referralQuadlets = wire.decodeCount(wire.TSP_HOP_LIST, frame, cur); + cur.pos += out.referralQuadlets * 3; + out.padding = padding(); + } else if (eq(typeCode, wire.XRFA)) { + out.type = "rfa"; + out.digest = decodeDigest(frame, cur); + out.replyDigest = decodeDigest(frame, cur); + out.padding = padding(); + } else if (eq(typeCode, wire.XRFD)) { + out.type = "rfd"; + out.digest = decodeDigest(frame, cur); + out.padding = padding(); + } else { + throw new Error("unexpected type code in a printed payload"); + } + if (out.type !== "scs" && out.type !== "hop") { + assert.equal(cur.pos, frame.length, "nothing follows the padding field"); + } + return out; +} + +/** Re-pack one vector from its own material; returns the qb2 bytes. */ +async function repack(name) { + const v = VECTORS.vectors[name]; + const sender = id(v.sender); + const receiver = id(v.receiver); + const p = readPrintedPayload(v.payload); + + // The two fields this packer has fixed behaviour for. Neither is a guess: if + // a vector used either differently, re-packing it would be a different claim + // and this says so instead of producing bytes that merely fail to match. + assert.equal(p.padding.length, 0, `${name}: the packer writes an empty padding field`); + assert.ok(p.sender === "" || p.sender === sender.id, `${name}: ESSR sender is NULL or the sender`); + + const keys = { senderSigningKey: b64u(sender.skS), receiverEncryptionKey: b64u(receiver.pkE) }; + const unsafe = { __unsafeIkmE: b64u(v.ikmE), nullPayloadSender: p.sender === "" }; + + switch (p.type) { + case "scs": + return (await __unsafeDeterministicPack(p.body, sender.id, receiver.id, keys, unsafe)).bytes; + case "rfi": { + assert.equal(p.referralQuadlets, 0, `${name}: referrals are decode-only here`); + const packed = await __unsafeDeterministicPackInvite( + sender.id, + receiver.id, + keys, + { route: p.replyPath, nonce: p.nonce }, + unsafe, + ); + assert.deepEqual(packed.threadDigest, p.digest, `${name}: the SAID we derive is the printed one`); + return packed.bytes; + } + case "rfa": { + const packed = await __unsafeDeterministicPackAccept(p.digest, sender.id, receiver.id, keys, unsafe); + assert.deepEqual(packed.threadDigest, p.replyDigest, `${name}: the Reply_Digest we derive is the printed one`); + return packed.bytes; + } + case "rfd": + return (await __unsafeDeterministicPackCancel(p.digest, sender.id, receiver.id, keys, unsafe)).bytes; + case "hop": + return p.hops.length === 0 + ? (await __unsafeDeterministicPackNested(p.inner, sender.id, receiver.id, keys, unsafe)).bytes + : (await __unsafeDeterministicPackRouted(p.inner, p.hops, sender.id, receiver.id, keys, unsafe)).bytes; + default: + throw new Error(`no packer for ${p.type}`); + } +} + +const REPACKED = [ + "direct-hpke-base", + "control-rfi-direct", + "control-rfa-direct", + "control-rfd", + "nested-direct", + "routed", +]; + +for (const name of REPACKED) { + test(`${name} — re-packs byte for byte from its published ikmE`, async () => { + const v = VECTORS.vectors[name]; + const got = await repack(name); + // Compare in the text domain the specification prints, so a failure names + // the qb64 offset a reader can find in Appendix A; then in qb2, the bytes on + // the wire. + assert.equal(qb64(got), v.message); + assert.deepEqual(got, b64u(v.message)); + }); +} + +test("each vector's ikmE derives the pkEm it publishes, and that key is in the message", () => { + for (const name of REPACKED) { + const v = VECTORS.vectors[name]; + const { pk } = deriveKeyPair(b64u(v.ikmE)); + assert.equal(qb64(pk), v.pkEm, `${name}: DeriveKeyPair(ikmE)`); + assert.ok(Buffer.from(b64u(v.message)).includes(Buffer.from(pk)), `${name}: enc leads the F field`); + } +}); + +test("DeriveKeyPair reproduces the CFRG RFC 9180 vector's skEm and pkEm", () => { + const cfrg = JSON.parse( + readFileSync(new URL("./fixtures/cfrg-auth-x25519-chacha.json", import.meta.url), "utf8"), + ).vectors[0]; + const hex = (u8) => Buffer.from(u8).toString("hex"); + const { sk, pk } = deriveKeyPair(new Uint8Array(Buffer.from(cfrg.ikmE, "hex"))); + assert.equal(hex(sk), cfrg.skEm); + assert.equal(hex(pk), cfrg.pkEm); +}); + +test("the re-packed nested and routed vectors carry the published inner message, which also opens", async () => { + // The inner message is opaque to the outer packer, so re-packing it proves + // nothing about it. Opening it closes that gap: it is the vectors' own + // direct message between the nested identities, and it must verify too. + for (const name of ["nested-direct", "routed"]) { + const v = VECTORS.vectors[name]; + const outer = await unpack(b64u(v.message), { + receiverDecryptionKey: b64u(id(v.receiver).skE), + senderSigningKey: b64u(id(v.sender).pkS), + }); + assert.deepEqual(outer.payload, readPrintedPayload(v.payload).inner, `${name}: inner as printed`); + + const { envelope } = decodeEnvelope(outer.payload); + const party = (vid) => Object.values(VECTORS.identifiers).find((i) => i.id === vid); + const inner = await unpack(outer.payload, { + receiverDecryptionKey: b64u(party(envelope.receiver).skE), + senderSigningKey: b64u(party(envelope.sender).pkS), + }); + assert.deepEqual(inner.payload, readPrintedPayload(v.innerPayload).body, `${name}: inner body`); + } +}); + +test("a pack without the unsafe material is not deterministic — the hook is the only way in", async () => { + const { pack } = await import("../dist/index.js"); + const v = VECTORS.vectors["direct-hpke-base"]; + const keys = { senderSigningKey: b64u(id("alice").skS), receiverEncryptionKey: b64u(id("bob").pkE) }; + const body = new TextEncoder().encode("hello world"); + const a = await pack(body, id("alice").id, id("bob").id, keys); + const b = await pack(body, id("alice").id, id("bob").id, keys); + assert.notDeepEqual(a.bytes, b.bytes, "a fresh ephemeral per message"); + assert.notEqual(qb64(a.bytes), v.message); + await assert.rejects( + () => __unsafeDeterministicPack(body, id("alice").id, id("bob").id, keys, {}), + /__unsafeIkmE/, + "an unsafe packer without its ikmE refuses rather than falling back to random", + ); +}); + +test("vectors that cannot be re-packed here are named, with the reason", () => { + const notRepacked = { + // The packer has no sealed box (§8.3) — it cannot even open one. + "direct-sealed-box": "libsodium sealed box (§8.3): not implemented", + "control-rfi-sealed-box": "libsodium sealed box (§8.3): not implemented", + // Deterministic anyway (no encryption), but there is no packer that emits + // an unencrypted `-E` frame; every pack here is HPKE-Base. + "direct-signed-only": "no signed-only packer", + // The hybrid KEM draws its own encapsulation randomness and the vector + // publishes no ephemeral material; nor does this package pack ML-KEM/ML-DSA. + "direct-hpke-base-pq": "ML-KEM-768/X25519 + ML-DSA-65: not implemented, and no published ephemeral", + }; + assert.deepEqual( + new Set([...REPACKED, ...Object.keys(notRepacked)]), + new Set(Object.keys(VECTORS.vectors)), + "every published vector is either re-packed or named", + ); + for (const name of Object.keys(notRepacked)) assert.equal(VECTORS.vectors[name].ikmE, undefined, name); +});