comparison dcrypt/crypto/prngs/PRNGFromHash.d @ 27:8b5eaf3c2979

Fixed error in hash message padding reported by Glenn Haecker.
author Thomas Dixon <reikon@reikon.us>
date Sat, 09 May 2009 23:29:20 -0400
parents 703901987976
children ad687db713a4
comparison
equal deleted inserted replaced
26:176c933827a8 27:8b5eaf3c2979
10 10
11 import dcrypt.crypto.PRNG; 11 import dcrypt.crypto.PRNG;
12 import dcrypt.crypto.Hash; 12 import dcrypt.crypto.Hash;
13 13
14 /** Creates a PRNG from a hash function. */ 14 /** Creates a PRNG from a hash function. */
15 class PRNGFromHash : PRNG { 15 class PRNGFromHash : PRNG
16 private { 16 {
17 private
18 {
17 const uint COUNTER_SIZE = 32; 19 const uint COUNTER_SIZE = 32;
18 20
19 Hash hash; 21 Hash hash;
20 ubyte[] counter, 22 ubyte[] counter,
21 seed, 23 seed,
22 state; 24 state;
23 uint index; 25 uint index;
24 } 26 }
25 27
26 char[] name() { 28 char[] name()
29 {
27 if (hash is null) 30 if (hash is null)
28 throw new NotInitializedError(name()~": PRNG not initialized"); 31 throw new NotInitializedError(name()~": PRNG not initialized");
29 32
30 return hash.name~"PRNG"; 33 return hash.name~"PRNG";
31 } 34 }
32 35
33 this(Hash hash) { 36 this(Hash hash)
37 {
34 if (hash is null) 38 if (hash is null)
35 throw new InvalidParameterError( 39 throw new InvalidParameterError(
36 name()~": Invalid parameter passed to constructor."); 40 name()~": Invalid parameter passed to constructor.");
41
37 this.hash = hash; 42 this.hash = hash;
38 this.hash.reset(); 43 this.hash.reset();
39 44
40 counter = new ubyte[COUNTER_SIZE]; 45 counter = new ubyte[COUNTER_SIZE];
41 seed = new ubyte[this.hash.digestSize]; 46 seed = new ubyte[this.hash.digestSize];
42 state = new ubyte[this.hash.digestSize]; 47 state = new ubyte[this.hash.digestSize];
43 48
44 index = this.hash.digestSize; // to force updating of the state 49 index = this.hash.digestSize; // to force updating of the state
45 } 50 }
46 51
47 void addEntropy(ubyte[] input) { 52 void addEntropy(ubyte[] input)
48 if (!_initialized) { 53 {
54 if (!_initialized)
55 {
49 hash.update(input); 56 hash.update(input);
50 seed = hash.digest(); 57 seed = hash.digest();
51 _initialized = true; 58 _initialized = true;
52 } else 59 } else
53 throw new NotSupportedError(name()~": state is immutable once initialized"); 60 throw new NotSupportedError(name()~": state is immutable once initialized");
54 } 61 }
55 62
56 uint read(ubyte[] output) { 63 uint read(ubyte[] output)
64 {
57 if (!_initialized) 65 if (!_initialized)
58 throw new NotInitializedError(name()~": PRNG not initialized"); 66 throw new NotInitializedError(name()~": PRNG not initialized");
59 67
60 for (uint i = 0; i < output.length; i++) { 68 for (uint i = 0; i < output.length; i++)
61 if (index == state.length) { 69 {
70 if (index == state.length)
71 {
62 hash.update(seed); 72 hash.update(seed);
63 hash.update(counter); 73 hash.update(counter);
64 state = hash.digest(); 74 state = hash.digest();
65 75
66 // Increment the counter 76 // Increment the counter
69 79
70 index = 0; 80 index = 0;
71 } 81 }
72 output[i] = state[index++]; 82 output[i] = state[index++];
73 } 83 }
84
74 return output.length; 85 return output.length;
75 } 86 }
76 } 87 }