Repository: ergoplatform/sigma-rust (language: rust)

Issue:
Bugs with `Gf2_192Poly::to_bytes`
The original Scala implementation for this method (https://github.com/ScorexFoundation/sigmastate-interpreter/blob/795c176debfe105646a7deef3f01bd537b79c81d/sigmastate/src/main/java/gf2t/GF2_192_Poly.java#L214-L224) gives the option to serialize a Gf2 polynomial with and without the zero-degree coefficient.

My adaptation of this method assumed that the serialization would include the zero-degree coefficient, but that is not how it's used in `ergotree-interpreter`: https://github.com/ergoplatform/sigma-rust/blob/c6919c6a248695efd6ff3febc0ea8f30a871786b/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs#L96-L97. Since this is the only place in the repo where `to_bytes` is used, we can make it not emit the zero-degree coefficient.

Also I didn't account for the `<=deg` within the for loop in the Scala code.


Discussion / hints:

Fix patch:
diff --git a/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs b/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs
index 4460ea031..a06c6aa32 100644
--- a/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs
+++ b/ergotree-interpreter/src/sigma_protocol/sig_serializer.rs
@@ -93,7 +93,7 @@ fn sig_write_bytes<W: SigmaByteWrite>(
                 k: _,
                 polynomial,
             } => {
-                // write the polynomial, except the zero coefficient
+                // write the polynomial, except the zero-degree coefficient
                 w.write_all(polynomial.to_bytes().as_mut_slice())?;
                 for child in children {
                     sig_write_bytes(child, w, false)?;
diff --git a/gf2_192/src/gf2_192poly.rs b/gf2_192/src/gf2_192poly.rs
index 426f2c3f2..f6b0938dd 100644
--- a/gf2_192/src/gf2_192poly.rs
+++ b/gf2_192/src/gf2_192poly.rs
@@ -125,14 +125,16 @@ impl Gf2_192Poly {
         res
     }
 
-    /// Returns Vec<u8> consisting of the concatenation of all the coefficients of the polynomial.
-    ///  - Degree-zero coefficient is located at index 0
-    ///  - Each coefficient takes 24 bytes for a total of `(self.degree+1)*24` bytes
+    /// Returns Vec<u8> consisting of the concatenation of all the coefficients of the polynomial
+    /// NOT including the degree-zero coefficient. Each coefficient takes 24 bytes for a total of
+    /// `self.degree * 24` bytes
     pub fn to_bytes(&self) -> Vec<u8> {
-        let mut res: Vec<_> = std::iter::repeat(0).take((self.degree + 1) * 24).collect();
-        for i in 0..self.degree {
+        let mut res: Vec<_> = std::iter::repeat(0).take(self.degree * 24).collect();
+        for i in 1..=self.degree {
             #[allow(clippy::unwrap_used)]
-            self.coefficients[i].to_i8_slice(&mut res, i * 24).unwrap();
+            self.coefficients[i]
+                .to_i8_slice(&mut res, (i - 1) * 24)
+                .unwrap();
         }
         res.into_iter().map(|x| x as u8).collect()
     }


Test patch: