1 package civitas.common.ballotdesign.tests;
2
3 import static org.junit.jupiter.api.Assertions.assertEquals;
4 import static org.junit.jupiter.api.Assertions.assertThrows;
5 import static org.mockito.Mockito.verify;
6
7 import org.junit.jupiter.api.DisplayName;
8 import org.junit.jupiter.api.Test;
9 import org.mockito.InjectMocks;
10 import org.mockito.Mock;
11
12 import civitas.common.ballotdesign.CalculateBallotLength;
13 import civitas.common.ballotdesign.CalculatePositionInBallot;
14 import civitas.common.ballotdesign.DecomposeBallot;
15 import civitas.common.capabilityencryption.EncryptCapability;
16 import civitas.common.encryptedchoice.EncryptChoice;
17 import civitas.common.tests.RandomAwareTestBase;
18 import civitas.common.votersubmission.VoterSubmission;
19 import civitas.common.votersubmission.tests.VoterSubmissionTestData;
20 import civitas.crypto.oneoflreencryption.tests.ElGamal1OfLReencryptionTestData;
21 import civitas.crypto.proofvote.ConstructProofVote;
22
23 class DecomposeBallotTest extends RandomAwareTestBase
24 implements VoterSubmissionTestData, ElGamal1OfLReencryptionTestData {
25
26 @InjectMocks
27 DecomposeBallot decomposeBallot;
28
29 @Mock
30 EncryptCapability encryptCapability;
31
32 @Mock
33 EncryptChoice encryptChoice;
34
35 @Mock
36 CalculatePositionInBallot calculatePositionInBallot;
37
38 @Mock
39 ConstructProofVote constructProofVote;
40
41 @Mock
42 CalculateBallotLength calculateBallotLength;
43
44 @Test
45 @DisplayName(
46 """
47 Decomposes a ballot into a VoterSubmission
48 - calculates the length of the ballot based on the number of candidates
49 - for each pair i,j:
50 - calculates their position in the matrix
51 - computes the encrypted choice by constructing an 1 of L reeencryption
52 - encrypts the capability from the map
53 - constructs a vote proof using all the above
54 - creates a verifiable vote using the context, the encryted capability and choice and the proof
55 - returns a voter submission for the voter block with the verifiable votes
56 """)
57 void test() {
58 VoterSubmission actual = decomposeBallot.apply(
59 BALLOTDESIGN,
60 BALLOT,
61 VOTER_BLOCK,
62 EL_GAMAL_PUBLIC_KEY_E,
63 CIPHERTEXT_LIST,
64 ADDITIONALENV,
65 CAPABILITY_MAP);
66 assertEquals(VOTER_SUBMISSION, actual);
67 verify(calculateBallotLength).apply(BALLOT.k);
68 CalculatePositionInBallot posStub = CalculatePositionInBallotStub.stub();
69 for (int i = 0; i < NUM_CANDIDATES; i++) {
70 for (int j = i + 1; j < NUM_CANDIDATES; j++) {
71 Integer pos = posStub.apply(i, j, NUM_CANDIDATES);
72 verify(encryptCapability).apply(EL_GAMAL_PUBLIC_KEY_E, CAPABILITY_MAP, CONTEXT_0);
73 verify(encryptChoice).apply(EL_GAMAL_PUBLIC_KEY_E, CIPHERTEXT_LIST, BALLOT.matrix, pos);
74 verify(calculatePositionInBallot).apply(i, j, NUM_CANDIDATES);
75
76 verify(constructProofVote)
77 .apply(
78 EL_GAMAL_PARAMETERS,
79 ENCRYPTED_SIGNED_VOTE_CAPABILITIES.get(pos),
80 EL_GAMAL_1_OF_L_REENCRYPTION_MAP
81 .get(BALLOT.matrix[pos])
82 .m(),
83 CONTEXT_MAP.get(pos),
84 ELGAMAL_REENCRYPT_FACTOR_E,
85 ELGAMAL_REENCRYPT_FACTOR_EPRIME);
86 }
87 }
88 }
89
90 @Test
91 @DisplayName("if the key is null, IllegalArgumentException is thrown")
92 void test1() {
93 assertThrows(
94 IllegalArgumentException.class,
95 () -> decomposeBallot.apply(
96 BALLOTDESIGN, BALLOT, VOTER_BLOCK, null, CIPHERTEXT_LIST, ADDITIONALENV, CAPABILITY_MAP));
97 }
98
99 @Test
100 @DisplayName("if the number of candidates in the ballot does not match the number of candidates,"
101 + "IllegalArgumentException is thrown")
102 void test2() {
103 assertThrows(
104 IllegalArgumentException.class,
105 () -> decomposeBallot.apply(
106 BALLOTDESIGN,
107 BALLOT_2_CANDIDATES,
108 VOTER_BLOCK,
109 EL_GAMAL_PUBLIC_KEY_E,
110 CIPHERTEXT_LIST,
111 ADDITIONALENV,
112 CAPABILITY_MAP));
113 }
114
115 @Test
116 @DisplayName("if the matrix length in the ballot does not match the number of candidates,"
117 + "IllegalArgumentException is thrown")
118 void test3() {
119 assertThrows(
120 IllegalArgumentException.class,
121 () -> decomposeBallot.apply(
122 BALLOTDESIGN,
123 BALLOT_SHORT_MATRIX,
124 VOTER_BLOCK,
125 EL_GAMAL_PUBLIC_KEY_E,
126 CIPHERTEXT_LIST,
127 ADDITIONALENV,
128 CAPABILITY_MAP));
129 }
130 }