Internet-Draft Evaluation Receipt Mappings October 2026
Gruszka Expires 15 April 2027 [Page]
Workgroup:
Network Working Group
Internet-Draft:
draft-gruszka-evaluation-receipt-mappings-03
Published:
Intended Status:
Informational
Expires:
Author:
K. Gruszka
b7n0de

Citing Signed Evaluation Receipts from Existing Envelopes

Abstract

A Signed Evaluation Receipt records one evaluation result as signed payload bytes B. This document describes how existing envelopes cite such a receipt by the SHA-256 digest of B, and how a DSSE envelope carries B with the receipt's own signature. It fixes those bytes and a matching rule, maps the parts of a receipt onto DSSE, the in-toto Statement with the test-result predicate and the SLSA Verification Summary Attestation, shows that the signature of a receipt is already a valid DSSE signature, gives a SCITT Signed Statement that names a receipt only by its digest, in a key profile and a certificate profile, declares the receipt digest as an artifact type for typed digest references, and relates a receipt to a pre-run criteria set written in PRML. It defines no new format and no new predicate.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 15 April 2027.

▲

Table of Contents

1. Introduction

A Signed Evaluation Receipt (receipt) [RECEIPTS] holds one assertion, whether a threshold held for a metric of a test suite, as payload bytes B. B is signed with Ed25519 over a pre-authentication encoding with a fixed type. A receipt carries no inclusion proof and does not prove registration with a Transparency Service. In SCITT, transparency additionally requires registering a Signed Statement that names the receipt and verifying the resulting SCITT Receipt (Section 5).

Other parties will want to refer to a receipt from the envelopes they already use: a DSSE envelope, an in-toto Statement, a SLSA Verification Summary, or a SCITT Signed Statement. This document is the third part of one line of work: [STATEMENT-ID] asks how a signed statement is named unambiguously, [RECEIPTS] fixes the bytes of a receipt, and this document shows how existing envelopes cite such a receipt by digest.

It also relates a receipt to a criteria set fixed before the run in PRML [PRML] (Section 6), and says where it meets the requirements of [ABAK] for exchanging evaluation evidence (Section 7).

This document defines no second receipt format, no new in-toto predicate and no new COSE header parameter. What a receipt does not prove stays unproven when an envelope cites it (Section 8).

2. Conventions and Terminology

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here.

The terms receipt, B, Issuer, Receiver and type are used as in [RECEIPTS]. The type is the fixed string

application/vnd.signed-evidence.eval-receipt+json

The type identifies B ([RECEIPTS] Section 10.1). The receipt object uses the same fixed string as its schema discriminator, but is a different JSON representation.

Receipt digest:

SHA-256 over B (Section 3).

Citation:

A hash algorithm and a digest value that an envelope carries to name a receipt.

Citing envelope:

An in-toto Statement or a COSE Signed Statement that carries a citation. A DSSE envelope carries B itself, not a citation (Section 4.1).

3. The Receipt Digest

3.1. Definition

The receipt digest is SHA-256 over B, the payload bytes of the receipt as defined in [RECEIPTS] Section 3.4: the bytes that steps 1 to 3 of [RECEIPTS] Section 5 obtain from payload_b64. A candidate for which one of those steps fails has no B, even if a lenient decoder would produce bytes from it (cases C6 and C7). It is not computed over the receipt bytes or over PAE(type, B). An envelope that carries the digest as text uses its 64 lowercase hexadecimal digits; one that carries it as bytes uses the 32 bytes. This document defines no other hash algorithm.

3.2. Why B

The digest runs over B for two reasons.

  • B is what is signed. The signing input PAE(type, B) depends on B alone, because the type is fixed ([RECEIPTS] Section 4.2). A digest over B therefore names exactly the signed content; a digest over the signing input would carry no further information.

  • The receipt bytes are not stable. The receipt object around B is not canonicalized, and its key hint is not signed. Vectors P1, P4 and P6 of [RECEIPTS] are three different receipt byte strings that all verify and all carry the same B (cases C1 to C3 of Table 1). A digest over the receipt bytes would give one signed statement three names, and it would change whenever the receipt object is written again. In-toto resource descriptors and the COSE Hash Envelope each name content by the digest of its bytes, and a DSSE envelope carries the bytes themselves.

The price of this choice: the receipt digest identifies the signed content, not the signature and not the key. Two receipts with the same B under different keys have the same digest. The iss and kid of a citing Signed Statement (Section 5.2) identify its signer, which need not be the receipt signer. This mapping does not encode a constraint on the receipt signer. A Receiver verifies the cited receipt under the receipt key it fixed independently.

3.3. Matching Rule

Given a citation and a candidate receipt, the result is computed as follows. For the JSON representation in Section 5.1, first apply that section's extraction rule; it either gives INDETERMINATE or supplies the algorithm and value for the steps below. The matching result is independent of the typed reference's processing state.

  1. If the citation's algorithm is not SHA-256, or its value is not 32 bytes (64 lowercase hexadecimal digits in text form), the result is INDETERMINATE. SHA-256 is named sha256 as the key of an in-toto digest set [INTOTO-DIGESTSET], -16 as the value of COSE header parameter 258, and sha-256 as the algorithm label of the examples (Appendix A); each name counts only in its own carrier, and names are compared exactly, so SHA256 is none of them. A typed digest reference names it SHA-256 (Section 5.1). The value is 64 lowercase hexadecimal digits in text form in a digest set (Section 4.3), in a typed digest reference (Section 5.1) and in the examples (Appendix A.2), and 32 bytes as the payload of a statement whose parameter 258 is -16 (Section 5.2). A digest set with several entries is matched on its sha256 entry alone; this document does not judge the other entries. This is narrower than the matching guidance of [INTOTO-DIGESTSET], under which two digest sets match if any acceptable field matches: here a digest set without a sha256 entry gives INDETERMINATE, and one whose sha256 entry passes step 1 but differs from SHA-256 over B gives NO_MATCH, whatever its other entries are.

  2. If steps 1 through 3 of [RECEIPTS] Section 5 do not all complete successfully, including when processing stops at a resource limit, B is not obtained and the result is INDETERMINATE.

  3. Otherwise the result is MATCH when SHA-256 over B equals the cited value, and NO_MATCH when it does not.

A MATCH establishes neither that the candidate verifies, nor who signed it, nor that its assertion is true. A Receiver that relies on a cited receipt runs the full procedure of [RECEIPTS] Section 5 under a key it fixed. Case C5 is a candidate that matches and fails that procedure at step 11.

Table 1: Citation cases
Case Candidate Result Verification of the candidate What it shows
C1 P1 MATCH PASS the receipt the citation was made from
C2 P4 MATCH PASS other receipt bytes (an escaped character in schema), same B
C3 P6 MATCH PASS other receipt bytes (no key hint), same B
C4 P2 NO_MATCH PASS another receipt with another B
C5 N7 MATCH FAIL, step 11 (profile 4) same B, signature made over another type: a match is not a verification
C6 N13 INDETERMINATE FAIL, step 3 payload_b64 is not canonical base64: B is not obtained
C7 N14 INDETERMINATE FAIL, step 1 the receipt has duplicate member names: B is not obtained
C8 P1 INDETERMINATE PASS the citation names an algorithm this document does not define

3.4. Against the Identification Requirements

[STATEMENT-ID] proposes requirements A1 to A5 for references to signed statements. This section checks the receipt digest against them. It is the author's analysis, not a conformance claim.

A1, unambiguous target and matching rule:

The scheme names the hash algorithm (SHA-256), the input bytes (B, as steps 1 to 3 of [RECEIPTS] Section 5 obtain it from payload_b64) and the encoding (64 lowercase hexadecimal digits or 32 bytes). Section 3.3 is the matching rule. An unsupported algorithm or a candidate without B gives INDETERMINATE, never MATCH (C6 to C8). Identity is preserved under every difference outside B that leaves steps 1 to 3 of [RECEIPTS] Section 5 succeeding: the receipt's whitespace and escapes, its key hint, and its signature value. In the terms of [STATEMENT-ID] Section 5 the receipt digest is a digest of the payload. Because the type is fixed and nothing else enters the signature, it also determines the signing input; neither names the signer.

A2, readable without interpreting the carrier's payload:

In the COSE Hash Envelope of Section 5.2 the citation is read from header parameters 258 and 259 and the payload, as [RFC9995] defines them, without interpreting application content. In an in-toto Statement the citation lies inside the predicate, which is the Statement's application content; a reader has to know the predicate to find it. A2 is met by the first and not by the second.

A3, matching independent of registration:

B does not change when the receipt is registered anywhere or its object is written again. Cases C2 and C3 carry other receipt bytes and still match.

A4, acceptance test for A3:

Cases C2 and C3 apply local changes that a re-encoding may cause (another JSON escape, a key hint left out), and the result stays MATCH. This is not a measurement of registration in two services.

A5, receipt-verification dependency:

Matching does not depend on a leaf hash or a COSE Receipt. A receipt has no inclusion proof of its own; a Transparency Service that registers a statement naming it fixes its own leaf construction, and matching does not use it.

4. Mapping to Existing Envelopes

Table 2 shows, for each part of a receipt, where it has a place in three envelopes and what that envelope does not have: DSSE [DSSE], the in-toto Statement v1 [INTOTO-STATEMENT] with the test-result predicate v0.1 [TEST-RESULT] (test-result in the table), and the SLSA Verification Summary Attestation v1 [VSA] (VSA). "None" means that the envelope has no field for it. This document defines no predicate of its own.

Table 2: Receipt parts in three envelopes
Receipt part Envelope Field there, or what is missing
B DSSE payload, base64 of B
  test-result none; a Statement that restates the members is other bytes
  VSA none; inputAttestations[].digest names B by its digest
type DSSE payloadType
  test-result none; the Statement's envelope carries an in-toto type
  VSA inputAttestations[].mediaType
signature.sig DSSE signatures[].sig, the same bytes (vector M1)
  test-result none; the Statement's envelope carries a new signature
  VSA none; the VSA is signed by its verifier
signature.alg DSSE none; DSSE names no signature algorithm
  test-result, VSA none
signature.key DSSE keyid, optional and not signed
  test-result, VSA none
passed DSSE inside B
  test-result result PASSED or FAILED; WARNED has no receipt counterpart
  VSA none; verificationResult is the verifier's result
payload schema DSSE inside B
  test-result none; predicateType names test-result, not the payload schema
  VSA none
suite, suite_version DSSE inside B
  test-result no field of its own; configuration or url can name the suite
  VSA none
metric, comparator, threshold, score, n DSSE inside B
  test-result, VSA none
criteria_digest, when present DSSE inside B
  test-result, VSA none
model_id_commit, dataset_id_commit, commit_alg DSSE inside B
  test-result none; subject wants a digest of the artifact, and a commitment is not one
  VSA none; subject and resourceUri name the verified artifact
timestamp DSSE inside B
  test-result none
  VSA none; timeVerified is the verifier's time

In the other direction, a receipt has no counterpart for the required VSA fields verifier, resourceUri, policy and verifiedLevels, for its optional timeVerified, or for the subject of an in-toto Statement.

4.1. DSSE

The signature of a receipt is a valid DSSE signature without any new signature. DSSE [DSSE] signs PAE(payloadType, payload) with the same pre-authentication encoding that [RECEIPTS] Section 4.1 defines. The envelope

