Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add discussion of xi c14n. #3

Merged
merged 11 commits into from
May 28, 2024
Binary file modified diagrams/dl-back.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified diagrams/dl-front.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified diagrams/ead-back.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified diagrams/ead-front.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
178 changes: 81 additions & 97 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,7 @@
This specification describes a mechanism to protect legacy optical barcodes,
such as those found on driver's licenses (PDF417) and travel documents (MRZ),
using Verifiable Credentials [[VC-DATA-MODEL-2.0]]. The Verifiable Credential
representations are compact enough such that they fit in under 140 bytes and
representations are compact enough such that they fit in under 150 bytes and
can thus be integrated with traditional two-dimensional barcodes that are
printed on physical cards using legacy printing processes.
</p>
Expand Down Expand Up @@ -278,8 +278,8 @@ <h3>Driver's License Example</h3>

<p>
The PDF417 data contains information that is secured using the algorithms
described in this specification. Namely, the PDF417 barcode contains the
following <a>verifiable credential</a>.
described in this specification. Namely, the PDF417 barcode contains a
<a>verifiable credential</a> of the following form.
</p>

<pre class="example nohighlight"
Expand Down Expand Up @@ -378,7 +378,7 @@ <h3>Employment Authorization Example</h3>
<p>
The MRZ data contains information that is secured using the algorithms
described in this specification. Namely, the QR Code on the front of the
card contains the following <a>verifiable credential</a>, which secures
card contains a <a>verifiable credential</a> of the following form, which secures
the information on the back of the card.
</p>

Expand Down Expand Up @@ -447,6 +447,21 @@ <h3>Terminology</h3>

</section>

<section id="terms-reference">
<h3>Terms defined by cited specifications</h3>
<dl data-sort="ascending">
<dt><dfn data-cite="XPATH-FUNCTIONS#codepoint-collation" data-lt="code point order|code point ordered|unicode codepoint collation">Unicode code point order</dfn></dt>
<dd>This refers to determining the order of two Unicode strings (`A` and `B`),
using <a>Unicode Codepoint Collation</a>,
as defined in [[XPATH-FUNCTIONS]],
which defines a
<a href="https://en.wikipedia.org/wiki/Total_order">total ordering</a>
of <a>strings</a> comparing code points.
Note that for UTF-8 encoded strings, comparing the byte sequences gives the same result as <a>code point order</a>.
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
</dd>
</dl>
</section>

<section id="conformance">
<p>
A <dfn>conforming document</dfn> is any concrete expression of the data model
Expand Down Expand Up @@ -517,11 +532,10 @@ <h3>OpticalBarcodeCredential</h3>
mandatory fields in an AAMVA compliant driver's license PDF417 [[aamva-dl-id-card-design-standard]],
and the first 22 bits of the `signatureBitfield` value correspond to these fields. Each AAMVA mandatory
field begins with a three character element ID (e.g. `DBA` for document expiration date). To construct
a mapping between bits in the `signatureBitfield` value and these fields, sort these element IDs lexically.
Then, if a bit in position `i` of `signatureBitfield` is `1`, then the AAMVA mandatory field in
position `i` of the sorted element IDs is digitally signed. The last two bits in `signatureBitfield`
MUST be `0`. For more information, see
<a href="#create-opticaldatahash">Section 3.5.4</a>.
a mapping between bits in the `signatureBitfield` value and these fields, sort these element IDs
according to Unicode code point order. Then, if a bit in position `i` of `signatureBitfield` is `1`,
the AAMVA mandatory field in position `i` of the sorted element IDs is digitally signed. The last two
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
bits in `signatureBitfield`MUST be `0`. For more information, see <a href="#create-opticaldatahash">Section 3.5.4</a>.
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
</p>

<p>
Expand Down Expand Up @@ -566,53 +580,48 @@ <h3>OpticalBarcodeCredential</h3>
<h3>TerseBitstringStatusListEntry</h3>

<p>
A `TerseBitstringStatusListEntry` is a subclass of a `BitstringStatusListEntry`
as defined in the [[[VC-BITSTRING-STATUS-LIST]]] specification, where only the
status list index is provided. The location of the status lists are discovered
through the issuer DID Document via the `service` property.
A `TerseBitstringStatusListEntry` is a compact representation
of a `BitstringStatusListEntry` as defined in the [[[VC-BITSTRING-STATUS-LIST]]]
specification.
</p>

