Boost logo

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