summaryrefslogtreecommitdiffhomepage
path: root/Share.hs
diff options
context:
space:
mode:
authorJoey Hess <joeyh@joeyh.name>2016-08-28 12:34:43 -0400
committerJoey Hess <joeyh@joeyh.name>2016-08-28 12:38:38 -0400
commitbb9d3ea8598a0b48e9d773df24ff58856cbb9aa0 (patch)
tree50e2f897dca46d3c2c7562e7e54bf59a910bb526 /Share.hs
parent9ee5de24760beedf4a186fb5a568b2aa69974391 (diff)
downloadkeysafe-bb9d3ea8598a0b48e9d773df24ff58856cbb9aa0.tar.gz
Removed embedded copy of secret-sharing library, since finite-field only supports prime fields.
This caused shares to double in size.
Diffstat (limited to 'Share.hs')
-rw-r--r--Share.hs29
1 files changed, 22 insertions, 7 deletions
diff --git a/Share.hs b/Share.hs
index 76d118c..e511afd 100644
--- a/Share.hs
+++ b/Share.hs
@@ -19,6 +19,7 @@ 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.Word
import Data.Monoid
data ShareIdents = ShareIdents
@@ -92,20 +93,34 @@ combineShares tunables shares
fromStorableObject so
sharesneeded = neededObjects (shareParams 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 shares
-- by share number.
encodeShare :: SS.Share -> B.ByteString
-encodeShare = B.pack . map (fromIntegral . SS.shareValue) . SS.theShare
+encodeShare = B.pack . concatMap (encodeShare' . SS.shareValue) . SS.theShare
decodeShare :: Int -> Int -> B.ByteString -> SS.Share
-decodeShare sharenum sharesneeded = SS.Share . map mk . B.unpack
+decodeShare sharenum sharesneeded = SS.Share . map mk . decodeShare' . B.unpack
where
- mk w = SS.ByteShare
+ mk v = SS.ByteShare
{ SS.shareId = sharenum
, SS.reconstructionThreshold = sharesneeded
- , SS.shareValue = fromIntegral w
+ , SS.shareValue = v
}
+
+-- | Each input byte generates a share in a finite field of size 1021,
+-- so encode it as the product of two bytes. This is inneffient; if the
+-- finite field was 255 then the encoded share would be the same size as
+-- the input. But, the finite-field library used by secret-sharing does
+-- not support a non-prime size.
+encodeShare' :: Int -> [Word8]
+encodeShare' v =
+ let (q, r) = quotRem v 255
+ in [fromIntegral q, fromIntegral r]
+
+decodeShare' :: [Word8] -> [Int]
+decodeShare' = go []
+ where
+ go c [] = reverse c
+ go c (q:r:rest) = go (((255 * fromIntegral q) + fromIntegral r):c) rest
+ go _ _ = error "Badly encoded share has odd number of bytes"