diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Entropy.hs | 37 | ||||
-rw-r--r-- | Types.hs | 13 | ||||
-rw-r--r-- | Types/Cost.hs | 3 | ||||
-rw-r--r-- | keysafe.cabal | 3 | ||||
-rw-r--r-- | stack.yaml | 1 |
6 files changed, 23 insertions, 35 deletions
@@ -1 +1,2 @@ dist/* +.stack-work/* @@ -1,5 +1,3 @@ -{-# LANGUAGE FlexibleInstances #-} - {- Copyright 2016 Joey Hess <id@joeyh.name> - - Licensed under the GNU AGPL version 3 or higher. @@ -7,23 +5,20 @@ module Entropy where -import Data.List +import Types +import Types.Cost import qualified Data.ByteString.UTF8 as B - -class ToChars t where - toChars :: t -> [Char] - -instance ToChars String where - toChars = id - -instance ToChars B.ByteString where - toChars = B.toString - -shannonEntropy :: ToChars s => s -> Double -shannonEntropy = sum . map lg' . fq' . map (fromIntegral.length) . group . sort . toChars - where - lg' c = (c * ) . logBase 2 $ 1.0 / c - fq' c = let sc = sum c in map (/ sc) c - -totalEntropy :: ToChars s => s -> Double -totalEntropy s = shannonEntropy s * fromIntegral (length (toChars s)) +import Text.Password.Strength (estimate, UserDict) + +-- | Calculation of the entropy of a password. +-- Uses zxcvbn so takes word lists, and other entropy weakening problems +-- into account. +passwordEntropy :: Password -> UserDict -> Entropy UnknownPassword +passwordEntropy (Password p) userdict = Entropy $ floor $ + estimate (B.toString p) userdict + +-- | Naive calculation of the entropy of a name. +-- Assumes that the attacker is not targeting a particular list of names. +nameEntropy :: Name -> Entropy UnknownName +nameEntropy (Name n) = Entropy $ floor $ + estimate (B.toString n) [] @@ -8,7 +8,6 @@ module Types where import Types.Cost -import Entropy import qualified Data.ByteString as B import Data.String @@ -42,22 +41,10 @@ type ShardNum = Int newtype Password = Password B.ByteString deriving (IsString) --- | Naive calculation of the entropy of a password. --- Does not take common passwords and password generation patterns into --- account, so this is an overestimation of how hard a password --- is to crack. -passwordEntropy :: Password -> Entropy UnknownPassword -passwordEntropy (Password p) = Entropy $ floor $ totalEntropy p - -- | A name associated with a key stored in keysafe. newtype Name = Name B.ByteString deriving (Show) --- | Very naive calculation of the entropy of a name. --- Assumes that the attacker is not targeting a particular list of names. -nameEntropy :: Name -> Entropy UnknownName -nameEntropy (Name n) = Entropy $ floor $ totalEntropy n - -- | The type of the key that is stored in keysafe. newtype KeyType = KeyType B.ByteString deriving (Show) diff --git a/Types/Cost.hs b/Types/Cost.hs index de091b8..a6a1160 100644 --- a/Types/Cost.hs +++ b/Types/Cost.hs @@ -51,6 +51,9 @@ unknownCostCalc = \_e -> error "No cost calculation available" 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)) diff --git a/keysafe.cabal b/keysafe.cabal index 28fa921..fc80725 100644 --- a/keysafe.cabal +++ b/keysafe.cabal @@ -18,7 +18,7 @@ Executable keysafe Main-Is: keysafe.hs GHC-Options: -Wall -fno-warn-tabs -O2 Build-Depends: - base (>= 4.5) + base (>= 4.5 && < 5.0) , bytestring == 0.10.* , deepseq == 1.4.* , random == 1.1.* @@ -35,6 +35,7 @@ Executable keysafe , process == 1.2.* , optparse-applicative == 0.12.* , readline == 1.0.* + , zxcvbn-c == 1.0.* -- secret-sharing == 1.0.* , dice-entropy-conduit >= 1.0.0.0 @@ -6,4 +6,5 @@ extra-deps: - finite-field-0.8.0 - polynomial-0.7.2 - raaz-0.0.2 + - zxcvbn-c-1.0.0 explicit-setup-deps: |