summaryrefslogtreecommitdiff
path: root/benchmarks/Election.hs
blob: c51b40d84b48162b6efbe96036b22d8552a372cb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
{-# LANGUAGE OverloadedStrings #-}
module Election where

import qualified Data.List as List
import qualified Data.Text as Text
import qualified Text.Printf as Printf

import Voting.Protocol
import Utils

makeElection :: forall c. Reifies c FFC => Int -> Int -> Election c
makeElection nQuests nChoices = hashElection $ Election
 { election_name = Text.pack $ "elec"<>show nQuests<>show nChoices
 , election_description = "benchmarkable election"
 , election_uuid
 , election_crypto = ElectionCrypto_FFC (reflect (Proxy::Proxy c)) $
	let secKey = credentialSecretKey election_uuid (Credential "xLcs7ev6Jy6FHHE") in
	publicKey secKey
 , election_hash = Hash ""
 , election_questions =
	(<$> [1..nQuests]) $ \quest -> Question
	 { question_text = Text.pack $ "quest"<>show quest
	 , question_choices = (<$> [1..nChoices]) $ \choice -> Text.pack $ "choice"<>show choice
	 , question_mini = one
	 , question_maxi = one -- sum $ List.replicate nChoices one
	 }
 } where election_uuid = UUID "xLcs7ev6Jy6FHH"

makeVotes :: Election c -> [[Bool]]
makeVotes Election{..} =
	[ True : List.tail [ False | _choice <- question_choices quest ]
	| quest <- election_questions
	]

makeBallot :: Reifies c FFC => Election c -> Ballot c
makeBallot elec =
	case runExcept $ (`evalStateT` mkStdGen seed) $ do
		ballotSecKey <- randomSecretKey
		encryptBallot elec (Just ballotSecKey) $
			makeVotes elec of
	 Right ballot -> ballot
	 Left err -> error ("encryptBallot: "<>show err)
	where
	seed = 0

titleElection :: Election c -> String
titleElection Election{..} =
	Printf.printf "(questions=%i)×(choices=%i)==%i"
	 nQuests nChoices (nQuests * nChoices)
	where
	nQuests  = List.length election_questions
	nChoices = List.foldr max 0 $ List.length . question_choices <$> election_questions

benchEncryptBallot :: FFC -> Int -> Int -> Benchmark
benchEncryptBallot ffc nQuests nChoices =
	reify ffc $ \(Proxy::Proxy c) ->
		let setupEnv = do
			let elec :: Election c = makeElection nQuests nChoices
			return elec in
		env setupEnv $ \ ~(elec) ->
			bench (titleElection elec) $
				nf makeBallot elec

benchVerifyBallot :: FFC -> Int -> Int -> Benchmark
benchVerifyBallot ffc nQuests nChoices =
	reify ffc $ \(Proxy::Proxy c) ->
		let setupEnv = do
			let elec :: Election c = makeElection nQuests nChoices
			let ballot = makeBallot elec
			return (elec,ballot) in
		env setupEnv $ \ ~(elec, ballot) ->
			bench (titleElection elec) $
				nf (verifyBallot elec) ballot

benchmarks :: [Benchmark]
benchmarks =
 let inputs =
	 [ (nQ,nC)
	 | nQ <- [1,5,10,15,20,25]
	 , nC <- [5,7]
	 ] in
 [ bgroup "weakFFC"
	 [ bgroup "encryptBallot"
		 [ benchEncryptBallot weakFFC nQuests nChoices
		 | (nQuests,nChoices) <- inputs
		 ]
	 , bgroup "verifyBallot"
		 [ benchVerifyBallot weakFFC nQuests nChoices
		 | (nQuests,nChoices) <- inputs
		 ]
	 ]
 , bgroup "beleniosFFC"
	 [ bgroup "encryptBallot"
		 [ benchEncryptBallot beleniosFFC nQuests nChoices
		 | (nQuests,nChoices) <- inputs
		 ]
	 , bgroup "verifyBallot"
		 [ benchVerifyBallot beleniosFFC nQuests nChoices
		 | (nQuests,nChoices) <- inputs
		 ]
	 ]
 ]