{-# 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 { GroupElement -> ByteString
unGE :: ByteString } deriving (GroupElement -> GroupElement -> Bool
(GroupElement -> GroupElement -> Bool)
-> (GroupElement -> GroupElement -> Bool) -> Eq GroupElement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GroupElement -> GroupElement -> Bool
$c/= :: GroupElement -> GroupElement -> Bool
== :: GroupElement -> GroupElement -> Bool
$c== :: GroupElement -> GroupElement -> Bool
Eq, Eq GroupElement
Eq GroupElement
-> (GroupElement -> GroupElement -> Ordering)
-> (GroupElement -> GroupElement -> Bool)
-> (GroupElement -> GroupElement -> Bool)
-> (GroupElement -> GroupElement -> Bool)
-> (GroupElement -> GroupElement -> Bool)
-> (GroupElement -> GroupElement -> GroupElement)
-> (GroupElement -> GroupElement -> GroupElement)
-> Ord GroupElement
GroupElement -> GroupElement -> Bool
GroupElement -> GroupElement -> Ordering
GroupElement -> GroupElement -> GroupElement
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: GroupElement -> GroupElement -> GroupElement
$cmin :: GroupElement -> GroupElement -> GroupElement
max :: GroupElement -> GroupElement -> GroupElement
$cmax :: GroupElement -> GroupElement -> GroupElement
>= :: GroupElement -> GroupElement -> Bool
$c>= :: GroupElement -> GroupElement -> Bool
> :: GroupElement -> GroupElement -> Bool
$c> :: GroupElement -> GroupElement -> Bool
<= :: GroupElement -> GroupElement -> Bool
$c<= :: GroupElement -> GroupElement -> Bool
< :: GroupElement -> GroupElement -> Bool
$c< :: GroupElement -> GroupElement -> Bool
compare :: GroupElement -> GroupElement -> Ordering
$ccompare :: GroupElement -> GroupElement -> Ordering
$cp1Ord :: Eq GroupElement
Ord, Int -> GroupElement -> Int
GroupElement -> Int
(Int -> GroupElement -> Int)
-> (GroupElement -> Int) -> Hashable GroupElement
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: GroupElement -> Int
$chash :: GroupElement -> Int
hashWithSalt :: Int -> GroupElement -> Int
$chashWithSalt :: Int -> GroupElement -> Int
Hashable, Typeable GroupElement
DataType
Constr
Typeable GroupElement
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> GroupElement -> c GroupElement)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c GroupElement)
-> (GroupElement -> Constr)
-> (GroupElement -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c GroupElement))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e))
    -> Maybe (c GroupElement))
-> ((forall b. Data b => b -> b) -> GroupElement -> GroupElement)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> GroupElement -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> GroupElement -> r)
-> (forall u. (forall d. Data d => d -> u) -> GroupElement -> [u])
-> (forall u.
    Int -> (forall d. Data d => d -> u) -> GroupElement -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> GroupElement -> m GroupElement)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> GroupElement -> m GroupElement)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> GroupElement -> m GroupElement)
-> Data GroupElement
GroupElement -> DataType
GroupElement -> Constr
(forall b. Data b => b -> b) -> GroupElement -> GroupElement
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> GroupElement -> c GroupElement
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c GroupElement
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> GroupElement -> u
forall u. (forall d. Data d => d -> u) -> GroupElement -> [u]
forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> GroupElement -> r
forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> GroupElement -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> GroupElement -> m GroupElement
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> GroupElement -> m GroupElement
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c GroupElement
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> GroupElement -> c GroupElement
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c GroupElement)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c GroupElement)
$cGE :: Constr
$tGroupElement :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> GroupElement -> m GroupElement
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> GroupElement -> m GroupElement
gmapMp :: (forall d. Data d => d -> m d) -> GroupElement -> m GroupElement
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> GroupElement -> m GroupElement
gmapM :: (forall d. Data d => d -> m d) -> GroupElement -> m GroupElement
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> GroupElement -> m GroupElement
gmapQi :: Int -> (forall d. Data d => d -> u) -> GroupElement -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> GroupElement -> u
gmapQ :: (forall d. Data d => d -> u) -> GroupElement -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> GroupElement -> [u]
gmapQr :: (r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> GroupElement -> r
$cgmapQr :: forall r r'.
(r' -> r -> r)
-> r -> (forall d. Data d => d -> r') -> GroupElement -> r
gmapQl :: (r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> GroupElement -> r
$cgmapQl :: forall r r'.
(r -> r' -> r)
-> r -> (forall d. Data d => d -> r') -> GroupElement -> r
gmapT :: (forall b. Data b => b -> b) -> GroupElement -> GroupElement
$cgmapT :: (forall b. Data b => b -> b) -> GroupElement -> GroupElement
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c GroupElement)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e))
-> Maybe (c GroupElement)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c GroupElement)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c GroupElement)
dataTypeOf :: GroupElement -> DataType
$cdataTypeOf :: GroupElement -> DataType
toConstr :: GroupElement -> Constr
$ctoConstr :: GroupElement -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c GroupElement
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c GroupElement
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> GroupElement -> c GroupElement
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> GroupElement -> c GroupElement
$cp1Data :: Typeable GroupElement
Data, Typeable, (forall x. GroupElement -> Rep GroupElement x)
-> (forall x. Rep GroupElement x -> GroupElement)
-> Generic GroupElement
forall x. Rep GroupElement x -> GroupElement
forall x. GroupElement -> Rep GroupElement x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep GroupElement x -> GroupElement
$cfrom :: forall x. GroupElement -> Rep GroupElement x
Generic, GroupElement -> ()
(GroupElement -> ()) -> NFData GroupElement
forall a. (a -> ()) -> NFData a
rnf :: GroupElement -> ()
$crnf :: GroupElement -> ()
NFData)
instance Show GroupElement where
    show :: GroupElement -> String
show = ByteString -> String
bin2hex (ByteString -> String)
-> (GroupElement -> ByteString) -> GroupElement -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. GroupElement -> ByteString
forall a. IsEncoding a => a -> ByteString
encode

instance IsEncoding GroupElement where
  decode :: ByteString -> Maybe GroupElement
decode ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
scalarmult_bytes
           then GroupElement -> Maybe GroupElement
forall a. a -> Maybe a
Just (ByteString -> GroupElement
GE ByteString
v)
           else Maybe GroupElement
forall a. Maybe a
Nothing
  {-# INLINE decode #-}
  encode :: GroupElement -> ByteString
encode (GE ByteString
v) = ByteString
v
  {-# INLINE encode #-}

-- | A scalar integer.
newtype Scalar       = Sc { Scalar -> ByteString
unSc :: ByteString } deriving (Scalar -> Scalar -> Bool
(Scalar -> Scalar -> Bool)
-> (Scalar -> Scalar -> Bool) -> Eq Scalar
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Scalar -> Scalar -> Bool
$c/= :: Scalar -> Scalar -> Bool
== :: Scalar -> Scalar -> Bool
$c== :: Scalar -> Scalar -> Bool
Eq, Eq Scalar
Eq Scalar
-> (Scalar -> Scalar -> Ordering)
-> (Scalar -> Scalar -> Bool)
-> (Scalar -> Scalar -> Bool)
-> (Scalar -> Scalar -> Bool)
-> (Scalar -> Scalar -> Bool)
-> (Scalar -> Scalar -> Scalar)
-> (Scalar -> Scalar -> Scalar)
-> Ord Scalar
Scalar -> Scalar -> Bool
Scalar -> Scalar -> Ordering
Scalar -> Scalar -> Scalar
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Scalar -> Scalar -> Scalar
$cmin :: Scalar -> Scalar -> Scalar
max :: Scalar -> Scalar -> Scalar
$cmax :: Scalar -> Scalar -> Scalar
>= :: Scalar -> Scalar -> Bool
$c>= :: Scalar -> Scalar -> Bool
> :: Scalar -> Scalar -> Bool
$c> :: Scalar -> Scalar -> Bool
<= :: Scalar -> Scalar -> Bool
$c<= :: Scalar -> Scalar -> Bool
< :: Scalar -> Scalar -> Bool
$c< :: Scalar -> Scalar -> Bool
compare :: Scalar -> Scalar -> Ordering
$ccompare :: Scalar -> Scalar -> Ordering
$cp1Ord :: Eq Scalar
Ord, Int -> Scalar -> Int
Scalar -> Int
(Int -> Scalar -> Int) -> (Scalar -> Int) -> Hashable Scalar
forall a. (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: Scalar -> Int
$chash :: Scalar -> Int
hashWithSalt :: Int -> Scalar -> Int
$chashWithSalt :: Int -> Scalar -> Int
Hashable, Typeable Scalar
DataType
Constr
Typeable Scalar
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Scalar -> c Scalar)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Scalar)
-> (Scalar -> Constr)
-> (Scalar -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Scalar))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Scalar))
-> ((forall b. Data b => b -> b) -> Scalar -> Scalar)
-> (forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Scalar -> r)
-> (forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Scalar -> r)
-> (forall u. (forall d. Data d => d -> u) -> Scalar -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> Scalar -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Scalar -> m Scalar)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Scalar -> m Scalar)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Scalar -> m Scalar)
-> Data Scalar
Scalar -> DataType
Scalar -> Constr
(forall b. Data b => b -> b) -> Scalar -> Scalar
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Scalar -> c Scalar
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Scalar
forall a.
Typeable a
-> (forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> a -> c a)
-> (forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c a)
-> (a -> Constr)
-> (a -> DataType)
-> (forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c a))
-> (forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
-> ((forall b. Data b => b -> b) -> a -> a)
-> (forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
-> (forall u. (forall d. Data d => d -> u) -> a -> [u])
-> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
-> (forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> (forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> a -> m a)
-> Data a
forall u. Int -> (forall d. Data d => d -> u) -> Scalar -> u
forall u. (forall d. Data d => d -> u) -> Scalar -> [u]
forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Scalar -> r
forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Scalar -> r
forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Scalar -> m Scalar
forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scalar -> m Scalar
forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Scalar
forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Scalar -> c Scalar
forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Scalar)
forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Scalar)
$cSc :: Constr
$tScalar :: DataType
gmapMo :: (forall d. Data d => d -> m d) -> Scalar -> m Scalar
$cgmapMo :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scalar -> m Scalar
gmapMp :: (forall d. Data d => d -> m d) -> Scalar -> m Scalar
$cgmapMp :: forall (m :: * -> *).
MonadPlus m =>
(forall d. Data d => d -> m d) -> Scalar -> m Scalar
gmapM :: (forall d. Data d => d -> m d) -> Scalar -> m Scalar
$cgmapM :: forall (m :: * -> *).
Monad m =>
(forall d. Data d => d -> m d) -> Scalar -> m Scalar
gmapQi :: Int -> (forall d. Data d => d -> u) -> Scalar -> u
$cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Scalar -> u
gmapQ :: (forall d. Data d => d -> u) -> Scalar -> [u]
$cgmapQ :: forall u. (forall d. Data d => d -> u) -> Scalar -> [u]
gmapQr :: (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Scalar -> r
$cgmapQr :: forall r r'.
(r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Scalar -> r
gmapQl :: (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Scalar -> r
$cgmapQl :: forall r r'.
(r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Scalar -> r
gmapT :: (forall b. Data b => b -> b) -> Scalar -> Scalar
$cgmapT :: (forall b. Data b => b -> b) -> Scalar -> Scalar
dataCast2 :: (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Scalar)
$cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
Typeable t =>
(forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Scalar)
dataCast1 :: (forall d. Data d => c (t d)) -> Maybe (c Scalar)
$cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
Typeable t =>
(forall d. Data d => c (t d)) -> Maybe (c Scalar)
dataTypeOf :: Scalar -> DataType
$cdataTypeOf :: Scalar -> DataType
toConstr :: Scalar -> Constr
$ctoConstr :: Scalar -> Constr
gunfold :: (forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Scalar
$cgunfold :: forall (c :: * -> *).
(forall b r. Data b => c (b -> r) -> c r)
-> (forall r. r -> c r) -> Constr -> c Scalar
gfoldl :: (forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Scalar -> c Scalar
$cgfoldl :: forall (c :: * -> *).
(forall d b. Data d => c (d -> b) -> d -> c b)
-> (forall g. g -> c g) -> Scalar -> c Scalar
$cp1Data :: Typeable Scalar
Data, Typeable, (forall x. Scalar -> Rep Scalar x)
-> (forall x. Rep Scalar x -> Scalar) -> Generic Scalar
forall x. Rep Scalar x -> Scalar
forall x. Scalar -> Rep Scalar x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Scalar x -> Scalar
$cfrom :: forall x. Scalar -> Rep Scalar x
Generic, Scalar -> ()
(Scalar -> ()) -> NFData Scalar
forall a. (a -> ()) -> NFData a
rnf :: Scalar -> ()
$crnf :: Scalar -> ()
NFData)
instance Show Scalar where
    show :: Scalar -> String
show = ByteString -> String
bin2hex (ByteString -> String)
-> (Scalar -> ByteString) -> Scalar -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Scalar -> ByteString
forall a. IsEncoding a => a -> ByteString
encode

instance IsEncoding Scalar where
  decode :: ByteString -> Maybe Scalar
decode ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
scalarmult_scalarbytes
           then Scalar -> Maybe Scalar
forall a. a -> Maybe a
Just (ByteString -> Scalar
Sc ByteString
v)
           else Maybe Scalar
forall a. Maybe a
Nothing
  {-# INLINE decode #-}
  encode :: Scalar -> ByteString
encode (Sc ByteString
v) = ByteString
v
  {-# INLINE encode #-}


scalarmult_bytes, scalarmult_scalarbytes :: Int

-- ScalarMult
-- | Size of a group element string representation for
-- @crypto_scalarmult@.
scalarmult_bytes :: Int
scalarmult_bytes = CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
c_crypto_scalarmult_bytes
-- | Size of a integer string representation for @crypto_scalarmult@.
scalarmult_scalarbytes :: Int
scalarmult_scalarbytes = CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
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