{-# LANGUAGE DataKinds #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE DerivingVia #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE RoleAnnotations #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeFamilies #-}

-- |
-- Copyright: © 2018-2021 IOHK
-- License: Apache-2.0
--

module Cardano.Wallet.Primitive.Passphrase.Types
    ( -- * Passphrases from the user
      Passphrase (..)
    , PassphraseMinLength (..)
    , PassphraseMaxLength (..)
    , validatePassphrase

      -- * Wallet passphrases stored as hashes
    , PassphraseHash (..)
    , PassphraseScheme (..)
    , WalletPassphraseInfo (..)

      -- * Error types
    , ErrWrongPassphrase(..)
    ) where

import Prelude

import Control.DeepSeq
    ( NFData )
import Crypto.Random.Types
    ( MonadRandom (..) )
import Data.Bifunctor
    ( first )
import Data.ByteArray
    ( ByteArray, ByteArrayAccess, ScrubbedBytes )
import Data.ByteArray.Encoding
    ( Base (..), convertToBase )
import Data.Proxy
    ( Proxy (..) )
import Data.Text
    ( Text )
import Data.Text.Class
    ( FromText (..), TextDecodingError (..), ToText (..) )
import Data.Time.Clock
    ( UTCTime )
import GHC.Generics
    ( Generic )
import GHC.TypeLits
    ( Symbol )

import qualified Data.ByteArray as BA
import qualified Data.Text as T
import qualified Data.Text.Encoding as T

{-------------------------------------------------------------------------------
                           Passphrases from the user
-------------------------------------------------------------------------------}

-- | An encapsulated passphrase. The inner format is free, but the wrapper helps
-- readability in function signatures.
--
-- Some type parameters in use are:
--
--  * @"user"@ - a passphrase entered by the user through the API. The 'FromText'
--    instance enforces password length rules.
--
--  * @"lenient"@ - like @"user"@, except without a minimum length restriction
--    in 'FromText'.`
--
--  * @"encryption"@ - the user's passphrase, transformed so that it can be used
--    as the key for encrypting wallet keys.
--
--  * @"salt"@ - the random salt part of a hashed passphrase.
--
newtype Passphrase (purpose :: Symbol) = Passphrase
    { Passphrase purpose -> ScrubbedBytes
unPassphrase :: ScrubbedBytes }
    deriving stock (Passphrase purpose -> Passphrase purpose -> Bool
(Passphrase purpose -> Passphrase purpose -> Bool)
-> (Passphrase purpose -> Passphrase purpose -> Bool)
-> Eq (Passphrase purpose)
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
forall (purpose :: Symbol).
Passphrase purpose -> Passphrase purpose -> Bool
/= :: Passphrase purpose -> Passphrase purpose -> Bool
$c/= :: forall (purpose :: Symbol).
Passphrase purpose -> Passphrase purpose -> Bool
== :: Passphrase purpose -> Passphrase purpose -> Bool
$c== :: forall (purpose :: Symbol).
Passphrase purpose -> Passphrase purpose -> Bool
Eq, Int -> Passphrase purpose -> ShowS
[Passphrase purpose] -> ShowS
Passphrase purpose -> String
(Int -> Passphrase purpose -> ShowS)
-> (Passphrase purpose -> String)
-> ([Passphrase purpose] -> ShowS)
-> Show (Passphrase purpose)
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
forall (purpose :: Symbol). Int -> Passphrase purpose -> ShowS
forall (purpose :: Symbol). [Passphrase purpose] -> ShowS
forall (purpose :: Symbol). Passphrase purpose -> String
showList :: [Passphrase purpose] -> ShowS
$cshowList :: forall (purpose :: Symbol). [Passphrase purpose] -> ShowS
show :: Passphrase purpose -> String
$cshow :: forall (purpose :: Symbol). Passphrase purpose -> String
showsPrec :: Int -> Passphrase purpose -> ShowS
$cshowsPrec :: forall (purpose :: Symbol). Int -> Passphrase purpose -> ShowS
Show)
    deriving newtype (b -> Passphrase purpose -> Passphrase purpose
NonEmpty (Passphrase purpose) -> Passphrase purpose
Passphrase purpose -> Passphrase purpose -> Passphrase purpose
(Passphrase purpose -> Passphrase purpose -> Passphrase purpose)
-> (NonEmpty (Passphrase purpose) -> Passphrase purpose)
-> (forall b.
    Integral b =>
    b -> Passphrase purpose -> Passphrase purpose)
-> Semigroup (Passphrase purpose)
forall b.
Integral b =>
b -> Passphrase purpose -> Passphrase purpose
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
forall (purpose :: Symbol).
NonEmpty (Passphrase purpose) -> Passphrase purpose
forall (purpose :: Symbol).
Passphrase purpose -> Passphrase purpose -> Passphrase purpose
forall (purpose :: Symbol) b.
Integral b =>
b -> Passphrase purpose -> Passphrase purpose
stimes :: b -> Passphrase purpose -> Passphrase purpose
$cstimes :: forall (purpose :: Symbol) b.
Integral b =>
b -> Passphrase purpose -> Passphrase purpose
sconcat :: NonEmpty (Passphrase purpose) -> Passphrase purpose
$csconcat :: forall (purpose :: Symbol).
NonEmpty (Passphrase purpose) -> Passphrase purpose
<> :: Passphrase purpose -> Passphrase purpose -> Passphrase purpose
$c<> :: forall (purpose :: Symbol).
Passphrase purpose -> Passphrase purpose -> Passphrase purpose
Semigroup, Semigroup (Passphrase purpose)
Passphrase purpose
Semigroup (Passphrase purpose)
-> Passphrase purpose
-> (Passphrase purpose -> Passphrase purpose -> Passphrase purpose)
-> ([Passphrase purpose] -> Passphrase purpose)
-> Monoid (Passphrase purpose)
[Passphrase purpose] -> Passphrase purpose
Passphrase purpose -> Passphrase purpose -> Passphrase purpose
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
forall (purpose :: Symbol). Semigroup (Passphrase purpose)
forall (purpose :: Symbol). Passphrase purpose
forall (purpose :: Symbol).
[Passphrase purpose] -> Passphrase purpose
forall (purpose :: Symbol).
Passphrase purpose -> Passphrase purpose -> Passphrase purpose
mconcat :: [Passphrase purpose] -> Passphrase purpose
$cmconcat :: forall (purpose :: Symbol).
[Passphrase purpose] -> Passphrase purpose
mappend :: Passphrase purpose -> Passphrase purpose -> Passphrase purpose
$cmappend :: forall (purpose :: Symbol).
Passphrase purpose -> Passphrase purpose -> Passphrase purpose
mempty :: Passphrase purpose
$cmempty :: forall (purpose :: Symbol). Passphrase purpose
$cp1Monoid :: forall (purpose :: Symbol). Semigroup (Passphrase purpose)
Monoid, Passphrase purpose -> ()
(Passphrase purpose -> ()) -> NFData (Passphrase purpose)
forall a. (a -> ()) -> NFData a
forall (purpose :: Symbol). Passphrase purpose -> ()
rnf :: Passphrase purpose -> ()
$crnf :: forall (purpose :: Symbol). Passphrase purpose -> ()
NFData, Passphrase purpose -> Int
Passphrase purpose -> Ptr p -> IO ()
Passphrase purpose -> (Ptr p -> IO a) -> IO a
(Passphrase purpose -> Int)
-> (forall p a. Passphrase purpose -> (Ptr p -> IO a) -> IO a)
-> (forall p. Passphrase purpose -> Ptr p -> IO ())
-> ByteArrayAccess (Passphrase purpose)
forall p. Passphrase purpose -> Ptr p -> IO ()
forall ba.
(ba -> Int)
-> (forall p a. ba -> (Ptr p -> IO a) -> IO a)
-> (forall p. ba -> Ptr p -> IO ())
-> ByteArrayAccess ba
forall p a. Passphrase purpose -> (Ptr p -> IO a) -> IO a
forall (purpose :: Symbol). Passphrase purpose -> Int
forall (purpose :: Symbol) p. Passphrase purpose -> Ptr p -> IO ()
forall (purpose :: Symbol) p a.
Passphrase purpose -> (Ptr p -> IO a) -> IO a
copyByteArrayToPtr :: Passphrase purpose -> Ptr p -> IO ()
$ccopyByteArrayToPtr :: forall (purpose :: Symbol) p. Passphrase purpose -> Ptr p -> IO ()
withByteArray :: Passphrase purpose -> (Ptr p -> IO a) -> IO a
$cwithByteArray :: forall (purpose :: Symbol) p a.
Passphrase purpose -> (Ptr p -> IO a) -> IO a
length :: Passphrase purpose -> Int
$clength :: forall (purpose :: Symbol). Passphrase purpose -> Int
ByteArrayAccess)

type role Passphrase phantom

-- | Little trick to be able to provide our own "random" salt in order to
-- deterministically re-compute a passphrase hash from a known salt. Note that,
-- this boils down to giving an extra argument to the `encryptPassphrase`
-- function which is the salt, in order to make it behave deterministically.
--
-- @
-- encryptPassphrase
--   :: MonadRandom m
--   => Passphrase purpose
--   -> m (Hash purpose)
--
--  ~
--
-- encryptPassphrase
--   :: Passphrase purpose
--   -> Passphrase "salt"
--   -> m (Hash purpose)
-- @
--
-- >>> encryptPassphrase pwd (Passphrase @"salt" salt)
-- Hash "..."
--
instance MonadRandom ((->) (Passphrase "salt")) where
    getRandomBytes :: Int -> Passphrase "salt" -> byteArray
getRandomBytes Int
_ (Passphrase ScrubbedBytes
salt) = ScrubbedBytes -> byteArray
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert ScrubbedBytes
salt

class PassphraseMinLength (purpose :: Symbol) where
    -- | Minimal Length for a passphrase, for lack of better validations
    passphraseMinLength :: Proxy purpose -> Int

class PassphraseMaxLength (purpose :: Symbol) where
    -- | Maximum length for a passphrase
    passphraseMaxLength :: Proxy purpose -> Int

instance PassphraseMinLength "user" where passphraseMinLength :: Proxy "user" -> Int
passphraseMinLength Proxy "user"
_ = Int
10
instance PassphraseMaxLength "user" where passphraseMaxLength :: Proxy "user" -> Int
passphraseMaxLength Proxy "user"
_ = Int
255

instance PassphraseMinLength "lenient" where passphraseMinLength :: Proxy "lenient" -> Int
passphraseMinLength Proxy "lenient"
_ = Int
0
instance PassphraseMaxLength "lenient" where passphraseMaxLength :: Proxy "lenient" -> Int
passphraseMaxLength Proxy "lenient"
_ = Int
255

validatePassphrase
    :: forall purpose.
       (PassphraseMaxLength purpose, PassphraseMinLength purpose)
    => Text
    -> Either String (Passphrase purpose)
validatePassphrase :: Text -> Either String (Passphrase purpose)
validatePassphrase Text
pwd
    | Text -> Int
T.length Text
pwd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
minLength = String -> Either String (Passphrase purpose)
forall a b. a -> Either a b
Left (String -> Either String (Passphrase purpose))
-> String -> Either String (Passphrase purpose)
forall a b. (a -> b) -> a -> b
$
        String
"passphrase is too short: expected at least "
        String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
minLength String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" characters"
    | Text -> Int
T.length Text
pwd Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
maxLength = String -> Either String (Passphrase purpose)
forall a b. a -> Either a b
Left (String -> Either String (Passphrase purpose))
-> String -> Either String (Passphrase purpose)
forall a b. (a -> b) -> a -> b
$
        String
"passphrase is too long: expected at most "
        String -> ShowS
forall a. Semigroup a => a -> a -> a
<> Int -> String
forall a. Show a => a -> String
show Int
maxLength String -> ShowS
forall a. Semigroup a => a -> a -> a
<> String
" characters"
    | Bool
otherwise = Passphrase purpose -> Either String (Passphrase purpose)
forall a b. b -> Either a b
Right (Passphrase purpose -> Either String (Passphrase purpose))
-> Passphrase purpose -> Either String (Passphrase purpose)
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> Passphrase purpose
forall (purpose :: Symbol). ScrubbedBytes -> Passphrase purpose
Passphrase (ScrubbedBytes -> Passphrase purpose)
-> ScrubbedBytes -> Passphrase purpose
forall a b. (a -> b) -> a -> b
$ ByteString -> ScrubbedBytes
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert (ByteString -> ScrubbedBytes) -> ByteString -> ScrubbedBytes
forall a b. (a -> b) -> a -> b
$ Text -> ByteString
T.encodeUtf8 Text
pwd
  where
    minLength :: Int
minLength = Proxy purpose -> Int
forall (purpose :: Symbol).
PassphraseMinLength purpose =>
Proxy purpose -> Int
passphraseMinLength (Proxy purpose
forall k (t :: k). Proxy t
Proxy :: Proxy purpose)
    maxLength :: Int
maxLength = Proxy purpose -> Int
forall (purpose :: Symbol).
PassphraseMaxLength purpose =>
Proxy purpose -> Int
passphraseMaxLength (Proxy purpose
forall k (t :: k). Proxy t
Proxy :: Proxy purpose)

instance
    ( PassphraseMaxLength purpose
    , PassphraseMinLength purpose
    ) => FromText (Passphrase purpose) where
    fromText :: Text -> Either TextDecodingError (Passphrase purpose)
fromText = (String -> TextDecodingError)
-> Either String (Passphrase purpose)
-> Either TextDecodingError (Passphrase purpose)
forall (p :: * -> * -> *) a b c.
Bifunctor p =>
(a -> b) -> p a c -> p b c
first String -> TextDecodingError
TextDecodingError (Either String (Passphrase purpose)
 -> Either TextDecodingError (Passphrase purpose))
-> (Text -> Either String (Passphrase purpose))
-> Text
-> Either TextDecodingError (Passphrase purpose)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either String (Passphrase purpose)
forall (purpose :: Symbol).
(PassphraseMaxLength purpose, PassphraseMinLength purpose) =>
Text -> Either String (Passphrase purpose)
validatePassphrase

instance ToText (Passphrase purpose) where
    toText :: Passphrase purpose -> Text
toText (Passphrase ScrubbedBytes
bytes) = ByteString -> Text
T.decodeUtf8 (ByteString -> Text) -> ByteString -> Text
forall a b. (a -> b) -> a -> b
$ ScrubbedBytes -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
bin -> bout
BA.convert ScrubbedBytes
bytes

{-------------------------------------------------------------------------------
                      Wallet passphrases stored as hashes
-------------------------------------------------------------------------------}

-- | A type to capture which encryption scheme should be used
data PassphraseScheme
    = EncryptWithScrypt
        -- ^ Legacy encryption scheme for passphrases
    | EncryptWithPBKDF2
        -- ^ Encryption scheme used since cardano-wallet
    deriving ((forall x. PassphraseScheme -> Rep PassphraseScheme x)
-> (forall x. Rep PassphraseScheme x -> PassphraseScheme)
-> Generic PassphraseScheme
forall x. Rep PassphraseScheme x -> PassphraseScheme
forall x. PassphraseScheme -> Rep PassphraseScheme x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep PassphraseScheme x -> PassphraseScheme
$cfrom :: forall x. PassphraseScheme -> Rep PassphraseScheme x
Generic, PassphraseScheme -> PassphraseScheme -> Bool
(PassphraseScheme -> PassphraseScheme -> Bool)
-> (PassphraseScheme -> PassphraseScheme -> Bool)
-> Eq PassphraseScheme
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PassphraseScheme -> PassphraseScheme -> Bool
$c/= :: PassphraseScheme -> PassphraseScheme -> Bool
== :: PassphraseScheme -> PassphraseScheme -> Bool
$c== :: PassphraseScheme -> PassphraseScheme -> Bool
Eq, Eq PassphraseScheme
Eq PassphraseScheme
-> (PassphraseScheme -> PassphraseScheme -> Ordering)
-> (PassphraseScheme -> PassphraseScheme -> Bool)
-> (PassphraseScheme -> PassphraseScheme -> Bool)
-> (PassphraseScheme -> PassphraseScheme -> Bool)
-> (PassphraseScheme -> PassphraseScheme -> Bool)
-> (PassphraseScheme -> PassphraseScheme -> PassphraseScheme)
-> (PassphraseScheme -> PassphraseScheme -> PassphraseScheme)
-> Ord PassphraseScheme
PassphraseScheme -> PassphraseScheme -> Bool
PassphraseScheme -> PassphraseScheme -> Ordering
PassphraseScheme -> PassphraseScheme -> PassphraseScheme
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 :: PassphraseScheme -> PassphraseScheme -> PassphraseScheme
$cmin :: PassphraseScheme -> PassphraseScheme -> PassphraseScheme
max :: PassphraseScheme -> PassphraseScheme -> PassphraseScheme
$cmax :: PassphraseScheme -> PassphraseScheme -> PassphraseScheme
>= :: PassphraseScheme -> PassphraseScheme -> Bool
$c>= :: PassphraseScheme -> PassphraseScheme -> Bool
> :: PassphraseScheme -> PassphraseScheme -> Bool
$c> :: PassphraseScheme -> PassphraseScheme -> Bool
<= :: PassphraseScheme -> PassphraseScheme -> Bool
$c<= :: PassphraseScheme -> PassphraseScheme -> Bool
< :: PassphraseScheme -> PassphraseScheme -> Bool
$c< :: PassphraseScheme -> PassphraseScheme -> Bool
compare :: PassphraseScheme -> PassphraseScheme -> Ordering
$ccompare :: PassphraseScheme -> PassphraseScheme -> Ordering
$cp1Ord :: Eq PassphraseScheme
Ord, Int -> PassphraseScheme -> ShowS
[PassphraseScheme] -> ShowS
PassphraseScheme -> String
(Int -> PassphraseScheme -> ShowS)
-> (PassphraseScheme -> String)
-> ([PassphraseScheme] -> ShowS)
-> Show PassphraseScheme
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PassphraseScheme] -> ShowS
$cshowList :: [PassphraseScheme] -> ShowS
show :: PassphraseScheme -> String
$cshow :: PassphraseScheme -> String
showsPrec :: Int -> PassphraseScheme -> ShowS
$cshowsPrec :: Int -> PassphraseScheme -> ShowS
Show, ReadPrec [PassphraseScheme]
ReadPrec PassphraseScheme
Int -> ReadS PassphraseScheme
ReadS [PassphraseScheme]
(Int -> ReadS PassphraseScheme)
-> ReadS [PassphraseScheme]
-> ReadPrec PassphraseScheme
-> ReadPrec [PassphraseScheme]
-> Read PassphraseScheme
forall a.
(Int -> ReadS a)
-> ReadS [a] -> ReadPrec a -> ReadPrec [a] -> Read a
readListPrec :: ReadPrec [PassphraseScheme]
$creadListPrec :: ReadPrec [PassphraseScheme]
readPrec :: ReadPrec PassphraseScheme
$creadPrec :: ReadPrec PassphraseScheme
readList :: ReadS [PassphraseScheme]
$creadList :: ReadS [PassphraseScheme]
readsPrec :: Int -> ReadS PassphraseScheme
$creadsPrec :: Int -> ReadS PassphraseScheme
Read)

instance NFData PassphraseScheme

instance ToText PassphraseScheme where
    toText :: PassphraseScheme -> Text
toText PassphraseScheme
EncryptWithScrypt = Text
"scrypt"
    toText PassphraseScheme
EncryptWithPBKDF2 = Text
"pbkdf2-hmac-sha512"

newtype PassphraseHash = PassphraseHash { PassphraseHash -> ScrubbedBytes
getPassphraseHash :: ScrubbedBytes }
    deriving stock (Int -> PassphraseHash -> ShowS
[PassphraseHash] -> ShowS
PassphraseHash -> String
(Int -> PassphraseHash -> ShowS)
-> (PassphraseHash -> String)
-> ([PassphraseHash] -> ShowS)
-> Show PassphraseHash
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [PassphraseHash] -> ShowS
$cshowList :: [PassphraseHash] -> ShowS
show :: PassphraseHash -> String
$cshow :: PassphraseHash -> String
showsPrec :: Int -> PassphraseHash -> ShowS
$cshowsPrec :: Int -> PassphraseHash -> ShowS
Show)
    deriving newtype (PassphraseHash -> PassphraseHash -> Bool
(PassphraseHash -> PassphraseHash -> Bool)
-> (PassphraseHash -> PassphraseHash -> Bool) -> Eq PassphraseHash
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: PassphraseHash -> PassphraseHash -> Bool
$c/= :: PassphraseHash -> PassphraseHash -> Bool
== :: PassphraseHash -> PassphraseHash -> Bool
$c== :: PassphraseHash -> PassphraseHash -> Bool
Eq, Eq PassphraseHash
Eq PassphraseHash
-> (PassphraseHash -> PassphraseHash -> Ordering)
-> (PassphraseHash -> PassphraseHash -> Bool)
-> (PassphraseHash -> PassphraseHash -> Bool)
-> (PassphraseHash -> PassphraseHash -> Bool)
-> (PassphraseHash -> PassphraseHash -> Bool)
-> (PassphraseHash -> PassphraseHash -> PassphraseHash)
-> (PassphraseHash -> PassphraseHash -> PassphraseHash)
-> Ord PassphraseHash
PassphraseHash -> PassphraseHash -> Bool
PassphraseHash -> PassphraseHash -> Ordering
PassphraseHash -> PassphraseHash -> PassphraseHash
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 :: PassphraseHash -> PassphraseHash -> PassphraseHash
$cmin :: PassphraseHash -> PassphraseHash -> PassphraseHash
max :: PassphraseHash -> PassphraseHash -> PassphraseHash
$cmax :: PassphraseHash -> PassphraseHash -> PassphraseHash
>= :: PassphraseHash -> PassphraseHash -> Bool
$c>= :: PassphraseHash -> PassphraseHash -> Bool
> :: PassphraseHash -> PassphraseHash -> Bool
$c> :: PassphraseHash -> PassphraseHash -> Bool
<= :: PassphraseHash -> PassphraseHash -> Bool
$c<= :: PassphraseHash -> PassphraseHash -> Bool
< :: PassphraseHash -> PassphraseHash -> Bool
$c< :: PassphraseHash -> PassphraseHash -> Bool
compare :: PassphraseHash -> PassphraseHash -> Ordering
$ccompare :: PassphraseHash -> PassphraseHash -> Ordering
$cp1Ord :: Eq PassphraseHash
Ord, b -> PassphraseHash -> PassphraseHash
NonEmpty PassphraseHash -> PassphraseHash
PassphraseHash -> PassphraseHash -> PassphraseHash
(PassphraseHash -> PassphraseHash -> PassphraseHash)
-> (NonEmpty PassphraseHash -> PassphraseHash)
-> (forall b. Integral b => b -> PassphraseHash -> PassphraseHash)
-> Semigroup PassphraseHash
forall b. Integral b => b -> PassphraseHash -> PassphraseHash
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: b -> PassphraseHash -> PassphraseHash
$cstimes :: forall b. Integral b => b -> PassphraseHash -> PassphraseHash
sconcat :: NonEmpty PassphraseHash -> PassphraseHash
$csconcat :: NonEmpty PassphraseHash -> PassphraseHash
<> :: PassphraseHash -> PassphraseHash -> PassphraseHash
$c<> :: PassphraseHash -> PassphraseHash -> PassphraseHash
Semigroup, Semigroup PassphraseHash
PassphraseHash
Semigroup PassphraseHash
-> PassphraseHash
-> (PassphraseHash -> PassphraseHash -> PassphraseHash)
-> ([PassphraseHash] -> PassphraseHash)
-> Monoid PassphraseHash
[PassphraseHash] -> PassphraseHash
PassphraseHash -> PassphraseHash -> PassphraseHash
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [PassphraseHash] -> PassphraseHash
$cmconcat :: [PassphraseHash] -> PassphraseHash
mappend :: PassphraseHash -> PassphraseHash -> PassphraseHash
$cmappend :: PassphraseHash -> PassphraseHash -> PassphraseHash
mempty :: PassphraseHash
$cmempty :: PassphraseHash
$cp1Monoid :: Semigroup PassphraseHash
Monoid, PassphraseHash -> ()
(PassphraseHash -> ()) -> NFData PassphraseHash
forall a. (a -> ()) -> NFData a
rnf :: PassphraseHash -> ()
$crnf :: PassphraseHash -> ()
NFData, PassphraseHash -> Int
PassphraseHash -> Ptr p -> IO ()
PassphraseHash -> (Ptr p -> IO a) -> IO a
(PassphraseHash -> Int)
-> (forall p a. PassphraseHash -> (Ptr p -> IO a) -> IO a)
-> (forall p. PassphraseHash -> Ptr p -> IO ())
-> ByteArrayAccess PassphraseHash
forall p. PassphraseHash -> Ptr p -> IO ()
forall ba.
(ba -> Int)
-> (forall p a. ba -> (Ptr p -> IO a) -> IO a)
-> (forall p. ba -> Ptr p -> IO ())
-> ByteArrayAccess ba
forall p a. PassphraseHash -> (Ptr p -> IO a) -> IO a
copyByteArrayToPtr :: PassphraseHash -> Ptr p -> IO ()
$ccopyByteArrayToPtr :: forall p. PassphraseHash -> Ptr p -> IO ()
withByteArray :: PassphraseHash -> (Ptr p -> IO a) -> IO a
$cwithByteArray :: forall p a. PassphraseHash -> (Ptr p -> IO a) -> IO a
length :: PassphraseHash -> Int
$clength :: PassphraseHash -> Int
ByteArrayAccess, Eq PassphraseHash
Ord PassphraseHash
Monoid PassphraseHash
ByteArrayAccess PassphraseHash
Eq PassphraseHash
-> Ord PassphraseHash
-> Monoid PassphraseHash
-> ByteArrayAccess PassphraseHash
-> (forall p a. Int -> (Ptr p -> IO a) -> IO (a, PassphraseHash))
-> ByteArray PassphraseHash
Int -> (Ptr p -> IO a) -> IO (a, PassphraseHash)
forall ba.
Eq ba
-> Ord ba
-> Monoid ba
-> ByteArrayAccess ba
-> (forall p a. Int -> (Ptr p -> IO a) -> IO (a, ba))
-> ByteArray ba
forall p a. Int -> (Ptr p -> IO a) -> IO (a, PassphraseHash)
allocRet :: Int -> (Ptr p -> IO a) -> IO (a, PassphraseHash)
$callocRet :: forall p a. Int -> (Ptr p -> IO a) -> IO (a, PassphraseHash)
$cp4ByteArray :: ByteArrayAccess PassphraseHash
$cp3ByteArray :: Monoid PassphraseHash
$cp2ByteArray :: Ord PassphraseHash
$cp1ByteArray :: Eq PassphraseHash
ByteArray)

instance ToText PassphraseHash where
    toText :: PassphraseHash -> Text
toText = ByteString -> Text
T.decodeUtf8 (ByteString -> Text)
-> (PassphraseHash -> ByteString) -> PassphraseHash -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Base -> ScrubbedBytes -> ByteString
forall bin bout.
(ByteArrayAccess bin, ByteArray bout) =>
Base -> bin -> bout
convertToBase Base
Base16 (ScrubbedBytes -> ByteString)
-> (PassphraseHash -> ScrubbedBytes)
-> PassphraseHash
-> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. PassphraseHash -> ScrubbedBytes
getPassphraseHash

data WalletPassphraseInfo = WalletPassphraseInfo
    { WalletPassphraseInfo -> UTCTime
lastUpdatedAt :: UTCTime
    , WalletPassphraseInfo -> PassphraseScheme
passphraseScheme :: PassphraseScheme
    } deriving ((forall x. WalletPassphraseInfo -> Rep WalletPassphraseInfo x)
-> (forall x. Rep WalletPassphraseInfo x -> WalletPassphraseInfo)
-> Generic WalletPassphraseInfo
forall x. Rep WalletPassphraseInfo x -> WalletPassphraseInfo
forall x. WalletPassphraseInfo -> Rep WalletPassphraseInfo x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep WalletPassphraseInfo x -> WalletPassphraseInfo
$cfrom :: forall x. WalletPassphraseInfo -> Rep WalletPassphraseInfo x
Generic, WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
(WalletPassphraseInfo -> WalletPassphraseInfo -> Bool)
-> (WalletPassphraseInfo -> WalletPassphraseInfo -> Bool)
-> Eq WalletPassphraseInfo
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
$c/= :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
== :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
$c== :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
Eq, Eq WalletPassphraseInfo
Eq WalletPassphraseInfo
-> (WalletPassphraseInfo -> WalletPassphraseInfo -> Ordering)
-> (WalletPassphraseInfo -> WalletPassphraseInfo -> Bool)
-> (WalletPassphraseInfo -> WalletPassphraseInfo -> Bool)
-> (WalletPassphraseInfo -> WalletPassphraseInfo -> Bool)
-> (WalletPassphraseInfo -> WalletPassphraseInfo -> Bool)
-> (WalletPassphraseInfo
    -> WalletPassphraseInfo -> WalletPassphraseInfo)
-> (WalletPassphraseInfo
    -> WalletPassphraseInfo -> WalletPassphraseInfo)
-> Ord WalletPassphraseInfo
WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
WalletPassphraseInfo -> WalletPassphraseInfo -> Ordering
WalletPassphraseInfo
-> WalletPassphraseInfo -> WalletPassphraseInfo
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 :: WalletPassphraseInfo
-> WalletPassphraseInfo -> WalletPassphraseInfo
$cmin :: WalletPassphraseInfo
-> WalletPassphraseInfo -> WalletPassphraseInfo
max :: WalletPassphraseInfo
-> WalletPassphraseInfo -> WalletPassphraseInfo
$cmax :: WalletPassphraseInfo
-> WalletPassphraseInfo -> WalletPassphraseInfo
>= :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
$c>= :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
> :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
$c> :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
<= :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
$c<= :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
< :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
$c< :: WalletPassphraseInfo -> WalletPassphraseInfo -> Bool
compare :: WalletPassphraseInfo -> WalletPassphraseInfo -> Ordering
$ccompare :: WalletPassphraseInfo -> WalletPassphraseInfo -> Ordering
$cp1Ord :: Eq WalletPassphraseInfo
Ord, Int -> WalletPassphraseInfo -> ShowS
[WalletPassphraseInfo] -> ShowS
WalletPassphraseInfo -> String
(Int -> WalletPassphraseInfo -> ShowS)
-> (WalletPassphraseInfo -> String)
-> ([WalletPassphraseInfo] -> ShowS)
-> Show WalletPassphraseInfo
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [WalletPassphraseInfo] -> ShowS
$cshowList :: [WalletPassphraseInfo] -> ShowS
show :: WalletPassphraseInfo -> String
$cshow :: WalletPassphraseInfo -> String
showsPrec :: Int -> WalletPassphraseInfo -> ShowS
$cshowsPrec :: Int -> WalletPassphraseInfo -> ShowS
Show)

instance NFData WalletPassphraseInfo

{-------------------------------------------------------------------------------
                                  Error types
-------------------------------------------------------------------------------}

-- | Indicate a failure when checking for a given 'Passphrase' match
data ErrWrongPassphrase
    = ErrWrongPassphrase
    | ErrPassphraseSchemeUnsupported PassphraseScheme
    deriving stock ((forall x. ErrWrongPassphrase -> Rep ErrWrongPassphrase x)
-> (forall x. Rep ErrWrongPassphrase x -> ErrWrongPassphrase)
-> Generic ErrWrongPassphrase
forall x. Rep ErrWrongPassphrase x -> ErrWrongPassphrase
forall x. ErrWrongPassphrase -> Rep ErrWrongPassphrase x
forall a.
(forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a
$cto :: forall x. Rep ErrWrongPassphrase x -> ErrWrongPassphrase
$cfrom :: forall x. ErrWrongPassphrase -> Rep ErrWrongPassphrase x
Generic, Int -> ErrWrongPassphrase -> ShowS
[ErrWrongPassphrase] -> ShowS
ErrWrongPassphrase -> String
(Int -> ErrWrongPassphrase -> ShowS)
-> (ErrWrongPassphrase -> String)
-> ([ErrWrongPassphrase] -> ShowS)
-> Show ErrWrongPassphrase
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [ErrWrongPassphrase] -> ShowS
$cshowList :: [ErrWrongPassphrase] -> ShowS
show :: ErrWrongPassphrase -> String
$cshow :: ErrWrongPassphrase -> String
showsPrec :: Int -> ErrWrongPassphrase -> ShowS
$cshowsPrec :: Int -> ErrWrongPassphrase -> ShowS
Show, ErrWrongPassphrase -> ErrWrongPassphrase -> Bool
(ErrWrongPassphrase -> ErrWrongPassphrase -> Bool)
-> (ErrWrongPassphrase -> ErrWrongPassphrase -> Bool)
-> Eq ErrWrongPassphrase
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: ErrWrongPassphrase -> ErrWrongPassphrase -> Bool
$c/= :: ErrWrongPassphrase -> ErrWrongPassphrase -> Bool
== :: ErrWrongPassphrase -> ErrWrongPassphrase -> Bool
$c== :: ErrWrongPassphrase -> ErrWrongPassphrase -> Bool
Eq)

instance NFData ErrWrongPassphrase