{"payloadType": <type>, "payload": <base64 of B>,
 "signatures": [{"sig": <the receipt's signature.sig>}]}

therefore verifies as DSSE under the Issuer's key when payloadType is exactly the type and payload decodes to B. Vector M1 (Appendix A) gives the bytes; its signature is the signature of vector P1 of [RECEIPTS], byte for byte. M1 leaves out keyid, which DSSE treats as an optional, unauthenticated hint.

A successful DSSE signature check alone is not a receipt verdict. DSSE also requires a supported payloadType and parsing the authenticated payload according to that type. To obtain a receipt verdict, a Receiver decodes the payload and the selected signature once, uses those same bytes to construct the receipt object with canonical base64 as required by [RECEIPTS] Section 3.1, and runs [RECEIPTS] Section 5 under its independently selected receipt verification key.

The signature is expected to be valid as DSSE only under this payloadType, because Ed25519 binds the exact signing input; this is not measured beyond sample types. Vector N7 of [RECEIPTS] shows the converse for the receipt itself: its signature, made over PAE with the type application/vnd.example.other+json, fails under the fixed type.

4.2. in-toto Statement with test-result

The test-result predicate [TEST-RESULT] records result (PASSED, WARNED or FAILED), configuration (a required list of resource descriptors), url, and the lists passedTests, warnedTests and failedTests. A Statement [INTOTO-STATEMENT] that restates a receipt maps passed to result PASSED or FAILED. No member of the predicate carries the metric, the comparator, the threshold, the score, the sample count or the timestamp; passedTests and failedTests are lists of test names, not a count. The Statement's subject names the tested artifact by digest; a commitment is not a digest of the artifact's bytes, so the model commitment cannot stand as subject without changing what subject means.

Such a Statement is a new statement by whoever signs its envelope [INTOTO-ENVELOPE]. It does not carry the receipt's signature and the predicate has no member for the evidence a result rests on. This document therefore does not cite receipts from test-result; the mapping states what a party loses when it restates a receipt in that form.

4.3. SLSA Verification Summary

A Verification Summary Attestation [VSA] states that a verifier verified an artifact against a policy. Its inputAttestations is a list of resource descriptors [INTOTO-RD], each of which carries a digest of the attestation it names. A verifier that used a receipt as evidence when it verified an artifact, for example the evaluated model, and verified the receipt under [RECEIPTS] Section 5, cites the receipt there; the artifact itself is the VSA's subject:

{"digest": {"sha256": "<receipt digest, 64 hex digits>"},
 "mediaType": "application/vnd.signed-evidence.eval-receipt+json"}

The mediaType identifies B. verificationResult is the verifier's result under its policy, not the receipt's passed: a receipt that verifies and records passed false (vector P2 of [RECEIPTS]) can be the input of a VSA whose verificationResult is PASSED, when the verifier's policy asks only for a valid receipt.

5. COSE and SCITT

A Signed Evaluation Receipt is not a COSE Receipt. Its format is JSON with Ed25519 over PAE, not COSE; it carries no inclusion proof, and no Transparency Service or Registration Policy [RFC9943] takes part in making it. In SCITT, a Transparency Service registers a Signed Statement and returns a COSE Receipt [RFC9942] proving its inclusion.

Two existing constructions carry the receipt digest without a new field: a typed digest reference (Section 5.1) and a Signed Statement whose payload is the digest (Section 5.2). Both name the receipt; neither carries it.

5.1. A Typed Digest Reference

[CPB] Section 8 defines a typed digest reference with the members type, purpose, digest_alg and digest, and leaves the declaration of artifact types to the profiles that accept them ([CPB] Section 8.1). This document declares one artifact type for the receipt digest:

  • type is application/vnd.signed-evidence.eval-receipt+json, the type, which identifies B;

  • there is one digest context, so purpose is absent;

  • the context has no purpose label, so a well-formed reference that carries purpose is Unresolved ([CPB] Section 8.1);

  • the canonicalization algorithm is as-transmitted ([CPB] Section 4.4), with the byte-boundary selector [RECEIPTS] Section 3.4, "The Bytes B";

  • the hash function is SHA-256, and digest_alg is exactly SHA-256;

  • digest is the receipt digest as its 64 lowercase hexadecimal digits, a text value; in the cpb-refs header parameter of [CPB] Section 8.3 it is a text string.

For the JSON representation defined here and used in Appendix A.7, a reference is one JSON object [RFC8259] with the required members type, digest_alg and digest, and the optional member purpose. Each of these members, when present, has a JSON string value. No other member is allowed. Member names of this object are compared after JSON string unescaping, without case folding or Unicode normalization; repeated names are detected before any conversion that could discard them. Input that violates the JSON grammar, is not an object, has a repeated member name, lacks a required member, has a non-string value for one of the named members, or has another member is Malformed ([CPB] Section 3). A byte order mark before the JSON text is not part of the JSON grammar, so such input is Malformed, although [RFC8259] Section 8.1 allows a parser to ignore it. This form check precedes reference resolution and verification. The rules assigning Unresolved, Failed or Verified apply only to well-formed references. These form requirements define this JSON representation; they do not replace the rules for cpb-refs or another profile's own serialization.

For this JSON representation, the independent matching result of Section 3.3 is INDETERMINATE unless the input conforms to the JSON grammar, its top-level value is an object, and that object contains exactly one digest_alg member and exactly one digest member, both with string values. Otherwise Section 3.3 applies to those two values regardless of the reference state. No occurrence is chosen from repeated digest_alg or digest members, even if their values agree, and non-string values are not converted to strings. A matching result does not change the reference state or make a Malformed reference Verified.

A reference under this declaration can stand in the cpb-refs header parameter of a Signed Statement, or in a payload that carries references in its own serialization, for example in the references of [CAPSULE]. For a well-formed reference, context selection and verification follow [CPB] Section 8.1. A consuming profile that does not name this declaration by normative reference leaves a well-formed reference to it Unresolved; no profile names it at the time of writing. Once this digest context has been selected, a digest_alg other than SHA-256 or a digest outside the declared text representation of 64 lowercase hexadecimal digits makes the reference Failed. Section 3.3 gives INDETERMINATE for either case. After those checks, a verifier obtains B by steps 1 to 3 of [RECEIPTS] Section 5. If B is not obtained, the reference is Unresolved and the matching result is INDETERMINATE. Otherwise the verifier computes SHA-256 over B and compares its hexadecimal text with digest: equality gives Verified and MATCH, and inequality gives Failed and NO_MATCH. Vectors R1 to R14 (Appendix A.7) illustrate these states and Malformed.

Only the digest crosses, as for the Signed Statement below. A reference that is Verified shows that the cited bytes are B; it does not show that the receipt verifies, who signed it, or that its assertion is true ([CPB] Section 8.5).

5.2. A Signed Statement that Cites a Receipt

A Signed Statement that cites a receipt is a COSE_Sign1 [RFC9052] with CBOR tag 18 in the form of a COSE Hash Envelope [RFC9995]. It has one of two profiles, which differ in how the statement names its signer. In the key profile, kid names an Ed25519 statement key that the Receiver has configured for the issuer. In the certificate profile, the protected header carries an X.509 certificate chain [RFC9360] whose last certificate is a trust anchor that the Receiver has configured for a did:x509 issuer [DIDX509]. The labels of the protected header select the profile (step 2 of Section 5.2.2). Vector M2 (Appendix A) is a statement in the key profile, vector X1 one in the certificate profile.

Both profiles share these rules:

  • The protected header holds exactly the parameters of its profile, given below, and no other. Three of them are the same in both profiles:

    • 15 (CWT Claims) [RFC9597]: a map with exactly 1 (iss), whose form each profile gives, and 2 (sub), the text value of model_id_commit of B;

    • 258 (payload hash algorithm): -16 (SHA-256);

    • 259 (preimage content type): the type, as a text string.

  • The unprotected header is the empty map.

  • The payload is the receipt digest, 32 bytes.

  • The COSE_Sign1, its protected header included, is encoded with the core deterministic encoding of [RFC8949] Section 4.2.1.

Key profile. The protected header holds exactly the five parameters 1, 4, 15, 258 and 259:

  • 1 (alg): -19, Ed25519 as fully specified in [RFC9864], or -8, EdDSA [RFC9053]. A party that makes a statement MUST write -19. A Receiver MUST accept both values and applies every other check of Section 5.2.2 to either; under the Ed25519 statement keys that step 3 selects, both values select the same signature algorithm. Changing alg changes the protected header bytes and requires a new signature (Section 5.2.4);

  • 4 (kid): the COSE Key Thumbprint [RFC9679] with SHA-256 of the statement key, a byte string of 32 bytes. For an Ed25519 public key x, kid is SHA-256 over the core-deterministically encoded COSE_Key map {1: 1, -1: 6, -2: x}; no optional COSE_Key parameter enters the thumbprint;

  • 15 (CWT Claims): iss is an absolute URI ([RFC3986] Section 4.3) that names the party that makes the statement.

Its form is fixed, so that one receipt digest, one statement key, one issuer and one algorithm value give one byte string.

Certificate profile. The protected header holds exactly the six parameters 1, 4, 15, 33, 258 and 259:

  • 1 (alg): -7, ECDSA with SHA-256 ([RFC9053] Section 2.1); the signature is r and s, 32 bytes each, under the P-256 public key of the leaf certificate (Section 5.2.4);

  • 4 (kid): SHA-256 over the DER encoding of the SubjectPublicKeyInfo [RFC5280] of the leaf certificate, a byte string of 32 bytes;

  • 15 (CWT Claims): iss is a did:x509 identifier [DIDX509] of exactly the form did:x509:0:sha256: F ::eku: O, where F is SHA-256 over the DER bytes of the last certificate of x5chain, encoded in base64url without padding (43 characters), and O is an object identifier in dotted decimal form: the first arc is 0, 1 or 2, it is followed by one or more further arcs, the second arc is at most 39 when the first arc is 0 or 1, the arcs are separated by full stops, and each arc is a decimal number without leading zeros;

  • 33 (x5chain) [RFC9360]: an array of exactly two byte strings, each a DER-encoded X.509 certificate [RFC5280]: first the leaf certificate, whose P-256 public key verifies the statement signature, then the trust anchor certificate, whose RSA public key signed the leaf certificate with sha256WithRSAEncryption (RSASSA-PKCS1-v1_5 with SHA-256, [RFC8017]).

This profile names one trust anchor and no intermediate certificate. The profile is limited to this form, two certificates with an RSA trust anchor, because it is the form measured to work (Section 12). An x5chain array with more or fewer than two elements, an x5chain that is a single byte string, and an iss with a predicate other than one eku give outside_profile in step 2 of Section 5.2.2. Certificate contents, key restrictions and their bindings are checked in step 3, which gives untrusted_key when one of those checks fails. An ECDSA signature depends on a per-signature nonce, so one statement in this profile can have more than one byte string; the vectors use the deterministic nonce of [RFC6979], which a Receiver does not check.

The value of sub is a choice of this example; the receipt digest does not depend on it. The key that signs a statement and the receipt key can be the same key or different keys. The statement carries its own signature over its own Sig_structure; it is not the receipt's signature, even when one key makes both. Registering M2 or X1 with a Transparency Service yields a COSE Receipt for that statement, not for the evaluation receipt.

5.2.1. Making a Statement

A party makes a statement for a receipt only after the receipt has passed the verification procedure of [RECEIPTS] Section 5 under a key that party fixed. A receipt that fails it gives no statement. The party computes the receipt digest over B, takes sub from the model_id_commit of B, writes the protected header of one profile, signs the Sig_structure of [RFC9052] Section 4.4 with an empty external_aad, under the statement key in the key profile and under the private key of the leaf certificate in the certificate profile, and encodes the COSE_Sign1.

5.2.2. Checking a Statement

The Receiver holds the statement, a candidate receipt, its independently selected receipt verification key, and configured pairs. A pair for the key profile is an issuer URI with an Ed25519 statement key; a pair for the certificate profile is a did:x509 identifier with a trust anchor certificate. The received iss value does not establish either association. It applies the following steps in order. The first step that fails gives the status named in it, and the statement is refused; only a statement that passes every step is accepted. A Receiver that stops because it reached a resource limit, in any step, reports a resource-limit error; that is no status, and the statement is not accepted.

  1. If the bytes are not one CBOR data item in the deterministic encoding, if the item is not a COSE_Sign1, or if its protected header is not a map in the deterministic encoding, the status is malformed. A data item that is well-formed but not valid under [RFC8949] Section 5.3.1, such as a text string that is not valid UTF-8 or a map with duplicate keys, is malformed; two keys are duplicates only when they are equal under the key equivalence of [RFC8949] Section 5.6.1, so the integer 1 and true are two keys and 0.0 and -0.0 are one. For the choices that [RFC8949] Section 4.2.2 leaves to a protocol, step 1 uses these: a NaN is in the deterministic encoding only as the half-precision quiet NaN 0xf97e00, and any other encoding of a NaN is malformed; no tag, the bignum tags 2 and 3 included, adds a rule of its own. Step 1 does not check whether the content of a tag inside the COSE_Sign1 is valid for that tag ([RFC8949] Section 5.3.2); the data items inside a tag are checked like any other data item. For step 1, the COSE_Sign1 check concerns only the outer tag, the four-element array and its element types: a wrapping in a CBOR tag other than 18 is not a COSE_Sign1 and is malformed, and an otherwise valid COSE_Sign1 without a tag goes on to step 2 and is outside_profile there. The protected-header byte string is decoded as a CBOR map, with the empty byte string treated as an empty map ([RFC9052] Section 3), which fails in step 2. CBOR validity and deterministic encoding are checked before step 2. Header label types are checked only in step 2; a header label that is not a label of either profile gives outside_profile if step 1 succeeds.

  2. A Transparent Statement [RFC9943] carries COSE Receipts [RFC9942] in its unprotected header under label 394. If the unprotected header holds label 394 and no other label, and the value of 394 is an array of one or more byte strings, the Receiver removes label 394 and applies the rest of this step and the following steps with the empty unprotected header; the protected header, the payload and the signature stay as they are. These steps do not read the receipts.

    The labels of the protected header select the profile: exactly the integer labels 1, 4, 15, 258 and 259 select the key profile, and exactly the integer labels 1, 4, 15, 33, 258 and 259 select the certificate profile. If the item is not tagged 18, the unprotected header is not empty, or the labels select neither profile, the status is outside_profile.

    In both profiles, kid is a byte string of 32 bytes; 15 is a map with exactly the integer labels 1 (iss) and 2 (sub), both text strings; 258 is the integer -16; and 259 is the type as a text string. In the key profile, alg is the integer -19 or -8, and iss is an absolute URI. In the certificate profile, alg is the integer -7, iss has the syntactic form given in Section 5.2, and x5chain is an array of exactly two byte strings. This step checks only the syntax of iss and the container form of x5chain; the certificate contents, key properties, and the bindings of iss and kid are checked in step 3. A violation of these structural rules, a detached payload, a payload that is not 32 bytes, or a signature that is not 64 bytes gives outside_profile. sub MUST match sha256: followed by exactly 64 lowercase hexadecimal digits; otherwise the status is outside_profile. Step 7 compares sub byte for byte with model_id_commit of B.

  3. Key profile. A configured pair counts only if its statement key is 32 octets and its point A meets rules 1 and 2 of [RECEIPTS] Section 4.4: A is a canonical encoding of a point of order L. A point of small order or of mixed order does not count. If no configured pair that counts has both an issuer URI exactly equal to iss and a statement key whose SHA-256 COSE Key Thumbprint equals kid, the status is untrusted_key. Subsequent signature verification uses only keys selected by this pairwise match.

    Certificate profile. A configured pair counts only if its identifier is exactly equal to iss, its trust anchor certificate is byte for byte the second certificate of x5chain, and F of iss is SHA-256 over that certificate. The status is untrusted_key if no configured pair counts, or if any of the following does not hold: both certificates are DER-encoded X.509 certificates; the public key of the trust anchor is an RSA key with a modulus of at least 2048 bits; the leaf certificate is signed by that key with sha256WithRSAEncryption; the issuer name of the leaf certificate is byte for byte the subject name of the trust anchor; the extended key usage of the leaf certificate contains O of iss; the public key of the leaf certificate is a P-256 key; and kid is SHA-256 over its SubjectPublicKeyInfo. This step is not certification path validation ([RFC5280] Section 6) and does not resolve iss as a DID: it evaluates no validity period, revocation status, name constraint, certificate policy or other extension. [DIDX509] requires path validation for resolution. An application that additionally performs path validation reports its result separately from the status of this procedure and may refuse to use a statement whose status is accepted.

  4. Key profile. If the signature does not meet the four rules of [RECEIPTS] Section 4.4 under a key that step 3 selected, with the Sig_structure of [RFC9052] Section 4.4 in place of PAE(type, B) in rule 4, the status is signature_invalid.

    Certificate profile. Read r and s as unsigned big-endian integers from the first and the last 32 bytes of the signature. If r or s is not in the range 1 to n-1, where n is the order of the P-256 base point, or the signature is not a valid ECDSA signature with SHA-256 over the Sig_structure under the public key of the leaf certificate, the status is signature_invalid.

  5. Run the verification procedure of [RECEIPTS] Section 5 under the Receiver's receipt key. Continue to step 6 only if it returns PASS. If it returns FAIL, the status is receipt_not_verified. If it stops with a resource-limit error, propagate that error and stop without accepting the statement.

  6. If the payload is not the receipt digest of the candidate, the status is digest_mismatch.

  7. If sub is not the model_id_commit of B, the status is subject_mismatch.

If every step passes, the status is accepted. Vector M2 with vector P1 of [RECEIPTS] is accepted, and Appendix A.6 gives a statement for each other status. Vector X1 with P1 is accepted under the certificate pair of Appendix A.8, and X2 to X6 fail at steps 2, 3 and 4 in the certificate profile. Vectors T1 to T5 (Appendix A.9) are Transparent Statements: T1 and T2 are accepted, and T3 to T5, whose unprotected headers hold more than the receipts or the receipts in another form, are outside_profile.

Steps 1 to 4 do not use the receipt. For the key profile, a general COSE verifier that implements the statement's alg value checks the signature under the rules of its own Ed25519 implementation, which can accept a signature that step 4 refuses, for example one whose R is a point of small order. For either profile, a COSE signature check alone does not apply steps 5 to 7, and its success does not show that the statement cites a receipt that verifies.

5.2.3. What Crosses and What Is Lost

Table 3: What a Signed Statement carries of a receipt
Receipt Signed Statement
B only its receipt digest, as the payload
model_id_commit of B sub (2) of the CWT Claims
the type parameter 259
the other members of B (schema, suite, suite_version, metric, comparator, threshold, score, passed, n, dataset_id_commit, commit_alg, timestamp), including criteria_digest when present not carried; named only through the digest
the receipt's signature and its key hint not carried
(none) iss, kid, alg and, in the certificate profile, x5chain: the statement of the party that signs it

A Receiver that relies on the assertion of a receipt needs the receipt itself; the statement only names it.

5.2.4. Choice of alg

In the key profile, value -19 is the fully specified Ed25519 identifier of [RFC9864], which sets the polymorphic EdDSA identifier -8 of [RFC9053] to Deprecated. A party that makes a statement therefore writes -19 only. Every Receiver accepts -8 as well, for statements made before a producer moved to -19 and for general COSE verifiers that implement -8 but not -19 (Section 12), so that one statement gives one status. -8 names EdDSA for any curve; step 3 of Section 5.2.2 counts only Ed25519 statement keys, so a statement with -8 under any other key is untrusted_key. Vector S1 (Appendix A.6) is M2 with alg -8, signed again under the same key; it is accepted.

The certificate profile fixes -7. [RFC9864] also sets -7 to Deprecated and registers -9 (ESP256) for ECDSA with SHA-256 on P-256. The certificate profile does not admit -9: the Transparency Service measured in Section 12 refuses a statement with -9 at registration, also when its configuration names ESP256, and neither the offline verifier nor the two general COSE libraries named there implement -9. A statement with -9 is outside the certificate profile (vector X2). -7 does not name a curve; step 3 counts only a P-256 leaf key, so -7 selects one signature algorithm here.

The payload follows the pattern of the hash-only mode of [PRML-PROFILE]: the 32 raw octets of a SHA-256, carried as a byte string and not as hexadecimal text. That profile leaves open how a verifier tells such a payload from a full one, and names a COSE header parameter that declares the digest algorithm as one candidate. Header parameters 258 and 259 of [RFC9995], used here, are such a declaration.

6. Criteria Sets in PRML

PRML [PRML] serializes an evaluation claim fixed before the run: a metric, a comparator, a threshold, a dataset content hash and a seed, in canonical YAML whose SHA-256 is the manifest hash. A receipt records one result after the run. A receipt names a criteria set at most through its optional criteria_digest ([RECEIPTS] Section 3.5). When the criteria set is a PRML manifest, the bytes that PRML fixes for it are its canonical bytes, whose SHA-256 is the manifest hash, and criteria_digest over them is sha256: followed by the manifest hash. Table 4 maps the members of a PRML manifest, version 0.1, onto a receipt.

Table 4: A PRML manifest and a receipt
PRML Receipt Lost or changed
version none which PRML rules apply
claim_id none the claim and its amendment chain; only one manifest is named, by criteria_digest
created_at none timestamp is when the Issuer states the evaluation ran, not when the criteria were written
metric metric nothing when the string is copied exactly
comparator comparator == has no counterpart; such a claim has no receipt
threshold threshold a number becomes a decimal string; the rule below compares values
dataset.id, dataset.hash dataset_id_commit the content hash; the receipt commits to an identifier with a salt, not to the content
seed none the seed
producer none the producer; the receipt names no issuer, the Receiver fixes the key
model model_id_commit the clear identifier; checking an opening requires the salt and identifier
prior_hash, metric_args, code, notes none all of them
none suite, suite_version, score, passed, n, timestamp a manifest has no result

A Receiver that holds a receipt and a PRML manifest compares them as follows and reports the two results separately.

  1. Run the procedure of [RECEIPTS] Section 5 under the Receiver's receipt key. Continue only if it returns PASS. If it returns FAIL, do not perform the comparison. If it stops with a resource-limit error, propagate that error and stop without reporting binding or agreement results.

  2. The manifest is canonicalized as [PRML] Section 3 requires, and its manifest hash is computed. A manifest that PRML rejects is not compared.

  3. Binding. The result is BOUND when the receipt carries criteria_digest and it equals sha256: followed by the manifest hash, and UNBOUND otherwise.

  4. Agreement. The result is AGREE when metric is the same string in both, comparator is the same and is not ==, and the receipt's threshold and the manifest's threshold are the same decimal number, the manifest's value read as the decimal that its canonical rendering denotes (so 0.8 in the manifest and 0.800 in the receipt agree, and 0.80000000000000001 in the receipt does not). Otherwise it is DIFFER.

BOUND says that the Issuer states this result belongs to that manifest; AGREE says that the two documents state the same metric, comparator and threshold. Neither result shows that the manifest existed before the run, which needs a time-anchored record of the manifest, such as a registration under [PRML-PROFILE], and evidence of when the run began. Neither shows that the dataset with the manifest's content hash was the one evaluated, or that the seed was used.

7. Relation to Claim-Preservation Requirements

[ABAK] states format-neutral requirements for converting and consuming evaluation evidence. This document addresses parts of these requirements for the conversions it describes; the correspondences below are not a conformance claim. Table 2 and Table 4 name what each envelope or document loses, in the sense of its requirement R-CP-9. Section 3.3 gives INDETERMINATE when B cannot be obtained or the algorithm is unknown, never a match (R-CP-8, R-CP-10). Section 8 keeps the result of a verifier or of a registration apart from the receipt's passed, and claims no order of criteria and run (R-CP-5, R-CP-11). It does not meet the requirements on coverage and attempts (R-CP-6) or on records of a mapping instance (R-CP-1): a receipt has no field for them, and this document defines none.

8. What Is Not Proven

The list of [RECEIPTS] Section 6 applies unchanged to a cited receipt. It is repeated here word for word; its one cross-reference is written as a reference to Section 5 of [RECEIPTS].

Verification establishes that the receipt passes the format, consistency and signature checks in Section 5 of [RECEIPTS] under the Receiver's selected key. It does not establish that the Issuer's claims are true. In particular:

Each envelope adds what it does not prove:

No envelope in this document carries sample data: a receipt commits to no sample result ([RECEIPTS] Section 6), and a citation names only B.

9. Security Considerations

This section follows the guidance of [RFC3552]. The attacker can read, create, modify, replay and reorder receipts and citing envelopes, and controls every input except the Receiver's choice of verification key.

Collisions. A citation names B only as well as SHA-256 resists collisions and second preimages.

Signer not bound. The receipt digest does not name a key. An attacker who signs the same B with its own key produces a receipt that matches every citation of B. It fails verification under the Receiver's key (Section 3.2).

Signature reuse across envelopes. By design the signature of a receipt is a valid DSSE signature under payloadType equal to the type (Section 4.1). A DSSE consumer that accepts that payloadType holds the B and the signature of a receipt, and applies [RECEIPTS] Section 5 before it relies on them. Under any other payloadType the signature is expected to be invalid (Section 4.1). It is not a COSE signature, because COSE signs a Sig_structure and not PAE.

Digest confusion. For one receipt, the receipt digest, the SHA-256 of the receipt bytes and the SHA-256 of a DSSE envelope are three different values. A Receiver compares only the receipt digest with a citation. Appendix A lists the first two for vector P1 and the third for M1. The type identifies B, but a receipt object carries the same string as its schema: a Receiver that fetches a receipt object for a citation takes B from it by steps 1 to 3 of [RECEIPTS] Section 5 and compares the digest of that B, never the digest of the object.

Algorithm. Only SHA-256 is defined. A citation with another algorithm gives INDETERMINATE (case C8), so it cannot be satisfied by a weaker digest.

Reference parsing. For the JSON representation in Section 5.1, duplicate detection precedes any conversion that could discard member names. Selecting a first or last occurrence can change the reference state or matching result. A MATCH is not a substitute for Verified: a Malformed, Unresolved or Failed reference is not relied on as evidence of a content binding ([CPB] Section 8.1).

Receipts not read. Step 2 of Section 5.2.2 removes the receipts of a Transparent Statement without reading them; vector T1 carries a receipt made for another statement and is accepted. An accepted status therefore says nothing about registration. A Receiver that relies on registration verifies each receipt under [RFC9942] with a Transparency Service key that it fixed itself. It fixes the key, not the issuer name in the receipt: two instances of a Transparency Service can carry the same issuer name and differ only in their keys (Section 12).

Digest not checked by registration alone. The Signed Statement carries a digest, not B. Registration under a Transparency Service's policy does not by itself establish that the payload equals SHA-256 over B; Section 12 records the registration of a statement whose payload was not that digest. The Receiver recomputes the receipt digest in step 6 of Section 5.2.2.

Configured trust. A Receiver trusts a statement key or a trust anchor because it configured it. In the certificate profile, the procedure checks the leaf under the configured anchor but evaluates no validity period or revocation status. A compromised leaf key can therefore continue to pass this procedure while the configured pair remains. Additional path validation or other acceptance policy can refuse its use separately. Removing a configured pair makes statements that would pass step 2 and whose only matching pair was removed fail at step 3 with untrusted_key.

10. Privacy Considerations

The receipt digest lets anyone who holds a candidate B confirm it. B carries salted commitments, so B cannot be guessed without them; a party that knows them can test guesses for the remaining members, such as score and threshold. A citation registered with a Transparency Service publishes the digest for as long as that service keeps its log. The sub of M2 repeats the model commitment of B in clear; registered, it links every receipt and statement that commit to the same model identifier with the same salt ([RECEIPTS] Section 9). The same holds for a criteria_digest that a receipt carries.

11. IANA Considerations

This document has no IANA actions.

12. Implementation Status

This section records the status of known implementations at the time of writing, following [RFC7942], and is to be removed before publication.

The examples of Appendix A were produced by a generator script whose two runs are byte-identical, and checked by a separate script that re-derives every value of Appendix A from the bytes: the match result of every case, with its own implementation of steps 1 to 3 of [RECEIPTS] Section 5; the status of M2, of every status vector and of every certificate-profile vector, with its own implementation of the steps of Section 5.2.2 in both profiles; and the state and the matching result of each of R1 to R14, with its own implementation of the form rules of Section 5.1.

An implementation of both directions of the key profile of Section 5.2, the open-source package proofbundle (module receipt_cose, experimental), reproduces M2 byte for byte from vector P1 of [RECEIPTS] and returns each status of Section 5.2.2 for a set of 49 statements and 6 receipts. M2 and the status vectors of Appendix A.6 are, byte for byte, statements of that set, made independently by the generator of Appendix A. It writes -19 only and reads -8 only under an Ed25519 statement key. Measured on 2026-10-08 with these pinned versions: pycose 1.1.0 (with cbor2 5.9.0) and go-cose v1.3.0 verified the statement with alg -8, refused the same statement with one signature bit changed, and reported alg -19 (vector M2) as an unknown algorithm; microsoft/scitt-verifier 0.4.0 evaluated the signature of neither statement (its result for both was cannot-evaluate, with the statement signature not evaluated). The certificate profile and the typed digest references of Section 5.1 are implemented only by the scripts of Appendix A.

Registration with a Transparency Service was measured on 2026-10-10 with a local instance of microsoft/scitt-ccf-ledger at commit 00101f76 (CCF 7.0.17, virtual mode); no hosted service took part. No statement in the exact form of the key profile was registered: the service refused its https issuer ("CWT_Claims issuer is unsupported") with alg -19 and with alg -8, and, under a did:x509 issuer with x5chain, refused alg -19 ("COSE algorithm -19 is not supported") and an Ed25519 key with alg -8 ("Unsupported key type"). A statement in the form of the certificate profile, with an RSA-3072 test root, a P-256 test leaf and alg -7, was registered, and microsoft/scitt-verifier 0.4.0 verified the Transparent Statement it returned offline, with the network unavailable, under a policy that fixed the receipt issuer, the statement issuer and the statement subject and compared the payload with SHA-256 over B. On 2026-10-12 the same service, built again at commit 00101f76 and configured for the test root, registered X1 again and refused X2, which is X1 with alg -9 signed again under the test leaf, with "COSE algorithm -9 is not supported", also when ESP256 was named among its accepted algorithms; its source at that commit and at commit d68579b5, the head of its main branch inspected that day, maps no -9. pycose 1.1.0 and go-cose v1.3.0 refused -9 as an unknown algorithm before verifying, and the source of microsoft/scitt-verifier at commit bd6fb8ba (package version 0.4.0) maps no -9 for the statement signature. The steps of Section 5.2.2, applied on 2026-10-11 to the registered statement under the certificate pair of its test root, give accepted, and so they do for the Transparent Statement that the service returned for it.

In the earlier registration and offline-verification measurement, the service registered a statement whose payload was not SHA-256 over the B it named, and two local instances of the service carried the same receipt issuer name (127.0.0.1:8000) and differed only in their service keys. microsoft/scitt-verifier 0.4.0 reported a receipt taken from another entry, a receipt with one byte changed and a receipt of the other instance as cannot-evaluate (exit status 3), not as untrusted (exit status 1); this document maps no verdict of another tool to a status of Section 5.2.2. scitt-verifier 0.4.0 did not anchor a chain whose leaf certificate was signed with ECDSA (exit status 3) and verified the chain with an RSA root. Vector T2 is the Transparent Statement that a local instance of the same service returned on 2026-10-11 for X1: X1 with one receipt under label 394, byte for byte.

The signature of M2 (alg -19) is checked from the text alone, without a COSE library: a script written from the texts of this document and of [RECEIPTS] builds the Sig_structure by hand and verifies the signature over it with a general Ed25519 implementation (its checks M2-17 and M2-18).

13. References

13.1. Normative References

[CPB]
Mih, S. and A. Sokolov, "Canonicalization Declaration for SCITT Signed Statements", Work in Progress, Internet-Draft, draft-mih-sokolov-scitt-payload-binding-05, , <https://datatracker.ietf.org/doc/draft-mih-sokolov-scitt-payload-binding/05/>.
[DIDX509]
Riechert, M. and A. Delignat-Lavaud, "did:x509 Method Specification, method version 0 (status: draft)", , <https://github.com/microsoft/did-x509/blob/054f1f6e364580c42fad862747903f2a6ee19976/specification.md>.
[DSSE]
Secure Systems Lab, "DSSE: Dead Simple Signing Envelope, protocol specification, version 1.0.2", , <https://github.com/secure-systems-lab/dsse/blob/v1.0.2/protocol.md>.
[INTOTO-DIGESTSET]
in-toto project, "in-toto Attestation Framework: DigestSet field type, v1 (release v1.2.0)", , <https://github.com/in-toto/attestation/blob/v1.2.0/spec/v1/digest_set.md>.
[INTOTO-RD]
in-toto project, "in-toto Attestation Framework: ResourceDescriptor field type, v1 (release v1.2.0)", , <https://github.com/in-toto/attestation/blob/v1.2.0/spec/v1/resource_descriptor.md>.
[INTOTO-STATEMENT]
in-toto project, "in-toto Attestation Framework: Statement layer, v1 (release v1.2.0)", , <https://github.com/in-toto/attestation/blob/v1.2.0/spec/v1/statement.md>.
[PRML]
Öztürk, C., Ed., "PRML: Pre-Registered ML Manifest Specification, Version 0.1", , <https://spec.falsify.dev/v0.1>.
[RECEIPTS]
Gruszka, K., "Signed Evaluation Receipts", Work in Progress, Internet-Draft, draft-gruszka-signed-evaluation-receipts-01, , <https://datatracker.ietf.org/doc/draft-gruszka-signed-evaluation-receipts/>.
[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, , <https://www.rfc-editor.org/info/rfc2119>.
[RFC3986]
Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, , <https://www.rfc-editor.org/info/rfc3986>.
[RFC5280]
Cooper, D., Santesson, S., Farrell, S., Boeyen, S., Housley, R., and W. Polk, "Internet X.509 Public Key Infrastructure Certificate and Certificate Revocation List (CRL) Profile", RFC 5280, , <https://www.rfc-editor.org/info/rfc5280>.
[RFC8017]
Moriarty, K., Ed., Kaliski, B., Jonsson, J., and A. Rusch, "PKCS #1: RSA Cryptography Specifications Version 2.2", RFC 8017, , <https://www.rfc-editor.org/info/rfc8017>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, , <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259]
Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, , <https://www.rfc-editor.org/info/rfc8259>.
[RFC8949]
Bormann, C. and P. Hoffman, "Concise Binary Object Representation (CBOR)", STD 94, RFC 8949, , <https://www.rfc-editor.org/info/rfc8949>.
[RFC9052]
Schaad, J., "CBOR Object Signing and Encryption (COSE): Structures and Process", STD 96, RFC 9052, , <https://www.rfc-editor.org/info/rfc9052>.
[RFC9053]
Schaad, J., "CBOR Object Signing and Encryption (COSE): Initial Algorithms", RFC 9053, , <https://www.rfc-editor.org/info/rfc9053>.
[RFC9360]
Schaad, J., "CBOR Object Signing and Encryption (COSE): Header Parameters for Carrying and Referencing X.509 Certificates", RFC 9360, , <https://www.rfc-editor.org/info/rfc9360>.
[RFC9597]
Prorock, M., Steele, O., Mahy, R., and H. Birkholz, "CBOR Web Token (CWT) Claims in COSE Headers", RFC 9597, , <https://www.rfc-editor.org/info/rfc9597>.
[RFC9679]
Isobe, K., Tschofenig, H., and O. Steele, "CBOR Object Signing and Encryption (COSE) Key Thumbprint", RFC 9679, , <https://www.rfc-editor.org/info/rfc9679>.
[RFC9864]
Jones, M. B. and O. Steele, "Fully-Specified Algorithms for JSON Object Signing and Encryption (JOSE) and CBOR Object Signing and Encryption (COSE)", RFC 9864, , <https://www.rfc-editor.org/info/rfc9864>.
[RFC9995]
Steele, O., Lasker, S., and H. Birkholz, "CBOR Object Signing and Encryption (COSE) Hash Envelope", RFC 9995, , <https://www.rfc-editor.org/info/rfc9995>.
[VSA]
OpenSSF SLSA project, "SLSA Verification Summary Attestation (VSA), version 1", n.d., <https://slsa.dev/spec/v1.2/verification_summary>.

13.2. Informative References

[ABAK]
Abak, A. T., "Claim-Preserving Exchange of AI Evaluation Evidence", Work in Progress, Internet-Draft, draft-abak-ai-evaluation-claim-preservation-00, , <https://datatracker.ietf.org/doc/draft-abak-ai-evaluation-claim-preservation/00/>.
[CAPSULE]
Mih, S., "An Agent Action Capsule Profile for SCITT", Work in Progress, Internet-Draft, draft-mih-scitt-agent-action-capsule-05, , <https://datatracker.ietf.org/doc/draft-mih-scitt-agent-action-capsule/05/>.
[INTOTO-ENVELOPE]
in-toto project, "in-toto Attestation Framework: Envelope layer, v1 (release v1.2.0)", , <https://github.com/in-toto/attestation/blob/v1.2.0/spec/v1/envelope.md>.
[PRML-PROFILE]
Öztürk, C., "A SCITT Profile for Pre-Run Evaluation Criteria (PRML)", Work in Progress, Internet-Draft, draft-ozturk-scitt-prml-profile-00, , <https://datatracker.ietf.org/doc/draft-ozturk-scitt-prml-profile/00/>.
[RFC3552]
Rescorla, E. and B. Korver, "Guidelines for Writing RFC Text on Security Considerations", BCP 72, RFC 3552, , <https://www.rfc-editor.org/info/rfc3552>.
[RFC6979]
Pornin, T., "Deterministic Usage of the Digital Signature Algorithm (DSA) and Elliptic Curve Digital Signature Algorithm (ECDSA)", RFC 6979, , <https://www.rfc-editor.org/info/rfc6979>.
[RFC7942]
Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, , <https://www.rfc-editor.org/info/rfc7942>.
[RFC9942]
Steele, O., Birkholz, H., Delignat-Lavaud, A., and C. Fournet, "CBOR Object Signing and Encryption (COSE) Receipts", RFC 9942, , <https://www.rfc-editor.org/info/rfc9942>.
[RFC9943]
Birkholz, H., Delignat-Lavaud, A., Fournet, C., Deshpande, Y., and S. Lasker, "An Architecture for Trustworthy and Transparent Digital Supply Chains", RFC 9943, , <https://www.rfc-editor.org/info/rfc9943>.
[STATEMENT-ID]
Gruszka, K., "Requirements and Test Cases for Identifying SCITT Signed Statements", Work in Progress, Internet-Draft, draft-gruszka-scitt-statement-identification-01, , <https://datatracker.ietf.org/doc/draft-gruszka-scitt-statement-identification/>.
[TEST-RESULT]
in-toto project, "in-toto Attestation Framework: Test Result predicate, v0.1 (release v1.2.0)", , <https://github.com/in-toto/attestation/blob/v1.2.0/spec/predicates/test-result.md>.

Appendix A. Examples

The values below are derived from vectors of [RECEIPTS] (P1, and the candidates named in Table 1 and Table 5) and from the issuer test key of that document, whose seed is given there; the issuer URI of the Signed Statement is a constant of this example. PURE TEST KEY. It MUST NOT be used for anything real.

A.1. Constants

Type:

application/vnd.signed-evidence.eval-receipt+json

Issuer test key, public key (base64 and hex):

x7ppA99DtumHO/Au0M/gumSK8IwCzNwPiID92BSFbak=
c7ba6903df43b6e9873bf02ed0cfe0ba648af08c02ccdc0f8880fdd814856da9

Issuer URI of the Signed Statement (iss):

https://issuer.example/eval

A.2. Digests of Vector P1

B, 458 bytes (hex):

7b22636f6d6d69745f616c67223a227368613235362d73616c7465642d763122
2c22636f6d70617261746f72223a223e3d222c22646174617365745f69645f63
6f6d6d6974223a227368613235363a6132316261346439366338303364343236
3364643364323136316263303339613330663434363262643539343730653331
626135613961623061396233623633222c226d6574726963223a226163637572
616379222c226d6f64656c5f69645f636f6d6d6974223a227368613235363a39
3034646534323536326639613139363531653139656237616231363565346666
6531313463653561326639386535376461353833383935393638346662306622
2c226e223a313830302c22706173736564223a747275652c22736368656d6122
3a2268747470733a2f2f7369676e65642d65766964656e63652e6f72672f6576
616c2d726563656970742f7631222c2273636f7265223a22302e383334222c22
7375697465223a2261636d652d7361666574792d7375697465222c2273756974
655f76657273696f6e223a22312e322e30222c227468726573686f6c64223a22
302e383030222c2274696d657374616d70223a22323032362d31302d30325430
303a30303a30305a227d

Receipt digest, SHA-256 over B:

8cd849a6dcce08aee334511d7b2f31c54e478885dda1795d3c8f972dd0d4811c

SHA-256 over the receipt bytes of P1; not the receipt digest:

02036d1f57509858330383755ec16c532bdc58b0f2d949464488d57abc9f95e7

A.3. Citation Cases

Every case cites B of P1. Cases C1 to C7 cite, with the algorithm sha-256, the receipt digest given in Appendix A.2. C8 cites, with the algorithm sha-512, this value over the same B:

d5cccf69bb4f9b2c6d102e1a4da3d057cf8fc00bbbae69c0889bb423d243e246
1685c907c22f86f34c15290063ee3cd0c5815a85e25e40ef1609fcd4e11c2dc8

The candidates are the vectors of [RECEIPTS] named in Table 1, whose bytes are given there. Case and SHA-256 over the candidate's receipt bytes:

C1 02036d1f57509858330383755ec16c532bdc58b0f2d949464488d57abc9f95e7
C2 c2a7943f0ea3de6e9da88c11925b1e112d32f697a403f07fcfbc3776bca10e72
C3 2c8144d50b4cc42a712d84e4d0417e52b0d8cbc484ad8e6d8d4b36a429b94ec1
C4 2405d1783d1803ddea207c027622fba40b3e82161686505ee96988e306e17278
C5 18b1b6dc631cf0f00d8b0d2c237b28a67b12c2d7088ae0313a2fb27760f96bdd
C6 31a34194edd90bade6568a3cb00dbb983dabab9efccfd7a8b38650bd3e8d5201
C7 8966f27c5f2566d986b0ab7821060ea0c901504fe984d450dfc7f8ca7d1c27e1
C8 02036d1f57509858330383755ec16c532bdc58b0f2d949464488d57abc9f95e7

The expected results are those of Table 1; the reasons are:

  • C1: SHA-256 over the candidate's B equals the cited digest.

  • C2: SHA-256 over the candidate's B equals the cited digest.

  • C3: SHA-256 over the candidate's B equals the cited digest.

  • C4: SHA-256 over the candidate's B differs from the cited digest.

  • C5: SHA-256 over the candidate's B equals the cited digest.

  • C6: B not obtained, step 3 of [RECEIPTS] Section 5 fails.

  • C7: B not obtained, step 1 of [RECEIPTS] Section 5 fails.

  • C8: Citation algorithm not defined.

A.4. M1, DSSE Envelope with the Receipt's Signature

The envelope is a JSON object with the members payloadType, payload and signatures, serialized without insignificant whitespace and with members sorted by name. Its only signature is signature.sig of P1, unchanged; it verifies as Ed25519 over PAE(payloadType, payload) under the issuer test key.

PAE(type, B), 522 bytes (hex):

445353457631203439206170706c69636174696f6e2f766e642e7369676e6564
2d65766964656e63652e6576616c2d726563656970742b6a736f6e2034353820
7b22636f6d6d69745f616c67223a227368613235362d73616c7465642d763122
2c22636f6d70617261746f72223a223e3d222c22646174617365745f69645f63
6f6d6d6974223a227368613235363a6132316261346439366338303364343236
3364643364323136316263303339613330663434363262643539343730653331
626135613961623061396233623633222c226d6574726963223a226163637572
616379222c226d6f64656c5f69645f636f6d6d6974223a227368613235363a39
3034646534323536326639613139363531653139656237616231363565346666
6531313463653561326639386535376461353833383935393638346662306622
2c226e223a313830302c22706173736564223a747275652c22736368656d6122
3a2268747470733a2f2f7369676e65642d65766964656e63652e6f72672f6576
616c2d726563656970742f7631222c2273636f7265223a22302e383334222c22
7375697465223a2261636d652d7361666574792d7375697465222c2273756974
655f76657273696f6e223a22312e322e30222c227468726573686f6c64223a22
302e383030222c2274696d657374616d70223a22323032362d31302d30325430
303a30303a30305a227d

Envelope, 806 bytes (hex):

7b227061796c6f6164223a2265794a6a62323174615852665957786e496a6f69
633268684d6a55324c584e686248526c5a4331324d534973496d4e7662584268
636d4630623349694f69492b50534973496d52686447467a5a58526661575266
5932397462576c30496a6f69633268684d6a55324f6d45794d574a684e475135
4e6d4d344d444e6b4e4449324d32526b4d3251794d545978596d4d774d7a6c68
4d7a426d4e4451324d6d4a6b4e546b304e7a426c4d7a4669595456684f574669
4d474535596a4e694e6a4d694c434a745a58527961574d694f694a6859324e31
636d466a65534973496d31765a47567358326c6b58324e766257317064434936
496e4e6f595449314e6a6f354d44526b5a5451794e5459795a6a6c684d546b32
4e54466c4d546c6c596a6468596a45324e5755305a6d5a6c4d54453059325531
59544a6d4f54686c4e54646b595455344d7a67354e546b324f44526d596a426d
49697769626949364d5467774d4377696347467a6332566b496a7030636e566c
4c434a7a5932686c625745694f694a6f64485277637a6f764c334e705a32356c
5a43316c646d6c6b5a57356a5a533576636d63765a585a68624331795a574e6c
615842304c3359784969776963324e76636d55694f6949774c6a677a4e434973
496e4e316158526c496a6f6959574e745a53317a59575a6c64486b7463335670
644755694c434a7a64576c305a5639325a584a7a61573975496a6f694d533479
4c6a41694c434a3061484a6c63326876624751694f6949774c6a67774d434973
496e52706257567a6447467463434936496a49774d6a59744d5441744d444a55
4d4441364d4441364d444261496e303d222c227061796c6f616454797065223a
226170706c69636174696f6e2f766e642e7369676e65642d65766964656e6365
2e6576616c2d726563656970742b6a736f6e222c227369676e61747572657322
3a5b7b22736967223a22434247744e323639464f68505372357865307a6c4a47
53424e427a47696e457a38693031664d36312b4a4e614a50646e5a793148626f
596934656d686d384b5a715055337973546d726d434578537653786f637a4241
3d3d227d5d7d

SHA-256 over the envelope bytes; not the receipt digest:

d96e0b9635949045a6f7c7b29eac8c163f6fad0d6d0bff446beeff601e45fed0

A.5. M2, SCITT Signed Statement Citing the Receipt by Digest

A COSE_Sign1 with CBOR tag 18 in the form of a COSE Hash Envelope. The protected header holds these parameters, in this order:

  • 1 (alg): -19

  • 4 (kid): a 32-byte string, given below

  • 15 (CWT Claims): a map with 1 (iss), the URI of Appendix A.1, and 2 (sub), the text string given below

  • 258 (payload hash algorithm): -16

  • 259 (preimage content type): the type, as a text string

kid, the COSE Key Thumbprint (SHA-256) of the issuer test key (hex):

c94d618c32417cedb44280d4d66029e6486aa834802d12cd919c817453eb1561

sub, the model commitment of B:

sha256:904de42562f9a19651e19eb7ab165e4ffe114ce5a2f98e57da5838959684fb0f

Protected header, 202 bytes (hex):

a50132045820c94d618c32417cedb44280d4d66029e6486aa834802d12cd919c
817453eb15610fa201781b68747470733a2f2f6973737565722e6578616d706c
652f6576616c0278477368613235363a39303464653432353632663961313936
3531653139656237616231363565346666653131346365356132663938653537
646135383338393539363834666230661901022f19010378316170706c696361
74696f6e2f766e642e7369676e65642d65766964656e63652e6576616c2d7265
63656970742b6a736f6e

The unprotected header is the empty map. The payload is the receipt digest given in Appendix A.2.

Sig_structure (ToBeSigned), 251 bytes (hex), with external_aad the empty byte string:

846a5369676e61747572653158caa50132045820c94d618c32417cedb44280d4
d66029e6486aa834802d12cd919c817453eb15610fa201781b68747470733a2f
2f6973737565722e6578616d706c652f6576616c0278477368613235363a3930
3464653432353632663961313936353165313965623761623136356534666665
3131346365356132663938653537646135383338393539363834666230661901
022f19010378316170706c69636174696f6e2f766e642e7369676e65642d6576
6964656e63652e6576616c2d726563656970742b6a736f6e4058208cd849a6dc
ce08aee334511d7b2f31c54e478885dda1795d3c8f972dd0d4811c

Signature, Ed25519 over the Sig_structure (hex):

f8be22ab6b1c196611d884ea635f610ac45c042ab7958828c2af46dd5e35ac8d
66b0c01fc115f7d93597f3cf783e95df37ef78da9006b773e08e6239af01a10e

COSE_Sign1, 307 bytes (hex):

d28458caa50132045820c94d618c32417cedb44280d4d66029e6486aa834802d
12cd919c817453eb15610fa201781b68747470733a2f2f6973737565722e6578
616d706c652f6576616c0278477368613235363a393034646534323536326639
6131393635316531396562376162313635653466666531313463653561326639
38653537646135383338393539363834666230661901022f1901037831617070
6c69636174696f6e2f766e642e7369676e65642d65766964656e63652e657661
6c2d726563656970742b6a736f6ea058208cd849a6dcce08aee334511d7b2f31
c54e478885dda1795d3c8f972dd0d4811c5840f8be22ab6b1c196611d884ea63
5f610ac45c042ab7958828c2af46dd5e35ac8d66b0c01fc115f7d93597f3cf78
3e95df37ef78da9006b773e08e6239af01a10e

SHA-256 over the COSE_Sign1 bytes:

64e78be4636b8d1e90cb7a1ebe06c4cfba2848603d6f64958d7c2080a901c575

A.6. Status Vectors

Each vector is a Signed Statement presented with a candidate receipt of [RECEIPTS], whose bytes are given there. The Receiver's receipt key is the issuer test key, and its one configured pair is the issuer URI of Appendix A.1 with the issuer test key. With M2, the vectors give one statement for each status of Section 5.2.2; S1 is the statement with alg -8 that every Receiver accepts (Section 5.2.4).

Table 5: Status vectors
Vector Candidate Status First failing step
M2 P1 accepted (none)
S1 P1 accepted (none)
S2 P1 malformed 1
S3 P1 outside_profile 2
S4 P1 untrusted_key 3
S5 P1 signature_invalid 4
S6 N7 receipt_not_verified 5
S7 P1 digest_mismatch 6
S8 P1 subject_mismatch 7

What each vector shows:

  • M2: the statement of Appendix A.5, with the receipt it was made from.

  • S1: M2 with alg -8 in place of -19, signed again under the issuer test key.

  • S2: the bytes of M2 with CBOR tag 98 (COSE_Sign) in place of tag 18.

  • S3: alg -7 (ES256), signed again under the issuer test key.

  • S4: kid names the foreign test key, which signs it; no configured pair has that key.

  • S5: kid names the issuer test key, the foreign test key signs it.

  • S6: M2, presented with N7, which fails step 11 of [RECEIPTS] Section 5.

  • S7: a statement on B of P2, with sub its model commitment, presented with P1.

  • S8: M2 with sub the dataset commitment of P1, signed again.

S4 and S5 are signed by a foreign test key whose seed is SHA-256 over the UTF-8 bytes of "receipt-cose foreign statement key, PURE TEST KEY"; it MUST NOT be used for anything real. Its public key (base64 and hex):

HTQB8sspu7jJw2lUq+w3qeb0xTjFNdCrzlq31dxTOmQ=
1d3401f2cb29bbb8c9c36954abec37a9e6f4c538c535d0abce5ab7d5dc533a64

S1, 307 bytes (hex):

d28458caa50127045820c94d618c32417cedb44280d4d66029e6486aa834802d
12cd919c817453eb15610fa201781b68747470733a2f2f6973737565722e6578
616d706c652f6576616c0278477368613235363a393034646534323536326639
6131393635316531396562376162313635653466666531313463653561326639
38653537646135383338393539363834666230661901022f1901037831617070
6c69636174696f6e2f766e642e7369676e65642d65766964656e63652e657661
6c2d726563656970742b6a736f6ea058208cd849a6dcce08aee334511d7b2f31
c54e478885dda1795d3c8f972dd0d4811c5840a4a112c376243af157d0335bab
e0d43aa1d6b6e50137a4c95d8b93a345786565546f009bd739bc3dcadf69f78e
f1f7870eba885d123dd480b528acb2f83c960c

S2, 308 bytes (hex):

d8628458caa50132045820c94d618c32417cedb44280d4d66029e6486aa83480
2d12cd919c817453eb15610fa201781b68747470733a2f2f6973737565722e65
78616d706c652f6576616c0278477368613235363a3930346465343235363266
3961313936353165313965623761623136356534666665313134636535613266
3938653537646135383338393539363834666230661901022f19010378316170
706c69636174696f6e2f766e642e7369676e65642d65766964656e63652e6576
616c2d726563656970742b6a736f6ea058208cd849a6dcce08aee334511d7b2f
31c54e478885dda1795d3c8f972dd0d4811c5840f8be22ab6b1c196611d884ea
635f610ac45c042ab7958828c2af46dd5e35ac8d66b0c01fc115f7d93597f3cf
783e95df37ef78da9006b773e08e6239af01a10e

S3, 307 bytes (hex):

d28458caa50126045820c94d618c32417cedb44280d4d66029e6486aa834802d
12cd919c817453eb15610fa201781b68747470733a2f2f6973737565722e6578
616d706c652f6576616c0278477368613235363a393034646534323536326639
6131393635316531396562376162313635653466666531313463653561326639
38653537646135383338393539363834666230661901022f1901037831617070
6c69636174696f6e2f766e642e7369676e65642d65766964656e63652e657661
6c2d726563656970742b6a736f6ea058208cd849a6dcce08aee334511d7b2f31
c54e478885dda1795d3c8f972dd0d4811c584076d76d742ee817df32f456dae6
ddf646442962a4e8993a00041bb4fb5bed959533bb7bc10ffd4bf2a2fa636556
5e0015e99b0f46809db250778f203921482201

S4, 307 bytes (hex):

d28458caa5013204582010383074b31812819c7a08986cc725bef0846cb90022
06958002b5f712b52ae20fa201781b68747470733a2f2f6973737565722e6578
616d706c652f6576616c0278477368613235363a393034646534323536326639
6131393635316531396562376162313635653466666531313463653561326639
38653537646135383338393539363834666230661901022f1901037831617070
6c69636174696f6e2f766e642e7369676e65642d65766964656e63652e657661
6c2d726563656970742b6a736f6ea058208cd849a6dcce08aee334511d7b2f31
c54e478885dda1795d3c8f972dd0d4811c5840bb9487d62831a52898b56a1af5
b9b49ecb2dd11a9ec2c6a07cf9eda6d2abaad6dd6a1ba531e375982cf64888b9
76097f7b47791bb85d89cc58da26e8aad5b10c

S5, 307 bytes (hex):

d28458caa50132045820c94d618c32417cedb44280d4d66029e6486aa834802d
12cd919c817453eb15610fa201781b68747470733a2f2f6973737565722e6578
616d706c652f6576616c0278477368613235363a393034646534323536326639
6131393635316531396562376162313635653466666531313463653561326639
38653537646135383338393539363834666230661901022f1901037831617070
6c69636174696f6e2f766e642e7369676e65642d65766964656e63652e657661
6c2d726563656970742b6a736f6ea058208cd849a6dcce08aee334511d7b2f31
c54e478885dda1795d3c8f972dd0d4811c584044f1e3209854c7a90ceeb357d5
63ff5b1f8c7001c5fad80f3aa62b224405fb32c8c3cdb8bd8f81448806227580
fbc1db9cb4d992a3882de7a000e26222d4fb06

S6, 307 bytes (hex):

d28458caa50132045820c94d618c32417cedb44280d4d66029e6486aa834802d
12cd919c817453eb15610fa201781b68747470733a2f2f6973737565722e6578
616d706c652f6576616c0278477368613235363a393034646534323536326639
6131393635316531396562376162313635653466666531313463653561326639
38653537646135383338393539363834666230661901022f1901037831617070
6c69636174696f6e2f766e642e7369676e65642d65766964656e63652e657661
6c2d726563656970742b6a736f6ea058208cd849a6dcce08aee334511d7b2f31
c54e478885dda1795d3c8f972dd0d4811c5840f8be22ab6b1c196611d884ea63
5f610ac45c042ab7958828c2af46dd5e35ac8d66b0c01fc115f7d93597f3cf78
3e95df37ef78da9006b773e08e6239af01a10e

S7, 307 bytes (hex):

d28458caa50132045820c94d618c32417cedb44280d4d66029e6486aa834802d
12cd919c817453eb15610fa201781b68747470733a2f2f6973737565722e6578
616d706c652f6576616c0278477368613235363a393034646534323536326639
6131393635316531396562376162313635653466666531313463653561326639
38653537646135383338393539363834666230661901022f1901037831617070
6c69636174696f6e2f766e642e7369676e65642d65766964656e63652e657661
6c2d726563656970742b6a736f6ea0582007182e9bff69baa8ab9a5646d69b51
18ccf3780b903b9a9d5b4bd0d9c9d70b875840e98ea4b9da8e6568c9905f308c
fdf4c609f941fe311c3484cae0813502201137a0fdd92fc83f542718508ccf61
22d80e73c42ec4dd61b366e9860a8bb472d700

S8, 307 bytes (hex):

d28458caa50132045820c94d618c32417cedb44280d4d66029e6486aa834802d
12cd919c817453eb15610fa201781b68747470733a2f2f6973737565722e6578
616d706c652f6576616c0278477368613235363a613231626134643936633830
3364343236336464336432313631626330333961333066343436326264353934
37306533316261356139616230613962336236331901022f1901037831617070
6c69636174696f6e2f766e642e7369676e65642d65766964656e63652e657661
6c2d726563656970742b6a736f6ea058208cd849a6dcce08aee334511d7b2f31
c54e478885dda1795d3c8f972dd0d4811c58401a820d86d8615d7b60d5e7d7f9
791a7ae27b49fbce1d554bb7444407b0a9926bec5ea93f45d342f86291b14c79
ee84d3d50e1bf915c21621b852afe91a613201

Vector and SHA-256 over its bytes:

S1 4ffcd0d2a970d9dfa17cc9ffed00d7ff84b368177390bb170ee270bc1a336bda
S2 652517f5fe70201d687a073ad81a5057079aa0f4575a6055950c50b472b6a90e
S3 75acb36c52ff43f1ee137aa816967f75142535213a08fb3b95d306cba38b227d
S4 eb53f003ae71f82b0e7156922fc60f7c227daf12748d82f1fbe04990c82829e2
S5 13ec9aa3bc725b13de9a6639ed7cc91e169797b50264bf9f3bd5033c8c52e333
S6 64e78be4636b8d1e90cb7a1ebe06c4cfba2848603d6f64958d7c2080a901c575
S7 8f275a639482390b6e187fd9e224e4c5af38b9985a321c7d148674e9ece0aae7
S8 7460b48972153c566ad6eaaad35a4d335f24d7f52512d58a519de215b016cc30

A.7. Typed Digest References

Each vector supplies an input to the typed digest reference processing of Section 5.1. R1 is a JSON object with exactly three members: type, the type; digest_alg, SHA-256; and digest, the receipt digest of Appendix A.2 as 64 lowercase hexadecimal digits. Each other vector is R1 with the change in Table 6; "names B of P2" means SHA-256 over B of vector P2 of [RECEIPTS], as 64 lowercase hexadecimal digits. The candidate is the vector of [RECEIPTS] named in the table. For State, assume a consuming profile that accepts the declaration in Section 5.1 by normative reference. State is the reference processing state in the terms of [CPB] Sections 3 and 8.1. Matching rule is the independent result of Section 3.3, including the JSON extraction rule in Section 5.1.

Table 6: Typed digest references
Vector Change to R1 Candidate State Matching rule
R1 (none) P1 Verified MATCH
R2 purpose evaluation added P1 Unresolved MATCH
R3 digest_alg sha-256 P1 Failed INDETERMINATE
R4 digest in uppercase P1 Failed INDETERMINATE
R5 digest names B of P2 P1 Failed NO_MATCH
R6 (none) N13 Unresolved INDETERMINATE
R7 member x added, value 1 P1 Malformed MATCH
R8 second digest member, names B of P2 P1 Malformed INDETERMINATE
R9 digest_alg removed P1 Malformed INDETERMINATE
R10 R1 as the only element of a JSON array P1 Malformed INDETERMINATE
R11 purpose added, value null P1 Malformed MATCH
R12 sole digest name written as "\u0064igest" P1 Verified MATCH
R13 second name "\u0064igest", same value P1 Malformed INDETERMINATE
R14 R1 preceded by the UTF-8 byte order mark P1 Malformed INDETERMINATE

What each vector shows:

  • R1: a reference under the declaration, with the receipt it names.

  • R2: R1 with a purpose member; the context has no purpose label.

  • R3: R1 with digest_alg sha-256, not the exact token SHA-256.

  • R4: R1 with the digest in uppercase hexadecimal digits.

  • R5: a reference that names B of P2, presented with P1.

  • R6: R1 presented with N13, from which B is not obtained.

  • R7: R1 with a member that the declaration does not name.

  • R8: R1 with a second digest member that names B of P2; neither value is chosen.

  • R9: R1 without digest_alg.

  • R10: R1 inside a JSON array, which is not a JSON object.

  • R11: R1 with purpose set to null, not a JSON string. Unlike R2, this is a form error before context selection.

  • R12: R1 with the sole digest member name written as "\u0064igest" in the JSON text; the decoded name is unchanged.

  • R13: R1 with an additional member named "\u0064igest" whose value equals the original digest. The decoded names are equal; equal values do not make a repeated name acceptable.

  • R14: R1 with the UTF-8 byte order mark EF BB BF before the JSON text; this representation does not ignore it.

The matching rule compares an unambiguously extracted algorithm and digest independently of the reference state. Thus R2 gives MATCH while Unresolved, and R7 and R11 give MATCH while Malformed. Neither result makes the reference Verified.

A.8. Certificate-Profile Vectors

Each vector is a Signed Statement in the form of the certificate profile, or one change away from it, presented with vector P1 of [RECEIPTS]. The Receiver's receipt key is the issuer test key, and its one configured certificate pair is the did:x509 identifier below with the test root certificate. The test root holds an RSA-3072 key and the test leaf a P-256 key; both certificates, and the other P-256 key that signs X6, are test material made by the generator of Appendix A, and they MUST NOT be used for anything real. The signatures use the deterministic nonce of [RFC6979].

iss of X1, the identifier of the configured pair, is did:x509:0:sha256: F ::eku: O with F, SHA-256 over the test root certificate in base64url without padding, and O, the object identifier of code signing:

F 27XKFJ4cMLsuFMzbCyW81i24r8Un94N9wwLkmA5QE20
O 1.3.6.1.5.5.7.3.3

Test leaf certificate, 819 bytes (hex):

3082032f30820197a003020102020102300d06092a864886f70d01010b050030
3f313d303b06035504030c346576616c2d72656365697074206d617070696e67
73207465737420726f6f742028505552452054455354204d4154455249414c29
301e170d3236303130313030303030305a170d3335313233313233353935395a
304b3149304706035504030c406576616c2d72656365697074206d617070696e
677320746573742073746174656d656e74207369676e65722028505552452054
455354204d4154455249414c293059301306072a8648ce3d020106082a8648ce
3d030107034200042b7ff297baafbcd54b9c2804c2025d5e84d51d24151ffe62
af08557f4cba8841c0b05fc73ddaf743e4a05f06c872da47c8af27d87a5a93c4
b85bc16a6f603735a3753073300c0603551d130101ff04023000300e0603551d
0f0101ff040403020780301d0603551d0e0416041492e1e87ec4a7fc7192a549
9386d6203c19ea2ab6301f0603551d230418301680144c0bb4bc8ca56a0d1643
ee21bb1e7c3dbf66305030130603551d25040c300a06082b0601050507030330
0d06092a864886f70d01010b050003820181002d0db050da36399de8a05cadf7
dbf3309a522c7c10dfdacd5f2538d689a147227dc1aaac7966f978f878c39420
c6ebb006b7dee8f359ad33fed0e3efd4d452448342a32b60b4a970c1f13370e0
f61e45545058aeaa911caf61c01f022770e11bd9f5c339e60b3a2a415b3a5827
dc35dda2515672ef6fdc2bcbe4301524a437636ec3f2da7ddecedd4b93842a27
f563842882b64c3baee82c73c1740cbeb90472e1a59c113a5e9fe72af4f8f5e5
cb8016e2a6db5c1f6ff0a47e1767ce8143955ba391ca97e18c24b4a86f0e6de0
1dfa74baab5f921fe751317ab3bc55892e5a76718a66f85c8b2a587b52f0b54c
8d54fb2122dcc9a52ca7dc81e1bc67304fe96df38f83b39e8ab3a07628a246f3
b19b74f7f7f30cbc4639db12e6807e3c3369952e8fc4ddd19cb048928ac2559b
3a10de43860b69dc2afdb1c2184940e8ceee3641e2e11251f47544b30534afd3
aa5a6bc7a1997042e442faf102d664a292dde70bfb266ed96ae87c0a63064947
fcefa92658e0f2684771c99688d1017a5a1838

Test root certificate, the trust anchor of the configured pair, 1120 bytes (hex):

3082045c308202c4a003020102020101300d06092a864886f70d01010b050030
3f313d303b06035504030c346576616c2d72656365697074206d617070696e67
73207465737420726f6f742028505552452054455354204d4154455249414c29
301e170d3236303130313030303030305a170d3335313233313233353935395a
303f313d303b06035504030c346576616c2d72656365697074206d617070696e
6773207465737420726f6f742028505552452054455354204d4154455249414c
29308201a2300d06092a864886f70d01010105000382018f003082018a028201
8100bf2c98f756260c3bdfa487f85009454ed25b4191589b4c6451cf683b69fc
b883f29f710166bf9f0c2a474c340d25fbd5b21514afbf2dfff6333e4f1ab5e1
58e38e5d8eddcd4d883337dc11aae54b0954b94e5b5e41964f4fc600fde25a8c
2406e24940fc5da14862d55fb86a7de2e7477d28d19c56cb4d404da14fd3a464
fe52015f93a504162b87807dc636a7dd2671c64e2eff4307609e12d68a5085f4
d80539bb9599b8aaf83e1abf37ed2671a08034e56c77faf8aa5743767b2dbe56
1e7adc2069164d62214e444799bdacbd6917d2219c83dff5b910ad6256e57302
16eb57fc0021a26e4581a06ded76f0f1c289b67577ba43db6a68c154a01e3512
558f618aac5c738f97b163164a6a76f3b07d48dd9b94fbcdc3a2edbd486cb385
3844e4c04653ae9c2b2060b7802cebb44a8cb918626c6ccb448d96f908579319
63196610d64a4cd2480a12410f3580ac7ceee44316b6930f585dfbe6abfdd0db
288552e03baee551a6c5b697e2537e32156ee66d644522d63640591f69d47cb0
d68d0203010001a3633061300f0603551d130101ff040530030101ff300e0603
551d0f0101ff040403020204301d0603551d0e041604144c0bb4bc8ca56a0d16
43ee21bb1e7c3dbf663050301f0603551d230418301680144c0bb4bc8ca56a0d
1643ee21bb1e7c3dbf663050300d06092a864886f70d01010b05000382018100
678c28e3f30305df549eac036a15ebfdad96843501900ac45dc5a3c632cd94b2
4e80df9ddc63998b354a1e51074cf763937306db4cb2961b2a0eb0f4e37e0301
bdc7dd06240e8ceaa1af908b1f83db81247f61c32166830c539ac6d488b0bced
7fa830c9e5c5d67f35c5f357007ce8cbfe004d210f54b1fd0cf84a240856759b
e99ea4e933f37a818c0dd355faef418350e40818274babc0e35debe3f04507c8
f84bdfd75ffa1f2aea2a440933c9d4d2c58a9b23655ff7783e21728d74c00343
69567e399133d06f5df1a44aa9c245a35d2db598265b9c01f3c9904ca2a43c2c
4ffe4e04459c8fa933be3ca466584673a0a7ad43305f428b82e8f201db81d625
235d4f5a520889a1b59df8e385f05ea617514cb82708361fd18eb942d6c9b1c0
ac1d1c3a00c58e3edf39403d56ee5affcad4faedcb0ebbeaa789b8140c0ea07d
165363808b7cb511eb080aefca268ddf446447dba0d6f472e6f04ec2c422b5b4
24721a7e8c1b792cda88aeef7ce3c6c851012c8c80c10635d7b26d53454b5d89

SHA-256 over the test leaf and over the test root certificate:

dafe68bab183c88b167482d58243e1eb99d490b2fac60515903103ec3286d034
dbb5ca149e1c30bb2e14ccdb0b25bcd62db8afc527f7837dc302e4980e50136d

kid of X1, SHA-256 over the SubjectPublicKeyInfo of the test leaf (hex):

a17f91f02052b42e799a7b1fc1061fe90f105bccac812a407c0e236005809fba

The protected header of X1 holds these parameters, in this order:

  • 1 (alg): -7

  • 4 (kid): the kid above

  • 15 (CWT Claims): a map with 1 (iss), the identifier above, and 2 (sub), the sub of Appendix A.5

  • 33 (x5chain): an array of the test leaf and the test root certificate

  • 258 (payload hash algorithm): -16

  • 259 (preimage content type): the type, as a text string

The unprotected header is the empty map, and the payload is the receipt digest of Appendix A.2.

X1, 2313 bytes (hex):

d28459089fa60126045820a17f91f02052b42e799a7b1fc1061fe90f105bccac
812a407c0e236005809fba0fa20178546469643a783530393a303a7368613235
363a3237584b464a34634d4c7375464d7a6243795738316932347238556e3934
4e3977774c6b6d4135514532303a3a656b753a312e332e362e312e352e352e37
2e332e330278477368613235363a393034646534323536326639613139363531
6531396562376162313635653466666531313463653561326639386535376461
35383338393539363834666230661821825903333082032f30820197a0030201
02020102300d06092a864886f70d01010b0500303f313d303b06035504030c34
6576616c2d72656365697074206d617070696e6773207465737420726f6f7420
28505552452054455354204d4154455249414c29301e170d3236303130313030
303030305a170d3335313233313233353935395a304b3149304706035504030c
406576616c2d72656365697074206d617070696e677320746573742073746174
656d656e74207369676e65722028505552452054455354204d4154455249414c
293059301306072a8648ce3d020106082a8648ce3d030107034200042b7ff297
baafbcd54b9c2804c2025d5e84d51d24151ffe62af08557f4cba8841c0b05fc7
3ddaf743e4a05f06c872da47c8af27d87a5a93c4b85bc16a6f603735a3753073
300c0603551d130101ff04023000300e0603551d0f0101ff040403020780301d
0603551d0e0416041492e1e87ec4a7fc7192a5499386d6203c19ea2ab6301f06
03551d230418301680144c0bb4bc8ca56a0d1643ee21bb1e7c3dbf6630503013
0603551d25040c300a06082b06010505070303300d06092a864886f70d01010b
050003820181002d0db050da36399de8a05cadf7dbf3309a522c7c10dfdacd5f
2538d689a147227dc1aaac7966f978f878c39420c6ebb006b7dee8f359ad33fe
d0e3efd4d452448342a32b60b4a970c1f13370e0f61e45545058aeaa911caf61
c01f022770e11bd9f5c339e60b3a2a415b3a5827dc35dda2515672ef6fdc2bcb
e4301524a437636ec3f2da7ddecedd4b93842a27f563842882b64c3baee82c73
c1740cbeb90472e1a59c113a5e9fe72af4f8f5e5cb8016e2a6db5c1f6ff0a47e
1767ce8143955ba391ca97e18c24b4a86f0e6de01dfa74baab5f921fe751317a
b3bc55892e5a76718a66f85c8b2a587b52f0b54c8d54fb2122dcc9a52ca7dc81
e1bc67304fe96df38f83b39e8ab3a07628a246f3b19b74f7f7f30cbc4639db12
e6807e3c3369952e8fc4ddd19cb048928ac2559b3a10de43860b69dc2afdb1c2
184940e8ceee3641e2e11251f47544b30534afd3aa5a6bc7a1997042e442faf1
02d664a292dde70bfb266ed96ae87c0a63064947fcefa92658e0f2684771c996
88d1017a5a18385904603082045c308202c4a003020102020101300d06092a86
4886f70d01010b0500303f313d303b06035504030c346576616c2d7265636569
7074206d617070696e6773207465737420726f6f742028505552452054455354
204d4154455249414c29301e170d3236303130313030303030305a170d333531
3233313233353935395a303f313d303b06035504030c346576616c2d72656365
697074206d617070696e6773207465737420726f6f7420285055524520544553
54204d4154455249414c29308201a2300d06092a864886f70d01010105000382
018f003082018a0282018100bf2c98f756260c3bdfa487f85009454ed25b4191
589b4c6451cf683b69fcb883f29f710166bf9f0c2a474c340d25fbd5b21514af
bf2dfff6333e4f1ab5e158e38e5d8eddcd4d883337dc11aae54b0954b94e5b5e
41964f4fc600fde25a8c2406e24940fc5da14862d55fb86a7de2e7477d28d19c
56cb4d404da14fd3a464fe52015f93a504162b87807dc636a7dd2671c64e2eff
4307609e12d68a5085f4d80539bb9599b8aaf83e1abf37ed2671a08034e56c77
faf8aa5743767b2dbe561e7adc2069164d62214e444799bdacbd6917d2219c83
dff5b910ad6256e5730216eb57fc0021a26e4581a06ded76f0f1c289b67577ba
43db6a68c154a01e3512558f618aac5c738f97b163164a6a76f3b07d48dd9b94
fbcdc3a2edbd486cb3853844e4c04653ae9c2b2060b7802cebb44a8cb918626c
6ccb448d96f90857931963196610d64a4cd2480a12410f3580ac7ceee44316b6
930f585dfbe6abfdd0db288552e03baee551a6c5b697e2537e32156ee66d6445
22d63640591f69d47cb0d68d0203010001a3633061300f0603551d130101ff04
0530030101ff300e0603551d0f0101ff040403020204301d0603551d0e041604
144c0bb4bc8ca56a0d1643ee21bb1e7c3dbf663050301f0603551d2304183016
80144c0bb4bc8ca56a0d1643ee21bb1e7c3dbf663050300d06092a864886f70d
01010b05000382018100678c28e3f30305df549eac036a15ebfdad9684350190
0ac45dc5a3c632cd94b24e80df9ddc63998b354a1e51074cf763937306db4cb2
961b2a0eb0f4e37e0301bdc7dd06240e8ceaa1af908b1f83db81247f61c32166
830c539ac6d488b0bced7fa830c9e5c5d67f35c5f357007ce8cbfe004d210f54
b1fd0cf84a240856759be99ea4e933f37a818c0dd355faef418350e40818274b
abc0e35debe3f04507c8f84bdfd75ffa1f2aea2a440933c9d4d2c58a9b23655f
f7783e21728d74c0034369567e399133d06f5df1a44aa9c245a35d2db598265b
9c01f3c9904ca2a43c2c4ffe4e04459c8fa933be3ca466584673a0a7ad43305f
428b82e8f201db81d625235d4f5a520889a1b59df8e385f05ea617514cb82708
361fd18eb942d6c9b1c0ac1d1c3a00c58e3edf39403d56ee5affcad4faedcb0e
bbeaa789b8140c0ea07d165363808b7cb511eb080aefca268ddf446447dba0d6
f472e6f04ec2c422b5b424721a7e8c1b792cda88aeef7ce3c6c851012c8c80c1
0635d7b26d53454b5d891901022f19010378316170706c69636174696f6e2f76
6e642e7369676e65642d65766964656e63652e6576616c2d726563656970742b
6a736f6ea058208cd849a6dcce08aee334511d7b2f31c54e478885dda1795d3c
8f972dd0d4811c5840a6c0730a565a1ab3e0a2a490fd18c9d885b317b1ff47d6
c4c8ab71b3c5b1d11bc94e3350ab2edc2ad5b3504d400ef79971f3493e477d6b
c44d73fc8b56212c05

Each of X2 to X6 is a COSE_Sign1 with tag 18 whose protected header is the deterministic encoding of the protected header of X1 with the change below, whose unprotected header is the empty map, whose payload is that of X1, and whose signature is given below, ECDSA with SHA-256 over its own Sig_structure, under the test leaf key except for X6, which the other P-256 test key signs.

X2: X1 with 1 (alg) -9 in place of -7. Signature (hex):

ae307dd37eb66ad7f53885d1bfbb638c60a2d531564414261c8a41c651839c67
2380e33157627c3e41815129a9232464eb8c8981a50ec022bb8302d01825e0e9

X3: X1 without parameter 33 (x5chain). Signature (hex):

884255369e0044d654ec7b2adf62df7275d8d7192228fe76c31432016c3ac895
8a40b0108236b4a3e797f6597f1532f1daf552a4f73fa465fd5186c639fc7260

X4: X1 with iss in the form of Section 5.2, whose F is SHA-256 over the test leaf certificate. Signature (hex):

1b9cf8ccc06086f9c87dc7cf44eda63a170f52818aab54b28684a28092240946
93f04574344a566777981423c9aa7f918bd092f8fc09c5e5e12b986434391db2

X5: X1 with one more parameter, 16 (typ), the text string "application/cose". Signature (hex):

e7f13c54e7ac52cd8080404fe5856da616195652ddfd3386da794388b4231fdb
fc4b232c87b0572dea5ed014619b722d69154c38dc1da1bfd28c87dfab9318f6

X6: X1's protected header unchanged. Signature (hex):

a902939e4d89caeae6a5e7f683ffb76c01273d0c4f0f099ebc499f9894064a11
fcb423d6238fd9d93df18a16d2f577b46464afaa1cbfb0bb5b0a6fe85945961b
Table 7: Certificate-profile vectors
Vector Bytes Candidate Status First failing step
X1 2313 P1 accepted (none)
X2 2313 P1 outside_profile 2
X3 365 P1 outside_profile 2
X4 2313 P1 untrusted_key 3
X5 2331 P1 outside_profile 2
X6 2313 P1 signature_invalid 4

What each vector shows:

  • X1: the certificate profile: alg -7, x5chain of the test leaf and the test root, iss a did:x509 identifier that names the test root.

  • X2: X1 with alg -9 (ESP256) in place of -7, signed again under the test leaf; the Transparency Service of Section 12 refuses it at registration.

  • X3: X1 without x5chain, signed again under the test leaf: its labels are those of the key profile, and -7 is not an alg value of that profile.

  • X4: X1 with an iss whose fingerprint names the test leaf certificate and not the test root, signed again under the test leaf.

  • X5: X1 with one more protected parameter, 16 (typ), signed again under the test leaf.

  • X6: X1 signed by another P-256 test key; kid and x5chain still name the test leaf.

Vector and SHA-256 over its bytes:

X1 fcf278cc997cbae6fbc9fa76c7b38da21231ee394c331c3477ea8a7aa060e1df
X2 2322eb9197b41fddbcbc9e68223b3be016111654f4017e77fd046d2e89271721
X3 c6c017fc3c6b1340c10b88c513e06a91c536c928fd0cb0ad350ace733ea139ce
X4 ef7a6ac337943b9bc8984749a3ab5d5bfc8ac33e62b7639220e6ca42a7bec7aa
X5 18fa79f5b6159308994129affcdd9ea9f1b0ebf57dd65d9f77d9423647c29c93
X6 a01501daefafa0c32793612675999e25c83fa8f1d5d5431eb2094727fc01091a

A.9. Transparent Statements

T2 is the Transparent Statement that a local instance of a Transparency Service returned on 2026-10-11 when X1 was registered (see Section 12). It is X1 with one COSE Receipt R under unprotected label 394; nothing else differs from X1. R was made by the service with the key of that test instance and is given here as recorded. Each vector below is a COSE_Sign1 with tag 18 in the deterministic encoding, made of the parts named, and is presented with vector P1 of [RECEIPTS]. The Receiver's configured pairs are the pair of Appendix A.6 and the certificate pair of Appendix A.8. The steps of Section 5.2.2 do not read R.

R, 472 bytes (hex):

d284588da5013822045840633566393532643661306331653364616537356434
3139313739343064366462366637393938663138303566643639313635356664
31643231353763386432300fa3016e3132372e302e302e313a38303030027673
636974742e6363662e7369676e61747572652e7631061a6acb64c519018b0266
6363662e7631a1647478696464322e3133a119018ca1208158dba2018358200c
1484f4d094e618cfb5f6c65c44ef651006c589c932aaca1d8ba0f441a54d9078
4863653a322e31323a3963363236346130383637653135366330303138363830
6264353832326639343431396632353533353737333933356239376364613038
6666306235383335335820fcf278cc997cbae6fbc9fa76c7b38da21231ee394c
331c3477ea8a7aa060e1df028282f558200b1afcd5a9b3799142e015598e429d
2d5572b686189b3737f9064b27465a548b82f558206e44317d4a8df07c74e928
c3fe66b5e01fd66f0ac6e3406ba7d61d72dfc4158df6586012cda8a3bb20d82c
d3c1e36e428bf18b7b6a4f6e4c63c7c3e84f7fdca13bb4a157e17fd3458dad91
95f1fb540b590a2b067ad16ae5c87e7fe0a205fbe98833c3eee31fdbf6e4f6c9
13df773b799896d6916a03d43142f6d37cd4cb1e19a50b1c
  • T1: the protected header, payload and signature of M2; unprotected header {394: [ R ]}.

  • T2: the protected header, payload and signature of X1; unprotected header {394: [ R ]}.

  • T3: as T2; unprotected header {4: the kid of X1, 394: [ R ]}.

  • T4: as T2; unprotected header {394: R}, the byte string not in an array.

  • T5: as T2; unprotected header {394: []}.

Table 8: Transparent Statements
Vector Bytes Candidate Status First failing step
T1 786 P1 accepted (none)
T2 2792 P1 accepted (none)
T3 2827 P1 outside_profile 2
T4 2791 P1 outside_profile 2
T5 2317 P1 outside_profile 2

What each vector shows:

  • T1: M2 with the receipt of T2 under unprotected label 394; that receipt is one for X1, and the steps of the checking procedure do not read it.

  • T2: the Transparent Statement that a local Transparency Service returned for X1: X1 with one receipt under unprotected label 394.

  • T3: T2 with one more unprotected parameter, 4 (kid), the kid of X1.

  • T4: T2 with the receipt under label 394 as a byte string and not in an array.

  • T5: T2 with an empty array under label 394.

Vector and SHA-256 over its bytes:

T1 241496e7136bf76a26cf916ef868ce172ef1915d18127a6ffacb63cef4290a82
T2 312a7d2a840607d4251c260f815fda0e0e1da8c11b1e5ae125c2927a32fcacbe
T3 5308f2023566dc02ab6039afc85053f79e1a5d85c0358df989d99a8f29734973
T4 cbb701b815313232d111dbfd7653267ef7bdf4fe2134212b231e7e22380279ca
T5 aabfeefa90488172b30c6913db50ab5bdc181e043a0c1202c52d66694567080e

Changes (to be removed before publication)

Since draft-gruszka-evaluation-receipt-mappings-02

  • The certificate profile does not admit alg -9 (ESP256). Section 5.2.4 gives the measured reason, Section 12 the measurement, and vector X2 (Appendix A.8) is the statement that was refused.

  • The Open Items section is removed. The in-toto references stay pinned to release v1.2.0, the draft names of [RECEIPTS] and [STATEMENT-ID] stay as cited, Section 5.1 already says that no profile names its declaration, and Section 5.2 now states the measured reason for retaining the certificate profile's existing limits.

  • Section 5.1 makes explicit that a byte order mark is not ignored in this JSON representation, and vector R14 illustrates the resulting Malformed state and INDETERMINATE matching result.

  • This appendix is added.

Since draft-gruszka-evaluation-receipt-mappings-01

  • Section 5.1 defines the JSON representation of a typed digest reference. Input outside it is Malformed before the other states, member names are compared after unescaping, and repeated names are found before any conversion. The matching rule takes exactly one digest_alg and one digest, both strings, whatever the state.

  • Vectors R7 to R13 (Appendix A.7) give Malformed inputs and an escaped member name.

  • Step 1 of Section 3.3 names the form of the value in each carrier.

  • Section 8 and Section 9 say that a MATCH is not a Verified reference, and [RFC8259] is a normative reference.

Since draft-gruszka-evaluation-receipt-mappings-00

  • Section 5.2 adds a certificate profile next to the key profile. Its statement carries an X.509 chain in x5chain and a did:x509 issuer and is signed with alg -7, and step 3 of Section 5.2.2 checks it against a did:x509 identifier and trust anchor that the Receiver configured. Vectors X1 to X6 (Appendix A.8) cover it.

  • Section 5.2.2 checks a Transparent Statement after removing its receipts under label 394 unread, and step 1 fixes the encoding choices that [RFC8949] Section 4.2.2 leaves to a protocol. Vectors T1 to T5 (Appendix A.9) are Transparent Statements, and Appendix A.6 gives a statement for each status other than accepted.

  • Section 5.1 assigns the states Unresolved and Failed of [CPB] Section 8.1 to typed digest references, with vectors R1 to R6 (Appendix A.7).

  • Section 8 adds that a receipt does not show where B came from, and Section 9 adds that an accepted status says nothing about registration and that registration alone does not establish that the payload is the receipt digest.

  • Section 12 records the registration of a statement in the certificate profile with a local Transparency Service and the offline verification of the Transparent Statement it returned.

Author's Address

Konrad Gruszka
b7n0de
Germany