Each SDMF slot is created with a public/private key pair. The public key is
known as the "verification key", while the private key is called the
-"signature key". The private key and public key are concatenated and the
-result is hashed to form the "write key" (an AES symmetric key). The write
-key is then hashed to form the "read key". The read key is hashed to form the
-"storage index" (a unique string used as an index to locate stored data).
+"signature key". The private key is hashed to form the "write key" (an AES
+symmetric key). The write key is then hashed to form the "read key". The read
+key is hashed to form the "storage index" (a unique string used as an index
+to locate stored data).
-The public key is hashed by itself to form the "verification key hash". The
-private key is encrypted
+The public key is hashed by itself to form the "verification key hash".
The write key is hashed a different way to form the "write enabler master".
For each storage server on which a share is kept, the write enabler master is
truncating to 16 bytes. The IV is randomly generated each time the slot is
updated, and stored next to the encrypted data.
-The read-write URI consists of just the write key. The read-only URI contains
-the read key and the verification key hash.
+The read-write URI consists of the write key and the verification key hash.
+The read-only URI contains the read key and the verification key hash. The
+verify-only URI contains the storage index and the verification key hash.
+
+ URI:SSK-RW:b2a(writekey):b2a(verification_key_hash)
+ URI:SSK-RO:b2a(readkey):b2a(verification_key_hash)
+ URI:SSK-Verify:b2a(storage_index):b2a(verification_key_hash)
+
+Note that this allows the read-only and verify-only URIs to be derived from
+the read-write URI without actually retrieving the public keys. Also note
+that it means the read-write agent must validate both the private key and the
+public key when they are first fetched. All users validate the public key in
+exactly the same way.
The SDMF slot is allocated by sending a request to the storage server with a
desired size, the storage index, and the write enabler for that server's
* the signature key, encrypted with the write key
The access pattern for read is:
+ * hash read-key to get storage index
* use storage index to locate 'k' shares with identical 'R' values
* either get one share, read 'k' from it, then read k-1 shares
* or read, say, 5 shares, discover k, either get more or be finished
* submit plaintext to application
The access pattern for write is:
+ * hash write-key to get read-key, hash read-key to get storage index
* use the storage index to locate at least one share
* read verification key and encrypted signature key
* decrypt signature key using write-key
- * concatenate signature and verification keys, compare against write-key
- * hash verification key to form read-key
+ * hash signature key, compare against write-key
+ * hash verification key, compare against verification key hash
* encrypt plaintext from application with read-key
+ * application can encrypt some data with the write-key to make it only
+ available to writers (use this for transitive read-onlyness of dirnodes)
* erasure-code crypttext to form shares
* split shares into blocks
* compute Merkle tree of blocks, giving root "r" for each share