packages feed

NaCl 0.0.1.0 → 0.0.2.0

raw patch · 8 files changed

+114/−147 lines, 8 filesdep −textdep ~memoryPVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependencies removed: text

Dependency ranges changed: memory

API changes (from Hackage documentation)

- Data.ByteArray.Sized: data OfLength (l :: Nat) ba
- Data.ByteArray.Sized: hasRightLength :: forall ba n. (ByteArrayAccess ba, KnownNat n) => ba -> Maybe (OfLength n ba)
- Data.ByteArray.Sized.Internal: OfLength :: ba -> OfLength (l :: Nat) ba
- Data.ByteArray.Sized.Internal: alloc :: forall ba n p. (ByteArray ba, KnownNat n) => (Ptr p -> IO ()) -> IO (OfLength n ba)
- Data.ByteArray.Sized.Internal: allocRet :: forall ba n p a. (ByteArray ba, KnownNat n) => (Ptr p -> IO a) -> IO (a, OfLength n ba)
- Data.ByteArray.Sized.Internal: hasRightLength :: forall ba n. (ByteArrayAccess ba, KnownNat n) => ba -> Maybe (OfLength n ba)
- Data.ByteArray.Sized.Internal: instance Data.ByteArray.Types.ByteArrayAccess ba => Data.ByteArray.Types.ByteArrayAccess (Data.ByteArray.Sized.Internal.OfLength l ba)
- Data.ByteArray.Sized.Internal: instance Data.The.The (Data.ByteArray.Sized.Internal.OfLength l ba) ba
- Data.ByteArray.Sized.Internal: instance GHC.Base.Monoid ba => GHC.Base.Monoid (Data.ByteArray.Sized.Internal.OfLength l ba)
- Data.ByteArray.Sized.Internal: instance GHC.Base.Semigroup ba => GHC.Base.Semigroup (Data.ByteArray.Sized.Internal.OfLength l ba)
- Data.ByteArray.Sized.Internal: instance GHC.Classes.Eq ba => GHC.Classes.Eq (Data.ByteArray.Sized.Internal.OfLength l ba)
- Data.ByteArray.Sized.Internal: instance GHC.Classes.Ord ba => GHC.Classes.Ord (Data.ByteArray.Sized.Internal.OfLength l ba)
- Data.ByteArray.Sized.Internal: newtype OfLength (l :: Nat) ba
- Crypto.Secretbox: create :: (ByteArrayAccess key, ByteArrayAccess nonce, ByteArrayAccess pt, ByteArray ct) => Key key -> Nonce nonce -> pt -> ct
+ Crypto.Secretbox: create :: (ByteArrayAccess keyBytes, ByteArrayAccess nonceBytes, ByteArrayAccess ptBytes, ByteArray ctBytes) => Key keyBytes -> Nonce nonceBytes -> ptBytes -> ctBytes
- Crypto.Secretbox: open :: (ByteArrayAccess key, ByteArrayAccess nonce, ByteArray pt, ByteArrayAccess ct) => Key key -> Nonce nonce -> ct -> Maybe pt
+ Crypto.Secretbox: open :: (ByteArrayAccess keyBytes, ByteArrayAccess nonceBytes, ByteArray ptBytes, ByteArrayAccess ctBytes) => Key keyBytes -> Nonce nonceBytes -> ctBytes -> Maybe ptBytes
- Crypto.Secretbox: type Key a = OfLength CRYPTO_SECRETBOX_KEYBYTES a
+ Crypto.Secretbox: type Key a = SizedByteArray CRYPTO_SECRETBOX_KEYBYTES a
- Crypto.Secretbox: type Nonce a = OfLength CRYPTO_SECRETBOX_NONCEBYTES a
+ Crypto.Secretbox: type Nonce a = SizedByteArray CRYPTO_SECRETBOX_NONCEBYTES a
- Crypto.Secretbox.Internal: type Key a = OfLength CRYPTO_SECRETBOX_KEYBYTES a
+ Crypto.Secretbox.Internal: type Key a = SizedByteArray CRYPTO_SECRETBOX_KEYBYTES a
- Crypto.Secretbox.Internal: type Nonce a = OfLength CRYPTO_SECRETBOX_NONCEBYTES a
+ Crypto.Secretbox.Internal: type Nonce a = SizedByteArray CRYPTO_SECRETBOX_NONCEBYTES a

Files

