BIG COMPATIBILITY BREAK: update hash tags, switch to SHA-256d everywhere
authorBrian Warner <warner@allmydata.com>
Fri, 15 Feb 2008 02:58:01 +0000 (19:58 -0700)
committerBrian Warner <warner@allmydata.com>
Fri, 15 Feb 2008 02:58:01 +0000 (19:58 -0700)
src/allmydata/test/test_cli.py
src/allmydata/test/test_util.py
src/allmydata/util/hashutil.py

index fe1dad44dc29645a328b79d0acd36b613c1450f4..0868d5a436e73d8bef55c28103ce3471f4759bc2 100644 (file)
@@ -88,38 +88,38 @@ class CLI(unittest.TestCase):
                            total_shares=total_shares,
                            size=size)
         output = self._dump_cap(u.to_string())
-        self.failUnless("CHK File:" in output)
+        self.failUnless("CHK File:" in output, output)
         self.failUnless("key: aaaqeayeaudaocajbifqydiob4" in output, output)
-        self.failUnless("UEB hash: 4d5euev6djvynq6vrg34mpy5xi3vl5x7oumdthqky6ovcy4wbvtq" in output, output)
-        self.failUnless("size: 1234" in output)
-        self.failUnless("k/N: 25/100" in output)
-        self.failUnless("storage index: kmkbjguwmkxej3wejdcvu74zki" in output, output)
+        self.failUnless("UEB hash: nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa" in output, output)
+        self.failUnless("size: 1234" in output, output)
+        self.failUnless("k/N: 25/100" in output, output)
+        self.failUnless("storage index: hdis5iaveku6lnlaiccydyid7q" in output, output)
 
         output = self._dump_cap("--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa",
                                 u.to_string())
-        self.failUnless("client renewal secret: jltcy6cppghq6ha3uzcawqr2lvwpzmw4teeqj2if6jd2vfpit6hq" in output, output)
+        self.failUnless("client renewal secret: znxmki5zdibb5qlt46xbdvk2t55j7hibejq3i5ijyurkr6m6jkhq" in output, output)
 
         output = self._dump_cap(u.get_verifier().to_string())
-        self.failIf("key: " in output)
-        self.failUnless("UEB hash: 4d5euev6djvynq6vrg34mpy5xi3vl5x7oumdthqky6ovcy4wbvtq" in output, output)
-        self.failUnless("size: 1234" in output)
-        self.failUnless("k/N: 25/100" in output)
-        self.failUnless("storage index: kmkbjguwmkxej3wejdcvu74zki" in output, output)
+        self.failIf("key: " in output, output)
+        self.failUnless("UEB hash: nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa" in output, output)
+        self.failUnless("size: 1234" in output, output)
+        self.failUnless("k/N: 25/100" in output, output)
+        self.failUnless("storage index: hdis5iaveku6lnlaiccydyid7q" in output, output)
 
         prefixed_u = "http://127.0.0.1/uri/%s" % urllib.quote(u.to_string())
         output = self._dump_cap(prefixed_u)
-        self.failUnless("CHK File:" in output)
+        self.failUnless("CHK File:" in output, output)
         self.failUnless("key: aaaqeayeaudaocajbifqydiob4" in output, output)
-        self.failUnless("UEB hash: 4d5euev6djvynq6vrg34mpy5xi3vl5x7oumdthqky6ovcy4wbvtq" in output, output)
-        self.failUnless("size: 1234" in output)
-        self.failUnless("k/N: 25/100" in output)
-        self.failUnless("storage index: kmkbjguwmkxej3wejdcvu74zki" in output, output)
+        self.failUnless("UEB hash: nf3nimquen7aeqm36ekgxomalstenpkvsdmf6fplj7swdatbv5oa" in output, output)
+        self.failUnless("size: 1234" in output, output)
+        self.failUnless("k/N: 25/100" in output, output)
+        self.failUnless("storage index: hdis5iaveku6lnlaiccydyid7q" in output, output)
 
     def test_dump_cap_lit(self):
         u = uri.LiteralFileURI("this is some data")
         output = self._dump_cap(u.to_string())
