@@ -38,8 +38,8 @@ def test_base_field_arithmetic() -> None:
3838 # Test equality against the same and different types
3939 assert a == Fp (value = 5 )
4040 assert a != b
41- assert a != 5 # type: ignore[comparison-overlap]
42- assert a != "5" # type: ignore[comparison-overlap]
41+ assert a != 5
42+ assert a != "5"
4343
4444 # Test error on inverting the zero element
4545 with pytest .raises (ZeroDivisionError , match = "Cannot invert the zero element." ):
@@ -91,10 +91,10 @@ def test_bytes_protocol() -> None:
9191 assert Fp .from_bytes (bytes (fp )) == fp
9292
9393 # Test error handling for invalid data length
94- with pytest .raises (ValueError , match = "Expected 4 bytes, got 3" ):
94+ with pytest .raises (ValueError , match = "Expected 4 bytes for Fp , got 3" ):
9595 Fp .from_bytes (b"\x01 \x02 \x03 " )
9696
97- with pytest .raises (ValueError , match = "Expected 4 bytes, got 5" ):
97+ with pytest .raises (ValueError , match = "Expected 4 bytes for Fp , got 5" ):
9898 Fp .from_bytes (b"\x01 \x02 \x03 \x04 \x05 " )
9999
100100 # Test error handling for values exceeding the modulus
@@ -172,3 +172,125 @@ def test_serialize_list_roundtrip_property() -> None:
172172
173173 assert recovered == elements
174174 assert len (data ) == count * 4
175+
176+
177+ def test_ssz_type_properties () -> None :
178+ """Test that Fp correctly implements SSZ type interface."""
179+ # Test is_fixed_size
180+ assert Fp .is_fixed_size () is True
181+
182+ # Test get_byte_length
183+ assert Fp .get_byte_length () == 4
184+
185+
186+ def test_ssz_serialize () -> None :
187+ """Test SSZ serialization using the serialize method."""
188+ import io
189+
190+ fp = Fp (value = 42 )
191+
192+ # Test serialize to stream
193+ stream = io .BytesIO ()
194+ bytes_written = fp .serialize (stream )
195+ assert bytes_written == 4
196+ assert stream .getvalue () == b"\x2a \x00 \x00 \x00 " # 42 in LE
197+
198+
199+ def test_ssz_deserialize () -> None :
200+ """Test SSZ deserialization using the deserialize method."""
201+ import io
202+
203+ # Test successful deserialization
204+ data = b"\x2a \x00 \x00 \x00 " # 42 in LE
205+ stream = io .BytesIO (data )
206+ fp = Fp .deserialize (stream , 4 )
207+ assert fp == Fp (value = 42 )
208+
209+
210+ def test_ssz_deserialize_wrong_scope () -> None :
211+ """Test deserialize error when scope doesn't match P_BYTES."""
212+ import io
213+
214+ data = b"\x2a \x00 \x00 \x00 "
215+ stream = io .BytesIO (data )
216+ with pytest .raises (ValueError , match = "Expected 4 bytes for Fp, got 3" ):
217+ Fp .deserialize (stream , 3 )
218+
219+
220+ def test_ssz_deserialize_short_data () -> None :
221+ """Test deserialize error when stream has insufficient data."""
222+ import io
223+
224+ stream = io .BytesIO (b"\x01 \x02 \x03 " ) # Only 3 bytes
225+ with pytest .raises (ValueError , match = "Expected 4 bytes for Fp, got 3" ):
226+ Fp .deserialize (stream , 4 )
227+
228+
229+ def test_ssz_deserialize_exceeds_modulus () -> None :
230+ """Test deserialize error when value exceeds field modulus."""
231+ import io
232+
233+ # P = 2^31 - 2^24 + 1 = 2130706433
234+ # Encode a value >= P (use P itself)
235+ invalid_data = P .to_bytes (4 , byteorder = "little" )
236+ stream = io .BytesIO (invalid_data )
237+ with pytest .raises (ValueError , match = "exceeds field modulus" ):
238+ Fp .deserialize (stream , 4 )
239+
240+
241+ def test_ssz_encode_decode_bytes () -> None :
242+ """Test SSZ encode_bytes and decode_bytes methods."""
243+ # Test encode_bytes
244+ fp = Fp (value = 100 )
245+ data = fp .encode_bytes ()
246+ assert len (data ) == 4
247+ assert data == b"\x64 \x00 \x00 \x00 " # 100 in LE
248+
249+ # Test decode_bytes
250+ fp2 = Fp .decode_bytes (data )
251+ assert fp2 == fp
252+
253+ # Test roundtrip for various values
254+ test_values = [0 , 1 , 42 , 255 , 256 , 1000 , 65535 , 65536 , 1000000 , P - 1 ]
255+ for value in test_values :
256+ fp = Fp (value = value )
257+ data = fp .encode_bytes ()
258+ recovered = Fp .decode_bytes (data )
259+ assert recovered == fp , f"Failed for value={ value } "
260+
261+
262+ def test_ssz_roundtrip () -> None :
263+ """Comprehensive SSZ roundtrip test with many values."""
264+ import random
265+
266+ random .seed (12345 )
267+
268+ for _ in range (100 ):
269+ # Test with random values
270+ value = random .randint (0 , P - 1 )
271+ fp = Fp (value = value )
272+
273+ # Test all serialization methods give same result
274+ data1 = bytes (fp )
275+ data2 = fp .encode_bytes ()
276+ assert data1 == data2
277+
278+ # Test all deserialization methods work
279+ recovered1 = Fp .from_bytes (data1 )
280+ recovered2 = Fp .decode_bytes (data2 )
281+ assert recovered1 == fp
282+ assert recovered2 == fp
283+
284+
285+ def test_ssz_deterministic () -> None :
286+ """Test that SSZ serialization is deterministic."""
287+ fp = Fp (value = 999 )
288+
289+ # Serialize multiple times
290+ data1 = fp .encode_bytes ()
291+ data2 = fp .encode_bytes ()
292+ data3 = bytes (fp )
293+
294+ # All should be identical
295+ assert data1 == data2
296+ assert data1 == data3
0 commit comments