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 +21/−11
- README.md +8/−38
- lib/Crypto/Secretbox.hs +79/−20
- lib/Crypto/Secretbox/Internal.hs +6/−5
- lib/Data/ByteArray/Sized.hs +0/−10
- lib/Data/ByteArray/Sized/Internal.hs +0/−63
- test/Test.hs +0/−0
- test/Test/Crypto/Secretbox.hs +0/−0
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