{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric, ForeignFunctionInterface #-} -- | -- Module : Crypto.Saltine.Internal.ScalarMult -- Copyright : (c) Max Amanshauser 2021 -- License : MIT -- -- Maintainer : max@lambdalifting.org -- Stability : experimental -- Portability : non-portable -- module Crypto.Saltine.Internal.ScalarMult ( scalarmult_bytes , scalarmult_scalarbytes , c_scalarmult , c_scalarmult_base , GroupElement(..) , Scalar(..) ) where import Control.DeepSeq import Crypto.Saltine.Class import Crypto.Saltine.Internal.Util as U import Data.ByteString (ByteString) import Data.Data (Data, Typeable) import Data.Hashable (Hashable) import Foreign.C import Foreign.Ptr import GHC.Generics (Generic) import qualified Data.ByteString as S -- | A group element. newtype GroupElement = GE { unGE :: ByteString } deriving (Eq, Ord, Hashable, Data, Typeable, Generic, NFData) instance Show GroupElement where show = bin2hex . encode instance IsEncoding GroupElement where decode v = if S.length v == scalarmult_bytes then Just (GE v) else Nothing {-# INLINE decode #-} encode (GE v) = v {-# INLINE encode #-} -- | A scalar integer. newtype Scalar = Sc { unSc :: ByteString } deriving (Eq, Ord, Hashable, Data, Typeable, Generic, NFData) instance Show Scalar where show = bin2hex . encode instance IsEncoding Scalar where decode v = if S.length v == scalarmult_scalarbytes then Just (Sc v) else Nothing {-# INLINE decode #-} encode (Sc v) = v {-# INLINE encode #-} scalarmult_bytes, scalarmult_scalarbytes :: Int -- ScalarMult -- | Size of a group element string representation for -- @crypto_scalarmult@. scalarmult_bytes = fromIntegral c_crypto_scalarmult_bytes -- | Size of a integer string representation for @crypto_scalarmult@. scalarmult_scalarbytes = fromIntegral c_crypto_scalarmult_scalarbytes -- src/libsodium/crypto_scalarmult/crypto_scalarmult.c foreign import ccall "crypto_scalarmult_bytes" c_crypto_scalarmult_bytes :: CSize foreign import ccall "crypto_scalarmult_scalarbytes" c_crypto_scalarmult_scalarbytes :: CSize 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 foreign import ccall "crypto_scalarmult_base" c_scalarmult_base :: Ptr CChar -- ^ Output group element buffer -> Ptr CChar -- ^ Input integer buffer -> IO CInt -- ^ Always 0