{-# LANGUAGE DeriveAnyClass #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE InstanceSigs #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}

-- | Leios specific key types and their 'Key' class instances
module Cardano.Api.Key.Internal.Leios
  ( -- * Key types
    BlsKey

    -- * Data family instances
  , AsType (..)
  , Hash (..)
  , VerificationKey (..)
  , SigningKey (..)

    -- * Possession proof
  , BlsPossessionProof
  , blsPossessionProof
  , createBlsPossessionProof
  )
where

import Cardano.Api.HasTypeProxy
import Cardano.Api.Hash
import Cardano.Api.Key.Internal.Class
import Cardano.Api.Pretty
import Cardano.Api.Serialise.Bech32
import Cardano.Api.Serialise.Cbor
import Cardano.Api.Serialise.Raw
import Cardano.Api.Serialise.SerialiseUsing
import Cardano.Api.Serialise.TextEnvelope.Internal

import Cardano.Crypto.DSIGN.BLS12381 qualified as Crypto
import Cardano.Crypto.DSIGN.Class qualified as Crypto
import Cardano.Crypto.Hash.Class qualified as Crypto
import Cardano.Ledger.Hashes (HASH)

import Data.ByteString (ByteString)
import Data.Either.Combinators (maybeToRight)
import Data.String (IsString (..))

-- | BLS keys. To participate in the Leios protocol as voting member/block producing node, stake pool operators must
-- register one additional cryptographic key for the voting scheme alongside their existing VRF and KES keys.
-- In this implementation, the BLS key is over the BLS12-381 elliptic curve.
--
-- The reason we use BLS keys for the voting scheme of Leios is that they support signature aggregation, which allows
-- multiple signature to be combined resulting in a single signature that is compact.
data BlsKey

instance HasTypeProxy BlsKey where
  data AsType BlsKey = AsBlsKey
  proxyToAsType :: Proxy BlsKey -> AsType BlsKey
proxyToAsType Proxy BlsKey
_ = AsType BlsKey
AsBlsKey

instance Key BlsKey where
  newtype VerificationKey BlsKey
    = BlsVerificationKey (Crypto.VerKeyDSIGN Crypto.BLS12381MinSigDSIGN)
    deriving stock VerificationKey BlsKey -> VerificationKey BlsKey -> Bool
(VerificationKey BlsKey -> VerificationKey BlsKey -> Bool)
-> (VerificationKey BlsKey -> VerificationKey BlsKey -> Bool)
-> Eq (VerificationKey BlsKey)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VerificationKey BlsKey -> VerificationKey BlsKey -> Bool
== :: VerificationKey BlsKey -> VerificationKey BlsKey -> Bool
$c/= :: VerificationKey BlsKey -> VerificationKey BlsKey -> Bool
/= :: VerificationKey BlsKey -> VerificationKey BlsKey -> Bool
Eq
    deriving (Int -> VerificationKey BlsKey -> ShowS
[VerificationKey BlsKey] -> ShowS
VerificationKey BlsKey -> String
(Int -> VerificationKey BlsKey -> ShowS)
-> (VerificationKey BlsKey -> String)
-> ([VerificationKey BlsKey] -> ShowS)
-> Show (VerificationKey BlsKey)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VerificationKey BlsKey -> ShowS
showsPrec :: Int -> VerificationKey BlsKey -> ShowS
$cshow :: VerificationKey BlsKey -> String
show :: VerificationKey BlsKey -> String
$cshowList :: [VerificationKey BlsKey] -> ShowS
showList :: [VerificationKey BlsKey] -> ShowS
Show, (forall ann. VerificationKey BlsKey -> Doc ann)
-> (forall ann. [VerificationKey BlsKey] -> Doc ann)
-> Pretty (VerificationKey BlsKey)
forall ann. [VerificationKey BlsKey] -> Doc ann
forall ann. VerificationKey BlsKey -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
$cpretty :: forall ann. VerificationKey BlsKey -> Doc ann
pretty :: forall ann. VerificationKey BlsKey -> Doc ann
$cprettyList :: forall ann. [VerificationKey BlsKey] -> Doc ann
prettyList :: forall ann. [VerificationKey BlsKey] -> Doc ann
Pretty) via UsingRawBytesHex (VerificationKey BlsKey)
    deriving newtype (Typeable (VerificationKey BlsKey)
Typeable (VerificationKey BlsKey) =>
(VerificationKey BlsKey -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy (VerificationKey BlsKey) -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy [VerificationKey BlsKey] -> Size)
-> ToCBOR (VerificationKey BlsKey)
VerificationKey BlsKey -> Encoding
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerificationKey BlsKey] -> Size
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerificationKey BlsKey) -> Size
forall a.
Typeable a =>
(a -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> ToCBOR a
$ctoCBOR :: VerificationKey BlsKey -> Encoding
toCBOR :: VerificationKey BlsKey -> Encoding
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerificationKey BlsKey) -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerificationKey BlsKey) -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerificationKey BlsKey] -> Size
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerificationKey BlsKey] -> Size
ToCBOR, Typeable (VerificationKey BlsKey)
Typeable (VerificationKey BlsKey) =>
(forall s. Decoder s (VerificationKey BlsKey))
-> (Proxy (VerificationKey BlsKey) -> Text)
-> FromCBOR (VerificationKey BlsKey)
Proxy (VerificationKey BlsKey) -> Text
forall s. Decoder s (VerificationKey BlsKey)
forall a.
Typeable a =>
(forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
$cfromCBOR :: forall s. Decoder s (VerificationKey BlsKey)
fromCBOR :: forall s. Decoder s (VerificationKey BlsKey)
$clabel :: Proxy (VerificationKey BlsKey) -> Text
label :: Proxy (VerificationKey BlsKey) -> Text
FromCBOR)
    deriving anyclass HasTypeProxy (VerificationKey BlsKey)
