Skip to content

Commit 39c325f

Browse files
committed
feat(init): add mode switching between DIRECT and HYBRID taps
1 parent 0f862ec commit 39c325f

1 file changed

Lines changed: 98 additions & 15 deletions

File tree

src/trueentropy/__init__.py

Lines changed: 98 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -48,23 +48,24 @@
4848
# Type Imports (for type hints)
4949
# -----------------------------------------------------------------------------
5050
from collections.abc import MutableSequence, Sequence
51-
from typing import TYPE_CHECKING, Any, TypeVar
51+
from typing import TYPE_CHECKING, Any, Literal, TypeVar
5252

5353
if TYPE_CHECKING:
5454
pass
5555

5656
# -----------------------------------------------------------------------------
5757
# Internal Module Imports
5858
# -----------------------------------------------------------------------------
59+
import trueentropy.config as _config_module
5960
from trueentropy.config import (
6061
TrueEntropyConfig,
61-
configure,
6262
get_config,
6363
reset_config,
6464
)
6565
from trueentropy.health import HealthStatus, entropy_health
66+
from trueentropy.hybrid import HybridTap
6667
from 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
@@ -78,12 +79,96 @@
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

Comments
 (0)