Repository: dusk-network/bls12_381 (language: rust)

Issue:
Deduplicate `from_bytes` and `to_bytes` for `Scalar`



Discussion / hints:

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f753359..df98718 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 
 - Add `to_be_bytes` to scalar [#151]
 
+### Changed
+
+- Change `from_bytes` and `to_bytes` methods in `Scalar` to use original implementation [#154]
+
 ## [0.14.1] - 2025-02-05
 
 ### Added
@@ -246,6 +250,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 - Rename `S` to `TWO_ADACITY` and export it
 
 <!-- Issues -->
+[#154]: https://github.com/dusk-network/bls12_381/issues/154
 [#151]: https://github.com/dusk-network/bls12_381/issues/151
 [#148]: https://github.com/dusk-network/bls12_381/issues/148
 [#145]: https://github.com/dusk-network/bls12_381/issues/145
diff --git a/src/scalar/dusk.rs b/src/scalar/dusk.rs
index 53a6a5e..0afecaa 100644
--- a/src/scalar/dusk.rs
+++ b/src/scalar/dusk.rs
@@ -11,8 +11,7 @@ use core::ops::{BitAnd, BitXor};
 use dusk_bytes::{Error as BytesError, Serializable};
 use subtle::{Choice, ConditionallySelectable, ConstantTimeEq};
 
-use super::{Scalar, MODULUS, R2};
-use crate::util::sbb;
+use super::{Scalar, R2};
 
 impl PartialOrd for Scalar {
     fn partial_cmp(&self, other: &Scalar) -> Option<Ordering> {
@@ -40,52 +39,15 @@ impl Serializable<32> for Scalar {
     /// Converts an element of `Scalar` into a byte representation in
     /// little-endian byte order.
     fn to_bytes(&self) -> [u8; Self::SIZE] {
-        // Turn into canonical form by computing
-        // (a.R) / R = a
-        let tmp = Scalar::montgomery_reduce(self.0[0], self.0[1], self.0[2], self.0[3], 0, 0, 0, 0);
-
-        let mut res = [0; Self::SIZE];
-        res[0..8].copy_from_slice(&tmp.0[0].to_le_bytes());
-        res[8..16].copy_from_slice(&tmp.0[1].to_le_bytes());
-        res[16..24].copy_from_slice(&tmp.0[2].to_le_bytes());
-        res[24..32].copy_from_slice(&tmp.0[3].to_le_bytes());
-
-        res
+        self.to_bytes()
     }
 
     /// Attempts to convert a little-endian byte representation of
     /// a scalar into a `Scalar`, failing if the input is not canonical.
     fn from_bytes(buf: &[u8; Self::SIZE]) -> Result<Self, Self::Error> {
-        let mut s = [0u64; 4];
-
-        s.iter_mut()
-            .zip(buf.chunks_exact(8))
-            .try_for_each(|(s, b)| {
-                <[u8; 8]>::try_from(b)
-                    .map(|b| *s = u64::from_le_bytes(b))
-                    .map_err(|_| BytesError::InvalidData)
-            })?;
-
-        // Try to subtract the modulus
-        let (_, borrow) = sbb(s[0], MODULUS.0[0], 0);
-        let (_, borrow) = sbb(s[1], MODULUS.0[1], borrow);
-        let (_, borrow) = sbb(s[2], MODULUS.0[2], borrow);
-        let (_, borrow) = sbb(s[3], MODULUS.0[3], borrow);
-
-        // If the element is smaller than MODULUS then the
-        // subtraction will underflow, producing a borrow value
-        // of 0xffff...ffff. Otherwise, it'll be zero.
-        if (borrow as u8) & 1 != 1 {
-            return Err(BytesError::InvalidData);
-        }
-
-        let mut s = Scalar(s);
-
-        // Convert to Montgomery form by computing
-        // (a.R^0 * R^2) / R = a.R
-        s *= &R2;
-
-        Ok(s)
+        Self::from_bytes(buf)
+            .into_option()
+            .ok_or(BytesError::InvalidData)
     }
 }
 


Test patch: