{-# LANGUAGE GeneralizedNewtypeDeriving, MultiParamTypeClasses, EmptyDataDecls #-} module Types.Cost where import Utility.HumanTime -- | An estimated cost to perform an operation. data Cost op = CPUCost Seconds -- ^ using 1 CPU core | GPUCost Seconds | CombinedCost (Cost op) (Cost op) deriving (Show) unknownCost :: Cost op unknownCost = CPUCost (Seconds 0) newtype Seconds = Seconds Integer deriving (Num) 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)) GPUCost (Seconds a) `mappend` GPUCost (Seconds b) = GPUCost (Seconds (a+b)) a `mappend` b = CombinedCost a b -- | 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) -- | 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