packages feed

crypton 1.0.6 → 1.1.0

raw patch · 10 files changed

+158/−141 lines, 10 filesdep +base16dep +primitivedep +ramdep −basementdep −memoryPVP ok

version bump matches the API change (PVP)

Dependencies added: base16, primitive, ram, text

Dependencies removed: basement, memory

API changes (from Hackage documentation)

Files

CHANGELOG.md view
@@ -1,5 +1,9 @@ # CHANGELOG for crypton +## 1.0.7++ Stop depending on basement, use upstream dependencies instead++ Stop transitively depending on basement by depending on ram.+ ## 1.0.6  * Fix test failures on less common 64-bit arches.
Crypto/Error/Types.hs view
@@ -22,7 +22,6 @@ import qualified Control.Exception as E import Data.Data -import Basement.Monad (MonadFailure (..))  -- | Enumeration of all possible errors that can be found in this library data CryptoError@@ -86,10 +85,6 @@         case m1 of             CryptoPassed a -> m2 a             CryptoFailed e -> CryptoFailed e--instance MonadFailure CryptoFailable where-    type Failure CryptoFailable = CryptoError-    mFail = CryptoFailed  -- | Throw an CryptoError as exception on CryptoFailed result, -- otherwise return the computed value
Crypto/Hash.hs view
@@ -47,18 +47,14 @@     module Crypto.Hash.Algorithms, ) where -import Basement.Block (Block, unsafeFreeze)-import Basement.Block.Mutable (copyFromPtr, new)-import Basement.Types.OffsetSize (CountOf (..)) import Crypto.Hash.Algorithms import Crypto.Hash.Types-import Crypto.Internal.ByteArray (ByteArrayAccess)+import Crypto.Internal.ByteArray (ByteArrayAccess, allocAndFreezePrim) import qualified Crypto.Internal.ByteArray as B-import Crypto.Internal.Compat (unsafeDoIO) import qualified Data.ByteString.Lazy as L import Data.Int (Int32)-import Data.Word (Word8)-import Foreign.Ptr (Ptr, plusPtr)+import qualified Foreign.Marshal.Utils as FMU+import Foreign.Ptr (Ptr, castPtr, plusPtr)  -- | Hash a strict bytestring into a digest. hash :: (ByteArrayAccess ba, HashAlgorithm a) => ba -> Digest a@@ -117,8 +113,8 @@      . HashAlgorithm a     => Context a     -> Digest a-hashFinalize !c =-    Digest $ B.allocAndFreeze (hashDigestSize (undefined :: a)) $ \(dig :: Ptr (Digest a)) -> do+hashFinalize !c = Digest $ allocAndFreezePrim (hashDigestSize (undefined :: a)) $+    \(dig :: Ptr (Digest a)) -> do         ((!_) :: B.Bytes) <- B.copy c $ \(ctx :: Ptr (Context a)) -> hashInternalFinalize ctx dig         return () @@ -135,8 +131,8 @@     -> ba     -> Int     -> Digest a-hashFinalizePrefix !c b len =-    Digest $ B.allocAndFreeze (hashDigestSize (undefined :: a)) $ \(dig :: Ptr (Digest a)) -> do+hashFinalizePrefix !c b len = Digest $ allocAndFreezePrim (hashDigestSize (undefined :: a)) $+    \(dig :: Ptr (Digest a)) -> do         ((!_) :: B.Bytes) <- B.copy c $ \(ctx :: Ptr (Context a)) ->             B.withByteArray b $ \d ->                 hashInternalFinalizePrefix@@ -171,13 +167,9 @@     from :: a -> ba -> Maybe (Digest a)     from alg bs         | B.length bs == (hashDigestSize alg) =-            Just $ Digest $ unsafeDoIO $ copyBytes bs+            Just $ Digest $ copyByteArray bs         | otherwise = Nothing -    copyBytes :: ba -> IO (Block Word8)-    copyBytes ba = do-        muArray <- new count-        B.withByteArray ba $ \ptr -> copyFromPtr ptr muArray 0 count-        unsafeFreeze muArray-      where-        count = CountOf (B.length ba)+    copyByteArray ba = allocAndFreezePrim (B.length ba) $ \dst ->+        B.withByteArray ba $ \src ->+            FMU.copyBytes dst (castPtr src) (B.length ba)
Crypto/Hash/IO.hs view
@@ -20,6 +20,7 @@ ) where  import Crypto.Hash.Types+import Crypto.Internal.ByteArray (allocAndFreezePrimIO) import qualified Crypto.Internal.ByteArray as B import Foreign.Ptr @@ -66,8 +67,10 @@ hashMutableFinalize     :: forall a. HashAlgorithm a => MutableContext a -> IO (Digest a) hashMutableFinalize mc = do-    b <- B.alloc (hashDigestSize (undefined :: a)) $ \dig -> B.withByteArray mc $ \(ctx :: Ptr (Context a)) -> hashInternalFinalize ctx dig-    return $ Digest b+    ba <- allocAndFreezePrimIO (hashDigestSize (undefined :: a)) $+        \(dig :: Ptr (Digest a)) ->+            B.withByteArray mc $ \(ctx :: Ptr (Context a)) -> hashInternalFinalize ctx dig+    return (Digest ba)  -- | Reset the mutable context to the initial state of the hash hashMutableReset :: HashAlgorithm a => MutableContext a -> IO ()
Crypto/Hash/Types.hs view
@@ -20,18 +20,21 @@     Digest (..), ) where -import Basement.Block (Block, unsafeFreeze)-import Basement.Block.Mutable (MutableBlock, new, unsafeWrite)-import Basement.NormalForm (deepseq)-import Basement.Types.OffsetSize (CountOf (..), Offset (..))+import Data.Primitive.ByteArray (ByteArray, MutableByteArray, writeByteArray, newPinnedByteArray, sizeofByteArray, unsafeFreezeByteArray, withByteArrayContents)+import Control.Monad.Primitive (PrimMonad (..))+import Control.DeepSeq (deepseq) import Control.Monad.ST-import Crypto.Internal.ByteArray (ByteArrayAccess, Bytes)+import Crypto.Internal.ByteArray (ByteArrayAccess (..), Bytes) import qualified Crypto.Internal.ByteArray as B import Crypto.Internal.Imports import Data.Char (digitToInt, isHexDigit) import Data.Data (Data)-import Foreign.Ptr (Ptr)+import Foreign.Ptr (Ptr, castPtr) import GHC.TypeLits (Nat)+import Data.Base16.Types (extractBase16)+import Data.ByteString (ByteString)+import Data.ByteString.Base16 (encodeBase16)+import qualified Data.Text as Text  -- | Class representing hashing algorithms. --@@ -104,34 +107,38 @@ -- -- Creating a digest from a bytearray is also possible with function -- 'Crypto.Hash.digestFromByteString'.-newtype Digest a = Digest (Block Word8)-    deriving (Eq, Ord, ByteArrayAccess, Data)+newtype Digest a = Digest ByteArray+    deriving (Eq, Ord, Data)  type role Digest nominal  instance NFData (Digest a) where     rnf (Digest u) = u `deepseq` () +instance ByteArrayAccess (Digest a) where+    length (Digest ba) = sizeofByteArray ba+    withByteArray (Digest ba) f = withByteArrayContents ba (f . castPtr)+ instance Show (Digest a) where-    show (Digest bs) =-        map (toEnum . fromIntegral) $-            B.unpack (B.convertToBase B.Base16 bs :: Bytes)+    show d =+            Text.unpack (extractBase16 $ encodeBase16 (B.convert d :: ByteString))  instance HashAlgorithm a => Read (Digest a) where     readsPrec _ str = runST $ do-        mut <- new (CountOf len)-        loop mut len str+        mut <- newPinnedByteArray len+        loop len mut len str       where         len = hashDigestSize (undefined :: a) -        loop :: MutableBlock Word8 s -> Int -> String -> ST s [(Digest a, String)]-        loop mut 0 cs = (\b -> [(Digest b, cs)]) <$> unsafeFreeze mut-        loop _ _ [] = return []-        loop _ _ [_] = return []-        loop mut n (c : (d : ds))+loop :: Int -> MutableByteArray (PrimState (ST s)) -> Int -> String -> ST s [(Digest a, String)]+loop _ mut 0 cs = (\b -> [(Digest b, cs)]) <$> unsafeFreezeByteArray mut+loop _ _ _ [] = return []+loop _ _ _ [_] = return []+loop len mut n (c : (d : ds))             | not (isHexDigit c) = return []             | not (isHexDigit d) = return []             | otherwise = do-                let w8 = fromIntegral $ digitToInt c * 16 + digitToInt d-                unsafeWrite mut (Offset $ len - n) w8-                loop mut (n - 1) ds+                let  w8 :: Word8+                     w8 = fromIntegral $ digitToInt c * 16 + digitToInt d+                writeByteArray mut (len - n) w8+                loop len mut (n - 1) ds
Crypto/Internal/ByteArray.hs view
@@ -14,6 +14,8 @@     module Data.ByteArray.Mapping,     module Data.ByteArray.Encoding,     constAllZero,+    allocAndFreezePrimIO,+    allocAndFreezePrim, ) where  import Data.ByteArray@@ -22,10 +24,25 @@  import Data.Bits ((.|.)) import Data.Word (Word8)-import Foreign.Ptr (Ptr)+import Foreign.Ptr (Ptr, castPtr) import Foreign.Storable (peekByteOff)+import qualified Data.Primitive.ByteArray as Prim  import Crypto.Internal.Compat (unsafeDoIO)++-- | Allocate a pinned 'Prim.ByteArray' of the given size, populate it via a+-- 'Ptr', then freeze and return it.  The pointer must not be retained after+-- the action returns.+allocAndFreezePrimIO :: Int -> (Ptr p -> IO ()) -> IO Prim.ByteArray+allocAndFreezePrimIO n f = do+    mba <- Prim.newPinnedByteArray n+    f (castPtr (Prim.mutableByteArrayContents mba))+    Prim.unsafeFreezeByteArray mba++-- | The allocation is strictly local,+-- the computation is deterministic, and no IO effects escape.+allocAndFreezePrim :: Int -> (Ptr p -> IO ()) -> Prim.ByteArray+allocAndFreezePrim n = unsafeDoIO . allocAndFreezePrimIO n  constAllZero :: ByteArrayAccess ba => ba -> Bool constAllZero b = unsafeDoIO $ withByteArray b $ \p -> loop p 0 0
Crypto/KDF/BCryptPBKDF.hs view
@@ -13,11 +13,6 @@ ) where -import Basement.Block (MutableBlock)-import qualified Basement.Block as Block-import qualified Basement.Block.Mutable as Block-import Basement.Monad (PrimState)-import Basement.Types.OffsetSize (CountOf (..), Offset (..)) import Control.Exception (finally) import Control.Monad (when) import qualified Crypto.Cipher.Blowfish.Box as Blowfish@@ -34,9 +29,11 @@ import Crypto.Internal.Compat (unsafeDoIO) import Data.Bits import qualified Data.ByteArray as B+import qualified Data.ByteString.Internal as BSI import Data.Foldable (forM_) import Data.Memory.PtrMethods (memCopy, memSet, memXor) import Data.Word+import Foreign.ForeignPtr (ForeignPtr, mallocForeignPtrBytes, withForeignPtr) import Foreign.Ptr (Ptr, castPtr) import Foreign.Storable (peekByteOff, pokeByteOff) @@ -76,70 +73,70 @@      deriveKey :: Ptr Word8 -> IO ()     deriveKey keyPtr = do-        -- Allocate all necessary memory. The algorihm shall not allocate-        -- any more dynamic memory after this point. Blocks need to be pinned-        -- as pointers to them are passed to the SHA512 implementation.-        ksClean <- Blowfish.createKeySchedule-        ksDirty <- Blowfish.createKeySchedule-        ctxMBlock <- Block.newPinned (CountOf ctxLen :: CountOf Word8)-        outMBlock <- Block.newPinned (CountOf outLen :: CountOf Word8)-        tmpMBlock <- Block.newPinned (CountOf tmpLen :: CountOf Word8)-        blkMBlock <- Block.newPinned (CountOf blkLen :: CountOf Word8)-        passHashMBlock <- Block.newPinned (CountOf hashLen :: CountOf Word8)-        saltHashMBlock <- Block.newPinned (CountOf hashLen :: CountOf Word8)+        -- Allocate all necessary memory. The algorithm shall not allocate+        -- any more dynamic memory after this point. ForeignPtrs allocate+        -- pinned memory, so raw pointers to them are stable.+        ksClean      <- Blowfish.createKeySchedule+        ksDirty      <- Blowfish.createKeySchedule+        ctxFP        <- mallocForeignPtrBytes ctxLen  :: IO (ForeignPtr Word8)+        outFP        <- mallocForeignPtrBytes outLen  :: IO (ForeignPtr Word8)+        tmpFP        <- mallocForeignPtrBytes tmpLen  :: IO (ForeignPtr Word8)+        blkFP        <- mallocForeignPtrBytes blkLen  :: IO (ForeignPtr Word8)+        passHashFP   <- mallocForeignPtrBytes hashLen :: IO (ForeignPtr Word8)+        saltHashFP   <- mallocForeignPtrBytes hashLen :: IO (ForeignPtr Word8)         -- Finally erase all memory areas that contain information from         -- which the derived key could be reconstructed.-        -- As all MutableBlocks are pinned it shall be guaranteed that-        -- no temporary trampoline buffers are allocated.-        finallyErase outMBlock $-            finallyErase passHashMBlock $+        finallyErase outFP outLen $+            finallyErase passHashFP hashLen $                 B.withByteArray pass $ \passPtr ->                     B.withByteArray salt $ \saltPtr ->-                        Block.withMutablePtr ctxMBlock $ \ctxPtr ->-                            Block.withMutablePtr outMBlock $ \outPtr ->-                                Block.withMutablePtr tmpMBlock $ \tmpPtr ->-                                    Block.withMutablePtr blkMBlock $ \blkPtr ->-                                        Block.withMutablePtr passHashMBlock $ \passHashPtr ->-                                            Block.withMutablePtr saltHashMBlock $ \saltHashPtr -> do-                                                -- Hash the password.-                                                let shaPtr = castPtr ctxPtr :: Ptr (Context SHA512)-                                                hashInternalInit shaPtr-                                                hashInternalUpdate shaPtr passPtr (fromIntegral passLen)-                                                hashInternalFinalize shaPtr (castPtr passHashPtr)-                                                passHashBlock <- Block.unsafeFreeze passHashMBlock-                                                forM_ [1 .. blocks] $ \block -> do-                                                    -- Poke the increased block counter.-                                                    Block.unsafeWrite blkMBlock 0 (fromIntegral $ block `shiftR` 24)-                                                    Block.unsafeWrite blkMBlock 1 (fromIntegral $ block `shiftR` 16)-                                                    Block.unsafeWrite blkMBlock 2 (fromIntegral $ block `shiftR` 8)-                                                    Block.unsafeWrite blkMBlock 3 (fromIntegral $ block `shiftR` 0)-                                                    -- First round (slightly different).-                                                    hashInternalInit shaPtr-                                                    hashInternalUpdate shaPtr saltPtr (fromIntegral saltLen)-                                                    hashInternalUpdate shaPtr blkPtr (fromIntegral blkLen)-                                                    hashInternalFinalize shaPtr (castPtr saltHashPtr)-                                                    Block.unsafeFreeze saltHashMBlock >>= \x -> do-                                                        Blowfish.copyKeySchedule ksDirty ksClean-                                                        hashInternalMutable ksDirty passHashBlock x tmpMBlock-                                                    memCopy outPtr tmpPtr outLen-                                                    -- Remaining rounds.-                                                    forM_ [2 .. iterCounts params] $ const $ do-                                                        hashInternalInit shaPtr-                                                        hashInternalUpdate shaPtr tmpPtr (fromIntegral tmpLen)-                                                        hashInternalFinalize shaPtr (castPtr saltHashPtr)-                                                        Block.unsafeFreeze saltHashMBlock >>= \x -> do-                                                            Blowfish.copyKeySchedule ksDirty ksClean-                                                            hashInternalMutable ksDirty passHashBlock x tmpMBlock-                                                        memXor outPtr outPtr tmpPtr outLen-                                                    -- Spread the current out buffer evenly over the key buffer.-                                                    -- After both loops have run every byte of the key buffer-                                                    -- will have been written to exactly once and every byte-                                                    -- of the output will have been used.-                                                    forM_ [0 .. outLen - 1] $ \outIdx -> do-                                                        let keyIdx = outIdx * blocks + block - 1-                                                        when (keyIdx < keyLen) $ do-                                                            w8 <- peekByteOff outPtr outIdx :: IO Word8-                                                            pokeByteOff keyPtr keyIdx w8+                        withForeignPtr ctxFP      $ \ctxPtr'     ->+                        withForeignPtr outFP      $ \outPtr      ->+                        withForeignPtr tmpFP      $ \tmpPtr      ->+                        withForeignPtr blkFP      $ \blkPtr      ->+                        withForeignPtr passHashFP $ \passHashPtr ->+                        withForeignPtr saltHashFP $ \saltHashPtr -> do+                            -- Hash the password.+                            let shaPtr = castPtr ctxPtr' :: Ptr (Context SHA512)+                            hashInternalInit shaPtr+                            hashInternalUpdate shaPtr passPtr (fromIntegral passLen)+                            hashInternalFinalize shaPtr (castPtr passHashPtr)+                            -- Create a stable ByteString view of the password hash+                            -- (passHashFP is not modified after this point).+                            let passHashBS = BSI.fromForeignPtr passHashFP 0 hashLen+                            forM_ [1 .. blocks] $ \block -> do+                                -- Poke the increased block counter.+                                pokeByteOff blkPtr 0 (fromIntegral (block `shiftR` 24) :: Word8)+                                pokeByteOff blkPtr 1 (fromIntegral (block `shiftR` 16) :: Word8)+                                pokeByteOff blkPtr 2 (fromIntegral (block `shiftR` 8) :: Word8)+                                pokeByteOff blkPtr 3 (fromIntegral (block `shiftR` 0 :: Int) :: Word8)+                                -- First round (slightly different).+                                hashInternalInit shaPtr+                                hashInternalUpdate shaPtr saltPtr (fromIntegral saltLen)+                                hashInternalUpdate shaPtr blkPtr (fromIntegral blkLen)+                                hashInternalFinalize shaPtr (castPtr saltHashPtr)+                                let saltHashBS = BSI.fromForeignPtr saltHashFP 0 hashLen+                                Blowfish.copyKeySchedule ksDirty ksClean+                                hashInternalMutable ksDirty passHashBS saltHashBS tmpPtr+                                memCopy outPtr tmpPtr outLen+                                -- Remaining rounds.+                                forM_ [2 .. iterCounts params] $ const $ do+                                    hashInternalInit shaPtr+                                    hashInternalUpdate shaPtr tmpPtr (fromIntegral tmpLen)+                                    hashInternalFinalize shaPtr (castPtr saltHashPtr)+                                    let saltHashBS2 = BSI.fromForeignPtr saltHashFP 0 hashLen+                                    Blowfish.copyKeySchedule ksDirty ksClean+                                    hashInternalMutable ksDirty passHashBS saltHashBS2 tmpPtr+                                    memXor outPtr outPtr tmpPtr outLen+                                -- Spread the current out buffer evenly over the key buffer.+                                -- After both loops have run every byte of the key buffer+                                -- will have been written to exactly once and every byte+                                -- of the output will have been used.+                                forM_ [0 .. outLen - 1] $ \outIdx -> do+                                    let keyIdx = outIdx * blocks + block - 1+                                    when (keyIdx < keyLen) $ do+                                        w8 <- peekByteOff outPtr outIdx :: IO Word8+                                        pokeByteOff keyPtr keyIdx w8  -- | Internal hash function used by `generate`. --@@ -154,18 +151,16 @@     | B.length saltHash /= 64 = error "saltHash must be 512 bits"     | otherwise = unsafeDoIO $ do         ks0 <- Blowfish.createKeySchedule-        outMBlock <- Block.newPinned 32-        hashInternalMutable ks0 passHash saltHash outMBlock-        B.convert `fmap` Block.freeze outMBlock+        B.alloc 32 $ \outPtr -> hashInternalMutable ks0 passHash saltHash outPtr  hashInternalMutable     :: (B.ByteArrayAccess pass, B.ByteArrayAccess salt)     => Blowfish.KeySchedule     -> pass     -> salt-    -> MutableBlock Word8 (PrimState IO)+    -> Ptr Word8     -> IO ()-hashInternalMutable bfks passHash saltHash outMBlock = do+hashInternalMutable bfks passHash saltHash outPtr = do     Blowfish.expandKeyWithSalt bfks passHash saltHash     forM_ [0 .. 63 :: Int] $ const $ do         Blowfish.expandKey bfks saltHash@@ -176,22 +171,20 @@     store 16 =<< cipher 64 0x6669736853776174     store 24 =<< cipher 64 0x44796e616d697465   where-    store :: Offset Word8 -> Word64 -> IO ()+    store :: Int -> Word64 -> IO ()     store o w64 = do-        Block.unsafeWrite outMBlock (o + 0) (fromIntegral $ w64 `shiftR` 32)-        Block.unsafeWrite outMBlock (o + 1) (fromIntegral $ w64 `shiftR` 40)-        Block.unsafeWrite outMBlock (o + 2) (fromIntegral $ w64 `shiftR` 48)-        Block.unsafeWrite outMBlock (o + 3) (fromIntegral $ w64 `shiftR` 56)-        Block.unsafeWrite outMBlock (o + 4) (fromIntegral $ w64 `shiftR` 0)-        Block.unsafeWrite outMBlock (o + 5) (fromIntegral $ w64 `shiftR` 8)-        Block.unsafeWrite outMBlock (o + 6) (fromIntegral $ w64 `shiftR` 16)-        Block.unsafeWrite outMBlock (o + 7) (fromIntegral $ w64 `shiftR` 24)+        pokeByteOff outPtr (o + 0) (fromIntegral (w64 `shiftR` 32) :: Word8)+        pokeByteOff outPtr (o + 1) (fromIntegral (w64 `shiftR` 40) :: Word8)+        pokeByteOff outPtr (o + 2) (fromIntegral (w64 `shiftR` 48) :: Word8)+        pokeByteOff outPtr (o + 3) (fromIntegral (w64 `shiftR` 56) :: Word8)+        pokeByteOff outPtr (o + 4) (fromIntegral (w64 `shiftR` 0)  :: Word8)+        pokeByteOff outPtr (o + 5) (fromIntegral (w64 `shiftR` 8)  :: Word8)+        pokeByteOff outPtr (o + 6) (fromIntegral (w64 `shiftR` 16) :: Word8)+        pokeByteOff outPtr (o + 7) (fromIntegral (w64 `shiftR` 24) :: Word8)     cipher :: Int -> Word64 -> IO Word64     cipher 0 block = return block     cipher i block = Blowfish.cipherBlockMutable bfks block >>= cipher (i - 1) -finallyErase :: MutableBlock Word8 (PrimState IO) -> IO () -> IO ()-finallyErase mblock action =-    action `finally` Block.withMutablePtr mblock (\ptr -> memSet ptr 0 len)-  where-    CountOf len = Block.mutableLengthBytes mblock+finallyErase :: ForeignPtr Word8 -> Int -> IO () -> IO ()+finallyErase fp len action =+    action `finally` withForeignPtr fp (\ptr -> memSet ptr 0 len)
Crypto/MAC/KMAC.hs view
@@ -29,6 +29,7 @@ import Crypto.Hash.Types (Digest (..), HashAlgorithm (..)) import qualified Crypto.Hash.Types as H import Crypto.Internal.Builder+import Crypto.Internal.ByteArray (allocAndFreezePrim) import Crypto.Internal.Imports import Data.Bits (shiftR) import Data.ByteArray (ByteArrayAccess)@@ -69,8 +70,8 @@     :: forall a suffix      . (HashSHAKE a, ByteArrayAccess suffix)     => H.Context a -> suffix -> Digest a-cshakeFinalize !c s =-    Digest $ B.allocAndFreeze (hashDigestSize (undefined :: a)) $ \dig -> do+cshakeFinalize !c s = Digest $ allocAndFreezePrim (hashDigestSize (undefined :: a)) $+    \(dig :: Ptr (Digest a)) -> do         ((!_) :: B.Bytes) <- B.copy c $ \(ctx :: Ptr (H.Context a)) -> do             B.withByteArray s $ \d ->                 hashInternalUpdate ctx d (fromIntegral $ B.length s)
Crypto/PubKey/ECDSA.hs view
@@ -261,8 +261,9 @@ tHashDigest     :: (EllipticCurveECDSA curve, HashAlgorithm hash)     => proxy curve -> Digest hash -> Scalar curve-tHashDigest prx (Digest digest) = throwCryptoError $ decodeScalar prx encoded+tHashDigest prx dig = throwCryptoError $ decodeScalar prx encoded   where+    digest = B.convert dig :: B.Bytes     m = curveOrderBits prx     d = m - B.length digest * 8     (n, r) = m `divMod` 8
crypton.cabal view
@@ -1,13 +1,13 @@ cabal-version:      1.18 name:               crypton-version:            1.0.6+version:            1.1.0 license:            BSD3 license-file:       LICENSE copyright:          Vincent Hanquez <vincent@snarc.org> maintainer:         Kazu Yamamoto <kazu@iij.ad.jp> author:             Vincent Hanquez <vincent@snarc.org> stability:          experimental-tested-with:        GHC ==8.8.4 || ==8.10.7 || ==9.0.2 || ==9.2.2+tested-with:        GHC ==9.2.8 || ==9.4.8 || ==9.6.7 || ==9.8.4 || ==9.10.1 || ==9.12.1 homepage:           https://github.com/kazu-yamamoto/crypton bug-reports:        https://github.com/kazu-yamamoto/crypton/issues synopsis:           Cryptography Primitives sink@@ -303,9 +303,13 @@     ghc-options:      -Wall -fwarn-tabs -optc-O3     build-depends:           base        >=4.13    && <5-        , basement    >=0.0.6         , bytestring-        , memory      >=0.14.18+        , primitive   >=0.9+        , deepseq+        , base16      >=1.0+        , bytestring+        , text+        , ram >=0.20.1 && < 0.22      if flag(old_toolchain_inliner)         cc-options: -fgnu89-inline@@ -502,7 +506,7 @@           base              >=4.13 && <5         , bytestring         , crypton-        , memory+        , ram         , tasty         , tasty-hunit         , tasty-kat@@ -521,7 +525,7 @@         , crypton         , deepseq         , gauge-        , memory+        , ram         , random  -- cabal-fmt: indent 4