{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, EmptyDataDecls #-} {- Copyright 2016 Joey Hess - - Licensed under the GNU AGPL version 3 or higher. -} module Types.Cost where import Utility.HumanTime -- | An estimated cost to perform an operation. data Cost op = CPUCost Seconds -- ^ using 1 CPU core deriving (Show, Eq, Ord) unknownCost :: Cost op unknownCost = CPUCost (Seconds 0) newtype Seconds = Seconds Integer deriving (Num, Eq, Ord) instance Show Seconds where show (Seconds n) = fromDuration (Duration n) data UsingHardware = UsingCPU | UsingGPU | UsingASIC deriving (Show) instance Monoid (Cost t) where mempty = CPUCost (Seconds 0) CPUCost (Seconds a) `mappend` CPUCost (Seconds b) = CPUCost (Seconds (a+b)) mapCost :: (Integer -> Integer) -> Cost op -> Cost op mapCost f (CPUCost (Seconds n)) = CPUCost (Seconds (f n)) -- | Operations whose cost can be measured. data DecryptionOp data CreationOp data BruteForceOp -- | Calculation of a cost that depends on some amount of entropy. type CostCalc op t = Entropy t -> Cost op unknownCostCalc :: CostCalc op t unknownCostCalc = \_e -> error "No cost calculation available" -- | Number of bits of entropy newtype Entropy t = Entropy Int deriving (Num, Show) class CalcEntropy d t where calcEntropy :: d -> Entropy t -- | Entropy can never go negative when subtracting bits from it. reduceEntropy :: Entropy t -> Int -> Entropy t reduceEntropy (Entropy a) b = Entropy (max 0 (a - b)) -- | Things that can be brute-forced track their CostCalc. class Bruteforceable t a where getBruteCostCalc :: t -> CostCalc BruteForceOp a -- | Things that can have entropy data UnknownPassword data UnknownName