01: package org.bouncycastle.crypto.prng;
02:
03: /**
04: * Takes bytes generated by an underling RandomGenerator and reverses the order in
05: * each small window (of configurable size).
06: * <p>
07: * Access to internals is synchronized so a single one of these can be shared.
08: * </p>
09: */
10: public class ReversedWindowGenerator implements RandomGenerator {
11: private final RandomGenerator generator;
12:
13: private byte[] window;
14: private int windowCount;
15:
16: public ReversedWindowGenerator(RandomGenerator generator,
17: int windowSize) {
18: if (generator == null) {
19: throw new IllegalArgumentException(
20: "generator cannot be null");
21: }
22: if (windowSize < 2) {
23: throw new IllegalArgumentException(
24: "windowSize must be at least 2");
25: }
26:
27: this .generator = generator;
28: this .window = new byte[windowSize];
29: }
30:
31: /**
32: * Add more seed material to the generator.
33: *
34: * @param seed a byte array to be mixed into the generator's state.
35: */
36: public void addSeedMaterial(byte[] seed) {
37: synchronized (this ) {
38: windowCount = 0;
39: generator.addSeedMaterial(seed);
40: }
41: }
42:
43: /**
44: * Add more seed material to the generator.
45: *
46: * @param seed a long value to be mixed into the generator's state.
47: */
48: public void addSeedMaterial(long seed) {
49: synchronized (this ) {
50: windowCount = 0;
51: generator.addSeedMaterial(seed);
52: }
53: }
54:
55: /**
56: * Fill bytes with random values.
57: *
58: * @param bytes byte array to be filled.
59: */
60: public void nextBytes(byte[] bytes) {
61: doNextBytes(bytes, 0, bytes.length);
62: }
63:
64: /**
65: * Fill part of bytes with random values.
66: *
67: * @param bytes byte array to be filled.
68: * @param start index to start filling at.
69: * @param len length of segment to fill.
70: */
71: public void nextBytes(byte[] bytes, int start, int len) {
72: doNextBytes(bytes, start, len);
73: }
74:
75: private void doNextBytes(byte[] bytes, int start, int len) {
76: synchronized (this ) {
77: int done = 0;
78: while (done < len) {
79: if (windowCount < 1) {
80: generator.nextBytes(window, 0, window.length);
81: windowCount = window.length;
82: }
83:
84: bytes[start + done++] = window[--windowCount];
85: }
86: }
87: }
88: }
|