ABSTRACT: We discuss how to configure and use turbid, which is a Hardware Random Number Generator (HRNG), also called a True Random Generator (TRNG). It is suitable for a wide range of applications, from the simplest benign applications to the most demanding high-stakes adversarial applications, including cryptography and gaming. It relies on a combination of physical process and cryptological algorithms, rather than either of those separately. It harvests randomness from physical processes, and uses that randomness efficiently. The hash saturation principle is used to distill the data, so that the output is virtually 100% random for all practical purposes. This is calculated based on physical properties of the inputs, not merely estimated by looking at the statistics of the outputs. In contrast to a Pseudo-Random Generator, it has no internal state to worry about. In particular, we describe a low-cost high-performance implementation, using the computer’s audio I/O system.
Other keywords: TRNG, HRNG, hardware random number generator, uniform hash, unbiased coin flip.
If you need some randomness right away, take a look at the suggestions at the beginning of reference 1.
The basic objective of turbid is to provide a supply of randomly-generated numbers, with quality and quantity suitable for a wide range of applications, including some very demanding applications. Some specific applications are discussed in reference 2. Quality requires, among other things, defending against various possible attacks. Some well-known attacks are discussed in reference 2. Some background and theoretical ideas are outlined in section 5 and developed more fully in reference 2.
Right now, in this section, we give a broad outline of what is possible and what is not possible.
So far, we have analyzed the HRNG mainly in terms of the density of adamance, denoted by ρ. We choose a criterion ρmin very close to 100%, and then build a generator that produces ρ > ρmin. We are not pretending to achieve ρ = 100% exactly.
Here are some of the criteria on which a random generator can be judged:
These criteria conflict in complex ways:
Hardware is fundamentally the origin of all true randomness. We then rely on algorithms to put the randomness into a very highly concentrated form. We use a cryptographic one-way function to make it infeasible for any adversary to exploit the infinitesimal remaining non-randomness.
These conflicts and tradeoffs leave us with more questions than answers. There are as-yet unanswered questions about the threat model, the cost of CPU cycles, the cost of obtaining raw randomness from physical processes, et cetera. The answers will vary wildly from platform to platform.
The current turbid code is compiled against version 1.0.25 of the libraries. Slightly older versions should be satisfactory; much older versions are not. If you are compiling from source, you might want to apply the patch in turbid/src/excl.patch, so that the mixer device can be opened in “exclusive” mode. To do that, cd to the directory in which you unpacked the turbid and alsa packages, and then incant something like patch -p1 < turbid/src/excl.patch. Then configure, make, and install the ALSA stuff (drivers, libraries, utilities). If you have never run ALSA on your system, you will need to run snddevices once. It may take some fussing to get the proper entries to describe your soundcard in /etc/modules.conf. Install the utils/alsasound script in /etc/rc.d/init.d/.
:; sox -r 48000 -b 32 -t alsa hw:0 -c 1 noise.wav trim .1 3 or :; arecord -D hw:0 --disable-softvol -f S32_LE -r 48000 -V mono -d 3 noise.wav then :; aplay noise.wav :; od -t x4 noise.wav
If turbid runs as non-root, it will open its output FIFOs in your $HOME/dev/ directory, look for its control files in your $HOME/etc/turbid/ directory, and scribble a .pid file in your $HOME/var/run/ directory.
In contrast, if turbid runs as root, it will use the system /dev/ and /etc/turbid/ /var/run/ directories.
Note: You can skip this section if you’ve been given a suitable turbid.tbd configuration file and mixer configuration (.ctl) file.
Configuration is important. It is remarkably easy to mis-configure a soundcard in such a way that it produces much less randomness than it otherwise would. This section outlines the general procedure; see appendix B for details on specific soundcards.
Terminology: we use the term soundcard loosely, to apply not just to card-shaped objects per se, but also to audio I/O subsystems embedded on the mainboard, USB dongles, external pods, et cetera.
See figure 4 and table 1 for the layout of a standard stereo connector.
Also note: When it starts up, turbid automatically takes commands from the configuration file turbid.tbd if it exists in the working directory. Other configuration files can be invoked on the command line using the “@” sign, as in turbid @foo.tbd for example.
The choice of card cannot be changed while turbid is running, so to experiment you need to stop turbid and restart it in the new configuration.
If that doesn’t work, some investigation is required. The command aplay -L (capital letter L) and/or aplay -l (lowercase letter l) to see what audio devices are available. If there are none, or only trivial devices such as “null”, you might try bestowing membership in the “audio” group to the user who will be running turbid. If the card you want to use is not visible, check that the hardware is installed (lspci -v -v or lsusb -v -v). Then check that the appropriate drivers are loaded.
hw:CARD=Intel,DEV=0 HDA Intel, CX20561 Analog Direct hardware device without any conversions
in which case you can invoke turbid card hw:CARD=Intel,DEV=0.
card 0: Intel [HDA Intel], device 1: CX20561 Digital [CX20561 Digital] Subdevices: 1/1 Subdevice #0: subdevice #0
in which case you can invoke turbid card hw:0,1 where the zero is the card number and the 1 is the device number on that card.
If the plug gets unplugged, plug it back in and restart turbid
See figure 4 and table 1 for the layout of a standard stereo connector.
Beware that on a typical mono mic-input jack, the “ring” connection is not an input at all, but instead a power output (Vbias).
Use alsamixer to adjust the output to some reasonable level. You don’t want the output to clipped or otherwise distorted.
If you want to use some other filename, that’s fine, but then you will need to add the mixer some-other.ctl option to every turbid invocation from now on. The turbid.tbd file is a convenient place to put that sort of thing.
You can do this using clips, but it’s probably quicker to just touch the voltmeter probes to the correct lugs on the audio plug
Go to the Vopen page on the turbid gui, and enter the observed voltage reading into the Vopen box. When you hit enter, this will update the gain factor (gVout), and correspondingly update the nominal sine amplitude. The sine amplitude should now be calibrated in actual volts, and should remain so from now on.
Note: On this page, there is no need to enter anything into the gVout box. The point of this page is to calculate gVout for you, when you enter the Vopen reading.
Note: In all cases, when we talk about a measured voltage – output voltage or input voltage – we mean RMS voltage (unless otherwise stated). If you are using an oscilloscope or something else that measures peak voltage, keep in in mind that the zero-to-peak amplitude of a sine wave is 1.4 times the RMS value ... and the peak-to-peak excursion is 2.8 times the RMS value.
Procedure: Go to the turbid gui and change the sine amplitude up and down. The output voltage, as observed on the voltmeter, should track the nominal sine amplitude. If lowering the amplitude gives a larger-than-expected output voltage, recalibrate at the lower voltage. (Don’t go to such low voltages that you get into trouble with noise, and/or with the limitations of the voltmeter.)
Find the largest voltage where things are still linear, then decrease that by approximately a factor of two, and then make it a nice round number. Use that as the “standard” sine amplitude setting from now on. Go to the Vopen box and hit enter one more time.
Most soundcards can put out 1 volt RMS without distorting, so a “standard” sine amplitude of 0.5 would not be surprising.
You probably want to copy-and-paste these two lines into your turbid.tbd file.
As a point of reference, the venerable Fluke voltmeter I use for this is rock solid up to 1 kHz. There is a 1-pole corner at 4 kHz. Above roughly 30 kHz the bottom drops out. Remember, this step is optional; if you are in a hurry you do not need to check your voltmeter with anywhere this level of detail.
Hook up the circuit shown in figure 7. Choose a resistance that will be small enough to decrease the voltage to roughly half of the open-circuit voltage. An initial guess of 100 Ω is reasonable. Measure the resistance using the multimeter. (Don’t rely on the markings on the resistor, except possibly as a rough guide when picking a resistor. For determining the actual resistance, the meter is more accurate and more convenient.) Plug the ends of the nresistor into two different rows in the matrix board, and then use clips to hook it across the output.
Enter the resistance value into the Rload box on the gui.
Then – after you have entered the resistance – measure the voltage across the output, on the lugs of the audio plug. Enter this into the Vloaded box on the gui.
On this page, there is no need to enter anything into the Rout box or the gVout box. The point of this page is to calculate Rout for you, when you enter the Vloaded reading.
You should probably copy-and-paste these two lines into your turbid.tbd file. (This is in addition to the two lines from the Vopen page.)
This is scary, because if you try to monitor the input in such a way that the microphone bias voltage gets routed to a real stereo input, it is entirely possible for the DC on the right channel to blow out your speaker.
At the chip level, most audio hardware these days is extremely configurable. This includes low-level details such as the number of input and output channels on each port. However, on most machines it’s not obvious how make changes to the low-level configuration. It may be that the hardware doesn’t support it, or the ALSA drivers don’t support it, or I’m not smart enough to figure it out. If anybody has good information on this, please let me know.
See also section H.
It may not be entirely obvious a priori what is your best is. You may have to go through the calibration process on each input to decide which provides the most randomness per unit time.
Take a moment to think about the following issue: We want to set up full-duplex audio. Full duplex means that the input signal is independent of the output signal. Most likely, you will have to fiddle with mixer settings (using alsamixer) to get this to work. Presumably you already have the output working (section 4.1), so now we need to get the input working without messing up the output.
This is trickier than it might seem, because recording engineers very commonly want to monitor the signal that is being recorded, there is sometimes a path within the mixer whereby the input signal can be looped back to some output. This kind of loopback interferes with what we are trying to do. This kind of mixer mis-configuration is sometimes hard to detect. Note the contrast:
|Recording engineers want to do input, with immediate re-output via the mixer (hairpin).||We want to do output, with immediate re-input via the calibration resistor network (loopback).|
Therefore, when configuring the input subsystem, the safest procedure is to use a signal that comes from a second, separate system.
So ... here’s the plan:
Note: Do not leave the headphones plugged in during the measurements that follow, when the player output is connected to the turbid input. In other words, do not use a “Y” splitter. That’s for two reasons:
- First of all, you run the risk of blowing out the right channel of your speakers, if you bridge output to microphone-input to speaker-input. As discussed in item 18, keep in mind that the right channel of the microphone jack is not an input at all, it’s a power output.
- Secondly, the headphones or speaker present an ill-characterized load to the system, interfering with any attempt to make quantitative measurements; see step 11.
The concept here is that turbid needs to do input as well as output, and the two things need to be independent.
All the contacts in the yellow-shaded region are connected together by the matrix board, internally. Choose Rtop to be approximately 10 kΩ and Rbot to be approximately 100 Ω. Measure the actual resistor values with the multimeter, and record them as lo.Rtop and lo.Rbot directives in your turbid.tbd file.
Ignore the third resistor in the diagram.
The green clip carries the signal from the computer output. The red clip carries the low-impedance signal from the voltage divider to the computer input. The black clip is the ground connection. This color-code is based on the standard color-coding of computer audio ports: The output port is normally green, while the mic-in port is normally pink, as in figure 9 for example.
Where the wires are coiled up, they are carefully coiled with an even number of turns, with an equal number of clockwise and counterclockwise turns, so that they do not act like pickup coils.
Now we want to calibrate the input impedance and gain, quantitatively. Fire up turbid sine .01. Choose sine amplitude that is about 10 times less than what was previously considered normal. That’s because we expect the input to be several hundreds of times more sensitive than the output, and the voltage divider gives us “only” a factor of 100 attenuation.
Select the Low Z tab on the turbid gui. Verify that the Rtop and Rbot numbers are correct. If not, correct them on the turbid gui (for now) and in the turbid.tbd file (for next time). The Rtap number should be zero. Leave it that way, but click on that entry box and hit <Return>.
Every time you hit <Return>, turbid should send to standard output an oripoint line, plus some comments.
Repeat the measurement to see whether the results are reproducible.
Change the Sine Ampl to see whether you get the same result. If increasing the Sine Ampl causes the ordinate of the oripoint to increase (more inverse gain, less gain) then the Sine Ampl is too high. Also look at the Y value in the comments. It should be around 0.1, certainly less than 1, but not insanely much smaller than 0.1.
A lightweight metal cookie tin will do. If you don’t have a cookie tin, an ordinary cooking pot will do. You can obtain even better results using a small box covered with aluminum foil, as in figure 10, although that’s more work than most people are willing to do. For consistency and concision, we will call this the “shield box”, no matter what it is made of.
You can use the following command
:; arecord -D hw:0 --disable-softvol -f S32_LE -r 48000 -V mono /dev/null
to display a VUmeter that gives a qualitative indication of what’s going on. Without the shield, the signal is affected by all sorts of strange things, such as how close you are sitting to the circuit. With the shield in place, the signal should be much better behaved.
Clip the grounding wire to a piece of scrap metal, so you can set it on top of the shield box and make contact that way. That’s more convenient than repeatedly clipping it to the box and then unclipping.
The same logic applies underneath: If the matrix board is not already attached to a metal backplane, find a suitable piece of metal and bolt the matrix board to it. In an emergency, a layer of aluminum foil suffices. Make arrangements for grounding the backplane.
Hook up the circuit shown in figure 11. It’s analogous to the previous figure, except that now the red clip is connected to Rtap. Cover the circuit with the shield box.
Select the High Z tab on the turbid gui. Verify that the Rtop, Rbot, and Rtap numbers are correct. If not, correct them on the turbid gui (for now) and in the turbid.tbd file (for next time). Click on the Rtap entry box and hit <Return>.
Every time you hit <Return>, turbid should send to standard output an oripoint line, an Rin line, a bVin line, and some comments.
Repeat the measurement to see whether the results are reproducible. Some typical results are shown in figure 12. You can see that turbid, when used with some skill, is capable of measuring the input impedance to high accuracy.
lo.oripoint: 97.3, 0.001193 # lo ladder v_eff: 0.009817 r_eff: 97.3 # Y: 0.411563 lockin_mag/\muV: 490.061 sine_ampl: 0.050000 hi.oripoint: 98197.3, 0.003658 # hi ladder v_eff: 0.009817 r_eff: 98197.3 # Y: 0.134197 lockin_mag/\muV: 159.792 sine_ampl: 0.050000 # slope: 2.512340e-08 intercept: 0.001191, 0.001191 Rin: 47395.4 # ohms bVin: 0.001191 # volts per hin hi.oripoint: 31997.3, 0.001995 # hi ladder v_eff: 0.009817 r_eff: 31997.3 # Y: 0.246005 lockin_mag/\muV: 292.925 sine_ampl: 0.050000 # slope: 2.514615e-08 intercept: 0.001191, 0.001191 Rin: 47352.4 # ohms bVin: 0.001191 # volts per hin hi.oripoint: 98197.3, 0.003659 # hi ladder v_eff: 0.009817 r_eff: 98197.3 # Y: 0.536591 lockin_mag/\muV: 638.834 sine_ampl: 0.200000 # slope: 2.513894e-08 intercept: 0.001191, 0.001191 Rin: 47358.5 # ohms bVin: 0.001191 # volts per hinFigure 12: Typical Oripoints
Turbid is meant to be easy to use, yet robust enough to handle a wide range of applications, including high-stakes adversarial applications. It is a Hardware Randomness Generator (HRNG). Sometimes people call it a True Randomness Generator (TRNG) which means the same thing. In any case, perfect randomness is not possible.
This stands in contrast to garden-variety “Random Number Generators” that may be good for non-demanding applications, but fail miserably if attacked. See reference 2 for a discussion of the range of applications, and of some of the things that can go wrong.
We now explain some theoretical ideas that will be important:
We have implemented a generator using these principles. Salient engineering features include:
If you ask three different people, you might get six or seven different definitions of “random”.
At a minimum, we need to consider the following ideas:
For example: Once upon a time I was working on a project that required a random generator. The pointy-haired boss directed me to get rid of my LFSR and instead use the value of the program counter (PC) as saved by the last interrupt, because that was «unpredictable». I kid thee not. In fact the PC was a terrible RNG. Successive calls tended to return the same value, and even if you got two different values, one of them was likely to be the PC of the null job (which was hardly surprising, since it was an event-driven system).
I tried to explain to him that even though the PC was not reliably predicatable, it was not reliably unpredictable. In other words, it was squish, with no useful lower bound on the amount of randomness.
The terminology is not well settled. I have heard intelligent experts call items 1, 2, 4, and 5 on the previous list “random”. I have also heard them call items 3, 4, and 5 “non-random” or “not really random”. Sometimes even item 2 is included in the catagory of “not really random”.
We consider the terms “random” and “non-random” to be vague, clumsy, and prone to misunderstanding. If a precise meaning is intended, careful clarification is necessary. This remains something of an unsolved problem, especially when talking about PRNGs.
Beware that in the cryptology community, the word «entropy» is rather widely abused. Sometimes it is thrown around as an all-purpose synonym for randomness, even in situations where the signal contains absolutely no real physics entropy. This is a bummer, because in physics, entropy has an agreed-upon, specific, and exceedingly useful meaning.
On the other hand, in the long run it’s not much of a problem, because it turns out that the physics entropy was almost certainly never what you wanted anyway. There exist distributions where the entropy is infinite but the adamance is only two bits. An adversary would have a rather easy time guessing some outputs of such a distribution, even though the entropy is infinite.
The essential concept here is probability distribution. The entropy is only one property of the distribution. See reference 2 for more discussion of this point.
In this document, and in reference 2, we use the word “entropy” in the strictest sense: “entropy” means physics entropy. The terms entropy and adamance are assigned very formal, specific meanings.
The contrast between a TRNG and a PRNG can be understood as follows:
|A Pseudo-Random Generator (PRNG) depends on an internal state variable. That means that if I wanted to, I could give my friend a copy of my PRNG (including the internal state) and then his PRNG would produce the same outputs as my PRNG.||A True Random Generator (TRNG) such as a Hardware Random Generator (HRNG) has the property that the outputs are unpredictable in principle. It does not have any internal state. If I give a copy to my friend, not only can he not predict the output of my TRNG, I cannot even predict the output of my own TRNG.|
|A high-quality PRNG depends on the assumption that it is computationally infeasible for any adversary to infer the internal state by observing the outputs. More generally, the assumption is that the adversary will find it not worthwhile to infer the internal state. This is a moving target, depending to some degree on the value of whatever the pseudo-random distribution is protecting.||A proper TRNG does not have any internal state. It does not need to be initialized.|
|Every PRNG depends on some crucial assumptions, namely the existence of a one-way function that is resistant to cryptanalytic attack.||To a lesser extent, the same is true for every practical HRNG that I know of.|
|This is probably not a serious limitation for a well-implemented PRNG. That’s because all of modern cryptography relies on similar assumptions. If these assumptions were to break down, the RNG would be the least of your problems. Still, one should always keep in mind that these assumptions are unproven.||This is even less of a problem for a HRNG, because any attack will be much more difficult to carry out. It is a known-codetext attack, with vastly less codetext available.|
Note the contrast:
Understanding turbid requires some interdisciplinary skills. It requires physics, analog electronics, and cryptography. If you are weak in one of those areas, it could take you a year to catch up.
This section exists mainly to dispel some misconceptions. Sometimes people decide that the the laws of physics do not apply to electronics, or decide on the basis of “intuition” that the noise in their audio system is negligible. If you do not suffer from these particular misconceptions, feel free to skip to section 6.3.
|A digital logic gate has considerable noise immunity. Noise, if it is not too large, is eliminated at every step. This requires both nonlinearity and power dissipation.||A linear analog system cannot eliminate noise in the same way. The fundamental equations of motion do not allow it.|
In principle, there are many physical devices that could be used as the source of raw randomness. We prefer the audio system (the “soundcard”) because such things are cheap, widely available, and easy to calibrate. We have a provable lower bound on the rate at which they produce randomness, and this rate in sufficient for a wide range of applications. This provides a way to make typical hosts very much more secure than they are now.
In contrast, a video frame-grabber card would produce randomness more copiously, but would be much more costly. Calibration and quality-assurance monitoring would be much more difficult.
There are many other sources that “might” produce usable randomness, but for which a provable nonzero lower bound is not available.
As mentioned before, we need a lower bound on the amount of randomness per sample. This is needed to ensure that the hash function’s buffer contains “enough” randomness, as discussed in reference 2.
Let us briefly explore the consequences of mis-estimating the amount of randomness in the raw data:
- 1a) If we make a slight overestimate, it means that the hash function, rather than putting out 2160 different outputs, will put out some rather smaller ensemble. In mild cases this may not be noticeable in practice.
- 1b) A major overestimate may allow an adversary to focus an attack on the few output-words being produced.
- 2a) If we modestly underestimate the amount of randomness in the raw data, there is no serious harm done.
- 2b) A major underestimate will reduce the total randomness production capability of the machine. This means the processes that consume random symbols may block, waiting for the HRNG to produce a usable output.
We looked at the power spectrum of the signal produced by a number of different sound cards. Based on these observations, and on general engineering principles, we can list various hypotheses as to what physical processes could be at work, namely:
Some of these are undoubtedly fine sources of randomness. The only problem is that except for item #1, we cannot calculate their magnitude without a great deal more engineering knowledge about the innards of the card. Using these sources might produce a HRNG that is correct, but not provably correct. Since we want something that is provably correct, we simply ignore these other contributions. They can’t hurt, and almost certainly provide a huge margin of safety.
That is: We need randomness in the raw data, and we need to know a provable lower bound on the amount of randomness. Turbid consistently applies the principle that having extra randomness is OK, and underestimating the amount of randomness is OK. This may give us less-than-optimally efficient use of the available randomness, but it guarantees correctness. Turbid consistently chooses correctness over efficiency.
Just to help you get the lay of the land, here are the key characteristics of a few soundcards. The older cards are of historical interest only. More recent cards perform better.
|Card||Q / µV||RIn / Ω||Kout||B||N||σ / µV||s / bits||ROut / Ω|
|Thinkpad cs4239 (Line)||19.6||7900||.037||9000||44100||1.07||0|
|Thinkpad cs4239 (Mike)||1.65||10100||.038||7300||44100||1.09||1.58|
Note that the CT4700 reports itself as “ENS1370” so it uses the ens1370.ctl control file.
By way of analogy, let us consider the relationship between code-breakers and code-makers. This is a complex ever-changing contest. The code-breakers make progress now and then, but the code-makers make progress, too. It is like an “arms race” but much less symmetric, so we prefer the term cat-and-mouse game.
At present, by all accounts, cryptographers enjoy a very lopsided advantage in this game.
There is an analogous relationship between those who make PRNGs and those who offer tools to test for randomness. The PRNG has a hidden pattern. Supposedly the tester “wants” the pattern to be found, while the PRNG-maker doesn’t.
We remark that in addition to the various programs that bill themselves as randomness-testers, any off-the-shelf compression routine can be used as a test: If the data is compressible, it isn’t random.
To deepen our understanding of the testing issue, let’s consider the following scenario: Suppose I establish a web server that puts out pseudo-random bytes. The underlying PRNG is very simple, namely a counter strongly encrypted with a key of my choosing. Each weekend, I choose a new key and reveal the old key.
The funny thing about this scenario is the difference between last week’s PRNG and this week’s PRNG. Specifically: this week’s PRNG will pass any empirical tests for randomness that my adversary cares to run, while last week’s PRNG can easily be shown to be highly non-random, by means of a simple test involving the now-known key.
As a modification of the previous scenario, suppose that each weekend I release a set of one billion keys, such that the key to last week’s PRNG is somewhere in that set. In this scenario, last week’s PRNG can still be shown to be highly non-random, but the test will be very laborious, involving on the order of a billion decryptions.
Note that to be effective against this PRNG, the randomness-testing program will need to release a new version each week. Each version will need to contain the billions of keys needed for checking whether my PRNG-server is “random” or not. This makes a mockery of the idea that there could ever be an all-purpose randomness tester. Even a tester that claims to be “universal” cannot be universal in any practical sense.2 An all-purpose randomness tester would be tantamount to an automatic all-purpose encryption-breaking machine.
To paraphrase Dijkstra: Measurement can prove the absence of randomness, but it cannot prove the presence of randomness. More specifically, any attempt to apply statistical tests to the output of the RNG will give an upper bound on the amount of randomness, but what we need is a lower bound, which is something else entirely.
As described in reference 2, we can calculate the amount of randomness in a physica process, based on a few macroscopic physical properties of the hardware. It is entirely appropriate to measure these macroscopic properties, and to remeasure them occasionally to verify that the hardware hasn’t failed. This provides a lower bound on the randomness, which is vastly more valuable than a statistically-measured upper bound.
As discussed in reference 2, tests such as Diehard (reference 9) and Maurer’s Universal Statistical Test (reference 10) are far from sufficient to prove the correctess of turbid. They provide upper bounds, whereas we need a lower bound.
When applied to the raw data (at the input to the hash function) such tests report nothing more than the obvious fact that the raw data is not 100% random. When applied to the output of the hash function, they are unable to find patterns, even when the density of randomness is 0%, a far cry from the standard (100%) we have set for ourselves.
A related point: Suppose you suspect a hitherto-undetected weakness in turbid. There are only a few possibilities:
The foregoing is a special case of a more general rule: it is hard to discover a pattern unless you have a pretty good idea what you’re looking for. Anything that could automatically discover general patterns would be a universal automatic code-breaker, and there is no reason to believe such a thing will exist anytime soon.
There are some tests that make sense. For instance:
On the one hand, there is nothing wrong with making measurements, if you know what you’re doing. On the other hand, people have gotten into trouble, again and again, by measuring an upper bound on the randomness and mistaking it for a lower bound.
The raison d’etre of turbid is that it provides a reliable lower bound on the density of randomness, relying on physics, not relying on empirical upper bounds.
We ran Maurer’s Universal Statistical Test (reference 10) a few times on the output of turbid. We also ran Diehard. No problems were detected. This is totally unsurprising, and it must be emphasized that we are not touting this a serious selling point for turbid; we hold turbid to an incomparably higher standard. As discussed in section 7.2, for a RNG to be considered high quality, we consider it necessary but nowhere near sufficient for it to pass statistical tests.
To summarize this subsection: At runtime, turbid makes specific checks for common failures. As discussed in section 7.3 occasionally but not routinely apply general-purpose tests to the output.
We believe non-specific tests are very unlikely to detect deficiencies in the raw data (except the grossest of deficiencies), because the hash function conceals a multitude of sins. You, the user, are welcome to apply whatever additional tests you like; who knows, you might catch an error.
We must consider the possibility that something might go wrong with our randomness generator. For example, the front-end transistor in the sound card might get damaged, losing its gain (partially or completely). Or there could be a hardware or software bug in the computer that performs that hashing and control functions. We start by considering the case where the failure is detected. (The other case is considered in section 8.2.)
At this point, there are two major options:
We can ornament either of those options by printing an error message somewhere, but experience indicates that such error messages tend to be ignored.
If the throttling option is selected, you might want to have multiple independent generators, so that if one is down, you can rely on the other(s).
The choice of throttling versus concealment depends on the application. There are plenty of high-grade applications where concealment would not be appropriate, since it is tantamount to hoping that your adversary won’t notice the degradation of your random generator.
In any case, there needs to be an option for turning off – or bypassing – error concealment, since it interferes with measurement and testing as described in section 7.
We can also try to defend against undetected flaws in the system. Someone could make a cryptanalytic breakthrough, revealing a flaw in the hash algorithm. Or there could be a hardware failure that is undetected by our quality-assurance system.
One option would be to build two independent instances of the generator (using different hardware and different hash algorithms) and combine the outputs. The combining function could be yet another hash function, or something simple like XOR.
For a discussion of the Fortuna class of random generators, and how that contrasts with turbid, see reference 11.
For a discussion of the Linux device driver for /dev/random and /dev/urandom, see reference 12.
There is a vast literature on hash functions in general. Reference 13 is a starting point. Reference 14 is a useful literature survey. Reference 15 was an influential early program for harvesting randomness from the audio system; it differs from turbid in not having calibration features. Reference 16 uses the physics of a spinning disk as a source of randomness.
Methods for removing bias from a coin-toss go back to von Neuman; see reference 17 and references therein; also reference 18.
Reference 19 suggests hashing 308 bits (biased 99% toward zero) and taking the low-order 5 bits of the hash to produce an unbiased result. This is correct as far as it goes, but it is inefficient, wasting 80% of the input adamance. Presumably that reflects an incomplete understanding of the hash-saturation principle, in particular the homogeneity property discussed in reference 2, which would have led immediately to consideration of wider hashcodes. There is also no attempt to quantify how closely the results come to being unbiased.
Thanks to Steve Bellovin, Paul Honig, and David Wagner for encouragement, incisive questions, and valuable suggestions.
Practical sources of randomness can be characterized in terms of the adamance density. The raw sources have an adamance density greater than zero and less than 100%. The methods disclosed here make it possible to produce an output that approaches 100% adamance density as closely as you wish, producing symbols that are random enough for any practical purpose. It is important to have a calculated lower bound on the adamance density. In contrast, statistical tests provide only an upper bound, which is not what we need.
It is possible to generate industrial-strength randomness at very low cost, for example by distilling the randomness that is present in ordinary audio interfaces.
In order to refine our notions of what is random and what is not, consider the following million-character strings. We start with
That seems distinctly non-random, very predictable, not very complex. Next, consider the string
That seems also non-random, very predictable, not very complex.
That is somewhat more interesting. The digits pass all known tests for randomness with one narrow exception (namely tests that check for digits of π). However, they must still be considered completely predictable. Finally, consider the two strings
The million-character string represented by example E5 is, as far as anybody knows, completely random and unpredictable. Example E4 is very similar, except that the letter “A” appears more often than it would by chance. This string is mostly unpredictable, but contains a small element of nonrandomness and predictability.
Following Solomonoff (reference 20 and reference 21) and Chaitin (reference 22) we quantify the surprisal of a string of symbols as follows:
Let z be a string of symbols. The elements of z are denoted zk and are drawn from some alphabet Z. The number of symbols in the alphabet is denoted #Z.
Let PC(z) be the probability that computer programs, when run on a given computer C, will print z and then halt. The surprisal is defined to be the negative logarithm of this probability, denoted $C(z) := − logPC(z). In this paper we choose to use base-2 logarithms, so that surprisal is measured in bits. Surprisal is also known as the surprise value or equivalently the unexpectedness. It is intimately related to entropy, as discussed below.
Note that we are using one probability distribution (the probability of choosing a computer program) to derive another (the probability PC(z) of a symbol string). To get this process started, we need to specify a method for choosing the programs. Better yet, using the notions of measure theory, we realize that probability need not involve choosing at all; instead all we really need is a method for assigning weight (i.e. measure) to each of the possible programs. Here is a simple method:3 Consider all possible programs of length exactly L* (measured in bits, since we are representing all programs as bit-strings). Assign each such program equal measure, namely 2−L*. Then test each one and count how many of them produce the desired output string z and then halt, when run on the given computer C. The measure of a string is the total measure of the set of programs that produce it. A string that can be produced by many different programs accumulates a large probability.
In this construction, a short program X (i.e. one which has a length L(X) less than L*) is not represented directly, but instead is represented by its children, i.e. programs formed from X by padding it with comments to reach the required length L*. There are at least 2L*−L(X) ways of doing the padding, and each way contributes 2−L* to the total measure. This means that a string z that can be produced by a short programs X will have a probability at least 2−L(X), no matter how large L* is. We take the limit as L* becomes very large and use this in the definition of PC(z).
Usually the probability PC(z) is dominated by (the children of) the shortest program that produces z. Therefore some people like to use the length of this shortest program as an estimate of the surprisal. This is often a good estimate, but it should not be taken as the definition.
The explicit dependence of PC(z) on the choice of computer C calls attention to an element of arbitrariness that is inherent in any definition of surprisal. Different people will assign different values to “the” surprisal, depending on what resources they have, and on what a priori information they have about the situation.
In an adversarial situation such as cryptography, we suggest that probabilities be defined in terms of the adversary’s computer. If you have multiple adversaries, they can be treated as a single adversary with a parallel computer.
In this section, for conciseness, we drop the subscript C ... but you should remember that the probabilities and related quantities are still implicitly dependent on the choice of C.
A relatively minor objection to this definition of surprisal is that PC(z) includes contributions from arbitrarily-long programs. That is a problem in theory, but in practice the sum is dominated by relatively short programs, and the limit converges quickly.
A much more serious objection is that even for modest-sized programs, the definition runs afoul of the halting problem. That is, there may well be programs that run for a million years without halting, and we don’t know whether they would eventually produce string z and then halt. This means the surprisal, as defined here, is a formally uncomputable quantity.
We will duck both these issues, except for the following remarks.
In this section we shift attention from the unpredictability of strings to the unpredictability of the individual symbols making up the string.
Let us re-examine the examples given at the beginning of this section. Example E5 has surprisal $(z) very close to L(z) log(#Z). We classify strings of this sort as absolutely-random, by which we mean algorithmically-random.
Examples E1, E2, and E3 all have surprisal much less than their length. These strings are clearly not absolutely-random.
The interesting case is example E4. Intuitively, we think of this as “somewhat unpredictable” but more predictable than E5. To make this notion quantitative, we introduce the notion of surprise density. The following quantity tells us the surprise density of the string z in the region from i to j:
where Front(z,i) is the substring formed by taking the first i symbols of the string z.
The surprise density for examples E1, E2, and E3 is zero for any region not too near the beginning. The surprise density for example E5 is as large as it possibly could be, namely 100% of log(#Z). Example E4 illustrates the interesting case where the surprise density is quite a bit greater than zero, but not quite 100% of log(#Z).
As mentioned in section 5.2, we consider the unadorned term “random” to be ambiguous, because it means different things to different people. Some people think “random” should denote 100% surprise density, and anything less than that is “non-random” even if it contains a great deal of unpredictability. Other folks think that “random” refers to anything with an surprisal density greater than zero, and “non-random” means completely predictable. Yet other folks extend “random” to include pseudo-random strings, as long as they are “random enough” for some application of interest. Even some professionals in the field use the word this way; reference 23 and the more recent reference 24 speak of “deterministic random number generators”, although it could be argued that it is impossible in principle for a process to be both deterministic and random. The randomness of a PRNG comes from the seed. Calling a PRNG “deterministic” seriously understates the importance of the seed.
In the space of all possible strings, almost all strings are absolutely-random, i.e. are algorithmically-random, i.e. contain 100% surprise density. However, the strings we find in nature, and the strings we can easily describe, all have very little surprise density. We can summarize this by saying: “All strings are absolutely-random, except for the ones we know about”.
We can use similar ideas to describe PRNGs and contrast them with HRNGs.
|Most of modern cryptography revolves around notions of computational intractability. (I’m not saying that’s good or bad; it is what it is.||In contrast, there is another set of notions, including adamance, entropy, and the related notion of unicity distance, that have got nothing to do with computational intractability.|
|The long strings produced by a good PRNG are conditionally compressible in the sense that we know there exists a shorter representation, but at the same time we believe them to be conditionally incompressible in the sense that the adversary has no feasible way of finding a shorter representation.||The long strings produced by a HRNG are unconditionally, absolutely incompressible. Specifically, the set of strings collectively cannot be compressed at all. As for each string individually, it is not compressible either, except possibly for trivially rare cases and/or trivial amounts of compression.|
This section is a collection of details about certain soundcards. (You can refer back to table 2 for a summary of the performance of a few soundcards. Also, section 4 provides step-by-step procedures that apply to “generic” soundcards.)
Soundcards generally include mixer functions. You have to initialize the mixer, to set the sliders on the features you want and/or to set the switches to bypass the features you don’t want. This is a bit of a black art, because the soundcards typically don’t come with any “principles of operation” documentation.
Graphical user interface (GUI) programs such as alsamixer may help you make some settings, but may not suffice to fully configure the mixer. All too often, the card has “routing switches” and other features that the GUI doesn’t know about. A reasonable procedure that gives complete control is to invoke “alsactl -f record.ctl store”, edit record.ctl, then “alsactl -f record.ctl restore”. Or you can use amixer to fiddle one setting without disturbing others.
The Intel High-Definition Audio spec (reference 25) describes the codec but says remarkably little about mixer functions.
This is yet another example of hype and deception from Creative Labs. The device itself, the box it comes in, and the advertising all prominently mention USB, 24-bit audio, and 96 kHz sampling rates. However, according to all available evidence, the device will not transmit 24-bit audio via USB to the DACs or from the ADCs (no matter what the data rate). It also will not transmit 96 kHz samples via USB to the DACs or from the ADCs (no matter what the word size).
Apparently the only way in which the Extigy can deal with 24 bits or 96 kHz is by shipping it digitally (e.g. via S/PDIF) to/from some other device.
It also has astonishingly poor input sensitivity. It’s about 5 times worse than a typical cheap sound card, and about 100 times worse than a decent 24-bit soundcard, as you can see from table 2.
The Extigy is no good for present purposes. I recommend you do not buy this product. Many other Creative Labs products have problems, too, so in fact I recommend that you never buy anything made by them.
This is a high-end system, with eight analog inputs, eight analog outputs, 96000 frames per second, and 24 bits of resolution. M-Audio was previously known as Midiman.
Each of the eight analog input and each of the eight analog outputs has a pushbutton that I call the “pro/con” switch. Professional studio equipment (pro) runs at lower impedances and lower signal levels than consumer-grade home audio equipment (con). That is, the pro setting (switch pushed in) means lower impedance and lower open-circuit voltage on output, and lower impedance and greater voltage-sensitivity on input. Whether you care about the lower impedance depends on the impedance of whatever the card is hooked to.
The card does not have an 8×8 or 10×10 mixer board. It is apparently 10×2. We bypass it, as discussed below.
The alsa driver always expects 10 channels of output: 8 analog plus 2 S/PDIF. If you are only interested in a subset thereof, you have to pad things so the buffer has 10 samples per frame anyway. Similarly, the alsa driver always produces 12 samples per frame on input: 8 analog plus 2 S/PDIF plus 2 from the mixer. For present purposes we use the 8 analog inputs and ignore the others, since they contain no additional randomness. Therefore you must pass the --channel-mask 255 option to turbid; otherwise the program will have less randomness than it thinks it has, by a factor of 8/12ths.
Each of the eight analog inputs is always routed directly to its own DAC, so the PCM input functionality is always unaffected by the sliders and switches on the mixer.
The routing can be set so that each of the eight analog outputs is fed directly from the PCM data. This is recommended. This makes the PCM output functionality independent of the sliders on the mixer.
Getting this to work requires the following tricks:
As usual, you will need the .ctl file (included in the turbid bundle) plus the settings in table 2.
The same jack doubles as a Line-In port and Mike-In port, depending on software settings. Unlike the typical Mike-In port as described in section 4.3, this Mike-In port is stereo and does not provide power to the microphone. This would be bad if you wanted to connect a microphone that needed power, but it’s ideal for our purposes. Basically it’s like an ordinary Line-In port, with higher sensitivity.
For reasons discussed in reference 8, the Johnson noise in any Ohmic resistor is nice white noise. Voltage samples are independent and identically distributed (IID), according to a Gaussian normal distribution with zero mean and variance given by
where k is Boltzmann’s constant, T is the temperature (300 K), B is the bandwidth, and the brackets ⟨⋯⟩ denote the ensemble average.
The bandwidth is essentially the average of gain squared, averaged over all frequencies. We care about the square of the gain, because in equation 2 we care about the square of the voltage.
The principle of the bandwidth measurement is as follows: Equation 2 tells us the variance of the voltage right at the resistor. The quantity we actually measure has been amplified, according to some gain function G which depends on frequency. So a more complete description is
|4 k T R |G(f)|2 df (3)|
where the subscript o on σo indicates this is the quantity we observe, and fmax is some “large enough” frequency; the real, relevant bandwidth B is hidden in G, which goes to zero at large frequencies. Since G is presumably an even function of frequency, we can rewrite this as
|2 k T R |G(f)|2 df (4)|
and in a discrete (sampled) system this becomes
|2 k T R |G(k Δf)|2 Δf (5)|
where we identify the sampling frequency N = MΔf = 2 fmax, covering the whole range of positive and negative frequencies. We can write this in the suggestive form
|σo2 = 4 k T R G*2 B (6)|
where G*2 is some nominal mid-band power gain, if we identify
||G(k Δf)|2 Δf (7)|
and we call B the power-averaged bandwidth.
By definition the gain G is Vo / Vr, where Vr is the voltage right at the resistor, and Vo is what we observe.
This expression applies to any Vo/Vr ratio, whether Vr comes from thermal noise or from any other source.
We choose to inject a non-thermal probe signal Vr. It is constructed to be “white” – i.e. it has constant magnitude independent of frequency. That allows us to pull it outside the summation:
and by Parseval’s theorem we can rewrite that frequency-domain expression as a time-domain expression
It is easy to get a good lower bound on B. At compile time, we know the root-mean-square (RMS) magnitude of the internal representation of the probe signal; by construction it is -15dBFS. Then given K and R (and Zref) we know ⟨Vr2⟩ in the passband. At frequencies outside the passband this voltage will roll off a little, because of the anti-aliasing filter in the soundcard output stage. This will cause us to under-estimate B by a little, which is harmless. Finally we determine ⟨Vo2⟩ by summing the squares of the observed voltage samples and multiplying by the appropriate calibration factors (involving Q).
You might have thought based on the form of equation 3 that we would need to take a Fourier transform, but we don’t, because of Parseval’s theorem.
In the turbid software, whenever possible, voltages are measured in SI volts.
If that is not possible, e.g. when representing raw readings as they come from the hardware, before calibration, anything that is linear in voltage is measured in input buffer units such that 1.0 ibu is full scale i.e. the largest thing that can be represented.
Meanwhile, anything that is measured in dBx is measured relative to a reference level that is 15 dB below full scale. This means that a rail-to-rail square wave (such as might result from extreme clipping) peaks at 1.0 ibu, has an RMS of 1.0 ibu, and a power level of +15 dBx. Similarly a sine wave that peaks at exactly 1.0 ibu has an RMS of 0.707 ibu, and a power level of +12 dBx.
As always, a dB is a power measurement. This includes dBx. It does not depend directly on the peak voltage. As a corollary, the peak voltage of a zero-dBx sine wave √2 higher than the top of a zero-dBx square wave.
Suppose the computer’s audio output circuit has some gain g and some Thévenin equivalent series resistance Rout, both of which we want to determine. We connect some external load resistance and measure the voltage. Then we connect some different load, and measure the voltage again. If one of the loads has infinite resistance, that gives us a direct measure of the open-circuit voltage.
During this process, the turbid output is represented in the output buffer by a sine wave of amplitude X (RMS), measured in hins. Therefore the open-circuit voltage is Voc = gX, which defines what we mean by g.
On the ith measurement, the voltage observed on the meter is:
So if we plot the inverse voltage gain (X/Vm, i) as a function of the inverse resistance (1/Rload, i), we should get a straight line with slope Rout/g and intercept 1/g.
In the turbid code, we speak of oropoints. Each oropoint is an ordered pair, (1/Rload, X/Vm). The gain g is represented in turbid by the variable gVout, which has dimensions of hins per volt.
Now let’s feed the computer’s audio output circuit into an external resistor network. The combination forms a linear circuit with some effective Thévenin equivalent open-circuit voltage Veff and effective series resistance Reff, both of which we can calculate from the known properties of the circuit. These properties include the computer’s output impedance, Rout, which is considered known, since it was determined in section E.1. Similarly the driving voltage Voc = gX is known, since we control X and we calibrated g in section E.1.
We connect the output of this network to the audio input. The input port has some input impedance Rin and some gain b, both of which we need to determine. We can observe the digitized input signal Yj as it appears in the input buffer, measured in hins.
So if we plot the observed inverse gain Veff/Yj as a function of the calibration network equivalent resistance Reff, j, we should get a straight line with slope b/Rin and intercept b. You can easily check this formula in the limiting cases Reff = 0 and Reff → ∞.
In the turbid code, we speak of oripoints. Each oripoint is an ordered pair (Reff, Veff/Y). The inverse gain b is represented by the variable bVin, and has units of volts per hin.
For some perspectives on Johnson noise and the Nyquist formula, including what happens when there is a frequency-dependent gain, see reference 26.
This has some interesting implications and ramifications for our randomness generator. There are a couple of regimes to consider:
In this regime, assuming the goal is to collect noise samples, you don’t want to add any additional resistance in parallel with what’s already there. That would just move the flat part of the curve to a lower voltage. (It would also push the corner frequency out to a higher frequency, but that doesn’t do any good if the digitizer doesn’t go that high.)
There are various ways of dealing with this.
In this regime it makes sense to add some resistance. This whitens the noise. It lowers the peak noise per unit bandwidth. However, remember that the area under the curve is independent of the resistance. So as long as the corner frequency is not large compared to what your digitizer can handle, you’re not losing anything by lowering the resistance.
If the added external resistance dominates the internal resistance, that provides a nice convenience: It means you know what the resistance value is. This simplifies the calibration.
The block size can plausibly be as small as the period, and as large as the buffer. On input, a small block size seems to have little or no effect on efficiency. In contrast, output block size seems to have a significant effect on efficiency. Larger blocks are more efficient. I have no clue how to explain the contrast.
Some ALSA timing is shown in figure 14. This is peculiar in a couple of ways. For one thing, the capture i/o buffer is a different size from the playback i/o buffer. Also, the first readi has been artificially delayed by 10 milliseconds relative to the first writei, just to clarify the relationship between the two streams.
Each rectangle represents an i/o call. The bottom of the rectangle is the number of frames (input or output) before the call, and the top is the number of frames (input or output) after the call. Similarly the left edge is the time at the start of the call, and the right edge is the time upon return from the call.
In figure 14 the command was turbid show timing comb 0 freq 1000 ochan 0. You can see that the playback process has a lot of work to do, so the corner of one red rectangle does not meet the corner of the next. In contrast, the capture process has very little work to do, so the rectangles very nearly meet corner-to-corner.
Now consider what happens when we use snd_pcm_link(...) to synchronize the two streams. At the time of the first write to the playback device, the playback stream starts running (obviously) ... and the capture stream also starts running (because it is linked). The artificial 10 ms delay is still there, but it affects only the left edge of the first rectangle, not the right edge.
Figure 16 comes from reference 27. As you can see, the audio circuitry «supposed» to be independent of the plug-sense circuits. However, the observed fact is that not all computer manufacturers play by these rules. There are machines from reputable companies where the Mic-In audio signal gets shorted to ground when the jack is removed.
The elegant behavior suggested by figure 16 stands in contrast to the old but not venerable AC’97 standard, as shown in figure 17. It called for grounding the audio signals when the plug was removed. However, 1997 was a lot of dog years ago. In an HD Audio system, grounding is nonstandard. From the turbid point of view, it is undesirable. It means you have to physically plug something into the jack in order to harvest high-quality noise.
Reconfig requires that the sound card not be in use. That means you have to shut down all of the following processes:
You might need to shut down some others also:
To find who’s using the audio system, you might use the command
:; lsof | grep /dev/snd
To exercise the early-patch features, such as hints, you do not need to unload the entire sound-driver stack. Unloading and reloading the snd_hda_intel is sufficient.
:; modprobe -r snd_hda_intel :; modprobe -a snd_hda_intel
The “early patch” firmware file requires vendor_id, subsystem_id, and card address. For any given card, you can get this information from:
:; head /proc/asound/card0/codec#0
Note that “codec” number is the same as “device” number, so that /proc/asound/card0/codec#0 corresponds to /dev/snd/hwC0D2.
Name the files after the vendor_id and subsystem_id, such as
The latter contains a single line, namely:
options snd-hda-intel patch=alsa-early-patch-0x14f15051-0x17aa2100.fw
The .fw file itself looks like:
[codec] 0x14f15051 0x17aa2100 0 [hint] jack_detect = false add_jack_modes = true
If you think jack_detect=false is too drastic, it suffices to use the milder alternative, namely auto_mic=false.
Key concept: The HDA chip has a bunch of widgets. In contrast, the ALSA system presents a bunch of controls. There is not a one-to-one relation between them. For example, the Master volume control is implemented by monkeying with the gain on multiple different audio widgets. To say the same thing the other way, the gain on the widget for a particular channel is likely to be the set according to the product of the per-channel volume control and the master volume control.
Similarly, what alsamixer calls a “recording switch” bears little resemblance to how it is implemented on the hardware. The kernel implements it by fiddling with the digital “stream” and analog “connection” properties of the various widgets.
Note the section on HD-Audio Reconfiguration, including the "user hints" especially auto_mic and jack_detect.
echo auto_mic=false > /sys/class/sound/hwC0D0/hints echo jack_detect=no > /sys/class/sound/hwC0D0/hints echo asdf > /sys/class/sound/hwC0D0/reconfig
This is an “experimental” feature and makes a big mess, but it may be useful for experimenting. On the other hand, writing a firmware file and unloading/reloading the drivers makes less of a mess.
“The High Definition Audio Specification defines a complete codec architecture that is fully discoverable and configurable so as to allow a software driver to control all typical operations of any codec.”
“Every Pin Widget must contain a Configuration Default Register as defined in Section 220.127.116.11. In order to save parameter space in a function group incorporating several Pin Widgets, the function group node may optionally contain defau lts for the amplifier parameters; however, these defaults may be overridden with local parameters if necessary.”
:; cat /proc/asound/card0/codec#0
:; echo auto_mic=false > /sys/class/sound/hwC0D0/hints :; echo asdf > /sys/class/sound/hwC0D0/reconfig
cat /sys/class/sound/hwC0D0/init_pin_configs | while read a b ; do echo echo -n "$a: " ~/turbid/src/hda-emu/hda-decode-pincfg $b done
:; hda-verb /dev/snd/hwC0D0 0x16 GET_PIN_SENSE 0 nid = 0x16, verb = 0xf09, param = 0x0 value = 0xffffffff # plugged :; hda-verb /dev/snd/hwC0D0 0x16 GET_PIN_SENSE 0 nid = 0x16, verb = 0xf09, param = 0x0 value = 0x7fffffff # unplugged :; hda-verb /dev/snd/hwC0D0 0x18 GET_PIN_SENSE 0 nid = 0x18, verb = 0xf09, param = 0x0 value = 0xffffffff # plugged :; hda-verb /dev/snd/hwC0D0 0x18 GET_PIN_SENSE 0 nid = 0x18, verb = 0xf09, param = 0x0 value = 0x7fffffff # unplugged
# color blue, cannot sense pin detect, i.e. no presence detect: :; hda-verb /dev/snd/hwC0D0 0x18 SET_CONFIG_DEFAULT_BYTES_1 0x31 # default pink, can do sense pin detect, i.e. no presence detect: :; hda-verb /dev/snd/hwC0D0 0x18 SET_CONFIG_DEFAULT_BYTES_1 0x90
The effect is cosmetic only: ./scan-hda shows the pin complex as having the noPD property, but it still notices the plug coming and going, and still mutes the input when unplugged. It takes effect immediately; there is no need to reconfigure the kernel software. Part of the problem is that the kernel looks at the PD indicators, even if the chip tells it not to. The only way to get the kernel to play along is via hints, as discussed above.
:; hda-verb /dev/snd/hwC0D0 0x18 SET_CONFIG_DEFAULT_BYTES_3 0x42 # default, connected to 1/8th inch jack: :; hda-verb /dev/snd/hwC0D0 0x18 SET_CONFIG_DEFAULT_BYTES_3 0x02 # Similar story: Immediate cosmetic effect, but no change in # performance. # zap the built-in microphone; was 0x10 :; hda-verb /dev/snd/hwC0D0 0x14 SET_CHANNEL_STREAMID 0x00 # turn on front microphone; was 0x00 :; hda-verb /dev/snd/hwC0D0 0x15 SET_CHANNEL_STREAMID 0x10
You cannot set pin_sense. The corresponding verb tells the device to measure the impedance of left versus right channel, in accordance with the spec, reference 25.
During system startup, the init scripts try to initialize the soundcard state from that file. The tool (alsactl) is very brittle, so if anything has changed initialization will fail.
It also reads /etc/pulse/client.conf and other strange stuff.
Then it tries to read file:///etc/asound.conf and finally file: /.asoundrc (in the user’s home directory).
amixer gives a decent look at the ALSA “controls”. It is complimentary to cat /proc/asound/card0/codec#0 which gives a good look at the audio widgets on the chip.
The following may put things in perspective:
The input impedance is on the order of 47 kΩ.
The protection circuits include a 220 pF capacitor, as indicated in figure 16.
That gives an RC time constant on the order of 10 microseconds. That corresponds to a corner frequency of 100,000 radians per second [1/(RC)], or about 15 kHz [1/(2πRC)].
If you actually do the integral, you find that the effective noise bandwidth is bigger than the corner frequency by a factor of π/2. This means there is a modest contribution (about 50% extra) from the wings of the distribution, above the corner frequency. In symbols, that gives us a noise bandwidth of 1/(4RC). Plugging into equation 2 give us:
The last line tells us the average energy in the capacitor is exactly what we would expect from the most fundamental notions of thermodynamics, i.e. equipartition.
We assume the operating temperature is 15 centigrade or above. That gives us an absolute temperature of 288.15 kelvin.
That gives a RMS voltage of 4.25 microvolts across the 220 pF protection capacitor. That is the σ i.e. the standard deviation of the voltage distribution.
A typical input sensitivity is 0.001191 volts per hin.
There are 5.62 hins per bath, so we can write the sensitivity as 0.0107 volts per bath, i.e. 0.0107 volts full scale, or 0.0214 volts peak-to-peak.
For 16-bit digitizer, that gives us 0.328 microvolts per code.
That means we have about 13 codes per σ.
The maximum probability of a Gaussian is 1/√(2π) 1/σ which in this scenario comes to 0.0308.
That means we get about 5 bits of adamance per sample.
All of Volume I is available online: