|
Boost : |
From: Peter Dimov (pdimov_at_[hidden])
Date: 2007-05-07 13:56:09
Peter Dimov wrote:
> For the default seed, you might want to look into combining several
> sources of entropy (unpredictable values) such as
>
> - time(0)
> - clock()
> - the values of an unsigned char[] array that is allocated on the
> stack and not initialized
> - the addresses of some variables or functions
> - the address of a newly allocated object
> - anything else that you can come up with
Here's one implementation of this. Feel free to use it:
#include "sha1.hpp"
#include <cstdlib>
#include <ctime>
#include <cstring>
#include <cstdio>
#include <memory>
namespace boost
{
namespace detail
{
inline unsigned * sha1_random_digest_state()
{
static unsigned state[ 5 ];
return state;
}
inline void sha1_random_digest( unsigned (&rd) [ 5 ] )
{
SHA1 sha;
unsigned * ps = sha1_random_digest_state();
unsigned state[ 5 ];
std::memcpy( state, ps, sizeof( state ) ); // harmless data race
sha.Input( (unsigned char const*)state, sizeof( state ) );
sha.Input( (unsigned char const*)&ps, sizeof( ps ) );
{
std::time_t tm = std::time( 0 );
sha.Input( (unsigned char const*)&tm, sizeof( tm ) );
}
{
std::clock_t ck = std::clock();
sha.Input( (unsigned char const*)&ck, sizeof( ck ) );
}
{
unsigned rn[] = { std::rand(), std::rand(), std::rand() };
sha.Input( (unsigned char const*)rn, sizeof( rn ) );
}
{
unsigned char buffer[ 20 ];
if( std::FILE * f = std::fopen( "/dev/urandom", "rb" ) )
{
std::fread( buffer, 1, 20, f );
std::fclose( f );
}
// using an uninitialized buffer[] if fopen fails
// intentional, we rely on its contents being random
sha.Input( buffer, sizeof( buffer ) );
}
{
unsigned * p = new unsigned;
sha.Input( (unsigned char const*)p, sizeof( *p ) );
sha.Input( (unsigned char const*)&p, sizeof( p ) );
delete p;
}
sha.Input( (unsigned char const*)rd, sizeof( rd ) );
unsigned digest[ 5 ];
sha.Result( digest );
for( int i = 0; i < 5; ++i )
{
// harmless data race
ps[ i ] ^= digest[ i ];
rd[ i ] ^= digest[ i ];
}
}
} // namespace detail
} // namespace boost
#include <iostream>
#include <iomanip>
static void print_digest( unsigned const (&digest) [ 5 ] )
{
std::cout << std::hex << std::setfill('0') << std::uppercase <<
std::setw( 8 ) << digest[ 0 ];
for( int i = 1; i < 5; ++i )
{
std::cout << '-' << std::setw( 8 ) << digest[ i ];
}
std::cout << std::endl;
}
int main()
{
unsigned rd[ 5 ];
for( int i = 0; i < 4; ++i )
{
boost::detail::sha1_random_digest( rd );
print_digest( rd );
}
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk