Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
593343a
Refactor code for new PolynomialCoefficients class
Brites101 Oct 13, 2021
7631ef9
Refactor code for new PolynomialCoefficients class
Brites101 Oct 13, 2021
d74c8f9
fixed typo in the filepath to run tests
Brites101 Oct 13, 2021
f819722
removed unsed import
Brites101 Oct 13, 2021
8364602
added methods to access commiment and proof
Brites101 Oct 20, 2021
66ba927
Merge branch 'refactor-polynomialcoefficients' of https://github.com/…
Brites101 Oct 20, 2021
51fdeb3
Update election_polynomial.py
Brites101 Oct 20, 2021
b9969aa
Merge branch 'main' into refactor-polynomialcoefficients
keithrfung Oct 20, 2021
4f39f7e
fixed method calls and tests
Brites101 Oct 20, 2021
d93d279
Merge branch 'refactor-polynomialcoefficients' of https://github.com/…
Brites101 Oct 20, 2021
229a71c
Update election_polynomial.py
Brites101 Oct 20, 2021
e41fe1f
Update test_election_polynomial.py
Brites101 Oct 20, 2021
45bcc6d
Update __init__.py
Brites101 Oct 20, 2021
9b52466
Update election_polynomial.py
Brites101 Oct 20, 2021
da02172
Update __init__.py
Brites101 Oct 20, 2021
2d53e0b
Update election_polynomial.py
Brites101 Oct 20, 2021
b4578f9
refactor test_compute_polynomial_coordinate
Brites101 Oct 21, 2021
ed89b89
Merge branch 'refactor-polynomialcoefficients' of https://github.com/…
Brites101 Oct 21, 2021
a8bd044
refactor test_compute_polynomial_coordinate
Brites101 Oct 21, 2021
9e849fb
removed trailing whitespaces
Brites101 Oct 25, 2021
6a23f71
addded missing imports
Brites101 Oct 28, 2021
c8d2feb
black formatting
Brites101 Oct 31, 2021
3519fd0
Merge branch 'main' into refactor-polynomialcoefficients
Brites101 Oct 31, 2021
ea75e76
Update election_polynomial.py
Brites101 Nov 1, 2021
74752a7
✅ Fix linting
keithrfung Nov 3, 2021
ce88c01
📝 Fix plural to singular
keithrfung Nov 4, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/electionguard/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,7 @@
sequence_order_sort,
)
from electionguard.election_polynomial import (
Coefficient,
ElectionPolynomial,
LagrangeCoefficientsRecord,
PublicCommitment,
Expand Down Expand Up @@ -409,6 +410,7 @@
"CiphertextTally",
"CiphertextTallyContest",
"CiphertextTallySelection",
"Coefficient",
"CompactPlaintextBallot",
"CompactSubmittedBallot",
"CompensatedDecryptionShare",
Expand Down
50 changes: 32 additions & 18 deletions src/electionguard/election_polynomial.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,22 @@
PublicCommitment = ElementModP # Public commitment of election polynomial


@dataclass
class Coefficient:
"""
A coefficient of an Election Polynomial
"""

value: SecretCoefficient
"""The secret coefficient `a_ij` """

commitment: PublicCommitment
"""The public key `K_ij` generated from secret coefficient"""

proof: SchnorrProof
"""A proof of possession of the private key for the secret coefficient"""


@dataclass
class ElectionPolynomial:
"""
Expand All @@ -31,14 +47,16 @@ class ElectionPolynomial:
be discovered by a quorum of n guardians corresponding to n coefficients.
"""

coefficients: List[SecretCoefficient]
"""The secret coefficients `a_ij` """
coefficients: List[Coefficient]
"""List of coefficient value, commitments and proofs"""

coefficient_commitments: List[PublicCommitment]
"""The public keys `K_ij`generated from secret coefficients"""
def get_commitments(self) -> List[PublicCommitment]:
"""Access the list of public keys generated from secret coefficient"""
return [coefficient.commitment for coefficient in self.coefficients]

coefficient_proofs: List[SchnorrProof]
"""A proof of posession of the private key for each secret coefficient"""
def get_proofs(self) -> List[SchnorrProof]:
"""Access the list of proof of possesion of the private key for the secret coefficient"""
return [coefficient.proof for coefficient in self.coefficients]


def generate_polynomial(
Expand All @@ -51,23 +69,19 @@ def generate_polynomial(
:param nonce: an optional nonce parameter that may be provided (useful for testing)
:return: Polynomial used to share election keys
"""
coefficients: List[SecretCoefficient] = []
commitments: List[PublicCommitment] = []
proofs: List[SchnorrProof] = []
coefficients: List[Coefficient] = []

for i in range(number_of_coefficients):
# Note: the nonce value is not safe. it is designed for testing only.
# Note: the nonce value is not safe. it is designed for testing only.
# this method should be called without the nonce in production.
coefficient = add_q(nonce, i) if nonce is not None else rand_q()
commitment = g_pow_p(coefficient)
value = add_q(nonce, i) if nonce is not None else rand_q()
commitment = g_pow_p(value)
proof = make_schnorr_proof(
ElGamalKeyPair(coefficient, commitment), rand_q()
ElGamalKeyPair(value, commitment), rand_q()
) # TODO Alternate schnoor proof method that doesn't need KeyPair

coefficient = Coefficient(value, commitment, proof)
coefficients.append(coefficient)
commitments.append(commitment)
proofs.append(proof)
return ElectionPolynomial(coefficients, commitments, proofs)
return ElectionPolynomial(coefficients)


def compute_polynomial_coordinate(
Expand All @@ -86,7 +100,7 @@ def compute_polynomial_coordinate(
computed_value = ZERO_MOD_Q
for (i, coefficient) in enumerate(polynomial.coefficients):
exponent = pow_q(exponent_modifier, i)
factor = mult_q(coefficient, exponent)
factor = mult_q(coefficient.value, exponent)
computed_value = add_q(computed_value, factor)
return computed_value

Expand Down
10 changes: 5 additions & 5 deletions src/electionguard/key_ceremony.py
Original file line number Diff line number Diff line change
Expand Up @@ -91,8 +91,8 @@ def share(self) -> ElectionPublicKey:
self.owner_id,
self.sequence_order,
self.key_pair.public_key,
self.polynomial.coefficient_commitments,
self.polynomial.coefficient_proofs,
self.polynomial.get_commitments(),
self.polynomial.get_proofs(),
)


Expand Down Expand Up @@ -217,7 +217,7 @@ def generate_election_key_pair(
"""
polynomial = generate_polynomial(quorum, nonce)
key_pair = ElGamalKeyPair(
polynomial.coefficients[0], polynomial.coefficient_commitments[0]
polynomial.coefficients[0].value, polynomial.coefficients[0].commitment
)
return ElectionKeyPair(guardian_id, sequence_order, key_pair, polynomial)

Expand Down Expand Up @@ -301,8 +301,8 @@ def generate_election_partial_key_challenge(
backup.designated_id,
backup.designated_sequence_order,
compute_polynomial_coordinate(backup.designated_sequence_order, polynomial),
polynomial.coefficient_commitments,
polynomial.coefficient_proofs,
polynomial.get_commitments(),
polynomial.get_proofs(),
)


Expand Down
19 changes: 13 additions & 6 deletions tests/unit/test_election_polynomial.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from tests.base_test_case import BaseTestCase

from electionguard.schnorr import make_schnorr_proof
from electionguard.elgamal import ElGamalKeyPair
from electionguard.group import rand_q
from electionguard.election_polynomial import (
Coefficient,
compute_polynomial_coordinate,
ElectionPolynomial,
generate_polynomial,
Expand All @@ -24,13 +27,17 @@ def test_generate_polynomial(self):
self.assertIsNotNone(polynomial)

def test_compute_polynomial_coordinate(self):
# create proofs
proof_one = make_schnorr_proof(ElGamalKeyPair(ONE_MOD_Q, ONE_MOD_P), rand_q())
proof_two = make_schnorr_proof(ElGamalKeyPair(TWO_MOD_Q, TWO_MOD_P), rand_q())

# Arrange
polynomial = ElectionPolynomial(
[ONE_MOD_Q, TWO_MOD_Q],
[ONE_MOD_P, TWO_MOD_P],
[],
[
Coefficient(ONE_MOD_Q, ONE_MOD_P, proof_one),
Coefficient(TWO_MOD_Q, TWO_MOD_P, proof_two),
]
)

# Act
value = compute_polynomial_coordinate(TEST_EXPONENT_MODIFIER, polynomial)

Expand All @@ -47,6 +54,6 @@ def test_verify_polynomial_coordinate(self):
# Assert
self.assertTrue(
verify_polynomial_coordinate(
value, TEST_EXPONENT_MODIFIER, polynomial.coefficient_commitments
value, TEST_EXPONENT_MODIFIER, polynomial.get_commitments()
)
)
10 changes: 4 additions & 6 deletions tests/unit/test_key_ceremony.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,10 @@ def test_generate_election_key_pair(self):
self.assertIsNotNone(election_key_pair.key_pair.public_key)
self.assertIsNotNone(election_key_pair.key_pair.secret_key)
self.assertIsNotNone(election_key_pair.polynomial)
self.assertEqual(
len(election_key_pair.polynomial.coefficient_commitments), QUORUM
)
self.assertEqual(len(election_key_pair.polynomial.coefficient_proofs), QUORUM)
for proof in election_key_pair.polynomial.coefficient_proofs:
self.assertTrue(proof.is_valid())

self.assertEqual(len(election_key_pair.polynomial.coefficients), QUORUM)
for coefficient in election_key_pair.polynomial.coefficients:
self.assertTrue(coefficient.proof.is_valid())

def test_generate_election_partial_key_backup(self):
# Arrange
Expand Down