Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.

Commit 2072474

Browse files
Made hRng.c finally use audio entropy with the fallback being the old timing implementation
QoL: Made distributionHelper.ps1 go back to tool dir Also noted __init__.py to 0.3.0-beta
1 parent c923bbf commit 2072474

4 files changed

Lines changed: 58 additions & 9 deletions

File tree

pyCTools/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,4 @@
66
if os.name != 'nt':
77
raise OSError('This package only supports Windows OS.')
88

9-
VERSION = "0.2.1-beta"
9+
VERSION = "0.3.0-beta"

pyCTools/hwrng.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,20 @@ def maxrng_threadsafe(self, size: int) -> bytes:
142142
if not success:
143143
raise RuntimeError("maxrng_threadsafe failed")
144144
return bytes(buf)
145+
146+
def setup_threads(self):
147+
"""
148+
Initialize the RNG for thread-safe operations.
149+
150+
This method should be called before using `maxrng_threadsafe()`.
151+
It prepares the RNG for multithreaded access.
152+
153+
Raises:
154+
RuntimeError: If the initialization fails.
155+
"""
156+
self.dll.maxrng_init()
157+
if not self.test_threading_available():
158+
raise RuntimeError(
159+
"Failed to initialize RNG for threading. "
160+
"Ensure that the hRng DLL supports thread-safe operations."
161+
)

src/hRng.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -84,14 +84,44 @@ static void collect_disk_entropy(const BCRYPT_HASH_HANDLE hHash)
8484
// Audio entropy fallback (simple timing fallback)
8585
static void collect_audio_entropy(const BCRYPT_HASH_HANDLE hHash)
8686
{
87-
// Simplified: no real audio capture to keep minimal
88-
// Just hash QueryPerformanceCounter several times with Sleep
89-
for (int i = 0; i < 5; i++)
90-
{
91-
LARGE_INTEGER counter;
92-
QueryPerformanceCounter(&counter);
93-
BCryptHashData(hHash, (PUCHAR)&counter, sizeof(counter), 0);
94-
Sleep(10);
87+
HWAVEIN hWaveIn = NULL;
88+
WAVEFORMATEX wfx = {0};
89+
wfx.wFormatTag = WAVE_FORMAT_PCM;
90+
wfx.nChannels = 1;
91+
wfx.nSamplesPerSec = 8000;
92+
wfx.wBitsPerSample = 8;
93+
wfx.nBlockAlign = 1;
94+
wfx.nAvgBytesPerSec = 8000;
95+
wfx.cbSize = 0;
96+
97+
const MMRESULT res = waveInOpen(&hWaveIn, WAVE_MAPPER, &wfx, 0, 0, CALLBACK_NULL);
98+
if (res == MMSYSERR_NOERROR && hWaveIn) {
99+
WAVEHDR hdr = {0};
100+
BYTE buffer[256] = {0};
101+
hdr.lpData = (LPSTR)buffer;
102+
hdr.dwBufferLength = sizeof(buffer);
103+
hdr.dwFlags = 0;
104+
105+
if (waveInPrepareHeader(hWaveIn, &hdr, sizeof(hdr)) == MMSYSERR_NOERROR) {
106+
if (waveInAddBuffer(hWaveIn, &hdr, sizeof(hdr)) == MMSYSERR_NOERROR) {
107+
if (waveInStart(hWaveIn) == MMSYSERR_NOERROR) {
108+
Sleep(50); // Let it capture some audio
109+
waveInStop(hWaveIn);
110+
BCryptHashData(hHash, buffer, sizeof(buffer), 0);
111+
}
112+
}
113+
waveInUnprepareHeader(hWaveIn, &hdr, sizeof(hdr));
114+
}
115+
waveInClose(hWaveIn);
116+
} else {
117+
// Fallback: Just hash QueryPerformanceCounter several times with Sleep
118+
for (int i = 0; i < 5; i++)
119+
{
120+
LARGE_INTEGER counter;
121+
QueryPerformanceCounter(&counter);
122+
BCryptHashData(hHash, (PUCHAR)&counter, sizeof(counter), 0);
123+
Sleep(10);
124+
}
95125
}
96126
}
97127

tool/distributionHelper.ps1

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,4 +140,6 @@ Hash : $($hashObj.Hash)
140140
} catch {
141141
Write-CustomError "Unexpected error occurred." $_.Exception.Message
142142
exit 1
143+
} finally {
144+
Set-Location tool
143145
}

0 commit comments

Comments
 (0)