{-# LANGUAGE CPP #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-}
module Cardano.Api.Keys.Class
( Key (..)
, generateSigningKey
, generateInsecureSigningKey
, CastVerificationKeyRole (..)
, CastSigningKeyRole (..)
, AsType (AsVerificationKey, AsSigningKey)
)
where
import Cardano.Api.Hash
import Cardano.Api.HasTypeProxy
import Cardano.Api.SerialiseRaw
import Cardano.Api.SerialiseTextEnvelope
import qualified Cardano.Crypto.DSIGN.Class as Crypto
import qualified Cardano.Crypto.Seed as Crypto
import Control.Monad.IO.Class
import Data.Kind (Type)
import qualified System.Random as Random
import System.Random (StdGen)
class
( Eq (VerificationKey keyrole)
, Show (VerificationKey keyrole)
, SerialiseAsRawBytes (Hash keyrole)
, HasTextEnvelope (VerificationKey keyrole)
, HasTextEnvelope (SigningKey keyrole)
) =>
Key keyrole
where
data VerificationKey keyrole :: Type
data SigningKey keyrole :: Type
getVerificationKey
:: ()
#if MIN_VERSION_base(4,17,0)
=> HasTypeProxy keyrole
#endif
=> SigningKey keyrole
-> VerificationKey keyrole
deterministicSigningKey :: AsType keyrole -> Crypto.Seed -> SigningKey keyrole
deterministicSigningKeySeedSize :: AsType keyrole -> Word
verificationKeyHash :: VerificationKey keyrole -> Hash keyrole
generateSigningKey
:: MonadIO m
=> Key keyrole
=> AsType keyrole
-> m (SigningKey keyrole)
generateSigningKey :: forall (m :: * -> *) keyrole.
(MonadIO m, Key keyrole) =>
AsType keyrole -> m (SigningKey keyrole)
generateSigningKey AsType keyrole
keytype = do
Seed
seed <- IO Seed -> m Seed
forall a. IO a -> m a
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO Seed -> m Seed) -> IO Seed -> m Seed
forall a b. (a -> b) -> a -> b
$ Word -> IO Seed
Crypto.readSeedFromSystemEntropy Word
seedSize
SigningKey keyrole -> m (SigningKey keyrole)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SigningKey keyrole -> m (SigningKey keyrole))
-> SigningKey keyrole -> m (SigningKey keyrole)
forall a b. (a -> b) -> a -> b
$! AsType keyrole -> Seed -> SigningKey keyrole
forall keyrole.
Key keyrole =>
AsType keyrole -> Seed -> SigningKey keyrole
deterministicSigningKey AsType keyrole
keytype Seed
seed
where
seedSize :: Word
seedSize = AsType keyrole -> Word
forall keyrole. Key keyrole => AsType keyrole -> Word
deterministicSigningKeySeedSize AsType keyrole
keytype
generateInsecureSigningKey
:: MonadIO m
=> Key keyrole
=> SerialiseAsRawBytes (SigningKey keyrole)
=> StdGen
-> AsType keyrole
-> m (SigningKey keyrole, StdGen)
generateInsecureSigningKey :: forall (m :: * -> *) keyrole.
(MonadIO m, Key keyrole,
SerialiseAsRawBytes (SigningKey keyrole)) =>
StdGen -> AsType keyrole -> m (SigningKey keyrole, StdGen)
generateInsecureSigningKey StdGen
g AsType keyrole
keytype = do
let (ByteString
bs, StdGen
g') = Int -> StdGen -> (ByteString, StdGen)
forall g. RandomGen g => Int -> g -> (ByteString, g)
Random.genByteString (Word -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Word -> Int) -> Word -> Int
forall a b. (a -> b) -> a -> b
$ AsType keyrole -> Word
forall keyrole. Key keyrole => AsType keyrole -> Word
deterministicSigningKeySeedSize AsType keyrole
keytype) StdGen
g
case AsType (SigningKey keyrole)
-> ByteString
-> Either SerialiseAsRawBytesError (SigningKey keyrole)
forall a.
SerialiseAsRawBytes a =>
AsType a -> ByteString -> Either SerialiseAsRawBytesError a
deserialiseFromRawBytes (AsType keyrole -> AsType (SigningKey keyrole)
forall a. AsType a -> AsType (SigningKey a)
AsSigningKey AsType keyrole
keytype) ByteString
bs of
Right SigningKey keyrole
key -> (SigningKey keyrole, StdGen) -> m (SigningKey keyrole, StdGen)
forall a. a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (SigningKey keyrole
key, StdGen
g')
Left (SerialiseAsRawBytesError [Char]
msg) -> [Char] -> m (SigningKey keyrole, StdGen)
forall a. HasCallStack => [Char] -> a
error ([Char] -> m (SigningKey keyrole, StdGen))
-> [Char] -> m (SigningKey keyrole, StdGen)
forall a b. (a -> b) -> a -> b
$ [Char]
"generateInsecureSigningKey: Unable to generate insecure key: " [Char] -> [Char] -> [Char]
forall a. Semigroup a => a -> a -> a
<> [Char]
msg
instance HasTypeProxy a => HasTypeProxy (VerificationKey a) where
data AsType (VerificationKey a) = AsVerificationKey (AsType a)
proxyToAsType :: Proxy (VerificationKey a) -> AsType (VerificationKey a)
proxyToAsType Proxy (VerificationKey a)
_ = AsType a -> AsType (VerificationKey a)
forall a. AsType a -> AsType (VerificationKey a)
AsVerificationKey (Proxy a -> AsType a
forall t. HasTypeProxy t => Proxy t -> AsType t
proxyToAsType (Proxy a
forall {a}. Proxy a
forall {k} (t :: k). Proxy t
Proxy :: Proxy a))
instance HasTypeProxy a => HasTypeProxy (SigningKey a) where
data AsType (SigningKey a) = AsSigningKey (AsType a)
proxyToAsType :: Proxy (SigningKey a) -> AsType (SigningKey a)
proxyToAsType Proxy (SigningKey a)
_ = AsType a -> AsType (SigningKey a)
forall a. AsType a -> AsType (SigningKey a)
AsSigningKey (Proxy a -> AsType a
forall t. HasTypeProxy t => Proxy t -> AsType t
proxyToAsType (Proxy a
forall {a}. Proxy a
forall {k} (t :: k). Proxy t
Proxy :: Proxy a))
class CastVerificationKeyRole keyroleA keyroleB where
castVerificationKey :: VerificationKey keyroleA -> VerificationKey keyroleB
class CastSigningKeyRole keyroleA keyroleB where
castSigningKey :: SigningKey keyroleA -> SigningKey keyroleB