{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE TypeApplications #-}
module PlutusCore.Crypto.BLS12_381.G1
( Element (..)
, add
, neg
, scalarMul
, hashToGroup
, compress
, uncompress
, offchain_zero
, compressed_zero
, compressed_generator
, memSizeBytes
, compressedSizeBytes
) where
import Cardano.Crypto.EllipticCurve.BLS12_381 qualified as BlstBindings
import Cardano.Crypto.EllipticCurve.BLS12_381.Internal qualified as BlstBindings.Internal
import PlutusCore.Crypto.BLS12_381.Error
import PlutusCore.Crypto.Utils (byteStringAsHex)
import PlutusCore.Pretty.PrettyConst (ConstConfig)
import Text.PrettyBy (PrettyBy)
import Control.DeepSeq (NFData, rnf, rwhnf)
import Data.ByteString (ByteString, length)
import Data.Coerce (coerce)
import Data.Hashable
import Data.Proxy (Proxy (..))
import Flat
import Prettyprinter
newtype Element = Element { Element -> Point Curve1
unElement :: BlstBindings.Point1 }
deriving newtype (Element -> Element -> Bool
(Element -> Element -> Bool)
-> (Element -> Element -> Bool) -> Eq Element
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Element -> Element -> Bool
== :: Element -> Element -> Bool
$c/= :: Element -> Element -> Bool
/= :: Element -> Element -> Bool
Eq)
instance Show Element where
show :: Element -> String
show = ByteString -> String
byteStringAsHex (ByteString -> String)
-> (Element -> ByteString) -> Element -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> ByteString
compress
instance Pretty Element where
pretty :: forall ann. Element -> Doc ann
pretty = String -> Doc ann
forall ann. String -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (String -> Doc ann) -> (Element -> String) -> Element -> Doc ann
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> String
forall a. Show a => a -> String
show
instance PrettyBy ConstConfig Element
instance Flat Element where
decode :: Get Element
decode = String -> Get Element
forall a. String -> Get a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"Flat decoding is not supported for objects of type bls12_381_G1_element: use bls12_381_G1_uncompress on a bytestring instead."
encode :: Element -> Encoding
encode = String -> Element -> Encoding
forall a. HasCallStack => String -> a
error String
"Flat encoding is not supported for objects of type bls12_381_G1_element: use bls12_381_G1_compress to obtain a bytestring instead."
size :: Element -> Int -> Int
size Element
_ = Int -> Int
forall a. a -> a
id
instance NFData Element where
rnf :: Element -> ()
rnf (Element Point Curve1
x) = Point Curve1 -> ()
forall a. a -> ()
rwhnf Point Curve1
x
instance Hashable Element where
hashWithSalt :: Int -> Element -> Int
hashWithSalt Int
salt = Int -> ByteString -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt (ByteString -> Int) -> (Element -> ByteString) -> Element -> Int
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Element -> ByteString
compress
add :: Element -> Element -> Element
add :: Element -> Element -> Element
add = (Point Curve1 -> Point Curve1 -> Point Curve1)
-> Element -> Element -> Element
forall a b. Coercible a b => a -> b
coerce (forall curve.
BLS curve =>
Point curve -> Point curve -> Point curve
BlstBindings.blsAddOrDouble @BlstBindings.Curve1)
{-# INLINE add #-}
neg :: Element -> Element
neg :: Element -> Element
neg = (Point Curve1 -> Point Curve1) -> Element -> Element
forall a b. Coercible a b => a -> b
coerce (forall curve. BLS curve => Point curve -> Point curve
BlstBindings.blsNeg @BlstBindings.Curve1)
{-# INLINE neg #-}
scalarMul :: Integer -> Element -> Element
scalarMul :: Integer -> Element -> Element
scalarMul = (Integer -> Point Curve1 -> Point Curve1)
-> Integer -> Element -> Element
forall a b. Coercible a b => a -> b
coerce ((Integer -> Point Curve1 -> Point Curve1)
-> Integer -> Element -> Element)
-> (Integer -> Point Curve1 -> Point Curve1)
-> Integer
-> Element
-> Element
forall a b. (a -> b) -> a -> b
$ (Point Curve1 -> Integer -> Point Curve1)
-> Integer -> Point Curve1 -> Point Curve1
forall a b c. (a -> b -> c) -> b -> a -> c
flip (forall curve. BLS curve => Point curve -> Integer -> Point curve
BlstBindings.blsMult @BlstBindings.Curve1)
{-# INLINE scalarMul #-}
compress :: Element -> ByteString
compress :: Element -> ByteString
compress = (Point Curve1 -> ByteString) -> Element -> ByteString
forall a b. Coercible a b => a -> b
coerce (forall curve. BLS curve => Point curve -> ByteString
BlstBindings.blsCompress @BlstBindings.Curve1)
{-# INLINE compress #-}
uncompress :: ByteString -> Either BlstBindings.BLSTError Element
uncompress :: ByteString -> Either BLSTError Element
uncompress = (ByteString -> Either BLSTError (Point Curve1))
-> ByteString -> Either BLSTError Element
forall a b. Coercible a b => a -> b
coerce (forall curve.
BLS curve =>
ByteString -> Either BLSTError (Point curve)
BlstBindings.blsUncompress @BlstBindings.Curve1)
{-# INLINE uncompress #-}
hashToGroup :: ByteString -> ByteString -> Either BLS12_381_Error Element
hashToGroup :: ByteString -> ByteString -> Either BLS12_381_Error Element
hashToGroup ByteString
msg ByteString
dst =
if ByteString -> Int
Data.ByteString.length ByteString
dst Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
255
then BLS12_381_Error -> Either BLS12_381_Error Element
forall a b. a -> Either a b
Left BLS12_381_Error
HashToCurveDstTooBig
else Element -> Either BLS12_381_Error Element
forall a b. b -> Either a b
Right (Element -> Either BLS12_381_Error Element)
-> (Point Curve1 -> Element)
-> Point Curve1
-> Either BLS12_381_Error Element
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Point Curve1 -> Element
Element (Point Curve1 -> Either BLS12_381_Error Element)
-> Point Curve1 -> Either BLS12_381_Error Element
forall a b. (a -> b) -> a -> b
$ forall curve.
BLS curve =>
ByteString -> Maybe ByteString -> Maybe ByteString -> Point curve
BlstBindings.blsHash @BlstBindings.Curve1 ByteString
msg (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
dst) Maybe ByteString
forall a. Maybe a
Nothing
offchain_zero :: Element
offchain_zero :: Element
offchain_zero = Point Curve1 -> Element
forall a b. Coercible a b => a -> b
coerce (forall curve. BLS curve => Point curve
BlstBindings.Internal.blsZero @BlstBindings.Curve1)
compressed_zero :: ByteString
compressed_zero :: ByteString
compressed_zero = Element -> ByteString
compress (Element -> ByteString) -> Element -> ByteString
forall a b. (a -> b) -> a -> b
$ Point Curve1 -> Element
forall a b. Coercible a b => a -> b
coerce (forall curve. BLS curve => Point curve
BlstBindings.Internal.blsZero @BlstBindings.Curve1)
{-# INLINABLE compressed_zero #-}
compressed_generator :: ByteString
compressed_generator :: ByteString
compressed_generator = Element -> ByteString
compress (Element -> ByteString) -> Element -> ByteString
forall a b. (a -> b) -> a -> b
$ Point Curve1 -> Element
forall a b. Coercible a b => a -> b
coerce (forall curve. BLS curve => Point curve
BlstBindings.Internal.blsGenerator @BlstBindings.Curve1)
memSizeBytes :: Int
memSizeBytes :: Int
memSizeBytes = Proxy Curve1 -> Int
forall curve. BLS curve => Proxy curve -> Int
BlstBindings.Internal.sizePoint (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @BlstBindings.Curve1)
compressedSizeBytes :: Int
compressedSizeBytes :: Int
compressedSizeBytes = Proxy Curve1 -> Int
forall curve. BLS curve => Proxy curve -> Int
BlstBindings.Internal.compressedSizePoint (forall t. Proxy t
forall {k} (t :: k). Proxy t
Proxy @BlstBindings.Curve1)