Пример #1
0
 def __init__(self, **kwargs):
     self.email_key = str(uuid4())
     keypair = keygen(threshold=1, n_shares=1, n_bits=32)
     self.public_key = keypair[0]
     self.private_key_ring = keypair[1]
     for key, value in kwargs.items():
         setattr(self, key, value)
Пример #2
0
    def test_01(self):
        """The test from the paper"""
        public_key, private_key_ring = keygen(n_bits=64,
                                              s=3,
                                              threshold=5,
                                              n_shares=9)

        candidates = [1, 2, 3]

        ballots = [
            CandidateOrderBallot(candidates, public_key.encrypt_list([3, 1,
                                                                      2]),
                                 public_key.encrypt(8))
        ]
        for_elimination = {3}
        eliminated = eliminate_candidate_set(for_elimination, ballots,
                                             private_key_ring, public_key)

        self.assertEqual(
            len(ballots), len(eliminated),
            "The number of ballots must stay the same after elimination")

        self.assertListEqual(
            [1, 2], eliminated[0].candidates,
            "The remaining candidates must be the not eliminated")

        self.assertListEqual([2, 1],
                             private_key_ring.decrypt_list(
                                 eliminated[0].preferences),
                             "Preferences must be right")

        self.assertEqual(8, private_key_ring.decrypt(eliminated[0].weight),
                         "Weight must be right")
Пример #3
0
    def test_01(self):
        """Test from the paper"""
        public_key, private_key_ring = keygen(n_bits=64,
                                              s=3,
                                              threshold=5,
                                              n_shares=9)

        candidates = [1, 2, 3]
        ballots = [
            CandidateOrderBallot(candidates, public_key.encrypt_list([3, 1,
                                                                      2]),
                                 public_key.encrypt(1))
        ]

        fpb, tallies = compute_first_preference_tallies(
            ballots, private_key_ring, public_key)

        self.assertListEqual([0, 1, 0], tallies, "The right tally counts")

        self.assertEqual(
            1, len(fpb),
            "The number of ballots must stay the same after computation")

        self.assertListEqual(candidates, fpb[0].candidates,
                             "The right candidates")
        self.assertListEqual([0, 1, 0],
                             private_key_ring.decrypt_list(fpb[0].weights),
                             "Weight 1 for first preference, 0 otherwise")
Пример #4
0
    def test_01(self):
        """Same as TestComputeFirstPreferenceTallies::test_03"""
        public_key, private_key_ring = keygen(n_bits=64,
                                              s=3,
                                              threshold=5,
                                              n_shares=9)

        candidates = [0, 1, 2, 3, 4, 5]

        ballots = [
            FirstPreferenceBallot(candidates,
                                  public_key.encrypt_list([0, 3, 4, 2, 1, 5]),
                                  public_key.encrypt_list([8, 0, 0, 0, 0, 0])),
            FirstPreferenceBallot(candidates,
                                  public_key.encrypt_list([4, 2, 3, 5, 0, 1]),
                                  public_key.encrypt_list([0, 0, 0, 0, 10,
                                                           0])),
            FirstPreferenceBallot(candidates,
                                  public_key.encrypt_list([5, 3, 0, 4, 2, 1]),
                                  public_key.encrypt_list([0, 0, 10, 0, 0,
                                                           0])),
            FirstPreferenceBallot(candidates,
                                  public_key.encrypt_list([3, 2, 4, 5, 0, 1]),
                                  public_key.encrypt_list([0, 0, 0, 0, 2, 0])),
            FirstPreferenceBallot(candidates,
                                  public_key.encrypt_list([2, 4, 3, 0, 1, 5]),
                                  public_key.encrypt_list([0, 0, 0, 2, 0, 0])),
        ]

        tallies = [8, 0, 10, 2, 12, 0]
        q = 5
        elected = {0, 2, 4}
        cobs, d_lcm = reweight_votes(ballots, elected, q, tallies, public_key)

        self.assertEqual(120, d_lcm, "The right lowest common multiple")
        self.assertEqual(
            len(ballots), len(cobs),
            "The number of ballots must stay the same after computation")

        cand_f = [45, 120, 60, 120, 70, 120]  # factors for each candidate

        # weights must be equal to the original weight multiplied by the weight factor for the candidate that was the
        # first preference in that ballot
        expected_weights = [
            8 * cand_f[0], 10 * cand_f[4], 10 * cand_f[2], 2 * cand_f[4],
            2 * cand_f[3]
        ]

        self.assertEqual(
            expected_weights,
            [private_key_ring.decrypt(cob.weight)
             for cob in cobs], "Weights must be right")
        for i in range(len(ballots)):
            self.assertListEqual(candidates, cobs[i].candidates,
                                 "The right candidates")
            self.assertListEqual(
                private_key_ring.decrypt_list(ballots[i].preferences),
                private_key_ring.decrypt_list(cobs[i].preferences),
                "The right preferences")
