saltine-0.2.2.0: src/Crypto/Saltine/Internal/Stream.hs
{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric, ForeignFunctionInterface #-}
-- |
-- Module : Crypto.Saltine.Internal.Stream
-- Copyright : (c) Max Amanshauser 2021
-- License : MIT
--
-- Maintainer : max@lambdalifting.org
-- Stability : experimental
-- Portability : non-portable
--
module Crypto.Saltine.Internal.Stream (
stream_keybytes
, stream_noncebytes
, c_stream
, c_stream_xor
, Key(..)
, Nonce(..)
) where
import Control.DeepSeq (NFData)
import Crypto.Saltine.Class
import Crypto.Saltine.Core.Hash (shorthash)
import Crypto.Saltine.Internal.Hash (nullShKey)
import Crypto.Saltine.Internal.Util as U
import Data.ByteString (ByteString)
import Data.Data (Data, Typeable)
import Data.Hashable (Hashable)
import Data.Monoid
import Foreign.C
import Foreign.Ptr
import GHC.Generics (Generic)
import qualified Data.ByteString as S
-- | An opaque 'stream' cryptographic key.
newtype Key = Key { unKey :: ByteString } deriving (Ord, Hashable, Data, Typeable, Generic, NFData)
instance Eq Key where
Key a == Key b = U.compare a b
instance Show Key where
show k = "Stream.Key {hashesTo = \"" <> (bin2hex . shorthash nullShKey $ encode k) <> "\"}"
instance IsEncoding Key where
decode v = if S.length v == stream_keybytes
then Just (Key v)
else Nothing
{-# INLINE decode #-}
encode (Key v) = v
{-# INLINE encode #-}
-- | An opaque 'stream' nonce.
newtype Nonce = Nonce { unNonce :: ByteString } deriving (Eq, Ord, Hashable, Data, Typeable, Generic, NFData)
instance Show Nonce where
show k = "Stream.Nonce " <> bin2hex (encode k)
instance IsNonce Nonce where
zero = Nonce (S.replicate stream_noncebytes 0)
nudge (Nonce n) = Nonce (nudgeBS n)
instance IsEncoding Nonce where
decode v = if S.length v == stream_noncebytes
then Just (Nonce v)
else Nothing
{-# INLINE decode #-}
encode (Nonce v) = v
{-# INLINE encode #-}
stream_keybytes, stream_noncebytes :: Int
-- Streams
-- | The size of a key for the cryptographic stream generation
stream_keybytes = fromIntegral c_crypto_stream_keybytes
-- | The size of a nonce for the cryptographic stream generation
stream_noncebytes = fromIntegral c_crypto_stream_noncebytes
-- src/libsodium/crypto_stream/crypto_stream.c
-- src/libsodium/include/sodium/crypto_stream.h
foreign import ccall "crypto_stream_keybytes"
c_crypto_stream_keybytes :: CSize
foreign import ccall "crypto_stream_noncebytes"
c_crypto_stream_noncebytes :: CSize
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
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