<s> """<STR_LIT>""" <EOL> import algs <EOL> import logging <EOL> import utils <EOL> import uuid <EOL> import datetime <EOL> class HeliosObject ( object ) : <EOL> """<STR_LIT>""" <EOL> FIELDS = [ ] <EOL> JSON_FIELDS = None <EOL> def __init__ ( self , ** kwargs ) : <EOL> self . set_from_args ( ** kwargs ) <EOL> if '<STR_LIT>' in self . FIELDS and ( not hasattr ( self , '<STR_LIT>' ) or self . uuid == None ) : <EOL> self . uuid = str ( uuid . uuid4 ( ) ) <EOL> def set_from_args ( self , ** kwargs ) : <EOL> for f in self . FIELDS : <EOL> if kwargs . has_key ( f ) : <EOL> new_val = self . process_value_in ( f , kwargs [ f ] ) <EOL> setattr ( self , f , new_val ) <EOL> else : <EOL> setattr ( self , f , None ) <EOL> def set_from_other_object ( self , o ) : <EOL> for f in self . FIELDS : <EOL> if hasattr ( o , f ) : <EOL> setattr ( self , f , self . process_value_in ( f , getattr ( o , f ) ) ) <EOL> else : <EOL> setattr ( self , f , None ) <EOL> def toJSON ( self ) : <EOL> return utils . to_json ( self . toJSONDict ( ) ) <EOL> def toJSONDict ( self , alternate_fields = None ) : <EOL> val = { } <EOL> for f in ( alternate_fields or self . JSON_FIELDS or self . FIELDS ) : <EOL> val [ f ] = self . process_value_out ( f , getattr ( self , f ) ) <EOL> return val <EOL> @ classmethod <EOL> def fromJSONDict ( cls , d ) : <EOL> new_d = { } <EOL> for k in d . keys ( ) : <EOL> new_d [ str ( k ) ] = d [ k ] <EOL> return cls ( ** new_d ) <EOL> @ classmethod <EOL> def fromOtherObject ( cls , o ) : <EOL> obj = cls ( ) <EOL> obj . set_from_other_object ( o ) <EOL> return obj <EOL> def toOtherObject ( self , o ) : <EOL> for f in self . FIELDS : <EOL> if hasattr ( o , f ) : <EOL> try : <EOL> setattr ( o , f , self . process_value_out ( f , getattr ( self , f ) ) ) <EOL> except : <EOL> pass <EOL> @ property <EOL> def hash ( self ) : <EOL> s = utils . to_json ( self . toJSONDict ( ) ) <EOL> return utils . hash_b64 ( s ) <EOL> def process_value_in ( self , field_name , field_value ) : <EOL> """<STR_LIT>""" <EOL> if field_value == None : <EOL> return None <EOL> val = self . _process_value_in ( field_name , field_value ) <EOL> if val != None : <EOL> return val <EOL> else : <EOL> return field_value <EOL> def _process_value_in ( self , field_name , field_value ) : <EOL> return None <EOL> def process_value_out ( self , field_name , field_value ) : <EOL> """<STR_LIT>""" <EOL> if field_value == None : <EOL> return None <EOL> val = self . _process_value_out ( field_name , field_value ) <EOL> if val != None : <EOL> return val <EOL> else : <EOL> return field_value <EOL> def _process_value_out ( self , field_name , field_value ) : <EOL> return None <EOL> def __eq__ ( self , other ) : <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> return super ( HeliosObject , self ) == other <EOL> return other != None and self . uuid == other . uuid <EOL> class EncryptedAnswer ( HeliosObject ) : <EOL> """<STR_LIT>""" <EOL> FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __init__ ( self , choices = None , individual_proofs = None , overall_proof = None , randomness = None , answer = None ) : <EOL> self . choices = choices <EOL> self . individual_proofs = individual_proofs <EOL> self . overall_proof = overall_proof <EOL> self . randomness = randomness <EOL> self . answer = answer <EOL> @ classmethod <EOL> def generate_plaintexts ( cls , pk , min = <NUM_LIT:0> , max = <NUM_LIT:1> ) : <EOL> plaintexts = [ ] <EOL> running_product = <NUM_LIT:1> <EOL> for i in range ( max + <NUM_LIT:1> ) : <EOL> if i >= min : <EOL> plaintexts . append ( algs . EGPlaintext ( running_product , pk ) ) <EOL> running_product = ( running_product * pk . g ) % pk . p <EOL> return plaintexts <EOL> def verify_plaintexts_and_randomness ( self , pk ) : <EOL> """<STR_LIT>""" <EOL> if not hasattr ( self , '<STR_LIT>' ) : <EOL> return False <EOL> for choice_num in range ( len ( self . choices ) ) : <EOL> choice = self . choices [ choice_num ] <EOL> choice . pk = pk <EOL> return False <EOL> def verify ( self , pk , min = <NUM_LIT:0> , max = <NUM_LIT:1> ) : <EOL> possible_plaintexts = self . generate_plaintexts ( pk ) <EOL> homomorphic_sum = <NUM_LIT:0> <EOL> for choice_num in range ( len ( self . choices ) ) : <EOL> choice = self . choices [ choice_num ] <EOL> choice . pk = pk <EOL> individual_proof = self . individual_proofs [ choice_num ] <EOL> if not choice . verify_disjunctive_encryption_proof ( possible_plaintexts , individual_proof , algs . EG_disjunctive_challenge_generator ) : <EOL> return False <EOL> if max != None : <EOL> homomorphic_sum = choice * homomorphic_sum <EOL> if max != None : <EOL> sum_possible_plaintexts = self . generate_plaintexts ( pk , min = min , max = max ) <EOL> return homomorphic_sum . verify_disjunctive_encryption_proof ( sum_possible_plaintexts , self . overall_proof , algs . EG_disjunctive_challenge_generator ) <EOL> else : <EOL> return True <EOL> def toJSONDict ( self , with_randomness = False ) : <EOL> value = { <EOL> '<STR_LIT>' : [ c . to_dict ( ) for c in self . choices ] , <EOL> '<STR_LIT>' : [ p . to_dict ( ) for p in self . individual_proofs ] <EOL> } <EOL> if self . overall_proof : <EOL> value [ '<STR_LIT>' ] = self . overall_proof . to_dict ( ) <EOL> else : <EOL> value [ '<STR_LIT>' ] = None <EOL> if with_randomness : <EOL> value [ '<STR_LIT>' ] = [ str ( r ) for r in self . randomness ] <EOL> value [ '<STR_LIT>' ] = self . answer <EOL> return value <EOL> @ classmethod <EOL> def fromJSONDict ( cls , d , pk = None ) : <EOL> ea = cls ( ) <EOL> ea . choices = [ algs . EGCiphertext . from_dict ( c , pk ) for c in d [ '<STR_LIT>' ] ] <EOL> ea . individual_proofs = [ algs . EGZKDisjunctiveProof . from_dict ( p ) for p in d [ '<STR_LIT>' ] ] <EOL> if d [ '<STR_LIT>' ] : <EOL> ea . overall_proof = algs . EGZKDisjunctiveProof . from_dict ( d [ '<STR_LIT>' ] ) <EOL> else : <EOL> ea . overall_proof = None <EOL> if d . has_key ( '<STR_LIT>' ) : <EOL> ea . randomness = [ int ( r ) for r in d [ '<STR_LIT>' ] ] <EOL> ea . answer = d [ '<STR_LIT>' ] <EOL> return ea <EOL> @ classmethod <EOL> def fromElectionAndAnswer ( cls , election , question_num , answer_indexes ) : <EOL> """<STR_LIT>""" <EOL> question = election . questions [ question_num ] <EOL> answers = question [ '<STR_LIT>' ] <EOL> pk = election . public_key <EOL> choices = [ None for a in range ( len ( answers ) ) ] <EOL> individual_proofs = [ None for a in range ( len ( answers ) ) ] <EOL> overall_proof = None <EOL> randomness = [ None for a in range ( len ( answers ) ) ] <EOL> plaintexts = cls . generate_plaintexts ( pk ) <EOL> num_selected_answers = <NUM_LIT:0> ; <EOL> homomorphic_sum = <NUM_LIT:0> <EOL> randomness_sum = <NUM_LIT:0> <EOL> min_answers = <NUM_LIT:0> <EOL> if question . has_key ( '<STR_LIT>' ) : <EOL> min_answers = question [ '<STR_LIT>' ] <EOL> max_answers = question [ '<STR_LIT>' ] <EOL> for answer_num in range ( len ( answers ) ) : <EOL> plaintext_index = <NUM_LIT:0> <EOL> if answer_num in answer_indexes : <EOL> plaintext_index = <NUM_LIT:1> <EOL> num_selected_answers += <NUM_LIT:1> <EOL> randomness [ answer_num ] = algs . Utils . random_mpz_lt ( pk . q ) <EOL> choices [ answer_num ] = pk . encrypt_with_r ( plaintexts [ plaintext_index ] , randomness [ answer_num ] ) <EOL> individual_proofs [ answer_num ] = choices [ answer_num ] . generate_disjunctive_encryption_proof ( plaintexts , plaintext_index , <EOL> randomness [ answer_num ] , algs . EG_disjunctive_challenge_generator ) <EOL> if max_answers != None : <EOL> homomorphic_sum = choices [ answer_num ] * homomorphic_sum <EOL> randomness_sum = ( randomness_sum + randomness [ answer_num ] ) % pk . q <EOL> if num_selected_answers < min_answers : <EOL> raise Exception ( "<STR_LIT>" % min_answers ) <EOL> if max_answers != None : <EOL> sum_plaintexts = cls . generate_plaintexts ( pk , min = min_answers , max = max_answers ) <EOL> overall_proof = homomorphic_sum . generate_disjunctive_encryption_proof ( sum_plaintexts , num_selected_answers - min_answers , randomness_sum , algs . EG_disjunctive_challenge_generator ) ; <EOL> else : <EOL> overall_proof = None <EOL> return cls ( choices , individual_proofs , overall_proof , randomness , answer_indexes ) <EOL> class EncryptedVote ( HeliosObject ) : <EOL> """<STR_LIT>""" <EOL> FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def verify ( self , election ) : <EOL> if len ( self . encrypted_answers ) != len ( election . questions ) : <EOL> return False <EOL> if self . election_hash != election . hash : <EOL> return False <EOL> if self . election_uuid != election . uuid : <EOL> return False <EOL> for question_num in range ( len ( election . questions ) ) : <EOL> ea = self . encrypted_answers [ question_num ] <EOL> question = election . questions [ question_num ] <EOL> min_answers = <NUM_LIT:0> <EOL> if question . has_key ( '<STR_LIT>' ) : <EOL> min_answers = question [ '<STR_LIT>' ] <EOL> if not ea . verify ( election . public_key , min = min_answers , max = question [ '<STR_LIT>' ] ) : <EOL> return False <EOL> return True <EOL> def get_hash ( self ) : <EOL> return utils . hash_b64 ( utils . to_json ( self . toJSONDict ( ) ) ) <EOL> def toJSONDict ( self , with_randomness = False ) : <EOL> return { <EOL> '<STR_LIT>' : [ a . toJSONDict ( with_randomness ) for a in self . encrypted_answers ] , <EOL> '<STR_LIT>' : self . election_hash , <EOL> '<STR_LIT>' : self . election_uuid <EOL> } <EOL> @ classmethod <EOL> def fromJSONDict ( cls , d , pk = None ) : <EOL> ev = cls ( ) <EOL> ev . encrypted_answers = [ EncryptedAnswer . fromJSONDict ( ea , pk ) for ea in d [ '<STR_LIT>' ] ] <EOL> ev . election_hash = d [ '<STR_LIT>' ] <EOL> ev . election_uuid = d [ '<STR_LIT>' ] <EOL> return ev <EOL> @ classmethod <EOL> def fromElectionAndAnswers ( cls , election , answers ) : <EOL> pk = election . public_key <EOL> encrypted_answers = [ EncryptedAnswer . fromElectionAndAnswer ( election , answer_num , answers [ answer_num ] ) for answer_num in range ( len ( answers ) ) ] <EOL> return cls ( encrypted_answers = encrypted_answers , election_hash = election . hash , election_uuid = election . uuid ) <EOL> def one_question_winner ( question , result , num_cast_votes ) : <EOL> """<STR_LIT>""" <EOL> counts = sorted ( enumerate ( result ) , key = lambda ( x ) : x [ <NUM_LIT:1> ] ) <EOL> counts . reverse ( ) <EOL> if question [ '<STR_LIT>' ] > <NUM_LIT:1> : <EOL> return [ c [ <NUM_LIT:0> ] for c in counts [ : question [ '<STR_LIT>' ] ] ] <EOL> if question [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> if counts [ <NUM_LIT:0> ] [ <NUM_LIT:1> ] >= ( num_cast_votes / <NUM_LIT:2> + <NUM_LIT:1> ) : <EOL> return [ counts [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] ] <EOL> else : <EOL> return [ ] <EOL> if question [ '<STR_LIT>' ] == '<STR_LIT>' : <EOL> return [ counts [ <NUM_LIT:0> ] [ <NUM_LIT:0> ] ] <EOL> class Election ( HeliosObject ) : <EOL> FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT:description>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:result>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> JSON_FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT>' , '<STR_LIT:description>' , '<STR_LIT>' , '<STR_LIT>' , <EOL> '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def init_tally ( self ) : <EOL> return Tally ( election = self ) <EOL> def _process_value_in ( self , field_name , field_value ) : <EOL> if field_name == '<STR_LIT>' or field_name == '<STR_LIT>' or field_name == '<STR_LIT>' : <EOL> if type ( field_value ) == str or type ( field_value ) == unicode : <EOL> return datetime . datetime . strptime ( field_value , '<STR_LIT>' ) <EOL> if field_name == '<STR_LIT>' : <EOL> return algs . EGPublicKey . fromJSONDict ( field_value ) <EOL> if field_name == '<STR_LIT>' : <EOL> return algs . EGSecretKey . fromJSONDict ( field_value ) <EOL> def _process_value_out ( self , field_name , field_value ) : <EOL> if field_name == '<STR_LIT>' or field_name == '<STR_LIT>' or field_name == '<STR_LIT>' : <EOL> return str ( field_value ) <EOL> if field_name == '<STR_LIT>' or field_name == '<STR_LIT>' : <EOL> return field_value . toJSONDict ( ) <EOL> @ property <EOL> def registration_status_pretty ( self ) : <EOL> if self . openreg : <EOL> return "<STR_LIT>" <EOL> else : <EOL> return "<STR_LIT>" <EOL> @ property <EOL> def winners ( self ) : <EOL> """<STR_LIT>""" <EOL> return [ one_question_winner ( self . questions [ i ] , self . result [ i ] , self . num_cast_votes ) for i in range ( len ( self . questions ) ) ] <EOL> @ property <EOL> def pretty_result ( self ) : <EOL> if not self . result : <EOL> return None <EOL> winners = self . winners <EOL> raw_result = self . result <EOL> prettified_result = [ ] <EOL> for i in range ( len ( self . questions ) ) : <EOL> q = self . questions [ i ] <EOL> pretty_question = [ ] <EOL> for j in range ( len ( q [ '<STR_LIT>' ] ) ) : <EOL> a = q [ '<STR_LIT>' ] [ j ] <EOL> count = raw_result [ i ] [ j ] <EOL> pretty_question . append ( { '<STR_LIT>' : a , '<STR_LIT:count>' : count , '<STR_LIT>' : ( j in winners [ i ] ) } ) <EOL> prettified_result . append ( { '<STR_LIT>' : q [ '<STR_LIT>' ] , '<STR_LIT>' : pretty_question } ) <EOL> return prettified_result <EOL> class Voter ( HeliosObject ) : <EOL> """<STR_LIT>""" <EOL> FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:name>' , '<STR_LIT>' ] <EOL> JSON_FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:name>' ] <EOL> ALIASED_VOTER_JSON_FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def toJSONDict ( self ) : <EOL> fields = None <EOL> if self . alias != None : <EOL> return super ( Voter , self ) . toJSONDict ( self . ALIASED_VOTER_JSON_FIELDS ) <EOL> else : <EOL> return super ( Voter , self ) . toJSONDict ( ) <EOL> @ property <EOL> def voter_id_hash ( self ) : <EOL> if self . voter_login_id : <EOL> return utils . hash_b64 ( self . voter_login_id ) <EOL> else : <EOL> return utils . hash_b64 ( self . voter_id ) <EOL> class Trustee ( HeliosObject ) : <EOL> """<STR_LIT>""" <EOL> FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT:email>' ] <EOL> def _process_value_in ( self , field_name , field_value ) : <EOL> if field_name == '<STR_LIT>' : <EOL> return algs . EGPublicKey . fromJSONDict ( field_value ) <EOL> if field_name == '<STR_LIT>' : <EOL> return algs . DLogProof . fromJSONDict ( field_value ) <EOL> def _process_value_out ( self , field_name , field_value ) : <EOL> if field_name == '<STR_LIT>' or field_name == '<STR_LIT>' : <EOL> return field_value . toJSONDict ( ) <EOL> class CastVote ( HeliosObject ) : <EOL> """<STR_LIT>""" <EOL> FIELDS = [ '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( CastVote , self ) . __init__ ( * args , ** kwargs ) <EOL> self . election = None <EOL> @ classmethod <EOL> def fromJSONDict ( cls , d , election = None ) : <EOL> o = cls ( ) <EOL> o . election = election <EOL> o . set_from_args ( ** d ) <EOL> return o <EOL> def toJSONDict ( self , include_vote = True ) : <EOL> result = super ( CastVote , self ) . toJSONDict ( ) <EOL> if not include_vote : <EOL> del result [ '<STR_LIT>' ] <EOL> return result <EOL> @ classmethod <EOL> def fromOtherObject ( cls , o , election ) : <EOL> obj = cls ( ) <EOL> obj . election = election <EOL> obj . set_from_other_object ( o ) <EOL> return obj <EOL> def _process_value_in ( self , field_name , field_value ) : <EOL> if field_name == '<STR_LIT>' : <EOL> if type ( field_value ) == str : <EOL> return datetime . datetime . strptime ( field_value , '<STR_LIT>' ) <EOL> if field_name == '<STR_LIT>' : <EOL> return EncryptedVote . fromJSONDict ( field_value , self . election . public_key ) <EOL> def _process_value_out ( self , field_name , field_value ) : <EOL> if field_name == '<STR_LIT>' : <EOL> return str ( field_value ) <EOL> if field_name == '<STR_LIT>' : <EOL> return field_value . toJSONDict ( ) <EOL> def issues ( self , election ) : <EOL> """<STR_LIT>""" <EOL> issues = [ ] <EOL> if self . vote . election_uuid != election . uuid : <EOL> issues . append ( "<STR_LIT>" ) <EOL> return issues <EOL> class DLogTable ( object ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , base , modulus ) : <EOL> self . dlogs = { } <EOL> self . dlogs [ <NUM_LIT:1> ] = <NUM_LIT:0> <EOL> self . last_dlog_result = <NUM_LIT:1> <EOL> self . counter = <NUM_LIT:0> <EOL> self . base = base <EOL> self . modulus = modulus <EOL> def increment ( self ) : <EOL> self . counter += <NUM_LIT:1> <EOL> new_value = ( self . last_dlog_result * self . base ) % self . modulus <EOL> self . dlogs [ new_value ] = self . counter <EOL> self . last_dlog_result = new_value <EOL> def precompute ( self , up_to ) : <EOL> while self . counter < up_to : <EOL> self . increment ( ) <EOL> def lookup ( self , value ) : <EOL> return self . dlogs . get ( value , None ) <EOL> class Tally ( HeliosObject ) : <EOL> """<STR_LIT>""" <EOL> FIELDS = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> JSON_FIELDS = [ '<STR_LIT>' , '<STR_LIT>' ] <EOL> def __init__ ( self , * args , ** kwargs ) : <EOL> super ( Tally , self ) . __init__ ( * args , ** kwargs ) <EOL> self . election = kwargs . get ( '<STR_LIT>' , None ) <EOL> if self . election : <EOL> self . init_election ( self . election ) <EOL> else : <EOL> self . questions = None <EOL> self . public_key = None <EOL> if not self . tally : <EOL> self . tally = None <EOL> if self . num_tallied == None : <EOL> self . num_tallied = <NUM_LIT:0> <EOL> def init_election ( self , election ) : <EOL> """<STR_LIT>""" <EOL> self . questions = election . questions <EOL> self . public_key = election . public_key <EOL> if not self . tally : <EOL> self . tally = [ [ <NUM_LIT:0> for a in q [ '<STR_LIT>' ] ] for q in self . questions ] <EOL> def add_vote_batch ( self , encrypted_votes , verify_p = True ) : <EOL> """<STR_LIT>""" <EOL> for vote in encrypted_votes : <EOL> self . add_vote ( vote , verify_p ) <EOL> def add_vote ( self , encrypted_vote , verify_p = True ) : <EOL> if verify_p : <EOL> if not encrypted_vote . verify ( self . election ) : <EOL> raise Exception ( '<STR_LIT>' ) <EOL> for question_num in range ( len ( self . questions ) ) : <EOL> question = self . questions [ question_num ] <EOL> answers = question [ '<STR_LIT>' ] <EOL> for answer_num in range ( len ( answers ) ) : <EOL> enc_vote_choice = encrypted_vote . encrypted_answers [ question_num ] . choices [ answer_num ] <EOL> enc_vote_choice . pk = self . public_key <EOL> self . tally [ question_num ] [ answer_num ] = encrypted_vote . encrypted_answers [ question_num ] . choices [ answer_num ] * self . tally [ question_num ] [ answer_num ] <EOL> self . num_tallied += <NUM_LIT:1> <EOL> def decryption_factors_and_proofs ( self , sk ) : <EOL> """<STR_LIT>""" <EOL> decryption_factors = [ ] <EOL> decryption_proof = [ ] <EOL> for question_num , question in enumerate ( self . questions ) : <EOL> answers = question [ '<STR_LIT>' ] <EOL> question_factors = [ ] <EOL> question_proof = [ ] <EOL> for answer_num , answer in enumerate ( answers ) : <EOL> dec_factor , proof = sk . decryption_factor_and_proof ( self . tally [ question_num ] [ answer_num ] ) <EOL> question_factors . append ( str ( dec_factor ) ) <EOL> question_proof . append ( proof . toJSONDict ( ) ) <EOL> decryption_factors . append ( question_factors ) <EOL> decryption_proof . append ( question_proof ) <EOL> return decryption_factors , decryption_proof <EOL> def decrypt_and_prove ( self , sk , discrete_logs = None ) : <EOL> """<STR_LIT>""" <EOL> if not discrete_logs : <EOL> discrete_logs = self . discrete_logs <EOL> decrypted_tally = [ ] <EOL> decryption_proof = [ ] <EOL> for question_num in range ( len ( self . questions ) ) : <EOL> question = self . questions [ question_num ] <EOL> answers = question [ '<STR_LIT>' ] <EOL> question_tally = [ ] <EOL> question_proof = [ ] <EOL> for answer_num in range ( len ( answers ) ) : <EOL> plaintext , proof = sk . prove_decryption ( self . tally [ question_num ] [ answer_num ] ) <EOL> question_tally . append ( discrete_logs [ plaintext ] ) <EOL> question_proof . append ( proof ) <EOL> decrypted_tally . append ( question_tally ) <EOL> decryption_proof . append ( question_proof ) <EOL> return decrypted_tally , decryption_proof <EOL> def verify_decryption_proofs ( self , decryption_factors , decryption_proofs , public_key , challenge_generator ) : <EOL> """<STR_LIT>""" <EOL> for q_num , q in enumerate ( self . tally ) : <EOL> for a_num , answer_tally in enumerate ( q ) : <EOL> proof = algs . EGZKProof . fromJSONDict ( decryption_proofs [ q_num ] [ a_num ] ) <EOL> if not proof . verify ( public_key . g , answer_tally . alpha , public_key . y , int ( decryption_factors [ q_num ] [ a_num ] ) , public_key . p , public_key . q , challenge_generator ) : <EOL> return False <EOL> return True <EOL> def decrypt_from_factors ( self , decryption_factors , public_key ) : <EOL> """<STR_LIT>""" <EOL> dlog_table = DLogTable ( base = public_key . g , modulus = public_key . p ) <EOL> dlog_table . precompute ( self . num_tallied ) <EOL> result = [ ] <EOL> for q_num , q in enumerate ( self . tally ) : <EOL> q_result = [ ] <EOL> for a_num , a in enumerate ( q ) : <EOL> dec_factor_list = [ df [ q_num ] [ a_num ] for df in decryption_factors ] <EOL> raw_value = self . tally [ q_num ] [ a_num ] . decrypt ( dec_factor_list , public_key ) <EOL> q_result . append ( dlog_table . lookup ( raw_value ) ) <EOL> result . append ( q_result ) <EOL> return result <EOL> def _process_value_in ( self , field_name , field_value ) : <EOL> if field_name == '<STR_LIT>' : <EOL> return [ [ algs . EGCiphertext . fromJSONDict ( a ) for a in q ] for q in field_value ] <EOL> def _process_value_out ( self , field_name , field_value ) : <EOL> if field_name == '<STR_LIT>' : <EOL> return [ [ a . toJSONDict ( ) for a in q ] for q in field_value ] </s>
