> If you have some hash function H = sha256 let us say, you could calculate h = H('{"name" : "bob", "pubkey" : "1A1zP1e"}')[:N] and then set record[57] = h (I'll use a 24-bit h = 71b686 for my examples, OP suggests a 48-bit).
You're responding to an earlier revision of the blog post, and the design has been updated to not truncate salts this way (nor store them at all), based on feedback on the design.
> This seems...tricky, if you can't give the clients the "name" field because when you can't trust the client replicas to "forget" it when they're "supposed" to.
The ciphertext is the aspect that's committed to the Merkle tree. The plaintext and the key are not committed to the Merkle tree, and can be freely deleted. That's the important bit.
As for your other concern, the replication aspect is specified clearly.
https://github.com/fedi-e2ee/public-key-directory-specificat...
If a non-conformant replica persists copies of the plaintext indefinitely, then you can now use the same legal process to request erasure from the replica. If they do not comply, then you have the same amount of legal recourse you had to begin with. This becomes a lawyer problem, not a technology problem.
> How can the replicas verify a query result without having access to the redactable data?
The thing you can continue to verify, after a record has been forgotten, is all of the other records in the ledger.
Before erasure, that includes the record in question. After erasure, you shouldn't have anything to verify, except that history hasn't been altered beyond the decryption key being zeroed out.
If you assert your right to be forgotten, the system should forget. You can no longer be verified, because as far as the system is concerned, the record in scope does not exist.
But either way, history remains intact. You don't break the Merkle proofs.
You can erase records by zeroing out the key, but you cannot alter them in any other way.
The plaintext commitment prevents a server that's committed to a ciphertext, Enc(k1, Alice), from responding with a plaintext for Bob.
The commitment is a slow hash that's included in the calculation of the authentication tag over the ciphertext (which is what's committed to the Merkle tree). The tree survives.
If this still doesn't make sense, check the docs on GitHub.
> OP if you're reading, clarification would be most welcome :)
Here's a short and oversimplified workflow to help illustrate it:
Alice -> Directory:
[Encrypted Data], [Keys]
Directory -> SigSum:
[Encrypted Data]
Bob -> Directory:
[Alice]?
Directory -> Bob:
[Encrypted Data], [Plaintext], [Merkle Proofs over Encrypted Data]
Is that easier to follow?
If Alice later requests her keys deleted, then you end up with:
Bob -> Directory:
[Alice]?
Directory -> Bob:
[Encrypted Data], nil, [Merkle Proofs over Encrypted Data]