File Coverage

blib/lib/CDS/C.pm
Criterion Covered Total %
statement 12 12 100.0
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 16 16 100.0


line stmt bran cond sub pod time code
1 1     1   5 use strict;
  1         2  
  1         23  
2 1     1   3 use warnings;
  1         1  
  1         36  
3             package CDS::C;
4             our $VERSION = '0.27';
5 1     1   4 use Exporter 'import';
  1         1  
  1         1592  
6             our @EXPORT = qw();
7 1     1   319 use CDS::C::Inline C => <
  1         2  
  1         31  
8             #include
9             #include
10              
11              
12             #line 1 "Condensation/../../c/configuration/default.inc.h"
13             typedef uint32_t cdsLength;
14             #define CDS_MAX_RECORD_DEPTH 64
15              
16             #line 4 "Condensation/C.inc.c"
17              
18             #line 1 "Condensation/../../c/random/multi-os.inc.c"
19             #if defined(WIN32) || defined(_WIN32)
20              
21             #line 1 "Condensation/../../c/random/windows.inc.c"
22             #define _CRT_RAND_S
23             #include
24              
25             static void fillRandom(uint8_t * buffer, uint32_t length) {
26             unsigned int value;
27             for (uint32_t i = 0; i < length; i++) {
28             rand_s(&value);
29             buffer[i] = value & 0xff;
30             }
31             }
32              
33             #line 2 "Condensation/../../c/random/multi-os.inc.c"
34             #else
35              
36             #line 1 "Condensation/../../c/random/dev-urandom.inc.c"
37             #include
38             #include
39             #include
40             #include
41              
42             static void fillRandom(uint8_t * buffer, uint32_t length) {
43             int fh = open("/dev/urandom", O_RDONLY | O_NONBLOCK);
44              
45             size_t count = 0;
46             while (count < length) {
47             ssize_t added = read(fh, buffer + count, length - count);
48             if (added < 0) break;
49             count += (size_t) added;
50             }
51              
52             close(fh);
53             }
54              
55             #line 4 "Condensation/../../c/random/multi-os.inc.c"
56             #endif
57              
58             #line 5 "Condensation/C.inc.c"
59              
60             #line 1 "Condensation/../../c/Condensation/littleEndian.inc.c"
61             static void copyReversed4(uint8_t * destination, const uint8_t * source) {
62             destination[0] = source[3];
63             destination[1] = source[2];
64             destination[2] = source[1];
65             destination[3] = source[0];
66             }
67              
68             static void copyReversed8(uint8_t * destination, const uint8_t * source) {
69             destination[0] = source[7];
70             destination[1] = source[6];
71             destination[2] = source[5];
72             destination[3] = source[4];
73             destination[4] = source[3];
74             destination[5] = source[2];
75             destination[6] = source[1];
76             destination[7] = source[0];
77             }
78              
79             void cdsSetUint32BE(uint8_t * bytes, uint32_t value) {
80             union {
81             uint8_t leBytes[4];
82             uint32_t value;
83             } u;
84              
85             u.value = value;
86             copyReversed4(bytes, u.leBytes);
87             }
88              
89             uint32_t cdsGetUint32BE(const uint8_t * bytes) {
90             union {
91             uint8_t leBytes[4];
92             uint32_t value;
93             } u;
94              
95             copyReversed4(u.leBytes, bytes);
96             return u.value;
97             }
98              
99             void cdsSetUint64BE(uint8_t * bytes, uint64_t value) {
100             union {
101             uint8_t leBytes[8];
102             uint64_t value;
103             } u;
104              
105             u.value = value;
106             copyReversed8(bytes, u.leBytes);
107             }
108              
109             uint64_t cdsGetUint64BE(const uint8_t * bytes) {
110             union {
111             uint8_t leBytes[8];
112             uint64_t value;
113             } u;
114              
115             copyReversed8(u.leBytes, bytes);
116             return u.value;
117             }
118              
119             void cdsSetFloat32BE(uint8_t * bytes, float value) {
120             union {
121             uint8_t leBytes[4];
122             float value;
123             } u;
124              
125             u.value = value;
126             copyReversed4(bytes, u.leBytes);
127             }
128              
129             float cdsGetFloat32BE(const uint8_t * bytes) {
130             union {
131             uint8_t leBytes[4];
132             float value;
133             } u;
134              
135             copyReversed4(u.leBytes, bytes);
136             return u.value;
137             }
138              
139             void cdsSetFloat64BE(uint8_t * bytes, double value) {
140             union {
141             uint8_t leBytes[4];
142             float value;
143             } u;
144              
145             u.value = value;
146             copyReversed8(bytes, u.leBytes);
147             }
148              
149             double cdsGetFloat64BE(const uint8_t * bytes) {
150             union {
151             uint8_t leBytes[8];
152             double value;
153             } u;
154              
155             copyReversed8(u.leBytes, bytes);
156             return u.value;
157             }
158              
159             #if defined(__BYTE_ORDER) && __BYTE_ORDER == __BIG_ENDIAN || defined(__BIG_ENDIAN__) || defined(__ARMEB__) || defined(__THUMBEB__) || defined(__AARCH64EB__) || defined(_MIBSEB) || defined(__MIBSEB) || defined(__MIBSEB__)
160             #error "This library was prepared for little-endian processor architectures. Your compiler indicates that you are compiling for a big-endian architecture."
161             #endif
162              
163             #line 6 "Condensation/C.inc.c"
164              
165             #line 1 "Condensation/../../c/Condensation/all.inc.h"
166             #include
167             #include
168              
169              
170             #line 1 "Condensation/../../c/Condensation/public.h"
171             #include
172             #include
173              
174             struct cdsBytes {
175             const uint8_t * data;
176             cdsLength length;
177             };
178              
179             struct cdsMutableBytes {
180             uint8_t * data;
181             cdsLength length;
182             };
183              
184             extern const struct cdsBytes cdsEmpty;
185              
186             #line 4 "Condensation/../../c/Condensation/all.inc.h"
187              
188             #line 1 "Condensation/../../c/Condensation/AES256/public.h"
189             extern const struct cdsBytes cdsZeroCtr;
190              
191             struct cdsAES256 {
192             int key[240];
193             };
194              
195             #line 5 "Condensation/../../c/Condensation/all.inc.h"
196              
197             #line 1 "Condensation/../../c/Condensation/SHA256/public.h"
198             struct cdsSHA256 {
199             uint32_t state[8];
200             uint8_t chunk[64];
201             uint8_t used;
202             uint32_t length;
203             };
204              
205             #line 6 "Condensation/../../c/Condensation/all.inc.h"
206              
207             #line 1 "Condensation/../../c/Condensation/RSA64/public.h"
208             #define CDS_BIG_INTEGER_SIZE 132 // 2048 / 32 * 2 + 4
209             #define CDS_BIG_INTEGER_ZERO {}
210              
211             struct cdsBigInteger {
212             int length;
213             uint32_t values[CDS_BIG_INTEGER_SIZE];
214             };
215              
216             struct cdsRSAModPowSmall {
217             struct cdsBigInteger bigInteger1;
218             struct cdsBigInteger bigInteger2;
219             struct cdsBigInteger gR;
220             struct cdsBigInteger * result;
221             };
222              
223             struct cdsRSAModPowBig {
224             struct cdsBigInteger bigInteger1;
225             struct cdsBigInteger bigInteger2;
226             uint32_t mp;
227             const struct cdsBigInteger * m;
228             struct cdsBigInteger gR[64];
229             struct cdsBigInteger * aR;
230             struct cdsBigInteger * tR;
231             int selection;
232             int usableSelection;
233             int usableBits;
234             int zeroBits;
235             struct cdsBigInteger * result;
236             };
237              
238             struct cdsRSAPublicCryptMemory {
239             struct cdsRSAModPowSmall modPowSmall;
240             struct cdsBigInteger input;
241             };
242              
243             struct cdsRSAPrivateCryptMemory {
244             struct cdsRSAModPowBig modPowBig;
245             struct cdsBigInteger input;
246             struct cdsBigInteger imodp;
247             struct cdsBigInteger mP;
248             struct cdsBigInteger imodq;
249             struct cdsBigInteger mQ;
250             struct cdsBigInteger result;
251             struct cdsBigInteger difference;
252             struct cdsBigInteger h;
253             };
254              
255             struct cdsRSAPublicKey {
256             struct cdsBigInteger e;
257             struct cdsBigInteger n;
258             bool isValid;
259             };
260              
261             struct cdsRSAPrivateKey {
262             struct cdsRSAPublicKey rsaPublicKey;
263             struct cdsBigInteger p;
264             struct cdsBigInteger q;
265             struct cdsBigInteger d;
266             struct cdsBigInteger dp;
267             struct cdsBigInteger dq;
268             struct cdsBigInteger pInv;
269             struct cdsBigInteger qInv;
270             bool isValid;
271             };
272              
273             #line 7 "Condensation/../../c/Condensation/all.inc.h"
274              
275             #line 1 "Condensation/../../c/Condensation/Serialization/public.h"
276             struct cdsHash {
277             uint8_t bytes[32];
278             };
279              
280             struct cdsHashAndKey {
281             struct cdsHash hash;
282             struct cdsBytes key;
283             uint8_t keyBytes[32];
284             };
285              
286             typedef void (*cdsHashCallback)(struct cdsHash hash);
287              
288             struct cdsObject {
289             struct cdsBytes bytes;
290             uint32_t hashesCount;
291             struct cdsBytes header;
292             struct cdsBytes data;
293             };
294              
295             struct cdsRecordBuilder {
296             struct cdsMutableBytes bytes;
297             cdsLength dataOffset;
298             cdsLength used;
299             cdsLength hashesUsed;
300             cdsLength levelPositions[CDS_MAX_RECORD_DEPTH];
301             int level;
302             int nextIsChild;
303             };
304              
305             struct cdsRecord {
306             struct cdsBytes bytes;
307             const uint8_t * hash;
308             struct cdsRecord * nextSibling;
309             struct cdsRecord * firstChild;
310             };
311              
312             #line 8 "Condensation/../../c/Condensation/all.inc.h"
313              
314             #line 7 "Condensation/C.inc.c"
315              
316             #line 1 "Condensation/../../c/Condensation/all.inc.c"
317             #include
318             #include
319             #include
320              
321              
322             #line 1 "Condensation/../../c/Condensation/minMax.inc.c"
323              
324             static cdsLength minLength(cdsLength a, cdsLength b) { return a < b ? a : b; }
325              
326              
327             static size_t minSize(size_t a, size_t b) { return a < b ? a : b; }
328              
329             #line 5 "Condensation/../../c/Condensation/all.inc.c"
330              
331             #line 1 "Condensation/../../c/Condensation/bytes.inc.c"
332             #include
333              
334             const struct cdsBytes cdsEmpty = {NULL, 0};
335              
336             struct cdsBytes cdsBytes(const uint8_t * bytes, cdsLength length) {
337             return (struct cdsBytes) {
338             bytes, length
339             };
340             }
341              
342             struct cdsBytes cdsByteSlice(const struct cdsBytes bytes, cdsLength offset, cdsLength length) {
343             if (offset > bytes.length) return cdsEmpty;
344             return (struct cdsBytes) {
345             bytes.data + offset, minLength(length, bytes.length - offset)
346             };
347             }
348              
349             struct cdsBytes cdsByteSliceFrom(const struct cdsBytes bytes, cdsLength offset) {
350             return (struct cdsBytes) {
351             bytes.data + offset, bytes.length - offset
352             };
353             }
354              
355             struct cdsBytes cdsBytesFromText(const char * text) {
356             return (struct cdsBytes) {
357             (const uint8_t *) text, (cdsLength) strlen(text)
358             };
359             }
360              
361             int cdsCompareBytes(const struct cdsBytes a, const struct cdsBytes b) {
362             cdsLength length = minLength(a.length, b.length);
363             for (cdsLength i = 0; i < length; i++) {
364             if (a.data[i] < b.data[i]) return -1;
365             if (a.data[i] > b.data[i]) return 1;
366             }
367              
368             if (a.length < b.length) return -1;
369             if (a.length > b.length) return 1;
370             return 0;
371             }
372              
373             bool cdsEqualBytes(const struct cdsBytes a, const struct cdsBytes b) {
374             if (a.length != b.length) return false;
375             for (cdsLength i = 0; i < a.length; i++)
376             if (a.data[i] != b.data[i]) return false;
377             return true;
378             }
379              
380             struct cdsMutableBytes cdsMutableBytes(uint8_t * bytes, cdsLength length) {
381             return (struct cdsMutableBytes) {
382             bytes, length
383             };
384             }
385              
386             struct cdsMutableBytes cdsMutableBytesFromText(char * text) {
387             return (struct cdsMutableBytes) {
388             (uint8_t *) text, (cdsLength) strlen(text)
389             };
390             }
391              
392             struct cdsBytes cdsSeal(const struct cdsMutableBytes bytes) {
393             return (struct cdsBytes) {
394             bytes.data, bytes.length
395             };
396             }
397              
398             struct cdsMutableBytes cdsMutableByteSlice(const struct cdsMutableBytes bytes, cdsLength offset, cdsLength length) {
399             return (struct cdsMutableBytes) {
400             bytes.data + offset, length
401             };
402             }
403              
404             struct cdsMutableBytes cdsMutableByteSliceFrom(const struct cdsMutableBytes bytes, cdsLength offset) {
405             return (struct cdsMutableBytes) {
406             bytes.data + offset, bytes.length - offset
407             };
408             }
409              
410             struct cdsMutableBytes cdsSetBytes(const struct cdsMutableBytes destination, cdsLength destinationOffset, const struct cdsBytes source) {
411             cdsLength length = minLength(destination.length - destinationOffset, source.length);
412             memcpy(destination.data + destinationOffset, source.data, length);
413             return cdsMutableBytes(destination.data + destinationOffset, length);
414             }
415              
416             #line 6 "Condensation/../../c/Condensation/all.inc.c"
417              
418             #line 1 "Condensation/../../c/Condensation/hex.inc.c"
419              
420             static char hexDigits[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
421             static uint8_t hexValues[] = {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255};
422              
423             char * cdsHexFromBytes(const struct cdsBytes bytes, char * buffer, cdsLength length) {
424             if (length == 0) return buffer;
425              
426             cdsLength w = 0;
427             cdsLength r = 0;
428             while (r < bytes.length && w < length - 2) {
429             buffer[w] = hexDigits[(bytes.data[r] >> 4) & 0xf];
430             w += 1;
431              
432             buffer[w] = hexDigits[bytes.data[r] & 0xf];
433             w += 1;
434              
435             r += 1;
436             }
437              
438             buffer[w] = 0;
439             return buffer;
440             }
441              
442             struct cdsBytes cdsBytesFromHex(const char * hex, uint8_t * buffer, cdsLength length) {
443             cdsLength i = 0;
444             while (i < length) {
445             uint8_t b1 = hexValues[(int)hex[i * 2]];
446             if (b1 >= 16) break;
447              
448             uint8_t b2 = hexValues[(int)hex[i * 2 + 1]];
449             if (b2 >= 16) break;
450              
451             buffer[i] = (b1 << 4) | b2;
452             i += 1;
453             }
454              
455             return cdsBytes(buffer, i);
456             }
457              
458             #line 7 "Condensation/../../c/Condensation/all.inc.c"
459              
460             #line 1 "Condensation/../../c/Condensation/random.inc.c"
461             struct cdsBytes cdsRandomBytes(uint8_t * buffer, cdsLength length) {
462             fillRandom(buffer, length);
463             return cdsBytes(buffer, length);
464             }
465              
466             #line 8 "Condensation/../../c/Condensation/all.inc.c"
467              
468              
469             #line 1 "Condensation/../../c/Condensation/AES256/AES256.inc.c"
470              
471             static int sbox[] = {99, 124, 119, 123, 242, 107, 111, 197, 48, 1, 103, 43, 254, 215, 171, 118, 202, 130, 201, 125, 250, 89, 71, 240, 173, 212, 162, 175, 156, 164, 114, 192, 183, 253, 147, 38, 54, 63, 247, 204, 52, 165, 229, 241, 113, 216, 49, 21, 4, 199, 35, 195, 24, 150, 5, 154, 7, 18, 128, 226, 235, 39, 178, 117, 9, 131, 44, 26, 27, 110, 90, 160, 82, 59, 214, 179, 41, 227, 47, 132, 83, 209, 0, 237, 32, 252, 177, 91, 106, 203, 190, 57, 74, 76, 88, 207, 208, 239, 170, 251, 67, 77, 51, 133, 69, 249, 2, 127, 80, 60, 159, 168, 81, 163, 64, 143, 146, 157, 56, 245, 188, 182, 218, 33, 16, 255, 243, 210, 205, 12, 19, 236, 95, 151, 68, 23, 196, 167, 126, 61, 100, 93, 25, 115, 96, 129, 79, 220, 34, 42, 144, 136, 70, 238, 184, 20, 222, 94, 11, 219, 224, 50, 58, 10, 73, 6, 36, 92, 194, 211, 172, 98, 145, 149, 228, 121, 231, 200, 55, 109, 141, 213, 78, 169, 108, 86, 244, 234, 101, 122, 174, 8, 186, 120, 37, 46, 28, 166, 180, 198, 232, 221, 116, 31, 75, 189, 139, 138, 112, 62, 181, 102, 72, 3, 246, 14, 97, 53, 87, 185, 134, 193, 29, 158, 225, 248, 152, 17, 105, 217, 142, 148, 155, 30, 135, 233, 206, 85, 40, 223, 140, 161, 137, 13, 191, 230, 66, 104, 65, 153, 45, 15, 176, 84, 187, 22};
472              
473             static int xtime[] = {0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 146, 148, 150, 152, 154, 156, 158, 160, 162, 164, 166, 168, 170, 172, 174, 176, 178, 180, 182, 184, 186, 188, 190, 192, 194, 196, 198, 200, 202, 204, 206, 208, 210, 212, 214, 216, 218, 220, 222, 224, 226, 228, 230, 232, 234, 236, 238, 240, 242, 244, 246, 248, 250, 252, 254, 27, 25, 31, 29, 19, 17, 23, 21, 11, 9, 15, 13, 3, 1, 7, 5, 59, 57, 63, 61, 51, 49, 55, 53, 43, 41, 47, 45, 35, 33, 39, 37, 91, 89, 95, 93, 83, 81, 87, 85, 75, 73, 79, 77, 67, 65, 71, 69, 123, 121, 127, 125, 115, 113, 119, 117, 107, 105, 111, 109, 99, 97, 103, 101, 155, 153, 159, 157, 147, 145, 151, 149, 139, 137, 143, 141, 131, 129, 135, 133, 187, 185, 191, 189, 179, 177, 183, 181, 171, 169, 175, 173, 163, 161, 167, 165, 219, 217, 223, 221, 211, 209, 215, 213, 203, 201, 207, 205, 195, 193, 199, 197, 251, 249, 255, 253, 243, 241, 247, 245, 235, 233, 239, 237, 227, 225, 231, 229};
474              
475             static const int keyLength = 240; // 16 * (14 + 1)
476              
477             uint8_t zeroCtrBuffer[16] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
478             const struct cdsBytes cdsZeroCtr = {zeroCtrBuffer, 16};
479              
480             void cdsInitializeEmptyAES256(struct cdsAES256 * this) { }
481              
482             void cdsInitializeAES256(struct cdsAES256 * this, struct cdsBytes key256) {
483             int i = 0;
484             int r = 1;
485             while (i < 32) {
486             this->key[i] = key256.data[i];
487             i++;
488             }
489              
490             while (i < keyLength) {
491             int mod = i % 32;
492             if (mod == 0) {
493             this->key[i + 0] = this->key[i + 0 - 32] ^ sbox[this->key[i - 3]] ^ r;
494             this->key[i + 1] = this->key[i + 1 - 32] ^ sbox[this->key[i - 2]];
495             this->key[i + 2] = this->key[i + 2 - 32] ^ sbox[this->key[i - 1]];
496             this->key[i + 3] = this->key[i + 3 - 32] ^ sbox[this->key[i - 4]];
497             r <<= 1;
498             } else if (mod == 16) {
499             this->key[i + 0] = this->key[i + 0 - 32] ^ sbox[this->key[i - 4]];
500             this->key[i + 1] = this->key[i + 1 - 32] ^ sbox[this->key[i - 3]];
501             this->key[i + 2] = this->key[i + 2 - 32] ^ sbox[this->key[i - 2]];
502             this->key[i + 3] = this->key[i + 3 - 32] ^ sbox[this->key[i - 1]];
503             } else {
504             this->key[i + 0] = this->key[i + 0 - 32] ^ this->key[i - 4];
505             this->key[i + 1] = this->key[i + 1 - 32] ^ this->key[i - 3];
506             this->key[i + 2] = this->key[i + 2 - 32] ^ this->key[i - 2];
507             this->key[i + 3] = this->key[i + 3 - 32] ^ this->key[i - 1];
508             }
509             i += 4;
510             }
511             }
512              
513             static void subBytes(uint8_t * block) {
514             for (int i = 0; i < 16; i++) block[i] = sbox[block[i]];
515             }
516              
517             static void addRoundKey(const int * key, uint8_t * block, int offset) {
518             for (int i = 0; i < 16; i++) block[i] ^= key[offset + i];
519             }
520              
521             static void shiftRows(uint8_t * block) {
522             int t1 = block[1];
523             block[1] = block[5];
524             block[5] = block[9];
525             block[9] = block[13];
526             block[13] = t1;
527             int t2 = block[2];
528             block[2] = block[10];
529             block[10] = t2;
530             int t3 = block[3];
531             block[3] = block[15];
532             block[15] = block[11];
533             block[11] = block[7];
534             block[7] = t3;
535             int t6 = block[6];
536             block[6] = block[14];
537             block[14] = t6;
538             }
539              
540             static void mixColumns(uint8_t * block) {
541             for (int i = 0; i < 16; i += 4) {
542             int s0 = block[i + 0];
543             int s1 = block[i + 1];
544             int s2 = block[i + 2];
545             int s3 = block[i + 3];
546             int h = s0 ^ s1 ^ s2 ^ s3;
547             block[i + 0] ^= h ^ xtime[s0 ^ s1];
548             block[i + 1] ^= h ^ xtime[s1 ^ s2];
549             block[i + 2] ^= h ^ xtime[s2 ^ s3];
550             block[i + 3] ^= h ^ xtime[s3 ^ s0];
551             }
552             }
553              
554             void cdsEncryptAES256Block(const struct cdsAES256 * this, uint8_t * block) {
555             addRoundKey(this->key, block, 0);
556             for (int i = 16; i < keyLength - 16; i += 16) {
557             subBytes(block);
558             shiftRows(block);
559             mixColumns(block);
560             addRoundKey(this->key, block, i);
561             }
562             subBytes(block);
563             shiftRows(block);
564             addRoundKey(this->key, block, keyLength - 16);
565             }
566              
567             void cdsIncrementCtr(uint8_t * counter) {
568             for (int n = 15; n >= 0; n--) {
569             counter[n] += 1;
570             if (counter[n] != 0) break;
571             }
572             }
573              
574             struct cdsBytes cdsCrypt(const struct cdsAES256 * aes, const struct cdsBytes bytes, const struct cdsBytes startCtr, uint8_t * buffer) {
575             uint8_t counter[16];
576             memcpy(counter, startCtr.data, 16);
577             uint8_t encryptedCounter[16];
578              
579             cdsLength i = 0;
580             for (; i + 16 < bytes.length; i += 16) {
581             memcpy(encryptedCounter, counter, 16);
582             cdsEncryptAES256Block(aes, encryptedCounter);
583             for (cdsLength n = 0; n < 16; n++) buffer[i + n] = bytes.data[i + n] ^ encryptedCounter[n];
584             cdsIncrementCtr(counter);
585             }
586              
587             cdsEncryptAES256Block(aes, counter);
588             for (cdsLength n = 0; n < bytes.length - i; n++) buffer[i + n] = bytes.data[i + n] ^ counter[n];
589              
590             return cdsBytes(buffer, bytes.length);
591             }
592              
593             #line 10 "Condensation/../../c/Condensation/all.inc.c"
594              
595              
596             #line 1 "Condensation/../../c/Condensation/SHA256/SHA256.inc.c"
597              
598             static uint32_t K[] = {
599             0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
600             0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
601             0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
602             0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
603             0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
604             0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
605             0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
606             0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
607             };
608              
609              
610             static uint32_t getUint32(const uint8_t * bytes) {
611             return (uint32_t)(bytes[0] << 24) | (uint32_t)(bytes[1] << 16) | (uint32_t)(bytes[2] << 8) | bytes[3];
612             }
613              
614             static void putUint32(uint8_t * bytes, uint32_t value) {
615             bytes[0] = (value >> 24) & 0xff;
616             bytes[1] = (value >> 16) & 0xff;
617             bytes[2] = (value >> 8) & 0xff;
618             bytes[3] = value & 0xff;
619             }
620              
621              
622             static uint32_t ROTR(uint32_t x, uint32_t n) {
623             return (x >> n) | (x << (32 - n));
624             }
625              
626             static uint32_t prepareS0(uint32_t x) {
627             return ROTR(x, 7) ^ ROTR(x, 18) ^ (x >> 3);
628             }
629              
630             static uint32_t prepareS1(uint32_t x) {
631             return ROTR(x, 17) ^ ROTR(x, 19) ^ (x >> 10);
632             }
633              
634             static uint32_t roundS0(uint32_t x) {
635             return ROTR(x, 2) ^ ROTR(x, 13) ^ ROTR(x, 22);
636             }
637              
638             static uint32_t roundS1(uint32_t x) {
639             return ROTR(x, 6) ^ ROTR(x, 11) ^ ROTR(x, 25);
640             }
641              
642             static uint32_t ch(uint32_t x, uint32_t y, uint32_t z) {
643             return (x & y) ^ (~x & z);
644             }
645              
646             static uint32_t maj(uint32_t x, uint32_t y, uint32_t z) {
647             return (x & y) ^ (x & z) ^ (y & z);
648             }
649              
650             static void sha256AddChunk(struct cdsSHA256 * this, const uint8_t * bytes) {
651             uint32_t w[64];
652             for (uint8_t i = 0; i < 16; i++)
653             w[i] = getUint32(bytes + i * 4);
654             for (uint8_t i = 16; i < 64; i++)
655             w[i] = prepareS1(w[i - 2]) + w[i - 7] + prepareS0(w[i - 15]) + w[i - 16];
656              
657             uint32_t s[8];
658             for (uint8_t i = 0; i < 8; i++)
659             s[i] = this->state[i];
660              
661             for (uint8_t i = 0; i < 64; i++) {
662             uint32_t t1 = s[7] + roundS1(s[4]) + ch(s[4], s[5], s[6]) + K[i] + w[i];
663             uint32_t t2 = roundS0(s[0]) + maj(s[0], s[1], s[2]);
664             s[7] = s[6];
665             s[6] = s[5];
666             s[5] = s[4];
667             s[4] = s[3] + t1;
668             s[3] = s[2];
669             s[2] = s[1];
670             s[1] = s[0];
671             s[0] = t1 + t2;
672             }
673              
674             for (uint8_t i = 0; i < 8; i++)
675             this->state[i] += s[i];
676             }
677              
678             uint32_t sha256InitialHash[] = {0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19};
679              
680             void cdsInitializeSHA256(struct cdsSHA256 * this) {
681             for (int i = 0; i < 8; i++)
682             this->state[i] = sha256InitialHash[i];
683             this->used = 0;
684             this->length = 0;
685             }
686              
687             static void sha256AddByte(struct cdsSHA256 * this, uint8_t byte) {
688             this->chunk[this->used] = byte;
689             this->used += 1;
690             this->length += 1;
691             if (this->used < 64) return;
692              
693             sha256AddChunk(this, this->chunk);
694             this->used = 0;
695             }
696              
697             void cdsAddBytesToSHA256(struct cdsSHA256 * this, struct cdsBytes bytes) {
698             for (uint32_t i = 0; i < bytes.length; i++)
699             sha256AddByte(this, bytes.data[i]);
700             }
701              
702             void cdsFinalizeSHA256(struct cdsSHA256 * this, uint8_t * result) {
703             uint32_t dataLength = this->length;
704              
705             sha256AddByte(this, 0x80);
706             while (this->used != 56)
707             sha256AddByte(this, 0);
708              
709             sha256AddByte(this, 0);
710             sha256AddByte(this, 0);
711             sha256AddByte(this, 0);
712             sha256AddByte(this, (dataLength & 0xe0000000) >> 29);
713             sha256AddByte(this, (dataLength & 0x1fe00000) >> 21);
714             sha256AddByte(this, (dataLength & 0x001fe000) >> 13);
715             sha256AddByte(this, (dataLength & 0x00001fe0) >> 5);
716             sha256AddByte(this, (dataLength & 0x0000001f) << 3);
717              
718             for (uint8_t i = 0; i < 8; i++)
719             putUint32(result + i * 4, this->state[i]);
720             }
721              
722             struct cdsBytes cdsSHA256(const struct cdsBytes bytes, uint8_t * result) {
723             struct cdsSHA256 sha;
724             cdsInitializeSHA256(&sha);
725             cdsAddBytesToSHA256(&sha, bytes);
726             cdsFinalizeSHA256(&sha, result);
727             return cdsBytes(result, 32);
728             }
729              
730             #line 12 "Condensation/../../c/Condensation/all.inc.c"
731              
732              
733             #line 1 "Condensation/../../c/Condensation/RSA64/production.inc.c"
734              
735             #define ELEMENT(x, n) x->values[n]
736              
737             #define X(index) ELEMENT(x, index)
738             #define Y(index) ELEMENT(y, index)
739             #define M(index) ELEMENT(m, index)
740             #define G(index) ELEMENT(g, index)
741             #define E(index) ELEMENT(e, index)
742             #define A(index) ELEMENT(a, index)
743              
744             #line 14 "Condensation/../../c/Condensation/all.inc.c"
745              
746             #line 1 "Condensation/../../c/Condensation/RSA64/Math.inc.c"
747              
748              
749             static void setZero(struct cdsBigInteger * x) {
750             x->length = 0;
751             }
752              
753             static void setUint32(struct cdsBigInteger * x, uint32_t value) {
754             x->length = 1;
755             X(0) = value;
756             }
757              
758             static void setRandom(struct cdsBigInteger * x, int n) {
759             assert(n >= 0);
760             assert(n <= CDS_BIG_INTEGER_SIZE);
761             cdsRandomBytes((uint8_t *) x->values, n * 4);
762             x->length = n;
763             }
764              
765             static int mostSignificantElement(const struct cdsBigInteger * x) {
766             int i = x->length - 1;
767             while (i >= 0 && X(i) == 0) i -= 1;
768             return i;
769             }
770              
771             static void trim(struct cdsBigInteger * x) {
772             while (x->length > 0 && X(x->length - 1) == 0) x->length -= 1;
773             }
774              
775             static void expand(struct cdsBigInteger * x, int n) {
776             assert(n >= 0);
777             assert(n <= CDS_BIG_INTEGER_SIZE);
778             while (x->length < n) {
779             x->length += 1;
780             X(x->length - 1) = 0;
781             }
782             }
783              
784             static int maxLength(const struct cdsBigInteger * x, const struct cdsBigInteger * y) {
785             return x->length > y->length ? x->length : y->length;
786             }
787              
788             static void copyD(struct cdsBigInteger * a, const struct cdsBigInteger * x, int d) {
789             a->length = x->length + d;
790             for (int i = 0; i < x->length; i++) A(i + d) = X(i);
791             for (int i = 0; i < d; i++) A(i) = 0;
792             }
793              
794              
795             void cdsBigIntegerFromBytes(struct cdsBigInteger * x, struct cdsBytes bytes) {
796             x->length = CDS_BIG_INTEGER_SIZE;
797              
798             int w = 0;
799             int n = (int)bytes.length;
800             while (n > 3 && w < CDS_BIG_INTEGER_SIZE) {
801             X(w) = ((uint32_t)bytes.data[n - 4] << 24) | ((uint32_t)bytes.data[n - 3] << 16) | ((uint32_t)bytes.data[n - 2] << 8) | (uint32_t)bytes.data[n - 1];
802             n -= 4;
803             w += 1;
804             }
805              
806             X(w) = 0;
807             if (n > 0) X(w) |= (uint32_t)bytes.data[n - 1];
808             if (n > 1) X(w) |= (uint32_t)bytes.data[n - 2] << 8;
809             if (n > 2) X(w) |= (uint32_t)bytes.data[n - 3] << 16;
810              
811             x->length = w + 1;
812             trim(x);
813             }
814              
815             struct cdsBytes cdsBytesFromBigInteger(struct cdsMutableBytes bytes, const struct cdsBigInteger * x) {
816             uint32_t n = bytes.length;
817             for (int r = 0; r < x->length; r++) {
818             n -= 1;
819             bytes.data[n] = X(r) & 0xff;
820             if (n == 0) break;
821             n -= 1;
822             bytes.data[n] = (X(r) >> 8) & 0xff;
823             if (n == 0) break;
824             n -= 1;
825             bytes.data[n] = (X(r) >> 16) & 0xff;
826             if (n == 0) break;
827             n -= 1;
828             bytes.data[n] = (X(r) >> 24) & 0xff;
829             if (n == 0) break;
830             }
831             memset(bytes.data, 0, n);
832             while (n < bytes.length && bytes.data[n] == 0) n++;
833             return cdsBytes(bytes.data + n, bytes.length - n);
834             }
835              
836              
837             static bool isEven(const struct cdsBigInteger * x) {
838             return x->length == 0 || (X(0) & 1) == 0;
839             }
840              
841             static bool isZero(const struct cdsBigInteger * x) {
842             return mostSignificantElement(x) == -1;
843             }
844              
845             static bool isOne(const struct cdsBigInteger * x) {
846             return mostSignificantElement(x) == 0 && X(0) == 1;
847             }
848              
849             static int compare(const struct cdsBigInteger * x, const struct cdsBigInteger * y) {
850             int xk = mostSignificantElement(x);
851             int yk = mostSignificantElement(y);
852             if (xk < yk) return -1;
853             if (xk > yk) return 1;
854             for (int i = xk; i >= 0; i--) {
855             if (X(i) < Y(i)) return -1;
856             if (X(i) > Y(i)) return 1;
857             }
858             return 0;
859             }
860              
861             static int compareShifted(const struct cdsBigInteger * x, const struct cdsBigInteger * y, int d) {
862             int xk = mostSignificantElement(x);
863             int yk = mostSignificantElement(y);
864             if (xk < yk + d) return -1;
865             if (xk > yk + d) return 1;
866             for (int i = yk; i >= 0; i--) {
867             if (X(i + d) < Y(i)) return -1;
868             if (X(i + d) > Y(i)) return 1;
869             }
870             return 0;
871             }
872              
873              
874             static void smallShiftLeft(struct cdsBigInteger * a, const struct cdsBigInteger * x, int bits) {
875             a->length = x->length;
876             int i = 0;
877             uint64_t cPrev = 0;
878             for (; i < a->length; i++) {
879             uint64_t cNext = (uint64_t)X(i) << bits;
880             A(i) = (uint32_t) (cNext | cPrev);
881             cPrev = cNext >> 32;
882             }
883             if (cPrev == 0) return;
884             a->length += 1;
885             A(i) = (uint32_t) cPrev;
886             }
887              
888             static void smallShiftRight(struct cdsBigInteger * a, const struct cdsBigInteger * x, int bits) {
889             a->length = x->length;
890             int i = 0;
891             for (; i + 1 < x->length; i++)
892             A(i) = (uint32_t) (X(i) >> bits | (uint64_t)X(i + 1) << (32 - bits));
893             A(i) = X(i) >> bits;
894             }
895              
896              
897             static void addN(struct cdsBigInteger * x, uint32_t n, const struct cdsBigInteger * y, int d) {
898             int yk = mostSignificantElement(y);
899              
900             if (x->length > 0 && X(x->length - 1) != 0) expand(x, x->length + 1);
901             expand(x, y->length + d + 2);
902              
903             uint64_t c = 0;
904             int i = 0;
905             for (; i <= yk; i++, d++) {
906             c += X(d) + (uint64_t)n * Y(i);
907             X(d) = c & 0xffffffff;
908             c >>= 32;
909             }
910              
911             for (; c != 0; d++) {
912             c += X(d);
913             X(d) = c & 0xffffffff;
914             c >>= 32;
915             }
916             }
917              
918             static void decrement(struct cdsBigInteger * x) {
919             int64_t c = -1;
920             for (int i = 0; c != 0; i++) {
921             c += X(i);
922             X(i) = c & 0xffffffff;
923             c >>= 32;
924             }
925             }
926              
927             static void subD(struct cdsBigInteger * x, const struct cdsBigInteger * y, int d) {
928             int64_t c = 0;
929             int i = 0;
930             for (; i < y->length && i < x->length; i++, d++) {
931             c += (int64_t)X(d) - Y(i);
932             X(d) = c & 0xffffffff;
933             c >>= 32;
934             }
935             for (; c != 0; d++) {
936             c += (int64_t)X(d);
937             X(d) = c & 0xffffffff;
938             c >>= 32;
939             }
940             }
941              
942             static void subN(struct cdsBigInteger * x, uint32_t n, const struct cdsBigInteger * y, int d) {
943             uint32_t nNeg = (uint32_t) (0x100000000 - n);
944             addN(x, nNeg, y, d);
945             subD(x, y, d + 1);
946             }
947              
948              
949             static void mul(struct cdsBigInteger * a, const struct cdsBigInteger * x, const struct cdsBigInteger * y) {
950             for (int i = 0; i < y->length; i++)
951             if (Y(i) != 0) addN(a, Y(i), x, i);
952             trim(a);
953             }
954              
955             static void sqr(struct cdsBigInteger * a, const struct cdsBigInteger * x) {
956             int xk = mostSignificantElement(x);
957             expand(a, a->length + 1);
958             expand(a, (xk + 1) << 1);
959             for (int i = 0; i <= xk; i++) {
960             if (X(i) == 0) continue;
961              
962             int r = i;
963             int w = i + r;
964             uint64_t cSum = A(w) + (uint64_t)X(r) * X(i);
965             A(w) = cSum & 0xffffffff;
966             cSum >>= 32;
967             w++;
968             r++;
969              
970             uint64_t cProduct = 0;
971             for (; r <= xk; w++, r++) {
972             cProduct += (uint64_t)X(r) * X(i);
973             cSum += A(w) + ((cProduct & 0xffffffff) << 1);
974             A(w) = cSum & 0xffffffff;
975             cProduct >>= 32;
976             cSum >>= 32;
977             }
978             for (; cSum != 0 || cProduct != 0; w++) {
979             cSum += A(w) + ((cProduct & 0xffffffff) << 1);
980             A(w) = cSum & 0xffffffff;
981             cProduct >>= 32;
982             cSum >>= 32;
983             }
984             }
985             trim(a);
986             }
987              
988              
989             static void mod(struct cdsBigInteger * x, const struct cdsBigInteger * m) {
990             int yk = mostSignificantElement(m);
991             uint32_t mse = M(yk);
992             int shift = 0;
993             while ((mse & 0x80000000) == 0) {
994             mse <<= 1;
995             shift += 1;
996             }
997              
998             struct cdsBigInteger bi = CDS_BIG_INTEGER_ZERO;
999             struct cdsBigInteger * y = &bi;
1000             smallShiftLeft(y, m, shift);
1001              
1002             if (shift > 0) smallShiftLeft(x, x, shift);
1003              
1004             int xk = mostSignificantElement(x);
1005             expand(x, xk + 2);
1006              
1007              
1008             uint64_t div = Y(yk) + 1;
1009             for (int d = xk - yk; d >= 0; d--) {
1010              
1011              
1012             uint64_t xmsb = ((uint64_t)X(yk + d + 1) << 32) + X(yk + d);
1013             if (xmsb > div) {
1014             uint64_t n = xmsb / div;
1015             subN(x, (uint32_t) n, y, d);
1016             }
1017              
1018             while (compareShifted(x, y, d) >= 0) {
1019             subD(x, y, d);
1020             }
1021              
1022             while (xk >= 0 && X(xk) == 0) xk -= 1;
1023             x->length = xk + 2;
1024             }
1025              
1026             if (shift > 0) smallShiftRight(x, x, shift);
1027             trim(x);
1028             }
1029              
1030              
1031             static uint32_t montInverse(const struct cdsBigInteger * m) {
1032             uint64_t q = M(0);
1033             uint32_t mp = q & 0x3; // mp = q^-1 mod 2^2 (for odd q)
1034             mp = (mp * (2 - (q & 0xf) * mp)) & 0xf; // mp = q^-1 mod 2^4
1035             mp = (mp * (2 - (q & 0xff) * mp)) & 0xff; // mp = q^-1 mod 2^8
1036             mp = (mp * (2 - (q & 0xffff) * mp)) & 0xffff; // mp = q^-1 mod 2^16
1037             mp = (mp * (2 - ((q * mp) & 0xffffffff))) & 0xffffffff; // mp = q^-1 mod 2^32
1038             return mp > 0 ? (uint32_t) (0x100000000 - mp) : -mp;
1039             }
1040              
1041             static void montConversion(struct cdsBigInteger * a, const struct cdsBigInteger * x, const struct cdsBigInteger * m) {
1042             int mk = mostSignificantElement(m);
1043             copyD(a, x, mk + 1);
1044              
1045             mod(a, m);
1046             }
1047              
1048             static void montConversionOne(struct cdsBigInteger * a, const struct cdsBigInteger * m) {
1049             int mk = mostSignificantElement(m);
1050             setZero(a);
1051             expand(a, mk + 2);
1052             A(mk + 1) = 1;
1053              
1054             mod(a, m);
1055             }
1056              
1057             static void montReduction(struct cdsBigInteger * x, const struct cdsBigInteger * m, uint32_t mp) {
1058             int mk = mostSignificantElement(m);
1059             for (int i = 0; i <= mk; i++) {
1060             uint32_t u = ((uint64_t)X(0) * mp) & 0xffffffff;
1061              
1062             addN(x, u, m, 0);
1063             for (int n = 0; n + 1 < x->length; n++) X(n) = X(n + 1);
1064             x->length -= 1;
1065             }
1066              
1067             if (compare(x, m) >= 0) subD(x, m, 0);
1068             assert(compare(x, m) < 0);
1069             trim(x);
1070             }
1071              
1072             static void montMul(struct cdsBigInteger * a, struct cdsBigInteger * x, struct cdsBigInteger * y, const struct cdsBigInteger * m, uint32_t mp) {
1073             int mk = mostSignificantElement(m);
1074             assert(mostSignificantElement(x) <= mk);
1075             assert(mostSignificantElement(y) <= mk);
1076             setZero(a);
1077             expand(a, mk + 2);
1078             expand(x, mk + 1);
1079             expand(y, mk + 1);
1080             for (int i = 0; i <= mk; i++) {
1081             uint64_t cProduct = (uint64_t)X(i) * Y(0);
1082             uint64_t u = (A(0) + cProduct) & 0xffffffff;
1083             u = (u * mp) & 0xffffffff;
1084              
1085             uint64_t cSum = A(0) + (cProduct & 0xffffffff) + u * M(0);
1086             cProduct >>= 32;
1087             cSum >>= 32;
1088             int n = 1;
1089             for (; n <= mk; n++) {
1090             cProduct += (uint64_t)X(i) * Y(n);
1091             cSum += A(n) + (cProduct & 0xffffffff) + u * M(n);
1092             A(n - 1) = cSum & 0xffffffff;
1093             cProduct >>= 32;
1094             cSum >>= 32;
1095             }
1096             cSum += A(n) + (cProduct & 0xffffffff);
1097             A(n - 1) = cSum & 0xffffffff;
1098             cProduct >>= 32;
1099             cSum >>= 32;
1100             cSum += cProduct & 0xffffffff;
1101             A(n) = cSum & 0xffffffff;
1102             }
1103              
1104             if (compare(a, m) >= 0) subD(a, m, 0);
1105             trim(a);
1106             }
1107              
1108             static void modPowSmallExp(struct cdsRSAModPowSmall * this, const struct cdsBigInteger * g, const struct cdsBigInteger * e, const struct cdsBigInteger * m) {
1109             uint32_t mp = montInverse(m);
1110             struct cdsBigInteger * gR = &this->gR;
1111             montConversion(gR, g, m);
1112              
1113             int ek = mostSignificantElement(e);
1114             uint32_t eMask = 0x80000000;
1115             while ((E(ek) & eMask) == 0) eMask >>= 1;
1116              
1117             struct cdsBigInteger * aR = &this->bigInteger1;
1118             copyD(aR, gR, 0);
1119              
1120             struct cdsBigInteger * tR = &this->bigInteger2;
1121             while (true) {
1122             eMask >>= 1;
1123             if (eMask == 0) {
1124             if (ek == 0) break;
1125             ek -= 1;
1126             eMask = 0x80000000;
1127             }
1128              
1129             setZero(tR);
1130             sqr(tR, aR);
1131             montReduction(tR, m, mp);
1132              
1133             if (E(ek) & eMask) {
1134             setZero(aR);
1135             montMul(aR, tR, gR, m, mp);
1136             } else {
1137             struct cdsBigInteger * temp = aR;
1138             aR = tR;
1139             tR = temp;
1140             }
1141             }
1142              
1143             montReduction(aR, m, mp);
1144             this->result = aR;
1145             }
1146              
1147             static void modPowBigSwap(struct cdsRSAModPowBig * this) {
1148             struct cdsBigInteger * temp = this->aR;
1149             this->aR = this->tR;
1150             this->tR = temp;
1151             }
1152              
1153             static void modPowBigSqrAR(struct cdsRSAModPowBig * this) {
1154             setZero(this->tR);
1155             assert(mostSignificantElement(this->aR) < 64);
1156             sqr(this->tR, this->aR);
1157             montReduction(this->tR, this->m, this->mp);
1158             assert(mostSignificantElement(this->tR) < 64);
1159             modPowBigSwap(this);
1160             }
1161              
1162             static void modPowBigFlushSelection(struct cdsRSAModPowBig * this) {
1163             for (; this->usableBits > 0; this->usableBits--) modPowBigSqrAR(this);
1164             setZero(this->tR);
1165             montMul(this->tR, this->aR, this->gR + this->usableSelection, this->m, this->mp);
1166             assert(mostSignificantElement(this->tR) < 64);
1167             modPowBigSwap(this);
1168             for (; this->zeroBits > 0; this->zeroBits--) modPowBigSqrAR(this);
1169              
1170             this->selection = 0;
1171             this->usableSelection = 0;
1172             }
1173              
1174             static void modPowBigResult(struct cdsRSAModPowBig * this) {
1175             copyD(this->tR, this->aR, 0);
1176             montReduction(this->tR, this->m, this->mp);
1177             this->result = this->tR;
1178             }
1179              
1180             static void modPowBigExp(struct cdsRSAModPowBig * this, const struct cdsBigInteger * g, const struct cdsBigInteger * e, const struct cdsBigInteger * m) {
1181             this->m = m;
1182             this->mp = montInverse(m);
1183              
1184             montConversion(this->gR + 1, g, m);
1185             montMul(this->gR + 2, this->gR + 1, this->gR + 1, m, this->mp);
1186             for (int i = 3; i < 64; i += 2)
1187             montMul(this->gR + i, this->gR + (i - 2), this->gR + 2, m, this->mp);
1188              
1189             this->aR = &this->bigInteger1;
1190             montConversionOne(this->aR, this->m);
1191             assert(mostSignificantElement(this->aR) < 64);
1192              
1193             int ek = mostSignificantElement(e);
1194             uint32_t eMask = 0x80000000;
1195             while ((E(ek) & eMask) == 0) eMask >>= 1;
1196              
1197             this->selection = 1; // = usableSelection * 2 ^ zeroBits
1198             this->usableSelection = 1;
1199             this->usableBits = 1;
1200             this->zeroBits = 0;
1201              
1202             this->tR = &this->bigInteger2;
1203             while (true) {
1204             eMask >>= 1;
1205             if (eMask == 0) {
1206             if (ek == 0) break;
1207             ek -= 1;
1208             eMask = 0x80000000;
1209             }
1210              
1211             if (E(ek) & eMask) {
1212             if (this->selection > 31) modPowBigFlushSelection(this);
1213             this->selection = this->selection * 2 + 1;
1214             this->usableSelection = this->selection;
1215             this->usableBits += this->zeroBits + 1;
1216             this->zeroBits = 0;
1217             } else if (this->usableBits == 0) {
1218             modPowBigSqrAR(this);
1219             } else {
1220             this->selection *= 2;
1221             this->zeroBits += 1;
1222             }
1223             }
1224              
1225             if (this->usableBits > 0) modPowBigFlushSelection(this);
1226             }
1227              
1228              
1229             static uint32_t sign(const struct cdsBigInteger * x) {
1230             return x->length > 0 && X(x->length - 1) & 0x80000000 ? 0xffffffff : 0;
1231             }
1232              
1233             static void expandS(struct cdsBigInteger * x, int n) {
1234             assert(n <= CDS_BIG_INTEGER_SIZE);
1235             uint32_t filler = sign(x);
1236             while (x->length < n) {
1237             x->length += 1;
1238             X(x->length - 1) = filler;
1239             }
1240             }
1241              
1242             static void trimS(struct cdsBigInteger * x) {
1243             uint32_t filler = sign(x);
1244             while (x->length > 1 && X(x->length - 1) == filler && ((X(x->length - 1) ^ X(x->length - 2)) & 0x80000000) == 0) x->length -= 1;
1245             }
1246              
1247             static void addSU(struct cdsBigInteger * x, struct cdsBigInteger * y) {
1248             expandS(x, maxLength(x, y) + 1);
1249             uint64_t c = 0;
1250             int i = 0;
1251             for (; i < y->length; i++) {
1252             c += (uint64_t)X(i) + Y(i);
1253             X(i) = c & 0xffffffff;
1254             c >>= 32;
1255             }
1256             for (; i < x->length && c != 0; i++) {
1257             c += (uint64_t)X(i);
1258             X(i) = c & 0xffffffff;
1259             c >>= 32;
1260             }
1261             trimS(x);
1262             }
1263              
1264             static void subSS(struct cdsBigInteger * x, struct cdsBigInteger * y) {
1265             expandS(x, maxLength(x, y) + 1);
1266             int64_t c = 0;
1267             int i = 0;
1268             for (; i < y->length; i++) {
1269             c += (int64_t)X(i) - (int64_t)Y(i);
1270             X(i) = c & 0xffffffff;
1271             c >>= 32;
1272             }
1273             int64_t filler = (int64_t)sign(y);
1274             for (; i < x->length; i++) {
1275             c += (int64_t)X(i) - filler;
1276             X(i) = c & 0xffffffff;
1277             c >>= 32;
1278             }
1279             trimS(x);
1280             }
1281              
1282             static void halveS(struct cdsBigInteger * x) {
1283             int i = 0;
1284             for (; i + 1 < x->length; i++)
1285             X(i) = X(i) >> 1 | X(i + 1) << 31;
1286             X(i) = (uint32_t)((int32_t)X(i) >> 1);
1287             trimS(x);
1288             }
1289              
1290             static void egcd(struct cdsBigInteger * x, struct cdsBigInteger * y, struct cdsBigInteger * a, struct cdsBigInteger * b, struct cdsBigInteger * gcd) {
1291             struct cdsBigInteger * u = gcd;
1292             struct cdsBigInteger v = CDS_BIG_INTEGER_ZERO;
1293              
1294             struct cdsBigInteger * A = a;
1295             struct cdsBigInteger * B = b;
1296             struct cdsBigInteger C = CDS_BIG_INTEGER_ZERO;
1297             struct cdsBigInteger D = CDS_BIG_INTEGER_ZERO;
1298              
1299             copyD(u, x, 0);
1300             copyD(&v, y, 0);
1301              
1302             setUint32(A, 1);
1303             setZero(B);
1304             setZero(&C);
1305             setUint32(&D, 0xffffffff);
1306              
1307             while (true) {
1308             while (isEven(u)) {
1309             smallShiftRight(u, u, 1);
1310             if (isEven(A) && isEven(B)) {
1311             halveS(A);
1312             halveS(B);
1313             } else {
1314             addSU(A, y);
1315             halveS(A);
1316             addSU(B, x);
1317             halveS(B);
1318             }
1319             }
1320              
1321             while (isEven(&v)) {
1322             smallShiftRight(&v, &v, 1);
1323             if (isEven(&C) && isEven(&D)) {
1324             halveS(&C);
1325             halveS(&D);
1326             } else {
1327             addSU(&C, y);
1328             halveS(&C);
1329             addSU(&D, x);
1330             halveS(&D);
1331             }
1332             }
1333              
1334             trim(u);
1335             trim(&v);
1336             int cmp = compare(u, &v);
1337             if (cmp == 0) return;
1338              
1339             if (cmp > 0) {
1340             subD(u, &v, 0);
1341             trim(u);
1342             subSS(A, &C);
1343             subSS(B, &D);
1344             } else {
1345             subD(&v, u, 0);
1346             trim(&v);
1347             subSS(&C, A);
1348             subSS(&D, B);
1349             }
1350             }
1351             }
1352              
1353             static bool modInverse(struct cdsBigInteger * a, struct cdsBigInteger * x, struct cdsBigInteger * m) {
1354             struct cdsBigInteger b = CDS_BIG_INTEGER_ZERO;
1355             struct cdsBigInteger gcd = CDS_BIG_INTEGER_ZERO;
1356             egcd(x, m, a, &b, &gcd);
1357              
1358             if (! isOne(&gcd)) return false;
1359              
1360             while (sign(a) != 0) addSU(a, m);
1361             trim(a);
1362             return true;
1363             }
1364              
1365              
1366             static int removeFactorsOf2(struct cdsBigInteger * x) {
1367             int d = 0;
1368             while (X(d) == 0) d += 1;
1369             if (d > 0) {
1370             for (int i = 0; i + d < x->length; i++) X(i) = X(i + d);
1371             x->length = x->length - d;
1372             }
1373              
1374             if (x->length == 0) return 0;
1375              
1376             int s = 0;
1377             uint32_t x0 = X(0);
1378             if ((x0 & 0xffff) == 0) {
1379             s += 14;
1380             x0 >>= 16;
1381             }
1382             if ((x0 & 0xff) == 0) {
1383             s += 7;
1384             x0 >>= 8;
1385             }
1386             if ((x0 & 0xf) == 0) {
1387             s += 4;
1388             x0 >>= 4;
1389             }
1390             if ((x0 & 0x3) == 0) {
1391             s += 2;
1392             x0 >>= 2;
1393             }
1394             if ((x0 & 0x1) == 0) s += 1;
1395             if (s > 0) smallShiftRight(x, x, s);
1396             trim(x);
1397             return s + 32 * d;
1398             }
1399              
1400             static bool millerRabin(struct cdsBigInteger * x, struct cdsRSAModPowBig * modPowBig) {
1401             struct cdsBigInteger x1 = CDS_BIG_INTEGER_ZERO;
1402             copyD(&x1, x, 0);
1403             decrement(&x1);
1404              
1405             struct cdsBigInteger r = CDS_BIG_INTEGER_ZERO;
1406             copyD(&r, &x1, 0);
1407             int s = removeFactorsOf2(&r);
1408              
1409             int repeat = 2;
1410             int xk = mostSignificantElement(x);
1411             struct cdsBigInteger a = CDS_BIG_INTEGER_ZERO;
1412             for (int i = 0; i < repeat; i++) {
1413             setRandom(&a, xk - 1);
1414             while (isZero(&a) || isOne(&a)) setRandom(&a, xk - 1);
1415              
1416             modPowBigExp(modPowBig, &a, &r, x);
1417             modPowBigResult(modPowBig);
1418             if (isOne(modPowBig->result) || compare(modPowBig->result, &x1) == 0) continue;
1419              
1420             int j = 1;
1421             for (; j < s; j++) {
1422             modPowBigSqrAR(modPowBig);
1423             modPowBigResult(modPowBig);
1424             if (isOne(modPowBig->result)) return false;
1425             if (compare(modPowBig->result, &x1) == 0) break;
1426             }
1427             if (j == s) return false;
1428             }
1429              
1430             return true;
1431             }
1432              
1433             static uint32_t modInt(struct cdsBigInteger * x, uint32_t y) {
1434             uint64_t c = 0;
1435             for (int i = mostSignificantElement(x); i >= 0; i--)
1436             c = ((c << 32) + X(i)) % y;
1437             return (uint32_t)c;
1438             }
1439              
1440              
1441             #ifndef KEY_GENERATION_RESET_WATCHDOG
1442             #define KEY_GENERATION_RESET_WATCHDOG() ;
1443             #endif
1444              
1445             static const int elementsFor1024Bits = 32;
1446             static const int elementsFor2048Bits = 64;
1447             static int bitCount4[] = {0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4};
1448              
1449             static int bitCount(uint32_t n) {
1450             int count = 0;
1451             for (; n != 0; n >>= 4)
1452             count += bitCount4[n & 0xf];
1453             return count;
1454             }
1455              
1456             static void gcd(struct cdsBigInteger * x, struct cdsBigInteger * y) {
1457             removeFactorsOf2(x);
1458             removeFactorsOf2(y);
1459             while (true) {
1460             int cmp = compare(x, y);
1461             if (cmp == 0) return;
1462              
1463             if (cmp > 0) {
1464             subD(x, y, 0);
1465             removeFactorsOf2(x);
1466             trim(x);
1467             } else {
1468             subD(y, x, 0);
1469             removeFactorsOf2(y);
1470             trim(y);
1471             }
1472             }
1473             }
1474              
1475             static void markInSieve(uint8_t * sieve, uint16_t s, uint16_t interval) {
1476             for (; s < 4096; s += interval) sieve[s] = 1;
1477             }
1478              
1479             static void randomPrime1024(struct cdsBigInteger * x, struct cdsBigInteger * e, struct cdsRSAModPowBig * modPowBig) {
1480             uint8_t sieve[4096];
1481             while (true) {
1482             struct cdsBigInteger start = CDS_BIG_INTEGER_ZERO;
1483             setRandom(&start, elementsFor1024Bits);
1484             start.values[0] |= 1;
1485             start.values[elementsFor1024Bits - 1] |= 0x80000000;
1486              
1487             KEY_GENERATION_RESET_WATCHDOG();
1488             memset(sieve, 0, 4096);
1489              
1490             for (uint16_t n = 0; n < 4096; n += 2) {
1491             if (sieve[n]) continue;
1492              
1493             setUint32(x, n);
1494             addN(x, 1, &start, 0);
1495             trim(x);
1496              
1497              
1498             #line 1 "Condensation/../../c/Condensation/RSA64/primality.inc.c"
1499             uint32_t m = modInt(x, 3234846615);
1500             if (m % 3 == 0) {
1501             markInSieve(sieve, n, 3);
1502             continue;
1503             }
1504             if (m % 5 == 0) {
1505             markInSieve(sieve, n, 5);
1506             continue;
1507             }
1508             if (m % 7 == 0) {
1509             markInSieve(sieve, n, 7);
1510             continue;
1511             }
1512             if (m % 11 == 0) {
1513             markInSieve(sieve, n, 11);
1514             continue;
1515             }
1516             if (m % 13 == 0) {
1517             markInSieve(sieve, n, 13);
1518             continue;
1519             }
1520             if (m % 17 == 0) {
1521             markInSieve(sieve, n, 17);
1522             continue;
1523             }
1524             if (m % 19 == 0) {
1525             markInSieve(sieve, n, 19);
1526             continue;
1527             }
1528             if (m % 23 == 0) {
1529             markInSieve(sieve, n, 23);
1530             continue;
1531             }
1532             if (m % 29 == 0) {
1533             markInSieve(sieve, n, 29);
1534             continue;
1535             }
1536             m = modInt(x, 95041567);
1537             if (m % 31 == 0) {
1538             markInSieve(sieve, n, 31);
1539             continue;
1540             }
1541             if (m % 37 == 0) {
1542             markInSieve(sieve, n, 37);
1543             continue;
1544             }
1545             if (m % 41 == 0) {
1546             markInSieve(sieve, n, 41);
1547             continue;
1548             }
1549             if (m % 43 == 0) {
1550             markInSieve(sieve, n, 43);
1551             continue;
1552             }
1553             if (m % 47 == 0) {
1554             markInSieve(sieve, n, 47);
1555             continue;
1556             }
1557             m = modInt(x, 907383479);
1558             if (m % 53 == 0) {
1559             markInSieve(sieve, n, 53);
1560             continue;
1561             }
1562             if (m % 59 == 0) {
1563             markInSieve(sieve, n, 59);
1564             continue;
1565             }
1566             if (m % 61 == 0) {
1567             markInSieve(sieve, n, 61);
1568             continue;
1569             }
1570             if (m % 67 == 0) {
1571             markInSieve(sieve, n, 67);
1572             continue;
1573             }
1574             if (m % 71 == 0) {
1575             markInSieve(sieve, n, 71);
1576             continue;
1577             }
1578             m = modInt(x, 4132280413);
1579             if (m % 73 == 0) {
1580             markInSieve(sieve, n, 73);
1581             continue;
1582             }
1583             if (m % 79 == 0) {
1584             markInSieve(sieve, n, 79);
1585             continue;
1586             }
1587             if (m % 83 == 0) {
1588             markInSieve(sieve, n, 83);
1589             continue;
1590             }
1591             if (m % 89 == 0) {
1592             markInSieve(sieve, n, 89);
1593             continue;
1594             }
1595             if (m % 97 == 0) {
1596             markInSieve(sieve, n, 97);
1597             continue;
1598             }
1599             m = modInt(x, 121330189);
1600             if (m % 101 == 0) {
1601             markInSieve(sieve, n, 101);
1602             continue;
1603             }
1604             if (m % 103 == 0) {
1605             markInSieve(sieve, n, 103);
1606             continue;
1607             }
1608             if (m % 107 == 0) {
1609             markInSieve(sieve, n, 107);
1610             continue;
1611             }
1612             if (m % 109 == 0) {
1613             markInSieve(sieve, n, 109);
1614             continue;
1615             }
1616             m = modInt(x, 257557397);
1617             if (m % 113 == 0) {
1618             markInSieve(sieve, n, 113);
1619             continue;
1620             }
1621             if (m % 127 == 0) {
1622             markInSieve(sieve, n, 127);
1623             continue;
1624             }
1625             if (m % 131 == 0) {
1626             markInSieve(sieve, n, 131);
1627             continue;
1628             }
1629             if (m % 137 == 0) {
1630             markInSieve(sieve, n, 137);
1631             continue;
1632             }
1633             m = modInt(x, 490995677);
1634             if (m % 139 == 0) {
1635             markInSieve(sieve, n, 139);
1636             continue;
1637             }
1638             if (m % 149 == 0) {
1639             markInSieve(sieve, n, 149);
1640             continue;
1641             }
1642             if (m % 151 == 0) {
1643             markInSieve(sieve, n, 151);
1644             continue;
1645             }
1646             if (m % 157 == 0) {
1647             markInSieve(sieve, n, 157);
1648             continue;
1649             }
1650             m = modInt(x, 842952707);
1651             if (m % 163 == 0) {
1652             markInSieve(sieve, n, 163);
1653             continue;
1654             }
1655             if (m % 167 == 0) {
1656             markInSieve(sieve, n, 167);
1657             continue;
1658             }
1659             if (m % 173 == 0) {
1660             markInSieve(sieve, n, 173);
1661             continue;
1662             }
1663             if (m % 179 == 0) {
1664             markInSieve(sieve, n, 179);
1665             continue;
1666             }
1667             m = modInt(x, 1314423991);
1668             if (m % 181 == 0) {
1669             markInSieve(sieve, n, 181);
1670             continue;
1671             }
1672             if (m % 191 == 0) {
1673             markInSieve(sieve, n, 191);
1674             continue;
1675             }
1676             if (m % 193 == 0) {
1677             markInSieve(sieve, n, 193);
1678             continue;
1679             }
1680             if (m % 197 == 0) {
1681             markInSieve(sieve, n, 197);
1682             continue;
1683             }
1684             m = modInt(x, 2125525169);
1685             if (m % 199 == 0) {
1686             markInSieve(sieve, n, 199);
1687             continue;
1688             }
1689             if (m % 211 == 0) {
1690             markInSieve(sieve, n, 211);
1691             continue;
1692             }
1693             if (m % 223 == 0) {
1694             markInSieve(sieve, n, 223);
1695             continue;
1696             }
1697             if (m % 227 == 0) {
1698             markInSieve(sieve, n, 227);
1699             continue;
1700             }
1701             m = modInt(x, 3073309843);
1702             if (m % 229 == 0) {
1703             markInSieve(sieve, n, 229);
1704             continue;
1705             }
1706             if (m % 233 == 0) {
1707             markInSieve(sieve, n, 233);
1708             continue;
1709             }
1710             if (m % 239 == 0) {
1711             markInSieve(sieve, n, 239);
1712             continue;
1713             }
1714             if (m % 241 == 0) {
1715             markInSieve(sieve, n, 241);
1716             continue;
1717             }
1718             m = modInt(x, 16965341);
1719             if (m % 251 == 0) {
1720             markInSieve(sieve, n, 251);
1721             continue;
1722             }
1723             if (m % 257 == 0) {
1724             markInSieve(sieve, n, 257);
1725             continue;
1726             }
1727             if (m % 263 == 0) {
1728             markInSieve(sieve, n, 263);
1729             continue;
1730             }
1731             m = modInt(x, 20193023);
1732             if (m % 269 == 0) {
1733             markInSieve(sieve, n, 269);
1734             continue;
1735             }
1736             if (m % 271 == 0) {
1737             markInSieve(sieve, n, 271);
1738             continue;
1739             }
1740             if (m % 277 == 0) {
1741             markInSieve(sieve, n, 277);
1742             continue;
1743             }
1744             m = modInt(x, 23300239);
1745             if (m % 281 == 0) {
1746             markInSieve(sieve, n, 281);
1747             continue;
1748             }
1749             if (m % 283 == 0) {
1750             markInSieve(sieve, n, 283);
1751             continue;
1752             }
1753             if (m % 293 == 0) {
1754             markInSieve(sieve, n, 293);
1755             continue;
1756             }
1757             m = modInt(x, 29884301);
1758             if (m % 307 == 0) {
1759             markInSieve(sieve, n, 307);
1760             continue;
1761             }
1762             if (m % 311 == 0) {
1763             markInSieve(sieve, n, 311);
1764             continue;
1765             }
1766             if (m % 313 == 0) {
1767             markInSieve(sieve, n, 313);
1768             continue;
1769             }
1770             m = modInt(x, 35360399);
1771             if (m % 317 == 0) {
1772             markInSieve(sieve, n, 317);
1773             continue;
1774             }
1775             if (m % 331 == 0) {
1776             markInSieve(sieve, n, 331);
1777             continue;
1778             }
1779             if (m % 337 == 0) {
1780             markInSieve(sieve, n, 337);
1781             continue;
1782             }
1783             m = modInt(x, 42749359);
1784             if (m % 347 == 0) {
1785             markInSieve(sieve, n, 347);
1786             continue;
1787             }
1788             if (m % 349 == 0) {
1789             markInSieve(sieve, n, 349);
1790             continue;
1791             }
1792             if (m % 353 == 0) {
1793             markInSieve(sieve, n, 353);
1794             continue;
1795             }
1796             m = modInt(x, 49143869);
1797             if (m % 359 == 0) {
1798             markInSieve(sieve, n, 359);
1799             continue;
1800             }
1801             if (m % 367 == 0) {
1802             markInSieve(sieve, n, 367);
1803             continue;
1804             }
1805             if (m % 373 == 0) {
1806             markInSieve(sieve, n, 373);
1807             continue;
1808             }
1809             m = modInt(x, 56466073);
1810             if (m % 379 == 0) {
1811             markInSieve(sieve, n, 379);
1812             continue;
1813             }
1814             if (m % 383 == 0) {
1815             markInSieve(sieve, n, 383);
1816             continue;
1817             }
1818             if (m % 389 == 0) {
1819             markInSieve(sieve, n, 389);
1820             continue;
1821             }
1822             m = modInt(x, 65111573);
1823             if (m % 397 == 0) {
1824             markInSieve(sieve, n, 397);
1825             continue;
1826             }
1827             if (m % 401 == 0) {
1828             markInSieve(sieve, n, 401);
1829             continue;
1830             }
1831             if (m % 409 == 0) {
1832             markInSieve(sieve, n, 409);
1833             continue;
1834             }
1835             m = modInt(x, 76027969);
1836             if (m % 419 == 0) {
1837             markInSieve(sieve, n, 419);
1838             continue;
1839             }
1840             if (m % 421 == 0) {
1841             markInSieve(sieve, n, 421);
1842             continue;
1843             }
1844             if (m % 431 == 0) {
1845             markInSieve(sieve, n, 431);
1846             continue;
1847             }
1848             m = modInt(x, 84208541);
1849             if (m % 433 == 0) {
1850             markInSieve(sieve, n, 433);
1851             continue;
1852             }
1853             if (m % 439 == 0) {
1854             markInSieve(sieve, n, 439);
1855             continue;
1856             }
1857             if (m % 443 == 0) {
1858             markInSieve(sieve, n, 443);
1859             continue;
1860             }
1861             m = modInt(x, 94593973);
1862             if (m % 449 == 0) {
1863             markInSieve(sieve, n, 449);
1864             continue;
1865             }
1866             if (m % 457 == 0) {
1867             markInSieve(sieve, n, 457);
1868             continue;
1869             }
1870             if (m % 461 == 0) {
1871             markInSieve(sieve, n, 461);
1872             continue;
1873             }
1874             m = modInt(x, 103569859);
1875             if (m % 463 == 0) {
1876             markInSieve(sieve, n, 463);
1877             continue;
1878             }
1879             if (m % 467 == 0) {
1880             markInSieve(sieve, n, 467);
1881             continue;
1882             }
1883             if (m % 479 == 0) {
1884             markInSieve(sieve, n, 479);
1885             continue;
1886             }
1887             m = modInt(x, 119319383);
1888             if (m % 487 == 0) {
1889             markInSieve(sieve, n, 487);
1890             continue;
1891             }
1892             if (m % 491 == 0) {
1893             markInSieve(sieve, n, 491);
1894             continue;
1895             }
1896             if (m % 499 == 0) {
1897             markInSieve(sieve, n, 499);
1898             continue;
1899             }
1900             m = modInt(x, 133390067);
1901             if (m % 503 == 0) {
1902             markInSieve(sieve, n, 503);
1903             continue;
1904             }
1905             if (m % 509 == 0) {
1906             markInSieve(sieve, n, 509);
1907             continue;
1908             }
1909             if (m % 521 == 0) {
1910             markInSieve(sieve, n, 521);
1911             continue;
1912             }
1913             m = modInt(x, 154769821);
1914             if (m % 523 == 0) {
1915             markInSieve(sieve, n, 523);
1916             continue;
1917             }
1918             if (m % 541 == 0) {
1919             markInSieve(sieve, n, 541);
1920             continue;
1921             }
1922             if (m % 547 == 0) {
1923             markInSieve(sieve, n, 547);
1924             continue;
1925             }
1926             m = modInt(x, 178433279);
1927             if (m % 557 == 0) {
1928             markInSieve(sieve, n, 557);
1929             continue;
1930             }
1931             if (m % 563 == 0) {
1932             markInSieve(sieve, n, 563);
1933             continue;
1934             }
1935             if (m % 569 == 0) {
1936             markInSieve(sieve, n, 569);
1937             continue;
1938             }
1939             m = modInt(x, 193397129);
1940             if (m % 571 == 0) {
1941             markInSieve(sieve, n, 571);
1942             continue;
1943             }
1944             if (m % 577 == 0) {
1945             markInSieve(sieve, n, 577);
1946             continue;
1947             }
1948             if (m % 587 == 0) {
1949             markInSieve(sieve, n, 587);
1950             continue;
1951             }
1952             m = modInt(x, 213479407);
1953             if (m % 593 == 0) {
1954             markInSieve(sieve, n, 593);
1955             continue;
1956             }
1957             if (m % 599 == 0) {
1958             markInSieve(sieve, n, 599);
1959             continue;
1960             }
1961             if (m % 601 == 0) {
1962             markInSieve(sieve, n, 601);
1963             continue;
1964             }
1965             m = modInt(x, 229580147);
1966             if (m % 607 == 0) {
1967             markInSieve(sieve, n, 607);
1968             continue;
1969             }
1970             if (m % 613 == 0) {
1971             markInSieve(sieve, n, 613);
1972             continue;
1973             }
1974             if (m % 617 == 0) {
1975             markInSieve(sieve, n, 617);
1976             continue;
1977             }
1978             m = modInt(x, 250367549);
1979             if (m % 619 == 0) {
1980             markInSieve(sieve, n, 619);
1981             continue;
1982             }
1983             if (m % 631 == 0) {
1984             markInSieve(sieve, n, 631);
1985             continue;
1986             }
1987             if (m % 641 == 0) {
1988             markInSieve(sieve, n, 641);
1989             continue;
1990             }
1991             m = modInt(x, 271661713);
1992             if (m % 643 == 0) {
1993             markInSieve(sieve, n, 643);
1994             continue;
1995             }
1996             if (m % 647 == 0) {
1997             markInSieve(sieve, n, 647);
1998             continue;
1999             }
2000             if (m % 653 == 0) {
2001             markInSieve(sieve, n, 653);
2002             continue;
2003             }
2004             m = modInt(x, 293158127);
2005             if (m % 659 == 0) {
2006             markInSieve(sieve, n, 659);
2007             continue;
2008             }
2009             if (m % 661 == 0) {
2010             markInSieve(sieve, n, 661);
2011             continue;
2012             }
2013             if (m % 673 == 0) {
2014             markInSieve(sieve, n, 673);
2015             continue;
2016             }
2017             m = modInt(x, 319512181);
2018             if (m % 677 == 0) {
2019             markInSieve(sieve, n, 677);
2020             continue;
2021             }
2022             if (m % 683 == 0) {
2023             markInSieve(sieve, n, 683);
2024             continue;
2025             }
2026             if (m % 691 == 0) {
2027             markInSieve(sieve, n, 691);
2028             continue;
2029             }
2030             m = modInt(x, 357349471);
2031             if (m % 701 == 0) {
2032             markInSieve(sieve, n, 701);
2033             continue;
2034             }
2035             if (m % 709 == 0) {
2036             markInSieve(sieve, n, 709);
2037             continue;
2038             }
2039             if (m % 719 == 0) {
2040             markInSieve(sieve, n, 719);
2041             continue;
2042             }
2043             m = modInt(x, 393806449);
2044             if (m % 727 == 0) {
2045             markInSieve(sieve, n, 727);
2046             continue;
2047             }
2048             if (m % 733 == 0) {
2049             markInSieve(sieve, n, 733);
2050             continue;
2051             }
2052             if (m % 739 == 0) {
2053             markInSieve(sieve, n, 739);
2054             continue;
2055             }
2056             m = modInt(x, 422400701);
2057             if (m % 743 == 0) {
2058             markInSieve(sieve, n, 743);
2059             continue;
2060             }
2061             if (m % 751 == 0) {
2062             markInSieve(sieve, n, 751);
2063             continue;
2064             }
2065             if (m % 757 == 0) {
2066             markInSieve(sieve, n, 757);
2067             continue;
2068             }
2069             m = modInt(x, 452366557);
2070             if (m % 761 == 0) {
2071             markInSieve(sieve, n, 761);
2072             continue;
2073             }
2074             if (m % 769 == 0) {
2075             markInSieve(sieve, n, 769);
2076             continue;
2077             }
2078             if (m % 773 == 0) {
2079             markInSieve(sieve, n, 773);
2080             continue;
2081             }
2082             m = modInt(x, 507436351);
2083             if (m % 787 == 0) {
2084             markInSieve(sieve, n, 787);
2085             continue;
2086             }
2087             if (m % 797 == 0) {
2088             markInSieve(sieve, n, 797);
2089             continue;
2090             }
2091             if (m % 809 == 0) {
2092             markInSieve(sieve, n, 809);
2093             continue;
2094             }
2095             m = modInt(x, 547978913);
2096             if (m % 811 == 0) {
2097             markInSieve(sieve, n, 811);
2098             continue;
2099             }
2100             if (m % 821 == 0) {
2101             markInSieve(sieve, n, 821);
2102             continue;
2103             }
2104             if (m % 823 == 0) {
2105             markInSieve(sieve, n, 823);
2106             continue;
2107             }
2108             m = modInt(x, 575204137);
2109             if (m % 827 == 0) {
2110             markInSieve(sieve, n, 827);
2111             continue;
2112             }
2113             if (m % 829 == 0) {
2114             markInSieve(sieve, n, 829);
2115             continue;
2116             }
2117             if (m % 839 == 0) {
2118             markInSieve(sieve, n, 839);
2119             continue;
2120             }
2121             m = modInt(x, 627947039);
2122             if (m % 853 == 0) {
2123             markInSieve(sieve, n, 853);
2124             continue;
2125             }
2126             if (m % 857 == 0) {
2127             markInSieve(sieve, n, 857);
2128             continue;
2129             }
2130             if (m % 859 == 0) {
2131             markInSieve(sieve, n, 859);
2132             continue;
2133             }
2134             m = modInt(x, 666785731);
2135             if (m % 863 == 0) {
2136             markInSieve(sieve, n, 863);
2137             continue;
2138             }
2139             if (m % 877 == 0) {
2140             markInSieve(sieve, n, 877);
2141             continue;
2142             }
2143             if (m % 881 == 0) {
2144             markInSieve(sieve, n, 881);
2145             continue;
2146             }
2147             m = modInt(x, 710381447);
2148             if (m % 883 == 0) {
2149             markInSieve(sieve, n, 883);
2150             continue;
2151             }
2152             if (m % 887 == 0) {
2153             markInSieve(sieve, n, 887);
2154             continue;
2155             }
2156             if (m % 907 == 0) {
2157             markInSieve(sieve, n, 907);
2158             continue;
2159             }
2160             m = modInt(x, 777767161);
2161             if (m % 911 == 0) {
2162             markInSieve(sieve, n, 911);
2163             continue;
2164             }
2165             if (m % 919 == 0) {
2166             markInSieve(sieve, n, 919);
2167             continue;
2168             }
2169             if (m % 929 == 0) {
2170             markInSieve(sieve, n, 929);
2171             continue;
2172             }
2173             m = modInt(x, 834985999);
2174             if (m % 937 == 0) {
2175             markInSieve(sieve, n, 937);
2176             continue;
2177             }
2178             if (m % 941 == 0) {
2179             markInSieve(sieve, n, 941);
2180             continue;
2181             }
2182             if (m % 947 == 0) {
2183             markInSieve(sieve, n, 947);
2184             continue;
2185             }
2186             m = modInt(x, 894826021);
2187             if (m % 953 == 0) {
2188             markInSieve(sieve, n, 953);
2189             continue;
2190             }
2191             if (m % 967 == 0) {
2192             markInSieve(sieve, n, 967);
2193             continue;
2194             }
2195             if (m % 971 == 0) {
2196             markInSieve(sieve, n, 971);
2197             continue;
2198             }
2199             m = modInt(x, 951747481);
2200             if (m % 977 == 0) {
2201             markInSieve(sieve, n, 977);
2202             continue;
2203             }
2204             if (m % 983 == 0) {
2205             markInSieve(sieve, n, 983);
2206             continue;
2207             }
2208             if (m % 991 == 0) {
2209             markInSieve(sieve, n, 991);
2210             continue;
2211             }
2212             m = modInt(x, 1019050649);
2213             if (m % 997 == 0) {
2214             markInSieve(sieve, n, 997);
2215             continue;
2216             }
2217             if (m % 1009 == 0) {
2218             markInSieve(sieve, n, 1009);
2219             continue;
2220             }
2221             if (m % 1013 == 0) {
2222             markInSieve(sieve, n, 1013);
2223             continue;
2224             }
2225             m = modInt(x, 1072651369);
2226             if (m % 1019 == 0) continue;
2227             if (m % 1021 == 0) continue;
2228             if (m % 1031 == 0) continue;
2229             m = modInt(x, 1125878063);
2230             if (m % 1033 == 0) continue;
2231             if (m % 1039 == 0) continue;
2232             if (m % 1049 == 0) continue;
2233             m = modInt(x, 1185362993);
2234             if (m % 1051 == 0) continue;
2235             if (m % 1061 == 0) continue;
2236             if (m % 1063 == 0) continue;
2237             m = modInt(x, 1267745273);
2238             if (m % 1069 == 0) continue;
2239             if (m % 1087 == 0) continue;
2240             if (m % 1091 == 0) continue;
2241             m = modInt(x, 1322520163);
2242             if (m % 1093 == 0) continue;
2243             if (m % 1097 == 0) continue;
2244             if (m % 1103 == 0) continue;
2245             m = modInt(x, 1391119619);
2246             if (m % 1109 == 0) continue;
2247             if (m % 1117 == 0) continue;
2248             if (m % 1123 == 0) continue;
2249             m = modInt(x, 1498299287);
2250             if (m % 1129 == 0) continue;
2251             if (m % 1151 == 0) continue;
2252             if (m % 1153 == 0) continue;
2253             m = modInt(x, 1608372013);
2254             if (m % 1163 == 0) continue;
2255             if (m % 1171 == 0) continue;
2256             if (m % 1181 == 0) continue;
2257             m = modInt(x, 1700725291);
2258             if (m % 1187 == 0) continue;
2259             if (m % 1193 == 0) continue;
2260             if (m % 1201 == 0) continue;
2261             m = modInt(x, 1805418283);
2262             if (m % 1213 == 0) continue;
2263             if (m % 1217 == 0) continue;
2264             if (m % 1223 == 0) continue;
2265             m = modInt(x, 1871456063);
2266             if (m % 1229 == 0) continue;
2267             if (m % 1231 == 0) continue;
2268             if (m % 1237 == 0) continue;
2269             m = modInt(x, 2008071007);
2270             if (m % 1249 == 0) continue;
2271             if (m % 1259 == 0) continue;
2272             if (m % 1277 == 0) continue;
2273             m = modInt(x, 2115193573);
2274             if (m % 1279 == 0) continue;
2275             if (m % 1283 == 0) continue;
2276             if (m % 1289 == 0) continue;
2277             m = modInt(x, 2178429527);
2278             if (m % 1291 == 0) continue;
2279             if (m % 1297 == 0) continue;
2280             if (m % 1301 == 0) continue;
2281             m = modInt(x, 2246284699);
2282             if (m % 1303 == 0) continue;
2283             if (m % 1307 == 0) continue;
2284             if (m % 1319 == 0) continue;
2285             m = modInt(x, 2385788087);
2286             if (m % 1321 == 0) continue;
2287             if (m % 1327 == 0) continue;
2288             if (m % 1361 == 0) continue;
2289             m = modInt(x, 2591986471);
2290             if (m % 1367 == 0) continue;
2291             if (m % 1373 == 0) continue;
2292             if (m % 1381 == 0) continue;
2293             m = modInt(x, 2805004793);
2294             if (m % 1399 == 0) continue;
2295             if (m % 1409 == 0) continue;
2296             if (m % 1423 == 0) continue;
2297             m = modInt(x, 2922149239);
2298             if (m % 1427 == 0) continue;
2299             if (m % 1429 == 0) continue;
2300             if (m % 1433 == 0) continue;
2301             m = modInt(x, 3021320083);
2302             if (m % 1439 == 0) continue;
2303             if (m % 1447 == 0) continue;
2304             if (m % 1451 == 0) continue;
2305             m = modInt(x, 3118412617);
2306             if (m % 1453 == 0) continue;
2307             if (m % 1459 == 0) continue;
2308             if (m % 1471 == 0) continue;
2309             m = modInt(x, 3265932301);
2310             if (m % 1481 == 0) continue;
2311             if (m % 1483 == 0) continue;
2312             if (m % 1487 == 0) continue;
2313             m = modInt(x, 3332392423);
2314             if (m % 1489 == 0) continue;
2315             if (m % 1493 == 0) continue;
2316             if (m % 1499 == 0) continue;
2317             m = modInt(x, 3523218343);
2318             if (m % 1511 == 0) continue;
2319             if (m % 1523 == 0) continue;
2320             if (m % 1531 == 0) continue;
2321             m = modInt(x, 3711836171);
2322             if (m % 1543 == 0) continue;
2323             if (m % 1549 == 0) continue;
2324             if (m % 1553 == 0) continue;
2325             m = modInt(x, 3837879163);
2326             if (m % 1559 == 0) continue;
2327             if (m % 1567 == 0) continue;
2328             if (m % 1571 == 0) continue;
2329             m = modInt(x, 3991792529);
2330             if (m % 1579 == 0) continue;
2331             if (m % 1583 == 0) continue;
2332             if (m % 1597 == 0) continue;
2333             m = modInt(x, 4139646463);
2334             if (m % 1601 == 0) continue;
2335             if (m % 1607 == 0) continue;
2336             if (m % 1609 == 0) continue;
2337             m = modInt(x, 4233155587);
2338             if (m % 1613 == 0) continue;
2339             if (m % 1619 == 0) continue;
2340             if (m % 1621 == 0) continue;
2341             m = modInt(x, 2663399);
2342             if (m % 1627 == 0) continue;
2343             if (m % 1637 == 0) continue;
2344             m = modInt(x, 2755591);
2345             if (m % 1657 == 0) continue;
2346             if (m % 1663 == 0) continue;
2347             m = modInt(x, 2782223);
2348             if (m % 1667 == 0) continue;
2349             if (m % 1669 == 0) continue;
2350             m = modInt(x, 2873021);
2351             if (m % 1693 == 0) continue;
2352             if (m % 1697 == 0) continue;
2353             m = modInt(x, 2903591);
2354             if (m % 1699 == 0) continue;
2355             if (m % 1709 == 0) continue;
2356             m = modInt(x, 2965283);
2357             if (m % 1721 == 0) continue;
2358             if (m % 1723 == 0) continue;
2359             m = modInt(x, 3017153);
2360             if (m % 1733 == 0) continue;
2361             if (m % 1741 == 0) continue;
2362             m = modInt(x, 3062491);
2363             if (m % 1747 == 0) continue;
2364             if (m % 1753 == 0) continue;
2365             m = modInt(x, 3125743);
2366             if (m % 1759 == 0) continue;
2367             if (m % 1777 == 0) continue;
2368             m = modInt(x, 3186221);
2369             if (m % 1783 == 0) continue;
2370             if (m % 1787 == 0) continue;
2371             m = modInt(x, 3221989);
2372             if (m % 1789 == 0) continue;
2373             if (m % 1801 == 0) continue;
2374             m = modInt(x, 3301453);
2375             if (m % 1811 == 0) continue;
2376             if (m % 1823 == 0) continue;
2377             m = modInt(x, 3381857);
2378             if (m % 1831 == 0) continue;
2379             if (m % 1847 == 0) continue;
2380             m = modInt(x, 3474487);
2381             if (m % 1861 == 0) continue;
2382             if (m % 1867 == 0) continue;
2383             m = modInt(x, 3504383);
2384             if (m % 1871 == 0) continue;
2385             if (m % 1873 == 0) continue;
2386             m = modInt(x, 3526883);
2387             if (m % 1877 == 0) continue;
2388             if (m % 1879 == 0) continue;
2389             m = modInt(x, 3590989);
2390             if (m % 1889 == 0) continue;
2391             if (m % 1901 == 0) continue;
2392             m = modInt(x, 3648091);
2393             if (m % 1907 == 0) continue;
2394             if (m % 1913 == 0) continue;
2395             m = modInt(x, 3732623);
2396             if (m % 1931 == 0) continue;
2397             if (m % 1933 == 0) continue;
2398             m = modInt(x, 3802499);
2399             if (m % 1949 == 0) continue;
2400             if (m % 1951 == 0) continue;
2401             m = modInt(x, 3904567);
2402             if (m % 1973 == 0) continue;
2403             if (m % 1979 == 0) continue;
2404             m = modInt(x, 3960091);
2405             if (m % 1987 == 0) continue;
2406             if (m % 1993 == 0) continue;
2407             m = modInt(x, 3992003);
2408             if (m % 1997 == 0) continue;
2409             if (m % 1999 == 0) continue;
2410              
2411             #line 955 "Condensation/../../c/Condensation/RSA64/Math.inc.c"
2412             KEY_GENERATION_RESET_WATCHDOG();
2413             if (! millerRabin(x, modPowBig)) continue;
2414              
2415             struct cdsBigInteger xme = CDS_BIG_INTEGER_ZERO;
2416             copyD(&xme, x, 0);
2417             mod(&xme, e);
2418             if (isOne(&xme)) continue;
2419              
2420             struct cdsBigInteger x1 = CDS_BIG_INTEGER_ZERO;
2421             copyD(&x1, x, 0);
2422             decrement(&x1);
2423             struct cdsBigInteger e1 = CDS_BIG_INTEGER_ZERO;
2424             copyD(&e1, e, 0);
2425             gcd(&x1, &e1);
2426             if (isOne(&x1)) return;
2427             }
2428             }
2429             }
2430              
2431             static void generateKey(struct cdsRSAPrivateKey * this, struct cdsRSAModPowBig * modPowBig) {
2432             struct cdsBigInteger * e = &this->rsaPublicKey.e;
2433             struct cdsBigInteger * p = &this->p;
2434             struct cdsBigInteger * q = &this->q;
2435             struct cdsBigInteger n = CDS_BIG_INTEGER_ZERO;
2436             struct cdsBigInteger n3 = CDS_BIG_INTEGER_ZERO;
2437              
2438             setUint32(e, 0x10001);
2439             while (true) {
2440             randomPrime1024(p, e, modPowBig);
2441              
2442             while (true) {
2443             randomPrime1024(q, e, modPowBig);
2444              
2445             if (compare(p, q) < 0) {
2446             struct cdsBigInteger * temp = p;
2447             p = q;
2448             q = temp;
2449             }
2450              
2451              
2452             setZero(&n);
2453             mul(&n, p, q);
2454              
2455             if (mostSignificantElement(&n) != elementsFor2048Bits - 1 || (n.values[elementsFor2048Bits - 1] & 0x80000000) == 0) continue;
2456              
2457             break;
2458             }
2459              
2460             setZero(&n3);
2461             addN(&n3, 3, &n, 0);
2462             int nk = elementsFor2048Bits - 1; // == mostSignificantElement(n), a condition for quitting the while loop above
2463             int nafCount = 0;
2464             for (int i = 0; i <= nk; i++) nafCount += bitCount(n.values[i] ^ n3.values[i]);
2465             if (nk + 1 < n3.length) nafCount += bitCount(n3.values[nk + 1]);
2466             if (nafCount < 512) continue;
2467              
2468             break;
2469             }
2470             }
2471              
2472             #line 15 "Condensation/../../c/Condensation/all.inc.c"
2473              
2474             #line 1 "Condensation/../../c/Condensation/RSA64/Encoding.inc.c"
2475             #include
2476              
2477             static const uint16_t emLength = 256; // = 2048 / 8
2478             static const uint16_t hashLength = 32;
2479             static const uint8_t OAEPZeroLabelHash[] = {0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb, 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4, 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52, 0xb8, 0x55};
2480              
2481             static void maskGenerationFunction1(struct cdsBytes seed, struct cdsMutableBytes mask) {
2482             struct cdsSHA256 sha256;
2483             uint8_t counter[4] = {0, 0, 0, 0};
2484             cdsLength blocks = mask.length / 32;
2485             for (cdsLength i = 0; i < blocks; i++) {
2486             counter[3] = i;
2487             cdsInitializeSHA256(&sha256);
2488             cdsAddBytesToSHA256(&sha256, seed);
2489             cdsAddBytesToSHA256(&sha256, cdsBytes(counter, 4));
2490             cdsFinalizeSHA256(&sha256, mask.data + i * 32);
2491             }
2492             }
2493              
2494             static void pssHash(struct cdsBytes digest, struct cdsBytes salt, uint8_t * h) {
2495             uint8_t sequence[8 + 256 + 222];
2496             cdsLength sequenceLength = 8 + digest.length + salt.length;
2497             memset(sequence, 0, 8);
2498             memcpy(sequence + 8, digest.data, digest.length);
2499             memcpy(sequence + 8 + digest.length, salt.data, salt.length);
2500             cdsSHA256(cdsBytes(sequence, sequenceLength), h);
2501             }
2502              
2503             static bool verifyPSS(struct cdsBytes digest, struct cdsBytes pss) {
2504             assert(digest.length <= 256);
2505             assert(pss.length == 256);
2506             const uint8_t * em = pss.data;
2507              
2508             if (em[emLength - 1] != 0xbc) return false;
2509              
2510             uint16_t dbLength = emLength - hashLength - 1; // 223
2511             uint8_t mask[224]; // rounded up to the next multiple of 32
2512             maskGenerationFunction1(cdsBytes(em + (emLength - hashLength - 1), hashLength), cdsMutableBytes(mask, 224));
2513             uint8_t unmasked[224];
2514             for (uint16_t i = 0; i < dbLength; i++) unmasked[i] = em[i] ^ mask[i];
2515              
2516             unmasked[0] &= 0x7f;
2517              
2518             uint16_t n = 0;
2519             while (unmasked[n] == 0 && n < dbLength) n++;
2520              
2521             if (unmasked[n] != 0x01) return false;
2522             n++;
2523              
2524             struct cdsBytes salt = cdsBytes(unmasked + n, dbLength - n);
2525              
2526             uint8_t h[hashLength];
2527             pssHash(digest, salt, h);
2528              
2529             for (uint16_t i = 0; i < 32; i++)
2530             if (h[i] != em[dbLength + i]) return false;
2531              
2532             return true;
2533             }
2534              
2535             static struct cdsBytes generatePSS(struct cdsBytes digest, uint8_t * em) {
2536             assert(digest.length <= 256);
2537             uint16_t dbLength = emLength - hashLength - 1; // 223
2538              
2539             uint8_t saltBuffer[32];
2540             struct cdsBytes salt = cdsRandomBytes(saltBuffer, 32);
2541              
2542             em[emLength - 1] = 0xbc;
2543             pssHash(digest, salt, em + dbLength);
2544              
2545             uint8_t mask[224];
2546             maskGenerationFunction1(cdsBytes(em + dbLength, hashLength), cdsMutableBytes(mask, 224));
2547              
2548             uint16_t n = 0;
2549             for (; n < dbLength - salt.length - 1; n++)
2550             em[n] = mask[n];
2551              
2552             em[n] = 0x01 ^ mask[n];
2553             n++;
2554              
2555             for (uint16_t i = 0; i < salt.length; i++, n++)
2556             em[n] = salt.data[i] ^ mask[n];
2557              
2558             em[0] &= 0x7f;
2559              
2560             return cdsBytes(em, emLength);
2561             }
2562              
2563             static struct cdsBytes encodeOAEP(struct cdsBytes message, uint8_t * em) {
2564             uint16_t dbLength = emLength - hashLength - 1; // 223
2565             uint8_t db[dbLength];
2566             memcpy(db, OAEPZeroLabelHash, 32);
2567             memset(db + 32, 0, dbLength - 32 - message.length - 1);
2568             db[dbLength - message.length - 1] = 0x01;
2569             memcpy(db + (dbLength - message.length), message.data, message.length);
2570              
2571             uint8_t seedBuffer[hashLength];
2572             struct cdsBytes seed = cdsRandomBytes(seedBuffer, hashLength);
2573              
2574             uint8_t dbMask[224];
2575             maskGenerationFunction1(seed, cdsMutableBytes(dbMask, 224));
2576             uint16_t n = hashLength + 1;
2577             for (uint16_t i = 0; i < dbLength; i++, n++)
2578             em[n] = db[i] ^ dbMask[i];
2579              
2580             uint8_t seedMask[hashLength];
2581             maskGenerationFunction1(cdsBytes(em + hashLength + 1, dbLength), cdsMutableBytes(seedMask, hashLength));
2582             em[0] = 0;
2583             n = 1;
2584             for (uint16_t i = 0; i < hashLength; i++, n++)
2585             em[n] = seed.data[i] ^ seedMask[i];
2586              
2587             return cdsBytes(em, emLength);
2588             }
2589              
2590             static struct cdsBytes decodeOAEP(struct cdsBytes oaep, uint8_t * message) {
2591             assert(oaep.length == 256);
2592             const uint8_t * em = oaep.data;
2593              
2594             uint16_t dbLength = emLength - hashLength - 1; // 223
2595             uint8_t seedMask[hashLength];
2596             maskGenerationFunction1(cdsBytes(em + hashLength + 1, dbLength), cdsMutableBytes(seedMask, hashLength));
2597             uint8_t seed[hashLength];
2598             uint16_t n = 1;
2599             for (uint16_t i = 0; i < hashLength; i++, n++)
2600             seed[i] = em[n] ^ seedMask[i];
2601              
2602             uint8_t dbMask[224];
2603             maskGenerationFunction1(cdsBytes(seed, hashLength), cdsMutableBytes(dbMask, 224));
2604              
2605             bool correct = true;
2606              
2607             uint16_t i = 0;
2608             for (; i < 32; n++, i++) {
2609             if (OAEPZeroLabelHash[i] != (em[n] ^ dbMask[i])) correct = false;
2610             }
2611              
2612             for (; em[n] == dbMask[i] && n < emLength; n++) i++;
2613              
2614             if (n >= emLength || (em[n] ^ dbMask[i]) != 0x01) correct = false;
2615             n++;
2616             i++;
2617              
2618             uint16_t messageLength = emLength - n;
2619             for (uint16_t k = 0; n < emLength; n++, i++, k++)
2620             message[k] = em[n] ^ dbMask[i];
2621              
2622             return correct ? cdsBytes(message, messageLength) : cdsEmpty;
2623             }
2624              
2625             #line 16 "Condensation/../../c/Condensation/all.inc.c"
2626              
2627             #line 1 "Condensation/../../c/Condensation/RSA64/PrivateKey.inc.c"
2628              
2629             static void precalculateCrtParameters(struct cdsRSAPrivateKey * this) {
2630             setZero(&this->rsaPublicKey.n);
2631             mul(&this->rsaPublicKey.n, &this->p, &this->q);
2632              
2633             struct cdsBigInteger p1 = CDS_BIG_INTEGER_ZERO;
2634             copyD(&p1, &this->p, 0);
2635             decrement(&p1);
2636              
2637             struct cdsBigInteger q1 = CDS_BIG_INTEGER_ZERO;
2638             copyD(&q1, &this->q, 0);
2639             decrement(&q1);
2640              
2641             struct cdsBigInteger phi = CDS_BIG_INTEGER_ZERO;
2642             mul(&phi, &p1, &q1);
2643              
2644             modInverse(&this->d, &this->rsaPublicKey.e, &phi);
2645              
2646             copyD(&this->dp, &this->d, 0);
2647             mod(&this->dp, &p1);
2648              
2649             copyD(&this->dq, &this->d, 0);
2650             mod(&this->dq, &q1);
2651              
2652             modInverse(&this->pInv, &this->p, &this->q);
2653              
2654             modInverse(&this->qInv, &this->q, &this->p);
2655             }
2656              
2657             void cdsGeneratePrivateKeyWithMemory(struct cdsRSAPrivateKey * this, struct cdsRSAModPowBig * modPowBig) {
2658             generateKey(this, modPowBig);
2659             this->isValid = true;
2660             this->rsaPublicKey.isValid = true;
2661             precalculateCrtParameters(this);
2662             }
2663              
2664             void cdsGeneratePrivateKey(struct cdsRSAPrivateKey * this) {
2665             struct cdsRSAModPowBig modPowBig;
2666             cdsGeneratePrivateKeyWithMemory(this, &modPowBig);
2667             }
2668              
2669             void cdsInitializeEmptyPrivateKey(struct cdsRSAPrivateKey * this) {
2670             this->isValid = false;
2671             this->rsaPublicKey.isValid = false;
2672             }
2673              
2674             void cdsInitializePrivateKey(struct cdsRSAPrivateKey * this, const struct cdsBytes e, const struct cdsBytes p, const struct cdsBytes q) {
2675             cdsBigIntegerFromBytes(&this->rsaPublicKey.e, e);
2676             cdsBigIntegerFromBytes(&this->p, p);
2677             cdsBigIntegerFromBytes(&this->q, q);
2678             this->isValid = ! isZero(&this->rsaPublicKey.e) && mostSignificantElement(&this->p) + 1 == elementsFor1024Bits && mostSignificantElement(&this->q) + 1 == elementsFor1024Bits;
2679             this->rsaPublicKey.isValid = this->isValid;
2680             if (this->isValid) precalculateCrtParameters(this);
2681             }
2682              
2683             static struct cdsBytes privateCrypt(const struct cdsRSAPrivateKey * this, const struct cdsBytes inputBytes, uint8_t * resultBuffer, struct cdsRSAPrivateCryptMemory * memory) {
2684             cdsBigIntegerFromBytes(&memory->input, inputBytes);
2685              
2686             copyD(&memory->imodp, &memory->input, 0);
2687             mod(&memory->imodp, &this->p);
2688             modPowBigExp(&memory->modPowBig, &memory->imodp, &this->dp, &this->p);
2689             modPowBigResult(&memory->modPowBig);
2690             copyD(&memory->mP, memory->modPowBig.result, 0);
2691              
2692             copyD(&memory->imodq, &memory->input, 0);
2693             mod(&memory->imodq, &this->q);
2694             modPowBigExp(&memory->modPowBig, &memory->imodq, &this->dq, &this->q);
2695             modPowBigResult(&memory->modPowBig);
2696             copyD(&memory->mQ, memory->modPowBig.result, 0);
2697              
2698             if (compare(&memory->mP, &memory->mQ) > 0) {
2699             copyD(&memory->difference, &memory->mP, 0);
2700             subD(&memory->difference, &memory->mQ, 0);
2701             setZero(&memory->h);
2702             mul(&memory->h, &this->qInv, &memory->difference);
2703             mod(&memory->h, &this->p);
2704              
2705             copyD(&memory->result, &memory->mQ, 0);
2706             mul(&memory->result, &memory->h, &this->q);
2707             } else {
2708             copyD(&memory->difference, &memory->mQ, 0);
2709             subD(&memory->difference, &memory->mP, 0);
2710             setZero(&memory->h);
2711             mul(&memory->h, &this->pInv, &memory->difference);
2712             mod(&memory->h, &this->q);
2713              
2714             copyD(&memory->result, &memory->mP, 0);
2715             mul(&memory->result, &memory->h, &this->p);
2716             }
2717              
2718             cdsBytesFromBigInteger(cdsMutableBytes(resultBuffer, 256), &memory->result);
2719             return cdsBytes(resultBuffer, 256);
2720             };
2721              
2722             struct cdsBytes cdsSignWithMemory(const struct cdsRSAPrivateKey * this, const struct cdsBytes digest, uint8_t * resultBuffer, struct cdsRSAPrivateCryptMemory * memory) {
2723             uint8_t buffer[256];
2724             struct cdsBytes pss = generatePSS(digest, buffer);
2725              
2726             return privateCrypt(this, pss, resultBuffer, memory);
2727             };
2728              
2729             struct cdsBytes cdsSign(const struct cdsRSAPrivateKey * this, const struct cdsBytes digest, uint8_t * resultBuffer) {
2730             struct cdsRSAPrivateCryptMemory memory;
2731             return cdsSignWithMemory(this, digest, resultBuffer, &memory);
2732             }
2733              
2734             struct cdsBytes cdsDecryptWithMemory(const struct cdsRSAPrivateKey * this, const struct cdsBytes encrypted, uint8_t * resultBuffer, struct cdsRSAPrivateCryptMemory * memory) {
2735             uint8_t buffer[256];
2736             struct cdsBytes oaep = privateCrypt(this, encrypted, buffer, memory);
2737              
2738             return decodeOAEP(oaep, resultBuffer);
2739             };
2740              
2741             struct cdsBytes cdsDecrypt(const struct cdsRSAPrivateKey * this, const struct cdsBytes encrypted, uint8_t * resultBuffer) {
2742             struct cdsRSAPrivateCryptMemory memory;
2743             return cdsDecryptWithMemory(this, encrypted, resultBuffer, &memory);
2744             }
2745              
2746              
2747             #line 17 "Condensation/../../c/Condensation/all.inc.c"
2748              
2749             #line 1 "Condensation/../../c/Condensation/RSA64/PublicKey.inc.c"
2750              
2751             void cdsInitializeEmptyPublicKey(struct cdsRSAPublicKey * this) {
2752             this->isValid = false;
2753             }
2754              
2755             void cdsInitializePublicKey(struct cdsRSAPublicKey * this, const struct cdsBytes e, const struct cdsBytes n) {
2756             cdsBigIntegerFromBytes(&this->e, e);
2757             cdsBigIntegerFromBytes(&this->n, n);
2758             this->isValid = ! isZero(&this->e) && mostSignificantElement(&this->n) + 1 == elementsFor2048Bits;
2759             }
2760              
2761             static struct cdsBytes publicCrypt(const struct cdsRSAPublicKey * this, const struct cdsBytes inputBytes, uint8_t * resultBuffer, struct cdsRSAPublicCryptMemory * memory) {
2762             cdsBigIntegerFromBytes(&memory->input, inputBytes);
2763              
2764             modPowSmallExp(&memory->modPowSmall, &memory->input, &this->e, &this->n);
2765              
2766             cdsBytesFromBigInteger(cdsMutableBytes(resultBuffer, 256), memory->modPowSmall.result);
2767             return cdsBytes(resultBuffer, 256);
2768             }
2769              
2770             bool cdsVerifyWithMemory(const struct cdsRSAPublicKey * this, const struct cdsBytes digest, const struct cdsBytes signature, struct cdsRSAPublicCryptMemory * memory) {
2771             uint8_t buffer[256];
2772             struct cdsBytes pss = publicCrypt(this, signature, buffer, memory);
2773              
2774             return verifyPSS(digest, pss);
2775             }
2776              
2777             bool cdsVerify(const struct cdsRSAPublicKey * this, const struct cdsBytes digest, const struct cdsBytes signature) {
2778             struct cdsRSAPublicCryptMemory memory;
2779             return cdsVerifyWithMemory(this, digest, signature, &memory);
2780             }
2781              
2782             struct cdsBytes cdsEncryptWithMemory(const struct cdsRSAPublicKey * this, const struct cdsBytes message, uint8_t * resultBuffer, struct cdsRSAPublicCryptMemory * memory) {
2783             uint8_t buffer[256];
2784             struct cdsBytes oaep = encodeOAEP(message, buffer);
2785              
2786             return publicCrypt(this, oaep, resultBuffer, memory);
2787             }
2788              
2789             struct cdsBytes cdsEncrypt(const struct cdsRSAPublicKey * this, const struct cdsBytes message, uint8_t * resultBuffer) {
2790             struct cdsRSAPublicCryptMemory memory;
2791             return cdsEncryptWithMemory(this, message, resultBuffer, &memory);
2792             }
2793              
2794             #line 18 "Condensation/../../c/Condensation/all.inc.c"
2795              
2796              
2797             #line 1 "Condensation/../../c/Condensation/Serialization/Hash.inc.c"
2798             struct cdsHash invalidHashForDebugging = {{0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x20, 0x48, 0x41, 0x53, 0x48, 0x20, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x20, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x20, 0x48, 0x41, 0x53, 0x48, 0x20}};
2799              
2800             struct cdsHash cdsHash(const uint8_t * bytes) {
2801             struct cdsHash hash;
2802             memcpy(hash.bytes, bytes, 32);
2803             return hash;
2804             }
2805              
2806             struct cdsHash cdsHashFromBytes(const struct cdsBytes hashBytes) {
2807             struct cdsHash hash;
2808             if (hashBytes.length >= 32)
2809             memcpy(hash.bytes, hashBytes.data, 32);
2810             else
2811             memset(hash.bytes, 0, 32);
2812             return hash;
2813             }
2814              
2815             struct cdsHash cdsHashFromBytesAtOffset(const struct cdsBytes hashBytes, cdsLength offset) {
2816             struct cdsHash hash;
2817             if (hashBytes.length >= offset + 32)
2818             memcpy(hash.bytes, hashBytes.data + offset, 32);
2819             else
2820             memset(hash.bytes, 0, 32);
2821             return hash;
2822             }
2823              
2824             struct cdsHash cdsHashFromHex(const char * hashHex) {
2825             struct cdsHash hash;
2826             cdsBytesFromHex(hashHex, hash.bytes, 32);
2827             return hash;
2828             }
2829              
2830             struct cdsHash cdsCalculateHash(const struct cdsBytes bytes) {
2831             struct cdsHash hash;
2832             cdsSHA256(bytes, hash.bytes);
2833             return hash;
2834             }
2835              
2836             char * cdsToHex(struct cdsHash * this, char * buffer, cdsLength length) {
2837             return cdsHexFromBytes(cdsBytes(this->bytes, 32), buffer, length);
2838             }
2839              
2840             char * cdsToShortHex(struct cdsHash * this, char * buffer, cdsLength length) {
2841             cdsHexFromBytes(cdsBytes(this->bytes, 4), buffer, length);
2842             if (length < 12) return buffer;
2843             buffer[8] = 0xe2;
2844             buffer[9] = 0x80;
2845             buffer[10] = 0xa6;
2846             buffer[11] = 0;
2847             return buffer;
2848             }
2849              
2850             struct cdsBytes cdsHashBytes(struct cdsHash * this) {
2851             return cdsBytes(this->bytes, 32);
2852             }
2853              
2854             bool cdsEqualHashes(const struct cdsHash * this, const struct cdsHash * that) {
2855             return memcmp(this->bytes, that->bytes, 32) == 0;
2856             }
2857              
2858             int cdsCompareHashes(const struct cdsHash * this, const struct cdsHash * that) {
2859             return memcmp(this->bytes, that->bytes, 32);
2860             }
2861              
2862             #line 20 "Condensation/../../c/Condensation/all.inc.c"
2863              
2864             #line 1 "Condensation/../../c/Condensation/Serialization/HashAndKey.inc.c"
2865             void cdsInitializeEmptyHashAndKey(struct cdsHashAndKey * this) {
2866             this->key = cdsEmpty;
2867             }
2868              
2869             void cdsInitializeHashAndKey(struct cdsHashAndKey * this, struct cdsHash * hash, struct cdsBytes key) {
2870             memcpy(this->hash.bytes, hash->bytes, 32);
2871             if (key.length >= 32)
2872             memcpy(this->keyBytes, key.data, 32);
2873             else
2874             memset(this->keyBytes, 0, 32);
2875             this->key = cdsBytes(this->keyBytes, 32);
2876             }
2877              
2878             #line 21 "Condensation/../../c/Condensation/all.inc.c"
2879              
2880             #line 1 "Condensation/../../c/Condensation/Serialization/Object.inc.c"
2881             void cdsInitializeEmptyObject(struct cdsObject * this) {
2882             this->bytes = cdsEmpty;
2883             this->hashesCount = 0;
2884             this->header = cdsEmpty;
2885             this->data = cdsEmpty;
2886             }
2887              
2888             void cdsInitializeObject(struct cdsObject * this, const struct cdsBytes bytes) {
2889             if (bytes.length < 4) return cdsInitializeEmptyObject(this);
2890              
2891             this->hashesCount = cdsGetUint32BE(bytes.data);
2892             cdsLength dataStart = (cdsLength) this->hashesCount * 32 + 4;
2893             if (dataStart > bytes.length) return cdsInitializeEmptyObject(this);
2894              
2895             this->bytes = bytes;
2896             this->header = cdsByteSlice(bytes, 0, dataStart);
2897             this->data = cdsByteSlice(bytes, dataStart, bytes.length - dataStart);
2898             }
2899              
2900             bool cdsIsValidObject(struct cdsObject * this) {
2901             return this->bytes.length >= 4;
2902             }
2903              
2904             void cdsInitializeCryptedObject(struct cdsObject * this, const struct cdsMutableBytes bytes, const struct cdsBytes key) {
2905             cdsInitializeObject(this, cdsSeal(bytes));
2906             if (! cdsIsValidObject(this)) return;
2907              
2908             struct cdsAES256 aes;
2909             cdsInitializeAES256(&aes, key);
2910             cdsLength dataStart = (cdsLength) this->hashesCount * 32 + 4;
2911             cdsCrypt(&aes, this->data, cdsZeroCtr, bytes.data + dataStart);
2912             }
2913              
2914             cdsLength cdsObjectByteLength(const struct cdsObject * this) {
2915             return this->bytes.length;
2916             }
2917              
2918             struct cdsHash cdsCalculateObjectHash(const struct cdsObject * this) {
2919             return cdsCalculateHash(this->bytes);
2920             }
2921              
2922             struct cdsHash cdsHashAtIndex(const struct cdsObject * this, uint32_t index) {
2923             if (index >= this->hashesCount) return invalidHashForDebugging;
2924             return cdsHashFromBytesAtOffset(this->bytes, (cdsLength) index * 32 + 4);
2925             }
2926              
2927             void withObjectHashes(const struct cdsObject * this, cdsHashCallback hashCallback) {
2928             for (uint32_t i = 0; i < this->hashesCount; i++)
2929             hashCallback(cdsHashAtIndex(this, i));
2930             }
2931              
2932             #line 22 "Condensation/../../c/Condensation/all.inc.c"
2933              
2934             #line 1 "Condensation/../../c/Condensation/Serialization/Record.inc.c"
2935             struct cdsRecord cdsEmptyRecord = {{NULL, 0}, NULL, NULL, NULL};
2936              
2937             struct cdsRecord * cdsChild(struct cdsRecord * this, struct cdsBytes bytes) {
2938             struct cdsRecord * child = this->firstChild;
2939             while (child) {
2940             if (cdsEqualBytes(child->bytes, bytes)) return child;
2941             child = child->nextSibling;
2942             }
2943              
2944             return &cdsEmptyRecord;
2945             }
2946              
2947             struct cdsRecord * cdsChildWithText(struct cdsRecord * this, const char * text) {
2948             return cdsChild(this, cdsBytesFromText(text));
2949             }
2950              
2951             bool cdsContainsChild(struct cdsRecord * this, struct cdsBytes bytes) {
2952             struct cdsRecord * child = this->firstChild;
2953             while (child) {
2954             if (cdsEqualBytes(child->bytes, bytes)) return true;
2955             child = child->nextSibling;
2956             }
2957              
2958             return false;
2959             }
2960              
2961             bool cdsContainsChildWithText(struct cdsRecord * this, char * text) {
2962             return cdsContainsChild(this, cdsBytesFromText(text));
2963             }
2964              
2965             struct cdsRecord * cdsFirstChild(struct cdsRecord * this) {
2966             if (this->firstChild) return this->firstChild;
2967             return &cdsEmptyRecord;
2968             }
2969              
2970             int cdsAsText(struct cdsRecord * this, char * buffer, int length) {
2971             if (length <= 0) return 0;
2972             size_t textLength = minSize(this->bytes.length, (size_t) length - 1);
2973             memcpy(buffer, this->bytes.data, textLength);
2974             buffer[textLength] = 0;
2975             return textLength;
2976             }
2977              
2978             bool cdsAsBoolean(struct cdsRecord * this) {
2979             return this->bytes.length > 0;
2980             }
2981              
2982             int64_t cdsAsInteger64(struct cdsRecord * this) {
2983             if (this->bytes.length == 0) return 0;
2984              
2985             int64_t value = (int64_t) this->bytes.data[0];
2986             if ((value & 0x80) > 0) value -= 256;
2987             for (cdsLength i = 1; i < this->bytes.length; i++)
2988             value = (value << 8) + ((int64_t) this->bytes.data[i]);
2989              
2990             return value;
2991             }
2992              
2993             uint64_t cdsAsUnsigned64(struct cdsRecord * this) {
2994             uint64_t value = 0;
2995             for (cdsLength i = 0; i < this->bytes.length; i++)
2996             value = (value << 8) + ((uint64_t) this->bytes.data[i]);
2997             return value;
2998             }
2999              
3000             int32_t cdsAsInteger(struct cdsRecord * this) {
3001             int64_t value = cdsAsInteger64(this);
3002             if (value < -2147483648) return -2147483648;
3003             if (value > 2147483647) return 2147483647;
3004             return (int32_t) value;
3005             }
3006              
3007             uint32_t cdsAsUnsigned(struct cdsRecord * this) {
3008             uint64_t value = cdsAsUnsigned64(this);
3009             if (value > 0xffffffff) return 0xffffffff;
3010             return (uint32_t) value;
3011             }
3012              
3013             bool cdsAsHash(struct cdsRecord * this, struct cdsHash * hash) {
3014             if (this->hash == NULL) return false;
3015             memcpy(hash->bytes, this->hash, 32);
3016             return true;
3017             }
3018              
3019             bool cdsAsHashAndKey(struct cdsRecord * this, struct cdsHashAndKey * hashAndKey) {
3020             if (this->bytes.length != 32) return false;
3021             if (this->hash == NULL) return false;
3022              
3023             memcpy(hashAndKey->hash.bytes, this->hash, 32);
3024             memcpy(hashAndKey->keyBytes, this->bytes.data, 32);
3025             hashAndKey->key = cdsBytes(hashAndKey->keyBytes, 32);
3026             return true;
3027             }
3028              
3029             void cdsAsBigInteger(struct cdsRecord * this, struct cdsBigInteger * bigInteger) {
3030             cdsBigIntegerFromBytes(bigInteger, this->bytes);
3031             }
3032              
3033             struct cdsBytes cdsBytesValue(struct cdsRecord * this) {
3034             if (! this->firstChild) return cdsEmpty;
3035             return this->firstChild->bytes;
3036             }
3037              
3038             int cdsTextValue(struct cdsRecord * this, char * buffer, int length) {
3039             if (! this->firstChild) {
3040             if (length > 0) buffer[0] = 0;
3041             return 0;
3042             }
3043              
3044             return cdsAsText(this->firstChild, buffer, length);
3045             }
3046              
3047             bool cdsBooleanValue(struct cdsRecord * this) {
3048             if (! this->firstChild) return false;
3049             return cdsAsBoolean(this->firstChild);
3050             }
3051              
3052             int32_t cdsIntegerValue(struct cdsRecord * this) {
3053             if (! this->firstChild) return 0;
3054             return cdsAsInteger(this->firstChild);
3055             }
3056              
3057             uint32_t cdsUnsignedValue(struct cdsRecord * this) {
3058             if (! this->firstChild) return 0U;
3059             return cdsAsUnsigned(this->firstChild);
3060             }
3061              
3062             int64_t cdsInteger64Value(struct cdsRecord * this) {
3063             if (! this->firstChild) return 0L;
3064             return cdsAsInteger64(this->firstChild);
3065             }
3066              
3067             uint64_t cdsUnsigned64Value(struct cdsRecord * this) {
3068             if (! this->firstChild) return 0UL;
3069             return cdsAsUnsigned64(this->firstChild);
3070             }
3071              
3072             bool cdsHashValue(struct cdsRecord * this, struct cdsHash * hash) {
3073             if (! this->firstChild) return false;
3074             return cdsAsHash(this->firstChild, hash);
3075             }
3076              
3077             bool cdsHashAndKeyValue(struct cdsRecord * this, struct cdsHashAndKey * hashAndKey) {
3078             if (! this->firstChild) return false;
3079             return cdsAsHashAndKey(this->firstChild, hashAndKey);
3080             }
3081              
3082             void cdsBigIntegerValue(struct cdsRecord * this, struct cdsBigInteger * bigInteger) {
3083             if (! this->firstChild) cdsBigIntegerFromBytes(bigInteger, cdsEmpty);
3084             cdsAsBigInteger(this->firstChild, bigInteger);
3085             }
3086              
3087             #line 23 "Condensation/../../c/Condensation/all.inc.c"
3088              
3089             #line 1 "Condensation/../../c/Condensation/Serialization/RecordBuilder.inc.c"
3090             void cdsInitializeEmptyRecordBuilder(struct cdsRecordBuilder * this) {
3091             this->bytes = cdsMutableBytes(NULL, 0);
3092             this->dataOffset = 0;
3093             this->used = 0;
3094             this->hashesUsed = 0;
3095             this->levelPositions[0] = 0;
3096             this->level = 0;
3097             this->nextIsChild = 0;
3098             }
3099              
3100             void cdsInitializeRecordBuilder(struct cdsRecordBuilder * this, struct cdsMutableBytes bytes, uint32_t hashesCount) {
3101             this->bytes = bytes;
3102             cdsSetUint32BE(bytes.data, hashesCount);
3103             this->dataOffset = 4 + hashesCount * 32;
3104             this->used = this->dataOffset;
3105             this->hashesUsed = 0;
3106             this->levelPositions[0] = 0;
3107             this->level = 0;
3108             this->nextIsChild = 0;
3109             }
3110              
3111             cdsLength cdsRecordLength(cdsLength length) {
3112             return (length < 30 ? 1 : length < 255 + 30 ? 2 : 9) + length;
3113             }
3114              
3115             cdsLength cdsRecordWithHashLength(cdsLength length) {
3116             return cdsRecordLength(length) + 36;
3117             }
3118              
3119             struct cdsMutableBytes cdsAddRecord(struct cdsRecordBuilder * this, cdsLength length) {
3120             if (this->used + 9 + length > this->bytes.length) return cdsMutableBytes(NULL, 0);
3121              
3122             if (this->nextIsChild && this->level < CDS_MAX_RECORD_DEPTH - 1) {
3123             this->nextIsChild -= 1;
3124             this->bytes.data[this->levelPositions[this->level]] |= 0b01000000;
3125             this->level += 1;
3126             } else if (this->level == 0) {
3127             this->level = 1;
3128             } else {
3129             this->bytes.data[this->levelPositions[this->level]] |= 0b10000000;
3130             }
3131              
3132             this->levelPositions[this->level] = this->used;
3133              
3134             if (length < 30) {
3135             this->bytes.data[this->used] = length;
3136             this->used += 1;
3137             } else if (length < 255 + 30) {
3138             this->bytes.data[this->used] = 30;
3139             this->used += 1;
3140             this->bytes.data[this->used] = length - 30;
3141             this->used += 1;
3142             } else {
3143             this->bytes.data[this->used] = 31;
3144              
3145             cdsLength value = length;
3146             for (cdsLength i = 0; i < 8; i++) {
3147             this->bytes.data[this->used + 8 - i] = value & 0xff;
3148             value >>= 8;
3149             }
3150              
3151             this->used += 9;
3152             }
3153              
3154             struct cdsMutableBytes slice = cdsMutableByteSlice(this->bytes, this->used, length);
3155             this->used += length;
3156             return slice;
3157             }
3158              
3159             void cdsStartChildren(struct cdsRecordBuilder * this) {
3160             this->nextIsChild += 1;
3161             }
3162              
3163             void cdsEndChildren(struct cdsRecordBuilder * this) {
3164             if (this->nextIsChild) {
3165             this->nextIsChild -= 1;
3166             return;
3167             }
3168              
3169             if (this->level)
3170             this->level -= 1;
3171             }
3172              
3173             void cdsEndRecord(struct cdsRecordBuilder * this) {
3174             this->nextIsChild = 0;
3175             this->level = 0;
3176             }
3177              
3178             void cdsAppendHash(struct cdsRecordBuilder * this, struct cdsHash hash) {
3179             if (this->used + 4 > this->bytes.length) return;
3180             if (this->level < 0) return;
3181             this->bytes.data[this->levelPositions[this->level]] |= 0b00100000;
3182             cdsSetUint32BE(this->bytes.data + this->used, this->hashesUsed);
3183             this->used += 4;
3184             cdsSetBytes(this->bytes, 4 + 32 * this->hashesUsed, cdsBytes(hash.bytes, 32));
3185             this->hashesUsed += 1;
3186             }
3187              
3188             struct cdsMutableBytes cdsAddBytes(struct cdsRecordBuilder * this, struct cdsBytes bytes) {
3189             struct cdsMutableBytes slice = cdsAddRecord(this, bytes.length);
3190             cdsSetBytes(slice, 0, bytes);
3191             return slice;
3192             }
3193              
3194             struct cdsMutableBytes cdsAddText(struct cdsRecordBuilder * this, const char * text) {
3195             struct cdsBytes bytes = cdsBytesFromText(text);
3196             struct cdsMutableBytes slice = cdsAddRecord(this, bytes.length);
3197             cdsSetBytes(slice, 0, bytes);
3198             return slice;
3199             }
3200              
3201             struct cdsMutableBytes cdsAddText2(struct cdsRecordBuilder * this, const char * text1, const char * text2) {
3202             struct cdsBytes bytes1 = cdsBytesFromText(text1);
3203             struct cdsBytes bytes2 = cdsBytesFromText(text2);
3204              
3205             struct cdsMutableBytes slice = cdsAddRecord(this, bytes1.length + bytes2.length);
3206             cdsSetBytes(slice, 0, bytes1);
3207             cdsSetBytes(slice, bytes1.length, bytes2);
3208             return slice;
3209             }
3210              
3211             void cdsAddInteger(struct cdsRecordBuilder * this, int32_t value) {
3212             uint8_t bytes[4];
3213             cdsLength length = 0;
3214              
3215             if (value < 0) {
3216             while (length < 4) {
3217             bytes[3 - length] = value & 0xff;
3218             length++;
3219             if (value >= -128) break;
3220             value >>= 8;
3221             }
3222             } else {
3223             while (length < 4) {
3224             bytes[3 - length] = value & 0xff;
3225             length++;
3226             if (value <= 127) break;
3227             value >>= 8;
3228             }
3229             }
3230              
3231             cdsAddBytes(this, cdsBytes(bytes + 4 - length, length));
3232             }
3233              
3234             void cdsAddUnsigned(struct cdsRecordBuilder * this, uint32_t value) {
3235             uint8_t bytes[4];
3236             cdsLength length = 0;
3237              
3238             while (length < 4) {
3239             if (value == 0) break;
3240             bytes[3 - length] = value & 0xff;
3241             length++;
3242             value >>= 8;
3243             }
3244              
3245             cdsAddBytes(this, cdsBytes(bytes + 4 - length, length));
3246             }
3247              
3248             void cdsAddInteger64(struct cdsRecordBuilder * this, int64_t value) {
3249             uint8_t bytes[8];
3250             cdsLength length = 0;
3251              
3252             if (value < 0) {
3253             while (length < 8) {
3254             bytes[7 - length] = value & 0xff;
3255             length++;
3256             if (value >= -128) break;
3257             value >>= 8;
3258             }
3259             } else {
3260             while (length < 8) {
3261             bytes[7 - length] = value & 0xff;
3262             length++;
3263             if (value <= 127) break;
3264             value >>= 8;
3265             }
3266             }
3267              
3268             cdsAddBytes(this, cdsBytes(bytes + 8 - length, length));
3269             }
3270              
3271             void cdsAddUnsigned64(struct cdsRecordBuilder * this, uint64_t value) {
3272             uint8_t bytes[8];
3273             cdsLength length = 0;
3274              
3275             while (length < 8) {
3276             if (value == 0) break;
3277             bytes[7 - length] = value & 0xff;
3278             length++;
3279             value >>= 8;
3280             }
3281              
3282             cdsAddBytes(this, cdsBytes(bytes + 8 - length, length));
3283             }
3284              
3285             void cdsAddBigInteger(struct cdsRecordBuilder * this, struct cdsBigInteger * value) {
3286             uint8_t bytes[256];
3287             cdsAddBytes(this, cdsBytesFromBigInteger(cdsMutableBytes(bytes, 256), value));
3288             }
3289              
3290             void cdsAddFloat32(struct cdsRecordBuilder * this, float value) {
3291             struct cdsMutableBytes slice = cdsAddRecord(this, 4);
3292             cdsSetFloat32BE(slice.data, value);
3293             }
3294              
3295             void cdsAddFloat64(struct cdsRecordBuilder * this, double value) {
3296             struct cdsMutableBytes slice = cdsAddRecord(this, 8);
3297             cdsSetFloat64BE(slice.data, value);
3298             }
3299              
3300             struct cdsBytes cdsToObject(struct cdsRecordBuilder * this) {
3301             return cdsByteSlice(cdsSeal(this->bytes), 0, this->used);
3302             }
3303              
3304             struct cdsMutableBytes cdsUsedBytes(struct cdsRecordBuilder * this) {
3305             return cdsMutableByteSlice(this->bytes, 0, this->used);
3306             }
3307              
3308             struct cdsBytes cdsToCryptedObject(struct cdsRecordBuilder * this, struct cdsBytes key) {
3309             struct cdsAES256 aes;
3310             cdsInitializeAES256(&aes, key);
3311             cdsCrypt(&aes, cdsByteSlice(cdsSeal(this->bytes), this->dataOffset, this->used - this->dataOffset), cdsZeroCtr, this->bytes.data + this->dataOffset);
3312             return cdsByteSlice(cdsSeal(this->bytes), 0, this->used);
3313             }
3314              
3315             #line 24 "Condensation/../../c/Condensation/all.inc.c"
3316              
3317             #line 1 "Condensation/../../c/Condensation/Serialization/RecordParser.inc.c"
3318             struct cdsRecord * cdsParseRecord(const struct cdsBytes bytes, struct cdsRecord * records, int length) {
3319             records[0].bytes = cdsEmpty;
3320             records[0].hash = NULL;
3321             records[0].nextSibling = NULL;
3322             records[0].firstChild = NULL;
3323              
3324             uint32_t hashesCount = cdsGetUint32BE(bytes.data);
3325             cdsLength pos = 4 + (cdsLength) hashesCount * 32;
3326             if (pos > bytes.length) return records;
3327              
3328             int usedRecords = 1;
3329             int level = 1;
3330             struct cdsRecord * lastSibling[CDS_MAX_RECORD_DEPTH] = {records, NULL, };
3331             bool hasMoreSiblings[CDS_MAX_RECORD_DEPTH] = {true, };
3332              
3333             while (pos < bytes.length) {
3334             int flags = bytes.data[pos];
3335             pos += 1;
3336              
3337             uint64_t byteLength = flags & 0x1f;
3338             if (byteLength == 30) {
3339             if (pos + 1 > bytes.length) break;
3340             byteLength = 30U + bytes.data[pos];
3341             pos += 1;
3342             } else if (byteLength == 31) {
3343             if (pos + 8 > bytes.length) break;
3344             byteLength = cdsGetUint64BE(bytes.data + pos);
3345             pos += 8;
3346             }
3347              
3348             if (pos + byteLength > bytes.length) break;
3349             records[usedRecords].bytes = cdsByteSlice(bytes, pos, byteLength);
3350             pos += byteLength;
3351              
3352             if (flags & 0x20) {
3353             if (pos + 4 > bytes.length) break;
3354             uint32_t hashIndex = cdsGetUint32BE(bytes.data + pos);
3355             pos += 4;
3356             if (hashIndex > hashesCount) break;
3357             records[usedRecords].hash = bytes.data + 4 + hashIndex * 32;
3358             } else {
3359             records[usedRecords].hash = NULL;
3360             }
3361              
3362             records[usedRecords].firstChild = NULL;
3363             records[usedRecords].nextSibling = NULL;
3364              
3365             if (lastSibling[level])
3366             lastSibling[level]->nextSibling = records + usedRecords;
3367             else
3368             lastSibling[level - 1]->firstChild = records + usedRecords;
3369              
3370             lastSibling[level] = records + usedRecords;
3371             hasMoreSiblings[level] = flags & 0x80 ? true : false;
3372              
3373             if (flags & 0x40) {
3374             level += 1;
3375             if (level >= 64) break;
3376             lastSibling[level] = NULL;
3377             } else {
3378             while (! hasMoreSiblings[level])
3379             level -= 1;
3380             }
3381              
3382             usedRecords += 1;
3383             if (usedRecords >= length) break;
3384              
3385             if (level == 0) break;
3386             }
3387              
3388             return records;
3389             }
3390              
3391             #line 25 "Condensation/../../c/Condensation/all.inc.c"
3392              
3393              
3394             #line 1 "Condensation/../../c/Condensation/Actors/PrivateKey.inc.c"
3395             struct cdsBytes cdsPrivateKeyFromBytes(struct cdsRSAPrivateKey * this, const struct cdsBytes bytes) {
3396             this->isValid = false;
3397              
3398             struct cdsRecord records[16];
3399             struct cdsRecord * root = cdsParseRecord(bytes, records, 16);
3400              
3401             struct cdsRecord * rsaKey = cdsChildWithText(root, "rsa key");
3402             struct cdsBytes e = cdsBytesValue(cdsChildWithText(rsaKey, "e"));
3403             struct cdsBytes p = cdsBytesValue(cdsChildWithText(rsaKey, "p"));
3404             struct cdsBytes q = cdsBytesValue(cdsChildWithText(rsaKey, "q"));
3405             cdsInitializePrivateKey(this, e, p, q);
3406             if (! this->isValid) return cdsEmpty;
3407              
3408             struct cdsBytes publicKeyObjectBytes = cdsBytesValue(cdsChildWithText(root, "public key object"));
3409             if (publicKeyObjectBytes.length > 500) return cdsEmpty;
3410             if (publicKeyObjectBytes.length < 100) return cdsEmpty;
3411              
3412             struct cdsObject publicKeyObject;
3413             cdsInitializeObject(&publicKeyObject, publicKeyObjectBytes);
3414             if (publicKeyObject.bytes.length == 0) return cdsEmpty;
3415              
3416             return publicKeyObjectBytes;
3417             }
3418              
3419             struct cdsBytes cdsSerializePrivateKey(struct cdsRSAPrivateKey * this, struct cdsBytes publicKeyObjectBytes, struct cdsMutableBytes bytes) {
3420             struct cdsRecordBuilder builder;
3421             cdsInitializeRecordBuilder(&builder, bytes, 0);
3422              
3423             cdsAddText(&builder, "public key object");
3424             cdsStartChildren(&builder);
3425             cdsAddBytes(&builder, publicKeyObjectBytes);
3426             cdsEndChildren(&builder);
3427              
3428             cdsAddText(&builder, "rsa key");
3429             cdsStartChildren(&builder);
3430              
3431             cdsAddText(&builder, "e");
3432             cdsStartChildren(&builder);
3433             cdsAddBigInteger(&builder, &this->rsaPublicKey.e);
3434             cdsEndChildren(&builder);
3435              
3436             cdsAddText(&builder, "p");
3437             cdsStartChildren(&builder);
3438             cdsAddBigInteger(&builder, &this->p);
3439             cdsEndChildren(&builder);
3440              
3441             cdsAddText(&builder, "q");
3442             cdsStartChildren(&builder);
3443             cdsAddBigInteger(&builder, &this->q);
3444             cdsEndChildren(&builder);
3445              
3446             cdsEndChildren(&builder);
3447             return cdsToObject(&builder);
3448             }
3449              
3450             #line 27 "Condensation/../../c/Condensation/all.inc.c"
3451              
3452             #line 1 "Condensation/../../c/Condensation/Actors/PublicKey.inc.c"
3453             bool cdsPublicKeyFromBytes(struct cdsRSAPublicKey * this, const struct cdsBytes bytes) {
3454             if (bytes.length > 500) return false;
3455             if (bytes.length < 100) return false;
3456              
3457             struct cdsRecord records[16];
3458             struct cdsRecord * root = cdsParseRecord(bytes, records, 16);
3459             struct cdsBytes e = cdsBytesValue(cdsChildWithText(root, "e"));
3460             struct cdsBytes n = cdsBytesValue(cdsChildWithText(root, "n"));
3461             cdsInitializePublicKey(this, e, n);
3462             return this->isValid;
3463             }
3464              
3465             struct cdsBytes cdsSerializePublicKey(struct cdsRSAPublicKey * this, struct cdsMutableBytes bytes) {
3466             struct cdsRecordBuilder builder;
3467             cdsInitializeRecordBuilder(&builder, bytes, 0);
3468              
3469             cdsAddText(&builder, "e");
3470             cdsStartChildren(&builder);
3471             cdsAddBigInteger(&builder, &this->e);
3472             cdsEndChildren(&builder);
3473              
3474             cdsAddText(&builder, "n");
3475             cdsStartChildren(&builder);
3476             cdsAddBigInteger(&builder, &this->n);
3477             cdsEndChildren(&builder);
3478              
3479             return cdsToObject(&builder);
3480             }
3481              
3482             #line 28 "Condensation/../../c/Condensation/all.inc.c"
3483              
3484             #line 8 "Condensation/C.inc.c"
3485              
3486             static struct cdsBytes bytesFromSV(SV * sv) {
3487             if (! SvPOK(sv)) return cdsEmpty;
3488             return cdsBytes((const uint8_t *) SvPVX(sv), SvCUR(sv));
3489             }
3490              
3491             static SV * svFromBytes(struct cdsBytes bytes) {
3492             return newSVpvn((const char *) bytes.data, bytes.length);
3493             }
3494              
3495             static SV * svFromBigInteger(struct cdsBigInteger * bigInteger) {
3496             uint8_t buffer[256];
3497             struct cdsBytes bytes = cdsBytesFromBigInteger(cdsMutableBytes(buffer, 256), bigInteger);
3498             return newSVpvn((const char *) bytes.data, bytes.length);
3499             }
3500              
3501              
3502             SV * randomBytes(SV * svCount) {
3503             int count = SvIV(svCount);
3504             if (count > 256) count = 256;
3505             if (count < 0) count = 0;
3506             uint8_t buffer[256];
3507             return svFromBytes(cdsRandomBytes(buffer, count));
3508             }
3509              
3510              
3511             SV * sha256(SV * svBytes) {
3512             uint8_t buffer[32];
3513             struct cdsBytes hash = cdsSHA256(bytesFromSV(svBytes), buffer);
3514             return svFromBytes(hash);
3515             }
3516              
3517              
3518             SV * aesCrypt(SV * svBytes, SV * svKey, SV * svStartCounter) {
3519             struct cdsBytes bytes = bytesFromSV(svBytes);
3520             struct cdsBytes key = bytesFromSV(svKey);
3521             if (key.length != 32) return &PL_sv_undef;
3522             struct cdsBytes startCounter = bytesFromSV(svStartCounter);
3523             if (startCounter.length != 16) return &PL_sv_undef;
3524              
3525             SV * svResult = newSV(bytes.length < 1 ? 1 : bytes.length); // newSV(0) has different semantics
3526             struct cdsAES256 aes;
3527             cdsInitializeAES256(&aes, key);
3528             cdsCrypt(&aes, bytes, startCounter, (uint8_t *) SvPVX(svResult));
3529              
3530             SvPOK_only(svResult);
3531             SvCUR_set(svResult, bytes.length);
3532             return svResult;
3533             }
3534              
3535             SV * counterPlusInt(SV * svCounter, SV * svAdd) {
3536             struct cdsBytes counter = bytesFromSV(svCounter);
3537             if (counter.length != 16) return &PL_sv_undef;
3538             int add = SvIV(svAdd);
3539              
3540             uint8_t buffer[16];
3541             struct cdsMutableBytes result = cdsMutableBytes(buffer, 16);
3542             for (int i = 15; i >= 0; i--) {
3543             add += counter.data[i];
3544             result.data[i] = add & 0xff;
3545             add = add >> 8;
3546             }
3547              
3548             return svFromBytes(cdsSeal(result));
3549             }
3550              
3551              
3552             static struct cdsRSAPrivateKey * privateKeyFromSV(SV * sv) {
3553             if (! SvPOK(sv)) return NULL;
3554             STRLEN length;
3555             struct cdsRSAPrivateKey * key = (struct cdsRSAPrivateKey *) SvPV(sv, length);
3556             return length == sizeof(struct cdsRSAPrivateKey) ? key : NULL;
3557             }
3558              
3559             SV * privateKeyGenerate() {
3560             struct cdsRSAPrivateKey key;
3561             cdsGeneratePrivateKey(&key);
3562             SV * obj = newSVpvn((char *) &key, sizeof(struct cdsRSAPrivateKey));
3563             SvREADONLY_on(obj);
3564             return obj;
3565             }
3566              
3567             SV * privateKeyNew(SV * svE, SV * svP, SV * svQ) {
3568             struct cdsRSAPrivateKey key;
3569             cdsInitializePrivateKey(&key, bytesFromSV(svE), bytesFromSV(svP), bytesFromSV(svQ));
3570             if (! key.isValid) return &PL_sv_undef;
3571             SV * obj = newSVpvn((char *) &key, sizeof(struct cdsRSAPrivateKey));
3572             SvREADONLY_on(obj);
3573             return obj;
3574             }
3575              
3576             SV * privateKeyE(SV * svThis) {
3577             struct cdsRSAPrivateKey * this = privateKeyFromSV(svThis);
3578             if (this == NULL) return &PL_sv_undef;
3579             return svFromBigInteger(&this->rsaPublicKey.e);
3580             }
3581              
3582             SV * privateKeyP(SV * svThis) {
3583             struct cdsRSAPrivateKey * this = privateKeyFromSV(svThis);
3584             if (this == NULL) return &PL_sv_undef;
3585             return svFromBigInteger(&this->p);
3586             }
3587              
3588             SV * privateKeyQ(SV * svThis) {
3589             struct cdsRSAPrivateKey * this = privateKeyFromSV(svThis);
3590             if (this == NULL) return &PL_sv_undef;
3591             return svFromBigInteger(&this->q);
3592             }
3593              
3594             SV * privateKeyD(SV * svThis) {
3595             struct cdsRSAPrivateKey * this = privateKeyFromSV(svThis);
3596             if (this == NULL) return &PL_sv_undef;
3597             return svFromBigInteger(&this->d);
3598             }
3599              
3600             SV * privateKeySign(SV * svThis, SV * svDigest) {
3601             struct cdsRSAPrivateKey * this = privateKeyFromSV(svThis);
3602             if (this == NULL) return &PL_sv_undef;
3603              
3604             uint8_t buffer[256];
3605             struct cdsBytes signature = cdsSign(this, bytesFromSV(svDigest), buffer);
3606             return svFromBytes(signature);
3607             }
3608              
3609             SV * privateKeyVerify(SV * svThis, SV * svDigest, SV * svSignature) {
3610             struct cdsRSAPrivateKey * this = privateKeyFromSV(svThis);
3611             if (this == NULL) return &PL_sv_undef;
3612              
3613             bool ok = cdsVerify(&this->rsaPublicKey, bytesFromSV(svDigest), bytesFromSV(svSignature));
3614             return ok ? &PL_sv_yes : &PL_sv_no;
3615             }
3616              
3617             SV * privateKeyEncrypt(SV * svThis, SV * svMessage) {
3618             struct cdsRSAPrivateKey * this = privateKeyFromSV(svThis);
3619             if (this == NULL) return &PL_sv_undef;
3620              
3621             uint8_t buffer[256];
3622             struct cdsBytes encrypted = cdsEncrypt(&this->rsaPublicKey, bytesFromSV(svMessage), buffer);
3623             return svFromBytes(encrypted);
3624             }
3625              
3626             SV * privateKeyDecrypt(SV * svThis, SV * svMessage) {
3627             struct cdsRSAPrivateKey * this = privateKeyFromSV(svThis);
3628             if (this == NULL) return &PL_sv_undef;
3629              
3630             uint8_t buffer[256];
3631             struct cdsBytes decrypted = cdsDecrypt(this, bytesFromSV(svMessage), buffer);
3632             return svFromBytes(decrypted);
3633             }
3634              
3635              
3636             static struct cdsRSAPublicKey * publicKeyFromSV(SV * sv) {
3637             if (! SvPOK(sv)) return NULL;
3638             STRLEN length;
3639             struct cdsRSAPublicKey * key = (struct cdsRSAPublicKey *) SvPV(sv, length);
3640             return length == sizeof(struct cdsRSAPublicKey) ? key : NULL;
3641             }
3642              
3643             SV * publicKeyFromPrivateKey(SV * svPrivateKey) {
3644             struct cdsRSAPrivateKey * key = privateKeyFromSV(svPrivateKey);
3645              
3646             struct cdsRSAPublicKey publicKey;
3647             memcpy(&publicKey.e, &key->rsaPublicKey.e, sizeof(struct cdsBigInteger));
3648             memcpy(&publicKey.n, &key->rsaPublicKey.n, sizeof(struct cdsBigInteger));
3649              
3650             SV * obj = newSVpvn((char *) &publicKey, sizeof(struct cdsRSAPublicKey));
3651             SvREADONLY_on(obj);
3652             return obj;
3653             }
3654              
3655             SV * publicKeyNew(SV * svE, SV * svN) {
3656             struct cdsRSAPublicKey key;
3657             cdsInitializePublicKey(&key, bytesFromSV(svE), bytesFromSV(svN));
3658             if (! key.isValid) return &PL_sv_undef;
3659             SV * obj = newSVpvn((char *) &key, sizeof(struct cdsRSAPublicKey));
3660             SvREADONLY_on(obj);
3661             return obj;
3662             }
3663              
3664             SV * publicKeyE(SV * svThis) {
3665             struct cdsRSAPublicKey * this = publicKeyFromSV(svThis);
3666             if (this == NULL) return &PL_sv_undef;
3667             return svFromBigInteger(&this->e);
3668             }
3669              
3670             SV * publicKeyN(SV * svThis) {
3671             struct cdsRSAPublicKey * this = publicKeyFromSV(svThis);
3672             if (this == NULL) return &PL_sv_undef;
3673             return svFromBigInteger(&this->n);
3674             }
3675              
3676             SV * publicKeyVerify(SV * svThis, SV * svDigest, SV * svSignature) {
3677             struct cdsRSAPublicKey * this = publicKeyFromSV(svThis);
3678             if (this == NULL) return &PL_sv_undef;
3679              
3680             bool ok = cdsVerify(this, bytesFromSV(svDigest), bytesFromSV(svSignature));
3681             return ok ? &PL_sv_yes : &PL_sv_no;
3682             }
3683              
3684             SV * publicKeyEncrypt(SV * svThis, SV * svMessage) {
3685             struct cdsRSAPublicKey * this = publicKeyFromSV(svThis);
3686             if (this == NULL) return &PL_sv_undef;
3687              
3688             uint8_t buffer[256];
3689             struct cdsBytes encrypted = cdsEncrypt(this, bytesFromSV(svMessage), buffer);
3690             return svFromBytes(encrypted);
3691             }
3692              
3693              
3694             SV * performanceStart() {
3695             struct timespec ts;
3696             clock_gettime(CLOCK_MONOTONIC, &ts);
3697             SV * obj = newSVpvn((char *) &ts, sizeof(struct timespec));
3698             SvREADONLY_on(obj);
3699             return obj;
3700             }
3701              
3702             static struct timespec * timerFromSV(SV * sv) {
3703             if (! SvPOK(sv)) return NULL;
3704             STRLEN length;
3705             struct timespec * ts = (struct timespec *) SvPV(sv, length);
3706             return length == sizeof(struct timespec) ? ts : NULL;
3707             }
3708              
3709             SV * performanceElapsed(SV * svThis) {
3710             struct timespec * this = timerFromSV(svThis);
3711             if (this == NULL) return &PL_sv_undef;
3712              
3713             struct timespec ts;
3714             clock_gettime(CLOCK_MONOTONIC, &ts);
3715             time_t dsec = ts.tv_sec - this->tv_sec;
3716             long dnano = ts.tv_nsec - this->tv_nsec;
3717              
3718             long diff = (long) dsec * 1000 * 1000 + dnano / 1000;
3719             return newSViv(diff);
3720             }
3721             ENDOFCODE
3722             1;