-- SPDX-FileCopyrightText: 2022 Serokell <https://serokell.io>
-- SPDX-License-Identifier: MPL-2.0

{-# OPTIONS_HADDOCK not-home #-}

-- | Types for lower-level bindings
module Crypto.BLST.Internal.Bindings.Types
  ( module Crypto.BLST.Internal.Bindings.Types
  ) where

import Prelude hiding (length)

import Control.DeepSeq (NFData(..))
import Data.ByteArray (Bytes, ScrubbedBytes)
import Data.ByteArray.Sized (SizedByteArray(..))
import Data.Coerce (coerce)
import Data.Kind (Type)
import GHC.TypeNats (Nat)

import Crypto.BLST.Internal.Demote

-- | Kind of point.
data PointKind = P1 | P2

instance Demote 'P1 where demote :: PointKind
demote = PointKind
P1
instance Demote 'P2 where demote :: PointKind
demote = PointKind
P2

-- | Size of type's representation in bytes.
type SizeOf :: Type -> Nat
type family SizeOf t

-- | Point representation.
newtype Point (a :: PointKind) = Point ( SizedByteArray (SizeOf (Point a)) Bytes )
  deriving stock (Int -> Point a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (a :: PointKind). Int -> Point a -> ShowS
forall (a :: PointKind). [Point a] -> ShowS
forall (a :: PointKind). Point a -> String
showList :: [Point a] -> ShowS
$cshowList :: forall (a :: PointKind). [Point a] -> ShowS
show :: Point a -> String
$cshow :: forall (a :: PointKind). Point a -> String
showsPrec :: Int -> Point a -> ShowS
$cshowsPrec :: forall (a :: PointKind). Int -> Point a -> ShowS
Show, Point a -> Point a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (a :: PointKind). Point a -> Point a -> Bool
/= :: Point a -> Point a -> Bool
$c/= :: forall (a :: PointKind). Point a -> Point a -> Bool
== :: Point a -> Point a -> Bool
$c== :: forall (a :: PointKind). Point a -> Point a -> Bool
Eq)

instance NFData (Point a) where
  rnf :: Point a -> ()
rnf = forall a. NFData a => a -> ()
rnf @Bytes forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) ba. SizedByteArray n ba -> ba
unSizedByteArray forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

-- | Affine point representation.
newtype Affine (a :: PointKind) = Affine { forall (a :: PointKind).
Affine a -> SizedByteArray (SizeOf (Affine a)) Bytes
unAffine :: SizedByteArray (SizeOf (Affine a)) Bytes }
  deriving stock (Int -> Affine a -> ShowS
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (a :: PointKind). Int -> Affine a -> ShowS
forall (a :: PointKind). [Affine a] -> ShowS
forall (a :: PointKind). Affine a -> String
showList :: [Affine a] -> ShowS
$cshowList :: forall (a :: PointKind). [Affine a] -> ShowS
show :: Affine a -> String
$cshow :: forall (a :: PointKind). Affine a -> String
showsPrec :: Int -> Affine a -> ShowS
$cshowsPrec :: forall (a :: PointKind). Int -> Affine a -> ShowS
Show, Affine a -> Affine a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (a :: PointKind). Affine a -> Affine a -> Bool
/= :: Affine a -> Affine a -> Bool
$c/= :: forall (a :: PointKind). Affine a -> Affine a -> Bool
== :: Affine a -> Affine a -> Bool
$c== :: forall (a :: PointKind). Affine a -> Affine a -> Bool
Eq)

instance NFData (Affine a) where
  rnf :: Affine a -> ()
rnf = forall a. NFData a => a -> ()
rnf @Bytes forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) ba. SizedByteArray n ba -> ba
unSizedByteArray forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

-- | Scalar value representation.
newtype Scalar = Scalar ( SizedByteArray (SizeOf Scalar) ScrubbedBytes )
  deriving stock (Int -> Scalar -> ShowS
[Scalar] -> ShowS
Scalar -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Scalar] -> ShowS
$cshowList :: [Scalar] -> ShowS
show :: Scalar -> String
$cshow :: Scalar -> String
showsPrec :: Int -> Scalar -> ShowS
$cshowsPrec :: Int -> Scalar -> ShowS
Show, Scalar -> Scalar -> Bool
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)

