Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 21 Jul 2000 18:48:05 -0700 (PDT)
From:      Kris Kennaway <kris@FreeBSD.org>
To:        arch@freebsd.org
Subject:   Quantifying entropy
Message-ID:  <Pine.BSF.4.21.0007211831540.68809-200000@freefall.freebsd.org>

index | next in thread | raw e-mail

[-- Attachment #1 --]
I've been playing around with measuring the entropy of sound card
microphone inputs when they have no microphone attached (i.e. intrinsic
noise in the sound card). I've tested on two systems: my SB16 and a
CS423x, and found quite different results:

My SB16 in 8bit mode has about 0.06 bits of entropy per sample
The CS423x has about 5.8 bits per sample (!).

SB16 in 16bit mode recording seems to be broken at the moment.
CS423x in 16bit mode has about 8.5 bits per sample.

The noise spectra look mostly gaussian (except for the SB16 which gives a
weird quantized spectrum of only 5 possible return values and a strongly
correlated output pattern ;-, though I've not plotted them, but only
inspected the frequency distribution table. I haven't performed any
statistical tests for signal correlation beyond calculating the Shannon
entropy in the probability distribution. I'd be interested to see results
from other people (test program attached)

What this seems to suggest is that in the wider picture of gathering
entropy, the amount of noise in a given (logical) source is going to be
very hardware and system-specific, and trying to assign a fixed weight to
it may either grossly overestimate or underestimate the amount of true
entropy in the sample.

It would seem to make sense then to provide a way for a userland tool to
attach to a specific entropy provider in the kernel, which would be fed
the raw measurements from the source for analysis over some representative
sample period. Using some tool or set of tools the entropy of the signal
can be calculated and then the weighting of the source tuned in the
kernel, using sysctl or something (although making it persistent might be
a problem).

We can still try and provide a set of resonable defaults by gathering and
averaging measurements from a lot of different systems, but an interested
administrator can tune things more efficiently for his local system.

Kris

--
In God we Trust -- all others must submit an X.509 certificate.
    -- Charles Forsythe <forsythe@alum.mit.edu>

[-- Attachment #2 --]
#include <sys/time.h>
#include <sys/types.h>
#include <sys/ioctl.h>
#include <sys/soundcard.h>

#include <err.h>
#include <fcntl.h>
#include <math.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

#define DEV "/dev/dsp"

int main() {
  int i, j, fd;
  uint16_t buf[8192]; 
  unsigned long n=0, m=0;
  uint32_t p[65536];
  float s, pr, ln2;
  struct timeval tv1, tv2;
  struct _snd_capabilities sndcap;
  struct _snd_chan_param sndpar;
  
  ln2 = logf(2);

  if ((fd = open(DEV, O_RDWR|O_NONBLOCK)) == NULL)
    err(1, "open");
  
  if (ioctl(fd, AIOGCAP, &sndcap) == -1)
    err(1, "AIOGCAP");

  printf("min=%d max=%d\n", sndcap.rate_min, sndcap.rate_max);

  sndpar.play_rate=sndcap.rate_max;
  sndpar.rec_rate=sndcap.rate_max;
  sndpar.play_format=AFMT_S16_LE;
  sndpar.rec_format=AFMT_S16_LE;

  if ((ioctl(fd, AIOSFMT, &sndpar)) == -1)
    err(1, "AIOSFMT");
  
  bzero(p, sizeof(p));
  
  gettimeofday(&tv1, NULL);
  
  while(1) {
    i = read(fd, &buf, sizeof(buf));
    for(j=0;j<(i/2);j++) {
      p[buf[j]]++;
      n++;
    }
    m++;
    if (m % 500000 == 0) {
      s=0.;
      gettimeofday(&tv2, NULL);
      for(i=0;i<65536;i++) {
#ifdef DEBUG
	if (p[i]) printf("%d=%d ",i,p[i]);
#endif
	pr = ((float)p[i]/(float)n);
	if (pr != 0.) {
	  s -= pr * logf(pr)/ ln2;
	}
      }
      printf("n = %d, rate = %f, s = %f\n", n, (float)(n)/(tv2.tv_sec - tv1.tv_sec), s);
    }
  }
}
help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?Pine.BSF.4.21.0007211831540.68809-200000>