NaCl.cabal view
@@ -4,11 +4,11 @@ -- -- see: https://github.com/sol/hpack ----- hash: 9b302cb2a6e7e7082c3f24456d474ba10bf82a95d7943fac58e002b7ad793a28+-- hash: 03e840884f33f5935cba7897a47476ae30b4577c0d482ca7f4d75cdad144e7c1  name:           NaCl-version:        0.0.1.0-synopsis:       Easy-and-safe-to-use library for cryptography+version:        0.0.2.0+synopsis:       Easy-and-safe-to-use high-level Haskell bindings to NaCl description:    This library uses <https://libsodium.org Sodium> under the hood,                 but only exposes the primitives that are part of the “classic” NaCl                 interface. We believe, it is better to be paranoid than sorry.@@ -18,9 +18,23 @@                 = Secret-key cryptography                 .                   * Authenticated encryption: "Crypto.Secretbox"+                .+                = Additional primitives+                .+                Sodium is more portable, but some people prefer to stick to NaCl.+                We agree that it is better to be paranoid than sorry.+                That is why, even though this library uses+                Sodium under the hood, it only exposes the primitives that+                are part of the “classic” NaCl interface.+                .+                Sodium provides useful algorithms, that are not part of NaCl,+                for example key derivation or random number generation.+                If you need them too (you probably do), you should use+                <https://hackage.haskell.org/package/crypto-sodium crypto-sodium>+                instead. category:       Cryptography-homepage:       https://github.com/serokell/haskell-nacl#readme-bug-reports:    https://github.com/serokell/haskell-nacl/issues+homepage:       https://github.com/serokell/haskell-crypto#readme+bug-reports:    https://github.com/serokell/haskell-crypto/issues author:         Kirill Elagin <kirelagin@serokell.io> maintainer:     Kirill Elagin <kirelagin@serokell.io> copyright:      2020 Serokell@@ -33,14 +47,12 @@  source-repository head   type: git-  location: https://github.com/serokell/haskell-nacl+  location: https://github.com/serokell/haskell-crypto  library   exposed-modules:       Crypto.Secretbox       Crypto.Secretbox.Internal-      Data.ByteArray.Sized-      Data.ByteArray.Sized.Internal   other-modules:       Paths_NaCl   hs-source-dirs:@@ -52,9 +64,8 @@     , bytestring >=0.9 && <0.11     , gdp >=0.0.0.1 && <0.1     , libsodium >=1.0 && <2-    , memory >=0.1 && <0.16+    , memory >=0.14.15 && <0.16     , safe-exceptions >=0.1 && <0.2-    , text >=0.7 && <1.3   default-language: Haskell2010  test-suite test@@ -79,5 +90,4 @@     , tasty     , tasty-hedgehog     , tasty-hunit-    , text >=0.7 && <1.3   default-language: Haskell2010
README.md view
@@ -1,49 +1,19 @@-# NaCl (`haskell-NaCl`)+# NaCl -Easy-and-safe-to-use library for cryptography.+Easy-and-safe-to-use high-level Haskell bindings to NaCl.  **Note: this package is experimental and WIP.** -Cryptography is hard to do right and you should never try to implement it-on your own, even if you have access to safe and secure cryptographic-primitives. Luckily, D. J. Bernstein created [NaCl].--NaCl was designed specifically to make it hard to use it incorrectly and-thus save your from a disaster. It exposes high-level cryptographic-algorithms with underlying implementations chosen for you, so you do not-get flexibility, but you get security, which is more important.--[Sodium] is a reimplementation of NaCl with the goal to make it more-portable across different platforms. With time, it started providing-not only the same interface as NaCl, the developers of Sodium decided-to add new primitives too.--Sodium is more portable, but some people are afraid of using it,-and prefer to stick to NaCl. We agree that it is better to be-paranoid than sorry. That is why, even though this library uses-Sodium under the hood, it only exposes the primitives that-are part of the “classic” NaCl interface.--[NaCl]: https://nacl.cr.yp.to/-[Sodium]: https://libsodium.org---## Why not?-- ## Use +### Get it -## Contributing+Add [`NaCl`][hackage:NaCl] to the dependencies of your package. -If you encounter any issues when using this library or have improvement ideas,-please open report in issue on GitHub. You are also very welcome to submit-pull request, if you feel like doing so.+### Documentation +All documentation exists is in the form of Haddock comments, you can+find them in the source code or [browse on Hackage][hackage:NaCl]. -## License -[MPL-2.0] © [Serokell]--[MPL-2.0]: https://spdx.org/licenses/MPL-2.0.html-[Serokell]: https://serokell.io/+[hackage:NaCl]: https://hackage.haskell.org/package/NaCl
lib/Crypto/Secretbox.hs view
@@ -2,6 +2,18 @@ -- -- SPDX-License-Identifier: MPL-2.0 +-- | Symmetric authenticated encryption.+--+-- It is best to import this module qualified:+--+-- @+-- import qualified Crypto.Secretbox as Secretbox+--+-- encrypted = Secretbox.'create' key nonce message+-- decrypted = Secretbox.'open' key nonce encrypted+-- @+--+-- This is @crypto_secretbox_*@ from NaCl. module Crypto.Secretbox   ( Key   , toKey@@ -23,31 +35,78 @@  -- | Encrypt a message. ----- Note: This function is similar to the C++ API of NaCl.--- That is, unlike @crypto_secretbox@ from the C API of NaCl,--- it does not require any special padding.+-- @+-- encrypted = Secretbox.create key nonce message+-- @+--+-- *   @key@ is the secret key used for encryption. There are two typical ways+--     of creating it:+--+--     1. /Derive from a password/. If you want to protect a message with a password,+--     you must use a+--     <https://en.wikipedia.org/wiki/Key_derivation_function key derivation function>+--     to turn this password into an encryption key.+--     NaCl does not provide a key derivation function, however+--     <https://hackage.haskell.org/package/crypto-sodium crypto-sodium> does.+--+--     2. /Generate a random one/. This can be useful in certain situations when+--     you want to have an intermediate key that you will encrypt and share+--     later. NaCl does not provide a cryptographically secure pseudo random+--     generator, however+--     <https://hackage.haskell.org/package/crypto-sodium crypto-sodium> does.+--+-- *   @nonce@ is an extra noise that ensures that if you encrypt the same+--     message with the same key multiple times, you will get different ciphertexts,+--     which is required for+--     <https://en.wikipedia.org/wiki/Semantic_security semantic security>.+--     There are two standard ways of getting it:+--+--     1. /Use a counter/. In this case you keep a counter of encrypted messages,+--     which means that the nonce will be new for each new message.+--+--     2. /Random/. You generate a random nonce every time you encrypt a message.+--     Since the nonce is large enough, the chances of you using the same+--     nonce twice are negligible.+--+--     <https://hackage.haskell.org/package/crypto-sodium crypto-sodium> has+--     useful helpers for both options.+--+-- *   @message@ is the data you are encrypting.+--+-- This function adds authentication data, so if anyone modifies the cyphertext,+-- @open@ will refuse to decrypt it. create-  ::  ( ByteArrayAccess key, ByteArrayAccess nonce-      , ByteArrayAccess pt, ByteArray ct+  ::  ( ByteArrayAccess keyBytes, ByteArrayAccess nonceBytes+      , ByteArrayAccess ptBytes, ByteArray ctBytes       )-  => Key key  -- ^ Secret key-  -> Nonce nonce  -- ^ Nonce-  -> pt -- ^ Plaintext message-  -> ct-create key nonce msg = unsafeDupablePerformIO $ I.create key nonce msg+  => Key keyBytes  -- ^ Secret key+  -> Nonce nonceBytes  -- ^ Nonce+  -> ptBytes -- ^ Plaintext message+  -> ctBytes+create key nonce msg =+  -- This IO is safe, because it is pure.+  unsafeDupablePerformIO $ I.create key nonce msg   -- | Decrypt a message. ----- Note: This function is similar to the C++ API of NaCl.--- That is, unlike @crypto_secretbox_open@ from the C API of NaCl,--- it does not require any special padding.+-- @+-- decrypted = Secretbox.open key nonce encrypted+-- @+--+-- * @key@ and @nonce@ are the same that were used for encryption.+-- * @encrypted@ is the output of 'create'.+--+-- This function will return @Nothing@ if the encrypted message was tampered+-- with after it was encrypted. open-  ::  ( ByteArrayAccess key, ByteArrayAccess nonce-      , ByteArray pt, ByteArrayAccess ct+  ::  ( ByteArrayAccess keyBytes, ByteArrayAccess nonceBytes+      , ByteArray ptBytes, ByteArrayAccess ctBytes       )-  => Key key  -- ^ Secret key-  -> Nonce nonce  -- ^ Nonce-  -> ct -- ^ Cyphertext-  -> Maybe pt-open key nonce ct = unsafeDupablePerformIO $ I.open key nonce ct+  => Key keyBytes  -- ^ Secret key+  -> Nonce nonceBytes  -- ^ Nonce+  -> ctBytes -- ^ Encrypted message (cyphertext)+  -> Maybe ptBytes+open key nonce ct =+  -- This IO is safe, because it is pure.+  unsafeDupablePerformIO $ I.open key nonce ct
lib/Crypto/Secretbox/Internal.hs view
@@ -2,6 +2,7 @@ -- -- SPDX-License-Identifier: MPL-2.0 +-- | Internals of @crypto_secretbox@. module Crypto.Secretbox.Internal   ( Key   , toKey@@ -19,7 +20,7 @@  import qualified Libsodium as Na -import Data.ByteArray.Sized (OfLength, hasRightLength)+import Data.ByteArray.Sized (SizedByteArray, sizedByteArray)   -- | Encryption key that can be used for Secretbox.@@ -27,28 +28,28 @@ -- This type is parametrised by the actual data type that contains -- bytes. This can be, for example, a @ByteString@, but, since this -- is a secret key, it is better to use @ScrubbedBytes@.-type Key a = OfLength Na.CRYPTO_SECRETBOX_KEYBYTES a+type Key a = SizedByteArray Na.CRYPTO_SECRETBOX_KEYBYTES a  -- | Make a 'Key' from an arbitrary byte array. -- -- This function returns @Just@ if and only if the byte array has -- the right length to be used as a key with a Secretbox. toKey :: ByteArrayAccess ba => ba -> Maybe (Key ba)-toKey = hasRightLength+toKey = sizedByteArray   -- | Nonce that can be used for Secretbox. -- -- This type is parametrised by the actual data type that contains -- bytes. This can be, for example, a @ByteString@.-type Nonce a = OfLength Na.CRYPTO_SECRETBOX_NONCEBYTES a+type Nonce a = SizedByteArray Na.CRYPTO_SECRETBOX_NONCEBYTES a  -- | Make a 'Nonce' from an arbitrary byte array. -- -- This function returns @Just@ if and only if the byte array has -- the right length to be used as a nonce with a Secretbox. toNonce :: ByteArrayAccess ba => ba -> Maybe (Nonce ba)-toNonce = hasRightLength+toNonce = sizedByteArray   -- | Encrypt a message.
− lib/Data/ByteArray/Sized.hs
@@ -1,10 +0,0 @@--- SPDX-FileCopyrightText: 2020 Serokell------ SPDX-License-Identifier: MPL-2.0---- | 'ByteArray' with length known at compile time.-module Data.ByteArray.Sized-  ( module M-  ) where--import Data.ByteArray.Sized.Internal as M (OfLength, hasRightLength)
− lib/Data/ByteArray/Sized/Internal.hs
@@ -1,63 +0,0 @@--- SPDX-FileCopyrightText: 2020 Serokell------ SPDX-License-Identifier: MPL-2.0---- | 'ByteArray' with length known at compile time. Internal module.-module Data.ByteArray.Sized.Internal-  ( OfLength (..)-  , hasRightLength--  , allocRet-  , alloc-  ) where--import Prelude hiding (length)--import Data.Bifunctor (second)-import Data.Proxy (Proxy (Proxy))-import Data.The (The)-import Foreign.Ptr (Ptr)-import GHC.TypeLits (KnownNat, Nat, natVal)--import Data.ByteArray (ByteArray, ByteArrayAccess, length)--import qualified Data.ByteArray----- Type of byte arrays that have length @l@.-newtype OfLength (l :: Nat) ba = OfLength ba-  deriving (ByteArrayAccess, Eq, Monoid, Ord, Semigroup)--instance The (OfLength l ba) ba----- | Check that the byte array has the given length.-hasRightLength-  :: forall ba n. (ByteArrayAccess ba, KnownNat n)-  => ba-  -> Maybe (OfLength n ba)-hasRightLength ba-  | fromIntegral (length ba) == natVal (Proxy :: Proxy n) = Just $ OfLength ba-  | otherwise = Nothing---- | Allocate a new byte array of the given length, and perform the given operation.------ This is the same as 'Data.ByteArray.allocRet'.-allocRet-  :: forall ba n p a. (ByteArray ba, KnownNat n)-  => (Ptr p -> IO a)-  -> IO (a, OfLength n ba)-allocRet-  = fmap (second OfLength)-  . Data.ByteArray.allocRet (fromIntegral $ natVal (Proxy :: Proxy n))---- | Allocate a new byte array of the given length, and run the initialiser.------ This is the same as 'Data.ByteArray.alloc'.-alloc-  :: forall ba n p. (ByteArray ba, KnownNat n)-  => (Ptr p -> IO ())-  -> IO (OfLength n ba)-alloc-  = fmap OfLength-  . Data.ByteArray.alloc (fromIntegral $ natVal (Proxy :: Proxy n))
test/Test.hs view
test/Test/Crypto/Secretbox.hs view