instance NFData Scalar where
  rnf :: Scalar -> ()
rnf = forall a. NFData a => a -> ()
rnf @ScrubbedBytes forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (n :: Nat) ba. SizedByteArray n ba -> ba
unSizedByteArray forall b c a. (b -> c) -> (a -> b) -> a -> c
. coerce :: forall a b. Coercible a b => a -> b
coerce

-- | Pairing context.
newtype PairingCtx = PairingCtx Bytes
  deriving newtype PairingCtx -> ()
forall a. (a -> ()) -> NFData a
rnf :: PairingCtx -> ()
$crnf :: PairingCtx -> ()
NFData

-- | Flag to choose whether values are hashed or encoded to the curve.
data EncodeMethod = Encode | Hash
  deriving stock (EncodeMethod -> EncodeMethod -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: EncodeMethod -> EncodeMethod -> Bool
$c/= :: EncodeMethod -> EncodeMethod -> Bool
== :: EncodeMethod -> EncodeMethod -> Bool
$c== :: EncodeMethod -> EncodeMethod -> Bool
Eq, Int -> EncodeMethod
EncodeMethod -> Int
EncodeMethod -> [EncodeMethod]
EncodeMethod -> EncodeMethod
EncodeMethod -> EncodeMethod -> [EncodeMethod]
EncodeMethod -> EncodeMethod -> EncodeMethod -> [EncodeMethod]
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: EncodeMethod -> EncodeMethod -> EncodeMethod -> [EncodeMethod]
$cenumFromThenTo :: EncodeMethod -> EncodeMethod -> EncodeMethod -> [EncodeMethod]
enumFromTo :: EncodeMethod -> EncodeMethod -> [EncodeMethod]
$cenumFromTo :: EncodeMethod -> EncodeMethod -> [EncodeMethod]
enumFromThen :: EncodeMethod -> EncodeMethod -> [EncodeMethod]
$cenumFromThen :: EncodeMethod -> EncodeMethod -> [EncodeMethod]
enumFrom :: EncodeMethod -> [EncodeMethod]
$cenumFrom :: EncodeMethod -> [EncodeMethod]
fromEnum :: EncodeMethod -> Int
$cfromEnum :: EncodeMethod -> Int
toEnum :: Int -> EncodeMethod
$ctoEnum :: Int -> EncodeMethod
pred :: EncodeMethod -> EncodeMethod
$cpred :: EncodeMethod -> EncodeMethod
succ :: EncodeMethod -> EncodeMethod
$csucc :: EncodeMethod -> EncodeMethod
Enum, EncodeMethod
forall a. a -> a -> Bounded a
maxBound :: EncodeMethod
$cmaxBound :: EncodeMethod
minBound :: EncodeMethod
$cminBound :: EncodeMethod
Bounded, Int -> EncodeMethod -> ShowS
[EncodeMethod] -> ShowS
EncodeMethod -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [EncodeMethod] -> ShowS
$cshowList :: [EncodeMethod] -> ShowS
show :: EncodeMethod -> String
$cshow :: EncodeMethod -> String
showsPrec :: Int -> EncodeMethod -> ShowS
$cshowsPrec :: Int -> EncodeMethod -> ShowS
Show)

instance Demote 'Hash where demote :: EncodeMethod
demote = EncodeMethod
Hash
instance Demote 'Encode where demote :: EncodeMethod
demote = EncodeMethod
Encode

-- | Serialized size of 'P1'.
type P1SerializeSize = 96

-- | Compressed serialized size of 'P1'.
type P1CompressSize = 48

-- | Serialized size of 'P2'.
type P2SerializeSize = 192

-- | Compressed serialized size of 'P2'.
type P2CompressSize = 96

-- | Scalar serialized size.
type SkSerializeSize = 32