identity_kit/vectors.rs
1//! The specification vectors the tests of this crate run against (feature `test-vectors`), so
2//! that a crate building on this one can test against the same examples: RFC 9901 (SD-JWT),
3//! SD-JWT VC, the Token Status List, VC-JOSE-COSE presentations, the DIF Well Known DID
4//! Configuration and DIF Linked Verifiable Presentation.
5//!
6//! Every constant is the text of the specification's example exactly as published, with a
7//! trailing newline; a compact token is one line, call `trim` before parsing it. The JOSE,
8//! DID and W3C VC examples the tests also use are short enough to live inline in the tests,
9//! and are not repeated here.
10//!
11//! ```
12//! use identity_kit::sd_jwt_vc::SdJwt;
13//! use identity_kit::vectors::sd_jwt::simple;
14//!
15//! let issuance = SdJwt::parse(simple::ISSUANCE.trim())?;
16//! assert_eq!(issuance.disclosures().len(), simple::DISCLOSURES.lines().count());
17//! # Ok::<(), identity_kit::sd_jwt_vc::SdJwtError>(())
18//! ```
19
20macro_rules! vectors {
21 ($($(#[$doc:meta])* $name:ident = $path:literal;)*) => {
22 $(
23 $(#[$doc])*
24 pub const $name: &str = include_str!(concat!("../tests/vectors/", $path));
25 )*
26 };
27}
28
29/// RFC 9901 (SD-JWT), all signed with the issuer key of Appendix A.5.
30pub mod sd_jwt {
31 /// §5: the simple example, issued and presented with key binding.
32 pub mod simple {
33 vectors! {
34 /// The issuer's claims before selective disclosure.
35 USER_CLAIMS = "sd_jwt/simple/user_claims.json";
36 /// The payload of the issuer-signed JWT.
37 PAYLOAD = "sd_jwt/simple/payload.json";
38 /// The disclosures, one per line.
39 DISCLOSURES = "sd_jwt/simple/disclosures.txt";
40 /// The issuer-signed JWT alone.
41 JWS = "sd_jwt/simple/jws.txt";
42 /// The SD-JWT as issued.
43 ISSUANCE = "sd_jwt/simple/issuance.txt";
44 /// The presentation with key binding.
45 PRESENTATION = "sd_jwt/simple/presentation.txt";
46 /// The payload of the key binding JWT.
47 KB_PAYLOAD = "sd_jwt/simple/kb_payload.json";
48 /// The claims the verifier obtains from the presentation.
49 VERIFIED = "sd_jwt/simple/verified.json";
50 }
51 }
52
53 /// §6.1: a flat SD-JWT, `address` disclosable as a whole.
54 pub mod flat {
55 vectors! {
56 /// The payload of the issuer-signed JWT.
57 PAYLOAD = "sd_jwt/flat/payload.json";
58 /// The disclosures, one per line.
59 DISCLOSURES = "sd_jwt/flat/disclosures.txt";
60 }
61 }
62
63 /// §6.2: a structured SD-JWT, the members of `address` disclosable one by one.
64 pub mod structured {
65 vectors! {
66 /// The payload of the issuer-signed JWT.
67 PAYLOAD = "sd_jwt/structured/payload.json";
68 /// The payload with `country` always disclosed.
69 PAYLOAD_ONE_OPEN = "sd_jwt/structured/payload_one_open.json";
70 /// The disclosures, one per line.
71 DISCLOSURES = "sd_jwt/structured/disclosures.txt";
72 }
73 }
74
75 /// §6.3: recursive disclosures, `address` and its members disclosable.
76 pub mod recursive {
77 vectors! {
78 /// The payload of the issuer-signed JWT.
79 PAYLOAD = "sd_jwt/recursive/payload.json";
80 /// The disclosures, one per line.
81 DISCLOSURES = "sd_jwt/recursive/disclosures.txt";
82 }
83 }
84
85 /// Appendix A.1: a simple structured SD-JWT with decoy digests.
86 pub mod simple_structured {
87 vectors! {
88 /// The issuer's claims before selective disclosure.
89 USER_CLAIMS = "sd_jwt/simple_structured/user_claims.json";
90 /// The payload of the issuer-signed JWT.
91 PAYLOAD = "sd_jwt/simple_structured/payload.json";
92 /// The disclosures, one per line.
93 DISCLOSURES = "sd_jwt/simple_structured/disclosures.txt";
94 /// The decoy digests, one per line.
95 DECOYS = "sd_jwt/simple_structured/decoys.txt";
96 /// The presentation.
97 PRESENTATION = "sd_jwt/simple_structured/presentation.txt";
98 /// The claims the verifier obtains from the presentation.
99 VERIFIED = "sd_jwt/simple_structured/verified.json";
100 }
101 }
102
103 /// Appendix A.2: the complex structured eKYC example.
104 pub mod complex_ekyc {
105 vectors! {
106 /// The issuer's claims before selective disclosure.
107 USER_CLAIMS = "sd_jwt/complex_ekyc/user_claims.json";
108 /// The payload of the issuer-signed JWT.
109 PAYLOAD = "sd_jwt/complex_ekyc/payload.json";
110 /// The disclosures, one per line.
111 DISCLOSURES = "sd_jwt/complex_ekyc/disclosures.txt";
112 /// The presentation.
113 PRESENTATION = "sd_jwt/complex_ekyc/presentation.txt";
114 /// The claims the verifier obtains from the presentation.
115 VERIFIED = "sd_jwt/complex_ekyc/verified.json";
116 }
117 }
118
119 /// Appendix A.3: an SD-JWT-based verifiable credential.
120 pub mod sd_jwt_vc {
121 vectors! {
122 /// The issuer's claims before selective disclosure.
123 USER_CLAIMS = "sd_jwt/sd_jwt_vc/user_claims.json";
124 /// The payload of the issuer-signed JWT.
125 PAYLOAD = "sd_jwt/sd_jwt_vc/payload.json";
126 /// The disclosures, one per line.
127 DISCLOSURES = "sd_jwt/sd_jwt_vc/disclosures.txt";
128 /// The SD-JWT as issued.
129 ISSUANCE = "sd_jwt/sd_jwt_vc/issuance.txt";
130 /// The presentation with key binding.
131 PRESENTATION = "sd_jwt/sd_jwt_vc/presentation.txt";
132 /// The payload of the key binding JWT.
133 KB_PAYLOAD = "sd_jwt/sd_jwt_vc/kb_payload.json";
134 /// The claims the verifier obtains from the presentation.
135 VERIFIED = "sd_jwt/sd_jwt_vc/verified.json";
136 }
137 }
138
139 /// Appendix A.4: a W3C Verifiable Credentials Data Model credential.
140 pub mod w3c_vcdm {
141 vectors! {
142 /// The issuer's claims before selective disclosure.
143 USER_CLAIMS = "sd_jwt/w3c_vcdm/user_claims.json";
144 /// The payload of the issuer-signed JWT.
145 PAYLOAD = "sd_jwt/w3c_vcdm/payload.json";
146 /// The disclosures, one per line.
147 DISCLOSURES = "sd_jwt/w3c_vcdm/disclosures.txt";
148 /// The SD-JWT as issued.
149 ISSUANCE = "sd_jwt/w3c_vcdm/issuance.txt";
150 /// The presentation with key binding.
151 PRESENTATION = "sd_jwt/w3c_vcdm/presentation.txt";
152 /// The claims the verifier obtains from the presentation.
153 VERIFIED = "sd_jwt/w3c_vcdm/verified.json";
154 }
155 }
156}
157
158/// SD-JWT VC: the credentials of §2.3 and Appendix A.1.
159pub mod sd_jwt_vc {
160 /// §2.3: the identity credential, issued and presented with and without key binding.
161 pub mod identity_credential {
162 vectors! {
163 /// The issuer's claims before selective disclosure.
164 USER_CLAIMS = "sd_jwt_vc/identity_credential/user_claims.json";
165 /// The payload of the issuer-signed JWT.
166 PAYLOAD = "sd_jwt_vc/identity_credential/payload.json";
167 /// The disclosures, one per line.
168 DISCLOSURES = "sd_jwt_vc/identity_credential/disclosures.txt";
169 /// The SD-JWT VC as issued.
170 ISSUANCE = "sd_jwt_vc/identity_credential/issuance.txt";
171 /// The presentation with key binding.
172 PRESENTATION = "sd_jwt_vc/identity_credential/presentation.txt";
173 /// The claims the verifier obtains from the presentation with key binding.
174 VERIFIED = "sd_jwt_vc/identity_credential/verified.json";
175 /// The presentation without key binding.
176 PRESENTATION_NO_KB = "sd_jwt_vc/identity_credential/presentation_no_kb.txt";
177 /// The claims the verifier obtains from the presentation without key binding.
178 VERIFIED_NO_KB = "sd_jwt_vc/identity_credential/verified_no_kb.json";
179 }
180 }
181
182 /// Appendix A.1: the person identification data (PID) credential.
183 pub mod pid {
184 vectors! {
185 /// The payload of the issuer-signed JWT.
186 PAYLOAD = "sd_jwt_vc/pid/payload.json";
187 /// The disclosures, one per line.
188 DISCLOSURES = "sd_jwt_vc/pid/disclosures.txt";
189 /// The SD-JWT VC as issued.
190 ISSUANCE = "sd_jwt_vc/pid/issuance.txt";
191 /// The presentation with key binding.
192 PRESENTATION = "sd_jwt_vc/pid/presentation.txt";
193 /// The payload of the key binding JWT.
194 KB_PAYLOAD = "sd_jwt_vc/pid/kb_payload.json";
195 /// The claims the verifier obtains from the presentation.
196 VERIFIED = "sd_jwt_vc/pid/verified.json";
197 }
198 }
199}
200
201/// SD-JWT VC type metadata (SD-JWT VC §5 and Appendix A.2).
202pub mod type_metadata {
203 vectors! {
204 /// §5.1: the type metadata document of the education credential, version 42.
205 EDUCATION_CREDENTIAL_V42 = "type_metadata/education_credential_v42.json";
206 /// Appendix A.2: the education credential's type metadata with display and claim
207 /// metadata.
208 EDUCATION_CREDENTIAL = "type_metadata/education_credential.json";
209 /// §5.6.1: the credential payload the claim path examples select from.
210 PAYLOAD = "type_metadata/payload.json";
211 }
212}
213
214/// The Token Status List.
215pub mod status_list {
216 vectors! {
217 /// §4.1: a list of 16 one-bit statuses.
218 LIST_1BIT = "status_list/list_1bit.json";
219 /// §4.2: a list of 12 two-bit statuses.
220 LIST_2BIT = "status_list/list_2bit.json";
221 /// §5: the status list token as a JWT.
222 TOKEN = "status_list/token.txt";
223 /// §5: the header of the status list token.
224 TOKEN_HEADER = "status_list/token_header.json";
225 /// §5: the payload of the status list token.
226 TOKEN_PAYLOAD = "status_list/token_payload.json";
227 /// §6: the header of the referenced token.
228 REFERENCED_HEADER = "status_list/referenced_header.json";
229 /// §6.2: the payload of a referenced token, with its `status` claim.
230 REFERENCED_PAYLOAD = "status_list/referenced_payload.json";
231 /// §6.2: an SD-JWT carrying the `status` claim.
232 REFERENCED_SD_JWT = "status_list/referenced_sd_jwt.txt";
233 /// §6.2: the processed payload of that SD-JWT.
234 REFERENCED_PROCESSED = "status_list/referenced_processed.json";
235 /// Appendix C.1: a one-bit status list.
236 C1_1BIT = "status_list/c1_1bit.json";
237 /// Appendix C.1: the statuses of the one-bit list, by index.
238 C1_1BIT_STATUSES = "status_list/c1_1bit_statuses.json";
239 /// Appendix C.2: a two-bit status list.
240 C2_2BIT = "status_list/c2_2bit.json";
241 /// Appendix C.2: the statuses of the two-bit list, by index.
242 C2_2BIT_STATUSES = "status_list/c2_2bit_statuses.json";
243 /// Appendix C.3: a four-bit status list.
244 C3_4BIT = "status_list/c3_4bit.json";
245 /// Appendix C.3: the statuses of the four-bit list, by index.
246 C3_4BIT_STATUSES = "status_list/c3_4bit_statuses.json";
247 /// Appendix C.4: an eight-bit status list.
248 C4_8BIT = "status_list/c4_8bit.json";
249 /// Appendix C.4: the statuses of the eight-bit list, by index.
250 C4_8BIT_STATUSES = "status_list/c4_8bit_statuses.json";
251 }
252}
253
254/// VC-JOSE-COSE: VCDM 2.0 presentations secured with JOSE (`vp+jwt`) and credentials secured
255/// with SD-JWT (`vc+sd-jwt`).
256pub mod vc_jose_cose {
257 vectors! {
258 /// W3C VC-JOSE-COSE test suite input `credential-selective.json`: the credential of
259 /// [`SUITE_CREDENTIAL_SDJWT_SELECTIVE`] before securing.
260 SUITE_CREDENTIAL_SELECTIVE = "vc_jose_cose/suite-credential-selective.json";
261 /// W3C VC-JOSE-COSE test suite input `credential-sdjwt-selective.txt` (test 20), a
262 /// `vc+sd-jwt` with `credentialSubject.firstName` and `lastName` selectively
263 /// disclosable, signed with [`SUITE_VM_P384`].
264 SUITE_CREDENTIAL_SDJWT_SELECTIVE = "vc_jose_cose/suite-credential-sdjwt-selective.txt";
265 /// W3C VC-JOSE-COSE test suite input `credential-nested-selective.json`: the credential
266 /// of [`SUITE_CREDENTIAL_SDJWT_NESTED`] before securing.
267 SUITE_CREDENTIAL_NESTED_SELECTIVE = "vc_jose_cose/suite-credential-nested-selective.json";
268 /// W3C VC-JOSE-COSE test suite input `credential-sdjwt-nested.txt` (test 21), a
269 /// `vc+sd-jwt` with nested properties and an array element selectively disclosable,
270 /// signed with [`SUITE_VM_P521`].
271 SUITE_CREDENTIAL_SDJWT_NESTED = "vc_jose_cose/suite-credential-sdjwt-nested.txt";
272 /// W3C VC-JOSE-COSE test suite input `credential-sdjwt-bad-signature.txt` (test 23):
273 /// [`SUITE_CREDENTIAL_SDJWT_SELECTIVE`] with its signature bytes rearranged.
274 SUITE_CREDENTIAL_SDJWT_BAD_SIGNATURE = "vc_jose_cose/suite-credential-sdjwt-bad-signature.txt";
275 /// W3C VC-JOSE-COSE test suite input `credential-sdjwt-bad-media-type.txt` (test 24),
276 /// `typ` `bad+typ`, signed with [`SUITE_VM_ED25519`].
277 SUITE_CREDENTIAL_SDJWT_BAD_MEDIA_TYPE = "vc_jose_cose/suite-credential-sdjwt-bad-media-type.txt";
278 /// The `vp+jwt` of the specification's "verifiable presentation secured with JOSE with
279 /// the `EnvelopedVerifiablePresentation` type" example, as its `data:` URL holds it.
280 ENVELOPED_PRESENTATION_JWT = "vc_jose_cose/enveloped_presentation_jwt.txt";
281 /// W3C VC-JOSE-COSE test suite input `presentation-jose-multiple.txt` (test 7), signed
282 /// with [`SUITE_VM_P384`]: a `vc+jwt`, an SD-JWT and a COSE credential enveloped.
283 SUITE_PRESENTATION_MULTIPLE = "vc_jose_cose/suite-presentation-jose-multiple.txt";
284 /// W3C VC-JOSE-COSE test suite input `presentation-jose-bad-media-type.txt` (test 14),
285 /// `typ` `bad+typ`, signed with [`SUITE_VM_ED25519`].
286 SUITE_PRESENTATION_BAD_MEDIA_TYPE = "vc_jose_cose/suite-presentation-jose-bad-media-type.txt";
287 /// W3C VC-JOSE-COSE test suite input `presentation-jose-bad-credential.txt` (test 16),
288 /// an envelope whose `id` is not a `data:` URL, signed with [`SUITE_VM_ED25519`].
289 SUITE_PRESENTATION_BAD_CREDENTIAL = "vc_jose_cose/suite-presentation-jose-bad-credential.txt";
290 /// The test suite's P-256 verification method (`vm-p256.json`, public part).
291 SUITE_VM_P256 = "vc_jose_cose/suite-vm-p256.json";
292 /// The test suite's P-384 verification method (`vm-p384.json`, public part).
293 SUITE_VM_P384 = "vc_jose_cose/suite-vm-p384.json";
294 /// The test suite's Ed25519 verification method (`vm-ed25519.json`, public part).
295 SUITE_VM_ED25519 = "vc_jose_cose/suite-vm-ed25519.json";
296 /// The test suite's P-521 verification method (`vm-p521.json`, public part).
297 SUITE_VM_P521 = "vc_jose_cose/suite-vm-p521.json";
298 }
299}
300
301/// DIF Well Known DID Configuration: the example resource and its credentials, and the example
302/// DID document with `LinkedDomains` services.
303pub mod did_configuration {
304 vectors! {
305 /// The example DID configuration resource, with a Linked Data Proof entry and a JSON
306 /// Web Token entry.
307 RESOURCE = "did_configuration/resource.json";
308 /// The Linked Data Proof entry of the resource.
309 LINKED_DATA_CREDENTIAL = "did_configuration/linked_data_credential.json";
310 /// The JSON Web Token entry of the resource.
311 JWT = "did_configuration/jwt.txt";
312 /// The header of that JWT.
313 HEADER = "did_configuration/header.json";
314 /// The payload of that JWT.
315 PAYLOAD = "did_configuration/payload.json";
316 /// The example DID document with two `LinkedDomains` services, one listing two origins
317 /// in an `origins` object, one a single origin string.
318 DID_DOCUMENT = "did_configuration/did_document.json";
319 }
320}
321
322/// DIF Linked Verifiable Presentation v1.0.0: the example DID documents and presentations.
323pub mod linked_vp {
324 vectors! {
325 /// The example DID document with an HTTPS and an IPFS `LinkedVerifiablePresentation`
326 /// service.
327 DID_DOCUMENT = "linked_vp/did_document.json";
328 /// The same document with hashlink-protected URLs (Security Considerations).
329 DID_DOCUMENT_HASHLINKS = "linked_vp/did_document_hashlinks.json";
330 /// The example presentation in the JSON Web Token form, one credential JWT inside.
331 JWT = "linked_vp/jwt.txt";
332 /// The header of that JWT, `typ` the literal `'vp+ld+jwt'`.
333 HEADER = "linked_vp/header.json";
334 /// The header of the credential JWT inside, `typ` the literal `'vc+ld+jwt'`.
335 CREDENTIAL_HEADER = "linked_vp/credential_header.json";
336 /// The example presentation in the JSON-LD form.
337 JSON_LD = "linked_vp/presentation.jsonld";
338 /// The presentation the specification repository's generator wrote with the
339 /// presentation members at the top level of the payload rather than in `vp`, which
340 /// the specification's "decoded JWT payload" example shows.
341 FLAT_JWT = "linked_vp/flat_jwt.txt";
342 /// The verification method that signed [`JWT`] and [`FLAT_JWT`], from the
343 /// specification repository's generator
344 /// (`resources/linked-vp/generate-config/keys/did-key-ed25519.json`, public part).
345 /// The example DID document shows another key, which verifies neither.
346 VERIFICATION_METHOD = "linked_vp/verification_method.json";
347 }
348}