Example #1
0
def verify(output_stream):
  # check that there are as many ballots in the P table as claimed
  assert len(p_table.rows) == election.num_ballots, "P Table has the wrong number of ballots, should be %s " % election.num_ballots

  num_d_tables = None

  # loop through partitions
  for p_id, partition in partitions.iteritems():
    this_num_d_tables = len(partition.values())
  
    # check that it's the same number of D tables
    if num_d_tables:
      assert this_num_d_tables == num_d_tables
    else:
      num_d_tables = this_num_d_tables
    
    # loop through d tables for that partition
    for d_table_id, d_table in partition.iteritems():
      # check that it has the right number of ballots
      assert len(d_table.rows) == election.num_ballots, "D Table %s in partition %s has the wrong number of ballots, should be %s" % (d_table_id, p_id, election.num_ballots)
    
  output_stream.write("""Election ID: %s
Meeting 1 Successful

%s Ballots
Partitions: %s
%s D-Tables

%s
""" % (election.spec.id, election.num_ballots, partitions.keys(), num_d_tables, base.fingerprint_report()))
def verify(output_stream, codes_output_stream=None):
  
  if codes_output_stream:
    codes_output_stream.write('Serial #,P-table ID')
    for q_id in sorted(contested_ballots.values()[0].questions.keys()):
      codes_output_stream.write(",question %s"%q_id)
    codes_output_stream.write("\n")    

  # for each contested ballot:
  for contested_ballot in contested_ballots.values():
    # is it a cast ballot?
    assert cast_ballots.has_key(contested_ballot.pid)
    
    # does it verify against the original ballots
    assert ballots[contested_ballot.pid].verify_code_openings(contested_ballot, election.constant)
    
    if codes_output_stream:
      codes_output_stream.write('%s,%s' % (contested_ballot.webSerial, contested_ballot.pid))
      for q_id in sorted(contested_ballot.questions.keys()):
        codes_output_stream.write(',"%s"' % ",".join([q['code'] for q in contested_ballot.questions[q_id].values()]))
      codes_output_stream.write("\n")
    
  # go through the contested ballots
  output_stream.write("""Election ID: %s
Contested Ballots Audit Successful

%s ballots contested and opened successfully

%s
""" % (election.spec.id, len(contested_ballots.keys()), base.fingerprint_report()))
Example #3
0
def verify(output_stream, codes_output_stream=None):
  # make sure none of the actual votes use ballots that were audited in Meeting2:
  assert set(p_table_votes.rows.keys()).isdisjoint(set(meeting2.challenge_row_ids))

  if codes_output_stream:
    BALLOTS = {}
    def new_code(webSerial, pid, q_id, s_id, confirmation_code):
      if not BALLOTS.has_key(webSerial):
        BALLOTS[webSerial] = {'pid': pid, 'questions': {}}
        
      if not BALLOTS[webSerial]['questions'].has_key(q_id):
        BALLOTS[webSerial]['questions'][q_id] = []
      
      BALLOTS[webSerial]['questions'][q_id].append(confirmation_code)
  else:
    new_code = None
  
  # check the openings
  for ballot_open in ballots_with_codes.values():
    ballot = ballots[ballot_open.pid]
    assert ballot.verify_code_openings(ballot_open, election.constant, code_callback_func = new_code)

    # check that the coded votes correspond to the confirmation code openings
    assert ballot_open.verify_encodings(election, p_table_votes)
    
  # we get the half-decrypted votes, but there's nothing to verify yet
  
  # we write out the codes
  if new_code:
    codes_output_stream.write('Serial #,P-table ID')
    for q_id in sorted(BALLOTS.values()[0]['questions'].keys()):
      codes_output_stream.write(",question %s"%q_id)
    codes_output_stream.write("\n")
    
    for serial in sorted(BALLOTS.keys()):
      codes_output_stream.write('%s,%s' % (serial, BALLOTS[serial]['pid']))
      for q_id in sorted(BALLOTS[serial]['questions'].keys()):
        codes_output_stream.write(',"%s"' % ",".join(BALLOTS[serial]['questions'][q_id]))
      codes_output_stream.write("\n")
    
  
  # we get the R table, and that can be tallied based on the type of question
  # however, just to separate the cryptographic verification from the actual
  # counting, which should be a lot simpler, the counting of the R table is done
  # in the tally.py program.
  
  output_stream.write("""Election ID: %s
Meeting 3 Successful

%s ballots cast

The tally can now be computed, not fully verified yet, using tally.py

%s
""" % (election.spec.id, len(ballots_with_codes), base.fingerprint_report()))
def verify(output_stream, codes_output_stream=None):

  if codes_output_stream:
    BALLOTS = {}
    def new_code(webSerial, pid, q_id, s_id, confirmation_code):
      if not BALLOTS.has_key(webSerial):
        BALLOTS[webSerial] = {'pid': pid, 'questions': {}}
        
      if not BALLOTS[webSerial]['questions'].has_key(q_id):
        BALLOTS[webSerial]['questions'][q_id] = []
      
      BALLOTS[webSerial]['questions'][q_id].append(confirmation_code)
  else:
    new_code = None

  # check codes
  for spoiled_ballot in spoiled_ballots.values():
    # does it verify against the original ballots
    assert ballots[spoiled_ballot.pid].verify_code_openings(spoiled_ballot, election.constant, code_callback_func = new_code)
  
  # we just verify that the D and P tables are opened properly
  # same as meeting2, only without a specific challenge set
  assert meeting2.verify_open_p_and_d_tables(election, meeting1.p_table, meeting1.partitions, spoiled_p_table, spoiled_partitions), "bad reveal of P and D tables"

  # we write out the codes
  if new_code:
    codes_output_stream.write('Serial #,P-table ID')
    for q_id in sorted(BALLOTS.values()[0]['questions'].keys()):
      codes_output_stream.write(",question %s"%q_id)
    codes_output_stream.write("\n")
    
    for serial in sorted(BALLOTS.keys()):
      codes_output_stream.write('%s,%s' % (serial, BALLOTS[serial]['pid']))
      for q_id in sorted(BALLOTS[serial]['questions'].keys()):
        codes_output_stream.write(',"%s"' % ",".join(BALLOTS[serial]['questions'][q_id]))
      codes_output_stream.write("\n")

  # go through the contested ballots
  output_stream.write("""Election ID: %s
Spoiled Ballots Audit Successful

%s ballots spoiled and opened successfully

%s
""" % (election.spec.id, len(spoiled_ballots.keys()), base.fingerprint_report()))
Example #5
0
def verify(output_stream):  
  p_table_permutations = {}
  
  # check the generation of the challenge rows
  # we assume that the length of the challenge list is the right one
  challenge_row_ids_ints = set([int(c) for c in challenge_row_ids])
  challenges_match_randomness = False
  seed = meeting_two_random_data + election.constant
  if challenge_row_ids_ints == set(base.generate_random_int_list(seed, election.num_ballots, len(challenge_row_ids))):
    challenges_match_randomness = True
  else:
    import pdb; pdb.set_trace()

  
  # check that the open P table rows match the challenge
  assert sorted(challenge_row_ids) == sorted([r['id'] for r in response_p_table.rows.values()]), "challenges don't match revealed row IDs in P table"
  
  # check that the P and D tables are properly revealed
  assert verify_open_p_and_d_tables(election, p_table, partitions, response_p_table, response_partitions), "bad reveal of P and D tables"
  
  print """Election ID: %s
Meeting 2 Successful

%s ballots challenged and answered successfully.

Challenges Match Randomness? %s

%s
""" % (election.spec.id, len(challenge_row_ids), str(challenges_match_randomness).upper(), base.fingerprint_report())
Example #6
0
def verify(output_stream):
  # verify that challenges are appropriately generated
  challenges_match_randomness = True
  
  # we assume that one D table always opens on the same side
  # we do a bit of an odd thing here to keep the partitions and d tables in order
  # because that's how counter is decided
  counter = 0
  
  # a dictionary of partition_ids, with values a dictionary of d_table ID
  expected_challenge_sides = {}
  
  seed = meeting_four_random_data + election.constant
  
  for p_id in sorted(cast_ballot_partitions.keys()):
    partition = cast_ballot_partitions[p_id]
    expected_challenge_sides[p_id] = {}
    
    # get the D tables ordered by their integer ID
    for d_table in data.sort_by_id(partition.values()):
      instance_id = d_table.id
      
      # which side is this d table opened on?
      expected_challenge_sides[p_id][instance_id] = ("LEFT","RIGHT")[base.prng(seed,counter,2)]
      counter += 1
  
  partition_map = election.partition_map
  partition_map_choices = election.partition_map_choices
  
  # go through the challenges and verify the corresponding commitments
  for p_id, partition in d_table_challenges.iteritems():
    for instance_id, d_table_challenge in partition.iteritems():
      
      d_table = d_table_commitments[p_id][instance_id]
      d_table_response = d_table_responses[p_id][instance_id]
      
      # check that the open rows now are disjoint from the open rows before
      assert set(d_table_challenge.rows.keys()).isdisjoint(set(already_open_d_tables[p_id][instance_id].rows.keys())), 'some challenges repeat the challenges from meeting2'
      
      # check opening of the new challenges
      for row in d_table_challenge.rows.values():
        # does it match the randomness?
        if row['side'] != expected_challenge_sides[p_id][instance_id]:
          import pdb; pdb.set_trace()
          challenges_match_randomness = False

        # response row
        response_row = d_table_response.rows[row['id']]
        # partially decrypted choices, d3 out of d2,d3,d4, so index 1.
        try:
          d_choices = cast_ballot_partitions[p_id][instance_id].get_permutations_by_row_id(row['id'], partition_map_choices[p_id])[1]
        except:
          import pdb; pdb.set_trace()
          print "oy"

        # check the appropriate side  
        if row['side'] == 'LEFT':
          # check proper reveal
          assert d_table.check_cl(p_id, instance_id, response_row, election.constant)
          
          d_left_perm = [data.Permutation(p) for p in d_table_response.get_permutations_by_row_id(row['id'], partition_map[p_id])[0]]

          # get the corresponding P3 permutation (index 2, then partition)
          p_choices = p_table_votes.get_permutations_by_row_id(response_row['pid'], partition_map_choices)[2][p_id]

          for q_num, p_choice in enumerate(p_choices):
            assert d_left_perm[q_num].permute_list(p_choice) == d_choices[q_num]
        else:
          # check reveal
          assert d_table.check_cr(p_id, instance_id, response_row, election.constant)
          
          # check right-hand permutation
          d_right_perm = [data.Permutation(p) for p in d_table_response.get_permutations_by_row_id(row['id'], partition_map[p_id])[2]]

          # get the corresponding R-table permutation (partition, then index 0)
          r_choices = r_tables_by_partition[p_id].get_permutations_by_row_id(response_row['rid'], partition_map_choices[p_id])[0]
          
          for q_num, r_choice in enumerate(r_choices):
            assert d_right_perm[q_num].permute_list(d_choices[q_num]) == r_choice        
    
  output_stream.write("""Election ID: %s
Meeting 4 Successful

Challenges Match Randomness? %s

%s
""" % (election.spec.id, challenges_match_randomness, base.fingerprint_report()))