comparison dcrypt/crypto/prngs/PRNGFromHash.d @ 14:5ce3012f1def

Removed some redundancy in code. Added NotSupportedError, a base PRNG class and a class which creates a PRNG from a hash function. Changed the MAC class' finalization methods to digest and hexDigest instead of finish and hexFinish respectively. Also added a base Checksum class, crc32 and adler32 in dcrypt.misc as per request.
author Thomas Dixon <reikon@reikon.us>
date Tue, 18 Nov 2008 18:03:40 -0500
parents
children 703901987976
comparison
equal deleted inserted replaced
13:7ea528b61802 14:5ce3012f1def
1 /**
2 * This file is part of the dcrypt project.
3 *
4 * Copyright: Copyright (C) dcrypt contributors 2008. All rights reserved.
5 * License: MIT
6 * Authors: Thomas Dixon
7 */
8
9 module dcrypt.crypto.prngs.PRNGFromHash;
10
11 import dcrypt.crypto.PRNG;
12 import dcrypt.crypto.Hash;
13 import dcrypt.crypto.hashes.SHA256;
14
15 /** Creates a PRNG from a hash function. */
16 class PRNGFromHash : PRNG {
17 private {
18 const uint COUNTER_SIZE = 32;
19
20 Hash hash;
21 ubyte[] counter,
22 seed,
23 state;
24 uint index;
25 }
26
27 char[] name() {
28 if (hash is null)
29 throw new NotInitializedError(name()~": PRNG not initialized");
30
31 return hash.name~"PRNG";
32 }
33
34 this(Hash hash=null) {
35 this.hash = (hash is null) ? new SHA256() : hash;
36 this.hash.reset();
37
38 counter = new ubyte[COUNTER_SIZE];
39 seed = new ubyte[this.hash.digestSize];
40 state = new ubyte[this.hash.digestSize];
41
42 index = this.hash.digestSize; // to force updating of the state
43 }
44
45 void addEntropy(ubyte[] input) {
46 if (!_initialized) {
47 hash.update(input);
48 seed = hash.digest();
49 _initialized = true;
50 } else
51 throw new NotSupportedError(name()~": state is immutable once initialized");
52 }
53
54 uint read(ubyte[] output) {
55 if (!_initialized)
56 throw new NotInitializedError(name()~": PRNG not initialized");
57
58 for (uint i = 0; i < output.length; i++) {
59 if (index == state.length) {
60 hash.update(seed);
61 hash.update(counter);
62 state = hash.digest();
63
64 // Increment the counter
65 for (uint j = COUNTER_SIZE-1; j >= 0; j--)
66 if (++counter[j]) break;
67
68 index = 0;
69 }
70 output[i] = state[index++];
71 }
72 return output.length;
73 }
74 }