1 package civitas.common.ballotdesign;
2
3 import java.util.Map;
4
5 import org.springframework.beans.factory.annotation.Autowired;
6 import org.springframework.stereotype.Controller;
7
8 import civitas.common.CommonConstants;
9 import civitas.common.VoteChoice;
10 import civitas.common.ballot.Ballot;
11 import civitas.common.capabilityencryption.CapabilityEncryption;
12 import civitas.common.capabilityencryption.EncryptCapability;
13 import civitas.common.encryptedchoice.EncryptChoice;
14 import civitas.common.encryptedchoice.EncryptedChoice;
15 import civitas.common.verifiablevote.VerifiableVote;
16 import civitas.common.votersubmission.CreateVoterSubmission;
17 import civitas.common.votersubmission.VoterSubmission;
18 import civitas.crypto.ciphertextlist.CiphertextList;
19 import civitas.crypto.proofvote.ConstructProofVote;
20 import civitas.crypto.proofvote.ProofVote;
21 import civitas.crypto.publickey.ElGamalPublicKey;
22 import civitas.crypto.votecapability.VoteCapability;
23
24 @Controller
25 public class DecomposeBallot implements CommonConstants {
26
27 @Autowired
28 EncryptCapability encryptCapability;
29
30 @Autowired
31 EncryptChoice encryptChoice;
32
33 @Autowired
34 CalculatePositionInBallot calculatePositionInBallot;
35
36 @Autowired
37 CalculateBallotLength calculateBallotLength;
38
39 @Autowired
40 ConstructProofVote constructProofVote;
41
42 @Autowired
43 CreateVoterSubmission createVoterSubmission;
44
45 public VoterSubmission apply(
46 final BallotDesign that,
47 final Ballot ballot,
48 final int voterBlock,
49 final ElGamalPublicKey key,
50 final CiphertextList ciphertexts,
51 final String context,
52 final Map<String, VoteCapability> capabilities) {
53
54 if (key == null) {
55 throw new IllegalArgumentException("No key supplied");
56 }
57 VoteChoice[] cbMatrix = ballot.matrix;
58 int matrixSize = calculateBallotLength.apply(ballot.k);
59 if (ballot.k != that.candidates.length || cbMatrix.length != matrixSize) {
60 throw new IllegalArgumentException("The ballot's matrix size is not correct.");
61 }
62
63 VerifiableVote[] votes = new VerifiableVote[matrixSize];
64 for (int i = 0; i < ballot.k; i++) {
65 for (int j = i + 1; j < ballot.k; j++) {
66 int pos = calculatePositionInBallot.apply(i, j, ballot.k);
67
68 EncryptedChoice encryptedChoice = encryptChoice.apply(key, ciphertexts, cbMatrix, pos);
69
70 String desiredContext = context + KIND + i + ":" + j;
71 CapabilityEncryption encryptedCapability = encryptCapability.apply(key, capabilities, desiredContext);
72 ProofVote proofVote = constructProofVote.apply(
73 key.params,
74 encryptedCapability.encCap(),
75 encryptedChoice.encChoice().m(),
76 desiredContext,
77 encryptedCapability.factor(),
78 encryptedChoice.factor());
79
80 VerifiableVote v = new VerifiableVote(
81 desiredContext, encryptedChoice.encChoice(), encryptedCapability.encCap(), proofVote);
82
83 votes[pos] = v;
84 }
85 }
86 return createVoterSubmission.apply(voterBlock, votes);
87 }
88 }