Skip to main content

lexe_common/
rng.rs

1//! Lexe [`Crng`] compatibility hacks to support LDK's [`EntropySource`].
2//!
3//! [`Crng`]: lexe_crypto::rng::Crng
4//! [`EntropySource`]: lightning::sign::EntropySource
5//
6// These types live in `lexe-common` to avoid including any `lightning`
7// dependencies in our low-level, foundational crates, as `lightning` takes a
8// long time to compile.
9
10#[cfg(any(test, feature = "test-utils"))]
11use lexe_crypto::rng::FastRng;
12use lexe_crypto::rng::{RngExt, SysRng};
13use lightning::sign::EntropySource;
14
15/// Dumb hack so we can pass `SysRng` as an LDK [`EntropySource`] without
16/// wrapping in an Arc/Box.
17#[repr(transparent)]
18pub struct SysRngDerefHack(InnerSysrng);
19
20impl SysRngDerefHack {
21    #[allow(clippy::new_without_default)]
22    pub fn new() -> Self {
23        Self(InnerSysrng)
24    }
25}
26
27impl std::ops::Deref for SysRngDerefHack {
28    type Target = InnerSysrng;
29    fn deref(&self) -> &Self::Target {
30        &self.0
31    }
32}
33
34#[doc(hidden)] // needs to be `pub` for `Deref<Target = InnerSysrng>`
35pub struct InnerSysrng;
36
37impl EntropySource for InnerSysrng {
38    fn get_secure_random_bytes(&self) -> [u8; 32] {
39        SysRng::new().gen_bytes()
40    }
41}
42
43/// Dumb hack so we can use a `FastRng` as an [`EntropySource`].
44///
45/// Note that because LDK requires `&self` for [`EntropySource`], this will
46/// return the same randomness for every `get_secure_random_bytes` call after
47/// creation.
48#[cfg(any(test, feature = "test-utils"))]
49#[repr(transparent)]
50pub struct FastRngDerefHack(InnerFastRng);
51
52#[cfg(any(test, feature = "test-utils"))]
53impl FastRngDerefHack {
54    pub fn from_u64(seed: u64) -> Self {
55        Self(InnerFastRng(FastRng::from_u64(seed)))
56    }
57
58    pub fn from_rng(rng: &mut FastRng) -> Self {
59        let rng = FastRng::from_u64(rng.gen_u64());
60        Self(InnerFastRng(rng))
61    }
62}
63
64#[cfg(any(test, feature = "test-utils"))]
65impl std::ops::Deref for FastRngDerefHack {
66    type Target = InnerFastRng;
67    fn deref(&self) -> &Self::Target {
68        &self.0
69    }
70}
71
72#[cfg(any(test, feature = "test-utils"))]
73#[doc(hidden)] // needs to be `pub` for `Deref<Target = InnerFastRng>`
74pub struct InnerFastRng(FastRng);
75
76#[cfg(any(test, feature = "test-utils"))]
77impl EntropySource for InnerFastRng {
78    fn get_secure_random_bytes(&self) -> [u8; 32] {
79        self.0.clone().gen_bytes()
80    }
81}