From b09db8d9e1db047841563bb6c2f70472b4a07618 Mon Sep 17 00:00:00 2001
From: Jean-Paul Calderone <exarkun@twistedmatrix.com>
Date: Mon, 2 Oct 2023 15:41:39 -0400
Subject: [PATCH] bump tahoe-chk to 0.2.0.0 and make adjustments so this works

---
 flake.lock                            | 12 ++++++------
 flake.nix                             |  2 +-
 src/Tahoe/SDMF/Internal/Capability.hs | 13 +++++++------
 src/Tahoe/SDMF/Internal/Encoding.hs   |  7 ++++---
 src/Tahoe/SDMF/Internal/Share.hs      |  5 +++--
 tahoe-ssk.cabal                       |  4 ++--
 test/Generators.hs                    | 23 +++++++++++++----------
 test/Spec.hs                          |  3 ++-
 8 files changed, 38 insertions(+), 31 deletions(-)

diff --git a/flake.lock b/flake.lock
index 17b6fae..c1bfd53 100644
--- a/flake.lock
+++ b/flake.lock
@@ -516,16 +516,16 @@
         ]
       },
       "locked": {
-        "lastModified": 1683552888,
-        "narHash": "sha256-h9pgP/LYPtUr5CeCAhqt1XJyAqKTnkQxuIygiTulU/U=",
-        "ref": "refs/tags/0.1.0.1",
-        "rev": "05aeb5a433b85406ca3c0c313c46299a1026ade0",
-        "revCount": 344,
+        "lastModified": 1696262854,
+        "narHash": "sha256-0/6VEsjXe7EvYY2BnkWkmHCVzdp1WcFLjx5mvHDMLnM=",
+        "ref": "refs/tags/0.2.0.0",
+        "rev": "42ae52257ec6e6d8eaa9a56662ca5edfbce8074b",
+        "revCount": 487,
         "type": "git",
         "url": "https://whetstone.private.storage/PrivateStorage/tahoe-chk"
       },
       "original": {
-        "ref": "refs/tags/0.1.0.1",
+        "ref": "refs/tags/0.2.0.0",
         "type": "git",
         "url": "https://whetstone.private.storage/PrivateStorage/tahoe-chk"
       }
