Mercurial > projects > dcrypt
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 } |