@@ -966,6 +966,7 @@ where
966966#[ cfg( test) ]
967967mod tests {
968968 use super :: * ;
969+ use itertools:: Itertools ;
969970 use pairing:: bls12_381:: Bls12 ;
970971 use rand:: { Rng , SeedableRng , XorShiftRng } ;
971972 use std:: io:: Cursor ;
@@ -1042,7 +1043,36 @@ mod tests {
10421043 }
10431044 }
10441045
1045- // `write_padded` for 151 bytes of 1s, check padding bits in byte 31 and 63.
1046+ // Simple (and slow) padder implementation using `BitVec`.
1047+ // It is technically not quite right to use `BitVec` to test
1048+ // `write_padded` since at the moment that function still uses
1049+ // it for some corner cases, but since largely this implementation
1050+ // has been replaced it seems reasonable.
1051+ fn bit_vec_padding ( raw_data : Vec < u8 > ) -> Box < [ u8 ] > {
1052+ let mut padded_data: BitVec < bitvec:: LittleEndian , u8 > = BitVec :: new ( ) ;
1053+ let raw_data: BitVec < bitvec:: LittleEndian , u8 > = BitVec :: from ( raw_data) ;
1054+
1055+ for data_unit in raw_data
1056+ . into_iter ( )
1057+ . chunks ( FR32_PADDING_MAP . data_bits )
1058+ . into_iter ( )
1059+ {
1060+ padded_data. extend ( data_unit. into_iter ( ) ) ;
1061+
1062+ // To avoid reconverting the iterator, we deduce if we need the padding
1063+ // by the length of `padded_data`: a full data unit would not leave the
1064+ // padded layout aligned (it would leave it unaligned by just `pad_bits()`).
1065+ if padded_data. len ( ) % 8 != 0 {
1066+ for _ in 0 ..FR32_PADDING_MAP . pad_bits ( ) {
1067+ padded_data. push ( false ) ;
1068+ }
1069+ }
1070+ }
1071+
1072+ padded_data. into_boxed_slice ( )
1073+ }
1074+
1075+ // `write_padded` for 151 bytes of 1s, check padding.
10461076 #[ test]
10471077 fn test_write_padded ( ) {
10481078 let data = vec ! [ 255u8 ; 151 ] ;
@@ -1055,16 +1085,17 @@ mod tests {
10551085 padded. len( ) ,
10561086 FR32_PADDING_MAP . transform_byte_offset( 151 , true )
10571087 ) ;
1088+
10581089 assert_eq ! ( & padded[ 0 ..31 ] , & data[ 0 ..31 ] ) ;
10591090 assert_eq ! ( padded[ 31 ] , 0b0011_1111 ) ;
10601091 assert_eq ! ( padded[ 32 ] , 0b1111_1111 ) ;
10611092 assert_eq ! ( & padded[ 33 ..63 ] , vec![ 255u8 ; 30 ] . as_slice( ) ) ;
10621093 assert_eq ! ( padded[ 63 ] , 0b0011_1111 ) ;
1094+ assert_eq ! ( padded. into_boxed_slice( ) , bit_vec_padding( data) ) ;
10631095 }
10641096
10651097 // `write_padded` for 256 bytes of 1s, splitting it in two calls of 127 bytes,
1066- // aligning the calls with the padded element boundaries, check padding bits
1067- // in byte 31 and 63.
1098+ // aligning the calls with the padded element boundaries, check padding.
10681099 #[ test]
10691100 fn test_write_padded_multiple_aligned ( ) {
10701101 let data = vec ! [ 255u8 ; 254 ] ;
@@ -1079,19 +1110,15 @@ mod tests {
10791110 padded. len( ) ,
10801111 FR32_PADDING_MAP . transform_byte_offset( 254 , true )
10811112 ) ;
1082- assert_eq ! ( & padded[ 0 ..31 ] , & data[ 0 ..31 ] ) ;
1083- assert_eq ! ( padded[ 31 ] , 0b0011_1111 ) ;
1084- assert_eq ! ( padded[ 32 ] , 0b1111_1111 ) ;
1085- assert_eq ! ( & padded[ 33 ..63 ] , vec![ 255u8 ; 30 ] . as_slice( ) ) ;
1086- assert_eq ! ( padded[ 63 ] , 0b0011_1111 ) ;
1087- // TODO: This test is not checking the padding in the boundary between the
1088- // `write_padded` calls, it doesn't seem then to be testing anything different
1089- // from the previous one.
1113+
1114+ assert_eq ! ( padded[ 127 ] , 0b0011_1111 ) ;
1115+ assert_eq ! ( padded[ 128 ] , 0b1111_1111 ) ;
1116+ assert_eq ! ( & padded[ 128 ..159 ] , vec![ 255u8 ; 31 ] . as_slice( ) ) ;
1117+ assert_eq ! ( padded. into_boxed_slice( ) , bit_vec_padding( data) ) ;
10901118 }
10911119
1092- // `write_padded` for 265 bytes of 1s, splitting it in two calls of 127 bytes,
1093- // aligning the calls with the padded element boundaries, check padding bits
1094- // in byte 31 and 63.
1120+ // `write_padded` for 265 bytes of 1s, splitting it in two calls of 128 bytes,
1121+ // aligning the calls with the padded element boundaries, check padding.
10951122 #[ test]
10961123 fn test_write_padded_multiple_first_aligned ( ) {
10971124 let data = vec ! [ 255u8 ; 265 ] ;
@@ -1106,12 +1133,12 @@ mod tests {
11061133 padded. len( ) ,
11071134 FR32_PADDING_MAP . transform_byte_offset( 265 , true )
11081135 ) ;
1109- assert_eq ! ( & padded [ 0 .. 31 ] , & data [ 0 .. 31 ] ) ;
1110- assert_eq ! ( padded[ 31 ] , 0b0011_1111 ) ;
1111- assert_eq ! ( padded[ 32 ] , 0b1111_1111 ) ;
1112- assert_eq ! ( & padded[ 33 .. 63 ] , vec![ 255u8 ; 30 ] . as_slice( ) ) ;
1113- assert_eq ! ( padded[ 63 ] , 0b0011_1111 ) ;
1114- // TODO: Same observation as before, what are we testing here?
1136+
1137+ assert_eq ! ( padded[ 127 ] , 0b0011_1111 ) ;
1138+ assert_eq ! ( padded[ 128 ] , 0b1111_1111 ) ;
1139+ assert_eq ! ( & padded[ 128 .. 159 ] , vec![ 255u8 ; 31 ] . as_slice( ) ) ;
1140+ assert_eq ! ( padded[ data . len ( ) ] , 0b1111_1111 ) ;
1141+ assert_eq ! ( padded . into_boxed_slice ( ) , bit_vec_padding ( data ) ) ;
11151142 }
11161143
11171144 fn validate_fr32 ( bytes : & [ u8 ] ) {
@@ -1125,13 +1152,12 @@ mod tests {
11251152 }
11261153
11271154 // `write_padded` for 127 bytes of 1s, splitting it in two calls of varying
1128- // sizes, from 0 to the full size, generating many unaligned calls, check
1129- // padding bits in byte 31 and 63.
1155+ // sizes, from 0 to the full size, generating many unaligned calls, check padding.
11301156 #[ test]
11311157 fn test_write_padded_multiple_unaligned ( ) {
11321158 // Use 127 for this test because it unpads to 128 – a multiple of 32.
11331159 // Otherwise the last chunk will be too short and cannot be converted to Fr.
1134- for i in 0 .. 127 {
1160+ for i in 1 .. 126 {
11351161 let data = vec ! [ 255u8 ; 127 ] ;
11361162 let buf = Vec :: new ( ) ;
11371163 let mut cursor = Cursor :: new ( buf) ;
@@ -1144,13 +1170,18 @@ mod tests {
11441170 padded. len( ) ,
11451171 FR32_PADDING_MAP . transform_byte_offset( 127 , true )
11461172 ) ;
1147- assert_eq ! ( & padded[ 0 ..31 ] , & data[ 0 ..31 ] ) ;
1148- assert_eq ! ( padded[ 31 ] , 0b0011_1111 ) ;
1149- assert_eq ! ( padded[ 32 ] , 0b1111_1111 ) ;
1150- assert_eq ! ( & padded[ 33 ..63 ] , vec![ 255u8 ; 30 ] . as_slice( ) ) ;
1151- assert_eq ! ( padded[ 63 ] , 0b0011_1111 ) ;
1152- // TODO: We seem to be repeating the same series of asserts,
1153- // maybe this can be abstracted away in a helper function.
1173+
1174+ // Check bytes in the boundary between calls: `i` and `i-1`.
1175+ for offset in [ i - 1 , i] . iter ( ) {
1176+ if * offset % 32 == 31 {
1177+ // Byte with padding.
1178+ assert_eq ! ( padded[ * offset] , 0b0011_1111 ) ;
1179+ } else {
1180+ assert_eq ! ( padded[ * offset] , 255u8 ) ;
1181+ }
1182+ }
1183+
1184+ assert_eq ! ( padded. into_boxed_slice( ) , bit_vec_padding( data) ) ;
11541185 }
11551186 }
11561187
@@ -1186,6 +1217,8 @@ mod tests {
11861217 assert_eq ! ( buf[ 66 ] , 9 << 4 ) ; // Another.
11871218 assert_eq ! ( buf[ 67 ] , 0xf0 ) ; // The final 0xff is split into two bytes. Here is the first half.
11881219 assert_eq ! ( buf[ 68 ] , 0x0f ) ; // And here is the second.
1220+
1221+ assert_eq ! ( buf. into_boxed_slice( ) , bit_vec_padding( source) ) ;
11891222 }
11901223
11911224 // `write_padded` and `write_unpadded` for 1016 bytes of 1s, check the
@@ -1209,6 +1242,7 @@ mod tests {
12091242 let unpadded_written = write_unpadded ( & padded, & mut unpadded, 0 , len) . unwrap ( ) ;
12101243 assert_eq ! ( unpadded_written, len) ;
12111244 assert_eq ! ( data, unpadded) ;
1245+ assert_eq ! ( padded. into_boxed_slice( ) , bit_vec_padding( data) ) ;
12121246 }
12131247
12141248 // `write_padded` and `write_unpadded` for 1016 bytes of random data, recover
@@ -1254,10 +1288,6 @@ mod tests {
12541288 }
12551289 }
12561290
1257- // TODO: Add a test that checks integrity counting the number of set bits
1258- // before and after padding. This would need to assume that padding is
1259- // always zero and the DC bit are also zero in the underlying implementation.
1260-
12611291 // TODO: Add a test that drops the last part of an element and tries to recover
12621292 // the rest of the data (may already be present in some form in the above tests).
12631293}
0 commit comments