module Plutarch.Builtin.BLS (
  PBuiltinBLS12_381_G1_Element (PBuiltinBLS12_381_G1_Element),
  PBuiltinBLS12_381_G2_Element (PBuiltinBLS12_381_G2_Element),
  PBuiltinBLS12_381_MlResult (PBuiltinBLS12_381_MlResult),
  pbls12_381_G1_add,
  pbls12_381_G1_scalarMul,
  pbls12_381_G1_neg,
  pbls12_381_G1_compress,
  pbls12_381_G1_uncompress,
  pbls12_381_G1_hashToGroup,
  pbls12_381_G1_compressed_zero,
  pbls12_381_G1_compressed_generator,
  pbls12_381_G2_add,
  pbls12_381_G2_scalarMul,
  pbls12_381_G2_neg,
  pbls12_381_G2_compress,
  pbls12_381_G2_uncompress,
  pbls12_381_G2_hashToGroup,
  pbls12_381_G2_compressed_zero,
  pbls12_381_G2_compressed_generator,
  pbls12_381_millerLoop,
  pbls12_381_mulMlResult,
  pbls12_381_finalVerify,
) where

import GHC.Generics (Generic)
import Plutarch.Builtin.Bool (PBool)
import Plutarch.Builtin.ByteString (PByteString)
import Plutarch.Builtin.Integer (PInteger)
import Plutarch.Builtin.Opaque (POpaque)
import Plutarch.Internal.Term (Term, punsafeBuiltin, punsafeConstantInternal, (:-->))
import PlutusCore qualified as PLC
import PlutusCore.Crypto.BLS12_381.G1 qualified as BLS12_381.G1
import PlutusCore.Crypto.BLS12_381.G2 qualified as BLS12_381.G2

