diff --git a/src/Tahoe/SDMF/Internal/Keys.hs b/src/Tahoe/SDMF/Internal/Keys.hs
index 29c017f690e0605a0648527090b36245874ee2c2..d4f6eaaa008f6c21950f59d2c0fc7758035a76cf 100644
--- a/src/Tahoe/SDMF/Internal/Keys.hs
+++ b/src/Tahoe/SDMF/Internal/Keys.hs
@@ -38,8 +38,9 @@ instance Show Write where
 data Read = Read {unRead :: AES128, readKeyBytes :: ByteArray.ScrubbedBytes}
 newtype StorageIndex = StorageIndex {unStorageIndex :: B.ByteString}
 
-newtype WriteEnablerMaster = WriteEnablerMaster B.ByteString
-data WriteEnabler = WriteEnabler StorageServerID B.ByteString
+newtype WriteEnablerMaster = WriteEnablerMaster ByteArray.ScrubbedBytes
+
+data WriteEnabler = WriteEnabler StorageServerID ByteArray.ScrubbedBytes
 
 data Data = Data {unData :: AES128, dataKeyBytes :: ByteArray.ScrubbedBytes}
 
@@ -97,10 +98,10 @@ 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"
 
+-- | Compute the storage index for a given read key for an SDMF share.
 deriveStorageIndex :: Read -> StorageIndex
 deriveStorageIndex r = StorageIndex si
   where
@@ -109,6 +110,19 @@ deriveStorageIndex r = StorageIndex si
 mutableStorageIndexTag :: B.ByteString
 mutableStorageIndexTag = "allmydata_mutable_readkey_to_storage_index_v1"
 
+{- | Derive the "write enabler master" secret for a given write key for an
+ SDMF share.
+-}
+deriveWriteEnablerMaster :: Write -> WriteEnablerMaster
+deriveWriteEnablerMaster w = WriteEnablerMaster bs
+  where
+    -- This one shouldn't be truncated.  Set the length to the size of sha256d
+    -- output.
+    bs = ByteArray.convert . taggedHash 32 mutableWriteEnablerMasterTag . ByteArray.convert . writeKeyBytes $ w
+
+mutableWriteEnablerMasterTag :: B.ByteString
+mutableWriteEnablerMasterTag = "allmydata_mutable_writekey_to_write_enabler_master_v1"
+
 {- | Encode a public key to the Tahoe-LAFS canonical bytes representation -
  X.509 SubjectPublicKeyInfo of the ASN.1 DER serialization of an RSA
  PublicKey.
diff --git a/src/Tahoe/SDMF/Keys.hs b/src/Tahoe/SDMF/Keys.hs
index 75a503bb0fe004711cec016738f5772075444f69..7b724d19626def89695df1230f243bc2dc0c9b00 100644
--- a/src/Tahoe/SDMF/Keys.hs
+++ b/src/Tahoe/SDMF/Keys.hs
@@ -8,9 +8,11 @@ import Tahoe.SDMF.Internal.Keys (
     Signature (..),
     StorageIndex (..),
     Write (..),
+    WriteEnablerMaster (..),
     deriveDataKey,
     deriveReadKey,
     deriveStorageIndex,
+    deriveWriteEnablerMaster,
     deriveWriteKey,
     toPublicKey,
  )
diff --git a/test/Spec.hs b/test/Spec.hs
index cb08caaff95a66e0c852e074bcfacfd88296aa23..e0061e9f6d194c61dfd7b73b21eeb737cfd755d5 100644
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -85,6 +85,7 @@ tests =
                     expectedReadKey = ("6ir6husgx6ubro3tbimmzskqri" :: T.Text)
                     expectedDataKey = ("bbj67exlrkfcaqutwlgwvukbfe" :: T.Text)
                     expectedStorageIndex = ("cmkuloz2t6fhsh7npxxteba6sq" :: T.Text)
+                    expectedWriteEnablerMaster = ("qgptod5dsanfep2kbimvxl2yixndnoks7ndoeamczj7g33gokcvq" :: T.Text)
 
                     -- Derive all the keys.
                     (Just iv) = Keys.SDMF_IV <$> makeIV (B.replicate 16 0x42)
@@ -92,6 +93,7 @@ tests =
                     (Just r@(Keys.Read _ derivedReadKey)) = Keys.deriveReadKey w
                     (Just (Keys.Data _ derivedDataKey)) = Keys.deriveDataKey iv r
                     (Keys.StorageIndex derivedStorageIndex) = Keys.deriveStorageIndex r
+                    (Keys.WriteEnablerMaster derivedWriteEnablerMaster) = Keys.deriveWriteEnablerMaster w
 
                     -- A helper to format a key as text for convenient
                     -- comparison to expected value.
@@ -103,21 +105,25 @@ tests =
                         -- instance so we go the other way.  We're not worried about
                         -- the safety of these test-only keys anyway.
                         assertEqual
-                            "expected writekey /= derived writekey"
+                            "writekey: expected /= derived"
                             expectedWriteKey
                             (fmtKey derivedWriteKey)
                         assertEqual
-                            "expected readkey /= derived readkey"
+                            "readkey: expected /= derived"
                             expectedReadKey
                             (fmtKey derivedReadKey)
                         assertEqual
-                            "expected datakey /= derived datakey"
+                            "datakey: expected /= derived"
                             expectedDataKey
                             (fmtKey derivedDataKey)
                         assertEqual
-                            "expected storage index /= derived storage index"
+                            "storage index: expected /= derived"
                             expectedStorageIndex
                             (T.toLower . encodeBase32Unpadded $ derivedStorageIndex)
+                        assertEqual
+                            "write enabler master: expected /= derived"
+                            expectedWriteEnablerMaster
+                            (fmtKey derivedWriteEnablerMaster)
         , testProperty "Share round-trips through bytes" $
             property $ do
                 share <- forAll shares
diff --git a/test/expected_values.py b/test/expected_values.py
index 8ad03d95cf546650be06aa582bf0d00bed52053e..31d18d9e3a05396116d406689947cfee020a7238 100644
--- a/test/expected_values.py
+++ b/test/expected_values.py
@@ -4,30 +4,32 @@
 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,
-    ssk_storage_index_hash,
-)
+from allmydata.util import hashutil
 
 # Arbitrarily select an IV.
 iv = b"\x42" * 16
+# And "peer id"
+peerid = b"\x42" * 20
 
 with open("data/rsa-privkey-0.der", "rb") as f:
     (priv, pub) = rsa.create_signing_keypair_from_string(f.read())
 
 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)
+readkey = hashutil.ssk_readkey_hash(writekey)
+datakey = hashutil.ssk_readkey_data_hash(iv, readkey)
+storage_index = hashutil.ssk_storage_index_hash(readkey)
+write_enabler_master = hashutil.ssk_write_enabler_master_hash(writekey)
+write_enabler = hashutil.ssk_write_enabler_hash(writekey, peerid)
 
 print("SDMF")
 print("writekey: ", base32.b2a(writekey))
 print("readkey: ", base32.b2a(readkey))
-print("datakey: ", base32.b2a(datakey))
+print("datakey (iv = \x42 * 16): ", base32.b2a(datakey))
 print("storage index: ", base32.b2a(storage_index))
 print("encrypted private key: ", base32.b2a(encprivkey))
 print("signature key hash: ", base32.b2a(fingerprint))
+print("write enabler master: ", base32.b2a(write_enabler_master))
+print("write enabler (peerid = \x42 * 20): ", base32.b2a(write_enabler))
 
 (priv, pub) = rsa.create_signing_keypair(2048)
 priv_bytes = rsa.der_string_from_signing_key(priv)