-        self.failUnless("Literal File URI:" in output)
-        self.failUnless("data: this is some data" in output)
+        self.failUnless("Literal File URI:" in output, output)
+        self.failUnless("data: this is some data" in output, output)
 
     def test_dump_cap_ssk(self):
         writekey = "\x01" * 16
@@ -127,52 +127,52 @@ class CLI(unittest.TestCase):
         u = uri.WriteableSSKFileURI(writekey, fingerprint)
 
         output = self._dump_cap(u.to_string())
-        self.failUnless("SSK Writeable URI:" in output)
+        self.failUnless("SSK Writeable URI:" in output, output)
         self.failUnless("writekey: aeaqcaibaeaqcaibaeaqcaibae" in output, output)
-        self.failUnless("readkey: x4gowaektauqze4y2sbsd5peye" in output, output)
-        self.failUnless("storage index: rqx7xnpexjxuqprto6pezagdxi" in output, output)
+        self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output)
+        self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output)
         self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output)
 
-        output = self._dump_cap("--client-secret", "tylkpgr364eav3ipsnq57yyafu",
+        output = self._dump_cap("--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa",
                                 u.to_string())
-        self.failUnless("file renewal secret: cs54qwurfjmeduruapo46kqwexpcvav5oemczblonglj6xmoyvkq" in output, output)
+        self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output)
 
         fileutil.make_dirs("cli/test_dump_cap/private")
         f = open("cli/test_dump_cap/private/secret", "w")
-        f.write("y6c7q34mjbt5kkf6hb3utuoj7u\n")
+        f.write("5s33nk3qpvnj2fw3z4mnm2y6fa\n")
         f.close()
         output = self._dump_cap("--client-dir", "cli/test_dump_cap",
                                 u.to_string())
-        self.failUnless("file renewal secret: 4jkip4ie2zgmbhcni6g4vmsivwuakpbw7hwnmdancsc6fkrv27kq" in output, output)
+        self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output)
 
         output = self._dump_cap("--client-dir", "cli/test_dump_cap_BOGUS",
                                 u.to_string())
-        self.failIf("file renewal secret:" in output)
+        self.failIf("file renewal secret:" in output, output)
 
         output = self._dump_cap("--nodeid", "tqc35esocrvejvg4mablt6aowg6tl43j",
                                 u.to_string())
-        self.failUnless("write_enabler: eok7o6u26dvl3abw4ok7kqrka4omdolnsx627hpcvtx3kkjwsu5q" in output, output)
-        self.failIf("file renewal secret:" in output)
+        self.failUnless("write_enabler: mgcavriox2wlb5eer26unwy5cw56elh3sjweffckkmivvsxtaknq" in output, output)
+        self.failIf("file renewal secret:" in output, output)
 
         output = self._dump_cap("--nodeid", "tqc35esocrvejvg4mablt6aowg6tl43j",
-                                "--client-secret", "6orzlv22ggdhphjpmsixcbwufq",
+                                "--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa",
                                 u.to_string())
-        self.failUnless("write_enabler: eok7o6u26dvl3abw4ok7kqrka4omdolnsx627hpcvtx3kkjwsu5q" in output, output)
-        self.failUnless("file renewal secret: aabhsp6kfsxb57jzdan4dnyzcd3m2prx34jd4z5nj5t5a7guf5fq" in output, output)
-        self.failUnless("lease renewal secret: bajcslergse474ga775msalmxxapgwr27lngeja4u7ef5j7yh4bq" in output, output)
+        self.failUnless("write_enabler: mgcavriox2wlb5eer26unwy5cw56elh3sjweffckkmivvsxtaknq" in output, output)
+        self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output)
+        self.failUnless("lease renewal secret: 7pjtaumrb7znzkkbvekkmuwpqfjyfyamznfz4bwwvmh4nw33lorq" in output, output)
 
         u = u.get_readonly()
         output = self._dump_cap(u.to_string())
