Changes between Version 1 and Version 2 of NewMutableEncodingDesign


Ignore:
Timestamp:
2009-08-28T01:08:42Z (15 years ago)
Author:
warner
Comment:

copy in some of the proposed designs

Legend:

Unmodified
Added
Removed
Modified
  • NewMutableEncodingDesign

    v1 v2  
    4242    continue to need protection unless/until they too are replaced with
    4343    signature verification). However, it would also increase server load.
     44
     45== Filecap Length ==
     46
     47A likely security parameter K (=kappa) would be 96 or 128 bits, and most of
     48the filecaps will be some multiple of K.
     49
     50Assuming a {{{tahoe:}}} prefix and no additional metadata, here's what
     51various lengths of base62-encoded filecaps would look like:
     52
     53 * 1*K:
     54 * 96 {{{tahoe:14efs6T5YNim0vDVV}}}
     55 * 128 {{{tahoe:4V2uIYVX0PcHu9fQrJ3GSH}}}
     56 * 2*K:
     57 * 192 {{{tahoe:072Og6e75IOP9ZZsbR1Twjs6X5xXJnBAF}}}
     58 * 256 {{{tahoe:fZeioazoWrO62reiAjzUAyV0uz3ssh6Hnanv8cKMClY}}}
     59 * 3*K:
     60 * 288 {{{tahoe:11DriaxD9nipA10ueBvv5uoMoehvxgPerpQiXyvMPeiUUdtf6}}}
     61 * 384 {{{tahoe:3a31SqUbf8fpWE1opRCT3coDhRqTU7bDU2AvC3RQJBu6ZNFhVscyxA9slYtPVT79x}}}
     62
     63Adding 2 metadata characters and a clear separator gives us:
     64
     65 * 96: {{{tahoe:MW-14efs6T5YNim0vDVV}}}
     66 * 128: {{{tahoe:DW-4V2uIYVX0PcHu9fQrJ3GSH}}}
     67 * 192: {{{tahoe:MR-072Og6e75IOP9ZZsbR1Twjs6X5xXJnBAF}}}
     68 * 256: {{{tahoe:DR-fZeioazoWrO62reiAjzUAyV0uz3ssh6Hnanv8cKMClY}}}
     69 * 288: {{{tahoe:MR-11DriaxD9nipA10ueBvv5uoMoehvxgPerpQiXyvMPeiUUdtf6}}}
     70 * 384: {{{tahoe:MR-3a31SqUbf8fpWE1opRCT3coDhRqTU7bDU2AvC3RQJBu6ZNFhVscyxA9slYtPVT79x}}}
     71
     72= Design Proposals =
     73
     74== Commonalities ==
     75
     76 * once we get the ciphertext, it gets segmented and erasure-coded in the
     77   same way as immutable files. Shares include a merkle tree over the share
     78   blocks, and a second one over the ciphertext segments.
     79 * we'd like to add a merkle tree over the plaintext, without reintroducing
     80   the partial-information-guessing attack that prompted us to remove it.
     81   This means encrypting the nodes of this merkle tree with a key derived
     82   from the readcap.
     83 * We'll continue to use the signing layout of the current mutable files:
     84   there will be a UEB that includes the root of the hash trees (and
     85   everything else in the share), which will be hashed to compute the
     86   "roothash" (which changes with each publish). A block of data that
     87   includes the roothash and a sequence number (as well as any
     88   data-encrypting salt) will be signed.
     89 * It might be good to make the layout a bit more extensible, like the way
     90   that immutable files have a dictionary-like structure for the UEB.
     91 * In general, the share will always contain a full copy of the pubkey, for
     92   the benefit of server-side validation. I don't think it matters whether
     93   the pubkey is stored inside or outside of the signed block, but it will
     94   probably make the upload-time share-verification code simpler to put it
     95   inside.
     96 * In general, the storage-index will be equal to the pubkey. If the pubkey
     97   is too long for this, the storage-index will be a sufficiently-long secure
     98   hash of the pubkey. The SI must be long enough to meet our
     99   collision-resistance criteria.
     100
     101== ECDSA, semi-private keys, no traversalcap ==
     102
     103Zooko captured the current leading semi-private-key-using mutable file design
     104nicely in the [http://allmydata.org/~zooko/lafs.pdf "StorageSS08" paper]
     105(in Figure 3). The design is:
     106
     107 * (1K) writecap = K-bit random string (perhaps derived from user-supplied
     108   material) (remember, K=kappa, probably 128bits)
     109 * (2K) readcap = 2*K-bit semiprivate key
     110 * (2K) verifycap = 2*K-bit public key
     111 * storage-index = truncated verifycap
     112
     113On each publish, a random salt is generated and stored in the share. The data
     114is encrypted with H(salt, readcap) and the ciphertext stored in the share. We
     115store the usual merkle trees.
     116
     117This provides offline attenuation and full server-side validation. It removes
     118the need to pull a copy of the pubkey or encprivkey from just one of the
     119servers (the salt must still be fetched, but it's small and lives in the
     120signed block that must be fetched anyways).
     121
     122=== add traversalcap ===
     123
     124Like above, but create two levels of semiprivate keys instead of just one:
     125
     126 * (1K) writecap = K-bit random string
     127 * (2K) readcap = 2*K-bit first semiprivate key
     128 * (2K) traversalcap = 2*K-bit second semiprivate key
     129 * (2K) verifycap = 2*K-bit public key
     130 * storage-index = truncated verifycap
     131
     132The dirnode encoding would use H(writecap) to protect the child writecaps,
     133H(readcap) to protect the child readcaps, and H(traversapcap) to protect the
     134child verifycap/traversalcaps.
     135
     136== ECDSA, no semi-private keys, no traversalcap ==
     137
     138Without semi-private keys, we need something more complicated to protect the
     139readkey: the only thing that can be mathematically derived from the writecap
     140is the pubkey, and that can't be used to protect the data because it's public
     141(and used by the server to validate shares). One approach is to use the
     142current (discrete-log DSA) mutable file structure, and merely move the
     143private key out of the share and into the writecap:
     144
     145 * (1K) writecap = K-bit random string
     146 * (3K) readcap = H(writecap)[:K] + H(pubkey)
     147 * (2K) verifycap = H(pubkey)
     148 * storage-index = truncated verifycap
     149
     150In this case, the readcap/verifycap holder is obligated to fetch the pubkey
     151from one of the shares, since they cannot derive it themselves. This
     152preserves offline attenuation and server-side validation. The readcap grows
     153to (1+2)*K : we can truncate the AES key since we only need K bits for K-bit
     154confidentiality, but require 2*K bits on H(pubkey) to attain K-bit collision
     155resistance. The verifycap is 2*K.
     156
     157=== include pubkey in cap ===
     158
     159Or, if the pubkey is short enough, include it in the cap rather than
     160requiring the client to fetch a copy:
     161
     162 * (1K) writecap = K-bit random string
     163 * (3K) readcap = H(writecap)[:K] + pubkey
     164 * (2K) verifycap = pubkey
     165 * storage-index = H(pubkey)
     166
     167I think ECDSA pubkeys are 2*K long, so this would not change the length of
     168the readcaps. It would just simplify/speed-up the download process. If we
     169could use shorter hashes, then the H(pubkey) design might give us slightly
     170shorter keys.
     171
     172=== add traversalcap ===
     173
     174Since a secure pubkey identifier (either H(pubkey) or the original privkey)
     175is present in all caps, it's easy to insert arbitrary intermediate levels. It
     176doesn't even change the way the existing caps are used:
     177
     178 * (1K) writecap = K-bit random string
     179 * (3K) readcap = H(writecap)[:K] + H(pubkey)
     180 * (3K) traversalcap: H(readcap)[:K] + H(pubkey)
     181 * (2K) verifycap = H(pubkey)
     182 * storage-index = truncated verifycap