1 {-# LANGUAGE DataKinds #-}
2 {-# LANGUAGE OverloadedStrings #-}
3 {-# LANGUAGE PatternSynonyms #-}
4 module HUnit.Election where
6 import Test.Tasty.HUnit
7 import qualified Data.List as List
8 import qualified Data.Text as Text
9 import qualified System.Random as Random
11 import Voting.Protocol
16 hunit = testGroup "Election"
17 [ testGroup "groupGenInverses"
18 [ testCase "WeakParams" $
19 reify weakFFC $ \(Proxy::Proxy c) ->
20 List.take 10 (groupGenInverses @c) @?=
21 [groupGen^neg (fromNatural n) | n <- [0..9]]
22 , testCase "BeleniosParams" $
23 reify beleniosFFC $ \(Proxy::Proxy c) ->
24 List.take 10 (groupGenInverses @c) @?=
25 [groupGen^neg (fromNatural n) | n <- [0..9]]
27 , testGroup "encryptBallot" $
28 [ testsEncryptBallot weakFFC
29 , testsEncryptBallot beleniosFFC
33 testsEncryptBallot :: FFC -> TestTree
34 testsEncryptBallot ffc =
35 testGroup (Text.unpack $ ffc_name ffc)
36 [ testEncryptBallot ffc 0
37 [Question "q1" ["a1","a2","a3"] zero one]
38 [[True, False, False]]
40 , testEncryptBallot ffc 0
41 [Question "q1" ["a1","a2","a3"] zero one]
42 [[False, False, False]]
44 , testEncryptBallot ffc 0
45 [Question "q1" ["a1","a2","a3"] zero one]
46 [[False, False, False]]
48 , testEncryptBallot ffc 0
49 [Question "q1" [] zero one]
51 (Left (ErrorBallot_WrongNumberOfAnswers 0 1))
52 , testEncryptBallot ffc 0
53 [Question "q1" ["a1","a2"] one one]
55 (Left (ErrorBallot_Answer (ErrorAnswer_WrongNumberOfOpinions 1 2)))
56 , testEncryptBallot ffc 0
57 [Question "q1" ["a1","a2","a3"] zero one]
59 (Left (ErrorBallot_Answer (ErrorAnswer_WrongSumOfOpinions 2 0 1)))
60 , testEncryptBallot ffc 0
61 [Question "q1" ["a1","a2","a3"] one one]
62 [[False, False, False]]
63 (Left (ErrorBallot_Answer (ErrorAnswer_WrongSumOfOpinions 0 1 1)))
64 , testEncryptBallot ffc 0
65 [Question "q1" ["a1","a2"] one one]
66 [[False, False, True]]
67 (Left (ErrorBallot_Answer (ErrorAnswer_WrongNumberOfOpinions 3 2)))
68 , testEncryptBallot ffc 0
69 [ Question "q1" ["a11","a12","a13"] zero (one+one)
70 , Question "q2" ["a21","a22","a23"] one one
73 , [False, True, False] ]
78 FFC -> Int -> [Question] -> [[Bool]] ->
79 Either ErrorBallot Bool ->
81 testEncryptBallot ffc seed quests opins exp =
83 reify ffc $ \(Proxy::Proxy c) ->
85 (`evalStateT` Random.mkStdGen seed) $ do
87 cred <- randomCredential
88 let ballotSecKey = credentialSecretKey @c uuid cred
89 elecPubKey <- publicKey <$> randomSecretKey
91 { election_name = "election"
92 , election_description = "description"
93 , election_crypto = ElectionCrypto_FFC ffc elecPubKey
94 , election_questions = quests
95 , election_uuid = uuid
96 , election_hash = hashElection elec
99 <$> encryptBallot elec (Just ballotSecKey) opins
101 testCase (show opins) $