You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adds the rotate_kps gRPC handler. Each current KP submits an encrypted
old share along with a state portion describing the rotation target
(new KP pubkeys, new N, new T, current commitments, current seq).
T-of-N digest-matched across submissions; the same digest is bound as
HPKE AAD on the encrypted share.
On reaching the current threshold the enclave:
- reconstructs the BTC key in memory from the old shares,
- re-splits it with fresh randomness for the new KP set using the
new (n, t),
- writes CurrentKeyState { seq = current_seq + 1, encrypted_shares,
secret_sharing_config } to key_state/.
Asymmetric rotation (new N/T differs from old) is supported.
Cross-checks: the KP-supplied current_share_commitments must match
what the enclave was given at operator_init (via SecretSharingConfig);
each old share is verified against those commitments before reaching
the digest-match step.
Tests cover happy path (symmetric + asymmetric), dup share, state
mismatch panic, share-not-matching-commitments, state commitments
not matching enclave, wrong pubkey count, duplicate new pubkeys, and
pre-operator-init rejection.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: crates/hashi-guardian/README.md
+2-2Lines changed: 2 additions & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,15 +18,15 @@ Where:
18
18
-`init_suffix` is a semantic label (`oi-attestation-unsigned`, `oi-guardian-info`, `pi-success-share-{share_id}`, `pi-enclave-fully-initialized`).
19
19
-`counter` is a zero-padded decimal sequence number (used in heartbeats only).
20
20
-`seq` (in `withdraw/`) is the zero-padded limiter sequence number consumed by the withdrawal.
21
-
-`sharing_seq` (in `secret_sharing/`) is a zero-padded rotation counter — `setup_new_key` writes `0`; future key-provisioner rotations will append`prev+1`.
21
+
-`sharing_seq` (in `secret_sharing/`) is a zero-padded rotation counter — `setup_new_key` writes `0`; each `rotate_kps` appends`prev+1`.
22
22
-`rand8` is a random 8-hex suffix to avoid key collisions (failures only — successes are uniquely keyed by seq).
23
23
24
24
## Stream semantics
25
25
26
26
-`init` logs are per-session and deterministic by semantic message kind.
27
27
-`heartbeat` logs are hour-partitioned and strictly ordered per session.
28
28
-`withdraw` logs are hour-partitioned. Successes are seq-sorted within a bucket so the KP rotating in the next enclave can recover limiter state by reading the lexicographically last success key.
29
-
-`secret_sharing` logs are flat (not date-partitioned). Each entry is a `SecretSharingLogMessage { encrypted_shares, secret_sharing_config }` written by `setup_new_key` (genesis, `sharing_seq=0`). KPs read the lexicographically last entry to learn the current authoritative commitments and to fetch their encrypted shares.
29
+
-`secret_sharing` logs are flat (not date-partitioned). Each entry is a `SecretSharingLogMessage { encrypted_shares, secret_sharing_config }` written by `setup_new_key` (genesis, `sharing_seq=0`) or `rotate_kps` (each rotation, `sharing_seq=prev+1`). KPs read the lexicographically last entry to learn the current authoritative scheme (commitments + N + T) and to fetch their encrypted shares.
0 commit comments