]> Git — Sourcephile - majurity.git/blob - hjugement-protocol/tests/HUnit/Trustee/Indispensable.hs
protocol: align {To,From}JSON on Belenios' schemas.
[majurity.git] / hjugement-protocol / tests / HUnit / Trustee / Indispensable.hs
1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE OverloadedStrings #-}
3 {-# LANGUAGE PatternSynonyms #-}
4 module HUnit.Trustee.Indispensable where
5
6 import Test.Tasty.HUnit
7 import qualified Data.Text as Text
8 import qualified System.Random as Random
9 import qualified Text.Printf as Printf
10
11 import Voting.Protocol
12
13 import Utils
14
15 hunit :: TestTree
16 hunit = testGroup "Indispensable"
17 [ testGroup "verifyIndispensableTrusteePublicKey" $
18 [ testsVerifyIndispensableTrusteePublicKey weakFFC
19 ]
20 , testGroup "verifyTally" $
21 [ testsVerifyTally weakFFC
22 , testsVerifyTally beleniosFFC
23 ]
24 ]
25
26 testsVerifyIndispensableTrusteePublicKey :: FFC -> TestTree
27 testsVerifyIndispensableTrusteePublicKey ffc =
28 testGroup (Text.unpack $ ffc_name ffc)
29 [ testVerifyIndispensableTrusteePublicKey ffc 0 (Right ())
30 ]
31
32 testVerifyIndispensableTrusteePublicKey ::
33 FFC -> Int -> Either ErrorTrusteePublicKey () -> TestTree
34 testVerifyIndispensableTrusteePublicKey ffc seed exp =
35 let got =
36 reify ffc $ \(Proxy::Proxy c) ->
37 runExcept $
38 (`evalStateT` Random.mkStdGen seed) $ do
39 trusteeSecKey :: SecretKey c <- randomSecretKey
40 trusteePubKey <- proveIndispensableTrusteePublicKey trusteeSecKey
41 lift $ verifyIndispensableTrusteePublicKey trusteePubKey
42 in
43 testCase (Text.unpack $ ffc_name ffc) $
44 got @?= exp
45
46 testsVerifyTally :: FFC -> TestTree
47 testsVerifyTally ffc =
48 testGroup (Text.unpack $ ffc_name ffc)
49 [ testVerifyTally ffc 0 1 1 1
50 , testVerifyTally ffc 0 2 1 1
51 , testVerifyTally ffc 0 1 2 1
52 , testVerifyTally ffc 0 2 2 1
53 , testVerifyTally ffc 0 5 10 5
54 ]
55
56 testVerifyTally :: FFC -> Int -> Natural -> Natural -> Natural -> TestTree
57 testVerifyTally ffc seed nTrustees nQuests nChoices =
58 let clearTallyResult = dummyTallyResult nQuests nChoices in
59 let decryptedTallyResult :: Either ErrorTally [[Natural]] =
60 reify ffc $ \(Proxy::Proxy c) ->
61 runExcept $
62 (`evalStateT` Random.mkStdGen seed) $ do
63 secKeyByTrustee :: [SecretKey c] <-
64 replicateM (fromIntegral nTrustees) $ randomSecretKey
65 trusteePubKeys <- forM secKeyByTrustee $ proveIndispensableTrusteePublicKey
66 let pubKeyByTrustee = trustee_PublicKey <$> trusteePubKeys
67 let elecPubKey = combineIndispensableTrusteePublicKeys trusteePubKeys
68 (encTally, countMax) <- encryptTallyResult elecPubKey clearTallyResult
69 decShareByTrustee <- forM secKeyByTrustee $ proveDecryptionShare encTally
70 lift $ verifyDecryptionShareByTrustee encTally pubKeyByTrustee decShareByTrustee
71 tally@Tally{..} <- lift $
72 proveTally (encTally, countMax) decShareByTrustee $
73 combineIndispensableDecryptionShares pubKeyByTrustee
74 lift $ verifyTally tally $
75 combineIndispensableDecryptionShares pubKeyByTrustee
76 return tally_countByChoiceByQuest
77 in
78 testCase (Printf.printf "#T=%i,#Q=%i,#C=%i (%i maxCount)"
79 nTrustees nQuests nChoices
80 (dummyTallyCount nQuests nChoices)) $
81 decryptedTallyResult @?= Right clearTallyResult
82
83 dummyTallyCount :: Natural -> Natural -> Natural
84 dummyTallyCount quest choice = quest * choice
85
86 dummyTallyResult :: Natural -> Natural -> [[Natural]]
87 dummyTallyResult nQuests nChoices =
88 [ [ dummyTallyCount q c | c <- [1..nChoices] ]
89 | q <- [1..nQuests]
90 ]
91
92 encryptTallyResult ::
93 Reifies c FFC =>
94 Monad m => RandomGen r =>
95 PublicKey c -> [[Natural]] -> StateT r m (EncryptedTally c, Natural)
96 encryptTallyResult pubKey countByChoiceByQuest =
97 (`runStateT` 0) $
98 forM countByChoiceByQuest $
99 mapM $ \count -> do
100 modify' $ max count
101 (_encNonce, enc) <- lift $ encrypt pubKey (fromNatural count)
102 return enc
103