diff --git a/networks/monero/primitives/src/tests.rs b/networks/monero/primitives/src/tests.rs index a14d1cd5..68d3df75 100644 --- a/networks/monero/primitives/src/tests.rs +++ b/networks/monero/primitives/src/tests.rs @@ -8,7 +8,7 @@ fn recover_scalars() { let stored = UnreducedScalar(hex::decode(stored).unwrap().try_into().unwrap()); let recovered = Scalar::from_canonical_bytes(hex::decode(recovered).unwrap().try_into().unwrap()).unwrap(); - assert_eq!(stored.recover_monero_slide_scalar(), recovered); + assert_eq!(stored.ref10_slide_scalar_vartime(), recovered); }; // https://www.moneroinflation.com/static/data_py/report_scalars_df.pdf diff --git a/networks/monero/primitives/src/unreduced_scalar.rs b/networks/monero/primitives/src/unreduced_scalar.rs index 90331cd7..bf11645a 100644 --- a/networks/monero/primitives/src/unreduced_scalar.rs +++ b/networks/monero/primitives/src/unreduced_scalar.rs @@ -54,7 +54,7 @@ impl UnreducedScalar { // This matches Monero's `slide` function and intentionally gives incorrect outputs under // certain conditions in order to match Monero. // - // This function does not execute in constant time. + // This function does not execute in constant time and must only be used with public data. fn non_adjacent_form(&self) -> [i8; 256] { let bits = self.as_bits(); let mut naf = [0i8; 256]; @@ -107,15 +107,17 @@ impl UnreducedScalar { naf } - /// Recover the scalar that an array of bytes was incorrectly interpreted as by Monero's `slide` - /// function. + /// Recover the scalar that an array of bytes was incorrectly interpreted as by ref10's `slide` + /// function (as used by the reference Monero implementation in C++). /// - /// In Borromean range proofs, Monero was not checking that the scalars used were - /// reduced. This lead to the scalar stored being interpreted as a different scalar. - /// This function recovers that scalar. + /// For Borromean range proofs, Monero did not check the scalars used were reduced. This led to + /// some scalars serialized being interpreted as distinct scalars. This function recovers these + /// distinct scalars, as required to verify Borromean range proofs within the Monero protocol. /// /// See for more info. - pub fn recover_monero_slide_scalar(&self) -> Scalar { + // + /// This function does not execute in constant time and must only be used with public data. + pub fn ref10_slide_scalar_vartime(&self) -> Scalar { if self.0[31] & 128 == 0 { // Computing the w-NAF of a number can only give an output with 1 more bit than // the number, so even if the number isn't reduced, the `slide` function will be diff --git a/networks/monero/ringct/borromean/src/lib.rs b/networks/monero/ringct/borromean/src/lib.rs index 5e105142..fc0f2194 100644 --- a/networks/monero/ringct/borromean/src/lib.rs +++ b/networks/monero/ringct/borromean/src/lib.rs @@ -56,13 +56,13 @@ impl BorromeanSignatures { let LL = EdwardsPoint::vartime_double_scalar_mul_basepoint( &self.ee, &keys_a[i], - &self.s0[i].recover_monero_slide_scalar(), + &self.s0[i].ref10_slide_scalar_vartime(), ); #[allow(non_snake_case)] let LV = EdwardsPoint::vartime_double_scalar_mul_basepoint( &keccak256_to_scalar(LL.compress().as_bytes()), &keys_b[i], - &self.s1[i].recover_monero_slide_scalar(), + &self.s1[i].ref10_slide_scalar_vartime(), ); transcript[(i * 32) .. ((i + 1) * 32)].copy_from_slice(LV.compress().as_bytes()); }