mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00
Migrate entropy testing to opaque.
This commit is contained in:
parent
86faab1e06
commit
b9d05f56d0
7 changed files with 156 additions and 87 deletions
100
src/OpaqueVal.cc
100
src/OpaqueVal.cc
|
@ -398,3 +398,103 @@ bool SHA256Val::DoUnserialize(UnserialInfo* info)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool EntropyVal::Feed(const void* data, size_t size)
|
||||
{
|
||||
state.add(data, size);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EntropyVal::Get(double *r_ent, double *r_chisq, double *r_mean,
|
||||
double *r_montepicalc, double *r_scc)
|
||||
{
|
||||
state.end(r_ent, r_chisq, r_mean, r_montepicalc, r_scc);
|
||||
return true;
|
||||
}
|
||||
|
||||
IMPLEMENT_SERIAL(EntropyVal, SER_ENTROPY_VAL);
|
||||
|
||||
bool EntropyVal::DoSerialize(SerialInfo* info) const
|
||||
{
|
||||
DO_SERIALIZE(SER_ENTROPY_VAL, OpaqueVal);
|
||||
|
||||
for ( int i = 0; i < 256; ++i )
|
||||
if ( ! SERIALIZE(state.ccount[i]) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.totalc) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.mp) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.sccfirst) )
|
||||
return false;
|
||||
for ( int i = 0; i < RT_MONTEN; ++i )
|
||||
if ( ! SERIALIZE(state.monte[i]) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.inmont) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.mcount) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.cexp) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.montex) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.montey) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.montepi) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.sccu0) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.scclast) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.scct1) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.scct2) )
|
||||
return false;
|
||||
if ( ! SERIALIZE(state.scct3) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EntropyVal::DoUnserialize(UnserialInfo* info)
|
||||
{
|
||||
DO_UNSERIALIZE(OpaqueVal);
|
||||
|
||||
for ( int i = 0; i < 256; ++i )
|
||||
if ( ! UNSERIALIZE(&state.ccount[i]) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.totalc) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.mp) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.sccfirst) )
|
||||
return false;
|
||||
for ( int i = 0; i < RT_MONTEN; ++i )
|
||||
if ( ! UNSERIALIZE(&state.monte[i]) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.inmont) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.mcount) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.cexp) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.montex) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.montey) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.montepi) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.sccu0) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.scclast) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.scct1) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.scct2) )
|
||||
return false;
|
||||
if ( ! UNSERIALIZE(&state.scct3) )
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef OPAQUEVAL_H
|
||||
#define OPAQUEVAL_H
|
||||
|
||||
#include "RandTest.h"
|
||||
#include "Val.h"
|
||||
#include "digest.h"
|
||||
|
||||
|
@ -86,4 +87,22 @@ private:
|
|||
SHA256_CTX ctx;
|
||||
};
|
||||
|
||||
class EntropyVal : public OpaqueVal {
|
||||
public:
|
||||
EntropyVal() : OpaqueVal(new OpaqueType("entropy")) { }
|
||||
|
||||
bool Feed(const void* data, size_t size);
|
||||
bool Get(double *r_ent, double *r_chisq, double *r_mean,
|
||||
double *r_montepicalc, double *r_scc);
|
||||
|
||||
protected:
|
||||
friend class Val;
|
||||
EntropyVal(OpaqueType* t);
|
||||
|
||||
DECLARE_SERIAL(EntropyVal);
|
||||
|
||||
private:
|
||||
RandTest state;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
Modified for Bro by Seth Hall - July 2010
|
||||
*/
|
||||
|
||||
#include <math.h>
|
||||
#include "RandTest.h"
|
||||
|
||||
#define log2of10 3.32192809488736234787
|
||||
|
|
|
@ -1,11 +1,14 @@
|
|||
#include <math.h>
|
||||
#ifndef RANDTEST_H
|
||||
#define RANDTEST_H
|
||||
|
||||
class EntropyVal;
|
||||
#include "util.h"
|
||||
|
||||
#define RT_MONTEN 6 /* Bytes used as Monte Carlo
|
||||
co-ordinates. This should be no more
|
||||
bits than the mantissa of your "double"
|
||||
floating point type. */
|
||||
class EntropyVal;
|
||||
|
||||
|
||||
class RandTest {
|
||||
public:
|
||||
|
@ -17,12 +20,14 @@ class RandTest {
|
|||
private:
|
||||
friend class EntropyVal;
|
||||
|
||||
long ccount[256]; /* Bins to count occurrences of values */
|
||||
long totalc; /* Total bytes counted */
|
||||
int64 ccount[256]; /* Bins to count occurrences of values */
|
||||
int64 totalc; /* Total bytes counted */
|
||||
int mp;
|
||||
int sccfirst;
|
||||
unsigned int monte[RT_MONTEN];
|
||||
long inmont, mcount;
|
||||
int64 inmont, mcount;
|
||||
double cexp, montex, montey, montepi,
|
||||
sccu0, scclast, scct1, scct2, scct3;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -103,6 +103,7 @@ SERIAL_VAL(HASH_VAL, 15)
|
|||
SERIAL_VAL(MD5_VAL, 16)
|
||||
SERIAL_VAL(SHA1_VAL, 17)
|
||||
SERIAL_VAL(SHA256_VAL, 18)
|
||||
SERIAL_VAL(ENTROPY_VAL, 19)
|
||||
|
||||
#define SERIAL_EXPR(name, val) SERIAL_CONST(name, val, EXPR)
|
||||
SERIAL_EXPR(EXPR, 1)
|
||||
|
|
87
src/bro.bif
87
src/bro.bif
|
@ -878,11 +878,6 @@ function identify_data%(data: string, return_mime: bool%): string
|
|||
return new StringVal(descr);
|
||||
%}
|
||||
|
||||
%%{
|
||||
#include <RandTest.h>
|
||||
static map<BroString, RandTest*> entropy_states;
|
||||
%%}
|
||||
|
||||
## Performs an entropy test on the given data.
|
||||
## See http://www.fourmilab.ch/random.
|
||||
##
|
||||
|
@ -927,13 +922,11 @@ function find_entropy%(data: string%): entropy_test_result
|
|||
%{
|
||||
double montepi, scc, ent, mean, chisq;
|
||||
montepi = scc = ent = mean = chisq = 0.0;
|
||||
EntropyVal e;
|
||||
e.Feed(data->Bytes(), data->Len());
|
||||
e.Get(&ent, &chisq, &mean, &montepi, &scc);
|
||||
|
||||
RecordVal* ent_result = new RecordVal(entropy_test_result);
|
||||
RandTest *rt = new RandTest();
|
||||
|
||||
rt->add((char*) data->Bytes(), data->Len());
|
||||
rt->end(&ent, &chisq, &mean, &montepi, &scc);
|
||||
delete rt;
|
||||
|
||||
ent_result->Assign(0, new Val(ent, TYPE_DOUBLE));
|
||||
ent_result->Assign(1, new Val(chisq, TYPE_DOUBLE));
|
||||
ent_result->Assign(2, new Val(mean, TYPE_DOUBLE));
|
||||
|
@ -942,98 +935,54 @@ function find_entropy%(data: string%): entropy_test_result
|
|||
return ent_result;
|
||||
%}
|
||||
|
||||
%%{
|
||||
BroString* convert_index_to_string(Val* index)
|
||||
{
|
||||
ODesc d;
|
||||
index->Describe(&d);
|
||||
BroString* s = new BroString(1, d.TakeBytes(), d.Len());
|
||||
s->SetUseFreeToDelete(1);
|
||||
return s;
|
||||
}
|
||||
%%}
|
||||
|
||||
## Initializes data structures for incremental entropy calculation.
|
||||
##
|
||||
## index: An arbitrary unique value per distinct computation.
|
||||
##
|
||||
## Returns: True on success.
|
||||
## Returns: An opaque handle to be used in subsequent operations.
|
||||
##
|
||||
## .. bro:see:: find_entropy entropy_test_add entropy_test_finish
|
||||
function entropy_test_init%(index: any%): bool
|
||||
function entropy_test_init%(%): opaque of entropy
|
||||
%{
|
||||
BroString* s = convert_index_to_string(index);
|
||||
int status = 0;
|
||||
|
||||
if ( entropy_states.count(*s) < 1 )
|
||||
{
|
||||
entropy_states[*s] = new RandTest();
|
||||
status = 1;
|
||||
}
|
||||
|
||||
delete s;
|
||||
return new Val(status, TYPE_BOOL);
|
||||
return new EntropyVal();
|
||||
%}
|
||||
|
||||
## Adds data to an incremental entropy calculation. Before using this function,
|
||||
## one needs to invoke :bro:id:`entropy_test_init`.
|
||||
## Adds data to an incremental entropy calculation.
|
||||
##
|
||||
## handle: The opaque handle representing the entropy calculation state.
|
||||
##
|
||||
## data: The data to add to the entropy calculation.
|
||||
##
|
||||
## index: An arbitrary unique value that identifies a particular entropy
|
||||
## computation.
|
||||
##
|
||||
## Returns: True on success.
|
||||
##
|
||||
## .. bro:see:: find_entropy entropy_test_add entropy_test_finish
|
||||
function entropy_test_add%(index: any, data: string%): bool
|
||||
function entropy_test_add%(handle: opaque of entropy, data: string%): bool
|
||||
%{
|
||||
BroString* s = convert_index_to_string(index);
|
||||
int status = 0;
|
||||
|
||||
if ( entropy_states.count(*s) > 0 )
|
||||
{
|
||||
entropy_states[*s]->add((char*) data->Bytes(), data->Len());
|
||||
status = 1;
|
||||
}
|
||||
|
||||
delete s;
|
||||
bool status = static_cast<EntropyVal*>(handle)->Feed(data->Bytes(),
|
||||
data->Len());
|
||||
return new Val(status, TYPE_BOOL);
|
||||
%}
|
||||
|
||||
## Finishes an incremental entropy calculation. Before using this function,
|
||||
## one needs to initialize the computation with :bro:id:`entropy_test_init` and
|
||||
## one needs to obtain an opaque handle with :bro:id:`entropy_test_init` and
|
||||
## add data to it via :bro:id:`entropy_test_add`.
|
||||
##
|
||||
## index: An arbitrary unique value that identifies a particular entropy
|
||||
## computation.
|
||||
## handle: The opaque handle representing the entropy calculation state.
|
||||
##
|
||||
## Returns: The result of the entropy test. See :bro:id:`find_entropy` for a
|
||||
## description of the individual components.
|
||||
##
|
||||
## .. bro:see:: find_entropy entropy_test_init entropy_test_add
|
||||
function entropy_test_finish%(index: any%): entropy_test_result
|
||||
function entropy_test_finish%(handle: opaque of entropy%): entropy_test_result
|
||||
%{
|
||||
BroString* s = convert_index_to_string(index);
|
||||
double montepi, scc, ent, mean, chisq;
|
||||
montepi = scc = ent = mean = chisq = 0.0;
|
||||
static_cast<EntropyVal*>(handle)->Get(&ent, &chisq, &mean, &montepi, &scc);
|
||||
|
||||
RecordVal* ent_result = new RecordVal(entropy_test_result);
|
||||
|
||||
if ( entropy_states.count(*s) > 0 )
|
||||
{
|
||||
RandTest *rt = entropy_states[*s];
|
||||
rt->end(&ent, &chisq, &mean, &montepi, &scc);
|
||||
entropy_states.erase(*s);
|
||||
delete rt;
|
||||
}
|
||||
|
||||
ent_result->Assign(0, new Val(ent, TYPE_DOUBLE));
|
||||
ent_result->Assign(1, new Val(chisq, TYPE_DOUBLE));
|
||||
ent_result->Assign(2, new Val(mean, TYPE_DOUBLE));
|
||||
ent_result->Assign(3, new Val(montepi, TYPE_DOUBLE));
|
||||
ent_result->Assign(4, new Val(scc, TYPE_DOUBLE));
|
||||
|
||||
delete s;
|
||||
return ent_result;
|
||||
%}
|
||||
|
||||
|
|
|
@ -5,20 +5,14 @@
|
|||
event bro_init()
|
||||
{
|
||||
local a = "dh3Hie02uh^s#Sdf9L3frd243h$d78r2G4cM6*Q05d(7rh46f!0|4-f";
|
||||
if ( entropy_test_init(1) != T )
|
||||
local handle = entropy_test_init();
|
||||
if ( ! entropy_test_add(handle, a) )
|
||||
exit(1);
|
||||
|
||||
if ( entropy_test_add(1, a) != T )
|
||||
exit(1);
|
||||
|
||||
print entropy_test_finish(1);
|
||||
print entropy_test_finish(handle);
|
||||
|
||||
local b = "0011000aaabbbbcccc000011111000000000aaaabbbbcccc0000000";
|
||||
if ( entropy_test_init(2) != T )
|
||||
handle = entropy_test_init();
|
||||
if ( ! entropy_test_add(handle, b) )
|
||||
exit(1);
|
||||
|
||||
if ( entropy_test_add(2, b) != T )
|
||||
exit(1);
|
||||
|
||||
print entropy_test_finish(2);
|
||||
print entropy_test_finish(handle);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue