1 package civitas.common.votercapabilitysharesandproofs;
2
3 import org.springframework.beans.factory.annotation.Autowired;
4 import org.springframework.stereotype.Controller;
5
6 import civitas.crypto.ciphertext.ElGamalCiphertext;
7 import civitas.crypto.ciphertext.ElGamalEncrypt;
8 import civitas.crypto.messagedigest.CryptoHash;
9 import civitas.crypto.parameters.ElGamalParameters;
10 import civitas.crypto.proofdvr.ElGamalProofDVR;
11 import civitas.crypto.proofdvr.VerifyElGamalProofDVR;
12 import civitas.crypto.publickey.ElGamalPublicKey;
13 import civitas.crypto.reencryptfactor.ElGamalReencryptFactor;
14 import civitas.crypto.signature.VerifyElGamalSignature;
15 import civitas.crypto.signedciphertext.ElGamalSignedCiphertext;
16 import civitas.crypto.votecapabilityshare.VoteCapabilityShare;
17 import jakarta.annotation.Nonnull;
18
19 @Controller
20 public class VerifyVoterCapabilitySharesAndProof {
21
22 @Autowired
23 VerifyElGamalSignature verifyElGamalSignature;
24
25 @Autowired
26 CryptoHash cryptoHash;
27
28 @Autowired
29 ElGamalEncrypt elGamalEncrypt;
30
31 @Autowired
32 VerifyElGamalProofDVR verifyElGamalProofDVR;
33
34 public boolean apply(
35 @Nonnull final VoterCapabilitySharesAndProof that,
36 @Nonnull final ElGamalSignedCiphertext[] postedCapabilities,
37 @Nonnull final ElGamalPublicKey voterPublicKey,
38 @Nonnull final ElGamalPublicKey tabTellerSharedPublicKey,
39 final String voterName,
40 final int tellerIndex) {
41 if (null == voterPublicKey) {
42 throw new NullPointerException();
43 }
44 if (that.capabilities.length != that.rencryptFactors.length
45 || that.capabilities.length != that.proofs.length
46 || postedCapabilities.length != that.capabilities.length) {
47 return false;
48 }
49
50 ElGamalParameters params = tabTellerSharedPublicKey.params;
51 byte[] hash = cryptoHash.apply((tellerIndex + voterName).getBytes());
52
53 for (int i = 0; i < that.capabilities.length; i++) {
54 VoteCapabilityShare vc = that.capabilities[i];
55 ElGamalReencryptFactor r = that.rencryptFactors[i];
56 ElGamalProofDVR p = that.proofs[i];
57 if (!p.e().equals(postedCapabilities[i])
58 || !verifyElGamalSignature.apply(params, postedCapabilities[i], hash)) {
59 return false;
60 }
61
62 ElGamalCiphertext encrypted = elGamalEncrypt.apply(tabTellerSharedPublicKey, vc, r);
63 if (!encrypted.equals(p.eprime())
64 || !verifyElGamalProofDVR.apply(p, tabTellerSharedPublicKey, voterPublicKey)) {
65 return false;
66 }
67 }
68 return true;
69 }
70 }