-        self.failUnless("SSK Read-only URI:" in output)
-        self.failUnless("readkey: x4gowaektauqze4y2sbsd5peye" in output, output)
-        self.failUnless("storage index: rqx7xnpexjxuqprto6pezagdxi" in output, output)
-        self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output)
+        self.failUnless("SSK Read-only URI:" in output, output)
+        self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output)
+        self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output)
+        self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output)
 
         u = u.get_verifier()
         output = self._dump_cap(u.to_string())
-        self.failUnless("SSK Verifier URI:" in output)
-        self.failUnless("storage index: rqx7xnpexjxuqprto6pezagdxi" in output, output)
-        self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output)
+        self.failUnless("SSK Verifier URI:" in output, output)
+        self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output)
+        self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output)
 
     def test_dump_cap_directory(self):
         writekey = "\x01" * 16
@@ -181,38 +181,40 @@ class CLI(unittest.TestCase):
         u = uri.NewDirectoryURI(u1)
 
         output = self._dump_cap(u.to_string())
-        self.failUnless("Directory Writeable URI:" in output)
-        self.failUnless("writekey: aeaqcaibaeaqcaibaeaqcaibae" in output, output)
-        self.failUnless("readkey: x4gowaektauqze4y2sbsd5peye" in output, output)
-        self.failUnless("storage index: rqx7xnpexjxuqprto6pezagdxi" in output, output)
+        self.failUnless("Directory Writeable URI:" in output, output)
+        self.failUnless("writekey: aeaqcaibaeaqcaibaeaqcaibae" in output,
+                        output)
+        self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output)
+        self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output,
+                        output)
         self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output)
 
-        output = self._dump_cap("--client-secret", "a3nyfbnkorp377jhguslgc2dqi",
+        output = self._dump_cap("--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa",
                                 u.to_string())
-        self.failUnless("file renewal secret: zwmq2azrd7lfcmhkrhpgjsxeb2vfpixgvrczbo2asqzdfbmiemwq" in output, output)
+        self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output)
 
         output = self._dump_cap("--nodeid", "tqc35esocrvejvg4mablt6aowg6tl43j",
                                 u.to_string())
-        self.failUnless("write_enabler: eok7o6u26dvl3abw4ok7kqrka4omdolnsx627hpcvtx3kkjwsu5q" in output, output)
-        self.failIf("file renewal secret:" in output)
+        self.failUnless("write_enabler: mgcavriox2wlb5eer26unwy5cw56elh3sjweffckkmivvsxtaknq" in output, output)
+        self.failIf("file renewal secret:" in output, output)
 
         output = self._dump_cap("--nodeid", "tqc35esocrvejvg4mablt6aowg6tl43j",
-                                "--client-secret", "rzaq5to2xm6e5otctpdvzw6bfa",
+                                "--client-secret", "5s33nk3qpvnj2fw3z4mnm2y6fa",
                                 u.to_string())
-        self.failUnless("write_enabler: eok7o6u26dvl3abw4ok7kqrka4omdolnsx627hpcvtx3kkjwsu5q" in output, output)
-        self.failUnless("file renewal secret: wdmu6rwefvmp2venbb4xz5u3273oybmuu553mi7uic37gfu6bacq" in output, output)
-        self.failUnless("lease renewal secret: tlvwfudyfeqyss5kybt6ya72foedqxdovumlbt6ok7u5pyrf2mfq" in output, output)
+        self.failUnless("write_enabler: mgcavriox2wlb5eer26unwy5cw56elh3sjweffckkmivvsxtaknq" in output, output)
+        self.failUnless("file renewal secret: arpszxzc2t6kb4okkg7sp765xgkni5z7caavj7lta73vmtymjlxq" in output, output)
+        self.failUnless("lease renewal secret: 7pjtaumrb7znzkkbvekkmuwpqfjyfyamznfz4bwwvmh4nw33lorq" in output, output)
 
         u = u.get_readonly()
         output = self._dump_cap(u.to_string())
-        self.failUnless("Directory Read-only URI:" in output)
-        self.failUnless("readkey: x4gowaektauqze4y2sbsd5peye" in output, output)
-        self.failUnless("storage index: rqx7xnpexjxuqprto6pezagdxi" in output, output)
-        self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output)
+        self.failUnless("Directory Read-only URI:" in output, output)
+        self.failUnless("readkey: nvgh5vj2ekzzkim5fgtb4gey5y" in output, output)
+        self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output)
+        self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output)
 
         u = u.get_verifier()
         output = self._dump_cap(u.to_string())
