-- SPDX-FileCopyrightText: 2020 Tocqueville Group
--
-- SPDX-License-Identifier: LicenseRef-MIT-TQ

-- | Cryptographic primitives used in Tezos.
--
-- WARNING: some functions may be vulnerable to timing attacks.
-- Also, this code was not reviewed by cryptography/security experts.
-- Do not use it with secret keys that have some value.
-- We provide 'SecretKey' type and (limited) signing functionality only
-- for testing.
-- If you need to sign something in production, use something else
-- (e. g. `tezos-client`).
--
-- Tezos supports 3 cryptographic curves that are denoted by the
-- number after tz in the public key hash: tz1, tz2 or tz3.
-- • tz1 — ed25519
-- • tz2 — secp256k1
-- • tz3 — P256
-- We have Tezos.Crypto.Curve module for each of these curves.
-- They expose very similar functionality and their main purpose is to hide
-- implementation details for each curve as well as some other specifics (e. g.
-- prefixes that are used for human-readable representation).
--
-- This module serves two purposes:
-- 1. It is an umbrella module that re-exports some stuff from other modules.
-- 2. Michelson types such as `key` and `signature` may store primitive of any
-- curve, so we need "union" types in Haskell as well.
--
-- During conversion to human-readable representation usually some magical
-- prefix is used. They have been found in source code in some repos (e. g.
-- <https://gitlab.com/tezos/tezos/blob/c52ee69231c5ae4d9cec1f3c8aba0c3573922e2a/src/lib_crypto/base58.ml>)
-- and checked manually. Existing tests confirm they are correct.

module Tezos.Crypto
  ( -- * Cryptographic primitive types
    PublicKey (..)
  , SecretKey (..) -- Currently we need to differentiate secret keys in morley-client
  , Signature (..)
  , KeyHashTag (..)
  , KeyHash (..)

  -- * Public/secret key functions
  , detSecretKey
  , toPublic

  -- * Signature
  , signatureToBytes
  , mkSignature
  , parseSignatureRaw
  , signatureLengthBytes
  , checkSignature

  -- * Formatting
  , CryptoParseError (..)
  , formatPublicKey
  , mformatPublicKey
  , parsePublicKey
  , parsePublicKeyRaw
  , formatSignature
  , mformatSignature
  , parseSignature
  , formatKeyHash
  , mformatKeyHash
  , parseKeyHash
  , parseKeyHashRaw
  , keyHashLengthBytes
  , formatSecretKey
  , parseSecretKey

  -- * Hashing
  , hashKey
  , blake2b
  , blake2b160
  , sha256
  , sha512

  -- * Utilities
  , encodeBase58Check
  , decodeBase58Check
  , B58CheckWithPrefixError (..)
  , decodeBase58CheckWithPrefix
  , keyDecoders
  , keyHashDecoders
  ) where

import Data.Aeson (FromJSON(..), ToJSON(..))
import qualified Data.Aeson as Aeson
import qualified Data.Aeson.Encoding as Aeson
import qualified Data.Binary.Get as Get
import qualified Data.ByteArray as BA
import qualified Data.ByteString as BS
import qualified Data.ByteString.Lazy as LBS
import qualified Data.Text as T
import Fmt (Buildable, build, hexF, pretty)
import Test.QuickCheck (Arbitrary(..), elements, oneof)

import Michelson.Text
import qualified Tezos.Crypto.Ed25519 as Ed25519
import Tezos.Crypto.Hash
import qualified Tezos.Crypto.P256 as P256
import qualified Tezos.Crypto.Secp256k1 as Secp256k1
import Tezos.Crypto.Util
import Util.CLI
import Util.Binary

----------------------------------------------------------------------------
-- Types, instances, conversions
----------------------------------------------------------------------------

-- | Public cryptographic key used by Tezos.
-- There are three cryptographic curves each represented by its own constructor.
data PublicKey
  = PublicKeyEd25519 Ed25519.PublicKey
  -- ^ Public key that uses the ed25519 cryptographic curve.
  | PublicKeySecp256k1 Secp256k1.PublicKey
  -- ^ Public key that uses the secp256k1 cryptographic curve.
  | PublicKeyP256 P256.PublicKey
  -- ^ Public key that uses the NIST P-256 cryptographic curve.
  deriving stock (Int -> PublicKey -> ShowS
[PublicKey] -> ShowS
PublicKey -> String
(Int -> PublicKey -> ShowS)
-> (PublicKey -> String)
-> ([PublicKey] -> ShowS)
-> Show PublicKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PublicKey] -> ShowS
$cshowList :: [PublicKey] -> ShowS
show :: PublicKey -> String
$cshow :: PublicKey -> String
showsPrec :: Int -> PublicKey -> ShowS
$cshowsPrec :: Int -> PublicKey -> ShowS
Show, PublicKey -> PublicKey -> Bool
(PublicKey -> PublicKey -> Bool)
-> (PublicKey -> PublicKey -> Bool) -> Eq PublicKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PublicKey -> PublicKey -> Bool
$c/= :: PublicKey -> PublicKey -> Bool
== :: PublicKey -> PublicKey -> Bool
$c== :: PublicKey -> PublicKey -> Bool
Eq, (forall x. PublicKey -> Rep PublicKey x)
-> (forall x. Rep PublicKey x -> PublicKey) -> Generic PublicKey
forall x. Rep PublicKey x -> PublicKey
forall x. PublicKey -> Rep PublicKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PublicKey x -> PublicKey
$cfrom :: forall x. PublicKey -> Rep PublicKey x
Generic)

instance NFData PublicKey

instance Arbitrary PublicKey where
  arbitrary :: Gen PublicKey
arbitrary = SecretKey -> PublicKey
toPublic (SecretKey -> PublicKey) -> Gen SecretKey -> Gen PublicKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen SecretKey
forall a. Arbitrary a => Gen a
arbitrary

-- | Secret cryptographic key used by Tezos.
-- Constructors correspond to 'PublicKey' constructors.
data SecretKey
  = SecretKeyEd25519 Ed25519.SecretKey
  -- ^ Secret key that uses the ed25519 cryptographic curve.
  | SecretKeySecp256k1 Secp256k1.SecretKey
  -- ^ Secret key that uses the secp256k1 cryptographic curve.
  | SecretKeyP256 P256.SecretKey
  -- ^ Secret key that uses the NIST P-256 cryptographic curve.
  deriving stock (Int -> SecretKey -> ShowS
[SecretKey] -> ShowS
SecretKey -> String
(Int -> SecretKey -> ShowS)
-> (SecretKey -> String)
-> ([SecretKey] -> ShowS)
-> Show SecretKey
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [SecretKey] -> ShowS
$cshowList :: [SecretKey] -> ShowS
show :: SecretKey -> String
$cshow :: SecretKey -> String
showsPrec :: Int -> SecretKey -> ShowS
$cshowsPrec :: Int -> SecretKey -> ShowS
Show, SecretKey -> SecretKey -> Bool
(SecretKey -> SecretKey -> Bool)
-> (SecretKey -> SecretKey -> Bool) -> Eq SecretKey
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: SecretKey -> SecretKey -> Bool
$c/= :: SecretKey -> SecretKey -> Bool
== :: SecretKey -> SecretKey -> Bool
$c== :: SecretKey -> SecretKey -> Bool
Eq, (forall x. SecretKey -> Rep SecretKey x)
-> (forall x. Rep SecretKey x -> SecretKey) -> Generic SecretKey
forall x. Rep SecretKey x -> SecretKey
forall x. SecretKey -> Rep SecretKey x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep SecretKey x -> SecretKey
$cfrom :: forall x. SecretKey -> Rep SecretKey x
Generic)

instance NFData SecretKey

instance HasCLReader SecretKey where
  getReader :: ReadM SecretKey
getReader = (String -> Either String SecretKey) -> ReadM SecretKey
forall a. (String -> Either String a) -> ReadM a
eitherReader ((CryptoParseError -> String)
-> Either CryptoParseError SecretKey -> Either String SecretKey
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first CryptoParseError -> String
forall a b. (Buildable a, FromBuilder b) => a -> b
pretty (Either CryptoParseError SecretKey -> Either String SecretKey)
-> (String -> Either CryptoParseError SecretKey)
-> String
-> Either String SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError SecretKey
parseSecretKey (Text -> Either CryptoParseError SecretKey)
-> (String -> Text) -> String -> Either CryptoParseError SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a. ToText a => a -> Text
toText)
  getMetavar :: String
getMetavar = "SECRET_KEY"