Пример #5
0
    def test_03(self):
        public_key, private_key_ring = keygen(n_bits=64,
                                              s=3,
                                              threshold=5,
                                              n_shares=9)

        candidates = [0, 1, 2, 3, 4, 5]

        ballots = [
            CandidateOrderBallot(candidates,
                                 public_key.encrypt_list([0, 3, 4, 2, 1, 5]),
                                 public_key.encrypt(8)),
            CandidateOrderBallot(candidates,
                                 public_key.encrypt_list([4, 2, 3, 5, 0, 1]),
                                 public_key.encrypt(10)),
            CandidateOrderBallot(candidates,
                                 public_key.encrypt_list([5, 3, 0, 4, 2, 1]),
                                 public_key.encrypt(10)),
            CandidateOrderBallot(candidates,
                                 public_key.encrypt_list([3, 2, 4, 5, 0, 1]),
                                 public_key.encrypt(2)),
            CandidateOrderBallot(candidates,
                                 public_key.encrypt_list([2, 4, 3, 0, 1, 5]),
                                 public_key.encrypt(2)),
        ]
        expected_tallies = [8, 0, 10, 2, 12, 0]

        fpb, tallies = compute_first_preference_tallies(
            ballots, private_key_ring, public_key)

        self.assertListEqual(expected_tallies, tallies,
                             "The right tally counts")

        self.assertEqual(
            len(ballots), len(fpb),
            "The number of ballots must stay the same after computation")

        for i in range(len(ballots)):
            self.assertListEqual(candidates, fpb[i].candidates,
                                 "The right candidates")

        self.assertListEqual([8, 0, 0, 0, 0, 0],
                             private_key_ring.decrypt_list(fpb[0].weights),
                             "Full weight for first preference, 0 otherwise")
        self.assertListEqual([0, 0, 0, 0, 10, 0],
                             private_key_ring.decrypt_list(fpb[1].weights),
                             "Full weight for first preference, 0 otherwise")
Пример #6
0
    def test_02(self):
        public_key, private_key_ring = keygen(n_bits=64,
                                              s=3,
                                              threshold=5,
                                              n_shares=9)

        candidates = [0, 1, 2, 3, 4, 5]

        ballots = [
            CandidateOrderBallot(candidates,
                                 public_key.encrypt_list([0, 3, 4, 2, 1, 5]),
                                 public_key.encrypt(8)),
            CandidateOrderBallot(candidates,
                                 public_key.encrypt_list([4, 2, 3, 5, 0, 1]),
                                 public_key.encrypt(4)),
        ]
        for_elimination = {0, 3, 4}
        eliminated = eliminate_candidate_set(for_elimination, ballots,
                                             private_key_ring, public_key)

        self.assertEqual(
            len(ballots), len(eliminated),
            "The number of ballots must stay the same after elimination")

        self.assertListEqual(
            [1, 2, 5], eliminated[0].candidates,
            "The remaining candidates must be the not eliminated")
        self.assertListEqual(
            [1, 2, 5], eliminated[1].candidates,
            "The remaining candidates must be the not eliminated")

        self.assertListEqual([0, 1, 2],
                             private_key_ring.decrypt_list(
                                 eliminated[0].preferences),
                             "Preferences must be right")
        self.assertListEqual([1, 2, 0],
                             private_key_ring.decrypt_list(
                                 eliminated[1].preferences),
                             "Preferences must be right")

        self.assertEqual(8, private_key_ring.decrypt(eliminated[0].weight),
                         "Weight must be right")
        self.assertEqual(4, private_key_ring.decrypt(eliminated[1].weight),
                         "Weight must be right")
