diff --git a/dhall-docs/dhall-docs.cabal b/dhall-docs/dhall-docs.cabal index 151b9d24f..f53289beb 100644 --- a/dhall-docs/dhall-docs.cabal +++ b/dhall-docs/dhall-docs.cabal @@ -62,9 +62,10 @@ Library Hs-Source-Dirs: src Build-Depends: base >= 4.11.0.0 && < 5 , + base16-bytestring >= 1.0.0.0 , bytestring < 0.12, containers , - cryptonite < 0.30, + cryptohash-sha256 , directory >= 1.3.0.0 && < 1.4 , dhall >= 1.38.0 && < 1.41, file-embed >= 0.0.10.0 , @@ -74,7 +75,6 @@ Library mmark >= 0.0.7.0 && < 0.8 , -- megaparsec follows SemVer: https://github.com/mrkkrp/megaparsec/issues/469#issuecomment-927918469 megaparsec >= 7 && < 10 , - memory < 0.17, path >= 0.7.0 && < 0.10, path-io >= 1.6.0 && < 1.7 , prettyprinter >= 1.7.0 && < 1.8 , diff --git a/dhall-docs/src/Dhall/Docs/Store.hs b/dhall-docs/src/Dhall/Docs/Store.hs index de08eabd9..94f6f4510 100644 --- a/dhall-docs/src/Dhall/Docs/Store.hs +++ b/dhall-docs/src/Dhall/Docs/Store.hs @@ -5,17 +5,16 @@ module Dhall.Docs.Store (getDocsHomeDirectory, makeHashForDirectory) where -import Crypto.Hash (Digest, SHA256) import Dhall.Crypto (SHA256Digest (..)) import Path (Abs, Dir, Path, Rel, ()) import Path.IO (XdgDirectory (..)) -import qualified Control.Monad as Monad -import qualified Crypto.Hash as Hash -import qualified Data.ByteArray as ByteArray -import qualified Data.ByteString as ByteString -import qualified Data.ByteString.Char8 as ByteString.Char8 -import qualified Data.List as List +import qualified Control.Monad as Monad +import qualified Crypto.Hash.SHA256 +import qualified Data.ByteString as ByteString +import qualified Data.ByteString.Base16 as Base16 +import qualified Data.ByteString.Char8 as ByteString.Char8 +import qualified Data.List as List import qualified Path import qualified Path.IO @@ -41,12 +40,12 @@ makeHashForDirectory :: Path Abs Dir -> IO SHA256Digest makeHashForDirectory dir = do (dirs, files) <- Path.IO.listDirRecurRel dir - let context0 = Hash.hashInit + let context0 = Crypto.Hash.SHA256.init let addDir context directory = do let nameBytes = ByteString.Char8.pack (Path.toFilePath directory) - return $! Hash.hashUpdate context nameBytes + return $! Crypto.Hash.SHA256.update context nameBytes context1 <- Monad.foldM addDir context0 (List.sort dirs) @@ -55,11 +54,8 @@ makeHashForDirectory dir = do contentBytes <- ByteString.readFile (Path.toFilePath (dir file)) - return $! Hash.hashUpdates context [ nameBytes, contentBytes ] + return $! Crypto.Hash.SHA256.updates context [ nameBytes, contentBytes ] context2 <- Monad.foldM addFile context1 (List.sort files) - let digest :: Digest SHA256 - digest = Hash.hashFinalize context2 - - return (SHA256Digest (ByteArray.convert digest)) + return (SHA256Digest (Crypto.Hash.SHA256.finalize context2)) diff --git a/dhall-nixpkgs/Main.hs b/dhall-nixpkgs/Main.hs index e940b34bd..fda5f3e8c 100644 --- a/dhall-nixpkgs/Main.hs +++ b/dhall-nixpkgs/Main.hs @@ -76,7 +76,6 @@ import Control.Monad.Morph (hoist) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.State.Strict (StateT) import Data.Aeson (FromJSON) -import Data.ByteArray.Encoding (Base (Base16, Base64), convertToBase) import Data.List.NonEmpty (NonEmpty (..)) import Data.Maybe (mapMaybe) import Data.Text (Text) @@ -108,6 +107,8 @@ import Dhall.Core import qualified Control.Foldl as Foldl import qualified Control.Monad.Trans.State.Strict as State import qualified Data.Aeson as Aeson +import qualified Data.ByteString.Base16 as Base16 +import qualified Data.ByteString.Base64 as Base64 import qualified Data.ByteString.Char8 as ByteString.Char8 import qualified Data.Foldable as Foldable import qualified Data.List.NonEmpty as NonEmpty @@ -432,10 +433,10 @@ dependencyToNixAsFOD url (SHA256Digest shaBytes) = do let functionParameter = Nothing let dhallHash = - "sha256:" <> ByteString.Char8.unpack (convertToBase Base16 shaBytes) + "sha256:" <> ByteString.Char8.unpack (Base16.encode shaBytes) let nixSRIHash = - "sha256-" <> ByteString.Char8.unpack (convertToBase Base64 shaBytes) + "sha256-" <> ByteString.Char8.unpack (Base64.encode shaBytes) let dependencyExpression = "buildDhallUrl" diff --git a/dhall-nixpkgs/dhall-nixpkgs.cabal b/dhall-nixpkgs/dhall-nixpkgs.cabal index b1b7ffad4..1d70b14b9 100644 --- a/dhall-nixpkgs/dhall-nixpkgs.cabal +++ b/dhall-nixpkgs/dhall-nixpkgs.cabal @@ -18,6 +18,8 @@ Executable dhall-to-nixpkgs Main-Is: Main.hs Build-Depends: base >= 4.11 && < 5 , aeson >= 1.0.0.0 && < 2.1 + , base16-bytestring >= 1.0.0.0 + , base64-bytestring >= 1.2.1.0 , bytestring < 0.12 , data-fix , dhall >= 1.32.0 && < 1.41 @@ -26,7 +28,6 @@ Executable dhall-to-nixpkgs , lens-family-core >= 1.0.0 && < 2.2 -- megaparsec follows SemVer: https://github.com/mrkkrp/megaparsec/issues/469#issuecomment-927918469 , megaparsec >= 7.0.0 && < 10 - , memory >= 0.14 && < 0.17 , mmorph < 1.3 , neat-interpolation < 0.6 , optparse-applicative >= 0.14.0.0 && < 0.17 diff --git a/dhall/dhall.cabal b/dhall/dhall.cabal index 092f1fd76..4d7a120e6 100644 --- a/dhall/dhall.cabal +++ b/dhall/dhall.cabal @@ -477,6 +477,7 @@ Library aeson-pretty < 0.9 , ansi-terminal >= 0.6.3.1 && < 0.12, atomic-write >= 0.2.0.7 && < 0.3 , + base16-bytestring >= 1.0.0.0 , bytestring < 0.12, case-insensitive < 1.3 , cborg >= 0.2.0.0 && < 0.3 , @@ -497,7 +498,6 @@ Library lens-family-core >= 1.0.0 && < 2.2 , -- megaparsec follows SemVer: https://github.com/mrkkrp/megaparsec/issues/469#issuecomment-927918469 megaparsec >= 8 && < 10 , - memory >= 0.14 && < 0.17, mmorph < 1.3 , mtl >= 2.2.1 && < 2.3 , network-uri >= 2.6 && < 2.7 , @@ -534,7 +534,7 @@ Library else Hs-Source-Dirs: ghc-src Build-Depends: - cryptonite >= 0.23 && < 0.30 + cryptohash-sha256 if flag(with-http) Build-Depends: http-types >= 0.7.0 && < 0.13, diff --git a/dhall/ghc-src/Dhall/Crypto.hs b/dhall/ghc-src/Dhall/Crypto.hs index 282739acb..0db35d09b 100644 --- a/dhall/ghc-src/Dhall/Crypto.hs +++ b/dhall/ghc-src/Dhall/Crypto.hs @@ -13,18 +13,17 @@ module Dhall.Crypto ( ) where import Control.DeepSeq (NFData) -import Crypto.Hash (SHA256) -import Data.ByteArray (ByteArrayAccess, convert) -import Data.ByteArray.Encoding (Base (Base16), convertToBase) import Data.ByteString (ByteString) import GHC.Generics (Generic) -import qualified Crypto.Hash -import qualified Data.ByteString.Char8 as ByteString.Char8 +import qualified Crypto.Hash.SHA256 +import qualified Data.ByteString as ByteString +import qualified Data.ByteString.Base16 as Base16 +import qualified Data.ByteString.Char8 as ByteString.Char8 -- | A SHA256 digest newtype SHA256Digest = SHA256Digest { unSHA256Digest :: ByteString } - deriving (Eq, Generic, Ord, NFData, ByteArrayAccess) + deriving (Eq, Generic, Ord, NFData) instance Show SHA256Digest where show = toString @@ -33,16 +32,14 @@ instance Show SHA256Digest where `Nothing` if the conversion fails -} sha256DigestFromByteString :: ByteString -> Maybe SHA256Digest -sha256DigestFromByteString bytes = SHA256Digest . convert <$> mh - where - mh = Crypto.Hash.digestFromByteString bytes :: Maybe (Crypto.Hash.Digest SHA256) +sha256DigestFromByteString bytes + | ByteString.length bytes == 32 = Just (SHA256Digest bytes) + | otherwise = Nothing -- | Hash a `ByteString` and return the hash as a `SHA256Digest` sha256Hash :: ByteString -> SHA256Digest -sha256Hash bytes = SHA256Digest $ convert h - where - h = Crypto.Hash.hash bytes :: Crypto.Hash.Digest SHA256 +sha256Hash = SHA256Digest . Crypto.Hash.SHA256.hash -- | 'String' representation of a 'SHA256Digest' toString :: SHA256Digest -> String -toString (SHA256Digest bytes) = ByteString.Char8.unpack $ convertToBase Base16 bytes +toString (SHA256Digest bytes) = ByteString.Char8.unpack $ Base16.encode bytes diff --git a/dhall/ghcjs-src/Dhall/Crypto.hs b/dhall/ghcjs-src/Dhall/Crypto.hs index 8cf8a3e5a..35ce2ca70 100644 --- a/dhall/ghcjs-src/Dhall/Crypto.hs +++ b/dhall/ghcjs-src/Dhall/Crypto.hs @@ -13,31 +13,30 @@ module Dhall.Crypto ( ) where import Control.DeepSeq (NFData) -import Data.ByteArray (ByteArrayAccess) -import Data.ByteArray.Encoding (Base (Base16), convertToBase) import Data.ByteString (ByteString) import GHC.Generics (Generic) import JavaScript.TypedArray.ArrayBuffer (ArrayBuffer) import System.IO.Unsafe (unsafePerformIO) -import qualified Data.ByteString as ByteString -import qualified Data.ByteString.Char8 as ByteString.Char8 -import qualified GHCJS.Buffer as Buffer +import qualified Data.ByteString as ByteString +import qualified Data.ByteString.Base16 as Base16 +import qualified Data.ByteString.Char8 as ByteString.Char8 +import qualified GHCJS.Buffer as Buffer -- | A SHA256 digest newtype SHA256Digest = SHA256Digest { unSHA256Digest :: ByteString } - deriving (Eq, Generic, Ord, NFData, ByteArrayAccess) + deriving (Eq, Generic, Ord, NFData) instance Show SHA256Digest where - show (SHA256Digest bytes) = ByteString.Char8.unpack $ convertToBase Base16 bytes + show (SHA256Digest bytes) = ByteString.Char8.unpack $ Base16.encode bytes {-| Attempt to interpret a `ByteString` as a `SHA256Digest`, returning `Nothing` if the conversion fails -} sha256DigestFromByteString :: ByteString -> Maybe SHA256Digest sha256DigestFromByteString bytes - | ByteString.length bytes == 32 = Just $ SHA256Digest bytes - | otherwise = Nothing + | ByteString.length bytes == 32 = Just (SHA256Digest bytes) + | otherwise = Nothing -- Use NodeJS' crypto module if there's a 'process' module, e.g. we're running -- inside GHCJS' THRunner. If we're running in the browser, use the WebCrypto diff --git a/dhall/src/Dhall/Binary.hs b/dhall/src/Dhall/Binary.hs index 3a4711cec..ba129fc77 100644 --- a/dhall/src/Dhall/Binary.hs +++ b/dhall/src/Dhall/Binary.hs @@ -61,7 +61,6 @@ import qualified Codec.CBOR.Decoding as Decoding import qualified Codec.CBOR.Encoding as Encoding import qualified Codec.CBOR.Read as Read import qualified Codec.Serialise as Serialise -import qualified Data.ByteArray import qualified Data.ByteString import qualified Data.ByteString.Lazy import qualified Data.ByteString.Short @@ -1271,7 +1270,7 @@ encodeImport import_ = Encoding.encodeNull Just digest -> - Encoding.encodeBytes ("\x12\x20" <> Data.ByteArray.convert digest) + Encoding.encodeBytes ("\x12\x20" <> Dhall.Crypto.unSHA256Digest digest) m = Encoding.encodeInt (case importMode of Code -> 0; RawText -> 1; Location -> 2;) diff --git a/dhall/src/Dhall/Parser/Expression.hs b/dhall/src/Dhall/Parser/Expression.hs index 2cee51843..e6dcc83c6 100644 --- a/dhall/src/Dhall/Parser/Expression.hs +++ b/dhall/src/Dhall/Parser/Expression.hs @@ -8,7 +8,6 @@ module Dhall.Parser.Expression where import Control.Applicative (Alternative (..), liftA2, optional) -import Data.ByteArray.Encoding (Base (..)) import Data.Foldable (foldl') import Data.List.NonEmpty (NonEmpty (..)) import Data.Text (Text) @@ -19,8 +18,7 @@ import Text.Parser.Combinators (choice, try, ()) import qualified Control.Monad import qualified Control.Monad.Combinators as Combinators import qualified Control.Monad.Combinators.NonEmpty as Combinators.NonEmpty -import qualified Data.ByteArray.Encoding -import qualified Data.ByteString +import qualified Data.ByteString.Base16 as Base16 import qualified Data.Char as Char import qualified Data.List import qualified Data.List.NonEmpty as NonEmpty @@ -1202,9 +1200,9 @@ importHash_ = do _ <- text "sha256:" t <- count 64 (satisfy hexdig "hex digit") let strictBytes16 = Data.Text.Encoding.encodeUtf8 t - strictBytes <- case Data.ByteArray.Encoding.convertFromBase Base16 strictBytes16 of + strictBytes <- case Base16.decode strictBytes16 of Left string -> fail string - Right strictBytes -> return (strictBytes :: Data.ByteString.ByteString) + Right strictBytes -> return strictBytes case Dhall.Crypto.sha256DigestFromByteString strictBytes of Nothing -> fail "Invalid sha256 hash" Just h -> pure h diff --git a/nix/packages/base64-bytestring.nix b/nix/packages/base64-bytestring.nix new file mode 100644 index 000000000..9510a9bf3 --- /dev/null +++ b/nix/packages/base64-bytestring.nix @@ -0,0 +1,18 @@ +{ mkDerivation, base, bytestring, criterion, deepseq, HUnit, lib +, QuickCheck, test-framework, test-framework-hunit +, test-framework-quickcheck2 +}: +mkDerivation { + pname = "base64-bytestring"; + version = "1.2.1.0"; + sha256 = "fbf8ed30edde271eb605352021431d8f1b055f95a56af31fe2eacf6bdfdc49c9"; + libraryHaskellDepends = [ base bytestring ]; + testHaskellDepends = [ + base bytestring HUnit QuickCheck test-framework + test-framework-hunit test-framework-quickcheck2 + ]; + benchmarkHaskellDepends = [ base bytestring criterion deepseq ]; + homepage = "https://github.com/haskell/base64-bytestring"; + description = "Fast base64 encoding and decoding for ByteStrings"; + license = lib.licenses.bsd3; +}