[tahoe-dev] how to encrypt, integrity-check, and offline-attenuate with only 2n bits
David-Sarah Hopwood
david-sarah at jacaranda.org
Tue Sep 8 22:38:12 PDT 2009
David-Sarah Hopwood wrote:
> I'll describe the immutable case first:
>
> let K1 = random symmetric key
> R = H_n(K1, H(plaintext))
> ciphertext = encrypt[K1](plaintext)
> V = H(ciphertext)
> K1_enc = encrypt[R](K1)
> storage_idx = H_n(R)
> V' = H_n(storage_idx, K1_enc, V)
> readcap = (R, V')
> verifycap = (storage_idx, V')
>
> The server stores (storage_idx, K1_enc, ciphertext).
>
> The verification check is
>
> verifycap.storage_idx == server.storage_idx &&
> verifycap.V' == H_n(server.storage_idx, server.K1_enc, H(server.ciphertext))
>
> There is an additional constraint on the encryption schemes used on
> K1 and the plaintext: if there are any additional random inputs to
> these schemes, such as IVs, they must be included in the input to
> the hash used to compute R (this is not shown above). Since the keys
> are only used once in the immutable protocol, it is probably simpler
> to avoid using random IVs.
Diagrams:
<http://jacaranda.org/tahoe/imm-short-readcap-davidsarah.png>
<http://jacaranda.org/tahoe/imm-short-readcap-davidsarah.svg>
The diagrams omit the intermediate hashes H(plaintext) and H(ciphertext),
since they are not strictly necessary. I've uppercased some of the variable
names to be consistent with Zooko's diagram.
> Explanation:
[...]
> However, these 2n bits do not need to all be in the value called R in
> Zooko's protocol. R needs to be at least n bits, in order to obtain
> sufficient security against brute-force attacks. However, it is possible
> for the other n bits of a readcap to encode information that both allows
> performing verification, and contributes to collision resistance.
I may not have been clear enough that this approach gives a confidentiality
strength of "only" 2^n, even though the read cap length is 2n bits. This
is a disadvantage, but I don't think it is a serious one as long as n is
chosen to be at least 128 bits.
> The mutable case is similar, but with added asymmetric sauce:
>
> let writecap = W = random seed
> K1 = KDF("K1", W)
> (K_sign, K_verify) = generate_keypair(KDF("key pair", W))
> R = H_n(K1, K_verify)
> ciphertext = encrypt[K1](plaintext)
> sig = sign[K_sign](ciphertext)
> K1_enc = encrypt[R](K1)
> storage_idx = H_n(R)
> V' = H_n(storage_idx, K1_enc, K_verify)
> readonlycap = R
> readverifycap = (R, V')
> verifycap = (storage_idx, V')
>
> The server stores (storage_idx, K1_enc, ciphertext, sig, K_verify).
>
> The verification check is
>
> verifycap.storage_idx == server.storage_idx &&
> verifycap.V' == H_n(server.storage_idx, server.K1_enc, server.K_verify) &&
> verify[server.K_verify](server.sig, server.ciphertext)
Diagram:
<http://jacaranda.org/tahoe/mut-short-readcap-davidsarah.png>
<http://jacaranda.org/tahoe/mut-short-readcap-davidsarah.svg>
Note that Firefox can render the SVG files, but does a poor job of it.
--
David-Sarah Hopwood ⚥ http://davidsarah.livejournal.com
More information about the tahoe-dev
mailing list