1- use std:: collections:: { HashMap , HashSet } ;
1+ use std:: {
2+ collections:: { HashMap , HashSet } ,
3+ fmt:: Write ,
4+ } ;
25
36use plonky2:: field:: types:: Field ;
47use serde:: { ser:: SerializeSeq , Deserialize , Serialize , Serializer } ;
@@ -13,10 +16,16 @@ fn serialize_field_tuple<S, const N: usize>(
1316where
1417 S : serde:: Serializer ,
1518{
16- serializer. serialize_str ( & format ! (
17- "{:016x}{:016x}{:016x}{:016x}" ,
18- value[ 0 ] . 0 , value[ 1 ] . 0 , value[ 2 ] . 0 , value[ 3 ] . 0
19- ) )
19+ // `value` is little-endian in memory. We serialize it as a big-endian hex string
20+ // for human readability.
21+ let s = value
22+ . iter ( )
23+ . rev ( )
24+ . fold ( String :: with_capacity ( N * 16 ) , |mut s, limb| {
25+ write ! ( s, "{:016x}" , limb. 0 ) . unwrap ( ) ;
26+ s
27+ } ) ;
28+ serializer. serialize_str ( & s)
2029}
2130
2231fn deserialize_field_tuple < ' de , D , const N : usize > ( deserializer : D ) -> Result < [ F ; N ] , D :: Error >
@@ -25,20 +34,29 @@ where
2534{
2635 let hex_str = String :: deserialize ( deserializer) ?;
2736
28- if !hex_str. chars ( ) . count ( ) == 64 || !hex_str. chars ( ) . all ( |c| c. is_ascii_hexdigit ( ) ) {
37+ let expected_len = N * 16 ;
38+ if hex_str. len ( ) != expected_len {
39+ return Err ( serde:: de:: Error :: custom ( format ! (
40+ "Invalid hex string length: expected {} characters, found {}" ,
41+ expected_len,
42+ hex_str. len( )
43+ ) ) ) ;
44+ }
45+ if !hex_str. chars ( ) . all ( |c| c. is_ascii_hexdigit ( ) ) {
2946 return Err ( serde:: de:: Error :: custom (
30- "Invalid hex string format - expected 64 hexadecimal characters" ,
47+ "Invalid hex string format: contains non- hexadecimal characters" ,
3148 ) ) ;
3249 }
3350
3451 let mut v = [ F :: ZERO ; N ] ;
35- for ( i , v_i ) in v . iter_mut ( ) . enumerate ( ) {
52+ for i in 0 .. N {
3653 let start = i * 16 ;
3754 let end = start + 16 ;
3855 let hex_part = & hex_str[ start..end] ;
39- * v_i = F :: from_canonical_u64 (
40- u64:: from_str_radix ( hex_part, 16 ) . map_err ( serde:: de:: Error :: custom) ?,
41- ) ;
56+ let u64_val = u64:: from_str_radix ( hex_part, 16 ) . map_err ( serde:: de:: Error :: custom) ?;
57+ // The hex string is big-endian, so the first chunk (i=0) is the most significant.
58+ // We store it in the last position of our little-endian array `v`.
59+ v[ N - 1 - i] = F :: from_canonical_u64 ( u64_val) ;
4260 }
4361 Ok ( v)
4462}
0 commit comments