diff --git a/flake.nix b/flake.nix
index 4fe75f9..b52496a 100644
--- a/flake.nix
+++ b/flake.nix
@@ -7,7 +7,7 @@
     hs-flake-utils.url = "git+https://whetstone.private.storage/jcalderone/hs-flake-utils.git?ref=main";
     nixpkgs.follows = "hs-flake-utils/nixpkgs";
     tahoe-chk = {
-      url = "git+https://whetstone.private.storage/PrivateStorage/tahoe-chk?ref=refs/tags/0.1.0.1";
+      url = "git+https://whetstone.private.storage/PrivateStorage/tahoe-chk?ref=refs/tags/0.2.0.0";
       inputs.nixpkgs.follows = "hs-flake-utils/nixpkgs";
     };
     tahoe-capabilities = {
diff --git a/src/Tahoe/SDMF/Internal/Capability.hs b/src/Tahoe/SDMF/Internal/Capability.hs
index a0a1943..d8b494f 100644
--- a/src/Tahoe/SDMF/Internal/Capability.hs
+++ b/src/Tahoe/SDMF/Internal/Capability.hs
@@ -5,7 +5,7 @@ import Prelude hiding (Read)
 
 import Control.Applicative ((<|>))
 import Control.Monad (void)
-import Crypto.Hash (Digest, SHA256, digestFromByteString)
+import Crypto.Hash (digestFromByteString)
 import Data.Binary (decode)
 import qualified Data.ByteArray as ByteArray
 import qualified Data.ByteString as B
@@ -16,6 +16,7 @@ import qualified Data.Text as T
 import qualified Data.Text.Encoding as T
 import Data.Void (Void)
 import Data.Word (Word16)
+import Tahoe.CHK.SHA256d (Digest' (Digest'), SHA256d)
 import Tahoe.Capability (ConfidentialShowable (..))
 import Tahoe.SDMF.Internal.Keys (
     Read (readKeyBytes),
@@ -49,7 +50,7 @@ instance ConfidentialShowable SDMF where
 -- | A verify capability for an SDMF object.
 data Verifier = Verifier
     { verifierStorageIndex :: StorageIndex
-    , verifierVerificationKeyHash :: Digest SHA256
+    , verifierVerificationKeyHash :: Digest' SHA256d
     }
     deriving (Eq, Show)
 
@@ -86,14 +87,14 @@ instance ConfidentialShowable Writer where
     confidentiallyShow = dangerRealShow . SDMFWriter
 
 -- | Diminish a write key to a read key and wrap it in a reader capability.
-deriveReader :: Write -> Digest SHA256 -> Maybe Reader
+deriveReader :: Write -> Digest' SHA256d -> Maybe Reader
 deriveReader w fingerprint = Reader <$> readKey <*> verifier
   where
     readKey = deriveReadKey w
     verifier = flip deriveVerifier fingerprint <$> readKey
 
 -- | Diminish a read key to a verify key and wrap it in a verifier capability.
-deriveVerifier :: Read -> Digest SHA256 -> Verifier
+deriveVerifier :: Read -> Digest' SHA256d -> Verifier
 deriveVerifier readKey = Verifier storageIndex
   where
     storageIndex = deriveStorageIndex readKey
@@ -133,7 +134,7 @@ pPieces ::
     -- | A function to convert the first bytestring to a result value.
     (B.ByteString -> a) ->
     -- | A parser for the two pieces of the SDMF capability.
-    Parser (a, Digest SHA256)
+    Parser (a, Digest' SHA256d)
 pPieces prefix convertSecret = do
     void $ string prefix
     secret <- convertSecret <$> pBase32 rfc3548Alphabet 128
@@ -142,7 +143,7 @@ pPieces prefix convertSecret = do
     case digestFromByteString digestBytes of
         Nothing -> failure Nothing mempty
         Just verificationKeyHash ->
-            pure (secret, verificationKeyHash)
+            pure (secret, Digest' verificationKeyHash)
 
 {- | A parser combinator for an arbitrary byte string of a fixed length,
  encoded using base32.
diff --git a/src/Tahoe/SDMF/Internal/Encoding.hs b/src/Tahoe/SDMF/Internal/Encoding.hs
index 5d98a76..f752286 100644
--- a/src/Tahoe/SDMF/Internal/Encoding.hs
+++ b/src/Tahoe/SDMF/Internal/Encoding.hs
@@ -5,8 +5,8 @@
 -}
 module Tahoe.SDMF.Internal.Encoding where
 
-import Control.Monad.Fail (MonadFail)
 import Control.Monad (when)
+import Control.Monad.Fail (MonadFail)
 import Control.Monad.IO.Class (MonadIO (liftIO))
 import Crypto.Hash (digestFromByteString)
 import Crypto.Random (MonadRandom)
@@ -18,6 +18,7 @@ import qualified Data.Text as T
 import Data.Word (Word16, Word64, Word8)
 import Tahoe.CHK (padCiphertext, zfec, zunfec)
 import Tahoe.CHK.Merkle (MerkleTree (MerkleLeaf))
+import Tahoe.CHK.SHA256d (Digest' (Digest'), zero)
 import Tahoe.SDMF.Internal.Capability (Reader (..), Writer (..), deriveReader)
 import Tahoe.SDMF.Internal.Converting (from, tryInto)
 import qualified Tahoe.SDMF.Internal.Keys as Keys
@@ -91,7 +92,7 @@ makeShare shareSequenceNumber shareIV shareRequiredShares shareTotalShares share
     shareRootHash = B.replicate 32 0
     shareSignature = B.replicate 32 0 -- XXX Actually compute sig, and is it 32 bytes?
     shareHashChain = HashChain []
-    shareBlockHashTree = MerkleLeaf (B.replicate 32 0) -- XXX Real hash here, plus length check
+    shareBlockHashTree = MerkleLeaf zero -- XXX Real hash here, plus length check
 
 {- | Decode some SDMF shares to recover the original ciphertext.
 
@@ -124,7 +125,7 @@ capabilityForKeyPair keypair =
     Writer <$> writerWriteKey <*> maybeToEither' "Failed to derive read capability" writerReader
   where
     writerWriteKey = maybeToEither "Failed to derive write key" . Keys.deriveWriteKey . Keys.toSignatureKey $ keypair
-    verificationKeyHash = digestFromByteString . Keys.deriveVerificationHash . Keys.toVerificationKey $ keypair
+    verificationKeyHash = fmap Digest' . digestFromByteString . Keys.deriveVerificationHash . Keys.toVerificationKey $ keypair
     writerReader = deriveReader <$> writerWriteKey <*> maybeToEither "Failed to interpret verification hash" verificationKeyHash
 
 maybeToEither :: a -> Maybe b -> Either a b
diff --git a/src/Tahoe/SDMF/Internal/Share.hs b/src/Tahoe/SDMF/Internal/Share.hs
index 685e1f4..dda046d 100644
--- a/src/Tahoe/SDMF/Internal/Share.hs
+++ b/src/Tahoe/SDMF/Internal/Share.hs
@@ -17,6 +17,7 @@ import Data.Int (Int64)
 import Data.Word (Word16, Word32, Word64, Word8)
 import Data.X509 (PrivKey (PrivKeyRSA), PubKey (PubKeyRSA))
 import Tahoe.CHK.Merkle (MerkleTree, leafHashes)
+import Tahoe.CHK.SHA256d (Digest' (Digest'), SHA256d, toBytes)
 import Tahoe.SDMF.Internal.Converting (From (from), into, tryInto)
 import qualified Tahoe.SDMF.Internal.Keys as Keys
 
@@ -81,7 +82,7 @@ data Share = Share
       -- ... something about verification I dunno. XXX
       shareHashChain :: HashChain
     , -- | A merkle tree where leaves are the hashes of the blocks in this share.
-      shareBlockHashTree :: MerkleTree
+      shareBlockHashTree :: MerkleTree B.ByteString SHA256d
     , -- | The share data (erasure encoded ciphertext).
       shareData :: LB.ByteString
     , -- | The encrypted 2048 bit "signature" RSA key.
@@ -113,7 +114,7 @@ instance Binary Share where
         putByteString shareEncryptedPrivateKey
       where
         verificationKeyBytes = Keys.verificationKeyToBytes shareVerificationKey
-        blockHashTreeBytes = B.concat . leafHashes $ shareBlockHashTree
+        blockHashTreeBytes = B.concat . fmap toBytes . leafHashes $ shareBlockHashTree
 
         -- Some conversions could fail because we can't be completely sure of
         -- the size of the data we're working with.  Put has no good failure
diff --git a/tahoe-ssk.cabal b/tahoe-ssk.cabal
index 6eceb3e..b0c4d8f 100644
--- a/tahoe-ssk.cabal
+++ b/tahoe-ssk.cabal
@@ -132,7 +132,7 @@ library
 
   -- This dependency isn't ideal.  Move common bits out to
   -- another library.
-  build-depends:   tahoe-chk >=0.1 && <0.2
+  build-depends:   tahoe-chk >=0.2 && <0.3
 
 test-suite tahoe-ssk-test
   import:
@@ -167,7 +167,7 @@ test-suite tahoe-ssk-test
     , megaparsec          >=8.0      && <9.3
     , memory              >=0.15     && <0.17
     , tahoe-capabilities  >=0.1      && <0.2
-    , tahoe-chk           >=0.1      && <0.2
+    , tahoe-chk           >=0.2      && <0.3
     , tahoe-ssk
     , tasty               >=1.2.3    && <1.5
     , tasty-hedgehog      >=1.0.0.2  && <1.2
diff --git a/test/Generators.hs b/test/Generators.hs
index 993edc5..73dea60 100644
--- a/test/Generators.hs
+++ b/test/Generators.hs
@@ -1,3 +1,5 @@
+{-# LANGUAGE ScopedTypeVariables #-}
+
 module Generators where
 
 import Crypto.Cipher.Types (makeIV)
@@ -10,7 +12,7 @@ import Data.Bifunctor (Bifunctor (first))
 import qualified Data.Binary as Binary
 import qualified Data.ByteString as B
 import qualified Data.ByteString.Lazy as LB
-import Data.Maybe (fromJust)
+import Data.Maybe (fromJust, fromMaybe)
 import Data.Word (Word16)
 import Data.X509 (PrivKey (PrivKeyRSA))
 import GHC.IO.Unsafe (unsafePerformIO)
@@ -18,6 +20,7 @@ import Hedgehog (MonadGen)
 import qualified Hedgehog.Gen as Gen
 import qualified Hedgehog.Range as Range
 import Tahoe.CHK.Merkle (MerkleTree (..), makeTreePartial)
+import Tahoe.CHK.SHA256d (Digest' (Digest'), SHA256d)
 import Tahoe.SDMF (Reader (..), SDMF (..), Share (..), Verifier (..), Writer (..))
 import Tahoe.SDMF.Internal.Capability (deriveReader)
 import Tahoe.SDMF.Internal.Keys (keyLength)
@@ -87,12 +90,16 @@ rsaKeyPair bs = do
                 _ -> error "Expected RSA Private Key"
     kp
 
-merkleTrees :: MonadGen m => Range.Range Int -> m MerkleTree
-merkleTrees r = makeTreePartial <$> Gen.list r genHash
+merkleTrees :: MonadGen m => Range.Range Int -> m (MerkleTree B.ByteString SHA256d)
+merkleTrees r = makeTreePartial <$> Gen.list r digests
 
--- | Generate ByteStrings which could be sha256d digests.
-genHash :: MonadGen m => m B.ByteString
-genHash = Gen.bytes . Range.singleton . hashDigestSize $ SHA256
+-- | Generate Digest' values for some hash algorithm.  Shrinks toward "aaa..."
+digests :: forall m hash. (MonadGen m, HashAlgorithm hash) => m (Digest' hash)
+digests =
+    Digest'
+        . fromMaybe (error "Failed to interpret bytes as digest")
+        . digestFromByteString
+        <$> Gen.bytes (Range.singleton (hashDigestSize (undefined :: hash)))
 
 -- | Generate lists of two-tuples of share identifier and share root hash.
 shareHashChains :: MonadGen m => m HashChain
@@ -142,7 +149,3 @@ verifiers = readerVerifier <$> readers
 -- | Build SDMF storage indexes.
 storageIndexes :: MonadGen m => m Keys.StorageIndex
 storageIndexes = Keys.StorageIndex <$> Gen.bytes (Range.singleton keyLength)
-
--- | Build SHA256 digests.
-digests :: MonadGen m => m (Digest SHA256)
-digests = fromJust . digestFromByteString <$> Gen.bytes (Range.singleton 32)
diff --git a/test/Spec.hs b/test/Spec.hs
index 30a209f..a078716 100644
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -27,6 +27,7 @@ import Generators (capabilities, encodingParameters, genRSAKeys, ivLength, share
 import qualified Hedgehog.Gen as Gen
 import qualified Hedgehog.Range as Range
 import System.IO (hSetEncoding, stderr, stdout, utf8)
+import Tahoe.CHK.SHA256d (Digest' (Digest'))
 import Tahoe.Capability (confidentiallyShow)
 import qualified Tahoe.SDMF
 import Tahoe.SDMF.Internal.Capability (deriveVerifier)
@@ -206,7 +207,7 @@ tests =
 
             let (Right writeKey) = Binary.decode . LB.fromStrict <$> decodeBase32Unpadded "vdv6pcqkblsguvkagrblr3gopu"
                 (Just readerReadKey) = Keys.deriveReadKey writeKey
-                (Just readerVerifier) = deriveVerifier readerReadKey <$> digestFromByteString ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" :: B.ByteString)
+                (Just readerVerifier) = deriveVerifier readerReadKey . Digest' <$> digestFromByteString ("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" :: B.ByteString)
                 reader = Tahoe.SDMF.Reader{..}
             ciphertext <- Tahoe.SDMF.decode reader [(0, s0), (6, s6), (9, s9)]
             let (Right expectedCiphertext) = LB.fromStrict <$> decodeBase32Unpadded "6gutkha6qd4g3lxahth2dw2wjekadwoxvmazrnfq5u5j6a7quu5qy6nz3dvosx2gisdjshdtd5xphqvqjco5pq73qi"
-- 
GitLab