feat(kt): add key revocation and Merkle-log audit support

Add RevocationLog with domain-separated leaf hashes (0x02 prefix) for
tracking revoked identity keys alongside the KT MerkleLog. Includes:

- RevocationLog with O(1) lookup, serialization, and double-revoke guard
- MerkleLog.append_raw() for pre-computed hashes
- MerkleLog.audit_log(start, end) for paginated log retrieval
- RevokeKey (510), CheckRevocation (511), AuditKeyTransparency (520) RPCs
- Server domain logic + v2 handlers + FileBackedStore/SqlStore persistence
- 4 new revocation tests + all 21 KT tests + 65 server tests passing
This commit is contained in:
2026-03-04 20:53:41 +01:00
parent f667281831
commit 1768f85258
11 changed files with 657 additions and 11 deletions

View File

@@ -93,6 +93,33 @@ impl MerkleLog {
.map(|i| i as u64)
}
/// Append a pre-computed leaf hash directly (used by revocation entries).
///
/// Returns the leaf index.
pub fn append_raw(&mut self, hash: [u8; 32]) -> u64 {
let idx = self.leaves.len() as u64;
self.leaves.push(hash);
idx
}
/// Return log entries in the range `[start, end)` as `(index, leaf_hash)` pairs.
///
/// Used for KT audit — clients download the full log and verify inclusion proofs.
/// Returns an empty vec if `start >= self.len()`.
pub fn audit_log(&self, start: u64, end: u64) -> Vec<(u64, [u8; 32])> {
let n = self.len();
let start = start.min(n) as usize;
let end = end.min(n) as usize;
if start >= end {
return Vec::new();
}
self.leaves[start..end]
.iter()
.enumerate()
.map(|(i, &h)| ((start + i) as u64, h))
.collect()
}
/// Serialise the log to bytes (bincode).
pub fn to_bytes(&self) -> Result<Vec<u8>, KtError> {
bincode::serialize(self)