mirror of
				https://github.com/paboyle/Grid.git
				synced 2025-10-31 12:04:33 +00:00 
			
		
		
		
	Added and tested SITMO PRNG
This commit is contained in:
		| @@ -319,7 +319,7 @@ AM_CONDITIONAL(BUILD_COMMS_MPI3L, [ test "${comms_type}X" == "mpi3lX" ] ) | |||||||
| AM_CONDITIONAL(BUILD_COMMS_NONE,  [ test "${comms_type}X" == "noneX" ]) | AM_CONDITIONAL(BUILD_COMMS_NONE,  [ test "${comms_type}X" == "noneX" ]) | ||||||
|  |  | ||||||
| ############### RNG selection | ############### RNG selection | ||||||
| AC_ARG_ENABLE([rng],[AC_HELP_STRING([--enable-rng=ranlux48|mt19937],\ | AC_ARG_ENABLE([rng],[AC_HELP_STRING([--enable-rng=ranlux48|mt19937|sitmo],\ | ||||||
| 	            [Select Random Number Generator to be used])],\ | 	            [Select Random Number Generator to be used])],\ | ||||||
| 	            [ac_RNG=${enable_rng}],[ac_RNG=ranlux48]) | 	            [ac_RNG=${enable_rng}],[ac_RNG=ranlux48]) | ||||||
|  |  | ||||||
| @@ -330,6 +330,9 @@ case ${ac_RNG} in | |||||||
|      mt19937) |      mt19937) | ||||||
|       AC_DEFINE([RNG_MT19937],[1],[RNG_MT19937] ) |       AC_DEFINE([RNG_MT19937],[1],[RNG_MT19937] ) | ||||||
|      ;; |      ;; | ||||||
|  |      sitmo) | ||||||
|  |       AC_DEFINE([RNG_SITMO],[1],[RNG_SITMO] ) | ||||||
|  |      ;; | ||||||
|      *) |      *) | ||||||
|       AC_MSG_ERROR([${ac_RNG} unsupported --enable-rng option]);  |       AC_MSG_ERROR([${ac_RNG} unsupported --enable-rng option]);  | ||||||
|      ;; |      ;; | ||||||
|   | |||||||
| @@ -30,6 +30,7 @@ Author: paboyle <paboyle@ph.ed.ac.uk> | |||||||
| #define GRID_LATTICE_RNG_H | #define GRID_LATTICE_RNG_H | ||||||
|  |  | ||||||
| #include <random> | #include <random> | ||||||
|  | #include <Grid/sitmo_rng/sitmo_prng_engine.hpp> | ||||||
|  |  | ||||||
| namespace Grid { | namespace Grid { | ||||||
|  |  | ||||||
| @@ -114,10 +115,14 @@ namespace Grid { | |||||||
|     typedef uint64_t      RngStateType; |     typedef uint64_t      RngStateType; | ||||||
|     typedef std::ranlux48 RngEngine; |     typedef std::ranlux48 RngEngine; | ||||||
|     static const int RngStateCount = 15; |     static const int RngStateCount = 15; | ||||||
| #else | #elif RNG_MT19937  | ||||||
|     typedef std::mt19937 RngEngine; |     typedef std::mt19937 RngEngine; | ||||||
|     typedef uint32_t     RngStateType; |     typedef uint32_t     RngStateType; | ||||||
|     static const int     RngStateCount = std::mt19937::state_size; |     static const int     RngStateCount = std::mt19937::state_size; | ||||||
|  | #elif RNG_SITMO | ||||||
|  |     typedef sitmo::prng_engine 	RngEngine; | ||||||
|  |     typedef uint64_t    	RngStateType; | ||||||
|  |     static const int    	RngStateCount = 4; | ||||||
| #endif | #endif | ||||||
|     std::vector<RngEngine>                             _generators; |     std::vector<RngEngine>                             _generators; | ||||||
|     std::vector<std::uniform_real_distribution<RealD>> _uniform; |     std::vector<std::uniform_real_distribution<RealD>> _uniform; | ||||||
|   | |||||||
							
								
								
									
										385
									
								
								lib/sitmo_rng/sitmo_prng_engine.hpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										385
									
								
								lib/sitmo_rng/sitmo_prng_engine.hpp
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,385 @@ | |||||||
|  | //  Copyright (c) 2012-2013 M.A. (Thijs) van den Berg, http://sitmo.com/ | ||||||
|  | // | ||||||
|  | //  Use, modification and distribution are subject to the MIT Software License.  | ||||||
|  | //   | ||||||
|  | //  The MIT License (MIT) | ||||||
|  | //  Permission is hereby granted, free of charge, to any person obtaining a copy | ||||||
|  | //  of this software and associated documentation files (the "Software"), to deal | ||||||
|  | //  in the Software without restriction, including without limitation the rights | ||||||
|  | //  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||||||
|  | //  copies of the Software, and to permit persons to whom the Software is | ||||||
|  | //  furnished to do so, subject to the following conditions: | ||||||
|  | //   | ||||||
|  | //  The above copyright notice and this permission notice shall be included in | ||||||
|  | //  all copies or substantial portions of the Software. | ||||||
|  | //   | ||||||
|  | //  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||||||
|  | //  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||||||
|  | //  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||||||
|  | //  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||||||
|  | //  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||||||
|  | //  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||||||
|  | //  THE SOFTWARE. | ||||||
|  |  | ||||||
|  | // version history: | ||||||
|  | // version 1,  6 Sep 2012 | ||||||
|  | // version 2, 10 Dec 2013 | ||||||
|  | //      bug fix in the discard() routine, it was discarding to many elements | ||||||
|  | //      added the version() method | ||||||
|  | // version 3...5, 13 Dec 2013 | ||||||
|  | //      fixed type-conversion earning | ||||||
|  | //      fixed potential issues with constructor template matching | ||||||
|  |  | ||||||
|  | #ifndef SITMO_PRNG_ENGINE_HPP | ||||||
|  | #define SITMO_PRNG_ENGINE_HPP | ||||||
|  | #include <iostream> | ||||||
|  |  | ||||||
|  | #ifdef __GNUC__ | ||||||
|  |     #include <stdint.h>                 // respecting the C99 standard. | ||||||
|  | #endif | ||||||
|  | #ifdef _MSC_VER | ||||||
|  |     typedef unsigned __int64 uint64_t;  // Visual Studio 6.0(VC6) and newer.. | ||||||
|  |     typedef unsigned __int32 uint32_t; | ||||||
|  | #endif | ||||||
|  |  | ||||||
|  | // Double mixing function | ||||||
|  | #define MIX2(x0,x1,rx,z0,z1,rz) \ | ||||||
|  |     x0 += x1; \ | ||||||
|  |     z0 += z1; \ | ||||||
|  |     x1 = (x1 << rx) | (x1 >> (64-rx)); \ | ||||||
|  |     z1 = (z1 << rz) | (z1 >> (64-rz)); \ | ||||||
|  |     x1 ^= x0; \ | ||||||
|  |     z1 ^= z0;  | ||||||
|  |  | ||||||
|  |  | ||||||
|  | // Double mixing function with key adition | ||||||
|  | #define MIXK(x0,x1,rx,z0,z1,rz,k0,k1,l0,l1) \ | ||||||
|  |     x1 += k1; \ | ||||||
|  |     z1 += l1; \ | ||||||
|  |     x0 += x1+k0; \ | ||||||
|  |     z0 += z1+l0; \ | ||||||
|  |     x1 = (x1 << rx) | (x1 >> (64-rx)); \ | ||||||
|  |     z1 = (z1 << rz) | (z1 >> (64-rz)); \ | ||||||
|  |     x1 ^= x0; \ | ||||||
|  |     z1 ^= z0; \ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | namespace sitmo { | ||||||
|  |  | ||||||
|  |     // enable_if for C__98 compilers | ||||||
|  |     template<bool C, typename T = void> | ||||||
|  |     struct sitmo_enable_if { typedef T type; }; | ||||||
|  |  | ||||||
|  |     template<typename T> | ||||||
|  |     struct sitmo_enable_if<false, T> { }; | ||||||
|  |  | ||||||
|  |     // SFINAE check for the existence of a "void generate(int*,int*)"member function | ||||||
|  |     template<typename T> | ||||||
|  |     struct has_generate_template | ||||||
|  |     { | ||||||
|  |         typedef char (&Two)[2];; | ||||||
|  |         template<typename F, void (F::*)(int *, int *)> struct helper {}; | ||||||
|  |         template<typename C> static char test(helper<C, &C::template generate<int*> >*); | ||||||
|  |         template<typename C> static Two test(...); | ||||||
|  |         static bool const value = sizeof(test<T>(0)) == sizeof(char); | ||||||
|  |     }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | class prng_engine | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |     // "req" are requirements as stated in the C++ 11 draft n3242=11-0012 | ||||||
|  |     // | ||||||
|  |     // req: 26.5.1.3 Uniform random number generator requirements, p.906, table 116, row 1 | ||||||
|  |     typedef uint32_t result_type; | ||||||
|  |      | ||||||
|  |     // req: 26.5.1.3 Uniform random number generator requirements, p.906, table 116, row 3 | ||||||
|  |     static result_type (min)() { return 0; } | ||||||
|  |  | ||||||
|  |     // req: 26.5.1.3 Uniform random number generator requirements, p.906, table 116, row 4 | ||||||
|  |     static result_type (max)() { return 0xFFFFFFFF; } | ||||||
|  |  | ||||||
|  |     // ------------------------------------------------- | ||||||
|  |     // Constructors | ||||||
|  |     // ------------------------------------------------- | ||||||
|  |  | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.907 table 117, row 1 | ||||||
|  |     // Creates an engine with the same initial state as all other | ||||||
|  |     // default-constructed engines of type E. | ||||||
|  |     prng_engine()  | ||||||
|  |     { | ||||||
|  |         seed(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.907 table 117, row 2 | ||||||
|  |     // Creates an engine that compares equal to x. | ||||||
|  |     prng_engine(const prng_engine& x) | ||||||
|  |     { | ||||||
|  |         for (unsigned short i=0; i<4; ++i) { | ||||||
|  |             _s[i] = x._s[i]; | ||||||
|  |             _k[i] = x._k[i]; | ||||||
|  |             _o[i] = x._o[i]; | ||||||
|  |         } | ||||||
|  |         _o_counter = x._o_counter; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.907 table 117, row 3 | ||||||
|  |     // Creates an engine with initial O(size of state) state determined by s. | ||||||
|  |     prng_engine(uint32_t s)  | ||||||
|  |     { | ||||||
|  |         seed(s); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |         // req: 26.5.1.4 Random number engine requirements, p.908 table 117, row 4 | ||||||
|  |     // Creates an engine with an initial state that depends on a sequence | ||||||
|  |     // produced by one call to q.generate. | ||||||
|  |     template<class Seq>  | ||||||
|  |     prng_engine(Seq& q, typename sitmo_enable_if< has_generate_template<Seq>::value >::type* = 0 ) | ||||||
|  |     { | ||||||
|  |         seed(q); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // ------------------------------------------------- | ||||||
|  |     // Seeding | ||||||
|  |     // ------------------------------------------------- | ||||||
|  |      | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.908 table 117, row 5 | ||||||
|  |     void seed() | ||||||
|  |     { | ||||||
|  |         for (unsigned short i=0; i<4; ++i) { | ||||||
|  |             _k[i] = 0; | ||||||
|  |             _s[i] = 0; | ||||||
|  |         } | ||||||
|  |         _o_counter = 0; | ||||||
|  |  | ||||||
|  |         _o[0] = 0x09218ebde6c85537; | ||||||
|  |         _o[1] = 0x55941f5266d86105; | ||||||
|  |         _o[2] = 0x4bd25e16282434dc; | ||||||
|  |         _o[3] = 0xee29ec846bd2e40b; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.908 table 117, row 6 | ||||||
|  |     // s needs to be of return_type, which is uint32_t | ||||||
|  |     void seed(uint32_t s) | ||||||
|  |     {  | ||||||
|  |         for (unsigned short i=0; i<4; ++i) { | ||||||
|  |             _k[i] = 0; | ||||||
|  |             _s[i] = 0; | ||||||
|  |         } | ||||||
|  |         _k[0] = s;  | ||||||
|  |         _o_counter = 0; | ||||||
|  |          | ||||||
|  |         encrypt_counter(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.908 table 117, row 7 | ||||||
|  |     template<class Seq>  | ||||||
|  |     void seed(Seq& q, typename sitmo_enable_if< has_generate_template<Seq>::value >::type* = 0 ) | ||||||
|  |     { | ||||||
|  |         typename Seq::result_type w[8]; | ||||||
|  |         q.generate(&w[0], &w[8]); | ||||||
|  |  | ||||||
|  |         for (unsigned short i=0; i<4; ++i) { | ||||||
|  |             _k[i] = ( static_cast<uint64_t>(w[2*i]) << 32) | w[2*i+1]; | ||||||
|  |             _s[i] = 0; | ||||||
|  |         } | ||||||
|  |         _o_counter = 0; | ||||||
|  |          | ||||||
|  |         encrypt_counter(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.908 table 117, row 8 | ||||||
|  |     // Advances e’s state ei to ei+1 = TA(ei) and returns GA(ei). | ||||||
|  |     uint32_t operator()() | ||||||
|  |     { | ||||||
|  |         // can we return a value from the current block? | ||||||
|  |         if (_o_counter < 8) { | ||||||
|  |             unsigned short _o_index = _o_counter >> 1; | ||||||
|  |             _o_counter++; | ||||||
|  |             if (_o_counter&1)  | ||||||
|  |                 return _o[_o_index] & 0xFFFFFFFF;  | ||||||
|  |             else | ||||||
|  |                 return _o[_o_index] >> 32; | ||||||
|  |         } | ||||||
|  |          | ||||||
|  |         // generate a new block and return the first 32 bits | ||||||
|  |         inc_counter(); | ||||||
|  |         encrypt_counter(); | ||||||
|  |         _o_counter = 1; // the next call | ||||||
|  |         return _o[0] & 0xFFFFFFFF;   // this call | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // ------------------------------------------------- | ||||||
|  |     // misc | ||||||
|  |     // ------------------------------------------------- | ||||||
|  |      | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.908 table 117, row 9 | ||||||
|  |     // Advances e’s state ei to ei+z by any means equivalent to z | ||||||
|  |     // consecutive calls e(). | ||||||
|  |     void discard(uint64_t z) | ||||||
|  |     { | ||||||
|  |         // check if we stay in the current block | ||||||
|  |         if (z < 8 - _o_counter) { | ||||||
|  |             _o_counter += static_cast<unsigned short>(z); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         // we will have to generate a new block... | ||||||
|  |         z -= (8 - _o_counter);  // discard the remainder of the current blok | ||||||
|  |         _o_counter = z % 8;     // set the pointer in the correct element in the new block | ||||||
|  |         z -= _o_counter;        // update z | ||||||
|  |         z >>= 3;                // the number of buffers is elements/8 | ||||||
|  |         ++z;                    // and one more because we crossed the buffer line | ||||||
|  |         inc_counter(z); | ||||||
|  |         encrypt_counter(); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |    // ------------------------------------------------- | ||||||
|  |    // IO | ||||||
|  |    // ------------------------------------------------- | ||||||
|  |    template<class CharT, class Traits> | ||||||
|  |    friend std::basic_ostream<CharT,Traits>& | ||||||
|  |    operator<<(std::basic_ostream<CharT,Traits>& os, const prng_engine& s) { | ||||||
|  |        for (unsigned short i=0; i<4; ++i) | ||||||
|  |            os << s._k[i] << ' ' << s._s[i] << ' ' << s._o[i] << ' '; | ||||||
|  |        os << s._o_counter; | ||||||
|  |        return os; | ||||||
|  |    } | ||||||
|  |  | ||||||
|  |    template<class CharT, class Traits> | ||||||
|  |    friend std::basic_istream<CharT,Traits>& | ||||||
|  |    operator>>(std::basic_istream<CharT,Traits>& is, prng_engine& s) { | ||||||
|  |        for (unsigned short i=0; i<4; ++i) | ||||||
|  |            is >> s._k[i] >> s._s[i] >> s._o[i]; | ||||||
|  |        is >> s._o_counter; | ||||||
|  |        return is; | ||||||
|  |    }  | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.908 table 117, row 10 | ||||||
|  |     // This operator is an equivalence relation. With Sx and Sy as the infinite  | ||||||
|  |     // sequences of values that would be generated by repeated future calls to  | ||||||
|  |     // x() and y(), respectively, returns true if Sx = Sy; else returns false. | ||||||
|  |     bool operator==(const prng_engine& y)  | ||||||
|  |     { | ||||||
|  |         if (_o_counter != y._o_counter) return false; | ||||||
|  |         for (unsigned short i=0; i<4; ++i) { | ||||||
|  |             if (_s[i] != y._s[i]) return false; | ||||||
|  |             if (_k[i] != y._k[i]) return false; | ||||||
|  |             if (_o[i] != y._o[i]) return false; | ||||||
|  |         } | ||||||
|  |         return true; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // req: 26.5.1.4 Random number engine requirements, p.908 table 117, row 11 | ||||||
|  |     bool operator!=(const prng_engine& y)  | ||||||
|  |     { | ||||||
|  |         return !(*this == y); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // Extra function to set the key | ||||||
|  |     void set_key(uint64_t k0=0, uint64_t k1=0, uint64_t k2=0, uint64_t k3=0) | ||||||
|  |     { | ||||||
|  |         _k[0] = k0; _k[1] = k1; _k[2] = k2; _k[3] = k3; | ||||||
|  |         encrypt_counter(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     // set the counter | ||||||
|  |     void set_counter(uint64_t s0=0, uint64_t s1=0, uint64_t s2=0, uint64_t s3=0, unsigned short o_counter=0) | ||||||
|  |     { | ||||||
|  |         _s[0] = s0;  | ||||||
|  |         _s[1] = s1;  | ||||||
|  |         _s[2] = s2;  | ||||||
|  |         _s[3] = s3; | ||||||
|  |         _o_counter = o_counter % 8; | ||||||
|  |         encrypt_counter(); | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |      | ||||||
|  |     // versioning | ||||||
|  |     uint32_t version() | ||||||
|  |     { | ||||||
|  |         return 5; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | private: | ||||||
|  |     void encrypt_counter() | ||||||
|  |     { | ||||||
|  |         uint64_t b[4]; | ||||||
|  |         uint64_t k[5]; | ||||||
|  |  | ||||||
|  |         for (unsigned short i=0; i<4; ++i) b[i] = _s[i]; | ||||||
|  |         for (unsigned short i=0; i<4; ++i) k[i] = _k[i]; | ||||||
|  |  | ||||||
|  |         k[4] = 0x1BD11BDAA9FC1A22 ^ k[0] ^ k[1] ^ k[2] ^ k[3]; | ||||||
|  |  | ||||||
|  |         MIXK(b[0], b[1], 14,   b[2], b[3], 16,   k[0], k[1], k[2], k[3]); | ||||||
|  |         MIX2(b[0], b[3], 52,   b[2], b[1], 57); | ||||||
|  |         MIX2(b[0], b[1], 23,   b[2], b[3], 40); | ||||||
|  |         MIX2(b[0], b[3],  5,   b[2], b[1], 37); | ||||||
|  |         MIXK(b[0], b[1], 25,   b[2], b[3], 33,   k[1], k[2], k[3], k[4]+1); | ||||||
|  |         MIX2(b[0], b[3], 46,   b[2], b[1], 12); | ||||||
|  |         MIX2(b[0], b[1], 58,   b[2], b[3], 22); | ||||||
|  |         MIX2(b[0], b[3], 32,   b[2], b[1], 32); | ||||||
|  |  | ||||||
|  |         MIXK(b[0], b[1], 14,   b[2], b[3], 16,   k[2], k[3], k[4], k[0]+2); | ||||||
|  |         MIX2(b[0], b[3], 52,   b[2], b[1], 57); | ||||||
|  |         MIX2(b[0], b[1], 23,   b[2], b[3], 40); | ||||||
|  |         MIX2(b[0], b[3],  5,   b[2], b[1], 37); | ||||||
|  |         MIXK(b[0], b[1], 25,   b[2], b[3], 33,   k[3], k[4], k[0], k[1]+3); | ||||||
|  |  | ||||||
|  |         MIX2(b[0], b[3], 46,   b[2], b[1], 12); | ||||||
|  |         MIX2(b[0], b[1], 58,   b[2], b[3], 22); | ||||||
|  |         MIX2(b[0], b[3], 32,   b[2], b[1], 32); | ||||||
|  |  | ||||||
|  |         MIXK(b[0], b[1], 14,   b[2], b[3], 16,   k[4], k[0], k[1], k[2]+4); | ||||||
|  |         MIX2(b[0], b[3], 52,   b[2], b[1], 57); | ||||||
|  |         MIX2(b[0], b[1], 23,   b[2], b[3], 40); | ||||||
|  |         MIX2(b[0], b[3],  5,   b[2], b[1], 37); | ||||||
|  |  | ||||||
|  |         for (unsigned int i=0; i<4; ++i) _o[i] = b[i] + k[i]; | ||||||
|  |         _o[3] += 5; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     void inc_counter() | ||||||
|  |     { | ||||||
|  |         ++_s[0];  | ||||||
|  |         if (_s[0] != 0) return; | ||||||
|  |          | ||||||
|  |         ++_s[1];  | ||||||
|  |         if (_s[1] != 0) return; | ||||||
|  |          | ||||||
|  |         ++_s[2];  | ||||||
|  |         if (_s[2] != 0) return; | ||||||
|  |          | ||||||
|  |         ++_s[3]; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  |     void inc_counter(uint64_t z) | ||||||
|  |     { | ||||||
|  |         if (z > 0xFFFFFFFFFFFFFFFF - _s[0]) {   // check if we will overflow the first 64 bit int | ||||||
|  |             ++_s[1]; | ||||||
|  |             if (_s[1] == 0) { | ||||||
|  |                 ++_s[2]; | ||||||
|  |                 if (_s[2] == 0) { | ||||||
|  |                     ++_s[3]; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |         _s[0] += z; | ||||||
|  |     } | ||||||
|  |      | ||||||
|  | private: | ||||||
|  |     uint64_t _k[4];             // key | ||||||
|  |     uint64_t _s[4];             // state (counter) | ||||||
|  |     uint64_t _o[4];             // cipher output    4 * 64 bit = 256 bit output | ||||||
|  |     unsigned short _o_counter;  // output chunk counter, the 256 random bits in _o  | ||||||
|  |                                 // are returned in eight 32 bit chunks | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | } // namespace sitmo | ||||||
|  |  | ||||||
|  | #undef MIXK | ||||||
|  | #undef MIX2 | ||||||
|  |  | ||||||
|  | #endif | ||||||
		Reference in New Issue
	
	Block a user