{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE UndecidableInstances #-}
{-# OPTIONS_GHC -Wno-orphans #-}

-- | Hydra multi-signature credentials and cryptographic primitives used to sign
-- and verify snapshots (or any messages) within the Hydra protocol.
--
-- We are re-using the 'Key' interface of 'cardano-api' for a consistent
-- representation. For example: Cardano credentials are 'VerificationKey
-- PaymentKey', Hydra credentials are 'VerificationKey HydraKey'.
--
-- Currently 'MultiSignature' interface is only supporting naiive, concatenated
-- multi-signatures and will change when we adopt aggregated multi-signatures
-- including aggregate keys.
module Hydra.Tx.Crypto (
  -- * Cardano Key interface

  --

  -- | NOTE: We re-export 'Key' but deliberately *omit* its
  -- 'getVerificationKey' method. The polymorphic 'getVerificationKey'
  -- exported below (via 'HasVerificationKey') subsumes it and additionally
  -- accepts 'Secret'-wrapped signing keys.
  Key (deterministicSigningKey, deterministicSigningKeySeedSize, verificationKeyHash),

  -- * Hydra specifics
  Hash (HydraKeyHash),
  AsType (AsHydraKey),
  SigningKey (HydraSigningKey),
  VerificationKey (HydraVerificationKey),
  HasVerificationKey (getVerificationKey),
  CanSignTx (signTx),
  module Hydra.Tx.Crypto,

  -- * Re-exports
  getSignableRepresentation,
) where

import Hydra.Prelude hiding (Key, show)

import Cardano.Binary (decodeFull', serialize')
import Cardano.Crypto.DSIGN (
  ContextDSIGN,
  Ed25519DSIGN,
  SigDSIGN,
  SignKeyDSIGN,
  VerKeyDSIGN,
  algorithmNameDSIGN,
  deriveVerKeyDSIGN,
  genKeyDSIGN,
  hashVerKeyDSIGN,
  rawDeserialiseSigDSIGN,
  rawDeserialiseSignKeyDSIGN,
  rawDeserialiseVerKeyDSIGN,
  rawSerialiseSigDSIGN,
  rawSerialiseSignKeyDSIGN,
  rawSerialiseVerKeyDSIGN,
  seedSizeDSIGN,
  signDSIGN,
  verifyDSIGN,
 )
import Cardano.Crypto.Hash (Blake2b_256, SHA256, castHash, hashFromBytes, hashToBytes)
import Cardano.Crypto.Hash qualified as Crypto
import Cardano.Crypto.Hash.Class (HashAlgorithm (digest))
import Cardano.Crypto.Seed (getSeedBytes, mkSeedFromBytes)
import Cardano.Crypto.Util (SignableRepresentation, getSignableRepresentation)
import Control.Exception (TypeError (..), throw)
import Data.Aeson qualified as Aeson
import Data.ByteString.Base16 qualified as Base16
import Data.ByteString.Char8 qualified as BSC
import Data.Map.Strict qualified as Map
import Hydra.Cardano.Api (
  AsType (..),
  BlockHeader,
  HasTextEnvelope (..),
  HasTypeProxy (..),
  Hash,
  Key (deterministicSigningKey, deterministicSigningKeySeedSize, verificationKeyHash),
  ScriptData (..),
  SerialiseAsCBOR (..),
  SerialiseAsRawBytes (..),
  SerialiseAsRawBytesError (..),
  SigningKey,
  TxId (..),
  UsingRawBytesHex (..),
  VerificationKey,
  serialiseToRawBytesHexText,
 )
import Hydra.Cardano.Api qualified as Cardano
import Hydra.Contract.HeadState qualified as OnChain
import Hydra.Tx.Secret (Forbid, Secret, mkSecret, withSecret)
import PlutusLedgerApi.V3 qualified as Plutus
import Text.Show (Show (..))

-- * Hydra keys

-- | Hydra keys (keyrole) which can be used to 'sign' and 'verify' messages, as
-- well as 'aggregate' multi-signatures.
data HydraKey

instance HasTypeProxy HydraKey where
  data AsType HydraKey = AsHydraKey
  proxyToAsType :: Proxy HydraKey -> AsType HydraKey
proxyToAsType Proxy HydraKey
_ = AsType HydraKey
AsHydraKey

-- | Hashes of Hydra keys
newtype instance Hash HydraKey
  = HydraKeyHash (Crypto.Hash Blake2b_256 (VerificationKey HydraKey))
  deriving stock (Eq (Hash HydraKey)
Eq (Hash HydraKey) =>
(Hash HydraKey -> Hash HydraKey -> Ordering)
-> (Hash HydraKey -> Hash HydraKey -> Bool)
-> (Hash HydraKey -> Hash HydraKey -> Bool)
-> (Hash HydraKey -> Hash HydraKey -> Bool)
-> (Hash HydraKey -> Hash HydraKey -> Bool)
-> (Hash HydraKey -> Hash HydraKey -> Hash HydraKey)
-> (Hash HydraKey -> Hash HydraKey -> Hash HydraKey)
-> Ord (Hash HydraKey)
Hash HydraKey -> Hash HydraKey -> Bool
Hash HydraKey -> Hash HydraKey -> Ordering
Hash HydraKey -> Hash HydraKey -> Hash HydraKey
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 HydraKey -> Hash HydraKey -> Ordering
compare :: Hash HydraKey -> Hash HydraKey -> Ordering
$c< :: Hash HydraKey -> Hash HydraKey -> Bool
< :: Hash HydraKey -> Hash HydraKey -> Bool
$c<= :: Hash HydraKey -> Hash HydraKey -> Bool
<= :: Hash HydraKey -> Hash HydraKey -> Bool
$c> :: Hash HydraKey -> Hash HydraKey -> Bool
> :: Hash HydraKey -> Hash HydraKey -> Bool
$c>= :: Hash HydraKey -> Hash HydraKey -> Bool
>= :: Hash HydraKey -> Hash HydraKey -> Bool
$cmax :: Hash HydraKey -> Hash HydraKey -> Hash HydraKey
max :: Hash HydraKey -> Hash HydraKey -> Hash HydraKey
$cmin :: Hash HydraKey -> Hash HydraKey -> Hash HydraKey
min :: Hash HydraKey -> Hash HydraKey -> Hash HydraKey
Ord, Hash HydraKey -> Hash HydraKey -> Bool
(Hash HydraKey -> Hash HydraKey -> Bool)
-> (Hash HydraKey -> Hash HydraKey -> Bool) -> Eq (Hash HydraKey)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Hash HydraKey -> Hash HydraKey -> Bool
== :: Hash HydraKey -> Hash HydraKey -> Bool
$c/= :: Hash HydraKey -> Hash HydraKey -> Bool
/= :: Hash HydraKey -> Hash HydraKey -> Bool
Eq, Int -> Hash HydraKey -> ShowS
[Hash HydraKey] -> ShowS
Hash HydraKey -> String
(Int -> Hash HydraKey -> ShowS)
-> (Hash HydraKey -> String)
-> ([Hash HydraKey] -> ShowS)
-> Show (Hash HydraKey)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Hash HydraKey -> ShowS
showsPrec :: Int -> Hash HydraKey -> ShowS
$cshow :: Hash HydraKey -> String
show :: Hash HydraKey -> String
$cshowList :: [Hash HydraKey] -> ShowS
showList :: [Hash HydraKey] -> ShowS
Show)

instance SerialiseAsRawBytes (Hash HydraKey) where
  serialiseToRawBytes :: Hash HydraKey -> ByteString
serialiseToRawBytes (HydraKeyHash Hash Blake2b_256 (VerificationKey HydraKey)
vkh) = Hash Blake2b_256 (VerificationKey HydraKey) -> ByteString
forall h a. Hash h a -> ByteString
hashToBytes Hash Blake2b_256 (VerificationKey HydraKey)
vkh

  deserialiseFromRawBytes :: AsType (Hash HydraKey)
-> ByteString -> Either SerialiseAsRawBytesError (Hash HydraKey)
deserialiseFromRawBytes (AsHash AsType HydraKey
R:AsTypeHydraKey
AsHydraKey) ByteString
bs =
    Either SerialiseAsRawBytesError (Hash HydraKey)
-> (Hash Blake2b_256 (VerificationKey HydraKey)
    -> Either SerialiseAsRawBytesError (Hash HydraKey))
-> Maybe (Hash Blake2b_256 (VerificationKey HydraKey))
-> Either SerialiseAsRawBytesError (Hash HydraKey)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (SerialiseAsRawBytesError
-> Either SerialiseAsRawBytesError (Hash HydraKey)
forall a b. a -> Either a b
Left (SerialiseAsRawBytesError
 -> Either SerialiseAsRawBytesError (Hash HydraKey))
-> SerialiseAsRawBytesError
-> Either SerialiseAsRawBytesError (Hash HydraKey)
forall a b. (a -> b) -> a -> b
$ String -> SerialiseAsRawBytesError
SerialiseAsRawBytesError String
"invalid length when deserializing Hash HydraKey")
      (Hash HydraKey -> Either SerialiseAsRawBytesError (Hash HydraKey)
forall a b. b -> Either a b
Right (Hash HydraKey -> Either SerialiseAsRawBytesError (Hash HydraKey))
-> (Hash Blake2b_256 (VerificationKey HydraKey) -> Hash HydraKey)
-> Hash Blake2b_256 (VerificationKey HydraKey)
-> Either SerialiseAsRawBytesError (Hash HydraKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash Blake2b_256 (VerificationKey HydraKey) -> Hash HydraKey
HydraKeyHash)
      (ByteString -> Maybe (Hash Blake2b_256 (VerificationKey HydraKey))
forall h a. HashAlgorithm h => ByteString -> Maybe (Hash h a)
hashFromBytes ByteString
bs)

instance SerialiseAsRawBytes a => IsString (UsingRawBytesHex a) where
  fromString :: String -> UsingRawBytesHex a
fromString =
    (RawBytesHexError -> UsingRawBytesHex a)
-> (a -> UsingRawBytesHex a)
-> Either RawBytesHexError a
-> UsingRawBytesHex a
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Text -> UsingRawBytesHex a
forall a t. (HasCallStack, IsText t) => t -> a
error (Text -> UsingRawBytesHex a)
-> (RawBytesHexError -> Text)
-> RawBytesHexError
-> UsingRawBytesHex a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Doc AnsiStyle -> Text
Cardano.docToText (Doc AnsiStyle -> Text)
-> (RawBytesHexError -> Doc AnsiStyle) -> RawBytesHexError -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawBytesHexError -> Doc AnsiStyle
forall e ann. Error e => e -> Doc ann
forall ann. RawBytesHexError -> Doc ann
Cardano.prettyError) a -> UsingRawBytesHex a
forall a. a -> UsingRawBytesHex a
UsingRawBytesHex
      (Either RawBytesHexError a -> UsingRawBytesHex a)
-> (String -> Either RawBytesHexError a)
-> String
-> UsingRawBytesHex a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either RawBytesHexError a
forall a.
SerialiseAsRawBytes a =>
ByteString -> Either RawBytesHexError a
Cardano.deserialiseFromRawBytesHex
      (ByteString -> Either RawBytesHexError a)
-> (String -> ByteString) -> String -> Either RawBytesHexError a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> ByteString
BSC.pack

deriving via UsingRawBytesHex (Hash BlockHeader) instance IsString (Hash BlockHeader)
deriving via UsingRawBytesHex TxId instance IsString TxId
deriving via UsingRawBytesHex (Hash ScriptData) instance IsString (Hash ScriptData)

instance Key HydraKey where
  -- Hydra verification key, which can be used to 'verify' signed messages.
  newtype VerificationKey HydraKey
    = HydraVerificationKey (VerKeyDSIGN Ed25519DSIGN)
    deriving stock (VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
(VerificationKey HydraKey -> VerificationKey HydraKey -> Bool)
-> (VerificationKey HydraKey -> VerificationKey HydraKey -> Bool)
-> Eq (VerificationKey HydraKey)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
== :: VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
$c/= :: VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
/= :: VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
Eq, Eq (VerificationKey HydraKey)
Eq (VerificationKey HydraKey) =>
(VerificationKey HydraKey -> VerificationKey HydraKey -> Ordering)
-> (VerificationKey HydraKey -> VerificationKey HydraKey -> Bool)
-> (VerificationKey HydraKey -> VerificationKey HydraKey -> Bool)
-> (VerificationKey HydraKey -> VerificationKey HydraKey -> Bool)
-> (VerificationKey HydraKey -> VerificationKey HydraKey -> Bool)
-> (VerificationKey HydraKey
    -> VerificationKey HydraKey -> VerificationKey HydraKey)
-> (VerificationKey HydraKey
    -> VerificationKey HydraKey -> VerificationKey HydraKey)
-> Ord (VerificationKey HydraKey)
(TypeError ...) => Eq (VerificationKey HydraKey)
(TypeError ...) =>
VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
(TypeError ...) =>
VerificationKey HydraKey -> VerificationKey HydraKey -> Ordering
(TypeError ...) =>
VerificationKey HydraKey
-> VerificationKey HydraKey -> VerificationKey HydraKey
VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
VerificationKey HydraKey -> VerificationKey HydraKey -> Ordering
VerificationKey HydraKey
-> VerificationKey HydraKey -> VerificationKey HydraKey
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 :: (TypeError ...) =>
VerificationKey HydraKey -> VerificationKey HydraKey -> Ordering
compare :: VerificationKey HydraKey -> VerificationKey HydraKey -> Ordering
$c< :: (TypeError ...) =>
VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
< :: VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
$c<= :: (TypeError ...) =>
VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
<= :: VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
$c> :: (TypeError ...) =>
VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
> :: VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
$c>= :: (TypeError ...) =>
VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
>= :: VerificationKey HydraKey -> VerificationKey HydraKey -> Bool
$cmax :: (TypeError ...) =>
VerificationKey HydraKey
-> VerificationKey HydraKey -> VerificationKey HydraKey
max :: VerificationKey HydraKey
-> VerificationKey HydraKey -> VerificationKey HydraKey
$cmin :: (TypeError ...) =>
VerificationKey HydraKey
-> VerificationKey HydraKey -> VerificationKey HydraKey
min :: VerificationKey HydraKey
-> VerificationKey HydraKey -> VerificationKey HydraKey
Ord)
    deriving (Int -> VerificationKey HydraKey -> ShowS
[VerificationKey HydraKey] -> ShowS
VerificationKey HydraKey -> String
(Int -> VerificationKey HydraKey -> ShowS)
-> (VerificationKey HydraKey -> String)
-> ([VerificationKey HydraKey] -> ShowS)
-> Show (VerificationKey HydraKey)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> VerificationKey HydraKey -> ShowS
showsPrec :: Int -> VerificationKey HydraKey -> ShowS
$cshow :: VerificationKey HydraKey -> String
show :: VerificationKey HydraKey -> String
$cshowList :: [VerificationKey HydraKey] -> ShowS
showList :: [VerificationKey HydraKey] -> ShowS
Show, String -> VerificationKey HydraKey
(String -> VerificationKey HydraKey)
-> IsString (VerificationKey HydraKey)
forall a. (String -> a) -> IsString a
$cfromString :: String -> VerificationKey HydraKey
fromString :: String -> VerificationKey HydraKey
IsString) via UsingRawBytesHex (VerificationKey HydraKey)
    deriving newtype (Typeable (VerificationKey HydraKey)
Typeable (VerificationKey HydraKey) =>
(VerificationKey HydraKey -> Encoding)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy (VerificationKey HydraKey) -> Size)
-> ((forall t. ToCBOR t => Proxy t -> Size)
    -> Proxy [VerificationKey HydraKey] -> Size)
-> ToCBOR (VerificationKey HydraKey)
VerificationKey HydraKey -> Encoding
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerificationKey HydraKey] -> Size
(forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerificationKey HydraKey) -> 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 HydraKey -> Encoding
toCBOR :: VerificationKey HydraKey -> Encoding
$cencodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerificationKey HydraKey) -> Size
encodedSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy (VerificationKey HydraKey) -> Size
$cencodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerificationKey HydraKey] -> Size
encodedListSizeExpr :: (forall t. ToCBOR t => Proxy t -> Size)
-> Proxy [VerificationKey HydraKey] -> Size
ToCBOR, Typeable (VerificationKey HydraKey)
Typeable (VerificationKey HydraKey) =>
(forall s. Decoder s (VerificationKey HydraKey))
-> (Proxy (VerificationKey HydraKey) -> Text)
-> FromCBOR (VerificationKey HydraKey)
Proxy (VerificationKey HydraKey) -> Text
forall s. Decoder s (VerificationKey HydraKey)
forall a.
Typeable a =>
(forall s. Decoder s a) -> (Proxy a -> Text) -> FromCBOR a
$cfromCBOR :: forall s. Decoder s (VerificationKey HydraKey)
fromCBOR :: forall s. Decoder s (VerificationKey HydraKey)
$clabel :: Proxy (VerificationKey HydraKey) -> Text
label :: Proxy (VerificationKey HydraKey) -> Text
FromCBOR)
    deriving anyclass (HasTypeProxy (VerificationKey HydraKey)
AsType (VerificationKey HydraKey)
-> ByteString -> Either DecoderError (VerificationKey HydraKey)
HasTypeProxy (VerificationKey HydraKey) =>
(VerificationKey HydraKey -> ByteString)
-> (AsType (VerificationKey HydraKey)
    -> ByteString -> Either DecoderError (VerificationKey HydraKey))
-> SerialiseAsCBOR (VerificationKey HydraKey)
VerificationKey HydraKey -> ByteString
forall a.
HasTypeProxy a =>
(a -> ByteString)
-> (AsType a -> ByteString -> Either DecoderError a)
-> SerialiseAsCBOR a
$cserialiseToCBOR :: VerificationKey HydraKey -> ByteString
serialiseToCBOR :: VerificationKey HydraKey -> ByteString
$cdeserialiseFromCBOR :: AsType (VerificationKey HydraKey)
-> ByteString -> Either DecoderError (VerificationKey HydraKey)
deserialiseFromCBOR :: AsType (VerificationKey HydraKey)
-> ByteString -> Either DecoderError (VerificationKey HydraKey)
SerialiseAsCBOR)

  -- Hydra signing key which can be used to 'sign' messages and 'aggregate'
  -- multi-signatures or 'deriveVerificationKey'.
  --
  -- No 'Show', 'ToJSON', 'FromJSON', 'ToCBOR' or 'FromCBOR' is provided:
  -- those are the channels through which a key could accidentally leak
  -- (logs, API responses, on-disk persistence). They are forbidden via
  -- 'Forbid'-bearing 'TypeError' instances further down, so any caller
  -- that tries to use one gets a precise compile error.
  --
  -- Wrap in 'Hydra.Tx.Secret.Secret' at the field level to extend the
  -- ban to enclosing records (their @deriving stock (Show)@ /
  -- @deriving anyclass (ToJSON)@ then propagates to the same custom
  -- error).
  newtype SigningKey HydraKey
    = HydraSigningKey (SignKeyDSIGN Ed25519DSIGN)
    deriving stock (SigningKey HydraKey -> SigningKey HydraKey -> Bool
(SigningKey HydraKey -> SigningKey HydraKey -> Bool)
-> (SigningKey HydraKey -> SigningKey HydraKey -> Bool)
-> Eq (SigningKey HydraKey)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: SigningKey HydraKey -> SigningKey HydraKey -> Bool
== :: SigningKey HydraKey -> SigningKey HydraKey -> Bool
$c/= :: SigningKey HydraKey -> SigningKey HydraKey -> Bool
/= :: SigningKey HydraKey -> SigningKey HydraKey -> Bool
Eq, Eq (SigningKey HydraKey)
Eq (SigningKey HydraKey) =>
(SigningKey HydraKey -> SigningKey HydraKey -> Ordering)
-> (SigningKey HydraKey -> SigningKey HydraKey -> Bool)
-> (SigningKey HydraKey -> SigningKey HydraKey -> Bool)
-> (SigningKey HydraKey -> SigningKey HydraKey -> Bool)
-> (SigningKey HydraKey -> SigningKey HydraKey -> Bool)
-> (SigningKey HydraKey
    -> SigningKey HydraKey -> SigningKey HydraKey)
-> (SigningKey HydraKey
    -> SigningKey HydraKey -> SigningKey HydraKey)
-> Ord (SigningKey HydraKey)
(TypeError ...) => Eq (SigningKey HydraKey)
(TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> Bool
(TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> Ordering
(TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> SigningKey HydraKey
SigningKey HydraKey -> SigningKey HydraKey -> Bool
SigningKey HydraKey -> SigningKey HydraKey -> Ordering
SigningKey HydraKey -> SigningKey HydraKey -> SigningKey HydraKey
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 :: (TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> Ordering
compare :: SigningKey HydraKey -> SigningKey HydraKey -> Ordering
$c< :: (TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> Bool
< :: SigningKey HydraKey -> SigningKey HydraKey -> Bool
$c<= :: (TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> Bool
<= :: SigningKey HydraKey -> SigningKey HydraKey -> Bool
$c> :: (TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> Bool
> :: SigningKey HydraKey -> SigningKey HydraKey -> Bool
$c>= :: (TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> Bool
>= :: SigningKey HydraKey -> SigningKey HydraKey -> Bool
$cmax :: (TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> SigningKey HydraKey
max :: SigningKey HydraKey -> SigningKey HydraKey -> SigningKey HydraKey
$cmin :: (TypeError ...) =>
SigningKey HydraKey -> SigningKey HydraKey -> SigningKey HydraKey
min :: SigningKey HydraKey -> SigningKey HydraKey -> SigningKey HydraKey
Ord)
    deriving (String -> SigningKey HydraKey
(String -> SigningKey HydraKey) -> IsString (SigningKey HydraKey)
forall a. (String -> a) -> IsString a
$cfromString :: String -> SigningKey HydraKey
fromString :: String -> SigningKey HydraKey
IsString) via UsingRawBytesHex (SigningKey HydraKey)

  -- Get the 'VerificationKey' for a given 'SigningKey'.
  getVerificationKey :: HasTypeProxy HydraKey =>
SigningKey HydraKey -> VerificationKey HydraKey
getVerificationKey (HydraSigningKey SignKeyDSIGN Ed25519DSIGN
sk) =
    VerKeyDSIGN Ed25519DSIGN -> VerificationKey HydraKey
HydraVerificationKey (VerKeyDSIGN Ed25519DSIGN -> VerificationKey HydraKey)
-> VerKeyDSIGN Ed25519DSIGN -> VerificationKey HydraKey
forall a b. (a -> b) -> a -> b
$ SignKeyDSIGN Ed25519DSIGN -> VerKeyDSIGN Ed25519DSIGN
forall v. DSIGNAlgorithm v => SignKeyDSIGN v -> VerKeyDSIGN v
deriveVerKeyDSIGN SignKeyDSIGN Ed25519DSIGN
sk

  -- Create a new 'SigningKey' from a 'Seed'. The 'cardano-api' 'Key'
  -- class returns a raw 'SigningKey'; callers (in tests / setup paths)
  -- should immediately wrap the result with 'mkSecret'. The
  -- public-facing 'generateSigningKey' below already does this.
  deterministicSigningKey :: AsType HydraKey -> Seed -> SigningKey HydraKey
deterministicSigningKey AsType HydraKey
R:AsTypeHydraKey
AsHydraKey Seed
seed =
    SignKeyDSIGN Ed25519DSIGN -> SigningKey HydraKey
HydraSigningKey (SignKeyDSIGN Ed25519DSIGN -> SigningKey HydraKey)
-> (Seed -> SignKeyDSIGN Ed25519DSIGN)
-> Seed
-> SigningKey HydraKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seed -> SignKeyDSIGN Ed25519DSIGN
forall v. DSIGNAlgorithm v => Seed -> SignKeyDSIGN v
genKeyDSIGN (Seed -> SigningKey HydraKey) -> Seed -> SigningKey HydraKey
forall a b. (a -> b) -> a -> b
$ ByteString -> Seed
mkSeedFromBytes (Seed -> ByteString
getSeedBytes Seed
seed)

  -- Get the number of bytes required to seed a signing key with
  -- 'deterministicSigningKey'.
  deterministicSigningKeySeedSize :: AsType HydraKey -> Word
deterministicSigningKeySeedSize AsType HydraKey
R:AsTypeHydraKey
AsHydraKey =
    Proxy Ed25519DSIGN -> Word
forall v (proxy :: * -> *). DSIGNAlgorithm v => proxy v -> Word
seedSizeDSIGN (Proxy Ed25519DSIGN
forall {k} (t :: k). Proxy t
Proxy :: Proxy Ed25519DSIGN)

  -- Get the verification key hash of a 'VerificationKey'. See 'Blake2b_256' for
  -- info on the used hashing algorithm.
  verificationKeyHash :: VerificationKey HydraKey -> Hash HydraKey
verificationKeyHash (HydraVerificationKey VerKeyDSIGN Ed25519DSIGN
vk) =
    Hash Blake2b_256 (VerificationKey HydraKey) -> Hash HydraKey
HydraKeyHash (Hash Blake2b_256 (VerificationKey HydraKey) -> Hash HydraKey)
-> (Hash Blake2b_256 (VerKeyDSIGN Ed25519DSIGN)
    -> Hash Blake2b_256 (VerificationKey HydraKey))
-> Hash Blake2b_256 (VerKeyDSIGN Ed25519DSIGN)
-> Hash HydraKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Hash Blake2b_256 (VerKeyDSIGN Ed25519DSIGN)
-> Hash Blake2b_256 (VerificationKey HydraKey)
forall h a b. Hash h a -> Hash h b
castHash (Hash Blake2b_256 (VerKeyDSIGN Ed25519DSIGN) -> Hash HydraKey)
-> Hash Blake2b_256 (VerKeyDSIGN Ed25519DSIGN) -> Hash HydraKey
forall a b. (a -> b) -> a -> b
$ VerKeyDSIGN Ed25519DSIGN
-> Hash Blake2b_256 (VerKeyDSIGN Ed25519DSIGN)
forall h.
HashAlgorithm h =>
VerKeyDSIGN Ed25519DSIGN -> Hash h (VerKeyDSIGN Ed25519DSIGN)
forall v h.
(DSIGNAlgorithm v, HashAlgorithm h) =>
VerKeyDSIGN v -> Hash h (VerKeyDSIGN v)
hashVerKeyDSIGN VerKeyDSIGN Ed25519DSIGN
vk

-- | Polymorphic 'getVerificationKey' that works on either a raw
-- 'SigningKey k' or a 'Secret'-wrapped 'Secret (SigningKey k)'. This
-- subsumes the cardano-api 'Key' class method of the same name and is
-- what 'Hydra.Tx.Crypto' re-exports. Callers can write
-- @getVerificationKey sk@ regardless of whether @sk@ is wrapped.
class HasVerificationKey s k | s -> k where
  getVerificationKey :: s -> VerificationKey k

instance (Key k, HasTypeProxy k) => HasVerificationKey (SigningKey k) k where
  getVerificationKey :: SigningKey k -> VerificationKey k
getVerificationKey = SigningKey k -> VerificationKey k
forall k.
(Key k, HasTypeProxy k) =>
SigningKey k -> VerificationKey k
Cardano.getVerificationKey

instance (Key k, HasTypeProxy k) => HasVerificationKey (Secret (SigningKey k)) k where
  getVerificationKey :: Secret (SigningKey k) -> VerificationKey k
getVerificationKey Secret (SigningKey k)
s = Secret (SigningKey k)
-> (SigningKey k -> VerificationKey k) -> VerificationKey k
forall a r. Secret a -> (a -> r) -> r
withSecret Secret (SigningKey k)
s SigningKey k -> VerificationKey k
forall k.
(Key k, HasTypeProxy k) =>
SigningKey k -> VerificationKey k
Cardano.getVerificationKey

-- | Polymorphic 'signTx' that accepts either a raw 'SigningKey PaymentKey'
-- or a 'Secret'-wrapped one. Production paths thread 'Secret' here and
-- benefit from the wrap-free call shape; tests can still pass raw keys.
class CanSignTx s where
  signTx :: s -> Cardano.Tx -> Cardano.Tx

instance CanSignTx (SigningKey Cardano.PaymentKey) where
  signTx :: SigningKey PaymentKey -> Tx -> Tx
signTx = SigningKey PaymentKey -> Tx -> Tx
forall era.
IsShelleyBasedEra era =>
SigningKey PaymentKey -> Tx era -> Tx era
Cardano.signTx

instance CanSignTx (Secret (SigningKey Cardano.PaymentKey)) where
  signTx :: Secret (SigningKey PaymentKey) -> Tx -> Tx
signTx Secret (SigningKey PaymentKey)
s Tx
tx = Secret (SigningKey PaymentKey)
-> (SigningKey PaymentKey -> Tx) -> Tx
forall a r. Secret a -> (a -> r) -> r
withSecret Secret (SigningKey PaymentKey)
s (SigningKey PaymentKey -> Tx -> Tx
forall era.
IsShelleyBasedEra era =>
SigningKey PaymentKey -> Tx era -> Tx era
`Cardano.signTx` Tx
tx)

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

instance SerialiseAsRawBytes (SigningKey HydraKey) where
  serialiseToRawBytes :: SigningKey HydraKey -> ByteString
serialiseToRawBytes (HydraSigningKey SignKeyDSIGN Ed25519DSIGN
sk) =
    SignKeyDSIGN Ed25519DSIGN -> ByteString
forall v. DSIGNAlgorithm v => SignKeyDSIGN v -> ByteString
rawSerialiseSignKeyDSIGN SignKeyDSIGN Ed25519DSIGN
sk

  deserialiseFromRawBytes :: AsType (SigningKey HydraKey)
-> ByteString
-> Either SerialiseAsRawBytesError (SigningKey HydraKey)
deserialiseFromRawBytes (AsSigningKey AsType HydraKey
R:AsTypeHydraKey
AsHydraKey) ByteString
bs =
    Either SerialiseAsRawBytesError (SigningKey HydraKey)
-> (SignKeyDSIGN Ed25519DSIGN
    -> Either SerialiseAsRawBytesError (SigningKey HydraKey))
-> Maybe (SignKeyDSIGN Ed25519DSIGN)
-> Either SerialiseAsRawBytesError (SigningKey HydraKey)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (SerialiseAsRawBytesError
-> Either SerialiseAsRawBytesError (SigningKey HydraKey)
forall a b. a -> Either a b
Left (String -> SerialiseAsRawBytesError
SerialiseAsRawBytesError String
"invalid length when deserializing SigningKey HydraKey"))
      (SigningKey HydraKey
-> Either SerialiseAsRawBytesError (SigningKey HydraKey)
forall a b. b -> Either a b
Right (SigningKey HydraKey
 -> Either SerialiseAsRawBytesError (SigningKey HydraKey))
-> (SignKeyDSIGN Ed25519DSIGN -> SigningKey HydraKey)
-> SignKeyDSIGN Ed25519DSIGN
-> Either SerialiseAsRawBytesError (SigningKey HydraKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SignKeyDSIGN Ed25519DSIGN -> SigningKey HydraKey
HydraSigningKey)
      (ByteString -> Maybe (SignKeyDSIGN Ed25519DSIGN)
forall v. DSIGNAlgorithm v => ByteString -> Maybe (SignKeyDSIGN v)
rawDeserialiseSignKeyDSIGN ByteString
bs)

instance SerialiseAsRawBytes (VerificationKey HydraKey) where
  serialiseToRawBytes :: VerificationKey HydraKey -> ByteString
serialiseToRawBytes (HydraVerificationKey VerKeyDSIGN Ed25519DSIGN
vk) =
    VerKeyDSIGN Ed25519DSIGN -> ByteString
forall v. DSIGNAlgorithm v => VerKeyDSIGN v -> ByteString
rawSerialiseVerKeyDSIGN VerKeyDSIGN Ed25519DSIGN
vk

  deserialiseFromRawBytes :: AsType (VerificationKey HydraKey)
-> ByteString
-> Either SerialiseAsRawBytesError (VerificationKey HydraKey)
deserialiseFromRawBytes (AsVerificationKey AsType HydraKey
R:AsTypeHydraKey
AsHydraKey) ByteString
bs =
    Either SerialiseAsRawBytesError (VerificationKey HydraKey)
-> (VerKeyDSIGN Ed25519DSIGN
    -> Either SerialiseAsRawBytesError (VerificationKey HydraKey))
-> Maybe (VerKeyDSIGN Ed25519DSIGN)
-> Either SerialiseAsRawBytesError (VerificationKey HydraKey)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (SerialiseAsRawBytesError
-> Either SerialiseAsRawBytesError (VerificationKey HydraKey)
forall a b. a -> Either a b
Left (SerialiseAsRawBytesError
 -> Either SerialiseAsRawBytesError (VerificationKey HydraKey))
-> SerialiseAsRawBytesError
-> Either SerialiseAsRawBytesError (VerificationKey HydraKey)
forall a b. (a -> b) -> a -> b
$ String -> SerialiseAsRawBytesError
SerialiseAsRawBytesError String
"invalid length when deserializing VerificationKey HydraKey")
      (VerificationKey HydraKey
-> Either SerialiseAsRawBytesError (VerificationKey HydraKey)
forall a b. b -> Either a b
Right (VerificationKey HydraKey
 -> Either SerialiseAsRawBytesError (VerificationKey HydraKey))
-> (VerKeyDSIGN Ed25519DSIGN -> VerificationKey HydraKey)
-> VerKeyDSIGN Ed25519DSIGN
-> Either SerialiseAsRawBytesError (VerificationKey HydraKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VerKeyDSIGN Ed25519DSIGN -> VerificationKey HydraKey
HydraVerificationKey)
      (ByteString -> Maybe (VerKeyDSIGN Ed25519DSIGN)
forall v. DSIGNAlgorithm v => ByteString -> Maybe (VerKeyDSIGN v)
rawDeserialiseVerKeyDSIGN ByteString
bs)

instance ToJSON (VerificationKey HydraKey) where
  toJSON :: VerificationKey HydraKey -> Value
toJSON = Text -> Value
forall a. ToJSON a => a -> Value
toJSON (Text -> Value)
-> (VerificationKey HydraKey -> Text)
-> VerificationKey HydraKey
-> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VerificationKey HydraKey -> Text
forall a. SerialiseAsRawBytes a => a -> Text
serialiseToRawBytesHexText

-- TODO: It would be nice(r) to have a bech32 representation for verification
-- keys BUT cardano-api decided to not expose the class internals which makes it
-- impossible to define new instances for that class :upside-down-smiling-face:
--
-- instance SerialiseAsBech32 VerificationKey where
--  bech32PrefixFor = const "hydra_vk"
--  bech32PrefixesPermitted _ = ["hydra_vk"]

instance FromJSON (VerificationKey HydraKey) where
  parseJSON :: Value -> Parser (VerificationKey HydraKey)
parseJSON = String
-> (Text -> Parser (VerificationKey HydraKey))
-> Value
-> Parser (VerificationKey HydraKey)
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText String
"VerificationKey" ((Text -> Parser (VerificationKey HydraKey))
 -> Value -> Parser (VerificationKey HydraKey))
-> (Text -> Parser (VerificationKey HydraKey))
-> Value
-> Parser (VerificationKey HydraKey)
forall a b. (a -> b) -> a -> b
$ Text -> Parser ByteString
forall (f :: * -> *). MonadFail f => Text -> f ByteString
decodeBase16 (Text -> Parser ByteString)
-> (ByteString -> Parser (VerificationKey HydraKey))
-> Text
-> Parser (VerificationKey HydraKey)
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> ByteString -> Parser (VerificationKey HydraKey)
deserialiseKey
   where
    deserialiseKey :: ByteString -> Parser (VerificationKey HydraKey)
deserialiseKey =
      Parser (VerificationKey HydraKey)
-> (VerKeyDSIGN Ed25519DSIGN -> Parser (VerificationKey HydraKey))
-> Maybe (VerKeyDSIGN Ed25519DSIGN)
-> Parser (VerificationKey HydraKey)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
        (String -> Parser (VerificationKey HydraKey)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"unable to deserialize VerificationKey, wrong length")
        (VerificationKey HydraKey -> Parser (VerificationKey HydraKey)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (VerificationKey HydraKey -> Parser (VerificationKey HydraKey))
-> (VerKeyDSIGN Ed25519DSIGN -> VerificationKey HydraKey)
-> VerKeyDSIGN Ed25519DSIGN
-> Parser (VerificationKey HydraKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. VerKeyDSIGN Ed25519DSIGN -> VerificationKey HydraKey
HydraVerificationKey)
        (Maybe (VerKeyDSIGN Ed25519DSIGN)
 -> Parser (VerificationKey HydraKey))
-> (ByteString -> Maybe (VerKeyDSIGN Ed25519DSIGN))
-> ByteString
-> Parser (VerificationKey HydraKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Maybe (VerKeyDSIGN Ed25519DSIGN)
forall v. DSIGNAlgorithm v => ByteString -> Maybe (VerKeyDSIGN v)
rawDeserialiseVerKeyDSIGN

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

-- | CBOR encode by delegating to the inner 'SignKeyDSIGN' (which has its own
-- 'ToCBOR' / 'FromCBOR'). This keeps the on-disk text-envelope format
-- identical to the previous newtype-derived encoding, while leaving
-- 'ToCBOR' / 'FromCBOR' on 'SigningKey HydraKey' itself forbidden.
instance SerialiseAsCBOR (SigningKey HydraKey) where
  serialiseToCBOR :: SigningKey HydraKey -> ByteString
serialiseToCBOR (HydraSigningKey SignKeyDSIGN Ed25519DSIGN
sk) = SignKeyDSIGN Ed25519DSIGN -> ByteString
forall a. ToCBOR a => a -> ByteString
serialize' SignKeyDSIGN Ed25519DSIGN
sk
  deserialiseFromCBOR :: AsType (SigningKey HydraKey)
-> ByteString -> Either DecoderError (SigningKey HydraKey)
deserialiseFromCBOR AsType (SigningKey HydraKey)
_ ByteString
bs = SignKeyDSIGN Ed25519DSIGN -> SigningKey HydraKey
HydraSigningKey (SignKeyDSIGN Ed25519DSIGN -> SigningKey HydraKey)
-> Either DecoderError (SignKeyDSIGN Ed25519DSIGN)
-> Either DecoderError (SigningKey HydraKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ByteString -> Either DecoderError (SignKeyDSIGN Ed25519DSIGN)
forall a. FromCBOR a => ByteString -> Either DecoderError a
decodeFull' ByteString
bs

-- Refuse 'ToJSON', 'FromJSON', 'ToCBOR' and 'FromCBOR' on raw signing
-- keys. No 'Show' instance is provided either: every holder of a
-- signing key in this codebase wraps it in 'Hydra.Tx.Secret.Secret', so
-- the rendering / serialisation goes through Secret's instances (Secret
-- has a redacting 'Show' and 'TypeError'-bearing JSON/CBOR instances).
-- Any code that tries to Show / JSON / CBOR a raw 'SigningKey HydraKey'
-- gets either a "no instance" or a 'Forbid' custom error from GHC.

-- The bodies below mirror the pattern in 'Hydra.Tx.Secret': the 'Forbid'
-- constraint fires at normal compile time, so the bodies are unreachable.
-- Under '-fdefer-type-errors' they get reached: throw a
-- 'Control.Exception.TypeError' so the runtime exception type matches
-- what the negative-spec helpers look for.
instance Forbid "encode to JSON" => ToJSON (SigningKey HydraKey) where
  toJSON :: SigningKey HydraKey -> Value
toJSON SigningKey HydraKey
_ = TypeError -> Value
forall a e. Exception e => e -> a
throw (String -> TypeError
TypeError String
"Refusing to encode SigningKey HydraKey to JSON")

instance Forbid "decode from JSON" => FromJSON (SigningKey HydraKey) where
  parseJSON :: Value -> Parser (SigningKey HydraKey)
parseJSON Value
_ = TypeError -> Parser (SigningKey HydraKey)
forall a e. Exception e => e -> a
throw (String -> TypeError
TypeError String
"Refusing to decode SigningKey HydraKey from JSON")

instance Forbid "CBOR-encode" => ToCBOR (SigningKey HydraKey) where
  toCBOR :: SigningKey HydraKey -> Encoding
toCBOR SigningKey HydraKey
_ = TypeError -> Encoding
forall a e. Exception e => e -> a
throw (String -> TypeError
TypeError String
"Refusing to CBOR-encode SigningKey HydraKey")

instance Forbid "CBOR-decode" => FromCBOR (SigningKey HydraKey) where
  fromCBOR :: forall s. Decoder s (SigningKey HydraKey)
fromCBOR = TypeError -> Decoder s (SigningKey HydraKey)
forall a e. Exception e => e -> a
throw (String -> TypeError
TypeError String
"Refusing to CBOR-decode SigningKey HydraKey")

-- | Create a new 'SigningKey' from a 'ByteString' seed, wrapped in
-- 'Secret'. The public API never returns a raw 'SigningKey HydraKey'.
-- The created keys are not random and insecure, so don't use this in
-- production code!
generateSigningKey :: ByteString -> Secret (SigningKey HydraKey)
generateSigningKey :: ByteString -> Secret (SigningKey HydraKey)
generateSigningKey ByteString
seed =
  SigningKey HydraKey -> Secret (SigningKey HydraKey)
forall a. a -> Secret a
mkSecret (SigningKey HydraKey -> Secret (SigningKey HydraKey))
-> (Seed -> SigningKey HydraKey)
-> Seed
-> Secret (SigningKey HydraKey)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SignKeyDSIGN Ed25519DSIGN -> SigningKey HydraKey
HydraSigningKey (SignKeyDSIGN Ed25519DSIGN -> SigningKey HydraKey)
-> (Seed -> SignKeyDSIGN Ed25519DSIGN)
-> Seed
-> SigningKey HydraKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Seed -> SignKeyDSIGN Ed25519DSIGN
forall v. DSIGNAlgorithm v => Seed -> SignKeyDSIGN v
genKeyDSIGN (Seed -> Secret (SigningKey HydraKey))
-> Seed -> Secret (SigningKey HydraKey)
forall a b. (a -> b) -> a -> b
$ ByteString -> Seed
mkSeedFromBytes ByteString
hashOfSeed
 where
  hashOfSeed :: ByteString
hashOfSeed = Proxy SHA256 -> ByteString -> ByteString
forall h (proxy :: * -> *).
HashAlgorithm h =>
proxy h -> ByteString -> ByteString
forall (proxy :: * -> *). proxy SHA256 -> ByteString -> ByteString
digest (Proxy SHA256
forall {k} (t :: k). Proxy t
Proxy :: Proxy SHA256) ByteString
seed

-- * Signatures

-- | Signature of 'a', not containing the actual payload.
newtype Signature (a :: Type) = HydraSignature (SigDSIGN Ed25519DSIGN)
  deriving stock (Signature a -> Signature a -> Bool
(Signature a -> Signature a -> Bool)
-> (Signature a -> Signature a -> Bool) -> Eq (Signature a)
forall a. Signature a -> Signature a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. Signature a -> Signature a -> Bool
== :: Signature a -> Signature a -> Bool
$c/= :: forall a. Signature a -> Signature a -> Bool
/= :: Signature a -> Signature a -> Bool
Eq, (forall x. Signature a -> Rep (Signature a) x)
-> (forall x. Rep (Signature a) x -> Signature a)
-> Generic (Signature a)
forall x. Rep (Signature a) x -> Signature a
forall x. Signature a -> Rep (Signature a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (Signature a) x -> Signature a
forall a x. Signature a -> Rep (Signature a) x
$cfrom :: forall a x. Signature a -> Rep (Signature a) x
from :: forall x. Signature a -> Rep (Signature a) x
$cto :: forall a x. Rep (Signature a) x -> Signature a
to :: forall x. Rep (Signature a) x -> Signature a
Generic)

instance Typeable a => ToCBOR (Signature a) where
  toCBOR :: Signature a -> Encoding
toCBOR = Signature a -> Encoding
forall a. (Generic a, GToCBOR (Rep a)) => a -> Encoding
genericToCBOR

instance Typeable a => FromCBOR (Signature a) where
  fromCBOR :: forall s. Decoder s (Signature a)
fromCBOR = Decoder s (Signature a)
forall a s. (Generic a, GFromCBOR (Rep a)) => Decoder s a
genericFromCBOR

instance Show (Signature a) where
  show :: Signature a -> String
show (HydraSignature SigDSIGN Ed25519DSIGN
sig) =
    String
"HydraSignature " String -> ShowS
forall a. Semigroup a => a -> a -> a
<> ByteString -> String
forall a. Show a => a -> String
show ByteString
hexBytes
   where
    hexBytes :: ByteString
hexBytes = ByteString -> ByteString
Base16.encode (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ SigDSIGN Ed25519DSIGN -> ByteString
forall v. DSIGNAlgorithm v => SigDSIGN v -> ByteString
rawSerialiseSigDSIGN SigDSIGN Ed25519DSIGN
sig

instance Hashable (Signature a) where
  hashWithSalt :: Int -> Signature a -> Int
hashWithSalt Int
salt (HydraSignature SigDSIGN Ed25519DSIGN
sig) =
    Int -> ByteString -> Int
forall a. Hashable a => Int -> a -> Int
hashWithSalt Int
salt (SigDSIGN Ed25519DSIGN -> ByteString
forall v. DSIGNAlgorithm v => SigDSIGN v -> ByteString
rawSerialiseSigDSIGN SigDSIGN Ed25519DSIGN
sig)

instance ToJSON a => ToJSON (Signature a) where
  toJSON :: Signature a -> Value
toJSON (HydraSignature SigDSIGN Ed25519DSIGN
sig) = Text -> Value
Aeson.String (Text -> Value) -> Text -> Value
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
forall a b. ConvertUtf8 a b => b -> a
decodeUtf8 ByteString
hexBytes
   where
    hexBytes :: ByteString
hexBytes = ByteString -> ByteString
Base16.encode (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ SigDSIGN Ed25519DSIGN -> ByteString
forall v. DSIGNAlgorithm v => SigDSIGN v -> ByteString
rawSerialiseSigDSIGN SigDSIGN Ed25519DSIGN
sig

instance FromJSON a => FromJSON (Signature a) where
  parseJSON :: Value -> Parser (Signature a)
parseJSON = String
-> (Text -> Parser (Signature a)) -> Value -> Parser (Signature a)
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText String
"Signed" ((Text -> Parser (Signature a)) -> Value -> Parser (Signature a))
-> (Text -> Parser (Signature a)) -> Value -> Parser (Signature a)
forall a b. (a -> b) -> a -> b
$ \Text
t -> do
    ByteString
bs <- Text -> Parser ByteString
forall (f :: * -> *). MonadFail f => Text -> f ByteString
decodeBase16 Text
t
    Parser (Signature a)
-> (SigDSIGN Ed25519DSIGN -> Parser (Signature a))
-> Maybe (SigDSIGN Ed25519DSIGN)
-> Parser (Signature a)
forall b a. b -> (a -> b) -> Maybe a -> b
maybe
      (String -> Parser (Signature a)
forall a. String -> Parser a
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"deserialise signature from bytes failed")
      (Signature a -> Parser (Signature a)
forall a. a -> Parser a
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Signature a -> Parser (Signature a))
-> (SigDSIGN Ed25519DSIGN -> Signature a)
-> SigDSIGN Ed25519DSIGN
-> Parser (Signature a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SigDSIGN Ed25519DSIGN -> Signature a
forall a. SigDSIGN Ed25519DSIGN -> Signature a
HydraSignature)
      (Maybe (SigDSIGN Ed25519DSIGN) -> Parser (Signature a))
-> Maybe (SigDSIGN Ed25519DSIGN) -> Parser (Signature a)
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe (SigDSIGN Ed25519DSIGN)
forall v. DSIGNAlgorithm v => ByteString -> Maybe (SigDSIGN v)
rawDeserialiseSigDSIGN ByteString
bs

-- | Sign some value 'a' with the provided 'Secret'-wrapped 'SigningKey'.
-- The unwrap is internal: callers don't need a 'withSecret' at the call
-- site, so the noisy continuation pattern is hidden where it matters.
sign :: SignableRepresentation a => Secret (SigningKey HydraKey) -> a -> Signature a
sign :: forall a.
SignableRepresentation a =>
Secret (SigningKey HydraKey) -> a -> Signature a
sign Secret (SigningKey HydraKey)
secret a
a =
  Secret (SigningKey HydraKey)
-> (SigningKey HydraKey -> Signature a) -> Signature a
forall a r. Secret a -> (a -> r) -> r
withSecret Secret (SigningKey HydraKey)
secret ((SigningKey HydraKey -> Signature a) -> Signature a)
-> (SigningKey HydraKey -> Signature a) -> Signature a
forall a b. (a -> b) -> a -> b
$ \(HydraSigningKey SignKeyDSIGN Ed25519DSIGN
sk) ->
    SigDSIGN Ed25519DSIGN -> Signature a
forall a. SigDSIGN Ed25519DSIGN -> Signature a
HydraSignature (ContextDSIGN Ed25519DSIGN
-> a -> SignKeyDSIGN Ed25519DSIGN -> SigDSIGN Ed25519DSIGN
forall v a.
(DSIGNAlgorithm v, Signable v a, HasCallStack) =>
ContextDSIGN v -> a -> SignKeyDSIGN v -> SigDSIGN v
forall a.
(Signable Ed25519DSIGN a, HasCallStack) =>
ContextDSIGN Ed25519DSIGN
-> a -> SignKeyDSIGN Ed25519DSIGN -> SigDSIGN Ed25519DSIGN
signDSIGN ()
ContextDSIGN Ed25519DSIGN
ctx a
a SignKeyDSIGN Ed25519DSIGN
sk)
 where
  ctx :: ContextDSIGN Ed25519DSIGN
ctx = () :: ContextDSIGN Ed25519DSIGN

-- | Verify a given 'Signature a' and value 'a' using provided 'VerificationKey'.
verify ::
  SignableRepresentation a =>
  VerificationKey HydraKey ->
  Signature a ->
  a ->
  Bool
verify :: forall a.
SignableRepresentation a =>
VerificationKey HydraKey -> Signature a -> a -> Bool
verify (HydraVerificationKey VerKeyDSIGN Ed25519DSIGN
vk) (HydraSignature SigDSIGN Ed25519DSIGN
sig) a
a =
  case ContextDSIGN Ed25519DSIGN
-> VerKeyDSIGN Ed25519DSIGN
-> a
-> SigDSIGN Ed25519DSIGN
-> Either String ()
forall v a.
(DSIGNAlgorithm v, Signable v a, HasCallStack) =>
ContextDSIGN v
-> VerKeyDSIGN v -> a -> SigDSIGN v -> Either String ()
forall a.
(Signable Ed25519DSIGN a, HasCallStack) =>
ContextDSIGN Ed25519DSIGN
-> VerKeyDSIGN Ed25519DSIGN
-> a
-> SigDSIGN Ed25519DSIGN
-> Either String ()
verifyDSIGN ()
ContextDSIGN Ed25519DSIGN
ctx VerKeyDSIGN Ed25519DSIGN
vk a
a SigDSIGN Ed25519DSIGN
sig of
    Right () -> Bool
True
    -- NOTE: Current implementation does not yield multiple Left cases, so no need
    -- to distinguish in our interface
    Left String
_ -> Bool
False
 where
  ctx :: ContextDSIGN Ed25519DSIGN
ctx = () :: ContextDSIGN Ed25519DSIGN

-- * Multi-signatures

-- | Naiively aggregated multi-signatures.
newtype MultiSignature (a :: Type) = HydraMultiSignature {forall a. MultiSignature a -> [Signature a]
multiSignature :: [Signature a]}
  deriving stock (MultiSignature a -> MultiSignature a -> Bool
(MultiSignature a -> MultiSignature a -> Bool)
-> (MultiSignature a -> MultiSignature a -> Bool)
-> Eq (MultiSignature a)
forall a. MultiSignature a -> MultiSignature a -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: forall a. MultiSignature a -> MultiSignature a -> Bool
== :: MultiSignature a -> MultiSignature a -> Bool
$c/= :: forall a. MultiSignature a -> MultiSignature a -> Bool
/= :: MultiSignature a -> MultiSignature a -> Bool
Eq, Int -> MultiSignature a -> ShowS
[MultiSignature a] -> ShowS
MultiSignature a -> String
(Int -> MultiSignature a -> ShowS)
-> (MultiSignature a -> String)
-> ([MultiSignature a] -> ShowS)
-> Show (MultiSignature a)
forall a. Int -> MultiSignature a -> ShowS
forall a. [MultiSignature a] -> ShowS
forall a. MultiSignature a -> String
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: forall a. Int -> MultiSignature a -> ShowS
showsPrec :: Int -> MultiSignature a -> ShowS
$cshow :: forall a. MultiSignature a -> String
show :: MultiSignature a -> String
$cshowList :: forall a. [MultiSignature a] -> ShowS
showList :: [MultiSignature a] -> ShowS
Show, (forall x. MultiSignature a -> Rep (MultiSignature a) x)
-> (forall x. Rep (MultiSignature a) x -> MultiSignature a)
-> Generic (MultiSignature a)
forall x. Rep (MultiSignature a) x -> MultiSignature a
forall x. MultiSignature a -> Rep (MultiSignature a) x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
forall a x. Rep (MultiSignature a) x -> MultiSignature a
forall a x. MultiSignature a -> Rep (MultiSignature a) x
$cfrom :: forall a x. MultiSignature a -> Rep (MultiSignature a) x
from :: forall x. MultiSignature a -> Rep (MultiSignature a) x
$cto :: forall a x. Rep (MultiSignature a) x -> MultiSignature a
to :: forall x. Rep (MultiSignature a) x -> MultiSignature a
Generic)
  deriving newtype (NonEmpty (MultiSignature a) -> MultiSignature a
MultiSignature a -> MultiSignature a -> MultiSignature a
(MultiSignature a -> MultiSignature a -> MultiSignature a)
-> (NonEmpty (MultiSignature a) -> MultiSignature a)
-> (forall b.
    Integral b =>
    b -> MultiSignature a -> MultiSignature a)
-> Semigroup (MultiSignature a)
forall b. Integral b => b -> MultiSignature a -> MultiSignature a
forall a. NonEmpty (MultiSignature a) -> MultiSignature a
forall a. MultiSignature a -> MultiSignature a -> MultiSignature a
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall a b. Integral b => b -> MultiSignature a -> MultiSignature a
$c<> :: forall a. MultiSignature a -> MultiSignature a -> MultiSignature a
<> :: MultiSignature a -> MultiSignature a -> MultiSignature a
$csconcat :: forall a. NonEmpty (MultiSignature a) -> MultiSignature a
sconcat :: NonEmpty (MultiSignature a) -> MultiSignature a
$cstimes :: forall a b. Integral b => b -> MultiSignature a -> MultiSignature a
stimes :: forall b. Integral b => b -> MultiSignature a -> MultiSignature a
Semigroup, Semigroup (MultiSignature a)
MultiSignature a
Semigroup (MultiSignature a) =>
MultiSignature a
-> (MultiSignature a -> MultiSignature a -> MultiSignature a)
-> ([MultiSignature a] -> MultiSignature a)
-> Monoid (MultiSignature a)
[MultiSignature a] -> MultiSignature a
MultiSignature a -> MultiSignature a -> MultiSignature a
forall a. Semigroup (MultiSignature a)
forall a. MultiSignature a
forall a.
Semigroup a =>
a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall a. [MultiSignature a] -> MultiSignature a
forall a. MultiSignature a -> MultiSignature a -> MultiSignature a
$cmempty :: forall a. MultiSignature a
mempty :: MultiSignature a
$cmappend :: forall a. MultiSignature a -> MultiSignature a -> MultiSignature a
mappend :: MultiSignature a -> MultiSignature a -> MultiSignature a
$cmconcat :: forall a. [MultiSignature a] -> MultiSignature a
mconcat :: [MultiSignature a] -> MultiSignature a
Monoid)

instance Typeable a => ToCBOR (MultiSignature a) where
  toCBOR :: MultiSignature a -> Encoding
toCBOR = MultiSignature a -> Encoding
forall a. (Generic a, GToCBOR (Rep a)) => a -> Encoding
genericToCBOR

instance Typeable a => FromCBOR (MultiSignature a) where
  fromCBOR :: forall s. Decoder s (MultiSignature a)
fromCBOR = Decoder s (MultiSignature a)
forall a s. (Generic a, GFromCBOR (Rep a)) => Decoder s a
genericFromCBOR

deriving anyclass instance ToJSON a => ToJSON (MultiSignature a)
deriving anyclass instance FromJSON a => FromJSON (MultiSignature a)

-- | Combine multiple signatures of 'a' into a 'MultiSignature a'.
aggregate :: [Signature a] -> MultiSignature a
aggregate :: forall a. [Signature a] -> MultiSignature a
aggregate = [Signature a] -> MultiSignature a
forall a. [Signature a] -> MultiSignature a
HydraMultiSignature

-- | Like aggregate, but use order of given list of keys instead.
-- FIXME(AB): This function exists solely because the order of signatures
-- matters on-chain, and it should match the order of parties as declared in the
-- initTx. This should disappear once we use a proper multisignature scheme
aggregateInOrder :: Ord k => Map k (Signature a) -> [k] -> MultiSignature a
aggregateInOrder :: forall k a. Ord k => Map k (Signature a) -> [k] -> MultiSignature a
aggregateInOrder Map k (Signature a)
signatures = [Signature a] -> MultiSignature a
forall a. [Signature a] -> MultiSignature a
HydraMultiSignature ([Signature a] -> MultiSignature a)
-> ([k] -> [Signature a]) -> [k] -> MultiSignature a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (k -> [Signature a] -> [Signature a])
-> [Signature a] -> [k] -> [Signature a]
forall a b. (a -> b -> b) -> b -> [a] -> b
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr k -> [Signature a] -> [Signature a]
appendSignature []
 where
  appendSignature :: k -> [Signature a] -> [Signature a]
appendSignature k
k [Signature a]
sigs =
    case k -> Map k (Signature a) -> Maybe (Signature a)
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup k
k Map k (Signature a)
signatures of
      Maybe (Signature a)
Nothing -> [Signature a]
sigs
      Just Signature a
sig -> Signature a
sig Signature a -> [Signature a] -> [Signature a]
forall a. a -> [a] -> [a]
: [Signature a]
sigs

-- | A result type for multisigs verification providing some information
-- in case of failure.
--
-- This type is of course structurally equivalent to `Maybe [VerificationKey HydraKey]` but it's much more explicit.
data Verified
  = Verified
  | FailedKeys {Verified -> [VerificationKey HydraKey]
failedKeys :: [VerificationKey HydraKey]}
  | KeyNumberMismatch
  deriving stock (Verified -> Verified -> Bool
(Verified -> Verified -> Bool)
-> (Verified -> Verified -> Bool) -> Eq Verified
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Verified -> Verified -> Bool
== :: Verified -> Verified -> Bool
$c/= :: Verified -> Verified -> Bool
/= :: Verified -> Verified -> Bool
Eq, Int -> Verified -> ShowS
[Verified] -> ShowS
Verified -> String
(Int -> Verified -> ShowS)
-> (Verified -> String) -> ([Verified] -> ShowS) -> Show Verified
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Verified -> ShowS
showsPrec :: Int -> Verified -> ShowS
$cshow :: Verified -> String
show :: Verified -> String
$cshowList :: [Verified] -> ShowS
showList :: [Verified] -> ShowS
Show, (forall x. Verified -> Rep Verified x)
-> (forall x. Rep Verified x -> Verified) -> Generic Verified
forall x. Rep Verified x -> Verified
forall x. Verified -> Rep Verified x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cfrom :: forall x. Verified -> Rep Verified x
from :: forall x. Verified -> Rep Verified x
$cto :: forall x. Rep Verified x -> Verified
to :: forall x. Rep Verified x -> Verified
Generic)

-- | Verify a given 'MultiSignature a' and value 'a' provided a list of
-- 'VerificationKey'.
--
-- Note that order of keys is relevant and that length of signature and
-- multisignature list needs to be the same.
verifyMultiSignature ::
  SignableRepresentation a =>
  [VerificationKey HydraKey] ->
  MultiSignature a ->
  a ->
  Verified
verifyMultiSignature :: forall a.
SignableRepresentation a =>
[VerificationKey HydraKey] -> MultiSignature a -> a -> Verified
verifyMultiSignature [VerificationKey HydraKey]
vks MultiSignature a
multisig a
a =
  [VerificationKey HydraKey]
-> MultiSignature a -> ByteString -> Verified
forall a.
[VerificationKey HydraKey]
-> MultiSignature a -> ByteString -> Verified
verifyMultiSignatureBytes [VerificationKey HydraKey]
vks MultiSignature a
multisig (a -> ByteString
forall a. SignableRepresentation a => a -> ByteString
getSignableRepresentation a
a)

-- | Like 'verifyMultiSignature' but operates on pre-computed signable bytes,
-- avoiding repeated calls to 'getSignableRepresentation'. Use this when the
-- same value would be verified multiple times (e.g. per-party in a round).
verifyMultiSignatureBytes ::
  [VerificationKey HydraKey] ->
  MultiSignature a ->
  ByteString ->
  Verified
verifyMultiSignatureBytes :: forall a.
[VerificationKey HydraKey]
-> MultiSignature a -> ByteString -> Verified
verifyMultiSignatureBytes [VerificationKey HydraKey]
vks HydraMultiSignature{[Signature a]
$sel:multiSignature:HydraMultiSignature :: forall a. MultiSignature a -> [Signature a]
multiSignature :: [Signature a]
multiSignature} ByteString
bs
  | [VerificationKey HydraKey] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [VerificationKey HydraKey]
vks Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== [Signature a] -> Int
forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [Signature a]
multiSignature =
      let ctx :: ContextDSIGN Ed25519DSIGN
ctx = () :: ContextDSIGN Ed25519DSIGN
          failures :: [VerificationKey HydraKey]
failures =
            ((VerificationKey HydraKey, Signature a)
 -> Maybe (VerificationKey HydraKey))
-> [(VerificationKey HydraKey, Signature a)]
-> [VerificationKey HydraKey]
forall a b. (a -> Maybe b) -> [a] -> [b]
mapMaybe
              ( \(vk :: VerificationKey HydraKey
vk@(HydraVerificationKey VerKeyDSIGN Ed25519DSIGN
rawVk), HydraSignature SigDSIGN Ed25519DSIGN
sig) ->
                  case ContextDSIGN Ed25519DSIGN
-> VerKeyDSIGN Ed25519DSIGN
-> ByteString
-> SigDSIGN Ed25519DSIGN
-> Either String ()
forall v a.
(DSIGNAlgorithm v, Signable v a, HasCallStack) =>
ContextDSIGN v
-> VerKeyDSIGN v -> a -> SigDSIGN v -> Either String ()
forall a.
(Signable Ed25519DSIGN a, HasCallStack) =>
ContextDSIGN Ed25519DSIGN
-> VerKeyDSIGN Ed25519DSIGN
-> a
-> SigDSIGN Ed25519DSIGN
-> Either String ()
verifyDSIGN ()
ContextDSIGN Ed25519DSIGN
ctx VerKeyDSIGN Ed25519DSIGN
rawVk ByteString
bs SigDSIGN Ed25519DSIGN
sig of
                    Right () -> Maybe (VerificationKey HydraKey)
forall a. Maybe a
Nothing
                    Left String
_ -> VerificationKey HydraKey -> Maybe (VerificationKey HydraKey)
forall a. a -> Maybe a
Just VerificationKey HydraKey
vk
              )
              ([VerificationKey HydraKey]
-> [Signature a] -> [(VerificationKey HydraKey, Signature a)]
forall a b. [a] -> [b] -> [(a, b)]
zip [VerificationKey HydraKey]
vks [Signature a]
multiSignature)
       in if [VerificationKey HydraKey] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [VerificationKey HydraKey]
failures
            then Verified
Verified
            else [VerificationKey HydraKey] -> Verified
FailedKeys [VerificationKey HydraKey]
failures
  | Bool
otherwise = Verified
KeyNumberMismatch

toPlutusSignatures :: MultiSignature a -> [OnChain.Signature]
toPlutusSignatures :: forall a. MultiSignature a -> [Signature]
toPlutusSignatures (HydraMultiSignature [Signature a]
sigs) =
  Signature a -> Signature
forall a. Signature a -> Signature
toPlutusSignature (Signature a -> Signature) -> [Signature a] -> [Signature]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Signature a]
sigs
 where
  toPlutusSignature :: Signature a -> OnChain.Signature
  toPlutusSignature :: forall a. Signature a -> Signature
toPlutusSignature (HydraSignature SigDSIGN Ed25519DSIGN
sig) =
    ByteString -> ToBuiltin ByteString
forall a. HasToBuiltin a => a -> ToBuiltin a
Plutus.toBuiltin (ByteString -> ToBuiltin ByteString)
-> ByteString -> ToBuiltin ByteString
forall a b. (a -> b) -> a -> b
$ SigDSIGN Ed25519DSIGN -> ByteString
forall v. DSIGNAlgorithm v => SigDSIGN v -> ByteString
rawSerialiseSigDSIGN SigDSIGN Ed25519DSIGN
sig