// Copyright (C) 2010-2011 Robin Carey. All rights reserved. // // This is public domain, just like the original IBAA algorithm (on // which this is based); written/developed by Bob Jenkins'; // http://www.burtleburtle.net/bob // http://www.burtleburtle.net/bob/rand/isaac.html // # ifndef OOO__IBAA32_h__OOO # define OOO__IBAA32_h__OOO # include // For: printf(3) # include // For: size_t # include // ``ISO C99''/``POSIX.1'' uint32_t // ^ means XOR, & means bitwise AND, a<> 12)) enum IBAA32OpType { IBAA32_OP_SUCCESS, IBAA32_OP_ERROR }; // IBAA32 // A 32-bit version of Bob Jenkins' IBAA CSPRNG, with a 32-bit counter // to ensure the cycle length is at least: 2^32. Also, the correctly // rounded up BETA(32)/SHIFT value of 20 is used (as opposed to 19 in // the original algorithm/source-code). // class IBAA32 { private: // Memory: array of SIZE ALPHA-bit terms // uint32_t Memory [ IBAA32_SIZE ]; // Results: the sequence, same size as m // uint32_t Results [ IBAA32_SIZE ]; uint32_t aa; // Accumulator: a single value uint32_t bb; // the previous result uint32_t counter; // Guarantee 2^32 cycle length. public: IBAA32 (void) : aa(0), bb(0), counter(0) { for (size_t i = 0; i < IBAA32_SIZE; ++i) { Memory [ i ] = i; Results [ i ] = 0; } } // Return the size of the Results/Memory arrays: // size_t QueryResultsMemorySize (void) const { return IBAA32_SIZE; } // Set the initial seed (through controlled access): // IBAA32OpType SetMemory (const size_t i, const uint32_t value) { if (i >= 0 && i < IBAA32_SIZE) { Memory [ i ] = value; return IBAA32_OP_SUCCESS; } else { return IBAA32_OP_ERROR; } } // Call this function to remove weak initial states (which // leak the internal state): // void WarmUp (void) { for (size_t i = 0; i < 10; ++i) { GenerateResults (); } } // Generate IBAA32_SIZE Results: // void GenerateResults (void) { uint32_t a, b, x, y; a = aa; # ifdef IBAA32_USE_COUNTER b = (bb + counter++); # else b = bb; # endif for (size_t i = 0; i < IBAA32_SIZE; ++i) { x = Memory [ i ]; a = IBAA32_barrel(a) + Memory [ IBAA32_ind(i + (IBAA32_SIZE / 2)) ]; // set a Memory [ i ] = y = Memory [ IBAA32_ind(x) ] + a + b; // set m Results [ i ] = b = Memory [ IBAA32_ind(y >> IBAA32_ALPHA) ] + x; // set r } bb = b; aa = a; } // Call this method to query an indexed Result (after a call to the // GenerateResults() method): // uint32_t QueryResult (const size_t i, IBAA32OpType * const Success) const { if (i >= 0 && i < IBAA32_SIZE) { *Success = IBAA32_OP_SUCCESS; return Results [ i ]; } else { *Success = IBAA32_OP_ERROR; return 0; } } void printState (void) const { printf ("aa = %u\n", aa); printf ("bb = %u\n", bb); for (size_t i = 0; i < IBAA32_SIZE; ++i) { printf ("MEM[%u] = %u, ", i, Memory [ i ]); } printf ("\n"); for (size_t i = 0; i < IBAA32_SIZE; ++i) { printf ("RES[%u] = %u, ", i, Results [ i ]); } printf ("\n"); } }; # endif // !OOO__IBAA32_h__OOO