Respond to 2 2

This commit is contained in:
Luke Parker
2025-07-23 09:27:50 -04:00
parent 6b8cf6653a
commit cb1e6535cb
3 changed files with 12 additions and 10 deletions

View File

@@ -8,7 +8,7 @@ fn recover_scalars() {
let stored = UnreducedScalar(hex::decode(stored).unwrap().try_into().unwrap()); let stored = UnreducedScalar(hex::decode(stored).unwrap().try_into().unwrap());
let recovered = let recovered =
Scalar::from_canonical_bytes(hex::decode(recovered).unwrap().try_into().unwrap()).unwrap(); 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 // https://www.moneroinflation.com/static/data_py/report_scalars_df.pdf

View File

@@ -54,7 +54,7 @@ impl UnreducedScalar {
// This matches Monero's `slide` function and intentionally gives incorrect outputs under // This matches Monero's `slide` function and intentionally gives incorrect outputs under
// certain conditions in order to match Monero. // 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] { fn non_adjacent_form(&self) -> [i8; 256] {
let bits = self.as_bits(); let bits = self.as_bits();
let mut naf = [0i8; 256]; let mut naf = [0i8; 256];
@@ -107,15 +107,17 @@ impl UnreducedScalar {
naf naf
} }
/// Recover the scalar that an array of bytes was incorrectly interpreted as by Monero's `slide` /// Recover the scalar that an array of bytes was incorrectly interpreted as by ref10's `slide`
/// function. /// function (as used by the reference Monero implementation in C++).
/// ///
/// In Borromean range proofs, Monero was not checking that the scalars used were /// For Borromean range proofs, Monero did not check the scalars used were reduced. This led to
/// reduced. This lead to the scalar stored being interpreted as a different scalar. /// some scalars serialized being interpreted as distinct scalars. This function recovers these
/// This function recovers that scalar. /// distinct scalars, as required to verify Borromean range proofs within the Monero protocol.
/// ///
/// See <https://github.com/monero-project/monero/issues/8438> for more info. /// See <https://github.com/monero-project/monero/issues/8438> 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 { if self.0[31] & 128 == 0 {
// Computing the w-NAF of a number can only give an output with 1 more bit than // 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 // the number, so even if the number isn't reduced, the `slide` function will be

View File

@@ -56,13 +56,13 @@ impl BorromeanSignatures {
let LL = EdwardsPoint::vartime_double_scalar_mul_basepoint( let LL = EdwardsPoint::vartime_double_scalar_mul_basepoint(
&self.ee, &self.ee,
&keys_a[i], &keys_a[i],
&self.s0[i].recover_monero_slide_scalar(), &self.s0[i].ref10_slide_scalar_vartime(),
); );
#[allow(non_snake_case)] #[allow(non_snake_case)]
let LV = EdwardsPoint::vartime_double_scalar_mul_basepoint( let LV = EdwardsPoint::vartime_double_scalar_mul_basepoint(
&keccak256_to_scalar(LL.compress().as_bytes()), &keccak256_to_scalar(LL.compress().as_bytes()),
&keys_b[i], &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()); transcript[(i * 32) .. ((i + 1) * 32)].copy_from_slice(LV.compress().as_bytes());
} }