// 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__IBAA64_h__OOO # define OOO__IBAA64_h__OOO # include // For: printf(3) # include // For: size_t # include // ``ISO C99''/``POSIX.1'' uint64_t // ^ means XOR, & means bitwise AND, a<> 24)) enum IBAA64OpType { IBAA64_OP_SUCCESS, IBAA64_OP_ERROR }; // IBAA64 // A 64-bit version of Bob Jenkins' IBAA CSPRNG, with a 64-bit counter // to ensure the cycle length is at least: 2^64. // class IBAA64 { private: // Memory: array of SIZE ALPHA-bit terms // uint64_t Memory [ IBAA64_SIZE ]; // Results: the sequence, same size as m // uint64_t Results [ IBAA64_SIZE ]; uint64_t aa; // Accumulator: a single value uint64_t bb; // the previous result uint64_t counter; // Guarantee 2^64 cycle length. public: IBAA64 (void) : aa(0), bb(0), counter(0) { for (size_t i = 0; i < IBAA64_SIZE; ++i) { Memory [ i ] = i; Results [ i ] = 0; } } // Return the size of the Results/Memory arrays: // size_t QueryResultsMemorySize (void) const { return IBAA64_SIZE; } // Set the initial seed (through controlled access): // IBAA64OpType SetMemory (const size_t i, const uint64_t value) { if (i >= 0 && i < IBAA64_SIZE) { Memory [ i ] = value; return IBAA64_OP_SUCCESS; } else { return IBAA64_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 IBAA64_SIZE Results: // void GenerateResults (void) { uint64_t a, b, x, y; a = aa; # ifdef IBAA64_USE_COUNTER b = (bb + counter++); # else b = bb; # endif for (size_t i = 0; i < IBAA64_SIZE; ++i) { x = Memory [ i ]; a = IBAA64_barrel(a) + Memory [ IBAA64_ind(i + (IBAA64_SIZE / 2)) ]; // set a Memory [ i ] = y = Memory [ IBAA64_ind(x) ] + a + b; // set m Results [ i ] = b = Memory [ IBAA64_ind(y >> IBAA64_ALPHA) ] + x; // set r } bb = b; aa = a; } // Call this method to query an indexed Result (after a call to the // GenerateResults() method): // uint64_t QueryResult (const size_t i, IBAA64OpType * const Success) const { if (i >= 0 && i < IBAA64_SIZE) { *Success = IBAA64_OP_SUCCESS; return Results [ i ]; } else { *Success = IBAA64_OP_ERROR; return 0; } } void printState (void) const { printf ("aa = %llu\n", aa); printf ("bb = %llu\n", bb); for (size_t i = 0; i < IBAA64_SIZE; ++i) { printf ("MEM[%u] = %llu, ", i, Memory [ i ]); } printf ("\n"); for (size_t i = 0; i < IBAA64_SIZE; ++i) { printf ("RES[%u] = %llu, ", i, Results [ i ]); } printf ("\n"); } }; # endif // !OOO__IBAA64_h__OOO