diem_crypto/
test_utils.rs1use crate::traits::Uniform;
11use serde::{Deserialize, Serialize};
12
13pub const TEST_SEED: [u8; 32] = [0u8; 32];
15
16#[cfg_attr(feature = "cloneable-private-keys", derive(Clone))]
18#[derive(Serialize, Deserialize, PartialEq, Eq)]
19pub struct KeyPair<S, P>
20where for<'a> P: From<&'a S>
21{
22 pub private_key: S,
24 pub public_key: P,
26}
27
28impl<S, P> From<S> for KeyPair<S, P>
29where for<'a> P: From<&'a S>
30{
31 fn from(private_key: S) -> Self {
32 KeyPair {
33 public_key: (&private_key).into(),
34 private_key,
35 }
36 }
37}
38
39impl<S, P> Uniform for KeyPair<S, P>
40where
41 S: Uniform,
42 for<'a> P: From<&'a S>,
43{
44 fn generate<R>(rng: &mut R) -> Self
45 where R: ::rand::RngCore + ::rand::CryptoRng {
46 let private_key = S::generate(rng);
47 private_key.into()
48 }
49}
50
51impl<S, P> Uniform for (S, P)
53where
54 S: Uniform,
55 for<'a> P: From<&'a S>,
56{
57 fn generate<R>(rng: &mut R) -> Self
58 where R: ::rand::RngCore + ::rand::CryptoRng {
59 let private_key = S::generate(rng);
60 let public_key = (&private_key).into();
61 (private_key, public_key)
62 }
63}
64
65impl<Priv, Pub> std::fmt::Debug for KeyPair<Priv, Pub>
66where
67 Priv: Serialize,
68 Pub: Serialize + for<'a> From<&'a Priv>,
69{
70 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
71 let mut v = bcs::to_bytes(&self.private_key).unwrap();
72 v.extend(&bcs::to_bytes(&self.public_key).unwrap());
73 write!(f, "{}", hex::encode(&v[..]))
74 }
75}
76
77#[cfg(any(test, feature = "fuzzing"))]
78use proptest::prelude::*;
79#[cfg(any(test, feature = "fuzzing"))]
80use rand::{rngs::StdRng, SeedableRng};
81
82#[cfg(any(test, feature = "fuzzing"))]
84pub fn uniform_keypair_strategy<Priv, Pub>(
85) -> impl Strategy<Value = KeyPair<Priv, Pub>>
86where
87 Pub: Serialize + for<'a> From<&'a Priv>,
88 Priv: Serialize + Uniform,
89{
90 any::<[u8; 32]>()
94 .prop_map(|seed| {
95 let mut rng = StdRng::from_seed(seed);
96 KeyPair::<Priv, Pub>::generate(&mut rng)
97 })
98 .no_shrink()
99}
100
101#[cfg(any(test, feature = "fuzzing"))]
104#[derive(Debug, Serialize, Deserialize)]
105pub struct TestDiemCrypto(pub String);
106
107#[cfg(any(test, feature = "fuzzing"))]
112pub struct TestDiemCryptoHasher(crate::hash::DefaultHasher);
113#[cfg(any(test, feature = "fuzzing"))]
114impl ::core::clone::Clone for TestDiemCryptoHasher {
115 #[inline]
116 fn clone(&self) -> TestDiemCryptoHasher {
117 match *self {
118 TestDiemCryptoHasher(ref __self_0_0) => TestDiemCryptoHasher(
119 ::core::clone::Clone::clone(&(*__self_0_0)),
120 ),
121 }
122 }
123}
124#[cfg(any(test, feature = "fuzzing"))]
125static TEST_DIEM_CRYPTO_SEED: crate::_once_cell::sync::OnceCell<[u8; 32]> =
126 crate::_once_cell::sync::OnceCell::new();
127#[cfg(any(test, feature = "fuzzing"))]
128impl TestDiemCryptoHasher {
129 fn new() -> Self {
130 let name = crate::_serde_name::trace_name::<TestDiemCrypto>().expect(
131 "The `CryptoHasher` macro only applies to structs and enums",
132 );
133 TestDiemCryptoHasher(crate::hash::DefaultHasher::new(&name.as_bytes()))
134 }
135}
136#[cfg(any(test, feature = "fuzzing"))]
137static TEST_DIEM_CRYPTO_HASHER: crate::_once_cell::sync::Lazy<
138 TestDiemCryptoHasher,
139> = crate::_once_cell::sync::Lazy::new(TestDiemCryptoHasher::new);
140#[cfg(any(test, feature = "fuzzing"))]
141impl std::default::Default for TestDiemCryptoHasher {
142 fn default() -> Self { TEST_DIEM_CRYPTO_HASHER.clone() }
143}
144#[cfg(any(test, feature = "fuzzing"))]
145impl crate::hash::CryptoHasher for TestDiemCryptoHasher {
146 fn seed() -> &'static [u8; 32] {
147 TEST_DIEM_CRYPTO_SEED.get_or_init(|| {
148 let name = crate::_serde_name::trace_name::<TestDiemCrypto>()
149 .expect("The `CryptoHasher` macro only applies to structs and enums.")
150 .as_bytes();
151 crate::hash::DefaultHasher::prefixed_hash(&name)
152 })
153 }
154
155 fn update(&mut self, bytes: &[u8]) { self.0.update(bytes); }
156
157 fn finish(self) -> crate::hash::HashValue { self.0.finish() }
158}
159#[cfg(any(test, feature = "fuzzing"))]
160impl std::io::Write for TestDiemCryptoHasher {
161 fn write(&mut self, bytes: &[u8]) -> std::io::Result<usize> {
162 self.0.update(bytes);
163 Ok(bytes.len())
164 }
165
166 fn flush(&mut self) -> std::io::Result<()> { Ok(()) }
167}
168#[cfg(any(test, feature = "fuzzing"))]
169impl crate::hash::CryptoHash for TestDiemCrypto {
170 type Hasher = TestDiemCryptoHasher;
171
172 fn hash(&self) -> crate::hash::HashValue {
173 use crate::hash::CryptoHasher;
174 let mut state = Self::Hasher::default();
175 bcs::serialize_into(&mut state, &self)
176 .expect("BCS serialization of TestDiemCrypto should not fail");
177 state.finish()
178 }
179}
180
181#[cfg(any(test, feature = "fuzzing"))]
183pub fn random_serializable_struct() -> impl Strategy<Value = TestDiemCrypto> {
184 (String::arbitrary()).prop_map(TestDiemCrypto).no_shrink()
185}