AsType (VerificationKey BlsKey)
-> ByteString -> Either DecoderError (VerificationKey BlsKey)
HasTypeProxy (VerificationKey BlsKey) =>
(VerificationKey BlsKey -> ByteString)
-> (AsType (VerificationKey BlsKey)
    -> ByteString -> Either DecoderError (VerificationKey BlsKey))
-> SerialiseAsCBOR (VerificationKey BlsKey)
VerificationKey BlsKey -> ByteString
forall a.
HasTypeProxy a =>
(a -> ByteString)
-> (AsType a -> ByteString -> Either DecoderError a)
-> SerialiseAsCBOR a
$cserialiseToCBOR :: VerificationKey BlsKey -> ByteString
serialiseToCBOR :: VerificationKey BlsKey -> ByteString
$cdeserialiseFromCBOR :: AsType (VerificationKey BlsKey)
-> ByteString -> Either DecoderError (VerificationKey BlsKey)
deserialiseFromCBOR :: AsType (VerificationKey BlsKey)
-> ByteString -> Either DecoderError (VerificationKey BlsKey)
SerialiseAsCBOR

  newtype SigningKey BlsKey
    = BlsSigningKey (Crypto.SignKeyDSIGN Crypto.BLS12381MinSigDSIGN)
    deriving (Int -> SigningKey BlsKey -> ShowS
[SigningKey BlsKey] -> ShowS
SigningKey BlsKey -> String
(Int -> SigningKey BlsKey -> ShowS)
-> (SigningKey BlsKey -> String)
-> ([SigningKey BlsKey] -> ShowS)
-> Show (SigningKey BlsKey)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> SigningKey BlsKey -> ShowS
showsPrec :: Int -> SigningKey BlsKey -> ShowS
$cshow :: SigningKey BlsKey -> String
show :: SigningKey BlsKey -> String
$cshowList :: [SigningKey BlsKey] -> ShowS
showList :: [SigningKey BlsKey] -> ShowS
Show, (forall ann. SigningKey BlsKey -> Doc ann)
-> (forall ann. [SigningKey BlsKey] -> Doc ann)
-> Pretty (SigningKey BlsKey)
forall ann. [SigningKey BlsKey] -> Doc ann
forall ann. SigningKey BlsKey -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
$cpretty :: forall ann. SigningKey BlsKey -> Doc ann
pretty :: forall ann. SigningKey BlsKey -> Doc ann
$cprettyList :: forall ann. [SigningKey BlsKey] -> Doc ann
prettyList :: forall ann. [SigningKey BlsKey] -> Doc ann
Pretty) via UsingRawBytesHex (SigningKey BlsKey)
    deriving newtype (Typeable (SigningKey BlsKey)
Typeable (SigningKey BlsKey) =>
(SigningKey BlsKey -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy (SigningKey BlsKey) -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy [SigningKey BlsKey] -> Size)
-> ToCBOR (SigningKey BlsKey)
SigningKey BlsKey -> Encoding
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [SigningKey BlsKey] -> Size
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (SigningKey BlsKey) -> Size
forall a.
Typeable a =>
(a -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> ToCBOR a
$ctoCBOR :: SigningKey BlsKey -> Encoding
toCBOR :: SigningKey BlsKey -> Encoding
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (SigningKey BlsKey) -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (SigningKey BlsKey) -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [SigningKey BlsKey] -> Size
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [SigningKey BlsKey] -> Size
ToCBOR, Typeable (SigningKey BlsKey)
Typeable (SigningKey BlsKey) =>
(forall s. Decoder s (SigningKey BlsKey))
-> (Proxy (SigningKey BlsKey) -> Text)
-> FromCBOR (SigningKey BlsKey)
Proxy (SigningKey BlsKey) -> Text
forall s. Decoder s (SigningKey BlsKey)
forall a.
Typeable a =>
(forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
$cfromCBOR :: forall s. Decoder s (SigningKey BlsKey)
fromCBOR :: forall s. Decoder s (SigningKey BlsKey)
$clabel :: Proxy (SigningKey BlsKey) -> Text
label :: Proxy (SigningKey BlsKey) -> Text
FromCBOR)
    deriving anyclass HasTypeProxy (SigningKey BlsKey)
AsType (SigningKey BlsKey)
-> ByteString -> Either DecoderError (SigningKey BlsKey)
HasTypeProxy (SigningKey BlsKey) =>
(SigningKey BlsKey -> ByteString)
-> (AsType (SigningKey BlsKey)
    -> ByteString -> Either DecoderError (SigningKey BlsKey))
-> SerialiseAsCBOR (SigningKey BlsKey)
SigningKey BlsKey -> ByteString
forall a.
HasTypeProxy a =>
(a -> ByteString)
-> (AsType a -> ByteString -> Either DecoderError a)
-> SerialiseAsCBOR a
$cserialiseToCBOR :: SigningKey BlsKey -> ByteString
serialiseToCBOR :: SigningKey BlsKey -> ByteString
$cdeserialiseFromCBOR :: AsType (SigningKey BlsKey)
-> ByteString -> Either DecoderError (SigningKey BlsKey)
deserialiseFromCBOR :: AsType (SigningKey BlsKey)
-> ByteString -> Either DecoderError (SigningKey BlsKey)
SerialiseAsCBOR

  deterministicSigningKey :: AsType BlsKey -> Crypto.Seed -> SigningKey BlsKey
  deterministicSigningKey :: AsType BlsKey -> Seed -> SigningKey BlsKey
deterministicSigningKey AsType BlsKey
R:AsTypeBlsKey
AsBlsKey =
    SignKeyDSIGN BLS12381MinSigDSIGN -> SigningKey BlsKey
BlsSigningKey (SignKeyDSIGN BLS12381MinSigDSIGN -> SigningKey BlsKey)
-> (Seed -> SignKeyDSIGN BLS12381MinSigDSIGN)
-> Seed
-> SigningKey BlsKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seed -> SignKeyDSIGN BLS12381MinSigDSIGN
forall v. DSIGNAlgorithm v => Seed -> SignKeyDSIGN v
Crypto.genKeyDSIGN

  deterministicSigningKeySeedSize :: AsType BlsKey -> Word
  deterministicSigningKeySeedSize :: AsType BlsKey -> Word
deterministicSigningKeySeedSize AsType BlsKey
R:AsTypeBlsKey
AsBlsKey =
    Proxy BLS12381MinSigDSIGN -> Word
forall v (proxy :: * -> *). DSIGNAlgorithm v => proxy v -> Word
Crypto.seedSizeDSIGN Proxy BLS12381MinSigDSIGN
proxy
   where
    proxy :: Proxy Crypto.BLS12381MinSigDSIGN
    proxy :: Proxy BLS12381MinSigDSIGN
proxy = Proxy BLS12381MinSigDSIGN
forall {k} (t :: k). Proxy t
Proxy

  getVerificationKey :: SigningKey BlsKey -> VerificationKey BlsKey
  getVerificationKey :: SigningKey BlsKey -> VerificationKey BlsKey
getVerificationKey (BlsSigningKey SignKeyDSIGN BLS12381MinSigDSIGN
sk) =
    VerKeyDSIGN BLS12381MinSigDSIGN -> VerificationKey BlsKey
BlsVerificationKey (SignKeyDSIGN BLS12381MinSigDSIGN -> VerKeyDSIGN BLS12381MinSigDSIGN
forall v. DSIGNAlgorithm v => SignKeyDSIGN v -> VerKeyDSIGN v
Crypto.deriveVerKeyDSIGN SignKeyDSIGN BLS12381MinSigDSIGN
sk)

  verificationKeyHash :: VerificationKey BlsKey -> Hash BlsKey
  verificationKeyHash :: VerificationKey BlsKey -> Hash BlsKey
verificationKeyHash (BlsVerificationKey VerKeyDSIGN BLS12381MinSigDSIGN
vkey) =
    Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN) -> Hash BlsKey
BlsKeyHash (VerKeyDSIGN BLS12381MinSigDSIGN
-> Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN)
forall h.
HashAlgorithm h =>
VerKeyDSIGN BLS12381MinSigDSIGN
-> Hash h (VerKeyDSIGN BLS12381MinSigDSIGN)
forall v h.
(DSIGNAlgorithm v, HashAlgorithm h) =>
VerKeyDSIGN v -> Hash h (VerKeyDSIGN v)
Crypto.hashVerKeyDSIGN VerKeyDSIGN BLS12381MinSigDSIGN
vkey)

