From 14ff8c7500b14aa80f11260d138090cc0dc9b718 Mon Sep 17 00:00:00 2001 From: daxpedda Date: Fri, 15 Aug 2025 20:34:11 +0200 Subject: [PATCH] Test with Proptest --- curve25519-dalek/Cargo.toml | 1 + curve25519-dalek/src/ristretto.rs | 58 +++++++++++++++++-------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/curve25519-dalek/Cargo.toml b/curve25519-dalek/Cargo.toml index 1fbd72d00..72bff1de7 100644 --- a/curve25519-dalek/Cargo.toml +++ b/curve25519-dalek/Cargo.toml @@ -41,6 +41,7 @@ sha2 = { version = "0.11.0-rc.0", default-features = false } bincode = "1" criterion = { version = "0.5", features = ["html_reports"] } hex = "0.4.2" +proptest = "1" rand = "0.9" rand_core = { version = "0.9", default-features = false, features = ["os_rng"] } diff --git a/curve25519-dalek/src/ristretto.rs b/curve25519-dalek/src/ristretto.rs index e67664ec0..8b867930d 100644 --- a/curve25519-dalek/src/ristretto.rs +++ b/curve25519-dalek/src/ristretto.rs @@ -1321,6 +1321,8 @@ impl Zeroize for RistrettoPoint { mod test { use super::*; use crate::edwards::CompressedEdwardsY; + #[cfg(feature = "group")] + use proptest::prelude::*; use rand_core::{OsRng, TryRngCore}; @@ -1867,32 +1869,36 @@ mod test { } } - #[test] - #[cfg(all(feature = "alloc", feature = "rand_core", feature = "group"))] - fn multiply_double_and_compress_1024_random_points() { - use ff::Field; - use group::Group; - let mut rng = OsRng; - - let mut scalars: Vec = (0..1024) - .map(|_| Scalar::try_from_rng(&mut rng).unwrap()) - .collect(); - scalars[500] = Scalar::ZERO; - - let mut points: Vec = (0..1024) - .map(|_| RistrettoPoint::try_from_rng(&mut rng).unwrap()) - .collect(); - points[500] = ::identity(); - - let multiplied_points: Vec = scalars - .iter() - .zip(&points) - .map(|(scalar, point)| scalar.div_by_2() * point) - .collect(); - let compressed = RistrettoPoint::double_and_compress_batch(&multiplied_points); - - for ((s, P), P2_compressed) in scalars.iter().zip(points).zip(compressed) { - assert_eq!(P2_compressed, (s * P).compress()); + #[cfg(feature = "group")] + proptest! { + #[test] + fn multiply_double_and_compress_random_points( + p1 in any::<[u8; 64]>(), + p2 in any::<[u8; 64]>(), + s1 in any::<[u8; 32]>(), + s2 in any::<[u8; 32]>(), + ) { + use group::Group; + + let scalars = [ + Scalar::from_bytes_mod_order(s1), + Scalar::ZERO, + Scalar::from_bytes_mod_order(s2), + ]; + + let points = [ + RistrettoPoint::from_uniform_bytes(&p1), + ::identity(), + RistrettoPoint::from_uniform_bytes(&p2), + ]; + + let multiplied_points: [_; 3] = + core::array::from_fn(|i| scalars[i].div_by_2() * points[i]); + let compressed = RistrettoPoint::double_and_compress_batch(&multiplied_points); + + for ((s, P), P2_compressed) in scalars.iter().zip(points).zip(compressed) { + prop_assert_eq!(P2_compressed, (s * P).compress()); + } } }