4848# Type Imports (for type hints)
4949# -----------------------------------------------------------------------------
5050from collections .abc import MutableSequence , Sequence
51- from typing import TYPE_CHECKING , Any , TypeVar
51+ from typing import TYPE_CHECKING , Any , Literal , TypeVar
5252
5353if TYPE_CHECKING :
5454 pass
5555
5656# -----------------------------------------------------------------------------
5757# Internal Module Imports
5858# -----------------------------------------------------------------------------
59+ import trueentropy .config as _config_module
5960from trueentropy .config import (
6061 TrueEntropyConfig ,
61- configure ,
6262 get_config ,
6363 reset_config ,
6464)
6565from trueentropy .health import HealthStatus , entropy_health
66+ from trueentropy .hybrid import HybridTap
6667from trueentropy .pool import EntropyPool
67- from trueentropy .tap import EntropyTap
68+ from trueentropy .tap import BaseTap , EntropyTap
6869
6970# -----------------------------------------------------------------------------
7071# Type Variables for Generic Functions
7879# Users can also create their own instances if needed.
7980
8081_pool : EntropyPool = EntropyPool ()
81- _tap : EntropyTap = EntropyTap (_pool )
82+ # _tap is initialized with EntropyTap (DIRECT mode) by default
83+ _tap : BaseTap = EntropyTap (_pool )
8284
8385# Flag to track if background collector is running
8486_collector_running : bool = False
8587
8688
89+ # -----------------------------------------------------------------------------
90+ # Configuration Helper
91+ # -----------------------------------------------------------------------------
92+
93+
94+ def _update_tap () -> None :
95+ """
96+ Update the global _tap instance based on current configuration.
97+
98+ Switches between EntropyTap (DIRECT) and HybridTap (HYBRID).
99+ """
100+ global _tap
101+ config = get_config ()
102+
103+ if config .mode == "HYBRID" :
104+ # Create new HybridTap if not already one
105+ if not isinstance (_tap , HybridTap ):
106+ _tap = HybridTap (_pool , reseed_interval = config .hybrid_reseed_interval )
107+ else :
108+ # Update existing HybridTap interval
109+ _tap ._reseed_interval = config .hybrid_reseed_interval
110+ else :
111+ # Default to DIRECT mode (EntropyTap)
112+ if not isinstance (_tap , EntropyTap ):
113+ _tap = EntropyTap (_pool )
114+
115+
116+ def configure (
117+ * ,
118+ mode : Literal ["DIRECT" , "HYBRID" ] | None = None ,
119+ hybrid_reseed_interval : float | None = None ,
120+ offline_mode : bool | None = None ,
121+ enable_timing : bool | None = None ,
122+ enable_system : bool | None = None ,
123+ enable_network : bool | None = None ,
124+ enable_external : bool | None = None ,
125+ enable_weather : bool | None = None ,
126+ enable_radioactive : bool | None = None ,
127+ ) -> TrueEntropyConfig :
128+ """
129+ Configure TrueEntropy globally.
130+
131+ This function updates the global configuration and switches operation mode
132+ (DIRECT vs HYBRID) if requested.
133+
134+ Args:
135+ mode: Operation mode ("DIRECT" or "HYBRID")
136+ hybrid_reseed_interval: Seconds between re-seeds in HYBRID mode
137+ offline_mode: If True, disables all network-dependent sources.
138+ enable_timing: Enable/disable CPU timing harvester
139+ enable_system: Enable/disable system state harvester
140+ enable_network: Enable/disable network latency harvester
141+ enable_external: Enable/disable external API harvester
142+ enable_weather: Enable/disable weather data harvester
143+ enable_radioactive: Enable/disable quantum randomness harvester
144+
145+ Returns:
146+ The updated global configuration
147+
148+ Example:
149+ >>> import trueentropy
150+ >>> # Switch to Hybrid Mode (faster)
151+ >>> trueentropy.configure(mode="HYBRID")
152+ """
153+ # Call the underlying config update
154+ cfg = _config_module .configure (
155+ mode = mode ,
156+ hybrid_reseed_interval = hybrid_reseed_interval ,
157+ offline_mode = offline_mode ,
158+ enable_timing = enable_timing ,
159+ enable_system = enable_system ,
160+ enable_network = enable_network ,
161+ enable_external = enable_external ,
162+ enable_weather = enable_weather ,
163+ enable_radioactive = enable_radioactive ,
164+ )
165+
166+ # Update the active tap based on new config
167+ _update_tap ()
168+
169+ return cfg
170+
171+
87172# =============================================================================
88173# PUBLIC API - Random Value Generation
89174# =============================================================================
@@ -93,9 +178,7 @@ def random() -> float:
93178 """
94179 Generate a random floating-point number in the range [0.0, 1.0).
95180
96- This function extracts entropy from the pool and converts it to a
97- uniformly distributed float. The distribution is uniform, meaning
98- all values in the range are equally likely.
181+ This function uses the currently configured tap (DIRECT or HYBRID).
99182
100183 Returns:
101184 A float value where 0.0 <= value < 1.0
@@ -182,9 +265,8 @@ def randbytes(n: int) -> bytes:
182265 """
183266 Generate n random bytes.
184267
185- This function extracts raw entropy from the pool and returns it
186- as a bytes object. Useful for generating cryptographic keys,
187- tokens, or other binary data.
268+ This function extracts raw entropy (or PRNG bytes in Hybrid mode).
269+ Useful for generating cryptographic keys, tokens, or other binary data.
188270
189271 Args:
190272 n: The number of bytes to generate (must be positive)
@@ -208,8 +290,7 @@ def shuffle(seq: MutableSequence[Any]) -> None:
208290 """
209291 Shuffle a mutable sequence in-place.
210292
211- Uses the Fisher-Yates shuffle algorithm with true random numbers
212- to ensure a uniform distribution of permutations.
293+ Uses the Fisher-Yates shuffle algorithm.
213294
214295 Args:
215296 seq: A mutable sequence (list) to shuffle in-place
@@ -503,15 +584,15 @@ def get_pool() -> EntropyPool:
503584 return _pool
504585
505586
506- def get_tap () -> EntropyTap :
587+ def get_tap () -> BaseTap :
507588 """
508589 Get the global entropy tap instance.
509590
510591 This is useful for advanced users who want to use the tap
511- directly or create their own tap with custom settings .
592+ directly or inspect which implementation (BaseTap/HybridTap) is active .
512593
513594 Returns:
514- The global EntropyTap instance
595+ The global BaseTap instance (EntropyTap or HybridTap)
515596 """
516597 return _tap
517598
@@ -557,6 +638,8 @@ def get_tap() -> EntropyTap:
557638 # Classes (for type hints and advanced usage)
558639 "EntropyPool" ,
559640 "EntropyTap" ,
641+ "HybridTap" ,
642+ "BaseTap" ,
560643 "HealthStatus" ,
561644 "TrueEntropyConfig" ,
562645]
0 commit comments