ASSUMPTIONS   [plain text]


Assumptions
===========

The Yarrow design, described in "Yarrow-160: Notes on the Design and
Analysis of the Yarrow Cryptographic Pseudonumber Generator" by John
Kelsey, Bruce Schneier and Niels Ferguson of Counterpane Systems
(available from http://www.counterpane.com/yarrow.html), left out some
implementation details and has some ambiguities in the protocol.  ZKS
has to made some assumptions and taken some decisions in its
implementation of Yarrow. In the text, `we' represents ZKS.

Here is the list of those assumptions: 

1) To simplify the code and speed up running time, we limit the number
of different sources to 20. This should be enough for most
applications. This can be changed by redefining YARROW_MAX_SOURCE in
yarrow.h.

2) The Yarrow paper (in section 5.3) state that Pt is either
implementation dependent or dynamically adjusted. We chose to fix the
slow pool's Pt to 100 and the fast pool's Pt to 10. This can be
changed by redefining YARROW_FAST_PT and YARROW_SLOW_PT in yarrow.c.

3) Initialization when there is no saved state is not discussed in the
Yarrow paper.  We have defined that CPRNG is becomes seeded after a
slow reseed.  During initialization, a slow reseed is triggered by
YARROW_K_OF_N_INIT_THRESH sources reaching the slow threshold
YARROW_SLOW_INIT_THRESH.  During initialization, fast reseeds are
triggered when a source reaches the fast threshold
YARROW_FAST_INIT_THRESH.  After reseed the behavior of the pools is
controlled by YARROW_K_OF_N_THRESH, YARROW_SLOW_THRESH and
YARROW_FAST_THRESH.  

Our default values for YARROW_K_OF_N_INIT_THRESH,
YARROW_SLOW_INIT_THRESH and YARROW_FAST_INIT_THRESH are the same as
YARROW_K_OF_N_THRESH, YARROW_SLOW_THRESH and YARROW_FAST_THRESH
respectively.  Note this means that a Yarrow_Poll call by itself can
never put us in an initialized state, as it only works on one pool,
and the default YARROW_K_OF_N_INIT_THRESH value is 2.

4) We define a function Yarrow_Poll which can gather entropy.  The
user must allocate a source_id, and call Yarrow_Poll manually.
Yarrow_Poll just adds samples from the machines state to the source
given as an argument.

5) Prior to initialization, Yarrow_Output will fail.

6) The actions to take on state load are not described in the yarrow
paper, all it says is that 2k bytes should be written (and by
implication read back in somehow).  We read in the 2k bytes, hash
them into the fast pool, and then do a forced fast reseed, and an
immediate state save.

7) In step 2 of the reseed process, we must hash the value i. The
representation of this integer will affect the hash value. In our
code, i is a 64-bit unsigned value. We update the hash context using
the 64 bit big endian representation of i.

8) Yarrow outputs random bits in blocks. If the calling function
requests less bits than available, then the unused bits are kept
in memory until the next call. In case of a reseed, we chose to 
discard those leftover bits.

9) The samples from one source must alternate between the two pools.
As a default, we initialize the first pool to send the sample too to
be the fast pool. This initialization is done only when a source is
added, not when we reseed from one.

10) The Yarrow paper states that the maximum number of outputs between
reseeding is limited to min(2^n,2^(k/3)*Pg), but does not explain
what is to happen when this limit is reached. It could be the case
that we reach the limit but there is not enough entropy in the pools 
to reseed. In our code, the Yarrow_Output_Block will do a forced
fast reseed. 

11) In the Yarrow paper, the limit on the number of outputs between
reseeding is expressed in number of outputs:

#oututs <= min(2^n, 2^(k/3).Pg)

but we redefine it in terms of gates by dividing the numbers by Pg,
the number of outputs per gate, and counting the number of gates
instead.  This makes an overflow a little less likely.

We don't use a bignum library, so in event of overflow, the limit in
number of gates before reseed (y->gates_limit) is reduced down to
2^64-1 (or 2^32-1 if 64 bit ints aren't available on the platform).

12) The Yarrow paper describes that the cipher block C should be 
incremented as part of the output function.  We treat the bytes
of C as a big endian number to do the increment.

13) Triple-DES key size.  The yarrow paper uses the letter k to
represent the keysize in bits.  Due to the parity bits, the size of k
is 192 bits.  However the effective key size is actually 168 bits, as
the value of k is used in security limits, k must be 168 bits.  The
paper uses k (eg set K to the next k output bits), so we have to do
the parity padding function, to copy bits 0-6 to 0-7, 7-13 to 8-15
etc.  The macro DES_Init performs the function of doing a DES key
schedule from a packed key (no parity bits), internally doing the
parity padding.  Other ciphers are simpler as there is no parity.