Пример #7
0
    parser.add_argument('--n_shares', type=int, default=3,
                        help='The number of PrivateKeyShares to generate.')
    parser.add_argument('--no_encryption', action='store_true', default=False,
                        help='Run the election without encryption')
    parser.add_argument('--debug', action='store_true', default=False,
                        help='Whether to print debug statements')
    args = parser.parse_args()

    set_debug(args.debug)

    if args.no_encryption:
        public_key, private_key_ring = mock_keygen()
    else:
        public_key, private_key_ring = keygen(
            n_bits=args.n_bits,
            s=args.s,
            threshold=args.threshold,
            n_shares=args.n_shares
        )
    
    contest_id_to_contest = load_ballot_data(
        master_lookup_path=args.master_lookup,
        ballot_image_path=args.ballot_image,
        public_key=public_key
    )

    for contest_id, contest in contest_id_to_contest.items():
        print(f'Processing contest id = {contest_id}')

        num_candidates = len(contest['candidate_id_to_candidate_name'])
        print(f'Number of candidates = {num_candidates}')
        print(f'Number of voters = {len(contest["ballots"]):,}')
Пример #8
0
                candidate_id: candidate_id_to_candidate_name[candidate_id]
                for candidate_id in candidate_ids
            },
            'stop_candidate_id': stop_candidate_id
        }

    return contest_id_to_contest


if __name__ == '__main__':
    parser = ArgumentParser()
    parser.add_argument('--master_lookup',
                        type=str,
                        required=True,
                        help='Path to a .txt file containing a master lookup')
    parser.add_argument('--ballot_image',
                        type=str,
                        required=True,
                        help='Path to a .txt file containing a ballot image')
    args = parser.parse_args()

    public_key, private_key_shares = keygen(n_bits=32,
                                            s=3,
                                            threshold=4,
                                            n_shares=10)

    contest_id_to_contest = load_ballot_data(
        master_lookup_path=args.master_lookup,
        ballot_image_path=args.ballot_image,
        public_key=public_key)
