Skip to content

Commit fbe28a0

Browse files
Add documentation and workflow for PyCTools package and tools
Used the wiki, makes documentation updates way easier
1 parent b71c18b commit fbe28a0

11 files changed

+2821
-0
lines changed

.github/workflows/publish-wiki.yml

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
name: Publish wiki
2+
on:
3+
push:
4+
branches: [main]
5+
paths:
6+
- wiki/**
7+
- .github/workflows/publish-wiki.yml
8+
concurrency:
9+
group: publish-wiki
10+
cancel-in-progress: true
11+
permissions:
12+
contents: write
13+
jobs:
14+
publish-wiki:
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v3
18+
- uses: Andrew-Chen-Wang/github-wiki-action@v4

wiki/C Documentation ‐ hRng.c.md

Lines changed: 351 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,351 @@
1+
# Hardware Random Number Generator (hRng)
2+
3+
The `/dev/urandom/` of Windows.
4+
5+
---
6+
7+
<details>
8+
<summary>Outdated documentation for v1.0.0 - hRng.c</summary>
9+
10+
## hRng.c
11+
12+
Implements a hardware random number generator using the RDRAND instruction (if supported by the CPU).
13+
14+
### Key Function
15+
- `int read_hwrng(unsigned char* buffer, int size)`
16+
- Fills `buffer` with `size` random bytes from the hardware RNG.
17+
- Returns 1 on success, 0 if RDRAND is not supported or fails.
18+
- Exported for use by Python via ctypes.
19+
20+
### Notes
21+
- Checks for RDRAND support using CPUID.
22+
- Used by `pyCTools.hwrng`.
23+
</details>
24+
25+
---
26+
27+
## Overview
28+
29+
The Hardware Random Number Generator (hRng) is a high-security random number generation library designed for Windows systems. It provides cryptographically secure random numbers by combining multiple entropy sources with hardware-based random number generation when available.
30+
31+
## Key Features
32+
33+
- Hardware-accelerated random number generation using Intel RDRAND instruction (when available)
34+
- Multiple entropy sources for enhanced security:
35+
- CPU-specific entropy (RDTSC, CPUID)
36+
- System performance metrics (timing, memory usage)
37+
- Process memory information
38+
- Disk space statistics
39+
- Network adapter and TCP statistics
40+
- Battery and power status information
41+
- Secure entropy mixing using SHA-256 via Windows BCrypt API
42+
- Thread-safe operation with proper synchronization
43+
- Configurable complexity levels for enhanced security
44+
- Fallback mechanisms when hardware RNG is unavailable
45+
46+
## API Reference
47+
48+
### `int test_rng_available(void)`
49+
Detects if the CPU supports the RDRAND instruction.
50+
51+
**Returns:**
52+
- `1` if RDRAND is supported
53+
- `0` if RDRAND is not supported
54+
55+
### `int test_threading_available(void)`
56+
Checks if threading primitives are initialized.
57+
58+
**Returns:**
59+
- `1` if threading primitives are initialized
60+
- `0` otherwise
61+
62+
### `int maxrng(unsigned char* buffer, const int size)`
63+
The primary RNG function that combines multiple entropy sources with basic complexity.
64+
65+
**Parameters:**
66+
- `buffer`: Pointer to the buffer to fill with random bytes
67+
- `size`: Number of bytes to generate
68+
69+
**Returns:**
70+
- `1` on success
71+
- `0` on failure
72+
73+
### `void maxrng_init(void)`
74+
Initializes threading primitives for thread-safe operation.
75+
This function must be called before using the thread-safe RNG functions.
76+
77+
If not called, the thread-safe RNG functions will not work correctly (crashing with invalid pointer errors).
78+
79+
> `test_threading_available` will always return `0` if this function has not been called.
80+
81+
**Returns:**
82+
- None
83+
84+
### `int maxrng_threadsafe(unsigned char* buffer, const int size)`
85+
Thread-safe wrapper for the RNG function.
86+
87+
**Parameters:**
88+
- `buffer`: Pointer to the buffer to fill with random bytes
89+
- `size`: Number of bytes to generate
90+
91+
**Returns:**
92+
- `1` on success
93+
- `0` on failure
94+
95+
### `int maxrng_ultra(unsigned char* buffer, const int size, int complexity)`
96+
Enhanced random number generation with configurable complexity level.
97+
98+
**Parameters:**
99+
- `buffer`: Pointer to the buffer to fill with random bytes
100+
- `size`: Number of bytes to generate
101+
- `complexity`: Level of entropy gathering intensity (1-10):
102+
- Higher values increase the number of entropy gathering rounds
103+
- Values are automatically clamped between 1 and 10
104+
105+
**Returns:**
106+
- `1` on success
107+
- `0` on failure
108+
109+
## Usage Examples
110+
111+
> [!IMPORTANT]
112+
> The following examples have not been tested in `C` - but the DLL worked in `Python` so minor tweaks should fix any issues in the provided examples.
113+
114+
### Basic Usage
115+
116+
```c
117+
#include <stdio.h>
118+
#include <windows.h>
119+
120+
// Import the DLL functions
121+
typedef int (*MaxRNG_Func)(unsigned char*, int);
122+
typedef int (*RngAvailable_Func)(void);
123+
124+
int main() {
125+
// Load the DLL
126+
HMODULE hRngDll = LoadLibrary("hRng.dll");
127+
if (!hRngDll) {
128+
printf("Failed to load hRng.dll\n");
129+
return 1;
130+
}
131+
132+
// Get function pointers
133+
MaxRNG_Func rng = (MaxRNG_Func)GetProcAddress(hRngDll, "maxrng");
134+
RngAvailable_Func rngAvailable = (RngAvailable_Func)GetProcAddress(hRngDll, "test_rng_available");
135+
136+
if (!rng || !rngAvailable) {
137+
printf("Failed to get function addresses\n");
138+
FreeLibrary(hRngDll);
139+
return 1;
140+
}
141+
142+
// Check if hardware RNG is available
143+
printf("Hardware RNG available: %s\n", rngAvailable() ? "Yes" : "No");
144+
145+
// Generate random bytes
146+
unsigned char buffer[32] = {0};
147+
if (rng(buffer, sizeof(buffer))) {
148+
printf("Random bytes generated successfully:\n");
149+
for (int i = 0; i < sizeof(buffer); i++) {
150+
printf("%02X ", buffer[i]);
151+
}
152+
printf("\n");
153+
} else {
154+
printf("Failed to generate random bytes\n");
155+
}
156+
157+
FreeLibrary(hRngDll);
158+
return 0;
159+
}
160+
```
161+
162+
### Thread-Safe Usage
163+
164+
```c
165+
#include <windows.h>
166+
#include <stdio.h>
167+
168+
// Import the DLL functions
169+
typedef void (*Init_Func)(void);
170+
typedef int (*ThreadSafe_RNG_Func)(unsigned char*, int);
171+
172+
DWORD WINAPI ThreadFunc(LPVOID lpParam) {
173+
ThreadSafe_RNG_Func rng = (ThreadSafe_RNG_Func)lpParam;
174+
175+
unsigned char buffer[16] = {0};
176+
int result = rng(buffer, sizeof(buffer));
177+
178+
// Print thread ID and result
179+
printf("Thread %lu: %s\n", GetCurrentThreadId(),
180+
result ? "Success" : "Failed");
181+
182+
return 0;
183+
}
184+
185+
int main() {
186+
HMODULE hRngDll = LoadLibrary("hRng.dll");
187+
if (!hRngDll) {
188+
printf("Failed to load hRng.dll\n");
189+
return 1;
190+
}
191+
192+
Init_Func init = (Init_Func)GetProcAddress(hRngDll, "maxrng_init");
193+
ThreadSafe_RNG_Func threadSafeRng =
194+
(ThreadSafe_RNG_Func)GetProcAddress(hRngDll, "maxrng_threadsafe");
195+
196+
if (!init || !threadSafeRng) {
197+
printf("Failed to get function addresses\n");
198+
FreeLibrary(hRngDll);
199+
return 1;
200+
}
201+
202+
// Initialize threading primitives
203+
init();
204+
205+
// Create multiple threads to test thread safety
206+
HANDLE threads[5];
207+
for (int i = 0; i < 5; i++) {
208+
threads[i] = CreateThread(NULL, 0, ThreadFunc,
209+
(LPVOID)threadSafeRng, 0, NULL);
210+
}
211+
212+
// Wait for all threads to complete
213+
WaitForMultipleObjects(5, threads, TRUE, INFINITE);
214+
215+
for (int i = 0; i < 5; i++) {
216+
CloseHandle(threads[i]);
217+
}
218+
219+
FreeLibrary(hRngDll);
220+
return 0;
221+
}
222+
```
223+
224+
### Using Ultra Mode for Maximum Security
225+
226+
```c
227+
#include <stdio.h>
228+
#include <windows.h>
229+
230+
// Import the DLL function
231+
typedef int (*MaxRNG_Ultra_Func)(unsigned char*, int, int);
232+
233+
int main() {
234+
HMODULE hRngDll = LoadLibrary("hRng.dll");
235+
if (!hRngDll) {
236+
printf("Failed to load hRng.dll\n");
237+
return 1;
238+
}
239+
240+
MaxRNG_Ultra_Func ultraRng =
241+
(MaxRNG_Ultra_Func)GetProcAddress(hRngDll, "maxrng_ultra");
242+
243+
if (!ultraRng) {
244+
printf("Failed to get function address\n");
245+
FreeLibrary(hRngDll);
246+
return 1;
247+
}
248+
249+
// Generate high-security random bytes (complexity level 10)
250+
unsigned char buffer[64] = {0};
251+
printf("Generating high-entropy random bytes...\n");
252+
253+
if (ultraRng(buffer, sizeof(buffer), 10)) {
254+
printf("Random bytes generated successfully:\n");
255+
for (int i = 0; i < sizeof(buffer); i++) {
256+
printf("%02X ", buffer[i]);
257+
if ((i + 1) % 16 == 0) printf("\n");
258+
}
259+
} else {
260+
printf("Failed to generate random bytes\n");
261+
}
262+
263+
FreeLibrary(hRngDll);
264+
return 0;
265+
}
266+
```
267+
268+
## Technical Details
269+
270+
### Entropy Sources
271+
272+
The library collects entropy from multiple sources:
273+
274+
1. **Hardware RNG (RDRAND)**
275+
- Uses Intel's RDRAND instruction when available
276+
- Implements retry logic for reliability (up to 10 retries)
277+
278+
2. **CPU-specific Sources**
279+
- RDTSC (Read Time-Stamp Counter)
280+
- CPUID information
281+
282+
3. **System Performance Metrics**
283+
- Process memory information via GetProcessMemoryInfo
284+
- High-precision performance counters via QueryPerformanceCounter
285+
286+
4. **Storage Information**
287+
- Disk free space statistics via GetDiskFreeSpaceEx
288+
289+
5. **Audio Timing**
290+
- Timing-based entropy collection with sleep intervals
291+
- Used as a fallback entropy source
292+
293+
6. **Battery/Power Information**
294+
- System power status via GetSystemPowerStatus
295+
296+
7. **Network Statistics**
297+
- TCP statistics via GetTcpStatistics
298+
- Network adapter information via GetAdaptersInfo
299+
300+
### Entropy Mixing
301+
302+
All entropy sources are securely combined using SHA-256 through the Windows BCrypt API:
303+
304+
- Multiple rounds of hashing based on the complexity parameter
305+
- Secure handling of hash state between rounds
306+
- Proper cleanup of cryptographic resources
307+
308+
### Thread Safety
309+
310+
- Uses Windows critical sections for thread synchronization
311+
- Initialization of threading primitives via maxrng_init()
312+
- Thread-safe API via maxrng_threadsafe()
313+
314+
### Security Considerations
315+
316+
- Multiple fallback mechanisms ensure reliability when hardware RNG is unavailable
317+
- Complexity parameter allows for trading off performance vs. security
318+
- Clean error handling with proper resource cleanup
319+
320+
## Building and Integration
321+
322+
### Requirements
323+
324+
- Windows operating system (Windows 7 or later)
325+
- Visual Studio or compatible C compiler
326+
- Required Windows libraries:
327+
- bcrypt.lib
328+
- winmm.lib
329+
- iphlpapi.lib
330+
- psapi.lib
331+
332+
### Linking with Your Application
333+
334+
When compiling your application, make sure to link against the required libraries:
335+
336+
```c
337+
#pragma comment(lib, "bcrypt.lib")
338+
#pragma comment(lib, "winmm.lib")
339+
#pragma comment(lib, "iphlpapi.lib")
340+
#pragma comment(lib, "psapi.lib")
341+
```
342+
343+
#### Dynamic Loading
344+
345+
```c
346+
HMODULE hRngDll = LoadLibrary("hRng.dll");
347+
if (hRngDll) {
348+
// Get function pointers using GetProcAddress
349+
// ...
350+
}
351+
```

0 commit comments

Comments
 (0)