Skip to content
Snippets Groups Projects
Commit c1f8057e authored by Nick Chang-Fong's avatar Nick Chang-Fong
Browse files

added server-side checks for trustee-supplied election parameters and to check...

added server-side checks for trustee-supplied election parameters and to check all ballot elements are in appropriate group
parent e8ffdfac
No related branches found
No related tags found
No related merge requests found
......@@ -243,6 +243,35 @@ class EGPublicKey:
return ((left_side == right_side) and (dlog_proof.challenge == expected_challenge))
def validate_pk_params(self):
# check primality of p
if not number.isPrime(self.p):
raise Exception("p is not prime.")
# check length of p
if not (number.size(self.p) >= 2048):
raise Exception("p of insufficient length. Should be 2048 bits or greater.")
# check primality of q
if not number.isPrime(self.q):
raise Exception("q is not prime.")
# check length of q
if not (number.size(self.q) >= 256):
raise Exception("q of insufficient length. Should be 256 bits or greater.")
if (pow(self.g,self.q,self.p)!=1):
raise Exception("g does not generate subgroup of order q.")
if not (1 < self.g < self.p-1):
raise Exception("g out of range.")
if not (1 < self.y < p-1):
raise Exception("y out of range.")
if (pow(self.y,self.q,self.p)!=1):
raise Exception("g does not generate proper group.")
@classmethod
def from_dict(cls, d):
"""
......@@ -253,6 +282,12 @@ class EGPublicKey:
pk.p = int(d['p'])
pk.g = int(d['g'])
pk.q = int(d['q'])
try:
pk.validate_pk_params()
except Exception as e:
raise
return pk
fromJSONDict = from_dict
......@@ -530,6 +565,9 @@ class EGCiphertext:
Proof contains commitment = {A, B}, challenge, response
"""
# check that A, B are in the correct group
if not (pow(proof.commitment['A'],self.pk.q,self.pk.p)==1 and pow(proof.commitment['B'],self.pk.q,self.pk.p)==1):
return False
# check that g^response = A * alpha^challenge
first_check = (pow(self.pk.g, proof.response, self.pk.p) == ((pow(self.alpha, proof.challenge, self.pk.p) * proof.commitment['A']) % self.pk.p))
......@@ -586,6 +624,26 @@ class EGCiphertext:
return running_decryption
def check_group_membership(self, pk):
"""
checks to see if an ElGamal element belongs to the group in the pk
"""
if not (1 < self.alpha < pk.p-1):
return False
elif not (1 < self.beta < pk.p-1):
return False
elif (pow(self.alpha, pk.q, pk.p)!=1):
return False
elif (pow(self.beta, pk.q, pk.p)!=1):
return False
else:
return True
def to_dict(self):
return {'alpha': str(self.alpha), 'beta': str(self.beta)}
......@@ -665,6 +723,10 @@ class EGZKProof(object):
"""
Verify a DH tuple proof
"""
# check that A, B are in the correct group
if not (pow(proof.commitment['A'],self.pk.q,self.pk.p)==1 and pow(proof.commitment['B'],self.pk.q,self.pk.p)==1):
return False
# check that little_g^response = A * big_g^challenge
first_check = (pow(little_g, self.response, p) == ((pow(big_g, self.challenge, p) * self.commitment['A']) % p))
......@@ -730,4 +792,3 @@ def EG_fiatshamir_challenge_generator(commitment):
def DLog_challenge_generator(commitment):
string_to_hash = str(commitment)
return int(hashlib.sha1(string_to_hash).hexdigest(),16)
......@@ -176,6 +176,10 @@ class EncryptedAnswer(HeliosObject):
choice.pk = pk
individual_proof = self.individual_proofs[choice_num]
# verify that elements belong to the proper group
if not choice.check_group_membership(pk):
return False
# verify the proof on the encryption of that choice
if not choice.verify_disjunctive_encryption_proof(possible_plaintexts, individual_proof, algs.EG_disjunctive_challenge_generator):
return False
......@@ -775,4 +779,3 @@ class Tally(HeliosObject):
def _process_value_out(self, field_name, field_value):
if field_name == 'tally':
return [[a.toJSONDict() for a in q] for q in field_value]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment