Skip to content

Commit 046ee64

Browse files
author
Christian
committed
Add RAII memory management, estimator tracking, and detailed test results in entropy calculations
- Introduce `DataGuard` class for automated cleanup using RAII. - Add per-estimator tracking and result population in `EntropyResult`. - Replace VLAs with `std::array` for C++ standard compliance. - Update gRPC layer to expose detailed test results and individual estimator details for IID and Non-IID assessments. - Enhance unit tests to validate individual estimator outputs and counts.
1 parent 216a6fb commit 046ee64

7 files changed

Lines changed: 219 additions & 42 deletions

File tree

internal/entropy/cgo_bridge.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,11 +49,32 @@ func calculateIIDEntropy(data []byte, bitsPerSymbol int, verbose int) (*Result,
4949
HAssessed: float64(cResult.h_assessed),
5050
DataWordSize: int(cResult.data_word_size),
5151
TestType: IID,
52+
Estimators: convertEstimators(cResult),
5253
}
5354

5455
return result, nil
5556
}
5657

58+
// convertEstimators converts C estimator array to Go slice
59+
func convertEstimators(cResult *C.EntropyResult) []EstimatorResult {
60+
count := int(cResult.estimator_count)
61+
if count <= 0 {
62+
return nil
63+
}
64+
65+
estimators := make([]EstimatorResult, count)
66+
for i := 0; i < count; i++ {
67+
cEst := cResult.estimators[i]
68+
estimators[i] = EstimatorResult{
69+
Name: C.GoString(&cEst.name[0]),
70+
EntropyEstimate: float64(cEst.entropy_estimate),
71+
Passed: bool(cEst.passed),
72+
IsEntropyValid: bool(cEst.is_entropy_valid),
73+
}
74+
}
75+
return estimators
76+
}
77+
5778
// calculateNonIIDEntropy calls the C wrapper to perform Non-IID entropy calculation
5879
func calculateNonIIDEntropy(data []byte, bitsPerSymbol int, verbose int) (*Result, error) {
5980
if len(data) == 0 {
@@ -90,6 +111,7 @@ func calculateNonIIDEntropy(data []byte, bitsPerSymbol int, verbose int) (*Resul
90111
HAssessed: float64(cResult.h_assessed),
91112
DataWordSize: int(cResult.data_word_size),
92113
TestType: NonIID,
114+
Estimators: convertEstimators(cResult),
93115
}
94116

95117
return result, nil

internal/entropy/cgo_stub.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,32 @@ import "math"
66

77
// Test stub for CGO-backed functions to allow fast unit testing without the C++ library.
88

9+
// stubIIDEstimators returns mock IID estimator results
10+
func stubIIDEstimators() []EstimatorResult {
11+
return []EstimatorResult{
12+
{Name: "Most Common Value", EntropyEstimate: 7.6, Passed: true, IsEntropyValid: true},
13+
{Name: "Chi-Square Tests", EntropyEstimate: -1.0, Passed: true, IsEntropyValid: false},
14+
{Name: "Length of Longest Repeated Substring Test", EntropyEstimate: -1.0, Passed: true, IsEntropyValid: false},
15+
{Name: "Permutation Tests", EntropyEstimate: -1.0, Passed: true, IsEntropyValid: false},
16+
}
17+
}
18+
19+
// stubNonIIDEstimators returns mock Non-IID estimator results
20+
func stubNonIIDEstimators() []EstimatorResult {
21+
return []EstimatorResult{
22+
{Name: "Most Common Value", EntropyEstimate: 6.8, Passed: true, IsEntropyValid: true},
23+
{Name: "Collision Test", EntropyEstimate: 6.9, Passed: true, IsEntropyValid: true},
24+
{Name: "Markov Test", EntropyEstimate: 6.7, Passed: true, IsEntropyValid: true},
25+
{Name: "Compression Test", EntropyEstimate: 6.5, Passed: true, IsEntropyValid: true},
26+
{Name: "t-Tuple Test", EntropyEstimate: 6.6, Passed: true, IsEntropyValid: true},
27+
{Name: "LRS Test", EntropyEstimate: 6.8, Passed: true, IsEntropyValid: true},
28+
{Name: "Multi Most Common in Window Test", EntropyEstimate: 6.7, Passed: true, IsEntropyValid: true},
29+
{Name: "Lag Prediction Test", EntropyEstimate: 6.9, Passed: true, IsEntropyValid: true},
30+
{Name: "Multi Markov Model with Counting Test", EntropyEstimate: 6.6, Passed: true, IsEntropyValid: true},
31+
{Name: "LZ78Y Test", EntropyEstimate: 6.5, Passed: true, IsEntropyValid: true},
32+
}
33+
}
34+
935
func calculateIIDEntropy(data []byte, bitsPerSymbol int, verbose int) (*Result, error) {
1036
if len(data) > 0 && data[0] == 0xFF {
1137
return nil, newError("calculateIIDEntropy", ErrInvalidData, "stub failure")
@@ -18,6 +44,7 @@ func calculateIIDEntropy(data []byte, bitsPerSymbol int, verbose int) (*Result,
1844
HAssessed: math.Inf(1),
1945
DataWordSize: bitsPerSymbol,
2046
TestType: IID,
47+
Estimators: nil,
2148
}, nil
2249
}
2350
return &Result{
@@ -27,6 +54,7 @@ func calculateIIDEntropy(data []byte, bitsPerSymbol int, verbose int) (*Result,
2754
HAssessed: 7.5,
2855
DataWordSize: bitsPerSymbol,
2956
TestType: IID,
57+
Estimators: stubIIDEstimators(),
3058
}, nil
3159
}
3260

@@ -42,6 +70,7 @@ func calculateNonIIDEntropy(data []byte, bitsPerSymbol int, verbose int) (*Resul
4270
HAssessed: math.Inf(1),
4371
DataWordSize: bitsPerSymbol,
4472
TestType: NonIID,
73+
Estimators: nil,
4574
}, nil
4675
}
4776
return &Result{
@@ -51,5 +80,6 @@ func calculateNonIIDEntropy(data []byte, bitsPerSymbol int, verbose int) (*Resul
5180
HAssessed: 6.5,
5281
DataWordSize: bitsPerSymbol,
5382
TestType: NonIID,
83+
Estimators: stubNonIIDEstimators(),
5484
}, nil
5585
}

internal/entropy/types.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,14 @@ func (t TestType) String() string {
2222
}
2323
}
2424

25+
// EstimatorResult contains the result of a single NIST SP 800-90B estimator
26+
type EstimatorResult struct {
27+
Name string // Estimator name (e.g., "Most Common Value")
28+
EntropyEstimate float64 // Entropy estimate (-1.0 if not applicable)
29+
Passed bool // Whether the test passed
30+
IsEntropyValid bool // true if EntropyEstimate is valid
31+
}
32+
2533
// Result contains the entropy assessment results
2634
type Result struct {
2735
MinEntropy float64 // Minimum entropy estimate
@@ -30,6 +38,9 @@ type Result struct {
3038
HAssessed float64 // Assessed entropy value
3139
DataWordSize int // Bits per symbol
3240
TestType TestType // Type of test performed
41+
42+
// Individual estimator results
43+
Estimators []EstimatorResult
3344
}
3445

3546
// Assessment configuration

0 commit comments

Comments
 (0)