<p>
Using the `issuer` property value in
<a href="#example-an-opticalbarcodecredential-utilizing-a-tersebitstringstatuslistentry">
Example 5</a> above (`did:web:dmv.utopia.example`), dereferencing the DID URL
will result in the DID Document below:
An object of type `TerseBitstringStatusListEntry` MUST have two additional properties:
<ul>
<li>
`terseStatusListBaseUrl`, which identifies the location of the status lists associated with this credential.
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
</li>
<li>
`terseStatusListIndex`, which specifies an individual status at the above URL. `terseStatusListIndex` MUST be
representable as a 32 bit unsigned integer.
</li>
</ul>
</p>
To process a `TerseBitstringStatusListEntry`, apply the algorithm in
<a href="#convert-status-list-entries">Section 3.4</a> to convert it to a `BitstringStatusListEntry`,
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
then process it as in [[[VC-BITSTRING-STATUS-LIST]]].
<p>
Implementers MUST set a value |listLength| for the length of an individual status list. This then yields
a number of status lists |listCount| = 2^32 / |listLength| for a 32-bit `terseStatusListIndex`.
|listLength| is needed to convert from a `TerseBitstringStatusListEntry` to a `BitstringStatusListEntry`.
Noting that some values of |listLength| will harm the privacy-preserving properties of these status lists, it is
RECOMMENDED that implementations use |listLength| = 2^17 and |listCount| = 2^15.
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
</p>

</section>

<pre class="example nohighlight"
title="A did:web DID Document expressing status services">
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/vdl/v2"
]
"id": "did:web:dmv.utopia.example",
"service": [{
"id": "did:web:dmv.utopia.example#revocation-service",
"type": "BitstringStatusListService",
"credentialType": "OpticalBarcodeCredential",
"statusPurpose": "revocation",
"serviceEndpoint": "https://dmv.utopia.example/status/revocation/{{YYYY}}/{{MM}}"
}, {
"id": "did:web:dmv.utopia.example#suspension-service",
"type": "BitstringStatusListService",
"credentialType": "OpticalBarcodeCredential",
"statusPurpose": "suspension",
"serviceEndpoint": "https://dmv.utopia.example/status/suspension/{{YYYY}}/{{MM}}"
}]
}
</pre>

<section>
<h3>Encoding to and from barcodes</h3>
While the credentials in this specification use CBOR-LD to efficiently encode Verifiable Credentials
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
in a binary format, binary data is often inefficient or incompatible to turn into standard barcode
image formats directly. To that end, we provide recommendations here for
<p>
It is RECOMMENDED that implementers re-encode CBOR-LD encoded `UsDriversLicenseWithMandatoryFieldsPdf417Barcode`
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
credentials as base64url before encoding them in a PDF417.
</p>
<p>
The `BitstringStatusListService` identifies a specific type of service that
utilizes a URL template that uses information from the
<a>verifiable credential</a> to determine the revocation and suspension status
list URLs. The `{{YYYY}}` and `{{MM}}` template values are replaced with the
issuance year and month, respectively, of the <a>verifiable credential</a>
which are encoded in the `proof`. The resulting document MUST be a
<a data-cite="VC-BITSTRING-STATUS-LIST#bitstringstatuslistcredential">
BitstringStatusListCredential</a> [[VC-BITSTRING-STATUS-LIST]]. See
Section <a href="#convert-status-list-entries"></a> for more details.
It is RECOMMENDED that implementers re-encode CBOR-LD encoded `CompleteMrzBarcode` credentials
as base32 with the string 'VC1-' prepended before encoding them in a QR code.
</p>
</section>

Expand Down Expand Up @@ -705,7 +714,7 @@ <h3>Credential Validation</h3>
</li>
<li>
Set |statusListEntry| to the result of applying the algorithm in
<a href="#convert-status-list-entries">Section 3.1</a> to |credential|.
<a href="#convert-status-list-entries">Section 3.4</a> to |credential|.
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
</li>
<li>
Set |statusResult| to the result of applying the algorithm in
Expand All @@ -730,65 +739,40 @@ <h3>Convert Status List Entries</h3>
<p>
After <a>verifiable credential</a> verification has been performed, the
algorithm takes an `OpticalBarcodeCredential` <a>verifiable credential</a>
([=struct=] |vc|) as input and returns a status object ([=map=] |result|) that
contains a [=boolean=] |status| [=map/entry=] and a [=list=] |statusListEntry|
of one or more [=struct=] values representing `BitstringStatusListEntry`
objects.
([=struct=] |vc|), an integer |listLength| containing the number of entries
in the `BitstringStatusListCredential` associated with |vc|, and a string
|statusPurpose| (e.g. 'revocation', 'suspension'...) as input and returns
a 'BitstringStatusListEntry' object.
</p>

