Skip to content

Commit

Permalink
Migrate from memory+cryptonite to base16-bytestring+cryptohash-sha256 (
Browse files Browse the repository at this point in the history
…#2335)

* dhall: memory+cryptonite -> base16-bytestring+cryptohash-sha256

* dhall-docs: memory+cryptonite -> base16-bytestring+cryptohash-sha256

* dhall-nixpkgs: memory -> base{16,64}-bytestring

* Add derivation for base64-bytestring

* Remove redundant type annotation

Co-authored-by: Gabriella Gonzalez <[email protected]>
  • Loading branch information
sjakobi and Gabriella439 authored Nov 17, 2021
1 parent 0aacc3d commit 30f9617
Show file tree
Hide file tree
Showing 10 changed files with 60 additions and 51 deletions.
4 changes: 2 additions & 2 deletions dhall-docs/dhall-docs.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -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 ,
Expand All @@ -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 ,
Expand Down
24 changes: 10 additions & 14 deletions dhall-docs/src/Dhall/Docs/Store.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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)

Expand All @@ -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))
7 changes: 4 additions & 3 deletions dhall-nixpkgs/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"
Expand Down
3 changes: 2 additions & 1 deletion dhall-nixpkgs/dhall-nixpkgs.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
4 changes: 2 additions & 2 deletions dhall/dhall.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -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 ,
Expand All @@ -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 ,
Expand Down Expand Up @@ -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,
Expand Down
23 changes: 10 additions & 13 deletions dhall/ghc-src/Dhall/Crypto.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
17 changes: 8 additions & 9 deletions dhall/ghcjs-src/Dhall/Crypto.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 1 addition & 2 deletions dhall/src/Dhall/Binary.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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;)

Expand Down
8 changes: 3 additions & 5 deletions dhall/src/Dhall/Parser/Expression.hs
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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
Expand Down
18 changes: 18 additions & 0 deletions nix/packages/base64-bytestring.nix
Original file line number Diff line number Diff line change
@@ -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;
}

0 comments on commit 30f9617

Please sign in to comment.