| From 19acc77a36970958a4a0e4daeb2c8cb2aab0ffd4 Mon Sep 17 00:00:00 2001 |
| From: George Spelvin <linux@horizon.com> |
| Date: Sat, 7 Feb 2015 00:32:06 -0500 |
| Subject: random: Fix fast_mix() function |
| |
| From: George Spelvin <linux@horizon.com> |
| |
| commit 19acc77a36970958a4a0e4daeb2c8cb2aab0ffd4 upstream. |
| |
| There was a bad typo in commit 43759d4f429c ("random: use an improved |
| fast_mix() function") and I didn't notice because it "looked right", so |
| I saw what I expected to see when I reviewed it. |
| |
| Only months later did I look and notice it's not the Threefish-inspired |
| mix function that I had designed and optimized. |
| |
| Mea Culpa. Each input bit still has a chance to affect each output bit, |
| and the fast pool is spilled *long* before it fills, so it's not a total |
| disaster, but it's definitely not the intended great improvement. |
| |
| I'm still working on finding better rotation constants. These are good |
| enough, but since it's unrolled twice, it's possible to get better |
| mixing for free by using eight different constants rather than repeating |
| the same four. |
| |
| Signed-off-by: George Spelvin <linux@horizon.com> |
| Cc: Theodore Ts'o <tytso@mit.edu> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/char/random.c | 8 ++++---- |
| 1 file changed, 4 insertions(+), 4 deletions(-) |
| |
| --- a/drivers/char/random.c |
| +++ b/drivers/char/random.c |
| @@ -569,19 +569,19 @@ static void fast_mix(struct fast_pool *f |
| __u32 c = f->pool[2], d = f->pool[3]; |
| |
| a += b; c += d; |
| - b = rol32(a, 6); d = rol32(c, 27); |
| + b = rol32(b, 6); d = rol32(d, 27); |
| d ^= a; b ^= c; |
| |
| a += b; c += d; |
| - b = rol32(a, 16); d = rol32(c, 14); |
| + b = rol32(b, 16); d = rol32(d, 14); |
| d ^= a; b ^= c; |
| |
| a += b; c += d; |
| - b = rol32(a, 6); d = rol32(c, 27); |
| + b = rol32(b, 6); d = rol32(d, 27); |
| d ^= a; b ^= c; |
| |
| a += b; c += d; |
| - b = rol32(a, 16); d = rol32(c, 14); |
| + b = rol32(b, 16); d = rol32(d, 14); |
| d ^= a; b ^= c; |
| |
| f->pool[0] = a; f->pool[1] = b; |