-
Notifications
You must be signed in to change notification settings - Fork 79
/
did-method-spec-template.html
589 lines (545 loc) · 31.4 KB
/
did-method-spec-template.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8'>
<title>Sovrin DID Method Specification</title>
<style>
#instructions {
border: dashed 1px black;
padding: 1em;
background-color:#d0d0d0;
}
.replace-me {
font-style:italic;
color:magenta
}
</style>
<script
src='https://www.w3.org/Tools/respec/respec-w3c-common'
class='remove'></script>
<script class='remove'>
var respecConfig = {
specStatus: "ED",
editors: [{
name: "Michael Lodder",
url: "https://evernym.com",
}, {
name: "Daniel Hardman",
url: "https://github.com/dhh1128"
}
],
processVersion: 2017,
edDraftURI: "https://github.com/sovrin-foundation/sovrin",
shortName: "sovrin"
};
</script>
</head>
<body>
<section class="introductory">
<h2>About</h2>
<p>The Sovrin DID method specification conforms to the requirements specified in the DID specification
currently published by the W3C Credentials Community Group. For more information about DIDs and
DID method specifications, please see the <a
href="https://github.com/WebOfTrustInfo/rebooting-the-web-of-trust-fall2017/blob/master/topics-and-advance-readings/did-primer.md"
target="_blank">DID Primer</a> and <a href="https://w3c-ccg.github.io/did-spec/">DID Spec</a>.</p>
</section>
<section id='abstract'>
<p>
Sovrin is a public ledger designed specifically and only for privacy-preserving
self-sovereign identity. The Sovrin Ledger is governed by the
international non-profit <a href="https://www.sovrin.org" target="_blank">Sovrin Foundation</a>.
As the only public ledger designed exclusively for self-sovereign identity,
Sovrin is optimized for DIDs and DID Documents. DIDs are created, stored,
and used with verifiable claims. This specification covers how these DIDs are
managed. It also describes related features of Sovrin of
particular interest to DID owners, guardians, and developers.
</p>
</section>
<section id='sotd'>
<p>
</p>
</section>
<section>
<h2>Sovrin DID Method </h2>
<p>The namestring that shall identify this DID method is: <code>sov</code></p>
<p>A DID that uses this method MUST begin with the following prefix: <code>did:sov</code>.
Per the DID specification, this string MUST be in lowercase. The remainder of the DID, after the prefix,
is the NSI specified below.</p>
</section>
<section>
<h2>Target System(s)</h2>
<p>This DID method applies to the Sovrin network in all its incarnations, beginning with Sovrin's
provisional launch on 31 July 2017.</p>
</section>
<section>
<h2>Namespace Specific Identifier (NSI)</h2>
<p>
The Sovrin DID scheme is defined by the following <a href="ftp://ftp.rfc-editor.org/in-notes/std/std68.txt">ABNF</a>:<br><br>
<code>
sovrin-did = "did:sov:" idstring *(":" subnamespace)<br>
idstring = 21*22(base58char)<br>
subnamespace = ALPHA *(ALPHA / DIGIT / "_" / "-")<br>
base58char = "1" / "2" / "3" / "4" / "5" / "6" / "7" / "8" / "9" / "A" / "B" / "C"<br/>
/ "D" / "E" / "F" / "G" / "H" / "J" / "K" / "L" / "M" / "N" / "P" / "Q"<br/>
/ "R" / "S" / "T" / "U" / "V" / "W" / "X" / "Y" / "Z" / "a" / "b" / "c"<br/>
/ "d" / "e" / "f" / "g" / "h" / "i" / "j" / "k" / "m" / "n" / "o" / "p"<br/>
/ "q" / "r" / "s" / "t" / "u" / "v" / "w" / "x" / "y" / "z"<br>
</code><br>
All Sovrin DIDs are base58 encoded using the Bitcoin/IPFS alphabets of a 16-byte uuid.
The encoding uses most alphas and digits, omitting 0OIl to avoid readability problems. This
gives an NSI length of either 21 or 22 characters, and it means that DIDs are case-sensitive and may not
be case-normalized, even though the prefix is always lower-case.<br>
<br>
Optional one or more sub namespaces may be specified to indicate which Sovrin system the DID should reference.
</p>
<h3>Namestring Generation Method</h3>
<p>The 16-byte uuid underlying a Sovrin DID can be generated in various ways--using standard uuid methods, for example, or
by selecting the first 16 bytes of a 256 bit Ed25519 verification key (the public
portion of the key pair). In the latter case, there may or may not be an active verification
key for the identity owner; that information is only available in the
key descriptions in the owner section of the DID Document.
</p>
<p>A convenient regex to match <code>sov</code> DIDs is: <br><br>
<code>^[1-9A-HJ-NP-Za-km-z]{21,22}$</code><br><br>
A convenient regex to match the entire did string is:<br><br>
<code>^did:sov:[1-9A-HJ-NP-Za-km-z]{21,22}(?<namespace>(?::\w[-\w]*)*)$</code>
</p>
<h3>Examples</h3>
<p>A valid <code>sov</code> DID might be: <code>did:sov:2wJPyULfLLnYTEFYzByfUR</code>.</p>
</section>
<section>
<h2>JSON-LD Context Definition</h2>
<p>On Sovrin, public DIDs and their corresponding documents are stored on the ledger.</p>
<p class="replace-me">TODO</p>
</section>
<section>
<h2>CRUD Operation Definitions</h2>
<h3>Create (Register)</h3>
<p>
The DID method specification must specify how a client creates a DID record—the combination of a DID and its associated document—on the
target system, including all cryptographic operations necessary to establish proof of ownership.
The Sovrin spec adds a new entry under <code>publicKey</code> called <code>authorizations</code>.
This is used to indicate possible authorizations the public key is supposed to have. The keyword <code>ALL</code> means that the public key can make whatever change it wants to the DID doc.
While creating a new DID doc, the field <code>authorizations</code> cannot be left empty. It has to either contain the keyword <code>ALL</code> or be omitted,
in that case it is assumed that the key has all authorizations.
</p>
<p>For example:</p>
<p>To create a DID, you must submit a <a href="https://hyperledger-indy.readthedocs.io/projects/node/en/latest/requests.html#nym">"NYM"</a> transaction that looks like this: <br>
<pre>
{
'operation': {
'type': <Transaction type -- NYM >,
'dest': <new DID that is being registered>,
'role': <Role given to the new DID -- based on network config>,
'verkey': <Key material encoded>,
},
'identifier': 'L5AD5g65TDQr1PPHHRoiGf' <Trust Anchor DID>,
'reqId': <A nonce for this transaction>,
'protocolVersion': 2,
'signature': <signature over this transaction from the Trust Anchor>
}
</pre> The transaction must be signed by a Trust Anchor and must provide an un-registered DID and a document of data
about that DID. Possible outcomes from the create operation include:
<ul>
<li>NACK: "Malformed transaction or missing required fields"</li>
<li>REJECT: "Authorization rules are invalid. DID already registered or non Trust Anchor authored the transaction or signature did not match”</li>
<li>SUCCESS: "Contains the sequence number of the transaction and the merkle proof"</li>
</ul>
</p>
<h4>DID Service Endpoint</h4>
<p>By convention, Indy DID Controllers often create an Indy ATTRIB object (using the <a href="https://hyperledger-indy.readthedocs.io/projects/node/en/latest/requests.html#attrib">"ATTRIB"</a>
transaction) related to the NYM with a raw value of "endpoint", and a URL that represents the service endpoint for the DID. As noted in the "Read" section of this specification
such an "endpoint" ATTRIB is read when resolving a DID and its data included in the resulting DID Document.
</p>
<h3>Read (Resolve)</h3>
<p>A Sovrin DID record can be looked up directly by the DID using a standard Sovrin GET_NYM transaction that simply
takes the DID and returns the DID record. The client trusts the DID record because it either receives the
same DID record from sufficient number of validators or it receives a proof of the DID record from a single validator
that the DID record is part of a merkle tree whose root has an aggregate signature from sufficient number of
validators.
</p>
<p>This is what the DID record query looks like</p>
<pre>
{
"submitterId": <Optional; DID of the author of this query>,
"reqId": <Optional; a nonce for this query>,
"operation": {
"did": <DID to be queried>,
"type": "GET_NYM"
}
}
</pre>
<p>Anyone can query a DID record by sending the above request. The response contains the data that can be used to create a DID document, as noted below.</p>
<h4>DID Service Endpoint</h4>
<p>When reading (resolving) a Sovrin DID, in addition to querying the DID record, a query MUST be performed for a related DID Service endpoint.
This is done by executing the <a href="https://hyperledger-indy.readthedocs.io/projects/node/en/latest/requests.html#get_attrib">"GET_ATTRIB"</a>
transaction. The format of the GET_ATTRIB request looks like
</p>
<pre>
{
"submitterId": <Optional; DID of the author of this query>,
"reqId": <Optional; a nonce for this query>,
"identifier": <Required; The DID being read/resolved>,
"operation": {
"raw": "{\"endpoint\":{\"endpoint\":\"https://example.com\"}}" <Required; the value must be endpoint>
}
}
</pre>
<p>The result may be a "Not Found" error, indicating the NYM does not have an optional corresponding ATTRIB <tt>endpoint</tt> record.
If the call is successful, the relevant part of the response of such a GET_ATTRIB request is:</p>
<pre>
{
...
'data': '{"endpoint":{"endpoint":"https://example.com/endpoint"}}',
'dest': 'AH4RRiPR78DUrCWatnCW2w' < The DID being read/resolved>,
'raw': 'endpoint',
...
}
</pre>
<p>The value of the inner <tt>endpoint</tt> item (<tt>https://example.com/endpoint</tt> in the example above) is the service endpoint for the DID.</p>
<p>Historically on the Sovrin MainNet (through June 2021), the format of the <tt>endpoint</tt> ATTRIB has been simply a single name ("endpoint") value (a URL) pair, as shown above.
An extended version of the <tt>endpoint</tt> ATTRIB MAY be written to an Indy ledger by a DID Controller to provide additional control over the generation of the DID Document.
The format is as follows:</p>
<pre>
{
"endpoint": "https://example.com",
"types": [ "endpoint", "did-communication", "DIDComm" ],
"routingKeys": [ "did:key12345", "did:key12345" ]
}
</pre>
<p>This corresponds to the raw value in the "ATTRIB" transaction as:</p>
<pre>
"raw": "{\"endpoint\":{\"endpoint\":\"https://example.com\",\"types\":[\"endpoint\",\"did-communication\",\"DIDComm\" ],\"routingKeys\":[\"did:key12345\",\"did:key12345\"]}}"
</pre>
<p>A <tt>did:sov</tt> resolver MUST process the <tt>endpoint</tt> ATTRIB (extended or not) as follows:</p>
<ul>
<li>If the <tt>types</tt> field is present it's entries MUST be <tt>endpoint</tt>, <tt>did-communication</tt> and/or <tt>DIDComm</tt>, generating entries in the DID Document <tt>service</tt> block.</li>
<ul><li>The three service block formats corresponding to the three types is defined in the next section of this document.</li></ul>
<li>If the endpoint is defined and the <tt>types</tt> item is NOT present, empty or contains any other values, default the <tt>types</tt> to <tt>"types": [ "endpoint", "did-communication" ]</tt>.</li>
<ul><li>Any <tt>did:sov</tt> DID wanting to include a DIDComm V2 (<tt>DIDComm</tt>) service entry MUST use the extended version of the "endpoint" ATTRIB with the <tt>types</tt> item included.</li></ul>
<li>If the <tt>routingKeys</tt> item is present, use its value as the array for <tt>routingKeys</tt> in the <tt>did-communication</tt> and <tt>DIDComm</tt> type service blocks.</li>
<li>If the <tt>routingKeys</tt> entry is not present, default to the it being an empty array (e.g. <tt>"routingKeys": [ ]</tt>)</li>
</ul>
<h4>Resolver DID Document Format</h4>
<p>The DID Document is generated by a resolver (not by the Indy/Sovrin ledger) by taking the GET_NYM and optional GET_ATTRIB/endpoint data and
rendering a DID Document as follows. See the notes following the rendering.
</p>
<pre>
{
"@context": [
"https://www.w3.org/ns/did/v1",
"https://w3id.org/security/suites/ed25519-2018/v1",
"https://w3id.org/security/suites/x25519-2019/v1"
],
"id": "did:sov:HR6vs6GEZ8rHaVgjg2WodM",
"verificationMethod": [
{
"type": "Ed25519VerificationKey2018",
"id": "did:sov:HR6vs6GEZ8rHaVgjg2WodM#key-1",
"publicKeyBase58": "9wvq2i4xUa5umXoThe83CDgx1e5bsjZKJL4DEWvTP9qe"
},
{
"type": "X25519KeyAgreementKey2019",
"id": "did:sov:HR6vs6GEZ8rHaVgjg2WodM#key-agreement-1",
"publicKeyBase58": "3mHtKcQFEzqeUcnce5BAuzAgLEbqKaV542pUf9xQ5Pf8"
}
],
"authentication": [
"did:sov:HR6vs6GEZ8rHaVgjg2WodM#key-1"
],
"assertionMethod": [
"did:sov:HR6vs6GEZ8rHaVgjg2WodM#key-1"
],
"keyAgreement": [
"did:sov:HR6vs6GEZ8rHaVgjg2WodM#key-agreement-1"
],
"service": [
{
"type": "endpoint",
"serviceEndpoint": "https://example.com/endpoint"
},
{
"id": "did:sov:HR6vs6GEZ8rHaVgjg2WodM#did-communication",
"type": "did-communication",
"priority": 0,
"recipientKeys": [
"did:sov:HR6vs6GEZ8rHaVgjg2WodM#key-agreement-1"
],
"routingKeys": [],
"accept": [
"didcomm/aip2;env=rfc19"
],
"serviceEndpoint": "https://example.com/endpoint"
}
]
}
</pre>
<p>If an <tt>endpoint</tt> ATTRIB does not exist for the NYM, the <tt>service</tt> block is an empty array (e.g. <tt>"service": []</tt></p>
<p>If the <tt>endpoint</tt> has a <tt>types</tt> item and that <tt>types</tt> item contains an entry <tt>"DIDComm"</tt>,
then the following extra service block is included:</p>
<pre>
{
"id": "did:sov:HR6vs6GEZ8rHaVgjg2WodM#didcomm-1",
"type": "DIDComm",
"serviceEndpoint": "https://example.com/endpoint",
"accept": [
"didcomm/v2"
],
"routingKeys": []
}
</pre>
In addition the service block, the following entry needs to be added to the <tt>@context</tt> array:
<pre>
"https://didcomm.org/messaging/contexts/v2"
</pre>
<h4>DID Document Notes</h4>
<p>The following are notes about the example DID Document above:
<ul>
<li>The DID Document text is boilerplate except for the "did:sov..." identifier, the public keys ("publicKeyBase58" values) and the references to the service endpoint ("serviceEndpoint").</li>
<li>The X25519 key MUST be derived from the ED25519 key by the resolver. The Indy "GET_NYM" call returns only the ED25519 key.</li>
<ul><li>Note that although the "keyAgreement" key is included in the DID Document, because of historical conventions it is the ED25519 key referenced in the <tt>recipientKeys</tt> item in the <tt>did-communication</tt> service block.
The pending "did:indy" DID Method will correct such conventions and provide Indy DID Controller clients with full control over the contents of their DID Documents.
</li></ul>
<li>If there is no result from the GET_ATTRIB transaction, the "service" item is NOT included in the document.</li>
<li>The entries in the service block are included based on the value or absence of the <tt>types</tt> item in the "endpoint" ATTRIB. The three entry formats cover the three "eras" of DIDComm,
AIP 1.0 (type "endpoint"), AIP 2.0 (type "did-communication") and DIDComm V2 (type "DIDComm").
</li>
<li>A DID controlled MAY use the extended form of the "endpoint" ATTRIB (see previous section of this document) to include <tt>routingKeys</tt> in the <tt>did-communication</tt> and <tt>DIDComm</tt> service block entries.</li>
</ul>
</p>
<h3>Update (Replace)</h3>
<p>To replace the DID document, the owner or guardian (guardianship ends once ownership begins) of the DID should send the following
transaction using a key referenced in the <strong>authentication</strong> property.
<pre>
{
"submitterId": <DID of the author of this query>,
"signature": [<signature over this transaction from the author>,]
"reqId": <a nonce for this query>,
"operation": {
"type": "NYM",
"did": <DID whose record needs to be updated>,
"document": {
"publicKey": [{
"id": <a valid unique identifier>
"type": <ED25519>
"publicKeyBase58": <Key material encoded in format>,
"authorizations": ["all"]
},{
"id": <a valid unique identifier>
"type": <ED25519>
"publicKeyBase58": <Key material encoded in format>
},{
"id": <a valid unique identifier>
"type": <ED25519>
"publicKeyBase58": <Key material encoded in format>
}],
"authentication": [{
"type": "ED25519SigningAuthenticationThreshold",
"threshold": <an integer>,
"publicKey": [<key references>]
}],
"service": [{
"type": <agentService, emailService, apiService, dnsService, authenticationService, etc>,
"serviceEndpoint": <A URI for the endpoint>
}]
}
}
}
</pre>
<br/>
This example shows how to update the DID document to require multiple signatures for authentication:
<pre>
{
"submitterId": "did:sov:qazWSX3erfcY459iLMh7",
"signature": ["1qaz2wsx3eeciguytGGVDR990ik=="]
"reqId": "897432983746n43g"
"operation": {
"type": "NYM",
"did": "did:sov:c432cDSGUASJN987jnJKb",
"document": {
"publicKey": [{
"id": "#key1",
"type": "ED25519VerificationKey",
"publicKeyBase58": ...
},{
"id": "#key2",
"type": "ED25519VerificationKey",
"publicKeyBase58": ...
},{
"id": "#key3",
"type": "ED25519VerificationKey",
"publicKeyBase58": ...
}],
"authentication": [{
"type": "ED25519SigningAuthenticationThreshold",
"threshold": 2,
"publicKey": ["#key1","#key2","#key3"]
}],
"service": [{
"type": "agentService",
"serviceEndpoint": "https://www.sovrin.org/agents"
}]
}
}
}
</pre>
</p>
<h3>Delete (Revoke)</h3>
<p>Deleting or revoking a verification key is not to be confused with temporary suspension or rotation. Deletion
sets an identity's verification key to null; this permanently terminates the identity's ability to operate
on the network because there is no key that the identity can use to authenticate itself--even to submit a
new key rotation request. It is irreversible.</p>
<p>Revocation may be appropriate
when a person dies or a business is legally dissolved. It does not remove any record or history of the
identity--it simply prevents any new history from accruing. This guarantees that
no malicious actor can recover and reactivate an identity that's dead.</p>
<p>The scope of deletion in Sovrin is one DID only. This does not prevent an entity from creating new DIDs;
it simply prevents an entity from reusing the old DID that has been terminated.</p>
<p> To revoke the document of the DID, the owner of
the DID should send the following transaction.
<pre>
{
"submitterId": <DID of the owner>,
"signature": <signature over this transaction from the DID in identifier>,
"reqId": <a nonce for this transaction>,
"operation": {
"type": "NYM",
"did": <DID whose key is being revoked>,
"document": null
}
}
</pre>
</p>
</section>
<section>
<h2>Security Considerations</h2>
<h3>Attacks</h3>
<p>Secure communication to the Sovrin Ledger uses <a href="http://curvezmq.org">CurveZMQ</a> to mitigate attacks like eavesdropping, replay, message insertion, deletion, modification, impersonation, and man-in-the-middle. Any vulnerabilities in that protocol will apply to Sovrin.</p>
<p>Sovrin uses a modified version of the Redundant Byzantinne Fault Tolerace protocol called <a href="https://github.com/hyperledger/indy-plenum/wiki">Plenum</a> to reach consensus.</p>
<p>Sovrin currently stores only the following data on the ledger:
<ul>
<li>Public DIDs/DID Documents which includes: public keys and service endpoints</li>
<li>Credential Schemas</li>
<li>Credential Definitions – the use of a specific Schema, by a specific DID for the purpose of issuing credentials and a reference to a Revocation Registry</li>
<li>Revocation Registries associated with Credential Definitions</li>
<li>Policy Registries – used for authorizing agents and a reference to a Policy Accumulator.</li>
<li>Policy Accumulators – proving authorizing agents in zero knowledge.</li>
</ul>
All confidential information such as cryptographic private keys are stored with end consumers of Sovrin.
</p>
<h3>Residual Risks</h3>
<p>We don't believe to have any residual risks at this time.</p>
<div class="replace-me">
<h3>Recovery From Key Compromise</h3>
<p>This section MUST provide integrity protection and update authentication for all operations required by Section 7 of this specification (DID Operations).</p>
<p><a href="https://en.wikipedia.org/wiki/Confused_deputy_problem" target="_blank">Confused Deputy Problem</a> when attempting separation of writeAuthorization from authenticationCredential.</p>
<p>Other sections from DID spec to incorporate into the outline:</p>
</div>
</section>
<section>
<h2>Privacy Considerations</h2>
<div>
Assume psuedonymous DID. What Sovrin is doing about privacy and addresses each of these.
<p>Considering <a href="http://www.lifewithalacrity.com/2015/04/the-four-kinds-of-privacy.html" target="_blank">all
four types of privacy</a>, explore issues from these sections of the DID spec:</p>
<pre style="color:magenta">
10. Privacy Considerations
10.1 Requirements of DID Method Specifications
10.2 Keep Personally-Identifiable Information (PII) Off-Ledger
10.3 DID Correlation Risks and Pseudonymous DIDs
10.4 Document Correlation Risks
10.5 Herd Privacy
</pre>
</div>
</section>
<section>
<h2>Reference Implementations</h2>
The code at <a href="https://github.com/hyperledger/indy-node/tree/stable" target="_blank">https://github.com/hyperledger/indy-node, stable</a>
and <a href="https://github.com/hyperledger/indy-sdk/tree/master" target="_blank">https://github.com/hyperledger/indy-sdk, master</a>
constitute a canonical implementation of Sovrin DIDs, and should be treated like an oracle.
<p>Note that the code includes a test suite; any other implementations should ensure that all tests pass before they claim compatibility.</p>
</section>
<section>
<h2>Resources</h2>
<p>Many developers maintaining the code and spec tend to hang out in RocketChat at chat.hyperledger.org, #indy and #indy-sdk.
You might also connect with us in Hyperledger and W3C working groups or at the semi-annual Internet Identity Workshop conferences.</p>
</section>
<section>
<h2>Appendix A: Key Algorithm Types</h2>
This is extracted from RFC 5480 and 5639:<br>
The NIST-named curves are:<br>
<br>
-- Note that in [X9.62] the curves are referred to as 'ansiX9' as<br>
-- opposed to 'sec'. For example, secp192r1 is the same curve as<br>
-- ansix9p192r1.<br>
<br>
-- Note that in [PKI-ALG] the secp192r1 curve was referred to as<br>
-- prime192v1 and the secp256r1 curve was referred to as<br>
-- prime256v1.<br>
<br>
-- Note that [FIPS186-3] refers to secp192r1 as P-192, secp224r1 as<br>
-- P-224, secp256r1 as P-256, secp384r1 as P-384, and secp521r1 as<br>
-- P-521.<br>
<br>
secp192r1 ... same as nistp192, prime192v1<br>
secp224r1 ... same as nistp224, prime224v1<br>
secp256k1 ... used by Bitcoin<br>
secp256r1 ... same as nistp256, prime256v1<br>
secp384r1 ... same as nistp384, prime384v1<br>
secp521r1 ... same as nistp521, prime521v1<br>
Curves from http://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf<br>
nistp192 ... same as secp192r1, prime192v1<br>
nistp224 ... same as secp224r1, prime224v1<br>
nistp256 ... same as secp256r1, prime256v1<br>
nistp384 ... same as secp384r1, prime384v1<br>
nistp521 ... same as secp521r1, prime521v1<br>
Curves from ANS X9.62<br>
prime192v1 ... same as nistp192, secp192r1<br>
prime192v2<br>
prime192v3<br>
prime224v1 ...same as nistp224, secp224r1<br>
prime239v1<br>
prime239v2<br>
prime239v3<br>
prime256v1 ... same as nistp256, secp256r1<br>
prime384v1 … same as nistp384, secp384r1<br>
prime521v1 ... same as nistp521, secp521r1<br>
<br>
Barreto Naehring curves are defined at <a href="https://tools.ietf.org/id/draft-kasamatsu-bncurves-01.html#rfc.section.4.3.1">ISO/IEC 15946-5</a>, <a href="https://eprint.iacr.org/2007/390.pdf">DevScoDah2007</a>, and <a href="https://fidoalliance.org/specs/fido-uaf-v1.1-id-20170202/fido-ecdaa-algorithm-v1.1-id-20170202.html">FIDO ECDAA Section 4</a>
<br><br>
The following are valid values for <strong>publicKey/type</strong><br><br>
<table border="1">
<tr><th>Key Type</th></tr>
<tr><td>rsa</td></tr>
<tr><td><a href="https://safecurves.cr.yp.to">Twisted Edwards/Montgomery Curves</a></td></tr>
<tr><td>m-221, e-222, ed1174, ed25519, ed383187, ed41417, e-382, m-383, ed448, e-521, m-511</td></tr>
<tr><td><a href="http://www.ecc-brainpool.org/download/Domain-parameters.pdf">BrainPool Curves</a></td></tr>
<tr><td>brainpoolp160r1, brainpoolp192r1, brainpoolp224r1, brainpoolp256r1, brainpoolp320r1, brainpoolp384r1, brainpoolp512r1</td></tr>
<tr><td><a href="http://www.secg.org/SEC2-Ver-1.0.pdf">SEC2 Curves</a></td></tr>
<tr><td>secp112r1, secp128r1, secp160r1, secp192r1, secp224r1, secp256r1, secp384r1, secp521r1</td></tr>
<tr><td>secp160k1, secp163k1, secp192k1, secp224k1, secp256k1</td></tr>
<tr><td>sect163r2, sect233r1, sect239r1, sect283r1, sect409r1, sect571r1</td></tr>
<tr><td><a href="https://tools.ietf.org/id/draft-kasamatsu-bncurves-01.html">Barreto Naehrig Curves</a></td></tr>
<tr><td>fp224bn, fp254bna, fp254bnb, fp256bn, fp384bn, fp512bn, fp638bn</td></tr>
</table>
</section>
<section>
<h2>Appendix B: Ed25519 Signature Suite</h2>
A description to the Ed25519 Signature Suite can be found <a href="https://w3c-dvcg.github.io/lds-ed255192018/">here</a>.
</section>
<section>
<h2>Appendix C: Public Key Authorizations</h2>
The following authorizations are supported:
<li>
<code>ADD_KEY</code>: Add new key to the DID doc. The new key can only have ADD_KEY authorization.
</li>
<li>
<code>REM_KEY</code>: Remove existing keys from the DID doc.
</li>
<li>
<code>ALL</code>: All possible authorizations. The key submitted during creation of DID doc has this authorisations.
The key with this authorization can add keys with ADD_KEY, REM_KEY and ALL authorization
</li>
</section>
</body>
</html>