-- | Deterministicaly generate a secret key from seed.
-- Type of the key depends on seed length.
detSecretKey :: HasCallStack => ByteString -> SecretKey
detSecretKey :: ByteString -> SecretKey
detSecretKey seed :: ByteString
seed = ByteString
seed ByteString -> (ByteString -> SecretKey) -> SecretKey
forall a b. a -> (a -> b) -> b
& case (ByteString -> Int
forall t. Container t => t -> Int
length ByteString
seed Int -> Int -> Int
forall a. Num a => a -> a -> a
+ 2) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` 3 of
  0 -> SecretKey -> SecretKey
SecretKeyEd25519 (SecretKey -> SecretKey)
-> (ByteString -> SecretKey) -> ByteString -> SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> SecretKey
Ed25519.detSecretKey
  1 -> SecretKey -> SecretKey
SecretKeySecp256k1 (SecretKey -> SecretKey)
-> (ByteString -> SecretKey) -> ByteString -> SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> SecretKey
Secp256k1.detSecretKey
  2 -> SecretKey -> SecretKey
SecretKeyP256 (SecretKey -> SecretKey)
-> (ByteString -> SecretKey) -> ByteString -> SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> SecretKey
P256.detSecretKey
  _ -> Text -> ByteString -> SecretKey
forall a. HasCallStack => Text -> a
error "detSecretKey: unexpected happened"

instance Arbitrary SecretKey where
  arbitrary :: Gen SecretKey
arbitrary = [Gen SecretKey] -> Gen SecretKey
forall a. [Gen a] -> Gen a
oneof
    [ SecretKey -> SecretKey
SecretKeyEd25519 (SecretKey -> SecretKey) -> Gen SecretKey -> Gen SecretKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen SecretKey
forall a. Arbitrary a => Gen a
arbitrary
    , SecretKey -> SecretKey
SecretKeySecp256k1 (SecretKey -> SecretKey) -> Gen SecretKey -> Gen SecretKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen SecretKey
forall a. Arbitrary a => Gen a
arbitrary
    , SecretKey -> SecretKey
SecretKeyP256 (SecretKey -> SecretKey) -> Gen SecretKey -> Gen SecretKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen SecretKey
forall a. Arbitrary a => Gen a
arbitrary
    ]

-- | Create a public key from a secret key.
toPublic :: SecretKey -> PublicKey
toPublic :: SecretKey -> PublicKey
toPublic = \case
  SecretKeyEd25519 sk :: SecretKey
sk -> PublicKey -> PublicKey
PublicKeyEd25519 (PublicKey -> PublicKey)
-> (SecretKey -> PublicKey) -> SecretKey -> PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> PublicKey
Ed25519.toPublic (SecretKey -> PublicKey) -> SecretKey -> PublicKey
forall a b. (a -> b) -> a -> b
$ SecretKey
sk
  SecretKeySecp256k1 sk :: SecretKey
sk -> PublicKey -> PublicKey
PublicKeySecp256k1 (PublicKey -> PublicKey)
-> (SecretKey -> PublicKey) -> SecretKey -> PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> PublicKey
Secp256k1.toPublic (SecretKey -> PublicKey) -> SecretKey -> PublicKey
forall a b. (a -> b) -> a -> b
$ SecretKey
sk
  SecretKeyP256 sk :: SecretKey
sk -> PublicKey -> PublicKey
PublicKeyP256 (PublicKey -> PublicKey)
-> (SecretKey -> PublicKey) -> SecretKey -> PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> PublicKey
P256.toPublic (SecretKey -> PublicKey) -> SecretKey -> PublicKey
forall a b. (a -> b) -> a -> b
$ SecretKey
sk

-- | Cryptographic signatures used by Tezos.
-- Constructors correspond to 'PublicKey' constructors.
--
-- Tezos distinguishes signatures for different curves.
-- For instance, ed25519 signatures and secp256k1 signatures
-- are printed differently (have different prefix).
-- However, signatures are packed without information about the
-- curve. For this purpose there is a generic signature which
-- only stores bytes and doesn't carry information about the curve.
-- Apparently unpacking from bytes always produces such signature.
-- Unpacking from string produces a signature with curve information.
data Signature
  = SignatureEd25519 Ed25519.Signature
  -- ^ Signature that uses the ed25519 cryptographic curve.
  | SignatureSecp256k1 Secp256k1.Signature
  -- ^ Siganture that uses the secp256k1 cryptographic curve.
  | SignatureP256 P256.Signature
  -- ^ Signature that uses the NIST P-256 cryptographic curve.
  | SignatureGeneric ByteString
  -- ^ Generic signature for which curve is unknown.
  deriving stock (Int -> Signature -> ShowS
[Signature] -> ShowS
Signature -> String
(Int -> Signature -> ShowS)
-> (Signature -> String)
-> ([Signature] -> ShowS)
-> Show Signature
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Signature] -> ShowS
$cshowList :: [Signature] -> ShowS
show :: Signature -> String
$cshow :: Signature -> String
showsPrec :: Int -> Signature -> ShowS
$cshowsPrec :: Int -> Signature -> ShowS
Show, (forall x. Signature -> Rep Signature x)
-> (forall x. Rep Signature x -> Signature) -> Generic Signature
forall x. Rep Signature x -> Signature
forall x. Signature -> Rep Signature x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep Signature x -> Signature
$cfrom :: forall x. Signature -> Rep Signature x
Generic)

instance NFData Signature

-- This instance slightly differs from the default one. If one
-- signature is generic and the other one is not, they still may be
-- equal if they have the same byte representation.
-- With default instance packing a signature and unpacking it would produce
-- a different (with respect to 'Eq') signature which is inconvenient.
instance Eq Signature where
  sig1 :: Signature
sig1 == :: Signature -> Signature -> Bool
== sig2 :: Signature
sig2 = case (Signature
sig1, Signature
sig2) of
    (SignatureGeneric bytes1 :: ByteString
bytes1, SignatureGeneric bytes2 :: ByteString
bytes2) -> ByteString
bytes1 ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
bytes2
    (SignatureGeneric bytes1 :: ByteString
bytes1, SignatureEd25519 (Signature -> ByteString
forall ba. ByteArray ba => Signature -> ba
Ed25519.signatureToBytes -> ByteString
bytes2)) ->
      ByteString
bytes1 ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
bytes2
    (SignatureGeneric bytes1 :: ByteString
bytes1, SignatureSecp256k1 (Signature -> ByteString
forall ba. ByteArray ba => Signature -> ba
Secp256k1.signatureToBytes -> ByteString
bytes2)) ->
      ByteString
bytes1 ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
bytes2
    (SignatureGeneric bytes1 :: ByteString
bytes1, SignatureP256 (Signature -> ByteString
forall ba. ByteArray ba => Signature -> ba
P256.signatureToBytes -> ByteString
bytes2)) ->
      ByteString
bytes1 ByteString -> ByteString -> Bool
forall a. Eq a => a -> a -> Bool
== ByteString
bytes2

    (_, SignatureGeneric {}) -> Signature
sig2 Signature -> Signature -> Bool
forall a. Eq a => a -> a -> Bool
== Signature
sig1

    (SignatureEd25519 s1 :: Signature
s1, SignatureEd25519 s2 :: Signature
s2) -> Signature
s1 Signature -> Signature -> Bool
forall a. Eq a => a -> a -> Bool
== Signature
s2
    (SignatureEd25519 {}, _) -> Bool
False

    (SignatureSecp256k1 s1 :: Signature
s1, SignatureSecp256k1 s2 :: Signature
s2) -> Signature
s1 Signature -> Signature -> Bool
forall a. Eq a => a -> a -> Bool
== Signature
s2
    (SignatureSecp256k1 {}, _) -> Bool
False

    (SignatureP256 s1 :: Signature
s1, SignatureP256 s2 :: Signature
s2) -> Signature
s1 Signature -> Signature -> Bool
forall a. Eq a => a -> a -> Bool
== Signature
s2
    (SignatureP256 {}, _) -> Bool
False

instance Arbitrary Signature where
  arbitrary :: Gen Signature
arbitrary = [Gen Signature] -> Gen Signature
forall a. [Gen a] -> Gen a
oneof
    [ Signature -> Signature
SignatureEd25519 (Signature -> Signature) -> Gen Signature -> Gen Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Signature
forall a. Arbitrary a => Gen a
arbitrary
    , Signature -> Signature
SignatureSecp256k1 (Signature -> Signature) -> Gen Signature -> Gen Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Signature
forall a. Arbitrary a => Gen a
arbitrary
    , Signature -> Signature
SignatureP256 (Signature -> Signature) -> Gen Signature -> Gen Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Signature
forall a. Arbitrary a => Gen a
arbitrary
    , ByteString -> Signature
SignatureGeneric (ByteString -> Signature)
-> (Word8 -> ByteString) -> Word8 -> Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> Word8 -> ByteString
BS.replicate Int
forall n. (HasCallStack, Integral n) => n
signatureLengthBytes (Word8 -> Signature) -> Gen Word8 -> Gen Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen Word8
forall a. Arbitrary a => Gen a
arbitrary
    ]

----------------------------------------------------------------------------
-- Signature
----------------------------------------------------------------------------

-- | Convert a 'Signature' to raw bytes.
signatureToBytes :: BA.ByteArray ba => Signature -> ba
signatureToBytes :: Signature -> ba
signatureToBytes = \case
  SignatureEd25519 sig :: Signature
sig -> Signature -> ba
forall ba. ByteArray ba => Signature -> ba
Ed25519.signatureToBytes Signature
sig
  SignatureSecp256k1 sig :: Signature
sig -> Signature -> ba
forall ba. ByteArray ba => Signature -> ba
Secp256k1.signatureToBytes Signature
sig
  SignatureP256 sig :: Signature
sig -> Signature -> ba
forall ba. ByteArray ba => Signature -> ba
P256.signatureToBytes Signature
sig
  SignatureGeneric bytes :: ByteString
bytes -> ByteString -> ba
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert ByteString
bytes

-- | Make a 'Signature' from raw bytes.
-- Can return only generic signature.
mkSignature :: BA.ByteArray ba => ba -> Maybe Signature
mkSignature :: ba -> Maybe Signature
mkSignature ba :: ba
ba =
  ByteString -> Signature
SignatureGeneric (ba -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert ba
ba) Signature -> Maybe () -> Maybe Signature
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Bool -> Maybe ()
forall (f :: * -> *). Alternative f => Bool -> f ()
guard (Int
l Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
forall n. (HasCallStack, Integral n) => n
signatureLengthBytes)
  where
    l :: Int
l = ba -> Int
forall ba. ByteArrayAccess ba => ba -> Int
BA.length ba
ba

parseSignatureRaw :: ByteString -> Either ParseSignatureRawError Signature
parseSignatureRaw :: ByteString -> Either ParseSignatureRawError Signature
parseSignatureRaw ba :: ByteString
ba = ParseSignatureRawError
-> Maybe Signature -> Either ParseSignatureRawError Signature
forall l r. l -> Maybe r -> Either l r
maybeToRight (ByteString -> ParseSignatureRawError
ParseSignatureRawWrongSize ByteString
ba) (Maybe Signature -> Either ParseSignatureRawError Signature)
-> Maybe Signature -> Either ParseSignatureRawError Signature
forall a b. (a -> b) -> a -> b
$ ByteString -> Maybe Signature
forall ba. ByteArray ba => ba -> Maybe Signature
mkSignature ByteString
ba

data ParseSignatureRawError
  = ParseSignatureRawWrongSize ByteString
  deriving stock (ParseSignatureRawError -> ParseSignatureRawError -> Bool
(ParseSignatureRawError -> ParseSignatureRawError -> Bool)
-> (ParseSignatureRawError -> ParseSignatureRawError -> Bool)
-> Eq ParseSignatureRawError
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ParseSignatureRawError -> ParseSignatureRawError -> Bool
$c/= :: ParseSignatureRawError -> ParseSignatureRawError -> Bool
== :: ParseSignatureRawError -> ParseSignatureRawError -> Bool
$c== :: ParseSignatureRawError -> ParseSignatureRawError -> Bool
Eq, Int -> ParseSignatureRawError -> ShowS
[ParseSignatureRawError] -> ShowS
ParseSignatureRawError -> String
(Int -> ParseSignatureRawError -> ShowS)
-> (ParseSignatureRawError -> String)
-> ([ParseSignatureRawError] -> ShowS)
-> Show ParseSignatureRawError
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ParseSignatureRawError] -> ShowS
$cshowList :: [ParseSignatureRawError] -> ShowS
show :: ParseSignatureRawError -> String
$cshow :: ParseSignatureRawError -> String
showsPrec :: Int -> ParseSignatureRawError -> ShowS
$cshowsPrec :: Int -> ParseSignatureRawError -> ShowS
Show, (forall x. ParseSignatureRawError -> Rep ParseSignatureRawError x)
-> (forall x.
    Rep ParseSignatureRawError x -> ParseSignatureRawError)
-> Generic ParseSignatureRawError
forall x. Rep ParseSignatureRawError x -> ParseSignatureRawError
forall x. ParseSignatureRawError -> Rep ParseSignatureRawError x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ParseSignatureRawError x -> ParseSignatureRawError
$cfrom :: forall x. ParseSignatureRawError -> Rep ParseSignatureRawError x
Generic)

instance Buildable ParseSignatureRawError where
  build :: ParseSignatureRawError -> Builder
build =
    \case
      ParseSignatureRawWrongSize ba :: ByteString
ba -> "Given raw signature " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<>
        ByteString -> Builder
forall a. FormatAsHex a => a -> Builder
hexF ByteString
ba Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> " has invalid length " Builder -> Builder -> Builder
forall a. Semigroup a => a -> a -> a
<> Int -> Builder
forall b a. (Show a, IsString b) => a -> b
show (ByteString -> Int
forall t. Container t => t -> Int
length ByteString
ba)

-- Apparently Tezos relies on the fact that in all schemes signature
-- size is 64 bytes, so it also has generic signature and always reads
-- 64 bytes during unpack.
-- So we can have one 'signatureLengthBytes' and do not have to
-- distinguish between curves.
-- However, we still have such a check here just in case as a precaution.
signatureLengthBytes :: HasCallStack => Integral n => n
signatureLengthBytes :: n
signatureLengthBytes
  | (Element [Int] -> Bool) -> [Int] -> Bool
forall t. Container t => (Element t -> Bool) -> t -> Bool
all Int -> Bool
Element [Int] -> Bool
is64
    [ Int
forall n. Integral n => n
Ed25519.signatureLengthBytes
    , Int
forall n. Integral n => n
P256.signatureLengthBytes
    , Int
forall n. Integral n => n
Secp256k1.signatureLengthBytes
    ] = 64
  | Bool
otherwise =
    Text -> n
forall a. HasCallStack => Text -> a
error "Apparently our understanding of signatures in Tezos is broken"
  where
    is64 :: Int -> Bool
    is64 :: Int -> Bool
is64 = (Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 64)

genericSignatureTag :: ByteString
genericSignatureTag :: ByteString
genericSignatureTag = "\004\130\043"

-- | Check that a sequence of bytes has been signed with a given key.
checkSignature :: PublicKey -> Signature -> ByteString -> Bool
checkSignature :: PublicKey -> Signature -> ByteString -> Bool
checkSignature pk0 :: PublicKey
pk0 sig0 :: Signature
sig0 bytes :: ByteString
bytes =
  case (PublicKey
pk0, Signature
sig0) of
    (PublicKeyEd25519 pk :: PublicKey
pk, SignatureEd25519 sig :: Signature
sig) ->
      PublicKey -> Signature -> ByteString -> Bool
Ed25519.checkSignature PublicKey
pk Signature
sig ByteString
bytes
    (PublicKeySecp256k1 pk :: PublicKey
pk, SignatureSecp256k1 sig :: Signature
sig) ->
      PublicKey -> Signature -> ByteString -> Bool
Secp256k1.checkSignature PublicKey
pk Signature
sig ByteString
bytes
    (PublicKeyP256 pk :: PublicKey
pk, SignatureP256 sig :: Signature
sig) ->
      PublicKey -> Signature -> ByteString -> Bool
P256.checkSignature PublicKey
pk Signature
sig ByteString
bytes
    (PublicKeyEd25519 pk :: PublicKey
pk, SignatureGeneric sBytes :: ByteString
sBytes) ->
      ByteString -> Either CryptoParseError Signature
forall ba.
ByteArrayAccess ba =>
ba -> Either CryptoParseError Signature
Ed25519.mkSignature ByteString
sBytes
        Either CryptoParseError Signature
-> (Either CryptoParseError Signature
    -> Either CryptoParseError Bool)
-> Either CryptoParseError Bool
forall a b. a -> (a -> b) -> b
& (Signature -> Bool)
-> Either CryptoParseError Signature
-> Either CryptoParseError Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\sig :: Signature
sig -> PublicKey -> Signature -> ByteString -> Bool
Ed25519.checkSignature PublicKey
pk Signature
sig ByteString
bytes)
        Either CryptoParseError Bool
-> (Either CryptoParseError Bool -> Bool) -> Bool
forall a b. a -> (a -> b) -> b
& Bool -> Either CryptoParseError Bool -> Bool
forall b a. b -> Either a b -> b
fromRight Bool
False
    (PublicKeySecp256k1 pk :: PublicKey
pk, SignatureGeneric sBytes :: ByteString
sBytes) ->
      ByteString -> Either CryptoParseError Signature
forall ba. ByteArray ba => ba -> Either CryptoParseError Signature
Secp256k1.mkSignature ByteString
sBytes
        Either CryptoParseError Signature
-> (Either CryptoParseError Signature
    -> Either CryptoParseError Bool)
-> Either CryptoParseError Bool
forall a b. a -> (a -> b) -> b
& (Signature -> Bool)
-> Either CryptoParseError Signature
-> Either CryptoParseError Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\sig :: Signature
sig -> PublicKey -> Signature -> ByteString -> Bool
Secp256k1.checkSignature PublicKey
pk Signature
sig ByteString
bytes)
        Either CryptoParseError Bool
-> (Either CryptoParseError Bool -> Bool) -> Bool
forall a b. a -> (a -> b) -> b
& Bool -> Either CryptoParseError Bool -> Bool
forall b a. b -> Either a b -> b
fromRight Bool
False
    (PublicKeyP256 pk :: PublicKey
pk, SignatureGeneric sBytes :: ByteString
sBytes) ->
      ByteString -> Either CryptoParseError Signature
forall ba. ByteArray ba => ba -> Either CryptoParseError Signature
P256.mkSignature ByteString
sBytes
        Either CryptoParseError Signature
-> (Either CryptoParseError Signature
    -> Either CryptoParseError Bool)
-> Either CryptoParseError Bool
forall a b. a -> (a -> b) -> b
& (Signature -> Bool)
-> Either CryptoParseError Signature
-> Either CryptoParseError Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\sig :: Signature
sig -> PublicKey -> Signature -> ByteString -> Bool
P256.checkSignature PublicKey
pk Signature
sig ByteString
bytes)
        Either CryptoParseError Bool
-> (Either CryptoParseError Bool -> Bool) -> Bool
forall a b. a -> (a -> b) -> b
& Bool -> Either CryptoParseError Bool -> Bool
forall b a. b -> Either a b -> b
fromRight Bool
False
    _ -> Bool
False

----------------------------------------------------------------------------
-- Formatting
----------------------------------------------------------------------------

formatPublicKey :: PublicKey -> Text
formatPublicKey :: PublicKey -> Text
formatPublicKey = \case
  PublicKeyEd25519 pk :: PublicKey
pk -> PublicKey -> Text
Ed25519.formatPublicKey PublicKey
pk
  PublicKeySecp256k1 pk :: PublicKey
pk -> PublicKey -> Text
Secp256k1.formatPublicKey PublicKey
pk
  PublicKeyP256 pk :: PublicKey
pk -> PublicKey -> Text
P256.formatPublicKey PublicKey
pk

mformatPublicKey :: PublicKey -> MText
mformatPublicKey :: PublicKey -> MText
mformatPublicKey = HasCallStack => Text -> MText
Text -> MText
mkMTextUnsafe (Text -> MText) -> (PublicKey -> Text) -> PublicKey -> MText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKey -> Text
formatPublicKey

instance Buildable PublicKey where
  build :: PublicKey -> Builder
build = Text -> Builder
forall p. Buildable p => p -> Builder
build (Text -> Builder) -> (PublicKey -> Text) -> PublicKey -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKey -> Text
formatPublicKey

parsePublicKey :: Text -> Either CryptoParseError PublicKey
parsePublicKey :: Text -> Either CryptoParseError PublicKey
parsePublicKey txt :: Text
txt =
  NonEmpty (Either CryptoParseError PublicKey)
-> Either CryptoParseError PublicKey
forall e a. NonEmpty (Either e a) -> Either e a
firstRight (NonEmpty (Either CryptoParseError PublicKey)
 -> Either CryptoParseError PublicKey)
-> NonEmpty (Either CryptoParseError PublicKey)
-> Either CryptoParseError PublicKey
forall a b. (a -> b) -> a -> b
$ ((Text -> Either CryptoParseError PublicKey)
 -> Either CryptoParseError PublicKey)
-> NonEmpty (Text -> Either CryptoParseError PublicKey)
-> NonEmpty (Either CryptoParseError PublicKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((Text -> Either CryptoParseError PublicKey)
-> Text -> Either CryptoParseError PublicKey
forall a b. (a -> b) -> a -> b
$ Text
txt)
    ( (PublicKey -> PublicKey)
-> Either CryptoParseError PublicKey
-> Either CryptoParseError PublicKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PublicKey -> PublicKey
PublicKeyEd25519 (Either CryptoParseError PublicKey
 -> Either CryptoParseError PublicKey)
-> (Text -> Either CryptoParseError PublicKey)
-> Text
-> Either CryptoParseError PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError PublicKey
Ed25519.parsePublicKey (Text -> Either CryptoParseError PublicKey)
-> [Text -> Either CryptoParseError PublicKey]
-> NonEmpty (Text -> Either CryptoParseError PublicKey)
forall a. a -> [a] -> NonEmpty a
:|
    [ (PublicKey -> PublicKey)
-> Either CryptoParseError PublicKey
-> Either CryptoParseError PublicKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PublicKey -> PublicKey
PublicKeySecp256k1 (Either CryptoParseError PublicKey
 -> Either CryptoParseError PublicKey)
-> (Text -> Either CryptoParseError PublicKey)
-> Text
-> Either CryptoParseError PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError PublicKey
Secp256k1.parsePublicKey
    , (PublicKey -> PublicKey)
-> Either CryptoParseError PublicKey
-> Either CryptoParseError PublicKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PublicKey -> PublicKey
PublicKeyP256 (Either CryptoParseError PublicKey
 -> Either CryptoParseError PublicKey)
-> (Text -> Either CryptoParseError PublicKey)
-> Text
-> Either CryptoParseError PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError PublicKey
P256.parsePublicKey
    ])

parsePublicKeyRaw :: ByteString -> Either Text PublicKey
parsePublicKeyRaw :: ByteString -> Either Text PublicKey
parsePublicKeyRaw ba :: ByteString
ba =
  case Get PublicKey
-> ByteString
-> Either
     (ByteString, ByteOffset, String)
     (ByteString, ByteOffset, PublicKey)
forall a.
Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
Get.runGetOrFail (String -> [TaggedDecoder PublicKey] -> Get PublicKey
forall a. String -> [TaggedDecoder a] -> Get a
decodeWithTag "key" [TaggedDecoder PublicKey]
keyDecoders) (ByteString -> ByteString
LBS.fromStrict ByteString
ba) of
    Right (_, _, result :: PublicKey
result) -> PublicKey -> Either Text PublicKey
forall a b. b -> Either a b
Right PublicKey
result
    Left (_, _, err :: String
err) -> Text -> Either Text PublicKey
forall a b. a -> Either a b
Left (String -> Text
forall a. ToText a => a -> Text
toText String
err)

formatSignature :: Signature -> Text
formatSignature :: Signature -> Text
formatSignature = \case
  SignatureEd25519 sig :: Signature
sig -> Signature -> Text
Ed25519.formatSignature Signature
sig
  SignatureSecp256k1 sig :: Signature
sig -> Signature -> Text
Secp256k1.formatSignature Signature
sig
  SignatureP256 sig :: Signature
sig -> Signature -> Text
P256.formatSignature Signature
sig
  SignatureGeneric sig :: ByteString
sig -> ByteString -> ByteString -> Text
forall x. ByteArrayAccess x => ByteString -> x -> Text
formatImpl ByteString
genericSignatureTag ByteString
sig

mformatSignature :: Signature -> MText
mformatSignature :: Signature -> MText
mformatSignature = HasCallStack => Text -> MText
Text -> MText
mkMTextUnsafe (Text -> MText) -> (Signature -> Text) -> Signature -> MText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signature -> Text
formatSignature

instance Buildable Signature where
  build :: Signature -> Builder
build = Text -> Builder
forall p. Buildable p => p -> Builder
build (Text -> Builder) -> (Signature -> Text) -> Signature -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signature -> Text
formatSignature

parseSignature :: Text -> Either CryptoParseError Signature
parseSignature :: Text -> Either CryptoParseError Signature
parseSignature txt :: Text
txt =
  NonEmpty (Either CryptoParseError Signature)
-> Either CryptoParseError Signature
forall e a. NonEmpty (Either e a) -> Either e a
firstRight (NonEmpty (Either CryptoParseError Signature)
 -> Either CryptoParseError Signature)
-> NonEmpty (Either CryptoParseError Signature)
-> Either CryptoParseError Signature
forall a b. (a -> b) -> a -> b
$ ((Text -> Either CryptoParseError Signature)
 -> Either CryptoParseError Signature)
-> NonEmpty (Text -> Either CryptoParseError Signature)
-> NonEmpty (Either CryptoParseError Signature)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map ((Text -> Either CryptoParseError Signature)
-> Text -> Either CryptoParseError Signature
forall a b. (a -> b) -> a -> b
$ Text
txt)
    ( (Signature -> Signature)
-> Either CryptoParseError Signature
-> Either CryptoParseError Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Signature -> Signature
SignatureEd25519 (Either CryptoParseError Signature
 -> Either CryptoParseError Signature)
-> (Text -> Either CryptoParseError Signature)
-> Text
-> Either CryptoParseError Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError Signature
Ed25519.parseSignature (Text -> Either CryptoParseError Signature)
-> [Text -> Either CryptoParseError Signature]
-> NonEmpty (Text -> Either CryptoParseError Signature)
forall a. a -> [a] -> NonEmpty a
:|
    [ (Signature -> Signature)
-> Either CryptoParseError Signature
-> Either CryptoParseError Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Signature -> Signature
SignatureSecp256k1 (Either CryptoParseError Signature
 -> Either CryptoParseError Signature)
-> (Text -> Either CryptoParseError Signature)
-> Text
-> Either CryptoParseError Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError Signature
Secp256k1.parseSignature
    , (Signature -> Signature)
-> Either CryptoParseError Signature
-> Either CryptoParseError Signature
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap Signature -> Signature
SignatureP256 (Either CryptoParseError Signature
 -> Either CryptoParseError Signature)
-> (Text -> Either CryptoParseError Signature)
-> Text
-> Either CryptoParseError Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError Signature
P256.parseSignature
    , ByteString
-> (ByteString -> Either CryptoParseError Signature)
-> Text
-> Either CryptoParseError Signature
forall res.
ByteString
-> (ByteString -> Either CryptoParseError res)
-> Text
-> Either CryptoParseError res
parseImpl ByteString
genericSignatureTag (Signature -> Either CryptoParseError Signature
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Signature -> Either CryptoParseError Signature)
-> (ByteString -> Signature)
-> ByteString
-> Either CryptoParseError Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Signature
SignatureGeneric)
    ])

formatSecretKey :: SecretKey -> Text
formatSecretKey :: SecretKey -> Text
formatSecretKey key :: SecretKey
key = "unencrypted:" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> case SecretKey
key of
  SecretKeyEd25519 sig :: SecretKey
sig -> SecretKey -> Text
Ed25519.formatSecretKey SecretKey
sig
  SecretKeySecp256k1 sig :: SecretKey
sig -> SecretKey -> Text
Secp256k1.formatSecretKey SecretKey
sig
  SecretKeyP256 sig :: SecretKey
sig -> SecretKey -> Text
P256.formatSecretKey SecretKey
sig

instance Buildable SecretKey where
  build :: SecretKey -> Builder
build = Text -> Builder
forall p. Buildable p => p -> Builder
build (Text -> Builder) -> (SecretKey -> Text) -> SecretKey -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. SecretKey -> Text
formatSecretKey

-- | Parse __unencrypted__ secret key. It accepts formats containing
-- either with or without the @unecrypted@ prefix.
parseSecretKey :: Text -> Either CryptoParseError SecretKey
parseSecretKey :: Text -> Either CryptoParseError SecretKey
parseSecretKey txt :: Text
txt =
  NonEmpty (Either CryptoParseError SecretKey)
-> Either CryptoParseError SecretKey
forall e a. NonEmpty (Either e a) -> Either e a
firstRight (NonEmpty (Either CryptoParseError SecretKey)
 -> Either CryptoParseError SecretKey)
-> NonEmpty (Either CryptoParseError SecretKey)
-> Either CryptoParseError SecretKey
forall a b. (a -> b) -> a -> b
$ ((Text -> Either CryptoParseError SecretKey)
 -> Either CryptoParseError SecretKey)
-> NonEmpty (Text -> Either CryptoParseError SecretKey)
-> NonEmpty (Either CryptoParseError SecretKey)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map (\f :: Text -> Either CryptoParseError SecretKey
f -> Text -> Either CryptoParseError SecretKey
f (Text -> Either CryptoParseError SecretKey)
-> Text -> Either CryptoParseError SecretKey
forall a b. (a -> b) -> a -> b
$ Text -> Text
removePrefix Text
txt)
    ( (SecretKey -> SecretKey)
-> Either CryptoParseError SecretKey
-> Either CryptoParseError SecretKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SecretKey -> SecretKey
SecretKeyEd25519 (Either CryptoParseError SecretKey
 -> Either CryptoParseError SecretKey)
-> (Text -> Either CryptoParseError SecretKey)
-> Text
-> Either CryptoParseError SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError SecretKey
Ed25519.parseSecretKey (Text -> Either CryptoParseError SecretKey)
-> [Text -> Either CryptoParseError SecretKey]
-> NonEmpty (Text -> Either CryptoParseError SecretKey)
forall a. a -> [a] -> NonEmpty a
:|
    [ (SecretKey -> SecretKey)
-> Either CryptoParseError SecretKey
-> Either CryptoParseError SecretKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SecretKey -> SecretKey
SecretKeySecp256k1 (Either CryptoParseError SecretKey
 -> Either CryptoParseError SecretKey)
-> (Text -> Either CryptoParseError SecretKey)
-> Text
-> Either CryptoParseError SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError SecretKey
Secp256k1.parseSecretKey
    , (SecretKey -> SecretKey)
-> Either CryptoParseError SecretKey
-> Either CryptoParseError SecretKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap SecretKey -> SecretKey
SecretKeyP256 (Either CryptoParseError SecretKey
 -> Either CryptoParseError SecretKey)
-> (Text -> Either CryptoParseError SecretKey)
-> Text
-> Either CryptoParseError SecretKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError SecretKey
P256.parseSecretKey
    ])
  where
    removePrefix :: Text -> Text
    removePrefix :: Text -> Text
removePrefix input :: Text
input =
      let unencrypted :: Text
unencrypted = "unencrypted:"
          (prefix :: Text
prefix, payload :: Text
payload) = Int -> Text -> (Text, Text)
T.splitAt (Text -> Int
forall t. Container t => t -> Int
length Text
unencrypted) Text
input
      in case Text
prefix Text -> Text -> Bool
forall a. Eq a => a -> a -> Bool
== Text
unencrypted of
        True -> Text
payload
        False -> Text
input

----------------------------------------------------------------------------
-- JSON encoding/decoding
----------------------------------------------------------------------------

-- If you ever need these instances for any particular 'PublicKey' or
-- 'Signature', you can define them in respective modules the same
-- way.

instance ToJSON PublicKey where
  toJSON :: PublicKey -> Value
toJSON = Text -> Value
Aeson.String (Text -> Value) -> (PublicKey -> Text) -> PublicKey -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKey -> Text
formatPublicKey
  toEncoding :: PublicKey -> Encoding
toEncoding = Text -> Encoding
forall a. Text -> Encoding' a
Aeson.text (Text -> Encoding) -> (PublicKey -> Text) -> PublicKey -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PublicKey -> Text
formatPublicKey

instance FromJSON PublicKey where
  parseJSON :: Value -> Parser PublicKey
parseJSON =
    String -> (Text -> Parser PublicKey) -> Value -> Parser PublicKey
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText "PublicKey" ((Text -> Parser PublicKey) -> Value -> Parser PublicKey)
-> (Text -> Parser PublicKey) -> Value -> Parser PublicKey
forall a b. (a -> b) -> a -> b
$
    (CryptoParseError -> Parser PublicKey)
-> (PublicKey -> Parser PublicKey)
-> Either CryptoParseError PublicKey
-> Parser PublicKey
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Parser PublicKey
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser PublicKey)
-> (CryptoParseError -> String)
-> CryptoParseError
-> Parser PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoParseError -> String
forall a b. (Buildable a, FromBuilder b) => a -> b
pretty) PublicKey -> Parser PublicKey
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either CryptoParseError PublicKey -> Parser PublicKey)
-> (Text -> Either CryptoParseError PublicKey)
-> Text
-> Parser PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError PublicKey
parsePublicKey

instance ToJSON Signature where
  toJSON :: Signature -> Value
toJSON = Text -> Value
Aeson.String (Text -> Value) -> (Signature -> Text) -> Signature -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signature -> Text
formatSignature
  toEncoding :: Signature -> Encoding
toEncoding = Text -> Encoding
forall a. Text -> Encoding' a
Aeson.text (Text -> Encoding) -> (Signature -> Text) -> Signature -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Signature -> Text
formatSignature

instance FromJSON Signature where
  parseJSON :: Value -> Parser Signature
parseJSON =
    String -> (Text -> Parser Signature) -> Value -> Parser Signature
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText "Signature" ((Text -> Parser Signature) -> Value -> Parser Signature)
-> (Text -> Parser Signature) -> Value -> Parser Signature
forall a b. (a -> b) -> a -> b
$
    (CryptoParseError -> Parser Signature)
-> (Signature -> Parser Signature)
-> Either CryptoParseError Signature
-> Parser Signature
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Parser Signature
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser Signature)
-> (CryptoParseError -> String)
-> CryptoParseError
-> Parser Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoParseError -> String
forall a b. (Buildable a, FromBuilder b) => a -> b
pretty) Signature -> Parser Signature
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either CryptoParseError Signature -> Parser Signature)
-> (Text -> Either CryptoParseError Signature)
-> Text
-> Parser Signature
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError Signature
parseSignature

instance ToJSON KeyHash where
  toJSON :: KeyHash -> Value
toJSON = Text -> Value
Aeson.String (Text -> Value) -> (KeyHash -> Text) -> KeyHash -> Value
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyHash -> Text
formatKeyHash
  toEncoding :: KeyHash -> Encoding
toEncoding = Text -> Encoding
forall a. Text -> Encoding' a
Aeson.text (Text -> Encoding) -> (KeyHash -> Text) -> KeyHash -> Encoding
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyHash -> Text
formatKeyHash

instance FromJSON KeyHash where
  parseJSON :: Value -> Parser KeyHash
parseJSON =
    String -> (Text -> Parser KeyHash) -> Value -> Parser KeyHash
forall a. String -> (Text -> Parser a) -> Value -> Parser a
Aeson.withText "KeyHash" ((Text -> Parser KeyHash) -> Value -> Parser KeyHash)
-> (Text -> Parser KeyHash) -> Value -> Parser KeyHash
forall a b. (a -> b) -> a -> b
$
    (CryptoParseError -> Parser KeyHash)
-> (KeyHash -> Parser KeyHash)
-> Either CryptoParseError KeyHash
-> Parser KeyHash
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (String -> Parser KeyHash
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> Parser KeyHash)
-> (CryptoParseError -> String)
-> CryptoParseError
-> Parser KeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CryptoParseError -> String
forall a b. (Buildable a, FromBuilder b) => a -> b
pretty) KeyHash -> Parser KeyHash
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either CryptoParseError KeyHash -> Parser KeyHash)
-> (Text -> Either CryptoParseError KeyHash)
-> Text
-> Parser KeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError KeyHash
parseKeyHash

----------------------------------------------------------------------------
-- KeyHash
----------------------------------------------------------------------------

-- | Which curve was used for the hashed public key inside 'KeyHash'.
data KeyHashTag
  = KeyHashEd25519
  | KeyHashSecp256k1
  | KeyHashP256
  deriving stock (Int -> KeyHashTag -> ShowS
[KeyHashTag] -> ShowS
KeyHashTag -> String
(Int -> KeyHashTag -> ShowS)
-> (KeyHashTag -> String)
-> ([KeyHashTag] -> ShowS)
-> Show KeyHashTag
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KeyHashTag] -> ShowS
$cshowList :: [KeyHashTag] -> ShowS
show :: KeyHashTag -> String
$cshow :: KeyHashTag -> String
showsPrec :: Int -> KeyHashTag -> ShowS
$cshowsPrec :: Int -> KeyHashTag -> ShowS
Show, KeyHashTag -> KeyHashTag -> Bool
(KeyHashTag -> KeyHashTag -> Bool)
-> (KeyHashTag -> KeyHashTag -> Bool) -> Eq KeyHashTag
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KeyHashTag -> KeyHashTag -> Bool
$c/= :: KeyHashTag -> KeyHashTag -> Bool
== :: KeyHashTag -> KeyHashTag -> Bool
$c== :: KeyHashTag -> KeyHashTag -> Bool
Eq, Eq KeyHashTag
Eq KeyHashTag =>
(KeyHashTag -> KeyHashTag -> Ordering)
-> (KeyHashTag -> KeyHashTag -> Bool)
-> (KeyHashTag -> KeyHashTag -> Bool)
-> (KeyHashTag -> KeyHashTag -> Bool)
-> (KeyHashTag -> KeyHashTag -> Bool)
-> (KeyHashTag -> KeyHashTag -> KeyHashTag)
-> (KeyHashTag -> KeyHashTag -> KeyHashTag)
-> Ord KeyHashTag
KeyHashTag -> KeyHashTag -> Bool
KeyHashTag -> KeyHashTag -> Ordering
KeyHashTag -> KeyHashTag -> KeyHashTag
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
min :: KeyHashTag -> KeyHashTag -> KeyHashTag
$cmin :: KeyHashTag -> KeyHashTag -> KeyHashTag
max :: KeyHashTag -> KeyHashTag -> KeyHashTag
$cmax :: KeyHashTag -> KeyHashTag -> KeyHashTag
>= :: KeyHashTag -> KeyHashTag -> Bool
$c>= :: KeyHashTag -> KeyHashTag -> Bool
> :: KeyHashTag -> KeyHashTag -> Bool
$c> :: KeyHashTag -> KeyHashTag -> Bool
<= :: KeyHashTag -> KeyHashTag -> Bool
$c<= :: KeyHashTag -> KeyHashTag -> Bool
< :: KeyHashTag -> KeyHashTag -> Bool
$c< :: KeyHashTag -> KeyHashTag -> Bool
compare :: KeyHashTag -> KeyHashTag -> Ordering
$ccompare :: KeyHashTag -> KeyHashTag -> Ordering
$cp1Ord :: Eq KeyHashTag
Ord, KeyHashTag
KeyHashTag -> KeyHashTag -> Bounded KeyHashTag
forall a. a -> a -> Bounded a
maxBound :: KeyHashTag
$cmaxBound :: KeyHashTag
minBound :: KeyHashTag
$cminBound :: KeyHashTag
Bounded, Int -> KeyHashTag
KeyHashTag -> Int
KeyHashTag -> [KeyHashTag]
KeyHashTag -> KeyHashTag
KeyHashTag -> KeyHashTag -> [KeyHashTag]
KeyHashTag -> KeyHashTag -> KeyHashTag -> [KeyHashTag]
(KeyHashTag -> KeyHashTag)
-> (KeyHashTag -> KeyHashTag)
-> (Int -> KeyHashTag)
-> (KeyHashTag -> Int)
-> (KeyHashTag -> [KeyHashTag])
-> (KeyHashTag -> KeyHashTag -> [KeyHashTag])
-> (KeyHashTag -> KeyHashTag -> [KeyHashTag])
-> (KeyHashTag -> KeyHashTag -> KeyHashTag -> [KeyHashTag])
-> Enum KeyHashTag
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
enumFromThenTo :: KeyHashTag -> KeyHashTag -> KeyHashTag -> [KeyHashTag]
$cenumFromThenTo :: KeyHashTag -> KeyHashTag -> KeyHashTag -> [KeyHashTag]
enumFromTo :: KeyHashTag -> KeyHashTag -> [KeyHashTag]
$cenumFromTo :: KeyHashTag -> KeyHashTag -> [KeyHashTag]
enumFromThen :: KeyHashTag -> KeyHashTag -> [KeyHashTag]
$cenumFromThen :: KeyHashTag -> KeyHashTag -> [KeyHashTag]
enumFrom :: KeyHashTag -> [KeyHashTag]
$cenumFrom :: KeyHashTag -> [KeyHashTag]
fromEnum :: KeyHashTag -> Int
$cfromEnum :: KeyHashTag -> Int
toEnum :: Int -> KeyHashTag
$ctoEnum :: Int -> KeyHashTag
pred :: KeyHashTag -> KeyHashTag
$cpred :: KeyHashTag -> KeyHashTag
succ :: KeyHashTag -> KeyHashTag
$csucc :: KeyHashTag -> KeyHashTag
Enum, (forall x. KeyHashTag -> Rep KeyHashTag x)
-> (forall x. Rep KeyHashTag x -> KeyHashTag) -> Generic KeyHashTag
forall x. Rep KeyHashTag x -> KeyHashTag
forall x. KeyHashTag -> Rep KeyHashTag x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep KeyHashTag x -> KeyHashTag
$cfrom :: forall x. KeyHashTag -> Rep KeyHashTag x
Generic)

instance Arbitrary KeyHashTag where
  arbitrary :: Gen KeyHashTag
arbitrary = [KeyHashTag] -> Gen KeyHashTag
forall a. [a] -> Gen a
elements [KeyHashTag
forall a. Bounded a => a
minBound .. ]

instance NFData KeyHashTag

-- | Blake2b_160 hash of a public key.
data KeyHash = KeyHash
  { KeyHash -> KeyHashTag
khTag :: KeyHashTag
  -- ^ We store which curve was used because it affects formatting.
  , KeyHash -> ByteString
khBytes :: ByteString
  -- ^ Hash itself.
  } deriving stock (Int -> KeyHash -> ShowS
[KeyHash] -> ShowS
KeyHash -> String
(Int -> KeyHash -> ShowS)
-> (KeyHash -> String) -> ([KeyHash] -> ShowS) -> Show KeyHash
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [KeyHash] -> ShowS
$cshowList :: [KeyHash] -> ShowS
show :: KeyHash -> String
$cshow :: KeyHash -> String
showsPrec :: Int -> KeyHash -> ShowS
$cshowsPrec :: Int -> KeyHash -> ShowS
Show, KeyHash -> KeyHash -> Bool
(KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> Bool) -> Eq KeyHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: KeyHash -> KeyHash -> Bool
$c/= :: KeyHash -> KeyHash -> Bool
== :: KeyHash -> KeyHash -> Bool
$c== :: KeyHash -> KeyHash -> Bool
Eq, Eq KeyHash
Eq KeyHash =>
(KeyHash -> KeyHash -> Ordering)
-> (KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> Bool)
-> (KeyHash -> KeyHash -> KeyHash)
-> (KeyHash -> KeyHash -> KeyHash)
-> Ord KeyHash
KeyHash -> KeyHash -> Bool
KeyHash -> KeyHash -> Ordering
KeyHash -> KeyHash -> KeyHash
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
min :: KeyHash -> KeyHash -> KeyHash
$cmin :: KeyHash -> KeyHash -> KeyHash
max :: KeyHash -> KeyHash -> KeyHash
$cmax :: KeyHash -> KeyHash -> KeyHash
>= :: KeyHash -> KeyHash -> Bool
$c>= :: KeyHash -> KeyHash -> Bool
> :: KeyHash -> KeyHash -> Bool
$c> :: KeyHash -> KeyHash -> Bool
<= :: KeyHash -> KeyHash -> Bool
$c<= :: KeyHash -> KeyHash -> Bool
< :: KeyHash -> KeyHash -> Bool
$c< :: KeyHash -> KeyHash -> Bool
compare :: KeyHash -> KeyHash -> Ordering
$ccompare :: KeyHash -> KeyHash -> Ordering
$cp1Ord :: Eq KeyHash
Ord, (forall x. KeyHash -> Rep KeyHash x)
-> (forall x. Rep KeyHash x -> KeyHash) -> Generic KeyHash
forall x. Rep KeyHash x -> KeyHash
forall x. KeyHash -> Rep KeyHash x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep KeyHash x -> KeyHash
$cfrom :: forall x. KeyHash -> Rep KeyHash x
Generic)

instance NFData KeyHash

-- | Length of key hash in bytes (only hash itself, no tags, checksums
-- or anything).
keyHashLengthBytes :: Integral n => n
keyHashLengthBytes :: n
keyHashLengthBytes = 20

instance Arbitrary KeyHash where
  arbitrary :: Gen KeyHash
arbitrary = PublicKey -> KeyHash
hashKey (PublicKey -> KeyHash) -> Gen PublicKey -> Gen KeyHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Gen PublicKey
forall a. Arbitrary a => Gen a
arbitrary

-- | Compute the b58check of a public key hash.
hashKey :: PublicKey -> KeyHash
hashKey :: PublicKey -> KeyHash
hashKey =
  \case
    PublicKeyEd25519 pk :: PublicKey
pk ->
      KeyHashTag -> ByteString -> KeyHash
KeyHash KeyHashTag
KeyHashEd25519 (ByteString -> ByteString
blake2b160 (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
Ed25519.publicKeyToBytes PublicKey
pk)
    PublicKeySecp256k1 pk :: PublicKey
pk ->
      KeyHashTag -> ByteString -> KeyHash
KeyHash KeyHashTag
KeyHashSecp256k1 (ByteString -> ByteString
blake2b160 (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
Secp256k1.publicKeyToBytes PublicKey
pk)
    PublicKeyP256 pk :: PublicKey
pk ->
      KeyHashTag -> ByteString -> KeyHash
KeyHash KeyHashTag
KeyHashP256 (ByteString -> ByteString
blake2b160 (ByteString -> ByteString) -> ByteString -> ByteString
forall a b. (a -> b) -> a -> b
$ PublicKey -> ByteString
forall ba. ByteArray ba => PublicKey -> ba
P256.publicKeyToBytes PublicKey
pk)

formatKeyHash :: KeyHash -> Text
formatKeyHash :: KeyHash -> Text
formatKeyHash (KeyHash tag :: KeyHashTag
tag bytes :: ByteString
bytes) = ByteString -> ByteString -> Text
forall x. ByteArrayAccess x => ByteString -> x -> Text
formatImpl (KeyHashTag -> ByteString
keyHashTagBytes KeyHashTag
tag) ByteString
bytes

mformatKeyHash :: KeyHash -> MText
mformatKeyHash :: KeyHash -> MText
mformatKeyHash = HasCallStack => Text -> MText
Text -> MText
mkMTextUnsafe (Text -> MText) -> (KeyHash -> Text) -> KeyHash -> MText
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyHash -> Text
formatKeyHash

instance Buildable KeyHash where
  build :: KeyHash -> Builder
build = Text -> Builder
forall p. Buildable p => p -> Builder
build (Text -> Builder) -> (KeyHash -> Text) -> KeyHash -> Builder
forall b c a. (b -> c) -> (a -> b) -> a -> c
. KeyHash -> Text
formatKeyHash

parseKeyHash :: Text -> Either CryptoParseError KeyHash
parseKeyHash :: Text -> Either CryptoParseError KeyHash
parseKeyHash txt :: Text
txt =
  let
    mkKeyHash :: KeyHashTag -> ByteString -> Either CryptoParseError KeyHash
mkKeyHash tag :: KeyHashTag
tag bs :: ByteString
bs =
      KeyHashTag -> ByteString -> KeyHash
KeyHash KeyHashTag
tag ByteString
bs KeyHash
-> Either CryptoParseError () -> Either CryptoParseError KeyHash
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$
        Bool -> Either CryptoParseError () -> Either CryptoParseError ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (ByteString -> Int
forall t. Container t => t -> Int
length ByteString
bs Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
forall n. Integral n => n
keyHashLengthBytes)
        (CryptoParseError -> Either CryptoParseError ()
forall a b. a -> Either a b
Left (CryptoParseError -> Either CryptoParseError ())
-> CryptoParseError -> Either CryptoParseError ()
forall a b. (a -> b) -> a -> b
$ Builder -> Int -> CryptoParseError
CryptoParseUnexpectedLength "KeyHash" (ByteString -> Int
forall t. Container t => t -> Int
length ByteString
bs))

    parse :: KeyHashTag -> Either CryptoParseError KeyHash
    parse :: KeyHashTag -> Either CryptoParseError KeyHash
parse tag :: KeyHashTag
tag = KeyHashTag -> ByteString -> Either CryptoParseError KeyHash
mkKeyHash KeyHashTag
tag (ByteString -> Either CryptoParseError KeyHash)
-> Either CryptoParseError ByteString
-> Either CryptoParseError KeyHash
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< ByteString
-> (ByteString -> Either CryptoParseError ByteString)
-> Text
-> Either CryptoParseError ByteString
forall res.
ByteString
-> (ByteString -> Either CryptoParseError res)
-> Text
-> Either CryptoParseError res
parseImpl (KeyHashTag -> ByteString
keyHashTagBytes KeyHashTag
tag) ByteString -> Either CryptoParseError ByteString
forall (f :: * -> *) a. Applicative f => a -> f a
pure Text
txt

  in NonEmpty (Either CryptoParseError KeyHash)
-> Either CryptoParseError KeyHash
forall e a. NonEmpty (Either e a) -> Either e a
firstRight (NonEmpty (Either CryptoParseError KeyHash)
 -> Either CryptoParseError KeyHash)
-> NonEmpty (Either CryptoParseError KeyHash)
-> Either CryptoParseError KeyHash
forall a b. (a -> b) -> a -> b
$ (KeyHashTag -> Either CryptoParseError KeyHash)
-> NonEmpty KeyHashTag
-> NonEmpty (Either CryptoParseError KeyHash)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
map KeyHashTag -> Either CryptoParseError KeyHash
parse (NonEmpty KeyHashTag -> NonEmpty (Either CryptoParseError KeyHash))
-> NonEmpty KeyHashTag
-> NonEmpty (Either CryptoParseError KeyHash)
forall a b. (a -> b) -> a -> b
$ KeyHashTag
forall a. Bounded a => a
minBound KeyHashTag -> [KeyHashTag] -> NonEmpty KeyHashTag
forall a. a -> [a] -> NonEmpty a
:| [KeyHashTag -> KeyHashTag
forall a. Enum a => a -> a
succ KeyHashTag
forall a. Bounded a => a
minBound ..]

parseKeyHashRaw :: ByteString -> Either CryptoParseError KeyHash
parseKeyHashRaw :: ByteString -> Either CryptoParseError KeyHash
parseKeyHashRaw ba :: ByteString
ba =
  if (ByteString -> Int
BS.length ByteString
ba Int -> Int -> Int
forall a. Num a => a -> a -> a
- 1 Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
forall n. Integral n => n
keyHashLengthBytes) then
    case Get KeyHash
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, KeyHash)
forall a.
Get a
-> ByteString
-> Either
     (ByteString, ByteOffset, String) (ByteString, ByteOffset, a)
Get.runGetOrFail (String -> [TaggedDecoder KeyHash] -> Get KeyHash
forall a. String -> [TaggedDecoder a] -> Get a
decodeWithTag "key_hash" [TaggedDecoder KeyHash]
keyHashDecoders) (ByteString -> ByteString
LBS.fromStrict ByteString
ba) of
      Right (_, _, result :: KeyHash
result) -> KeyHash -> Either CryptoParseError KeyHash
forall a b. b -> Either a b
Right KeyHash
result
      Left (_, _, err :: String
err) -> CryptoParseError -> Either CryptoParseError KeyHash
forall a b. a -> Either a b
Left (CryptoParseError -> Either CryptoParseError KeyHash)
-> CryptoParseError -> Either CryptoParseError KeyHash
forall a b. (a -> b) -> a -> b
$ Text -> CryptoParseError
CryptoParseBinaryError (String -> Text
forall a. ToText a => a -> Text
toText String
err)
  else
    CryptoParseError -> Either CryptoParseError KeyHash
forall a b. a -> Either a b
Left (CryptoParseError -> Either CryptoParseError KeyHash)
-> CryptoParseError -> Either CryptoParseError KeyHash
forall a b. (a -> b) -> a -> b
$ Builder -> Int -> CryptoParseError
CryptoParseUnexpectedLength "key_hash" (ByteString -> Int
BS.length ByteString
ba)

keyHashTagBytes :: KeyHashTag -> ByteString
keyHashTagBytes :: KeyHashTag -> ByteString
keyHashTagBytes =
  \case
    KeyHashEd25519 -> "\006\161\159"
    KeyHashSecp256k1 -> "\006\161\161"
    KeyHashP256 -> "\006\161\164"

instance HasCLReader KeyHash where
  getReader :: ReadM KeyHash
getReader = (String -> Either String KeyHash) -> ReadM KeyHash
forall a. (String -> Either String a) -> ReadM a
eitherReader ((CryptoParseError -> String)
-> Either CryptoParseError KeyHash -> Either String KeyHash
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first CryptoParseError -> String
forall a b. (Buildable a, FromBuilder b) => a -> b
pretty (Either CryptoParseError KeyHash -> Either String KeyHash)
-> (String -> Either CryptoParseError KeyHash)
-> String
-> Either String KeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either CryptoParseError KeyHash
parseKeyHash (Text -> Either CryptoParseError KeyHash)
-> (String -> Text) -> String -> Either CryptoParseError KeyHash
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
forall a. ToText a => a -> Text
toText)
  getMetavar :: String
getMetavar = "KEY_HASH"

keyDecoders :: [TaggedDecoder PublicKey]
keyDecoders :: [TaggedDecoder PublicKey]
keyDecoders =
  [ 0x00 Word8 -> Get PublicKey -> TaggedDecoder PublicKey
forall a. Word8 -> Get a -> TaggedDecoder a
#: String
-> (ByteString -> Either CryptoParseError PublicKey)
-> Get PublicKey
forall err a.
Buildable err =>
String -> (ByteString -> Either err a) -> Get a
decodeBytesLike "key Ed25519"
      ((PublicKey -> PublicKey)
-> Either CryptoParseError PublicKey
-> Either CryptoParseError PublicKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PublicKey -> PublicKey
PublicKeyEd25519 (Either CryptoParseError PublicKey
 -> Either CryptoParseError PublicKey)
-> (ByteString -> Either CryptoParseError PublicKey)
-> ByteString
-> Either CryptoParseError PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either CryptoParseError PublicKey
forall ba.
ByteArrayAccess ba =>
ba -> Either CryptoParseError PublicKey
Ed25519.mkPublicKey)
  , 0x01 Word8 -> Get PublicKey -> TaggedDecoder PublicKey
forall a. Word8 -> Get a -> TaggedDecoder a
#: String
-> (ByteString -> Either CryptoParseError PublicKey)
-> Get PublicKey
forall err a.
Buildable err =>
String -> (ByteString -> Either err a) -> Get a
decodeBytesLike "key Secp256k1"
      ((PublicKey -> PublicKey)
-> Either CryptoParseError PublicKey
-> Either CryptoParseError PublicKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PublicKey -> PublicKey
PublicKeySecp256k1 (Either CryptoParseError PublicKey
 -> Either CryptoParseError PublicKey)
-> (ByteString -> Either CryptoParseError PublicKey)
-> ByteString
-> Either CryptoParseError PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either CryptoParseError PublicKey
forall ba.
ByteArrayAccess ba =>
ba -> Either CryptoParseError PublicKey
Secp256k1.mkPublicKey)
  , 0x02 Word8 -> Get PublicKey -> TaggedDecoder PublicKey
forall a. Word8 -> Get a -> TaggedDecoder a
#: String
-> (ByteString -> Either CryptoParseError PublicKey)
-> Get PublicKey
forall err a.
Buildable err =>
String -> (ByteString -> Either err a) -> Get a
decodeBytesLike "key P256"
      ((PublicKey -> PublicKey)
-> Either CryptoParseError PublicKey
-> Either CryptoParseError PublicKey
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap PublicKey -> PublicKey
PublicKeyP256 (Either CryptoParseError PublicKey
 -> Either CryptoParseError PublicKey)
-> (ByteString -> Either CryptoParseError PublicKey)
-> ByteString
-> Either CryptoParseError PublicKey
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Either CryptoParseError PublicKey
forall ba.
ByteArrayAccess ba =>
ba -> Either CryptoParseError PublicKey
P256.mkPublicKey)
  ]

keyHashDecoders :: [TaggedDecoder KeyHash]
keyHashDecoders :: [TaggedDecoder KeyHash]
keyHashDecoders =
  [ 0x00 Word8 -> Get KeyHash -> TaggedDecoder KeyHash
forall a. Word8 -> Get a -> TaggedDecoder a
#: KeyHashTag -> ByteString -> KeyHash
KeyHash KeyHashTag
KeyHashEd25519 (ByteString -> KeyHash) -> Get ByteString -> Get KeyHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get ByteString
getPayload
  , 0x01 Word8 -> Get KeyHash -> TaggedDecoder KeyHash
forall a. Word8 -> Get a -> TaggedDecoder a
#: KeyHashTag -> ByteString -> KeyHash
KeyHash KeyHashTag
KeyHashSecp256k1 (ByteString -> KeyHash) -> Get ByteString -> Get KeyHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get ByteString
getPayload
  , 0x02 Word8 -> Get KeyHash -> TaggedDecoder KeyHash
forall a. Word8 -> Get a -> TaggedDecoder a
#: KeyHashTag -> ByteString -> KeyHash
KeyHash KeyHashTag
KeyHashP256 (ByteString -> KeyHash) -> Get ByteString -> Get KeyHash
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Get ByteString
getPayload
  ]
  where
    getPayload :: Get ByteString
getPayload = Int -> Get ByteString
getByteStringCopy Int
forall n. Integral n => n
keyHashLengthBytes