<ol class="algorithm">
<li>
Set |result| to be an empty [=map=] and initialize the |result|.|status| value
to `false`.
Set |result| to be an empty [=map=].
</li>
<li>
Set |year| and |month| to the respective values specified in the
|vc|.|proof|.|created| field.
Set |listIndex| to ⌊|vc|.|credentialStatus|.|terseStatusListIndex|/|listLength|⌋.
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
</li>
<li>
Set |didDocument| to be the result of dereferencing |issuer|. If the dereference
does not result in a conforming DID Document, raise an
<a data-cite="VC-DATA-INTEGRITY#INVALID_CONTROLLER_DOCUMENT">
INVALID_CONTROLLER_DOCUMENT</a> error.
Set |statusListIndex| to |vc|.|credentialStatus|.|terseStatusListIndex| % |listLength|.
</li>
<li>
For each |service| value in |didDocument| where the |service|.|type| is
`BitstringStatusListService`:
<ol class="algorithm">
<li>
Initialize |bslEntry| to an empty [=map=].
</li>
<li>
Set |bslEntry|.|type| to `BitstringStatusListEntry`.
</li>
<li>
Set |bslEntry|.|statusPurpose| to |service|.|statusPurpose|.
</li>
<li>
Set |bslEntry|.|statusListIndex| to |vc|.|credentialStatus|.|index|, ensuring
that the value is converted to a string.
</li>
<li>
Set |bslEntry|.|statusListCredential| to |service|.|serviceEndpoint|,
replacing any `{{YYYY}}` text with a four-character representation of |year|
and any `{{MM}}` text with a two-character representation of |month|, using
leading zeros as necessary.
</li>
<li>
Add |bslEntry| to |result|.|statusListEntry|.
</li>
<li>
Set |result|.|status| to `true`.
</li>
</ol>
Set |result|.|statusListCredential| to
'${|vc|.|credentialStatus|.|terseStatusListBaseUrl|}/${|statusPurpose|}/${|listIndex|}'.
wes-smith marked this conversation as resolved.
Show resolved Hide resolved
</li>
<li>
Set |result|.|type| to 'BitstringStatusListEntry'.
</li>
<li>
Set |result|.|statusListIndex| to |statusListIndex|.
</li>
Set |result|.|statusPurpose| to |statusPurpose|.
<li>
Return |result|.
</li>
</ol>

<p>
Each value in |result|.|statusList| can be used as input to the
|result| can be used as input to the
<a data-cite="VC-BITSTRING-STATUS-LIST#validate-algorithm">
validation algorithm</a> in the [[[VC-BITSTRING-STATUS-LIST]]] specification.
</p>
Expand Down Expand Up @@ -916,7 +900,7 @@ <h5>`UsDriversLicenseWithMandatoryFieldsPdf417Barcode` Credentials</h5>
</li>
<li>
Set |fieldsAlphabetized| to be an array containing the 22 AAMVA mandatory PDF417 Element IDs
[[aamva-dl-id-card-design-standard]] sorted in lexical order (i.e. ['DAC', 'DAD' ... 'DDG']).
[[aamva-dl-id-card-design-standard]] sorted in Unicode code point order (i.e. ['DAC', 'DAD' ... 'DDG']).
</li>
<li>
For each bit with value `1` in |bitfieldDecoded|:
Expand All @@ -933,7 +917,7 @@ <h5>`UsDriversLicenseWithMandatoryFieldsPdf417Barcode` Credentials</h5>
</ol>
</li>
<li>
Set |canonicalizedData| to the result of lexically sorting |dataToCanonicalize| and then applying a join operation
Set |canonicalizedData| to the result of sorting |dataToCanonicalize| in Unicode code point order and then applying a join operation
to create a single string from the array.
</li>
<li>
Expand All @@ -960,8 +944,8 @@ <h5>`CompleteMrzBarcode` Credentials</h5>
</ol>
</li>
<li>
Set |canonicalizedData| to the result of lexically sorting |dataToCanonicalize| and then applying a join operation
to create a single string from the array.
Set |canonicalizedData| to the result of ordering the elements of |dataToCanonicalize| to match the order they appear
on the credential and then applying a join operation to create a single string from the array.
</li>
<li>
Hash |canonicalizedData| and return the result.
Expand Down
Loading