Tiny is divided into two parts, the Entropy Gateway (EG) and the
Pseudo-Random Number Generator (PRNG).  The PRNG is a slight
modification of the PRNG used in Yarrow-160 (we use a MAC in counter
mode instead of a block cipher in counter mode, and make other minor
changes).  The entropy gateway is totally different than anything
specified in the Yarrow paper, and is also completely different from
the Yarrow-AES algorithm John and Pravir worked on while at Cigital
(potential IP issues was one reason for this new algorithm; efficiency
was the other).


The Tiny EG

Parameters: 
N:      maximum number of sources (1..)
POOLSZ: Size of entropy pool in bytes (128, 256, 512, 1024, 2048)
UOL:    Output length of UMAC algorithm in bytes (1-32)
KEYSZ:  Size of UMAC Key in bytes (16 or 32)
BUFSZ:  Size of output buffer in UMAC-output blocks. (1..)
P/Q:    Fraction of outputs that get mixed in with the UMAC key. (any)
R:      Number of sources we assume can be compromised by an attacker. (1..N-1)

Recommended values are as follows:

N:      10
POOLSZ: 512
UOL:    8
KEYSZ:  16
BUFSZ:  32
P:      1
Q:      10
R:      1

The Tiny EG is composed of an "entropy pool" (a buffer), an array of N
estimates on how much entropy each source has contributed, a UMAC key,
an output counter (an unsigned 128-bit counter which counts the number
of blocks that have been output) and an output buffer.  Other data
structures may be used in an implementation if desirable.

The UMAC nonce is initialized with the current time (gettimeofday()).
It is incremented after every UMAC operation.

The entropy pool is really 8 parallel linear shift feedback registers
(LSFRs).  Entropy sources will mix their data into this pool.  Bytes
get mixed in using a primitive polynomial of the appropriate size over
GF(2).  We can use polynomials from /dev/random, but note that we
cannot directly use the same mixing code, since they use 32 parallel
LSFRS, not 8 (that is, operations here are on bytes not words).  The
entropy pool is initialized to all ones.

When entropy comes in from a source, the entropy counter for that
source is incremented (note that there is no need to count past 64,
and doing so might result in overflow errors).

After entropy is added, the EG checks to see if the LSFR has enough
entropy to output.  The output rule is as follows:

Total the entropy collected from all sources, after subtracting out
the top R contributors.  If the number of bits is > UOL*8, then an
output occurs.

Outputs can go to the output buffer or to the UMAC key.  The rules for
where to output are as follows:

The first KEYSZ/UOL outputs go to the UMAC key.  Whenever the output
buffer is full, outputs go to the UMAC key.  Otherwise, P out of every
Q outputs go to the UMAC key, and all other outputs go to the output
buffer.  The first Q-P outputs should go to the output buffer, and
then the remainder to the UMAC key.

To output to the output buffer:

1) Instantiate a UMAC context.  It should be UMAC64, modified
(potentially) by the UOL and KEYSZ parameters.  

2) Key the context with the UMAC key.

3) Increment the output counter.

3) UMAC the contents of the entropy pool concatenated with the output
counter, placing the result in the output buffer.  Use the nonce and
increment.

4) Set the entropy pool to empty (all ones).


To output to the UMAC key: The UMAC key is broken up into KEYSZ/UOL
parts.  On an output, we only modify one part.  The parts are modified
in order, by XORing the current value of the part with the output.

Outputs are serviced from the buffer.  Outputs should be given in
byte-quantities.  Pending requests that cannot be fufilled should be
queued until output is available.  If multiple requests are pending,
they should be served in round-robin style.

The Tiny EG should be able to save and restore its state.  The UMAC
key should be stored, and perhaps the entropy buffer could be stored
as well.

LSFR polynomials

Here are primitive polynomials taken from /dev/random.  Hopefully they
are not too sparse:

2048 bytes: x^2048 + x^1638 + x^1231 + x^819 + x^411 + x + 1
  (mix 1638th, 1231st, 819th, 411th and 1st byte)
1024 bytes: x^1024 + x^817 + x^615 + x^412 + x^204 + x + 1
512 bytes:  x^512 + x^411 + x^308 + x^208 + x^104 + x + 1
256 bytes:  x^256 + x^205 + x^155 + x^101 + x^52 + x + 1
128 bytes:  x^128 + x^103 + x^76 + x^51 + x^25 + x + 1


EG Rationalle

The EG tries to output pure entropy.  We try to collect at least as
many bits of entropy as we wish to output, and usually collect more,
because of a conservative assumption that an attacker might be able to
compromise one or more entropy sources.  If sufficient entropy exists,
the EG should produce "good" outputs.  We mearly compress and whiten
the entropy pool using UMAC.

When sufficient entropy is not available due to compromise, the UMAC
key provides cryptographic security as a fallback, assuming that the
system has ever mixed sufficient entropy into the UMAC key.  The
output counter is necessary for the case where an attacker can
completely control all input to the entropy pool.

We clear the entropy pool every time to ensure that there are no
correlations between successive outputs (other than the UMAC key,
which does not allow an attacker to predict outputs, even if
compromised).

We use UMAC because it is fast and has good provable properties.  The
only assumption we need to make (assuming our design doesn't suck) is
the cryptographic strength of AES.

The Tiny PRNG

Tiny uses the original Yarrow-160 PRNG, except that:

1) We use UMAC in counter mode instead of a block cipher. 
2) We use a step parameter, instead of a constant step of 1.
3) time() is used as a nonce, which is incremented after each UMAC 
   operation.

The generator gate frequency is a system parameter (for
self-rekeying).  The default frequency is every 10 outputs, as in
Yarrow-160.  The self-rekey operation is about the same as in
Yarrow. The key is overwritten with blocks of generator output, along
with the counter and the counter step.  The step parameter is always
modified to be odd after a rekey.

The seed should be raw entropy, and big enough to set the counter, the
UMAC key and the step parameter.  If the step parameter is not odd, it
is modified to be so.

"Real" reseeds (ones where we add new entropy to the PRNG) can happen
by periodic polling, or by push.  In both cases, there should be a
parameter, minimum time between reseeds.  We recommend 60 seconds as
the default parameter.



