1 module crypto.rsa;
2 
3 import std.bigint;
4 import std.bitmanip;
5 import std.datetime;
6 import std.base64;
7 import std.typecons;
8 
9 import crypto.utils;
10 
11 struct RSAKeyPair
12 {
13     string privateKey;
14     string publicKey;
15 
16     this(string privateKey, string publicKey)
17     {
18         this.privateKey = privateKey;
19         this.publicKey = publicKey;
20     }
21 }
22 
23 struct RSAKeyInfo
24 {
25     @property BigInt modulus()
26     {
27         return _modulus;
28     }
29 
30     @property ubyte[] modulus_bytes()
31     {
32         return _modulus_bytes;
33     }
34 
35     @property BigInt exponent()
36     {
37         return _exponent;
38     }
39 
40     @property ubyte[] exponent_bytes()
41     {
42         return _exponent_bytes;
43     }
44 
45     this(BigInt modulus, ubyte[] modulus_bytes, BigInt exponent, ubyte[] exponent_bytes)
46     {
47         _modulus = modulus;
48         _modulus_bytes = modulus_bytes;
49         _exponent = exponent;
50         _exponent_bytes = exponent_bytes;
51     }
52 
53 private:
54 
55     BigInt _modulus;
56     ubyte[] _modulus_bytes;
57     BigInt _exponent;
58     ubyte[] _exponent_bytes;
59 }
60 
61 class RSA
62 {
63 public:
64 
65     static RSAKeyPair generateKeyPair(uint bitLength = 1024)
66     {
67         assert((bitLength >= 128) && (bitLength % 8 == 0), "Bitlength is required to be a multiple of 8 and not less than 128.");
68 
69         BigInt x, y;
70 
71         BigInt ex_gcd(BigInt a, BigInt b)
72         {
73             if (b == 0)
74             {
75                 x = BigInt("1");
76                 y = BigInt("0");
77                 return a;
78             }
79             BigInt ans = ex_gcd(b, a % b);
80             BigInt temp = x;
81             x = y;
82             y = temp - (a / b * y);
83             return ans;
84         }
85 
86         BigInt cal(BigInt a, BigInt k)
87         {
88             BigInt gcd = ex_gcd(a, k);
89             if (gcd % 1 != 0)
90             {
91                 return BigInt("-1");
92             }
93             x = x * (1 / gcd);
94             if (k < 0)
95                 k *= -1;
96             BigInt ans = x % k;
97             if (ans < 0)
98                 ans = ans += k;
99             return ans;
100         }
101 
102         BigInt p, q, n, t, e;
103 
104         while (true)
105         {
106             p = generateRandomBigInt(bitLength / 2, 1, 1);
107             if (isProbablePrime(p))
108                 break;
109         }
110         while (true)
111         {
112             q = generateRandomBigInt(bitLength / 2, 1, 1);
113             if (isProbablePrime(q))
114                 break;
115         }
116         n = p * q;
117         t = (p - 1) * (q - 1);
118         e = PRIMES[(rnd.next % 42) + 6500];
119 
120         BigInt d = cal(e, t);
121 
122         return RSAKeyPair(encodeKey(n, d), encodeKey(n, e));
123     }
124 
125     static string encodeKey(T : iPKCS = SimpleFormat)(BigInt modulus, BigInt exponent)
126     {
127         return T.encodeKey(modulus, exponent);
128     }
129 
130     static RSAKeyInfo decodeKey(T : iPKCS = SimpleFormat)(string key)
131     {
132         return T.decodeKey(key);
133     }
134 
135     static ubyte[] encrypt(T : iPKCS = SimpleFormat)(string key, ubyte[] data, bool mixinXteaMode = false)
136     {
137         return encrypt_decrypt!("encrypt", T)(key, data, mixinXteaMode);
138     }
139 
140     static ubyte[] encrypt(RSAKeyInfo key, ubyte[] data, bool mixinXteaMode = false)
141     {
142         return encrypt_decrypt!"encrypt"(key, data, mixinXteaMode);
143     }
144 
145     static ubyte[] decrypt(T : iPKCS = SimpleFormat)(string key, ubyte[] data, bool mixinXteaMode = false)
146     {
147         return encrypt_decrypt!("decrypt", T)(key, data, mixinXteaMode);
148     }
149 
150     static ubyte[] decrypt(RSAKeyInfo key, ubyte[] data, bool mixinXteaMode = false)
151     {
152         return encrypt_decrypt!"decrypt"(key, data, mixinXteaMode);
153     }
154 
155 private:
156     static InsecureRandomGenerator rnd;
157 
158     static BigInt generateRandomBigInt(uint bitLength, int highBit = -1, int lowBit = -1)
159     {
160         ubyte[] buffer = new ubyte[bitLength / 8];
161 
162         uint pos = 0;
163         uint current = 0;
164         foreach (ref a; buffer)
165         {
166             if (pos == 0)
167                 current = rnd.next;
168             a = cast(ubyte)(current >> 8 * pos);
169             pos = (pos + 1) % uint.sizeof;
170         }
171 
172         if (highBit == 0)
173             buffer[0] &= (0xFF >> 1);
174         else if (highBit == 1)
175             buffer[0] |= (0x01 << 7);
176 
177         if (lowBit == 0)
178             buffer[$ - 1] &= (0xFF << 1);
179         else if (lowBit == 1)
180             buffer[$ - 1] |= 0x01;
181 
182         return BigIntHelper.bigIntFromUByteArray(buffer);
183     }
184 
185     static bool isProbablePrime(BigInt n)
186     {
187         if (n == 2)
188             return true;
189 
190         foreach (prime; PRIMES)
191         {
192             if (n % prime == 0)
193                 return false;
194         }
195 
196         return millerRabinPrimeTest(n);
197     }
198 
199     static bool millerRabinPrimeTest(BigInt n)
200     {
201         int s = 40;
202         BigInt a;
203 
204         for (int i = 0; i < s; i++)
205         {
206             a = rnd.next % (n - 2) + 2;
207             if (BigIntHelper.powMod(a, n, n - 1) != 1)
208                 return false;
209         }
210 
211         return true;
212     }
213 
214     static ubyte[] encrypt_decrypt(string T1, T2 : iPKCS = SimpleFormat)(string key, ubyte[] data, bool mixinXteaMode)
215     if (T1 == "encrypt" || T1 == "decrypt")
216     {
217         RSAKeyInfo ki = decodeKey!T2(key);
218         return encrypt_decrypt!(T1)(ki, data, mixinXteaMode);
219     }
220 
221     static ubyte[] encrypt_decrypt(string T)(RSAKeyInfo key, ubyte[] data, bool mixinXteaMode)
222     if (T == "encrypt" || T == "decrypt")
223     {
224         if (mixinXteaMode)
225         {
226             return encrypt_decrypt_mixinXteaMode!T(key, data);
227         }
228         
229         size_t keySize = key.modulus_bytes.length;
230 
231         BigInt getNextBlock(out size_t blockSize)
232         {
233             if (data.length == 0)
234             {
235                 blockSize = 0;
236                 return BigInt("0");
237             }
238 
239             if (T == "decrypt")
240             {
241                 ubyte[] block = data[0 .. ($ >= keySize) ? keySize : $];
242                 blockSize = block.length;
243                 return BigIntHelper.bigIntFromUByteArray(block);
244             }
245             else
246             {
247                 // Prevent preamble 0, and make the encrypto results random
248                 ubyte preamble = rnd.next!ubyte(0x01, 0xFF);
249                 blockSize = (keySize <= data.length) ? keySize : data.length;
250 
251                 while (true)
252                 {
253                     ubyte[] block = [preamble] ~ data[0 .. blockSize];
254                     BigInt t = BigIntHelper.bigIntFromUByteArray(block);
255                     if (t >= key.modulus)
256                     {
257                         blockSize--;
258                         assert(blockSize > 0, "Key bits is too small.");
259                         continue;
260                     }
261                     return t;
262                 }
263             }
264         }
265 
266         ubyte[] ret;
267 
268         while (data.length > 0)
269         {
270             size_t blockSize;
271             BigInt block = getNextBlock(blockSize);
272             if (blockSize == 0)
273             {
274                 break;
275             }
276 
277             block = BigIntHelper.powMod(block, key.modulus, key.exponent);
278             ubyte[] block_buf = BigIntHelper.bigIntToUByteArray(block);
279             if (T == "encrypt")
280             {
281                 for (size_t i; i < keySize - block_buf.length; i++)
282                 {
283                     ret ~= cast(ubyte)0;
284                 }
285             }
286             else
287             {
288                 block_buf = block_buf[1 .. $];
289             }
290 
291             ret ~= block_buf;
292             data = data[blockSize .. $];
293         }
294 
295         return ret;
296     }
297     
298     static ubyte[] encrypt_decrypt_mixinXteaMode(string T)(RSAKeyInfo key, ubyte[] data)
299     if (T == "encrypt" || T == "decrypt")
300     {
301         import crypto.tea;
302 
303         int[4] xteaKey;
304         int rounds = 64;
305         size_t keySize = key.modulus_bytes.length;
306 
307         void generateXteaKey(in ubyte[] buf)
308         {
309             ubyte[] data = new ubyte[int.sizeof * 4];
310             for (int i = 0; i < int.sizeof * 4; i++)
311             {
312                 data[i] = buf[i % buf.length];
313             }
314 
315             for (int i = 0; i < 4; i++)
316             {
317                 xteaKey[i] = data.peek!int(i * int.sizeof);
318             } 
319         }
320 
321         BigInt getNextBlock(out size_t blockSize)
322         {
323             if (data.length == 0)
324             {
325                 blockSize = 0;
326                 return BigInt("0");
327             }
328 
329             if (T == "decrypt")
330             {
331                 ubyte[] block = data[0 .. ($ >= keySize) ? keySize : $];
332                 blockSize = block.length;
333                 return BigIntHelper.bigIntFromUByteArray(block);
334             }
335             else
336             {
337                 // Prevent preamble 0, and make the encrypto results random
338                 ubyte preamble = rnd.next!ubyte(0x01, 0xFF);
339                 blockSize = (keySize <= data.length) ? keySize : data.length;
340 
341                 while (true)
342                 {
343                     ubyte[] block = [preamble] ~ data[0 .. blockSize];
344                     BigInt t = BigIntHelper.bigIntFromUByteArray(block);
345                     if (t >= key.modulus)
346                     {
347                         blockSize--;
348                         assert(blockSize > 0, "Key bits is too small.");
349                         continue;
350                     }
351 
352                     generateXteaKey(block);
353                     return t;
354                 }
355             }
356         }
357 
358         ubyte[] ret;
359 
360         size_t blockSize;
361         BigInt block = getNextBlock(blockSize);
362         if (blockSize == 0)
363         {
364             return ret;
365         }
366 
367         block = BigIntHelper.powMod(block, key.modulus, key.exponent);
368         ubyte[] block_buf = BigIntHelper.bigIntToUByteArray(block);
369         if (T == "encrypt")
370         {
371             for (size_t i; i < keySize - block_buf.length; i++)
372             {
373                 ret ~= cast(ubyte)0;
374             }
375         }
376         else
377         {
378             generateXteaKey(block_buf);
379             block_buf = block_buf[1 .. $];
380         }
381 
382         ret ~= block_buf;
383 
384         if (blockSize >= data.length)
385         {
386             return ret;
387         }
388 
389         data = data[blockSize .. $];
390 
391         if (T == "encrypt")
392         {
393             ret ~= Xtea.encrypt(data, xteaKey, rounds);
394         }
395         else
396         {
397             ret ~= Xtea.decrypt(data, xteaKey, rounds);
398         }
399 
400         return ret;
401     }
402 
403     immutable static size_t PRIME_TABLE_SIZE = 6543;
404     immutable static uint[PRIME_TABLE_SIZE] PRIMES = [
405         2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61,
406         67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137,
407         139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211,
408         223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283,
409         293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379,
410         383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461,
411         463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563,
412         569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643,
413         647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 733, 739,
414         743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 827, 829,
415         839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 929, 937,
416         941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 1021,
417         1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 1097,
418         1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 1193,
419         1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 1283,
420         1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 1373,
421         1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 1459,
422         1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 1549,
423         1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 1619,
424         1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 1721,
425         1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 1811,
426         1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 1907,
427         1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 2003,
428         2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 2089,
429         2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 2203,
430         2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 2287,
431         2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 2377,
432         2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 2459,
433         2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 2579,
434         2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 2677,
435         2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 2741,
436         2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 2837,
437         2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 2939,
438         2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 3041,
439         3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 3167,
440         3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 3257,
441         3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 3347,
442         3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 3461,
443         3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 3541,
444         3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 3631,
445         3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 3727,
446         3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 3833,
447         3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 3923,
448         3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 4021,
449         4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 4129,
450         4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 4231,
451         4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 4337,
452         4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 4447,
453         4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 4547,
454         4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 4649,
455         4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 4751,
456         4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 4871,
457         4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 4967,
458         4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 5051,
459         5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 5167,
460         5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 5279,
461         5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 5399,
462         5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 5479,
463         5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 5573,
464         5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 5683,
465         5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 5791,
466         5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 5867,
467         5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 6007,
468         6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 6101,
469         6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 6211,
470         6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 6301,
471         6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 6379,
472         6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 6529,
473         6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 6637,
474         6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 6733,
475         6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 6833,
476         6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 6949,
477         6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 7027,
478         7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 7159,
479         7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 7253,
480         7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 7411,
481         7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 7517,
482         7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 7589,
483         7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 7691,
484         7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 7817,
485         7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 7919,
486         7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 8053,
487         8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 8161,
488         8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 8263,
489         8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 8369,
490         8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 8501,
491         8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 8609,
492         8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 8699,
493         8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 8803,
494         8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 8893,
495         8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 9011,
496         9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 9133,
497         9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 9227,
498         9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 9341,
499         9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 9433,
500         9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 9533,
501         9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 9649,
502         9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 9767,
503         9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 9857,
504         9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 9967,
505         9973, 10007, 10009, 10037, 10039, 10061, 10067, 10069, 10079, 10091,
506         10093, 10099, 10103, 10111, 10133, 10139, 10141, 10151, 10159, 10163,
507         10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, 10253, 10259,
508         10267, 10271, 10273, 10289, 10301, 10303, 10313, 10321, 10331, 10333,
509         10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, 10453,
510         10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529, 10531,
511         10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 10639,
512         10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 10729,
513         10733, 10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, 10847,
514         10853, 10859, 10861, 10867, 10883, 10889, 10891, 10903, 10909, 10937,
515         10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, 11027, 11047,
516         11057, 11059, 11069, 11071, 11083, 11087, 11093, 11113, 11117, 11119,
517         11131, 11149, 11159, 11161, 11171, 11173, 11177, 11197, 11213, 11239,
518         11243, 11251, 11257, 11261, 11273, 11279, 11287, 11299, 11311, 11317,
519         11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, 11411, 11423,
520         11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491, 11497, 11503,
521         11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617, 11621,
522         11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 11731,
523         11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 11827,
524         11831, 11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, 11923,
525         11927, 11933, 11939, 11941, 11953, 11959, 11969, 11971, 11981, 11987,
526         12007, 12011, 12037, 12041, 12043, 12049, 12071, 12073, 12097, 12101,
527         12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, 12163, 12197,
528         12203, 12211, 12227, 12239, 12241, 12251, 12253, 12263, 12269, 12277,
529         12281, 12289, 12301, 12323, 12329, 12343, 12347, 12373, 12377, 12379,
530         12391, 12401, 12409, 12413, 12421, 12433, 12437, 12451, 12457, 12473,
531         12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 12539, 12541,
532         12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613, 12619,
533         12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 12713,
534         12721, 12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 12821,
535         12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, 12911, 12917,
536         12919, 12923, 12941, 12953, 12959, 12967, 12973, 12979, 12983, 13001,
537         13003, 13007, 13009, 13033, 13037, 13043, 13049, 13063, 13093, 13099,
538         13103, 13109, 13121, 13127, 13147, 13151, 13159, 13163, 13171, 13177,
539         13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, 13267, 13291,
540         13297, 13309, 13313, 13327, 13331, 13337, 13339, 13367, 13381, 13397,
541         13399, 13411, 13417, 13421, 13441, 13451, 13457, 13463, 13469, 13477,
542         13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577, 13591, 13597,
543         13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687, 13691,
544         13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 13759,
545         13763, 13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 13873,
546         13877, 13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931, 13933,
547         13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, 14051, 14057,
548         14071, 14081, 14083, 14087, 14107, 14143, 14149, 14153, 14159, 14173,
549         14177, 14197, 14207, 14221, 14243, 14249, 14251, 14281, 14293, 14303,
550         14321, 14323, 14327, 14341, 14347, 14369, 14387, 14389, 14401, 14407,
551         14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, 14479, 14489,
552         14503, 14519, 14533, 14537, 14543, 14549, 14551, 14557, 14561, 14563,
553         14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653, 14657, 14669,
554         14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 14753,
555         14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 14831,
556         14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 14929,
557         14939, 14947, 14951, 14957, 14969, 14983, 15013, 15017, 15031, 15053,
558         15061, 15073, 15077, 15083, 15091, 15101, 15107, 15121, 15131, 15137,
559         15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, 15227, 15233,
560         15241, 15259, 15263, 15269, 15271, 15277, 15287, 15289, 15299, 15307,
561         15313, 15319, 15329, 15331, 15349, 15359, 15361, 15373, 15377, 15383,
562         15391, 15401, 15413, 15427, 15439, 15443, 15451, 15461, 15467, 15473,
563         15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, 15581, 15583,
564         15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661, 15667,
565         15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749, 15761,
566         15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 15859,
567         15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 15937,
568         15959, 15971, 15973, 15991, 16001, 16007, 16033, 16057, 16061, 16063,
569         16067, 16069, 16073, 16087, 16091, 16097, 16103, 16111, 16127, 16139,
570         16141, 16183, 16187, 16189, 16193, 16217, 16223, 16229, 16231, 16249,
571         16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, 16361, 16363,
572         16369, 16381, 16411, 16417, 16421, 16427, 16433, 16447, 16451, 16453,
573         16477, 16481, 16487, 16493, 16519, 16529, 16547, 16553, 16561, 16567,
574         16573, 16603, 16607, 16619, 16631, 16633, 16649, 16651, 16657, 16661,
575         16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 16759, 16763,
576         16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883, 16889,
577         16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 16981,
578         16987, 16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 17053,
579         17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, 17167, 17183,
580         17189, 17191, 17203, 17207, 17209, 17231, 17239, 17257, 17291, 17293,
581         17299, 17317, 17321, 17327, 17333, 17341, 17351, 17359, 17377, 17383,
582         17387, 17389, 17393, 17401, 17417, 17419, 17431, 17443, 17449, 17467,
583         17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, 17539, 17551,
584         17569, 17573, 17579, 17581, 17597, 17599, 17609, 17623, 17627, 17657,
585         17659, 17669, 17681, 17683, 17707, 17713, 17729, 17737, 17747, 17749,
586         17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839, 17851, 17863,
587         17881, 17891, 17903, 17909, 17911, 17921, 17923, 17929, 17939, 17957,
588         17959, 17971, 17977, 17981, 17987, 17989, 18013, 18041, 18043, 18047,
589         18049, 18059, 18061, 18077, 18089, 18097, 18119, 18121, 18127, 18131,
590         18133, 18143, 18149, 18169, 18181, 18191, 18199, 18211, 18217, 18223,
591         18229, 18233, 18251, 18253, 18257, 18269, 18287, 18289, 18301, 18307,
592         18311, 18313, 18329, 18341, 18353, 18367, 18371, 18379, 18397, 18401,
593         18413, 18427, 18433, 18439, 18443, 18451, 18457, 18461, 18481, 18493,
594         18503, 18517, 18521, 18523, 18539, 18541, 18553, 18583, 18587, 18593,
595         18617, 18637, 18661, 18671, 18679, 18691, 18701, 18713, 18719, 18731,
596         18743, 18749, 18757, 18773, 18787, 18793, 18797, 18803, 18839, 18859,
597         18869, 18899, 18911, 18913, 18917, 18919, 18947, 18959, 18973, 18979,
598         19001, 19009, 19013, 19031, 19037, 19051, 19069, 19073, 19079, 19081,
599         19087, 19121, 19139, 19141, 19157, 19163, 19181, 19183, 19207, 19211,
600         19213, 19219, 19231, 19237, 19249, 19259, 19267, 19273, 19289, 19301,
601         19309, 19319, 19333, 19373, 19379, 19381, 19387, 19391, 19403, 19417,
602         19421, 19423, 19427, 19429, 19433, 19441, 19447, 19457, 19463, 19469,
603         19471, 19477, 19483, 19489, 19501, 19507, 19531, 19541, 19543, 19553,
604         19559, 19571, 19577, 19583, 19597, 19603, 19609, 19661, 19681, 19687,
605         19697, 19699, 19709, 19717, 19727, 19739, 19751, 19753, 19759, 19763,
606         19777, 19793, 19801, 19813, 19819, 19841, 19843, 19853, 19861, 19867,
607         19889, 19891, 19913, 19919, 19927, 19937, 19949, 19961, 19963, 19973,
608         19979, 19991, 19993, 19997, 20011, 20021, 20023, 20029, 20047, 20051,
609         20063, 20071, 20089, 20101, 20107, 20113, 20117, 20123, 20129, 20143,
610         20147, 20149, 20161, 20173, 20177, 20183, 20201, 20219, 20231, 20233,
611         20249, 20261, 20269, 20287, 20297, 20323, 20327, 20333, 20341, 20347,
612         20353, 20357, 20359, 20369, 20389, 20393, 20399, 20407, 20411, 20431,
613         20441, 20443, 20477, 20479, 20483, 20507, 20509, 20521, 20533, 20543,
614         20549, 20551, 20563, 20593, 20599, 20611, 20627, 20639, 20641, 20663,
615         20681, 20693, 20707, 20717, 20719, 20731, 20743, 20747, 20749, 20753,
616         20759, 20771, 20773, 20789, 20807, 20809, 20849, 20857, 20873, 20879,
617         20887, 20897, 20899, 20903, 20921, 20929, 20939, 20947, 20959, 20963,
618         20981, 20983, 21001, 21011, 21013, 21017, 21019, 21023, 21031, 21059,
619         21061, 21067, 21089, 21101, 21107, 21121, 21139, 21143, 21149, 21157,
620         21163, 21169, 21179, 21187, 21191, 21193, 21211, 21221, 21227, 21247,
621         21269, 21277, 21283, 21313, 21317, 21319, 21323, 21341, 21347, 21377,
622         21379, 21383, 21391, 21397, 21401, 21407, 21419, 21433, 21467, 21481,
623         21487, 21491, 21493, 21499, 21503, 21517, 21521, 21523, 21529, 21557,
624         21559, 21563, 21569, 21577, 21587, 21589, 21599, 21601, 21611, 21613,
625         21617, 21647, 21649, 21661, 21673, 21683, 21701, 21713, 21727, 21737,
626         21739, 21751, 21757, 21767, 21773, 21787, 21799, 21803, 21817, 21821,
627         21839, 21841, 21851, 21859, 21863, 21871, 21881, 21893, 21911, 21929,
628         21937, 21943, 21961, 21977, 21991, 21997, 22003, 22013, 22027, 22031,
629         22037, 22039, 22051, 22063, 22067, 22073, 22079, 22091, 22093, 22109,
630         22111, 22123, 22129, 22133, 22147, 22153, 22157, 22159, 22171, 22189,
631         22193, 22229, 22247, 22259, 22271, 22273, 22277, 22279, 22283, 22291,
632         22303, 22307, 22343, 22349, 22367, 22369, 22381, 22391, 22397, 22409,
633         22433, 22441, 22447, 22453, 22469, 22481, 22483, 22501, 22511, 22531,
634         22541, 22543, 22549, 22567, 22571, 22573, 22613, 22619, 22621, 22637,
635         22639, 22643, 22651, 22669, 22679, 22691, 22697, 22699, 22709, 22717,
636         22721, 22727, 22739, 22741, 22751, 22769, 22777, 22783, 22787, 22807,
637         22811, 22817, 22853, 22859, 22861, 22871, 22877, 22901, 22907, 22921,
638         22937, 22943, 22961, 22963, 22973, 22993, 23003, 23011, 23017, 23021,
639         23027, 23029, 23039, 23041, 23053, 23057, 23059, 23063, 23071, 23081,
640         23087, 23099, 23117, 23131, 23143, 23159, 23167, 23173, 23189, 23197,
641         23201, 23203, 23209, 23227, 23251, 23269, 23279, 23291, 23293, 23297,
642         23311, 23321, 23327, 23333, 23339, 23357, 23369, 23371, 23399, 23417,
643         23431, 23447, 23459, 23473, 23497, 23509, 23531, 23537, 23539, 23549,
644         23557, 23561, 23563, 23567, 23581, 23593, 23599, 23603, 23609, 23623,
645         23627, 23629, 23633, 23663, 23669, 23671, 23677, 23687, 23689, 23719,
646         23741, 23743, 23747, 23753, 23761, 23767, 23773, 23789, 23801, 23813,
647         23819, 23827, 23831, 23833, 23857, 23869, 23873, 23879, 23887, 23893,
648         23899, 23909, 23911, 23917, 23929, 23957, 23971, 23977, 23981, 23993,
649         24001, 24007, 24019, 24023, 24029, 24043, 24049, 24061, 24071, 24077,
650         24083, 24091, 24097, 24103, 24107, 24109, 24113, 24121, 24133, 24137,
651         24151, 24169, 24179, 24181, 24197, 24203, 24223, 24229, 24239, 24247,
652         24251, 24281, 24317, 24329, 24337, 24359, 24371, 24373, 24379, 24391,
653         24407, 24413, 24419, 24421, 24439, 24443, 24469, 24473, 24481, 24499,
654         24509, 24517, 24527, 24533, 24547, 24551, 24571, 24593, 24611, 24623,
655         24631, 24659, 24671, 24677, 24683, 24691, 24697, 24709, 24733, 24749,
656         24763, 24767, 24781, 24793, 24799, 24809, 24821, 24841, 24847, 24851,
657         24859, 24877, 24889, 24907, 24917, 24919, 24923, 24943, 24953, 24967,
658         24971, 24977, 24979, 24989, 25013, 25031, 25033, 25037, 25057, 25073,
659         25087, 25097, 25111, 25117, 25121, 25127, 25147, 25153, 25163, 25169,
660         25171, 25183, 25189, 25219, 25229, 25237, 25243, 25247, 25253, 25261,
661         25301, 25303, 25307, 25309, 25321, 25339, 25343, 25349, 25357, 25367,
662         25373, 25391, 25409, 25411, 25423, 25439, 25447, 25453, 25457, 25463,
663         25469, 25471, 25523, 25537, 25541, 25561, 25577, 25579, 25583, 25589,
664         25601, 25603, 25609, 25621, 25633, 25639, 25643, 25657, 25667, 25673,
665         25679, 25693, 25703, 25717, 25733, 25741, 25747, 25759, 25763, 25771,
666         25793, 25799, 25801, 25819, 25841, 25847, 25849, 25867, 25873, 25889,
667         25903, 25913, 25919, 25931, 25933, 25939, 25943, 25951, 25969, 25981,
668         25997, 25999, 26003, 26017, 26021, 26029, 26041, 26053, 26083, 26099,
669         26107, 26111, 26113, 26119, 26141, 26153, 26161, 26171, 26177, 26183,
670         26189, 26203, 26209, 26227, 26237, 26249, 26251, 26261, 26263, 26267,
671         26293, 26297, 26309, 26317, 26321, 26339, 26347, 26357, 26371, 26387,
672         26393, 26399, 26407, 26417, 26423, 26431, 26437, 26449, 26459, 26479,
673         26489, 26497, 26501, 26513, 26539, 26557, 26561, 26573, 26591, 26597,
674         26627, 26633, 26641, 26647, 26669, 26681, 26683, 26687, 26693, 26699,
675         26701, 26711, 26713, 26717, 26723, 26729, 26731, 26737, 26759, 26777,
676         26783, 26801, 26813, 26821, 26833, 26839, 26849, 26861, 26863, 26879,
677         26881, 26891, 26893, 26903, 26921, 26927, 26947, 26951, 26953, 26959,
678         26981, 26987, 26993, 27011, 27017, 27031, 27043, 27059, 27061, 27067,
679         27073, 27077, 27091, 27103, 27107, 27109, 27127, 27143, 27179, 27191,
680         27197, 27211, 27239, 27241, 27253, 27259, 27271, 27277, 27281, 27283,
681         27299, 27329, 27337, 27361, 27367, 27397, 27407, 27409, 27427, 27431,
682         27437, 27449, 27457, 27479, 27481, 27487, 27509, 27527, 27529, 27539,
683         27541, 27551, 27581, 27583, 27611, 27617, 27631, 27647, 27653, 27673,
684         27689, 27691, 27697, 27701, 27733, 27737, 27739, 27743, 27749, 27751,
685         27763, 27767, 27773, 27779, 27791, 27793, 27799, 27803, 27809, 27817,
686         27823, 27827, 27847, 27851, 27883, 27893, 27901, 27917, 27919, 27941,
687         27943, 27947, 27953, 27961, 27967, 27983, 27997, 28001, 28019, 28027,
688         28031, 28051, 28057, 28069, 28081, 28087, 28097, 28099, 28109, 28111,
689         28123, 28151, 28163, 28181, 28183, 28201, 28211, 28219, 28229, 28277,
690         28279, 28283, 28289, 28297, 28307, 28309, 28319, 28349, 28351, 28387,
691         28393, 28403, 28409, 28411, 28429, 28433, 28439, 28447, 28463, 28477,
692         28493, 28499, 28513, 28517, 28537, 28541, 28547, 28549, 28559, 28571,
693         28573, 28579, 28591, 28597, 28603, 28607, 28619, 28621, 28627, 28631,
694         28643, 28649, 28657, 28661, 28663, 28669, 28687, 28697, 28703, 28711,
695         28723, 28729, 28751, 28753, 28759, 28771, 28789, 28793, 28807, 28813,
696         28817, 28837, 28843, 28859, 28867, 28871, 28879, 28901, 28909, 28921,
697         28927, 28933, 28949, 28961, 28979, 29009, 29017, 29021, 29023, 29027,
698         29033, 29059, 29063, 29077, 29101, 29123, 29129, 29131, 29137, 29147,
699         29153, 29167, 29173, 29179, 29191, 29201, 29207, 29209, 29221, 29231,
700         29243, 29251, 29269, 29287, 29297, 29303, 29311, 29327, 29333, 29339,
701         29347, 29363, 29383, 29387, 29389, 29399, 29401, 29411, 29423, 29429,
702         29437, 29443, 29453, 29473, 29483, 29501, 29527, 29531, 29537, 29567,
703         29569, 29573, 29581, 29587, 29599, 29611, 29629, 29633, 29641, 29663,
704         29669, 29671, 29683, 29717, 29723, 29741, 29753, 29759, 29761, 29789,
705         29803, 29819, 29833, 29837, 29851, 29863, 29867, 29873, 29879, 29881,
706         29917, 29921, 29927, 29947, 29959, 29983, 29989, 30011, 30013, 30029,
707         30047, 30059, 30071, 30089, 30091, 30097, 30103, 30109, 30113, 30119,
708         30133, 30137, 30139, 30161, 30169, 30181, 30187, 30197, 30203, 30211,
709         30223, 30241, 30253, 30259, 30269, 30271, 30293, 30307, 30313, 30319,
710         30323, 30341, 30347, 30367, 30389, 30391, 30403, 30427, 30431, 30449,
711         30467, 30469, 30491, 30493, 30497, 30509, 30517, 30529, 30539, 30553,
712         30557, 30559, 30577, 30593, 30631, 30637, 30643, 30649, 30661, 30671,
713         30677, 30689, 30697, 30703, 30707, 30713, 30727, 30757, 30763, 30773,
714         30781, 30803, 30809, 30817, 30829, 30839, 30841, 30851, 30853, 30859,
715         30869, 30871, 30881, 30893, 30911, 30931, 30937, 30941, 30949, 30971,
716         30977, 30983, 31013, 31019, 31033, 31039, 31051, 31063, 31069, 31079,
717         31081, 31091, 31121, 31123, 31139, 31147, 31151, 31153, 31159, 31177,
718         31181, 31183, 31189, 31193, 31219, 31223, 31231, 31237, 31247, 31249,
719         31253, 31259, 31267, 31271, 31277, 31307, 31319, 31321, 31327, 31333,
720         31337, 31357, 31379, 31387, 31391, 31393, 31397, 31469, 31477, 31481,
721         31489, 31511, 31513, 31517, 31531, 31541, 31543, 31547, 31567, 31573,
722         31583, 31601, 31607, 31627, 31643, 31649, 31657, 31663, 31667, 31687,
723         31699, 31721, 31723, 31727, 31729, 31741, 31751, 31769, 31771, 31793,
724         31799, 31817, 31847, 31849, 31859, 31873, 31883, 31891, 31907, 31957,
725         31963, 31973, 31981, 31991, 32003, 32009, 32027, 32029, 32051, 32057,
726         32059, 32063, 32069, 32077, 32083, 32089, 32099, 32117, 32119, 32141,
727         32143, 32159, 32173, 32183, 32189, 32191, 32203, 32213, 32233, 32237,
728         32251, 32257, 32261, 32297, 32299, 32303, 32309, 32321, 32323, 32327,
729         32341, 32353, 32359, 32363, 32369, 32371, 32377, 32381, 32401, 32411,
730         32413, 32423, 32429, 32441, 32443, 32467, 32479, 32491, 32497, 32503,
731         32507, 32531, 32533, 32537, 32561, 32563, 32569, 32573, 32579, 32587,
732         32603, 32609, 32611, 32621, 32633, 32647, 32653, 32687, 32693, 32707,
733         32713, 32717, 32719, 32749, 32771, 32779, 32783, 32789, 32797, 32801,
734         32803, 32831, 32833, 32839, 32843, 32869, 32887, 32909, 32911, 32917,
735         32933, 32939, 32941, 32957, 32969, 32971, 32983, 32987, 32993, 32999,
736         33013, 33023, 33029, 33037, 33049, 33053, 33071, 33073, 33083, 33091,
737         33107, 33113, 33119, 33149, 33151, 33161, 33179, 33181, 33191, 33199,
738         33203, 33211, 33223, 33247, 33287, 33289, 33301, 33311, 33317, 33329,
739         33331, 33343, 33347, 33349, 33353, 33359, 33377, 33391, 33403, 33409,
740         33413, 33427, 33457, 33461, 33469, 33479, 33487, 33493, 33503, 33521,
741         33529, 33533, 33547, 33563, 33569, 33577, 33581, 33587, 33589, 33599,
742         33601, 33613, 33617, 33619, 33623, 33629, 33637, 33641, 33647, 33679,
743         33703, 33713, 33721, 33739, 33749, 33751, 33757, 33767, 33769, 33773,
744         33791, 33797, 33809, 33811, 33827, 33829, 33851, 33857, 33863, 33871,
745         33889, 33893, 33911, 33923, 33931, 33937, 33941, 33961, 33967, 33997,
746         34019, 34031, 34033, 34039, 34057, 34061, 34123, 34127, 34129, 34141,
747         34147, 34157, 34159, 34171, 34183, 34211, 34213, 34217, 34231, 34253,
748         34259, 34261, 34267, 34273, 34283, 34297, 34301, 34303, 34313, 34319,
749         34327, 34337, 34351, 34361, 34367, 34369, 34381, 34403, 34421, 34429,
750         34439, 34457, 34469, 34471, 34483, 34487, 34499, 34501, 34511, 34513,
751         34519, 34537, 34543, 34549, 34583, 34589, 34591, 34603, 34607, 34613,
752         34631, 34649, 34651, 34667, 34673, 34679, 34687, 34693, 34703, 34721,
753         34729, 34739, 34747, 34757, 34759, 34763, 34781, 34807, 34819, 34841,
754         34843, 34847, 34849, 34871, 34877, 34883, 34897, 34913, 34919, 34939,
755         34949, 34961, 34963, 34981, 35023, 35027, 35051, 35053, 35059, 35069,
756         35081, 35083, 35089, 35099, 35107, 35111, 35117, 35129, 35141, 35149,
757         35153, 35159, 35171, 35201, 35221, 35227, 35251, 35257, 35267, 35279,
758         35281, 35291, 35311, 35317, 35323, 35327, 35339, 35353, 35363, 35381,
759         35393, 35401, 35407, 35419, 35423, 35437, 35447, 35449, 35461, 35491,
760         35507, 35509, 35521, 35527, 35531, 35533, 35537, 35543, 35569, 35573,
761         35591, 35593, 35597, 35603, 35617, 35671, 35677, 35729, 35731, 35747,
762         35753, 35759, 35771, 35797, 35801, 35803, 35809, 35831, 35837, 35839,
763         35851, 35863, 35869, 35879, 35897, 35899, 35911, 35923, 35933, 35951,
764         35963, 35969, 35977, 35983, 35993, 35999, 36007, 36011, 36013, 36017,
765         36037, 36061, 36067, 36073, 36083, 36097, 36107, 36109, 36131, 36137,
766         36151, 36161, 36187, 36191, 36209, 36217, 36229, 36241, 36251, 36263,
767         36269, 36277, 36293, 36299, 36307, 36313, 36319, 36341, 36343, 36353,
768         36373, 36383, 36389, 36433, 36451, 36457, 36467, 36469, 36473, 36479,
769         36493, 36497, 36523, 36527, 36529, 36541, 36551, 36559, 36563, 36571,
770         36583, 36587, 36599, 36607, 36629, 36637, 36643, 36653, 36671, 36677,
771         36683, 36691, 36697, 36709, 36713, 36721, 36739, 36749, 36761, 36767,
772         36779, 36781, 36787, 36791, 36793, 36809, 36821, 36833, 36847, 36857,
773         36871, 36877, 36887, 36899, 36901, 36913, 36919, 36923, 36929, 36931,
774         36943, 36947, 36973, 36979, 36997, 37003, 37013, 37019, 37021, 37039,
775         37049, 37057, 37061, 37087, 37097, 37117, 37123, 37139, 37159, 37171,
776         37181, 37189, 37199, 37201, 37217, 37223, 37243, 37253, 37273, 37277,
777         37307, 37309, 37313, 37321, 37337, 37339, 37357, 37361, 37363, 37369,
778         37379, 37397, 37409, 37423, 37441, 37447, 37463, 37483, 37489, 37493,
779         37501, 37507, 37511, 37517, 37529, 37537, 37547, 37549, 37561, 37567,
780         37571, 37573, 37579, 37589, 37591, 37607, 37619, 37633, 37643, 37649,
781         37657, 37663, 37691, 37693, 37699, 37717, 37747, 37781, 37783, 37799,
782         37811, 37813, 37831, 37847, 37853, 37861, 37871, 37879, 37889, 37897,
783         37907, 37951, 37957, 37963, 37967, 37987, 37991, 37993, 37997, 38011,
784         38039, 38047, 38053, 38069, 38083, 38113, 38119, 38149, 38153, 38167,
785         38177, 38183, 38189, 38197, 38201, 38219, 38231, 38237, 38239, 38261,
786         38273, 38281, 38287, 38299, 38303, 38317, 38321, 38327, 38329, 38333,
787         38351, 38371, 38377, 38393, 38431, 38447, 38449, 38453, 38459, 38461,
788         38501, 38543, 38557, 38561, 38567, 38569, 38593, 38603, 38609, 38611,
789         38629, 38639, 38651, 38653, 38669, 38671, 38677, 38693, 38699, 38707,
790         38711, 38713, 38723, 38729, 38737, 38747, 38749, 38767, 38783, 38791,
791         38803, 38821, 38833, 38839, 38851, 38861, 38867, 38873, 38891, 38903,
792         38917, 38921, 38923, 38933, 38953, 38959, 38971, 38977, 38993, 39019,
793         39023, 39041, 39043, 39047, 39079, 39089, 39097, 39103, 39107, 39113,
794         39119, 39133, 39139, 39157, 39161, 39163, 39181, 39191, 39199, 39209,
795         39217, 39227, 39229, 39233, 39239, 39241, 39251, 39293, 39301, 39313,
796         39317, 39323, 39341, 39343, 39359, 39367, 39371, 39373, 39383, 39397,
797         39409, 39419, 39439, 39443, 39451, 39461, 39499, 39503, 39509, 39511,
798         39521, 39541, 39551, 39563, 39569, 39581, 39607, 39619, 39623, 39631,
799         39659, 39667, 39671, 39679, 39703, 39709, 39719, 39727, 39733, 39749,
800         39761, 39769, 39779, 39791, 39799, 39821, 39827, 39829, 39839, 39841,
801         39847, 39857, 39863, 39869, 39877, 39883, 39887, 39901, 39929, 39937,
802         39953, 39971, 39979, 39983, 39989, 40009, 40013, 40031, 40037, 40039,
803         40063, 40087, 40093, 40099, 40111, 40123, 40127, 40129, 40151, 40153,
804         40163, 40169, 40177, 40189, 40193, 40213, 40231, 40237, 40241, 40253,
805         40277, 40283, 40289, 40343, 40351, 40357, 40361, 40387, 40423, 40427,
806         40429, 40433, 40459, 40471, 40483, 40487, 40493, 40499, 40507, 40519,
807         40529, 40531, 40543, 40559, 40577, 40583, 40591, 40597, 40609, 40627,
808         40637, 40639, 40693, 40697, 40699, 40709, 40739, 40751, 40759, 40763,
809         40771, 40787, 40801, 40813, 40819, 40823, 40829, 40841, 40847, 40849,
810         40853, 40867, 40879, 40883, 40897, 40903, 40927, 40933, 40939, 40949,
811         40961, 40973, 40993, 41011, 41017, 41023, 41039, 41047, 41051, 41057,
812         41077, 41081, 41113, 41117, 41131, 41141, 41143, 41149, 41161, 41177,
813         41179, 41183, 41189, 41201, 41203, 41213, 41221, 41227, 41231, 41233,
814         41243, 41257, 41263, 41269, 41281, 41299, 41333, 41341, 41351, 41357,
815         41381, 41387, 41389, 41399, 41411, 41413, 41443, 41453, 41467, 41479,
816         41491, 41507, 41513, 41519, 41521, 41539, 41543, 41549, 41579, 41593,
817         41597, 41603, 41609, 41611, 41617, 41621, 41627, 41641, 41647, 41651,
818         41659, 41669, 41681, 41687, 41719, 41729, 41737, 41759, 41761, 41771,
819         41777, 41801, 41809, 41813, 41843, 41849, 41851, 41863, 41879, 41887,
820         41893, 41897, 41903, 41911, 41927, 41941, 41947, 41953, 41957, 41959,
821         41969, 41981, 41983, 41999, 42013, 42017, 42019, 42023, 42043, 42061,
822         42071, 42073, 42083, 42089, 42101, 42131, 42139, 42157, 42169, 42179,
823         42181, 42187, 42193, 42197, 42209, 42221, 42223, 42227, 42239, 42257,
824         42281, 42283, 42293, 42299, 42307, 42323, 42331, 42337, 42349, 42359,
825         42373, 42379, 42391, 42397, 42403, 42407, 42409, 42433, 42437, 42443,
826         42451, 42457, 42461, 42463, 42467, 42473, 42487, 42491, 42499, 42509,
827         42533, 42557, 42569, 42571, 42577, 42589, 42611, 42641, 42643, 42649,
828         42667, 42677, 42683, 42689, 42697, 42701, 42703, 42709, 42719, 42727,
829         42737, 42743, 42751, 42767, 42773, 42787, 42793, 42797, 42821, 42829,
830         42839, 42841, 42853, 42859, 42863, 42899, 42901, 42923, 42929, 42937,
831         42943, 42953, 42961, 42967, 42979, 42989, 43003, 43013, 43019, 43037,
832         43049, 43051, 43063, 43067, 43093, 43103, 43117, 43133, 43151, 43159,
833         43177, 43189, 43201, 43207, 43223, 43237, 43261, 43271, 43283, 43291,
834         43313, 43319, 43321, 43331, 43391, 43397, 43399, 43403, 43411, 43427,
835         43441, 43451, 43457, 43481, 43487, 43499, 43517, 43541, 43543, 43573,
836         43577, 43579, 43591, 43597, 43607, 43609, 43613, 43627, 43633, 43649,
837         43651, 43661, 43669, 43691, 43711, 43717, 43721, 43753, 43759, 43777,
838         43781, 43783, 43787, 43789, 43793, 43801, 43853, 43867, 43889, 43891,
839         43913, 43933, 43943, 43951, 43961, 43963, 43969, 43973, 43987, 43991,
840         43997, 44017, 44021, 44027, 44029, 44041, 44053, 44059, 44071, 44087,
841         44089, 44101, 44111, 44119, 44123, 44129, 44131, 44159, 44171, 44179,
842         44189, 44201, 44203, 44207, 44221, 44249, 44257, 44263, 44267, 44269,
843         44273, 44279, 44281, 44293, 44351, 44357, 44371, 44381, 44383, 44389,
844         44417, 44449, 44453, 44483, 44491, 44497, 44501, 44507, 44519, 44531,
845         44533, 44537, 44543, 44549, 44563, 44579, 44587, 44617, 44621, 44623,
846         44633, 44641, 44647, 44651, 44657, 44683, 44687, 44699, 44701, 44711,
847         44729, 44741, 44753, 44771, 44773, 44777, 44789, 44797, 44809, 44819,
848         44839, 44843, 44851, 44867, 44879, 44887, 44893, 44909, 44917, 44927,
849         44939, 44953, 44959, 44963, 44971, 44983, 44987, 45007, 45013, 45053,
850         45061, 45077, 45083, 45119, 45121, 45127, 45131, 45137, 45139, 45161,
851         45179, 45181, 45191, 45197, 45233, 45247, 45259, 45263, 45281, 45289,
852         45293, 45307, 45317, 45319, 45329, 45337, 45341, 45343, 45361, 45377,
853         45389, 45403, 45413, 45427, 45433, 45439, 45481, 45491, 45497, 45503,
854         45523, 45533, 45541, 45553, 45557, 45569, 45587, 45589, 45599, 45613,
855         45631, 45641, 45659, 45667, 45673, 45677, 45691, 45697, 45707, 45737,
856         45751, 45757, 45763, 45767, 45779, 45817, 45821, 45823, 45827, 45833,
857         45841, 45853, 45863, 45869, 45887, 45893, 45943, 45949, 45953, 45959,
858         45971, 45979, 45989, 46021, 46027, 46049, 46051, 46061, 46073, 46091,
859         46093, 46099, 46103, 46133, 46141, 46147, 46153, 46171, 46181, 46183,
860         46187, 46199, 46219, 46229, 46237, 46261, 46271, 46273, 46279, 46301,
861         46307, 46309, 46327, 46337, 46349, 46351, 46381, 46399, 46411, 46439,
862         46441, 46447, 46451, 46457, 46471, 46477, 46489, 46499, 46507, 46511,
863         46523, 46549, 46559, 46567, 46573, 46589, 46591, 46601, 46619, 46633,
864         46639, 46643, 46649, 46663, 46679, 46681, 46687, 46691, 46703, 46723,
865         46727, 46747, 46751, 46757, 46769, 46771, 46807, 46811, 46817, 46819,
866         46829, 46831, 46853, 46861, 46867, 46877, 46889, 46901, 46919, 46933,
867         46957, 46993, 46997, 47017, 47041, 47051, 47057, 47059, 47087, 47093,
868         47111, 47119, 47123, 47129, 47137, 47143, 47147, 47149, 47161, 47189,
869         47207, 47221, 47237, 47251, 47269, 47279, 47287, 47293, 47297, 47303,
870         47309, 47317, 47339, 47351, 47353, 47363, 47381, 47387, 47389, 47407,
871         47417, 47419, 47431, 47441, 47459, 47491, 47497, 47501, 47507, 47513,
872         47521, 47527, 47533, 47543, 47563, 47569, 47581, 47591, 47599, 47609,
873         47623, 47629, 47639, 47653, 47657, 47659, 47681, 47699, 47701, 47711,
874         47713, 47717, 47737, 47741, 47743, 47777, 47779, 47791, 47797, 47807,
875         47809, 47819, 47837, 47843, 47857, 47869, 47881, 47903, 47911, 47917,
876         47933, 47939, 47947, 47951, 47963, 47969, 47977, 47981, 48017, 48023,
877         48029, 48049, 48073, 48079, 48091, 48109, 48119, 48121, 48131, 48157,
878         48163, 48179, 48187, 48193, 48197, 48221, 48239, 48247, 48259, 48271,
879         48281, 48299, 48311, 48313, 48337, 48341, 48353, 48371, 48383, 48397,
880         48407, 48409, 48413, 48437, 48449, 48463, 48473, 48479, 48481, 48487,
881         48491, 48497, 48523, 48527, 48533, 48539, 48541, 48563, 48571, 48589,
882         48593, 48611, 48619, 48623, 48647, 48649, 48661, 48673, 48677, 48679,
883         48731, 48733, 48751, 48757, 48761, 48767, 48779, 48781, 48787, 48799,
884         48809, 48817, 48821, 48823, 48847, 48857, 48859, 48869, 48871, 48883,
885         48889, 48907, 48947, 48953, 48973, 48989, 48991, 49003, 49009, 49019,
886         49031, 49033, 49037, 49043, 49057, 49069, 49081, 49103, 49109, 49117,
887         49121, 49123, 49139, 49157, 49169, 49171, 49177, 49193, 49199, 49201,
888         49207, 49211, 49223, 49253, 49261, 49277, 49279, 49297, 49307, 49331,
889         49333, 49339, 49363, 49367, 49369, 49391, 49393, 49409, 49411, 49417,
890         49429, 49433, 49451, 49459, 49463, 49477, 49481, 49499, 49523, 49529,
891         49531, 49537, 49547, 49549, 49559, 49597, 49603, 49613, 49627, 49633,
892         49639, 49663, 49667, 49669, 49681, 49697, 49711, 49727, 49739, 49741,
893         49747, 49757, 49783, 49787, 49789, 49801, 49807, 49811, 49823, 49831,
894         49843, 49853, 49871, 49877, 49891, 49919, 49921, 49927, 49937, 49939,
895         49943, 49957, 49991, 49993, 49999, 50021, 50023, 50033, 50047, 50051,
896         50053, 50069, 50077, 50087, 50093, 50101, 50111, 50119, 50123, 50129,
897         50131, 50147, 50153, 50159, 50177, 50207, 50221, 50227, 50231, 50261,
898         50263, 50273, 50287, 50291, 50311, 50321, 50329, 50333, 50341, 50359,
899         50363, 50377, 50383, 50387, 50411, 50417, 50423, 50441, 50459, 50461,
900         50497, 50503, 50513, 50527, 50539, 50543, 50549, 50551, 50581, 50587,
901         50591, 50593, 50599, 50627, 50647, 50651, 50671, 50683, 50707, 50723,
902         50741, 50753, 50767, 50773, 50777, 50789, 50821, 50833, 50839, 50849,
903         50857, 50867, 50873, 50891, 50893, 50909, 50923, 50929, 50951, 50957,
904         50969, 50971, 50989, 50993, 51001, 51031, 51043, 51047, 51059, 51061,
905         51071, 51109, 51131, 51133, 51137, 51151, 51157, 51169, 51193, 51197,
906         51199, 51203, 51217, 51229, 51239, 51241, 51257, 51263, 51283, 51287,
907         51307, 51329, 51341, 51343, 51347, 51349, 51361, 51383, 51407, 51413,
908         51419, 51421, 51427, 51431, 51437, 51439, 51449, 51461, 51473, 51479,
909         51481, 51487, 51503, 51511, 51517, 51521, 51539, 51551, 51563, 51577,
910         51581, 51593, 51599, 51607, 51613, 51631, 51637, 51647, 51659, 51673,
911         51679, 51683, 51691, 51713, 51719, 51721, 51749, 51767, 51769, 51787,
912         51797, 51803, 51817, 51827, 51829, 51839, 51853, 51859, 51869, 51871,
913         51893, 51899, 51907, 51913, 51929, 51941, 51949, 51971, 51973, 51977,
914         51991, 52009, 52021, 52027, 52051, 52057, 52067, 52069, 52081, 52103,
915         52121, 52127, 52147, 52153, 52163, 52177, 52181, 52183, 52189, 52201,
916         52223, 52237, 52249, 52253, 52259, 52267, 52289, 52291, 52301, 52313,
917         52321, 52361, 52363, 52369, 52379, 52387, 52391, 52433, 52453, 52457,
918         52489, 52501, 52511, 52517, 52529, 52541, 52543, 52553, 52561, 52567,
919         52571, 52579, 52583, 52609, 52627, 52631, 52639, 52667, 52673, 52691,
920         52697, 52709, 52711, 52721, 52727, 52733, 52747, 52757, 52769, 52783,
921         52807, 52813, 52817, 52837, 52859, 52861, 52879, 52883, 52889, 52901,
922         52903, 52919, 52937, 52951, 52957, 52963, 52967, 52973, 52981, 52999,
923         53003, 53017, 53047, 53051, 53069, 53077, 53087, 53089, 53093, 53101,
924         53113, 53117, 53129, 53147, 53149, 53161, 53171, 53173, 53189, 53197,
925         53201, 53231, 53233, 53239, 53267, 53269, 53279, 53281, 53299, 53309,
926         53323, 53327, 53353, 53359, 53377, 53381, 53401, 53407, 53411, 53419,
927         53437, 53441, 53453, 53479, 53503, 53507, 53527, 53549, 53551, 53569,
928         53591, 53593, 53597, 53609, 53611, 53617, 53623, 53629, 53633, 53639,
929         53653, 53657, 53681, 53693, 53699, 53717, 53719, 53731, 53759, 53773,
930         53777, 53783, 53791, 53813, 53819, 53831, 53849, 53857, 53861, 53881,
931         53887, 53891, 53897, 53899, 53917, 53923, 53927, 53939, 53951, 53959,
932         53987, 53993, 54001, 54011, 54013, 54037, 54049, 54059, 54083, 54091,
933         54101, 54121, 54133, 54139, 54151, 54163, 54167, 54181, 54193, 54217,
934         54251, 54269, 54277, 54287, 54293, 54311, 54319, 54323, 54331, 54347,
935         54361, 54367, 54371, 54377, 54401, 54403, 54409, 54413, 54419, 54421,
936         54437, 54443, 54449, 54469, 54493, 54497, 54499, 54503, 54517, 54521,
937         54539, 54541, 54547, 54559, 54563, 54577, 54581, 54583, 54601, 54617,
938         54623, 54629, 54631, 54647, 54667, 54673, 54679, 54709, 54713, 54721,
939         54727, 54751, 54767, 54773, 54779, 54787, 54799, 54829, 54833, 54851,
940         54869, 54877, 54881, 54907, 54917, 54919, 54941, 54949, 54959, 54973,
941         54979, 54983, 55001, 55009, 55021, 55049, 55051, 55057, 55061, 55073,
942         55079, 55103, 55109, 55117, 55127, 55147, 55163, 55171, 55201, 55207,
943         55213, 55217, 55219, 55229, 55243, 55249, 55259, 55291, 55313, 55331,
944         55333, 55337, 55339, 55343, 55351, 55373, 55381, 55399, 55411, 55439,
945         55441, 55457, 55469, 55487, 55501, 55511, 55529, 55541, 55547, 55579,
946         55589, 55603, 55609, 55619, 55621, 55631, 55633, 55639, 55661, 55663,
947         55667, 55673, 55681, 55691, 55697, 55711, 55717, 55721, 55733, 55763,
948         55787, 55793, 55799, 55807, 55813, 55817, 55819, 55823, 55829, 55837,
949         55843, 55849, 55871, 55889, 55897, 55901, 55903, 55921, 55927, 55931,
950         55933, 55949, 55967, 55987, 55997, 56003, 56009, 56039, 56041, 56053,
951         56081, 56087, 56093, 56099, 56101, 56113, 56123, 56131, 56149, 56167,
952         56171, 56179, 56197, 56207, 56209, 56237, 56239, 56249, 56263, 56267,
953         56269, 56299, 56311, 56333, 56359, 56369, 56377, 56383, 56393, 56401,
954         56417, 56431, 56437, 56443, 56453, 56467, 56473, 56477, 56479, 56489,
955         56501, 56503, 56509, 56519, 56527, 56531, 56533, 56543, 56569, 56591,
956         56597, 56599, 56611, 56629, 56633, 56659, 56663, 56671, 56681, 56687,
957         56701, 56711, 56713, 56731, 56737, 56747, 56767, 56773, 56779, 56783,
958         56807, 56809, 56813, 56821, 56827, 56843, 56857, 56873, 56891, 56893,
959         56897, 56909, 56911, 56921, 56923, 56929, 56941, 56951, 56957, 56963,
960         56983, 56989, 56993, 56999, 57037, 57041, 57047, 57059, 57073, 57077,
961         57089, 57097, 57107, 57119, 57131, 57139, 57143, 57149, 57163, 57173,
962         57179, 57191, 57193, 57203, 57221, 57223, 57241, 57251, 57259, 57269,
963         57271, 57283, 57287, 57301, 57329, 57331, 57347, 57349, 57367, 57373,
964         57383, 57389, 57397, 57413, 57427, 57457, 57467, 57487, 57493, 57503,
965         57527, 57529, 57557, 57559, 57571, 57587, 57593, 57601, 57637, 57641,
966         57649, 57653, 57667, 57679, 57689, 57697, 57709, 57713, 57719, 57727,
967         57731, 57737, 57751, 57773, 57781, 57787, 57791, 57793, 57803, 57809,
968         57829, 57839, 57847, 57853, 57859, 57881, 57899, 57901, 57917, 57923,
969         57943, 57947, 57973, 57977, 57991, 58013, 58027, 58031, 58043, 58049,
970         58057, 58061, 58067, 58073, 58099, 58109, 58111, 58129, 58147, 58151,
971         58153, 58169, 58171, 58189, 58193, 58199, 58207, 58211, 58217, 58229,
972         58231, 58237, 58243, 58271, 58309, 58313, 58321, 58337, 58363, 58367,
973         58369, 58379, 58391, 58393, 58403, 58411, 58417, 58427, 58439, 58441,
974         58451, 58453, 58477, 58481, 58511, 58537, 58543, 58549, 58567, 58573,
975         58579, 58601, 58603, 58613, 58631, 58657, 58661, 58679, 58687, 58693,
976         58699, 58711, 58727, 58733, 58741, 58757, 58763, 58771, 58787, 58789,
977         58831, 58889, 58897, 58901, 58907, 58909, 58913, 58921, 58937, 58943,
978         58963, 58967, 58979, 58991, 58997, 59009, 59011, 59021, 59023, 59029,
979         59051, 59053, 59063, 59069, 59077, 59083, 59093, 59107, 59113, 59119,
980         59123, 59141, 59149, 59159, 59167, 59183, 59197, 59207, 59209, 59219,
981         59221, 59233, 59239, 59243, 59263, 59273, 59281, 59333, 59341, 59351,
982         59357, 59359, 59369, 59377, 59387, 59393, 59399, 59407, 59417, 59419,
983         59441, 59443, 59447, 59453, 59467, 59471, 59473, 59497, 59509, 59513,
984         59539, 59557, 59561, 59567, 59581, 59611, 59617, 59621, 59627, 59629,
985         59651, 59659, 59663, 59669, 59671, 59693, 59699, 59707, 59723, 59729,
986         59743, 59747, 59753, 59771, 59779, 59791, 59797, 59809, 59833, 59863,
987         59879, 59887, 59921, 59929, 59951, 59957, 59971, 59981, 59999, 60013,
988         60017, 60029, 60037, 60041, 60077, 60083, 60089, 60091, 60101, 60103,
989         60107, 60127, 60133, 60139, 60149, 60161, 60167, 60169, 60209, 60217,
990         60223, 60251, 60257, 60259, 60271, 60289, 60293, 60317, 60331, 60337,
991         60343, 60353, 60373, 60383, 60397, 60413, 60427, 60443, 60449, 60457,
992         60493, 60497, 60509, 60521, 60527, 60539, 60589, 60601, 60607, 60611,
993         60617, 60623, 60631, 60637, 60647, 60649, 60659, 60661, 60679, 60689,
994         60703, 60719, 60727, 60733, 60737, 60757, 60761, 60763, 60773, 60779,
995         60793, 60811, 60821, 60859, 60869, 60887, 60889, 60899, 60901, 60913,
996         60917, 60919, 60923, 60937, 60943, 60953, 60961, 61001, 61007, 61027,
997         61031, 61043, 61051, 61057, 61091, 61099, 61121, 61129, 61141, 61151,
998         61153, 61169, 61211, 61223, 61231, 61253, 61261, 61283, 61291, 61297,
999         61331, 61333, 61339, 61343, 61357, 61363, 61379, 61381, 61403, 61409,
1000         61417, 61441, 61463, 61469, 61471, 61483, 61487, 61493, 61507, 61511,
1001         61519, 61543, 61547, 61553, 61559, 61561, 61583, 61603, 61609, 61613,
1002         61627, 61631, 61637, 61643, 61651, 61657, 61667, 61673, 61681, 61687,
1003         61703, 61717, 61723, 61729, 61751, 61757, 61781, 61813, 61819, 61837,
1004         61843, 61861, 61871, 61879, 61909, 61927, 61933, 61949, 61961, 61967,
1005         61979, 61981, 61987, 61991, 62003, 62011, 62017, 62039, 62047, 62053,
1006         62057, 62071, 62081, 62099, 62119, 62129, 62131, 62137, 62141, 62143,
1007         62171, 62189, 62191, 62201, 62207, 62213, 62219, 62233, 62273, 62297,
1008         62299, 62303, 62311, 62323, 62327, 62347, 62351, 62383, 62401, 62417,
1009         62423, 62459, 62467, 62473, 62477, 62483, 62497, 62501, 62507, 62533,
1010         62539, 62549, 62563, 62581, 62591, 62597, 62603, 62617, 62627, 62633,
1011         62639, 62653, 62659, 62683, 62687, 62701, 62723, 62731, 62743, 62753,
1012         62761, 62773, 62791, 62801, 62819, 62827, 62851, 62861, 62869, 62873,
1013         62897, 62903, 62921, 62927, 62929, 62939, 62969, 62971, 62981, 62983,
1014         62987, 62989, 63029, 63031, 63059, 63067, 63073, 63079, 63097, 63103,
1015         63113, 63127, 63131, 63149, 63179, 63197, 63199, 63211, 63241, 63247,
1016         63277, 63281, 63299, 63311, 63313, 63317, 63331, 63337, 63347, 63353,
1017         63361, 63367, 63377, 63389, 63391, 63397, 63409, 63419, 63421, 63439,
1018         63443, 63463, 63467, 63473, 63487, 63493, 63499, 63521, 63527, 63533,
1019         63541, 63559, 63577, 63587, 63589, 63599, 63601, 63607, 63611, 63617,
1020         63629, 63647, 63649, 63659, 63667, 63671, 63689, 63691, 63697, 63703,
1021         63709, 63719, 63727, 63737, 63743, 63761, 63773, 63781, 63793, 63799,
1022         63803, 63809, 63823, 63839, 63841, 63853, 63857, 63863, 63901, 63907,
1023         63913, 63929, 63949, 63977, 63997, 64007, 64013, 64019, 64033, 64037,
1024         64063, 64067, 64081, 64091, 64109, 64123, 64151, 64153, 64157, 64171,
1025         64187, 64189, 64217, 64223, 64231, 64237, 64271, 64279, 64283, 64301,
1026         64303, 64319, 64327, 64333, 64373, 64381, 64399, 64403, 64433, 64439,
1027         64451, 64453, 64483, 64489, 64499, 64513, 64553, 64567, 64577, 64579,
1028         64591, 64601, 64609, 64613, 64621, 64627, 64633, 64661, 64663, 64667,
1029         64679, 64693, 64709, 64717, 64747, 64763, 64781, 64783, 64793, 64811,
1030         64817, 64849, 64853, 64871, 64877, 64879, 64891, 64901, 64919, 64921,
1031         64927, 64937, 64951, 64969, 64997, 65003, 65011, 65027, 65029, 65033,
1032         65053, 65063, 65071, 65089, 65099, 65101, 65111, 65119, 65123, 65129,
1033         65141, 65147, 65167, 65171, 65173, 65179, 65183, 65203, 65213, 65239,
1034         65257, 65267, 65269, 65287, 65293, 65309, 65323, 65327, 65353, 65357,
1035         65371, 65381, 65393, 65407, 65413, 65419, 65423, 65437, 65447, 65449,
1036         65479, 65497, 65519, 65521, 65537
1037     ];
1038 }
1039 
1040 interface iPKCS
1041 {
1042     static string encodeKey(BigInt modulus, BigInt exponent);
1043     static Nullable!RSAKeyInfo decodeKey(string key);
1044 }
1045 
1046 class SimpleFormat : iPKCS
1047 {
1048     static string encodeKey(BigInt modulus, BigInt exponent)
1049     {
1050         ubyte[] m_bytes = BigIntHelper.bigIntToUByteArray(modulus);
1051         ubyte[] e_bytes = BigIntHelper.bigIntToUByteArray(exponent);
1052 
1053         ubyte[] buffer = new ubyte[4];
1054 
1055         buffer.write!int(cast(int) m_bytes.length, 0);
1056         buffer ~= m_bytes;
1057         buffer ~= e_bytes;
1058 
1059         return Base64.encode(buffer);
1060     }
1061 
1062     static Nullable!RSAKeyInfo decodeKey(string key)
1063     {
1064         ubyte[] buffer = Base64.decode(key);
1065         int m_len = buffer.peek!int(0);
1066         ubyte[] modulus_bytes = buffer[4 .. 4 + m_len];
1067         ubyte[] exponent_bytes = buffer[4 + m_len .. $];
1068 
1069         return Nullable!RSAKeyInfo(RSAKeyInfo(BigIntHelper.bigIntFromUByteArray(modulus_bytes),
1070                 modulus_bytes, BigIntHelper.bigIntFromUByteArray(exponent_bytes), exponent_bytes));
1071     }
1072 }
1073 
1074 class PKCS1 : iPKCS
1075 {
1076     static string encodeKey(BigInt modulus, BigInt exponent)
1077     {
1078         return string.init;
1079     }
1080 
1081     static Nullable!RSAKeyInfo decodeKey(string key)
1082     {
1083         return Nullable!RSAKeyInfo();
1084     }
1085 }
1086 
1087 class PKCS8 : iPKCS
1088 {
1089     static string encodeKey(BigInt modulus, BigInt exponent)
1090     {
1091         return string.init;
1092     }
1093 
1094     static Nullable!RSAKeyInfo decodeKey(string key)
1095     {
1096         return Nullable!RSAKeyInfo();
1097     }
1098 }
1099 
1100 unittest
1101 {
1102     import std.stdio;
1103 
1104     import crypto.rsa;
1105 
1106     RSAKeyPair keyPair = RSA.generateKeyPair(1024);
1107     writeln(keyPair.privateKey);
1108     writeln(keyPair.publicKey);
1109 
1110     string data = `
1111 And the workload proves (POW) reusable workload proof (RPOW) 2. hash function
1112 The hash function (Hash Function), also known as a hash function, gives an input x, which calculates the corresponding output H (x). The main features of a hash function are:
1113 The input x can be a string of any length
1114 The output, that is, the length of H (x) is fixed
1115 
1116 The procedure for calculating H (x) is efficient (for string X of length n), the time complexity of H (x) should be O (n)
1117 For bitcoin, the hash function used by such cryptographic systems, it needs to have the following properties:
1118 	`;
1119 
1120     ubyte[] sb = cast(ubyte[]) data;
1121     ubyte[] db = RSA.encrypt(keyPair.privateKey, sb);
1122     sb = RSA.decrypt(keyPair.publicKey, db);
1123     writeln(cast(string) sb);
1124 }
1125 
1126 unittest
1127 {
1128     import std.stdio;
1129 
1130     import std.bigint;
1131     import crypto.rsa;
1132 
1133     RSAKeyPair keyPair = RSA.generateKeyPair(1024);
1134     writeln(keyPair.privateKey);
1135     writeln(keyPair.publicKey);
1136 
1137     RSAKeyInfo pri_key = RSA.decodeKey(keyPair.privateKey);
1138     RSAKeyInfo pub_key = RSA.decodeKey(keyPair.publicKey);
1139 
1140     string data = `
1141 And the workload proves (POW) reusable workload proof (RPOW) 2. hash function
1142 The hash function (Hash Function), also known as a hash function, gives an input x, which calculates the corresponding output H (x). The main features of a hash function are:
1143 The input x can be a string of any length
1144 The output, that is, the length of H (x) is fixed
1145 
1146 The procedure for calculating H (x) is efficient (for string X of length n), the time complexity of H (x) should be O (n)
1147 For bitcoin, the hash function used by such cryptographic systems, it needs to have the following properties:
1148 	`;
1149 
1150     ubyte[] sb = cast(ubyte[]) data;
1151     ubyte[] db = RSA.encrypt(pri_key, sb);
1152     sb = RSA.decrypt(pub_key, db);
1153     writeln(cast(string) sb);
1154 }