instance SerialiseAsRawBytes (VerificationKey BlsKey) where
  serialiseToRawBytes :: VerificationKey BlsKey -> ByteString
serialiseToRawBytes (BlsVerificationKey VerKeyDSIGN BLS12381MinSigDSIGN
vk) =
    VerKeyDSIGN BLS12381MinSigDSIGN -> ByteString
forall v. DSIGNAlgorithm v => VerKeyDSIGN v -> ByteString
Crypto.rawSerialiseVerKeyDSIGN VerKeyDSIGN BLS12381MinSigDSIGN
vk

  deserialiseFromRawBytes :: AsType (VerificationKey BlsKey)
-> ByteString
-> Either SerialiseAsRawBytesError (VerificationKey BlsKey)
deserialiseFromRawBytes (AsVerificationKey AsType BlsKey
R:AsTypeBlsKey
AsBlsKey) ByteString
bs =
    SerialiseAsRawBytesError
-> Maybe (VerificationKey BlsKey)
-> Either SerialiseAsRawBytesError (VerificationKey BlsKey)
forall b a. b -> Maybe a -> Either b a
maybeToRight (String -> SerialiseAsRawBytesError
SerialiseAsRawBytesError String
"Unable to deserialise VerificationKey BlsKey") (Maybe (VerificationKey BlsKey)
 -> Either SerialiseAsRawBytesError (VerificationKey BlsKey))
-> Maybe (VerificationKey BlsKey)
-> Either SerialiseAsRawBytesError (VerificationKey BlsKey)
forall a b. (a -> b) -> a -> b
$
      VerKeyDSIGN BLS12381MinSigDSIGN -> VerificationKey BlsKey
