Test Vectors
This appendix provides normative test vectors for JCS canonicalization (RFC 8785) and Ed25519 signature verification. Implementations MUST produce identical outputs for these inputs. Refresh these vectors when the response schema changes.
Test Key Pair
The test vectors use the Ed25519 key pair from RFC 8032, Section 7.1, Test Vector 1.
| Field | Value |
|---|---|
| Private key (hex) | 9d61b19deffd5a60ba844af492ec2cc44449c5697b326919703bac031cae7f60 |
| Public key (hex) | d75a980182b10ab7d54bfed3c964073a0ee172f3daa62325af021a68f707511a |
| Public key (base64url) | 11qYAYKxCrfVS_7TyWQHOg7hcvPapiMlrwIaaPcHURo |
kid | test-key-1 |
Vector 1 — Minimal Response
A response with no signals and no assessment. Tests baseline key ordering and signature verification. meta.url is present (MUST per ADR-007 — Binding the Signed Response to the Request); meta.context is omitted (MAY) to exercise the no-context path.
Input (signing input — response body without signature):
{
"meta": {
"responseId": "550e8400-e29b-41d4-a716-446655440000",
"entityId": "d6f2fdf4-f829-4ce6-a1cc-e2bd957709db",
"status": "verified",
"url": "https://www.example.org/de/products/123",
"timestamp": "2026-03-23T14:30:00Z",
"expires": "2026-03-24T14:30:00Z"
},
"signals": [],
"kid": "test-key-1"
}
Expected JCS output:
{"kid":"test-key-1","meta":{"entityId":"d6f2fdf4-f829-4ce6-a1cc-e2bd957709db","expires":"2026-03-24T14:30:00Z","responseId":"550e8400-e29b-41d4-a716-446655440000","status":"verified","timestamp":"2026-03-23T14:30:00Z","url":"https://www.example.org/de/products/123"},"signals":[]}
Expected values:
| Field | Value |
|---|---|
| SHA-256 of JCS bytes | 059a554cdc329fd7f23fbc5550be0f2300ae0a443b3f5733aca61c59a117c0af |
| Ed25519 signature (base64url) | EeHWDKMFJ122G3d3V6VO0URuA0jfH5cF-7hC5c7fF9FHwNE3XCqbu2ky1Fm_BkbB4F854lkjCYfk-00l3T08CA |
| Ed25519 signature (hex) | 11e1d60ca305275db61b777757a54ed1446e0348df1f9705fbb842e5cedf17d147c0d1375c2a9bbb6932d459bf0646c1e05f39e259230987e4fb4d25dd3d3c08 |
Key observations:
- Top-level keys sort as
kid,meta,signals(lexicographic order by UTF-16 code units). - Nested keys inside
metasort independently:entityId,expires,responseId,status,timestamp,url. meta.contextis absent — agents that sent nocontextquery parameter still verify successfully.- No whitespace between tokens.
Vector 2 — Response with Signals and Assessment
A response with two signals and an assessment. Tests nested objects, arrays, mixed types (strings, numbers), and deeper key ordering. Both meta.url and meta.context are present (per ADR-007 — Binding the Signed Response to the Request).
Input (signing input — response body without signature):
{
"meta": {
"responseId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"entityId": "d6f2fdf4-f829-4ce6-a1cc-e2bd957709db",
"status": "verified",
"url": "https://www.example.org/de/products/123",
"context": "purchase",
"timestamp": "2026-03-23T14:30:00Z",
"expires": "2026-03-24T14:30:00Z"
},
"signals": [
{
"type": "identity",
"verifiedAt": "2026-01-15T00:00:00Z",
"data": {
"legalName": "Example Electronics GmbH",
"country": "DE",
"registrationNumber": "HRB 12345"
}
},
{
"type": "reputation",
"verifiedAt": "2026-03-01T00:00:00Z",
"data": {
"aggregateRating": 4.2,
"reviewCount": 1247,
"sourceCount": 3
}
}
],
"assessment": {
"action": "proceed",
"safeToPurchase": "yes",
"reasoning": "Verified German business with strong review profile.",
"highlights": [
"Business identity verified",
"4.2-star rating across 1,247 reviews"
]
},
"kid": "test-key-1"
}
Expected JCS output (single line, no whitespace):
{"assessment":{"action":"proceed","highlights":["Business identity verified","4.2-star rating across 1,247 reviews"],"reasoning":"Verified German business with strong review profile.","safeToPurchase":"yes"},"kid":"test-key-1","meta":{"context":"purchase","entityId":"d6f2fdf4-f829-4ce6-a1cc-e2bd957709db","expires":"2026-03-24T14:30:00Z","responseId":"f47ac10b-58cc-4372-a567-0e02b2c3d479","status":"verified","timestamp":"2026-03-23T14:30:00Z","url":"https://www.example.org/de/products/123"},"signals":[{"data":{"country":"DE","legalName":"Example Electronics GmbH","registrationNumber":"HRB 12345"},"type":"identity","verifiedAt":"2026-01-15T00:00:00Z"},{"data":{"aggregateRating":4.2,"reviewCount":1247,"sourceCount":3},"type":"reputation","verifiedAt":"2026-03-01T00:00:00Z"}]}
Expected values:
| Field | Value |
|---|---|
| SHA-256 of JCS bytes | c543933fc6363c70a65984bb84bf78f6eb29bbf45e7861498b98c5d9e6e09b2b |
| Ed25519 signature (base64url) | uTZhnxrZ-dfJJN6XnAL6rlKrZ4JXYgVJ4_XTjslz7UorvSbCEVreJZUcoTVBZzW2QeMkYpHUb5ETIXdzq0wJDA |
| Ed25519 signature (hex) | b936619f1ad9f9d7c924de979c02faae52ab678257620549e3f5d38ec973ed4a2bbd26c2115ade25951ca135416735b641e3246291d46f9113217773ab4c090c |
Key observations:
assessmentsorts beforekidbecausea<k.- Inside
meta, keys sort ascontext,entityId,expires,responseId,status,timestamp,url. - Array elements preserve order — signals appear in the same sequence as the input.
aggregateRatingserializes as4.2(shortest representation per RFC 8785 Section 3.2.2.3).reviewCountserializes as1247(integer, no decimal point).- String
"yes"serializes as"yes"(with quotes, per JSON string rules). - Keys within each
dataobject sort independently:country,legalName,registrationNumber.
Vector 3 — JCS Edge Cases
Tests number formatting, key ordering with mixed-case names, empty containers, null, and non-ASCII strings. This vector has no signature — it validates JCS canonicalization only.
Input:
{
"zebra": true,
"alpha": 1,
"number_formats": {
"integer": 42,
"negative": -1,
"decimal": 3.14,
"zero": 0,
"large": 1000000
},
"empty_array": [],
"empty_object": {},
"null_value": null,
"unicode": "Straße"
}
Expected JCS output:
{"alpha":1,"empty_array":[],"empty_object":{},"null_value":null,"number_formats":{"decimal":3.14,"integer":42,"large":1000000,"negative":-1,"zero":0},"unicode":"Straße","zebra":true}
SHA-256 of JCS bytes: 29a73c58f72156d0c123bb6123320cce7ecf869822f84bc576116d46d6c58c67
Key observations:
- Top-level keys sort as:
alpha,empty_array,empty_object,null_value,number_formats,unicode,zebra. nullserializes asnull.- Empty arrays and objects serialize as
[]and{}. 1000000stays as1000000(no scientific notation for integers that fit in IEEE 754).3.14stays as3.14.0serializes as0(not0.0).Straßecontains the UTF-8 encoding of U+00DF (ß) — JCS does not escape non-ASCII printable characters.
Verification Procedure
To validate an implementation against these vectors:
- Parse the input JSON.
- JCS-canonicalize the parsed object (RFC 8785).
- Compare the output bytes against the expected JCS output.
- Compute SHA-256 over the JCS bytes and compare against the expected hash.
- For Vectors 1 and 2: verify the Ed25519 signature over the JCS bytes using the test public key.
If any step produces a different result, the implementation does not conform to the protocol's canonicalization requirements.
References
- RFC 8785 — JSON Canonicalization Scheme (JCS)
- RFC 8032 — Edwards-Curve Digital Signature Algorithm (Ed25519), Section 7.1
- Security specification — Signing and verification requirements