-        self.failUnless("Directory Verifier URI:" in output)
-        self.failUnless("storage index: rqx7xnpexjxuqprto6pezagdxi" in output, output)
+        self.failUnless("Directory Verifier URI:" in output, output)
+        self.failUnless("storage index: nt4fwemuw7flestsezvo2eveke" in output, output)
         self.failUnless("fingerprint: 737p57x6737p57x6737p57x6737p57x6737p57x6737p57x6737a" in output, output)
 
index 1a8a4d1bb06bb9c84aeef1c539faea5c41df0d62..9c2c0ccad2e1550f19c80999ed91d13a0837bdee 100644 (file)
@@ -385,15 +385,17 @@ class DeferredUtilTests(unittest.TestCase):
 
 class HashUtilTests(unittest.TestCase):
     def test_sha256d(self):
-        h1 = hashutil.tagged_hash_256d("tag1", "value")
-        h2 = hashutil.tagged_hasher_256d("tag1")
+        h1 = hashutil.tagged_hash("tag1", "value")
+        h2 = hashutil.tagged_hasher("tag1")
         h2.update("value")
-        h2 = h2.digest()
-        self.failUnlessEqual(h1, h2)
+        h2a = h2.digest()
+        h2b = h2.digest()
+        self.failUnlessEqual(h1, h2a)
+        self.failUnlessEqual(h2a, h2b)
 
     def test_sha256d_truncated(self):
-        h1 = hashutil.tagged_hash_256d("tag1", "value", 16)
-        h2 = hashutil.tagged_hasher_256d("tag1", 16)
+        h1 = hashutil.tagged_hash("tag1", "value", 16)
+        h2 = hashutil.tagged_hasher("tag1", 16)
         h2.update("value")
         h2 = h2.digest()
         self.failUnlessEqual(len(h1), 16)
index ee2b0cd2a47877a5030f204be970e38ee238c5fa..6f6f90ea58e736f50aed413b3e5be9e8f8d253f4 100644 (file)
@@ -1,7 +1,12 @@
 from pycryptopp.hash.sha256 import SHA256
 import os
 
-# Various crypto values are this size: hash outputs (from SHA-256),
+# Be very very cautious when modifying this file. Almost any change will
+# cause a compatibility break, invalidating all outstanding URIs and making
+# any previously uploaded files become inaccessible. BE CONSERVATIVE AND TEST
+# AGAINST OLD DATA!
+
+# Various crypto values are this size: hash outputs (from SHA-256d),
 # randomly-generated secrets such as the lease secret, and symmetric encryption
 # keys.  In the near future we will add DSA private keys, and salts of various
 # kinds.
@@ -11,57 +16,78 @@ class IntegrityCheckError(Exception):
     pass
 
 def netstring(s):
-    assert isinstance(s, str), s
+    assert isinstance(s, str), s # no unicode here
     return "%d:%s," % (len(s), s,)
 
-def tagged_hash(tag, val):
-    s = SHA256()
-    s.update(netstring(tag))
-    s.update(val)
-    return s.digest()
-
-def tagged_hash_256d(tag, val, truncate_to=None):
+class _SHA256d_Hasher:
     # use SHA-256d, as defined by Ferguson and Schneier: hash the output
     # again to prevent length-extension attacks
-    s = SHA256()
-    s.update(netstring(tag))
-    s.update(val)
-    h = s.digest()
-    h2 = SHA256(h).digest()
-    if truncate_to:
-        h2 = h2[:truncate_to]
-    return h2
-
-class SHA256d_Hasher:
     def __init__(self, truncate_to=None):
         self.h = SHA256()
         self.truncate_to = truncate_to
+        self._digest = None
     def update(self, data):
+        assert isinstance(data, str) # no unicode
         self.h.update(data)
     def digest(self):