BlsVerificationKey (VerKeyDSIGN BLS12381MinSigDSIGN -> VerificationKey BlsKey)
-> Maybe (VerKeyDSIGN BLS12381MinSigDSIGN)
-> Maybe (VerificationKey BlsKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Maybe (VerKeyDSIGN BLS12381MinSigDSIGN)
forall v. DSIGNAlgorithm v => ByteString -> Maybe (VerKeyDSIGN v)
Crypto.rawDeserialiseVerKeyDSIGN ByteString
bs

instance SerialiseAsRawBytes (SigningKey BlsKey) where
  serialiseToRawBytes :: SigningKey BlsKey -> ByteString
serialiseToRawBytes (BlsSigningKey SignKeyDSIGN BLS12381MinSigDSIGN
sk) =
    SignKeyDSIGN BLS12381MinSigDSIGN -> ByteString
forall v. DSIGNAlgorithm v => SignKeyDSIGN v -> ByteString
Crypto.rawSerialiseSignKeyDSIGN SignKeyDSIGN BLS12381MinSigDSIGN
sk

  deserialiseFromRawBytes :: AsType (SigningKey BlsKey)
-> ByteString
-> Either SerialiseAsRawBytesError (SigningKey BlsKey)
deserialiseFromRawBytes (AsSigningKey AsType BlsKey
R:AsTypeBlsKey
AsBlsKey) ByteString
bs =
    SerialiseAsRawBytesError
-> Maybe (SigningKey BlsKey)
-> Either SerialiseAsRawBytesError (SigningKey BlsKey)
forall b a. b -> Maybe a -> Either b a
maybeToRight (String -> SerialiseAsRawBytesError
SerialiseAsRawBytesError String
"Unable to deserialise SigningKey BlsKey") (Maybe (SigningKey BlsKey)
 -> Either SerialiseAsRawBytesError (SigningKey BlsKey))
-> Maybe (SigningKey BlsKey)
-> Either SerialiseAsRawBytesError (SigningKey BlsKey)
forall a b. (a -> b) -> a -> b
$
      SignKeyDSIGN BLS12381MinSigDSIGN -> SigningKey BlsKey
BlsSigningKey (SignKeyDSIGN BLS12381MinSigDSIGN -> SigningKey BlsKey)
-> Maybe (SignKeyDSIGN BLS12381MinSigDSIGN)
-> Maybe (SigningKey BlsKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Maybe (SignKeyDSIGN BLS12381MinSigDSIGN)
forall v. DSIGNAlgorithm v => ByteString -> Maybe (SignKeyDSIGN v)
Crypto.rawDeserialiseSignKeyDSIGN ByteString
bs

instance SerialiseAsBech32 (VerificationKey BlsKey) where
  bech32PrefixFor :: VerificationKey BlsKey -> HumanReadablePart
bech32PrefixFor VerificationKey BlsKey
_ = HasCallStack => Text -> HumanReadablePart
Text -> HumanReadablePart
unsafeHumanReadablePartFromText Text
"bls_vk"
  bech32PrefixesPermitted :: AsType (VerificationKey BlsKey) -> [HumanReadablePart]
bech32PrefixesPermitted AsType (VerificationKey BlsKey)
_ = HasCallStack => Text -> HumanReadablePart
Text -> HumanReadablePart
unsafeHumanReadablePartFromText (Text -> HumanReadablePart) -> [Text] -> [HumanReadablePart]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text
"bls_vk"]

instance SerialiseAsBech32 (SigningKey BlsKey) where
  bech32PrefixFor :: SigningKey BlsKey -> HumanReadablePart
bech32PrefixFor SigningKey BlsKey
_ = HasCallStack => Text -> HumanReadablePart
Text -> HumanReadablePart
unsafeHumanReadablePartFromText Text
"bls_sk"
  bech32PrefixesPermitted :: AsType (SigningKey BlsKey) -> [HumanReadablePart]
bech32PrefixesPermitted AsType (SigningKey BlsKey)
_ = HasCallStack => Text -> HumanReadablePart
Text -> HumanReadablePart
unsafeHumanReadablePartFromText (Text -> HumanReadablePart) -> [Text] -> [HumanReadablePart]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Text
"bls_sk"]

