saltine 0.1.0.2 → 0.1.1.0
raw patch · 16 files changed
+244/−35 lines, 16 filesdep +hashabledep ~basedep ~bytestringdep ~profunctorsPVP ok
version bump matches the API change (PVP)
Dependencies added: hashable
Dependency ranges changed: base, bytestring, profunctors
API changes (from Hackage documentation)
+ Crypto.Saltine.Core.AEAD: instance Data.Data.Data Crypto.Saltine.Core.AEAD.Key
+ Crypto.Saltine.Core.AEAD: instance Data.Data.Data Crypto.Saltine.Core.AEAD.Nonce
+ Crypto.Saltine.Core.AEAD: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.AEAD.Key
+ Crypto.Saltine.Core.AEAD: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.AEAD.Nonce
+ Crypto.Saltine.Core.AEAD: instance GHC.Generics.Generic Crypto.Saltine.Core.AEAD.Key
+ Crypto.Saltine.Core.AEAD: instance GHC.Generics.Generic Crypto.Saltine.Core.AEAD.Nonce
+ Crypto.Saltine.Core.Auth: instance Data.Data.Data Crypto.Saltine.Core.Auth.Authenticator
+ Crypto.Saltine.Core.Auth: instance Data.Data.Data Crypto.Saltine.Core.Auth.Key
+ Crypto.Saltine.Core.Auth: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Auth.Authenticator
+ Crypto.Saltine.Core.Auth: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Auth.Key
+ Crypto.Saltine.Core.Auth: instance GHC.Generics.Generic Crypto.Saltine.Core.Auth.Authenticator
+ Crypto.Saltine.Core.Auth: instance GHC.Generics.Generic Crypto.Saltine.Core.Auth.Key
+ Crypto.Saltine.Core.Box: instance Data.Data.Data Crypto.Saltine.Core.Box.CombinedKey
+ Crypto.Saltine.Core.Box: instance Data.Data.Data Crypto.Saltine.Core.Box.Nonce
+ Crypto.Saltine.Core.Box: instance Data.Data.Data Crypto.Saltine.Core.Box.PublicKey
+ Crypto.Saltine.Core.Box: instance Data.Data.Data Crypto.Saltine.Core.Box.SecretKey
+ Crypto.Saltine.Core.Box: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Box.CombinedKey
+ Crypto.Saltine.Core.Box: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Box.Nonce
+ Crypto.Saltine.Core.Box: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Box.PublicKey
+ Crypto.Saltine.Core.Box: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Box.SecretKey
+ Crypto.Saltine.Core.Box: instance GHC.Generics.Generic Crypto.Saltine.Core.Box.CombinedKey
+ Crypto.Saltine.Core.Box: instance GHC.Generics.Generic Crypto.Saltine.Core.Box.Nonce
+ Crypto.Saltine.Core.Box: instance GHC.Generics.Generic Crypto.Saltine.Core.Box.PublicKey
+ Crypto.Saltine.Core.Box: instance GHC.Generics.Generic Crypto.Saltine.Core.Box.SecretKey
+ Crypto.Saltine.Core.Hash: data GenerichashKey
+ Crypto.Saltine.Core.Hash: data GenerichashOutLen
+ Crypto.Saltine.Core.Hash: generichash :: GenerichashKey -> ByteString -> GenerichashOutLen -> ByteString
+ Crypto.Saltine.Core.Hash: generichashOutLen :: Int -> Maybe GenerichashOutLen
+ Crypto.Saltine.Core.Hash: instance Crypto.Saltine.Class.IsEncoding Crypto.Saltine.Core.Hash.GenerichashKey
+ Crypto.Saltine.Core.Hash: instance Data.Data.Data Crypto.Saltine.Core.Hash.GenerichashKey
+ Crypto.Saltine.Core.Hash: instance Data.Data.Data Crypto.Saltine.Core.Hash.GenerichashOutLen
+ Crypto.Saltine.Core.Hash: instance Data.Data.Data Crypto.Saltine.Core.Hash.ShorthashKey
+ Crypto.Saltine.Core.Hash: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Hash.GenerichashKey
+ Crypto.Saltine.Core.Hash: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Hash.GenerichashOutLen
+ Crypto.Saltine.Core.Hash: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Hash.ShorthashKey
+ Crypto.Saltine.Core.Hash: instance GHC.Classes.Eq Crypto.Saltine.Core.Hash.GenerichashKey
+ Crypto.Saltine.Core.Hash: instance GHC.Classes.Eq Crypto.Saltine.Core.Hash.GenerichashOutLen
+ Crypto.Saltine.Core.Hash: instance GHC.Classes.Ord Crypto.Saltine.Core.Hash.GenerichashKey
+ Crypto.Saltine.Core.Hash: instance GHC.Classes.Ord Crypto.Saltine.Core.Hash.GenerichashOutLen
+ Crypto.Saltine.Core.Hash: instance GHC.Generics.Generic Crypto.Saltine.Core.Hash.GenerichashKey
+ Crypto.Saltine.Core.Hash: instance GHC.Generics.Generic Crypto.Saltine.Core.Hash.GenerichashOutLen
+ Crypto.Saltine.Core.Hash: instance GHC.Generics.Generic Crypto.Saltine.Core.Hash.ShorthashKey
+ Crypto.Saltine.Core.Hash: newGenerichashKey :: Int -> IO (Maybe GenerichashKey)
+ Crypto.Saltine.Core.OneTimeAuth: instance Data.Data.Data Crypto.Saltine.Core.OneTimeAuth.Authenticator
+ Crypto.Saltine.Core.OneTimeAuth: instance Data.Data.Data Crypto.Saltine.Core.OneTimeAuth.Key
+ Crypto.Saltine.Core.OneTimeAuth: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.OneTimeAuth.Authenticator
+ Crypto.Saltine.Core.OneTimeAuth: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.OneTimeAuth.Key
+ Crypto.Saltine.Core.OneTimeAuth: instance GHC.Generics.Generic Crypto.Saltine.Core.OneTimeAuth.Authenticator
+ Crypto.Saltine.Core.OneTimeAuth: instance GHC.Generics.Generic Crypto.Saltine.Core.OneTimeAuth.Key
+ Crypto.Saltine.Core.ScalarMult: instance Data.Data.Data Crypto.Saltine.Core.ScalarMult.GroupElement
+ Crypto.Saltine.Core.ScalarMult: instance Data.Data.Data Crypto.Saltine.Core.ScalarMult.Scalar
+ Crypto.Saltine.Core.ScalarMult: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.ScalarMult.GroupElement
+ Crypto.Saltine.Core.ScalarMult: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.ScalarMult.Scalar
+ Crypto.Saltine.Core.ScalarMult: instance GHC.Classes.Ord Crypto.Saltine.Core.ScalarMult.GroupElement
+ Crypto.Saltine.Core.ScalarMult: instance GHC.Classes.Ord Crypto.Saltine.Core.ScalarMult.Scalar
+ Crypto.Saltine.Core.ScalarMult: instance GHC.Generics.Generic Crypto.Saltine.Core.ScalarMult.GroupElement
+ Crypto.Saltine.Core.ScalarMult: instance GHC.Generics.Generic Crypto.Saltine.Core.ScalarMult.Scalar
+ Crypto.Saltine.Core.SecretBox: instance Data.Data.Data Crypto.Saltine.Core.SecretBox.Key
+ Crypto.Saltine.Core.SecretBox: instance Data.Data.Data Crypto.Saltine.Core.SecretBox.Nonce
+ Crypto.Saltine.Core.SecretBox: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.SecretBox.Key
+ Crypto.Saltine.Core.SecretBox: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.SecretBox.Nonce
+ Crypto.Saltine.Core.SecretBox: instance GHC.Generics.Generic Crypto.Saltine.Core.SecretBox.Key
+ Crypto.Saltine.Core.SecretBox: instance GHC.Generics.Generic Crypto.Saltine.Core.SecretBox.Nonce
+ Crypto.Saltine.Core.Sign: instance Data.Data.Data Crypto.Saltine.Core.Sign.PublicKey
+ Crypto.Saltine.Core.Sign: instance Data.Data.Data Crypto.Saltine.Core.Sign.SecretKey
+ Crypto.Saltine.Core.Sign: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Sign.PublicKey
+ Crypto.Saltine.Core.Sign: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Sign.SecretKey
+ Crypto.Saltine.Core.Sign: instance GHC.Generics.Generic Crypto.Saltine.Core.Sign.PublicKey
+ Crypto.Saltine.Core.Sign: instance GHC.Generics.Generic Crypto.Saltine.Core.Sign.SecretKey
+ Crypto.Saltine.Core.Stream: instance Data.Data.Data Crypto.Saltine.Core.Stream.Key
+ Crypto.Saltine.Core.Stream: instance Data.Data.Data Crypto.Saltine.Core.Stream.Nonce
+ Crypto.Saltine.Core.Stream: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Stream.Key
+ Crypto.Saltine.Core.Stream: instance Data.Hashable.Class.Hashable Crypto.Saltine.Core.Stream.Nonce
+ Crypto.Saltine.Core.Stream: instance GHC.Generics.Generic Crypto.Saltine.Core.Stream.Key
+ Crypto.Saltine.Core.Stream: instance GHC.Generics.Generic Crypto.Saltine.Core.Stream.Nonce
+ Crypto.Saltine.Internal.ByteSizes: generichashKeyLenMax :: Int
+ Crypto.Saltine.Internal.ByteSizes: generichashOutLenMax :: Int
Files
- CHANGELOG.md +14/−0
- README.md +69/−0
- saltine.cabal +10/−5
- src/Crypto/Saltine/Core/AEAD.hs +7/−2
- src/Crypto/Saltine/Core/Auth.hs +7/−2
- src/Crypto/Saltine/Core/Box.hs +9/−4
- src/Crypto/Saltine/Core/Hash.hs +68/−6
- src/Crypto/Saltine/Core/OneTimeAuth.hs +7/−2
- src/Crypto/Saltine/Core/ScalarMult.hs +7/−2
- src/Crypto/Saltine/Core/SecretBox.hs +7/−2
- src/Crypto/Saltine/Core/Sign.hs +8/−2
- src/Crypto/Saltine/Core/Stream.hs +7/−2
- src/Crypto/Saltine/Internal/ByteSizes.hs +16/−2
- tests/AEADProperties.hs +3/−2
- tests/Main.hs +2/−0
- tests/SecretBoxProperties.hs +3/−2
+ CHANGELOG.md view
@@ -0,0 +1,14 @@+# Changelog+All notable changes to this project will be documented in this file.++The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)++## [Unreleased]++## [0.1.1.0] - 2020-02-29+### Added+- bindings to generichash (Blake2), thanks [@donatello](https://github.com/donatello)++### Changed+- Don't use `fail` in tests to fix compilation with GHC 8.8+- Windows install instructions added, thanks [@tmcl](https://github.com/tmcl)
+ README.md view
@@ -0,0 +1,69 @@+# Saltine 0.1.1.0 [](https://travis-ci.org/tel/saltine)[](https://hackage.haskell.org/package/saltine)++A Haskell binding for @jedisct1's portable binding for djb's+NaCl. **This is an early release.** Please try it out, but don't just+yet stake your life or job on it.++It is imperative you call `sodiumInit` before using any other function.++``` haskell+import Crypto.Saltine+import Crypto.Saltine.Core.SecretBox+import qualified Data.ByteString.Char8 as BSC8++main = do+ sodiumInit+ k <- newKey+ n <- newNonce+ let ciphertext = secretbox k n (BSC8.pack "foobar")+ print $ secretboxOpen k n ciphertext++-- Just "foobar"+```++In+[*The Security Impact of a New Cryptographic Library*](http://cryptojedi.org/papers/coolnacl-20111201.pdf)+Bernstein, Lange, and Schwabe argue that high-level cryptographic+libraries eliminate whole spaces of cryptographic disasters which are+nigh inevitable whenever programmers use low-level crypto primitives.++* [Security Stack Exchange: Why Shouldn't We Roll Our Own?](http://security.stackexchange.com/questions/18197/why-shouldnt-we-roll-our-own)+* [Hacker News on "All the Crypto Code You've Ever Written is Probably Broken"](https://news.ycombinator.com/item?id=4779015)+* [Stack Overflow: When can you trust yourself to implement cryptography based solutions?](http://stackoverflow.com/questions/1914257/when-can-you-trust-yourself-to-implement-cryptography-based-solutions)+* [Coding Horror: Why isn't my encryption... encrypting?](http://www.codinghorror.com/blog/2009/05/why-isnt-my-encryption-encrypting.html)++Crypto is complicated, so pre-rolled solutions are important+prevention mechanisms.++[NaCl](http://nacl.cr.yp.to/) is Bernstein, Lange, and Schwabe's+solution: a high-level, performant cryptography library with a no-fuss+interface. [Saltine](http://github.com/tel/saltine) is a Haskell+binding to NaCl (via+[`libsodium`](https://github.com/jedisct1/libsodium)) which hopes to+provide even more simplicity and safety to the usage of cryptography.++Note that it's still possible to shoot yourself in the foot pretty+easily using Saltine. Nonces must always be unique which must be managed +by the library user.+[`Crypto.Saltine.Core.Stream`](https://github.com/tel/saltine/blob/master/src/Crypto/Saltine/Core/Stream.hs)+produces messages which can beundetectably tampered with in-flight. +Keys are insecurely read from disk—they may be copied and then paged +back to disk.++When uncertain, use [`Crypto.Saltine.Core.SecretBox`](https://github.com/tel/saltine/blob/master/src/Crypto/Saltine/Core/SecretBox.hs) +and [`Crypto.Saltine.Core.Box`](https://github.com/tel/saltine/blob/master/src/Crypto/Saltine/Core/Box.hs).+If you can think of ways to use Haskell's type system to enforce +security invariants, please suggest them.++To use it on Windows systems, download +[a prebuild libsodium-\*-stable-mingw.tar.gz file](https://download.libsodium.org/libsodium/releases/) +and copy the files in `libsodium-win64` into the equivalent places +in `C:\Program Files\Haskell Platform\*\mingw`. Then just add saltine +to your cabal file and watch it go.++Tested with [`libsodium-1.0.13`](https://download.libsodium.org/libsodium/releases/).++Inspired by @thoughtpolice's+[`salt`](http://github.com/thoughtpolice/salt) library. `salt` also+binds to NaCl, but uses a Haskell managed version of djb's code+instead of `libsodium`.
saltine.cabal view
@@ -1,5 +1,5 @@ name: saltine-version: 0.1.0.2+version: 0.1.1.0 synopsis: Cryptography that's easy to digest (NaCl/libsodium bindings). description: @@ -18,6 +18,10 @@ /Saltine/ is a Haskell binding to the NaCl primitives going through Sodium for build convenience and, eventually, portability. +extra-source-files:+ README.md+ CHANGELOG.md+ license: MIT license-file: LICENSE author: Joseph Abrahamson@@ -27,7 +31,7 @@ category: Cryptography build-type: Simple cabal-version: >=1.10-tested-with: GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.1+tested-with: GHC==7.8.4, GHC==7.10.3, GHC==8.0.2, GHC==8.2.2, GHC==8.4.3, GHC==8.6.5, GHC==8.8.3 source-repository head type: git@@ -62,8 +66,9 @@ default-language: Haskell2010 build-depends: base >= 4.5 && < 5- , bytestring- , profunctors+ , bytestring >= 0.10.8 && < 0.11+ , profunctors >= 5.3 && < 5.6+ , hashable test-suite tests type: exitcode-stdio-1.0@@ -83,7 +88,7 @@ hs-source-dirs: tests default-language: Haskell2010 build-depends:- base >= 4.5 && < 5+ base >= 4.7 && < 5 , saltine , bytestring , QuickCheck
src/Crypto/Saltine/Core/AEAD.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}+ -- | -- Module : Crypto.Saltine.Core.AEAD -- Copyright : (c) Thomas DuBuisson 2017@@ -47,11 +49,14 @@ import Foreign.Ptr import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Hashable (Hashable)+import Data.Data (Data, Typeable)+import GHC.Generics (Generic) -- $types -- | An opaque 'secretbox' cryptographic key.-newtype Key = Key ByteString deriving (Eq, Ord)+newtype Key = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding Key where decode v = if S.length v == Bytes.secretBoxKey@@ -62,7 +67,7 @@ {-# INLINE encode #-} -- | An opaque 'secretbox' nonce.-newtype Nonce = Nonce ByteString deriving (Eq, Ord)+newtype Nonce = Nonce ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding Nonce where decode v = if S.length v == Bytes.secretBoxNonce
src/Crypto/Saltine/Core/Auth.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}+ -- | -- Module : Crypto.Saltine.Core.Auth -- Copyright : (c) Joseph Abrahamson 2013@@ -52,14 +54,17 @@ import Foreign.Ptr import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Hashable (Hashable)+import Data.Data (Data, Typeable)+import GHC.Generics (Generic) -- $types -- | An opaque 'auth' cryptographic key.-newtype Key = Key ByteString deriving (Eq, Ord)+newtype Key = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) -- | An opaque 'auth' authenticator.-newtype Authenticator = Au ByteString deriving (Eq, Ord)+newtype Authenticator = Au ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding Key where decode v = if S.length v == Bytes.authKey
src/Crypto/Saltine/Core/Box.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}+ -- | -- Module : Crypto.Saltine.Core.Box -- Copyright : (c) Joseph Abrahamson 2013@@ -94,12 +96,15 @@ import Foreign.Ptr import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Hashable (Hashable)+import Data.Data (Data, Typeable)+import GHC.Generics (Generic) -- $types -- | An opaque 'box' cryptographic secret key.-newtype SecretKey = SK ByteString deriving (Eq, Ord)+newtype SecretKey = SK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding SecretKey where decode v = if S.length v == Bytes.boxSK@@ -110,7 +115,7 @@ {-# INLINE encode #-} -- | An opaque 'box' cryptographic public key.-newtype PublicKey = PK ByteString deriving (Eq, Ord)+newtype PublicKey = PK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding PublicKey where decode v = if S.length v == Bytes.boxPK@@ -124,7 +129,7 @@ type Keypair = (SecretKey, PublicKey) -- | An opaque 'boxAfterNM' cryptographic combined key.-newtype CombinedKey = CK ByteString deriving (Eq, Ord)+newtype CombinedKey = CK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding CombinedKey where decode v = if S.length v == Bytes.boxBeforeNM@@ -135,7 +140,7 @@ {-# INLINE encode #-} -- | An opaque 'box' nonce.-newtype Nonce = Nonce ByteString deriving (Eq, Ord)+newtype Nonce = Nonce ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding Nonce where decode v = if S.length v == Bytes.boxNonce
src/Crypto/Saltine/Core/Hash.hs view
@@ -1,4 +1,6 @@--- |+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}++ -- | -- Module : Crypto.Saltine.Core.Hash -- Copyright : (c) Joseph Abrahamson 2013 -- License : MIT@@ -34,16 +36,20 @@ -- alternatives that inspire satisfactory levels of confidence. One -- can hope that NIST's SHA-3 competition will improve the situation. ----- Sodium includes an implementation of the Blake2 hash--- (<https://blake2.net/>) but since this is not standard NaCl nor was--- Blake2 selected to be SHA-3 the library doesn't bind it.+-- Sodium includes an implementation of the Blake2b hash function+-- (<https://blake2.net/>) and is bound here as the 'generichash'+-- function. -- -- This is version 2010.08.30 of the hash.html web page. Information -- about SipHash has been added. module Crypto.Saltine.Core.Hash ( ShorthashKey, hash,- shorthash, newShorthashKey+ shorthash, newShorthashKey,+ GenerichashKey,+ newGenerichashKey,+ GenerichashOutLen,+ generichashOutLen, generichash ) where import Crypto.Saltine.Class@@ -55,6 +61,9 @@ import Foreign.Ptr import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Hashable (Hashable)+import Data.Data (Data, Typeable)+import GHC.Generics (Generic) -- | Computes a cryptographically collision-resistant hash making -- @hash m == hash m' ==> m == m'@ highly likely even when under@@ -67,7 +76,7 @@ constByteStrings [m] $ \[(pm, _)] -> c_hash ph pm (fromIntegral $ S.length m) -- | An opaque 'shorthash' cryptographic secret key.-newtype ShorthashKey = ShK ByteString deriving (Eq, Ord)+newtype ShorthashKey = ShK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding ShorthashKey where decode v = if S.length v == Bytes.shorthashKey@@ -91,6 +100,43 @@ constByteStrings [k, m] $ \[(pk, _), (pm, _)] -> c_shorthash ph pm (fromIntegral $ S.length m) pk +-- | An opaque 'generichash' cryptographic secret key.+newtype GenerichashKey = GhK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic)++instance IsEncoding GenerichashKey where+ decode v = if S.length v <= Bytes.generichashKeyLenMax+ then Just (GhK v)+ else Nothing+ {-# INLINE decode #-}+ encode (GhK v) = v+ {-# INLINE encode #-}++-- | Randomly generates a new key for 'generichash' of the given length.+newGenerichashKey :: Int -> IO (Maybe GenerichashKey)+newGenerichashKey n = if n >= 0 && n <= Bytes.generichashKeyLenMax+ then Just . GhK <$> randomByteString n+ else return Nothing++newtype GenerichashOutLen = GhOL Int deriving (Eq, Ord, Hashable, Data, Typeable, Generic)++-- | Create a validated Generichash output length+generichashOutLen :: Int -> Maybe GenerichashOutLen+generichashOutLen n = if n > 0 && n <= Bytes.generichashOutLenMax+ then Just $ GhOL $ fromIntegral n+ else Nothing++-- | Computes a generic, keyed hash.+generichash :: GenerichashKey+ -> ByteString+ -- ^ Message+ -> GenerichashOutLen+ -- ^ Desired output hash length+ -> ByteString+ -- ^ Hash+generichash (GhK k) m (GhOL outLen) = snd . buildUnsafeByteString outLen $ \ph ->+ constByteStrings [k, m] $ \[(pk, _), (pm, _)] ->+ c_generichash ph (fromIntegral outLen) pm (fromIntegral $ S.length m) pk (fromIntegral $ S.length k)+ foreign import ccall "crypto_hash" c_hash :: Ptr CChar -- ^ Output hash buffer@@ -112,3 +158,19 @@ -- ^ Constant Key buffer -> IO CInt -- ^ Always 0++foreign import ccall "crypto_generichash"+ c_generichash :: Ptr CChar+ -- ^ Output hash buffer+ -> CULLong+ -- ^ Output hash length+ -> Ptr CChar+ -- ^ Constant message buffer+ -> CULLong+ -- ^ Message buffer length+ -> Ptr CChar+ -- ^ Constant Key buffer+ -> CULLong+ -- ^ Key buffer length+ -> IO CInt+ -- ^ Always 0
src/Crypto/Saltine/Core/OneTimeAuth.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}+ -- | -- Module : Crypto.Saltine.Core.OneTimeAuth -- Copyright : (c) Joseph Abrahamson 2013@@ -48,14 +50,17 @@ import Foreign.Ptr import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Hashable (Hashable)+import Data.Data (Data, Typeable)+import GHC.Generics (Generic) -- $types -- | An opaque 'auth' cryptographic key.-newtype Key = Key ByteString deriving (Eq, Ord)+newtype Key = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) -- | An opaque 'auth' authenticator.-newtype Authenticator = Au ByteString deriving (Eq, Ord)+newtype Authenticator = Au ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding Key where decode v = if S.length v == Bytes.onetimeKey
src/Crypto/Saltine/Core/ScalarMult.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}+ -- | -- Module : Crypto.Saltine.Core.ScalarMult -- Copyright : (c) Joseph Abrahamson 2013@@ -63,14 +65,17 @@ import Foreign.Ptr import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Hashable (Hashable)+import Data.Data (Data, Typeable)+import GHC.Generics (Generic) -- $types -- | A group element.-newtype GroupElement = GE ByteString deriving (Eq)+newtype GroupElement = GE ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) -- | A scalar integer.-newtype Scalar = Sc ByteString deriving (Eq)+newtype Scalar = Sc ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding GroupElement where decode v = if S.length v == Bytes.mult
src/Crypto/Saltine/Core/SecretBox.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}+ -- | -- Module : Crypto.Saltine.Core.SecretBox -- Copyright : (c) Joseph Abrahamson 2013@@ -53,11 +55,14 @@ import Foreign.Ptr import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Hashable (Hashable)+import Data.Data (Data, Typeable)+import GHC.Generics (Generic) -- $types -- | An opaque 'secretbox' cryptographic key.-newtype Key = Key ByteString deriving (Eq, Ord)+newtype Key = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding Key where decode v = if S.length v == Bytes.secretBoxKey@@ -68,7 +73,7 @@ {-# INLINE encode #-} -- | An opaque 'secretbox' nonce.-newtype Nonce = Nonce ByteString deriving (Eq, Ord)+newtype Nonce = Nonce ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding Nonce where decode v = if S.length v == Bytes.secretBoxNonce
src/Crypto/Saltine/Core/Sign.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}+ -- | -- Module : Crypto.Saltine.Core.Sign -- Copyright : (c) Joseph Abrahamson 2013@@ -43,11 +45,15 @@ import System.IO.Unsafe import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Data (Data, Typeable)+import Data.Hashable (Hashable)+import GHC.Generics (Generic) + -- $types -- | An opaque 'box' cryptographic secret key.-newtype SecretKey = SK ByteString deriving (Eq, Ord)+newtype SecretKey = SK ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding SecretKey where decode v = if S.length v == Bytes.signSK@@ -58,7 +64,7 @@ {-# INLINE encode #-} -- | An opaque 'box' cryptographic public key.-newtype PublicKey = PK ByteString deriving (Eq, Ord)+newtype PublicKey = PK ByteString deriving (Eq, Ord, Data, Typeable, Hashable, Generic) instance IsEncoding PublicKey where decode v = if S.length v == Bytes.signPK
src/Crypto/Saltine/Core/Stream.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}+ -- | -- Module : Crypto.Saltine.Core.Stream -- Copyright : (c) Joseph Abrahamson 2013@@ -62,11 +64,14 @@ import Foreign.Ptr import qualified Data.ByteString as S import Data.ByteString (ByteString)+import Data.Hashable (Hashable)+import Data.Data (Data, Typeable)+import GHC.Generics (Generic) -- $types -- | An opaque 'stream' cryptographic key.-newtype Key = Key ByteString deriving (Eq, Ord)+newtype Key = Key ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsEncoding Key where decode v = if S.length v == Bytes.streamKey@@ -77,7 +82,7 @@ {-# INLINE encode #-} -- | An opaque 'stream' nonce.-newtype Nonce = Nonce ByteString deriving (Eq, Ord)+newtype Nonce = Nonce ByteString deriving (Eq, Ord, Hashable, Data, Typeable, Generic) instance IsNonce Nonce where zero = Nonce (S.replicate Bytes.streamNonce 0)
src/Crypto/Saltine/Internal/ByteSizes.hs view
@@ -46,7 +46,9 @@ streamNonce, hash, shorthash,- shorthashKey+ shorthashKey,+ generichashOutLenMax,+ generichashKeyLenMax ) where import Foreign.C@@ -62,7 +64,7 @@ sign, signPK, signSK :: Int streamKey, streamNonce :: Int hash, shorthash, shorthashKey :: Int-+generichashOutLenMax, generichashKeyLenMax :: Int -- Authentication -- | Size of a @crypto_auth@ authenticator.@@ -148,6 +150,12 @@ -- | The size of a hashing key for the keyed hash function -- 'Crypto.Saltine.Internal.Hash.shorthash'. shorthashKey = fromIntegral c_crypto_shorthash_keybytes+-- | The maximum output size of the generic hash function+-- 'Crypto.Saltine.Core.Hash.generichash'+generichashOutLenMax = fromIntegral c_crypto_generichash_bytes_max+-- | The maximum key size of the generic hash function+-- 'Crypto.Saltine.Core.Hash.generichash'+generichashKeyLenMax = fromIntegral c_crypto_generichash_keybytes_max -- src/libsodium/crypto_auth/crypto_auth.c foreign import ccall "crypto_auth_bytes"@@ -206,6 +214,12 @@ c_crypto_sign_publickeybytes :: CSize foreign import ccall "crypto_sign_secretkeybytes" c_crypto_sign_secretkeybytes :: CSize++-- src/libsodium/crypto_generichash/crypto_generichash.c+foreign import ccall "crypto_generichash_bytes_max"+ c_crypto_generichash_bytes_max :: CSize+foreign import ccall "crypto_generichash_keybytes_max"+ c_crypto_generichash_keybytes_max :: CSize -- HARDCODED -- ---------
tests/AEADProperties.hs view
@@ -12,6 +12,7 @@ import Control.Applicative import qualified Data.ByteString as S+import Data.Maybe (fromJust) import Test.Framework.Providers.QuickCheck2 import Test.Framework import Test.QuickCheck (Property, (==>))@@ -20,12 +21,12 @@ instance Arbitrary Nonce where arbitrary = do bs <- S.pack <$> vector Bytes.secretBoxNonce- maybe (fail "impossible arbitrary failure.") pure (decode bs)+ pure $ fromJust (decode bs) instance Arbitrary Key where arbitrary = do bs <- S.pack <$> vector Bytes.secretBoxKey- maybe (fail "impossible arbitrary failure.") pure (decode bs)+ pure $ fromJust (decode bs) instance Show Key where show = show . encode
tests/Main.hs view
@@ -10,6 +10,7 @@ import AuthProperties (testAuth) import OneTimeAuthProperties (testOneTimeAuth) import SignProperties (testSign)+import HashProperties (testHash) import ScalarMultProperties (testScalarMult) import Crypto.Saltine @@ -36,5 +37,6 @@ testAuth, testOneTimeAuth, testSign,+ testHash, testScalarMult ]
tests/SecretBoxProperties.hs view
@@ -12,6 +12,7 @@ import Control.Applicative import qualified Data.ByteString as S+import Data.Maybe (fromJust) import Test.Framework.Providers.QuickCheck2 import Test.Framework import Test.QuickCheck (Property, (==>))@@ -20,12 +21,12 @@ instance Arbitrary Nonce where arbitrary = do bs <- S.pack <$> vector Bytes.secretBoxNonce- maybe (fail "impossible arbitrary failure.") pure (decode bs)+ pure $ fromJust (decode bs) instance Arbitrary Key where arbitrary = do bs <- S.pack <$> vector Bytes.secretBoxKey- maybe (fail "impossible arbitrary failure.") pure (decode bs)+ pure $ fromJust (decode bs) instance Show Key where show = show . encode instance Show Nonce where