Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
rndstraw.cpp
Go to the documentation of this file.
1/*
2** Command & Conquer Generals Zero Hour(tm)
3** Copyright 2025 Electronic Arts Inc.
4**
5** This program is free software: you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation, either version 3 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18
19/***********************************************************************************************
20 *** C O N F I D E N T I A L --- W E S T W O O D S T U D I O S ***
21 ***********************************************************************************************
22 * *
23 * Project Name : Command & Conquer *
24 * *
25 * $Archive:: /Commando/Library/RNDSTRAW.CPP $*
26 * *
27 * $Author:: Greg_h $*
28 * *
29 * $Modtime:: 7/22/97 11:37a $*
30 * *
31 * $Revision:: 1 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * RandomStraw::Get -- Fetch random data. *
36 * RandomStraw::RandomStraw -- Constructor for the random straw class. *
37 * RandomStraw::Reset -- Reset the data to known initial state. *
38 * RandomStraw::Scramble_Seed -- Masks any coorelation between the seed bits. *
39 * RandomStraw::Seed_Bit -- Add a random bit to the accumulated seed value. *
40 * RandomStraw::Seed_Bits_Needed -- Fetches the number of seed bits needed. *
41 * RandomStraw::Seed_Byte -- Submit 8 bits to the random number seed. *
42 * RandomStraw::Seed_Long -- Submit 32 bits to the random number seed. *
43 * RandomStraw::Seed_Short -- Submit 16 bits to the random number seed. *
44 * RandomStraw::~RandomStraw -- Destructor for random straw class. *
45 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
46
47#include "always.h"
48#include "rndstraw.h"
49#include "sha.h"
50#include <limits.h>
51#include <string.h>
52
53
54/***********************************************************************************************
55 * RandomStraw::RandomStraw -- Constructor for the random straw class. *
56 * *
57 * This will initialize the random straw into a known state. The initial state is useless *
58 * for cryptographic purposes. It must be seeded before it should be used. *
59 * *
60 * INPUT: none *
61 * *
62 * OUTPUT: none *
63 * *
64 * WARNINGS: none *
65 * *
66 * HISTORY: *
67 * 07/10/1996 JLB : Created. *
68 *=============================================================================================*/
70 SeedBits(0),
71 Current(0)
72{
73 Reset();
74}
75
76
77/***********************************************************************************************
78 * RandomStraw::~RandomStraw -- Destructor for random straw class. *
79 * *
80 * This destructor will clear out the seed data so that there won't be any sensitive *
81 * information left over in the memory this object occupied. *
82 * *
83 * INPUT: none *
84 * *
85 * OUTPUT: none *
86 * *
87 * WARNINGS: none *
88 * *
89 * HISTORY: *
90 * 07/10/1996 JLB : Created. *
91 *=============================================================================================*/
93{
94 Reset();
95}
96
97
98/***********************************************************************************************
99 * RandomStraw::Reset -- Reset the data to known initial state. *
100 * *
101 * This routine is functionally equivalent to performing an placement new on the object. It *
102 * clears out all the seed data. *
103 * *
104 * INPUT: none *
105 * *
106 * OUTPUT: none *
107 * *
108 * WARNINGS: You must reseed it before fetching random numbers. *
109 * *
110 * HISTORY: *
111 * 07/10/1996 JLB : Created. *
112 *=============================================================================================*/
114{
115 SeedBits = 0;
116 Current = 0;
117 memset(Random, '\0', sizeof(Random));
118}
119
120
121/***********************************************************************************************
122 * RandomStraw::Seed_Bits_Needed -- Fetches the number of seed bits needed. *
123 * *
124 * This routine is used when seeding the random straw. Keep feeding random bits to this *
125 * class until the Seed_Bits_Needed value returns zero. Random bits should be gathered from *
126 * sources external to the immediate program. Examples would be the system clock (good for *
127 * a few bits), the delay between player keystrokes (good for a few bits per keystroke), *
128 * etc. When gathering random bits from integers, use the low order bits (since they *
129 * characteristically are less predictable and more 'random' than the others). *
130 * *
131 * INPUT: none *
132 * *
133 * OUTPUT: Returns with the number of bits required in order to fully seed this random *
134 * number generator. *
135 * *
136 * WARNINGS: Even if this routine returns zero, you are still allowed and encouraged to feed *
137 * more random bits when the opportunity arrises. *
138 * *
139 * HISTORY: *
140 * 07/10/1996 JLB : Created. *
141 *=============================================================================================*/
143{
144 const int total = sizeof(Random) * CHAR_BIT;
145 if (SeedBits < total) {
146 return(total - SeedBits);
147 }
148 return(0);
149}
150
151
152/***********************************************************************************************
153 * RandomStraw::Seed_Bit -- Add a random bit to the accumulated seed value. *
154 * *
155 * This routine should be called to feed a single random bit to the random straw object. *
156 * You must feed as many bits as requested by the Seed_Bits_Needed() function. Submitting *
157 * additional bits is not only allowed, but encouraged. *
158 * *
159 * INPUT: seed -- The bit (lowest order bit) to feed to the random number seed. *
160 * *
161 * OUTPUT: none *
162 * *
163 * WARNINGS: none *
164 * *
165 * HISTORY: *
166 * 07/10/1996 JLB : Created. *
167 *=============================================================================================*/
169{
170 char * ptr = ((char *)&Random[0]) + ((SeedBits / CHAR_BIT) % sizeof(Random));
171 char frac = (char)(1 << (SeedBits & (CHAR_BIT-1)));
172
173 if (seed & 0x01) {
174 *ptr ^= frac;
175 }
176 SeedBits++;
177
178 if (SeedBits == (sizeof(Random) * CHAR_BIT)) {
179 Scramble_Seed();
180 }
181}
182
183
184/***********************************************************************************************
185 * RandomStraw::Seed_Byte -- Submit 8 bits to the random number seed. *
186 * *
187 * This will submit 8 bits (as specified) to the random number seed. *
188 * *
189 * INPUT: seed -- The seed bits to submit. *
190 * *
191 * OUTPUT: none *
192 * *
193 * WARNINGS: none *
194 * *
195 * HISTORY: *
196 * 07/10/1996 JLB : Created. *
197 *=============================================================================================*/
199{
200 for (int index = 0; index < CHAR_BIT; index++) {
201 Seed_Bit(seed);
202 seed >>= 1;
203 }
204}
205
206
207/***********************************************************************************************
208 * RandomStraw::Seed_Short -- Submit 16 bits to the random number seed. *
209 * *
210 * This will submit 16 bits to the accumulated seed. *
211 * *
212 * INPUT: seed -- The 16 bits to submit to the seed. *
213 * *
214 * OUTPUT: none *
215 * *
216 * WARNINGS: none *
217 * *
218 * HISTORY: *
219 * 07/10/1996 JLB : Created. *
220 *=============================================================================================*/
222{
223 for (int index = 0; index < (sizeof(seed)*CHAR_BIT); index++) {
224 Seed_Bit(seed);
225 seed >>= 1;
226 }
227}
228
229
230/***********************************************************************************************
231 * RandomStraw::Seed_Long -- Submit 32 bits to the random number seed. *
232 * *
233 * This will submit a full 32 bits to the accumulated seed value. *
234 * *
235 * INPUT: seed -- The 32 bits to submit. *
236 * *
237 * OUTPUT: none *
238 * *
239 * WARNINGS: none *
240 * *
241 * HISTORY: *
242 * 07/10/1996 JLB : Created. *
243 *=============================================================================================*/
245{
246 for (int index = 0; index < (sizeof(seed)*CHAR_BIT); index++) {
247 Seed_Bit(seed);
248 seed >>= 1;
249 }
250}
251
252
253/***********************************************************************************************
254 * RandomStraw::Scramble_Seed -- Masks any coorelation between the seed bits. *
255 * *
256 * This routine is called when a full set of seed bits has been accumulated. It will take *
257 * the existing seed and scramble the bits. An effective way of doing this is to use the *
258 * Secure Hash Algorithm. It is necessary to have this routine because there might be *
259 * some coorelation in the seed bits. Even more important is that this routine will result *
260 * in every bit of the seed having a scrambling effect on every other bit. *
261 * *
262 * INPUT: none *
263 * *
264 * OUTPUT: none *
265 * *
266 * WARNINGS: none *
267 * *
268 * HISTORY: *
269 * 07/10/1996 JLB : Created. *
270 *=============================================================================================*/
271void RandomStraw::Scramble_Seed(void)
272{
273 SHAEngine sha;
274
275 for (int index = 0; index < sizeof(Random); index++) {
276 char digest[20];
277
278 sha.Hash(&Random[0], sizeof(Random));
279 sha.Result(digest);
280
281 int tocopy = sizeof(digest) < (sizeof(Random)-index) ? sizeof(digest) : (sizeof(Random)-index);
282 memmove(((char *)&Random[0]) + index, digest, tocopy);
283 }
284}
285
286
287/***********************************************************************************************
288 * RandomStraw::Get -- Fetch random data. *
289 * *
290 * This routine will fetch random data and store it into the buffer specified. *
291 * *
292 * INPUT: source -- Pointer to the buffer to fill with random data. *
293 * *
294 * length -- The number of bytes to store into the buffer. *
295 * *
296 * OUTPUT: Returns with the actual number of bytes stored into the buffer. This will always *
297 * be the number of bytes requested since random numbers are unexhaustible. *
298 * *
299 * WARNINGS: none *
300 * *
301 * HISTORY: *
302 * 07/04/1996 JLB : Created. *
303 * 07/10/1996 JLB : Revamped to make cryptographically secure. *
304 *=============================================================================================*/
305int RandomStraw::Get(void * source, int slen)
306{
307 if (source == NULL || slen < 1) {
308 return(Straw::Get(source, slen));
309 }
310
311 int total = 0;
312 while (slen > 0) {
313 *(char *)source = (char)(Random[Current++]());
314 Current = Current % (sizeof(Random) / sizeof(Random[0]));
315 source = (char*)source + sizeof(char);
316 slen--;
317 total++;
318 }
319 return(total);
320}
#define NULL
Definition BaseType.h:92
RandomStraw(void)
Definition rndstraw.cpp:69
int Seed_Bits_Needed(void) const
Definition rndstraw.cpp:142
void Seed_Bit(int seed)
Definition rndstraw.cpp:168
void Seed_Short(short seed)
Definition rndstraw.cpp:221
virtual ~RandomStraw(void)
Definition rndstraw.cpp:92
void Reset(void)
Definition rndstraw.cpp:113
virtual int Get(void *source, int slen)
Definition rndstraw.cpp:305
void Seed_Long(long seed)
Definition rndstraw.cpp:244
void Seed_Byte(char seed)
Definition rndstraw.cpp:198
void Hash(void const *data, long length)
Definition sha.cpp:124
int Result(void *result) const
Definition sha.cpp:179
virtual int Get(void *buffer, int slen)
Definition straw.cpp:132
Random4Class Random
Definition sampler.cpp:55