1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 | #include <algorithm> #include <iostream> #include <sstream> static const std::string h = "0123456789abcdef"; uint64_t toint(const std::string & s, const int & base = 10){ // Changees strings to uint64_t uint64_t INT = 0; switch (base){ case 2: for(unsigned int x = 0; x < s.size(); x++) INT = (INT << 1) + (s[x] == '\x31'); break; case 8: std::stringstream(s) >> std::oct >> INT; break; case 10: std::stringstream(s) >> std::dec >> INT; break; case 16: std::stringstream(s) >> std::hex >> INT; break; case 256: for(uint8_t x = 0; x < s.size(); x++) INT = (INT << 8) + (uint8_t) s[x]; break; default: exit(1); break; }; return INT; } template<typename T> std::string makehex(T value, unsigned int size = 2 * sizeof(T)){ // Changes a value to its hexadecimal string if (!size){ std::stringstream out; out << std::hex << value; return out.str(); } std::string out(size, '0'); while (value && size){ out[--size] = h[value & 15]; value >>= 4; } return out; } std::string hexlify(const std::string & in){ // Changes an ASCII string to an ASCII string containing the // hexadecimal representation of the orignal chars std::string out = ""; for(unsigned int x = 0; x < in.size(); x++) out += makehex((unsigned char) in[x], 2); return out; } std::string unhexlify(const std::string & in){ if (in.size() & 1) exit(1); std::string out = ""; for(unsigned int x = 0; x < in.size(); x += 2) if (in.substr(x, 2) == "00") out += std::string(1, 0); else out += (unsigned char) ((h.find(tolower(in[x])) << 4) + h.find(tolower(in[x + 1]))); return out; } class MISTY1{ private: bool keyset; uint16_t EK[32]; uint8_t S7TABLE[128]; uint16_t S9TABLE[512]; uint16_t FI(uint16_t FI_IN, uint16_t FI_KEY){ uint16_t d9 = FI_IN >> 7; uint16_t d7 = FI_IN & 0x7f; d9 = S9TABLE[d9] ^ d7; d7 = S7TABLE[d7] ^ d9; // ( d7 = d7 & 0x7f; ) d7 = d7 ^ (FI_KEY >> 9); d9 = d9 ^ (FI_KEY & 0x1ff); d9 = S9TABLE[d9] ^ d7; return ((uint16_t) (d7 && 0xffffU) << 9) | d9; } uint32_t FO(uint32_t FO_IN, uint16_t k){ uint16_t t0 = FO_IN >> 16; uint16_t t1 = FO_IN & 0xffff; t0 = t0 ^ EK[k]; t0 = FI(t0, EK[(k+5)%8+8]); t0 = t0 ^ t1; t1 = t1 ^ EK[(k+2)%8]; t1 = FI(t1, EK[(k+1)%8+8]); t1 = t1 ^ t0; t0 = t0 ^ EK[(k+7)%8]; t0 = FI(t0, EK[(k+3)%8+8]); t0 = t0 ^ t1; t1 = t1 ^ EK[(k+4)%8]; return (t1 << 16) | t0; } uint32_t FL(uint32_t FL_IN, uint32_t k){ uint16_t d0 = FL_IN >> 16; uint16_t d1 = FL_IN & 0xffff; if (!(k & 1)){ d1 = d1 ^ (d0 & EK[k/2]); d0 = d0 ^ (d1 | EK[(k/2+6)%8+8]); } else{ d1 = d1 ^ (d0 & EK[((k-1)/2+2)%8+8]); d0 = d0 ^ (d1 | EK[((k-1)/2+4)%8]); } return (d0 << 16) | d1; } uint32_t FLINV(uint32_t FL_IN, uint32_t k){ uint16_t d0 = FL_IN >> 16; uint16_t d1 = FL_IN & 0xffff; if (!(k & 1)){ d0 = d0 ^ (d1 | EK[(k/2+6)%8+8]); d1 = d1 ^ (d0 & EK[k/2]); } else{ d0 = d0 ^ (d1 | EK[((k-1)/2+4)%8]); d1 = d1 ^ (d0 & EK[((k-1)/2+2)%8+8]); } return (d0 << 16) | d1; } public: MISTY1() : keyset(false) {} MISTY1(std::string key){ keyset = false; setkey(key); } void setkey(std::string key){ if (keyset) exit(2); uint8_t S7[128] = { 0x1b, 0x32, 0x33, 0x5a, 0x3b, 0x10, 0x17, 0x54, 0x5b, 0x1a, 0x72, 0x73, 0x6b, 0x2c, 0x66, 0x49, 0x1f, 0x24, 0x13, 0x6c, 0x37, 0x2e, 0x3f, 0x4a, 0x5d, 0x0f, 0x40, 0x56, 0x25, 0x51, 0x1c, 0x04, 0x0b, 0x46, 0x20, 0x0d, 0x7b, 0x35, 0x44, 0x42, 0x2b, 0x1e, 0x41, 0x14, 0x4b, 0x79, 0x15, 0x6f, 0x0e, 0x55, 0x09, 0x36, 0x74, 0x0c, 0x67, 0x53, 0x28, 0x0a, 0x7e, 0x38, 0x02, 0x07, 0x60, 0x29, 0x19, 0x12, 0x65, 0x2f, 0x30, 0x39, 0x08, 0x68, 0x5f, 0x78, 0x2a, 0x4c, 0x64, 0x45, 0x75, 0x3d, 0x59, 0x48, 0x03, 0x57, 0x7c, 0x4f, 0x62, 0x3c, 0x1d, 0x21, 0x5e, 0x27, 0x6a, 0x70, 0x4d, 0x3a, 0x01, 0x6d, 0x6e, 0x63, 0x18, 0x77, 0x23, 0x05, 0x26, 0x76, 0x00, 0x31, 0x2d, 0x7a, 0x7f, 0x61, 0x50, 0x22, 0x11, 0x06, 0x47, 0x16, 0x52, 0x4e, 0x71, 0x3e, 0x69, 0x43, 0x34, 0x5c, 0x58, 0x7d}; uint16_t S9[512] = {0x1c3, 0x0cb, 0x153, 0x19f, 0x1e3, 0x0e9, 0x0fb, 0x035, 0x181, 0x0b9, 0x117, 0x1eb, 0x133, 0x009, 0x02d, 0x0d3, 0x0c7, 0x14a, 0x037, 0x07e, 0x0eb, 0x164, 0x193, 0x1d8, 0x0a3, 0x11e, 0x055, 0x02c, 0x01d, 0x1a2, 0x163, 0x118, 0x14b, 0x152, 0x1d2, 0x00f, 0x02b, 0x030, 0x13a, 0x0e5, 0x111, 0x138, 0x18e, 0x063, 0x0e3, 0x0c8, 0x1f4, 0x01b, 0x001, 0x09d, 0x0f8, 0x1a0, 0x16d, 0x1f3, 0x01c, 0x146, 0x07d, 0x0d1, 0x082, 0x1ea, 0x183, 0x12d, 0x0f4, 0x19e, 0x1d3, 0x0dd, 0x1e2, 0x128, 0x1e0, 0x0ec, 0x059, 0x091, 0x011, 0x12f, 0x026, 0x0dc, 0x0b0, 0x18c, 0x10f, 0x1f7, 0x0e7, 0x16c, 0x0b6, 0x0f9, 0x0d8, 0x151, 0x101, 0x14c, 0x103, 0x0b8, 0x154, 0x12b, 0x1ae, 0x017, 0x071, 0x00c, 0x047, 0x058, 0x07f, 0x1a4, 0x134, 0x129, 0x084, 0x15d, 0x19d, 0x1b2, 0x1a3, 0x048, 0x07c, 0x051, 0x1ca, 0x023, 0x13d, 0x1a7, 0x165, 0x03b, 0x042, 0x0da, 0x192, 0x0ce, 0x0c1, 0x06b, 0x09f, 0x1f1, 0x12c, 0x184, 0x0fa, 0x196, 0x1e1, 0x169, 0x17d, 0x031, 0x180, 0x10a, 0x094, 0x1da, 0x186, 0x13e, 0x11c, 0x060, 0x175, 0x1cf, 0x067, 0x119, 0x065, 0x068, 0x099, 0x150, 0x008, 0x007, 0x17c, 0x0b7, 0x024, 0x019, 0x0de, 0x127, 0x0db, 0x0e4, 0x1a9, 0x052, 0x109, 0x090, 0x19c, 0x1c1, 0x028, 0x1b3, 0x135, 0x16a, 0x176, 0x0df, 0x1e5, 0x188, 0x0c5, 0x16e, 0x1de, 0x1b1, 0x0c3, 0x1df, 0x036, 0x0ee, 0x1ee, 0x0f0, 0x093, 0x049, 0x09a, 0x1b6, 0x069, 0x081, 0x125, 0x00b, 0x05e, 0x0b4, 0x149, 0x1c7, 0x174, 0x03e, 0x13b, 0x1b7, 0x08e, 0x1c6, 0x0ae, 0x010, 0x095, 0x1ef, 0x04e, 0x0f2, 0x1fd, 0x085, 0x0fd, 0x0f6, 0x0a0, 0x16f, 0x083, 0x08a, 0x156, 0x09b, 0x13c, 0x107, 0x167, 0x098, 0x1d0, 0x1e9, 0x003, 0x1fe, 0x0bd, 0x122, 0x089, 0x0d2, 0x18f, 0x012, 0x033, 0x06a, 0x142, 0x0ed, 0x170, 0x11b, 0x0e2, 0x14f, 0x158, 0x131, 0x147, 0x05d, 0x113, 0x1cd, 0x079, 0x161, 0x1a5, 0x179, 0x09e, 0x1b4, 0x0cc, 0x022, 0x132, 0x01a, 0x0e8, 0x004, 0x187, 0x1ed, 0x197, 0x039, 0x1bf, 0x1d7, 0x027, 0x18b, 0x0c6, 0x09c, 0x0d0, 0x14e, 0x06c, 0x034, 0x1f2, 0x06e, 0x0ca, 0x025, 0x0ba, 0x191, 0x0fe, 0x013, 0x106, 0x02f, 0x1ad, 0x172, 0x1db, 0x0c0, 0x10b, 0x1d6, 0x0f5, 0x1ec, 0x10d, 0x076, 0x114, 0x1ab, 0x075, 0x10c, 0x1e4, 0x159, 0x054, 0x11f, 0x04b, 0x0c4, 0x1be, 0x0f7, 0x029, 0x0a4, 0x00e, 0x1f0, 0x077, 0x04d, 0x17a, 0x086, 0x08b, 0x0b3, 0x171, 0x0bf, 0x10e, 0x104, 0x097, 0x15b, 0x160, 0x168, 0x0d7, 0x0bb, 0x066, 0x1ce, 0x0fc, 0x092, 0x1c5, 0x06f, 0x016, 0x04a, 0x0a1, 0x139, 0x0af, 0x0f1, 0x190, 0x00a, 0x1aa, 0x143, 0x17b, 0x056, 0x18d, 0x166, 0x0d4, 0x1fb, 0x14d, 0x194, 0x19a, 0x087, 0x1f8, 0x123, 0x0a7, 0x1b8, 0x141, 0x03c, 0x1f9, 0x140, 0x02a, 0x155, 0x11a, 0x1a1, 0x198, 0x0d5, 0x126, 0x1af, 0x061, 0x12e, 0x157, 0x1dc, 0x072, 0x18a, 0x0aa, 0x096, 0x115, 0x0ef, 0x045, 0x07b, 0x08d, 0x145, 0x053, 0x05f, 0x178, 0x0b2, 0x02e, 0x020, 0x1d5, 0x03f, 0x1c9, 0x1e7, 0x1ac, 0x044, 0x038, 0x014, 0x0b1, 0x16b, 0x0ab, 0x0b5, 0x05a, 0x182, 0x1c8, 0x1d4, 0x018, 0x177, 0x064, 0x0cf, 0x06d, 0x100, 0x199, 0x130, 0x15a, 0x005, 0x120, 0x1bb, 0x1bd, 0x0e0, 0x04f, 0x0d6, 0x13f, 0x1c4, 0x12a, 0x015, 0x006, 0x0ff, 0x19b, 0x0a6, 0x043, 0x088, 0x050, 0x15f, 0x1e8, 0x121, 0x073, 0x17e, 0x0bc, 0x0c2, 0x0c9, 0x173, 0x189, 0x1f5, 0x074, 0x1cc, 0x1e6, 0x1a8, 0x195, 0x01f, 0x041, 0x00d, 0x1ba, 0x032, 0x03d, 0x1d1, 0x080, 0x0a8, 0x057, 0x1b9, 0x162, 0x148, 0x0d9, 0x105, 0x062, 0x07a, 0x021, 0x1ff, 0x112, 0x108, 0x1c0, 0x0a9, 0x11d, 0x1b0, 0x1a6, 0x0cd, 0x0f3, 0x05c, 0x102, 0x05b, 0x1d9, 0x144, 0x1f6, 0x0ad, 0x0a5, 0x03a, 0x1cb, 0x136, 0x17f, 0x046, 0x0e1, 0x01e, 0x1dd, 0x0e6, 0x137, 0x1fa, 0x185, 0x08c, 0x08f, 0x040, 0x1b5, 0x0be, 0x078, 0x000, 0x0ac, 0x110, 0x15e, 0x124, 0x002, 0x1bc, 0x0a2, 0x0ea, 0x070, 0x1fc, 0x116, 0x15c, 0x04c, 0x1c2}; for(uint8_t i = 0; i < 128; i++) S7TABLE[i] = S7[i]; for(uint16_t i = 0; i < 512; i++) S9TABLE[i] = S9[i]; for(uint8_t i = 0; i < 8; i++) EK[i] = ((key[i*2]*256) & 0xffff) + (key[i*2+1] & 0xff); for(uint8_t i = 0; i < 8; i++){ EK[i+ 8] = FI(EK[i], EK[(i+1)%8]); EK[i+16] = EK[i+8] & 0x1ff; EK[i+24] = EK[i+8] >> 9; } keyset = true; } std::string encrypt(std::string data){ if (!keyset) exit(1); uint32_t D0 = toint(data.substr(0, 4), 256); uint32_t D1 = toint(data.substr(4, 4), 256); // 0 round D0 = FL(D0, 0); D1 = FL(D1, 1); D1 = D1 ^ FO(D0, 0); // 1 round D0 = D0 ^ FO(D1, 1); // 2 round D0 = FL(D0, 2); D1 = FL(D1, 3); D1 = D1 ^ FO(D0, 2); // 3 round D0 = D0 ^ FO(D1, 3); // 4 round D0 = FL(D0, 4); D1 = FL(D1, 5); D1 = D1 ^ FO(D0, 4); // 5 round D0 = D0 ^ FO(D1, 5); // 6 round D0 = FL(D0, 6); D1 = FL(D1, 7); D1 = D1 ^ FO(D0, 6); // 7 round D0 = D0 ^ FO(D1, 7); // final D0 = FL(D0, 8); D1 = FL(D1, 9); return unhexlify(makehex(D1, 8) + makehex(D0, 8)); } std::string decrypt(std::string data){ if (!keyset) exit(1); uint32_t D0 = toint(data.substr(4, 4), 256); uint32_t D1 = toint(data.substr(0, 4), 256); D0 = FLINV(D0, 8); D1 = FLINV(D1, 9); D0 = D0 ^ FO(D1, 7); D1 = D1 ^ FO(D0, 6); D0 = FLINV(D0, 6); D1 = FLINV(D1, 7); D0 = D0 ^ FO(D1, 5); D1 = D1 ^ FO(D0, 4); D0 = FLINV(D0, 4); D1 = FLINV(D1, 5); D0 = D0 ^ FO(D1, 3); D1 = D1 ^ FO(D0, 2); D0 = FLINV(D0, 2); D1 = FLINV(D1, 3); D0 = D0 ^ FO(D1, 1); D1 = D1 ^ FO(D0, 0); D0 = FLINV(D0, 0); D1 = FLINV(D1, 1); return unhexlify(makehex(D0, 8) + makehex(D1)); } }; int main(){ std::string k = unhexlify("00112233445566778899aabbccddeeff"); std::string p = unhexlify("0123456789abcdef"); // fedcba9876543210 std::string c = unhexlify("8b1da5f56ab3d07c"); // 04b68240b13be95d MISTY1 m(k); std::string test_p = m.encrypt(p); std::cout << hexlify(test_p) << std::endl; std::cout << hexlify(m.decrypt(test_p)) << std::endl; return 0; } |
I2luY2x1ZGUgPGFsZ29yaXRobT4KI2luY2x1ZGUgPGlvc3RyZWFtPgojaW5jbHVkZSA8c3N0cmVhbT4KCnN0YXRpYyBjb25zdCBzdGQ6OnN0cmluZyBoID0gIjAxMjM0NTY3ODlhYmNkZWYiOwoKdWludDY0X3QgdG9pbnQoY29uc3Qgc3RkOjpzdHJpbmcgJiBzLCBjb25zdCBpbnQgJiBiYXNlID0gMTApewogICAgLy8gQ2hhbmdlZXMgc3RyaW5ncyB0byB1aW50NjRfdAogICAgdWludDY0X3QgSU5UID0gMDsKICAgIHN3aXRjaCAoYmFzZSl7CiAgICAgICAgY2FzZSAyOgogICAgICAgICAgICBmb3IodW5zaWduZWQgaW50IHggPSAwOyB4IDwgcy5zaXplKCk7IHgrKykKICAgICAgICAgICAgICAgIElOVCA9IChJTlQgPDwgMSkgKyAoc1t4XSA9PSAnXHgzMScpOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDg6CiAgICAgICAgICAgIHN0ZDo6c3RyaW5nc3RyZWFtKHMpID4+IHN0ZDo6b2N0ID4+IElOVDsKICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgY2FzZSAxMDoKICAgICAgICAgICAgc3RkOjpzdHJpbmdzdHJlYW0ocykgPj4gc3RkOjpkZWMgPj4gSU5UOwogICAgICAgICAgICBicmVhazsKICAgICAgICBjYXNlIDE2OgogICAgICAgICAgICBzdGQ6OnN0cmluZ3N0cmVhbShzKSA+PiBzdGQ6OmhleCA+PiBJTlQ7CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGNhc2UgMjU2OgogICAgICAgICAgICBmb3IodWludDhfdCB4ID0gMDsgeCA8IHMuc2l6ZSgpOyB4KyspCiAgICAgICAgICAgICAgICBJTlQgPSAoSU5UIDw8IDgpICsgKHVpbnQ4X3QpIHNbeF07CiAgICAgICAgICAgIGJyZWFrOwogICAgICAgIGRlZmF1bHQ6CiAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIGJyZWFrOwogICAgfTsKICAgIHJldHVybiBJTlQ7Cn0KCnRlbXBsYXRlPHR5cGVuYW1lIFQ+CnN0ZDo6c3RyaW5nIG1ha2VoZXgoVCB2YWx1ZSwgdW5zaWduZWQgaW50IHNpemUgPSAyICogc2l6ZW9mKFQpKXsKICAgIC8vIENoYW5nZXMgYSB2YWx1ZSB0byBpdHMgaGV4YWRlY2ltYWwgc3RyaW5nCiAgICBpZiAoIXNpemUpewogICAgICAgIHN0ZDo6c3RyaW5nc3RyZWFtIG91dDsKICAgICAgICBvdXQgPDwgc3RkOjpoZXggPDwgdmFsdWU7CiAgICAgICAgcmV0dXJuIG91dC5zdHIoKTsKICAgIH0KICAgIHN0ZDo6c3RyaW5nIG91dChzaXplLCAnMCcpOwogICAgd2hpbGUgKHZhbHVlICYmIHNpemUpewogICAgICAgIG91dFstLXNpemVdID0gaFt2YWx1ZSAmIDE1XTsKICAgICAgICB2YWx1ZSA+Pj0gNDsKICAgIH0KICAgIHJldHVybiBvdXQ7Cn0KCnN0ZDo6c3RyaW5nIGhleGxpZnkoY29uc3Qgc3RkOjpzdHJpbmcgJiBpbil7CiAgICAvLyBDaGFuZ2VzIGFuIEFTQ0lJIHN0cmluZyB0byBhbiBBU0NJSSBzdHJpbmcgY29udGFpbmluZyB0aGUKICAgIC8vIGhleGFkZWNpbWFsIHJlcHJlc2VudGF0aW9uIG9mIHRoZSBvcmlnbmFsIGNoYXJzCiAgICBzdGQ6OnN0cmluZyBvdXQgPSAiIjsKICAgIGZvcih1bnNpZ25lZCBpbnQgeCA9IDA7IHggPCBpbi5zaXplKCk7IHgrKykKICAgICAgICBvdXQgKz0gbWFrZWhleCgodW5zaWduZWQgY2hhcikgaW5beF0sIDIpOwogICAgcmV0dXJuIG91dDsKfQoKc3RkOjpzdHJpbmcgdW5oZXhsaWZ5KGNvbnN0IHN0ZDo6c3RyaW5nICYgaW4pewoJaWYgKGluLnNpemUoKSAmIDEpCiAgICAgICAgZXhpdCgxKTsKICAgIHN0ZDo6c3RyaW5nIG91dCA9ICIiOwoJZm9yKHVuc2lnbmVkIGludCB4ID0gMDsgeCA8IGluLnNpemUoKTsgeCArPSAyKQoJCWlmIChpbi5zdWJzdHIoeCwgMikgPT0gIjAwIikKCQkJb3V0ICs9IHN0ZDo6c3RyaW5nKDEsIDApOwoJCWVsc2UKCQkJb3V0ICs9ICh1bnNpZ25lZCBjaGFyKSAoKGguZmluZCh0b2xvd2VyKGluW3hdKSkgPDwgNCkgKyBoLmZpbmQodG9sb3dlcihpblt4ICsgMV0pKSk7CglyZXR1cm4gb3V0Owp9CgpjbGFzcyBNSVNUWTF7CiAgICBwcml2YXRlOgogICAgICAgIGJvb2wga2V5c2V0OwogICAgICAgIHVpbnQxNl90IEVLWzMyXTsKICAgICAgICB1aW50OF90IFM3VEFCTEVbMTI4XTsKICAgICAgICB1aW50MTZfdCBTOVRBQkxFWzUxMl07CgogICAgICAgIHVpbnQxNl90IEZJKHVpbnQxNl90IEZJX0lOLCB1aW50MTZfdCBGSV9LRVkpewogICAgICAgICAgICB1aW50MTZfdCBkOSA9IEZJX0lOID4+IDc7CiAgICAgICAgICAgIHVpbnQxNl90IGQ3ID0gRklfSU4gJiAweDdmOwogICAgICAgICAgICBkOSA9IFM5VEFCTEVbZDldIF4gZDc7CiAgICAgICAgICAgIGQ3ID0gUzdUQUJMRVtkN10gXiBkOTsKLy8gICAgICAgICAgICAoIGQ3ID0gZDcgJiAweDdmOyApCiAgICAgICAgICAgIGQ3ID0gZDcgXiAoRklfS0VZID4+IDkpOwogICAgICAgICAgICBkOSA9IGQ5IF4gKEZJX0tFWSAmIDB4MWZmKTsKICAgICAgICAgICAgZDkgPSBTOVRBQkxFW2Q5XSBeIGQ3OwogICAgICAgICAgICByZXR1cm4gKCh1aW50MTZfdCkgKGQ3ICYmIDB4ZmZmZlUpIDw8IDkpIHwgZDk7CiAgICAgICAgfQoKICAgICAgICB1aW50MzJfdCBGTyh1aW50MzJfdCBGT19JTiwgdWludDE2X3Qgayl7CiAgICAgICAgICAgIHVpbnQxNl90IHQwID0gRk9fSU4gPj4gMTY7CiAgICAgICAgICAgIHVpbnQxNl90IHQxID0gRk9fSU4gJiAweGZmZmY7CiAgICAgICAgICAgIHQwID0gdDAgXiBFS1trXTsKICAgICAgICAgICAgdDAgPSBGSSh0MCwgRUtbKGsrNSklOCs4XSk7CiAgICAgICAgICAgIHQwID0gdDAgXiB0MTsKICAgICAgICAgICAgdDEgPSB0MSBeIEVLWyhrKzIpJThdOwogICAgICAgICAgICB0MSA9IEZJKHQxLCBFS1soaysxKSU4KzhdKTsKICAgICAgICAgICAgdDEgPSB0MSBeIHQwOwogICAgICAgICAgICB0MCA9IHQwIF4gRUtbKGsrNyklOF07CiAgICAgICAgICAgIHQwID0gRkkodDAsIEVLWyhrKzMpJTgrOF0pOwogICAgICAgICAgICB0MCA9IHQwIF4gdDE7CiAgICAgICAgICAgIHQxID0gdDEgXiBFS1soays0KSU4XTsKICAgICAgICAgICAgcmV0dXJuICh0MSA8PCAxNikgfCB0MDsKICAgICAgICB9CgogICAgICAgIHVpbnQzMl90IEZMKHVpbnQzMl90IEZMX0lOLCB1aW50MzJfdCBrKXsKICAgICAgICAgICAgdWludDE2X3QgZDAgPSBGTF9JTiA+PiAxNjsKICAgICAgICAgICAgdWludDE2X3QgZDEgPSBGTF9JTiAmIDB4ZmZmZjsKICAgICAgICAgICAgaWYgKCEoayAmIDEpKXsKICAgICAgICAgICAgICAgZDEgPSBkMSBeIChkMCAmIEVLW2svMl0pOwogICAgICAgICAgICAgICBkMCA9IGQwIF4gKGQxIHwgRUtbKGsvMis2KSU4KzhdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICBkMSA9IGQxIF4gKGQwICYgRUtbKChrLTEpLzIrMiklOCs4XSk7CiAgICAgICAgICAgICAgIGQwID0gZDAgXiAoZDEgfCBFS1soKGstMSkvMis0KSU4XSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIChkMCA8PCAxNikgfCBkMTsKICAgICAgICB9CgogICAgICAgIHVpbnQzMl90IEZMSU5WKHVpbnQzMl90IEZMX0lOLCB1aW50MzJfdCBrKXsKICAgICAgICAgICAgdWludDE2X3QgZDAgPSBGTF9JTiA+PiAxNjsKICAgICAgICAgICAgdWludDE2X3QgZDEgPSBGTF9JTiAmIDB4ZmZmZjsKICAgICAgICAgICAgaWYgKCEoayAmIDEpKXsKICAgICAgICAgICAgICAgZDAgPSBkMCBeIChkMSB8IEVLWyhrLzIrNiklOCs4XSk7CiAgICAgICAgICAgICAgIGQxID0gZDEgXiAoZDAgJiBFS1trLzJdKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbHNlewogICAgICAgICAgICAgICBkMCA9IGQwIF4gKGQxIHwgRUtbKChrLTEpLzIrNCklOF0pOwogICAgICAgICAgICAgICBkMSA9IGQxIF4gKGQwICYgRUtbKChrLTEpLzIrMiklOCs4XSk7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIChkMCA8PCAxNikgfCBkMTsKICAgICAgICB9CgogICAgcHVibGljOgogICAgICAgIE1JU1RZMSgpIDoga2V5c2V0KGZhbHNlKSB7fQoKICAgICAgICBNSVNUWTEoc3RkOjpzdHJpbmcga2V5KXsKICAgICAgICAgICAga2V5c2V0ID0gZmFsc2U7CiAgICAgICAgICAgIHNldGtleShrZXkpOwogICAgICAgIH0KCiAgICAgICAgdm9pZCBzZXRrZXkoc3RkOjpzdHJpbmcga2V5KXsKICAgICAgICAgICAgaWYgKGtleXNldCkKICAgICAgICAgICAgICAgIGV4aXQoMik7CiAgICAgICAgICAgIHVpbnQ4X3QgUzdbMTI4XSA9IHsgMHgxYiwgMHgzMiwgMHgzMywgMHg1YSwgMHgzYiwgMHgxMCwgMHgxNywgMHg1NCwgMHg1YiwgMHgxYSwgMHg3MiwgMHg3MywgMHg2YiwgMHgyYywgMHg2NiwgMHg0OSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDFmLCAweDI0LCAweDEzLCAweDZjLCAweDM3LCAweDJlLCAweDNmLCAweDRhLCAweDVkLCAweDBmLCAweDQwLCAweDU2LCAweDI1LCAweDUxLCAweDFjLCAweDA0LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MGIsIDB4NDYsIDB4MjAsIDB4MGQsIDB4N2IsIDB4MzUsIDB4NDQsIDB4NDIsIDB4MmIsIDB4MWUsIDB4NDEsIDB4MTQsIDB4NGIsIDB4NzksIDB4MTUsIDB4NmYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwZSwgMHg1NSwgMHgwOSwgMHgzNiwgMHg3NCwgMHgwYywgMHg2NywgMHg1MywgMHgyOCwgMHgwYSwgMHg3ZSwgMHgzOCwgMHgwMiwgMHgwNywgMHg2MCwgMHgyOSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDE5LCAweDEyLCAweDY1LCAweDJmLCAweDMwLCAweDM5LCAweDA4LCAweDY4LCAweDVmLCAweDc4LCAweDJhLCAweDRjLCAweDY0LCAweDQ1LCAweDc1LCAweDNkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NTksIDB4NDgsIDB4MDMsIDB4NTcsIDB4N2MsIDB4NGYsIDB4NjIsIDB4M2MsIDB4MWQsIDB4MjEsIDB4NWUsIDB4MjcsIDB4NmEsIDB4NzAsIDB4NGQsIDB4M2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMSwgMHg2ZCwgMHg2ZSwgMHg2MywgMHgxOCwgMHg3NywgMHgyMywgMHgwNSwgMHgyNiwgMHg3NiwgMHgwMCwgMHgzMSwgMHgyZCwgMHg3YSwgMHg3ZiwgMHg2MSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweDUwLCAweDIyLCAweDExLCAweDA2LCAweDQ3LCAweDE2LCAweDUyLCAweDRlLCAweDcxLCAweDNlLCAweDY5LCAweDQzLCAweDM0LCAweDVjLCAweDU4LCAweDdkfTsKCiAgICAgICAgICAgIHVpbnQxNl90IFM5WzUxMl0gPSB7MHgxYzMsIDB4MGNiLCAweDE1MywgMHgxOWYsIDB4MWUzLCAweDBlOSwgMHgwZmIsIDB4MDM1LCAweDE4MSwgMHgwYjksIDB4MTE3LCAweDFlYiwgMHgxMzMsIDB4MDA5LCAweDAyZCwgMHgwZDMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwYzcsIDB4MTRhLCAweDAzNywgMHgwN2UsIDB4MGViLCAweDE2NCwgMHgxOTMsIDB4MWQ4LCAweDBhMywgMHgxMWUsIDB4MDU1LCAweDAyYywgMHgwMWQsIDB4MWEyLCAweDE2MywgMHgxMTgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNGIsIDB4MTUyLCAweDFkMiwgMHgwMGYsIDB4MDJiLCAweDAzMCwgMHgxM2EsIDB4MGU1LCAweDExMSwgMHgxMzgsIDB4MThlLCAweDA2MywgMHgwZTMsIDB4MGM4LCAweDFmNCwgMHgwMWIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMDEsIDB4MDlkLCAweDBmOCwgMHgxYTAsIDB4MTZkLCAweDFmMywgMHgwMWMsIDB4MTQ2LCAweDA3ZCwgMHgwZDEsIDB4MDgyLCAweDFlYSwgMHgxODMsIDB4MTJkLCAweDBmNCwgMHgxOWUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxZDMsIDB4MGRkLCAweDFlMiwgMHgxMjgsIDB4MWUwLCAweDBlYywgMHgwNTksIDB4MDkxLCAweDAxMSwgMHgxMmYsIDB4MDI2LCAweDBkYywgMHgwYjAsIDB4MThjLCAweDEwZiwgMHgxZjcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwZTcsIDB4MTZjLCAweDBiNiwgMHgwZjksIDB4MGQ4LCAweDE1MSwgMHgxMDEsIDB4MTRjLCAweDEwMywgMHgwYjgsIDB4MTU0LCAweDEyYiwgMHgxYWUsIDB4MDE3LCAweDA3MSwgMHgwMGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwNDcsIDB4MDU4LCAweDA3ZiwgMHgxYTQsIDB4MTM0LCAweDEyOSwgMHgwODQsIDB4MTVkLCAweDE5ZCwgMHgxYjIsIDB4MWEzLCAweDA0OCwgMHgwN2MsIDB4MDUxLCAweDFjYSwgMHgwMjMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxM2QsIDB4MWE3LCAweDE2NSwgMHgwM2IsIDB4MDQyLCAweDBkYSwgMHgxOTIsIDB4MGNlLCAweDBjMSwgMHgwNmIsIDB4MDlmLCAweDFmMSwgMHgxMmMsIDB4MTg0LCAweDBmYSwgMHgxOTYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxZTEsIDB4MTY5LCAweDE3ZCwgMHgwMzEsIDB4MTgwLCAweDEwYSwgMHgwOTQsIDB4MWRhLCAweDE4NiwgMHgxM2UsIDB4MTFjLCAweDA2MCwgMHgxNzUsIDB4MWNmLCAweDA2NywgMHgxMTksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwNjUsIDB4MDY4LCAweDA5OSwgMHgxNTAsIDB4MDA4LCAweDAwNywgMHgxN2MsIDB4MGI3LCAweDAyNCwgMHgwMTksIDB4MGRlLCAweDEyNywgMHgwZGIsIDB4MGU0LCAweDFhOSwgMHgwNTIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxMDksIDB4MDkwLCAweDE5YywgMHgxYzEsIDB4MDI4LCAweDFiMywgMHgxMzUsIDB4MTZhLCAweDE3NiwgMHgwZGYsIDB4MWU1LCAweDE4OCwgMHgwYzUsIDB4MTZlLCAweDFkZSwgMHgxYjEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwYzMsIDB4MWRmLCAweDAzNiwgMHgwZWUsIDB4MWVlLCAweDBmMCwgMHgwOTMsIDB4MDQ5LCAweDA5YSwgMHgxYjYsIDB4MDY5LCAweDA4MSwgMHgxMjUsIDB4MDBiLCAweDA1ZSwgMHgwYjQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNDksIDB4MWM3LCAweDE3NCwgMHgwM2UsIDB4MTNiLCAweDFiNywgMHgwOGUsIDB4MWM2LCAweDBhZSwgMHgwMTAsIDB4MDk1LCAweDFlZiwgMHgwNGUsIDB4MGYyLCAweDFmZCwgMHgwODUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwZmQsIDB4MGY2LCAweDBhMCwgMHgxNmYsIDB4MDgzLCAweDA4YSwgMHgxNTYsIDB4MDliLCAweDEzYywgMHgxMDcsIDB4MTY3LCAweDA5OCwgMHgxZDAsIDB4MWU5LCAweDAwMywgMHgxZmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwYmQsIDB4MTIyLCAweDA4OSwgMHgwZDIsIDB4MThmLCAweDAxMiwgMHgwMzMsIDB4MDZhLCAweDE0MiwgMHgwZWQsIDB4MTcwLCAweDExYiwgMHgwZTIsIDB4MTRmLCAweDE1OCwgMHgxMzEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNDcsIDB4MDVkLCAweDExMywgMHgxY2QsIDB4MDc5LCAweDE2MSwgMHgxYTUsIDB4MTc5LCAweDA5ZSwgMHgxYjQsIDB4MGNjLCAweDAyMiwgMHgxMzIsIDB4MDFhLCAweDBlOCwgMHgwMDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxODcsIDB4MWVkLCAweDE5NywgMHgwMzksIDB4MWJmLCAweDFkNywgMHgwMjcsIDB4MThiLCAweDBjNiwgMHgwOWMsIDB4MGQwLCAweDE0ZSwgMHgwNmMsIDB4MDM0LCAweDFmMiwgMHgwNmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwY2EsIDB4MDI1LCAweDBiYSwgMHgxOTEsIDB4MGZlLCAweDAxMywgMHgxMDYsIDB4MDJmLCAweDFhZCwgMHgxNzIsIDB4MWRiLCAweDBjMCwgMHgxMGIsIDB4MWQ2LCAweDBmNSwgMHgxZWMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxMGQsIDB4MDc2LCAweDExNCwgMHgxYWIsIDB4MDc1LCAweDEwYywgMHgxZTQsIDB4MTU5LCAweDA1NCwgMHgxMWYsIDB4MDRiLCAweDBjNCwgMHgxYmUsIDB4MGY3LCAweDAyOSwgMHgwYTQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMGUsIDB4MWYwLCAweDA3NywgMHgwNGQsIDB4MTdhLCAweDA4NiwgMHgwOGIsIDB4MGIzLCAweDE3MSwgMHgwYmYsIDB4MTBlLCAweDEwNCwgMHgwOTcsIDB4MTViLCAweDE2MCwgMHgxNjgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwZDcsIDB4MGJiLCAweDA2NiwgMHgxY2UsIDB4MGZjLCAweDA5MiwgMHgxYzUsIDB4MDZmLCAweDAxNiwgMHgwNGEsIDB4MGExLCAweDEzOSwgMHgwYWYsIDB4MGYxLCAweDE5MCwgMHgwMGEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxYWEsIDB4MTQzLCAweDE3YiwgMHgwNTYsIDB4MThkLCAweDE2NiwgMHgwZDQsIDB4MWZiLCAweDE0ZCwgMHgxOTQsIDB4MTlhLCAweDA4NywgMHgxZjgsIDB4MTIzLCAweDBhNywgMHgxYjgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxNDEsIDB4MDNjLCAweDFmOSwgMHgxNDAsIDB4MDJhLCAweDE1NSwgMHgxMWEsIDB4MWExLCAweDE5OCwgMHgwZDUsIDB4MTI2LCAweDFhZiwgMHgwNjEsIDB4MTJlLCAweDE1NywgMHgxZGMsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwNzIsIDB4MThhLCAweDBhYSwgMHgwOTYsIDB4MTE1LCAweDBlZiwgMHgwNDUsIDB4MDdiLCAweDA4ZCwgMHgxNDUsIDB4MDUzLCAweDA1ZiwgMHgxNzgsIDB4MGIyLCAweDAyZSwgMHgwMjAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxZDUsIDB4MDNmLCAweDFjOSwgMHgxZTcsIDB4MWFjLCAweDA0NCwgMHgwMzgsIDB4MDE0LCAweDBiMSwgMHgxNmIsIDB4MGFiLCAweDBiNSwgMHgwNWEsIDB4MTgyLCAweDFjOCwgMHgxZDQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwMTgsIDB4MTc3LCAweDA2NCwgMHgwY2YsIDB4MDZkLCAweDEwMCwgMHgxOTksIDB4MTMwLCAweDE1YSwgMHgwMDUsIDB4MTIwLCAweDFiYiwgMHgxYmQsIDB4MGUwLCAweDA0ZiwgMHgwZDYsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxM2YsIDB4MWM0LCAweDEyYSwgMHgwMTUsIDB4MDA2LCAweDBmZiwgMHgxOWIsIDB4MGE2LCAweDA0MywgMHgwODgsIDB4MDUwLCAweDE1ZiwgMHgxZTgsIDB4MTIxLCAweDA3MywgMHgxN2UsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwYmMsIDB4MGMyLCAweDBjOSwgMHgxNzMsIDB4MTg5LCAweDFmNSwgMHgwNzQsIDB4MWNjLCAweDFlNiwgMHgxYTgsIDB4MTk1LCAweDAxZiwgMHgwNDEsIDB4MDBkLCAweDFiYSwgMHgwMzIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwM2QsIDB4MWQxLCAweDA4MCwgMHgwYTgsIDB4MDU3LCAweDFiOSwgMHgxNjIsIDB4MTQ4LCAweDBkOSwgMHgxMDUsIDB4MDYyLCAweDA3YSwgMHgwMjEsIDB4MWZmLCAweDExMiwgMHgxMDgsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxYzAsIDB4MGE5LCAweDExZCwgMHgxYjAsIDB4MWE2LCAweDBjZCwgMHgwZjMsIDB4MDVjLCAweDEwMiwgMHgwNWIsIDB4MWQ5LCAweDE0NCwgMHgxZjYsIDB4MGFkLCAweDBhNSwgMHgwM2EsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgxY2IsIDB4MTM2LCAweDE3ZiwgMHgwNDYsIDB4MGUxLCAweDAxZSwgMHgxZGQsIDB4MGU2LCAweDEzNywgMHgxZmEsIDB4MTg1LCAweDA4YywgMHgwOGYsIDB4MDQwLCAweDFiNSwgMHgwYmUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgwNzgsIDB4MDAwLCAweDBhYywgMHgxMTAsIDB4MTVlLCAweDEyNCwgMHgwMDIsIDB4MWJjLCAweDBhMiwgMHgwZWEsIDB4MDcwLCAweDFmYywgMHgxMTYsIDB4MTVjLCAweDA0YywgMHgxYzJ9OwogICAgICAgICAgICBmb3IodWludDhfdCBpID0gMDsgaSA8IDEyODsgaSsrKQogICAgICAgICAgICAgICAgUzdUQUJMRVtpXSA9IFM3W2ldOwogICAgICAgICAgICBmb3IodWludDE2X3QgaSA9IDA7IGkgPCA1MTI7IGkrKykKICAgICAgICAgICAgICAgIFM5VEFCTEVbaV0gPSBTOVtpXTsKICAgICAgICAgICAgZm9yKHVpbnQ4X3QgaSA9IDA7IGkgPCA4OyBpKyspCiAgICAgICAgICAgICAgICBFS1tpXSA9ICgoa2V5W2kqMl0qMjU2KSAmIDB4ZmZmZikgKyAoa2V5W2kqMisxXSAmIDB4ZmYpOwogICAgICAgICAgICBmb3IodWludDhfdCBpID0gMDsgaSA8IDg7IGkrKyl7CiAgICAgICAgICAgICAgICBFS1tpKyA4XSA9IEZJKEVLW2ldLCBFS1soaSsxKSU4XSk7CiAgICAgICAgICAgICAgICBFS1tpKzE2XSA9IEVLW2krOF0gJiAweDFmZjsKICAgICAgICAgICAgICAgIEVLW2krMjRdID0gRUtbaSs4XSA+PiA5OwogICAgICAgICAgICB9CiAgICAgICAgICAgIGtleXNldCA9IHRydWU7CiAgICAgICAgfQoKICAgICAgICBzdGQ6OnN0cmluZyBlbmNyeXB0KHN0ZDo6c3RyaW5nIGRhdGEpewogICAgICAgICAgICBpZiAoIWtleXNldCkKICAgICAgICAgICAgICAgIGV4aXQoMSk7CiAgICAgICAgICAgIHVpbnQzMl90IEQwID0gdG9pbnQoZGF0YS5zdWJzdHIoMCwgNCksIDI1Nik7CiAgICAgICAgICAgIHVpbnQzMl90IEQxID0gdG9pbnQoZGF0YS5zdWJzdHIoNCwgNCksIDI1Nik7CiAgICAgICAgICAgIC8vIDAgcm91bmQKICAgICAgICAgICAgRDAgPSBGTChEMCwgMCk7CiAgICAgICAgICAgIEQxID0gRkwoRDEsIDEpOwogICAgICAgICAgICBEMSA9IEQxIF4gRk8oRDAsIDApOwogICAgICAgICAgICAvLyAxIHJvdW5kCiAgICAgICAgICAgIEQwID0gRDAgXiBGTyhEMSwgMSk7CiAgICAgICAgICAgIC8vIDIgcm91bmQKICAgICAgICAgICAgRDAgPSBGTChEMCwgMik7CiAgICAgICAgICAgIEQxID0gRkwoRDEsIDMpOwogICAgICAgICAgICBEMSA9IEQxIF4gRk8oRDAsIDIpOwogICAgICAgICAgICAvLyAzIHJvdW5kCiAgICAgICAgICAgIEQwID0gRDAgXiBGTyhEMSwgMyk7CiAgICAgICAgICAgIC8vIDQgcm91bmQKICAgICAgICAgICAgRDAgPSBGTChEMCwgNCk7CiAgICAgICAgICAgIEQxID0gRkwoRDEsIDUpOwogICAgICAgICAgICBEMSA9IEQxIF4gRk8oRDAsIDQpOwogICAgICAgICAgICAvLyA1IHJvdW5kCiAgICAgICAgICAgIEQwID0gRDAgXiBGTyhEMSwgNSk7CiAgICAgICAgICAgIC8vIDYgcm91bmQKICAgICAgICAgICAgRDAgPSBGTChEMCwgNik7CiAgICAgICAgICAgIEQxID0gRkwoRDEsIDcpOwogICAgICAgICAgICBEMSA9IEQxIF4gRk8oRDAsIDYpOwogICAgICAgICAgICAvLyA3IHJvdW5kCiAgICAgICAgICAgIEQwID0gRDAgXiBGTyhEMSwgNyk7CiAgICAgICAgICAgIC8vIGZpbmFsCiAgICAgICAgICAgIEQwID0gRkwoRDAsIDgpOwogICAgICAgICAgICBEMSA9IEZMKEQxLCA5KTsKICAgICAgICAgICAgcmV0dXJuIHVuaGV4bGlmeShtYWtlaGV4KEQxLCA4KSArIG1ha2VoZXgoRDAsIDgpKTsKICAgICAgICB9CgogICAgICAgIHN0ZDo6c3RyaW5nIGRlY3J5cHQoc3RkOjpzdHJpbmcgZGF0YSl7CiAgICAgICAgICAgIGlmICgha2V5c2V0KQogICAgICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICAgICAgdWludDMyX3QgRDAgPSB0b2ludChkYXRhLnN1YnN0cig0LCA0KSwgMjU2KTsKICAgICAgICAgICAgdWludDMyX3QgRDEgPSB0b2ludChkYXRhLnN1YnN0cigwLCA0KSwgMjU2KTsKICAgICAgICAgICAgRDAgPSBGTElOVihEMCwgOCk7CiAgICAgICAgICAgIEQxID0gRkxJTlYoRDEsIDkpOwogICAgICAgICAgICBEMCA9IEQwIF4gRk8oRDEsIDcpOwogICAgICAgICAgICBEMSA9IEQxIF4gRk8oRDAsIDYpOwogICAgICAgICAgICBEMCA9IEZMSU5WKEQwLCA2KTsKICAgICAgICAgICAgRDEgPSBGTElOVihEMSwgNyk7CiAgICAgICAgICAgIEQwID0gRDAgXiBGTyhEMSwgNSk7CiAgICAgICAgICAgIEQxID0gRDEgXiBGTyhEMCwgNCk7CiAgICAgICAgICAgIEQwID0gRkxJTlYoRDAsIDQpOwogICAgICAgICAgICBEMSA9IEZMSU5WKEQxLCA1KTsKICAgICAgICAgICAgRDAgPSBEMCBeIEZPKEQxLCAzKTsKICAgICAgICAgICAgRDEgPSBEMSBeIEZPKEQwLCAyKTsKICAgICAgICAgICAgRDAgPSBGTElOVihEMCwgMik7CiAgICAgICAgICAgIEQxID0gRkxJTlYoRDEsIDMpOwogICAgICAgICAgICBEMCA9IEQwIF4gRk8oRDEsIDEpOwogICAgICAgICAgICBEMSA9IEQxIF4gRk8oRDAsIDApOwogICAgICAgICAgICBEMCA9IEZMSU5WKEQwLCAwKTsKICAgICAgICAgICAgRDEgPSBGTElOVihEMSwgMSk7CiAgICAgICAgICAgIHJldHVybiB1bmhleGxpZnkobWFrZWhleChEMCwgOCkgKyBtYWtlaGV4KEQxKSk7CiAgICAgICAgfQp9OwoKaW50IG1haW4oKXsKCiAgICBzdGQ6OnN0cmluZyBrID0gdW5oZXhsaWZ5KCIwMDExMjIzMzQ0NTU2Njc3ODg5OWFhYmJjY2RkZWVmZiIpOwogICAgc3RkOjpzdHJpbmcgcCA9IHVuaGV4bGlmeSgiMDEyMzQ1Njc4OWFiY2RlZiIpOyAvLyBmZWRjYmE5ODc2NTQzMjEwCiAgICBzdGQ6OnN0cmluZyBjID0gdW5oZXhsaWZ5KCI4YjFkYTVmNTZhYjNkMDdjIik7IC8vIDA0YjY4MjQwYjEzYmU5NWQKCiAgICBNSVNUWTEgbShrKTsKICAgIHN0ZDo6c3RyaW5nIHRlc3RfcCA9IG0uZW5jcnlwdChwKTsKICAgIHN0ZDo6Y291dCA8PCBoZXhsaWZ5KHRlc3RfcCkgPDwgc3RkOjplbmRsOwogICAgc3RkOjpjb3V0IDw8IGhleGxpZnkobS5kZWNyeXB0KHRlc3RfcCkpIDw8IHN0ZDo6ZW5kbDsKCiAgICByZXR1cm4gMDsKfQ==
-
upload with new input
-
result: Success time: 0s memory: 3040 kB returned value: 0
2013cedaa983669d 0123456789abcdef


