[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Linux entropy pool / random number benchmark



debian-user:

I found some more information on Intel's Secure Key:


https://software.intel.com/en-us/articles/intel-digital-random-number-generator-drng-software-implementation-guide

    As shown in Figure 3, the DRNG can be thought of as three logical
    components forming an asynchronous production pipeline: an entropy
    source (ES) that produces random bits from a nondeterministic
    hardware process at around 3 Gbps, a conditioner that uses AES (4)
    in CBC-MAC (5) mode to distill the entropy into high-quality
    nondeterministic random numbers, and two parallel outputs:

        A deterministic random bit generator (DRBG) seeded from the
        conditioner.

        An enhanced, nondeterministic random number generator (ENRNG)
        that provides seeds from the entropy conditioner.


I've improved my Linux entropy pool / random number benchmark script (see below):

1.  Waits for enough entropy before starting.

2.  Runs at maximum speed until entropy pool gets low.

3.  Continues running only as fast as the entropy pool is refilled.

4. Added more columns of information, notably "cost" (entropy bits per random number) and "efficiency" (random number bytes per entropy bit).

5. Tuned the script parameters for my Wheezy 7.7 i386 machine with a Pentium 4 3.4E GHz HT processor (no Secure Key). (Note that I needed to wiggle the mouse for stages #1 and #3.)

6. Added statistics to help measure random number generation rates for stages #2 and #3.


I invite other people to run the script and post the results.


David



$ cat entropy-random-bench
#!/usr/bin/perl
# $Id: entropy-random-bench,v 1.11 2014/11/30 02:25:20 dpchrist Exp $
#######################################################################
# Argument defaults -- edit to suit:

my $entropy		= '/proc/sys/kernel/random/entropy_avail';
my $random		= '/dev/urandom';
my $start_entropy	= 0.8 * 4096;		# bits
my $continue_entropy	= 0.2 * 4096;		# bits
my $min_cost		=         64;		# bits
my $length		=          8;		# bytes
my $max_trials		=         80;		# each

#######################################################################
# The rest of the script should not be edited:

use strict;
use warnings;

use Data::Dumper;
use Getopt::Long		qw( :config
				    auto_help
				    auto_version );
use List::Util			qw( min max sum );
use Pod::Usage;
use Time::HiRes			qw( sleep time );

$| = 1;

our $VERSION    = sprintf("%d.%03d", q$Revision: 1.11 $ =~ /(\d+)/g);
my $debug	= 0;

sub get_random
{
    open(my $fh, $random)  or die "error opening $random: $!";
    my $buf;
    my $n = sysread($fh, $buf, $length);
    die "nor reading $fh: $!" unless defined $n && $n;
    return $buf;
}

sub get_entropy
{
    open(my $fh, $entropy) or die "error opening $entropy: $!";
    my $e = <$fh>;
    chomp $e;
    return $e;
}

sub print_header
{
print "trial e1 length time rate cost efficiency\n", "- bits bytes seconds bytes/second bits bytes/bit\n", "====== ====== ====== ============== ============== ====== ==============\n";
}

sub print_row
{
    my $trial = shift;
    printf "%6i  %6i  %6i  %14e  %14e  %6i  %14e\n",
	$trial->{trial},
	$trial->{e1},
	$trial->{length},
	$trial->{time},
	$trial->{rate},
	$trial->{cost},
	$trial->{efficiency},
    @_;
}

sub lower
{
    my @a = sort @_;
    my $n = scalar @a;
    pop @a for ( 1 .. $n/2 );
    return @a;
}

sub middle
{
    my @a = sort @_;
    my $n = scalar @a;
    shift @a for ( 1 .. $n/4 );
    pop   @a for ( 1 .. $n/4 );
    return @a;
}

sub upper
{
    my @a = sort @_;
    my $n = scalar @a;
    shift @a for ( 1 .. $n/2 );
    return @a;
}

sub mean
{
    return sum(@_) / scalar @_;
}

sub print_statistics
{
    my $trials = shift;
    my %stats;

    my @rates = map { $_->{rate} } @$trials;
    $stats{n_rates} = scalar @rates;

    $stats{max_rate}			= max  @rates;
    $stats{mean_rate}			= mean @rates;
    $stats{min_rate}			= min  @rates;

    $stats{max_middle_rate}		= max  middle @rates;
    $stats{mean_middle_rate}		= mean middle @rates;
    $stats{min_middle_rate}		= min  middle @rates;

    $stats{max_middle_upper_rate}	= max  middle upper @rates;
    $stats{mean_middle_upper_rate}	= mean middle upper @rates;
    $stats{min_middle_upper_rate}	= min  middle upper @rates;

    $stats{max_middle_lower_rate}	= max  middle lower @rates;
    $stats{mean_middle_lower_rate}	= mean middle lower @rates;
    $stats{min_middle_lower_rate}	= min  middle lower @rates;

    print "\n";
    for my $k (sort keys %stats) {
	printf "%32s = %s\n", $k, $stats{$k};
    }
}

### main
{
    my $man;

    GetOptions(
	"entropy=s"		=> \$entropy,
	"random=s"		=> \$random,
	"start-entropy"		=> \$start_entropy,
	"continue-entropy"	=> \$continue_entropy,
	"min-cost"		=> \$min_cost,
	"length=i"		=> \$length,
	"max-trials=i"		=> \$max_trials,
	"man"			=> \$man,
	"debug+"		=> \$debug,
    ) or pod2usage(2);
    pod2usage(-exitstatus => 0, -verbose => 2) if $man;

    my $begin_t			= time();

    my $trial			= 0;
    my $t1			= 0.0;
    my @trials;

    my $e1 = get_entropy();;
    if ($e1 < $start_entropy) {
	print "waiting for sufficient entropy ";
	while (($e1 = get_entropy()) < $start_entropy) {
	    print "$e1 ";
	    sleep 1;
	}
	print "\n";
    }

    print_header();

    do {
	$trial++;

      AGAIN:

	$e1	= get_entropy();
	goto AGAIN if $e1 < $continue_entropy;

	get_random();

	my $e2 = get_entropy();
	my $cost = $e1 - $e2;
	
	if ($cost < $min_cost) {
	    $t1 = time() - $begin_t;
	    goto AGAIN;
	}

	my $efficiency = $length / $cost;

	my $t2   = time() - $begin_t;
	my $time = $t2 - $t1;
	my $rate = $length / $time;

	my %trial = (
	    trial	=> $trial,
	    length	=> $length,
	    e1		=> $e1,
	    e2		=> $e2,
	    cost	=> $cost,
	    efficiency	=> $efficiency,
	    t1		=> $t1,
	    t2		=> $t2,
	    time	=> $time,
	    rate	=> $rate,
	);

	print_row \%trial;

	push @trials, \%trial;

	$t1 = $t2;

    } while ($trial < $max_trials);

  DONE:

    print_statistics \@trials;
}

__END__

=head1 NAME

entropy-random-bench - Linux entropy pool / random number benchmark

=head1 SYNOPSIS

 entropy-random-bench [options]

  Options:
   --entropy			path to entropy availble file
   --random			path to random number file
   --start-entropy		min entropy to start benchmark
   --continue-entropy		min entropy to continue benchmark
   --min-cost			min cost to consider a trial valid
   --length			number of bytes to read from random
   --max-trials			max number of trials
   --man			print manual page and exit
   --help, -?			print usage message and exit
   --debug			print debug messages

=head1 DESCRIPTION

Interactive benchmark for Linux entropy pool
and random number generator.

$Revision: 1.11 $

=head1 SEE ALSO

=head1 AUTHOR

David Paul Christensen, E<lt>dpchrist@holgerdanske.comE<gt>

=head1 COPYRIGHT AND LICENSE

Copyright (C) 2014 by David Paul Christensen

This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself, either Perl version 5.14.2 or,
at your option, any later version of Perl 5 you may have available.

=cut

#######################################################################



$ perl entropy-random-bench
waiting for sufficient entropy 263 296 402 510 617 725 845 952 1060 1166 1274 1381 1499 1606 1713 1821 1928 2057 2164 2272 2379 2487 2595 2702 2809 2917 3024 3132 3239
trial   e1      length  time            rate            cost    efficiency
-       bits    bytes   seconds         bytes/second    bits    bytes/bit
====== ====== ====== ============== ============== ====== ============== 1 3346 8 2.900799e+01 2.757861e-01 64 1.250000e-01 2 3282 8 1.559258e-04 5.130647e+04 64 1.250000e-01 3 3218 8 1.108646e-04 7.216007e+04 64 1.250000e-01 4 3154 8 1.080036e-04 7.407159e+04 64 1.250000e-01 5 3090 8 1.060963e-04 7.540322e+04 64 1.250000e-01 6 3026 8 1.080036e-04 7.407159e+04 64 1.250000e-01 7 2962 8 1.211166e-04 6.605203e+04 64 1.250000e-01 8 2898 8 1.058578e-04 7.557305e+04 64 1.250000e-01 9 2834 8 1.060963e-04 7.540322e+04 64 1.250000e-01 10 2770 8 1.070499e-04 7.473147e+04 64 1.250000e-01 11 2706 8 1.108646e-04 7.216007e+04 64 1.250000e-01 12 2642 8 1.089573e-04 7.342326e+04 64 1.250000e-01 13 2578 8 1.060963e-04 7.540322e+04 64 1.250000e-01 14 2514 8 1.139641e-04 7.019756e+04 64 1.250000e-01 15 2450 8 1.060963e-04 7.540322e+04 64 1.250000e-01 16 2386 8 1.058578e-04 7.557305e+04 64 1.250000e-01 17 2322 8 1.251698e-04 6.391320e+04 64 1.250000e-01 18 2258 8 1.058578e-04 7.557305e+04 64 1.250000e-01 19 2194 8 1.039505e-04 7.695971e+04 64 1.250000e-01 20 2130 8 1.051426e-04 7.608715e+04 64 1.250000e-01 21 2003 8 1.139641e-04 7.019756e+04 64 1.250000e-01 22 1939 8 1.909733e-04 4.189068e+04 64 1.250000e-01 23 1875 8 1.149178e-04 6.961500e+04 64 1.250000e-01 24 1811 8 1.051426e-04 7.608715e+04 64 1.250000e-01 25 1747 8 1.058578e-04 7.557305e+04 64 1.250000e-01 26 1683 8 1.051426e-04 7.608715e+04 64 1.250000e-01 27 1619 8 1.058578e-04 7.557305e+04 64 1.250000e-01 28 1555 8 1.041889e-04 7.678360e+04 64 1.250000e-01 29 1491 8 1.049042e-04 7.626007e+04 64 1.250000e-01 30 1427 8 1.099110e-04 7.278619e+04 64 1.250000e-01 31 1363 8 1.070499e-04 7.473147e+04 64 1.250000e-01 32 1299 8 1.080036e-04 7.407159e+04 64 1.250000e-01 33 1235 8 1.161098e-04 6.890027e+04 64 1.250000e-01 34 1171 8 1.080036e-04 7.407159e+04 64 1.250000e-01 35 1107 8 1.068115e-04 7.489829e+04 64 1.250000e-01 36 1043 8 1.101494e-04 7.262864e+04 64 1.250000e-01 37 979 8 1.070499e-04 7.473147e+04 64 1.250000e-01 38 915 8 1.068115e-04 7.489829e+04 64 1.250000e-01 39 851 8 1.130104e-04 7.078994e+04 64 1.250000e-01 40 820 8 2.951131e-01 2.710825e+01 64 1.250000e-01 41 820 8 9.311321e-01 8.591692e+00 64 1.250000e-01 42 820 8 5.943420e-01 1.346026e+01 64 1.250000e-01 43 820 8 5.942919e-01 1.346140e+01 64 1.250000e-01 44 820 8 5.942590e-01 1.346214e+01 64 1.250000e-01 45 820 8 4.456880e-01 1.794978e+01 64 1.250000e-01 46 820 8 5.942011e-01 1.346346e+01 64 1.250000e-01 47 820 8 5.943089e-01 1.346101e+01 64 1.250000e-01 48 820 8 5.944021e-01 1.345890e+01 64 1.250000e-01 49 820 8 5.843971e-01 1.368932e+01 64 1.250000e-01 50 820 8 5.942190e-01 1.346305e+01 64 1.250000e-01 51 820 8 5.942919e-01 1.346140e+01 64 1.250000e-01 52 820 8 5.943420e-01 1.346026e+01 64 1.250000e-01 53 828 8 5.729330e-01 1.396324e+01 64 1.250000e-01 54 820 8 4.967840e-01 1.610358e+01 64 1.250000e-01 55 820 8 5.842531e-01 1.369270e+01 64 1.250000e-01 56 820 8 5.942631e-01 1.346205e+01 64 1.250000e-01 57 820 8 5.944080e-01 1.345877e+01 64 1.250000e-01 58 820 8 5.942678e-01 1.346194e+01 64 1.250000e-01 59 820 8 5.843821e-01 1.368967e+01 64 1.250000e-01 60 820 8 5.942130e-01 1.346319e+01 64 1.250000e-01 61 820 8 5.943429e-01 1.346024e+01 64 1.250000e-01 62 820 8 5.943570e-01 1.345992e+01 64 1.250000e-01 63 820 8 4.655199e-01 1.718509e+01 64 1.250000e-01 64 820 8 5.942540e-01 1.346226e+01 64 1.250000e-01 65 820 8 5.842640e-01 1.369244e+01 64 1.250000e-01 66 820 8 5.942981e-01 1.346126e+01 64 1.250000e-01 67 820 8 5.943689e-01 1.345965e+01 64 1.250000e-01 68 820 8 5.942941e-01 1.346135e+01 64 1.250000e-01 69 820 8 5.843458e-01 1.369052e+01 64 1.250000e-01 70 820 8 5.943000e-01 1.346121e+01 64 1.250000e-01 71 820 8 5.943351e-01 1.346042e+01 64 1.250000e-01 72 820 8 4.555719e-01 1.756035e+01 64 1.250000e-01 73 820 8 5.942521e-01 1.346230e+01 64 1.250000e-01 74 820 8 5.942049e-01 1.346337e+01 64 1.250000e-01 75 820 8 5.845132e-01 1.368660e+01 64 1.250000e-01 76 820 8 5.943279e-01 1.346058e+01 64 1.250000e-01 77 820 8 5.942540e-01 1.346226e+01 64 1.250000e-01 78 820 8 5.942509e-01 1.346233e+01 64 1.250000e-01 79 820 8 5.844100e-01 1.368902e+01 64 1.250000e-01 80 820 8 5.943482e-01 1.346012e+01 64 1.250000e-01

           max_middle_lower_rate = 13.6890208155784
                 max_middle_rate = 74731.4743875278
           max_middle_upper_rate = 75573.045045045
                        max_rate = 76959.7064220184
          mean_middle_lower_rate = 13.4846087389023
                mean_middle_rate = 32683.8048518722
          mean_middle_upper_rate = 74309.7280757781
                       mean_rate = 34307.7406298095
           min_middle_lower_rate = 13.4605823510345
                 min_middle_rate = 13.46225649774
           min_middle_upper_rate = 72160.0688172043
                        min_rate = 0.275786074918936
                         n_rates = 80


Reply to: