{-# LANGUAGE DeriveDataTypeable, GeneralizedNewtypeDeriving, DeriveGeneric #-}

-- |
-- Module      : Crypto.Saltine.Core.ScalarMult
-- Copyright   : (c) Joseph Abrahamson 2013
-- License     : MIT
--
-- Maintainer  : me@jspha.com
-- Stability   : experimental
-- Portability : non-portable
--
-- Scalar multiplication: "Crypto.Saltine.Core.ScalarMult"
--
-- The 'mult' function multiplies a group element by an integer of
-- length 'Bytes.multScalar'. It returns the resulting group element
-- of length 'Bytes.mult'. The 'multBase' function multiplies a
-- standard group element by an integer of length
-- 'Bytes.multScalar'. It returns the resulting group element of
-- length 'Bytes.mult'.
--
-- The correspondence between strings and group elements depends on
-- the primitive implemented by 'mult'. The correspondence is not
-- necessarily injective in either direction, but it is compatible
-- with scalar multiplication in the group. The correspondence does
-- not necessarily include all group elements, but it does include all
-- strings; i.e., every string represents at least one group element.
--
-- The correspondence between strings and integers also depends on the
-- primitive implemented by 'mult'. Every string represents at least
-- one integer.
--
-- 'mult' is designed to be strong as a component of various
-- well-known \"hashed Diffie–Hellman\" applications. In particular,
-- it is designed to make the \"computational Diffie–Hellman\" problem
-- (CDH) difficult with respect to the standard base. 'mult' is also
-- designed to make CDH difficult with respect to other nontrivial
-- bases. In particular, if a represented group element has small
-- order, then it is annihilated by all represented scalars. This
-- feature allows protocols to avoid validating membership in the
-- subgroup generated by the standard base.
--
-- NaCl does not make any promises regarding the \"decisional
-- Diffie–Hellman\" problem (DDH), the \"static Diffie–Hellman\"
-- problem (SDH), etc. Users are responsible for hashing group
-- elements.
--
-- 'mult' is the function @crypto_scalarmult_curve25519@ specified in
-- \"Cryptography in NaCl\", Sections 2, 3, and 4
-- (<http://nacl.cr.yp.to/valid.html>). This function is conjectured
-- to be strong. For background see Bernstein, \"Curve25519: new
-- Diffie-Hellman speed records,\" Lecture Notes in Computer Science
-- 3958 (2006), 207–228, <http://cr.yp.to/papers.html#curve25519>.
--
-- This is version 2010.08.30 of the scalarmult.html web page.
module Crypto.Saltine.Core.ScalarMult (
  Scalar, GroupElement,
  mult, multBase
  ) where

import           Crypto.Saltine.Class
import           Crypto.Saltine.Internal.Util
import qualified Crypto.Saltine.Internal.ByteSizes as Bytes

import           Foreign.C
import           Foreign.Ptr
import qualified Data.ByteString                   as S
import           Data.ByteString                     (ByteString)
import           Data.Hashable (Hashable)
import           Data.Data (Data, Typeable)
import           GHC.Generics (Generic)

-- $types

-- | A group element.
newtype GroupElement = GE 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)

-- | A scalar integer.
newtype Scalar       = Sc 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)

instance IsEncoding GroupElement where
  decode :: ByteString -> Maybe GroupElement
decode v :: ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
Bytes.mult
           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 v :: ByteString
v) = ByteString
v
  {-# INLINE encode #-}

instance IsEncoding Scalar where
  decode :: ByteString -> Maybe Scalar
decode v :: ByteString
v = if ByteString -> Int
S.length ByteString
v Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
Bytes.multScalar
           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 v :: ByteString
v) = ByteString
v
  {-# INLINE encode #-}

mult :: Scalar -> GroupElement -> GroupElement
mult :: Scalar -> GroupElement -> GroupElement
mult (Sc n :: ByteString
n) (GE p :: ByteString
p) = ByteString -> GroupElement
GE (ByteString -> GroupElement)
-> ((Ptr CChar -> IO CInt) -> ByteString)
-> (Ptr CChar -> IO CInt)
-> GroupElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CInt, ByteString) -> ByteString
forall a b. (a, b) -> b
snd ((CInt, ByteString) -> ByteString)
-> ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt)
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> (b, ByteString)
buildUnsafeByteString Int
Bytes.mult ((Ptr CChar -> IO CInt) -> GroupElement)
-> (Ptr CChar -> IO CInt) -> GroupElement
forall a b. (a -> b) -> a -> b
$ \pq :: Ptr CChar
pq ->
  [ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
n, ByteString
p] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \[(pn :: Ptr CChar
pn, _), (pp :: Ptr CChar
pp, _)] ->
    Ptr CChar -> Ptr CChar -> Ptr CChar -> IO CInt
c_scalarmult Ptr CChar
pq Ptr CChar
pn Ptr CChar
pp

multBase :: Scalar -> GroupElement
multBase :: Scalar -> GroupElement
multBase (Sc n :: ByteString
n) = ByteString -> GroupElement
GE (ByteString -> GroupElement)
-> ((Ptr CChar -> IO CInt) -> ByteString)
-> (Ptr CChar -> IO CInt)
-> GroupElement
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (CInt, ByteString) -> ByteString
forall a b. (a, b) -> b
snd ((CInt, ByteString) -> ByteString)
-> ((Ptr CChar -> IO CInt) -> (CInt, ByteString))
-> (Ptr CChar -> IO CInt)
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> (Ptr CChar -> IO CInt) -> (CInt, ByteString)
forall b. Int -> (Ptr CChar -> IO b) -> (b, ByteString)
buildUnsafeByteString Int
Bytes.mult ((Ptr CChar -> IO CInt) -> GroupElement)
-> (Ptr CChar -> IO CInt) -> GroupElement
forall a b. (a -> b) -> a -> b
$ \pq :: Ptr CChar
pq ->
  [ByteString] -> ([CStringLen] -> IO CInt) -> IO CInt
forall b. [ByteString] -> ([CStringLen] -> IO b) -> IO b
constByteStrings [ByteString
n] (([CStringLen] -> IO CInt) -> IO CInt)
-> ([CStringLen] -> IO CInt) -> IO CInt
forall a b. (a -> b) -> a -> b
$ \[(pn :: Ptr CChar
pn, _)] ->
    Ptr CChar -> Ptr CChar -> IO CInt
c_scalarmult_base Ptr CChar
pq Ptr CChar
pn

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