summaryrefslogtreecommitdiffhomepage
path: root/Cost.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2016-08-06 21:39:38 -0400
committerJoey Hess <joeyh@joeyh.name>2016-08-06 21:58:20 -0400
commit94d351004688992f8aeac7d03da55d179ef50e8c (patch)
treed6db9a60d4b7b61e490926c8cc130d19aa6a3fca /Cost.hs
parente85b077676dffa9038a7f34e57523e77c3945261 (diff)
downloadkeysafe-94d351004688992f8aeac7d03da55d179ef50e8c.tar.gz
more cost calculation and refactored Tunables
Diffstat (limited to 'Cost.hs')
-rw-r--r--Cost.hs76
1 files changed, 76 insertions, 0 deletions
diff --git a/Cost.hs b/Cost.hs
new file mode 100644
index 0000000..0425707
--- /dev/null
+++ b/Cost.hs
@@ -0,0 +1,76 @@
+{-# LANGUAGE GeneralizedNewtypeDeriving #-}
+
+module Cost where
+
+import Utility.HumanTime
+import Data.Monoid
+
+-- | An estimated cost to perform an operation.
+data Cost op = CPUCost Seconds | GPUCost Seconds | CombinedCost (Cost op) (Cost op)
+ deriving (Show)
+
+newtype Seconds = Seconds Integer
+ deriving (Num)
+
+instance Show Seconds where
+ show (Seconds n) = fromDuration (Duration n)
+
+-- | Cost in seconds, with the type of hardware needed.
+totalCost :: Cost op -> (Seconds, [UsingHardware])
+totalCost (CPUCost s) = (s, [UsingCPU])
+totalCost (GPUCost s) = (s, [UsingGPU])
+totalCost (CombinedCost a b) =
+ let (s1, h1) = totalCost a
+ (s2, h2) = totalCost b
+ in (s1+s2, h1++h2)
+
+data UsingHardware = UsingCPU | UsingGPU | UsingASIC
+ deriving (Show)
+
+raiseCostPower :: Cost c -> Entropy e -> Cost c
+raiseCostPower c (Entropy e) = adjustCost c (* 2^e)
+
+adjustCost :: Cost c -> (Seconds -> Seconds) -> Cost c
+adjustCost (CPUCost s) f = CPUCost (f s)
+adjustCost (GPUCost s) f = GPUCost (f s)
+adjustCost (CombinedCost a b) f = CombinedCost (adjustCost a f) (adjustCost b f)
+
+castCost :: Cost a -> Cost b
+castCost (CPUCost s) = CPUCost s
+castCost (GPUCost s) = GPUCost s
+castCost (CombinedCost a b) = CombinedCost (castCost a) (castCost b)
+
+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
+
+-- | Number of bits of entropy
+newtype Entropy t = Entropy Int
+
+-- | 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 have entropy
+data UnknownPassword
+
+-- | CostCalc for a brute force linear search through an entropy space
+-- in which each step entails paying a cost.
+--
+-- On average, the solution will be found half way through.
+-- This is equivilant to one bit less of entropy.
+bruteForceLinearSearch :: Cost step -> CostCalc BruteForceOp t
+bruteForceLinearSearch stepcost e =
+ castCost stepcost `raiseCostPower` reduceEntropy e 1