Skip to content

Commit d1d4853

Browse files
authored
Merge branch 'main' into feature/ballot-decryption-functions
2 parents d537b29 + 46b5f6b commit d1d4853

3 files changed

Lines changed: 110 additions & 60 deletions

File tree

src/electionguard/key_ceremony.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class ElectionPartialKeyChallenge(NamedTuple):
131131
The sequence order of the designated guardian
132132
"""
133133

134-
value: int
134+
value: ElementModQ
135135
coefficient_commitments: List[ElementModP]
136136
coefficient_proofs: List[SchnorrProof]
137137

@@ -264,9 +264,7 @@ def generate_election_partial_key_challenge(
264264
backup.owner_id,
265265
backup.designated_id,
266266
backup.designated_sequence_order,
267-
compute_polynomial_coordinate(
268-
backup.designated_sequence_order, polynomial
269-
).to_int(),
267+
compute_polynomial_coordinate(backup.designated_sequence_order, polynomial),
270268
backup.coefficient_commitments,
271269
backup.coefficient_proofs,
272270
)
@@ -286,7 +284,7 @@ def verify_election_partial_key_challenge(
286284
challenge.designated_id,
287285
verifier_id,
288286
verify_polynomial_coordinate(
289-
get_optional(int_to_q(challenge.value)),
287+
challenge.value,
290288
challenge.designated_sequence_order,
291289
challenge.coefficient_commitments,
292290
),

src/electionguard/serializable.py

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from dataclasses import dataclass
22
from datetime import datetime
33
from os import path
4-
from typing import Any, cast, TypeVar, Generic
4+
from typing import Any, cast, Type, TypeVar
55

66
from jsons import (
77
dump,
@@ -17,6 +17,7 @@
1717
default_nonetype_deserializer,
1818
)
1919

20+
S = TypeVar("S", bound="Serializable")
2021
T = TypeVar("T")
2122

2223
JSON_FILE_EXTENSION: str = ".json"
@@ -28,7 +29,7 @@
2829

2930

3031
@dataclass
31-
class Serializable(Generic[T]):
32+
class Serializable:
3233
"""
3334
Serializable class with methods to convert to json
3435
"""
@@ -61,35 +62,29 @@ def to_json_file(
6162
write_json_file(self, file_name, file_path, strip_privates)
6263

6364
@classmethod
64-
def from_json(cls, data: str) -> T:
65+
def from_json(cls: Type[S], data: str) -> S:
6566
"""
6667
Deserialize the provided data string into the specified instance
6768
:param data: JSON string
6869
"""
69-
set_deserializers()
70-
return cast(T, loads(data, cls))
70+
return read_json(data, cls)
7171

7272
@classmethod
73-
def from_json_object(cls, data: object) -> T:
73+
def from_json_object(cls: Type[S], data: object) -> S:
7474
"""
7575
Deserialize the provided data object into the specified instance
7676
:param data: JSON object
7777
"""
78-
set_deserializers()
79-
return cast(T, load(data, cls))
78+
return read_json_object(data, cls)
8079

8180
@classmethod
82-
def from_json_file(cls, file_name: str, file_path: str = "") -> T:
81+
def from_json_file(cls: Type[S], file_name: str, file_path: str = "") -> S:
8382
"""
8483
Deserialize the provided file into the specified instance
8584
:param file_name: File name
8685
:param file_path: File path
8786
"""
88-
json_file_path: str = path.join(file_path, file_name + JSON_FILE_EXTENSION)
89-
with open(json_file_path, READ) as json_file:
90-
data = json_file.read()
91-
target = cls.from_json(data)
92-
return target
87+
return read_json_file(cls, file_name, file_path)
9388

9489

9590
def _remove_key(obj: Any, key_to_remove: str) -> Any:
@@ -169,6 +164,44 @@ def write_json_file(
169164
json_file.write(write_json(object_to_write, strip_privates))
170165

171166

167+
def read_json(data: Any, class_out: Type[T]) -> T:
168+
"""
169+
Deserialize json file to object
170+
:param data: Json file data
171+
:param class_out: Object type
172+
:return: Deserialized object
173+
"""
174+
set_deserializers()
175+
return cast(T, loads(data, class_out))
176+
177+
178+
def read_json_object(data: Any, class_out: Type[T]) -> T:
179+
"""
180+
Deserialize json file to object
181+
:param data: Json file data
182+
:param class_out: Object type
183+
:return: Deserialized object
184+
"""
185+
set_deserializers()
186+
return cast(T, load(data, class_out))
187+
188+
189+
def read_json_file(class_out: Type[T], file_name: str, file_path: str = "") -> T:
190+
"""
191+
Deserialize json file to object
192+
:param class_out: Object type
193+
:param file_name: File name
194+
:param file_path: File path
195+
:return: Deserialized object
196+
"""
197+
set_deserializers()
198+
json_file_path: str = path.join(file_path, file_name + JSON_FILE_EXTENSION)
199+
with open(json_file_path, READ) as json_file:
200+
data = json_file.read()
201+
target: T = read_json(data, class_out)
202+
return target
203+
204+
172205
def set_serializers() -> None:
173206
"""Set serializers for jsons to use to cast specific classes"""
174207

tests/test_serializable.py

Lines changed: 60 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,74 +1,93 @@
1+
from dataclasses import dataclass
12
from unittest import TestCase
3+
from typing import Any, List, Optional
24
from os import remove
35

46
from electionguard.serializable import (
57
set_deserializers,
68
set_serializers,
9+
read_json,
10+
read_json_file,
11+
read_json_object,
12+
write_json,
713
write_json_file,
814
write_json_object,
9-
write_json,
1015
)
1116

1217

18+
@dataclass
19+
class NestedModel:
20+
"""Nested model for testing"""
21+
22+
test: int
23+
from_json_file: Optional[Any] = None
24+
25+
26+
@dataclass
27+
class DataModel:
28+
"""Data model for testing"""
29+
30+
test: int
31+
nested: NestedModel
32+
array: List[NestedModel]
33+
from_json_file: Optional[Any] = None
34+
35+
36+
JSON_DATA: DataModel = DataModel(
37+
test=1, nested=NestedModel(test=1), array=[NestedModel(test=1)]
38+
)
39+
EXPECTED_JSON_STRING = '{"array": [{"test": 1}], "nested": {"test": 1}, "test": 1}'
40+
EXPECTED_JSON_OBJECT = {
41+
"test": 1,
42+
"nested": {"test": 1},
43+
"array": [{"test": 1}],
44+
}
45+
46+
1347
class TestSerializable(TestCase):
14-
def test_write_json(self) -> None:
15-
# Arrange
16-
json_data = {
17-
"from_json_file": {},
18-
"test": 1,
19-
"nested": {"from_json_file": {}, "test": 1},
20-
"array": [{"from_json_file": {}, "test": 1}],
21-
}
22-
expected_json_string = (
23-
'{"test": 1, "nested": {"test": 1}, "array": [{"test": 1}]}'
24-
)
48+
def test_read_and_write_json(self) -> None:
49+
# Act
50+
json_string = write_json(JSON_DATA)
51+
52+
# Assert
53+
self.assertEqual(json_string, EXPECTED_JSON_STRING)
2554

2655
# Act
27-
json_string = write_json(json_data)
56+
read_json_data = read_json(json_string, DataModel)
2857

2958
# Assert
30-
self.assertEqual(json_string, expected_json_string)
59+
self.assertEqual(read_json_data, JSON_DATA)
3160

32-
def test_write_json_object(self) -> None:
33-
# Arrange
34-
json_data = {
35-
"from_json_file": {},
36-
"test": 1,
37-
"nested": {"from_json_file": {}, "test": 1},
38-
"array": [{"from_json_file": {}, "test": 1}],
39-
}
40-
expected_json_object = {
41-
"test": 1,
42-
"nested": {"test": 1},
43-
"array": [{"test": 1}],
44-
}
61+
def test_read_and_write_json_object(self) -> None:
62+
# Act
63+
json_object = write_json_object(JSON_DATA)
64+
65+
# Assert
66+
self.assertEqual(json_object, EXPECTED_JSON_OBJECT)
4567

4668
# Act
47-
json_object = write_json_object(json_data)
69+
read_json_data = read_json_object(json_object, DataModel)
4870

4971
# Assert
50-
self.assertEqual(json_object, expected_json_object)
72+
self.assertEqual(read_json_data, JSON_DATA)
5173

52-
def test_write_json_file(self) -> None:
74+
def test_read_and_write_json_file(self) -> None:
5375
# Arrange
54-
json_data = {
55-
"from_json_file": {},
56-
"test": 1,
57-
"nested": {"from_json_file": {}, "test": 1},
58-
"array": [{"from_json_file": {}, "test": 1}],
59-
}
60-
expected_json_data = (
61-
'{"test": 1, "nested": {"test": 1}, "array": [{"test": 1}]}'
62-
)
6376
file_name = "json_write_test"
6477
json_file = file_name + ".json"
6578

6679
# Act
67-
write_json_file(json_data, file_name)
80+
write_json_file(JSON_DATA, file_name)
6881

6982
# Assert
7083
with open(json_file) as reader:
71-
self.assertEqual(reader.read(), expected_json_data)
84+
self.assertEqual(reader.read(), EXPECTED_JSON_STRING)
85+
86+
# Act
87+
read_json_data = read_json_file(DataModel, file_name)
88+
89+
# Assert
90+
self.assertEqual(read_json_data, JSON_DATA)
7291

7392
# Cleanup
7493
remove(json_file)

0 commit comments

Comments
 (0)