CINXE.COM
JSON Web Signature 2020
<!DOCTYPE html><html lang="en" dir="ltr"><head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> <meta name="generator" content="ReSpec 32.2.0"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <style> span.example-title{text-transform:none} :is(aside,div).example,div.illegal-example{padding:.5em;margin:1em 0;position:relative;clear:both} div.illegal-example{color:red} div.illegal-example p{color:#000} :is(aside,div).example{border-left-width:.5em;border-left-style:solid;border-color:#e0cb52;background:#fcfaee} aside.example div.example{border-left-width:.1em;border-color:#999;background:#fff} .example pre{background-color:rgba(0,0,0,.03)} </style> <style> .issue-label{text-transform:initial} .warning>p:first-child{margin-top:0} .warning{padding:.5em;border-left-width:.5em;border-left-style:solid} span.warning{padding:.1em .5em .15em} .issue.closed span.issue-number{text-decoration:line-through} .issue.closed span.issue-number::after{content:" (Closed)";font-size:smaller} .warning{border-color:#f11;border-width:.2em;border-style:solid;background:#fbe9e9} .warning-title:before{content:"⚠";font-size:1.3em;float:left;padding-right:.3em;margin-top:-.3em} li.task-list-item{list-style:none} input.task-list-item-checkbox{margin:0 .35em .25em -1.6em;vertical-align:middle} .issue a.respec-gh-label{padding:5px;margin:0 2px 0 2px;font-size:10px;text-transform:none;text-decoration:none;font-weight:700;border-radius:4px;position:relative;bottom:2px;border:none;display:inline-block} </style> <style> dfn{cursor:pointer} .dfn-panel{position:absolute;z-index:35;min-width:300px;max-width:500px;padding:.5em .75em;margin-top:.6em;font-family:"Helvetica Neue",sans-serif;font-size:small;background:#fff;color:#000;box-shadow:0 1em 3em -.4em rgba(0,0,0,.3),0 0 1px 1px rgba(0,0,0,.05);border-radius:2px} .dfn-panel:not(.docked)>.caret{position:absolute;top:-9px} .dfn-panel:not(.docked)>.caret::after,.dfn-panel:not(.docked)>.caret::before{content:"";position:absolute;border:10px solid transparent;border-top:0;border-bottom:10px solid #fff;top:0} .dfn-panel:not(.docked)>.caret::before{border-bottom:9px solid #a2a9b1} .dfn-panel *{margin:0} .dfn-panel b{display:block;color:#000;margin-top:.25em} .dfn-panel ul a[href]{color:#333} .dfn-panel>div{display:flex} .dfn-panel a.self-link{font-weight:700;margin-right:auto} .dfn-panel .marker{padding:.1em;margin-left:.5em;border-radius:.2em;text-align:center;white-space:nowrap;font-size:90%;color:#040b1c} .dfn-panel .marker.dfn-exported{background:#d1edfd;box-shadow:0 0 0 .125em #1ca5f940} .dfn-panel .marker.idl-block{background:#8ccbf2;box-shadow:0 0 0 .125em #0670b161} .dfn-panel a:not(:hover){text-decoration:none!important;border-bottom:none!important} .dfn-panel a[href]:hover{border-bottom-width:1px} .dfn-panel ul{padding:0} .dfn-panel li{margin-left:1em} .dfn-panel.docked{position:fixed;left:.5em;top:unset;bottom:2em;margin:0 auto;max-width:calc(100vw - .75em * 2 - .5em - .2em * 2);max-height:30vh;overflow:auto} </style> <title>JSON Web Signature 2020</title> <style id="respec-mainstyle"> @keyframes pop{ 0%{transform:scale(1,1)} 25%{transform:scale(1.25,1.25);opacity:.75} 100%{transform:scale(1,1)} } :is(h1,h2,h3,h4,h5,h6,a) abbr{border:none} dfn{font-weight:700} a.internalDFN{color:inherit;border-bottom:1px solid #99c;text-decoration:none} a.externalDFN{color:inherit;border-bottom:1px dotted #ccc;text-decoration:none} a.bibref{text-decoration:none} .respec-offending-element:target{animation:pop .25s ease-in-out 0s 1} .respec-offending-element,a[href].respec-offending-element{text-decoration:red wavy underline} @supports not (text-decoration:red wavy underline){ .respec-offending-element:not(pre){display:inline-block} .respec-offending-element{background:url(data:image/gif;base64,R0lGODdhBAADAPEAANv///8AAP///wAAACwAAAAABAADAEACBZQjmIAFADs=) bottom repeat-x} } #references :target{background:#eaf3ff;animation:pop .4s ease-in-out 0s 1} cite .bibref{font-style:normal} code{color:#c63501} th code{color:inherit} a[href].orcid{padding-left:4px;padding-right:4px} a[href].orcid>svg{margin-bottom:-2px} .toc a,.tof a{text-decoration:none} a .figno,a .secno{color:#000} ol.tof,ul.tof{list-style:none outside none} .caption{margin-top:.5em;font-style:italic} table.simple{border-spacing:0;border-collapse:collapse;border-bottom:3px solid #005a9c} .simple th{background:#005a9c;color:#fff;padding:3px 5px;text-align:left} .simple th a{color:#fff;padding:3px 5px;text-align:left} .simple th[scope=row]{background:inherit;color:inherit;border-top:1px solid #ddd} .simple td{padding:3px 10px;border-top:1px solid #ddd} .simple tr:nth-child(even){background:#f0f6ff} .section dd>p:first-child{margin-top:0} .section dd>p:last-child{margin-bottom:0} .section dd{margin-bottom:1em} .section dl.attrs dd,.section dl.eldef dd{margin-bottom:0} #issue-summary>ul{column-count:2} #issue-summary li{list-style:none;display:inline-block} details.respec-tests-details{margin-left:1em;display:inline-block;vertical-align:top} details.respec-tests-details>*{padding-right:2em} details.respec-tests-details[open]{z-index:999999;position:absolute;border:thin solid #cad3e2;border-radius:.3em;background-color:#fff;padding-bottom:.5em} details.respec-tests-details[open]>summary{border-bottom:thin solid #cad3e2;padding-left:1em;margin-bottom:1em;line-height:2em} details.respec-tests-details>ul{width:100%;margin-top:-.3em} details.respec-tests-details>li{padding-left:1em} .self-link:hover{opacity:1;text-decoration:none;background-color:transparent} aside.example .marker>a.self-link{color:inherit} .header-wrapper{display:flex;align-items:baseline} :is(h2,h3,h4,h5,h6):not(#toc>h2,#abstract>h2,#sotd>h2,.head>h2){position:relative;left:-.5em} :is(h2,h3,h4,h5,h6):not(#toch2)+a.self-link{color:inherit;order:-1;position:relative;left:-1.1em;font-size:1rem;opacity:.5} :is(h2,h3,h4,h5,h6)+a.self-link::before{content:"§";text-decoration:none;color:var(--heading-text)} :is(h2,h3)+a.self-link{top:-.2em} :is(h4,h5,h6)+a.self-link::before{color:#000} @media (max-width:767px){ dd{margin-left:0} } @media print{ .removeOnSave{display:none} } </style> <style> pre .highlight { font-weight: bold; color: green; } pre .comment { font-weight: bold; color: Gray; } .color-text { font-weight: bold; text-shadow: -1px 0 black, 0 1px black, 1px 0 black, 0 -1px black; } ol.algorithm { counter-reset: numsection; list-style-type: none; } ol.algorithm li { margin: 0.5em 0; } ol.algorithm li:before { font-weight: bold; counter-increment: numsection; content: counters(numsection, ".") ") "; } </style> <meta name="description" content="This specification describes a JSON Web Signature Suite created in 2020 for the Linked Data Proof specification. The Signature Suite utilizes Detached JWS signatures to provide support for a subset of the digital signature algorithms registered with IANA."> <link rel="canonical" href="https://www.w3.org/community/reports/credentials/CG-FINAL-lds-jws2020-20220721/"> <style> .hljs{display:block;overflow-x:auto;padding:.5em;color:#383a42;background:#fafafa} .hljs-comment,.hljs-quote{color:#717277;font-style:italic} .hljs-doctag,.hljs-formula,.hljs-keyword{color:#a626a4} .hljs-deletion,.hljs-name,.hljs-section,.hljs-selector-tag,.hljs-subst{color:#ca4706;font-weight:700} .hljs-literal{color:#0b76c5} .hljs-addition,.hljs-attribute,.hljs-meta-string,.hljs-regexp,.hljs-string{color:#42803c} .hljs-built_in,.hljs-class .hljs-title{color:#9a6a01} .hljs-attr,.hljs-number,.hljs-selector-attr,.hljs-selector-class,.hljs-selector-pseudo,.hljs-template-variable,.hljs-type,.hljs-variable{color:#986801} .hljs-bullet,.hljs-link,.hljs-meta,.hljs-selector-id,.hljs-symbol,.hljs-title{color:#336ae3} .hljs-emphasis{font-style:italic} .hljs-strong{font-weight:700} .hljs-link{text-decoration:underline} </style> <style> var{position:relative;cursor:pointer} var[data-type]::after,var[data-type]::before{position:absolute;left:50%;top:-6px;opacity:0;transition:opacity .4s;pointer-events:none} var[data-type]::before{content:"";transform:translateX(-50%);border-width:4px 6px 0 6px;border-style:solid;border-color:transparent;border-top-color:#000} var[data-type]::after{content:attr(data-type);transform:translateX(-50%) translateY(-100%);background:#000;text-align:center;font-family:"Dank Mono","Fira Code",monospace;font-style:normal;padding:6px;border-radius:3px;color:#daca88;text-indent:0;font-weight:400} var[data-type]:hover::after,var[data-type]:hover::before{opacity:1} </style> <script id="initialUserConfig" type="application/json">{ "specStatus": "CG-FINAL", "group": "credentials", "wgPublicList": "public-credentials", "shortName": "lds-jws2020", "latestVersion": "https://www.w3.org/community/reports/credentials/CG-FINAL-lds-jws2020-20220721/", "edDraftURI": "https://w3id.org/security/suites/jws-2020", "editors": [ { "name": "Orie Steele", "url": "https://transmute.industries", "company": "Transmute", "companyURL": "https://transmute.industries" }, { "name": "Michael Prorock", "url": "https://mesur.io/", "company": "mesur.io", "companyURL": "https://mesur.io/" }, { "name": "Charles E. Lehner", "url": "https://www.w3.org/wiki/User:cel", "company": "Spruce", "companyURL": "https://spruceid.com/" } ], "wg": "Credentials Community Group", "wgURI": "https://www.w3.org/community/credentials/", "wgPatentURI": "https://www.w3.org/community/about/agreements/cla/", "otherLinks": [ { "key": "Source control", "data": [ { "value": "https://github.com/w3c-ccg/lds-jws2020/", "href": "https://github.com/w3c-ccg/lds-jws2020/" } ] }, { "key": "Issue Tracker", "data": [ { "value": "https://github.com/w3c-ccg/lds-jws2020/issues/", "href": "https://github.com/w3c-ccg/lds-jws2020/issues/" } ] } ], "maxTocLevel": 4, "localBiblio": { "RDF-DATASET-NORMALIZATION": { "title": "RDF Dataset Normalization 1.0", "href": "http://json-ld.github.io/normalization/spec/", "authors": [ "David Longley", "Manu Sporny" ], "status": "CGDRAFT", "publisher": "JSON-LD Community Group", "id": "rdf-dataset-normalization" }, "RDF-CONCEPTS": { "title": "RDF 1.1 Concepts and Abstract Syntax", "href": "https://www.w3.org/TR/rdf11-concepts/", "authors": [ "Richard Cyganiak", "David Wood", "Markus Lanthaler" ], "status": "Recommendation", "publisher": "W3C" }, "RDF-N-Quads": { "title": "RDF 1.1 N-Quads", "href": "http://json-ld.github.io/normalization/spec/", "authors": [ "Gaven Carothers" ], "status": "Recommendation", "id": "rdf-n-quads" }, "SECURITY-VOCABULARY": { "title": "Security Linked Data Vocabulary", "href": "https://w3id.org/security", "authors": [ "Manu Sporny", "David Longley" ], "status": "CGDRAFT", "publisher": "Web Payments Community Group" }, "LD-PROOFS": { "title": "Linked Data Proofs 1.0", "href": "https://w3c-ccg.github.io/ld-proofs", "authors": [ "David Longley", "Manu Sporny" ], "status": "CGDRAFT", "publisher": "Web Payments Community Group", "id": "ld-proofs" }, "ISO_8601": { "title": "ISO_8601", "href": "https://en.wikipedia.org/wiki/ISO_8601", "id": "iso_8601" }, "IANA_JOSE": { "title": "JOSE", "href": "https://www.iana.org/assignments/jose/jose.xhtml", "id": "iana_jose" } }, "publishISODate": "2022-07-21T00:00:00.000Z", "generatedSubtitle": "Final Community Group Report 21 July 2022" }</script> <link rel="stylesheet" href="https://www.w3.org/StyleSheets/TR/2021/cg-final"></head> <body class="h-entry"><div class="head"> <h1 id="title" class="title">JSON Web Signature 2020</h1> <p id="w3c-state"> <a href="https://www.w3.org/standards/types#reports">Final Community Group Report</a> <time class="dt-published" datetime="2022-07-21">21 July 2022</time> </p> <dl> <dt>This version:</dt><dd> <a class="u-url" href="https://www.w3.org/community/reports/credentials/CG-FINAL-lds-jws2020-20220721/">https://www.w3.org/community/reports/credentials/CG-FINAL-lds-jws2020-20220721/</a> </dd> <dt>Latest published version:</dt><dd> <a href="https://www.w3.org/community/reports/credentials/CG-FINAL-lds-jws2020-20220721/">https://www.w3.org/community/reports/credentials/CG-FINAL-lds-jws2020-20220721/</a> </dd> <dt>Latest editor's draft:</dt><dd><a href="https://w3id.org/security/suites/jws-2020">https://w3id.org/security/suites/jws-2020</a></dd> <dt>Editors:</dt><dd class="editor p-author h-card vcard"> <a class="u-url url p-name fn" href="https://transmute.industries">Orie Steele</a> (<a class="p-org org h-org" href="https://transmute.industries">Transmute</a>) </dd><dd class="editor p-author h-card vcard"> <a class="u-url url p-name fn" href="https://mesur.io/">Michael Prorock</a> (<a class="p-org org h-org" href="https://mesur.io/">mesur.io</a>) </dd><dd class="editor p-author h-card vcard"> <a class="u-url url p-name fn" href="https://www.w3.org/wiki/User:cel">Charles E. Lehner</a> (<a class="p-org org h-org" href="https://spruceid.com/">Spruce</a>) </dd> <dt>Feedback:</dt><dd><a href="mailto:public-credentials@w3.org?subject=%5Blds-jws2020%5D%20YOUR%20TOPIC%20HERE">public-credentials@w3.org</a> with subject line <kbd>[lds-jws2020] <em>… message topic …</em></kbd> (<a rel="discussion" href="https://lists.w3.org/Archives/Public/public-credentials">archives</a>)</dd> </dl> <p class="copyright"> <a href="https://www.w3.org/Consortium/Legal/ipr-notice#Copyright">Copyright</a> © 2022 the Contributors to the JSON Web Signature 2020 Specification, published by the <a href="https://www.w3.org/groups/cg/credentials">Credentials Community Group</a> under the <a href="https://www.w3.org/community/about/agreements/fsa/">W3C Community Final Specification Agreement (FSA)</a>. A human-readable <a href="https://www.w3.org/community/about/agreements/fsa-deed/">summary</a> is available. </p> <hr title="Separator for header"> </div> <section id="abstract" class="introductory"><h2>Abstract</h2> <p> This specification describes a JSON Web Signature Suite created in 2020 for the Linked Data Proof specification. The Signature Suite utilizes Detached JWS signatures to provide support for a subset of the digital signature algorithms registered with IANA. </p> </section> <section id="sotd" class="introductory"><h2>Status of This Document</h2><p> This specification was published by the <a href="https://www.w3.org/groups/cg/credentials">Credentials Community Group</a>. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the <a href="https://www.w3.org/community/about/agreements/final/">W3C Community Final Specification Agreement (FSA)</a> other conditions apply. Learn more about <a href="https://www.w3.org/community/">W3C Community and Business Groups</a>. </p> <p> This is an experimental specification and is undergoing regular revisions. It is not fit for production deployment. </p> <p> If you wish to make comments regarding this document, please send them to <a href="mailto:public-credentials@w3.org">public-credentials@w3.org</a> (<a href="mailto:public-credentials-request@w3.org?subject=subscribe">subscribe</a>, <a href="https://lists.w3.org/Archives/Public/public-credentials/">archives</a>). </p></section><nav id="toc"><h2 class="introductory" id="table-of-contents">Table of Contents</h2><ol class="toc"><li class="tocline"><a class="tocxref" href="#abstract">Abstract</a></li><li class="tocline"><a class="tocxref" href="#sotd">Status of This Document</a></li><li class="tocline"><a class="tocxref" href="#introduction"><bdi class="secno">1. </bdi>Introduction</a></li><li class="tocline"><a class="tocxref" href="#terminology"><bdi class="secno">2. </bdi>Terminology</a></li><li class="tocline"><a class="tocxref" href="#suite-definition"><bdi class="secno">3. </bdi>Suite Definition</a><ol class="toc"><li class="tocline"><a class="tocxref" href="#jose-conformance"><bdi class="secno">3.1 </bdi>JOSE Conformance</a></li><li class="tocline"><a class="tocxref" href="#verification-method"><bdi class="secno">3.2 </bdi>Verification Method</a><ol class="toc"><li class="tocline"><a class="tocxref" href="#json-web-key-2020"><bdi class="secno">3.2.1 </bdi>JSON Web Key 2020</a></li></ol></li><li class="tocline"><a class="tocxref" href="#proof-representation"><bdi class="secno">3.3 </bdi>Proof Representation</a><ol class="toc"><li class="tocline"><a class="tocxref" href="#json-web-signature-2020"><bdi class="secno">3.3.1 </bdi>JSON Web Signature 2020</a></li></ol></li></ol></li><li class="tocline"><a class="tocxref" href="#test-vectors"><bdi class="secno">4. </bdi>Test Vectors</a></li><li class="tocline"><a class="tocxref" href="#conformance"><bdi class="secno">5. </bdi>Conformance</a></li><li class="tocline"><a class="tocxref" href="#security-considerations"><bdi class="secno">6. </bdi>Security Considerations</a></li><li class="tocline"><a class="tocxref" href="#references"><bdi class="secno">A. </bdi>References</a><ol class="toc"><li class="tocline"><a class="tocxref" href="#normative-references"><bdi class="secno">A.1 </bdi>Normative references</a></li><li class="tocline"><a class="tocxref" href="#informative-references"><bdi class="secno">A.2 </bdi>Informative references</a></li></ol></li></ol></nav> <section id="introduction"><div class="header-wrapper"><h2 id="x1-introduction"><bdi class="secno">1. </bdi>Introduction</h2><a class="self-link" href="#introduction" aria-label="Permalink for Section 1."></a></div> <p> This specification defines a cryptographic suite for the purpose of creating, verifying proofs for JSON Web Signatures in conformance with the Linked Data Proofs [<cite><a class="bibref" data-link-type="biblio" href="#bib-ld-proofs" title="Linked Data Proofs 1.0">LD-PROOFS</a></cite>] specification. </p> <p> In general the suites uses the RDF Dataset Normalization Algorithm [<cite><a class="bibref" data-link-type="biblio" href="#bib-rdf-dataset-normalization" title="RDF Dataset Normalization 1.0">RDF-DATASET-NORMALIZATION</a></cite>] to transform an input document into its canonical form. The cannonical representation is then hashed and signed with a detached signature algorithm. </p> </section> <section id="terminology"><div class="header-wrapper"><h2 id="x2-terminology"><bdi class="secno">2. </bdi>Terminology</h2><a class="self-link" href="#terminology" aria-label="Permalink for Section 2."></a></div> <p> The following terms are used to describe concepts involved in the generation and verification of the Linked Data Proof <a href="#dfn-signature-suite" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-signature-suite-1">signature suite</a>. </p> <dl> <dt><dfn id="dfn-signature-suite" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">signature suite</dfn></dt> <dd> A specified set of cryptographic primitives typically consisting of a canonicalization algorithm, a message digest algorithm, and a signature algorithm that are bundled together by cryptographers for developers for the purposes of safety and convenience. </dd> <dt><dfn id="dfn-canonicalization-algorithm" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">canonicalization algorithm</dfn></dt> <dd> An algorithm that takes an input document that has more than one possible representation and always transforms it into a <a href="#dfn-canonical-form" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-canonical-form-1">canonical form</a>. This process is sometimes also called normalization. </dd> <dt> <dfn data-lt="message digest algorithm|message digest algorithms" id="dfn-message-digest-algorithm" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">message digest algorithm</dfn> </dt> <dd> An algorithm that takes a message, prefferably in some <a href="#dfn-canonical-form" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-canonical-form-2">canonical form</a> and produces a cryptographic output called a digest that is often many orders of magnitude smaller than the input message. These algorithms are often 1) very fast, 2) non-reversible, 3) cause the output to change significantly when even one bit of the input message changes, and 4) make it infeasible to find two different inputs for the same output. </dd> <dt><dfn id="dfn-canonical-form" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">canonical form</dfn></dt> <dd> The output of applying a <a href="#dfn-canonicalization-algorithm" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-canonicalization-algorithm-1">canonicalization algorithm</a> to an input document. </dd> <dt><dfn id="dfn-signature-algorithm" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">signature algorithm</dfn></dt> <dd> An algorithm that takes an input message and produces an output value where the receiver of the message can mathematically verify that the message has not been modified in transit and came from someone possessing a particular secret. </dd> <dt> <dfn data-lt="linked data document|linked data documents" id="dfn-linked-data-document" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">linked data document</dfn> </dt> <dd>A document comprised of linked data.</dd> <dt> <dfn data-lt="linked data proof|linked data proofs" id="dfn-linked-data-proof" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">linked data proof</dfn> </dt> <dd> A <a href="https://w3c-ccg.github.io/data-integrity-spec/#signatures" class="externalDFN">linked data proof</a> which is a set of attributes that represent a linked data digital proof and the parameters required to verify it as defined by [<cite><a class="bibref" data-link-type="biblio" href="#bib-rdf-n-quads" title="RDF 1.1 N-Quads">RDF-N-Quads</a></cite>]. </dd> <dt>linked data proof document</dt> <dd> A <a href="#dfn-linked-data-document" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-linked-data-document-1">linked data document</a> featuring one or more <a href="#dfn-linked-data-proof" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-linked-data-proof-1">linked data proofs</a>. </dd> <dt><dfn id="dfn-jsonwebkey2020" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">JsonWebKey2020</dfn></dt> <dd> The <code>type</code> of the verification method for the signature suite <a href="#dfn-jsonwebsignature2020" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-jsonwebsignature2020-1">JsonWebSignature2020</a>. </dd> <dt><dfn id="dfn-jsonwebsignature2020" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">JsonWebSignature2020</dfn></dt> <dd> The <code>type</code> of the linked data proof for the signature suite <a href="#dfn-jsonwebsignature2020" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-jsonwebsignature2020-2">JsonWebSignature2020</a>. </dd> </dl> </section> <section id="suite-definition"><div class="header-wrapper"><h2 id="x3-suite-definition"><bdi class="secno">3. </bdi>Suite Definition</h2><a class="self-link" href="#suite-definition" aria-label="Permalink for Section 3."></a></div> <p> The JSON Web Signature <a href="#dfn-signature-suite" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-signature-suite-2">signature suite</a> 2020 <em class="rfc2119">MUST</em> be used in conjunction with the signing and verification algorithms in the Linked Data Proofs [<cite><a class="bibref" data-link-type="biblio" href="#bib-ld-proofs" title="Linked Data Proofs 1.0">LD-PROOFS</a></cite>] specification. The suite consists of the following algorithms: </p> <table class="simple"> <thead> <tr><th>Parameter</th> <th>Value</th> <th>Specification</th> </tr></thead> <tbody> <tr> <td><a href="#dfn-canonicalization-algorithm" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-canonicalization-algorithm-2">canonicalization algorithm</a></td> <td>https://w3id.org/security#URDNA2015</td> <td>[<cite><a class="bibref" data-link-type="biblio" href="#bib-rdf-dataset-normalization" title="RDF Dataset Normalization 1.0">RDF-DATASET-NORMALIZATION</a></cite>]</td> </tr> <tr> <td><a href="#dfn-message-digest-algorithm" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-message-digest-algorithm-1">message digest algorithm</a></td> <td>SHA-256</td> <td>[<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc4634" title="US Secure Hash Algorithms (SHA and HMAC-SHA)">RFC4634</a></cite>]</td> </tr> <tr> <td><a href="#dfn-signature-algorithm" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-signature-algorithm-1">signature algorithm</a></td> <td>JSON Web Signature (JWS) Unencoded Payload Option</td> <td>[<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc7797" title="JSON Web Signature (JWS) Unencoded Payload Option">RFC7797</a></cite>]</td> </tr> </tbody> </table> <section id="jose-conformance"><div class="header-wrapper"><h3 id="x3-1-jose-conformance"><bdi class="secno">3.1 </bdi>JOSE Conformance</h3><a class="self-link" href="#jose-conformance" aria-label="Permalink for Section 3.1"></a></div> <p> This suite support cryptographic agility, see [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc7696" title="Guidelines for Cryptographic Algorithm Agility and Selecting Mandatory-to-Implement Algorithms">RFC7696</a></cite>]. This table maps a key type to a subset of [<cite><a class="bibref" data-link-type="biblio" href="#bib-iana_jose" title="JOSE">IANA_JOSE</a></cite>] supported signing and encryption algorithms. </p> <table class="simple"> <thead> <tr><th>kty</th> <th>crvOrSize</th> <th>signature</th> <th>keyAgreement</th> <th>encryption</th> </tr></thead> <tbody> <tr> <td>OKP</td> <td>Ed25519</td> <td>EdDSA</td> <td></td> <td>ECDH-ES+A256KW</td> </tr> <tr> <td>OKP</td> <td>X25519</td> <td></td> <td>ECDH</td> <td>ECDH-ES+A256KW</td> </tr> <tr> <td>EC</td> <td>secp256k1</td> <td>ES256K</td> <td>ECDH</td> <td>ECDH-ES+A256KW</td> </tr> <tr> <td>EC</td> <td>P-256</td> <td>ES256</td> <td>ECDH</td> <td>ECDH-ES+A256KW</td> </tr> <tr> <td>EC</td> <td>P-384</td> <td>ES384</td> <td>ECDH</td> <td>ECDH-ES+A256KW</td> </tr> <tr> <td>RSA</td> <td>2048+</td> <td>PS256</td> <td></td> <td>RSA-OAEP</td> </tr> </tbody> </table> </section> <section id="verification-method"><div class="header-wrapper"><h3 id="x3-2-verification-method"><bdi class="secno">3.2 </bdi>Verification Method</h3><a class="self-link" href="#verification-method" aria-label="Permalink for Section 3.2"></a></div> <p> The cryptographic material used to verify a linked data proof is called the verification method. </p> <p> This suite relies on public key material represented using [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc7517" title="JSON Web Key (JWK)">RFC7517</a></cite>]. </p> <p> This suite supports public key use for both digital signature verification, according to [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc7515" title="JSON Web Signature (JWS)">RFC7515</a></cite>], and key agreement according to [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc8037" title="CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE)">RFC8037</a></cite>]. </p> <p> This suite <em class="rfc2119">MAY</em> be used to verify linked data proofs produced by key material in any representation that can be converted to JWK, however it is <em class="rfc2119">RECOMMENDED</em> that this suite be used with verification method's of type <a href="#dfn-jsonwebkey2020" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-jsonwebkey2020-1">JsonWebKey2020</a>. </p> <section id="json-web-key-2020"><div class="header-wrapper"><h4 id="x3-2-1-json-web-key-2020"><bdi class="secno">3.2.1 </bdi>JSON Web Key 2020</h4><a class="self-link" href="#json-web-key-2020" aria-label="Permalink for Section 3.2.1"></a></div> <p> The <code>id</code> of the verification method <em class="rfc2119">SHOULD</em> be the JWK thumbprint calculated from the <code>publicKeyJwk</code> property value according to [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc7638" title="JSON Web Key (JWK) Thumbprint">RFC7638</a></cite>]. </p> <p> The <code>type</code> of the verification method <em class="rfc2119">SHOULD</em> be <a href="#dfn-jsonwebkey2020" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-jsonwebkey2020-2">JsonWebKey2020</a>. </p> <p> The <code>controller</code> of the verification method <em class="rfc2119">SHOULD</em> be a URI. </p> <p> The <code>publicKeyJwk</code> property of the verification method <em class="rfc2119">SHOULD</em> be a JWK formatted according to [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc7517" title="JSON Web Key (JWK)">RFC7517</a></cite>]. </p> <p class="advisement"> Be careful not to accidentally publish the JWK representation of a private key. See <a href="https://tools.ietf.org/html/rfc7517#appendix-A.2">rfc7517#appendix-A.2</a> for examples of private key representations. The property <code>publicKeyJwk</code> <em class="rfc2119">MUST</em> never contain <code>"d"</code>. </p> <div class="example" id="example-1"> <div class="marker"> <a class="self-link" href="#example-1">Example<bdi> 1</bdi></a> </div> <pre aria-busy="false"><code class="hljs json">{ <span class="hljs-attr">"id"</span>: <span class="hljs-string">"https://example.com/issuer/123#ovsDKYBjFemIy8DVhc-w2LSi8CvXMw2AYDzHj04yxkc"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"https://example.com/issuer/123"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"OKP"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"Ed25519"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"CV-aGlld3nVdgnhoZK0D36Wk-9aIMlZjZOK2XhPMnkQ"</span> } }</code></pre> </div> <div class="example" id="example-example-in-did-document"> <div class="marker"> <a class="self-link" href="#example-example-in-did-document">Example<bdi> 2</bdi></a><span class="example-title">: Example in DID Document.</span> </div> <pre aria-busy="false"><code class="hljs json">{ <span class="hljs-attr">"@context"</span>: [<span class="hljs-string">"https://www.w3.org/ns/did/v1"</span>, <span class="hljs-string">"https://w3id.org/security/suites/jws-2020/v1"</span>], <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:123"</span>, <span class="hljs-attr">"publicKey"</span>: [ { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:example:123"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"OKP"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"Ed25519"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"VCpo2LMLhn6iWku8MKvSLg2ZAoC-nlOyPVQaO3FxVeQ"</span> } }, { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:123#4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:example:123"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"EC"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"secp256k1"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"Z4Y3NNOxv0J6tCgqOBFnHnaZhJF6LdulT7z8A-2D5_8"</span>, <span class="hljs-attr">"y"</span>: <span class="hljs-string">"i5a2NtJoUKXkLm6q8nOEu9WOkso1Ag6FTUT6k_LMnGk"</span> } }, { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:123#n4cQ-I_WkHMcwXBJa7IHkYu8CMfdNcZKnKsOrnHLpFs"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:example:123"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"RSA"</span>, <span class="hljs-attr">"e"</span>: <span class="hljs-string">"AQAB"</span>, <span class="hljs-attr">"n"</span>: <span class="hljs-string">"omwsC1AqEk6whvxyOltCFWheSQvv1MExu5RLCMT4jVk9khJKv8JeMXWe3bWHatjPskdf2dlaGkW5QjtOnUKL742mvr4tCldKS3ULIaT1hJInMHHxj2gcubO6eEegACQ4QSu9LO0H-LM_L3DsRABB7Qja8HecpyuspW1Tu_DbqxcSnwendamwL52V17eKhlO4uXwv2HFlxufFHM0KmCJujIKyAxjD_m3q__IiHUVHD1tDIEvLPhG9Azsn3j95d-saIgZzPLhQFiKluGvsjrSkYU5pXVWIsV-B2jtLeeLC14XcYxWDUJ0qVopxkBvdlERcNtgF4dvW4X00EHj4vCljFw"</span> } }, { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:123#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:example:123"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"EC"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"P-256"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"38M1FDts7Oea7urmseiugGW7tWc3mLpJh6rKe7xINZ8"</span>, <span class="hljs-attr">"y"</span>: <span class="hljs-string">"nDQW6XZ7b_u2Sy9slofYLlG03sOEoug3I0aAPQ0exs4"</span> } }, { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:123#8wgRfY3sWmzoeAL-78-oALNvNj67ZlQxd1ss_NX1hZY"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:example:123"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"EC"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"P-384"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"GnLl6mDti7a2VUIZP5w6pcRX8q5nvEIgB3Q_5RI2p9F_QVsaAlDN7IG68Jn0dS_F"</span>, <span class="hljs-attr">"y"</span>: <span class="hljs-string">"jq4QoAHKiIzezDp88s_cxSPXtuXYFliuCGndgU4Qp8l91xzD1spCmFIzQgVjqvcP"</span> } }, { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:123#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:example:123"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"EC"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"P-521"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"AVlZG23LyXYwlbjbGPMxZbHmJpDSu-IvpuKigEN2pzgWtSo--Rwd-n78nrWnZzeDc187Ln3qHlw5LRGrX4qgLQ-y"</span>, <span class="hljs-attr">"y"</span>: <span class="hljs-string">"ANIbFeRdPHf1WYMCUjcPz-ZhecZFybOqLIJjVOlLETH7uPlyG0gEoMWnIZXhQVypPy_HtUiUzdnSEPAylYhHBTX2"</span> } } ], <span class="hljs-attr">"authentication"</span>: [ <span class="hljs-string">"did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"</span>, <span class="hljs-string">"did:example:123#4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A"</span>, <span class="hljs-string">"did:example:123#n4cQ-I_WkHMcwXBJa7IHkYu8CMfdNcZKnKsOrnHLpFs"</span>, <span class="hljs-string">"did:example:123#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw"</span>, <span class="hljs-string">"did:example:123#8wgRfY3sWmzoeAL-78-oALNvNj67ZlQxd1ss_NX1hZY"</span>, <span class="hljs-string">"did:example:123#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"</span> ], <span class="hljs-attr">"assertionMethod"</span>: [ <span class="hljs-string">"did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"</span>, <span class="hljs-string">"did:example:123#4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A"</span>, <span class="hljs-string">"did:example:123#n4cQ-I_WkHMcwXBJa7IHkYu8CMfdNcZKnKsOrnHLpFs"</span>, <span class="hljs-string">"did:example:123#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw"</span>, <span class="hljs-string">"did:example:123#8wgRfY3sWmzoeAL-78-oALNvNj67ZlQxd1ss_NX1hZY"</span>, <span class="hljs-string">"did:example:123#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"</span> ], <span class="hljs-attr">"capabilityDelegation"</span>: [ <span class="hljs-string">"did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"</span>, <span class="hljs-string">"did:example:123#4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A"</span>, <span class="hljs-string">"did:example:123#n4cQ-I_WkHMcwXBJa7IHkYu8CMfdNcZKnKsOrnHLpFs"</span>, <span class="hljs-string">"did:example:123#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw"</span>, <span class="hljs-string">"did:example:123#8wgRfY3sWmzoeAL-78-oALNvNj67ZlQxd1ss_NX1hZY"</span>, <span class="hljs-string">"did:example:123#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"</span> ], <span class="hljs-attr">"capabilityInvocation"</span>: [ <span class="hljs-string">"did:example:123#_Qq0UL2Fq651Q0Fjd6TvnYE-faHiOpRlPVQcY_-tA4A"</span>, <span class="hljs-string">"did:example:123#4SZ-StXrp5Yd4_4rxHVTCYTHyt4zyPfN1fIuYsm6k3A"</span>, <span class="hljs-string">"did:example:123#n4cQ-I_WkHMcwXBJa7IHkYu8CMfdNcZKnKsOrnHLpFs"</span>, <span class="hljs-string">"did:example:123#_TKzHv2jFIyvdTGF1Dsgwngfdg3SH6TpDv0Ta1aOEkw"</span>, <span class="hljs-string">"did:example:123#8wgRfY3sWmzoeAL-78-oALNvNj67ZlQxd1ss_NX1hZY"</span>, <span class="hljs-string">"did:example:123#NjQ6Y_ZMj6IUK_XkgCDwtKHlNTUTVjEYOWZtxhp1n-E"</span> ] }</code></pre> </div> </section> </section> <section id="proof-representation"><div class="header-wrapper"><h3 id="x3-3-proof-representation"><bdi class="secno">3.3 </bdi>Proof Representation</h3><a class="self-link" href="#proof-representation" aria-label="Permalink for Section 3.3"></a></div> <p> The cryptographic material used to represent a linked data proof is called the proof type. </p> <p> This suite relies on detached digital signatures represented using [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc7797" title="JSON Web Signature (JWS) Unencoded Payload Option">RFC7797</a></cite>]. </p> <section id="json-web-signature-2020"><div class="header-wrapper"><h4 id="x3-3-1-json-web-signature-2020"><bdi class="secno">3.3.1 </bdi>JSON Web Signature 2020</h4><a class="self-link" href="#json-web-signature-2020" aria-label="Permalink for Section 3.3.1"></a></div> <p> The <code>verificationMethod</code> property of the proof <em class="rfc2119">SHOULD</em> be a URI. Dereferencing the <code>verificationMethod</code> <em class="rfc2119">SHOULD</em> result in an object of <code>type</code> <a href="#dfn-jsonwebkey2020" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-jsonwebkey2020-3">JsonWebKey2020</a>. </p> <p> The <code>type</code> property of the proof <em class="rfc2119">MUST</em> be <a href="#dfn-jsonwebsignature2020" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-jsonwebsignature2020-3">JsonWebSignature2020</a>. </p> <p> The <code>created</code> property of the proof <em class="rfc2119">MUST</em> be an [<cite><a class="bibref" data-link-type="biblio" href="#bib-iso_8601" title="ISO_8601">ISO_8601</a></cite>] formated date string. </p> <p> The <code>proofPurpose</code> property of the proof <em class="rfc2119">MUST</em> be a string, and <em class="rfc2119">SHOULD</em> match the verification relationship expressed by the verification method <code>controller</code>. </p> <p> The <code>jws</code> property of the proof <em class="rfc2119">MUST</em> be a detached JWS produced according to [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc7797" title="JSON Web Signature (JWS) Unencoded Payload Option">RFC7797</a></cite>]. </p><p class="advisement"> The header of the detached JWS <em class="rfc2119">MUST</em> look like this: <code>{"b64":false,"crit":["b64"],"alg":"PS256"}</code> where <code>alg</code> is a value registered in [<cite><a class="bibref" data-link-type="biblio" href="#bib-iana_jose" title="JOSE">IANA_JOSE</a></cite>] AND is present in the supported algorithms table of this suite. </p> <p></p> </section> </section> </section> <section id="test-vectors"><div class="header-wrapper"><h2 id="x4-test-vectors"><bdi class="secno">4. </bdi>Test Vectors</h2><a class="self-link" href="#test-vectors" aria-label="Permalink for Section 4."></a></div> <p>The following test vectors are provided to assist with implementers.</p> <div class="example" id="example-3"> <div class="marker"> <a class="self-link" href="#example-3">Example<bdi> 3</bdi></a> </div> <pre aria-busy="false"><code class="hljs json">{ <span class="hljs-attr">"seed_0"</span>: <span class="hljs-string">"9b937b81322d816cfab9d5a3baacc9b2a5febe4b149f126b3630f93a29527017"</span> }</code></pre> </div> <div class="example" id="example-4"> <div class="marker"> <a class="self-link" href="#example-4">Example<bdi> 4</bdi></a> </div> <pre aria-busy="false"><code class="hljs json">{ <span class="hljs-attr">"keypair_0"</span>: { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"#ovsDKYBjFemIy8DVhc-w2LSi8CvXMw2AYDzHj04yxkc"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:key:z6Mkf5rGMoatrSj1f4CyvuHBeXJELe9RPdzo2PKGNCKVtZxP"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"OKP"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"Ed25519"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"CV-aGlld3nVdgnhoZK0D36Wk-9aIMlZjZOK2XhPMnkQ"</span> }, <span class="hljs-attr">"privateKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"OKP"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"Ed25519"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"CV-aGlld3nVdgnhoZK0D36Wk-9aIMlZjZOK2XhPMnkQ"</span>, <span class="hljs-attr">"d"</span>: <span class="hljs-string">"m5N7gTItgWz6udWjuqzJsqX-vksUnxJrNjD5OilScBc"</span> } }, <span class="hljs-attr">"keypair_1"</span>: { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"#zaS0k3zk2KpT4NqqpdUA1YD0JVTOtQf3pNoKDI-wes0"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:key:zQ3shP2mWsZYWgvgM11nenXRTx9L1yiJKmkf9dfX7NaMKb1pX"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"EC"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"secp256k1"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"GBMxavme-AfIVDKqI6WBJ4V5wZItsxJ9muhxPByllHQ"</span>, <span class="hljs-attr">"y"</span>: <span class="hljs-string">"SChlfVBhTXG_sRGc9ZdFeCYzI3Kbph3ivE12OFVk4jo"</span> }, <span class="hljs-attr">"privateKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"EC"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"secp256k1"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"GBMxavme-AfIVDKqI6WBJ4V5wZItsxJ9muhxPByllHQ"</span>, <span class="hljs-attr">"y"</span>: <span class="hljs-string">"SChlfVBhTXG_sRGc9ZdFeCYzI3Kbph3ivE12OFVk4jo"</span>, <span class="hljs-attr">"d"</span>: <span class="hljs-string">"m5N7gTItgWz6udWjuqzJsqX-vksUnxJrNjD5OilScBc"</span> } }, <span class="hljs-attr">"keypair_2"</span>: { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"#zwlFQYyCqQXZ3nzpxkxJFxlpGU2l8LZQ9gxIxDdEhuY"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"did:key:zUewtYk1yGS3SWp7kxrFK3DZRHMFbGEnrgFrqsi6hG8Z7EpRzbMP7d5y49HhrUv4tgV4DHCSoQUtF1NRNe43bymdi7K91PkwEGJRR4jv4Vb2mu2ZcBJXbw3d35JfqsVeLcwXFUi"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"EC"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"P-384"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"eQbMauiHc9HuiqXT894gW5XTCrOpeY8cjLXAckfRtdVBLzVHKaiXAAxBFeVrSB75"</span>, <span class="hljs-attr">"y"</span>: <span class="hljs-string">"YOjxhMkdH9QnNmGCGuGXJrjAtk8CQ1kTmEEi9cg2R9ge-zh8SFT1Xu6awoUjK5Bv"</span> }, <span class="hljs-attr">"privateKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"EC"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"P-384"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"eQbMauiHc9HuiqXT894gW5XTCrOpeY8cjLXAckfRtdVBLzVHKaiXAAxBFeVrSB75"</span>, <span class="hljs-attr">"y"</span>: <span class="hljs-string">"YOjxhMkdH9QnNmGCGuGXJrjAtk8CQ1kTmEEi9cg2R9ge-zh8SFT1Xu6awoUjK5Bv"</span>, <span class="hljs-attr">"d"</span>: <span class="hljs-string">"dXghMAzYZmv46SNRuxmfDIuAlv7XIhvlkPzW3vXsopB1ihWp47tx0hqjZmYO6fJa"</span> } } }</code></pre> </div> <div class="example" id="example-5"> <div class="marker"> <a class="self-link" href="#example-5">Example<bdi> 5</bdi></a> </div> <pre aria-busy="false"><code class="hljs json">{ <span class="hljs-attr">"message_0"</span>: <span class="hljs-string">"hello world"</span> }</code></pre> </div> <div class="example" id="example-6"> <div class="marker"> <a class="self-link" href="#example-6">Example<bdi> 6</bdi></a> </div> <pre aria-busy="false"><code class="hljs json">{ <span class="hljs-attr">"signature_0"</span>: <span class="hljs-string">"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..v_Tni1_9lPQsS52GOnCMTFp7vDRjZIcj3pmuY1mF9W7nMAH94DpGecNwdFsXrz09n9bDTd8gJFqXWZeWIGvUAA"</span>, <span class="hljs-attr">"signature_1"</span>: <span class="hljs-string">"eyJhbGciOiJFUzI1NksiLCJiNjQiOmZhbHNlLCJjcml0IjpbImI2NCJdfQ..dsgrLHXb5-VsUKVop4JJyO9dkFvJKRVNeOcEDD9nBAl3MqzJrJYfEfL8wArG-9ZjL12UD8btrJljZ7_C8p51mA"</span> }</code></pre> </div> <div class="example" id="example-7"> <div class="marker"> <a class="self-link" href="#example-7">Example<bdi> 7</bdi></a> </div> <pre aria-busy="false"><code class="hljs json">{ <span class="hljs-attr">"issuer_0"</span>: { <span class="hljs-attr">"@context"</span>: [ <span class="hljs-string">"https://www.w3.org/ns/did/v1"</span>, <span class="hljs-string">"https://w3id.org/security/suites/jws-2020/v1"</span>, { <span class="hljs-attr">"@base"</span>: <span class="hljs-string">"https://example.com/issuer/123"</span> } ], <span class="hljs-attr">"id"</span>: <span class="hljs-string">"https://example.com/issuer/123"</span>, <span class="hljs-attr">"publicKey"</span>: [ { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"#ovsDKYBjFemIy8DVhc-w2LSi8CvXMw2AYDzHj04yxkc"</span>, <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebKey2020"</span>, <span class="hljs-attr">"controller"</span>: <span class="hljs-string">"https://example.com/issuer/123"</span>, <span class="hljs-attr">"publicKeyJwk"</span>: { <span class="hljs-attr">"kty"</span>: <span class="hljs-string">"OKP"</span>, <span class="hljs-attr">"crv"</span>: <span class="hljs-string">"Ed25519"</span>, <span class="hljs-attr">"x"</span>: <span class="hljs-string">"CV-aGlld3nVdgnhoZK0D36Wk-9aIMlZjZOK2XhPMnkQ"</span> } } ], <span class="hljs-attr">"assertionMethod"</span>: [<span class="hljs-string">"#ovsDKYBjFemIy8DVhc-w2LSi8CvXMw2AYDzHj04yxkc"</span>] } }</code></pre> </div> <div class="example" id="example-8"> <div class="marker"> <a class="self-link" href="#example-8">Example<bdi> 8</bdi></a> </div> <pre aria-busy="false"><code class="hljs json">{ <span class="hljs-attr">"vc_template_0"</span>: { <span class="hljs-attr">"@context"</span>: [ <span class="hljs-string">"https://www.w3.org/2018/credentials/v1"</span>, <span class="hljs-string">"https://www.w3.org/2018/credentials/examples/v1"</span>, <span class="hljs-string">"https://w3id.org/security/suites/jws-2020/v1"</span> ], <span class="hljs-attr">"id"</span>: <span class="hljs-string">"http://example.gov/credentials/3732"</span>, <span class="hljs-attr">"type"</span>: [<span class="hljs-string">"VerifiableCredential"</span>, <span class="hljs-string">"UniversityDegreeCredential"</span>], <span class="hljs-attr">"issuer"</span>: { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:123"</span> }, <span class="hljs-attr">"issuanceDate"</span>: <span class="hljs-string">"2020-03-10T04:24:12.164Z"</span>, <span class="hljs-attr">"credentialSubject"</span>: { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:456"</span>, <span class="hljs-attr">"degree"</span>: { <span class="hljs-attr">"type"</span>: <span class="hljs-string">"BachelorDegree"</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Bachelor of Science and Arts"</span> } } }, <span class="hljs-attr">"vc_0"</span>: { <span class="hljs-attr">"@context"</span>: [ <span class="hljs-string">"https://www.w3.org/2018/credentials/v1"</span>, <span class="hljs-string">"https://www.w3.org/2018/credentials/examples/v1"</span>, <span class="hljs-string">"https://w3id.org/security/suites/jws-2020/v1"</span> ], <span class="hljs-attr">"id"</span>: <span class="hljs-string">"http://example.gov/credentials/3732"</span>, <span class="hljs-attr">"type"</span>: [<span class="hljs-string">"VerifiableCredential"</span>, <span class="hljs-string">"UniversityDegreeCredential"</span>], <span class="hljs-attr">"issuer"</span>: { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"https://example.com/issuer/123"</span> }, <span class="hljs-attr">"issuanceDate"</span>: <span class="hljs-string">"2020-03-10T04:24:12.164Z"</span>, <span class="hljs-attr">"credentialSubject"</span>: { <span class="hljs-attr">"id"</span>: <span class="hljs-string">"did:example:456"</span>, <span class="hljs-attr">"degree"</span>: { <span class="hljs-attr">"type"</span>: <span class="hljs-string">"BachelorDegree"</span>, <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Bachelor of Science and Arts"</span> } }, <span class="hljs-attr">"proof"</span>: { <span class="hljs-attr">"type"</span>: <span class="hljs-string">"JsonWebSignature2020"</span>, <span class="hljs-attr">"created"</span>: <span class="hljs-string">"2019-12-11T03:50:55Z"</span>, <span class="hljs-attr">"jws"</span>: <span class="hljs-string">"eyJhbGciOiJFZERTQSIsImI2NCI6ZmFsc2UsImNyaXQiOlsiYjY0Il19..MJ5GwWRMsadCyLNXU_flgJtsS32584MydBxBuygps_cM0sbU3abTEOMyUvmLNcKOwOBE1MfDoB1_YY425W3sAg"</span>, <span class="hljs-attr">"proofPurpose"</span>: <span class="hljs-string">"assertionMethod"</span>, <span class="hljs-attr">"verificationMethod"</span>: <span class="hljs-string">"https://example.com/issuer/123#ovsDKYBjFemIy8DVhc-w2LSi8CvXMw2AYDzHj04yxkc"</span> } } }</code></pre> </div> </section> <section id="conformance"><div class="header-wrapper"><h2 id="x5-conformance"><bdi class="secno">5. </bdi>Conformance</h2><a class="self-link" href="#conformance" aria-label="Permalink for Section 5."></a></div><p>As well as sections marked as non-normative, all authoring guidelines, diagrams, examples, and notes in this specification are non-normative. Everything else in this specification is normative.</p><p> The key words <em class="rfc2119">MAY</em>, <em class="rfc2119">MUST</em>, <em class="rfc2119">RECOMMENDED</em>, and <em class="rfc2119">SHOULD</em> in this document are to be interpreted as described in <a href="https://datatracker.ietf.org/doc/html/bcp14">BCP 14</a> [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc2119" title="Key words for use in RFCs to Indicate Requirement Levels">RFC2119</a></cite>] [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc8174" title="Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words">RFC8174</a></cite>] when, and only when, they appear in all capitals, as shown here. </p> <p> A <dfn id="dfn-conforming-document" tabindex="0" aria-haspopup="dialog" data-dfn-type="dfn">conforming document</dfn> is any concrete expression of the data model that complies with the normative statements in this specification. Specifically, all relevant normative statements in Sections <a href="#terminology" class="sec-ref"><bdi class="secno">2. </bdi>Terminology</a> and <a href="#suite-definition" class="sec-ref"><bdi class="secno">3. </bdi>Suite Definition</a> of this document <em class="rfc2119">MUST</em> be enforced. </p> <p> A <code>conforming processor</code> is any algorithm realized as software and/or hardware that generates or consumes a <a href="#dfn-conforming-document" class="internalDFN" data-link-type="dfn" id="ref-for-dfn-conforming-document-1">conforming document</a>. Conforming processors <em class="rfc2119">MUST</em> produce errors when non-conforming documents are consumed. </p> <p> This document also contains examples that contain JSON and JSON-LD content. Some of these examples contain characters that are invalid JSON, such as inline comments (<code>//</code>) and the use of ellipsis (<code>...</code>) to denote information that adds little value to the example. Implementers are cautioned to remove this content if they desire to use the information as valid JSON or JSON-LD. </p> </section> <section id="security-considerations"><div class="header-wrapper"><h2 id="x6-security-considerations"><bdi class="secno">6. </bdi>Security Considerations</h2><a class="self-link" href="#security-considerations" aria-label="Permalink for Section 6."></a></div> <p> The following section describes security considerations that developers implementing this specification should be aware of in order to create secure software. </p> <div class="note" role="note" id="issue-container-generatedID"><div role="heading" class="note-title marker" id="h-note" aria-level="3"><span>Note</span></div><p class="">This specification relies on URDNA2015, please review [<cite><a class="bibref" data-link-type="biblio" href="#bib-rdf-dataset-normalization" title="RDF Dataset Normalization 1.0">RDF-DATASET-NORMALIZATION</a></cite>].</p></div> <div class="note" role="note" id="issue-container-generatedID-0"><div role="heading" class="note-title marker" id="h-note-0" aria-level="3"><span>Note</span></div><p class="">This specification relies on [<cite><a class="bibref" data-link-type="biblio" href="#bib-iana_jose" title="JOSE">IANA_JOSE</a></cite>], please review [<cite><a class="bibref" data-link-type="biblio" href="#bib-rfc8725" title="JSON Web Token Best Current Practices">RFC8725</a></cite>].</p></div> <div class="issue" id="issue-container-number-1"><div role="heading" class="issue-title marker" id="h-issue" aria-level="3"><span>Issue 1</span></div><div class=""> TODO: We need to add a complete list of security considerations. </div></div> </section> <section id="references" class="appendix"><div class="header-wrapper"><h2 id="a-references"><bdi class="secno">A. </bdi>References</h2><a class="self-link" href="#references" aria-label="Permalink for Appendix A."></a></div><section id="normative-references"><div class="header-wrapper"><h3 id="a-1-normative-references"><bdi class="secno">A.1 </bdi>Normative references</h3><a class="self-link" href="#normative-references" aria-label="Permalink for Appendix A.1"></a></div> <dl class="bibliography"><dt id="bib-iana_jose">[IANA_JOSE]</dt><dd> <a href="https://www.iana.org/assignments/jose/jose.xhtml"><cite>JOSE</cite></a>. URL: <a href="https://www.iana.org/assignments/jose/jose.xhtml">https://www.iana.org/assignments/jose/jose.xhtml</a> </dd><dt id="bib-iso_8601">[ISO_8601]</dt><dd> <a href="https://en.wikipedia.org/wiki/ISO_8601"><cite>ISO_8601</cite></a>. URL: <a href="https://en.wikipedia.org/wiki/ISO_8601">https://en.wikipedia.org/wiki/ISO_8601</a> </dd><dt id="bib-ld-proofs">[LD-PROOFS]</dt><dd> <a href="https://w3c-ccg.github.io/ld-proofs"><cite>Linked Data Proofs 1.0</cite></a>. David Longley; Manu Sporny. Web Payments Community Group. CGDRAFT. URL: <a href="https://w3c-ccg.github.io/ld-proofs">https://w3c-ccg.github.io/ld-proofs</a> </dd><dt id="bib-rdf-dataset-normalization">[RDF-DATASET-NORMALIZATION]</dt><dd> <a href="http://json-ld.github.io/normalization/spec/"><cite>RDF Dataset Normalization 1.0</cite></a>. David Longley; Manu Sporny. JSON-LD Community Group. CGDRAFT. URL: <a href="http://json-ld.github.io/normalization/spec/">http://json-ld.github.io/normalization/spec/</a> </dd><dt id="bib-rdf-n-quads">[RDF-N-Quads]</dt><dd> <a href="http://json-ld.github.io/normalization/spec/"><cite>RDF 1.1 N-Quads</cite></a>. Gaven Carothers. Recommendation. URL: <a href="http://json-ld.github.io/normalization/spec/">http://json-ld.github.io/normalization/spec/</a> </dd><dt id="bib-rfc2119">[RFC2119]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc2119"><cite>Key words for use in RFCs to Indicate Requirement Levels</cite></a>. S. Bradner. IETF. March 1997. Best Current Practice. URL: <a href="https://www.rfc-editor.org/rfc/rfc2119">https://www.rfc-editor.org/rfc/rfc2119</a> </dd><dt id="bib-rfc4634">[RFC4634]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc4634"><cite>US Secure Hash Algorithms (SHA and HMAC-SHA)</cite></a>. D. Eastlake 3rd; T. Hansen. IETF. July 2006. Informational. URL: <a href="https://www.rfc-editor.org/rfc/rfc4634">https://www.rfc-editor.org/rfc/rfc4634</a> </dd><dt id="bib-rfc7515">[RFC7515]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc7515"><cite>JSON Web Signature (JWS)</cite></a>. M. Jones; J. Bradley; N. Sakimura. IETF. May 2015. Proposed Standard. URL: <a href="https://www.rfc-editor.org/rfc/rfc7515">https://www.rfc-editor.org/rfc/rfc7515</a> </dd><dt id="bib-rfc7517">[RFC7517]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc7517"><cite>JSON Web Key (JWK)</cite></a>. M. Jones. IETF. May 2015. Proposed Standard. URL: <a href="https://www.rfc-editor.org/rfc/rfc7517">https://www.rfc-editor.org/rfc/rfc7517</a> </dd><dt id="bib-rfc7638">[RFC7638]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc7638"><cite>JSON Web Key (JWK) Thumbprint</cite></a>. M. Jones; N. Sakimura. IETF. September 2015. Proposed Standard. URL: <a href="https://www.rfc-editor.org/rfc/rfc7638">https://www.rfc-editor.org/rfc/rfc7638</a> </dd><dt id="bib-rfc7696">[RFC7696]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc7696"><cite>Guidelines for Cryptographic Algorithm Agility and Selecting Mandatory-to-Implement Algorithms</cite></a>. R. Housley. IETF. November 2015. Best Current Practice. URL: <a href="https://www.rfc-editor.org/rfc/rfc7696">https://www.rfc-editor.org/rfc/rfc7696</a> </dd><dt id="bib-rfc7797">[RFC7797]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc7797"><cite>JSON Web Signature (JWS) Unencoded Payload Option</cite></a>. M. Jones. IETF. February 2016. Proposed Standard. URL: <a href="https://www.rfc-editor.org/rfc/rfc7797">https://www.rfc-editor.org/rfc/rfc7797</a> </dd><dt id="bib-rfc8037">[RFC8037]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc8037"><cite>CFRG Elliptic Curve Diffie-Hellman (ECDH) and Signatures in JSON Object Signing and Encryption (JOSE)</cite></a>. I. Liusvaara. IETF. January 2017. Proposed Standard. URL: <a href="https://www.rfc-editor.org/rfc/rfc8037">https://www.rfc-editor.org/rfc/rfc8037</a> </dd><dt id="bib-rfc8174">[RFC8174]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc8174"><cite>Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words</cite></a>. B. Leiba. IETF. May 2017. Best Current Practice. URL: <a href="https://www.rfc-editor.org/rfc/rfc8174">https://www.rfc-editor.org/rfc/rfc8174</a> </dd></dl> </section><section id="informative-references"><div class="header-wrapper"><h3 id="a-2-informative-references"><bdi class="secno">A.2 </bdi>Informative references</h3><a class="self-link" href="#informative-references" aria-label="Permalink for Appendix A.2"></a></div> <dl class="bibliography"><dt id="bib-rfc8725">[RFC8725]</dt><dd> <a href="https://www.rfc-editor.org/rfc/rfc8725"><cite>JSON Web Token Best Current Practices</cite></a>. Y. Sheffer; D. Hardt; M. Jones. IETF. February 2020. Best Current Practice. URL: <a href="https://www.rfc-editor.org/rfc/rfc8725">https://www.rfc-editor.org/rfc/rfc8725</a> </dd></dl> </section></section><p role="navigation" id="back-to-top"> <a href="#title"><abbr title="Back to Top">↑</abbr></a> </p><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-signature-suite" aria-label="Links in this document to definition: signature suite"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-signature-suite" aria-label="Permalink for definition: signature suite. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-signature-suite-1" title="§ 2. Terminology">§ 2. Terminology</a> </li><li> <a href="#ref-for-dfn-signature-suite-2" title="§ 3. Suite Definition">§ 3. Suite Definition</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-canonicalization-algorithm" aria-label="Links in this document to definition: canonicalization algorithm"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-canonicalization-algorithm" aria-label="Permalink for definition: canonicalization algorithm. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-canonicalization-algorithm-1" title="§ 2. Terminology">§ 2. Terminology</a> </li><li> <a href="#ref-for-dfn-canonicalization-algorithm-2" title="§ 3. Suite Definition">§ 3. Suite Definition</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-message-digest-algorithm" aria-label="Links in this document to definition: message digest algorithm"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-message-digest-algorithm" aria-label="Permalink for definition: message digest algorithm. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-message-digest-algorithm-1" title="§ 3. Suite Definition">§ 3. Suite Definition</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-canonical-form" aria-label="Links in this document to definition: canonical form"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-canonical-form" aria-label="Permalink for definition: canonical form. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-canonical-form-1" title="§ 2. Terminology">§ 2. Terminology</a> <a href="#ref-for-dfn-canonical-form-2" title="Reference 2">(2)</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-signature-algorithm" aria-label="Links in this document to definition: signature algorithm"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-signature-algorithm" aria-label="Permalink for definition: signature algorithm. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-signature-algorithm-1" title="§ 3. Suite Definition">§ 3. Suite Definition</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-linked-data-document" aria-label="Links in this document to definition: linked data document"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-linked-data-document" aria-label="Permalink for definition: linked data document. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-linked-data-document-1" title="§ 2. Terminology">§ 2. Terminology</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-linked-data-proof" aria-label="Links in this document to definition: linked data proof"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-linked-data-proof" aria-label="Permalink for definition: linked data proof. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-linked-data-proof-1" title="§ 2. Terminology">§ 2. Terminology</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-jsonwebkey2020" aria-label="Links in this document to definition: JsonWebKey2020"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-jsonwebkey2020" aria-label="Permalink for definition: JsonWebKey2020. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-jsonwebkey2020-1" title="§ 3.2 Verification Method">§ 3.2 Verification Method</a> </li><li> <a href="#ref-for-dfn-jsonwebkey2020-2" title="§ 3.2.1 JSON Web Key 2020">§ 3.2.1 JSON Web Key 2020</a> </li><li> <a href="#ref-for-dfn-jsonwebkey2020-3" title="§ 3.3.1 JSON Web Signature 2020">§ 3.3.1 JSON Web Signature 2020</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-jsonwebsignature2020" aria-label="Links in this document to definition: JsonWebSignature2020"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-jsonwebsignature2020" aria-label="Permalink for definition: JsonWebSignature2020. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-jsonwebsignature2020-1" title="§ 2. Terminology">§ 2. Terminology</a> <a href="#ref-for-dfn-jsonwebsignature2020-2" title="Reference 2">(2)</a> </li><li> <a href="#ref-for-dfn-jsonwebsignature2020-3" title="§ 3.3.1 JSON Web Signature 2020">§ 3.3.1 JSON Web Signature 2020</a> </li> </ul> </div><div class="dfn-panel" hidden="" role="dialog" aria-modal="true" id="dfn-panel-for-dfn-conforming-document" aria-label="Links in this document to definition: conforming document"> <span class="caret"></span> <div> <a class="self-link" href="#dfn-conforming-document" aria-label="Permalink for definition: conforming document. Activate to close this dialog.">Permalink</a> </div> <p><b>Referenced in:</b></p> <ul> <li> <a href="#ref-for-dfn-conforming-document-1" title="§ 5. Conformance">§ 5. Conformance</a> </li> </ul> </div><script id="respec-dfn-panel">(() => { // @ts-check if (document.respec) { document.respec.ready.then(setupPanel); } else { setupPanel(); } function setupPanel() { const listener = panelListener(); document.body.addEventListener("keydown", listener); document.body.addEventListener("click", listener); } function panelListener() { /** @type {HTMLElement} */ let panel = null; return event => { const { target, type } = event; if (!(target instanceof HTMLElement)) return; // For keys, we only care about Enter key to activate the panel // otherwise it's activated via a click. if (type === "keydown" && event.key !== "Enter") return; const action = deriveAction(event); switch (action) { case "show": { hidePanel(panel); /** @type {HTMLElement} */ const dfn = target.closest("dfn, .index-term"); panel = document.getElementById(`dfn-panel-for-${dfn.id}`); const coords = deriveCoordinates(event); displayPanel(dfn, panel, coords); break; } case "dock": { panel.style.left = null; panel.style.top = null; panel.classList.add("docked"); break; } case "hide": { hidePanel(panel); panel = null; break; } } }; } /** * @param {MouseEvent|KeyboardEvent} event */ function deriveCoordinates(event) { const target = /** @type HTMLElement */ (event.target); // We prevent synthetic AT clicks from putting // the dialog in a weird place. The AT events sometimes // lack coordinates, so they have clientX/Y = 0 const rect = target.getBoundingClientRect(); if ( event instanceof MouseEvent && event.clientX >= rect.left && event.clientY >= rect.top ) { // The event probably happened inside the bounding rect... return { x: event.clientX, y: event.clientY }; } // Offset to the middle of the element const x = rect.x + rect.width / 2; // Placed at the bottom of the element const y = rect.y + rect.height; return { x, y }; } /** * @param {Event} event */ function deriveAction(event) { const target = /** @type {HTMLElement} */ (event.target); const hitALink = !!target.closest("a"); if (target.closest("dfn:not([data-cite]), .index-term")) { return hitALink ? "none" : "show"; } if (target.closest(".dfn-panel")) { if (hitALink) { return target.classList.contains("self-link") ? "hide" : "dock"; } const panel = target.closest(".dfn-panel"); return panel.classList.contains("docked") ? "hide" : "none"; } if (document.querySelector(".dfn-panel:not([hidden])")) { return "hide"; } return "none"; } /** * @param {HTMLElement} dfn * @param {HTMLElement} panel * @param {{ x: number, y: number }} clickPosition */ function displayPanel(dfn, panel, { x, y }) { panel.hidden = false; // distance (px) between edge of panel and the pointing triangle (caret) const MARGIN = 20; const dfnRects = dfn.getClientRects(); // Find the `top` offset when the `dfn` can be spread across multiple lines let closestTop = 0; let minDiff = Infinity; for (const rect of dfnRects) { const { top, bottom } = rect; const diffFromClickY = Math.abs((top + bottom) / 2 - y); if (diffFromClickY < minDiff) { minDiff = diffFromClickY; closestTop = top; } } const top = window.scrollY + closestTop + dfnRects[0].height; const left = x - MARGIN; panel.style.left = `${left}px`; panel.style.top = `${top}px`; // Find if the panel is flowing out of the window const panelRect = panel.getBoundingClientRect(); const SCREEN_WIDTH = Math.min(window.innerWidth, window.screen.width); if (panelRect.right > SCREEN_WIDTH) { const newLeft = Math.max(MARGIN, x + MARGIN - panelRect.width); const newCaretOffset = left - newLeft; panel.style.left = `${newLeft}px`; /** @type {HTMLElement} */ const caret = panel.querySelector(".caret"); caret.style.left = `${newCaretOffset}px`; } // As it's a dialog, we trap focus. // TODO: when <dialog> becomes a implemented, we should really // use that. trapFocus(panel, dfn); } /** * @param {HTMLElement} panel * @param {HTMLElement} dfn * @returns */ function trapFocus(panel, dfn) { /** @type NodeListOf<HTMLAnchorElement> elements */ const anchors = panel.querySelectorAll("a[href]"); // No need to trap focus if (!anchors.length) return; // Move focus to first anchor element const first = anchors.item(0); first.focus(); const trapListener = createTrapListener(anchors, panel, dfn); panel.addEventListener("keydown", trapListener); // Hiding the panel releases the trap const mo = new MutationObserver(records => { const [record] = records; const target = /** @type HTMLElement */ (record.target); if (target.hidden) { panel.removeEventListener("keydown", trapListener); mo.disconnect(); } }); mo.observe(panel, { attributes: true, attributeFilter: ["hidden"] }); } /** * * @param {NodeListOf<HTMLAnchorElement>} anchors * @param {HTMLElement} panel * @param {HTMLElement} dfn * @returns */ function createTrapListener(anchors, panel, dfn) { const lastIndex = anchors.length - 1; let currentIndex = 0; return event => { switch (event.key) { // Hitting "Tab" traps us in a nice loop around elements. case "Tab": { event.preventDefault(); currentIndex += event.shiftKey ? -1 : +1; if (currentIndex < 0) { currentIndex = lastIndex; } else if (currentIndex > lastIndex) { currentIndex = 0; } anchors.item(currentIndex).focus(); break; } // Hitting "Enter" on an anchor releases the trap. case "Enter": hidePanel(panel); break; // Hitting "Escape" returns focus to dfn. case "Escape": hidePanel(panel); dfn.focus(); return; } }; } /** @param {HTMLElement} panel */ function hidePanel(panel) { if (!panel) return; panel.hidden = true; panel.classList.remove("docked"); } })()</script><script src="https://www.w3.org/scripts/TR/2021/fixup.js"></script></body></html>