Skip to content

Commit

Permalink
Update usage of Hydra.Crypto to new interface
Browse files Browse the repository at this point in the history
  • Loading branch information
ch1bo committed Jun 9, 2022
1 parent 2050c15 commit e11eb5a
Show file tree
Hide file tree
Showing 20 changed files with 113 additions and 134 deletions.
4 changes: 2 additions & 2 deletions hydra-cluster/bench/Bench/EndToEnd.hs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ import Data.Set ((\\))
import qualified Data.Set as Set
import Data.Time (UTCTime (UTCTime), nominalDiffTimeToSeconds, utctDayTime)
import Hydra.Cardano.Api (Tx, TxId, UTxO, getVerificationKey)
import qualified Hydra.Crypto as Hydra
import Hydra.Crypto (generateSigningKey)
import Hydra.Generator (ClientDataset (..), Dataset (..))
import Hydra.Ledger (txId)
import Hydra.Logging (withTracerOutputTo)
Expand Down Expand Up @@ -77,7 +77,7 @@ bench timeoutSeconds workDir dataset@Dataset{clientDatasets} clusterSize =
failAfter timeoutSeconds $ do
putTextLn "Starting benchmark"
let cardanoKeys = map (\ClientDataset{signingKey} -> (getVerificationKey signingKey, signingKey)) clientDatasets
let hydraKeys = Hydra.generateSigningKey . show <$> [1 .. toInteger (length cardanoKeys)]
let hydraKeys = generateSigningKey . show <$> [1 .. toInteger (length cardanoKeys)]
let parties = Set.fromList (deriveParty <$> hydraKeys)
config <- newNodeConfig workDir
withOSStats workDir $
Expand Down
15 changes: 7 additions & 8 deletions hydra-cluster/src/HydraNode.hs
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ import qualified Data.ByteString as BS
import qualified Data.List as List
import qualified Data.Text as T
import Hydra.Cluster.Util (readConfigFile)
import Hydra.Crypto (deriveVerificationKey, serialiseSigningKeyToRawBytes, serialiseVerificationKeyToRawBytes)
import qualified Hydra.Crypto as Hydra
import Hydra.Crypto (HydraKey)
import Hydra.Logging (Tracer, traceWith)
import Hydra.Network (Host (Host))
import qualified Hydra.Network as Network
Expand Down Expand Up @@ -196,7 +195,7 @@ withHydraCluster ::
Int ->
-- | NOTE: This decides on the size of the cluster!
[(VerificationKey PaymentKey, SigningKey PaymentKey)] ->
[Hydra.SigningKey] ->
[SigningKey HydraKey] ->
(NonEmpty HydraClient -> IO ()) ->
IO ()
withHydraCluster tracer workDir nodeSocket firstNodeId allKeys hydraKeys action = do
Expand All @@ -218,7 +217,7 @@ withHydraCluster tracer workDir nodeSocket firstNodeId allKeys hydraKeys action
[] -> action (fromList $ reverse clients)
(nodeId : rest) -> do
let hydraSKey = hydraKeys Prelude.!! (nodeId - firstNodeId)
hydraVKeys = map deriveVerificationKey $ filter (/= hydraSKey) hydraKeys
hydraVKeys = map getVerificationKey $ filter (/= hydraSKey) hydraKeys
cardanoVerificationKeys = [workDir </> show i <.> "vk" | i <- allNodeIds, i /= nodeId]
cardanoSigningKey = workDir </> show nodeId <.> "sk"
chainConfig =
Expand All @@ -242,8 +241,8 @@ withHydraNode ::
ChainConfig ->
FilePath ->
Int ->
Hydra.SigningKey ->
[Hydra.VerificationKey] ->
SigningKey HydraKey ->
[VerificationKey HydraKey] ->
[Int] ->
(HydraClient -> IO a) ->
IO a
Expand All @@ -255,10 +254,10 @@ withHydraNode tracer chainConfig workDir hydraNodeId hydraSKey hydraVKeys allNod
let cardanoLedgerProtocolParametersFile = dir </> "protocol-parameters.json"
readConfigFile "protocol-parameters.json" >>= writeFileBS cardanoLedgerProtocolParametersFile
let hydraSigningKey = dir </> (show hydraNodeId <> ".sk")
BS.writeFile hydraSigningKey (serialiseSigningKeyToRawBytes hydraSKey)
BS.writeFile hydraSigningKey (serialiseToRawBytes hydraSKey)
hydraVerificationKeys <- forM (zip [1 ..] hydraVKeys) $ \(i :: Int, vKey) -> do
let filepath = dir </> (show i <> ".vk")
filepath <$ BS.writeFile filepath (serialiseVerificationKeyToRawBytes vKey)
filepath <$ BS.writeFile filepath (serialiseToRawBytes vKey)
let ledgerConfig =
CardanoLedgerConfig
{ cardanoLedgerGenesisFile
Expand Down
6 changes: 3 additions & 3 deletions hydra-cluster/test/Test/DirectChainSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import Control.Concurrent (MVar, newEmptyMVar, putMVar, takeMVar)
import qualified Data.ByteString.Char8 as B8
import Hydra.Cardano.Api (
ChainPoint (..),
SigningKey,
lovelaceToValue,
txOutValue,
unSlotNo,
Expand All @@ -46,8 +47,7 @@ import Hydra.Chain.Direct (
withIOManager,
)
import Hydra.Chain.Direct.Handlers (DirectChainLog, closeGraceTime)
import Hydra.Crypto (aggregate, generateSigningKey, sign)
import qualified Hydra.Crypto as Hydra
import Hydra.Crypto (HydraKey, aggregate, generateSigningKey, sign)
import Hydra.Ledger (IsTx (..))
import Hydra.Ledger.Cardano (Tx, genOneUTxOFor)
import Hydra.Logging (nullTracer, showLogsOnFailure)
Expand Down Expand Up @@ -274,7 +274,7 @@ alice = deriveParty aliceSigningKey
bob = deriveParty $ generateSigningKey "bob"
carol = deriveParty $ generateSigningKey "carol"

aliceSigningKey :: Hydra.SigningKey
aliceSigningKey :: SigningKey HydraKey
aliceSigningKey = generateSigningKey "alice"

data TestClusterLog
Expand Down
15 changes: 8 additions & 7 deletions hydra-cluster/test/Test/EndToEndSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,18 @@ import Hydra.Cardano.Api (
NetworkId (Testnet),
NetworkMagic (NetworkMagic),
PaymentKey,
SigningKey,
TxId,
TxIn (..),
VerificationKey,
getVerificationKey,
lovelaceToValue,
mkVkAddress,
serialiseAddress,
unSlotNo,
)
import Hydra.Chain.Direct.Handlers (closeGraceTime)
import Hydra.Crypto (deriveVerificationKey, generateSigningKey)
import qualified Hydra.Crypto as Hydra
import Hydra.Crypto (HydraKey, generateSigningKey)
import Hydra.Ledger (txId)
import Hydra.Ledger.Cardano (genKeyPair, mkSimpleTx)
import Hydra.Logging (Tracer, showLogsOnFailure)
Expand Down Expand Up @@ -71,15 +72,15 @@ allNodeIds = [1 .. 3]

spec :: Spec
spec = around showLogsOnFailure $ do
let aliceSk, bobSk, carolSk :: Hydra.SigningKey
let aliceSk, bobSk, carolSk :: SigningKey HydraKey
aliceSk = generateSigningKey "alice"
bobSk = generateSigningKey "bob"
carolSk = generateSigningKey "carol"

aliceVk, bobVk, carolVk :: Hydra.VerificationKey
aliceVk = deriveVerificationKey aliceSk
bobVk = deriveVerificationKey bobSk
carolVk = deriveVerificationKey carolSk
aliceVk, bobVk, carolVk :: VerificationKey HydraKey
aliceVk = getVerificationKey aliceSk
bobVk = getVerificationKey bobSk
carolVk = getVerificationKey carolSk

alice, bob, carol :: Party
alice = deriveParty aliceSk
Expand Down
5 changes: 2 additions & 3 deletions hydra-node/src/Hydra/Chain/Direct/Context.hs
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ import Hydra.Chain.Direct.State (
initialize,
observeTx,
)
import Hydra.Crypto (HydraKey)
import qualified Hydra.Crypto as Hydra
import Hydra.Crypto (HydraKey, generateSigningKey)
import Hydra.Ledger.Cardano (genOneUTxOFor, genTxIn, genUTxO, genVerificationKey, renderTx, simplifyUTxO)
import Hydra.Ledger.Cardano.Evaluate (genPointInTime, slotNoToPOSIXTime)
import Hydra.Party (Party, deriveParty)
Expand Down Expand Up @@ -75,7 +74,7 @@ genHydraContext maxParties = choose (1, maxParties) >>= genHydraContextFor
genHydraContextFor :: Int -> Gen HydraContext
genHydraContextFor n = do
ctxVerificationKeys <- replicateM n genVerificationKey
ctxHydraSigningKeys <- fmap Hydra.generateSigningKey <$> vector n
ctxHydraSigningKeys <- fmap generateSigningKey <$> vector n
ctxNetworkId <- Testnet . NetworkMagic <$> arbitrary
ctxContestationPeriod <- arbitrary
pure $
Expand Down
92 changes: 34 additions & 58 deletions hydra-node/src/Hydra/Crypto.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
-- representation. For example: Cardano credentials are 'VerificationKey
-- PaymentKey', Hydra credentials are 'VerificationKey HydraKey'.
--
-- Currently this interface is only supporting naiive, concatenated
-- Currently 'MultiSignature' interface is only supporting naiive, concatenated
-- multi-signatures and will change when we adopt aggregated multi-signatures
-- including aggregate keys.
module Hydra.Crypto where
Expand Down Expand Up @@ -44,7 +44,7 @@ import qualified Data.ByteString as BS
import qualified Data.ByteString.Base16 as Base16
import qualified Data.Map as Map
import Hydra.Cardano.Api (
AsType (AsHash, AsVerificationKey),
AsType (AsHash, AsSigningKey, AsVerificationKey),
HasTextEnvelope (..),
HasTypeProxy (..),
Hash,
Expand Down Expand Up @@ -101,57 +101,41 @@ instance Key HydraKey where
deriving newtype (ToCBOR, FromCBOR)
deriving anyclass (SerialiseAsCBOR)

getVerificationKey = deriveVerificationKey
-- Get the 'VerificationKey' for a given 'SigningKey'.
getVerificationKey (HydraSigningKey sk) =
HydraVerificationKey $ deriveVerKeyDSIGN sk

-- Create a new 'SigningKey' from a 'Seed'. See 'generateSigningKey'
deterministicSigningKey AsHydraKey =
generateSigningKey . getSeedBytes

-- Get the number of bytes required to seed a signing key with
-- 'deterministicSigningKey'.
deterministicSigningKeySeedSize AsHydraKey =
seedSizeDSIGN (Proxy :: Proxy SignAlg)

verificationKeyHash = hashVerificationKey
-- Get the verification key hash of a 'VerificationKey'. See 'HashAlg' for
-- info on the used hashing algorithm.
verificationKeyHash (HydraVerificationKey vk) =
HydraKeyHash . castHash $ hashVerKeyDSIGN vk

instance Arbitrary (SigningKey HydraKey) where
arbitrary = generateSigningKey <$> arbitrary

instance HasTextEnvelope (VerificationKey HydraKey) where
textEnvelopeType _ =
"HydraVerificationKey_"
<> fromString (algorithmNameDSIGN (Proxy :: Proxy SignAlg))
instance SerialiseAsRawBytes (SigningKey HydraKey) where
serialiseToRawBytes (HydraSigningKey sk) =
rawSerialiseSignKeyDSIGN sk

deserialiseFromRawBytes (AsSigningKey AsHydraKey) bs =
HydraSigningKey <$> rawDeserialiseSignKeyDSIGN bs

instance HasTextEnvelope (SigningKey HydraKey) where
textEnvelopeType _ =
"HydraSigningKey_"
<> fromString (algorithmNameDSIGN (Proxy :: Proxy SignAlg))

-- | Serialise the signing key material as raw bytes.
serialiseSigningKeyToRawBytes :: SigningKey HydraKey -> ByteString
serialiseSigningKeyToRawBytes (HydraSigningKey sk) = rawSerialiseSignKeyDSIGN sk
{-# DEPRECATED serialiseSigningKeyToRawBytes "use Key interface instead" #-}

-- | Deserialise a signing key from raw bytes.
deserialiseSigningKeyFromRawBytes :: MonadFail m => ByteString -> m (SigningKey HydraKey)
deserialiseSigningKeyFromRawBytes bytes =
case rawDeserialiseSignKeyDSIGN bytes of
Nothing -> fail "failed to deserialise signing key"
Just key -> pure $ HydraSigningKey key
{-# DEPRECATED deserialiseSigningKeyFromRawBytes "use Key interface instead" #-}

-- | Get the 'VerificationKey' for a given 'SigningKey'.
deriveVerificationKey :: SigningKey HydraKey -> VerificationKey HydraKey
deriveVerificationKey (HydraSigningKey sk) = HydraVerificationKey (deriveVerKeyDSIGN sk)
{-# DEPRECATED deriveVerificationKey "use Key interface instead" #-}

-- | Create a new 'SigningKey' from a 'ByteString' seed. The created keys are
-- not random and insecure, so don't use this in production code!
generateSigningKey :: ByteString -> SigningKey HydraKey
generateSigningKey seed =
HydraSigningKey . genKeyDSIGN $ mkSeedFromBytes padded
where
needed = fromIntegral $ seedSizeDSIGN (Proxy :: Proxy SignAlg)
provided = BS.length seed
padded = seed <> BS.pack (replicate (needed - provided) 0)
{-# DEPRECATED generateSigningKey "use Key interface instead" #-}
instance Arbitrary (VerificationKey HydraKey) where
arbitrary = getVerificationKey . generateSigningKey <$> arbitrary

instance SerialiseAsRawBytes (VerificationKey HydraKey) where
serialiseToRawBytes (HydraVerificationKey vk) =
Expand Down Expand Up @@ -180,28 +164,20 @@ instance FromJSON (VerificationKey HydraKey) where
(pure . HydraVerificationKey)
. rawDeserialiseVerKeyDSIGN

instance Arbitrary (VerificationKey HydraKey) where
arbitrary = deriveVerificationKey . generateSigningKey <$> arbitrary

-- | Serialise the verification key material as raw bytes.
serialiseVerificationKeyToRawBytes :: VerificationKey HydraKey -> ByteString
serialiseVerificationKeyToRawBytes (HydraVerificationKey vk) = rawSerialiseVerKeyDSIGN vk
{-# DEPRECATED serialiseVerificationKeyToRawBytes "use Key interface instead" #-}

-- | Deserialise a verirfication key from raw bytes.
deserialiseVerificationKeyFromRawBytes :: MonadFail m => ByteString -> m (VerificationKey HydraKey)
deserialiseVerificationKeyFromRawBytes bytes =
case rawDeserialiseVerKeyDSIGN bytes of
Nothing -> fail "failed to deserialise verification key"
Just key -> pure $ HydraVerificationKey key
{-# DEPRECATED deserialiseVerificationKeyFromRawBytes "use Key interface instead" #-}

-- | Get the verification key hash of a 'VerificationKey'. See 'HashAlg' for
-- info on the used hashing algorithm.
hashVerificationKey :: VerificationKey HydraKey -> Hash HydraKey
hashVerificationKey (HydraVerificationKey vk) =
HydraKeyHash . castHash $ hashVerKeyDSIGN vk
{-# DEPRECATED hashVerificationKey "use Key interface instead" #-}
instance HasTextEnvelope (VerificationKey HydraKey) where
textEnvelopeType _ =
"HydraVerificationKey_"
<> fromString (algorithmNameDSIGN (Proxy :: Proxy SignAlg))

-- | Create a new 'SigningKey' from a 'ByteString' seed. The created keys are
-- not random and insecure, so don't use this in production code!
generateSigningKey :: ByteString -> SigningKey HydraKey
generateSigningKey seed =
HydraSigningKey . genKeyDSIGN $ mkSeedFromBytes padded
where
needed = fromIntegral $ seedSizeDSIGN (Proxy :: Proxy SignAlg)
provided = BS.length seed
padded = seed <> BS.pack (replicate (needed - provided) 0)

-- * Signatures

Expand Down
4 changes: 2 additions & 2 deletions hydra-node/src/Hydra/Network/Message.hs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ module Hydra.Network.Message where

import Hydra.Prelude

import qualified Hydra.Crypto as Hydra
import Hydra.Crypto (Signature)
import Hydra.Ledger (IsTx, UTxOType)
import Hydra.Network (Host)
import Hydra.Party (Party)
Expand All @@ -15,7 +15,7 @@ import Hydra.Snapshot (Snapshot, SnapshotNumber)
data Message tx
= ReqTx {party :: Party, transaction :: tx}
| ReqSn {party :: Party, snapshotNumber :: SnapshotNumber, transactions :: [tx]}
| AckSn {party :: Party, signed :: Hydra.Signature (Snapshot tx), snapshotNumber :: SnapshotNumber}
| AckSn {party :: Party, signed :: Signature (Snapshot tx), snapshotNumber :: SnapshotNumber}
| Connected {peer :: Host}
| Disconnected {peer :: Host}
deriving stock (Generic, Eq, Show)
Expand Down
14 changes: 8 additions & 6 deletions hydra-node/src/Hydra/Node.hs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,10 @@ import Control.Monad.Class.MonadSTM (
writeTQueue,
)
import Hydra.API.Server (Server, sendOutput)
import Hydra.Cardano.Api (AsType (AsSigningKey, AsVerificationKey), deserialiseFromRawBytes)
import Hydra.Chain (Chain (..), ChainEvent, PostTxError)
import Hydra.ClientInput (ClientInput)
import Hydra.Crypto (
deserialiseSigningKeyFromRawBytes,
deserialiseVerificationKeyFromRawBytes,
)
import Hydra.Crypto (AsType (AsHydraKey))
import Hydra.HeadLogic (
Effect (..),
Environment (..),
Expand Down Expand Up @@ -69,14 +67,18 @@ initEnvironment Options{hydraSigningKey, hydraVerificationKeys} = do
, otherParties
}
where
-- TODO: use text envelopes instead of this maybe fail stuff
loadSigningKey p =
readFileBS p >>= deserialiseSigningKeyFromRawBytes
readFileBS p >>= maybeFail <$> deserialiseFromRawBytes (AsSigningKey AsHydraKey)

loadParty p =
Party <$> loadVerificationKey p

loadVerificationKey p = do
readFileBS p >>= deserialiseVerificationKeyFromRawBytes
readFileBS p >>= maybeFail <$> deserialiseFromRawBytes (AsVerificationKey AsHydraKey)

maybeFail = maybe (fail "could not deserialise from raw bytes") pure

-- ** Create and run a hydra node

data HydraNode tx m = HydraNode
Expand Down
15 changes: 8 additions & 7 deletions hydra-node/src/Hydra/Party.hs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,8 @@ import Hydra.Prelude hiding (show)

import Data.Aeson (ToJSONKey)
import Data.Aeson.Types (FromJSONKey)
import Hydra.Cardano.Api (SigningKey, VerificationKey)
import Hydra.Crypto (HydraKey, hashVerificationKey)
import qualified Hydra.Crypto as Hydra
import Hydra.Cardano.Api (AsType (AsVerificationKey), SerialiseAsRawBytes (deserialiseFromRawBytes, serialiseToRawBytes), SigningKey, VerificationKey, getVerificationKey, verificationKeyHash)
import Hydra.Crypto (AsType (AsHydraKey), HydraKey)
import qualified Hydra.Data.Party as OnChain

-- | Identifies a party in a Hydra head by it's 'VerificationKey'.
Expand All @@ -21,7 +20,7 @@ newtype Party = Party {vkey :: VerificationKey HydraKey}
-- based on Hashable?
instance Ord Party where
Party{vkey = a} <= Party{vkey = b} =
hashVerificationKey a <= hashVerificationKey b
verificationKeyHash a <= verificationKeyHash b

instance Arbitrary Party where
arbitrary = Party <$> arbitrary
Expand All @@ -34,19 +33,21 @@ instance ToCBOR Party where

-- | Get the 'Party' given some Hydra 'SigningKey'.
deriveParty :: SigningKey HydraKey -> Party
deriveParty = Party . Hydra.deriveVerificationKey
deriveParty = Party . getVerificationKey

-- | Convert "high-level" 'Party' to the "low-level" representation as used
-- on-chain. See 'Hydra.Data.Party.Party' for an explanation why this is a
-- distinct type.
partyToChain :: Party -> OnChain.Party
partyToChain Party{vkey} =
OnChain.partyFromVerificationKeyBytes $ Hydra.serialiseVerificationKeyToRawBytes vkey
OnChain.partyFromVerificationKeyBytes $ serialiseToRawBytes vkey

-- | Retrieve the "high-level" 'Party from the "low-level" on-chain
-- representation. This can fail because of the lower type-safety used on-chain
-- and a non-guaranteed verification key length. See 'Hydra.Data.Party.Party'
-- for an explanation why this is a distinct type.
partyFromChain :: MonadFail m => OnChain.Party -> m Party
partyFromChain =
fmap Party . Hydra.deserialiseVerificationKeyFromRawBytes . OnChain.partyToVerficationKeyBytes
maybe (fail "partyFromChain got Nothing") (pure . Party)
. deserialiseFromRawBytes (AsVerificationKey AsHydraKey)
. OnChain.partyToVerficationKeyBytes
Loading

0 comments on commit e11eb5a

Please sign in to comment.