diff options
author | Joey Hess <joeyh@joeyh.name> | 2016-08-19 16:36:46 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2016-08-19 16:36:46 -0400 |
commit | 0afe2e6177b48078db381d26334d3f4fd13363da (patch) | |
tree | ce23c42a9273394c0738978a6e0724d69b90777a /Share.hs | |
parent | fdc80b7a2416782d3208acf154fb8afb7fb2279b (diff) | |
download | keysafe-0afe2e6177b48078db381d26334d3f4fd13363da.tar.gz |
chunking
This changed the storage format, not that it matters because nobody is
using it yet.
Diffstat (limited to 'Share.hs')
-rw-r--r-- | Share.hs | 57 |
1 files changed, 35 insertions, 22 deletions
@@ -18,18 +18,21 @@ import qualified Raaz.Core.Encode as Raaz import qualified Raaz.Hash.Sha256 as Raaz import qualified Data.Text as T import qualified Data.Text.Encoding as E +import qualified Data.Set as S import Data.Monoid -import Control.DeepSeq data ShareIdents = ShareIdents - { getIdents :: [StorableObjectIdent] - -- ^ An infinite list of idents to use for shares. + { identsStream :: [S.Set StorableObjectIdent] + -- ^ Each item in the infinite list is the idents to + -- use for the shares of a chunk of data. , identsCreationCost :: Cost CreationOp , identsBruteForceCalc :: CostCalc BruteForceOp UnknownName } -instance NFData ShareIdents where - rnf = rnf . getIdents +nextShareIdents :: ShareIdents -> (S.Set StorableObjectIdent, ShareIdents) +nextShareIdents sis = + let (s:rest) = identsStream sis + in (s, sis { identsStream = rest }) instance HasCreationCost ShareIdents where getCreationCost = identsCreationCost @@ -45,7 +48,7 @@ instance Bruteforceable ShareIdents UnknownName where -- when the same name is chosen for multiple keys. shareIdents :: Tunables -> Name -> SecretKeySource -> ShareIdents shareIdents tunables (Name name) keyid = - ShareIdents idents creationcost bruteforcecalc + ShareIdents (segmentbyshare idents) creationcost bruteforcecalc where (ExpensiveHash creationcost basename) = expensiveHash hashtunables (Salt keyid) name @@ -53,31 +56,41 @@ shareIdents tunables (Name name) keyid = E.encodeUtf8 $ basename <> T.pack (show n) mksha :: B.ByteString -> Raaz.Base16 mksha = Raaz.encode . Raaz.sha256 - idents = map mk [1..] bruteforcecalc = bruteForceLinearSearch creationcost hashtunables = nameGenerationHash $ nameGenerationTunable tunables + idents = map mk ([1..] :: [Integer]) + m = totalObjects (shareParams tunables) + segmentbyshare l = + let (shareis, l') = splitAt m l + in S.fromList shareis : segmentbyshare l' -genShares :: EncryptedSecretKey -> Tunables -> IO [Share] -genShares (EncryptedSecretKey esk _) tunables = do - shares <- SS.encode - (neededObjects $ shareParams tunables) - (totalObjects $ shareParams tunables) - (BL.fromStrict esk) - return $ map (\(n, share) -> Share n (StorableObject $ encodeShare share)) - (zip [1..] shares) +-- | Generates shares of an EncryptedSecretKey. +-- Each chunk of the key creates its own set of shares. +genShares :: EncryptedSecretKey -> Tunables -> IO [S.Set Share] +genShares (EncryptedSecretKey cs _) tunables = do + shares <- mapM encode cs + return $ map (S.fromList . map (uncurry Share) . zip [1..]) shares + where + encode :: B.ByteString -> IO [StorableObject] + encode b = map (StorableObject . encodeShare) + <$> SS.encode + (neededObjects $ shareParams tunables) + (totalObjects $ shareParams tunables) + (BL.fromStrict b) -combineShares :: Tunables -> [Share] -> Either String EncryptedSecretKey +-- | If not enough sets of shares are provided, the EncryptedSecretKey may +-- be incomplete, only containing some chunks of the key +combineShares :: Tunables -> [S.Set Share] -> Either String EncryptedSecretKey combineShares tunables shares - | null shares = - Left "No shares could be downloaded. Perhaps you entered the wrong name or password?" - | length shares < neededObjects (shareParams tunables) = + | null shares || any null shares || any (\l -> length l < sharesneeded) shares = Left "Not enough shares are currently available to reconstruct your data." - | otherwise = Right $ mk $ SS.decode $ map decodeshare shares + | otherwise = Right $ mk $ + map (BL.toStrict . SS.decode . map decodeshare . S.toList) shares where - mk b = EncryptedSecretKey (BL.toStrict b) unknownCostCalc + mk cs = EncryptedSecretKey cs unknownCostCalc decodeshare (Share sharenum so) = decodeShare sharenum sharesneeded $ fromStorableObject so - sharesneeded = neededObjects $ shareParams tunables + sharesneeded = neededObjects (shareParams tunables) -- | This efficient encoding relies on the share using a finite field of -- size 256, so it maps directly to bytes. |