-        h1 = self.h.digest()
-        del self.h
-        h2 = SHA256(h1).digest()
-        if self.truncate_to:
-            h2 = h2[:self.truncate_to]
-        return h2
-
-def tagged_hasher_256d(tag, truncate_to=None):
-    hasher = SHA256d_Hasher(truncate_to)
+        if self._digest is None:
+            h1 = self.h.digest()
+            del self.h
+            h2 = SHA256(h1).digest()
+            if self.truncate_to:
+                h2 = h2[:self.truncate_to]
+            self._digest = h2
+        return self._digest
+
+
+
+def tagged_hasher(tag, truncate_to=None):
+    hasher = _SHA256d_Hasher(truncate_to)
     hasher.update(netstring(tag))
     return hasher
 
-def tagged_pair_hash(tag, val1, val2):
-    s = SHA256()
+def tagged_hash(tag, val, truncate_to=None):
+    hasher = tagged_hasher(tag, truncate_to)
+    hasher.update(val)
+    return hasher.digest()
+
+def tagged_pair_hash(tag, val1, val2, truncate_to=None):
+    s = _SHA256d_Hasher(truncate_to)
     s.update(netstring(tag))
     s.update(netstring(val1))
     s.update(netstring(val2))
     return s.digest()
 
-# specific hash tags that we use
-
-def tagged_hasher(tag):
-    return SHA256(netstring(tag))
+## specific hash tags that we use
+
+# immutable
+STORAGE_INDEX_TAG = "allmydata_immutable_key_to_storage_index_v1"
+BLOCK_TAG = "allmydata_encoded_subshare_v1"
+UEB_TAG = "allmydata_uri_extension_v1"
+PLAINTEXT_TAG = "allmydata_plaintext_v1"
+CIPHERTEXT_TAG = "allmydata_crypttext_v1"
+CIPHERTEXT_SEGMENT_TAG = "allmydata_crypttext_segment_v1"
+PLAINTEXT_SEGMENT_TAG = "allmydata_plaintext_segment_v1"
+CONTENT_HASH_KEY_TAG = "allmydata_immutable_content_to_key_v1+"
+
+CLIENT_RENEWAL_TAG = "allmydata_client_renewal_secret_v1"
+CLIENT_CANCEL_TAG = "allmydata_client_cancel_secret_v1"
+FILE_RENEWAL_TAG = "allmydata_file_renewal_secret_v1"
+FILE_CANCEL_TAG = "allmydata_file_cancel_secret_v1"
+BUCKET_RENEWAL_TAG = "allmydata_bucket_renewal_secret_v1"
+BUCKET_CANCEL_TAG = "allmydata_bucket_cancel_secret_v1"
+
+# mutable
+MUTABLE_WRITEKEY_TAG = "allmydata_mutable_privkey_to_writekey_v1"
+MUTABLE_WRITE_ENABLER_MASTER_TAG = "allmydata_mutable_writekey_to_write_enabler_master_v1"
+MUTABLE_WRITE_ENABLER_TAG = "allmydata_mutable_write_enabler_master_and_nodeid_to_write_enabler_v1"
+MUTABLE_PUBKEY_TAG = "allmydata_mutable_pubkey_to_fingerprint_v1"
+MUTABLE_READKEY_TAG = "allmydata_mutable_writekey_to_readkey_v1"
+MUTABLE_DATAKEY_TAG = "allmydata_mutable_readkey_to_datakey_v1"
+MUTABLE_STORAGEINDEX_TAG = "allmydata_mutable_readkey_to_storage_index_v1"
+
+# dirnodes
+DIRNODE_CHILD_WRITECAP_TAG = "allmydata_mutable_writekey_and_salt_to_dirnode_child_capkey_v1"
 
 def storage_index_hash(key):
     # storage index is truncated to 128 bits (16 bytes). We're only hashing a
@@ -69,94 +95,77 @@ def storage_index_hash(key):
     # We use this same tagged hash to go from encryption key to storage index
     # for random-keyed immutable files and content-hash-keyed immutabie
     # files. Mutable files use ssk_storage_index_hash().
-    return tagged_hash_256d("allmydata_immutable_storage_index_v2", key, 16)
+    return tagged_hash(STORAGE_INDEX_TAG, key, 16)
 
 def block_hash(data):
