// PureNoise CryptoLib (c) 1997-2004, PureNoise Ltd Vaduz #include #include #include #include "convert.h" #include static const unsigned char BASE_16_DIGITS[0x100] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\x0A\x0B\x0C\x0D\x0E\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\x0A\x0B\x0C\x0D\x0E\x0F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x00\xFF\xFF\xFF\xFF\x3F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; static const unsigned char BASE_64_DIGITS[0x100] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\x3F\xFF\xFF\xFF\xFF\xFF\xFF\x3E\xFF\xFF\xFF\x3F\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\xFF\xFF\xFF\xFF\x3E" "\xFF\x1A\x1B\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; static const unsigned char BASE_94_DIGITS[0x100] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E" "\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E" "\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"; /* static const unsigned char BASE_128_DIGITS[0x100] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\xFF\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E" "\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E" "\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\xFF" "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x5E\x5F\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x60\xFF\xFF\xFF\xFF\xFF\xFF\x61\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x62\x63\x64\x65\x66\x67\xFF\xFF\x68\x69\x6A\x6B\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x6C\x6D\x6E\x6F\x70\x71\xFF\xFF\x72\x73\x74\x75\xFF\xFF\xFF\xFF\xFF\xFF\x76\x77\x78\x79\x7A\xFF\xFF\x7B\x7C\x7D\x7E\x7F\xFF\xFF"; */ static const unsigned char BASE_222_DIGITS[0x100] = "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF" "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\xFF" "\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E" "\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E" "\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE" "\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xFF"; /* static const unsigned char BASE_252_DIGITS[0x100] = "\xFF\x00\x01\x02\x03\x04\xFF\x05\x06\x07\xFF\x08\x09\xFF\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B" "\x1C\x1D\x1E\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B" "\x3C\x3D\x3E\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B" "\x5C\x5D\x5E\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B" "\x7C\x7D\x7E\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B" "\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB" "\xBC\xBD\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB" "\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB"; */ static const unsigned char BASE_255_DIGITS[0x100] = "\xFF\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E" "\x1F\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E" "\x3F\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E" "\x5F\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E" "\x7F\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E" "\x9F\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE" "\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE" "\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE"; static const unsigned char BASE_16_CHARS[16] = "0123456789ABCDEF"; const unsigned char BASE_64_CHARS[64] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_$"; // It's not precisely BASE-64 but it has a major advantage over it: no popular separators in it! static const unsigned char BASE_94_CHARS[94] = "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F" // 15 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" // 16 "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F" // 16 "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F" // 16 "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F" // 16 "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E"; // 15 /* static const unsigned char BASE_128_CHARS[128] = "\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F" // 15 "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" // 16 "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F" // 16 "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F" // 16 "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F" // 16 "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E" // 15 "\xA0\xA1\xAD\xB4" // 4 "\xC0\xC1\xC2\xC3\xC4\xC5\xC8\xC9\xCA\xCB" // 10 "\xE0\xE1\xE2\xE3\xE4\xE5\xE8\xE9\xEA\xEB" // 10 "\xF2\xF3\xF4\xF5\xF6\xF9\xFA\xFB\xFC\xFD"; // 10 */ static const unsigned char BASE_222_CHARS[222] = "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E" "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF" "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF" "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE"; /* static const unsigned char BASE_252_CHARS[252] = "\x01\x02\x03\x04\x05" "\x07\x08\x09" "\x0B\x0C" "\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F" "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF" "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF" "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"; */ static const unsigned char BASE_255_CHARS[255] = "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F" "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2A\x2B\x2C\x2D\x2E\x2F\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3A\x3B\x3C\x3D\x3E\x3F" "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4A\x4B\x4C\x4D\x4E\x4F\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5A\x5B\x5C\x5D\x5E\x5F" "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6A\x6B\x6C\x6D\x6E\x6F\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7A\x7B\x7C\x7D\x7E\x7F" "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8A\x8B\x8C\x8D\x8E\x8F\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F" "\xA0\xA1\xA2\xA3\xA4\xA5\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD\xBE\xBF" "\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF" "\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF"; static __forceinline void big_copy (const unsigned long *x, unsigned long *y) { if (x != y) { memcpy (y, x, (x[0] + 1) * sizeof (unsigned long)); y[x[0]+1] = 0; } } static __inline void big_padd (const unsigned long *x, const unsigned long *y, unsigned long *z) { // add two big numbers, z = x + y where x and y are positive unsigned long lx = x[0], ly = y[0], i = 1, carry = 0, psum, la, lz; if (ly > lx) { la = lx; lz = ly; if (x != z) { big_copy (y, z); } else la = ly; } else { la = ly; lz = lx; if (y != z) { big_copy (x, z); } else la = lx; } z[z[0] = lz + 1] = 0; for (; (i <= la) || carry; i++) { // add by columns psum = x[i] + y[i] + carry; if (psum > x[i]) carry = 0; else if (psum < x[i]) carry = 1; z[i] = psum; } if (z[z[0]] == 0) z[0]--; else z[z[0] + 1] = 0; } #if defined (_MSC_VER) #pragma warning (push) #pragma warning (disable:4731) #endif static __inline void big_pmul (const unsigned long *x, const unsigned long sn, unsigned long *z) { unsigned long m,xl; #if (CRYPTO_INLINE_ASM != 3) && (CRYPTO_INLINE_ASM != 4) OCTET p = {{0}}; #define carry p.D[ord2(1)] #else unsigned long carry = 0; #endif if (x != z) { z[0] = 0; z[1] = 0; if (sn == 0) return; } else if (sn == 0) { z[0] = 0; z[1] = 0; return; } else if (sn == 1) { big_copy (x, z); return; } m = 0; xl = x[0]; // inline 80x86 assembly - substitutes for loop below #if CRYPTO_INLINE_ASM == 3 ASM mov ecx,xl ASM or ecx,ecx ASM je _mrarth1_out1 ASM mov ebx,sn ASM mov edi,z ASM mov esi,x ASM add esi,4 ASM add edi,4 ASM push ebp ASM xor ebp,ebp _mrarth1_tcl1: ASM mov eax,[esi] ASM add esi,4 ASM mul ebx ASM add eax,ebp ASM adc edx,0 ASM mov [edi],eax ASM add edi,4 ASM mov ebp,edx ASM dec ecx ASM jnz _mrarth1_tcl1 ASM mov eax,ebp ASM pop ebp ASM mov carry,eax _mrarth1_out1: #elif CRYPTO_INLINE_ASM == 4 ASM ("\n" "movl %4,%%ecx\n" "orl %%ecx,%%ecx\n" "je 1f\n" "movl %3,%%ebx\n" "movl %1,%%edi\n" "movl %2,%%esi\n" "addl $4,%%esi\n" "addl $4,%%edi\n" "pushl %%ebp\n" "xorl %%ebp,%%ebp\n" "0:\n" "movl (%%esi),%%eax\n" "addl $4,%%esi\n" "mull %%ebx\n" "addl %%ebp,%%eax\n" "adcl $0,%%edx\n" "movl %%eax,(%%edi)\n" "addl $4,%%edi\n" "movl %%edx,%%ebp\n" "decl %%ecx\n" "jnz 0b\n" "movl %%ebp,%%eax\n" "popl %%ebp\n" "movl %%eax,%0\n" "1:" :"=g"(carry) :"g"(z),"g"(x),"g"(sn),"g"(xl) :"eax","edi","esi","ebx","ecx","edx","memory" ); #else for (m = 1; m <= xl; m++) { p.Q[0] = (unsigned __int64) x[m] * sn + p.D[ord2(1)]; z[m] = p.D[ord2(0)]; } #endif if (carry) { z[++xl] = carry; } z[0] = xl; z[xl + 1] = 0; #ifdef carry #undef carry #endif } static __inline unsigned long big_sdiv (const unsigned long *x, const unsigned long sn, unsigned long *z) { unsigned long xl = x[0], i; #if (CRYPTO_INLINE_ASM != 3) && (CRYPTO_INLINE_ASM != 4) OCTET p = {{0}}; #define sr p.D[ord2(1)] #else unsigned long sr; #endif if (sn==1) // special case { big_copy(x,z); return 0; } if (x != z) { z[0] = 0; z[1] = 0; } // inline - substitutes for loop below #if CRYPTO_INLINE_ASM == 3 ASM mov ecx,xl ASM xor eax,eax ASM or ecx,ecx ASM je _mrarth1_out2 ASM mov ebx,ecx ASM shl ebx,2 ASM mov esi, x ASM add esi,ebx ASM mov edi, z ASM add edi,ebx ASM mov ebx,sn ASM push ebp ASM xor ebp,ebp _mrarth1_tcl2: ASM mov edx,ebp ASM mov eax,[esi] ASM sub esi,4 ASM div ebx ASM mov ebp,edx ASM mov [edi],eax ASM sub edi,4 ASM dec ecx ASM jnz _mrarth1_tcl2 ASM mov eax,ebp ASM pop ebp _mrarth1_out2:; ASM mov sr,eax #elif CRYPTO_INLINE_ASM == 4 ASM ("\n" "movl %4,%%ecx\n" "xorl %%eax,%%eax\n" "orl %%ecx,%%ecx\n" "je 3f\n" "movl %%ecx,%%ebx\n" "shll $2,%%ebx\n" "movl %2,%%esi\n" "addl %%ebx,%%esi\n" "movl %1,%%edi\n" "addl %%ebx,%%edi\n" "movl %3,%%ebx\n" "pushl %%ebp\n" "xorl %%ebp,%%ebp\n" "2:\n" "movl %%ebp,%%edx\n" "movl (%%esi),%%eax\n" "subl $4,%%esi\n" "divl %%ebx\n" "movl %%edx,%%ebp\n" "movl %%eax,(%%edi)\n" "subl $4,%%edi\n" "decl %%ecx\n" "jnz 2b\n" "movl %%ebp,%%eax\n" "popl %%ebp\n" "3:\n" "movl %%eax,%0\n" "\n" :"=g"(sr) :"g"(z),"g"(x),"g"(sn),"g"(xl) :"eax","edi","esi","ebx","ecx","edx","memory" ); #else for (i = xl; i > 0; i--) { p.D[ord2(0)] = x[i]; z[i] = (unsigned long)(p.Q[0] / sn); p.D[ord2(1)] = (unsigned long)(p.Q[0] % sn); } #endif for (i = x[0]; i && (z[i] == 0); i--); z[(z[0] = i) + 1] = 0; return sr; #ifdef sr #undef sr #endif } #if defined (_MSC_VER) #pragma warning (pop) #endif unsigned char * big_to_str (const unsigned long *inbig, unsigned char *outstr, const unsigned char base, const unsigned long total_chars) { unsigned long d[0x103]; // numbers up to 8192 bit are handled ok here signed long i; const unsigned char *base_chars; d[0] = 0; if ((outstr == NULL) || (inbig == NULL)) return outstr; switch (base) { case 16: base_chars = BASE_16_CHARS; break; case 64: base_chars = BASE_64_CHARS; break; case 94: base_chars = BASE_94_CHARS; break; // case 128: // base_chars = BASE_128_CHARS; // break; case 222: base_chars = BASE_222_CHARS; break; // case 252: // base_chars = BASE_252_CHARS; // break; case 255: base_chars = BASE_255_CHARS; break; default: return NULL; } big_copy (inbig, d); for (i = inbig[0]; (i != 0) && (d[i] == 0); i--); d[0] = i; outstr[total_chars] = '\0'; for (i = total_chars - 1; i >= 0; i--) outstr[i] = base_chars[(unsigned char) big_sdiv (d, base, d)]; return outstr + total_chars; } unsigned long str_to_big (const unsigned char *instr, unsigned long *outbig, const unsigned char base, const unsigned long total_chars) { unsigned long chars = total_chars; unsigned long d[3] = {1, 0, 0}; const unsigned char *base_digits; unsigned char c; if (instr == NULL) return 0; outbig[0] = 0; outbig[1] = 0; switch (base) { case 16: base_digits = BASE_16_DIGITS; break; case 64: base_digits = BASE_64_DIGITS; break; case 94: base_digits = BASE_94_DIGITS; break; // case 128: // base_digits = BASE_128_DIGITS; // break; case 222: base_digits = BASE_222_DIGITS; break; // case 252: // base_digits = BASE_252_DIGITS; // break; case 255: base_digits = BASE_255_DIGITS; break; default: return 0; } while (chars) { c = base_digits[*instr++]; if (c >= base) break; // what is it doing there? d[1] = c; big_pmul (outbig, base, outbig); big_padd (outbig, d, outbig); chars--; } return total_chars - chars; } unsigned char * bytes_to_str (const unsigned char *inbytes, unsigned char *outstr, const unsigned char base, const unsigned long nbytes) { unsigned long c = 0, i, n = nbytes, base_mask, base_bits; const unsigned char *base_chars; switch (base) { case 16: base_bits = 4; base_mask = 0x0F; base_chars = BASE_16_CHARS; break; case 64: base_bits = 6; base_mask = 0x3F; base_chars = BASE_64_CHARS; break; // case 128: // base_bits = 7; // base_mask = 0x7F; // base_chars = BASE_128_CHARS; // break; default: return 0; } for (i = 0; n > 0; inbytes++, n--) { c = (c << 8) | *inbytes; i += 8; while (i >= base_bits) { *outstr++ = base_chars[(c >> (i - base_bits)) & base_mask]; i -= base_bits; } } if (i) { *outstr++ = base_chars[rotl32 (c, base_bits - i) & base_mask]; } *outstr = '\0'; return outstr; } unsigned long str_to_bytes (const unsigned char *instr, unsigned char *outbytes, const unsigned char base, const unsigned long maxbytes) { unsigned long c = 0, i, total, base_mask, base_bits; const unsigned char *base_digits; switch (base) { case 16: base_bits = 4; base_mask = 0x0F; base_digits = BASE_16_DIGITS; break; case 64: base_bits = 6; base_mask = 0x3F; base_digits = BASE_64_DIGITS; break; // case 128: // base_bits = 7; // base_mask = 0x7F; // base_digits = BASE_128_DIGITS; // break; default: return 0; } for (i = 0, total = 0; total < maxbytes; instr++) { if (base_digits[*instr] > base_mask) { if (i >= 8) { i -= 8; *outbytes++ = (unsigned char) (c >> i); total++; } if (i) { *outbytes++ = (unsigned char) (c >> i); total++; break; } } c = (c << base_bits) | base_digits[*instr]; i += base_bits; if (i > 8) { i -= 8; *outbytes++ = (unsigned char) (c >> i); total++; } } return total; }