diff --git a/yarrow256.c b/yarrow256.c
index 16722c3aa3c82d74ad3180e6beb263f6a51347cc..674143aa7fa3b1ef22d0e9ab494c5b1c0e75b5b2 100644
--- a/yarrow256.c
+++ b/yarrow256.c
@@ -37,6 +37,15 @@
 /* Generator gate threshold */
 #define YARROW_GATE_THRESHOLD 10
 
+/* Entropy threshold for reseeding from the fast pool */
+#define YARROW_FAST_THRESHOLD 100
+
+/* Entropy threshold for reseeding from the fast pool */
+#define YARROW_SLOW_THRESHOLD 160
+
+/* Number of sources that must exceed the threshold for slow reseed */
+#define YARROW_SLOW_K 2
+
 /* Entropy estimates sticks to this value, it is treated as infinity
  * in calculations. It should fit comfortably in an uint32_t, to avoid
  * overflows. */
@@ -52,10 +61,61 @@ yarrow256_init(struct yarrow256_ctx *ctx,
 
   ctx->seeded = 0;
 
+  /* Means that we have no buffered output */
+  ctx->index = sizeof(ctx->buffer);
+  
   ctx->nsources = n;
   ctx->sources = s;
 }
 
+/* NOTE: The SHA-256 digest size equals the AES key size, so we need
+ * no "size adaptor". We also use P_t = 0, i.e. we don't currently try
+ * to make reseeding computationally expensive. */
+
+static void
+yarrow_fast_reseed(struct yarrow256_ctx *ctx)
+{
+  uint8_t digest[SHA256_DIGEST_SIZE];
+  
+  unsigned i;
+
+  sha256_final(&ctx->pools[YARROW_FAST]);
+  sha256_digest(&ctx->pools[YARROW_FAST], sizeof(digest), digest);
+  sha256_init(&ctx->pools[YARROW_FAST]);
+  
+  aes_set_key(&ctx->key, sizeof(digest), digest);
+
+  /* Derive new counter value */
+  memset(ctx->counter, 0, sizeof(ctx->counter));
+  aes_encrypt(&ctx->key, sizeof(ctx->counter), ctx->counter, ctx->counter);
+  
+  /* Reset estimates. */
+  for (i = 0; i<ctx->nsources; i++)
+    ctx->sources[i].estimate[YARROW_FAST] = 0;
+}
+
+static void
+yarrow_slow_reseed(struct yarrow256_ctx *ctx)
+{
+  uint8_t digest[SHA256_DIGEST_SIZE];
+  unsigned i;
+
+  /* Get digest of the slow pool*/
+  
+  sha256_final(&ctx->pools[YARROW_SLOW]);
+  sha256_digest(&ctx->pools[YARROW_SLOW], sizeof(digest), digest);
+  sha256_init(&ctx->pools[YARROW_SLOW]);
+
+  /* Feed it into the fast pool */
+  sha256_update(&ctx->pools[YARROW_SLOW], sizeof(digest), digest);
+
+  yarrow_fast_reseed(ctx);
+  
+  /* Reset estimates. */
+  for (i = 0; i<ctx->nsources; i++)
+    ctx->sources[i].estimate[YARROW_SLOW] = 0;
+}
+
 void
 yarrow256_update(struct yarrow256_ctx *ctx,
 		 unsigned source_index, unsigned entropy,
@@ -107,7 +167,29 @@ yarrow256_update(struct yarrow256_ctx *ctx,
     }
 
   /* Check for seed/reseed */
-  
+  switch(current)
+    {
+    case YARROW_FAST:
+      if (source->estimate[YARROW_FAST] >= YARROW_FAST_THRESHOLD)
+	yarrow_fast_reseed(ctx);
+      break;
+    case YARROW_SLOW:
+      {
+	/* FIXME: This is somewhat inefficient. It would be better to
+	 * either maintain the count, or do this loop only if the
+	 * current source just crossed the threshold. */
+	unsigned k, i;
+	for (i = k = 0; i < ctx->nsources; i++)
+	  if (ctx->sources[i].estimate[YARROW_SLOW] >= YARROW_SLOW_THRESHOLD)
+	    k++;
+
+	if (k >= YARROW_SLOW_K)
+	  {
+	    yarrow_slow_reseed(ctx);
+	    ctx->seeded = 1;
+	  }
+      }
+    }
 }
 
 static void
@@ -116,14 +198,16 @@ yarrow_generate_block(struct yarrow256_ctx *ctx,
 {
   unsigned i;
   
-  aes_encrypt(&ctx->key, AES_BLOCK_SIZE, block, ctx->counter);
+  aes_encrypt(&ctx->key, sizeof(ctx->counter), block, ctx->counter);
 
-  /* Increment counter, treating it as a big-endian number.
+  /* Increment counter, treating it as a big-endian number. This is
+   * machine independent, and follows appendix B of the NIST
+   * specification of cipher modes of operation.
    *
-   * We could keep a representation of th counter as 4 32-bit values,
+   * We could keep a representation of thy counter as 4 32-bit values,
    * and write entire words (in big-endian byteorder) into the counter
    * block, whenever they change. */
-  for (i = AES_BLOCK_SIZE; i--; )
+  for (i = sizeof(ctx->counter); i--; )
     {
       if (++ctx->counter[i])
 	break;