{- | A point on the BLS12-381 G1 curve.

@since 1.9.0
-}
newtype PBuiltinBLS12_381_G1_Element s = PBuiltinBLS12_381_G1_Element (Term s POpaque)
  deriving stock ((forall x.
 PBuiltinBLS12_381_G1_Element s
 -> Rep (PBuiltinBLS12_381_G1_Element s) x)
-> (forall x.
    Rep (PBuiltinBLS12_381_G1_Element s) x
    -> PBuiltinBLS12_381_G1_Element s)
-> Generic (PBuiltinBLS12_381_G1_Element s)
forall x.
Rep (PBuiltinBLS12_381_G1_Element s) x
-> PBuiltinBLS12_381_G1_Element s
forall x.
PBuiltinBLS12_381_G1_Element s
-> Rep (PBuiltinBLS12_381_G1_Element s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x.
Rep (PBuiltinBLS12_381_G1_Element s) x
-> PBuiltinBLS12_381_G1_Element s
forall (s :: S) x.
PBuiltinBLS12_381_G1_Element s
-> Rep (PBuiltinBLS12_381_G1_Element s) x
$cfrom :: forall (s :: S) x.
PBuiltinBLS12_381_G1_Element s
-> Rep (PBuiltinBLS12_381_G1_Element s) x
from :: forall x.
PBuiltinBLS12_381_G1_Element s
-> Rep (PBuiltinBLS12_381_G1_Element s) x
$cto :: forall (s :: S) x.
Rep (PBuiltinBLS12_381_G1_Element s) x
-> PBuiltinBLS12_381_G1_Element s
to :: forall x.
Rep (PBuiltinBLS12_381_G1_Element s) x
-> PBuiltinBLS12_381_G1_Element s
Generic)

{- | Add two points on the BLS12-381 G1 curve.

@since 1.9.0
-}
pbls12_381_G1_add :: Term s (PBuiltinBLS12_381_G1_Element :--> PBuiltinBLS12_381_G1_Element :--> PBuiltinBLS12_381_G1_Element)
pbls12_381_G1_add :: forall (s :: S).
Term
  s
  (PBuiltinBLS12_381_G1_Element
   :--> (PBuiltinBLS12_381_G1_Element
         :--> PBuiltinBLS12_381_G1_Element))
pbls12_381_G1_add = DefaultFun
-> Term
     s
     (PBuiltinBLS12_381_G1_Element
      :--> (PBuiltinBLS12_381_G1_Element
            :--> PBuiltinBLS12_381_G1_Element))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G1_add

{- | Multiply a point on the BLS12-381 G1 curve by a scalar.

@since 1.9.0
-}
pbls12_381_G1_scalarMul :: Term s (PInteger :--> PBuiltinBLS12_381_G1_Element :--> PBuiltinBLS12_381_G1_Element)
pbls12_381_G1_scalarMul :: forall (s :: S).
Term
  s
  (PInteger
   :--> (PBuiltinBLS12_381_G1_Element
         :--> PBuiltinBLS12_381_G1_Element))
pbls12_381_G1_scalarMul = DefaultFun
-> Term
     s
     (PInteger
      :--> (PBuiltinBLS12_381_G1_Element
            :--> PBuiltinBLS12_381_G1_Element))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G1_scalarMul

{- | Negate a point on the BLS12-381 G1 curve.

@since 1.9.0
-}
pbls12_381_G1_neg :: Term s (PBuiltinBLS12_381_G1_Element :--> PBuiltinBLS12_381_G1_Element)
pbls12_381_G1_neg :: forall (s :: S).
Term
  s (PBuiltinBLS12_381_G1_Element :--> PBuiltinBLS12_381_G1_Element)
pbls12_381_G1_neg = DefaultFun
-> Term
     s (PBuiltinBLS12_381_G1_Element :--> PBuiltinBLS12_381_G1_Element)
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G1_neg

{- | Compress a point on the BLS12-381 G1 curve to a byte string.

@since 1.9.0
-}
pbls12_381_G1_compress :: Term s (PBuiltinBLS12_381_G1_Element :--> PByteString)
pbls12_381_G1_compress :: forall (s :: S).
Term s (PBuiltinBLS12_381_G1_Element :--> PByteString)
pbls12_381_G1_compress = DefaultFun
-> Term s (PBuiltinBLS12_381_G1_Element :--> PByteString)
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G1_compress

{- | Uncompress a byte string to a point on the BLS12-381 G1 curve.

@since 1.9.0
-}
pbls12_381_G1_uncompress :: Term s (PByteString :--> PBuiltinBLS12_381_G1_Element)
pbls12_381_G1_uncompress :: forall (s :: S).
Term s (PByteString :--> PBuiltinBLS12_381_G1_Element)
pbls12_381_G1_uncompress = DefaultFun
-> Term s (PByteString :--> PBuiltinBLS12_381_G1_Element)
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G1_uncompress

{- | Hash a message to a point on the BLS12-381 G1 curve.

@since 1.9.0
-}
pbls12_381_G1_hashToGroup :: Term s (PByteString :--> PByteString :--> PBuiltinBLS12_381_G1_Element)
pbls12_381_G1_hashToGroup :: forall (s :: S).
Term
  s
  (PByteString :--> (PByteString :--> PBuiltinBLS12_381_G1_Element))
pbls12_381_G1_hashToGroup = DefaultFun
-> Term
     s
     (PByteString :--> (PByteString :--> PBuiltinBLS12_381_G1_Element))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G1_hashToGroup

{- | The compressed representation of the zero point on the BLS12-381 G1 curve.

@since 1.9.0
-}
pbls12_381_G1_compressed_zero :: Term s PByteString
pbls12_381_G1_compressed_zero :: forall (s :: S). Term s PByteString
pbls12_381_G1_compressed_zero = Some @Type (ValueOf DefaultUni) -> Term s PByteString
forall (s :: S) (a :: PType).
Some @Type (ValueOf DefaultUni) -> Term s a
punsafeConstantInternal (Some @Type (ValueOf DefaultUni) -> Term s PByteString)
-> Some @Type (ValueOf DefaultUni) -> Term s PByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> Some @Type (ValueOf DefaultUni)
forall a (uni :: Type -> Type).
Contains @Type uni a =>
a -> Some @Type (ValueOf uni)
PLC.someValue ByteString
BLS12_381.G1.compressed_zero

{- | The compressed representation of the generator point on the BLS12-381 G1 curve.

@since 1.9.0
-}
pbls12_381_G1_compressed_generator :: Term s PByteString
pbls12_381_G1_compressed_generator :: forall (s :: S). Term s PByteString
pbls12_381_G1_compressed_generator = Some @Type (ValueOf DefaultUni) -> Term s PByteString
forall (s :: S) (a :: PType).
Some @Type (ValueOf DefaultUni) -> Term s a
punsafeConstantInternal (Some @Type (ValueOf DefaultUni) -> Term s PByteString)
-> Some @Type (ValueOf DefaultUni) -> Term s PByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> Some @Type (ValueOf DefaultUni)
forall a (uni :: Type -> Type).
Contains @Type uni a =>
a -> Some @Type (ValueOf uni)
PLC.someValue ByteString
BLS12_381.G1.compressed_generator

-- | @since 1.9.0
newtype PBuiltinBLS12_381_G2_Element s = PBuiltinBLS12_381_G2_Element (Term s POpaque)
  deriving stock ((forall x.
 PBuiltinBLS12_381_G2_Element s
 -> Rep (PBuiltinBLS12_381_G2_Element s) x)
-> (forall x.
    Rep (PBuiltinBLS12_381_G2_Element s) x
    -> PBuiltinBLS12_381_G2_Element s)
-> Generic (PBuiltinBLS12_381_G2_Element s)
forall x.
Rep (PBuiltinBLS12_381_G2_Element s) x
-> PBuiltinBLS12_381_G2_Element s
forall x.
PBuiltinBLS12_381_G2_Element s
-> Rep (PBuiltinBLS12_381_G2_Element s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x.
Rep (PBuiltinBLS12_381_G2_Element s) x
-> PBuiltinBLS12_381_G2_Element s
forall (s :: S) x.
PBuiltinBLS12_381_G2_Element s
-> Rep (PBuiltinBLS12_381_G2_Element s) x
$cfrom :: forall (s :: S) x.
PBuiltinBLS12_381_G2_Element s
-> Rep (PBuiltinBLS12_381_G2_Element s) x
from :: forall x.
PBuiltinBLS12_381_G2_Element s
-> Rep (PBuiltinBLS12_381_G2_Element s) x
$cto :: forall (s :: S) x.
Rep (PBuiltinBLS12_381_G2_Element s) x
-> PBuiltinBLS12_381_G2_Element s
to :: forall x.
Rep (PBuiltinBLS12_381_G2_Element s) x
-> PBuiltinBLS12_381_G2_Element s
Generic)

{- | Add two points on the BLS12-381 G2 curve.

@since 1.9.0
-}
pbls12_381_G2_add :: Term s (PBuiltinBLS12_381_G2_Element :--> PBuiltinBLS12_381_G2_Element :--> PBuiltinBLS12_381_G2_Element)
pbls12_381_G2_add :: forall (s :: S).
Term
  s
  (PBuiltinBLS12_381_G2_Element
   :--> (PBuiltinBLS12_381_G2_Element
         :--> PBuiltinBLS12_381_G2_Element))
pbls12_381_G2_add = DefaultFun
-> Term
     s
     (PBuiltinBLS12_381_G2_Element
      :--> (PBuiltinBLS12_381_G2_Element
            :--> PBuiltinBLS12_381_G2_Element))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G2_add

{- | Multiply a point on the BLS12-381 G2 curve by a scalar.

@since 1.9.0
-}
pbls12_381_G2_scalarMul :: Term s (PInteger :--> PBuiltinBLS12_381_G2_Element :--> PBuiltinBLS12_381_G2_Element)
pbls12_381_G2_scalarMul :: forall (s :: S).
Term
  s
  (PInteger
   :--> (PBuiltinBLS12_381_G2_Element
         :--> PBuiltinBLS12_381_G2_Element))
pbls12_381_G2_scalarMul = DefaultFun
-> Term
     s
     (PInteger
      :--> (PBuiltinBLS12_381_G2_Element
            :--> PBuiltinBLS12_381_G2_Element))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G2_scalarMul

{- | Negate a point on the BLS12-381 G2 curve.

@since 1.9.0
-}
pbls12_381_G2_neg :: Term s (PBuiltinBLS12_381_G2_Element :--> PBuiltinBLS12_381_G2_Element)
pbls12_381_G2_neg :: forall (s :: S).
Term
  s (PBuiltinBLS12_381_G2_Element :--> PBuiltinBLS12_381_G2_Element)
pbls12_381_G2_neg = DefaultFun
-> Term
     s (PBuiltinBLS12_381_G2_Element :--> PBuiltinBLS12_381_G2_Element)
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G2_neg

{- | Compress a point on the BLS12-381 G2 curve to a byte string.

@since 1.9.0
-}
pbls12_381_G2_compress :: Term s (PBuiltinBLS12_381_G2_Element :--> PByteString)
pbls12_381_G2_compress :: forall (s :: S).
Term s (PBuiltinBLS12_381_G2_Element :--> PByteString)
pbls12_381_G2_compress = DefaultFun
-> Term s (PBuiltinBLS12_381_G2_Element :--> PByteString)
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G2_compress

{- | Uncompress a byte string to a point on the BLS12-381 G2 curve.

@since 1.9.0
-}
pbls12_381_G2_uncompress :: Term s (PByteString :--> PBuiltinBLS12_381_G2_Element)
pbls12_381_G2_uncompress :: forall (s :: S).
Term s (PByteString :--> PBuiltinBLS12_381_G2_Element)
pbls12_381_G2_uncompress = DefaultFun
-> Term s (PByteString :--> PBuiltinBLS12_381_G2_Element)
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G2_uncompress

{- | Hash a message to a point on the BLS12-381 G2 curve.

@since 1.9.0
-}
pbls12_381_G2_hashToGroup :: Term s (PByteString :--> PByteString :--> PBuiltinBLS12_381_G2_Element)
pbls12_381_G2_hashToGroup :: forall (s :: S).
Term
  s
  (PByteString :--> (PByteString :--> PBuiltinBLS12_381_G2_Element))
pbls12_381_G2_hashToGroup = DefaultFun
-> Term
     s
     (PByteString :--> (PByteString :--> PBuiltinBLS12_381_G2_Element))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_G2_hashToGroup

{- | The compressed representation of the zero point on the BLS12-381 G2 curve.

@since 1.9.0
-}
pbls12_381_G2_compressed_zero :: Term s PByteString
pbls12_381_G2_compressed_zero :: forall (s :: S). Term s PByteString
pbls12_381_G2_compressed_zero = Some @Type (ValueOf DefaultUni) -> Term s PByteString
forall (s :: S) (a :: PType).
Some @Type (ValueOf DefaultUni) -> Term s a
punsafeConstantInternal (Some @Type (ValueOf DefaultUni) -> Term s PByteString)
-> Some @Type (ValueOf DefaultUni) -> Term s PByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> Some @Type (ValueOf DefaultUni)
forall a (uni :: Type -> Type).
Contains @Type uni a =>
a -> Some @Type (ValueOf uni)
PLC.someValue ByteString
BLS12_381.G2.compressed_zero

{- | The compressed representation of the generator point on the BLS12-381 G2 curve.

@since 1.9.0
-}
pbls12_381_G2_compressed_generator :: Term s PByteString
pbls12_381_G2_compressed_generator :: forall (s :: S). Term s PByteString
pbls12_381_G2_compressed_generator = Some @Type (ValueOf DefaultUni) -> Term s PByteString
forall (s :: S) (a :: PType).
Some @Type (ValueOf DefaultUni) -> Term s a
punsafeConstantInternal (Some @Type (ValueOf DefaultUni) -> Term s PByteString)
-> Some @Type (ValueOf DefaultUni) -> Term s PByteString
forall a b. (a -> b) -> a -> b
$ ByteString -> Some @Type (ValueOf DefaultUni)
forall a (uni :: Type -> Type).
Contains @Type uni a =>
a -> Some @Type (ValueOf uni)
PLC.someValue ByteString
BLS12_381.G2.compressed_generator

{- | Represents the result of a Miller loop operation in BLS12-381 pairing.

@since 1.9.0
-}
newtype PBuiltinBLS12_381_MlResult s = PBuiltinBLS12_381_MlResult (Term s POpaque)
  deriving stock ((forall x.
 PBuiltinBLS12_381_MlResult s
 -> Rep (PBuiltinBLS12_381_MlResult s) x)
-> (forall x.
    Rep (PBuiltinBLS12_381_MlResult s) x
    -> PBuiltinBLS12_381_MlResult s)
-> Generic (PBuiltinBLS12_381_MlResult s)
forall x.
Rep (PBuiltinBLS12_381_MlResult s) x
-> PBuiltinBLS12_381_MlResult s
forall x.
PBuiltinBLS12_381_MlResult s
-> Rep (PBuiltinBLS12_381_MlResult s) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall (s :: S) x.
Rep (PBuiltinBLS12_381_MlResult s) x
-> PBuiltinBLS12_381_MlResult s
forall (s :: S) x.
PBuiltinBLS12_381_MlResult s
-> Rep (PBuiltinBLS12_381_MlResult s) x
$cfrom :: forall (s :: S) x.
PBuiltinBLS12_381_MlResult s
-> Rep (PBuiltinBLS12_381_MlResult s) x
from :: forall x.
PBuiltinBLS12_381_MlResult s
-> Rep (PBuiltinBLS12_381_MlResult s) x
$cto :: forall (s :: S) x.
Rep (PBuiltinBLS12_381_MlResult s) x
-> PBuiltinBLS12_381_MlResult s
to :: forall x.
Rep (PBuiltinBLS12_381_MlResult s) x
-> PBuiltinBLS12_381_MlResult s
Generic)

{- | Perform a Miller loop operation on a G1 and G2 element.

@since 1.9.0
-}
pbls12_381_millerLoop :: Term s (PBuiltinBLS12_381_G1_Element :--> PBuiltinBLS12_381_G2_Element :--> PBuiltinBLS12_381_MlResult)
pbls12_381_millerLoop :: forall (s :: S).
Term
  s
  (PBuiltinBLS12_381_G1_Element
   :--> (PBuiltinBLS12_381_G2_Element
         :--> PBuiltinBLS12_381_MlResult))
pbls12_381_millerLoop = DefaultFun
-> Term
     s
     (PBuiltinBLS12_381_G1_Element
      :--> (PBuiltinBLS12_381_G2_Element
            :--> PBuiltinBLS12_381_MlResult))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_millerLoop

{- | Multiply two Miller loop results.

@since 1.9.0
-}
pbls12_381_mulMlResult :: Term s (PBuiltinBLS12_381_MlResult :--> PBuiltinBLS12_381_MlResult :--> PBuiltinBLS12_381_MlResult)
pbls12_381_mulMlResult :: forall (s :: S).
Term
  s
  (PBuiltinBLS12_381_MlResult
   :--> (PBuiltinBLS12_381_MlResult :--> PBuiltinBLS12_381_MlResult))
pbls12_381_mulMlResult = DefaultFun
-> Term
     s
     (PBuiltinBLS12_381_MlResult
      :--> (PBuiltinBLS12_381_MlResult :--> PBuiltinBLS12_381_MlResult))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_mulMlResult

{- | Perform the final verification step in BLS12-381 pairing.

@since 1.9.0
-}
pbls12_381_finalVerify :: Term s (PBuiltinBLS12_381_MlResult :--> PBuiltinBLS12_381_MlResult :--> PBool)
pbls12_381_finalVerify :: forall (s :: S).
Term
  s
  (PBuiltinBLS12_381_MlResult
   :--> (PBuiltinBLS12_381_MlResult :--> PBool))
pbls12_381_finalVerify = DefaultFun
-> Term
     s
     (PBuiltinBLS12_381_MlResult
      :--> (PBuiltinBLS12_381_MlResult :--> PBool))
forall (s :: S) (a :: PType). DefaultFun -> Term s a
punsafeBuiltin DefaultFun
PLC.Bls12_381_finalVerify