Пример #9
0
    def test_02(self):
        public_key, private_key_ring = keygen(n_bits=64,
                                              s=3,
                                              threshold=5,
                                              n_shares=9)

        candidates = list(range(10))
        preferences = [[6, 8, 3, 2, 0, 9, 1, 4, 7, 5],
                       [9, 6, 7, 0, 5, 2, 3, 4, 8, 1],
                       [0, 5, 2, 9, 4, 8, 7, 6, 1, 3],
                       [3, 1, 2, 0, 9, 4, 7, 8, 6, 5],
                       [0, 5, 8, 6, 4, 3, 2, 9, 7, 1],
                       [0, 7, 3, 2, 9, 6, 8, 4, 5, 1],
                       [5, 0, 8, 1, 9, 6, 2, 7, 3, 4],
                       [5, 2, 6, 0, 1, 9, 4, 3, 8, 7],
                       [9, 6, 5, 3, 4, 7, 1, 8, 2, 0],
                       [3, 8, 5, 4, 6, 2, 0, 7, 9, 1],
                       [2, 5, 3, 7, 4, 1, 8, 6, 0, 9],
                       [5, 1, 8, 7, 6, 4, 2, 0, 9, 3],
                       [2, 1, 4, 7, 8, 9, 5, 0, 3, 6],
                       [2, 3, 6, 7, 9, 1, 4, 5, 0, 8],
                       [6, 2, 8, 7, 5, 4, 1, 3, 0, 9],
                       [3, 0, 7, 8, 9, 1, 4, 6, 2, 5],
                       [9, 8, 5, 0, 3, 4, 7, 6, 2, 1],
                       [5, 3, 7, 4, 1, 8, 9, 2, 6, 0],
                       [3, 5, 2, 7, 1, 8, 9, 0, 4, 6],
                       [0, 2, 8, 7, 5, 3, 1, 4, 9, 6],
                       [9, 3, 1, 5, 0, 6, 8, 4, 7, 2],
                       [4, 3, 5, 2, 7, 8, 9, 1, 6, 0],
                       [7, 3, 1, 5, 0, 6, 9, 2, 8, 4],
                       [4, 2, 7, 8, 3, 0, 1, 6, 5, 9],
                       [3, 2, 0, 9, 5, 1, 4, 7, 6, 8],
                       [7, 4, 3, 6, 9, 2, 1, 8, 0, 5],
                       [0, 8, 1, 6, 9, 7, 2, 3, 4, 5],
                       [1, 7, 9, 0, 6, 5, 8, 3, 4, 2],
                       [5, 7, 1, 3, 2, 4, 0, 6, 8, 9],
                       [7, 1, 3, 9, 4, 0, 6, 2, 8, 5],
                       [5, 3, 1, 8, 2, 0, 4, 6, 7, 9],
                       [7, 6, 0, 1, 4, 3, 9, 5, 8, 2],
                       [8, 4, 1, 6, 3, 2, 9, 5, 0, 7],
                       [9, 4, 6, 8, 7, 3, 5, 0, 1, 2],
                       [3, 5, 9, 6, 2, 1, 7, 8, 0, 4],
                       [7, 2, 8, 9, 0, 5, 4, 1, 6, 3],
                       [9, 1, 4, 3, 8, 6, 0, 2, 7, 5],
                       [7, 0, 5, 1, 4, 3, 8, 9, 6, 2],
                       [2, 8, 4, 1, 5, 3, 9, 7, 6, 0],
                       [4, 1, 2, 6, 7, 5, 9, 8, 0, 3],
                       [1, 2, 7, 3, 8, 4, 5, 6, 0, 9],
                       [2, 6, 8, 5, 4, 1, 7, 3, 9, 0],
                       [5, 2, 8, 0, 1, 7, 6, 9, 4, 3],
                       [6, 2, 1, 4, 3, 9, 8, 0, 5, 7],
                       [0, 2, 5, 7, 9, 4, 3, 8, 6, 1],
                       [0, 7, 8, 1, 2, 5, 4, 9, 3, 6],
                       [2, 9, 7, 4, 3, 0, 8, 1, 5, 6],
                       [4, 2, 6, 3, 5, 8, 0, 7, 1, 9],
                       [9, 4, 8, 0, 6, 2, 3, 7, 1, 5],
                       [4, 3, 0, 9, 1, 7, 2, 8, 5, 6],
                       [6, 4, 2, 3, 5, 0, 7, 9, 8, 1],
                       [0, 1, 4, 8, 2, 6, 3, 5, 7, 9],
                       [3, 9, 2, 8, 0, 5, 1, 4, 6, 7],
                       [2, 1, 4, 0, 3, 6, 7, 8, 5, 9],
                       [2, 8, 5, 7, 9, 3, 1, 4, 0, 6],
                       [2, 4, 3, 8, 1, 7, 0, 6, 9, 5],
                       [5, 6, 8, 7, 1, 2, 4, 9, 3, 0],
                       [8, 3, 0, 9, 6, 5, 4, 2, 1, 7],
                       [2, 3, 0, 7, 1, 5, 9, 4, 6, 8],
                       [0, 5, 6, 2, 8, 9, 3, 7, 1, 4],
                       [2, 7, 9, 6, 3, 5, 4, 8, 1, 0],
                       [3, 8, 5, 4, 6, 1, 0, 9, 2, 7],
                       [6, 4, 9, 3, 8, 2, 5, 0, 1, 7],
                       [3, 6, 5, 0, 7, 9, 1, 2, 4, 8],
                       [7, 9, 3, 8, 0, 6, 5, 2, 4, 1],
                       [2, 4, 6, 0, 5, 9, 1, 8, 7, 3],
                       [5, 3, 4, 6, 8, 9, 2, 7, 1, 0],
                       [8, 1, 7, 5, 2, 9, 6, 0, 4, 3],
                       [3, 1, 5, 6, 2, 7, 8, 4, 0, 9],
                       [3, 8, 4, 5, 9, 6, 7, 1, 2, 0],
                       [9, 6, 4, 2, 3, 1, 0, 8, 5, 7],
                       [5, 0, 7, 8, 1, 3, 9, 4, 2, 6],
                       [3, 6, 8, 5, 4, 9, 0, 1, 2, 7],
                       [8, 0, 6, 7, 1, 2, 3, 5, 9, 4],
                       [1, 5, 3, 9, 4, 7, 6, 0, 8, 2],
                       [6, 8, 9, 1, 5, 7, 4, 2, 0, 3],
                       [2, 1, 5, 0, 8, 3, 7, 9, 6, 4],
                       [0, 4, 7, 5, 8, 1, 6, 3, 2, 9],
                       [7, 6, 5, 3, 1, 0, 2, 9, 4, 8],
                       [3, 0, 8, 1, 5, 2, 7, 9, 4, 6],
                       [6, 9, 3, 8, 2, 7, 0, 5, 4, 1],
                       [5, 9, 7, 3, 2, 8, 1, 4, 6, 0],
                       [7, 0, 4, 3, 1, 2, 6, 9, 5, 8],
                       [6, 9, 3, 8, 4, 5, 2, 1, 0, 7],
                       [9, 7, 6, 8, 2, 5, 3, 4, 1, 0],
                       [6, 8, 1, 7, 2, 4, 5, 3, 9, 0],
                       [4, 6, 0, 1, 3, 9, 2, 8, 5, 7],
                       [7, 2, 8, 3, 4, 9, 5, 6, 0, 1],
                       [7, 3, 0, 8, 5, 1, 4, 6, 2, 9],
                       [8, 2, 7, 6, 3, 4, 9, 1, 5, 0],
                       [8, 3, 5, 7, 4, 2, 0, 9, 1, 6],
                       [3, 6, 5, 1, 8, 2, 0, 9, 7, 4],
                       [4, 9, 5, 8, 0, 1, 7, 6, 2, 3],
                       [4, 5, 9, 8, 2, 1, 0, 3, 6, 7],
                       [3, 2, 8, 9, 6, 5, 1, 0, 7, 4],
                       [6, 1, 4, 2, 5, 3, 7, 9, 0, 8],
                       [0, 5, 2, 3, 7, 6, 1, 4, 8, 9],
                       [9, 3, 4, 1, 5, 6, 7, 0, 2, 8],
                       [3, 0, 6, 7, 9, 2, 5, 8, 1, 4],
                       [0, 1, 5, 2, 7, 3, 9, 4, 6, 8]]
        tallies = [12, 8, 7, 11, 7, 6, 12, 10, 14, 13]
        ballots = [
            FirstPreferenceBallot(
                candidates, public_key.encrypt_list(prefs),
                public_key.encrypt_list(
                    [1 if pref == 0 else 0 for pref in prefs]))
            for prefs in preferences
        ]

        q = 12
        elected = {0, 6, 8}
        cobs, d_lcm = reweight_votes(ballots, elected, q, tallies, public_key)

        self.assertEqual(84, d_lcm, "The right lowest common multiple")
        self.assertEqual(
            len(ballots), len(cobs),
            "The number of ballots must stay the same after computation")

        cand_f = [0] + [84] * 5 + [0, 84, 12, 84]  # factors for each candidate

        # weights must be equal to the original weight (1 in this case for all ballots) multiplied by the weight factor
        # for the candidate that was the first preference in that ballot
        expected_weights = [cand_f[prefs.index(0)] for prefs in preferences]

        self.assertEqual(
            expected_weights,
            [private_key_ring.decrypt(cob.weight)
             for cob in cobs], "Weights must be right")
        for i in range(len(ballots)):
            self.assertListEqual(candidates, cobs[i].candidates,
                                 "The right candidates")
            self.assertListEqual(
                preferences[i],
                private_key_ring.decrypt_list(cobs[i].preferences),
                "The right preferences")
Пример #10
0
 def setUp(self):
     self.public_key, self.private_key_ring = keygen(n_bits=64,
                                                     s=3,
                                                     threshold=5,
                                                     n_shares=9)