-    return tagged_hash("allmydata_encoded_subshare_v1", data)
+    return tagged_hash(BLOCK_TAG, data)
 def block_hasher():
-    return tagged_hasher("allmydata_encoded_subshare_v1")
+    return tagged_hasher(BLOCK_TAG)
 
 def uri_extension_hash(data):
-    return tagged_hash("allmydata_uri_extension_v1", data)
+    return tagged_hash(UEB_TAG, data)
 def uri_extension_hasher():
-    return tagged_hasher("allmydata_uri_extension_v1")
+    return tagged_hasher(UEB_TAG)
 
 def plaintext_hash(data):
-    return tagged_hash("allmydata_plaintext_hash_v1", data)
+    return tagged_hash(PLAINTEXT_TAG, data)
 def plaintext_hasher():
-    return tagged_hasher("allmydata_plaintext_hash_v1")
+    return tagged_hasher(PLAINTEXT_TAG)
 
 def crypttext_hash(data):
-    return tagged_hash("allmydata_crypttext_hash_v1", data)
+    return tagged_hash(CIPHERTEXT_TAG, data)
 def crypttext_hasher():
-    return tagged_hasher("allmydata_crypttext_hash_v1")
+    return tagged_hasher(CIPHERTEXT_TAG)
 
 def crypttext_segment_hash(data):
-    return tagged_hash("allmydata_crypttext_segment_v1", data)
+    return tagged_hash(CIPHERTEXT_SEGMENT_TAG, data)
 def crypttext_segment_hasher():
-    return tagged_hasher("allmydata_crypttext_segment_v1")
+    return tagged_hasher(CIPHERTEXT_SEGMENT_TAG)
 
 def plaintext_segment_hash(data):
-    return tagged_hash("allmydata_plaintext_segment_v1", data)
+    return tagged_hash(PLAINTEXT_SEGMENT_TAG, data)
 def plaintext_segment_hasher():
-    return tagged_hasher("allmydata_plaintext_segment_v1")
+    return tagged_hasher(PLAINTEXT_SEGMENT_TAG)
+
+KEYLEN = 16
 
 def content_hash_key_hash(k, n, segsize, data):
-    # This is defined to return a 16-byte AES key. We use SHA-256d here.
+    # this is defined to return a 16-byte AES key. We use SHA-256d here..
     # we'd like to use it everywhere, but we're only switching algorithms
     # when we can hide the compatibility breaks in other necessary changes.
     param_tag = netstring("%d,%d,%d" % (k, n, segsize))
-    h = tagged_hash_256d("allmydata_encryption_key_v2+" + param_tag, data, 16)
+    tag = CONTENT_HASH_KEY_TAG + param_tag
+    h = tagged_hash(tag, data, KEYLEN)
     return h
 def content_hash_key_hasher(k, n, segsize):
     param_tag = netstring("%d,%d,%d" % (k, n, segsize))
-    return tagged_hasher_256d("allmydata_encryption_key_v2+" + param_tag, 16)
+    tag = CONTENT_HASH_KEY_TAG + param_tag
+    return tagged_hasher(tag, KEYLEN)
 
-KEYLEN = 16
 def random_key():
     return os.urandom(KEYLEN)
 
 def my_renewal_secret_hash(my_secret):
-    return tagged_hash(my_secret, "bucket_renewal_secret")
+    return tagged_hash(my_secret, CLIENT_RENEWAL_TAG)
 def my_cancel_secret_hash(my_secret):
-    return tagged_hash(my_secret, "bucket_cancel_secret")
+    return tagged_hash(my_secret, CLIENT_CANCEL_TAG)
 
 def file_renewal_secret_hash(client_renewal_secret, storage_index):
