| 181 | | * (2K) verifycap = H(pubkey) |
| 182 | | * storage-index = truncated verifycap |
| | 186 | * verifycap = H(pubkey) |
| | 187 | * storage-index = truncated verifycap |
| | 188 | |
| | 189 | == Shorter readcaps == |
| | 190 | |
| | 191 | To make the readcap shorter, we must give up something, like complete |
| | 192 | server-side validation and complete offline attenuation. |
| | 193 | |
| | 194 | * (1K) writecap = K-bit random string = privkey |
| | 195 | * (1K) readcap = H(writecap)[:K] |
| | 196 | * storage-index = H(readcap) |
| | 197 | * verifycap = storage-index + pubkey |
| | 198 | |
| | 199 | The readcap is used as an HMAC key, and the share contains (inside the signed |
| | 200 | block) an HMAC of the pubkey. The readcap is also hashed with the per-publish |
| | 201 | salt to form the AES key with which the actual data is encrypted. |
| | 202 | |
| | 203 | The writecap begets the readcap, and the readcap begets the storage-index, so |
| | 204 | both writers and readers will be able to find the shares, and writecaps can |
| | 205 | be attenuated into readcaps offline. Wally the writecap-holder can generate |
| | 206 | the pubkey himself and not use (or validate) the value stored in the share. |
| | 207 | But Rose the readcap-holder must first retrieve the (pubkey,HMAC) pair and |
| | 208 | validate them, then she can use the pubkey to validate the rest of the share. |
| | 209 | |
| | 210 | Wally can generate the verifycap offline, but Rose cannot, since she has to |
| | 211 | fetch the pubkey first. |
| | 212 | |
| | 213 | The verifycap must contain a copy of the pubkey (or its hash), because the |
| | 214 | storage-index is not usable to validate the pubkey (the HMAC doesn't help, |
| | 215 | because it is keyed on the readcap, which is unavailable to the Val the |
| | 216 | verifycap-holder). And it must contain a copy of the storage-index, because |
| | 217 | the pubkey is insufficient to generate it. |
| | 218 | |
| | 219 | The storage-index must be derived from the readcap, not the pubkey, because |
| | 220 | the pubkey is too long to get into the readcap, and Rose the readcap-holder |
| | 221 | must have some way of getting the storage-index. |
| | 222 | |
| | 223 | The server can check the signature against the embedded pubkey, but has no |
| | 224 | way to confirm that the embedded pubkey is correct, because the validatable |
| | 225 | binding between pubkey and storage-index is only available to Rose. You could |
| | 226 | copy the verifycap into the share, but there's no cryptographic binding |
| | 227 | between it and the storage index. You could put a copy of the storage-index |
| | 228 | in the signed block, but again that doesn't prove that the storage-index is |
| | 229 | the right one. Only a scheme in which the storage-index is securely derived |
| | 230 | from the pubkey will give the desired property. |
| | 231 | |
| | 232 | Another possibility is to have a 2K-long readcap and put K bits of a pubkey |
| | 233 | hash in it. That would look like: |
| | 234 | |
| | 235 | * (1K) writecap = K-bit random string = privkey |
| | 236 | * (1K) storage-index = H(pubkey)[:K] |
| | 237 | * (2K) readcap = H(writecap)[:K] + storage-index |
| | 238 | * verifycap = storage-index |
| | 239 | |
| | 240 | This "half-verifycap" approach restores full offline attenuation, and gives |
| | 241 | the server 1K bits of validation, but reduces Val the verifycap-holder's |
| | 242 | validation bits in half (from 2K to 1K). A full verifycap, H(pubkey), could |
| | 243 | be generated offline by Wally, or by Rose after fetching the pubkey. You |
| | 244 | still need the HMAC on the pubkey to give Rose 2K confidence that she's got |
| | 245 | the right pubkey: the storage-index only gives 1K. |
| | 246 | |