diff --git a/src/Tahoe/SDMF/Internal/Keys.hs b/src/Tahoe/SDMF/Internal/Keys.hs index 3478225d46f7ddddfff4ccfc7ff82f3b247f0229..29c017f690e0605a0648527090b36245874ee2c2 100644 --- a/src/Tahoe/SDMF/Internal/Keys.hs +++ b/src/Tahoe/SDMF/Internal/Keys.hs @@ -97,9 +97,15 @@ deriveDataKey (SDMF_IV iv) r = sbs = B.take keyLength . taggedPairHash keyLength mutableDataKeyTag (B.pack . ByteArray.unpack $ iv) . ByteArray.convert . readKeyBytes $ r key = maybeCryptoError . cipherInit $ sbs +-- | Compute the storage index for a given read key for an SDMF share. mutableDataKeyTag :: B.ByteString mutableDataKeyTag = "allmydata_mutable_readkey_to_datakey_v1" +deriveStorageIndex :: Read -> StorageIndex +deriveStorageIndex r = StorageIndex si + where + si = taggedHash keyLength mutableStorageIndexTag . ByteArray.convert . readKeyBytes $ r + mutableStorageIndexTag :: B.ByteString mutableStorageIndexTag = "allmydata_mutable_readkey_to_storage_index_v1" diff --git a/src/Tahoe/SDMF/Keys.hs b/src/Tahoe/SDMF/Keys.hs index f5ba4ce1f1e5bb8d6a7a7a19e59e2cefb847a188..75a503bb0fe004711cec016738f5772075444f69 100644 --- a/src/Tahoe/SDMF/Keys.hs +++ b/src/Tahoe/SDMF/Keys.hs @@ -6,9 +6,11 @@ import Tahoe.SDMF.Internal.Keys ( Read (..), SDMF_IV (..), Signature (..), + StorageIndex (..), Write (..), deriveDataKey, deriveReadKey, + deriveStorageIndex, deriveWriteKey, toPublicKey, ) diff --git a/test/Spec.hs b/test/Spec.hs index b576ac03cbd1e9a4bec6e7772dbebd3093cacb11..cb08caaff95a66e0c852e074bcfacfd88296aa23 100644 --- a/test/Spec.hs +++ b/test/Spec.hs @@ -84,12 +84,14 @@ tests = expectedWriteKey = ("v7iymuxkc5yv2fomi3xwbjdd4e" :: T.Text) expectedReadKey = ("6ir6husgx6ubro3tbimmzskqri" :: T.Text) expectedDataKey = ("bbj67exlrkfcaqutwlgwvukbfe" :: T.Text) + expectedStorageIndex = ("cmkuloz2t6fhsh7npxxteba6sq" :: T.Text) -- Derive all the keys. (Just iv) = Keys.SDMF_IV <$> makeIV (B.replicate 16 0x42) (Just w@(Keys.Write _ derivedWriteKey)) = Keys.deriveWriteKey sigKey (Just r@(Keys.Read _ derivedReadKey)) = Keys.deriveReadKey w - (Just d@(Keys.Data _ derivedDataKey)) = Keys.deriveDataKey iv r + (Just (Keys.Data _ derivedDataKey)) = Keys.deriveDataKey iv r + (Keys.StorageIndex derivedStorageIndex) = Keys.deriveStorageIndex r -- A helper to format a key as text for convenient -- comparison to expected value. @@ -112,6 +114,10 @@ tests = "expected datakey /= derived datakey" expectedDataKey (fmtKey derivedDataKey) + assertEqual + "expected storage index /= derived storage index" + expectedStorageIndex + (T.toLower . encodeBase32Unpadded $ derivedStorageIndex) , testProperty "Share round-trips through bytes" $ property $ do share <- forAll shares diff --git a/test/expected_values.py b/test/expected_values.py index c85de972f46c9c233a0bd20c63eb322e035c7cf3..8ad03d95cf546650be06aa582bf0d00bed52053e 100644 --- a/test/expected_values.py +++ b/test/expected_values.py @@ -4,7 +4,11 @@ from allmydata.crypto import rsa from allmydata.mutable.common import derive_mutable_keys from allmydata.util import base32 -from allmydata.util.hashutil import ssk_readkey_hash, ssk_readkey_data_hash +from allmydata.util.hashutil import ( + ssk_readkey_hash, + ssk_readkey_data_hash, + ssk_storage_index_hash, +) # Arbitrarily select an IV. iv = b"\x42" * 16 @@ -15,11 +19,13 @@ with open("data/rsa-privkey-0.der", "rb") as f: writekey, encprivkey, fingerprint = derive_mutable_keys((pub, priv)) readkey = ssk_readkey_hash(writekey) datakey = ssk_readkey_data_hash(iv, readkey) +storage_index = ssk_storage_index_hash(readkey) print("SDMF") print("writekey: ", base32.b2a(writekey)) print("readkey: ", base32.b2a(readkey)) print("datakey: ", base32.b2a(datakey)) +print("storage index: ", base32.b2a(storage_index)) print("encrypted private key: ", base32.b2a(encprivkey)) print("signature key hash: ", base32.b2a(fingerprint))