-
Notifications
You must be signed in to change notification settings - Fork 105
Description
Is there an existing issue for this?
- I have searched the existing issues
Current Behavior
CiphertextTallySelection defines its ciphertext field with a default instance:
ciphertext: ElGamalCiphertext = field(
default=ElGamalCiphertext(ONE_MOD_P, ONE_MOD_P)
)This means the default ElGamalCiphertext object is created once at class definition time and then shared across all CiphertextTallySelection instances that do not receive an explicit ciphertext value.
As a result, multiple tally selections can unintentionally reference the same default ciphertext object. Any in-place mutation of that object can leak across instances.
This pattern also causes Python 3.11+ dataclass validation to fail because mutable defaults must be provided through default_factory.
Expected Behavior
Each CiphertextTallySelection should receive its own ElGamalCiphertext instance initialized at instance initialization, and not at class definition (thanks to default_factory instead of default).
The default value should represent the same initial ciphertext content for every instance, but it should not be the same shared object in memory.
Using a per-instance default avoids unintended shared state and keeps the field compatible with Python 3.11+ dataclass validation rules.
Steps To Reproduce
- Create two
CiphertextTallySelectioninstances without passing an explicitciphertext:
from electionguard.tally import CiphertextTallySelection
from electionguard.group import ONE_MOD_Q, TWO_MOD_P
first = CiphertextTallySelection("selection-1", 1, ONE_MOD_Q)
second = CiphertextTallySelection("selection-2", 2, ONE_MOD_Q)- Observe that both instances share the same default object:
print(first.ciphertext is second.ciphertext)- Mutate the ciphertext of one instance in place:
first.ciphertext.pad = TWO_MOD_P- Observe that the mutation is visible from the second instance as well:
print(second.ciphertext.pad == TWO_MOD_P)- On Python 3.11+, importing
electionguardwill raise an error, making the lib unusable:
ValueError: mutable default <class 'electionguard.elgamal.ElGamalCiphertext'> for field ciphertext is not allowed: use default_factory
Environment
- OS: Windows 11Anything else?
https://docs.python.org/3/library/dataclasses.html#mutable-default-values