diff options
author | Joey Hess <joeyh@joeyh.name> | 2016-08-11 16:33:26 -0400 |
---|---|---|
committer | Joey Hess <joeyh@joeyh.name> | 2016-08-11 16:33:26 -0400 |
commit | b2719f6e84c0c1f49ac6ab9b60846a899563961c (patch) | |
tree | 47c93357b3362e71baf0bf83a21372ae376dfba5 /Shard.hs | |
parent | 5decbad3eb779b1bbe11245cbde84701909e9c68 (diff) | |
download | keysafe-b2719f6e84c0c1f49ac6ab9b60846a899563961c.tar.gz |
inline slightly modified version of secret-sharing
Needed for efficient serialization of shares, unless upstream takes my
suggestion to make the finite field be size 256.
Diffstat (limited to 'Shard.hs')
-rw-r--r-- | Shard.hs | 38 |
1 files changed, 31 insertions, 7 deletions
@@ -1,19 +1,23 @@ {-# LANGUAGE OverloadedStrings, MultiParamTypeClasses #-} +{- Copyright 2016 Joey Hess <id@joeyh.name> + - + - Licensed under the GNU AGPL version 3 or higher. + -} + module Shard where import Types import Tunables import ExpensiveHash import Cost -import qualified Crypto.SecretSharing as SS +import qualified Crypto.SecretSharing.Internal as SS import qualified Data.ByteString as B import qualified Data.ByteString.Lazy as BL 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 Data.Binary import Data.Monoid data ShardIdents = ShardIdents @@ -47,14 +51,34 @@ shardIdents tunables (Name name) keyid = genShards :: EncryptedSecretKey -> Tunables -> IO [StorableObject] genShards (EncryptedSecretKey esk _) tunables = - map (StorableObject . encode) <$> SS.encode + map (StorableObject . encodeShare) <$> SS.encode (neededObjects $ head $ shardParams tunables) (totalObjects $ head $ shardParams tunables) (BL.fromStrict esk) -- Throws AssertionFailed if the number of shares is too small. -combineShards :: [StorableObject] -> EncryptedSecretKey -combineShards = mk . BL.toStrict . SS.decode . map conv +combineShards :: Tunables -> [StorableObject] -> EncryptedSecretKey +combineShards tunables = mk . SS.decode + . map ds . zip [1..] . map fromStorableObject + where + mk b = EncryptedSecretKey (BL.toStrict b) unknownCostCalc + ds (sharenum, b) = decodeShare sharenum sharesneeded b + sharesneeded = neededObjects $ head $ shardParams tunables + +-- | This efficient encoding relies on the share using a finite field of +-- size 256, so it maps directly to bytes. +-- +-- Note that this does not include the share number in the encoded +-- bytestring. This prevents an attacker from partitioning their shards +-- by share number. +encodeShare :: SS.Share -> B.ByteString +encodeShare = B.pack . map (fromIntegral . SS.shareValue) . SS.theShare + +decodeShare :: Int -> Int -> B.ByteString -> SS.Share +decodeShare sharenum sharesneeded = SS.Share . map mk . B.unpack where - conv = decode . fromStorableObject - mk b = EncryptedSecretKey b unknownCostCalc + mk w = SS.ByteShare + { SS.shareId = sharenum + , SS.reconstructionThreshold = sharesneeded + , SS.shareValue = fromIntegral w + } |