newtype instance Hash BlsKey
  = BlsKeyHash
      ( Crypto.Hash
          HASH
          (Crypto.VerKeyDSIGN Crypto.BLS12381MinSigDSIGN)
      )
  deriving stock (Hash BlsKey -> Hash BlsKey -> Bool
(Hash BlsKey -> Hash BlsKey -> Bool)
-> (Hash BlsKey -> Hash BlsKey -> Bool) -> Eq (Hash BlsKey)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Hash BlsKey -> Hash BlsKey -> Bool
== :: Hash BlsKey -> Hash BlsKey -> Bool
$c/= :: Hash BlsKey -> Hash BlsKey -> Bool
/= :: Hash BlsKey -> Hash BlsKey -> Bool
Eq, Eq (Hash BlsKey)
Eq (Hash BlsKey) =>
(Hash BlsKey -> Hash BlsKey -> Ordering)
-> (Hash BlsKey -> Hash BlsKey -> Bool)
-> (Hash BlsKey -> Hash BlsKey -> Bool)
-> (Hash BlsKey -> Hash BlsKey -> Bool)
-> (Hash BlsKey -> Hash BlsKey -> Bool)
-> (Hash BlsKey -> Hash BlsKey -> Hash BlsKey)
-> (Hash BlsKey -> Hash BlsKey -> Hash BlsKey)
-> Ord (Hash BlsKey)
Hash BlsKey -> Hash BlsKey -> Bool
Hash BlsKey -> Hash BlsKey -> Ordering
Hash BlsKey -> Hash BlsKey -> Hash BlsKey
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
$ccompare :: Hash BlsKey -> Hash BlsKey -> Ordering
compare :: Hash BlsKey -> Hash BlsKey -> Ordering
$c< :: Hash BlsKey -> Hash BlsKey -> Bool
< :: Hash BlsKey -> Hash BlsKey -> Bool
$c<= :: Hash BlsKey -> Hash BlsKey -> Bool
<= :: Hash BlsKey -> Hash BlsKey -> Bool
$c> :: Hash BlsKey -> Hash BlsKey -> Bool
> :: Hash BlsKey -> Hash BlsKey -> Bool
$c>= :: Hash BlsKey -> Hash BlsKey -> Bool
>= :: Hash BlsKey -> Hash BlsKey -> Bool
$cmax :: Hash BlsKey -> Hash BlsKey -> Hash BlsKey
max :: Hash BlsKey -> Hash BlsKey -> Hash BlsKey
$cmin :: Hash BlsKey -> Hash BlsKey -> Hash BlsKey
min :: Hash BlsKey -> Hash BlsKey -> Hash BlsKey
Ord)
  deriving (Int -> Hash BlsKey -> ShowS
[Hash BlsKey] -> ShowS
Hash BlsKey -> String
(Int -> Hash BlsKey -> ShowS)
-> (Hash BlsKey -> String)
-> ([Hash BlsKey] -> ShowS)
-> Show (Hash BlsKey)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Hash BlsKey -> ShowS
showsPrec :: Int -> Hash BlsKey -> ShowS
$cshow :: Hash BlsKey -> String
show :: Hash BlsKey -> String
$cshowList :: [Hash BlsKey] -> ShowS
showList :: [Hash BlsKey] -> ShowS
Show, (forall ann. Hash BlsKey -> Doc ann)
-> (forall ann. [Hash BlsKey] -> Doc ann) -> Pretty (Hash BlsKey)
forall ann. [Hash BlsKey] -> Doc ann
forall ann. Hash BlsKey -> Doc ann
forall a.
(forall ann. a -> Doc ann)
-> (forall ann. [a] -> Doc ann) -> Pretty a
$cpretty :: forall ann. Hash BlsKey -> Doc ann
pretty :: forall ann. Hash BlsKey -> Doc ann
$cprettyList :: forall ann. [Hash BlsKey] -> Doc ann
prettyList :: forall ann. [Hash BlsKey] -> Doc ann
Pretty) via UsingRawBytesHex (Hash BlsKey)
  deriving (Typeable (Hash BlsKey)
Typeable (Hash BlsKey) =>
(Hash BlsKey -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy (Hash BlsKey) -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy [Hash BlsKey] -> Size)
-> ToCBOR (Hash BlsKey)
Hash BlsKey -> Encoding
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [Hash BlsKey] -> Size
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (Hash BlsKey) -> Size
forall a.
Typeable a =>
(a -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> ToCBOR a
$ctoCBOR :: Hash BlsKey -> Encoding
toCBOR :: Hash BlsKey -> Encoding
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (Hash BlsKey) -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (Hash BlsKey) -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [Hash BlsKey] -> Size
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [Hash BlsKey] -> Size
ToCBOR, Typeable (Hash BlsKey)
Typeable (Hash BlsKey) =>
(forall s. Decoder s (Hash BlsKey))
-> (Proxy (Hash BlsKey) -> Text) -> FromCBOR (Hash BlsKey)
Proxy (Hash BlsKey) -> Text
forall s. Decoder s (Hash BlsKey)
forall a.
Typeable a =>
(forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
$cfromCBOR :: forall s. Decoder s (Hash BlsKey)
fromCBOR :: forall s. Decoder s (Hash BlsKey)
$clabel :: Proxy (Hash BlsKey) -> Text
label :: Proxy (Hash BlsKey) -> Text
FromCBOR) via UsingRawBytes (Hash BlsKey)
  deriving anyclass HasTypeProxy (Hash BlsKey)
AsType (Hash BlsKey)
-> ByteString -> Either DecoderError (Hash BlsKey)
HasTypeProxy (Hash BlsKey) =>
(Hash BlsKey -> ByteString)
-> (AsType (Hash BlsKey)
    -> ByteString -> Either DecoderError (Hash BlsKey))
-> SerialiseAsCBOR (Hash BlsKey)
Hash BlsKey -> ByteString
forall a.
HasTypeProxy a =>
(a -> ByteString)
-> (AsType a -> ByteString -> Either DecoderError a)
-> SerialiseAsCBOR a
$cserialiseToCBOR :: Hash BlsKey -> ByteString
serialiseToCBOR :: Hash BlsKey -> ByteString
$cdeserialiseFromCBOR :: AsType (Hash BlsKey)
-> ByteString -> Either DecoderError (Hash BlsKey)
deserialiseFromCBOR :: AsType (Hash BlsKey)
-> ByteString -> Either DecoderError (Hash BlsKey)
SerialiseAsCBOR

instance SerialiseAsRawBytes (Hash BlsKey) where
  serialiseToRawBytes :: Hash BlsKey -> ByteString
serialiseToRawBytes (BlsKeyHash Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN)
vkh) =
    Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN) -> ByteString
forall h a. Hash h a -> ByteString
Crypto.hashToBytes Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN)
vkh

  deserialiseFromRawBytes :: AsType (Hash BlsKey)
-> ByteString -> Either SerialiseAsRawBytesError (Hash BlsKey)
deserialiseFromRawBytes (AsHash AsType BlsKey
R:AsTypeBlsKey
AsBlsKey) ByteString
bs =
    SerialiseAsRawBytesError
