1 // 2 //! \file libecc/rng.h 3 //! \brief Random number generator. 4 //! 5 //! This header file declares <code>class libecc::rng</code>, a pseudo random number generator. 6 // 7 // This file is part of the libecc package. 8 // Copyright (C) 2002, by 9 // 10 // Carlo Wood, Run on IRC <carlo@alinoe.com> 11 // RSA-1024 0x624ACAD5 1997-01-26 Sign & Encrypt 12 // Fingerprint16 = 32 EC A7 B6 AC DB 65 A6 F6 F6 55 DD 1C DC FF 61 13 // 14 // This program is free software; you can redistribute it and/or 15 // modify it under the terms of the GNU General Public License 16 // as published by the Free Software Foundation; either version 2 17 // of the License, or (at your option) any later version. 18 // 19 // This program is distributed in the hope that it will be useful, 20 // but WITHOUT ANY WARRANTY; without even the implied warranty of 21 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 // GNU General Public License for more details. 23 // 24 // You should have received a copy of the GNU General Public License 25 // along with this program; if not, write to the Free Software 26 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 27 // 28 29 #ifndef LIBECC_RNG_H 30 #define LIBECC_RNG_H 31 32 #include <libecc/bitset.h> 33 34 namespace libecc { 35 36 class rng { 37 public: 38 static unsigned int const S_pool_size = 521; //!< Pool size in bits. This RNG uses a pool of 521 bits. 39 40 private: 41 uint32_t M_pool[S_pool_size / 32 + 1]; 42 bitset<512> M_out; 43 unsigned int M_out_cnt; 44 45 class bit_iterator { 46 private: 47 uint32_t* M_ptr; 48 uint32_t M_head_mask; 49 public: bit_iterator(uint32_t * pool,int bit)50 bit_iterator(uint32_t* pool, int bit) : M_ptr(pool + bit / 32), M_head_mask(1 << bit % 32) { } toggle(void)51 void toggle(void) const { *M_ptr ^= M_head_mask; } set(void)52 void set(void) { *M_ptr |= M_head_mask; } clear(void)53 void clear(void) { *M_ptr &= ~M_head_mask; } increment_and_test(uint32_t * pool)54 uint32_t increment_and_test(uint32_t* pool) 55 { 56 M_head_mask <<= 1; 57 if (M_head_mask == 0) 58 { 59 M_head_mask = 1; 60 ++M_ptr; 61 } 62 else if (M_head_mask == (1 << (S_pool_size % 32)) && M_ptr - pool == S_pool_size / 32) 63 { 64 M_ptr = pool; 65 M_head_mask = 1; 66 } 67 return (*M_ptr & M_head_mask); 68 } 69 }; 70 71 uint32_t* M_entropy_ptr; 72 uint32_t const* M_entropy_ptr_end; 73 74 bit_iterator M_head; 75 bit_iterator M_fbp1; 76 bit_iterator M_fbp2; 77 bit_iterator M_fbp3; 78 bit_iterator M_fbp4; 79 bit_iterator M_fbp5; 80 bit_iterator M_fbp6; 81 bit_iterator M_fbp7; 82 bit_iterator M_fbp8; 83 bit_iterator M_fbp9; 84 85 public: 86 /** 87 * \brief The type of the constructor argument. 88 */ 89 typedef bitset<S_pool_size> pool_type; 90 rng(pool_type const& seed); 91 92 void generate_512_bits(void); 93 /** \brief Retrieve a reference to the 512 bits that were generated with a call to rng::generate_512_bits(). */ get_512_bits(void)94 bitset<512> const& get_512_bits(void) const { return M_out; } 95 96 void add_entropy(uint32_t const* noise, unsigned int number_of_ints); 97 98 /** 99 * \brief Add entropy from a bitset. 100 * 101 * Calls <code>add_entropy(uint32_t const*, unsigned int)</code>. 102 */ 103 template<unsigned int n> add_entropy(bitset<n> const noise)104 void add_entropy(bitset<n> const noise) 105 { 106 add_entropy(reinterpret_cast<uint32_t const*>(noise.digits_ptr()), bitset<n>::digits * sizeof(bitset_digit_t) / 4); 107 } 108 }; 109 110 } // namespace libecc 111 112 #endif // LIBECC_RNG_H 113