From 2aac0e15b4360b0ffed0fad89438f9b5a72b0129 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Mon, 18 Mar 2024 10:55:01 +0100 Subject: [PATCH 1/5] verification-key: make code easier to read --- cardano-cli/src/Cardano/CLI/Types/Key.hs | 60 ++++++++---------------- 1 file changed, 20 insertions(+), 40 deletions(-) diff --git a/cardano-cli/src/Cardano/CLI/Types/Key.hs b/cardano-cli/src/Cardano/CLI/Types/Key.hs index b8b2f8bfc7..eafd527780 100644 --- a/cardano-cli/src/Cardano/CLI/Types/Key.hs +++ b/cardano-cli/src/Cardano/CLI/Types/Key.hs @@ -386,47 +386,27 @@ readSigningKeyFile skFile = readKeyFileAnyOf bech32FileTypes textEnvFileTypes skFile where textEnvFileTypes = - [ FromSomeType (AsSigningKey AsByronKey) - AByronSigningKey - , FromSomeType (AsSigningKey AsPaymentKey) - APaymentSigningKey - , FromSomeType (AsSigningKey AsPaymentExtendedKey) - APaymentExtendedSigningKey - , FromSomeType (AsSigningKey AsStakeKey) - AStakeSigningKey - , FromSomeType (AsSigningKey AsStakeExtendedKey) - AStakeExtendedSigningKey - , FromSomeType (AsSigningKey AsStakePoolKey) - AStakePoolSigningKey - , FromSomeType (AsSigningKey AsGenesisKey) - AGenesisSigningKey - , FromSomeType (AsSigningKey AsGenesisExtendedKey) - AGenesisExtendedSigningKey - , FromSomeType (AsSigningKey AsGenesisDelegateKey) - AGenesisDelegateSigningKey - , FromSomeType (AsSigningKey AsGenesisDelegateExtendedKey) - AGenesisDelegateExtendedSigningKey - , FromSomeType (AsSigningKey AsGenesisUTxOKey) - AGenesisUTxOSigningKey - , FromSomeType (AsSigningKey AsVrfKey) - AVrfSigningKey - , FromSomeType (AsSigningKey AsKesKey) - AKesSigningKey + [ FromSomeType (AsSigningKey AsByronKey) AByronSigningKey + , FromSomeType (AsSigningKey AsPaymentKey) APaymentSigningKey + , FromSomeType (AsSigningKey AsPaymentExtendedKey) APaymentExtendedSigningKey + , FromSomeType (AsSigningKey AsStakeKey) AStakeSigningKey + , FromSomeType (AsSigningKey AsStakeExtendedKey) AStakeExtendedSigningKey + , FromSomeType (AsSigningKey AsStakePoolKey) AStakePoolSigningKey + , FromSomeType (AsSigningKey AsGenesisKey) AGenesisSigningKey + , FromSomeType (AsSigningKey AsGenesisExtendedKey) AGenesisExtendedSigningKey + , FromSomeType (AsSigningKey AsGenesisDelegateKey) AGenesisDelegateSigningKey + , FromSomeType (AsSigningKey AsGenesisDelegateExtendedKey) AGenesisDelegateExtendedSigningKey + , FromSomeType (AsSigningKey AsGenesisUTxOKey) AGenesisUTxOSigningKey + , FromSomeType (AsSigningKey AsVrfKey) AVrfSigningKey + , FromSomeType (AsSigningKey AsKesKey) AKesSigningKey ] bech32FileTypes = - [ FromSomeType (AsSigningKey AsPaymentKey) - APaymentSigningKey - , FromSomeType (AsSigningKey AsPaymentExtendedKey) - APaymentExtendedSigningKey - , FromSomeType (AsSigningKey AsStakeKey) - AStakeSigningKey - , FromSomeType (AsSigningKey AsStakeExtendedKey) - AStakeExtendedSigningKey - , FromSomeType (AsSigningKey AsStakePoolKey) - AStakePoolSigningKey - , FromSomeType (AsSigningKey AsVrfKey) - AVrfSigningKey - , FromSomeType (AsSigningKey AsKesKey) - AKesSigningKey + [ FromSomeType (AsSigningKey AsPaymentKey) APaymentSigningKey + , FromSomeType (AsSigningKey AsPaymentExtendedKey) APaymentExtendedSigningKey + , FromSomeType (AsSigningKey AsStakeKey) AStakeSigningKey + , FromSomeType (AsSigningKey AsStakeExtendedKey) AStakeExtendedSigningKey + , FromSomeType (AsSigningKey AsStakePoolKey) AStakePoolSigningKey + , FromSomeType (AsSigningKey AsVrfKey) AVrfSigningKey + , FromSomeType (AsSigningKey AsKesKey) AKesSigningKey ] From a78711ec078b20c2b879abb235d1336d58f1166e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Mon, 18 Mar 2024 14:48:47 +0100 Subject: [PATCH 2/5] key verification-key: add tests of non-extended keys --- cardano-cli/cardano-cli.cabal | 2 + .../Test/Cardano/CLI/Aeson.hs | 47 ++++++++++++++- .../Test/Cli/VerificationKey.hs | 57 +++++++++++++++++++ 3 files changed, 104 insertions(+), 2 deletions(-) create mode 100644 cardano-cli/test/cardano-cli-test/Test/Cli/VerificationKey.hs diff --git a/cardano-cli/cardano-cli.cabal b/cardano-cli/cardano-cli.cabal index be1f9b4e63..edce287f9e 100644 --- a/cardano-cli/cardano-cli.cabal +++ b/cardano-cli/cardano-cli.cabal @@ -293,6 +293,7 @@ test-suite cardano-cli-test , filepath , hedgehog , hedgehog-extras ^>= 0.6.1.0 + , exceptions , tasty , tasty-hedgehog , text @@ -313,6 +314,7 @@ test-suite cardano-cli-test Test.Cli.Pioneers.Exercise5 Test.Cli.Pioneers.Exercise6 Test.Cli.Pipes + Test.Cli.VerificationKey Test.Cli.Shelley.Run.Query ghc-options: -threaded -rtsopts "-with-rtsopts=-N -T" diff --git a/cardano-cli/test/cardano-cli-test-lib/Test/Cardano/CLI/Aeson.hs b/cardano-cli/test/cardano-cli-test-lib/Test/Cardano/CLI/Aeson.hs index d9327eb8ae..c3d8ae432f 100644 --- a/cardano-cli/test/cardano-cli-test-lib/Test/Cardano/CLI/Aeson.hs +++ b/cardano-cli/test/cardano-cli-test-lib/Test/Cardano/CLI/Aeson.hs @@ -1,6 +1,9 @@ +{-# LANGUAGE TypeApplications #-} + module Test.Cardano.CLI.Aeson ( - assertHasKeys, - assertHasMappings, + assertEqualModuloDesc + , assertHasKeys + , assertHasMappings ) where import Control.Monad (forM_) @@ -118,3 +121,43 @@ assertHasMapping file obj key value = GHC.withFrozenCallStack $ do H.failure +-- | @assertEqualModuloDesc file1 file2@ loads @file1@ and @file2@ from disk, +-- then it strips the field @description@ from the loaded content, and finally compare +-- the two values. The values must be equal, otherwise the test is failed. +-- +-- Required, because command @"key" "verification-key"@ generates keys without descriptions. +-- Note that it would be better to write descriptions, see: +-- https://github.com/IntersectMBO/cardano-cli/issues/429#issuecomment-2003880575 +assertEqualModuloDesc :: () + => (HasCallStack, MonadIO m, MonadTest m) + => FilePath -- ^ The file of the first generated verification key + -> FilePath -- ^ The file of the second generated verification key, i.e. the one + -- generated by calling "key verification-key" + -> m () +assertEqualModuloDesc file1 file2 = GHC.withFrozenCallStack $ do + value1 <- H.readJsonFileOk @Value file1 + value1' <- removeDescription value1 + + value2 <- H.readJsonFileOk @Value file2 + value2' <- removeDescription value2 + + value1' H.=== value2' + +-- | Removes the @description@ field from a JSON object. +removeDescription :: () + => (HasCallStack, MonadTest m) + => Value + -> m Value +removeDescription v = + case v of + Object inner -> + return $ Object $ Aeson.KeyMap.delete (Aeson.fromText "description") inner + Array _ -> failWrongType "array" + Number _ -> failWrongType "number" + Bool _ -> failWrongType "bool" + String _ -> failWrongType "string" + Null -> failWrongType "null" + where + failWrongType got = do + H.note_ $ "Expected object but got: " <> got + H.failure diff --git a/cardano-cli/test/cardano-cli-test/Test/Cli/VerificationKey.hs b/cardano-cli/test/cardano-cli-test/Test/Cli/VerificationKey.hs new file mode 100644 index 0000000000..9a5cb9c62c --- /dev/null +++ b/cardano-cli/test/cardano-cli-test/Test/Cli/VerificationKey.hs @@ -0,0 +1,57 @@ +-- | Tests of the command "key verification-key", in particular tests of +-- https://github.com/IntersectMBO/cardano-cli/issues/651 +module Test.Cli.VerificationKey where + +import Control.Monad.Catch (MonadCatch) +import Control.Monad.IO.Class (MonadIO) +import GHC.Stack (HasCallStack) +import qualified GHC.Stack as GHC + +import Test.Cardano.CLI.Aeson (assertEqualModuloDesc) +import Test.Cardano.CLI.Util + +import Hedgehog (MonadTest, Property) +import qualified Hedgehog.Extras.Test.Base as H + +-- | Execute me with: +-- @cabal test cardano-cli-test --test-options '-p "/verification key drep/"'@ +hprop_verification_key_drep :: Property +hprop_verification_key_drep = + propertyOnce . H.moduleWorkspace "tmp" $ runOne ["drep", "key-gen"] + +-- | Execute me with: +-- @cabal test cardano-cli-test --test-options '-p "/verification key committee hot/"'@ +hprop_verification_key_committee_hot :: Property +hprop_verification_key_committee_hot = + propertyOnce . H.moduleWorkspace "tmp" $ runOne ["committee", "key-gen-hot"] + +-- | Execute me with: +-- @cabal test cardano-cli-test --test-options '-p "/verification key committee cold/"'@ +hprop_verification_key_committee_cold :: Property +hprop_verification_key_committee_cold = + propertyOnce . H.moduleWorkspace "tmp" $ runOne ["committee", "key-gen-cold"] + +runOne :: () + => (HasCallStack, MonadCatch m, MonadIO m, MonadTest m) + => [String] -- ^ The piece of the command to generate the keys + -> FilePath -- ^ The temporary directory, i.e. where the test is allowed to generate files + -> m () +runOne cmd tempDir = GHC.withFrozenCallStack $ do + verificationKeyFile <- noteTempFile tempDir "gen.vkey" + signingKeyFile <- noteTempFile tempDir "gen.skey" + verificationKeyFileOut <- noteTempFile tempDir "vkey.out" + + H.noteM_ $ execCardanoCLI $ + [ "conway", "governance" ] + ++ cmd ++ + [ "--verification-key-file", verificationKeyFile + , "--signing-key-file", signingKeyFile + ] + + H.noteM_ $ execCardanoCLI + [ "conway", "key", "verification-key" + , "--signing-key-file", signingKeyFile + , "--verification-key-file", verificationKeyFileOut + ] + + assertEqualModuloDesc verificationKeyFile verificationKeyFileOut From 95519ecbd9bd188a1db4b7d1a5f422c4f59626f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Mon, 18 Mar 2024 15:17:11 +0100 Subject: [PATCH 3/5] key verification-key: add tests of extended committee keys --- .../Test/Golden/Governance/Committee.hs | 29 +++++++++++++++++-- .../committee/cc.extended.cold.vkey | 5 ++++ .../governance/committee/cc.extended.hot.vkey | 5 ++++ 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 cardano-cli/test/cardano-cli-golden/files/golden/governance/committee/cc.extended.cold.vkey create mode 100644 cardano-cli/test/cardano-cli-golden/files/golden/governance/committee/cc.extended.hot.vkey diff --git a/cardano-cli/test/cardano-cli-golden/Test/Golden/Governance/Committee.hs b/cardano-cli/test/cardano-cli-golden/Test/Golden/Governance/Committee.hs index 841abdb6b9..1784187974 100644 --- a/cardano-cli/test/cardano-cli-golden/Test/Golden/Governance/Committee.hs +++ b/cardano-cli/test/cardano-cli-golden/Test/Golden/Governance/Committee.hs @@ -4,7 +4,7 @@ module Test.Golden.Governance.Committee where -import Control.Monad (void) +import Control.Monad (forM_, void) import Text.Regex.TDFA ((=~)) import Test.Cardano.CLI.Util @@ -220,4 +220,29 @@ hprop_golden_governance_committee_hot_extended_key_signing = , "--out-file", outFile ] - H.diffFileVsGoldenFile outFile outGold \ No newline at end of file + H.diffFileVsGoldenFile outFile outGold + +-- | Execute me with: +-- @cabal test cardano-cli-golden --test-options '-p "/golden verification key committee/"'@ +hprop_golden_verification_key_committee :: Property +hprop_golden_verification_key_committee = do + let values = [ ( "test/cardano-cli-golden/files/input/governance/committee/cc.extended.hot.skey" + , "test/cardano-cli-golden/files/golden/governance/committee/cc.extended.hot.vkey" + ) + , + ( "test/cardano-cli-golden/files/input/governance/committee/cc.extended.cold.skey" + , "test/cardano-cli-golden/files/golden/governance/committee/cc.extended.cold.vkey" + ) + ] + + propertyOnce $ forM_ values $ \(skeyFile, vkeyGolden) -> + H.moduleWorkspace "tmp" $ \tempDir -> do + vkeyFileOut <- noteTempFile tempDir "cc.extended.vkey" + + H.noteM_ $ execCardanoCLI + [ "conway", "key", "verification-key" + , "--signing-key-file", skeyFile + , "--verification-key-file", vkeyFileOut + ] + + H.diffFileVsGoldenFile vkeyFileOut vkeyGolden diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/governance/committee/cc.extended.cold.vkey b/cardano-cli/test/cardano-cli-golden/files/golden/governance/committee/cc.extended.cold.vkey new file mode 100644 index 0000000000..c2a21b6a0d --- /dev/null +++ b/cardano-cli/test/cardano-cli-golden/files/golden/governance/committee/cc.extended.cold.vkey @@ -0,0 +1,5 @@ +{ + "type": "ConstitutionalCommitteeColdExtendedVerificationKey_ed25519_bip32", + "description": "", + "cborHex": "58400a9d35aa5299580a67b1e43a3a4b6d43ef29c94e56c51ce4c17e9a53c1d0f39aa7f68837c38ef680b2dc8f047581707a32f6fcade23d4e02177d389002484798" +} diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/governance/committee/cc.extended.hot.vkey b/cardano-cli/test/cardano-cli-golden/files/golden/governance/committee/cc.extended.hot.vkey new file mode 100644 index 0000000000..9cb85beea6 --- /dev/null +++ b/cardano-cli/test/cardano-cli-golden/files/golden/governance/committee/cc.extended.hot.vkey @@ -0,0 +1,5 @@ +{ + "type": "ConstitutionalCommitteeHotExtendedVerificationKey_ed25519_bip32", + "description": "", + "cborHex": "5840f010c4332699c6ea1e43b427919860277169382d43d2969b28a110cfa08d955c4f178f20955541ce918a6a1352c32536f22677008f9f918d109663e4d2bdc084" +} From eed5249e13cb14d2498ca2aee1b0e021a055a8ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Mon, 18 Mar 2024 15:49:39 +0100 Subject: [PATCH 4/5] key verification-key: add tests of extended DRep keys --- .../Test/Golden/Governance/DRep.hs | 22 +++++++++++++++++-- .../governance/drep/drep-extended.vkey.out | 5 +++++ 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 cardano-cli/test/cardano-cli-golden/files/golden/governance/drep/drep-extended.vkey.out diff --git a/cardano-cli/test/cardano-cli-golden/Test/Golden/Governance/DRep.hs b/cardano-cli/test/cardano-cli-golden/Test/Golden/Governance/DRep.hs index ada2aee671..2f2700fbb0 100644 --- a/cardano-cli/test/cardano-cli-golden/Test/Golden/Governance/DRep.hs +++ b/cardano-cli/test/cardano-cli-golden/Test/Golden/Governance/DRep.hs @@ -16,7 +16,8 @@ import Numeric (showOct) import System.Posix.Files (fileMode, getFileStatus) #endif -import Test.Cardano.CLI.Util (FileSem, bracketSem, execCardanoCLI, noteInputFile, noteTempFile, propertyOnce, newFileSem) +import Test.Cardano.CLI.Util (FileSem, bracketSem, execCardanoCLI, newFileSem, + noteInputFile, noteTempFile, propertyOnce) import Hedgehog import qualified Hedgehog as H @@ -105,7 +106,7 @@ hprop_golden_governance_drep_extended_key_signing = outFile <- H.noteTempFile tempDir "outFile" outGold <- H.note "test/cardano-cli-golden/files/golden/governance/drep/extended-key-signing/tx.signed" - void $ execCardanoCLI + H.noteShowM_ $ execCardanoCLI [ "conway", "transaction", "sign" , "--tx-body-file", txBody , "--signing-key-file", skeyFile @@ -276,3 +277,20 @@ hprop_golden_governance_drep_update_certificate_vkey_file = propertyOnce . H.mod ] H.diffFileVsGoldenFile outFile goldenFile + +-- | Execute me with: +-- @cabal test cardano-cli-golden --test-options '-p "/golden verification key drep/"'@ +hprop_golden_verification_key_drep :: Property +hprop_golden_verification_key_drep = + propertyOnce . H.moduleWorkspace "tmp" $ \tempDir -> do + skeyFile <- noteInputFile "test/cardano-cli-golden/files/input/governance/drep/extended-key-signing/drep.skey" + vkeyFileOut <- noteTempFile tempDir "drep.extended.vkey" + goldenFile <- H.note "test/cardano-cli-golden/files/golden/governance/drep/drep-extended.vkey.out" + + H.noteShowM_ $ execCardanoCLI + [ "conway", "key", "verification-key" + , "--signing-key-file", skeyFile + , "--verification-key-file", vkeyFileOut + ] + + H.diffFileVsGoldenFile vkeyFileOut goldenFile diff --git a/cardano-cli/test/cardano-cli-golden/files/golden/governance/drep/drep-extended.vkey.out b/cardano-cli/test/cardano-cli-golden/files/golden/governance/drep/drep-extended.vkey.out new file mode 100644 index 0000000000..bb986f10ab --- /dev/null +++ b/cardano-cli/test/cardano-cli-golden/files/golden/governance/drep/drep-extended.vkey.out @@ -0,0 +1,5 @@ +{ + "type": "DRepExtendedVerificationKey_ed25519_bip32", + "description": "", + "cborHex": "5840b18eacea2003b68e39137545e9d42ce5bca133ca0334d6a75aa9cb1fd02be7ec90e91f5357e2c68949f0f09717c5b9809b6a74d5f87ea35383c82841f2357564" +} From 2b374d061cd8062fefae0012b5210bf18c300aec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=A9ment=20Hurlin?= Date: Mon, 18 Mar 2024 11:25:51 +0100 Subject: [PATCH 5/5] key verification-key: support drep and CC keys --- cardano-cli/src/Cardano/CLI/Read.hs | 2 ++ cardano-cli/src/Cardano/CLI/Types/Key.hs | 22 +++++++++++++++++++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/cardano-cli/src/Cardano/CLI/Read.hs b/cardano-cli/src/Cardano/CLI/Read.hs index 2af45a0f5a..c02cbbc15e 100644 --- a/cardano-cli/src/Cardano/CLI/Read.hs +++ b/cardano-cli/src/Cardano/CLI/Read.hs @@ -721,6 +721,8 @@ readWitnessSigningData (KeyWitnessSigningData skFile mbByronAddr) = do -- A Byron address should only be specified along with a Byron signing key. Left ReadWitnessSigningDataSigningKeyAndAddressMismatch where + -- If you update these variables, consider updating the ones with the same + -- names in Cardano.CLI.Types.Key textEnvFileTypes = [ FromSomeType (AsSigningKey AsByronKey ) (`AByronSigningWitness` mbByronAddr) , FromSomeType (AsSigningKey AsPaymentKey ) APaymentSigningWitness diff --git a/cardano-cli/src/Cardano/CLI/Types/Key.hs b/cardano-cli/src/Cardano/CLI/Types/Key.hs index eafd527780..436f4a5f43 100644 --- a/cardano-cli/src/Cardano/CLI/Types/Key.hs +++ b/cardano-cli/src/Cardano/CLI/Types/Key.hs @@ -355,6 +355,12 @@ data SomeSigningKey | AGenesisDelegateSigningKey (SigningKey GenesisDelegateKey) | AGenesisDelegateExtendedSigningKey (SigningKey GenesisDelegateExtendedKey) | AGenesisUTxOSigningKey (SigningKey GenesisUTxOKey) + | ADRepSigningKey (SigningKey DRepKey) + | ADRepExtendedSigningKey (SigningKey DRepExtendedKey) + | ACommitteeColdSigningKey (SigningKey CommitteeColdKey) + | ACommitteeColdExtendedSigningKey (SigningKey CommitteeColdExtendedKey) + | ACommitteeHotSigningKey (SigningKey CommitteeHotKey) + | ACommitteeHotExtendedSigningKey (SigningKey CommitteeHotExtendedKey) | AVrfSigningKey (SigningKey VrfKey) | AKesSigningKey (SigningKey KesKey) @@ -375,6 +381,12 @@ withSomeSigningKey ssk f = AGenesisDelegateSigningKey sk -> f sk AGenesisDelegateExtendedSigningKey sk -> f sk AGenesisUTxOSigningKey sk -> f sk + ADRepSigningKey sk -> f sk + ADRepExtendedSigningKey sk -> f sk + ACommitteeColdSigningKey sk -> f sk + ACommitteeColdExtendedSigningKey sk -> f sk + ACommitteeHotSigningKey sk -> f sk + ACommitteeHotExtendedSigningKey sk -> f sk AVrfSigningKey sk -> f sk AKesSigningKey sk -> f sk @@ -385,6 +397,8 @@ readSigningKeyFile skFile = newExceptT $ readKeyFileAnyOf bech32FileTypes textEnvFileTypes skFile where + -- If you update these variables, consider updating the ones with the same + -- names in Cardano.CLI.Read textEnvFileTypes = [ FromSomeType (AsSigningKey AsByronKey) AByronSigningKey , FromSomeType (AsSigningKey AsPaymentKey) APaymentSigningKey @@ -397,6 +411,12 @@ readSigningKeyFile skFile = , FromSomeType (AsSigningKey AsGenesisDelegateKey) AGenesisDelegateSigningKey , FromSomeType (AsSigningKey AsGenesisDelegateExtendedKey) AGenesisDelegateExtendedSigningKey , FromSomeType (AsSigningKey AsGenesisUTxOKey) AGenesisUTxOSigningKey + , FromSomeType (AsSigningKey AsDRepKey) ADRepSigningKey + , FromSomeType (AsSigningKey AsDRepExtendedKey) ADRepExtendedSigningKey + , FromSomeType (AsSigningKey AsCommitteeColdKey) ACommitteeColdSigningKey + , FromSomeType (AsSigningKey AsCommitteeColdExtendedKey) ACommitteeColdExtendedSigningKey + , FromSomeType (AsSigningKey AsCommitteeHotKey) ACommitteeHotSigningKey + , FromSomeType (AsSigningKey AsCommitteeHotExtendedKey) ACommitteeHotExtendedSigningKey , FromSomeType (AsSigningKey AsVrfKey) AVrfSigningKey , FromSomeType (AsSigningKey AsKesKey) AKesSigningKey ] @@ -409,4 +429,4 @@ readSigningKeyFile skFile = , FromSomeType (AsSigningKey AsStakePoolKey) AStakePoolSigningKey , FromSomeType (AsSigningKey AsVrfKey) AVrfSigningKey , FromSomeType (AsSigningKey AsKesKey) AKesSigningKey - ] + ] \ No newline at end of file