Richard Boegli's CnC_Generals_Zero_Hour Fork WIP
This is documentation of Richard Boegil's Zero Hour Fork
 
Loading...
Searching...
No Matches
pk.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/PK.CPP $*
26 * *
27 * $Author:: Greg_h $*
28 * *
29 * $Modtime:: 7/22/97 11:37a $*
30 * *
31 * $Revision:: 1 $*
32 * *
33 *---------------------------------------------------------------------------------------------*
34 * Functions: *
35 * PKey::Decode_Exponent -- Decodes the exponent back into the key. *
36 * PKey::Decode_Modulus -- Decodes the modulus value back into the key. *
37 * PKey::Decrypt -- Decrypt supplied cyphertext into its original plaintext. *
38 * PKey::Encode_Exponent -- Encode the exponent portion of the key into a buffer. *
39 * PKey::Encode_Modulus -- Encode the modulus portion of the key. *
40 * PKey::Encrypt -- Encrypt blocks of plaintext. *
41 * PKey::Generate -- Generate a public and private key. *
42 * PKey::PKey -- Construct a key using encoded strings. *
43 * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
44
45#include "always.h"
46#include "pk.h"
47#include "rndstraw.h"
48#include <string.h>
49
50
51#if defined(__BORLANDC__)
52extern BigInt Generate_Prime<BigInt>(Straw &, int, BigInt const *);
53#endif
54
55#ifdef _MSC_VER
56//BigInt Generate_Prime(Straw &, int, BigInt const *);
57#endif
58
59
60/***********************************************************************************************
61 * PKey::PKey -- Construct a key using encoded strings. *
62 * *
63 * This constructor will construct a key based on the encoded strings supplied. *
64 * *
65 * INPUT: exponent -- The encoded string for the exponent portion of the key. *
66 * *
67 * modulus -- The encoded string for the modulus portion of the key. *
68 * *
69 * OUTPUT: none *
70 * *
71 * WARNINGS: none *
72 * *
73 * HISTORY: *
74 * 07/08/1996 JLB : Created. *
75 *=============================================================================================*/
76PKey::PKey(void const * exponent, void const * modulus)
77{
78 Modulus.DERDecode((unsigned char *)modulus);
79 Exponent.DERDecode((unsigned char *)exponent);
80 BitPrecision = Modulus.BitCount()-1;
81}
82
83
84/***********************************************************************************************
85 * PKey::Encode_Modulus -- Encode the modulus portion of the key. *
86 * *
87 * This will store the modulus portion of the key into a buffer. The number of bytes *
88 * stored into the buffer depends on the value of the key. *
89 * *
90 * INPUT: buffer -- Pointer to the buffer that will hold the encoded modulus value. *
91 * *
92 * OUTPUT: Returns with the number of bytes stored to the buffer. *
93 * *
94 * WARNINGS: Be sure that the buffer can hold the encoded bytes. This is normally around the *
95 * same size as the Crypt_Block_Size() (plus a byte or two). *
96 * *
97 * HISTORY: *
98 * 07/08/1996 JLB : Created. *
99 *=============================================================================================*/
100int PKey::Encode_Modulus(void * buffer) const
101{
102 if (buffer == NULL) {
103 return(0);
104 }
105 return(Modulus.DEREncode((unsigned char *)buffer));
106}
107
108
109/***********************************************************************************************
110 * PKey::Encode_Exponent -- Encode the exponent portion of the key into a buffer. *
111 * *
112 * This routine will encode the exponent portion of the key. This is only necessary for the *
113 * slow key since the fast key always has an exponent of 65537. *
114 * *
115 * INPUT: buffer -- Pointer to the buffer that will be filled with the encoded exponent. *
116 * *
117 * OUTPUT: Returns with the nuber of bytes stored into the buffer. *
118 * *
119 * WARNINGS: Be sure the buffer is big enough to hold the encoded exponent. Usually this is *
120 * about the same size as the Crypt_Block_Size (plus a byte or two). *
121 * *
122 * HISTORY: *
123 * 07/08/1996 JLB : Created. *
124 *=============================================================================================*/
125int PKey::Encode_Exponent(void * buffer) const
126{
127 if (buffer == NULL) {
128 return(0);
129 }
130 return(Exponent.DEREncode((unsigned char *)buffer));
131}
132
133
134/***********************************************************************************************
135 * PKey::Decode_Modulus -- Decodes the modulus value back into the key. *
136 * *
137 * This is the counterpart to the Encode_Modulus() function. It will initialize the *
138 * modulus portion of the key with the encoded data supplied. *
139 * *
140 * INPUT: buffer -- Pointer to the buffer that holds the previously encoded modulus value. *
141 * *
142 * OUTPUT: void *
143 * *
144 * WARNINGS: void *
145 * *
146 * HISTORY: *
147 * 07/08/1996 JLB : Created. *
148 *=============================================================================================*/
149void PKey::Decode_Modulus(void * buffer)
150{
151 Modulus.DERDecode((unsigned char *)buffer);
152 BitPrecision = Modulus.BitCount()-1;
153}
154
155
156/***********************************************************************************************
157 * PKey::Decode_Exponent -- Decodes the exponent back into the key. *
158 * *
159 * This is the counterpart to the Encode_Exponent function. It will decode a previously *
160 * encoded exponent portion back into the key. *
161 * *
162 * INPUT: buffer -- Pointer to the buffer that holds the encoded exponent value. *
163 * *
164 * OUTPUT: none *
165 * *
166 * WARNINGS: none *
167 * *
168 * HISTORY: *
169 * 07/08/1996 JLB : Created. *
170 *=============================================================================================*/
171void PKey::Decode_Exponent(void * buffer)
172{
173 Exponent.DERDecode((unsigned char *)buffer);
174}
175
176
177/***********************************************************************************************
178 * PKey::Generate -- Generate a public and private key. *
179 * *
180 * Public key cryptography relies on having two paired keys. The key used to encrypt *
181 * data must be decrypted by using the other key. Which key designated as the public or *
182 * private key is arbitrary. However, one is faster than the other. Use the faster key for *
183 * the more common operation. *
184 * *
185 * INPUT: random -- Reference to a source of random data. *
186 * *
187 * bits -- The number of bits to use for key generation. Use a number greater *
188 * than 16 but less than 2048. The ideal bit size is one that is evenly *
189 * divisible by 8 and then add one. Practical numbers range from 65 to *
190 * 1025 bits. *
191 * *
192 * fastkey -- Reference to the key that has fast encryption/decryption properties. *
193 * *
194 * slowkey -- Reference to the mate key of the other. *
195 * *
196 * OUTPUT: none *
197 * *
198 * WARNINGS: This routine can take a very long time. It can take MINUTES to generate a *
199 * 1024 bit key (even on a Pentium Pro 200Mghz machine). *
200 * *
201 * HISTORY: *
202 * 07/05/1996 JLB : Created. *
203 * 07/10/1996 JLB : Must supply source of random data. *
204 *=============================================================================================*/
205void PKey::Generate(Straw & random, int bits, PKey & fastkey, PKey & slowkey)
206{
207 /*
208 ** Key generation consists of create a key pair and then testing the key
209 ** pair. If the test fails, then repeat the process. The test and repeat
210 ** method is required since the prime number generating process can't
211 ** guarantee the generation of a prime number -- it can only generate a
212 ** highly likely prime number.
213 */
214 for (;;) {
215 /*
216 ** Generate the two random prime numbers. This is the longest
217 ** step.
218 */
219 BigInt p = Generate_Prime(random, bits, &p);
220 BigInt q = Generate_Prime(random, bits, &q);
221
222 /*
223 ** The exponent factors are easy to calculate from the prime numbers.
224 */
225 BigInt e = Fast_Exponent();
226 BigInt n = p * q;
227 BigInt pqmin = (p-(unsigned short)1)*(q-(unsigned short)1);
228 BigInt d = e.Inverse(pqmin);
229
230 /*
231 ** Store the data into the key objects. Notice that the modulus is the
232 ** same for both the fast and slow keys. Also notice that the exponent for
233 ** the fast key is ALWAYS 65537. Given this, it is possible to economize the
234 ** fast key into being just the modulus and the slow key to being just the
235 ** exponent (presuming the slow key also has access to the fast key so that
236 ** it can get the modulus).
237 */
238 fastkey.Exponent = e;
239 fastkey.Modulus = n;
240 fastkey.BitPrecision = n.BitCount()-1;
241
242 slowkey.Exponent = d;
243 slowkey.Modulus = n;
244 slowkey.BitPrecision = fastkey.BitPrecision;
245
246 /*
247 ** Test the keys by encrypting a block of random bytes. If it decrypts
248 ** correctly, then a valid key pair has been generated -- bail.
249 */
250 char before[256];
251 char after[256];
252
253 for (int index = 0; index < fastkey.Plain_Block_Size(); index++) {
254 before[index] = (char)rand();
255 }
256 fastkey.Encrypt(before, fastkey.Plain_Block_Size(), after);
257 slowkey.Decrypt(after, slowkey.Crypt_Block_Size(), after);
258
259 /*
260 ** Compare the pre and post processing buffer. A match indicates
261 ** a valid key pair.
262 */
263 if (memcmp(before, after, fastkey.Plain_Block_Size()) == 0) break;
264 }
265}
266
267
268/***********************************************************************************************
269 * PKey::Encrypt -- Encrypt blocks of plaintext. *
270 * *
271 * This routine will encrypt the supplied plaintext into cyphertext by processing the input *
272 * in block. The source is processed in whole blocks. Partial blocks are not supported by *
273 * public key cryptography. *
274 * *
275 * INPUT: source -- Pointer to the source plaintext that will be encrypted. *
276 * *
277 * length -- The length of the plaintext to encrypt. *
278 * *
279 * dest -- Pointer to the buffer that will hold the encrypted data. *
280 * *
281 * OUTPUT: Returns with the number of cypher text bytes placed into the destination buffer. *
282 * *
283 * WARNINGS: Be sure that the destination buffer is big enough to hold the output. *
284 * *
285 * HISTORY: *
286 * 07/05/1996 JLB : Created. *
287 *=============================================================================================*/
288int PKey::Encrypt(void const * source, int slen, void * dest) const
289{
290 int total = 0;
291
292 /*
293 ** Encrypt the source data in full blocks. Partial blocks are not processed and are not
294 ** copied to the destination buffer.
295 */
296 while (slen >= Plain_Block_Size()) {
297
298 /*
299 ** Perform the encryption of the block.
300 */
301 BigInt temp = 0;
302 memmove(&temp, source, Plain_Block_Size());
303 temp = temp.exp_b_mod_c(Exponent, Modulus);
304
305 /*
306 ** Move the cypher block to the destination.
307 */
308 memmove(dest, &temp, Crypt_Block_Size());
309 slen -= Plain_Block_Size();
310 source = (char *)source + Plain_Block_Size();
311 dest = (char *)dest + Crypt_Block_Size();
312 total += Crypt_Block_Size();
313 }
314
315 return(total);
316}
317
318
319/***********************************************************************************************
320 * PKey::Decrypt -- Decrypt supplied cyphertext into its original plaintext. *
321 * *
322 * This routine will process the supplied cyphertext by breaking it up into blocks and *
323 * then decrypting each block in turn. The block size is dependant upon the key. By NOT *
324 * embedding this information into the cypher data, it makes the encryption more secure. *
325 * *
326 * INPUT: source -- Pointer to the cypher text to be decrypted. *
327 * *
328 * length -- The number of cypher text bytes supplied to this routine. *
329 * *
330 * dest -- Pointer to the buffer to hold the plaintext. *
331 * *
332 * OUTPUT: Returns with the number of plaintext bytes output to the destination buffer. *
333 * *
334 * WARNINGS: Only whole blocks are processed. If the source has any partial block sized *
335 * data, then it will be left unprocessed. *
336 * *
337 * HISTORY: *
338 * 07/05/1996 JLB : Created. *
339 *=============================================================================================*/
340int PKey::Decrypt(void const * source, int slen, void * dest) const
341{
342 int total = 0;
343 BigInt temp;
344
345 /*
346 ** Decrypt the source data in full blocks. Partial blocks are not processed in any way.
347 */
348 while (slen >= Crypt_Block_Size()) {
349
350 /*
351 ** Perform the encryption.
352 */
353 temp = 0;
354 memmove(&temp, source, Crypt_Block_Size());
355 temp = temp.exp_b_mod_c(Exponent, Modulus);
356
357 /*
358 ** Move the cypher block to the destination.
359 */
360 memmove(dest, &temp, Plain_Block_Size());
361 slen -= Crypt_Block_Size();
362 source = (char *)source + Crypt_Block_Size();
363 dest = (char *)dest + Plain_Block_Size();
364 total += Plain_Block_Size();
365 }
366
367 return(total);
368}
#define NULL
Definition BaseType.h:92
T Generate_Prime(Straw &rng, int pbits, T const *)
Definition INT.H:269
Int< MAX_UNIT_PRECISION > BigInt
Definition INT.H:306
static long Fast_Exponent(void)
Definition PK.H:83
PKey(void)
Definition PK.H:65
int Encrypt(void const *source, int slen, void *dest) const
Definition pk.cpp:288
int Decrypt(void const *source, int slen, void *dest) const
Definition pk.cpp:340
int Encode_Exponent(void *buffer) const
Definition pk.cpp:125
int Crypt_Block_Size(void) const
Definition PK.H:74
int Encode_Modulus(void *buffer) const
Definition pk.cpp:100
int BitPrecision
Definition PK.H:95
BigInt Exponent
Definition PK.H:92
int Plain_Block_Size(void) const
Definition PK.H:73
void Decode_Exponent(void *buffer)
Definition pk.cpp:171
BigInt Modulus
Definition PK.H:88
void Decode_Modulus(void *buffer)
Definition pk.cpp:149
static void Generate(Straw &random, int bits, PKey &fastkey, PKey &slowkey)
Definition pk.cpp:205
Definition STRAW.H:51
int q
Definition test1.cpp:94
Int exp_b_mod_c(const Int &e, const Int &m) const
Definition INT.H:159
Int Inverse(const Int &modulus) const
Definition INT.H:169
int BitCount(void) const
Definition INT.H:101