Repository navigation
Expand file tree
/
Copy pathindex.html
More file actions
1452 lines (1361 loc) · 65.3 KB
/
Copy pathindex.html
File metadata and controls
1452 lines (1361 loc) · 65.3 KB
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
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html><html lang="en"><head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>VHCEL v0.1</title>
<script src="./respec-config.js" class="remove"></script>
<script src="https://www.w3.org/Tools/respec/respec-w3c" class="remove" async=""></script>
<style>
/* Follow CEL's code, property-table, and algorithm conventions. */
:not(pre) > code { color: #b54300; color: light-dark(#b54300, #ffb380); font-weight: bold; }
pre { overflow-x: auto; white-space: pre-wrap; overflow-wrap: anywhere; }
table.simple { border-collapse: collapse; margin: 25px 0; width: 100%; border: 1px solid #ddd; }
table.simple thead tr { background-color: #005a9c; color: #fff; text-align: left; }
table.simple th, table.simple td { padding: 12px 15px; text-align: left; vertical-align: top; }
table.simple tbody tr { border-bottom: 1px solid #ddd; }
table.simple tbody tr:nth-of-type(even) { background-color: light-dark(#00000008, #ffffff08); }
table.simple tbody tr:last-of-type { border-bottom: 2px solid #005a9c; }
caption { text-align: left; font-weight: bold; margin-bottom: 0.5em; }
ol.algorithm, ol.algorithm ol { 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, ".") ") "; }
dt { margin-top: 1em; }
dd > p:first-child { margin-top: 0.3em; }
</style>
</head>
<body><!-- ReSpec moves this notice into the generated header. --><p class="copyright">Copyright and licensing terms are to be confirmed by the editors.</p><section id="abstract"><h2>Abstract</h2><p>This specification defines a processing model for maintaining and verifying
the history of an evolving data object using a Cryptographic Event Log.
Every history has a self-certifying identifier derived from genesis. The model
describes event continuity, authorization, state transitions, pre-rotation, and
witnessing, with application-specific behavior defined by profiles.</p></section>
<section id="sotd">
<p>This is version 0.1 of an exploratory editor's draft.
It is a proposal for discussion, not an adopted DIF or W3C specification.
The draft is maintained in the <a href="https://github.com/aviarytech/vhcel/">VHCEL repository</a>
and published on <a href="https://aviarytech.github.io/vhcel/">GitHub Pages</a>.
Editors, standards publication venue, and licensing are to be confirmed.</p>
<p>The draft specifies a history processing model. A concrete CEL binding and
application profile are still required for interoperable implementations.
Examples are conceptual; abbreviated digests and empty proof arrays are not test vectors.
Editorial issues identify choices that remain open.</p>
</section>
<section id="introduction">
<h2>Introduction</h2>
<p>This specification defines <strong>Verifiable History (VH)</strong>, a mechanism for
maintaining and verifying the history of an evolving data object using a
Cryptographic Event Log (CEL).</p>
<p>A Verifiable History consists of an ordered sequence of cryptographically
linked events. Each event describes an operation against an application-defined
state. Each non-genesis event is cryptographically bound to its predecessor.</p>
<p>Verifiers can independently establish that:</p>
<ul><li><p>the history begins with the expected genesis event, when an expected identity is supplied;</p>
</li>
<li><p>the supplied events satisfy their cryptographic commitments and predecessor links;</p>
</li>
<li><p>each state transition was authorized according to the applicable
authorization policy; and</p>
</li>
<li><p>the current state can be deterministically derived from the history.</p>
</li>
</ul>
<p>Verification alone does not establish that the supplied history is the latest
available history or the only valid branch. See <a href="#history-truncation"></a>
and <a href="#forks"></a>.</p>
<p>This specification defines the processing model necessary to construct and
verify a Verifiable History while delegating application-specific state
semantics to application specifications.</p>
<p>Verifiable History is independent of any particular identifier system,
transport, storage system, or application data model.</p>
<p>DID methods, digital assets, social objects, configuration systems, registries,
and other applications MAY define application specifications based on this
specification.</p>
<p>VHCEL builds on the history mechanisms of [[?DID-WEBVH]] and the
separation of events, operations, and external references in [[?CEL]].
This draft proposes an alignment; it does not establish wire compatibility
with either specification.</p>
<p>Many systems publish data whose value changes over time.</p>
<p>Examples include:</p>
<ul><li><p>DID Documents;</p>
</li>
<li><p>public keys and authorization policies;</p>
</li>
<li><p>digital assets;</p>
</li>
<li><p>social objects;</p>
</li>
<li><p>configuration documents;</p>
</li>
<li><p>registries; and</p>
</li>
<li><p>other persistent digital objects.</p>
</li>
</ul>
<p>Publishing only the latest representation of such an object does not provide
cryptographic evidence of how the object reached that state.</p>
<p>A Verifiable History provides that evidence.</p>
<p>Conceptually:</p>
<pre class="nohighlight example" title="Evolution of application state">Genesis Event
|
v
Event 1
|
v
Event 2
|
v
Event 3
|
v
Current State</pre>
<p>Each non-genesis event cryptographically commits to its predecessor. Application-defined
authorization rules determine whether an operation represented by an event is
permitted.</p>
<p>The resulting history can be verified independently of the system from which
the history was retrieved.</p>
<p>This distinction is fundamental:</p>
<blockquote><p>Discovery determines where a history can be found. Verifiable History
determines whether that history is authentic.</p>
</blockquote>
<p>A Verifiable History therefore does not require a blockchain, distributed
ledger, trusted database, or particular network protocol.</p>
<section id="design-goals" class="informative">
<h3>Goals</h3>
<p>This specification has the following design goals.</p>
<dl><dt id="transport-independence">Transport Independence</dt>
<dd>
<p>A Verifiable History MUST NOT depend upon a particular transport or storage
system for its integrity.</p>
<p>A conforming history MAY be distributed using HTTPS, local files, content
addressed storage, peer-to-peer networks, databases, or other mechanisms.</p>
</dd>
<dt id="application-independence">Application Independence</dt>
<dd>
<p>The core history format MUST NOT depend upon the semantics of the object whose
history is being represented.</p>
<p>Applications define how operations modify application state.</p>
</dd>
<dt id="independent-verification">Independent Verification</dt>
<dd>
<p>A verifier possessing a history and the required cryptographic material MUST
be able to verify that history without trusting the system from which the
history was retrieved.</p>
</dd>
<dt id="deterministic-processing">Deterministic Processing</dt>
<dd>
<p>Two conforming processors given the same valid history and application
specification MUST derive the same current state.</p>
</dd>
<dt id="cryptographic-agility">Cryptographic Agility</dt>
<dd>
<p>The format SHOULD permit cryptographic algorithms to evolve without requiring
a new history data model.</p>
</dd></dl></section>
<section id="terminology">
<h3>Terminology</h3>
<dl><dt id="verifiable-history"><dfn>Verifiable History</dfn></dt>
<dd>
<p>An ordered sequence of cryptographically linked events describing the evolution
of an object.</p>
</dd>
<dt id="cryptographic-event-log"><dfn>Cryptographic Event Log</dfn></dt>
<dd>
<p>The representation containing the events that comprise a Verifiable History.</p>
</dd>
<dt id="event"><dfn>Event</dfn></dt>
<dd>
<p>A record carrying an operation. Each non-genesis event also carries a
reference to the cryptographic digest of its immediate predecessor.</p>
</dd>
<dt id="genesis-event"><dfn>Genesis Event</dfn></dt>
<dd>
<p>The first event in a Verifiable History.</p>
</dd>
<dt id="event-identifier"><dfn>Event Identifier</dfn></dt>
<dd>
<p>A cryptographic digest identifying an event.</p>
</dd>
<dt id="previous-event"><dfn>Previous Event</dfn></dt>
<dd>
<p>The event immediately preceding another event.</p>
</dd>
<dt id="operation"><dfn>Operation</dfn></dt>
<dd>
<p>Application-defined information describing a proposed state transition.</p>
</dd>
<dt id="state"><dfn>State</dfn></dt>
<dd>
<p>The application-defined representation resulting from processing zero or more
operations.</p>
</dd>
<dt id="controller"><dfn>Controller</dfn></dt>
<dd>
<p>An entity authorized according to an application's authorization policy to
create an event.</p>
</dd>
<dt id="witness"><dfn>Witness</dfn></dt>
<dd>
<p>An entity that produces cryptographic evidence acknowledging an event.</p>
</dd>
<dt id="history-identifier"><dfn>History Identifier</dfn></dt>
<dd>
<p>The required Self-Certifying History Identifier (SCID), derived from genesis
and stable for the lifetime of a Verifiable History.</p>
</dd>
<dt id="application-specification"><dfn>Application Specification</dfn></dt>
<dd>
<p>A specification defining how a particular application interprets and processes
events.</p>
</dd></dl></section>
<section id="architecture">
<h3>Architecture</h3>
<p>For a concise prototype checklist, see the separate
<a href="implementation-guide.html">Short Implementation Guide</a>.</p>
<p>Verifiable History separates four concerns:</p>
<pre class="nohighlight example" title="History architecture">+--------------------------------+
| Application State |
+--------------------------------+
| Application Operations |
+--------------------------------+
| Verifiable History |
+--------------------------------+
| Cryptographic Event Log |
+--------------------------------+</pre>
<p>The Cryptographic Event Log establishes event integrity and ordering.</p>
<p>Verifiable History establishes continuity and history verification.</p>
<p>Application specifications establish authorization and state transition
semantics.</p>
<p>Transport and discovery are outside the scope of this specification.</p>
</section>
<section id="conformance">
<p>A conforming history MUST have a genesis-derived SCID and every non-genesis
event MUST reference its immediate predecessor through <code>previousEvent</code>.
SCIDs are a core requirement, not an optional application capability.</p>
<p>Conformance is relative to a named binding and application profile.
This draft alone does not define a complete interoperable wire protocol.</p>
<p>A conforming Verifiable History processor:</p>
<ul><li><p>MUST implement the history verification algorithm defined by this
specification;</p>
</li>
<li><p>MUST implement at least one compatible Cryptographic Event Log
representation;</p>
</li>
<li><p>MUST reject histories that fail required cryptographic or application
verification;</p>
</li>
<li><p>MUST NOT silently resolve forks unless permitted by the applicable
application specification; and</p>
</li>
<li><p>MUST expose sufficient verification results for callers to distinguish a
successfully verified history from an unverified representation.</p>
</li>
</ul>
<p>A conforming application specification MUST satisfy the requirements in
<a href="#application-specifications"></a>.</p>
</section></section>
<section id="data-model"><h2>Data Model</h2><p>For the design choices carried forward from related log formats, see <a href="#comparison-didwebvh"></a> and <a href="#comparison-cel"></a>.</p><p>The data model describes the events, operations, and policies that comprise a verifiable history. Concrete property names and encodings are selected by a CEL binding.</p><section id="event-model">
<h3>Event Entry</h3><p>A history contains one or more events. The following table summarizes the abstract event properties.</p>
<table class="simple"><caption>Conceptual event properties</caption><thead><tr><th scope="col">Property</th><th scope="col">Description</th></tr></thead>
<tbody>
<tr><td><code>operation</code></td><td>REQUIRED. Describes the application-defined state transition. See <a href="#operations-and-state"></a>.</td></tr>
<tr><td><code>previousEvent</code></td><td>REQUIRED for non-genesis events; absent at genesis. References the cryptographic digest of the immediately preceding event. See <a href="#event-chaining"></a>.</td></tr>
<tr><td><code>scid</code></td><td>REQUIRED in genesis. Identifies the entire history and is immutable. Subsequent events are bound to it through the chain. See <a href="#self-certifying-history-identifiers"></a>.</td></tr>
<tr><td><code>time</code></td><td>OPTIONAL. An asserted event timestamp. Its interpretation is defined by the application.</td></tr>
<tr><td>Authorization proofs</td><td>Required when the application policy requires authorization. Placement and proof coverage are defined by the CEL binding.</td></tr>
<tr><td>External references</td><td>OPTIONAL. Cryptographic commitments to data held outside the event. See <a href="#external-data"></a>.</td></tr>
<tr><td>Application properties</td><td>OPTIONAL. Additional information defined by the application specification.</td></tr>
</tbody></table><pre class="example language-json" title="Conceptual update event">{
"previousEvent": "<previous-event-digest>",
"time": "2026-09-12T07:00:00Z",
"operation": {
"type": "update",
"data": {}
},
"proof": []
}</pre>
<p>The event's identifier is computed from its protected content; it need not
be stored in the event. The <code>previousEvent</code> value is part of that
content. The history's SCID is established by genesis and is not repeated in
this update sketch. Exact placement and encoding MUST be specified by the
VHCEL binding; the examples illustrate the selected model, not a finalized
wire format.</p>
<p class="issue" id="issue-cel-binding">Select a concrete CEL version and define
its mapping to this model, including event envelopes, controller proofs,
witness proofs, mandatory SCIDs, predecessor references, and chunk boundaries.
[[?CEL]] is the alignment target; this model retains its explicit
<code>previousEvent</code> linkage, but compatibility has not yet been demonstrated.</p>
</section>
<section id="external-data">
<h3>External References</h3>
<p>An event MAY cryptographically commit to data that is not embedded directly in
the event.</p>
<p>Conceptually:</p>
<pre class="example language-json" title="Conceptual external data reference">{
"previousEvent": "<previous-event-digest>",
"operation": {
"type": "update",
"dataReference": {
"digestMultibase": "uEi..."
}
}
}</pre>
<p>The referenced data MAY be available from one or more locations.</p>
<p>The integrity of externally referenced data MUST be established from its
cryptographic digest and MUST NOT depend solely upon the location from which it
was retrieved.</p>
<p>This permits:</p>
<pre class="nohighlight example" title="Retrieving committed data"> +--> HTTPS
|
Event -> Hash +--> IPFS
|
+--> P2P
|
+--> local storage</pre>
<p>without changing the cryptographic identity of the referenced data.</p>
<p>If external data is required to validate or apply an operation, a processor
MUST retrieve and verify it before accepting the resulting state. If it is
unavailable, the processor MUST report incomplete verification or failure;
it MUST NOT report the dependent state as verified. Optional data MAY remain
unretrieved only when the application profile permits this, and the result
MUST identify that data as unverified.</p>
</section>
<section id="operations-and-state">
<h3>Operations and State</h3>
<p>An operation describes an application-defined state transition.</p>
<p>Common operation types MAY include:</p>
<pre class="nohighlight example" title="Illustrative operation types">create
update
deactivate</pre>
<p>Applications MAY define additional operation types.</p>
<p>The core Verifiable History processor MUST NOT assign semantics to application
operations beyond those required by this specification.</p>
<p>An application specification MUST define:</p>
<ol><li><p>valid operation types;</p>
</li>
<li><p>operation syntax;</p>
</li>
<li><p>the initial state construction algorithm;</p>
</li>
<li><p>the state transition algorithm; and</p>
</li>
<li><p>conditions under which an operation MUST be rejected.</p>
</li>
</ol>
<p>Given:</p>
<pre class="nohighlight example" title="State and operation notation">S(n) = application state after event n
O(n) = operation contained in event n</pre>
<p>state processing is conceptually:</p>
<pre class="nohighlight example" title="State transition model">S(0) = CREATE(O(0))
S(n) = APPLY(S(n-1), O(n))</pre>
</section>
<section id="self-certifying-history-identifiers">
<h3>Self-Certifying History Identifiers</h3>
<p>Every Verifiable History MUST have a <strong>Self-Certifying History Identifier
(SCID)</strong> derived from its genesis commitment. Genesis MUST carry this
value. The SCID identifies the history as a whole; an event identifier identifies
a particular event within that history.</p>
<p>The SCID MUST remain unchanged throughout the history, including when its
storage or discovery location changes. A successor MUST NOT establish a different
SCID for the same history. The chain binds subsequent events to the genesis SCID;
it does not require every event to repeat the value.</p>
<p>SCID derivation and event chaining are separate procedures. The SCID commits
to genesis. Each successor's <code>previousEvent</code> commits to the digest of
the completed preceding event. A stored current-event identifier and an
identifier-substitution procedure are not required.</p>
<pre class="nohighlight example" title="SCID and predecessor linkage">SCID = DERIVE_SCID(genesisTemplate)
E[0].scid = SCID
E[1].previousEvent = EVENT_DIGEST(E[0])
E[2].previousEvent = EVENT_DIGEST(E[1])</pre>
<p class="note">The stable SCID and the digest of the completed genesis event
serve different roles and are not assumed to be equal. The functions above
describe the processing relationship, not concrete cryptographic algorithms.</p>
<pre class="example language-json" title="Genesis with a required SCID (conceptual)">{
"scid": "<self-certifying-history-id>",
"operation": {
"type": "create",
"data": { "name": "Example object" }
},
"proof": [{ "proofValue": "<controller-proof>" }]
}</pre>
<p>A processor verifying from genesis MUST recompute the SCID and compare it
with the value carried by genesis. It MUST reject a missing or mismatched SCID.
If the caller supplies an expected SCID, the processor MUST also compare against
that value. Internal consistency alone does not establish that a supplied history
is the history the caller intended. See <a href="#genesis-substitution"></a>
for concrete attacks this expected-identity check addresses and its limits.</p>
<p class="issue" id="issue-scid">SCIDs are mandatory. Finalize the common genesis
commitment procedure, including coverage of initial state, authorization
material, and bootstrap policies; domain separation; canonicalization; encoding;
and deterministic treatment of the SCID field and
any embedded SCID references to avoid circular hash input. Placeholder processing
is one candidate for genesis derivation; it does not require replacing CEL's
<code>previousEvent</code> linkage. The exact derivation algorithm remains to be
specified by the binding.</p>
<pre class="nohighlight example" title="One history at multiple locations">SCID
|
+--> HTTPS location A
|
+--> HTTPS location B
|
+--> content-addressed network
|
+--> local archive</pre>
<p>The same SCID can be verified regardless of where the history is retrieved.</p>
</section>
<section id="authorization">
<h3>Authorization</h3>
<p>Applications MAY require events to be authorized.</p>
<p>An application specification using authorization MUST define:</p>
<ul><li><p>how controllers are identified;</p>
</li>
<li><p>how authorization keys are represented;</p>
</li>
<li><p>which cryptographic proof mechanisms are permitted;</p>
</li>
<li><p>which controllers may authorize each operation; and</p>
</li>
<li><p>how authorization changes over time.</p>
</li>
</ul>
<p>For non-genesis events, authorization MUST be evaluated under the policy
established by previously verified state. New keys in an event MUST NOT grant
that event authority unless the prior policy explicitly permits their use,
for example through a previously established pre-rotation commitment.
Genesis authorization MUST follow the application specification's bootstrap rules.</p>
<p>Conceptually:</p>
<pre class="nohighlight example" title="Authorization from the previous state">State N
|
+-- authorized keys: A, B
|
v
Event N+1
|
+-- proof from A</pre>
<p>The event is valid only if the authorization policy established by State N
permits A to authorize the operation.</p>
<p>This prevents an event from granting itself authority.</p>
</section>
<section id="authorization-transitions">
<h3>Authorization Transitions</h3>
<p>An operation MAY change the authorization policy governing subsequent events.</p>
<p>For example:</p>
<pre class="nohighlight example" title="Changing the active authorization key">Event N
Authorized:
Key A
|
| signed by A
v
Event N+1
Authorized:
Key B</pre>
<p>Event N+1 MUST be authorized according to the policy established before the
transition.</p>
<p>The new policy becomes effective only after Event N+1 has been successfully
verified. An application MAY permit Key B to authorize this transition when
the prior policy already authorizes its use through a verified commitment.</p>
</section>
<section id="pre-rotation">
<h3>Pre-Rotation</h3>
<p class="issue" id="issue-pre-rotation">Specify the exact committed key bytes,
commitment lifecycle, activation policy, and recovery behavior. Decide when
prior commitments authorize a revealing key to sign the transition.</p>
<p>A Verifiable History MAY support <strong>pre-rotation</strong>.</p>
<p>Pre-rotation allows a controller to commit to future authorization keys before
those keys become active.</p>
<p>For example:</p>
<pre class="nohighlight example" title="Committing to a future authorization key">Event N
Active:
Key A
Commitment:
HASH(Key B)
|
v
Event N+1
Reveal:
Key B</pre>
<p>A processor implementing pre-rotation MUST verify that newly activated
cryptographic material satisfies a commitment established by an earlier valid
event.</p>
<p>An application specification using pre-rotation MUST define:</p>
<ul><li><p>the commitment algorithm;</p>
</li>
<li><p>when commitments are established;</p>
</li>
<li><p>when committed keys may be revealed;</p>
</li>
<li><p>whether multiple future keys may be committed;</p>
</li>
<li><p>how unused commitments are handled; and</p>
</li>
<li><p>how authorization recovery interacts with pre-rotation.</p>
</li>
</ul>
<p>Pre-rotation enables compromise of an active authorization key to be
distinguished from possession of previously committed future key material.</p>
</section>
<section id="witnesses">
<h3>Witnesses</h3>
<p>An event MAY be acknowledged by one or more witnesses.</p>
<p>A witness produces cryptographic evidence committing to an event identifier.</p>
<p>Conceptually:</p>
<pre class="nohighlight example" title="Independent witness acknowledgments"> +--> Witness A
|
Event ------ +--> Witness B
|
+--> Witness C</pre>
<p>Witness proofs MUST NOT modify the identifier of the event they witness.</p>
<p>This permits witnesses to independently acknowledge the same immutable event.</p>
</section>
<section id="witness-policies">
<h3>Witness Policies</h3>
<p>Applications MAY define witness policies.</p>
<p>A witness policy MAY specify:</p>
<ul><li><p>authorized witnesses;</p>
</li>
<li><p>threshold requirements;</p>
</li>
<li><p>witness rotation;</p>
</li>
<li><p>witness proof mechanisms;</p>
</li>
<li><p>timing requirements; and</p>
</li>
<li><p>whether witnessing is required or advisory.</p>
</li>
</ul>
<p>For example:</p>
<pre class="nohighlight example" title="Two-of-three witness policy">Witnesses:
A
B
C
Threshold:
2</pre>
<p>In this example, an event is considered sufficiently witnessed when valid proofs from at least
two distinct authorized witnesses are present.</p>
<p>Witness policy changes MUST themselves occur through valid history operations.</p>
<p>The application specification MUST define which witness policy applies to a
policy-changing event, including any requirement for the old set, the new set,
or both. A processor MUST count distinct authorized witnesses, not the number
of signatures, when checking a threshold. Witness evidence MUST NOT substitute
for required controller authorization or operation validation.</p>
<p class="issue" id="issue-witness-transition">Define a common witness profile:
policy activation, rotation handover, receipt representation, threshold counting,
and the meaning of a witness acknowledgment remain to be standardized.</p>
</section></section>
<section id="serialization">
<h2>Serializations</h2>
<p class="issue" id="issue-serialization">Select the required exchange format,
media type, version negotiation, and any log chunking rules. Listing possible
formats below does not establish support or cross-format hash equivalence.</p>
<p>A Verifiable History MAY be serialized using any representation defined by a
compatible Cryptographic Event Log specification.</p>
<p>Possible serializations include:</p>
<ul><li><p>JSON;</p>
</li>
<li><p>JSON Lines;</p>
</li>
<li><p>CBOR; or</p>
</li>
<li><p>application-defined binary representations.</p>
</li>
</ul>
<p>Serialization MUST NOT alter the cryptographic meaning of an event.</p>
<p>Applications requiring interoperable exchange MUST identify the serialization
formats they support.</p>
</section>
<section id="algorithms"><h2>Algorithms</h2><p>The following processing rules define event identification, history continuity, and verification. A selected CEL binding supplies the cryptographic procedures referenced by these algorithms.</p><section id="event-identification">
<h3>Event Identification</h3>
<p>Every event MUST have a deterministic cryptographic identifier calculated
from its protected content. This identifier is the event's digest; it need not
be stored as a property of the event.</p>
<pre class="nohighlight example" title="Conceptual event digest calculation">EVENT_DIGEST(event) = ENCODE(HASH(CANONICALIZE(PROTECTED(event))))</pre>
<p>The binding MUST define protected fields, canonicalization, byte encoding,
digest algorithms, and identifier encoding. The protected content MUST include
the SCID carried by genesis and the <code>previousEvent</code> reference carried
by each successor. Witness receipts MUST remain outside the event identity
calculation.</p>
<p class="issue" id="issue-event-identity">CEL-style predecessor references are
the selected model. Finalize the event-digest procedure, controller-proof
inclusion and coverage, unknown-property handling, and algorithm transitions.
The conceptual formula is not yet an implementable hashing algorithm.</p>
<p>A verifier MUST reconstruct the hash input and calculate the identifier of
every event, including the final supplied event. It MUST check successor
references, required proofs, and any trusted event commitments against the
protected content or calculated identifiers as specified by the binding.
Calculating a digest alone does not authenticate an event.</p>
<p>Changing cryptographically protected content, including a predecessor reference,
MUST change the calculated identifier except with negligible cryptographic probability.</p>
</section>
<section id="event-chaining">
<h3>Event Chaining</h3>
<p>Every non-genesis event MUST carry a <code>previousEvent</code> reference to
the cryptographic digest of its immediate predecessor.</p>
<pre class="nohighlight example" title="Predecessor links">E[2] --> E[1] --> E[0] (genesis carries the SCID)
previousEvent references</pre>
<pre class="nohighlight example" title="Checking predecessor references">REQUIRE E[1].previousEvent == EVENT_DIGEST(E[0])
REQUIRE E[2].previousEvent == EVENT_DIGEST(E[1])</pre>
<p>A verifier compares each <code>previousEvent</code> with the calculated digest
of the immediately preceding verified event. A missing reference or a mismatch
MUST cause verification to fail.</p>
<p>This detects a broken link within the supplied sequence. An attacker may
still serve a valid prefix or an alternative authorized branch. The mandatory
SCID binds the history to genesis; it does not by itself establish freshness
or uniqueness of succession.</p>
</section>
<section id="genesis">
<h3>Genesis</h3>
<p>The first event in a Verifiable History is the <strong>genesis event</strong>.
It MUST establish the history's SCID and sufficient information to initialize
application state, and MUST satisfy the application's genesis requirements.</p>
<p>Genesis has no preceding event and MUST NOT carry a <code>previousEvent</code>
property. Its SCID MUST be verified according to the binding. The digest of the
completed genesis event is calculated for use by its successor and any applicable
proofs or trusted commitments.</p>
</section>
<section id="history-verification">
<h3>History Verification</h3>
<p>A conforming processor MUST perform the following steps, or an equivalent
algorithm producing the same result. Inputs are an ordered sequence
<code>E[0..n]</code>, the selected binding and application specification, and
any independently obtained expected SCID or trusted event commitment.</p>
<ol class="algorithm">
<li>Reject an empty sequence. Validate profile selection against the caller's
permitted configurations. Parse events using the selected binding and reject
ambiguous or unsupported representations and prohibited algorithms.</li>
<li>Require the SCID in <code>E[0]</code>. Reconstruct the genesis commitment,
calculate the SCID, and compare it with the supplied value. Reject a mismatch.
If the caller supplies an expected SCID, also require it to match.</li>
<li>Verify that <code>E[0]</code> satisfies the application's genesis rules.
Reject a <code>previousEvent</code> property at genesis. Calculate the digest
of the completed genesis event using the binding's event-digest procedure.</li>
<li>Validate the genesis operation and any external data needed to process it.
Verify every required genesis authorization proof, pre-rotation constraint,
and witness requirement under the application's bootstrap rules. Only then
initialize the verified state <code>S[0]</code>.</li>
<li>For each event <code>E[i]</code>, where <code>i > 0</code>:
<ol>
<li>Require <code>E[i].previousEvent</code> to match the calculated digest
of the verified <code>E[i-1]</code>. Reject a missing reference or a mismatch.</li>
<li>Calculate the digest of <code>E[i]</code>, including its
<code>previousEvent</code> reference, under the binding and algorithm-transition
rules permitted by the previously verified state.</li>
<li>Reject any attempt to change the history's SCID. If the binding permits
a repeated SCID, require it to match the genesis SCID.</li>
<li>Check whether <code>S[i-1]</code> permits a successor, including any
deactivation restrictions.</li>
<li>Validate the operation and retrieve and verify any external data
required to validate or apply it.</li>
<li>Verify required cryptographic proofs, their purpose and context, and
authorization using the policy established by <code>S[i-1]</code>.
Verify applicable pre-rotation reveals against previously verified commitments.</li>
<li>Verify required witness evidence over this event's calculated identifier
using the applicable witness policy and transition rules.</li>
<li>Apply the application state transition to a candidate state.
Commit it as <code>S[i]</code> only after all required checks succeed.</li>
</ol>
</li>
<li>Check any other trusted event commitment at the position and under the
rules specified by the application. Reject a mismatch or a missing required
commitment.</li>
<li>If competing successors are known, apply the application's fork policy.
Do not silently select a branch in the absence of such a policy.</li>
<li>Return the verified SCID, verified state, calculated identifier of the last
supplied event, verified event count, selected binding and application profile,
whether verification began at genesis or a checkpoint, the outcome of any
expected-SCID check, and application-defined metadata. Distinguish freshness
evidence and witness satisfaction from successful chain verification.</li>
</ol>
<p>If any required check fails, the processor MUST reject the history as a
successfully verified result. It MAY return diagnostics or a verified prefix,
but MUST identify the failure and MUST NOT present that prefix as verification
of the entire supplied history.</p>
<p>The returned state and metadata describe the scope of verification. They do
not prescribe a programming-language API or a serialized result format. A
boolean can answer a precisely scoped validation question, but does not by
itself communicate the verified state or whether verification began at genesis
or a trusted checkpoint.</p>
<p>A successful result describes the supplied sequence. A processor MUST NOT
claim global uniqueness, absence of undisclosed forks, or freshness without
additional evidence defined by the application.</p>
</section>
<section id="partial-histories">
<h3>Partial Histories</h3>
<p>Applications MAY permit verification from a trusted checkpoint rather than from
genesis.</p>
<p>An authenticated checkpoint MUST bind:</p>
<ul><li><p>the verified event identifier at which verification begins;</p>
</li>
<li><p>sufficient application state to continue processing subsequent events, including
authorization policy, active commitments, witness policy, and deactivation status; and
</p></li><li><p>the mandatory SCID and the applicable binding and application profile.</p>
</li>
</ul>
<p>Checkpoint verification starts with the authenticated checkpoint state and
continues with the successor checks in <a href="#history-verification"></a>.
It does not rerun genesis processing on the first supplied successor. The
checkpoint supplies the authenticated SCID and event identifier used to resume
verification. Any expected SCID MUST match the checkpoint SCID; accepting a
checkpoint does not independently verify the genesis derivation.</p>
<p>A processor MUST NOT represent a history verified only from a checkpoint as
having been independently verified from genesis.</p>
</section>
<section id="forks">
<h3>Forks</h3>
<p>Two valid events MAY reference the same previous event:</p>
<pre class="nohighlight example" title="Competing successors"> +--> Event B
|
Event A -----+
|
+--> Event C</pre>
<p>This condition constitutes a <strong>fork</strong>.</p>
<p>The core Verifiable History specification does not define a universal mechanism
for choosing between competing branches.</p>
<p>An application specification MUST define its fork policy if forks are possible.</p>
<p>A fork policy MAY:</p>
<ul><li><p>reject all forks;</p>
</li>
<li><p>select a branch according to application-defined consensus;</p>
</li>
<li><p>require witness evidence;</p>
</li>
<li><p>use external consensus;</p>
</li>
<li><p>preserve multiple branches.</p>
</li>
</ul>
<p>Processors MUST NOT silently select a branch unless the applicable application
specification defines how that selection is made.</p>
</section>
<section id="deactivation">
<h3>Deactivation</h3>
<p>An application MAY define an operation that permanently or temporarily prevents
further state transitions.</p>
<p>A deactivation operation MUST be authorized according to the state immediately
preceding the deactivation event.</p>
<p>An application specification MUST define whether events following deactivation
are permitted.</p>
</section></section>
<section id="application-specifications">
<h2>Application Specifications</h2>
<p>An application specification conforming to this specification MUST define:</p>
<ol><li><p>the application state model;</p>
</li>
<li><p>valid operations;</p>
</li>
<li><p>genesis processing consistent with the mandatory SCID derivation and event-identifier rules;</p>
</li>
<li><p>state transition processing;</p>
</li>
<li><p>authorization requirements, if applicable;</p>
</li>
<li><p>witness requirements, if applicable;</p>
</li>
<li><p>pre-rotation requirements, if applicable;</p>
</li>
<li><p>fork handling;</p>
</li>
<li><p>deactivation semantics, if applicable;</p>
</li>
<li><p>supported CEL serialization and cryptographic mechanisms; and</p>
</li>
<li><p>discovery mechanisms, if required.</p>
</li>
</ol>
<p>Application specifications SHOULD reuse standardized profiles rather than
defining equivalent mechanisms independently.</p>
<section id="discovery">
<h3>Discovery</h3>
<p>Discovery is explicitly separate from verification.</p>
<p>An application specification MAY define mechanisms for discovering a
Verifiable History.</p>
<p>For example:</p>
<pre class="nohighlight example" title="Discovery mechanisms">identifier
|
+--> HTTPS
+--> DNS
+--> DHT
+--> content-addressed network
+--> peer-to-peer protocol</pre>
<p>A discovery mechanism MUST NOT be considered authoritative merely because it
returned a history.</p>
<p>The returned history MUST still satisfy Verifiable History verification.</p>
</section>
<section id="did-application-profile" class="informative">
<h3>DID Application Profile</h3>
<p>A DID method MAY use Verifiable History to represent changes to a DID Document.</p>
<p>Such a profile could map:</p>
<table class="simple"><caption>Verifiable History concepts in a DID profile</caption><thead><tr><th scope="col">Verifiable History</th><th scope="col">DID profile</th></tr></thead>
<tbody><tr><td>History</td><td>DID history</td></tr>
<tr><td>Genesis</td><td>DID creation</td></tr>
<tr><td>State</td><td>DID Document</td></tr>
<tr><td>Update operation</td><td>DID update</td></tr>
<tr><td>Authorization</td><td>DID controller authority</td></tr>
<tr><td>Deactivation</td><td>DID deactivation</td></tr>
<tr><td>SCID</td><td>DID self-certifying identifier</td></tr></tbody></table>
<p>The DID profile SHOULD NOT redefine event chaining, hashing, witnessing, or
other mechanisms already defined by this specification or CEL profiles.</p>
</section>
<section id="did-webvh-application" class="informative">
<h3>did:webvh Application</h3>
<p class="note">This is a proposed decomposition of [[?DID-WEBVH]]. Existing
<code>did:webvh</code> logs retain their original hashing and proof semantics.
Renaming fields or wrapping an entry in CEL does not preserve its signatures.</p>
<p>A future <code>did:webvh</code> profile could be expressed as a Verifiable History application combining:</p>
<pre class="nohighlight example" title="Proposed did:webvh profile composition">Verifiable History
|
+-- CEL event representation
|
+-- Self-Certifying History Identifier
|
+-- Authorization
|
+-- Pre-Rotation
|
+-- Witness Policy
|
+-- DID state machine
|
+-- Web discovery</pre>
<p>The <code>did:webvh</code> specification remains responsible for:</p>
<ul><li><p>DID syntax;</p>
</li>
<li><p>DID-to-HTTPS transformation;</p>
</li>
<li><p>DID Document semantics;</p>
</li>
<li><p>web-based discovery;</p>
</li>
<li><p>DID portability;</p>
</li>
<li><p>DID URL behavior; and</p>
</li>
<li><p>DID-specific processing.</p>
</li>
</ul>
<p>Generic history mechanics SHOULD be defined by this specification rather than
independently by the DID method.</p>
</section></section>
<section id="security-considerations">
<h2>Security Considerations</h2>
<section id="hash-function-security">
<h3>Hash Function Security</h3>
<p>The integrity of a Verifiable History depends upon the collision and
second-preimage resistance of the selected hash function.</p>
<p>Applications MUST define acceptable cryptographic algorithms.</p>
<p>Applications SHOULD provide a migration mechanism for histories that use
algorithms that later become unsuitable.</p>
</section>
<section id="authorization-key-compromise">
<h3>Authorization Key Compromise</h3>
<p>Compromise of an active authorization key may permit unauthorized events to be
created.</p>
<p>Applications requiring stronger compromise resistance SHOULD use pre-rotation,
witnesses, or both.</p>
<p>Pre-rotation does not prevent an attacker who possesses both the active key and
the required future key material from authorizing subsequent transitions.</p>
<p>Applications SHOULD define recovery procedures appropriate to their threat
model.</p>
</section>
<section id="history-truncation">
<h3>History Truncation</h3>
<p>Hash chaining detects modification of known history but does not inherently
prove that a verifier has received the latest event.</p>
<p>Applications requiring freshness guarantees MUST define an additional
mechanism.</p>
<p>Such mechanisms MAY include:</p>
<ul><li><p>witness receipts;</p>
</li>
<li><p>trusted checkpoints;</p>
</li>
<li><p>independently published event identifiers;</p>
</li>
<li><p>transparency services;</p>
</li>
<li><p>periodic anchors;</p>
</li>
<li><p>application-defined heartbeat events; or</p>
</li>
<li><p>comparison with multiple independent sources.</p>
</li>
</ul>
<p>A verifier MUST NOT infer that a valid terminal event is the most recent event
solely because the supplied history is internally consistent.</p>
</section>
<section id="history-suppression">
<h3>History Suppression</h3>
<p>An attacker controlling a discovery or storage mechanism may suppress valid
events while continuing to serve an older valid prefix of the history.</p>
<p>Cryptographic event chaining alone does not detect this condition.</p>
<p>Applications concerned with suppression SHOULD permit verifiers to obtain
history information from independent sources or require freshness evidence from
witnesses or other external mechanisms.</p>
</section>
<section id="fork-attacks">
<h3>Fork Attacks</h3>
<p>A controller possessing valid authorization material may produce multiple
events referencing the same predecessor.</p>
<p>Each branch may be individually cryptographically valid.</p>
<p>Hash chaining therefore provides tamper evidence but does not, by itself,
provide consensus or uniqueness of succession.</p>
<p>Applications in which forks are security-significant MUST define a deterministic
fork policy or an external mechanism capable of identifying the accepted
branch.</p>
<p>Witnessing MAY reduce the ability to present inconsistent branches to different
verifiers, but witness behavior and threshold assumptions MUST be considered
part of the application's trust model.</p>
</section>
<section id="equivocation">
<h3>Equivocation</h3>
<p>A controller, witness, or publication service may present different valid
histories to different parties.</p>
<p>Applications requiring detection of equivocation SHOULD support exchange or
publication of event identifiers, witness receipts, checkpoints, or other
cryptographic commitments between independent observers.</p>
<p>A witness system does not prevent equivocation unless the witness protocol or
policy requires witnesses to detect or refuse conflicting histories.</p>
</section>
<section id="witness-compromise-and-collusion">
<h3>Witness Compromise and Collusion</h3>
<p>Witnesses are not inherently trusted authorities.</p>
<p>A compromised witness may sign an event it should not have acknowledged.</p>
<p>A set of colluding witnesses may acknowledge conflicting or unreviewed events
and satisfy a numerical threshold. This does not make a history that fails
authorization, integrity, or state transition checks valid.</p>
<p>Applications MUST select witness thresholds and witness independence assumptions
consistent with their threat model.</p>
<p>Where practical, witness sets SHOULD be chosen so that compromise of a single
administrative, infrastructure, or cryptographic domain does not satisfy the
required threshold.</p>
</section>
<section id="replay">
<h3>Replay</h3>
<p>A cryptographically valid event copied from one context into another may remain
cryptographically valid unless the signed or hashed event data binds the event