-> Maybe (Hash BlsKey)
-> Either SerialiseAsRawBytesError (Hash BlsKey)
forall b a. b -> Maybe a -> Either b a
maybeToRight (String -> SerialiseAsRawBytesError
SerialiseAsRawBytesError String
"Unable to deserialise Hash BlsKey") (Maybe (Hash BlsKey)
 -> Either SerialiseAsRawBytesError (Hash BlsKey))
-> Maybe (Hash BlsKey)
-> Either SerialiseAsRawBytesError (Hash BlsKey)
forall a b. (a -> b) -> a -> b
$
      Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN) -> Hash BlsKey
BlsKeyHash (Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN) -> Hash BlsKey)
-> Maybe (Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN))
-> Maybe (Hash BlsKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Maybe (Hash HASH (VerKeyDSIGN BLS12381MinSigDSIGN))
forall h a. HashAlgorithm h => ByteString -> Maybe (Hash h a)
Crypto.hashFromBytes ByteString
bs

instance HasTextEnvelope (VerificationKey BlsKey) where
  textEnvelopeType :: AsType (VerificationKey BlsKey) -> TextEnvelopeType
  textEnvelopeType :: AsType (VerificationKey BlsKey) -> TextEnvelopeType
textEnvelopeType AsType (VerificationKey BlsKey)
_ =
    TextEnvelopeType
"BlsVerificationKey_"
      TextEnvelopeType -> TextEnvelopeType -> TextEnvelopeType
forall a. Semigroup a => a -> a -> a
<> String -> TextEnvelopeType
forall a. IsString a => String -> a
fromString (Proxy BLS12381MinSigDSIGN -> String
forall v (proxy :: * -> *). DSIGNAlgorithm v => proxy v -> String
forall (proxy :: * -> *). proxy BLS12381MinSigDSIGN -> String
Crypto.algorithmNameDSIGN Proxy BLS12381MinSigDSIGN
proxy)
   where
    proxy :: Proxy Crypto.BLS12381MinSigDSIGN
    proxy :: Proxy BLS12381MinSigDSIGN
proxy = Proxy BLS12381MinSigDSIGN
forall {k} (t :: k). Proxy t
Proxy

  textEnvelopeDefaultDescr :: VerificationKey BlsKey -> TextEnvelopeDescr
  textEnvelopeDefaultDescr :: VerificationKey BlsKey -> TextEnvelopeDescr
textEnvelopeDefaultDescr VerificationKey BlsKey
_ = TextEnvelopeDescr
"BLS12-381 verification key"

instance HasTextEnvelope (SigningKey BlsKey) where
  textEnvelopeType :: AsType (SigningKey BlsKey) -> TextEnvelopeType
  textEnvelopeType :: AsType (SigningKey BlsKey) -> TextEnvelopeType
textEnvelopeType AsType (SigningKey BlsKey)
_ =
    TextEnvelopeType
"BlsSigningKey_"
      TextEnvelopeType -> TextEnvelopeType -> TextEnvelopeType
forall a. Semigroup a => a -> a -> a
<> String -> TextEnvelopeType
forall a. IsString a => String -> a
fromString (Proxy BLS12381MinSigDSIGN -> String
forall v (proxy :: * -> *). DSIGNAlgorithm v => proxy v -> String
forall (proxy :: * -> *). proxy BLS12381MinSigDSIGN -> String
Crypto.algorithmNameDSIGN Proxy BLS12381MinSigDSIGN
proxy)
   where
    proxy :: Proxy Crypto.BLS12381MinSigDSIGN
    proxy :: Proxy BLS12381MinSigDSIGN
proxy = Proxy BLS12381MinSigDSIGN
forall {k} (t :: k). Proxy t
Proxy

  textEnvelopeDefaultDescr :: SigningKey BlsKey -> TextEnvelopeDescr
  textEnvelopeDefaultDescr :: SigningKey BlsKey -> TextEnvelopeDescr
textEnvelopeDefaultDescr SigningKey BlsKey
_ = TextEnvelopeDescr
"BLS12-381 signing key"

-- | BlsPossessionProof is used in the Leios protocol to prove ownership of a BLS signing key
-- when registering a BLS verification key for a stake pool. This is required to prevent malicious
-- actors from registering a BLS verification key for a stake pool without actually owning the
-- corresponding signing key.
newtype BlsPossessionProof = BlsPossessionProof (Crypto.PossessionProofDSIGN Crypto.BLS12381MinSigDSIGN)
  deriving stock BlsPossessionProof -> BlsPossessionProof -> Bool
(BlsPossessionProof -> BlsPossessionProof -> Bool)
-> (BlsPossessionProof -> BlsPossessionProof -> Bool)
-> Eq BlsPossessionProof
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: BlsPossessionProof -> BlsPossessionProof -> Bool
== :: BlsPossessionProof -> BlsPossessionProof -> Bool
$c/= :: BlsPossessionProof -> BlsPossessionProof -> Bool
/= :: BlsPossessionProof -> BlsPossessionProof -> Bool
Eq
  deriving newtype (Typeable BlsPossessionProof
Typeable BlsPossessionProof =>
(BlsPossessionProof -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy BlsPossessionProof -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy [BlsPossessionProof] -> Size)
-> ToCBOR BlsPossessionProof
BlsPossessionProof -> Encoding
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [BlsPossessionProof] -> Size
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy BlsPossessionProof -> Size
forall a.
Typeable a =>
(a -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy a -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size) -> Proxy [a] -> Size)
-> ToCBOR a
$ctoCBOR :: BlsPossessionProof -> Encoding
toCBOR :: BlsPossessionProof -> Encoding
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy BlsPossessionProof -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy BlsPossessionProof -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [BlsPossessionProof] -> Size
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [BlsPossessionProof] -> Size
ToCBOR, Typeable BlsPossessionProof
Typeable BlsPossessionProof =>
(forall s. Decoder s BlsPossessionProof)
-> (Proxy BlsPossessionProof -> Text)
-> FromCBOR BlsPossessionProof
Proxy BlsPossessionProof -> Text
forall s. Decoder s BlsPossessionProof
forall a.
Typeable a =>
(forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
$cfromCBOR :: forall s. Decoder s BlsPossessionProof
fromCBOR :: forall s. Decoder s BlsPossessionProof
$clabel :: Proxy BlsPossessionProof -> Text
label :: Proxy BlsPossessionProof -> Text
FromCBOR)
  deriving anyclass HasTypeProxy BlsPossessionProof
AsType BlsPossessionProof
-> ByteString -> Either DecoderError BlsPossessionProof
HasTypeProxy BlsPossessionProof =>
(BlsPossessionProof -> ByteString)
-> (AsType BlsPossessionProof
    -> ByteString -> Either DecoderError BlsPossessionProof)
-> SerialiseAsCBOR BlsPossessionProof
BlsPossessionProof -> ByteString
forall a.
HasTypeProxy a =>
(a -> ByteString)
-> (AsType a -> ByteString -> Either DecoderError a)
-> SerialiseAsCBOR a
$cserialiseToCBOR :: BlsPossessionProof -> ByteString
serialiseToCBOR :: BlsPossessionProof -> ByteString
$cdeserialiseFromCBOR :: AsType BlsPossessionProof
-> ByteString -> Either DecoderError BlsPossessionProof
deserialiseFromCBOR :: AsType BlsPossessionProof
-> ByteString -> Either DecoderError BlsPossessionProof
SerialiseAsCBOR

instance Show BlsPossessionProof where
  show :: BlsPossessionProof -> String
show BlsPossessionProof
p = String
"blsPossessionProof " String -> ShowS
forall a. [a] -> [a] -> [a]
++ ByteString -> String
forall a. Show a => a -> String
show (BlsPossessionProof -> ByteString
forall a. SerialiseAsRawBytes a => a -> ByteString
serialiseToRawBytesHex BlsPossessionProof
p)

instance Pretty BlsPossessionProof where
  pretty :: forall ann. BlsPossessionProof -> Doc ann
pretty BlsPossessionProof
p = Doc ann
"blsPossessionProof" Doc ann -> Doc ann -> Doc ann
forall ann. Doc ann -> Doc ann -> Doc ann
<+> Text -> Doc ann
forall ann. Text -> Doc ann
forall a ann. Pretty a => a -> Doc ann
pretty (BlsPossessionProof -> Text
forall a. SerialiseAsRawBytes a => a -> Text
serialiseToRawBytesHexText BlsPossessionProof
p)

instance SerialiseAsRawBytes BlsPossessionProof where
  serialiseToRawBytes :: BlsPossessionProof -> ByteString
serialiseToRawBytes (BlsPossessionProof PossessionProofDSIGN BLS12381MinSigDSIGN
proof) =
    PossessionProofDSIGN BLS12381MinSigDSIGN -> ByteString
forall v.
DSIGNAggregatable v =>
PossessionProofDSIGN v -> ByteString
Crypto.rawSerialisePossessionProofDSIGN PossessionProofDSIGN BLS12381MinSigDSIGN
proof

  deserialiseFromRawBytes :: AsType BlsPossessionProof
-> ByteString -> Either SerialiseAsRawBytesError BlsPossessionProof
deserialiseFromRawBytes AsType BlsPossessionProof
R:AsTypeBlsPossessionProof
AsBlsPossessionProof ByteString
bs =
    SerialiseAsRawBytesError
-> Maybe BlsPossessionProof
-> Either SerialiseAsRawBytesError BlsPossessionProof
forall b a. b -> Maybe a -> Either b a
maybeToRight (String -> SerialiseAsRawBytesError
SerialiseAsRawBytesError String
"Unable to deserialise BlsPossessionProof") (Maybe BlsPossessionProof
 -> Either SerialiseAsRawBytesError BlsPossessionProof)
-> Maybe BlsPossessionProof
-> Either SerialiseAsRawBytesError BlsPossessionProof
forall a b. (a -> b) -> a -> b
$
      PossessionProofDSIGN BLS12381MinSigDSIGN -> BlsPossessionProof
BlsPossessionProof (PossessionProofDSIGN BLS12381MinSigDSIGN -> BlsPossessionProof)
-> Maybe (PossessionProofDSIGN BLS12381MinSigDSIGN)
-> Maybe BlsPossessionProof
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Maybe (PossessionProofDSIGN BLS12381MinSigDSIGN)
forall v.
DSIGNAggregatable v =>
ByteString -> Maybe (PossessionProofDSIGN v)
Crypto.rawDeserialisePossessionProofDSIGN ByteString
bs

-- | Construct a 'BlsPossessionProof' from a hex-encoded raw 'ByteString'.
--
-- This is a partial function that calls 'error' if the input is not valid.
-- It is intended to be used with the output of 'show' or 'pretty' to
-- reconstruct a 'BlsPossessionProof' value.
blsPossessionProof :: ByteString -> BlsPossessionProof
blsPossessionProof :: ByteString -> BlsPossessionProof
blsPossessionProof ByteString
hexBs =
  case ByteString -> Either RawBytesHexError BlsPossessionProof
forall a.
SerialiseAsRawBytes a =>
ByteString -> Either RawBytesHexError a
deserialiseFromRawBytesHex ByteString
hexBs of
    Left RawBytesHexError
e -> String -> BlsPossessionProof
forall a. HasCallStack => String -> a
error (String -> BlsPossessionProof) -> String -> BlsPossessionProof
forall a b. (a -> b) -> a -> b
$ String
"blsPossessionProof: " String -> ShowS
forall a. [a] -> [a] -> [a]
++ RawBytesHexError -> String
forall a. Show a => a -> String
show RawBytesHexError
e
    Right BlsPossessionProof
p -> BlsPossessionProof
p

-- | Signing context including the Domain Separation Tag (DST) for the proofs-of-possession of
-- BLS keys using the minimal-signature-size BLS12-381 variant.
--
-- A Domain Separation Tag is a unique tag (like a magic number) that we add to ensure that
-- the signature is used only in the context that it was intended for.
-- This is because BLS keys and signatures can be used for multiple purposes, and
-- we don't want a proof of possession for one purpose to be interpreted as something different
-- in a different context.
minSigPoPContext :: Crypto.BLS12381SignContext
minSigPoPContext :: BLS12381SignContext
minSigPoPContext = Maybe ByteString -> Maybe ByteString -> BLS12381SignContext
Crypto.BLS12381SignContext (ByteString -> Maybe ByteString
forall a. a -> Maybe a
Just ByteString
minSigPoPDST) Maybe ByteString
forall a. Maybe a
Nothing

-- TODO: This is a provisional definition. Import @minSigPoPDST@ from
-- @Cardano.Crypto.DSIGN.BLS12381@ (cardano-crypto-class) when
-- IntersectMBO/cardano-base#635 is merged and the dependency is bumped.
minSigPoPDST :: ByteString
minSigPoPDST :: ByteString
minSigPoPDST = ByteString
"BLS_SIG_BLS12381G1_XMD:SHA-256_SSWU_RO_POP_"

-- | Create a proof of possession for a BLS signing key.
--
-- This proof demonstrates that the holder of a BLS verification key knows the corresponding
-- secret key, which is required before the key can safely participate in signature aggregation.
-- Without this proof, an attacker could register a crafted verification key that cancels out
-- honest participants' keys during aggregation (a rogue key attack).
createBlsPossessionProof :: SigningKey BlsKey -> BlsPossessionProof
createBlsPossessionProof :: SigningKey BlsKey -> BlsPossessionProof
createBlsPossessionProof (BlsSigningKey SignKeyDSIGN BLS12381MinSigDSIGN
sk) =
  PossessionProofDSIGN BLS12381MinSigDSIGN -> BlsPossessionProof
BlsPossessionProof (ContextDSIGN BLS12381MinSigDSIGN
-> SignKeyDSIGN BLS12381MinSigDSIGN
-> PossessionProofDSIGN BLS12381MinSigDSIGN
forall v.
(DSIGNAggregatable v, HasCallStack) =>
ContextDSIGN v -> SignKeyDSIGN v -> PossessionProofDSIGN v
Crypto.createPossessionProofDSIGN ContextDSIGN BLS12381MinSigDSIGN
BLS12381SignContext
minSigPoPContext SignKeyDSIGN BLS12381MinSigDSIGN
sk)

instance HasTypeProxy BlsPossessionProof where
  data AsType BlsPossessionProof = AsBlsPossessionProof
  proxyToAsType :: Proxy BlsPossessionProof -> AsType BlsPossessionProof
proxyToAsType Proxy BlsPossessionProof
_ = AsType BlsPossessionProof
AsBlsPossessionProof

instance HasTextEnvelope BlsPossessionProof where
  textEnvelopeType :: AsType BlsPossessionProof -> TextEnvelopeType
  textEnvelopeType :: AsType BlsPossessionProof -> TextEnvelopeType
textEnvelopeType AsType BlsPossessionProof
_ =
    TextEnvelopeType
"BlsPossessionProof_"
      TextEnvelopeType -> TextEnvelopeType -> TextEnvelopeType
forall a. Semigroup a => a -> a -> a
<> String -> TextEnvelopeType
forall a. IsString a => String -> a
fromString (Proxy BLS12381MinSigDSIGN -> String
forall v (proxy :: * -> *). DSIGNAlgorithm v => proxy v -> String
forall (proxy :: * -> *). proxy BLS12381MinSigDSIGN -> String
Crypto.algorithmNameDSIGN Proxy BLS12381MinSigDSIGN
proxy)
   where
    proxy :: Proxy Crypto.BLS12381MinSigDSIGN
    proxy :: Proxy BLS12381MinSigDSIGN
proxy = Proxy BLS12381MinSigDSIGN
forall {k} (t :: k). Proxy t
Proxy

  textEnvelopeDefaultDescr :: BlsPossessionProof -> TextEnvelopeDescr
  textEnvelopeDefaultDescr :: BlsPossessionProof -> TextEnvelopeDescr
textEnvelopeDefaultDescr BlsPossessionProof
_ = TextEnvelopeDescr
"BLS12-381 possession proof"