Key State Machine¶
Module: KERI.KeyState
Key state¶
The key state is the cumulative result of processing a KEL from inception through all subsequent events:
| Field | Type | Meaning |
|---|---|---|
prefix |
SAID | Identifier (immutable after inception) |
sequenceNumber |
Nat | Current sequence number |
lastDigest |
Digest | Digest of the most recent event |
signingThreshold |
Nat | Required signature count |
keys |
List Key | Current signing keys |
nextThreshold |
Nat | Threshold for next key set |
nextKeys |
List Digest | Commitments to next keys |
witnessThreshold |
Nat | Required witness receipt count |
witnesses |
List Key | Current witness set |
State transitions¶
stateDiagram-v2
[*] --> KeyState: Icp (initialState)
KeyState --> KeyState: Rot (rotate keys)
KeyState --> KeyState: Ixn (anchor data)
KeyState --> KeyState: Rct (no-op)
note right of KeyState
Guards checked on every transition:
- seqNum = prev + 1
- prefix matches
- not Icp
end note
initialState¶
Creates the initial key state from an inception event. Requires:
- Sequence number = 0
- No prior digest
applyEvent¶
graph TD
E[Event] --> CHK_SEQ{"seqNum =
state.seqNum + 1?"}
CHK_SEQ -->|no| NONE1[none]
CHK_SEQ -->|yes| CHK_PFX{"prefix
matches?"}
CHK_PFX -->|no| NONE2[none]
CHK_PFX -->|yes| CHK_TYPE{"event type?"}
CHK_TYPE -->|Icp| NONE3["none (rejected)"]
CHK_TYPE -->|Rot| ROT["Update keys,
next-key commitments,
witnesses"]
CHK_TYPE -->|Ixn| IXN["Update seqNum,
lastDigest"]
CHK_TYPE -->|Rct| RCT["Return state
unchanged"]
Applies a non-inception event to an existing state. Validates:
- Sequence number = current + 1
- Prefix matches
- Event type is not inception
Then updates the state according to the event type:
- Rotation: replaces keys, next-key commitments, updates witnesses
- Interaction: increments sequence number, updates last digest
- Receipt: no-op (state unchanged)
Proven invariants¶
Initialization¶
initial_state_seq_zero— The initial state always has sequence number 0initial_state_prefix— The initial state's prefix matches the inception event's prefix
Transition guards¶
apply_rejects_inception— You cannot apply an inception event to an existing state. Inception is only valid as the first event.apply_checks_sequence— A successfulapplyEventrequirese.sequenceNumber = ks.sequenceNumber + 1. Events cannot be applied out of order.apply_checks_prefix— A successfulapplyEventrequires the event's prefix to match the state's prefix. Events for a different identifier are rejected.
State updates¶
receipt_neutral— Receipt events leave the key state unchanged. They are acknowledgments, not mutations.apply_updates_sequence— For non-receipt events, a successful application increments the sequence number by exactly 1.