-    return tagged_pair_hash("file_renewal_secret",
+    return tagged_pair_hash(FILE_RENEWAL_TAG,
                             client_renewal_secret, storage_index)
 
 def file_cancel_secret_hash(client_cancel_secret, storage_index):
-    return tagged_pair_hash("file_cancel_secret",
+    return tagged_pair_hash(FILE_CANCEL_TAG,
                             client_cancel_secret, storage_index)
 
 def bucket_renewal_secret_hash(file_renewal_secret, peerid):
     assert len(peerid) == 20, "%s: %r" % (len(peerid), peerid) # binary!
-    return tagged_pair_hash("bucket_renewal_secret",
-                            file_renewal_secret, peerid)
+    return tagged_pair_hash(BUCKET_RENEWAL_TAG, file_renewal_secret, peerid)
 
 def bucket_cancel_secret_hash(file_cancel_secret, peerid):
     assert len(peerid) == 20, "%s: %r" % (len(peerid), peerid) # binary!
-    return tagged_pair_hash("bucket_cancel_secret",
-                            file_cancel_secret, peerid)
-
-def dir_write_enabler_hash(write_key):
-    return tagged_hash("allmydata_dir_write_enabler_v1", write_key)
-def dir_read_key_hash(write_key):
-    return tagged_hash("allmydata_dir_read_key_v1", write_key)[:KEYLEN]
-def dir_index_hash(read_key):
-    return tagged_hash("allmydata_dir_index_v1", read_key)
-def dir_name_hash(readkey, name):
-    return tagged_pair_hash("allmydata_dir_name_v1", readkey, name)
-
-def generate_dirnode_keys_from_writekey(write_key):
-    readkey = dir_read_key_hash(write_key)
-    write_enabler = dir_write_enabler_hash(write_key)
-    index = dir_index_hash(readkey)
-    return write_key, write_enabler, readkey, index
-
-def generate_dirnode_keys_from_readkey(read_key):
-    index = dir_index_hash(read_key)
-    return None, None, read_key, index
+    return tagged_pair_hash(BUCKET_CANCEL_TAG, file_cancel_secret, peerid)
+
 
 def _xor(a, b):
     return "".join([chr(ord(c) ^ ord(b)) for c in a])
@@ -169,22 +178,23 @@ def hmac(tag, data):
     return h2
 
 def mutable_rwcap_key_hash(iv, writekey):
-    return tagged_pair_hash("allmydata_mutable_rwcap_key_v1", iv, writekey)[:16]
+    return tagged_pair_hash(DIRNODE_CHILD_WRITECAP_TAG, iv, writekey, KEYLEN)
+
 def ssk_writekey_hash(privkey):
-    return tagged_hash("allmydata_mutable_writekey_v1", privkey)[:16]
+    return tagged_hash(MUTABLE_WRITEKEY_TAG, privkey, KEYLEN)
 def ssk_write_enabler_master_hash(writekey):
-    return tagged_hash("allmydata_mutable_write_enabler_master_v1", writekey)
+    return tagged_hash(MUTABLE_WRITE_ENABLER_MASTER_TAG, writekey)
 def ssk_write_enabler_hash(writekey, peerid):
     assert len(peerid) == 20, "%s: %r" % (len(peerid), peerid) # binary!
     wem = ssk_write_enabler_master_hash(writekey)
-    return tagged_pair_hash("allmydata_mutable_write_enabler_v1", wem, peerid)
+    return tagged_pair_hash(MUTABLE_WRITE_ENABLER_TAG, wem, peerid)
 
 def ssk_pubkey_fingerprint_hash(pubkey):
-    return tagged_hash("allmydata_mutable_pubkey_v1", pubkey)
+    return tagged_hash(MUTABLE_PUBKEY_TAG, pubkey)
 
 def ssk_readkey_hash(writekey):
-    return tagged_hash("allmydata_mutable_readkey_v1", writekey)[:16]
+    return tagged_hash(MUTABLE_READKEY_TAG, writekey, KEYLEN)
 def ssk_readkey_data_hash(IV, readkey):
-    return tagged_pair_hash("allmydata_mutable_readkey_data_v1", IV, readkey)[:16]
+    return tagged_pair_hash(MUTABLE_DATAKEY_TAG, IV, readkey, KEYLEN)
 def ssk_storage_index_hash(readkey):
-    return tagged_hash("allmydata_mutable_storage_index_v1", readkey)[:16]
+    return tagged_hash(MUTABLE_STORAGEINDEX_TAG, readkey, KEYLEN)