packages feed

saltine 0.0.0.4 → 0.0.0.5

raw patch · 22 files changed

+660/−602 lines, 22 filesdep −vectornew-uploaderPVP: minor bump suggested

API additions: PVP suggests at least a minor version bump

Dependencies removed: vector

API changes (from Hackage documentation)

+ Crypto.Saltine.Core.Box: boxSeal :: PublicKey -> ByteString -> IO ByteString
+ Crypto.Saltine.Core.Box: boxSealOpen :: PublicKey -> SecretKey -> ByteString -> Maybe ByteString
+ Crypto.Saltine.Internal.ByteSizes: sealedBox :: Int

Files

saltine.cabal view
@@ -1,10 +1,10 @@ name:                saltine-version:             0.0.0.4+version:             0.0.0.5 synopsis:            Cryptography that's easy to digest (NaCl/libsodium bindings). description:    /NaCl/ (pronounced \"salt\") is a new easy-to-use high-speed software-  library for network communica tion, encryption, decryption,+  library for network communication, encryption, decryption,   signatures, etc. NaCl's goal is to provide all of the core   operations needed to build higher-level cryptographic tools.   .@@ -21,13 +21,13 @@ license:             MIT license-file:        LICENSE author:              Joseph Abrahamson-maintainer:          Joseph Abrahamson <me@jspha.com>+maintainer:          Max Amanshauser <max@lambdalifting.org> bug-reports:         http://github.com/tel/saltine/issues copyright:           Copyright (c) Joseph Abrahamson 2013 category:            Cryptography build-type:          Simple cabal-version:       >=1.10-tested-with:         GHC==7.6.3, GHC==7.8.4, GHC==7.10.1+tested-with:         GHC==7.8.4, GHC==7.10.3, GHC==8.0.2  source-repository head   type: git@@ -36,48 +36,47 @@ library   hs-source-dirs:     src   exposed-modules:-    Crypto.Saltine-    Crypto.Saltine.Internal.ByteSizes-    Crypto.Saltine.Core.SecretBox-    Crypto.Saltine.Core.Box-    Crypto.Saltine.Core.Stream-    Crypto.Saltine.Core.Auth-    Crypto.Saltine.Core.OneTimeAuth-    Crypto.Saltine.Core.Sign-    Crypto.Saltine.Core.Hash-    Crypto.Saltine.Core.ScalarMult-    Crypto.Saltine.Class+                  Crypto.Saltine+                  Crypto.Saltine.Internal.ByteSizes+                  Crypto.Saltine.Core.SecretBox+                  Crypto.Saltine.Core.Box+                  Crypto.Saltine.Core.Stream+                  Crypto.Saltine.Core.Auth+                  Crypto.Saltine.Core.OneTimeAuth+                  Crypto.Saltine.Core.Sign+                  Crypto.Saltine.Core.Hash+                  Crypto.Saltine.Core.ScalarMult+                  Crypto.Saltine.Class   other-modules:-    Crypto.Saltine.Internal.Util+                Crypto.Saltine.Internal.Util   extra-libraries:    sodium   cc-options:         -Wall   ghc-options:        -Wall -funbox-strict-fields   default-language:   Haskell2010   build-depends:-    base >= 4.5 && < 5,-    bytestring,-    profunctors+                base >= 4.5 && < 5+              , bytestring+              , profunctors  test-suite tests   type:    exitcode-stdio-1.0   main-is: Main.hs   other-modules:-    AuthProperties-    BoxProperties-    OneTimeAuthProperties-    ScalarMultProperties-    SecretBoxProperties-    SignProperties-    StreamProperties-    Util+                AuthProperties+                BoxProperties+                OneTimeAuthProperties+                ScalarMultProperties+                SecretBoxProperties+                SignProperties+                StreamProperties+                Util   ghc-options: -Wall -threaded -O0 -rtsopts   hs-source-dirs: tests   default-language: Haskell2010   build-depends:-    base >= 4.5 && < 5,-    saltine,-    bytestring,-    vector,-    QuickCheck,-    test-framework-quickcheck2,-    test-framework+                base >= 4.5 && < 5+              , saltine+              , bytestring+              , QuickCheck+              , test-framework-quickcheck2+              , test-framework
src/Crypto/Saltine.hs view
@@ -1,6 +1,5 @@ {-# LANGUAGE ForeignFunctionInterface #-}-{-# LANGUAGE DeriveDataTypeable #-}-{-# LANGUAGE TypeFamilies #-}+{-# LANGUAGE TypeFamilies             #-}  module Crypto.Saltine (   optimize,@@ -10,11 +9,9 @@ import Foreign.C import Crypto.Saltine.Core.SecretBox --- | Runs Sodiums's optimizer. This has no semantic effect, but both--- may boost the speed of Sodium after running it. It is recommended--- in production environments. It is, however, NOT thread-safe so no--- other Sodium functions should be called until it successfully--- returns.+-- | Runs Sodiums's initialization routine. This should be called before+-- using any other function. It is thread-safe since libsodium 1.0.11,+-- but not before. optimize :: IO () optimize = do   err <- c_sodiumInit
src/Crypto/Saltine/Class.hs view
@@ -2,25 +2,24 @@ -- Module      : Crypto.Saltine.Class -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- +-- -- Saltine type classes module Crypto.Saltine.Class (   IsEncoding (..),   IsNonce (..)   ) where -import Data.Profunctor-import qualified Data.ByteString as S-import           Data.ByteString (ByteString)-import Control.Applicative+import           Control.Applicative+import           Data.Profunctor+import           Data.ByteString     (ByteString)  -- | Class for all keys and nonces in Saltine which have a--- representation as 'V.Vector' of 'Word8'. 'encoded' is a 'Prism' of--- type @Prism' (V.Vector Word8) a@ compatible with "Control.Lens" and+-- representation as ByteString. 'encoded' is a 'Prism' of+-- type @Prism' ByteString a@ compatible with "Control.Lens" and -- is automatically deduced. class IsEncoding a where   encode  :: a -> ByteString
src/Crypto/Saltine/Core/Auth.hs view
@@ -2,19 +2,19 @@ -- Module      : Crypto.Saltine.Core.Auth -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- --- Secret-key message authentication: +--+-- Secret-key message authentication: -- "Crypto.Saltine.Core.Auth"--- +-- -- The 'auth' function authenticates a message 'ByteString' using a -- secret key The function returns an authenticator. The 'verify' -- function checks if it's passed a correct authenticator of a message -- under the given secret key.--- +-- -- The 'auth' function, viewed as a function of the message for a -- uniform random key, is designed to meet the standard notion of -- unforgeability. This means that an attacker cannot find@@ -25,17 +25,17 @@ -- cipher block chaining message authentication code,\" Journal of -- Computer and System Sciences 61 (2000), 362–399; -- <http://www-cse.ucsd.edu/~mihir/papers/cbc.html>.--- +-- -- Saltine does not make any promises regarding \"strong\" -- unforgeability; perhaps one valid authenticator can be converted -- into another valid authenticator for the same message. NaCl also -- does not make any promises regarding \"truncated unforgeability.\"--- +-- -- "Crypto.Saltine.Core.Auth" is currently an implementation of -- HMAC-SHA-512-256, i.e., the first 256 bits of -- HMAC-SHA-512. HMAC-SHA-512-256 is conjectured to meet the standard -- notion of unforgeability.--- +-- -- This is version 2010.08.30 of the auth.html web page. module Crypto.Saltine.Core.Auth (   Key, Authenticator,@@ -43,37 +43,36 @@   auth, verify   ) where -import Crypto.Saltine.Class-import Crypto.Saltine.Internal.Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Internal.Util import qualified Crypto.Saltine.Internal.ByteSizes as Bytes -import Foreign.C-import Foreign.Ptr-import qualified Data.ByteString as S-import           Data.ByteString (ByteString)--import Control.Applicative+import           Control.Applicative+import           Foreign.C+import           Foreign.Ptr+import qualified Data.ByteString                   as S+import           Data.ByteString                     (ByteString)  -- $types  -- | An opaque 'auth' cryptographic key.-newtype Key = Key ByteString deriving (Eq, Ord)+newtype Key           = Key ByteString deriving (Eq, Ord)  -- | An opaque 'auth' authenticator.-newtype Authenticator = Au ByteString deriving (Eq, Ord)+newtype Authenticator = Au ByteString  deriving (Eq, Ord)  instance IsEncoding Key where-  decode v = case S.length v == Bytes.authKey of-    True -> Just (Key v)-    False -> Nothing+  decode v = if S.length v == Bytes.authKey+           then Just (Key v)+           else Nothing   {-# INLINE decode #-}   encode (Key v) = v   {-# INLINE encode #-}  instance IsEncoding Authenticator where-  decode v = case S.length v == Bytes.auth of-    True -> Just (Au v)-    False -> Nothing+  decode v = if S.length v == Bytes.auth+           then Just (Au v)+           else Nothing   {-# INLINE decode #-}   encode (Au v) = v   {-# INLINE encode #-}@@ -86,10 +85,10 @@ -- is infeasible to forge these authenticators without the key, even -- if an attacker observes many authenticators and messages and has -- the ability to influence the messages sent.-auth :: Key -        -> ByteString-        -- ^ Message-        -> Authenticator+auth :: Key+     -> ByteString+     -- ^ Message+     -> Authenticator auth (Key key) msg =   Au . snd . buildUnsafeCVector Bytes.auth $ \pa ->     constVectors [key, msg] $ \[(pk, _), (pm, mlen)] ->@@ -98,37 +97,37 @@ -- | Checks to see if an authenticator is a correct proof that a -- message was signed by some key. verify :: Key-          -> Authenticator-          -> ByteString-          -- ^ Message-          -> Bool-          -- ^ Is this message authentic?+       -> Authenticator+       -> ByteString+       -- ^ Message+       -> Bool+       -- ^ Is this message authentic? verify (Key key) (Au a) msg =   unsafeDidSucceed $ constVectors [key, msg, a] $ \[(pk, _), (pm, mlen), (pa, _)] ->-  return $ c_auth_verify pa pm (fromIntegral mlen) pk+    return $ c_auth_verify pa pm (fromIntegral mlen) pk  foreign import ccall "crypto_auth"   c_auth :: Ptr CChar-            -- ^ Authenticator output buffer-            -> Ptr CChar-            -- ^ Constant message buffer-            -> CULLong-            -- ^ Length of message buffer-            -> Ptr CChar-            -- ^ Constant key buffer-            -> IO CInt-            -- ^ Always 0+         -- ^ Authenticator output buffer+         -> Ptr CChar+         -- ^ Constant message buffer+         -> CULLong+         -- ^ Length of message buffer+         -> Ptr CChar+         -- ^ Constant key buffer+         -> IO CInt+         -- ^ Always 0  -- | We don't even include this in the IO monad since all of the -- buffers are constant. foreign import ccall "crypto_auth_verify"   c_auth_verify :: Ptr CChar-                   -- ^ Constant authenticator buffer-                   -> Ptr CChar-                   -- ^ Constant message buffer-                   -> CULLong-                   -- ^ Length of message buffer-                   -> Ptr CChar-                   -- ^ Constant key buffer-                   -> CInt-                   -- ^ Success if 0, failure if -1+                -- ^ Constant authenticator buffer+                -> Ptr CChar+                -- ^ Constant message buffer+                -> CULLong+                -- ^ Length of message buffer+                -> Ptr CChar+                -- ^ Constant key buffer+                -> CInt+                -- ^ Success if 0, failure if -1
src/Crypto/Saltine/Core/Box.hs view
@@ -2,28 +2,32 @@ -- Module      : Crypto.Saltine.Core.Box -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- --- Public-key authenticated encryption:+--+-- Public-key cryptography abstraction: -- "Crypto.Saltine.Core.Box"--- --- The 'box' function encrypts and authenticates a message+--+-- This module consists of functions dealing with two public-key+-- cryptography concepts in libsodium.+--+-- The first one is an authenticated encryption scheme. In this+-- scheme, the 'box' function encrypts and authenticates a message -- 'ByteString' using the sender's secret key, the receiver's public -- key, and a nonce. The 'boxOpen' function verifies and decrypts a -- ciphertext 'ByteString' using the receiver's secret key, the -- sender's public key, and a nonce. If the ciphertext fails -- verification, 'boxOpen' returns 'Nothing'.--- --- The "Crypto.Saltine.Core.Box" module is designed to meet the+--+-- The set of box functions is designed to meet the -- standard notions of privacy and third-party unforgeability for a -- public-key authenticated-encryption scheme using nonces. For formal -- definitions see, e.g., Jee Hea An, "Authenticated encryption in the -- public-key setting: security notions and analyses," -- <http://eprint.iacr.org/2001/079>.--- +-- -- Distinct messages between the same @{sender, receiver}@ set are -- required to have distinct nonces. For example, the -- lexicographically smaller public key can use nonce 1 for its first@@ -33,13 +37,22 @@ -- nonce 4 for its second message, nonce 6 for its third message, -- etc. Nonces are long enough that randomly generated nonces have -- negligible risk of collision.--- +-- -- There is no harm in having the same nonce for different messages if -- the @{sender, receiver}@ sets are different. This is true even if -- the sets overlap. For example, a sender can use the same nonce for -- two different messages if the messages are sent to two different -- public keys.--- +--+-- The second concept is sealed boxes, which provide encryption and+-- preservation of integrity, but not authentication. Technically,+-- the sender of a message generates a keypair, uses the regular+-- box mechanism, attaches the public key to the message and then+-- immediately destroys the private key. This is useful, e.g. when+-- the receiver cannot know the sender's public key in advance and+-- hence cannot use the regular box functions, or when you want to+-- send messages anonymously.+-- -- The "Crypto.Saltine.Core.Box" module is not meant to provide -- non-repudiation. On the contrary: the crypto_box function -- guarantees repudiability. A receiver can freely modify a boxed@@ -50,37 +63,38 @@ -- <http://groups.google.com/group/sci.crypt/msg/ec5c18b23b11d82c>, -- crypto_box uses "public-key authenticators" rather than "public-key -- signatures."--- +-- -- Users who want public verifiability (or receiver-assisted public -- verifiability) should instead use signatures (or -- signcryption). Signatures are documented in the -- "Crypto.Saltine.Core.Sign" module.--- +-- -- "Crypto.Saltine.Core.Box" is @curve25519xsalsa20poly1305@, a -- particular combination of Curve25519, Salsa20, and Poly1305 -- specified in "Cryptography in NaCl" -- (<http://nacl.cr.yp.to/valid.html>). This function is conjectured -- to meet the standard notions of privacy and third-party -- unforgeability.--- +-- -- This is version 2010.08.30 of the box.html web page. module Crypto.Saltine.Core.Box (   SecretKey, PublicKey, Keypair, CombinedKey, Nonce,   newKeypair, beforeNM, newNonce,   box, boxOpen,-  boxAfterNM, boxOpenAfterNM  +  boxAfterNM, boxOpenAfterNM,+  boxSeal, boxSealOpen   ) where -import Crypto.Saltine.Class-import Crypto.Saltine.Internal.Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Internal.Util import qualified Crypto.Saltine.Internal.ByteSizes as Bytes -import Foreign.C-import Foreign.Ptr-import qualified Data.ByteString as S+import           Control.Applicative+import           Foreign.C+import           Foreign.Ptr+import qualified Data.ByteString                   as S import           Data.ByteString (ByteString) -import Control.Applicative  -- $types @@ -88,9 +102,9 @@ newtype SecretKey = SK ByteString deriving (Eq, Ord)  instance IsEncoding SecretKey where-  decode v = case S.length v == Bytes.boxSK of-    True -> Just (SK v)-    False -> Nothing+  decode v = if S.length v == Bytes.boxSK+           then Just (SK v)+           else Nothing   {-# INLINE decode #-}   encode (SK v) = v   {-# INLINE encode #-}@@ -99,9 +113,9 @@ newtype PublicKey = PK ByteString deriving (Eq, Ord)  instance IsEncoding PublicKey where-  decode v = case S.length v == Bytes.boxPK of-    True -> Just (PK v)-    False -> Nothing+  decode v = if S.length v == Bytes.boxPK+           then Just (PK v)+           else Nothing   {-# INLINE decode #-}   encode (PK v) = v   {-# INLINE encode #-}@@ -113,9 +127,9 @@ newtype CombinedKey = CK ByteString deriving (Eq, Ord)  instance IsEncoding CombinedKey where-  decode v = case S.length v == Bytes.boxBeforeNM of-    True -> Just (CK v)-    False -> Nothing+  decode v = if S.length v == Bytes.boxBeforeNM+           then Just (CK v)+           else Nothing   {-# INLINE decode #-}   encode (CK v) = v   {-# INLINE encode #-}@@ -124,15 +138,15 @@ newtype Nonce = Nonce ByteString deriving (Eq, Ord)  instance IsEncoding Nonce where-  decode v = case S.length v == Bytes.boxNonce of-    True -> Just (Nonce v)-    False -> Nothing+  decode v = if S.length v == Bytes.boxNonce+           then Just (Nonce v)+           else Nothing   {-# INLINE decode #-}   encode (Nonce v) = v   {-# INLINE encode #-}  instance IsNonce Nonce where-  zero = Nonce (S.replicate Bytes.boxNonce 0)+  zero            = Nonce (S.replicate Bytes.boxNonce 0)   nudge (Nonce n) = Nonce (nudgeBS n)  -- | Randomly generates a secret key and a corresponding public key.@@ -142,7 +156,7 @@   -- _err ought to always be 0.   ((_err, sk), pk) <- buildUnsafeCVector' Bytes.boxPK $ \pkbuf ->     buildUnsafeCVector' Bytes.boxSK $ \skbuf ->-    c_box_keypair pkbuf skbuf+      c_box_keypair pkbuf skbuf   return (SK sk, PK pk)  -- | Randomly generates a nonce for usage with 'box' and 'boxOpen'.@@ -155,39 +169,39 @@ beforeNM :: SecretKey -> PublicKey -> CombinedKey beforeNM (SK sk) (PK pk) = CK $ snd $ buildUnsafeCVector Bytes.boxBeforeNM $ \ckbuf ->   constVectors [pk, sk] $ \[(ppk, _), (psk, _)] ->-  c_box_beforenm ckbuf ppk psk+    c_box_beforenm ckbuf ppk psk  -- | Encrypts a message for sending to the owner of the public -- key. They must have your public key in order to decrypt the -- message. It is infeasible for an attacker to decrypt the message so -- long as the 'Nonce' is not repeated. box :: PublicKey -> SecretKey -> Nonce-       -> ByteString-       -- ^ Message-       -> ByteString-       -- ^ Ciphertext+    -> ByteString+    -- ^ Message+    -> ByteString+    -- ^ Ciphertext box (PK pk) (SK sk) (Nonce nonce) msg =   unpad' . snd . buildUnsafeCVector len $ \pc ->     constVectors [pk, sk, pad' msg, nonce] $ \       [(ppk, _), (psk, _), (pm, _), (pn, _)] ->-      c_box pc pm (fromIntegral len) pn ppk psk+        c_box pc pm (fromIntegral len) pn ppk psk   where len    = S.length msg + Bytes.boxZero         pad'   = pad Bytes.boxZero         unpad' = unpad Bytes.boxBoxZero  -- | Decrypts a message sent from the owner of the public key. They--- must have encrypted it using your secret key. Returns 'Nothing' if+-- must have encrypted it using your public key. Returns 'Nothing' if -- the keys and message do not match. boxOpen :: PublicKey -> SecretKey -> Nonce-           -> ByteString-           -- ^ Ciphertext-           -> Maybe ByteString-           -- ^ Message+        -> ByteString+        -- ^ Ciphertext+        -> Maybe ByteString+        -- ^ Message boxOpen (PK pk) (SK sk) (Nonce nonce) cipher =   let (err, vec) = buildUnsafeCVector len $ \pm ->         constVectors [pk, sk, pad' cipher, nonce] $ \           [(ppk, _), (psk, _), (pc, _), (pn, _)] ->-          c_box_open pm pc (fromIntegral len) pn ppk psk+            c_box_open pm pc (fromIntegral len) pn ppk psk   in hush . handleErrno err $ unpad' vec   where len    = S.length cipher + Bytes.boxBoxZero         pad'   = pad Bytes.boxBoxZero@@ -195,116 +209,174 @@  -- | 'box' using a 'CombinedKey' and is thus faster. boxAfterNM :: CombinedKey -> Nonce-              -> ByteString-              -- ^ Message-              -> ByteString-              -- ^ Ciphertext+           -> ByteString+           -- ^ Message+           -> ByteString+           -- ^ Ciphertext boxAfterNM (CK ck) (Nonce nonce) msg =   unpad' . snd . buildUnsafeCVector len $ \pc ->     constVectors [ck, pad' msg, nonce] $ \       [(pck, _), (pm, _), (pn, _)] ->-      c_box_afternm pc pm (fromIntegral len) pn pck+        c_box_afternm pc pm (fromIntegral len) pn pck   where len    = S.length msg + Bytes.boxZero         pad'   = pad Bytes.boxZero         unpad' = unpad Bytes.boxBoxZero  -- | 'boxOpen' using a 'CombinedKey' and is thus faster. boxOpenAfterNM :: CombinedKey -> Nonce-           -> ByteString-           -- ^ Ciphertext-           -> Maybe ByteString-           -- ^ Message+               -> ByteString+               -- ^ Ciphertext+               -> Maybe ByteString+               -- ^ Message boxOpenAfterNM (CK ck) (Nonce nonce) cipher =   let (err, vec) = buildUnsafeCVector len $ \pm ->         constVectors [ck, pad' cipher, nonce] $ \           [(pck, _), (pc, _), (pn, _)] ->-          c_box_open_afternm pm pc (fromIntegral len) pn pck+            c_box_open_afternm pm pc (fromIntegral len) pn pck   in hush . handleErrno err $ unpad' vec   where len    = S.length cipher + Bytes.boxBoxZero         pad'   = pad Bytes.boxBoxZero         unpad' = unpad Bytes.boxZero  +-- | Encrypts a message for sending to the owner of the public+-- key. The message is unauthenticated, but permits integrity checking.+boxSeal :: PublicKey -> ByteString -> IO ByteString+boxSeal (PK pk) msg = fmap snd . buildUnsafeCVector' strlen $ \pc ->+    constVectors [pk, msg] $ \+      [(ppk, _), (pm, _)] ->+        c_box_seal pc pm (fromIntegral len) ppk+  where strlen    = S.length msg + Bytes.sealedBox+        len       = S.length msg++-- | Decrypts a sealed box message. The message must have been+-- encrypted using the receiver's public key.+-- Returns 'Nothing' if keys and message do not match or integrity+-- is violated.+boxSealOpen :: PublicKey -> SecretKey+            -> ByteString+            -- ^ Ciphertext+            -> Maybe ByteString+            -- ^ Message+boxSealOpen (PK pk) (SK sk) cipher =+  let (err, vec) = buildUnsafeCVector strlen $ \pm ->+        constVectors [pk, sk, cipher] $ \+          [(ppk, _), (psk, _), (pc, _)] ->+          c_box_seal_open pm pc (fromIntegral len) ppk psk+  in hush . handleErrno err $ vec+  where strlen    = S.length cipher - Bytes.sealedBox+        len       = S.length cipher++ -- | Should always return a 0. foreign import ccall "crypto_box_keypair"   c_box_keypair :: Ptr CChar-                   -- ^ Public key-                   -> Ptr CChar-                   -- ^ Secret key-                   -> IO CInt-                   -- ^ Always 0+                -- ^ Public key+                -> Ptr CChar+                -- ^ Secret key+                -> IO CInt+                -- ^ Always 0  -- | The secretbox C API uses 0-padded C strings. foreign import ccall "crypto_box"   c_box :: Ptr CChar-           -- ^ Cipher 0-padded output buffer-           -> Ptr CChar-           -- ^ Constant 0-padded message input buffer-           -> CULLong-           -- ^ Length of message input buffer (incl. 0s)-           -> Ptr CChar-           -- ^ Constant nonce buffer-           -> Ptr CChar-           -- ^ Constant public key buffer-           -> Ptr CChar-           -- ^ Constant secret key buffer-           -> IO CInt-           -- ^ Always 0+        -- ^ Cipher 0-padded output buffer+        -> Ptr CChar+        -- ^ Constant 0-padded message input buffer+        -> CULLong+        -- ^ Length of message input buffer (incl. 0s)+        -> Ptr CChar+        -- ^ Constant nonce buffer+        -> Ptr CChar+        -- ^ Constant public key buffer+        -> Ptr CChar+        -- ^ Constant secret key buffer+        -> IO CInt+        -- ^ Always 0  -- | The secretbox C API uses 0-padded C strings. foreign import ccall "crypto_box_open"   c_box_open :: Ptr CChar-                -- ^ Message 0-padded output buffer-                -> Ptr CChar-                -- ^ Constant 0-padded ciphertext input buffer-                -> CULLong-                -- ^ Length of message input buffer (incl. 0s)-                -> Ptr CChar-                -- ^ Constant nonce buffer-                -> Ptr CChar-                -- ^ Constant public key buffer-                -> Ptr CChar-                -- ^ Constant secret key buffer-                -> IO CInt-                -- ^ 0 for success, -1 for failure to verify+             -- ^ Message 0-padded output buffer+             -> Ptr CChar+             -- ^ Constant 0-padded ciphertext input buffer+             -> CULLong+             -- ^ Length of message input buffer (incl. 0s)+             -> Ptr CChar+             -- ^ Constant nonce buffer+             -> Ptr CChar+             -- ^ Constant public key buffer+             -> Ptr CChar+             -- ^ Constant secret key buffer+             -> IO CInt+             -- ^ 0 for success, -1 for failure to verify  -- | Single target key precompilation. foreign import ccall "crypto_box_beforenm"   c_box_beforenm :: Ptr CChar-                    -- ^ Combined key output buffer-                    -> Ptr CChar-                    -- ^ Constant public key buffer-                    -> Ptr CChar-                    -- ^ Constant secret key buffer-                    -> IO CInt-                    -- ^ Always 0+                 -- ^ Combined key output buffer+                 -> Ptr CChar+                 -- ^ Constant public key buffer+                 -> Ptr CChar+                 -- ^ Constant secret key buffer+                 -> IO CInt+                 -- ^ Always 0  -- | Precompiled key crypto box. Uses 0-padded C strings. foreign import ccall "crypto_box_afternm"   c_box_afternm :: Ptr CChar-                   -- ^ Cipher 0-padded output buffer-                   -> Ptr CChar-                   -- ^ Constant 0-padded message input buffer-                   -> CULLong-                   -- ^ Length of message input buffer (incl. 0s)-                   -> Ptr CChar-                   -- ^ Constant nonce buffer-                   -> Ptr CChar-                   -- ^ Constant combined key buffer-                   -> IO CInt-                   -- ^ Always 0+                -- ^ Cipher 0-padded output buffer+                -> Ptr CChar+                -- ^ Constant 0-padded message input buffer+                -> CULLong+                -- ^ Length of message input buffer (incl. 0s)+                -> Ptr CChar+                -- ^ Constant nonce buffer+                -> Ptr CChar+                -- ^ Constant combined key buffer+                -> IO CInt+                -- ^ Always 0  -- | The secretbox C API uses 0-padded C strings. foreign import ccall "crypto_box_open_afternm"   c_box_open_afternm :: Ptr CChar-                        -- ^ Message 0-padded output buffer-                        -> Ptr CChar-                        -- ^ Constant 0-padded ciphertext input buffer-                        -> CULLong-                        -- ^ Length of message input buffer (incl. 0s)-                        -> Ptr CChar-                        -- ^ Constant nonce buffer-                        -> Ptr CChar-                        -- ^ Constant combined key buffer-                        -> IO CInt-                        -- ^ 0 for success, -1 for failure to verify+                     -- ^ Message 0-padded output buffer+                     -> Ptr CChar+                     -- ^ Constant 0-padded ciphertext input buffer+                     -> CULLong+                     -- ^ Length of message input buffer (incl. 0s)+                     -> Ptr CChar+                     -- ^ Constant nonce buffer+                     -> Ptr CChar+                     -- ^ Constant combined key buffer+                     -> IO CInt+                     -- ^ 0 for success, -1 for failure to verify+++-- | The sealedbox C API uses C strings.+foreign import ccall "crypto_box_seal"+  c_box_seal :: Ptr CChar+             -- ^ Cipher output buffer+             -> Ptr CChar+             -- ^ Constant message input buffer+             -> CULLong+             -- ^ Length of message input buffer+             -> Ptr CChar+             -- ^ Constant public key buffer+             -> IO CInt+             -- ^ Always 0++-- | The sealedbox C API uses C strings.+foreign import ccall "crypto_box_seal_open"+  c_box_seal_open :: Ptr CChar+                  -- ^ Message output buffer+                  -> Ptr CChar+                  -- ^ Constant ciphertext input buffer+                  -> CULLong+                  -- ^ Length of message input buffer+                  -> Ptr CChar+                  -- ^ Constant public key buffer+                  -> Ptr CChar+                  -- ^ Constant secret key buffer+                  -> IO CInt+                  -- ^ 0 for success, -1 for failure to decrypt
src/Crypto/Saltine/Core/Hash.hs view
@@ -2,19 +2,19 @@ -- Module      : Crypto.Saltine.Core.Hash -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- +-- -- Hashing: "Crypto.Saltine.Core.Hash"--- +-- -- The 'hash' function hashes a message 'ByteString' and returns a -- hash. Hashes are always of length 'Bytes.hash'. The 'shorthash' -- function hashes a message 'ByteString' with respect to a secret key -- and returns a very short hash. Short hashes are always of length -- 'Bytes.shorthash'.--- +-- -- The 'hash' function is designed to be usable as a strong component -- of DSA, RSA-PSS, key derivation, hash-based message-authentication -- codes, hash-based ciphers, and various other common@@ -23,21 +23,21 @@ -- security of the applications against generic attacks. In -- particular, the 'hash' function is designed to make finding -- collisions difficult.--- +-- -- 'hash' is currently an implementation of SHA-512. 'shorthash' is -- currently an implementation of SipHash-2-4 -- (<https://131002.net/siphash/>).--- +-- -- There has been considerable degradation of public confidence in the -- security conjectures for many hash functions, including -- SHA-512. However, for the moment, there do not appear to be -- 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.--- +-- -- This is version 2010.08.30 of the hash.html web page. Information -- about SipHash has been added. module Crypto.Saltine.Core.Hash (@@ -46,24 +46,23 @@   shorthash, newShorthashKey   ) where -import Crypto.Saltine.Class-import Crypto.Saltine.Internal.Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Internal.Util import qualified Crypto.Saltine.Internal.ByteSizes as Bytes -import Foreign.C-import Foreign.Ptr+import           Control.Applicative+import           Foreign.C+import           Foreign.Ptr import qualified Data.ByteString as S import           Data.ByteString (ByteString) -import Control.Applicative- -- | Computes a cryptographically collision-resistant hash making -- @hash m == hash m' ==> m == m'@ highly likely even when under -- attack. hash :: ByteString-        -- ^ Message-        -> ByteString-        -- ^ Hash+     -- ^ Message+     -> ByteString+     -- ^ Hash hash m = snd . buildUnsafeCVector Bytes.hash $ \ph ->   constVectors [m] $ \[(pm, _)] -> c_hash ph pm (fromIntegral $ S.length m) @@ -71,9 +70,9 @@ newtype ShorthashKey = ShK ByteString deriving (Eq, Ord)  instance IsEncoding ShorthashKey where-  decode v = case S.length v == Bytes.shorthashKey of-    True -> Just (ShK v)-    False -> Nothing+  decode v = if S.length v == Bytes.shorthashKey+           then Just (ShK v)+           else Nothing   {-# INLINE decode #-}   encode (ShK v) = v   {-# INLINE encode #-}@@ -84,32 +83,32 @@  -- | Computes a very short, fast keyed hash. shorthash :: ShorthashKey-             -> ByteString-             -- ^ Message-             -> ByteString-             -- ^ Hash+          -> ByteString+          -- ^ Message+          -> ByteString+          -- ^ Hash shorthash (ShK k) m = snd . buildUnsafeCVector Bytes.shorthash $ \ph ->   constVectors [k, m] $ \[(pk, _), (pm, _)] ->-  c_shorthash ph pm (fromIntegral $ S.length m) pk-             +    c_shorthash ph pm (fromIntegral $ S.length m) pk+ foreign import ccall "crypto_hash"   c_hash :: Ptr CChar-            -- ^ Output hash buffer-            -> Ptr CChar-            -- ^ Constant message buffer-            -> CULLong-            -- ^ Constant message buffer length-            -> IO CInt-            -- ^ Always 0+         -- ^ Output hash buffer+         -> Ptr CChar+         -- ^ Constant message buffer+         -> CULLong+         -- ^ Constant message buffer length+         -> IO CInt+         -- ^ Always 0  foreign import ccall "crypto_shorthash"   c_shorthash :: Ptr CChar-                 -- ^ Output hash buffer-                 -> Ptr CChar-                 -- ^ Constant message buffer-                 -> CULLong-                 -- ^ Message buffer length-                 -> Ptr CChar-                 -- ^ Constant Key buffer-                 -> IO CInt-                 -- ^ Always 0+              -- ^ Output hash buffer+              -> Ptr CChar+              -- ^ Constant message buffer+              -> CULLong+              -- ^ Message buffer length+              -> Ptr CChar+              -- ^ Constant Key buffer+              -> IO CInt+              -- ^ Always 0
src/Crypto/Saltine/Core/OneTimeAuth.hs view
@@ -2,36 +2,36 @@ -- Module      : Crypto.Saltine.Core.OneTimeAuth -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- +-- -- Secret-key single-message authentication: -- "Crypto.Saltine.Core.OneTimeAuth"--- +-- -- The 'auth' function authenticates a message 'ByteString' using a -- secret key The function returns an authenticator. The 'verify' -- function checks if it's passed a correct authenticator of a message -- under the given secret key.--- +-- -- The 'auth' function, viewed as a function of the message for a -- uniform random key, is designed to meet the standard notion of -- unforgeability after a single message. After the sender -- authenticates one message, an attacker cannot find authenticators -- for any other messages.--- +-- -- The sender must not use 'auth' to authenticate more than one -- message under the same key. Authenticators for two messages under -- the same key should be expected to reveal enough information to -- allow forgeries of authenticators on other messages.--- +-- -- "Crypto.Saltine.Core.OneTimeAuth" is -- @crypto_onetimeauth_poly1305@, an authenticator specified in -- "Cryptography in NaCl" (<http://nacl.cr.yp.to/valid.html>), Section -- 9. This authenticator is proven to meet the standard notion of -- unforgeability after a single message.--- +-- -- This is version 2010.08.30 of the onetimeauth.html web page. module Crypto.Saltine.Core.OneTimeAuth (   Key, Authenticator,@@ -39,37 +39,36 @@   auth, verify   ) where -import Crypto.Saltine.Class-import Crypto.Saltine.Internal.Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Internal.Util import qualified Crypto.Saltine.Internal.ByteSizes as Bytes -import Foreign.C-import Foreign.Ptr-import qualified Data.ByteString as S-import           Data.ByteString (ByteString)--import Control.Applicative+import           Control.Applicative+import           Foreign.C+import           Foreign.Ptr+import qualified Data.ByteString                   as S+import           Data.ByteString                     (ByteString)  -- $types  -- | An opaque 'auth' cryptographic key.-newtype Key = Key ByteString deriving (Eq, Ord)+newtype Key           = Key ByteString deriving (Eq, Ord)  -- | An opaque 'auth' authenticator.-newtype Authenticator = Au ByteString deriving (Eq, Ord)+newtype Authenticator = Au ByteString  deriving (Eq, Ord)  instance IsEncoding Key where-  decode v = case S.length v == Bytes.onetimeKey of-    True -> Just (Key v)-    False -> Nothing+  decode v = if S.length v == Bytes.onetimeKey+           then Just (Key v)+           else Nothing   {-# INLINE decode #-}   encode (Key v) = v   {-# INLINE encode #-}  instance IsEncoding Authenticator where-  decode v = case S.length v == Bytes.onetime of-    True -> Just (Au v)-    False -> Nothing+  decode v = if S.length v == Bytes.onetime+           then Just (Au v)+           else Nothing   {-# INLINE decode #-}   encode (Au v) = v   {-# INLINE encode #-}@@ -82,48 +81,48 @@ -- 'Authenticator' is /impossible/ to forge so long as the 'Key' is -- never used twice. auth :: Key-        -> ByteString-        -- ^ Message-        -> Authenticator+     -> ByteString+     -- ^ Message+     -> Authenticator auth (Key key) msg =   Au . snd . buildUnsafeCVector Bytes.onetime $ \pa ->     constVectors [key, msg] $ \[(pk, _), (pm, _)] ->-    c_onetimeauth pa pm (fromIntegral $ S.length msg) pk+      c_onetimeauth pa pm (fromIntegral $ S.length msg) pk  -- | Verifies that an 'Authenticator' matches a given message and key. verify :: Key-          -> Authenticator-          -> ByteString-          -- ^ Message-          -> Bool-          -- ^ Is this message authentic?+       -> Authenticator+       -> ByteString+       -- ^ Message+       -> Bool+       -- ^ Is this message authentic? verify (Key key) (Au a) msg =   unsafeDidSucceed $ constVectors [key, msg, a] $ \     [(pk, _), (pm, _), (pa, _)] ->-    return $ c_onetimeauth_verify pa pm (fromIntegral $ S.length msg) pk+      return $ c_onetimeauth_verify pa pm (fromIntegral $ S.length msg) pk  foreign import ccall "crypto_onetimeauth"   c_onetimeauth :: Ptr CChar-                   -- ^ Authenticator output buffer-                   -> Ptr CChar-                   -- ^ Constant message buffer-                   -> CULLong-                   -- ^ Length of message buffer-                   -> Ptr CChar-                   -- ^ Constant key buffer-                   -> IO CInt-                   -- ^ Always 0+                -- ^ Authenticator output buffer+                -> Ptr CChar+                -- ^ Constant message buffer+                -> CULLong+                -- ^ Length of message buffer+                -> Ptr CChar+                -- ^ Constant key buffer+                -> IO CInt+                -- ^ Always 0  -- | We don't even include this in the IO monad since all of the -- buffers are constant. foreign import ccall "crypto_onetimeauth_verify"   c_onetimeauth_verify :: Ptr CChar-                          -- ^ Constant authenticator buffer-                          -> Ptr CChar-                          -- ^ Constant message buffer-                          -> CULLong-                          -- ^ Length of message buffer-                          -> Ptr CChar-                          -- ^ Constant key buffer-                          -> CInt-                          -- ^ Success if 0, failure if -1+                       -- ^ Constant authenticator buffer+                       -> Ptr CChar+                       -- ^ Constant message buffer+                       -> CULLong+                       -- ^ Length of message buffer+                       -> Ptr CChar+                       -- ^ Constant key buffer+                       -> CInt+                       -- ^ Success if 0, failure if -1
src/Crypto/Saltine/Core/ScalarMult.hs view
@@ -2,31 +2,31 @@ -- Module      : Crypto.Saltine.Core.ScalarMult -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- +-- -- Scalar multiplication: "Crypto.Saltine.Core.ScalarMult"--- +-- -- The 'mult' function multiplies a group element by an integer of -- length 'Bytes.multScalar'. It returns the resulting group element -- of length 'Bytes.mult'. The 'multBase' function multiplies a -- standard group element by an integer of length -- 'Bytes.multScalar'. It returns the resulting group element of -- length 'Bytes.mult'.--- +-- -- The correspondence between strings and group elements depends on -- the primitive implemented by 'mult'. The correspondence is not -- necessarily injective in either direction, but it is compatible -- with scalar multiplication in the group. The correspondence does -- not necessarily include all group elements, but it does include all -- strings; i.e., every string represents at least one group element.--- +-- -- The correspondence between strings and integers also depends on the -- primitive implemented by 'mult'. Every string represents at least -- one integer.--- +-- -- 'mult' is designed to be strong as a component of various -- well-known \"hashed Diffie–Hellman\" applications. In particular, -- it is designed to make the \"computational Diffie–Hellman\" problem@@ -36,33 +36,33 @@ -- order, then it is annihilated by all represented scalars. This -- feature allows protocols to avoid validating membership in the -- subgroup generated by the standard base.--- +-- -- NaCl does not make any promises regarding the \"decisional -- Diffie–Hellman\" problem (DDH), the \"static Diffie–Hellman\" -- problem (SDH), etc. Users are responsible for hashing group -- elements.--- +-- -- 'mult' is the function @crypto_scalarmult_curve25519@ specified in -- \"Cryptography in NaCl\", Sections 2, 3, and 4 -- (<http://nacl.cr.yp.to/valid.html>). This function is conjectured -- to be strong. For background see Bernstein, \"Curve25519: new -- Diffie-Hellman speed records,\" Lecture Notes in Computer Science -- 3958 (2006), 207–228, <http://cr.yp.to/papers.html#curve25519>.--- +-- -- This is version 2010.08.30 of the scalarmult.html web page. module Crypto.Saltine.Core.ScalarMult (   Scalar, GroupElement,   mult, multBase   ) where -import Crypto.Saltine.Class-import Crypto.Saltine.Internal.Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Internal.Util import qualified Crypto.Saltine.Internal.ByteSizes as Bytes -import Foreign.C-import Foreign.Ptr-import qualified Data.ByteString as S-import           Data.ByteString (ByteString)+import           Foreign.C+import           Foreign.Ptr+import qualified Data.ByteString                   as S+import           Data.ByteString                     (ByteString)  -- $types @@ -70,20 +70,20 @@ newtype GroupElement = GE ByteString deriving (Eq)  -- | A scalar integer.-newtype Scalar = Sc ByteString deriving (Eq)+newtype Scalar       = Sc ByteString deriving (Eq)  instance IsEncoding GroupElement where-  decode v = case S.length v == Bytes.mult of-    True -> Just (GE v)-    False -> Nothing+  decode v = if S.length v == Bytes.mult+           then Just (GE v)+           else Nothing   {-# INLINE decode #-}   encode (GE v) = v   {-# INLINE encode #-}  instance IsEncoding Scalar where-  decode v = case S.length v == Bytes.multScalar of-    True -> Just (Sc v)-    False -> Nothing+  decode v = if S.length v == Bytes.multScalar+           then Just (Sc v)+           else Nothing   {-# INLINE decode #-}   encode (Sc v) = v   {-# INLINE encode #-}@@ -91,27 +91,27 @@ mult :: Scalar -> GroupElement -> GroupElement mult (Sc n) (GE p) = GE . snd . buildUnsafeCVector Bytes.mult $ \pq ->   constVectors [n, p] $ \[(pn, _), (pp, _)] ->-  c_scalarmult pq pn pp+    c_scalarmult pq pn pp  multBase :: Scalar -> GroupElement multBase (Sc n) = GE . snd . buildUnsafeCVector Bytes.mult $ \pq ->   constVectors [n] $ \[(pn, _)] ->-  c_scalarmult_base pq pn+    c_scalarmult_base pq pn  foreign import ccall "crypto_scalarmult"   c_scalarmult :: Ptr CChar-                  -- ^ Output group element buffer-                  -> Ptr CChar-                  -- ^ Input integer buffer-                  -> Ptr CChar-                  -- ^ Input group element buffer-                  -> IO CInt-                  -- ^ Always 0+               -- ^ Output group element buffer+               -> Ptr CChar+               -- ^ Input integer buffer+               -> Ptr CChar+               -- ^ Input group element buffer+               -> IO CInt+               -- ^ Always 0  foreign import ccall "crypto_scalarmult_base"   c_scalarmult_base :: Ptr CChar-                       -- ^ Output group element buffer-                       -> Ptr CChar-                       -- ^ Input integer buffer-                       -> IO CInt-                       -- ^ Always 0+                    -- ^ Output group element buffer+                    -> Ptr CChar+                    -- ^ Input integer buffer+                    -> IO CInt+                    -- ^ Always 0
src/Crypto/Saltine/Core/SecretBox.hs view
@@ -2,20 +2,20 @@ -- Module      : Crypto.Saltine.Core.SecretBox -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- +-- -- Secret-key authenticated encryption: -- "Crypto.Saltine.Core.SecretBox"--- +-- -- The 'secretbox' function encrypts and authenticates a message -- 'ByteString' using a secret key and a nonce. The 'secretboxOpen' -- function verifies and decrypts a ciphertext 'ByteString' using a -- secret key and a nonce. If the ciphertext fails validation, -- 'secretboxOpen' returns 'Nothing'.--- +-- -- The "Crypto.Saltine.Core.SecretBox" module is designed to meet -- the standard notions of privacy and authenticity for a secret-key -- authenticated-encryption scheme using nonces. For formal@@ -23,19 +23,19 @@ -- encryption: relations among notions and analysis of the generic -- composition paradigm," Lecture Notes in Computer Science 1976 -- (2000), 531–545, <http://www-cse.ucsd.edu/~mihir/papers/oem.html>.--- +-- -- Note that the length is not hidden. Note also that it is the -- caller's responsibility to ensure the uniqueness of nonces—for -- example, by using nonce 1 for the first message, nonce 2 for the -- second message, etc. Nonces are long enough that randomly generated -- nonces have negligible risk of collision.--- +-- -- "Crypto.Saltine.Core.SecretBox" is -- @crypto_secretbox_xsalsa20poly1305@, a particular combination of -- Salsa20 and Poly1305 specified in \"Cryptography in NaCl\" -- (<http://nacl.cr.yp.to/valid.html>). This function is conjectured -- to meet the standard notions of privacy and authenticity.--- +-- -- This is version 2010.08.30 of the secretbox.html web page. module Crypto.Saltine.Core.SecretBox (   Key, Nonce,@@ -43,16 +43,15 @@   newKey, newNonce   ) where -import Crypto.Saltine.Class-import Crypto.Saltine.Internal.Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Internal.Util import qualified Crypto.Saltine.Internal.ByteSizes as Bytes -import Foreign.C-import Foreign.Ptr-import qualified Data.ByteString as S-import           Data.ByteString (ByteString)--import Control.Applicative+import           Control.Applicative+import           Foreign.C+import           Foreign.Ptr+import qualified Data.ByteString                   as S+import           Data.ByteString                     (ByteString)  -- $types @@ -60,9 +59,9 @@ newtype Key = Key ByteString deriving (Eq, Ord)  instance IsEncoding Key where-  decode v = case S.length v == Bytes.secretBoxKey of-    True -> Just (Key v)-    False -> Nothing+  decode v = if S.length v == Bytes.secretBoxKey+           then Just (Key v)+           else Nothing   {-# INLINE decode #-}   encode (Key v) = v   {-# INLINE encode #-}@@ -71,15 +70,15 @@ newtype Nonce = Nonce ByteString deriving (Eq, Ord)  instance IsEncoding Nonce where-  decode v = case S.length v == Bytes.secretBoxNonce of-    True -> Just (Nonce v)-    False -> Nothing+  decode v = if S.length v == Bytes.secretBoxNonce+           then Just (Nonce v)+           else Nothing   {-# INLINE decode #-}   encode (Nonce v) = v   {-# INLINE encode #-}  instance IsNonce Nonce where-  zero = Nonce (S.replicate Bytes.secretBoxNonce 0)+  zero            = Nonce (S.replicate Bytes.secretBoxNonce 0)   nudge (Nonce n) = Nonce (nudgeBS n)  -- | Creates a random key of the correct size for 'secretbox'.@@ -93,15 +92,15 @@ -- | Encrypts a message. It is infeasible for an attacker to decrypt -- the message so long as the 'Nonce' is never repeated. secretbox :: Key -> Nonce-             -> ByteString-             -- ^ Message-             -> ByteString-             -- ^ Ciphertext+          -> ByteString+          -- ^ Message+          -> ByteString+          -- ^ Ciphertext secretbox (Key key) (Nonce nonce) msg =   unpad' . snd . buildUnsafeCVector len $ \pc ->     constVectors [key, pad' msg, nonce] $ \       [(pk, _), (pm, _), (pn, _)] ->-      c_secretbox pc pm (fromIntegral len) pn pk+        c_secretbox pc pm (fromIntegral len) pn pk   where len    = S.length msg + Bytes.secretBoxZero         pad'   = pad Bytes.secretBoxZero         unpad' = unpad Bytes.secretBoxBoxZero@@ -117,7 +116,7 @@   let (err, vec) = buildUnsafeCVector len $ \pm ->         constVectors [key, pad' cipher, nonce] $ \           [(pk, _), (pc, _), (pn, _)] ->-          c_secretbox_open pm pc (fromIntegral len) pn pk+            c_secretbox_open pm pc (fromIntegral len) pn pk   in hush . handleErrno err $ unpad' vec   where len    = S.length cipher + Bytes.secretBoxBoxZero         pad'   = pad Bytes.secretBoxBoxZero@@ -126,28 +125,28 @@ -- | The secretbox C API uses 0-padded C strings. Always returns 0. foreign import ccall "crypto_secretbox"   c_secretbox :: Ptr CChar-                 -- ^ Cipher 0-padded output buffer-                 -> Ptr CChar-                 -- ^ Constant 0-padded message input buffer-                 -> CULLong-                 -- ^ Length of message input buffer (incl. 0s)-                 -> Ptr CChar-                 -- ^ Constant nonce buffer-                 -> Ptr CChar-                 -- ^ Constant key buffer-                 -> IO CInt+              -- ^ Cipher 0-padded output buffer+              -> Ptr CChar+              -- ^ Constant 0-padded message input buffer+              -> CULLong+              -- ^ Length of message input buffer (incl. 0s)+              -> Ptr CChar+              -- ^ Constant nonce buffer+              -> Ptr CChar+              -- ^ Constant key buffer+              -> IO CInt  -- | The secretbox C API uses 0-padded C strings. Returns 0 if -- successful or -1 if verification failed. foreign import ccall "crypto_secretbox_open"   c_secretbox_open :: Ptr CChar-                      -- ^ Message 0-padded output buffer-                      -> Ptr CChar-                      -- ^ Constant 0-padded message input buffer-                      -> CULLong-                      -- ^ Length of message input buffer (incl. 0s)-                      -> Ptr CChar-                      -- ^ Constant nonce buffer-                      -> Ptr CChar-                      -- ^ Constant key buffer-                      -> IO CInt+                   -- ^ Message 0-padded output buffer+                   -> Ptr CChar+                   -- ^ Constant 0-padded message input buffer+                   -> CULLong+                   -- ^ Length of message input buffer (incl. 0s)+                   -> Ptr CChar+                   -- ^ Constant nonce buffer+                   -> Ptr CChar+                   -- ^ Constant key buffer+                   -> IO CInt
src/Crypto/Saltine/Core/Sign.hs view
@@ -2,20 +2,20 @@ -- Module      : Crypto.Saltine.Core.Sign -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- +-- -- Signatures: "Crypto.Saltine.Core.Sign"--- +-- -- The 'newKeypair' function randomly generates a secret key and a -- corresponding public key. The 'sign' function signs a message -- 'ByteString' using the signer's secret key and returns the -- resulting signed message. The 'signOpen' function verifies the -- signature in a signed message using the signer's public key then -- returns the message without its signature.--- +-- -- "Crypto.Saltine.Core.Sign" is an EdDSA signature using -- elliptic-curve Curve25519 (see: <http://ed25519.cr.yp.to/>). See -- also, \"Daniel J. Bernstein, Niels Duif, Tanja Lange, Peter@@ -31,17 +31,17 @@   sign, signOpen   ) where -import Crypto.Saltine.Class-import Crypto.Saltine.Internal.Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Internal.Util import qualified Crypto.Saltine.Internal.ByteSizes as Bytes -import Foreign.C-import Foreign.Ptr-import Foreign.Marshal.Alloc-import Foreign.Storable-import System.IO.Unsafe-import qualified Data.ByteString as S-import           Data.ByteString (ByteString)+import           Foreign.C+import           Foreign.Ptr+import           Foreign.Marshal.Alloc+import           Foreign.Storable+import           System.IO.Unsafe+import qualified Data.ByteString                   as S+import           Data.ByteString                     (ByteString)  -- $types @@ -49,9 +49,9 @@ newtype SecretKey = SK ByteString deriving (Eq, Ord)  instance IsEncoding SecretKey where-  decode v = case S.length v == Bytes.signSK of-    True -> Just (SK v)-    False -> Nothing+  decode v = if S.length v == Bytes.signSK+           then Just (SK v)+           else Nothing   {-# INLINE decode #-}   encode (SK v) = v   {-# INLINE encode #-}@@ -60,9 +60,9 @@ newtype PublicKey = PK ByteString deriving (Eq, Ord)  instance IsEncoding PublicKey where-  decode v = case S.length v == Bytes.signPK of-    True -> Just (PK v)-    False -> Nothing+  decode v = if S.length v == Bytes.signPK+           then Just (PK v)+           else Nothing   {-# INLINE decode #-}   encode (PK v) = v   {-# INLINE encode #-}@@ -78,21 +78,21 @@   -- _err ought to always be 0.   ((_err, sk), pk) <- buildUnsafeCVector' Bytes.signPK $ \pkbuf ->     buildUnsafeCVector' Bytes.signSK $ \skbuf ->-    c_sign_keypair pkbuf skbuf+      c_sign_keypair pkbuf skbuf   return (SK sk, PK pk)  -- | Augments a message with a signature forming a \"signed -- message\". sign :: SecretKey-        -> ByteString-        -- ^ Message-        -> ByteString-        -- ^ Signed message-sign (SK k) m = unsafePerformIO $ +     -> ByteString+     -- ^ Message+     -> ByteString+     -- ^ Signed message+sign (SK k) m = unsafePerformIO $   alloca $ \psmlen -> do     (_err, sm) <- buildUnsafeCVector' (len + Bytes.sign) $ \psmbuf ->       constVectors [k, m] $ \[(pk, _), (pm, _)] ->-      c_sign psmbuf psmlen pm (fromIntegral len) pk+        c_sign psmbuf psmlen pm (fromIntegral len) pk     smlen <- peek psmlen     return $ S.take (fromIntegral smlen) sm   where len = S.length m@@ -101,54 +101,54 @@ -- iff the signature was generated using the 'SecretKey' corresponding -- to the given 'PublicKey'. Returns 'Nothing' otherwise. signOpen :: PublicKey-            -> ByteString-            -- ^ Signed message-            -> Maybe ByteString-            -- ^ Maybe the restored message+         -> ByteString+         -- ^ Signed message+         -> Maybe ByteString+         -- ^ Maybe the restored message signOpen (PK k) sm = unsafePerformIO $   alloca $ \pmlen -> do     (err, m) <- buildUnsafeCVector' smlen $ \pmbuf ->       constVectors [k, sm] $ \[(pk, _), (psm, _)] ->-      c_sign_open pmbuf pmlen psm (fromIntegral smlen) pk+        c_sign_open pmbuf pmlen psm (fromIntegral smlen) pk     mlen <- peek pmlen     case err of       0 -> return $ Just $ S.take (fromIntegral mlen) m-      _ -> return $ Nothing+      _ -> return   Nothing   where smlen = S.length sm   foreign import ccall "crypto_sign_keypair"   c_sign_keypair :: Ptr CChar-                    -- ^ Public key output buffer-                    -> Ptr CChar-                    -- ^ Secret key output buffer-                    -> IO CInt-                    -- ^ Always 0+                 -- ^ Public key output buffer+                 -> Ptr CChar+                 -- ^ Secret key output buffer+                 -> IO CInt+                 -- ^ Always 0  foreign import ccall "crypto_sign"   c_sign :: Ptr CChar-            -- ^ Signed message output buffer-            -> Ptr CULLong-            -- ^ Length of signed message-            -> Ptr CChar-            -- ^ Constant message buffer-            -> CULLong-            -- ^ Length of message input buffer-            -> Ptr CChar-            -- ^ Constant secret key buffer-            -> IO CInt-            -- ^ Always 0+         -- ^ Signed message output buffer+         -> Ptr CULLong+         -- ^ Length of signed message+         -> Ptr CChar+         -- ^ Constant message buffer+         -> CULLong+         -- ^ Length of message input buffer+         -> Ptr CChar+         -- ^ Constant secret key buffer+         -> IO CInt+         -- ^ Always 0  foreign import ccall "crypto_sign_open"   c_sign_open :: Ptr CChar-                 -- ^ Message output buffer-                 -> Ptr CULLong-                 -- ^ Length of message-                 -> Ptr CChar-                 -- ^ Constant signed message buffer-                 -> CULLong-                 -- ^ Length of signed message buffer-                 -> Ptr CChar-                 -- ^ Public key buffer-                 -> IO CInt-                 -- ^ 0 if signature is verifiable, -1 otherwise+              -- ^ Message output buffer+              -> Ptr CULLong+              -- ^ Length of message+              -> Ptr CChar+              -- ^ Constant signed message buffer+              -> CULLong+              -- ^ Length of signed message buffer+              -> Ptr CChar+              -- ^ Public key buffer+              -> IO CInt+              -- ^ 0 if signature is verifiable, -1 otherwise
src/Crypto/Saltine/Core/Stream.hs view
@@ -2,21 +2,21 @@ -- Module      : Crypto.Saltine.Core.Stream -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- +-- -- Secret-key encryption: -- "Crypto.Saltine.Core.Stream"--- +-- -- The 'stream' function produces a sized stream 'ByteString' as a -- function of a secret key and a nonce. The 'xor' function encrypts a -- message 'ByteString' using a secret key and a nonce.  The 'xor' -- function guarantees that the ciphertext has the same length as the -- plaintext, and is the @plaintext `xor` stream k n@. Consequently -- 'xor' can also be used to decrypt.--- +-- -- The 'stream' function, viewed as a function of the nonce for a -- uniform random key, is designed to meet the standard notion of -- unpredictability (\"PRF\"). For a formal definition see, e.g.,@@ -29,22 +29,22 @@ -- 'xor' with /a different nonce for each message/, the ciphertexts -- are indistinguishable from uniform random strings of the same -- length.--- +-- -- Note that the length is not hidden. Note also that it is the -- caller's responsibility to ensure the uniqueness of nonces—for -- example, by using nonce 1 for the first message, nonce 2 for the -- second message, etc. Nonces are long enough that randomly generated -- nonces have negligible risk of collision.--- +-- -- Saltine does not make any promises regarding the resistance of -- crypto_stream to \"related-key attacks.\" It is the caller's -- responsibility to use proper key-derivation functions.--- +-- -- "Crypto.Saltine.Core.Stream" is @crypto_stream_xsalsa20@, a -- particular cipher specified in \"Cryptography in NaCl\" -- (<http://nacl.cr.yp.to/valid.html>), Section 7. This cipher is -- conjectured to meet the standard notion of unpredictability.--- +-- -- This is version 2010.08.30 of the stream.html web page.  module Crypto.Saltine.Core.Stream (@@ -53,26 +53,25 @@   stream, xor   ) where -import Crypto.Saltine.Class-import Crypto.Saltine.Internal.Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Internal.Util import qualified Crypto.Saltine.Internal.ByteSizes as Bytes -import Foreign.C-import Foreign.Ptr+import           Control.Applicative+import           Foreign.C+import           Foreign.Ptr import qualified Data.ByteString as S import           Data.ByteString (ByteString) -import Control.Applicative- -- $types  -- | An opaque 'stream' cryptographic key. newtype Key = Key ByteString deriving (Eq, Ord)  instance IsEncoding Key where-  decode v = case S.length v == Bytes.streamKey of-    True -> Just (Key v)-    False -> Nothing+  decode v = if S.length v == Bytes.streamKey+           then Just (Key v)+           else Nothing   {-# INLINE decode #-}   encode (Key v) = v   {-# INLINE encode #-}@@ -85,9 +84,9 @@   nudge (Nonce n) = Nonce (nudgeBS n)  instance IsEncoding Nonce where-  decode v = case S.length v == Bytes.streamNonce of-    True -> Just (Nonce v)-    False -> Nothing+  decode v = if S.length v == Bytes.streamNonce+           then Just (Nonce v)+           else Nothing   {-# INLINE decode #-}   encode (Nonce v) = v   {-# INLINE encode #-}@@ -105,8 +104,8 @@ -- 'Nonce'. These streams are indistinguishable from random noise so -- long as the 'Nonce' is not used more than once. stream :: Key -> Nonce -> Int-          -> ByteString-          -- ^ Cryptographic stream+       -> ByteString+       -- ^ Cryptographic stream stream (Key key) (Nonce nonce) n =   snd . buildUnsafeCVector n $ \ps ->     constVectors [key, nonce] $ \[(pk, _), (pn, _)] ->@@ -119,11 +118,11 @@ -- for encryption and decryption, it is /possible for an attacker to/ -- /manipulate the message in transit without detection/. USE AT YOUR -- OWN RISK.-xor :: Key -> Nonce -       -> ByteString-       -- ^ Message-       -> ByteString-       -- ^ Ciphertext+xor :: Key -> Nonce+    -> ByteString+    -- ^ Message+    -> ByteString+    -- ^ Ciphertext xor (Key key) (Nonce nonce) msg =   snd . buildUnsafeCVector len $ \pc ->     constVectors [key, nonce, msg] $ \[(pk, _), (pn, _), (pm, _)] ->@@ -132,26 +131,26 @@  foreign import ccall "crypto_stream"   c_stream :: Ptr CChar-              -- ^ Stream output buffer-              -> CULLong-              -- ^ Length of stream to generate-              -> Ptr CChar-              -- ^ Constant nonce buffer-              -> Ptr CChar-              -- ^ Constant key buffer-              -> IO CInt-              -- ^ Always 0+           -- ^ Stream output buffer+           -> CULLong+           -- ^ Length of stream to generate+           -> Ptr CChar+           -- ^ Constant nonce buffer+           -> Ptr CChar+           -- ^ Constant key buffer+           -> IO CInt+           -- ^ Always 0  foreign import ccall "crypto_stream_xor"   c_stream_xor :: Ptr CChar-                  -- ^ Ciphertext output buffer-                  -> Ptr CChar-                  -- ^ Constant message buffer-                  -> CULLong-                  -- ^ Length of message buffer-                  -> Ptr CChar-                  -- ^ Constant nonce buffer-                  -> Ptr CChar-                  -- ^ Constant key buffer-                  -> IO CInt-                  -- ^ Always 0+               -- ^ Ciphertext output buffer+               -> Ptr CChar+               -- ^ Constant message buffer+               -> CULLong+               -- ^ Length of message buffer+               -> Ptr CChar+               -- ^ Constant nonce buffer+               -> Ptr CChar+               -- ^ Constant key buffer+               -> IO CInt+               -- ^ Always 0
src/Crypto/Saltine/Internal/ByteSizes.hs view
@@ -3,17 +3,17 @@ -- Module      : Crypto.Saltine.Core.ScalarMult -- Copyright   : (c) Joseph Abrahamson 2013 -- License     : MIT--- +-- -- Maintainer  : me@jspha.com -- Stability   : experimental -- Portability : non-portable--- +-- -- Various sizes--- +-- -- While technically these sizes are hidden behind opaque newtype -- wrappers, they can be useful for computation and sizing and are -- thus exposed.--- +-- -- As of @libsodium-4.1@ some of these sizes are not exported and thus -- are hardcoded here. This limitation should be removed in later -- versions of @libsodium@.@@ -28,6 +28,7 @@   boxBoxZero,   boxMac,   boxBeforeNM,+  sealedBox,   onetime,   onetimeKey,   mult,@@ -44,7 +45,6 @@   hash,   shorthash,   shorthashKey-     ) where  import Foreign.C@@ -52,7 +52,8 @@ -- Constants for  auth, authKey :: Int-boxPK, boxSK, boxNonce, boxZero, boxBoxZero, boxMac, boxBeforeNM :: Int+boxPK, boxSK, boxNonce, boxZero, boxBoxZero :: Int+boxMac, boxBeforeNM, sealedBox :: Int onetime, onetimeKey :: Int mult, multScalar :: Int secretBoxKey, secretBoxNonce, secretBoxZero, secretBoxBoxZero :: Int@@ -64,7 +65,7 @@ -- Authentication -- | Size of a @crypto_auth@ authenticator. auth    = fromIntegral c_crypto_auth_bytes--- | Size of a @crypto_auth@ authenticator key. +-- | Size of a @crypto_auth@ authenticator key. authKey = fromIntegral c_crypto_auth_keybytes  -- Box@@ -85,6 +86,11 @@ boxBeforeNM =   fromIntegral c_crypto_box_beforenmbytes +-- SealedBox+-- | Amount by which ciphertext is longer than plaintext+-- in sealed boxes+sealedBox = fromIntegral c_crypto_box_sealbytes+ -- OneTimeAuth -- | Size of a @crypto_onetimeauth@ authenticator. onetime    = fromIntegral c_crypto_onetimeauth_bytes@@ -157,7 +163,11 @@   c_crypto_box_boxzerobytes :: CSize foreign import ccall "crypto_box_macbytes"   c_crypto_box_macbytes :: CSize-                           ++-- src/libsodium/crypto_box_seal.c+foreign import ccall "crypto_box_sealbytes"+  c_crypto_box_sealbytes :: CSize+ -- src/libsodium/crypto_onetimeauth/crypto_onetimeauth.c foreign import ccall "crypto_onetimeauth_bytes"   c_crypto_onetimeauth_bytes :: CSize
src/Crypto/Saltine/Internal/Util.hs view
@@ -1,13 +1,14 @@ module Crypto.Saltine.Internal.Util where -import Foreign.C-import Foreign.Ptr-import System.IO.Unsafe+import           Foreign.C+import           Foreign.Ptr+import           System.IO.Unsafe -import Data.Monoid-import qualified Data.ByteString as S-import Data.ByteString (ByteString)-import Data.ByteString.Unsafe+import           Control.Applicative+import qualified Data.ByteString        as S+import           Data.ByteString          (ByteString)+import           Data.ByteString.Unsafe+import           Data.Monoid  -- | @snd . cycleSucc@ computes the 'succ' of a 'Bounded', 'Eq' 'Enum' -- with wraparound. The @fst . cycleSuc@ is whether the wraparound@@ -20,16 +21,17 @@ -- it. nudgeBS :: ByteString -> ByteString nudgeBS i = fst $ S.unfoldrN (S.length i) go (True, i) where-  go (toSucc, bs) =-    do (hd, tl) <- S.uncons bs-       let (top, hd') = cycleSucc hd-       if toSucc-         then return (hd', (top, tl))-         else return (hd, (top && toSucc, tl))+  go (toSucc, bs) = do+    (hd, tl)      <- S.uncons bs+    let (top, hd') = cycleSucc hd +    if   toSucc+    then return (hd', (top, tl))+    else return (hd, (top && toSucc, tl))+ -- | Computes the orbit of a endomorphism... in a very brute force -- manner. Exists just for the below property.--- +-- -- prop> length . orbit nudgeBS . S.pack . replicate 0 == (256^) orbit :: Eq a => (a -> a) -> a -> [a] orbit f a0 = orbit' (f a0) where@@ -66,7 +68,7 @@ buildUnsafeCVector' :: Int -> (Ptr CChar -> IO b) -> IO (b, ByteString) buildUnsafeCVector' n k = do   let bs = S.replicate n 0-  out <- unsafeUseAsCString bs k+  out   <- unsafeUseAsCString bs k   return (out, bs)  -- | Extremely unsafe function, use with utmost care! Builds a new@@ -80,7 +82,7 @@ -- @/dev/urandom@. randomVector :: Int -> IO ByteString randomVector n =-  fmap snd $ buildUnsafeCVector' n (`c_randombytes_buf` fromIntegral n)+  snd <$> buildUnsafeCVector' n (`c_randombytes_buf` fromIntegral n)  -- | To prevent a dependency on package 'errors' hush :: Either s a -> Maybe a
tests/AuthProperties.hs view
@@ -5,7 +5,6 @@   ) where  import Util- import Crypto.Saltine.Core.Auth  import Test.Framework.Providers.QuickCheck2@@ -17,6 +16,6 @@   return $ testGroup "...Internal.Auth" [      testProperty "Authenticates message"-    $ \(Message bs) -> verify k (auth k bs) bs  == True+    $ \(Message bs) -> verify k (auth k bs) bs == True      ]
tests/BoxProperties.hs view
@@ -4,17 +4,14 @@   testBox   ) where -import Util--import Crypto.Saltine.Core.Box--import qualified Data.ByteString as S--import Test.Framework.Providers.QuickCheck2-import Test.Framework+import           Util+import           Crypto.Saltine.Core.Box+import qualified Data.ByteString                      as S -import Test.QuickCheck.Property-import Test.QuickCheck.Monadic+import           Test.Framework.Providers.QuickCheck2+import           Test.Framework+import           Test.QuickCheck.Property+import           Test.QuickCheck.Monadic  -- | Ciphertext can be decrypted rightInverseProp :: Keypair -> Keypair -> Nonce -> Message -> Bool@@ -67,7 +64,6 @@  testBox :: Test testBox = buildTest $ do-   (sk1, pk1) <- newKeypair   (sk2, pk2) <- newKeypair   let ck_1for2 = beforeNM sk1 pk2@@ -78,39 +74,37 @@   return $ testGroup "...Internal.Box" [      testGroup "Can decrypt ciphertext using..." [-       +        testProperty "... public key/secret key"        $ rightInverseProp (sk1, pk1) (sk2, pk2) n1 ,-       +        testProperty "... combined key"        $ rightInverseAfterNMProp ck_1for2 ck_2for1 n1-       +        ],      testGroup "Fail to verify ciphertext when..." [-      +       testProperty "... not using proper secret key"       $ rightInverseFailureProp1 (sk1, pk1) (sk2, pk2) n1,-      +       testProperty "... not actually sent to you"       $ rightInverseFailureProp2 (sk1, pk1) (sk2, pk2) n1,-      +       testProperty "... ciphertext has been perturbed"       $ rightInverseFailureProp3 (sk1, pk1) (sk2, pk2) n1,-      +       testProperty "... using the wrong nonce"       $ cannotDecryptNonceProp (sk1, pk1) (sk2, pk2) n1 n2,-      +       testProperty "... using the wrong combined key"       $ rightInverseFailureAfterNMProp1 ck_1for2 ck_2for1 n1-      +       ],      testGroup "(properties)" [        testProperty "beforeNM is anti-symmetric" beforeNMCreateSecretKeyProp-      +       ]     ]-    -       
tests/Main.hs view
@@ -2,19 +2,21 @@  module Main where -import SecretBoxProperties (testSecretBox)-import BoxProperties (testBox)-import StreamProperties (testStream)-import AuthProperties (testAuth)+import SecretBoxProperties   (testSecretBox)+import BoxProperties         (testBox)+import SealedBoxProperties   (testSealedBox)+import StreamProperties      (testStream)+import AuthProperties        (testAuth) import OneTimeAuthProperties (testOneTimeAuth)-import SignProperties (testSign)-import ScalarMultProperties (testScalarMult)+import SignProperties        (testSign)+import ScalarMultProperties  (testScalarMult)  import Test.Framework  main :: IO () main = defaultMain [   testBox,+  testSealedBox,   testSecretBox,   testStream,   testAuth,
tests/OneTimeAuthProperties.hs view
tests/ScalarMultProperties.hs view
@@ -4,16 +4,14 @@   testScalarMult   ) where -import Util--import Crypto.Saltine.Class-import Crypto.Saltine.Core.ScalarMult--import qualified Data.ByteString as S-import Data.Maybe (fromJust)+import           Util+import           Crypto.Saltine.Class+import           Crypto.Saltine.Core.ScalarMult -import Test.Framework.Providers.QuickCheck2-import Test.Framework+import qualified Data.ByteString                      as S+import           Data.Maybe                             (fromJust)+import           Test.Framework.Providers.QuickCheck2+import           Test.Framework  -- Test vectors extracted from "Cryptography in NaCl", -- http://cr.yp.to/highspeed/naclcrypto-20090310.pdf@@ -47,7 +45,7 @@     ,0x76,0xf0,0x9b,0x3c,0x1e,0x16,0x17,0x42]  testScalarMult :: Test-testScalarMult = buildTest $ do+testScalarMult = buildTest $   return $ testGroup "...Internal.ScalarMult" [      testProperty "mult a (multBase a) /= multBase a"
tests/SecretBoxProperties.hs view
@@ -4,14 +4,12 @@   testSecretBox   ) where -import Util--import Crypto.Saltine.Core.SecretBox--import qualified Data.ByteString as S+import           Util+import           Crypto.Saltine.Core.SecretBox -import Test.Framework.Providers.QuickCheck2-import Test.Framework+import qualified Data.ByteString                      as S+import           Test.Framework.Providers.QuickCheck2+import           Test.Framework  -- | Ciphertext can be decrypted rightInverseProp :: Key -> Nonce -> Message -> Bool@@ -55,6 +53,6 @@        testProperty "... using the wrong nonce"       $ cannotDecryptNonceProp k1 n1 n2-      +       ]     ]
tests/SignProperties.hs view
@@ -4,15 +4,13 @@   testSign   ) where -import Util--import Crypto.Saltine.Core.Sign--import qualified Data.ByteString as S+import           Util+import           Crypto.Saltine.Core.Sign -import Test.Framework.Providers.QuickCheck2-import Test.Framework-import Test.QuickCheck+import qualified Data.ByteString                      as S+import           Test.Framework.Providers.QuickCheck2+import           Test.Framework+import           Test.QuickCheck  testSign :: Test testSign = buildTest $ do@@ -28,6 +26,6 @@     $ \(Message bs) -> S.length (sign sk1 bs) >= S.length bs,      testProperty "Rejects message with mismatched key"-    $ \(Message bs) -> (not $ S.null bs) ==> signOpen pk2 (sign sk1 bs) == Nothing+    $ \(Message bs) -> not (S.null bs) ==> signOpen pk2 (sign sk1 bs) == Nothing      ]
tests/StreamProperties.hs view
@@ -4,15 +4,13 @@   testStream   ) where -import Util--import Crypto.Saltine.Core.Stream--import qualified Data.ByteString as S+import           Util+import           Crypto.Saltine.Core.Stream -import Test.Framework.Providers.QuickCheck2-import Test.Framework-import Test.QuickCheck+import qualified Data.ByteString                      as S+import           Test.Framework.Providers.QuickCheck2+import           Test.Framework+import           Test.QuickCheck  testStream :: Test testStream = buildTest $ do@@ -30,7 +28,5 @@      testProperty "xor is involutive"     $ \(Message bs) -> xor k n (xor k n bs) == bs-    +     ]-    -       
tests/Util.hs view
@@ -1,19 +1,18 @@ module Util where -import Test.QuickCheck--import Crypto.Saltine.Class+import           Crypto.Saltine.Class -import qualified Data.ByteString as S+import           Control.Applicative+import           Control.Monad           (replicateM)+import qualified Data.ByteString       as S import qualified Data.ByteString.Char8 as S8-import Control.Monad (replicateM)+import           Data.Maybe              (fromMaybe)+import           Test.QuickCheck -import Control.Applicative  perturb :: IsEncoding a => a -> a-perturb a = case decode (S.reverse (encode a)) of-  Just x -> x-  Nothing -> error "Util.perturb"+perturb a = fromMaybe (error "Util.perturb")+                      (decode (S.reverse (encode a)))  newtype ByteString32 = ByteString32 S.ByteString deriving (Show)