├── README.md ├── build-cmd ├── linux ├── macos └── windows └── src ├── aes.h ├── base58.cpp ├── base58.h ├── base64.cpp ├── base64.h ├── export.cpp ├── md5.cpp ├── md5.h ├── rsa.cpp ├── rsa.h ├── tea ├── xtea.cpp └── xtea.h ├── test.cpp └── utils ├── bigint.cpp ├── bigint.h ├── random.h ├── types.h └── utility.h /README.md: -------------------------------------------------------------------------------- 1 | # A C++ Library of encryption, decryption, encode, hash, and message digital signatures. 2 | 3 | The same functional and fully compatible dlang project: 4 | https://github.com/shove70/crypto 5 | 6 | For more examples, see dlang project, Thanks. 7 | 8 | ! This project has been included in the shove.c project, and subsequent updates will only be included in the shove.c project: 9 | https://github.com/shove70/shove.c -------------------------------------------------------------------------------- /build-cmd/linux: -------------------------------------------------------------------------------- 1 | mkdir Release 2 | mkdir Release/src 3 | mkdir Release/src/utils 4 | mkdir Release/src/tea 5 | cd Release 6 | 7 | g++ -std=c++11 -fPIC -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/utils/bigint.d" -MT"src/utils/bigint.o" -o "src/utils/bigint.o" "../src/utils/bigint.cpp" 8 | g++ -std=c++11 -fPIC -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/tea/xtea.d" -MT"src/tea/xtea.o" -o "src/tea/xtea.o" "../src/tea/xtea.cpp" 9 | g++ -std=c++11 -fPIC -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/base58.d" -MT"src/base58.o" -o "src/base58.o" "../src/base58.cpp" 10 | g++ -std=c++11 -fPIC -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/base64.d" -MT"src/base64.o" -o "src/base64.o" "../src/base64.cpp" 11 | g++ -std=c++11 -fPIC -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/export.d" -MT"src/export.o" -o "src/export.o" "../src/export.cpp" 12 | g++ -std=c++11 -fPIC -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/md5.d" -MT"src/md5.o" -o "src/md5.o" "../src/md5.cpp" 13 | g++ -std=c++11 -fPIC -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/rsa.d" -MT"src/rsa.o" -o "src/rsa.o" "../src/rsa.cpp" 14 | g++ -shared -o "libcrypt.so" ./src/utils/bigint.o ./src/tea/xtea.o ./src/base58.o ./src/base64.o ./src/export.o ./src/md5.o ./src/rsa.o 15 | -------------------------------------------------------------------------------- /build-cmd/macos: -------------------------------------------------------------------------------- 1 | mkdir Release 2 | mkdir Release/src 3 | mkdir Release/src/utils 4 | mkdir Release/src/tea 5 | cd Release 6 | 7 | g++ -std=c++11 -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/utils/bigint.d" -MT"src/utils/bigint.o" -o "src/utils/bigint.o" "../src/utils/bigint.cpp" 8 | g++ -std=c++11 -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/tea/xtea.d" -MT"src/tea/xtea.o" -o "src/tea/xtea.o" "../src/tea/xtea.cpp" 9 | g++ -std=c++11 -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/base58.d" -MT"src/base58.o" -o "src/base58.o" "../src/base58.cpp" 10 | g++ -std=c++11 -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/base64.d" -MT"src/base64.o" -o "src/base64.o" "../src/base64.cpp" 11 | g++ -std=c++11 -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/export.d" -MT"src/export.o" -o "src/export.o" "../src/export.cpp" 12 | g++ -std=c++11 -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/md5.d" -MT"src/md5.o" -o "src/md5.o" "../src/md5.cpp" 13 | g++ -std=c++11 -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/rsa.d" -MT"src/rsa.o" -o "src/rsa.o" "../src/rsa.cpp" 14 | g++ -dynamiclib -o "libcrypt.dylib" ./src/utils/bigint.o ./src/tea/xtea.o ./src/base58.o ./src/base64.o ./src/export.o ./src/md5.o ./src/rsa.o 15 | -------------------------------------------------------------------------------- /build-cmd/windows: -------------------------------------------------------------------------------- 1 | md Release 2 | mkdir Release/src 3 | mkdir Release/src/utils 4 | mkdir Release/src/tea 5 | cd Release 6 | 7 | g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/utils/bigint.d" -MT"src/utils/bigint.o" -o "src/utils/bigint.o" "../src/utils/bigint.cpp" 8 | g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/tea/xtea.d" -MT"src/tea/xtea.o" -o "src/tea/xtea.o" "../src/tea/xtea.cpp" 9 | g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/base58.d" -MT"src/base58.o" -o "src/base58.o" "../src/base58.cpp" 10 | g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/base64.d" -MT"src/base64.o" -o "src/base64.o" "../src/base64.cpp" 11 | g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/export.d" -MT"src/export.o" -o "src/export.o" "../src/export.cpp" 12 | g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/md5.d" -MT"src/md5.o" -o "src/md5.o" "../src/md5.cpp" 13 | g++ -O3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/rsa.d" -MT"src/rsa.o" -o "src/rsa.o" "../src/rsa.cpp" 14 | g++ -shared -fPIC -o "crypt.dll" ./src/utils/bigint.o ./src/tea/xtea.o ./src/base58.o ./src/base64.o ./src/export.o ./src/md5.o ./src/rsa.o 15 | -------------------------------------------------------------------------------- /src/aes.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "utils/types.h" 7 | #include "utils/utility.h" 8 | 9 | using namespace std; 10 | using namespace crypto::utils; 11 | 12 | namespace crypto 13 | { 14 | namespace aes 15 | { 16 | 17 | static const ubyte sbox[] = { 0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5, 0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76, 0xca, 0x82, 0xc9, 0x7d, 18 | 0xfa, 0x59, 0x47, 0xf0, 0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0, 0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc, 0x34, 0xa5, 0xe5, 0xf1, 19 | 0x71, 0xd8, 0x31, 0x15, 0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a, 0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75, 0x09, 0x83, 0x2c, 0x1a, 20 | 0x1b, 0x6e, 0x5a, 0xa0, 0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84, 0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b, 0x6a, 0xcb, 0xbe, 0x39, 21 | 0x4a, 0x4c, 0x58, 0xcf, 0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85, 0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8, 0x51, 0xa3, 0x40, 0x8f, 22 | 0x92, 0x9d, 0x38, 0xf5, 0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2, 0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17, 0xc4, 0xa7, 0x7e, 0x3d, 23 | 0x64, 0x5d, 0x19, 0x73, 0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88, 0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb, 0xe0, 0x32, 0x3a, 0x0a, 24 | 0x49, 0x06, 0x24, 0x5c, 0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79, 0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9, 0x6c, 0x56, 0xf4, 0xea, 25 | 0x65, 0x7a, 0xae, 0x08, 0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6, 0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a, 0x70, 0x3e, 0xb5, 0x66, 26 | 0x48, 0x03, 0xf6, 0x0e, 0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e, 0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94, 0x9b, 0x1e, 0x87, 0xe9, 27 | 0xce, 0x55, 0x28, 0xdf, 0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68, 0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16 }; 28 | 29 | static const ubyte isbox[] = { 0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38, 0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb, 0x7c, 0xe3, 0x39, 0x82, 30 | 0x9b, 0x2f, 0xff, 0x87, 0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb, 0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d, 0xee, 0x4c, 0x95, 0x0b, 31 | 0x42, 0xfa, 0xc3, 0x4e, 0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2, 0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25, 0x72, 0xf8, 0xf6, 0x64, 32 | 0x86, 0x68, 0x98, 0x16, 0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92, 0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda, 0x5e, 0x15, 0x46, 0x57, 33 | 0xa7, 0x8d, 0x9d, 0x84, 0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a, 0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06, 0xd0, 0x2c, 0x1e, 0x8f, 34 | 0xca, 0x3f, 0x0f, 0x02, 0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b, 0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea, 0x97, 0xf2, 0xcf, 0xce, 35 | 0xf0, 0xb4, 0xe6, 0x73, 0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85, 0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e, 0x47, 0xf1, 0x1a, 0x71, 36 | 0x1d, 0x29, 0xc5, 0x89, 0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b, 0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20, 0x9a, 0xdb, 0xc0, 0xfe, 37 | 0x78, 0xcd, 0x5a, 0xf4, 0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31, 0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f, 0x60, 0x51, 0x7f, 0xa9, 38 | 0x19, 0xb5, 0x4a, 0x0d, 0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef, 0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0, 0xc8, 0xeb, 0xbb, 0x3c, 39 | 0x83, 0x53, 0x99, 0x61, 0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26, 0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d }; 40 | 41 | static const uint t1[] = { 42 | 0xa56363c6, 0x847c7cf8, 0x997777ee, 0x8d7b7bf6, 0x0df2f2ff, 0xbd6b6bd6, 0xb16f6fde, 0x54c5c591, 0x50303060, 0x03010102, 43 | 0xa96767ce, 0x7d2b2b56, 0x19fefee7, 0x62d7d7b5, 0xe6abab4d, 0x9a7676ec, 0x45caca8f, 0x9d82821f, 0x40c9c989, 0x877d7dfa, 44 | 0x15fafaef, 0xeb5959b2, 0xc947478e, 0x0bf0f0fb, 0xecadad41, 0x67d4d4b3, 0xfda2a25f, 0xeaafaf45, 0xbf9c9c23, 0xf7a4a453, 45 | 0x967272e4, 0x5bc0c09b, 0xc2b7b775, 0x1cfdfde1, 0xae93933d, 0x6a26264c, 0x5a36366c, 0x413f3f7e, 0x02f7f7f5, 0x4fcccc83, 46 | 0x5c343468, 0xf4a5a551, 0x34e5e5d1, 0x08f1f1f9, 0x937171e2, 0x73d8d8ab, 0x53313162, 0x3f15152a, 0x0c040408, 0x52c7c795, 47 | 0x65232346, 0x5ec3c39d, 0x28181830, 0xa1969637, 0x0f05050a, 0xb59a9a2f, 0x0907070e, 0x36121224, 0x9b80801b, 0x3de2e2df, 48 | 0x26ebebcd, 0x6927274e, 0xcdb2b27f, 0x9f7575ea, 0x1b090912, 0x9e83831d, 0x742c2c58, 0x2e1a1a34, 0x2d1b1b36, 0xb26e6edc, 49 | 0xee5a5ab4, 0xfba0a05b, 0xf65252a4, 0x4d3b3b76, 0x61d6d6b7, 0xceb3b37d, 0x7b292952, 0x3ee3e3dd, 0x712f2f5e, 0x97848413, 50 | 0xf55353a6, 0x68d1d1b9, 0x00000000, 0x2cededc1, 0x60202040, 0x1ffcfce3, 0xc8b1b179, 0xed5b5bb6, 0xbe6a6ad4, 0x46cbcb8d, 51 | 0xd9bebe67, 0x4b393972, 0xde4a4a94, 0xd44c4c98, 0xe85858b0, 0x4acfcf85, 0x6bd0d0bb, 0x2aefefc5, 0xe5aaaa4f, 0x16fbfbed, 52 | 0xc5434386, 0xd74d4d9a, 0x55333366, 0x94858511, 0xcf45458a, 0x10f9f9e9, 0x06020204, 0x817f7ffe, 0xf05050a0, 0x443c3c78, 53 | 0xba9f9f25, 0xe3a8a84b, 0xf35151a2, 0xfea3a35d, 0xc0404080, 0x8a8f8f05, 0xad92923f, 0xbc9d9d21, 0x48383870, 0x04f5f5f1, 54 | 0xdfbcbc63, 0xc1b6b677, 0x75dadaaf, 0x63212142, 0x30101020, 0x1affffe5, 0x0ef3f3fd, 0x6dd2d2bf, 0x4ccdcd81, 0x140c0c18, 55 | 0x35131326, 0x2fececc3, 0xe15f5fbe, 0xa2979735, 0xcc444488, 0x3917172e, 0x57c4c493, 0xf2a7a755, 0x827e7efc, 0x473d3d7a, 56 | 0xac6464c8, 0xe75d5dba, 0x2b191932, 0x957373e6, 0xa06060c0, 0x98818119, 0xd14f4f9e, 0x7fdcdca3, 0x66222244, 0x7e2a2a54, 57 | 0xab90903b, 0x8388880b, 0xca46468c, 0x29eeeec7, 0xd3b8b86b, 0x3c141428, 0x79dedea7, 0xe25e5ebc, 0x1d0b0b16, 0x76dbdbad, 58 | 0x3be0e0db, 0x56323264, 0x4e3a3a74, 0x1e0a0a14, 0xdb494992, 0x0a06060c, 0x6c242448, 0xe45c5cb8, 0x5dc2c29f, 0x6ed3d3bd, 59 | 0xefacac43, 0xa66262c4, 0xa8919139, 0xa4959531, 0x37e4e4d3, 0x8b7979f2, 0x32e7e7d5, 0x43c8c88b, 0x5937376e, 0xb76d6dda, 60 | 0x8c8d8d01, 0x64d5d5b1, 0xd24e4e9c, 0xe0a9a949, 0xb46c6cd8, 0xfa5656ac, 0x07f4f4f3, 0x25eaeacf, 0xaf6565ca, 0x8e7a7af4, 61 | 0xe9aeae47, 0x18080810, 0xd5baba6f, 0x887878f0, 0x6f25254a, 0x722e2e5c, 0x241c1c38, 0xf1a6a657, 0xc7b4b473, 0x51c6c697, 62 | 0x23e8e8cb, 0x7cdddda1, 0x9c7474e8, 0x211f1f3e, 0xdd4b4b96, 0xdcbdbd61, 0x868b8b0d, 0x858a8a0f, 0x907070e0, 0x423e3e7c, 63 | 0xc4b5b571, 0xaa6666cc, 0xd8484890, 0x05030306, 0x01f6f6f7, 0x120e0e1c, 0xa36161c2, 0x5f35356a, 0xf95757ae, 0xd0b9b969, 64 | 0x91868617, 0x58c1c199, 0x271d1d3a, 0xb99e9e27, 0x38e1e1d9, 0x13f8f8eb, 0xb398982b, 0x33111122, 0xbb6969d2, 0x70d9d9a9, 65 | 0x898e8e07, 0xa7949433, 0xb69b9b2d, 0x221e1e3c, 0x92878715, 0x20e9e9c9, 0x49cece87, 0xff5555aa, 0x78282850, 0x7adfdfa5, 66 | 0x8f8c8c03, 0xf8a1a159, 0x80898909, 0x170d0d1a, 0xdabfbf65, 0x31e6e6d7, 0xc6424284, 0xb86868d0, 0xc3414182, 0xb0999929, 67 | 0x772d2d5a, 0x110f0f1e, 0xcbb0b07b, 0xfc5454a8, 0xd6bbbb6d, 0x3a16162c, }; 68 | 69 | static const uint t2[] = { 70 | 0x6363c6a5, 0x7c7cf884, 0x7777ee99, 0x7b7bf68d, 0xf2f2ff0d, 0x6b6bd6bd, 0x6f6fdeb1, 0xc5c59154, 0x30306050, 0x01010203, 71 | 0x6767cea9, 0x2b2b567d, 0xfefee719, 0xd7d7b562, 0xabab4de6, 0x7676ec9a, 0xcaca8f45, 0x82821f9d, 0xc9c98940, 0x7d7dfa87, 72 | 0xfafaef15, 0x5959b2eb, 0x47478ec9, 0xf0f0fb0b, 0xadad41ec, 0xd4d4b367, 0xa2a25ffd, 0xafaf45ea, 0x9c9c23bf, 0xa4a453f7, 73 | 0x7272e496, 0xc0c09b5b, 0xb7b775c2, 0xfdfde11c, 0x93933dae, 0x26264c6a, 0x36366c5a, 0x3f3f7e41, 0xf7f7f502, 0xcccc834f, 74 | 0x3434685c, 0xa5a551f4, 0xe5e5d134, 0xf1f1f908, 0x7171e293, 0xd8d8ab73, 0x31316253, 0x15152a3f, 0x0404080c, 0xc7c79552, 75 | 0x23234665, 0xc3c39d5e, 0x18183028, 0x969637a1, 0x05050a0f, 0x9a9a2fb5, 0x07070e09, 0x12122436, 0x80801b9b, 0xe2e2df3d, 76 | 0xebebcd26, 0x27274e69, 0xb2b27fcd, 0x7575ea9f, 0x0909121b, 0x83831d9e, 0x2c2c5874, 0x1a1a342e, 0x1b1b362d, 0x6e6edcb2, 77 | 0x5a5ab4ee, 0xa0a05bfb, 0x5252a4f6, 0x3b3b764d, 0xd6d6b761, 0xb3b37dce, 0x2929527b, 0xe3e3dd3e, 0x2f2f5e71, 0x84841397, 78 | 0x5353a6f5, 0xd1d1b968, 0x00000000, 0xededc12c, 0x20204060, 0xfcfce31f, 0xb1b179c8, 0x5b5bb6ed, 0x6a6ad4be, 0xcbcb8d46, 79 | 0xbebe67d9, 0x3939724b, 0x4a4a94de, 0x4c4c98d4, 0x5858b0e8, 0xcfcf854a, 0xd0d0bb6b, 0xefefc52a, 0xaaaa4fe5, 0xfbfbed16, 80 | 0x434386c5, 0x4d4d9ad7, 0x33336655, 0x85851194, 0x45458acf, 0xf9f9e910, 0x02020406, 0x7f7ffe81, 0x5050a0f0, 0x3c3c7844, 81 | 0x9f9f25ba, 0xa8a84be3, 0x5151a2f3, 0xa3a35dfe, 0x404080c0, 0x8f8f058a, 0x92923fad, 0x9d9d21bc, 0x38387048, 0xf5f5f104, 82 | 0xbcbc63df, 0xb6b677c1, 0xdadaaf75, 0x21214263, 0x10102030, 0xffffe51a, 0xf3f3fd0e, 0xd2d2bf6d, 0xcdcd814c, 0x0c0c1814, 83 | 0x13132635, 0xececc32f, 0x5f5fbee1, 0x979735a2, 0x444488cc, 0x17172e39, 0xc4c49357, 0xa7a755f2, 0x7e7efc82, 0x3d3d7a47, 84 | 0x6464c8ac, 0x5d5dbae7, 0x1919322b, 0x7373e695, 0x6060c0a0, 0x81811998, 0x4f4f9ed1, 0xdcdca37f, 0x22224466, 0x2a2a547e, 85 | 0x90903bab, 0x88880b83, 0x46468cca, 0xeeeec729, 0xb8b86bd3, 0x1414283c, 0xdedea779, 0x5e5ebce2, 0x0b0b161d, 0xdbdbad76, 86 | 0xe0e0db3b, 0x32326456, 0x3a3a744e, 0x0a0a141e, 0x494992db, 0x06060c0a, 0x2424486c, 0x5c5cb8e4, 0xc2c29f5d, 0xd3d3bd6e, 87 | 0xacac43ef, 0x6262c4a6, 0x919139a8, 0x959531a4, 0xe4e4d337, 0x7979f28b, 0xe7e7d532, 0xc8c88b43, 0x37376e59, 0x6d6ddab7, 88 | 0x8d8d018c, 0xd5d5b164, 0x4e4e9cd2, 0xa9a949e0, 0x6c6cd8b4, 0x5656acfa, 0xf4f4f307, 0xeaeacf25, 0x6565caaf, 0x7a7af48e, 89 | 0xaeae47e9, 0x08081018, 0xbaba6fd5, 0x7878f088, 0x25254a6f, 0x2e2e5c72, 0x1c1c3824, 0xa6a657f1, 0xb4b473c7, 0xc6c69751, 90 | 0xe8e8cb23, 0xdddda17c, 0x7474e89c, 0x1f1f3e21, 0x4b4b96dd, 0xbdbd61dc, 0x8b8b0d86, 0x8a8a0f85, 0x7070e090, 0x3e3e7c42, 91 | 0xb5b571c4, 0x6666ccaa, 0x484890d8, 0x03030605, 0xf6f6f701, 0x0e0e1c12, 0x6161c2a3, 0x35356a5f, 0x5757aef9, 0xb9b969d0, 92 | 0x86861791, 0xc1c19958, 0x1d1d3a27, 0x9e9e27b9, 0xe1e1d938, 0xf8f8eb13, 0x98982bb3, 0x11112233, 0x6969d2bb, 0xd9d9a970, 93 | 0x8e8e0789, 0x949433a7, 0x9b9b2db6, 0x1e1e3c22, 0x87871592, 0xe9e9c920, 0xcece8749, 0x5555aaff, 0x28285078, 0xdfdfa57a, 94 | 0x8c8c038f, 0xa1a159f8, 0x89890980, 0x0d0d1a17, 0xbfbf65da, 0xe6e6d731, 0x424284c6, 0x6868d0b8, 0x414182c3, 0x999929b0, 95 | 0x2d2d5a77, 0x0f0f1e11, 0xb0b07bcb, 0x5454a8fc, 0xbbbb6dd6, 0x16162c3a, }; 96 | 97 | static const uint t3[] = { 98 | 0x63c6a563, 0x7cf8847c, 0x77ee9977, 0x7bf68d7b, 0xf2ff0df2, 0x6bd6bd6b, 0x6fdeb16f, 0xc59154c5, 0x30605030, 0x01020301, 99 | 0x67cea967, 0x2b567d2b, 0xfee719fe, 0xd7b562d7, 0xab4de6ab, 0x76ec9a76, 0xca8f45ca, 0x821f9d82, 0xc98940c9, 0x7dfa877d, 100 | 0xfaef15fa, 0x59b2eb59, 0x478ec947, 0xf0fb0bf0, 0xad41ecad, 0xd4b367d4, 0xa25ffda2, 0xaf45eaaf, 0x9c23bf9c, 0xa453f7a4, 101 | 0x72e49672, 0xc09b5bc0, 0xb775c2b7, 0xfde11cfd, 0x933dae93, 0x264c6a26, 0x366c5a36, 0x3f7e413f, 0xf7f502f7, 0xcc834fcc, 102 | 0x34685c34, 0xa551f4a5, 0xe5d134e5, 0xf1f908f1, 0x71e29371, 0xd8ab73d8, 0x31625331, 0x152a3f15, 0x04080c04, 0xc79552c7, 103 | 0x23466523, 0xc39d5ec3, 0x18302818, 0x9637a196, 0x050a0f05, 0x9a2fb59a, 0x070e0907, 0x12243612, 0x801b9b80, 0xe2df3de2, 104 | 0xebcd26eb, 0x274e6927, 0xb27fcdb2, 0x75ea9f75, 0x09121b09, 0x831d9e83, 0x2c58742c, 0x1a342e1a, 0x1b362d1b, 0x6edcb26e, 105 | 0x5ab4ee5a, 0xa05bfba0, 0x52a4f652, 0x3b764d3b, 0xd6b761d6, 0xb37dceb3, 0x29527b29, 0xe3dd3ee3, 0x2f5e712f, 0x84139784, 106 | 0x53a6f553, 0xd1b968d1, 0x00000000, 0xedc12ced, 0x20406020, 0xfce31ffc, 0xb179c8b1, 0x5bb6ed5b, 0x6ad4be6a, 0xcb8d46cb, 107 | 0xbe67d9be, 0x39724b39, 0x4a94de4a, 0x4c98d44c, 0x58b0e858, 0xcf854acf, 0xd0bb6bd0, 0xefc52aef, 0xaa4fe5aa, 0xfbed16fb, 108 | 0x4386c543, 0x4d9ad74d, 0x33665533, 0x85119485, 0x458acf45, 0xf9e910f9, 0x02040602, 0x7ffe817f, 0x50a0f050, 0x3c78443c, 109 | 0x9f25ba9f, 0xa84be3a8, 0x51a2f351, 0xa35dfea3, 0x4080c040, 0x8f058a8f, 0x923fad92, 0x9d21bc9d, 0x38704838, 0xf5f104f5, 110 | 0xbc63dfbc, 0xb677c1b6, 0xdaaf75da, 0x21426321, 0x10203010, 0xffe51aff, 0xf3fd0ef3, 0xd2bf6dd2, 0xcd814ccd, 0x0c18140c, 111 | 0x13263513, 0xecc32fec, 0x5fbee15f, 0x9735a297, 0x4488cc44, 0x172e3917, 0xc49357c4, 0xa755f2a7, 0x7efc827e, 0x3d7a473d, 112 | 0x64c8ac64, 0x5dbae75d, 0x19322b19, 0x73e69573, 0x60c0a060, 0x81199881, 0x4f9ed14f, 0xdca37fdc, 0x22446622, 0x2a547e2a, 113 | 0x903bab90, 0x880b8388, 0x468cca46, 0xeec729ee, 0xb86bd3b8, 0x14283c14, 0xdea779de, 0x5ebce25e, 0x0b161d0b, 0xdbad76db, 114 | 0xe0db3be0, 0x32645632, 0x3a744e3a, 0x0a141e0a, 0x4992db49, 0x060c0a06, 0x24486c24, 0x5cb8e45c, 0xc29f5dc2, 0xd3bd6ed3, 115 | 0xac43efac, 0x62c4a662, 0x9139a891, 0x9531a495, 0xe4d337e4, 0x79f28b79, 0xe7d532e7, 0xc88b43c8, 0x376e5937, 0x6ddab76d, 116 | 0x8d018c8d, 0xd5b164d5, 0x4e9cd24e, 0xa949e0a9, 0x6cd8b46c, 0x56acfa56, 0xf4f307f4, 0xeacf25ea, 0x65caaf65, 0x7af48e7a, 117 | 0xae47e9ae, 0x08101808, 0xba6fd5ba, 0x78f08878, 0x254a6f25, 0x2e5c722e, 0x1c38241c, 0xa657f1a6, 0xb473c7b4, 0xc69751c6, 118 | 0xe8cb23e8, 0xdda17cdd, 0x74e89c74, 0x1f3e211f, 0x4b96dd4b, 0xbd61dcbd, 0x8b0d868b, 0x8a0f858a, 0x70e09070, 0x3e7c423e, 119 | 0xb571c4b5, 0x66ccaa66, 0x4890d848, 0x03060503, 0xf6f701f6, 0x0e1c120e, 0x61c2a361, 0x356a5f35, 0x57aef957, 0xb969d0b9, 120 | 0x86179186, 0xc19958c1, 0x1d3a271d, 0x9e27b99e, 0xe1d938e1, 0xf8eb13f8, 0x982bb398, 0x11223311, 0x69d2bb69, 0xd9a970d9, 121 | 0x8e07898e, 0x9433a794, 0x9b2db69b, 0x1e3c221e, 0x87159287, 0xe9c920e9, 0xce8749ce, 0x55aaff55, 0x28507828, 0xdfa57adf, 122 | 0x8c038f8c, 0xa159f8a1, 0x89098089, 0x0d1a170d, 0xbf65dabf, 0xe6d731e6, 0x4284c642, 0x68d0b868, 0x4182c341, 0x9929b099, 123 | 0x2d5a772d, 0x0f1e110f, 0xb07bcbb0, 0x54a8fc54, 0xbb6dd6bb, 0x162c3a16, }; 124 | 125 | static const uint t4[] = { 126 | 0xc6a56363, 0xf8847c7c, 0xee997777, 0xf68d7b7b, 0xff0df2f2, 0xd6bd6b6b, 0xdeb16f6f, 0x9154c5c5, 0x60503030, 0x02030101, 127 | 0xcea96767, 0x567d2b2b, 0xe719fefe, 0xb562d7d7, 0x4de6abab, 0xec9a7676, 0x8f45caca, 0x1f9d8282, 0x8940c9c9, 0xfa877d7d, 128 | 0xef15fafa, 0xb2eb5959, 0x8ec94747, 0xfb0bf0f0, 0x41ecadad, 0xb367d4d4, 0x5ffda2a2, 0x45eaafaf, 0x23bf9c9c, 0x53f7a4a4, 129 | 0xe4967272, 0x9b5bc0c0, 0x75c2b7b7, 0xe11cfdfd, 0x3dae9393, 0x4c6a2626, 0x6c5a3636, 0x7e413f3f, 0xf502f7f7, 0x834fcccc, 130 | 0x685c3434, 0x51f4a5a5, 0xd134e5e5, 0xf908f1f1, 0xe2937171, 0xab73d8d8, 0x62533131, 0x2a3f1515, 0x080c0404, 0x9552c7c7, 131 | 0x46652323, 0x9d5ec3c3, 0x30281818, 0x37a19696, 0x0a0f0505, 0x2fb59a9a, 0x0e090707, 0x24361212, 0x1b9b8080, 0xdf3de2e2, 132 | 0xcd26ebeb, 0x4e692727, 0x7fcdb2b2, 0xea9f7575, 0x121b0909, 0x1d9e8383, 0x58742c2c, 0x342e1a1a, 0x362d1b1b, 0xdcb26e6e, 133 | 0xb4ee5a5a, 0x5bfba0a0, 0xa4f65252, 0x764d3b3b, 0xb761d6d6, 0x7dceb3b3, 0x527b2929, 0xdd3ee3e3, 0x5e712f2f, 0x13978484, 134 | 0xa6f55353, 0xb968d1d1, 0x00000000, 0xc12ceded, 0x40602020, 0xe31ffcfc, 0x79c8b1b1, 0xb6ed5b5b, 0xd4be6a6a, 0x8d46cbcb, 135 | 0x67d9bebe, 0x724b3939, 0x94de4a4a, 0x98d44c4c, 0xb0e85858, 0x854acfcf, 0xbb6bd0d0, 0xc52aefef, 0x4fe5aaaa, 0xed16fbfb, 136 | 0x86c54343, 0x9ad74d4d, 0x66553333, 0x11948585, 0x8acf4545, 0xe910f9f9, 0x04060202, 0xfe817f7f, 0xa0f05050, 0x78443c3c, 137 | 0x25ba9f9f, 0x4be3a8a8, 0xa2f35151, 0x5dfea3a3, 0x80c04040, 0x058a8f8f, 0x3fad9292, 0x21bc9d9d, 0x70483838, 0xf104f5f5, 138 | 0x63dfbcbc, 0x77c1b6b6, 0xaf75dada, 0x42632121, 0x20301010, 0xe51affff, 0xfd0ef3f3, 0xbf6dd2d2, 0x814ccdcd, 0x18140c0c, 139 | 0x26351313, 0xc32fecec, 0xbee15f5f, 0x35a29797, 0x88cc4444, 0x2e391717, 0x9357c4c4, 0x55f2a7a7, 0xfc827e7e, 0x7a473d3d, 140 | 0xc8ac6464, 0xbae75d5d, 0x322b1919, 0xe6957373, 0xc0a06060, 0x19988181, 0x9ed14f4f, 0xa37fdcdc, 0x44662222, 0x547e2a2a, 141 | 0x3bab9090, 0x0b838888, 0x8cca4646, 0xc729eeee, 0x6bd3b8b8, 0x283c1414, 0xa779dede, 0xbce25e5e, 0x161d0b0b, 0xad76dbdb, 142 | 0xdb3be0e0, 0x64563232, 0x744e3a3a, 0x141e0a0a, 0x92db4949, 0x0c0a0606, 0x486c2424, 0xb8e45c5c, 0x9f5dc2c2, 0xbd6ed3d3, 143 | 0x43efacac, 0xc4a66262, 0x39a89191, 0x31a49595, 0xd337e4e4, 0xf28b7979, 0xd532e7e7, 0x8b43c8c8, 0x6e593737, 0xdab76d6d, 144 | 0x018c8d8d, 0xb164d5d5, 0x9cd24e4e, 0x49e0a9a9, 0xd8b46c6c, 0xacfa5656, 0xf307f4f4, 0xcf25eaea, 0xcaaf6565, 0xf48e7a7a, 145 | 0x47e9aeae, 0x10180808, 0x6fd5baba, 0xf0887878, 0x4a6f2525, 0x5c722e2e, 0x38241c1c, 0x57f1a6a6, 0x73c7b4b4, 0x9751c6c6, 146 | 0xcb23e8e8, 0xa17cdddd, 0xe89c7474, 0x3e211f1f, 0x96dd4b4b, 0x61dcbdbd, 0x0d868b8b, 0x0f858a8a, 0xe0907070, 0x7c423e3e, 147 | 0x71c4b5b5, 0xccaa6666, 0x90d84848, 0x06050303, 0xf701f6f6, 0x1c120e0e, 0xc2a36161, 0x6a5f3535, 0xaef95757, 0x69d0b9b9, 148 | 0x17918686, 0x9958c1c1, 0x3a271d1d, 0x27b99e9e, 0xd938e1e1, 0xeb13f8f8, 0x2bb39898, 0x22331111, 0xd2bb6969, 0xa970d9d9, 149 | 0x07898e8e, 0x33a79494, 0x2db69b9b, 0x3c221e1e, 0x15928787, 0xc920e9e9, 0x8749cece, 0xaaff5555, 0x50782828, 0xa57adfdf, 150 | 0x038f8c8c, 0x59f8a1a1, 0x09808989, 0x1a170d0d, 0x65dabfbf, 0xd731e6e6, 0x84c64242, 0xd0b86868, 0x82c34141, 0x29b09999, 151 | 0x5a772d2d, 0x1e110f0f, 0x7bcbb0b0, 0xa8fc5454, 0x6dd6bbbb, 0x2c3a1616, }; 152 | 153 | static const uint it[] = { 154 | 0x50a7f451, 0x5365417e, 0xc3a4171a, 0x965e273a, 0xcb6bab3b, 0xf1459d1f, 0xab58faac, 0x9303e34b, 0x55fa3020, 0xf66d76ad, 155 | 0x9176cc88, 0x254c02f5, 0xfcd7e54f, 0xd7cb2ac5, 0x80443526, 0x8fa362b5, 0x495ab1de, 0x671bba25, 0x980eea45, 0xe1c0fe5d, 156 | 0x02752fc3, 0x12f04c81, 0xa397468d, 0xc6f9d36b, 0xe75f8f03, 0x959c9215, 0xeb7a6dbf, 0xda595295, 0x2d83bed4, 0xd3217458, 157 | 0x2969e049, 0x44c8c98e, 0x6a89c275, 0x78798ef4, 0x6b3e5899, 0xdd71b927, 0xb64fe1be, 0x17ad88f0, 0x66ac20c9, 0xb43ace7d, 158 | 0x184adf63, 0x82311ae5, 0x60335197, 0x457f5362, 0xe07764b1, 0x84ae6bbb, 0x1ca081fe, 0x942b08f9, 0x58684870, 0x19fd458f, 159 | 0x876cde94, 0xb7f87b52, 0x23d373ab, 0xe2024b72, 0x578f1fe3, 0x2aab5566, 0x0728ebb2, 0x03c2b52f, 0x9a7bc586, 0xa50837d3, 160 | 0xf2872830, 0xb2a5bf23, 0xba6a0302, 0x5c8216ed, 0x2b1ccf8a, 0x92b479a7, 0xf0f207f3, 0xa1e2694e, 0xcdf4da65, 0xd5be0506, 161 | 0x1f6234d1, 0x8afea6c4, 0x9d532e34, 0xa055f3a2, 0x32e18a05, 0x75ebf6a4, 0x39ec830b, 0xaaef6040, 0x069f715e, 0x51106ebd, 162 | 0xf98a213e, 0x3d06dd96, 0xae053edd, 0x46bde64d, 0xb58d5491, 0x055dc471, 0x6fd40604, 0xff155060, 0x24fb9819, 0x97e9bdd6, 163 | 0xcc434089, 0x779ed967, 0xbd42e8b0, 0x888b8907, 0x385b19e7, 0xdbeec879, 0x470a7ca1, 0xe90f427c, 0xc91e84f8, 0x00000000, 164 | 0x83868009, 0x48ed2b32, 0xac70111e, 0x4e725a6c, 0xfbff0efd, 0x5638850f, 0x1ed5ae3d, 0x27392d36, 0x64d90f0a, 0x21a65c68, 165 | 0xd1545b9b, 0x3a2e3624, 0xb1670a0c, 0x0fe75793, 0xd296eeb4, 0x9e919b1b, 0x4fc5c080, 0xa220dc61, 0x694b775a, 0x161a121c, 166 | 0x0aba93e2, 0xe52aa0c0, 0x43e0223c, 0x1d171b12, 0x0b0d090e, 0xadc78bf2, 0xb9a8b62d, 0xc8a91e14, 0x8519f157, 0x4c0775af, 167 | 0xbbdd99ee, 0xfd607fa3, 0x9f2601f7, 0xbcf5725c, 0xc53b6644, 0x347efb5b, 0x7629438b, 0xdcc623cb, 0x68fcedb6, 0x63f1e4b8, 168 | 0xcadc31d7, 0x10856342, 0x40229713, 0x2011c684, 0x7d244a85, 0xf83dbbd2, 0x1132f9ae, 0x6da129c7, 0x4b2f9e1d, 0xf330b2dc, 169 | 0xec52860d, 0xd0e3c177, 0x6c16b32b, 0x99b970a9, 0xfa489411, 0x2264e947, 0xc48cfca8, 0x1a3ff0a0, 0xd82c7d56, 0xef903322, 170 | 0xc74e4987, 0xc1d138d9, 0xfea2ca8c, 0x360bd498, 0xcf81f5a6, 0x28de7aa5, 0x268eb7da, 0xa4bfad3f, 0xe49d3a2c, 0x0d927850, 171 | 0x9bcc5f6a, 0x62467e54, 0xc2138df6, 0xe8b8d890, 0x5ef7392e, 0xf5afc382, 0xbe805d9f, 0x7c93d069, 0xa92dd56f, 0xb31225cf, 172 | 0x3b99acc8, 0xa77d1810, 0x6e639ce8, 0x7bbb3bdb, 0x097826cd, 0xf418596e, 0x01b79aec, 0xa89a4f83, 0x656e95e6, 0x7ee6ffaa, 173 | 0x08cfbc21, 0xe6e815ef, 0xd99be7ba, 0xce366f4a, 0xd4099fea, 0xd67cb029, 0xafb2a431, 0x31233f2a, 0x3094a5c6, 0xc066a235, 174 | 0x37bc4e74, 0xa6ca82fc, 0xb0d090e0, 0x15d8a733, 0x4a9804f1, 0xf7daec41, 0x0e50cd7f, 0x2ff69117, 0x8dd64d76, 0x4db0ef43, 175 | 0x544daacc, 0xdf0496e4, 0xe3b5d19e, 0x1b886a4c, 0xb81f2cc1, 0x7f516546, 0x04ea5e9d, 0x5d358c01, 0x737487fa, 0x2e410bfb, 176 | 0x5a1d67b3, 0x52d2db92, 0x335610e9, 0x1347d66d, 0x8c61d79a, 0x7a0ca137, 0x8e14f859, 0x893c13eb, 0xee27a9ce, 0x35c961b7, 177 | 0xede51ce1, 0x3cb1477a, 0x59dfd29c, 0x3f73f255, 0x79ce1418, 0xbf37c773, 0xeacdf753, 0x5baafd5f, 0x146f3ddf, 0x86db4478, 178 | 0x81f3afca, 0x3ec468b9, 0x2c342438, 0x5f40a3c2, 0x72c31d16, 0x0c25e2bc, 0x8b493c28, 0x41950dff, 0x7101a839, 0xdeb30c08, 179 | 0x9ce4b4d8, 0x90c15664, 0x6184cb7b, 0x70b632d5, 0x745c6c48, 0x4257b8d0, }; 180 | 181 | template 182 | class AES 183 | { 184 | private: 185 | uint w[Nb * (Nr + 1)]; 186 | uint dw[Nb * (Nr + 1)]; 187 | 188 | size_t padding(ubyte* input, size_t len, ubyte* output) 189 | { 190 | size_t output_len = len; 191 | while ((output_len + 4) % 16 != 0) output_len++; 192 | 193 | for (size_t i = 0; i < len; i++) 194 | output[i] = input[i]; 195 | for (size_t i = len; i < output_len; i++) 196 | output[i] = 0; 197 | 198 | Utility::writeIntToBytes((uint)len, output + output_len, ENDIAN_BIG); 199 | 200 | return output_len + 4; 201 | } 202 | 203 | void keyExpansion(ubyte* key, size_t len) 204 | { 205 | assert(len >= Nk * 4); // At least (Nk * 4) bytes long key must be set. 206 | 207 | const uint rCon[10] = { 0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36 }; 208 | 209 | uint i = 0; 210 | while (i < Nk) 211 | { 212 | w[i] = key[4 * i] | key[4 * i + 1] << 8 | key[4 * i + 2] << 16 | key[4 * i + 3] << 24; 213 | i++; 214 | } 215 | 216 | uint tmp; 217 | i = Nk; 218 | 219 | while (i < Nb * (Nr + 1)) 220 | { 221 | tmp = w[i - 1]; 222 | if (i % Nk == 0) 223 | tmp = subWord(rotWord(tmp)) ^ rCon[i/Nk-1]; 224 | if (Nk > 6) 225 | if (i % Nk == 4) 226 | tmp = subWord(tmp); 227 | w[i] = w[i - Nk] ^ tmp; 228 | dw[i] = w[i]; 229 | ++i; 230 | } 231 | 232 | for (i = 0; i < Nk; i++) 233 | { 234 | dw[i] = w[i]; 235 | } 236 | 237 | for (i = 1; i < Nr; ++i) 238 | invMixColumns(dw + i * Nb); 239 | } 240 | 241 | // Need to compute xtimes(a, b). Use table lookup in inverse table (over 0x0b0d090e), 242 | // and isbox(sbox(x)) = x to avoid implementing finite field multiplication in GF(256). 243 | void invMixColumns(uint* s) 244 | { 245 | for (int col = 0; col < 4; ++col) 246 | { 247 | ubyte a = s[col] & 0xff; 248 | ubyte b = (s[col] >> 8) & 0xff; 249 | ubyte c = (s[col] >> 16) & 0xff; 250 | ubyte d = (s[col] >> 24) & 0xff; 251 | s[col] = (it[sbox[a]] & 0xff) ^ ((it[sbox[b]] >> 24) & 0xff) ^ ((it[sbox[c]] >> 16) & 0xff) ^ ((it[sbox[d]] >> 8) & 0xff); 252 | s[col] |= (((it[sbox[a]] >> 8) & 0xff) ^ (it[sbox[b]] & 0xff) ^ ((it[sbox[c]] >> 24) & 0xff) ^ ((it[sbox[d]] >> 16) & 0xff)) << 8; 253 | s[col] |= (((it[sbox[a]] >> 16) & 0xff) ^ ((it[sbox[b]] >> 8) & 0xff) ^ (it[sbox[c]] & 0xff) ^ ((it[sbox[d]] >> 24) & 0xff)) << 16; 254 | s[col] |= (((it[sbox[a]] >> 24) & 0xff) ^ ((it[sbox[b]] >> 16) & 0xff) ^ ((it[sbox[c]] >> 8) & 0xff) ^ (it[sbox[d]] & 0xff)) << 24; 255 | } 256 | } 257 | 258 | uint rotate(uint n, uint w) 259 | { 260 | assert(n == 0 || n == 1 || n == 2 || n == 3); 261 | return w << (n * 8) | w >> ((4 - n) * 8); 262 | } 263 | 264 | uint subWord(uint w) 265 | { 266 | return sbox[(ubyte)(w)] | sbox[(ubyte)(w >> 8)] << 8 | sbox[(ubyte)(w >> 16)] << 16 | sbox[(ubyte)(w >> 24)] << 24; 267 | } 268 | 269 | uint rotWord(uint w) 270 | { 271 | return (w >> 8) | (w << 24); 272 | } 273 | 274 | public: 275 | 276 | AES(ubyte* key, size_t len) 277 | { 278 | static_assert ((Nb == 4 && Nk == 4 && Nr == 10) || (Nb == 4 && Nk == 6 && Nr == 12) || (Nb == 4 && Nk == 8 && Nr == 14), "template parameter error."); 279 | keyExpansion(key, len); 280 | } 281 | 282 | size_t encrypt(ubyte* data, size_t len, ubyte* result) 283 | { 284 | size_t output_len = padding(data, len, result); 285 | 286 | for (size_t i = 0; i < output_len / 16; i++) 287 | { 288 | uint* state = (uint*)result + i * 4; 289 | uint t[4] = { 0, 0, 0, 0 }; 290 | uint round = 0; 291 | 292 | // Add initial round key 293 | state[0] ^= w[0]; 294 | state[1] ^= w[1]; 295 | state[2] ^= w[2]; 296 | state[3] ^= w[3]; 297 | for (uint i = 0; i < Nb; i++) 298 | { 299 | t[i] = state[i]; 300 | } 301 | 302 | while (round++ < Nr - 1) 303 | { 304 | // SubBytes, ShiftRows and MixColumns 305 | state[0] = t1[(ubyte)(t[0])] ^ t2[(ubyte)(t[1] >> 8)] ^ t3[(ubyte)(t[2] >> 16)] ^ t4[(ubyte)(t[3] >> 24)] ^ w[round * Nb]; 306 | state[1] = t1[(ubyte)(t[1])] ^ t2[(ubyte)(t[2] >> 8)] ^ t3[(ubyte)(t[3] >> 16)] ^ t4[(ubyte)(t[0] >> 24)] ^ w[round * Nb + 1]; 307 | state[2] = t1[(ubyte)(t[2])] ^ t2[(ubyte)(t[3] >> 8)] ^ t3[(ubyte)(t[0] >> 16)] ^ t4[(ubyte)(t[1] >> 24)] ^ w[round * Nb + 2]; 308 | state[3] = t1[(ubyte)(t[3])] ^ t2[(ubyte)(t[0] >> 8)] ^ t3[(ubyte)(t[1] >> 16)] ^ t4[(ubyte)(t[2] >> 24)] ^ w[round * Nb + 3]; 309 | for (uint i = 0; i < Nb; i++) 310 | { 311 | t[i] = state[i]; 312 | } 313 | } 314 | 315 | // SubBytes and ShiftRows 316 | state[0] = sbox[(ubyte)(t[0])] ^ ((sbox[(ubyte)(t[1] >> 8)]) << 8) ^ ((sbox[(ubyte)(t[2] >> 16)]) << 16) ^ ((sbox[(ubyte)(t[3] >> 24)]) << 24) ^ w[round * Nb]; 317 | state[1] = sbox[(ubyte)(t[1])] ^ ((sbox[(ubyte)(t[2] >> 8)]) << 8) ^ ((sbox[(ubyte)(t[3] >> 16)]) << 16) ^ ((sbox[(ubyte)(t[0] >> 24)]) << 24) ^ w[round * Nb + 1]; 318 | state[2] = sbox[(ubyte)(t[2])] ^ ((sbox[(ubyte)(t[3] >> 8)]) << 8) ^ ((sbox[(ubyte)(t[0] >> 16)]) << 16) ^ ((sbox[(ubyte)(t[1] >> 24)]) << 24) ^ w[round * Nb + 2]; 319 | state[3] = sbox[(ubyte)(t[3])] ^ ((sbox[(ubyte)(t[0] >> 8)]) << 8) ^ ((sbox[(ubyte)(t[1] >> 16)]) << 16) ^ ((sbox[(ubyte)(t[2] >> 24)]) << 24) ^ w[round * Nb + 3]; 320 | } 321 | 322 | return output_len; 323 | } 324 | 325 | size_t decrypt(ubyte* data, size_t len, ubyte* result) 326 | { 327 | assert(len % 16 == 0); 328 | 329 | for (size_t i = 0; i < len; i++) 330 | { 331 | result[i] = data[i]; 332 | } 333 | 334 | for (size_t i = 0; i < len / 16; i++) 335 | { 336 | uint *state = (uint*)result + i * 4; 337 | uint t[4] = { 0, 0, 0, 0 }; 338 | 339 | // Add last round key 340 | state[0] ^= dw[Nr * Nb]; 341 | state[1] ^= dw[Nr * Nb + 1]; 342 | state[2] ^= dw[Nr * Nb + 2]; 343 | state[3] ^= dw[Nr * Nb + 3]; 344 | for (uint i = 0; i < Nb; i++) { 345 | t[i] = state[i]; 346 | } 347 | 348 | for (int round = Nr - 1; round > 0; --round) 349 | { 350 | // InvSubBytes, InvShiftRows and InvMixColumns combined 351 | state[0] = it[(ubyte)(t[0])] ^ rotate(1, it[(ubyte)(t[3] >> 8)]) ^ rotate(2, it[(ubyte)(t[2] >> 16)]) ^ rotate(3, it[(ubyte)(t[1] >> 24)]) ^ dw[round * Nb]; 352 | state[1] = it[(ubyte)(t[1])] ^ rotate(1, it[(ubyte)(t[0] >> 8)]) ^ rotate(2, it[(ubyte)(t[3] >> 16)]) ^ rotate(3, it[(ubyte)(t[2] >> 24)]) ^ dw[round * Nb + 1]; 353 | state[2] = it[(ubyte)(t[2])] ^ rotate(1, it[(ubyte)(t[1] >> 8)]) ^ rotate(2, it[(ubyte)(t[0] >> 16)]) ^ rotate(3, it[(ubyte)(t[3] >> 24)]) ^ dw[round * Nb + 2]; 354 | state[3] = it[(ubyte)(t[3])] ^ rotate(1, it[(ubyte)(t[2] >> 8)]) ^ rotate(2, it[(ubyte)(t[1] >> 16)]) ^ rotate(3, it[(ubyte)(t[0] >> 24)]) ^ dw[round * Nb + 3]; 355 | for (uint i = 0; i < Nb; i++) 356 | { 357 | t[i] = state[i]; 358 | } 359 | } 360 | 361 | // InvSubBytes and InvShiftRows combined 362 | state[0] = isbox[(ubyte)(t[0])] ^ ((isbox[(ubyte)(t[3] >> 8)]) << 8) ^ ((isbox[(ubyte)(t[2] >> 16)]) << 16) ^ ((isbox[(ubyte)(t[1] >> 24)]) << 24) ^ dw[0]; 363 | state[1] = isbox[(ubyte)(t[1])] ^ ((isbox[(ubyte)(t[0] >> 8)]) << 8) ^ ((isbox[(ubyte)(t[3] >> 16)]) << 16) ^ ((isbox[(ubyte)(t[2] >> 24)]) << 24) ^ dw[1]; 364 | state[2] = isbox[(ubyte)(t[2])] ^ ((isbox[(ubyte)(t[1] >> 8)]) << 8) ^ ((isbox[(ubyte)(t[0] >> 16)]) << 16) ^ ((isbox[(ubyte)(t[3] >> 24)]) << 24) ^ dw[2]; 365 | state[3] = isbox[(ubyte)(t[3])] ^ ((isbox[(ubyte)(t[2] >> 8)]) << 8) ^ ((isbox[(ubyte)(t[1] >> 16)]) << 16) ^ ((isbox[(ubyte)(t[0] >> 24)]) << 24) ^ dw[3]; 366 | } 367 | 368 | return Utility::readIntFromBytes(result + (len - 4), ENDIAN_BIG); 369 | } 370 | }; 371 | 372 | typedef AES<4, 4, 10> AES128; 373 | typedef AES<4, 6, 12> AES192; 374 | typedef AES<4, 8, 14> AES256; 375 | 376 | class AESUtils 377 | { 378 | public: 379 | template 380 | static size_t encrypt(ubyte* data, size_t len, string key, ubyte* result) 381 | { 382 | return handle(data, len, key, result); 383 | } 384 | 385 | template 386 | static size_t decrypt(ubyte* data, size_t len, string key, ubyte* result) 387 | { 388 | return handle(data, len, key, result); 389 | } 390 | 391 | private: 392 | template 393 | static size_t handle(ubyte* data, size_t len, string key, ubyte* result) 394 | { 395 | AES_X aes((ubyte*)key.c_str(), key.length()); 396 | return (EorD == 1) ? aes.encrypt(data, len, result) : aes.decrypt(data, len, result); 397 | } 398 | }; 399 | 400 | } 401 | } 402 | -------------------------------------------------------------------------------- /src/base58.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "base58.h" 5 | 6 | namespace crypto 7 | { 8 | namespace base58 9 | { 10 | 11 | void Base58::init(int* INDEXES, char* ALPHABET) 12 | { 13 | for (int i = 0; i < 128; i++) 14 | { 15 | INDEXES[i] = -1; 16 | } 17 | 18 | for (int i = 0; i < 58; i++) 19 | { 20 | INDEXES[(int)ALPHABET[i]] = i; 21 | } 22 | } 23 | 24 | string Base58::encode(ubyte* data, size_t len) 25 | { 26 | if (len == 0) 27 | { 28 | return ""; 29 | } 30 | 31 | int INDEXES[128]; 32 | char* ALPHABET = (char*)"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; 33 | init(INDEXES, ALPHABET); 34 | 35 | int zeros = 0; 36 | while ((zeros < (int)len) && (data[zeros] == 0)) 37 | { 38 | ++zeros; 39 | } 40 | 41 | ubyte* input = new ubyte[len]; 42 | for (size_t i = 0; i < len; i++) 43 | { 44 | input[i] = data[i]; 45 | } 46 | 47 | char* encoded = new char[len * 3]; 48 | size_t outputStart = len * 3; 49 | 50 | for (size_t inputStart = zeros; inputStart < len;) 51 | { 52 | encoded[--outputStart] = ALPHABET[divmod(input, len, (int)inputStart, 256, 58)]; 53 | 54 | if (input[inputStart] == 0) 55 | { 56 | ++inputStart; 57 | } 58 | } 59 | 60 | while (outputStart < len * 3 && encoded[outputStart] == ALPHABET[0]) 61 | { 62 | ++outputStart; 63 | } 64 | 65 | while (--zeros >= 0) 66 | { 67 | encoded[--outputStart] = ALPHABET[0]; 68 | } 69 | 70 | string ret(encoded + outputStart, len * 3 - outputStart); 71 | delete[] input; 72 | delete[] encoded; 73 | 74 | return ret; 75 | } 76 | 77 | size_t Base58::decode(string const& data, ubyte* result) 78 | { 79 | if (data.length() == 0) 80 | { 81 | result[0] = 0; 82 | return 0; 83 | } 84 | 85 | int INDEXES[128]; 86 | char* ALPHABET = (char*)"123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; 87 | init(INDEXES, ALPHABET); 88 | 89 | ubyte* input58 = new ubyte[data.length()]; 90 | 91 | for (size_t i = 0; i < data.length(); ++i) 92 | { 93 | char c = data[i]; 94 | int digit = (int)c < 128 ? INDEXES[(int)c] : -1; 95 | 96 | if (digit < 0) 97 | { 98 | throw; 99 | } 100 | 101 | input58[i] = (ubyte)digit; 102 | } 103 | 104 | size_t zeros = 0; 105 | while (zeros < data.length() && input58[zeros] == 0) 106 | { 107 | ++zeros; 108 | } 109 | 110 | ubyte* decoded = new ubyte[data.length()]; 111 | size_t outputStart = data.length(); 112 | 113 | for (size_t inputStart = zeros; inputStart < data.length();) 114 | { 115 | decoded[--outputStart] = divmod(input58, data.length(), (int)inputStart, 58, 256); 116 | 117 | if (input58[inputStart] == 0) 118 | { 119 | ++inputStart; 120 | } 121 | } 122 | 123 | while (outputStart < data.length() && decoded[outputStart] == 0) 124 | { 125 | ++outputStart; 126 | } 127 | 128 | for (size_t i = outputStart - zeros; i < data.length(); i++) 129 | { 130 | result[i - outputStart - zeros] = decoded[i]; 131 | } 132 | result[data.length() - outputStart - zeros] = 0; 133 | 134 | delete[] input58; 135 | delete[] decoded; 136 | 137 | return data.length() - outputStart - zeros; 138 | } 139 | 140 | BigInt Base58::decodeToBigInteger(string input) 141 | { 142 | ubyte* buf = new ubyte[input.length() * 2]; 143 | size_t len = Base58::decode(input, buf); 144 | 145 | BigInt bi(buf, (int)len); 146 | delete[] buf; 147 | 148 | return bi; 149 | } 150 | 151 | ubyte Base58::divmod(ubyte* number, size_t len, int firstDigit, int base, int divisor) 152 | { 153 | int remainder = 0; 154 | 155 | for (size_t i = firstDigit; i < len; i++) 156 | { 157 | int digit = (int)number[i] & 0xFF; 158 | int temp = remainder * base + digit; 159 | number[i] = (ubyte)(temp / divisor); 160 | remainder = temp % divisor; 161 | } 162 | 163 | return (ubyte)remainder; 164 | } 165 | 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /src/base58.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "utils/types.h" 4 | #include "utils/bigint.h" 5 | 6 | using namespace std; 7 | using namespace crypto::utils; 8 | 9 | namespace crypto 10 | { 11 | namespace base58 12 | { 13 | 14 | class Base58 15 | { 16 | private: 17 | static void init(int*, char*); 18 | static BigInt decodeToBigInteger(string input); 19 | static ubyte divmod(ubyte* number, size_t len, int firstDigit, int base, int divisor); 20 | public: 21 | static string encode(ubyte*, size_t); 22 | static size_t decode(string const&, ubyte*); 23 | }; 24 | 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/base64.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "base64.h" 4 | 5 | namespace crypto 6 | { 7 | namespace base64 8 | { 9 | 10 | string Base64::encode(ubyte* data, size_t len) 11 | { 12 | const string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 13 | string ret; 14 | int i = 0; 15 | int j = 0; 16 | ubyte char_array_3[3]; 17 | ubyte char_array_4[4]; 18 | 19 | while (len--) 20 | { 21 | char_array_3[i++] = *(data++); 22 | if (i == 3) 23 | { 24 | char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; 25 | char_array_4[1] = ((char_array_3[0] & 0x03) << 4) 26 | + ((char_array_3[1] & 0xf0) >> 4); 27 | char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) 28 | + ((char_array_3[2] & 0xc0) >> 6); 29 | char_array_4[3] = char_array_3[2] & 0x3f; 30 | 31 | for (i = 0; (i < 4); i++) 32 | ret += base64_chars[char_array_4[i]]; 33 | i = 0; 34 | } 35 | } 36 | 37 | if (i) 38 | { 39 | for (j = i; j < 3; j++) 40 | char_array_3[j] = '\0'; 41 | 42 | char_array_4[0] = (char_array_3[0] & 0xfc) >> 2; 43 | char_array_4[1] = ((char_array_3[0] & 0x03) << 4) + ((char_array_3[1] & 0xf0) >> 4); 44 | char_array_4[2] = ((char_array_3[1] & 0x0f) << 2) + ((char_array_3[2] & 0xc0) >> 6); 45 | char_array_4[3] = char_array_3[2] & 0x3f; 46 | 47 | for (j = 0; (j < i + 1); j++) 48 | ret += base64_chars[char_array_4[j]]; 49 | 50 | while ((i++ < 3)) 51 | ret += '='; 52 | } 53 | 54 | return ret; 55 | } 56 | 57 | size_t Base64::decode(string const& data, ubyte* result) 58 | { 59 | const string base64_chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; 60 | size_t in_len = data.size(); 61 | int i = 0; 62 | int j = 0; 63 | int in_ = 0; 64 | int k = 0; 65 | ubyte char_array_4[4], char_array_3[3]; 66 | 67 | while (in_len-- && (data[in_] != '=') && isBase64Char(data[in_])) 68 | { 69 | char_array_4[i++] = data[in_]; 70 | in_++; 71 | 72 | if (i == 4) 73 | { 74 | for (i = 0; i < 4; i++) 75 | char_array_4[i] = (ubyte)base64_chars.find(char_array_4[i]); 76 | 77 | char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); 78 | char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); 79 | char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; 80 | 81 | for (i = 0; (i < 3); i++) 82 | result[k++] = char_array_3[i]; 83 | i = 0; 84 | } 85 | } 86 | 87 | if (i) 88 | { 89 | for (j = i; j < 4; j++) 90 | char_array_4[j] = 0; 91 | 92 | for (j = 0; j < 4; j++) 93 | char_array_4[j] = (ubyte)base64_chars.find(char_array_4[j]); 94 | 95 | char_array_3[0] = (char_array_4[0] << 2) + ((char_array_4[1] & 0x30) >> 4); 96 | char_array_3[1] = ((char_array_4[1] & 0xf) << 4) + ((char_array_4[2] & 0x3c) >> 2); 97 | char_array_3[2] = ((char_array_4[2] & 0x3) << 6) + char_array_4[3]; 98 | 99 | for (j = 0; (j < i - 1); j++) 100 | result[k++] = char_array_3[j]; 101 | } 102 | 103 | return k; 104 | } 105 | 106 | } 107 | } 108 | -------------------------------------------------------------------------------- /src/base64.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "utils/types.h" 4 | 5 | using namespace std; 6 | 7 | namespace crypto 8 | { 9 | namespace base64 10 | { 11 | 12 | class Base64 13 | { 14 | private: 15 | 16 | static inline bool isBase64Char(unsigned char c) 17 | { 18 | return (isalnum(c) || (c == '+') || (c == '/')); 19 | } 20 | 21 | public: 22 | 23 | static string encode(ubyte*, size_t); 24 | static size_t decode(string const&, ubyte*); 25 | }; 26 | 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/export.cpp: -------------------------------------------------------------------------------- 1 | #include "rsa.h" 2 | #include "tea/xtea.h" 3 | #include "utils/random.h" 4 | #include "utils/utility.h" 5 | #include "base64.h" 6 | #include 7 | using namespace std; 8 | using namespace crypto::rsa; 9 | using namespace crypto::base64; 10 | 11 | #ifdef _WIN32 12 | 13 | #ifndef WIN32_LEAN_AND_MEAN 14 | #define WIN32_LEAN_AND_MEAN 15 | #endif 16 | #include 17 | 18 | #define DLL_EXPORT __declspec(dllexport) __stdcall 19 | #ifdef __cplusplus 20 | extern "C" 21 | { 22 | #endif 23 | 24 | size_t DLL_EXPORT rsaKeyGenerate(int bitLength, char* buf); 25 | long DLL_EXPORT rsaEncrypt(char* key, int keyLength, ubyte* data, size_t len, ubyte* result); 26 | long DLL_EXPORT rsaDecrypt(char* key, int keyLength, ubyte* data, size_t len, ubyte* result); 27 | 28 | #ifdef __cplusplus 29 | } 30 | #endif 31 | 32 | extern "C" DLL_EXPORT BOOL APIENTRY DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 33 | { 34 | switch (fdwReason) 35 | { 36 | case DLL_PROCESS_ATTACH: 37 | break; 38 | case DLL_PROCESS_DETACH: 39 | break; 40 | case DLL_THREAD_ATTACH: 41 | break; 42 | case DLL_THREAD_DETACH: 43 | break; 44 | } 45 | 46 | return TRUE; 47 | } 48 | 49 | #else 50 | 51 | extern "C" size_t rsaKeyGenerate(int bitLength, char* result); 52 | extern "C" long rsaEncrypt(char* key, int keyLength, ubyte* data, size_t len, ubyte* result); 53 | extern "C" long rsaDecrypt(char* key, int keyLength, ubyte* data, size_t len, ubyte* result); 54 | 55 | #endif 56 | 57 | size_t rsaKeyGenerate(int bitLength, char* result) 58 | { 59 | RSAKeyPair keyPair = RSA::generateKeyPair(bitLength); 60 | string key = "privateKey:\r\n" + keyPair.privateKey + "\r\npublicKey:\r\n" + keyPair.publicKey; 61 | 62 | ubyte* p = (ubyte*)key.c_str(); 63 | size_t i; 64 | for (i = 0; i < key.length(); i++) 65 | { 66 | result[i] = p[i]; 67 | } 68 | result[i] = 0; 69 | 70 | return key.length(); 71 | } 72 | 73 | long rsaEncrypt(char* key, int keyLength, ubyte* data, size_t len, ubyte* result) 74 | { 75 | string sKey(key, keyLength); 76 | ubyte* buf = new ubyte[len * 2 + keyLength]; 77 | size_t t_len = 0; 78 | 79 | try 80 | { 81 | t_len = RSA::encrypt(sKey, data, len, buf, true); 82 | } 83 | catch (...) 84 | { 85 | delete[] buf; 86 | return -1; 87 | } 88 | 89 | string baseStr = crypto::base64::Base64::encode(buf, t_len); 90 | delete[] buf; 91 | 92 | size_t i = 0; 93 | ubyte* p = (ubyte*)baseStr.c_str(); 94 | 95 | while (i < baseStr.size()) 96 | { 97 | result[i] = p[i]; 98 | i++; 99 | } 100 | result[i] = 0; 101 | 102 | return (long)baseStr.size(); 103 | } 104 | 105 | long rsaDecrypt(char* key, int keyLength, ubyte* data, size_t len, ubyte* result) 106 | { 107 | string sData((char*)data, len); 108 | unsigned char* buf = new unsigned char[len * 2]; 109 | size_t t_len = 0; 110 | 111 | try 112 | { 113 | t_len = crypto::base64::Base64::decode(sData, buf); 114 | } 115 | catch (...) 116 | { 117 | delete[] buf; 118 | return -1; 119 | } 120 | 121 | string sKey(key, keyLength); 122 | 123 | try 124 | { 125 | t_len = RSA::decrypt(sKey, buf, t_len, result, true); 126 | } 127 | catch (...) 128 | { 129 | delete[] buf; 130 | return -2; 131 | } 132 | 133 | delete[] buf; 134 | 135 | return (long)t_len; 136 | } 137 | -------------------------------------------------------------------------------- /src/md5.cpp: -------------------------------------------------------------------------------- 1 | #include "md5.h" 2 | 3 | namespace crypto 4 | { 5 | 6 | #define GET_UINT32(n, b, i) \ 7 | { \ 8 | (n) = (__uint32) ((__uint8 *) b)[(i)] \ 9 | | (((__uint32) ((__uint8 *) b)[(i)+1]) << 8) \ 10 | | (((__uint32) ((__uint8 *) b)[(i)+2]) << 16) \ 11 | | (((__uint32) ((__uint8 *) b)[(i)+3]) << 24); \ 12 | } 13 | 14 | #define PUT_UINT32(n, b, i) \ 15 | { \ 16 | (((__uint8 *) b)[(i)] ) = (__uint8) (((n) ) & 0xFF); \ 17 | (((__uint8 *) b)[(i)+1]) = (__uint8) (((n) >> 8) & 0xFF); \ 18 | (((__uint8 *) b)[(i)+2]) = (__uint8) (((n) >> 16) & 0xFF); \ 19 | (((__uint8 *) b)[(i)+3]) = (__uint8) (((n) >> 24) & 0xFF); \ 20 | } 21 | 22 | void MD5::md5_starts(struct md5_context *ctx ) 23 | { 24 | ctx->total[0] = 0; 25 | ctx->total[1] = 0; 26 | ctx->state[0] = 0x67452301; 27 | ctx->state[1] = 0xEFCDAB89; 28 | ctx->state[2] = 0x98BADCFE; 29 | ctx->state[3] = 0x10325476; 30 | } 31 | 32 | void MD5::md5_process(struct md5_context *ctx, __uint8 data[64]) 33 | { 34 | __uint32 A, B, C, D, X[16]; 35 | 36 | GET_UINT32( X[0], data, 0 ); 37 | GET_UINT32( X[1], data, 4 ); 38 | GET_UINT32( X[2], data, 8 ); 39 | GET_UINT32( X[3], data, 12 ); 40 | GET_UINT32( X[4], data, 16 ); 41 | GET_UINT32( X[5], data, 20 ); 42 | GET_UINT32( X[6], data, 24 ); 43 | GET_UINT32( X[7], data, 28 ); 44 | GET_UINT32( X[8], data, 32 ); 45 | GET_UINT32( X[9], data, 36 ); 46 | GET_UINT32( X[10], data, 40 ); 47 | GET_UINT32( X[11], data, 44 ); 48 | GET_UINT32( X[12], data, 48 ); 49 | GET_UINT32( X[13], data, 52 ); 50 | GET_UINT32( X[14], data, 56 ); 51 | GET_UINT32( X[15], data, 60 ); 52 | 53 | #define S(x, n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n))) 54 | 55 | #define P(a,b,c,d,k,s,t) \ 56 | { \ 57 | a += F(b,c,d) + X[k] + t; a = S(a,s) + b; \ 58 | } 59 | 60 | A = ctx->state[0]; 61 | B = ctx->state[1]; 62 | C = ctx->state[2]; 63 | D = ctx->state[3]; 64 | 65 | #define F(x,y,z) (z ^ (x & (y ^ z))) 66 | 67 | P( A, B, C, D, 0, 7, 0xD76AA478 ); 68 | P( D, A, B, C, 1, 12, 0xE8C7B756 ); 69 | P( C, D, A, B, 2, 17, 0x242070DB ); 70 | P( B, C, D, A, 3, 22, 0xC1BDCEEE ); 71 | P( A, B, C, D, 4, 7, 0xF57C0FAF ); 72 | P( D, A, B, C, 5, 12, 0x4787C62A ); 73 | P( C, D, A, B, 6, 17, 0xA8304613 ); 74 | P( B, C, D, A, 7, 22, 0xFD469501 ); 75 | P( A, B, C, D, 8, 7, 0x698098D8 ); 76 | P( D, A, B, C, 9, 12, 0x8B44F7AF ); 77 | P( C, D, A, B, 10, 17, 0xFFFF5BB1 ); 78 | P( B, C, D, A, 11, 22, 0x895CD7BE ); 79 | P( A, B, C, D, 12, 7, 0x6B901122 ); 80 | P( D, A, B, C, 13, 12, 0xFD987193 ); 81 | P( C, D, A, B, 14, 17, 0xA679438E ); 82 | P( B, C, D, A, 15, 22, 0x49B40821 ); 83 | 84 | #undef F 85 | 86 | #define F(x,y,z) (y ^ (z & (x ^ y))) 87 | 88 | P( A, B, C, D, 1, 5, 0xF61E2562 ); 89 | P( D, A, B, C, 6, 9, 0xC040B340 ); 90 | P( C, D, A, B, 11, 14, 0x265E5A51 ); 91 | P( B, C, D, A, 0, 20, 0xE9B6C7AA ); 92 | P( A, B, C, D, 5, 5, 0xD62F105D ); 93 | P( D, A, B, C, 10, 9, 0x02441453 ); 94 | P( C, D, A, B, 15, 14, 0xD8A1E681 ); 95 | P( B, C, D, A, 4, 20, 0xE7D3FBC8 ); 96 | P( A, B, C, D, 9, 5, 0x21E1CDE6 ); 97 | P( D, A, B, C, 14, 9, 0xC33707D6 ); 98 | P( C, D, A, B, 3, 14, 0xF4D50D87 ); 99 | P( B, C, D, A, 8, 20, 0x455A14ED ); 100 | P( A, B, C, D, 13, 5, 0xA9E3E905 ); 101 | P( D, A, B, C, 2, 9, 0xFCEFA3F8 ); 102 | P( C, D, A, B, 7, 14, 0x676F02D9 ); 103 | P( B, C, D, A, 12, 20, 0x8D2A4C8A ); 104 | 105 | #undef F 106 | 107 | #define F(x,y,z) (x ^ y ^ z) 108 | 109 | P( A, B, C, D, 5, 4, 0xFFFA3942 ); 110 | P( D, A, B, C, 8, 11, 0x8771F681 ); 111 | P( C, D, A, B, 11, 16, 0x6D9D6122 ); 112 | P( B, C, D, A, 14, 23, 0xFDE5380C ); 113 | P( A, B, C, D, 1, 4, 0xA4BEEA44 ); 114 | P( D, A, B, C, 4, 11, 0x4BDECFA9 ); 115 | P( C, D, A, B, 7, 16, 0xF6BB4B60 ); 116 | P( B, C, D, A, 10, 23, 0xBEBFBC70 ); 117 | P( A, B, C, D, 13, 4, 0x289B7EC6 ); 118 | P( D, A, B, C, 0, 11, 0xEAA127FA ); 119 | P( C, D, A, B, 3, 16, 0xD4EF3085 ); 120 | P( B, C, D, A, 6, 23, 0x04881D05 ); 121 | P( A, B, C, D, 9, 4, 0xD9D4D039 ); 122 | P( D, A, B, C, 12, 11, 0xE6DB99E5 ); 123 | P( C, D, A, B, 15, 16, 0x1FA27CF8 ); 124 | P( B, C, D, A, 2, 23, 0xC4AC5665 ); 125 | 126 | #undef F 127 | 128 | #define F(x,y,z) (y ^ (x | ~z)) 129 | 130 | P( A, B, C, D, 0, 6, 0xF4292244 ); 131 | P( D, A, B, C, 7, 10, 0x432AFF97 ); 132 | P( C, D, A, B, 14, 15, 0xAB9423A7 ); 133 | P( B, C, D, A, 5, 21, 0xFC93A039 ); 134 | P( A, B, C, D, 12, 6, 0x655B59C3 ); 135 | P( D, A, B, C, 3, 10, 0x8F0CCC92 ); 136 | P( C, D, A, B, 10, 15, 0xFFEFF47D ); 137 | P( B, C, D, A, 1, 21, 0x85845DD1 ); 138 | P( A, B, C, D, 8, 6, 0x6FA87E4F ); 139 | P( D, A, B, C, 15, 10, 0xFE2CE6E0 ); 140 | P( C, D, A, B, 6, 15, 0xA3014314 ); 141 | P( B, C, D, A, 13, 21, 0x4E0811A1 ); 142 | P( A, B, C, D, 4, 6, 0xF7537E82 ); 143 | P( D, A, B, C, 11, 10, 0xBD3AF235 ); 144 | P( C, D, A, B, 2, 15, 0x2AD7D2BB ); 145 | P( B, C, D, A, 9, 21, 0xEB86D391 ); 146 | 147 | #undef F 148 | 149 | ctx->state[0] += A; 150 | ctx->state[1] += B; 151 | ctx->state[2] += C; 152 | ctx->state[3] += D; 153 | } 154 | 155 | void MD5::md5_update(struct md5_context* ctx, __uint8* input, size_t length) 156 | { 157 | __uint32 left, fill; 158 | 159 | if (!length ) return; 160 | 161 | left = ( ctx->total[0] >> 3 ) & 0x3F; 162 | fill = 64 - left; 163 | 164 | ctx->total[0] += (unsigned int)(length << 3); 165 | ctx->total[1] += (unsigned int)(length >> 29); 166 | 167 | ctx->total[0] &= 0xFFFFFFFF; 168 | ctx->total[1] += ctx->total[0] < length << 3; 169 | 170 | if (left && length >= fill) 171 | { 172 | memcpy((void *) (ctx->buffer + left), (void*)input, fill ); 173 | md5_process(ctx, ctx->buffer); 174 | length -= fill; 175 | input += fill; 176 | left = 0; 177 | } 178 | 179 | while (length >= 64) 180 | { 181 | md5_process(ctx, input); 182 | length -= 64; 183 | input += 64; 184 | } 185 | 186 | if (length) 187 | { 188 | memcpy((void *)(ctx->buffer + left), (void *)input, length); 189 | } 190 | } 191 | 192 | static __uint8 md5_padding[64] = 193 | { 194 | 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 196 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 197 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 198 | }; 199 | 200 | void MD5::md5_finish(struct md5_context* ctx, __uint8 digest[16]) 201 | { 202 | __uint32 last, padn; 203 | __uint8 msglen[8]; 204 | 205 | PUT_UINT32( ctx->total[0], msglen, 0 ); 206 | PUT_UINT32( ctx->total[1], msglen, 4 ); 207 | 208 | last = ( ctx->total[0] >> 3 ) & 0x3F; 209 | padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last ); 210 | 211 | md5_update( ctx, md5_padding, padn ); 212 | md5_update( ctx, msglen, 8 ); 213 | 214 | PUT_UINT32( ctx->state[0], digest, 0 ); 215 | PUT_UINT32( ctx->state[1], digest, 4 ); 216 | PUT_UINT32( ctx->state[2], digest, 8 ); 217 | PUT_UINT32( ctx->state[3], digest, 12 ); 218 | } 219 | 220 | string MD5::GenerateMD5(unsigned char* buffer, size_t bufferlen) 221 | { 222 | struct md5_context context; 223 | md5_starts (&context); 224 | md5_update (&context, buffer, bufferlen); 225 | md5_finish (&context,(unsigned char*)m_data); 226 | 227 | return this->ToString(); 228 | } 229 | 230 | MD5::MD5() 231 | { 232 | for(int i = 0;i < 4; i++) 233 | m_data[i] = 0; 234 | } 235 | 236 | MD5::MD5(unsigned int* md5src) 237 | { 238 | memcpy(m_data, md5src, 16); 239 | } 240 | 241 | int _httoi(const char* value) 242 | { 243 | struct CHexMap 244 | { 245 | char chr; 246 | int value; 247 | }; 248 | 249 | const int HexMapL = 16; 250 | CHexMap HexMap[HexMapL] = 251 | { 252 | {'0', 0}, {'1', 1}, 253 | {'2', 2}, {'3', 3}, 254 | {'4', 4}, {'5', 5}, 255 | {'6', 6}, {'7', 7}, 256 | {'8', 8}, {'9', 9}, 257 | {'a', 10}, {'b', 11}, 258 | {'c', 12}, {'d', 13}, 259 | {'e', 14}, {'f', 15} 260 | }; 261 | 262 | #ifdef _MSC_VER 263 | char* mstr = _strdup(value); 264 | #else 265 | char* mstr = strdup(value); 266 | #endif 267 | char* s = mstr; 268 | int result = 0; 269 | if (*s == '0' && *(s + 1) == 'X') s += 2; 270 | bool firsttime = true; 271 | while (*s != '\0') 272 | { 273 | bool found = false; 274 | for (int i = 0; i < HexMapL; i++) 275 | { 276 | if (*s == HexMap[i].chr) 277 | { 278 | if (!firsttime) result <<= 4; 279 | result |= HexMap[i].value; 280 | found = true; 281 | break; 282 | } 283 | } 284 | if (!found) break; 285 | s++; 286 | firsttime = false; 287 | } 288 | 289 | free(mstr); 290 | 291 | return result; 292 | } 293 | 294 | MD5::MD5(const char* md5src) 295 | { 296 | if (strcmp(md5src, "") == 0) 297 | { 298 | for(int i = 0;i < 4; i++) 299 | m_data[i] = 0; 300 | 301 | return; 302 | } 303 | 304 | for (int j = 0; j < 16; j++ ) 305 | { 306 | char buf[10]; 307 | strncpy(buf, md5src, 2); 308 | md5src += 2; 309 | ((unsigned char*)m_data)[j] = _httoi(buf); 310 | } 311 | } 312 | 313 | MD5 MD5::operator + (MD5 adder) 314 | { 315 | unsigned int m_newdata[4]; 316 | 317 | for(int i = 0; i < 4; i++) 318 | m_newdata[i] = m_data[i] ^ (adder.m_data[i]); 319 | 320 | return MD5(m_newdata); 321 | } 322 | 323 | bool MD5::operator == (MD5 cmper) 324 | { 325 | return (memcmp(cmper.m_data, m_data, 16) == 0); 326 | } 327 | 328 | string MD5::ToString() 329 | { 330 | char output[33]; 331 | 332 | for(int j = 0; j < 16; j++ ) 333 | { 334 | sprintf(output + j * 2, "%02x", ((unsigned char *)m_data)[j]); 335 | } 336 | 337 | return string(output); 338 | } 339 | 340 | } 341 | -------------------------------------------------------------------------------- /src/md5.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | using namespace std; 9 | 10 | namespace crypto 11 | { 12 | 13 | class MD5 14 | { 15 | 16 | private: 17 | 18 | #define __uint8 unsigned char 19 | #define __uint32 unsigned int 20 | 21 | struct MD5_DATA 22 | { 23 | unsigned int data[4]; 24 | 25 | bool operator < (const MD5_DATA& p) const 26 | { 27 | return memcmp(data, p.data, 4 * sizeof(int)) > 0; 28 | } 29 | }; 30 | 31 | struct md5_context 32 | { 33 | __uint32 total[2]; 34 | __uint32 state[4]; 35 | __uint8 buffer[64]; 36 | }; 37 | 38 | void md5_starts(struct md5_context* ctx); 39 | void md5_process(struct md5_context* ctx, __uint8 data[64]); 40 | void md5_update(struct md5_context* ctx, __uint8* input, size_t length); 41 | void md5_finish(struct md5_context* ctx, __uint8 digest[16]); 42 | 43 | public: 44 | 45 | string GenerateMD5(unsigned char* buffer, size_t bufferlen); 46 | MD5(); 47 | MD5(const char * md5src); 48 | MD5(unsigned int* md5src); 49 | MD5 operator +(MD5 adder); 50 | bool operator ==(MD5 cmper); 51 | string ToString(); 52 | 53 | unsigned int m_data[4]; 54 | }; 55 | 56 | static MD5 MD5Utils; 57 | 58 | } 59 | -------------------------------------------------------------------------------- /src/rsa.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "rsa.h" 4 | #include "tea/xtea.h" 5 | #include "utils/random.h" 6 | #include "utils/utility.h" 7 | #include "base64.h" 8 | 9 | using namespace crypto::rsa; 10 | 11 | namespace crypto 12 | { 13 | namespace rsa 14 | { 15 | 16 | Random rnd; 17 | 18 | RSAKeyPair RSA::generateKeyPair(uint bitLength = 1024) 19 | { 20 | assert((bitLength >= 128) && (bitLength % 8 == 0)); 21 | 22 | BigInt p, q, n, t, e; 23 | 24 | p = p.genPseudoPrime(bitLength / 2, 40, rnd); 25 | q = q.genPseudoPrime(bitLength / 2, 40, rnd); 26 | n = p * q; 27 | t = (p - 1) * (q - 1); 28 | e = Primes[(rnd.next() % 42) + 6500]; 29 | 30 | BigInt d = e.modInverse(t); 31 | 32 | return RSAKeyPair(encodeKey(n, d), encodeKey(n, e)); 33 | } 34 | 35 | string RSA::encodeKey(BigInt modulus, BigInt exponent) 36 | { 37 | int m_len = modulus.dataLength << 2; 38 | ubyte* m_bytes = new ubyte[m_len]; 39 | m_len = modulus.getBytesRemovedZero(m_bytes, m_len); 40 | 41 | int e_len = exponent.dataLength << 2; 42 | ubyte* e_bytes = new ubyte[e_len]; 43 | e_len = exponent.getBytesRemovedZero(e_bytes, e_len); 44 | 45 | ubyte* buffer = new ubyte[4 + m_len + e_len]; 46 | Utility::writeIntToBytes(m_len, buffer, ENDIAN_BIG); 47 | 48 | for (int i = 0; i < m_len; i++) 49 | { 50 | buffer[i + 4] = m_bytes[i]; 51 | } 52 | 53 | for (int i = 0; i < e_len; i++) 54 | { 55 | buffer[i + 4 + m_len] = e_bytes[i]; 56 | } 57 | 58 | string ret = crypto::base64::Base64::encode(buffer, 4 + m_len + e_len); 59 | delete[] m_bytes; 60 | delete[] e_bytes; 61 | delete[] buffer; 62 | 63 | return ret; 64 | } 65 | 66 | RSAKeyInfo RSA::decodeKey(string const& key) 67 | { 68 | ubyte* buffer = new ubyte[key.size()]; 69 | size_t size = crypto::base64::Base64::decode(key, buffer); 70 | int m_len = Utility::readIntFromBytes(buffer, ENDIAN_BIG); 71 | 72 | ubyte* m_bytes = new ubyte[m_len]; 73 | for (int i = 0; i < m_len; i++) 74 | { 75 | m_bytes[i] = buffer[i + 4]; 76 | } 77 | 78 | ubyte* e_bytes = new ubyte[size - 4 - m_len]; 79 | for (size_t i = 0; i < size - 4 - m_len; i++) 80 | { 81 | e_bytes[i] = buffer[i + 4 + m_len]; 82 | } 83 | 84 | RSAKeyInfo ret = RSAKeyInfo(BigInt(m_bytes, m_len), BigInt(e_bytes, (int)(size - 4 - m_len))); 85 | delete[] buffer; 86 | delete[] m_bytes; 87 | delete[] e_bytes; 88 | 89 | return ret; 90 | } 91 | 92 | size_t RSA::encrypt(string const& key, ubyte* data, size_t len, ubyte* result, bool mixinXteaMode) 93 | { 94 | RSAKeyInfo keyInfo = decodeKey(key); 95 | return encrypt(keyInfo, data, len, result, mixinXteaMode); 96 | } 97 | 98 | size_t RSA::encrypt(RSAKeyInfo key, ubyte* data, size_t len, ubyte* result, bool mixinXteaMode) 99 | { 100 | if (mixinXteaMode) 101 | { 102 | return encrypt_mixinXteaMode(key, data, len, result); 103 | } 104 | 105 | int keySize = key.modulus.dataLength << 2; 106 | ubyte* t_buf = new ubyte[keySize]; 107 | keySize = key.modulus.getBytesRemovedZero(t_buf, keySize); 108 | delete[] t_buf; 109 | size_t pos = 0, ret_pos = 0; 110 | ubyte* block; 111 | BigInt bi; 112 | 113 | while (pos < len) 114 | { 115 | int blockSize = (int)(((keySize - 1) <= (int)(len - pos)) ? (keySize - 1) : (len - pos)); 116 | ubyte preamble = (ubyte)rnd.next(0x01, 0xFF); 117 | 118 | while (true) 119 | { 120 | block = new ubyte[blockSize + 1]; 121 | block[0] = preamble; 122 | 123 | for (size_t i = pos; i < pos + blockSize; i++) 124 | { 125 | block[i - pos + 1] = data[i]; 126 | } 127 | 128 | bi = BigInt(block, blockSize + 1); 129 | if (bi >= key.modulus) 130 | { 131 | delete[] block; 132 | blockSize--; 133 | assert(blockSize > 0); 134 | continue; 135 | } 136 | else 137 | { 138 | break; 139 | } 140 | } 141 | 142 | pos += blockSize; 143 | bi = bi.modPow(key.exponent, key.modulus); 144 | delete[] block; 145 | int block_len = bi.dataLength << 2; 146 | block = new ubyte[block_len]; 147 | block_len = bi.getBytesRemovedZero(block, block_len); 148 | 149 | if (block_len < keySize) 150 | { 151 | for (int i = 0; i < keySize - block_len; i++) 152 | { 153 | result[ret_pos++] = 0x00; 154 | } 155 | } 156 | for (int i = 0; i < block_len; i++) 157 | { 158 | result[ret_pos++] = block[i]; 159 | } 160 | 161 | delete[] block; 162 | } 163 | 164 | result[ret_pos] = 0; 165 | return ret_pos; 166 | } 167 | 168 | size_t RSA::encrypt_mixinXteaMode(RSAKeyInfo key, ubyte* data, size_t len, ubyte* result) 169 | { 170 | int keySize = key.modulus.dataLength << 2; 171 | ubyte* t_buf = new ubyte[keySize]; 172 | keySize = key.modulus.getBytesRemovedZero(t_buf, keySize); 173 | delete[] t_buf; 174 | size_t pos = 0; 175 | ubyte* block; 176 | BigInt bi; 177 | 178 | int blockSize = (int)(((keySize - 1) <= (int)len) ? (keySize - 1) : len); 179 | ubyte preamble = (ubyte)rnd.next(0x01, 0xFF); 180 | int xteaKey[4]; 181 | 182 | while (true) 183 | { 184 | block = new ubyte[blockSize + 1]; 185 | block[0] = preamble; 186 | 187 | for (int i = 0; i < blockSize; i++) 188 | { 189 | block[i + 1] = data[i]; 190 | } 191 | 192 | bi = BigInt(block, blockSize + 1); 193 | if (bi >= key.modulus) 194 | { 195 | delete[] block; 196 | blockSize--; 197 | assert(blockSize > 0); 198 | continue; 199 | } 200 | else 201 | { 202 | generateXteaKey(block, blockSize + 1, xteaKey); 203 | break; 204 | } 205 | } 206 | 207 | bi = bi.modPow(key.exponent, key.modulus); 208 | delete[] block; 209 | int t_len = bi.dataLength << 2; 210 | block = new ubyte[t_len]; 211 | t_len = bi.getBytesRemovedZero(block, t_len); 212 | 213 | if (t_len < keySize) 214 | { 215 | for (int i = 0; i < keySize - t_len; i++) 216 | { 217 | result[pos++] = 0x00; 218 | } 219 | } 220 | for (int i = 0; i < t_len; i++) 221 | { 222 | result[pos++] = block[i]; 223 | } 224 | 225 | delete[] block; 226 | 227 | if (blockSize >= (int)len) 228 | { 229 | result[pos] = 0; 230 | return pos; 231 | } 232 | 233 | block = new ubyte[len - blockSize + 12]; 234 | size_t remainder_len = crypto::tea::xtea::XTEAUtils::encrypt(data + blockSize, len - blockSize, xteaKey, block); 235 | for (size_t i = 0; i < remainder_len; i++) 236 | { 237 | result[pos++] = block[i]; 238 | } 239 | delete[] block; 240 | 241 | result[pos] = 0; 242 | return pos; 243 | } 244 | 245 | size_t RSA::decrypt(string const& key, ubyte* data, size_t len, ubyte* result, bool mixinXteaMode) 246 | { 247 | RSAKeyInfo keyInfo = decodeKey(key); 248 | return decrypt(keyInfo, data, len, result, mixinXteaMode); 249 | } 250 | 251 | size_t RSA::decrypt(RSAKeyInfo key, ubyte* data, size_t len, ubyte* result, bool mixinXteaMode) 252 | { 253 | if (mixinXteaMode) 254 | { 255 | return decrypt_mixinXteaMode(key, data, len, result); 256 | } 257 | 258 | int keySize = key.modulus.dataLength << 2; 259 | ubyte* t_buf = new ubyte[keySize]; 260 | keySize = key.modulus.getBytesRemovedZero(t_buf, keySize); 261 | delete[] t_buf; 262 | size_t pos = 0, ret_pos = 0; 263 | ubyte* block; 264 | BigInt bi; 265 | 266 | while (pos < len) 267 | { 268 | int blockSize = (int)((keySize <= (int)(len - pos)) ? keySize : (len - pos)); 269 | block = new ubyte[blockSize]; 270 | 271 | for (size_t i = pos; i < pos + blockSize; i++) 272 | { 273 | block[i - pos] = data[i]; 274 | } 275 | 276 | bi = BigInt(block, blockSize); 277 | delete[] block; 278 | pos += blockSize; 279 | bi = bi.modPow(key.exponent, key.modulus); 280 | 281 | int block_len = bi.dataLength << 2; 282 | block = new ubyte[block_len]; 283 | block_len = bi.getBytesRemovedZero(block, block_len); 284 | 285 | for (int i = 1; i < block_len; i++) // skip [0] first random element. 286 | { 287 | result[ret_pos++] = block[i]; 288 | } 289 | 290 | delete[] block; 291 | } 292 | 293 | result[ret_pos] = 0; 294 | return ret_pos; 295 | } 296 | 297 | size_t RSA::decrypt_mixinXteaMode(RSAKeyInfo key, ubyte* data, size_t len, ubyte* result) 298 | { 299 | int keySize = key.modulus.dataLength << 2; 300 | ubyte* t_buf = new ubyte[keySize]; 301 | keySize = key.modulus.getBytesRemovedZero(t_buf, keySize); 302 | delete[] t_buf; 303 | size_t pos = 0; 304 | ubyte* block; 305 | int xteaKey[4]; 306 | 307 | int blockSize = (int)((keySize <= (int)len) ? keySize : len); 308 | block = new ubyte[blockSize]; 309 | 310 | for (int i = 0; i < blockSize; i++) 311 | { 312 | block[i] = data[i]; 313 | } 314 | 315 | BigInt bi = BigInt(block, blockSize); 316 | delete[] block; 317 | bi = bi.modPow(key.exponent, key.modulus); 318 | 319 | int t_len = bi.dataLength << 2; 320 | block = new ubyte[t_len]; 321 | t_len = bi.getBytesRemovedZero(block, t_len); 322 | 323 | generateXteaKey(block, t_len, xteaKey); 324 | 325 | for (int i = 1; i < t_len; i++) // skip [0] first random element. 326 | { 327 | result[pos++] = block[i]; 328 | } 329 | delete[] block; 330 | 331 | if (blockSize >= (int)len) 332 | { 333 | result[pos] = 0; 334 | return pos; 335 | } 336 | 337 | block = new ubyte[len - blockSize]; 338 | size_t remainder_len = crypto::tea::xtea::XTEAUtils::decrypt(data + blockSize, len - blockSize, xteaKey, block); 339 | 340 | for (size_t i = 0; i < remainder_len; i++) 341 | { 342 | result[pos++] = block[i]; 343 | } 344 | delete[] block; 345 | 346 | result[pos] = 0; 347 | return pos; 348 | } 349 | 350 | void RSA::generateXteaKey(ubyte* buf, size_t len, int* xteaKey) 351 | { 352 | ubyte* data = new ubyte[sizeof(int) * 4]; 353 | for (int i = 0; i < (int)sizeof(int) * 4; i++) 354 | { 355 | data[i] = buf[i % len]; 356 | } 357 | 358 | for (int i = 0; i < 4; i++) 359 | { 360 | *(xteaKey + i) = Utility::readIntFromBytes(data + i * sizeof(int), ENDIAN_BIG); 361 | } 362 | 363 | delete[] data; 364 | } 365 | 366 | } 367 | } 368 | -------------------------------------------------------------------------------- /src/rsa.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "utils/types.h" 4 | #include "utils/bigint.h" 5 | #include "utils/random.h" 6 | 7 | using namespace std; 8 | using namespace crypto::utils; 9 | 10 | namespace crypto 11 | { 12 | namespace rsa 13 | { 14 | 15 | struct RSAKeyPair 16 | { 17 | public: 18 | string privateKey; 19 | string publicKey; 20 | 21 | RSAKeyPair() 22 | { 23 | } 24 | 25 | RSAKeyPair(string privateKey, string publicKey) 26 | { 27 | this->privateKey = privateKey; 28 | this->publicKey = publicKey; 29 | } 30 | }; 31 | 32 | struct RSAKeyInfo 33 | { 34 | public: 35 | BigInt modulus; 36 | BigInt exponent; 37 | 38 | RSAKeyInfo() 39 | { 40 | } 41 | 42 | RSAKeyInfo(BigInt modulus, BigInt exponent) 43 | { 44 | this->modulus = modulus; 45 | this->exponent = exponent; 46 | } 47 | }; 48 | 49 | class RSA 50 | { 51 | public: 52 | static RSAKeyPair generateKeyPair(uint); 53 | static string encodeKey(BigInt, BigInt); 54 | static RSAKeyInfo decodeKey(string const&); 55 | static size_t encrypt(string const&, ubyte*, size_t, ubyte*, bool mixinXteaMode = false); 56 | static size_t encrypt(RSAKeyInfo, ubyte*, size_t, ubyte*, bool mixinXteaMode = false); 57 | static size_t decrypt(string const&, ubyte*, size_t, ubyte*, bool mixinXteaMode = false); 58 | static size_t decrypt(RSAKeyInfo, ubyte*, size_t, ubyte*, bool mixinXteaMode = false); 59 | 60 | private: 61 | static size_t encrypt_mixinXteaMode(RSAKeyInfo, ubyte*, size_t, ubyte*); 62 | static size_t decrypt_mixinXteaMode(RSAKeyInfo, ubyte*, size_t, ubyte*); 63 | 64 | static void generateXteaKey(ubyte* buf, size_t len, int* xteaKey); 65 | }; 66 | 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /src/tea/xtea.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include "xtea.h" 4 | 5 | using namespace crypto::utils; 6 | 7 | namespace crypto 8 | { 9 | namespace tea 10 | { 11 | namespace xtea 12 | { 13 | 14 | XTEA::XTEA(int* key, int rounds) 15 | { 16 | this->DELTA = 0x9E3779B9; 17 | this->m_key = key; 18 | this->m_rounds = rounds; 19 | } 20 | 21 | size_t XTEA::padding(ubyte* data, size_t len, ubyte* output) 22 | { 23 | size_t output_len = len; 24 | while ((output_len + 4) % 8 != 0) output_len++; 25 | 26 | for (size_t i = 0; i < len; i++) 27 | output[i] = data[i]; 28 | for (size_t i = len; i < output_len; i++) 29 | output[i] = 0; 30 | 31 | Utility::writeIntToBytes((uint)len, output + output_len, ENDIAN_BIG); 32 | 33 | return output_len + 4; 34 | } 35 | 36 | // Encrypt given ubyte array (length to be crypted must be 8 ubyte aligned) 37 | size_t XTEA::encrypt(ubyte* data, size_t len, ubyte* result) 38 | { 39 | size_t output_len = padding(data, len, result); 40 | 41 | for (size_t i = 0; i < (output_len + 4) / 8; i++) 42 | { 43 | int v0 = Utility::readIntFromBytes(result + (i * 8)); 44 | int v1 = Utility::readIntFromBytes(result + (i * 8 + 4)); 45 | 46 | int sum = 0; 47 | 48 | for (int j = 0; j < m_rounds; j++) 49 | { 50 | v0 += ((v1 << 4 ^ (int)((uint)v1 >> 5)) + v1) ^ (sum + m_key[sum & 3]); 51 | sum += DELTA; 52 | v1 += ((v0 << 4 ^ (int)((uint)v0 >> 5)) + v0) ^ (sum + m_key[(int)((uint)sum >> 11) & 3]); 53 | } 54 | 55 | Utility::writeIntToBytes(v0, result + (i * 8)); 56 | Utility::writeIntToBytes(v1, result + (i * 8 + 4)); 57 | } 58 | 59 | return output_len; 60 | } 61 | 62 | // Decrypt given ubyte array (length to be crypted must be 8 ubyte aligned) 63 | size_t XTEA::decrypt(ubyte* data, size_t len, ubyte* result) 64 | { 65 | assert(len > 0 && len % 8 == 0); 66 | 67 | for (size_t i = 0; i < len; i++) 68 | result[i] = data[i]; 69 | 70 | for (size_t i = 0; i < len / 8; i++) 71 | { 72 | int v0 = Utility::readIntFromBytes(result + (i * 8)); 73 | int v1 = Utility::readIntFromBytes(result + (i * 8 + 4)); 74 | 75 | int sum = (int)((uint)DELTA * (uint)m_rounds); 76 | 77 | for (int j = 0; j < m_rounds; j++) 78 | { 79 | v1 -= ((v0 << 4 ^ (int)((uint)v0 >> 5)) + v0) ^ (sum + m_key[(int)((uint)sum >> 11) & 3]); 80 | sum -= DELTA; 81 | v0 -= ((v1 << 4 ^ (int)((uint)v1 >> 5)) + v1) ^ (sum + m_key[sum & 3]); 82 | } 83 | 84 | Utility::writeIntToBytes(v0, result + (i * 8)); 85 | Utility::writeIntToBytes(v1, result + (i * 8 + 4)); 86 | } 87 | 88 | return Utility::readIntFromBytes(result + (len - 4), ENDIAN_BIG); 89 | } 90 | 91 | size_t XTEAUtils::encrypt(ubyte* data, size_t len, int key[], ubyte* result) 92 | { 93 | return handle(data, len, key, result, 1); 94 | } 95 | 96 | size_t XTEAUtils::decrypt(ubyte* data, size_t len, int key[], ubyte* result) 97 | { 98 | return handle(data, len, key, result, 2); 99 | } 100 | 101 | size_t XTEAUtils::handle(ubyte* data, size_t len, int key[], ubyte* result, int EorD) 102 | { 103 | XTEA xtea(key, 64); 104 | return (EorD == 1) ? xtea.encrypt(data, len, result) : xtea.decrypt(data, len, result); 105 | } 106 | 107 | } 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/tea/xtea.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include "../utils/types.h" 6 | #include "../utils/utility.h" 7 | 8 | namespace crypto 9 | { 10 | namespace tea 11 | { 12 | namespace xtea 13 | { 14 | 15 | class XTEA 16 | { 17 | private: 18 | int DELTA; // XTEA delta constant 19 | int* m_key; // Key - 4 integer 20 | int m_rounds; // Round to go - 64 are commonly used 21 | 22 | size_t padding(ubyte*, size_t, ubyte*); 23 | public: 24 | XTEA(int* _key, int _rounds); 25 | 26 | size_t encrypt(ubyte*, size_t, ubyte*); 27 | size_t decrypt(ubyte*, size_t, ubyte*); 28 | }; 29 | 30 | class XTEAUtils 31 | { 32 | public: 33 | static size_t encrypt(ubyte* data, size_t len, int key[], ubyte* result); 34 | static size_t decrypt(ubyte* data, size_t len, int key[], ubyte* result); 35 | 36 | private: 37 | static size_t handle(ubyte* data, size_t len, int key[], ubyte* result, int EorD); 38 | }; 39 | 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/test.cpp: -------------------------------------------------------------------------------- 1 | //#include "rsa.h" 2 | //#include "base58.h" 3 | //#include "tea/xtea.h" 4 | //#include "aes.h" 5 | //#include 6 | // 7 | //using namespace crypto::rsa; 8 | //using namespace crypto::base58; 9 | //using namespace crypto::tea::xtea; 10 | //using namespace crypto::aes; 11 | 12 | //int main() 13 | //{ 14 | //} 15 | 16 | //int main_aes() 17 | //{ 18 | // ubyte key[] = "123456789012345678901234"; 19 | // AES128 aes(key, 24); 20 | // 21 | // ubyte data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 22 | // 23 | // ubyte* en = new ubyte[16 + 20]; 24 | // size_t len = aes.encrypt(data, 16, en); 25 | // 26 | // for (size_t i = 0; i < len; i ++) 27 | // { 28 | // cout << (int)en[i] << ", "; 29 | // } 30 | // cout << endl; 31 | // 32 | // ubyte* de = new ubyte[len]; 33 | // len = aes.decrypt(en, len, de); 34 | // 35 | // for (size_t i = 0; i < len; i ++) 36 | // { 37 | // cout << (int)de[i] << ", "; 38 | // } 39 | // 40 | // delete[] en; 41 | // delete[] de; 42 | // 43 | // return 0; 44 | //} 45 | 46 | //int main_aes2() 47 | //{ 48 | // string key = "123456789012345678901234"; 49 | // ubyte data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 }; 50 | // 51 | // ubyte* en = new ubyte[16 + 20]; 52 | // size_t len = AESUtils::encrypt(data, 16, key, en); 53 | // for (size_t i = 0; i < len; i ++) 54 | // { 55 | // cout << (int)en[i] << ", "; 56 | // } 57 | // cout << endl; 58 | // 59 | // 60 | // ubyte* de = new ubyte[len]; 61 | // len = AESUtils::decrypt(en, len, key, de); 62 | // 63 | // for (size_t i = 0; i < len; i ++) 64 | // { 65 | // cout << (int)de[i] << ", "; 66 | // } 67 | // 68 | // delete[] en; 69 | // delete[] de; 70 | // 71 | // return 0; 72 | //} 73 | 74 | //int main_xtea() 75 | //{ 76 | // int key[] = {10, 20, 30, 40}; 77 | // XTEA xtea(key, 64); 78 | // 79 | // ubyte data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12 }; 80 | // ubyte* en = new ubyte[12 + 12]; 81 | // size_t len = xtea.encrypt(data, 12, en); 82 | // 83 | // for (size_t i = 0; i < len; i ++) 84 | // { 85 | // cout << (int)en[i] << endl; 86 | // } 87 | // 88 | // ubyte* de = new ubyte[len]; 89 | // len = xtea.decrypt(en, len, de); 90 | // 91 | // for (size_t i = 0; i < len; i ++) 92 | // { 93 | // cout << (int)de[i] << endl; 94 | // } 95 | // 96 | // delete[] en; 97 | // delete[] de; 98 | // 99 | // return 0; 100 | //} 101 | 102 | //int main_xtea() 103 | //{ 104 | // string data = "abcdefg123"; 105 | // ubyte* p = (ubyte*)data.c_str(); 106 | // 107 | // string ret = Base58::encode(p, data.length()); 108 | // cout << ret << endl; 109 | // 110 | // p = new ubyte[data.length() * 2]; 111 | // size_t len = Base58::decode(ret, p); 112 | // 113 | // cout << string((char*)p, len); 114 | // return 0; 115 | //} 116 | 117 | //int main_rsa() 118 | //{ 119 | // RSAKeyPair keyPair = RSA::generateKeyPair(256); 120 | // cout << keyPair.privateKey << endl; 121 | // cout << keyPair.publicKey << endl; 122 | // 123 | // string data = "Copyright: Copyright Digital Mars 2007 - 2011.License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0)."; 124 | // 125 | // ubyte* buf = new ubyte[data.length() * 2 + 256]; // 256 is key size. 126 | // ubyte* p = (ubyte*)data.c_str(); 127 | // size_t len = RSA::encrypt(keyPair.privateKey, p, strlen((char*)p), buf); 128 | // 129 | // ubyte* buf2 = new ubyte[data.length() * 2]; 130 | // len = RSA::decrypt(keyPair.publicKey, buf, len, buf2); 131 | // 132 | // string ret((char*)buf2, len); 133 | // cout << ret; 134 | // 135 | // delete[] buf; 136 | // delete[] buf2; 137 | // 138 | // return 0; 139 | //} 140 | -------------------------------------------------------------------------------- /src/utils/bigint.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "bigint.h" 5 | 6 | namespace crypto 7 | { 8 | namespace utils 9 | { 10 | 11 | BigInt::BigInt(void) 12 | { 13 | init(); 14 | dataLength = 1; 15 | } 16 | 17 | BigInt::BigInt(uint64 value) 18 | { 19 | init(); 20 | 21 | dataLength = 0; 22 | while (value != 0 && dataLength < maxLength) 23 | { 24 | data[dataLength] = (uint) (value & 0xFFFFFFFF); 25 | value = value >> 32; 26 | dataLength++; 27 | } 28 | 29 | if (dataLength == 0) 30 | { 31 | dataLength = 1; 32 | } 33 | } 34 | 35 | BigInt::BigInt(const BigInt &bi) 36 | { 37 | init(); 38 | 39 | dataLength = bi.dataLength; 40 | 41 | for (int i = 0; i < dataLength; i++) 42 | { 43 | data[i] = bi.data[i]; 44 | } 45 | } 46 | 47 | BigInt::BigInt(const uint inData[], int length) 48 | { 49 | init(); 50 | 51 | dataLength = length; 52 | 53 | if (dataLength > maxLength) 54 | { 55 | dataLength = maxLength; 56 | } 57 | 58 | for (int i = dataLength - 1, j = 0; i >= 0; i--, j++) 59 | { 60 | data[j] = inData[i]; 61 | } 62 | 63 | while (dataLength > 1 && data[dataLength - 1] == 0) 64 | { 65 | dataLength--; 66 | } 67 | 68 | } 69 | 70 | BigInt::BigInt(const uint inData[], int length, bool direct) 71 | { 72 | init(); 73 | 74 | dataLength = length; 75 | 76 | if (dataLength > maxLength) 77 | { 78 | dataLength = maxLength; 79 | } 80 | 81 | if (direct) 82 | { 83 | for (int i = 0; i < dataLength; i++) 84 | { 85 | data[i] = inData[i]; 86 | } 87 | } 88 | else 89 | { 90 | for (int i = dataLength - 1, j = 0; i >= 0; i--, j++) 91 | { 92 | data[j] = inData[i]; 93 | } 94 | } 95 | 96 | while (dataLength > 1 && data[dataLength - 1] == 0) 97 | { 98 | dataLength--; 99 | } 100 | } 101 | 102 | BigInt::BigInt(const ubyte inData[], int length) 103 | { 104 | init(); 105 | dataLength = length >> 2; 106 | 107 | int leftOver = length & 0x3; 108 | 109 | if (leftOver != 0) // length not multiples of 4 110 | { 111 | dataLength++; 112 | } 113 | 114 | if (dataLength > maxLength) 115 | { 116 | dataLength = maxLength; 117 | length = dataLength << 2; 118 | } 119 | 120 | for (int i = length - 1, j = 0; i >= 3; i -= 4, j++) 121 | { 122 | data[j] = (uint) (((uint) inData[i - 3] << 24) + ((uint) inData[i - 2] << 16) + ((uint) inData[i - 1] << 8) + inData[i]); 123 | } 124 | 125 | if (leftOver == 1) 126 | { 127 | data[dataLength - 1] = (uint) inData[0]; 128 | } 129 | else if (leftOver == 2) 130 | { 131 | data[dataLength - 1] = (uint) (((uint) inData[0] << 8) + inData[1]); 132 | } 133 | else if (leftOver == 3) 134 | { 135 | data[dataLength - 1] = (uint) (((uint) inData[0] << 16) + ((uint) inData[1] << 8) + inData[2]); 136 | } 137 | 138 | while (dataLength > 1 && data[dataLength - 1] == 0) 139 | { 140 | dataLength--; 141 | } 142 | } 143 | 144 | BigInt::~BigInt(void) 145 | { 146 | } 147 | 148 | void BigInt::init() 149 | { 150 | dataLength = 0; 151 | for (int i = 0; i < maxLength; i++) 152 | { 153 | data[i] = 0u; 154 | } 155 | } 156 | 157 | BigInt operator +(const BigInt &bi1, const BigInt &bi2) 158 | { 159 | BigInt result; 160 | result.dataLength = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength; 161 | 162 | int64 carry = 0; 163 | for (int i = 0; i < result.dataLength; i++) 164 | { 165 | int64 sum = (int64) bi1.data[i] + (int64) bi2.data[i] + carry; 166 | carry = sum >> 32; 167 | result.data[i] = (uint) (sum & 0xFFFFFFFF); 168 | } 169 | 170 | if (carry != 0 && result.dataLength < maxLength) 171 | { 172 | result.data[result.dataLength] = (uint) (carry); 173 | result.dataLength++; 174 | } 175 | 176 | while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0) 177 | result.dataLength--; 178 | 179 | return result; 180 | } 181 | 182 | BigInt operator ++(BigInt& bi) 183 | { 184 | 185 | int64 val, carry = 1; 186 | int index = 0; 187 | 188 | while (carry != 0 && index < maxLength) 189 | { 190 | val = (int64) (bi.data[index]); 191 | val++; 192 | 193 | bi.data[index] = (uint) (val & 0xFFFFFFFF); 194 | carry = val >> 32; 195 | 196 | index++; 197 | } 198 | 199 | if (index > bi.dataLength) 200 | bi.dataLength = index; 201 | else 202 | { 203 | while (bi.dataLength > 1 && bi.data[bi.dataLength - 1] == 0) 204 | bi.dataLength--; 205 | } 206 | 207 | return bi; 208 | } 209 | 210 | BigInt operator -(const BigInt& bi1, const BigInt& bi2) 211 | { 212 | BigInt result; 213 | 214 | result.dataLength = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength; 215 | 216 | int64 carryIn = 0; 217 | for (int i = 0; i < result.dataLength; i++) 218 | { 219 | int64 diff; 220 | 221 | diff = (int64) bi1.data[i] - (int64) bi2.data[i] - carryIn; 222 | result.data[i] = (uint) (diff & 0xFFFFFFFF); 223 | 224 | if (diff < 0) 225 | carryIn = 1; 226 | else 227 | carryIn = 0; 228 | } 229 | 230 | // roll over to negative 231 | if (carryIn != 0) 232 | { 233 | for (int i = result.dataLength; i < maxLength; i++) 234 | result.data[i] = 0xFFFFFFFF; 235 | result.dataLength = maxLength; 236 | } 237 | 238 | // fixed in v1.03 to give correct datalength for a - (-b) 239 | while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0) 240 | result.dataLength--; 241 | 242 | return result; 243 | } 244 | 245 | BigInt operator --(BigInt &bi) 246 | { 247 | int64 val; 248 | bool carryIn = true; 249 | int index = 0; 250 | 251 | while (carryIn && index < maxLength) 252 | { 253 | val = (int64) (bi.data[index]); 254 | val--; 255 | 256 | bi.data[index] = (uint) (val & 0xFFFFFFFF); 257 | 258 | if (val >= 0) 259 | carryIn = false; 260 | 261 | index++; 262 | } 263 | 264 | if (index > bi.dataLength) 265 | bi.dataLength = index; 266 | 267 | while (bi.dataLength > 1 && bi.data[bi.dataLength - 1] == 0) 268 | bi.dataLength--; 269 | 270 | return bi; 271 | } 272 | 273 | BigInt operator -=(BigInt &bi1, const BigInt &bi2) 274 | { 275 | bi1 = bi1 - bi2; 276 | return bi1; 277 | } 278 | 279 | BigInt operator -(const BigInt& bi1) 280 | { 281 | if (bi1.dataLength == 1 && bi1.data[0] == 0) 282 | { 283 | BigInt result; 284 | return result; 285 | } 286 | 287 | BigInt result(bi1); 288 | 289 | // 1's complement 290 | for (int i = 0; i < maxLength; i++) 291 | { 292 | result.data[i] = (uint) (~(bi1.data[i])); 293 | } 294 | // add one to result of 1's complement 295 | int64 val, carry = 1; 296 | int index = 0; 297 | 298 | while (carry != 0 && index < maxLength) 299 | { 300 | val = (int64) (result.data[index]); 301 | val++; 302 | 303 | result.data[index] = (uint) (val & 0xFFFFFFFF); 304 | carry = val >> 32; 305 | 306 | index++; 307 | } 308 | 309 | result.dataLength = maxLength; 310 | 311 | while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0) 312 | { 313 | result.dataLength--; 314 | } 315 | 316 | return result; 317 | } 318 | 319 | BigInt operator *(BigInt bi1, BigInt bi2) 320 | { 321 | int lastPos = maxLength - 1; 322 | bool bi1Neg = false, bi2Neg = false; 323 | 324 | if ((bi1.data[lastPos] & 0x80000000) != 0) // bi1 negative 325 | { 326 | bi1Neg = true; 327 | bi1 = -bi1; 328 | } 329 | 330 | if ((bi2.data[lastPos] & 0x80000000) != 0) // bi2 negative 331 | { 332 | bi2Neg = true; 333 | bi2 = -bi2; 334 | } 335 | 336 | BigInt result; 337 | 338 | for (int i = 0; i < bi1.dataLength; i++) 339 | { 340 | if (bi1.data[i] == 0) 341 | continue; 342 | 343 | uint64 mcarry = 0; 344 | for (int j = 0, k = i; j < bi2.dataLength; j++, k++) 345 | { 346 | uint64 val = ((uint64) bi1.data[i] * (uint64) bi2.data[j]) + (uint64) result.data[k] + mcarry; 347 | 348 | result.data[k] = (uint) (val & 0xFFFFFFFF); 349 | mcarry = (val >> 32); 350 | } 351 | 352 | if (mcarry != 0) 353 | { 354 | result.data[i + bi2.dataLength] = (uint) mcarry; 355 | } 356 | } 357 | 358 | result.dataLength = bi1.dataLength + bi2.dataLength; 359 | if (result.dataLength > maxLength) 360 | result.dataLength = maxLength; 361 | 362 | while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0) 363 | result.dataLength--; 364 | 365 | // overflow check (result is -ve) 366 | if ((result.data[lastPos] & 0x80000000) != 0) 367 | { 368 | if (bi1Neg != bi2Neg && result.data[lastPos] == 0x80000000) // different sign 369 | { 370 | // handle the special case where multiplication produces 371 | // a max negative number in 2's complement. 372 | 373 | if (result.dataLength == 1) 374 | return result; 375 | else 376 | { 377 | bool isMaxNeg = true; 378 | for (int i = 0; i < result.dataLength - 1 && isMaxNeg; i++) 379 | { 380 | if (result.data[i] != 0) 381 | isMaxNeg = false; 382 | } 383 | 384 | if (isMaxNeg) 385 | return result; 386 | } 387 | } else { 388 | //Multiplication overflow 389 | } 390 | 391 | } 392 | 393 | // if input has different signs, then result is -ve 394 | if (bi1Neg != bi2Neg) 395 | return -result; 396 | 397 | return result; 398 | } 399 | 400 | BigInt operator <<(const BigInt &bi1, int offset) 401 | { 402 | BigInt result = BigInt(bi1); 403 | 404 | if (offset == 0) 405 | { 406 | return result; 407 | } 408 | 409 | result.dataLength = BigInt::shiftLeft(result.data, result.dataLength, offset); 410 | 411 | return result; 412 | } 413 | 414 | BigInt operator >>(const BigInt &bi1, int shiftVal) 415 | { 416 | BigInt result(bi1); 417 | 418 | if (shiftVal == 0) 419 | { 420 | return result; 421 | } 422 | 423 | result.dataLength = BigInt::shiftRight(result.data, result.dataLength, shiftVal); 424 | 425 | int i = 0; 426 | if ((bi1.data[maxLength - 1] & 0x80000000) != 0) // negative 427 | { 428 | for (i = maxLength - 1; i >= result.dataLength; i--) 429 | result.data[i] = 0xFFFFFFFF; 430 | 431 | uint mask = 0x80000000; 432 | for (i = 0; i < 32; i++) 433 | { 434 | if ((result.data[result.dataLength - 1] & mask) != 0) 435 | break; 436 | 437 | result.data[result.dataLength - 1] |= mask; 438 | mask >>= 1; 439 | } 440 | result.dataLength = maxLength; 441 | } 442 | 443 | return result; 444 | } 445 | 446 | int BigInt::shiftLeft(uint buffer[], int bufLen, int shiftVal) 447 | { 448 | int shiftAmount = 32; 449 | 450 | int index = bufLen; 451 | 452 | while (index > 1 && buffer[index - 1] == 0) 453 | { 454 | index--; 455 | } 456 | 457 | for (int count = shiftVal; count > 0;) 458 | { 459 | if (count < shiftAmount) 460 | { 461 | shiftAmount = count; 462 | } 463 | 464 | uint64 carry = 0; 465 | for (int i = 0; i < index; i++) 466 | { 467 | uint64 val = ((uint64) buffer[i]) << shiftAmount; 468 | val |= carry; 469 | 470 | buffer[i] = (uint) (val & 0xFFFFFFFF); 471 | carry = val >> 32; 472 | } 473 | 474 | if (carry != 0) 475 | { 476 | if (index + 1 <= bufLen) 477 | { 478 | buffer[index] = (uint) carry; 479 | index++; 480 | } 481 | } 482 | count -= shiftAmount; 483 | } 484 | 485 | return index; 486 | } 487 | 488 | int BigInt::shiftRight(uint buffer[], int bufLen, int shiftVal) 489 | { 490 | int shiftAmount = 32; 491 | int invShift = 0; 492 | 493 | while (bufLen > 1 && buffer[bufLen - 1] == 0) 494 | bufLen--; 495 | 496 | for (int count = shiftVal; count > 0;) 497 | { 498 | if (count < shiftAmount) 499 | { 500 | shiftAmount = count; 501 | invShift = 32 - shiftAmount; 502 | } 503 | 504 | uint64 carry = 0; 505 | for (int i = bufLen - 1; i >= 0; i--) 506 | { 507 | uint64 val = ((uint64) buffer[i]) >> shiftAmount; 508 | val |= carry; 509 | 510 | carry = ((uint64) buffer[i]) << invShift; 511 | buffer[i] = (uint) (val); 512 | } 513 | 514 | count -= shiftAmount; 515 | } 516 | 517 | while (bufLen > 1 && buffer[bufLen - 1] == 0) 518 | bufLen--; 519 | 520 | return bufLen; 521 | } 522 | 523 | BigInt operator ~(const BigInt &bi) 524 | { 525 | BigInt result(bi); 526 | 527 | for (int i = 0; i < maxLength; i++) 528 | { 529 | result.data[i] = (uint) (~(bi.data[i])); 530 | } 531 | 532 | result.dataLength = maxLength; 533 | 534 | while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0) 535 | { 536 | result.dataLength--; 537 | } 538 | 539 | return result; 540 | } 541 | 542 | bool operator ==(const BigInt &bi1, const BigInt &bi2) 543 | { 544 | if (bi1.dataLength != bi2.dataLength) 545 | { 546 | return false; 547 | } 548 | 549 | for (int i = 0; i < bi1.dataLength; i++) 550 | { 551 | if (bi1.data[i] != bi2.data[i]) 552 | { 553 | return false; 554 | } 555 | } 556 | 557 | return true; 558 | } 559 | 560 | bool operator !=(const BigInt &bi1, const BigInt &bi2) 561 | { 562 | if (bi1.dataLength != bi2.dataLength) 563 | { 564 | return true; 565 | } 566 | 567 | for (int i = 0; i < bi1.dataLength; i++) 568 | { 569 | if (bi1.data[i] != bi2.data[i]) 570 | { 571 | return true; 572 | } 573 | } 574 | 575 | return false; 576 | } 577 | 578 | bool operator >(const BigInt &bi1, const BigInt &bi2) 579 | { 580 | int pos = maxLength - 1; 581 | 582 | // bi1 is negative, bi2 is positive 583 | if ((bi1.data[pos] & 0x80000000) != 0 && (bi2.data[pos] & 0x80000000) == 0) 584 | return false; 585 | 586 | // bi1 is positive, bi2 is negative 587 | else if ((bi1.data[pos] & 0x80000000) == 0 && (bi2.data[pos] & 0x80000000) != 0) 588 | return true; 589 | 590 | // same sign 591 | int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength; 592 | 593 | for (pos = len - 1; pos >= 0 && bi1.data[pos] == bi2.data[pos]; pos--); 594 | 595 | return ((pos >= 0) && (bi1.data[pos] > bi2.data[pos])); 596 | } 597 | 598 | bool operator <(const BigInt &bi1, const BigInt &bi2) 599 | { 600 | int pos = maxLength - 1; 601 | 602 | // bi1 is negative, bi2 is positive 603 | if ((bi1.data[pos] & 0x80000000) != 0 && (bi2.data[pos] & 0x80000000) == 0) 604 | return true; 605 | 606 | // bi1 is positive, bi2 is negative 607 | else if ((bi1.data[pos] & 0x80000000) == 0 && (bi2.data[pos] & 0x80000000) != 0) 608 | return false; 609 | 610 | // same sign 611 | int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength; 612 | 613 | for (pos = len - 1; pos >= 0 && bi1.data[pos] == bi2.data[pos]; pos--); 614 | 615 | return ((pos >= 0) && (bi1.data[pos] < bi2.data[pos])); 616 | } 617 | 618 | bool operator >=(const BigInt &bi1, const BigInt &bi2) 619 | { 620 | return (bi1 == bi2 || bi1 > bi2); 621 | } 622 | 623 | bool operator <=(const BigInt &bi1, const BigInt &bi2) 624 | { 625 | return (bi1 == bi2 || bi1 < bi2); 626 | } 627 | 628 | void BigInt::multiByteDivide(BigInt bi1, BigInt bi2, BigInt &outQuotient, BigInt& outRemainder) 629 | { 630 | int i = 0; 631 | uint result[maxLength]; 632 | 633 | for (i = 0; i < maxLength; i++) 634 | { 635 | result[i] = 0; 636 | } 637 | 638 | int remainderLen = bi1.dataLength + 1; 639 | 640 | uint* remainder = new uint[remainderLen]; 641 | 642 | for (i = 0; i < remainderLen; i++) 643 | { 644 | remainder[i] = 0; 645 | } 646 | 647 | uint mask = 0x80000000; 648 | uint val = bi2.data[bi2.dataLength - 1]; 649 | 650 | int shift = 0, resultPos = 0; 651 | 652 | while (mask != 0 && (val & mask) == 0) 653 | { 654 | shift++; 655 | mask >>= 1; 656 | } 657 | 658 | for (i = 0; i < bi1.dataLength; i++) 659 | { 660 | remainder[i] = bi1.data[i]; 661 | } 662 | 663 | BigInt::shiftLeft(remainder, remainderLen, shift); 664 | 665 | bi2 = bi2 << shift; 666 | 667 | int j = remainderLen - bi2.dataLength; 668 | int pos = remainderLen - 1; 669 | 670 | uint64 firstDivisorByte = bi2.data[bi2.dataLength - 1]; 671 | uint64 secondDivisorByte = bi2.data[bi2.dataLength - 2]; 672 | 673 | int divisorLen = bi2.dataLength + 1; 674 | uint* dividendPart = new uint[divisorLen]; 675 | 676 | for (i = 0; i < divisorLen; i++) 677 | { 678 | dividendPart[i] = 0; 679 | } 680 | 681 | while (j > 0) 682 | { 683 | uint64 dividend = ((uint64) remainder[pos] << 32) + (uint64) remainder[pos - 1]; 684 | 685 | uint64 q_hat = dividend / firstDivisorByte; 686 | uint64 r_hat = dividend % firstDivisorByte; 687 | 688 | bool done = false; 689 | while (!done) 690 | { 691 | done = true; 692 | 693 | if (q_hat == 0x100000000 || (q_hat * secondDivisorByte) > ((r_hat << 32) + remainder[pos - 2])) 694 | { 695 | q_hat--; 696 | r_hat += firstDivisorByte; 697 | 698 | if (r_hat < 0x100000000) 699 | done = false; 700 | } 701 | } 702 | 703 | int h = 0; 704 | for (h = 0; h < divisorLen; h++) 705 | dividendPart[h] = remainder[pos - h]; 706 | 707 | BigInt kk(dividendPart, divisorLen); 708 | BigInt ss = bi2 * (int64) q_hat; 709 | 710 | while (ss > kk) 711 | { 712 | q_hat--; 713 | ss -= bi2; 714 | } 715 | 716 | BigInt yy = kk - ss; 717 | 718 | for (h = 0; h < divisorLen; h++) 719 | remainder[pos - h] = yy.data[bi2.dataLength - h]; 720 | 721 | result[resultPos++] = (uint) q_hat; 722 | 723 | pos--; 724 | j--; 725 | } 726 | 727 | outQuotient.dataLength = resultPos; 728 | int y = 0; 729 | for (int x = outQuotient.dataLength - 1; x >= 0; x--, y++) 730 | outQuotient.data[y] = result[x]; 731 | for (; y < maxLength; y++) 732 | outQuotient.data[y] = 0; 733 | 734 | while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0) 735 | outQuotient.dataLength--; 736 | 737 | if (outQuotient.dataLength == 0) 738 | outQuotient.dataLength = 1; 739 | 740 | outRemainder.dataLength = BigInt::shiftRight(remainder, remainderLen, shift); 741 | 742 | for (y = 0; y < outRemainder.dataLength; y++) 743 | outRemainder.data[y] = remainder[y]; 744 | for (; y < maxLength; y++) 745 | outRemainder.data[y] = 0; 746 | if (remainder != 0) 747 | { 748 | delete[] remainder; 749 | } 750 | if (dividendPart != 0) 751 | { 752 | delete[] dividendPart; 753 | } 754 | } 755 | 756 | void BigInt::singleByteDivide(BigInt bi1, BigInt bi2, BigInt& outQuotient, BigInt& outRemainder) 757 | { 758 | uint result[maxLength]; 759 | int resultPos = 0; 760 | int i = 0; 761 | int j = 0; 762 | 763 | // copy dividend to reminder 764 | for (i = 0; i < maxLength; i++) 765 | outRemainder.data[i] = bi1.data[i]; 766 | outRemainder.dataLength = bi1.dataLength; 767 | 768 | while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0) 769 | outRemainder.dataLength--; 770 | 771 | uint64 divisor = (uint64) bi2.data[0]; 772 | int pos = outRemainder.dataLength - 1; 773 | uint64 dividend = (uint64) outRemainder.data[pos]; 774 | 775 | if (dividend >= divisor) 776 | { 777 | uint64 quotient = dividend / divisor; 778 | result[resultPos++] = (uint) quotient; 779 | 780 | outRemainder.data[pos] = (uint) (dividend % divisor); 781 | } 782 | pos--; 783 | 784 | while (pos >= 0) 785 | { 786 | 787 | dividend = ((uint64) outRemainder.data[pos + 1] << 32) + (uint64) outRemainder.data[pos]; 788 | uint64 quotient = dividend / divisor; 789 | result[resultPos++] = (uint) quotient; 790 | 791 | outRemainder.data[pos + 1] = 0; 792 | outRemainder.data[pos--] = (uint) (dividend % divisor); 793 | } 794 | 795 | outQuotient.dataLength = resultPos; 796 | 797 | for (i = outQuotient.dataLength - 1; i >= 0; i--, j++) 798 | outQuotient.data[j] = result[i]; 799 | for (; j < maxLength; j++) 800 | outQuotient.data[j] = 0; 801 | 802 | while (outQuotient.dataLength > 1 && outQuotient.data[outQuotient.dataLength - 1] == 0) 803 | outQuotient.dataLength--; 804 | 805 | if (outQuotient.dataLength == 0) 806 | outQuotient.dataLength = 1; 807 | 808 | while (outRemainder.dataLength > 1 && outRemainder.data[outRemainder.dataLength - 1] == 0) 809 | outRemainder.dataLength--; 810 | } 811 | 812 | BigInt operator /(BigInt bi1, BigInt bi2) 813 | { 814 | BigInt quotient; 815 | BigInt remainder; 816 | 817 | int lastPos = maxLength - 1; 818 | bool divisorNeg = false, dividendNeg = false; 819 | 820 | if ((bi1.data[lastPos] & 0x80000000) != 0) // bi1 negative 821 | { 822 | bi1 = -bi1; 823 | dividendNeg = true; 824 | } 825 | 826 | if ((bi2.data[lastPos] & 0x80000000) != 0) // bi2 negative 827 | { 828 | bi2 = -bi2; 829 | divisorNeg = true; 830 | } 831 | 832 | if (bi1 < bi2) 833 | { 834 | return quotient; 835 | } 836 | else 837 | { 838 | if (bi2.dataLength == 1) 839 | BigInt::singleByteDivide(bi1, bi2, quotient, remainder); 840 | else 841 | BigInt::multiByteDivide(bi1, bi2, quotient, remainder); 842 | 843 | if (dividendNeg != divisorNeg) 844 | return -quotient; 845 | 846 | return quotient; 847 | } 848 | } 849 | 850 | BigInt operator %(BigInt bi1, BigInt bi2) 851 | { 852 | BigInt quotient; 853 | BigInt remainder(bi1); 854 | 855 | int lastPos = maxLength - 1; 856 | bool dividendNeg = false; 857 | 858 | if ((bi1.data[lastPos] & 0x80000000) != 0) // bi1 negative 859 | { 860 | bi1 = -bi1; 861 | dividendNeg = true; 862 | } 863 | 864 | if ((bi2.data[lastPos] & 0x80000000) != 0) // bi2 negative 865 | bi2 = -bi2; 866 | 867 | if (bi1 < bi2) 868 | { 869 | return remainder; 870 | } 871 | else 872 | { 873 | if (bi2.dataLength == 1) 874 | BigInt::singleByteDivide(bi1, bi2, quotient, remainder); 875 | else 876 | BigInt::multiByteDivide(bi1, bi2, quotient, remainder); 877 | 878 | if (dividendNeg) 879 | return -remainder; 880 | 881 | return remainder; 882 | } 883 | } 884 | 885 | BigInt operator &(const BigInt &bi1, const BigInt &bi2) 886 | { 887 | BigInt result; 888 | 889 | int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength; 890 | 891 | for (int i = 0; i < len; i++) 892 | { 893 | uint sum = (uint) (bi1.data[i] & bi2.data[i]); 894 | result.data[i] = sum; 895 | } 896 | 897 | result.dataLength = maxLength; 898 | 899 | while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0) 900 | result.dataLength--; 901 | 902 | return result; 903 | } 904 | 905 | BigInt operator |(const BigInt& bi1, const BigInt& bi2) 906 | { 907 | BigInt result; 908 | 909 | int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength; 910 | 911 | for (int i = 0; i < len; i++) 912 | { 913 | uint sum = (uint) (bi1.data[i] | bi2.data[i]); 914 | result.data[i] = sum; 915 | } 916 | 917 | result.dataLength = maxLength; 918 | 919 | while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0) 920 | result.dataLength--; 921 | 922 | return result; 923 | } 924 | 925 | BigInt operator ^(const BigInt& bi1, const BigInt& bi2) 926 | { 927 | BigInt result; 928 | 929 | int len = (bi1.dataLength > bi2.dataLength) ? bi1.dataLength : bi2.dataLength; 930 | 931 | for (int i = 0; i < len; i++) 932 | { 933 | uint sum = (uint) (bi1.data[i] ^ bi2.data[i]); 934 | result.data[i] = sum; 935 | } 936 | 937 | result.dataLength = maxLength; 938 | 939 | while (result.dataLength > 1 && result.data[result.dataLength - 1] == 0) 940 | result.dataLength--; 941 | 942 | return result; 943 | } 944 | 945 | int BigInt::jacobi(BigInt a, BigInt b) 946 | { 947 | if ((b.data[0] & 0x1) == 0) 948 | { 949 | //Exception::Jacobi defined only for odd integers 950 | } 951 | 952 | if (a >= b) 953 | a = a % b; 954 | if (a.dataLength == 1 && a.data[0] == 0) 955 | return 0; // a == 0 956 | if (a.dataLength == 1 && a.data[0] == 1) 957 | return 1; // a == 1 958 | 959 | if (a < BigInt()) 960 | { 961 | if ((((b - 1).data[0]) & 0x2) == 0) //if( (((b-1) >> 1).data[0] & 0x1) == 0) 962 | return jacobi(-a, b); 963 | else 964 | return -jacobi(-a, b); 965 | } 966 | 967 | int e = 0; 968 | for (int index = 0; index < a.dataLength; index++) 969 | { 970 | uint mask = 0x01; 971 | 972 | for (int i = 0; i < 32; i++) 973 | { 974 | if ((a.data[index] & mask) != 0) 975 | { 976 | index = a.dataLength; // to break the outer loop 977 | break; 978 | } 979 | mask <<= 1; 980 | e++; 981 | } 982 | } 983 | 984 | BigInt a1 = a >> e; 985 | 986 | int s = 1; 987 | if ((e & 0x1) != 0 && ((b.data[0] & 0x7) == 3 || (b.data[0] & 0x7) == 5)) 988 | s = -1; 989 | 990 | if ((b.data[0] & 0x3) == 3 && (a1.data[0] & 0x3) == 3) 991 | s = -s; 992 | 993 | if (a1.dataLength == 1 && a1.data[0] == 1) 994 | return s; 995 | else 996 | return (s * jacobi(b % a1, a1)); 997 | } 998 | 999 | BigInt BigInt::genPseudoPrime(int bits, int confidence, Random &rnd) 1000 | { 1001 | BigInt result; 1002 | bool done = false; 1003 | 1004 | while (!done) 1005 | { 1006 | result.genRandomBits(bits, rnd); 1007 | 1008 | result.data[0] |= 0x01; // make it odd 1009 | 1010 | // prime test 1011 | done = result.isProbablePrime(confidence, rnd); 1012 | } 1013 | 1014 | return result; 1015 | } 1016 | 1017 | BigInt* BigInt::lucasSequence(BigInt P, BigInt Q, BigInt k, BigInt n) 1018 | { 1019 | if (k.dataLength == 1 && k.data[0] == 0) 1020 | { 1021 | BigInt* result = new BigInt[3]; 1022 | 1023 | result[0] = BigInt(); 1024 | result[1] = BigInt(2) % n; 1025 | result[2] = BigInt(1) % n; 1026 | return result; 1027 | } 1028 | 1029 | // calculate constant = b^(2k) / m 1030 | // for Barrett Reduction 1031 | BigInt constant; 1032 | 1033 | int nLen = n.dataLength << 1; 1034 | constant.data[nLen] = 0x00000001; 1035 | constant.dataLength = nLen + 1; 1036 | 1037 | constant = constant / n; 1038 | 1039 | // calculate values of s and t 1040 | int s = 0; 1041 | 1042 | for (int index = 0; index < k.dataLength; index++) 1043 | { 1044 | uint mask = 0x01; 1045 | 1046 | for (int i = 0; i < 32; i++) 1047 | { 1048 | if ((k.data[index] & mask) != 0) 1049 | { 1050 | index = k.dataLength; // to break the outer loop 1051 | break; 1052 | } 1053 | mask <<= 1; 1054 | s++; 1055 | } 1056 | } 1057 | 1058 | BigInt t = k >> s; 1059 | 1060 | return lucasSequenceHelper(P, Q, t, n, constant, s); 1061 | } 1062 | 1063 | BigInt* BigInt::lucasSequenceHelper(BigInt P, BigInt Q, BigInt k, BigInt n, BigInt constant, int s) 1064 | { 1065 | int i = 0; 1066 | 1067 | BigInt* result = new BigInt[3]; 1068 | 1069 | for (i = 0; i < 3; i++) 1070 | { 1071 | result[i] = 0; 1072 | } 1073 | 1074 | if ((k.data[0] & 0x00000001) == 0) 1075 | { 1076 | //Exception::"Argument k must be odd." 1077 | } 1078 | int numbits = k.bitCount(); 1079 | 1080 | uint mask = (uint) 0x1 << ((numbits & 0x1F) - 1); 1081 | 1082 | // v = v0, v1 = v1, u1 = u1, Q_k = Q^0 1083 | 1084 | BigInt v = 2 % n, Q_k = 1 % n, v1 = P % n, u1 = Q_k; 1085 | bool flag = true; 1086 | 1087 | for (i = k.dataLength - 1; i >= 0; i--) // iterate on the binary expansion of k 1088 | { 1089 | while (mask != 0) 1090 | { 1091 | if (i == 0 && mask == 0x00000001) // last bit 1092 | break; 1093 | 1094 | if ((k.data[i] & mask) != 0) // bit is set 1095 | { 1096 | // index doubling with addition 1097 | u1 = (u1 * v1) % n; 1098 | 1099 | v = ((v * v1) - (P * Q_k)) % n; 1100 | v1 = n.barrettReduction(v1 * v1, n, constant); 1101 | v1 = (v1 - ((Q_k * Q) << 1)) % n; 1102 | 1103 | if (flag) 1104 | flag = false; 1105 | else 1106 | Q_k = n.barrettReduction(Q_k * Q_k, n, constant); 1107 | 1108 | Q_k = (Q_k * Q) % n; 1109 | } 1110 | else 1111 | { 1112 | // index doubling 1113 | u1 = ((u1 * v) - Q_k) % n; 1114 | 1115 | v1 = ((v * v1) - (P * Q_k)) % n; 1116 | v = n.barrettReduction(v * v, n, constant); 1117 | v = (v - (Q_k << 1)) % n; 1118 | 1119 | if (flag) 1120 | { 1121 | Q_k = Q % n; 1122 | flag = false; 1123 | } 1124 | else 1125 | { 1126 | Q_k = n.barrettReduction(Q_k * Q_k, n, constant); 1127 | } 1128 | } 1129 | 1130 | mask >>= 1; 1131 | } 1132 | mask = 0x80000000; 1133 | } 1134 | 1135 | // at this point u1 = u(n+1) and v = v(n) 1136 | // since the last bit always 1, we need to transform u1 to u(2n+1) and v to v(2n+1) 1137 | 1138 | u1 = ((u1 * v) - Q_k) % n; 1139 | v = ((v * v1) - (P * Q_k)) % n; 1140 | if (flag) 1141 | flag = false; 1142 | else 1143 | Q_k = n.barrettReduction(Q_k * Q_k, n, constant); 1144 | 1145 | Q_k = (Q_k * Q) % n; 1146 | 1147 | for (i = 0; i < s; i++) 1148 | { 1149 | // index doubling 1150 | u1 = (u1 * v) % n; 1151 | v = ((v * v) - (Q_k << 1)) % n; 1152 | 1153 | if (flag) 1154 | { 1155 | Q_k = Q % n; 1156 | flag = false; 1157 | } 1158 | else 1159 | { 1160 | Q_k = n.barrettReduction(Q_k * Q_k, n, constant); 1161 | } 1162 | } 1163 | 1164 | result[0] = u1; 1165 | result[1] = v; 1166 | result[2] = Q_k; 1167 | 1168 | return result; 1169 | } 1170 | 1171 | bool BigInt::lucasStrongTestHelper(BigInt thisVal) 1172 | { 1173 | int64 D = 5, sign = -1, dCount = 0; 1174 | bool done = false; 1175 | 1176 | while (!done) 1177 | { 1178 | int Jresult = BigInt::jacobi(D, thisVal); 1179 | 1180 | if (Jresult == -1) 1181 | done = true; // J(D, this) = 1 1182 | else 1183 | { 1184 | if ((Jresult == 0) && (BigInt::abs(D) < thisVal)) // divisor found 1185 | return false; 1186 | 1187 | if (dCount == 20) 1188 | { 1189 | // check for square 1190 | BigInt root = thisVal.sqrt(); 1191 | if (root * root == thisVal) 1192 | return false; 1193 | } 1194 | 1195 | D = (BigInt::abs(D) + 2) * sign; 1196 | sign = -sign; 1197 | } 1198 | dCount++; 1199 | } 1200 | 1201 | int64 Q = (1 - D) >> 2; 1202 | 1203 | BigInt p_add1 = thisVal + 1; 1204 | int s = 0; 1205 | 1206 | for (int index = 0; index < p_add1.dataLength; index++) 1207 | { 1208 | uint mask = 0x01; 1209 | 1210 | for (int i = 0; i < 32; i++) 1211 | { 1212 | if ((p_add1.data[index] & mask) != 0) 1213 | { 1214 | index = p_add1.dataLength; // to break the outer loop 1215 | break; 1216 | } 1217 | mask <<= 1; 1218 | s++; 1219 | } 1220 | } 1221 | 1222 | BigInt t = p_add1 >> s; 1223 | 1224 | // calculate constant = b^(2k) / m 1225 | // for Barrett Reduction 1226 | BigInt constant; 1227 | 1228 | int nLen = thisVal.dataLength << 1; 1229 | constant.data[nLen] = 0x00000001; 1230 | constant.dataLength = nLen + 1; 1231 | 1232 | constant = constant / thisVal; 1233 | 1234 | BigInt* lucas = lucasSequenceHelper(1, Q, t, thisVal, constant, 0); 1235 | bool isPrime = false; 1236 | 1237 | if ((lucas[0].dataLength == 1 && lucas[0].data[0] == 0) || (lucas[1].dataLength == 1 && lucas[1].data[0] == 0)) 1238 | { 1239 | // u(t) = 0 or V(t) = 0 1240 | isPrime = true; 1241 | } 1242 | 1243 | for (int i = 1; i < s; i++) 1244 | { 1245 | if (!isPrime) 1246 | { 1247 | // doubling of index 1248 | lucas[1] = thisVal.barrettReduction(lucas[1] * lucas[1], thisVal, constant); 1249 | lucas[1] = (lucas[1] - (lucas[2] << 1)) % thisVal; 1250 | 1251 | if ((lucas[1].dataLength == 1 && lucas[1].data[0] == 0)) 1252 | isPrime = true; 1253 | } 1254 | 1255 | lucas[2] = thisVal.barrettReduction(lucas[2] * lucas[2], thisVal, constant); //Q^k 1256 | } 1257 | 1258 | if (isPrime) // additional checks for composite numbers 1259 | { 1260 | // If n is prime and gcd(n, Q) == 1, then 1261 | // Q^((n+1)/2) = Q * Q^((n-1)/2) is congruent to (Q * J(Q, n)) mod n 1262 | 1263 | BigInt g = thisVal.gcd(Q); 1264 | if (g.dataLength == 1 && g.data[0] == 1) // gcd(this, Q) == 1 1265 | { 1266 | if ((lucas[2].data[maxLength - 1] & 0x80000000) != 0) 1267 | lucas[2] = lucas[2] + thisVal; 1268 | 1269 | BigInt temp = (Q * BigInt::jacobi(Q, thisVal)) % thisVal; 1270 | if ((temp.data[maxLength - 1] & 0x80000000) != 0) 1271 | temp = temp + thisVal; 1272 | 1273 | if (lucas[2] != temp) 1274 | isPrime = false; 1275 | } 1276 | } 1277 | 1278 | if (lucas != 0) 1279 | { 1280 | delete lucas; 1281 | } 1282 | 1283 | return isPrime; 1284 | } 1285 | 1286 | BigInt BigInt::abs() 1287 | { 1288 | if ((this->data[maxLength - 1] & 0x80000000) != 0) 1289 | return -(*this); 1290 | else 1291 | return BigInt(*this); 1292 | } 1293 | 1294 | BigInt BigInt::modPow(BigInt exp, BigInt n) 1295 | { 1296 | if ((exp.data[maxLength - 1] & 0x80000000) != 0) 1297 | { 1298 | //Exception::"Positive exponents only." 1299 | } 1300 | 1301 | BigInt resultNum = 1; 1302 | BigInt tempNum; 1303 | bool thisNegative = false; 1304 | 1305 | if ((this->data[maxLength - 1] & 0x80000000) != 0) // negative this 1306 | { 1307 | tempNum = (-(*this)) % n; 1308 | thisNegative = true; 1309 | } 1310 | else 1311 | tempNum = (*this) % n; // ensures (tempNum * tempNum) < b^(2k) 1312 | 1313 | if ((n.data[maxLength - 1] & 0x80000000) != 0) // negative n 1314 | n = -n; 1315 | 1316 | // calculate constant = b^(2k) / m 1317 | BigInt constant; 1318 | 1319 | int i = n.dataLength << 1; 1320 | constant.data[i] = 0x00000001; 1321 | constant.dataLength = i + 1; 1322 | 1323 | constant = constant / n; 1324 | int totalBits = exp.bitCount(); 1325 | int count = 0; 1326 | 1327 | // perform squaring and multiply exponentiation 1328 | for (int pos = 0; pos < exp.dataLength; pos++) 1329 | { 1330 | uint mask = 0x01; 1331 | 1332 | for (int index = 0; index < 32; index++) 1333 | { 1334 | if ((exp.data[pos] & mask) != 0) 1335 | resultNum = barrettReduction(resultNum * tempNum, n, constant); 1336 | 1337 | mask <<= 1; 1338 | 1339 | tempNum = barrettReduction(tempNum * tempNum, n, constant); 1340 | 1341 | if (tempNum.dataLength == 1 && tempNum.data[0] == 1) 1342 | { 1343 | if (thisNegative && (exp.data[0] & 0x1) != 0) //odd exp 1344 | return -resultNum; 1345 | return resultNum; 1346 | } 1347 | 1348 | count++; 1349 | if (count == totalBits) 1350 | break; 1351 | } 1352 | } 1353 | 1354 | if (thisNegative && (exp.data[0] & 0x1) != 0) //odd exp 1355 | return -resultNum; 1356 | 1357 | return resultNum; 1358 | } 1359 | 1360 | BigInt BigInt::barrettReduction(BigInt x, BigInt n, BigInt constant) 1361 | { 1362 | int k = n.dataLength, kPlusOne = k + 1, kMinusOne = k - 1; 1363 | int i = 0, j = 0; 1364 | BigInt q1; 1365 | 1366 | // q1 = x / b^(k-1) 1367 | for (i = kMinusOne, j = 0; i < x.dataLength; i++, j++) 1368 | q1.data[j] = x.data[i]; 1369 | 1370 | q1.dataLength = x.dataLength - kMinusOne; 1371 | if (q1.dataLength <= 0) 1372 | q1.dataLength = 1; 1373 | 1374 | BigInt q2 = q1 * constant; 1375 | BigInt q3; 1376 | 1377 | // q3 = q2 / b^(k+1) 1378 | for (i = kPlusOne, j = 0; i < q2.dataLength; i++, j++) 1379 | q3.data[j] = q2.data[i]; 1380 | q3.dataLength = q2.dataLength - kPlusOne; 1381 | if (q3.dataLength <= 0) 1382 | q3.dataLength = 1; 1383 | 1384 | BigInt r1; 1385 | int lengthToCopy = (x.dataLength > kPlusOne) ? kPlusOne : x.dataLength; 1386 | for (i = 0; i < lengthToCopy; i++) 1387 | r1.data[i] = x.data[i]; 1388 | r1.dataLength = lengthToCopy; 1389 | 1390 | BigInt r2; 1391 | for (i = 0; i < q3.dataLength; i++) 1392 | { 1393 | if (q3.data[i] == 0) 1394 | continue; 1395 | 1396 | uint64 mcarry = 0; 1397 | int t = i; 1398 | for (int j = 0; j < n.dataLength && t < kPlusOne; j++, t++) 1399 | { 1400 | // t = i + j 1401 | uint64 val = ((uint64) q3.data[i] * (uint64) n.data[j]) + (uint64) r2.data[t] + mcarry; 1402 | 1403 | r2.data[t] = (uint) (val & 0xFFFFFFFF); 1404 | mcarry = (val >> 32); 1405 | } 1406 | 1407 | if (t < kPlusOne) 1408 | r2.data[t] = (uint) mcarry; 1409 | } 1410 | 1411 | r2.dataLength = kPlusOne; 1412 | while (r2.dataLength > 1 && r2.data[r2.dataLength - 1] == 0) 1413 | r2.dataLength--; 1414 | 1415 | r1 -= r2; 1416 | if ((r1.data[maxLength - 1] & 0x80000000) != 0) // negative 1417 | { 1418 | BigInt val; 1419 | val.data[kPlusOne] = 0x00000001; 1420 | val.dataLength = kPlusOne + 1; 1421 | r1 = r1 + val; 1422 | } 1423 | 1424 | while (r1 >= n) 1425 | r1 -= n; 1426 | 1427 | return r1; 1428 | } 1429 | 1430 | BigInt BigInt::gcd(const BigInt &bi) 1431 | { 1432 | BigInt x; 1433 | BigInt y; 1434 | 1435 | if ((data[maxLength - 1] & 0x80000000) != 0) // negative 1436 | x = -(*this); 1437 | else 1438 | x = *this; 1439 | 1440 | if ((bi.data[maxLength - 1] & 0x80000000) != 0) // negative 1441 | y = -bi; 1442 | else 1443 | y = bi; 1444 | 1445 | BigInt g = y; 1446 | 1447 | while (x.dataLength > 1 || (x.dataLength == 1 && x.data[0] != 0)) 1448 | { 1449 | g = x; 1450 | x = y % x; 1451 | y = g; 1452 | } 1453 | 1454 | return g; 1455 | } 1456 | 1457 | void BigInt::genRandomBits(int bits, Random &rnd) 1458 | { 1459 | int dwords = bits >> 5; 1460 | int remBits = bits & 0x1F; 1461 | int i = 0; 1462 | 1463 | if (remBits != 0) 1464 | dwords++; 1465 | 1466 | if (dwords > maxLength) 1467 | { 1468 | //Exception::"Number of required bits > maxLength." 1469 | } 1470 | 1471 | for (i = 0; i < dwords; i++) 1472 | { 1473 | data[i] = rnd.next(); 1474 | } 1475 | 1476 | for (i = dwords; i < maxLength; i++) 1477 | data[i] = 0; 1478 | 1479 | if (remBits != 0) { 1480 | uint mask = (uint) (0x01 << (remBits - 1)); 1481 | data[dwords - 1] |= mask; 1482 | 1483 | mask = (uint) (0xFFFFFFFF >> (32 - remBits)); 1484 | data[dwords - 1] &= mask; 1485 | } else 1486 | data[dwords - 1] |= 0x80000000; 1487 | 1488 | dataLength = dwords; 1489 | 1490 | if (dataLength == 0) 1491 | dataLength = 1; 1492 | } 1493 | 1494 | int BigInt::bitCount() 1495 | { 1496 | while (dataLength > 1 && data[dataLength - 1] == 0) 1497 | { 1498 | dataLength--; 1499 | } 1500 | 1501 | uint value = data[dataLength - 1]; 1502 | 1503 | uint mask = 0x80000000; 1504 | 1505 | int bits = 32; 1506 | 1507 | while (bits > 0 && (value & mask) == 0) 1508 | { 1509 | bits--; 1510 | mask >>= 1; 1511 | } 1512 | 1513 | bits += ((dataLength - 1) << 5); 1514 | 1515 | return bits; 1516 | } 1517 | 1518 | bool BigInt::fermatLittleTest(int confidence, Random &rnd) 1519 | { 1520 | BigInt thisVal; 1521 | 1522 | if ((this->data[maxLength - 1] & 0x80000000) != 0) // negative 1523 | thisVal = -(*this); 1524 | else 1525 | thisVal = *this; 1526 | 1527 | if (thisVal.dataLength == 1) 1528 | { 1529 | // test small numbers 1530 | if (thisVal.data[0] == 0 || thisVal.data[0] == 1) 1531 | return false; 1532 | else if (thisVal.data[0] == 2 || thisVal.data[0] == 3) 1533 | return true; 1534 | } 1535 | 1536 | if ((thisVal.data[0] & 0x1) == 0) // even numbers 1537 | return false; 1538 | 1539 | int bits = thisVal.bitCount(); 1540 | BigInt a; 1541 | BigInt p_sub1 = thisVal - BigInt(1); 1542 | 1543 | for (int round = 0; round < confidence; round++) 1544 | { 1545 | bool done = false; 1546 | 1547 | while (!done) // generate a < n 1548 | { 1549 | int testBits = 0; 1550 | 1551 | // make sure "a" has at least 2 bits 1552 | testBits = rnd.next(2, bits - 1); 1553 | 1554 | a.genRandomBits(testBits, rnd); 1555 | 1556 | int byteLen = a.dataLength; 1557 | 1558 | // make sure "a" is not 0 1559 | if (byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) 1560 | done = true; 1561 | } 1562 | 1563 | // check whether a factor exists (fix for version 1.03) 1564 | BigInt gcdTest = a.gcd(thisVal); 1565 | if (gcdTest.dataLength == 1 && gcdTest.data[0] != 1) 1566 | return false; 1567 | 1568 | // calculate a^(p-1) mod p 1569 | BigInt expResult = a.modPow(p_sub1, thisVal); 1570 | 1571 | int resultLen = expResult.dataLength; 1572 | 1573 | // is NOT prime is a^(p-1) mod p != 1 1574 | 1575 | if (resultLen > 1 || (resultLen == 1 && expResult.data[0] != 1)) 1576 | { 1577 | return false; 1578 | } 1579 | } 1580 | 1581 | return true; 1582 | } 1583 | 1584 | bool BigInt::rabinMillerTest(int confidence, Random &rnd) 1585 | { 1586 | BigInt thisVal; 1587 | 1588 | if ((this->data[maxLength - 1] & 0x80000000) != 0) // negative 1589 | thisVal = -(*this); 1590 | else 1591 | thisVal = *this; 1592 | 1593 | if (thisVal.dataLength == 1) 1594 | { 1595 | // test small numbers 1596 | if (thisVal.data[0] == 0 || thisVal.data[0] == 1) 1597 | return false; 1598 | else if (thisVal.data[0] == 2 || thisVal.data[0] == 3) 1599 | return true; 1600 | } 1601 | 1602 | if ((thisVal.data[0] & 0x1) == 0) // even numbers 1603 | return false; 1604 | 1605 | // calculate values of s and t 1606 | BigInt p_sub1 = thisVal - BigInt(1); 1607 | int s = 0; 1608 | 1609 | for (int index = 0; index < p_sub1.dataLength; index++) 1610 | { 1611 | uint mask = 0x01; 1612 | 1613 | for (int i = 0; i < 32; i++) 1614 | { 1615 | if ((p_sub1.data[index] & mask) != 0) 1616 | { 1617 | index = p_sub1.dataLength; // to break the outer loop 1618 | break; 1619 | } 1620 | mask <<= 1; 1621 | s++; 1622 | } 1623 | } 1624 | 1625 | BigInt t = p_sub1 >> s; 1626 | 1627 | int bits = thisVal.bitCount(); 1628 | BigInt a; 1629 | 1630 | for (int round = 0; round < confidence; round++) 1631 | { 1632 | bool done = false; 1633 | 1634 | while (!done) // generate a < n 1635 | { 1636 | int testBits = 0; 1637 | 1638 | //make sure "a" has at least 2 bits 1639 | testBits = rnd.next(2, bits - 1); 1640 | a.genRandomBits(testBits, rnd); 1641 | int byteLen = a.dataLength; 1642 | 1643 | // make sure "a" is not 0 1644 | if (byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) 1645 | done = true; 1646 | } 1647 | 1648 | // check whether a factor exists (fix for version 1.03) 1649 | BigInt gcdTest = a.gcd(thisVal); 1650 | if (gcdTest.dataLength == 1 && gcdTest.data[0] != 1) 1651 | return false; 1652 | 1653 | BigInt b = a.modPow(t, thisVal); 1654 | 1655 | bool result = false; 1656 | 1657 | if (b.dataLength == 1 && b.data[0] == 1) // a^t mod p = 1 1658 | result = true; 1659 | 1660 | for (int j = 0; result == false && j < s; j++) 1661 | { 1662 | if (b == p_sub1) // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 1663 | { 1664 | result = true; 1665 | break; 1666 | } 1667 | 1668 | b = (b * b) % thisVal; 1669 | } 1670 | 1671 | if (result == false) 1672 | return false; 1673 | } 1674 | 1675 | return true; 1676 | } 1677 | 1678 | bool BigInt::solovayStrassenTest(int confidence, Random &rnd) 1679 | { 1680 | BigInt thisVal; 1681 | 1682 | if ((this->data[maxLength - 1] & 0x80000000) != 0) // negative 1683 | thisVal = -(*this); 1684 | else 1685 | thisVal = (*this); 1686 | 1687 | if (thisVal.dataLength == 1) 1688 | { 1689 | // test small numbers 1690 | if (thisVal.data[0] == 0 || thisVal.data[0] == 1) 1691 | return false; 1692 | else if (thisVal.data[0] == 2 || thisVal.data[0] == 3) 1693 | return true; 1694 | } 1695 | 1696 | if ((thisVal.data[0] & 0x1) == 0) // even numbers 1697 | return false; 1698 | 1699 | int bits = thisVal.bitCount(); 1700 | BigInt a; 1701 | BigInt p_sub1 = thisVal - 1; 1702 | BigInt p_sub1_shift = p_sub1 >> 1; 1703 | 1704 | //Random rand; 1705 | 1706 | for (int round = 0; round < confidence; round++) 1707 | { 1708 | bool done = false; 1709 | 1710 | while (!done) // generate a < n 1711 | { 1712 | int testBits = 0; 1713 | 1714 | // make sure "a" has at least 2 bits 1715 | 1716 | testBits = rnd.next(2, bits - 1); 1717 | 1718 | a.genRandomBits(testBits, rnd); 1719 | 1720 | int byteLen = a.dataLength; 1721 | 1722 | // make sure "a" is not 0 1723 | if (byteLen > 1 || (byteLen == 1 && a.data[0] != 1)) 1724 | done = true; 1725 | } 1726 | 1727 | // check whether a factor exists (fix for version 1.03) 1728 | BigInt gcdTest = a.gcd(thisVal); 1729 | if (gcdTest.dataLength == 1 && gcdTest.data[0] != 1) 1730 | return false; 1731 | 1732 | // calculate a^((p-1)/2) mod p 1733 | 1734 | BigInt expResult = a.modPow(p_sub1_shift, thisVal); 1735 | if (expResult == p_sub1) 1736 | expResult = -1; 1737 | 1738 | // calculate Jacobi symbol 1739 | BigInt jacob = jacobi(a, thisVal); 1740 | 1741 | // if they are different then it is not prime 1742 | if (expResult != jacob) 1743 | return false; 1744 | } 1745 | 1746 | return true; 1747 | } 1748 | 1749 | bool BigInt::lucasStrongTest() 1750 | { 1751 | BigInt thisVal; 1752 | 1753 | if ((this->data[maxLength - 1] & 0x80000000) != 0) // negative 1754 | thisVal = -(*this); 1755 | else 1756 | thisVal = *this; 1757 | 1758 | if (thisVal.dataLength == 1) 1759 | { 1760 | // test small numbers 1761 | if (thisVal.data[0] == 0 || thisVal.data[0] == 1) 1762 | return false; 1763 | else if (thisVal.data[0] == 2 || thisVal.data[0] == 3) 1764 | return true; 1765 | } 1766 | 1767 | if ((thisVal.data[0] & 0x1) == 0) // even numbers 1768 | return false; 1769 | 1770 | return lucasStrongTestHelper(thisVal); 1771 | } 1772 | 1773 | bool BigInt::isProbablePrime(int confidence, Random &rnd) 1774 | { 1775 | BigInt thisVal; 1776 | 1777 | if ((this->data[maxLength - 1] & 0x80000000) != 0) // negative 1778 | thisVal = -(*this); 1779 | else 1780 | thisVal = *this; 1781 | 1782 | // test for divisibility by primes 1783 | for (int p = 0; p < NumberPrimes; p++) 1784 | { 1785 | BigInt divisor = Primes[p]; 1786 | 1787 | if (divisor >= thisVal) 1788 | break; 1789 | 1790 | BigInt resultNum = thisVal % divisor; 1791 | if (resultNum.intValue() == 0) 1792 | { 1793 | return false; 1794 | } 1795 | } 1796 | 1797 | return (thisVal.rabinMillerTest(confidence, rnd)); 1798 | } 1799 | 1800 | bool BigInt::isProbablePrime() 1801 | { 1802 | BigInt thisVal; 1803 | 1804 | if ((this->data[maxLength - 1] & 0x80000000) != 0) // negative 1805 | thisVal = -(*this); 1806 | else 1807 | thisVal = (*this); 1808 | 1809 | if (thisVal.dataLength == 1) 1810 | { 1811 | // test small numbers 1812 | if (thisVal.data[0] == 0 || thisVal.data[0] == 1) 1813 | return false; 1814 | else if (thisVal.data[0] == 2 || thisVal.data[0] == 3) 1815 | return true; 1816 | } 1817 | 1818 | if ((thisVal.data[0] & 0x1) == 0) // even numbers 1819 | return false; 1820 | 1821 | // test for divisibility by primes < 2000 1822 | for (int p = 0; p < NumberPrimes; p++) 1823 | { 1824 | BigInt divisor = Primes[p]; 1825 | 1826 | if (divisor >= thisVal) 1827 | break; 1828 | 1829 | BigInt resultNum = thisVal % divisor; 1830 | if (resultNum.intValue() == 0) 1831 | { 1832 | return false; 1833 | } 1834 | } 1835 | 1836 | // Perform BASE 2 Rabin-Miller Test 1837 | 1838 | // calculate values of s and t 1839 | BigInt p_sub1 = thisVal - BigInt(1); 1840 | int s = 0; 1841 | 1842 | for (int index = 0; index < p_sub1.dataLength; index++) 1843 | { 1844 | uint mask = 0x01; 1845 | 1846 | for (int i = 0; i < 32; i++) 1847 | { 1848 | if ((p_sub1.data[index] & mask) != 0) 1849 | { 1850 | index = p_sub1.dataLength; // to break the outer loop 1851 | break; 1852 | } 1853 | mask <<= 1; 1854 | s++; 1855 | } 1856 | } 1857 | 1858 | BigInt t = p_sub1 >> s; 1859 | 1860 | //int bits = thisVal.bitCount(); 1861 | BigInt a = 2; 1862 | 1863 | // b = a^t mod p 1864 | BigInt b = a.modPow(t, thisVal); 1865 | bool result = false; 1866 | 1867 | if (b.dataLength == 1 && b.data[0] == 1) // a^t mod p = 1 1868 | result = true; 1869 | 1870 | for (int j = 0; result == false && j < s; j++) 1871 | { 1872 | if (b == p_sub1) // a^((2^j)*t) mod p = p-1 for some 0 <= j <= s-1 1873 | { 1874 | result = true; 1875 | break; 1876 | } 1877 | 1878 | b = (b * b) % thisVal; 1879 | } 1880 | 1881 | // if number is strong pseudoprime to base 2, then do a strong lucas test 1882 | if (result) 1883 | result = lucasStrongTestHelper(thisVal); 1884 | 1885 | return result; 1886 | } 1887 | 1888 | int BigInt::intValue() 1889 | { 1890 | return (int) data[0]; 1891 | } 1892 | 1893 | uint64 BigInt::longValue() 1894 | { 1895 | uint64 val = 0; 1896 | val = (uint64) data[0]; 1897 | val |= (uint64) data[1] << 32; 1898 | 1899 | return val; 1900 | } 1901 | 1902 | BigInt BigInt::genCoPrime(int bits, Random &rnd) 1903 | { 1904 | bool done = false; 1905 | BigInt result; 1906 | 1907 | while (!done) 1908 | { 1909 | result.genRandomBits(bits, rnd); 1910 | 1911 | // gcd test 1912 | BigInt g = result.gcd(*this); 1913 | if (g.dataLength == 1 && g.data[0] == 1) 1914 | done = true; 1915 | } 1916 | 1917 | return result; 1918 | } 1919 | 1920 | BigInt BigInt::modInverse(BigInt modulus) 1921 | { 1922 | BigInt p[2] = { BigInt(), BigInt(1) }; 1923 | BigInt q[2] = { 0, 0 }; // quotients 1924 | BigInt r[2] = { BigInt(), BigInt() }; // remainders 1925 | 1926 | int step = 0; 1927 | 1928 | BigInt a = modulus; 1929 | BigInt b = *this; 1930 | 1931 | while (b.dataLength > 1 || (b.dataLength == 1 && b.data[0] != 0)) 1932 | { 1933 | BigInt quotient; 1934 | BigInt remainder; 1935 | 1936 | if (step > 1) 1937 | { 1938 | BigInt pval = (p[0] - (p[1] * q[0])) % modulus; 1939 | p[0] = p[1]; 1940 | p[1] = pval; 1941 | } 1942 | 1943 | if (b.dataLength == 1) 1944 | singleByteDivide(a, b, quotient, remainder); 1945 | else 1946 | multiByteDivide(a, b, quotient, remainder); 1947 | 1948 | q[0] = q[1]; 1949 | r[0] = r[1]; 1950 | q[1] = quotient; 1951 | r[1] = remainder; 1952 | 1953 | a = b; 1954 | b = remainder; 1955 | 1956 | step++; 1957 | } 1958 | 1959 | if (r[0].dataLength > 1 || (r[0].dataLength == 1 && r[0].data[0] != 1)) 1960 | { 1961 | //Exception::"No inverse!" 1962 | } 1963 | 1964 | BigInt result = ((p[0] - (p[1] * q[0])) % modulus); 1965 | 1966 | if ((result.data[maxLength - 1] & 0x80000000) != 0) 1967 | result = result + modulus; // get the least positive modulus 1968 | 1969 | return result; 1970 | } 1971 | 1972 | void BigInt::getBytes(ubyte result[]) 1973 | { 1974 | int i = 0; 1975 | int pos = 0; 1976 | uint val = 0; 1977 | 1978 | for (i = dataLength - 1; i >= 0; i--, pos += 4) 1979 | { 1980 | val = data[i]; 1981 | result[pos + 3] = (ubyte)(val & 0xFF); 1982 | val >>= 8; 1983 | result[pos + 2] = (ubyte)(val & 0xFF); 1984 | val >>= 8; 1985 | result[pos + 1] = (ubyte)(val & 0xFF); 1986 | val >>= 8; 1987 | result[pos] = (ubyte)(val & 0xFF); 1988 | } 1989 | } 1990 | 1991 | int BigInt::getBytesRemovedZero(ubyte result[], int orgLength) 1992 | { 1993 | int numBits = bitCount(); 1994 | int i = 0; 1995 | int numBytes = numBits >> 3; 1996 | 1997 | if ((numBits & 0x7) != 0) 1998 | numBytes++; 1999 | 2000 | for (i = 0; i < orgLength; i++) 2001 | { 2002 | result[i] = 0; 2003 | } 2004 | 2005 | int pos = 0; 2006 | 2007 | uint val = data[dataLength - 1]; 2008 | bool isHaveData = false; 2009 | 2010 | uint tempVal = (val >> 24 & 0xFF); 2011 | if (tempVal != 0) 2012 | { 2013 | result[pos++] = (ubyte) tempVal; 2014 | isHaveData = true; 2015 | } 2016 | 2017 | tempVal = (val >> 16 & 0xFF); 2018 | if (isHaveData || tempVal != 0) 2019 | { 2020 | result[pos++] = (ubyte) tempVal; 2021 | isHaveData = true; 2022 | } 2023 | 2024 | tempVal = (val >> 8 & 0xFF); 2025 | if (isHaveData || tempVal != 0) 2026 | { 2027 | result[pos++] = (ubyte) tempVal; 2028 | isHaveData = true; 2029 | } 2030 | 2031 | tempVal = (val & 0xFF); 2032 | if (isHaveData || tempVal != 0) 2033 | { 2034 | result[pos++] = (ubyte) tempVal; 2035 | } 2036 | 2037 | for (i = dataLength - 2; i >= 0; i--, pos += 4) 2038 | { 2039 | val = data[i]; 2040 | result[pos + 3] = (ubyte)(val & 0xFF); 2041 | val >>= 8; 2042 | result[pos + 2] = (ubyte)(val & 0xFF); 2043 | val >>= 8; 2044 | result[pos + 1] = (ubyte)(val & 0xFF); 2045 | val >>= 8; 2046 | result[pos] = (ubyte)(val & 0xFF); 2047 | } 2048 | 2049 | return numBytes; 2050 | } 2051 | 2052 | void BigInt::setBit(uint bitNum) 2053 | { 2054 | uint bytePos = bitNum >> 5; // divide by 32 2055 | char bitPos = (char) (bitNum & 0x1F); // get the lowest 5 bits 2056 | 2057 | uint mask = (uint) 1 << bitPos; 2058 | this->data[bytePos] |= mask; 2059 | 2060 | if (bytePos >= (uint) this->dataLength) 2061 | { 2062 | this->dataLength = (int) bytePos + 1; 2063 | } 2064 | } 2065 | 2066 | void BigInt::unsetBit(uint bitNum) 2067 | { 2068 | uint bytePos = bitNum >> 5; 2069 | 2070 | if (bytePos < (uint) this->dataLength) 2071 | { 2072 | char bitPos = (char) (bitNum & 0x1F); 2073 | 2074 | uint mask = (uint) 1 << bitPos; 2075 | uint mask2 = 0xFFFFFFFF ^ mask; 2076 | 2077 | this->data[bytePos] &= mask2; 2078 | 2079 | if (this->dataLength > 1 && this->data[this->dataLength - 1] == 0) 2080 | this->dataLength--; 2081 | } 2082 | } 2083 | 2084 | BigInt BigInt::sqrt() 2085 | { 2086 | uint numBits = (uint) bitCount(); 2087 | 2088 | if ((numBits & 0x1) != 0) // odd number of bits 2089 | numBits = (numBits >> 1) + 1; 2090 | else 2091 | numBits = (numBits >> 1); 2092 | 2093 | uint bytePos = numBits >> 5; 2094 | char bitPos = (char) (numBits & 0x1F); 2095 | 2096 | uint mask; 2097 | 2098 | BigInt result; 2099 | if (bitPos == 0) 2100 | mask = 0x80000000; 2101 | else 2102 | { 2103 | mask = (uint) 1 << bitPos; 2104 | bytePos++; 2105 | } 2106 | result.dataLength = (int) bytePos; 2107 | 2108 | for (int i = (int) bytePos - 1; i >= 0; i--) 2109 | { 2110 | while (mask != 0) 2111 | { 2112 | // guess 2113 | result.data[i] ^= mask; 2114 | 2115 | // undo the guess if its square is larger than this 2116 | if ((result * result) > *this) 2117 | result.data[i] ^= mask; 2118 | 2119 | mask >>= 1; 2120 | } 2121 | mask = 0x80000000; 2122 | } 2123 | 2124 | return result; 2125 | } 2126 | 2127 | int64 BigInt::abs(int64 value) 2128 | { 2129 | return (value < 0) ? -value : value; 2130 | } 2131 | 2132 | } 2133 | } 2134 | -------------------------------------------------------------------------------- /src/utils/bigint.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | #include "random.h" 5 | 6 | namespace crypto 7 | { 8 | namespace utils 9 | { 10 | 11 | const int maxLength = 200; // 200*32 = 6400 bits 12 | 13 | //已知素数长度 14 | const int NumberPrimes = 2048; 15 | 16 | //素数数组 17 | const int Primes[] = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 18 | 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 19 | 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 20 | 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 21 | 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 22 | 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 23 | 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 24 | 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 25 | 641, 643, 647, 653, 659, 661, 673, 677, 683, 691, 701, 709, 719, 727, 26 | 733, 739, 743, 751, 757, 761, 769, 773, 787, 797, 809, 811, 821, 823, 27 | 827, 829, 839, 853, 857, 859, 863, 877, 881, 883, 887, 907, 911, 919, 28 | 929, 937, 941, 947, 953, 967, 971, 977, 983, 991, 997, 1009, 1013, 1019, 29 | 1021, 1031, 1033, 1039, 1049, 1051, 1061, 1063, 1069, 1087, 1091, 1093, 30 | 1097, 1103, 1109, 1117, 1123, 1129, 1151, 1153, 1163, 1171, 1181, 1187, 31 | 1193, 1201, 1213, 1217, 1223, 1229, 1231, 1237, 1249, 1259, 1277, 1279, 32 | 1283, 1289, 1291, 1297, 1301, 1303, 1307, 1319, 1321, 1327, 1361, 1367, 33 | 1373, 1381, 1399, 1409, 1423, 1427, 1429, 1433, 1439, 1447, 1451, 1453, 34 | 1459, 1471, 1481, 1483, 1487, 1489, 1493, 1499, 1511, 1523, 1531, 1543, 35 | 1549, 1553, 1559, 1567, 1571, 1579, 1583, 1597, 1601, 1607, 1609, 1613, 36 | 1619, 1621, 1627, 1637, 1657, 1663, 1667, 1669, 1693, 1697, 1699, 1709, 37 | 1721, 1723, 1733, 1741, 1747, 1753, 1759, 1777, 1783, 1787, 1789, 1801, 38 | 1811, 1823, 1831, 1847, 1861, 1867, 1871, 1873, 1877, 1879, 1889, 1901, 39 | 1907, 1913, 1931, 1933, 1949, 1951, 1973, 1979, 1987, 1993, 1997, 1999, 40 | 2003, 2011, 2017, 2027, 2029, 2039, 2053, 2063, 2069, 2081, 2083, 2087, 41 | 2089, 2099, 2111, 2113, 2129, 2131, 2137, 2141, 2143, 2153, 2161, 2179, 42 | 2203, 2207, 2213, 2221, 2237, 2239, 2243, 2251, 2267, 2269, 2273, 2281, 43 | 2287, 2293, 2297, 2309, 2311, 2333, 2339, 2341, 2347, 2351, 2357, 2371, 44 | 2377, 2381, 2383, 2389, 2393, 2399, 2411, 2417, 2423, 2437, 2441, 2447, 45 | 2459, 2467, 2473, 2477, 2503, 2521, 2531, 2539, 2543, 2549, 2551, 2557, 46 | 2579, 2591, 2593, 2609, 2617, 2621, 2633, 2647, 2657, 2659, 2663, 2671, 47 | 2677, 2683, 2687, 2689, 2693, 2699, 2707, 2711, 2713, 2719, 2729, 2731, 48 | 2741, 2749, 2753, 2767, 2777, 2789, 2791, 2797, 2801, 2803, 2819, 2833, 49 | 2837, 2843, 2851, 2857, 2861, 2879, 2887, 2897, 2903, 2909, 2917, 2927, 50 | 2939, 2953, 2957, 2963, 2969, 2971, 2999, 3001, 3011, 3019, 3023, 3037, 51 | 3041, 3049, 3061, 3067, 3079, 3083, 3089, 3109, 3119, 3121, 3137, 3163, 52 | 3167, 3169, 3181, 3187, 3191, 3203, 3209, 3217, 3221, 3229, 3251, 3253, 53 | 3257, 3259, 3271, 3299, 3301, 3307, 3313, 3319, 3323, 3329, 3331, 3343, 54 | 3347, 3359, 3361, 3371, 3373, 3389, 3391, 3407, 3413, 3433, 3449, 3457, 55 | 3461, 3463, 3467, 3469, 3491, 3499, 3511, 3517, 3527, 3529, 3533, 3539, 56 | 3541, 3547, 3557, 3559, 3571, 3581, 3583, 3593, 3607, 3613, 3617, 3623, 57 | 3631, 3637, 3643, 3659, 3671, 3673, 3677, 3691, 3697, 3701, 3709, 3719, 58 | 3727, 3733, 3739, 3761, 3767, 3769, 3779, 3793, 3797, 3803, 3821, 3823, 59 | 3833, 3847, 3851, 3853, 3863, 3877, 3881, 3889, 3907, 3911, 3917, 3919, 60 | 3923, 3929, 3931, 3943, 3947, 3967, 3989, 4001, 4003, 4007, 4013, 4019, 61 | 4021, 4027, 4049, 4051, 4057, 4073, 4079, 4091, 4093, 4099, 4111, 4127, 62 | 4129, 4133, 4139, 4153, 4157, 4159, 4177, 4201, 4211, 4217, 4219, 4229, 63 | 4231, 4241, 4243, 4253, 4259, 4261, 4271, 4273, 4283, 4289, 4297, 4327, 64 | 4337, 4339, 4349, 4357, 4363, 4373, 4391, 4397, 4409, 4421, 4423, 4441, 65 | 4447, 4451, 4457, 4463, 4481, 4483, 4493, 4507, 4513, 4517, 4519, 4523, 66 | 4547, 4549, 4561, 4567, 4583, 4591, 4597, 4603, 4621, 4637, 4639, 4643, 67 | 4649, 4651, 4657, 4663, 4673, 4679, 4691, 4703, 4721, 4723, 4729, 4733, 68 | 4751, 4759, 4783, 4787, 4789, 4793, 4799, 4801, 4813, 4817, 4831, 4861, 69 | 4871, 4877, 4889, 4903, 4909, 4919, 4931, 4933, 4937, 4943, 4951, 4957, 70 | 4967, 4969, 4973, 4987, 4993, 4999, 5003, 5009, 5011, 5021, 5023, 5039, 71 | 5051, 5059, 5077, 5081, 5087, 5099, 5101, 5107, 5113, 5119, 5147, 5153, 72 | 5167, 5171, 5179, 5189, 5197, 5209, 5227, 5231, 5233, 5237, 5261, 5273, 73 | 5279, 5281, 5297, 5303, 5309, 5323, 5333, 5347, 5351, 5381, 5387, 5393, 74 | 5399, 5407, 5413, 5417, 5419, 5431, 5437, 5441, 5443, 5449, 5471, 5477, 75 | 5479, 5483, 5501, 5503, 5507, 5519, 5521, 5527, 5531, 5557, 5563, 5569, 76 | 5573, 5581, 5591, 5623, 5639, 5641, 5647, 5651, 5653, 5657, 5659, 5669, 77 | 5683, 5689, 5693, 5701, 5711, 5717, 5737, 5741, 5743, 5749, 5779, 5783, 78 | 5791, 5801, 5807, 5813, 5821, 5827, 5839, 5843, 5849, 5851, 5857, 5861, 79 | 5867, 5869, 5879, 5881, 5897, 5903, 5923, 5927, 5939, 5953, 5981, 5987, 80 | 6007, 6011, 6029, 6037, 6043, 6047, 6053, 6067, 6073, 6079, 6089, 6091, 81 | 6101, 6113, 6121, 6131, 6133, 6143, 6151, 6163, 6173, 6197, 6199, 6203, 82 | 6211, 6217, 6221, 6229, 6247, 6257, 6263, 6269, 6271, 6277, 6287, 6299, 83 | 6301, 6311, 6317, 6323, 6329, 6337, 6343, 6353, 6359, 6361, 6367, 6373, 84 | 6379, 6389, 6397, 6421, 6427, 6449, 6451, 6469, 6473, 6481, 6491, 6521, 85 | 6529, 6547, 6551, 6553, 6563, 6569, 6571, 6577, 6581, 6599, 6607, 6619, 86 | 6637, 6653, 6659, 6661, 6673, 6679, 6689, 6691, 6701, 6703, 6709, 6719, 87 | 6733, 6737, 6761, 6763, 6779, 6781, 6791, 6793, 6803, 6823, 6827, 6829, 88 | 6833, 6841, 6857, 6863, 6869, 6871, 6883, 6899, 6907, 6911, 6917, 6947, 89 | 6949, 6959, 6961, 6967, 6971, 6977, 6983, 6991, 6997, 7001, 7013, 7019, 90 | 7027, 7039, 7043, 7057, 7069, 7079, 7103, 7109, 7121, 7127, 7129, 7151, 91 | 7159, 7177, 7187, 7193, 7207, 7211, 7213, 7219, 7229, 7237, 7243, 7247, 92 | 7253, 7283, 7297, 7307, 7309, 7321, 7331, 7333, 7349, 7351, 7369, 7393, 93 | 7411, 7417, 7433, 7451, 7457, 7459, 7477, 7481, 7487, 7489, 7499, 7507, 94 | 7517, 7523, 7529, 7537, 7541, 7547, 7549, 7559, 7561, 7573, 7577, 7583, 95 | 7589, 7591, 7603, 7607, 7621, 7639, 7643, 7649, 7669, 7673, 7681, 7687, 96 | 7691, 7699, 7703, 7717, 7723, 7727, 7741, 7753, 7757, 7759, 7789, 7793, 97 | 7817, 7823, 7829, 7841, 7853, 7867, 7873, 7877, 7879, 7883, 7901, 7907, 98 | 7919, 7927, 7933, 7937, 7949, 7951, 7963, 7993, 8009, 8011, 8017, 8039, 99 | 8053, 8059, 8069, 8081, 8087, 8089, 8093, 8101, 8111, 8117, 8123, 8147, 100 | 8161, 8167, 8171, 8179, 8191, 8209, 8219, 8221, 8231, 8233, 8237, 8243, 101 | 8263, 8269, 8273, 8287, 8291, 8293, 8297, 8311, 8317, 8329, 8353, 8363, 102 | 8369, 8377, 8387, 8389, 8419, 8423, 8429, 8431, 8443, 8447, 8461, 8467, 103 | 8501, 8513, 8521, 8527, 8537, 8539, 8543, 8563, 8573, 8581, 8597, 8599, 104 | 8609, 8623, 8627, 8629, 8641, 8647, 8663, 8669, 8677, 8681, 8689, 8693, 105 | 8699, 8707, 8713, 8719, 8731, 8737, 8741, 8747, 8753, 8761, 8779, 8783, 106 | 8803, 8807, 8819, 8821, 8831, 8837, 8839, 8849, 8861, 8863, 8867, 8887, 107 | 8893, 8923, 8929, 8933, 8941, 8951, 8963, 8969, 8971, 8999, 9001, 9007, 108 | 9011, 9013, 9029, 9041, 9043, 9049, 9059, 9067, 9091, 9103, 9109, 9127, 109 | 9133, 9137, 9151, 9157, 9161, 9173, 9181, 9187, 9199, 9203, 9209, 9221, 110 | 9227, 9239, 9241, 9257, 9277, 9281, 9283, 9293, 9311, 9319, 9323, 9337, 111 | 9341, 9343, 9349, 9371, 9377, 9391, 9397, 9403, 9413, 9419, 9421, 9431, 112 | 9433, 9437, 9439, 9461, 9463, 9467, 9473, 9479, 9491, 9497, 9511, 9521, 113 | 9533, 9539, 9547, 9551, 9587, 9601, 9613, 9619, 9623, 9629, 9631, 9643, 114 | 9649, 9661, 9677, 9679, 9689, 9697, 9719, 9721, 9733, 9739, 9743, 9749, 115 | 9767, 9769, 9781, 9787, 9791, 9803, 9811, 9817, 9829, 9833, 9839, 9851, 116 | 9857, 9859, 9871, 9883, 9887, 9901, 9907, 9923, 9929, 9931, 9941, 9949, 117 | 9967, 9973, 10007, 10009, 10037, 10039, 10061, 10067, 10069, 10079, 118 | 10091, 10093, 10099, 10103, 10111, 10133, 10139, 10141, 10151, 10159, 119 | 10163, 10169, 10177, 10181, 10193, 10211, 10223, 10243, 10247, 10253, 120 | 10259, 10267, 10271, 10273, 10289, 10301, 10303, 10313, 10321, 10331, 121 | 10333, 10337, 10343, 10357, 10369, 10391, 10399, 10427, 10429, 10433, 122 | 10453, 10457, 10459, 10463, 10477, 10487, 10499, 10501, 10513, 10529, 123 | 10531, 10559, 10567, 10589, 10597, 10601, 10607, 10613, 10627, 10631, 124 | 10639, 10651, 10657, 10663, 10667, 10687, 10691, 10709, 10711, 10723, 125 | 10729, 10733, 10739, 10753, 10771, 10781, 10789, 10799, 10831, 10837, 126 | 10847, 10853, 10859, 10861, 10867, 10883, 10889, 10891, 10903, 10909, 127 | 10937, 10939, 10949, 10957, 10973, 10979, 10987, 10993, 11003, 11027, 128 | 11047, 11057, 11059, 11069, 11071, 11083, 11087, 11093, 11113, 11117, 129 | 11119, 11131, 11149, 11159, 11161, 11171, 11173, 11177, 11197, 11213, 130 | 11239, 11243, 11251, 11257, 11261, 11273, 11279, 11287, 11299, 11311, 131 | 11317, 11321, 11329, 11351, 11353, 11369, 11383, 11393, 11399, 11411, 132 | 11423, 11437, 11443, 11447, 11467, 11471, 11483, 11489, 11491, 11497, 133 | 11503, 11519, 11527, 11549, 11551, 11579, 11587, 11593, 11597, 11617, 134 | 11621, 11633, 11657, 11677, 11681, 11689, 11699, 11701, 11717, 11719, 135 | 11731, 11743, 11777, 11779, 11783, 11789, 11801, 11807, 11813, 11821, 136 | 11827, 11831, 11833, 11839, 11863, 11867, 11887, 11897, 11903, 11909, 137 | 11923, 11927, 11933, 11939, 11941, 11953, 11959, 11969, 11971, 11981, 138 | 11987, 12007, 12011, 12037, 12041, 12043, 12049, 12071, 12073, 12097, 139 | 12101, 12107, 12109, 12113, 12119, 12143, 12149, 12157, 12161, 12163, 140 | 12197, 12203, 12211, 12227, 12239, 12241, 12251, 12253, 12263, 12269, 141 | 12277, 12281, 12289, 12301, 12323, 12329, 12343, 12347, 12373, 12377, 142 | 12379, 12391, 12401, 12409, 12413, 12421, 12433, 12437, 12451, 12457, 143 | 12473, 12479, 12487, 12491, 12497, 12503, 12511, 12517, 12527, 12539, 144 | 12541, 12547, 12553, 12569, 12577, 12583, 12589, 12601, 12611, 12613, 145 | 12619, 12637, 12641, 12647, 12653, 12659, 12671, 12689, 12697, 12703, 146 | 12713, 12721, 12739, 12743, 12757, 12763, 12781, 12791, 12799, 12809, 147 | 12821, 12823, 12829, 12841, 12853, 12889, 12893, 12899, 12907, 12911, 148 | 12917, 12919, 12923, 12941, 12953, 12959, 12967, 12973, 12979, 12983, 149 | 13001, 13003, 13007, 13009, 13033, 13037, 13043, 13049, 13063, 13093, 150 | 13099, 13103, 13109, 13121, 13127, 13147, 13151, 13159, 13163, 13171, 151 | 13177, 13183, 13187, 13217, 13219, 13229, 13241, 13249, 13259, 13267, 152 | 13291, 13297, 13309, 13313, 13327, 13331, 13337, 13339, 13367, 13381, 153 | 13397, 13399, 13411, 13417, 13421, 13441, 13451, 13457, 13463, 13469, 154 | 13477, 13487, 13499, 13513, 13523, 13537, 13553, 13567, 13577, 13591, 155 | 13597, 13613, 13619, 13627, 13633, 13649, 13669, 13679, 13681, 13687, 156 | 13691, 13693, 13697, 13709, 13711, 13721, 13723, 13729, 13751, 13757, 157 | 13759, 13763, 13781, 13789, 13799, 13807, 13829, 13831, 13841, 13859, 158 | 13873, 13877, 13879, 13883, 13901, 13903, 13907, 13913, 13921, 13931, 159 | 13933, 13963, 13967, 13997, 13999, 14009, 14011, 14029, 14033, 14051, 160 | 14057, 14071, 14081, 14083, 14087, 14107, 14143, 14149, 14153, 14159, 161 | 14173, 14177, 14197, 14207, 14221, 14243, 14249, 14251, 14281, 14293, 162 | 14303, 14321, 14323, 14327, 14341, 14347, 14369, 14387, 14389, 14401, 163 | 14407, 14411, 14419, 14423, 14431, 14437, 14447, 14449, 14461, 14479, 164 | 14489, 14503, 14519, 14533, 14537, 14543, 14549, 14551, 14557, 14561, 165 | 14563, 14591, 14593, 14621, 14627, 14629, 14633, 14639, 14653, 14657, 166 | 14669, 14683, 14699, 14713, 14717, 14723, 14731, 14737, 14741, 14747, 167 | 14753, 14759, 14767, 14771, 14779, 14783, 14797, 14813, 14821, 14827, 168 | 14831, 14843, 14851, 14867, 14869, 14879, 14887, 14891, 14897, 14923, 169 | 14929, 14939, 14947, 14951, 14957, 14969, 14983, 15013, 15017, 15031, 170 | 15053, 15061, 15073, 15077, 15083, 15091, 15101, 15107, 15121, 15131, 171 | 15137, 15139, 15149, 15161, 15173, 15187, 15193, 15199, 15217, 15227, 172 | 15233, 15241, 15259, 15263, 15269, 15271, 15277, 15287, 15289, 15299, 173 | 15307, 15313, 15319, 15329, 15331, 15349, 15359, 15361, 15373, 15377, 174 | 15383, 15391, 15401, 15413, 15427, 15439, 15443, 15451, 15461, 15467, 175 | 15473, 15493, 15497, 15511, 15527, 15541, 15551, 15559, 15569, 15581, 176 | 15583, 15601, 15607, 15619, 15629, 15641, 15643, 15647, 15649, 15661, 177 | 15667, 15671, 15679, 15683, 15727, 15731, 15733, 15737, 15739, 15749, 178 | 15761, 15767, 15773, 15787, 15791, 15797, 15803, 15809, 15817, 15823, 179 | 15859, 15877, 15881, 15887, 15889, 15901, 15907, 15913, 15919, 15923, 180 | 15937, 15959, 15971, 15973, 15991, 16001, 16007, 16033, 16057, 16061, 181 | 16063, 16067, 16069, 16073, 16087, 16091, 16097, 16103, 16111, 16127, 182 | 16139, 16141, 16183, 16187, 16189, 16193, 16217, 16223, 16229, 16231, 183 | 16249, 16253, 16267, 16273, 16301, 16319, 16333, 16339, 16349, 16361, 184 | 16363, 16369, 16381, 16411, 16417, 16421, 16427, 16433, 16447, 16451, 185 | 16453, 16477, 16481, 16487, 16493, 16519, 16529, 16547, 16553, 16561, 186 | 16567, 16573, 16603, 16607, 16619, 16631, 16633, 16649, 16651, 16657, 187 | 16661, 16673, 16691, 16693, 16699, 16703, 16729, 16741, 16747, 16759, 188 | 16763, 16787, 16811, 16823, 16829, 16831, 16843, 16871, 16879, 16883, 189 | 16889, 16901, 16903, 16921, 16927, 16931, 16937, 16943, 16963, 16979, 190 | 16981, 16987, 16993, 17011, 17021, 17027, 17029, 17033, 17041, 17047, 191 | 17053, 17077, 17093, 17099, 17107, 17117, 17123, 17137, 17159, 17167, 192 | 17183, 17189, 17191, 17203, 17207, 17209, 17231, 17239, 17257, 17291, 193 | 17293, 17299, 17317, 17321, 17327, 17333, 17341, 17351, 17359, 17377, 194 | 17383, 17387, 17389, 17393, 17401, 17417, 17419, 17431, 17443, 17449, 195 | 17467, 17471, 17477, 17483, 17489, 17491, 17497, 17509, 17519, 17539, 196 | 17551, 17569, 17573, 17579, 17581, 17597, 17599, 17609, 17623, 17627, 197 | 17657, 17659, 17669, 17681, 17683, 17707, 17713, 17729, 17737, 17747, 198 | 17749, 17761, 17783, 17789, 17791, 17807, 17827, 17837, 17839, 17851, 199 | 17863, 17881, 17891, 17903, 17909, 17911, 17921, 17923, 17929, 17939, 200 | 17957, 17959, 17971, 17977, 17981, 17987, 17989, 18013, 18041, 18043, 201 | 18047, 18049, 18059, 18061, 18077, 18089, 18097, 18119, 18121, 18127, 202 | 18131, 18133, 18143, 18149, 18169, 18181, 18191, 18199, 18211, 18217, 203 | 18223, 18229, 18233, 18251, 18253, 18257, 18269, 18287, 18289, 18301, 204 | 18307, 18311, 18313, 18329, 18341, 18353, 18367, 18371, 18379, 18397, 205 | 18401, 18413, 18427, 18433, 18439, 18443, 18451, 18457, 18461, 18481, 206 | 18493, 18503, 18517, 18521, 18523, 18539, 18541, 18553, 18583, 18587, 207 | 18593, 18617, 18637, 18661, 18671, 18679, 18691, 18701, 18713, 18719, 208 | 18731, 18743, 18749, 18757, 18773, 18787, 18793, 18797, 18803, 18839, 209 | 18859, 18869, 18899, 18911, 18913, 18917, 18919, 18947, 18959, 18973, 210 | 18979, 19001, 19009, 19013, 19031, 19037, 19051, 19069, 19073, 19079, 211 | 19081, 19087, 19121, 19139, 19141, 19157, 19163, 19181, 19183, 19207, 212 | 19211, 19213, 19219, 19231, 19237, 19249, 19259, 19267, 19273, 19289, 213 | 19301, 19309, 19319, 19333, 19373, 19379, 19381, 19387, 19391, 19403, 214 | 19417, 19421, 19423, 19427, 19429, 19433, 19441, 19447, 19457, 19463, 215 | 19469, 19471, 19477, 19483, 19489, 19501, 19507, 19531, 19541, 19543, 216 | 19553, 19559, 19571, 19577, 19583, 19597, 19603, 19609, 19661, 19681, 217 | 19687, 19697, 19699, 19709, 19717, 19727, 19739, 19751, 19753, 19759, 218 | 19763, 19777, 19793, 19801, 19813, 19819, 19841, 19843, 19853, 19861, 219 | 19867, 19889, 19891, 19913, 19919, 19927, 19937, 19949, 19961, 19963, 220 | 19973, 19979, 19991, 19993, 19997, 20011, 20021, 20023, 20029, 20047, 221 | 20051, 20063, 20071, 20089, 20101, 20107, 20113, 20117, 20123, 20129, 222 | 20143, 20147, 20149, 20161, 20173, 20177, 20183, 20201, 20219, 20231, 223 | 20233, 20249, 20261, 20269, 20287, 20297, 20323, 20327, 20333, 20341, 224 | 20347, 20353, 20357, 20359, 20369, 20389, 20393, 20399, 20407, 20411, 225 | 20431, 20441, 20443, 20477, 20479, 20483, 20507, 20509, 20521, 20533, 226 | 20543, 20549, 20551, 20563, 20593, 20599, 20611, 20627, 20639, 20641, 227 | 20663, 20681, 20693, 20707, 20717, 20719, 20731, 20743, 20747, 20749, 228 | 20753, 20759, 20771, 20773, 20789, 20807, 20809, 20849, 20857, 20873, 229 | 20879, 20887, 20897, 20899, 20903, 20921, 20929, 20939, 20947, 20959, 230 | 20963, 20981, 20983, 21001, 21011, 21013, 21017, 21019, 21023, 21031, 231 | 21059, 21061, 21067, 21089, 21101, 21107, 21121, 21139, 21143, 21149, 232 | 21157, 21163, 21169, 21179, 21187, 21191, 21193, 21211, 21221, 21227, 233 | 21247, 21269, 21277, 21283, 21313, 21317, 21319, 21323, 21341, 21347, 234 | 21377, 21379, 21383, 21391, 21397, 21401, 21407, 21419, 21433, 21467, 235 | 21481, 21487, 21491, 21493, 21499, 21503, 21517, 21521, 21523, 21529, 236 | 21557, 21559, 21563, 21569, 21577, 21587, 21589, 21599, 21601, 21611, 237 | 21613, 21617, 21647, 21649, 21661, 21673, 21683, 21701, 21713, 21727, 238 | 21737, 21739, 21751, 21757, 21767, 21773, 21787, 21799, 21803, 21817, 239 | 21821, 21839, 21841, 21851, 21859, 21863, 21871, 21881, 21893, 21911, 240 | 21929, 21937, 21943, 21961, 21977, 21991, 21997, 22003, 22013, 22027, 241 | 22031, 22037, 22039, 22051, 22063, 22067, 22073, 22079, 22091, 22093, 242 | 22109, 22111, 22123, 22129, 22133, 22147, 22153, 22157, 22159, 22171, 243 | 22189, 22193, 22229, 22247, 22259, 22271, 22273, 22277, 22279, 22283, 244 | 22291, 22303, 22307, 22343, 22349, 22367, 22369, 22381, 22391, 22397, 245 | 22409, 22433, 22441, 22447, 22453, 22469, 22481, 22483, 22501, 22511, 246 | 22531, 22541, 22543, 22549, 22567, 22571, 22573, 22613, 22619, 22621, 247 | 22637, 22639, 22643, 22651, 22669, 22679, 22691, 22697, 22699, 22709, 248 | 22717, 22721, 22727, 22739, 22741, 22751, 22769, 22777, 22783, 22787, 249 | 22807, 22811, 22817, 22853, 22859, 22861, 22871, 22877, 22901, 22907, 250 | 22921, 22937, 22943, 22961, 22963, 22973, 22993, 23003, 23011, 23017, 251 | 23021, 23027, 23029, 23039, 23041, 23053, 23057, 23059, 23063, 23071, 252 | 23081, 23087, 23099, 23117, 23131, 23143, 23159, 23167, 23173, 23189, 253 | 23197, 23201, 23203, 23209, 23227, 23251, 23269, 23279, 23291, 23293, 254 | 23297, 23311, 23321, 23327, 23333, 23339, 23357, 23369, 23371, 23399, 255 | 23417, 23431, 23447, 23459, 23473, 23497, 23509, 23531, 23537, 23539, 256 | 23549, 23557, 23561, 23563, 23567, 23581, 23593, 23599, 23603, 23609, 257 | 23623, 23627, 23629, 23633, 23663, 23669, 23671, 23677, 23687, 23689, 258 | 23719, 23741, 23743, 23747, 23753, 23761, 23767, 23773, 23789, 23801, 259 | 23813, 23819, 23827, 23831, 23833, 23857, 23869, 23873, 23879, 23887, 260 | 23893, 23899, 23909, 23911, 23917, 23929, 23957, 23971, 23977, 23981, 261 | 23993, 24001, 24007, 24019, 24023, 24029, 24043, 24049, 24061, 24071, 262 | 24077, 24083, 24091, 24097, 24103, 24107, 24109, 24113, 24121, 24133, 263 | 24137, 24151, 24169, 24179, 24181, 24197, 24203, 24223, 24229, 24239, 264 | 24247, 24251, 24281, 24317, 24329, 24337, 24359, 24371, 24373, 24379, 265 | 24391, 24407, 24413, 24419, 24421, 24439, 24443, 24469, 24473, 24481, 266 | 24499, 24509, 24517, 24527, 24533, 24547, 24551, 24571, 24593, 24611, 267 | 24623, 24631, 24659, 24671, 24677, 24683, 24691, 24697, 24709, 24733, 268 | 24749, 24763, 24767, 24781, 24793, 24799, 24809, 24821, 24841, 24847, 269 | 24851, 24859, 24877, 24889, 24907, 24917, 24919, 24923, 24943, 24953, 270 | 24967, 24971, 24977, 24979, 24989, 25013, 25031, 25033, 25037, 25057, 271 | 25073, 25087, 25097, 25111, 25117, 25121, 25127, 25147, 25153, 25163, 272 | 25169, 25171, 25183, 25189, 25219, 25229, 25237, 25243, 25247, 25253, 273 | 25261, 25301, 25303, 25307, 25309, 25321, 25339, 25343, 25349, 25357, 274 | 25367, 25373, 25391, 25409, 25411, 25423, 25439, 25447, 25453, 25457, 275 | 25463, 25469, 25471, 25523, 25537, 25541, 25561, 25577, 25579, 25583, 276 | 25589, 25601, 25603, 25609, 25621, 25633, 25639, 25643, 25657, 25667, 277 | 25673, 25679, 25693, 25703, 25717, 25733, 25741, 25747, 25759, 25763, 278 | 25771, 25793, 25799, 25801, 25819, 25841, 25847, 25849, 25867, 25873, 279 | 25889, 25903, 25913, 25919, 25931, 25933, 25939, 25943, 25951, 25969, 280 | 25981, 25997, 25999, 26003, 26017, 26021, 26029, 26041, 26053, 26083, 281 | 26099, 26107, 26111, 26113, 26119, 26141, 26153, 26161, 26171, 26177, 282 | 26183, 26189, 26203, 26209, 26227, 26237, 26249, 26251, 26261, 26263, 283 | 26267, 26293, 26297, 26309, 26317, 26321, 26339, 26347, 26357, 26371, 284 | 26387, 26393, 26399, 26407, 26417, 26423, 26431, 26437, 26449, 26459, 285 | 26479, 26489, 26497, 26501, 26513, 26539, 26557, 26561, 26573, 26591, 286 | 26597, 26627, 26633, 26641, 26647, 26669, 26681, 26683, 26687, 26693, 287 | 26699, 26701, 26711, 26713, 26717, 26723, 26729, 26731, 26737, 26759, 288 | 26777, 26783, 26801, 26813, 26821, 26833, 26839, 26849, 26861, 26863, 289 | 26879, 26881, 26891, 26893, 26903, 26921, 26927, 26947, 26951, 26953, 290 | 26959, 26981, 26987, 26993, 27011, 27017, 27031, 27043, 27059, 27061, 291 | 27067, 27073, 27077, 27091, 27103, 27107, 27109, 27127, 27143, 27179, 292 | 27191, 27197, 27211, 27239, 27241, 27253, 27259, 27271, 27277, 27281, 293 | 27283, 27299, 27329, 27337, 27361, 27367, 27397, 27407, 27409, 27427, 294 | 27431, 27437, 27449, 27457, 27479, 27481, 27487, 27509, 27527, 27529, 295 | 27539, 27541, 27551, 27581, 27583, 27611, 27617, 27631, 27647, 27653, 296 | 27673, 27689, 27691, 27697, 27701, 27733, 27737, 27739, 27743, 27749, 297 | 27751, 27763, 27767, 27773, 27779, 27791, 27793, 27799, 27803, 27809, 298 | 27817, 27823, 27827, 27847, 27851, 27883, 27893, 27901, 27917, 27919, 299 | 27941, 27943, 27947, 27953, 27961, 27967, 27983, 27997, 28001, 28019, 300 | 28027, 28031, 28051, 28057, 28069, 28081, 28087, 28097, 28099, 28109, 301 | 28111, 28123, 28151, 28163, 28181, 28183, 28201, 28211, 28219, 28229, 302 | 28277, 28279, 28283, 28289, 28297, 28307, 28309, 28319, 28349, 28351, 303 | 28387, 28393, 28403, 28409, 28411, 28429, 28433, 28439, 28447, 28463, 304 | 28477, 28493, 28499, 28513, 28517, 28537, 28541, 28547, 28549, 28559, 305 | 28571, 28573, 28579, 28591, 28597, 28603, 28607, 28619, 28621, 28627, 306 | 28631, 28643, 28649, 28657, 28661, 28663, 28669, 28687, 28697, 28703, 307 | 28711, 28723, 28729, 28751, 28753, 28759, 28771, 28789, 28793, 28807, 308 | 28813, 28817, 28837, 28843, 28859, 28867, 28871, 28879, 28901, 28909, 309 | 28921, 28927, 28933, 28949, 28961, 28979, 29009, 29017, 29021, 29023, 310 | 29027, 29033, 29059, 29063, 29077, 29101, 29123, 29129, 29131, 29137, 311 | 29147, 29153, 29167, 29173, 29179, 29191, 29201, 29207, 29209, 29221, 312 | 29231, 29243, 29251, 29269, 29287, 29297, 29303, 29311, 29327, 29333, 313 | 29339, 29347, 29363, 29383, 29387, 29389, 29399, 29401, 29411, 29423, 314 | 29429, 29437, 29443, 29453, 29473, 29483, 29501, 29527, 29531, 29537, 315 | 29567, 29569, 29573, 29581, 29587, 29599, 29611, 29629, 29633, 29641, 316 | 29663, 29669, 29671, 29683, 29717, 29723, 29741, 29753, 29759, 29761, 317 | 29789, 29803, 29819, 29833, 29837, 29851, 29863, 29867, 29873, 29879, 318 | 29881, 29917, 29921, 29927, 29947, 29959, 29983, 29989, 30011, 30013, 319 | 30029, 30047, 30059, 30071, 30089, 30091, 30097, 30103, 30109, 30113, 320 | 30119, 30133, 30137, 30139, 30161, 30169, 30181, 30187, 30197, 30203, 321 | 30211, 30223, 30241, 30253, 30259, 30269, 30271, 30293, 30307, 30313, 322 | 30319, 30323, 30341, 30347, 30367, 30389, 30391, 30403, 30427, 30431, 323 | 30449, 30467, 30469, 30491, 30493, 30497, 30509, 30517, 30529, 30539, 324 | 30553, 30557, 30559, 30577, 30593, 30631, 30637, 30643, 30649, 30661, 325 | 30671, 30677, 30689, 30697, 30703, 30707, 30713, 30727, 30757, 30763, 326 | 30773, 30781, 30803, 30809, 30817, 30829, 30839, 30841, 30851, 30853, 327 | 30859, 30869, 30871, 30881, 30893, 30911, 30931, 30937, 30941, 30949, 328 | 30971, 30977, 30983, 31013, 31019, 31033, 31039, 31051, 31063, 31069, 329 | 31079, 31081, 31091, 31121, 31123, 31139, 31147, 31151, 31153, 31159, 330 | 31177, 31181, 31183, 31189, 31193, 31219, 31223, 31231, 31237, 31247, 331 | 31249, 31253, 31259, 31267, 31271, 31277, 31307, 31319, 31321, 31327, 332 | 31333, 31337, 31357, 31379, 31387, 31391, 31393, 31397, 31469, 31477, 333 | 31481, 31489, 31511, 31513, 31517, 31531, 31541, 31543, 31547, 31567, 334 | 31573, 31583, 31601, 31607, 31627, 31643, 31649, 31657, 31663, 31667, 335 | 31687, 31699, 31721, 31723, 31727, 31729, 31741, 31751, 31769, 31771, 336 | 31793, 31799, 31817, 31847, 31849, 31859, 31873, 31883, 31891, 31907, 337 | 31957, 31963, 31973, 31981, 31991, 32003, 32009, 32027, 32029, 32051, 338 | 32057, 32059, 32063, 32069, 32077, 32083, 32089, 32099, 32117, 32119, 339 | 32141, 32143, 32159, 32173, 32183, 32189, 32191, 32203, 32213, 32233, 340 | 32237, 32251, 32257, 32261, 32297, 32299, 32303, 32309, 32321, 32323, 341 | 32327, 32341, 32353, 32359, 32363, 32369, 32371, 32377, 32381, 32401, 342 | 32411, 32413, 32423, 32429, 32441, 32443, 32467, 32479, 32491, 32497, 343 | 32503, 32507, 32531, 32533, 32537, 32561, 32563, 32569, 32573, 32579, 344 | 32587, 32603, 32609, 32611, 32621, 32633, 32647, 32653, 32687, 32693, 345 | 32707, 32713, 32717, 32719, 32749, 32771, 32779, 32783, 32789, 32797, 346 | 32801, 32803, 32831, 32833, 32839, 32843, 32869, 32887, 32909, 32911, 347 | 32917, 32933, 32939, 32941, 32957, 32969, 32971, 32983, 32987, 32993, 348 | 32999, 33013, 33023, 33029, 33037, 33049, 33053, 33071, 33073, 33083, 349 | 33091, 33107, 33113, 33119, 33149, 33151, 33161, 33179, 33181, 33191, 350 | 33199, 33203, 33211, 33223, 33247, 33287, 33289, 33301, 33311, 33317, 351 | 33329, 33331, 33343, 33347, 33349, 33353, 33359, 33377, 33391, 33403, 352 | 33409, 33413, 33427, 33457, 33461, 33469, 33479, 33487, 33493, 33503, 353 | 33521, 33529, 33533, 33547, 33563, 33569, 33577, 33581, 33587, 33589, 354 | 33599, 33601, 33613, 33617, 33619, 33623, 33629, 33637, 33641, 33647, 355 | 33679, 33703, 33713, 33721, 33739, 33749, 33751, 33757, 33767, 33769, 356 | 33773, 33791, 33797, 33809, 33811, 33827, 33829, 33851, 33857, 33863, 357 | 33871, 33889, 33893, 33911, 33923, 33931, 33937, 33941, 33961, 33967, 358 | 33997, 34019, 34031, 34033, 34039, 34057, 34061, 34123, 34127, 34129, 359 | 34141, 34147, 34157, 34159, 34171, 34183, 34211, 34213, 34217, 34231, 360 | 34253, 34259, 34261, 34267, 34273, 34283, 34297, 34301, 34303, 34313, 361 | 34319, 34327, 34337, 34351, 34361, 34367, 34369, 34381, 34403, 34421, 362 | 34429, 34439, 34457, 34469, 34471, 34483, 34487, 34499, 34501, 34511, 363 | 34513, 34519, 34537, 34543, 34549, 34583, 34589, 34591, 34603, 34607, 364 | 34613, 34631, 34649, 34651, 34667, 34673, 34679, 34687, 34693, 34703, 365 | 34721, 34729, 34739, 34747, 34757, 34759, 34763, 34781, 34807, 34819, 366 | 34841, 34843, 34847, 34849, 34871, 34877, 34883, 34897, 34913, 34919, 367 | 34939, 34949, 34961, 34963, 34981, 35023, 35027, 35051, 35053, 35059, 368 | 35069, 35081, 35083, 35089, 35099, 35107, 35111, 35117, 35129, 35141, 369 | 35149, 35153, 35159, 35171, 35201, 35221, 35227, 35251, 35257, 35267, 370 | 35279, 35281, 35291, 35311, 35317, 35323, 35327, 35339, 35353, 35363, 371 | 35381, 35393, 35401, 35407, 35419, 35423, 35437, 35447, 35449, 35461, 372 | 35491, 35507, 35509, 35521, 35527, 35531, 35533, 35537, 35543, 35569, 373 | 35573, 35591, 35593, 35597, 35603, 35617, 35671, 35677, 35729, 35731, 374 | 35747, 35753, 35759, 35771, 35797, 35801, 35803, 35809, 35831, 35837, 375 | 35839, 35851, 35863, 35869, 35879, 35897, 35899, 35911, 35923, 35933, 376 | 35951, 35963, 35969, 35977, 35983, 35993, 35999, 36007, 36011, 36013, 377 | 36017, 36037, 36061, 36067, 36073, 36083, 36097, 36107, 36109, 36131, 378 | 36137, 36151, 36161, 36187, 36191, 36209, 36217, 36229, 36241, 36251, 379 | 36263, 36269, 36277, 36293, 36299, 36307, 36313, 36319, 36341, 36343, 380 | 36353, 36373, 36383, 36389, 36433, 36451, 36457, 36467, 36469, 36473, 381 | 36479, 36493, 36497, 36523, 36527, 36529, 36541, 36551, 36559, 36563, 382 | 36571, 36583, 36587, 36599, 36607, 36629, 36637, 36643, 36653, 36671, 383 | 36677, 36683, 36691, 36697, 36709, 36713, 36721, 36739, 36749, 36761, 384 | 36767, 36779, 36781, 36787, 36791, 36793, 36809, 36821, 36833, 36847, 385 | 36857, 36871, 36877, 36887, 36899, 36901, 36913, 36919, 36923, 36929, 386 | 36931, 36943, 36947, 36973, 36979, 36997, 37003, 37013, 37019, 37021, 387 | 37039, 37049, 37057, 37061, 37087, 37097, 37117, 37123, 37139, 37159, 388 | 37171, 37181, 37189, 37199, 37201, 37217, 37223, 37243, 37253, 37273, 389 | 37277, 37307, 37309, 37313, 37321, 37337, 37339, 37357, 37361, 37363, 390 | 37369, 37379, 37397, 37409, 37423, 37441, 37447, 37463, 37483, 37489, 391 | 37493, 37501, 37507, 37511, 37517, 37529, 37537, 37547, 37549, 37561, 392 | 37567, 37571, 37573, 37579, 37589, 37591, 37607, 37619, 37633, 37643, 393 | 37649, 37657, 37663, 37691, 37693, 37699, 37717, 37747, 37781, 37783, 394 | 37799, 37811, 37813, 37831, 37847, 37853, 37861, 37871, 37879, 37889, 395 | 37897, 37907, 37951, 37957, 37963, 37967, 37987, 37991, 37993, 37997, 396 | 38011, 38039, 38047, 38053, 38069, 38083, 38113, 38119, 38149, 38153, 397 | 38167, 38177, 38183, 38189, 38197, 38201, 38219, 38231, 38237, 38239, 398 | 38261, 38273, 38281, 38287, 38299, 38303, 38317, 38321, 38327, 38329, 399 | 38333, 38351, 38371, 38377, 38393, 38431, 38447, 38449, 38453, 38459, 400 | 38461, 38501, 38543, 38557, 38561, 38567, 38569, 38593, 38603, 38609, 401 | 38611, 38629, 38639, 38651, 38653, 38669, 38671, 38677, 38693, 38699, 402 | 38707, 38711, 38713, 38723, 38729, 38737, 38747, 38749, 38767, 38783, 403 | 38791, 38803, 38821, 38833, 38839, 38851, 38861, 38867, 38873, 38891, 404 | 38903, 38917, 38921, 38923, 38933, 38953, 38959, 38971, 38977, 38993, 405 | 39019, 39023, 39041, 39043, 39047, 39079, 39089, 39097, 39103, 39107, 406 | 39113, 39119, 39133, 39139, 39157, 39161, 39163, 39181, 39191, 39199, 407 | 39209, 39217, 39227, 39229, 39233, 39239, 39241, 39251, 39293, 39301, 408 | 39313, 39317, 39323, 39341, 39343, 39359, 39367, 39371, 39373, 39383, 409 | 39397, 39409, 39419, 39439, 39443, 39451, 39461, 39499, 39503, 39509, 410 | 39511, 39521, 39541, 39551, 39563, 39569, 39581, 39607, 39619, 39623, 411 | 39631, 39659, 39667, 39671, 39679, 39703, 39709, 39719, 39727, 39733, 412 | 39749, 39761, 39769, 39779, 39791, 39799, 39821, 39827, 39829, 39839, 413 | 39841, 39847, 39857, 39863, 39869, 39877, 39883, 39887, 39901, 39929, 414 | 39937, 39953, 39971, 39979, 39983, 39989, 40009, 40013, 40031, 40037, 415 | 40039, 40063, 40087, 40093, 40099, 40111, 40123, 40127, 40129, 40151, 416 | 40153, 40163, 40169, 40177, 40189, 40193, 40213, 40231, 40237, 40241, 417 | 40253, 40277, 40283, 40289, 40343, 40351, 40357, 40361, 40387, 40423, 418 | 40427, 40429, 40433, 40459, 40471, 40483, 40487, 40493, 40499, 40507, 419 | 40519, 40529, 40531, 40543, 40559, 40577, 40583, 40591, 40597, 40609, 420 | 40627, 40637, 40639, 40693, 40697, 40699, 40709, 40739, 40751, 40759, 421 | 40763, 40771, 40787, 40801, 40813, 40819, 40823, 40829, 40841, 40847, 422 | 40849, 40853, 40867, 40879, 40883, 40897, 40903, 40927, 40933, 40939, 423 | 40949, 40961, 40973, 40993, 41011, 41017, 41023, 41039, 41047, 41051, 424 | 41057, 41077, 41081, 41113, 41117, 41131, 41141, 41143, 41149, 41161, 425 | 41177, 41179, 41183, 41189, 41201, 41203, 41213, 41221, 41227, 41231, 426 | 41233, 41243, 41257, 41263, 41269, 41281, 41299, 41333, 41341, 41351, 427 | 41357, 41381, 41387, 41389, 41399, 41411, 41413, 41443, 41453, 41467, 428 | 41479, 41491, 41507, 41513, 41519, 41521, 41539, 41543, 41549, 41579, 429 | 41593, 41597, 41603, 41609, 41611, 41617, 41621, 41627, 41641, 41647, 430 | 41651, 41659, 41669, 41681, 41687, 41719, 41729, 41737, 41759, 41761, 431 | 41771, 41777, 41801, 41809, 41813, 41843, 41849, 41851, 41863, 41879, 432 | 41887, 41893, 41897, 41903, 41911, 41927, 41941, 41947, 41953, 41957, 433 | 41959, 41969, 41981, 41983, 41999, 42013, 42017, 42019, 42023, 42043, 434 | 42061, 42071, 42073, 42083, 42089, 42101, 42131, 42139, 42157, 42169, 435 | 42179, 42181, 42187, 42193, 42197, 42209, 42221, 42223, 42227, 42239, 436 | 42257, 42281, 42283, 42293, 42299, 42307, 42323, 42331, 42337, 42349, 437 | 42359, 42373, 42379, 42391, 42397, 42403, 42407, 42409, 42433, 42437, 438 | 42443, 42451, 42457, 42461, 42463, 42467, 42473, 42487, 42491, 42499, 439 | 42509, 42533, 42557, 42569, 42571, 42577, 42589, 42611, 42641, 42643, 440 | 42649, 42667, 42677, 42683, 42689, 42697, 42701, 42703, 42709, 42719, 441 | 42727, 42737, 42743, 42751, 42767, 42773, 42787, 42793, 42797, 42821, 442 | 42829, 42839, 42841, 42853, 42859, 42863, 42899, 42901, 42923, 42929, 443 | 42937, 42943, 42953, 42961, 42967, 42979, 42989, 43003, 43013, 43019, 444 | 43037, 43049, 43051, 43063, 43067, 43093, 43103, 43117, 43133, 43151, 445 | 43159, 43177, 43189, 43201, 43207, 43223, 43237, 43261, 43271, 43283, 446 | 43291, 43313, 43319, 43321, 43331, 43391, 43397, 43399, 43403, 43411, 447 | 43427, 43441, 43451, 43457, 43481, 43487, 43499, 43517, 43541, 43543, 448 | 43573, 43577, 43579, 43591, 43597, 43607, 43609, 43613, 43627, 43633, 449 | 43649, 43651, 43661, 43669, 43691, 43711, 43717, 43721, 43753, 43759, 450 | 43777, 43781, 43783, 43787, 43789, 43793, 43801, 43853, 43867, 43889, 451 | 43891, 43913, 43933, 43943, 43951, 43961, 43963, 43969, 43973, 43987, 452 | 43991, 43997, 44017, 44021, 44027, 44029, 44041, 44053, 44059, 44071, 453 | 44087, 44089, 44101, 44111, 44119, 44123, 44129, 44131, 44159, 44171, 454 | 44179, 44189, 44201, 44203, 44207, 44221, 44249, 44257, 44263, 44267, 455 | 44269, 44273, 44279, 44281, 44293, 44351, 44357, 44371, 44381, 44383, 456 | 44389, 44417, 44449, 44453, 44483, 44491, 44497, 44501, 44507, 44519, 457 | 44531, 44533, 44537, 44543, 44549, 44563, 44579, 44587, 44617, 44621, 458 | 44623, 44633, 44641, 44647, 44651, 44657, 44683, 44687, 44699, 44701, 459 | 44711, 44729, 44741, 44753, 44771, 44773, 44777, 44789, 44797, 44809, 460 | 44819, 44839, 44843, 44851, 44867, 44879, 44887, 44893, 44909, 44917, 461 | 44927, 44939, 44953, 44959, 44963, 44971, 44983, 44987, 45007, 45013, 462 | 45053, 45061, 45077, 45083, 45119, 45121, 45127, 45131, 45137, 45139, 463 | 45161, 45179, 45181, 45191, 45197, 45233, 45247, 45259, 45263, 45281, 464 | 45289, 45293, 45307, 45317, 45319, 45329, 45337, 45341, 45343, 45361, 465 | 45377, 45389, 45403, 45413, 45427, 45433, 45439, 45481, 45491, 45497, 466 | 45503, 45523, 45533, 45541, 45553, 45557, 45569, 45587, 45589, 45599, 467 | 45613, 45631, 45641, 45659, 45667, 45673, 45677, 45691, 45697, 45707, 468 | 45737, 45751, 45757, 45763, 45767, 45779, 45817, 45821, 45823, 45827, 469 | 45833, 45841, 45853, 45863, 45869, 45887, 45893, 45943, 45949, 45953, 470 | 45959, 45971, 45979, 45989, 46021, 46027, 46049, 46051, 46061, 46073, 471 | 46091, 46093, 46099, 46103, 46133, 46141, 46147, 46153, 46171, 46181, 472 | 46183, 46187, 46199, 46219, 46229, 46237, 46261, 46271, 46273, 46279, 473 | 46301, 46307, 46309, 46327, 46337, 46349, 46351, 46381, 46399, 46411, 474 | 46439, 46441, 46447, 46451, 46457, 46471, 46477, 46489, 46499, 46507, 475 | 46511, 46523, 46549, 46559, 46567, 46573, 46589, 46591, 46601, 46619, 476 | 46633, 46639, 46643, 46649, 46663, 46679, 46681, 46687, 46691, 46703, 477 | 46723, 46727, 46747, 46751, 46757, 46769, 46771, 46807, 46811, 46817, 478 | 46819, 46829, 46831, 46853, 46861, 46867, 46877, 46889, 46901, 46919, 479 | 46933, 46957, 46993, 46997, 47017, 47041, 47051, 47057, 47059, 47087, 480 | 47093, 47111, 47119, 47123, 47129, 47137, 47143, 47147, 47149, 47161, 481 | 47189, 47207, 47221, 47237, 47251, 47269, 47279, 47287, 47293, 47297, 482 | 47303, 47309, 47317, 47339, 47351, 47353, 47363, 47381, 47387, 47389, 483 | 47407, 47417, 47419, 47431, 47441, 47459, 47491, 47497, 47501, 47507, 484 | 47513, 47521, 47527, 47533, 47543, 47563, 47569, 47581, 47591, 47599, 485 | 47609, 47623, 47629, 47639, 47653, 47657, 47659, 47681, 47699, 47701, 486 | 47711, 47713, 47717, 47737, 47741, 47743, 47777, 47779, 47791, 47797, 487 | 47807, 47809, 47819, 47837, 47843, 47857, 47869, 47881, 47903, 47911, 488 | 47917, 47933, 47939, 47947, 47951, 47963, 47969, 47977, 47981, 48017, 489 | 48023, 48029, 48049, 48073, 48079, 48091, 48109, 48119, 48121, 48131, 490 | 48157, 48163, 48179, 48187, 48193, 48197, 48221, 48239, 48247, 48259, 491 | 48271, 48281, 48299, 48311, 48313, 48337, 48341, 48353, 48371, 48383, 492 | 48397, 48407, 48409, 48413, 48437, 48449, 48463, 48473, 48479, 48481, 493 | 48487, 48491, 48497, 48523, 48527, 48533, 48539, 48541, 48563, 48571, 494 | 48589, 48593, 48611, 48619, 48623, 48647, 48649, 48661, 48673, 48677, 495 | 48679, 48731, 48733, 48751, 48757, 48761, 48767, 48779, 48781, 48787, 496 | 48799, 48809, 48817, 48821, 48823, 48847, 48857, 48859, 48869, 48871, 497 | 48883, 48889, 48907, 48947, 48953, 48973, 48989, 48991, 49003, 49009, 498 | 49019, 49031, 49033, 49037, 49043, 49057, 49069, 49081, 49103, 49109, 499 | 49117, 49121, 49123, 49139, 49157, 49169, 49171, 49177, 49193, 49199, 500 | 49201, 49207, 49211, 49223, 49253, 49261, 49277, 49279, 49297, 49307, 501 | 49331, 49333, 49339, 49363, 49367, 49369, 49391, 49393, 49409, 49411, 502 | 49417, 49429, 49433, 49451, 49459, 49463, 49477, 49481, 49499, 49523, 503 | 49529, 49531, 49537, 49547, 49549, 49559, 49597, 49603, 49613, 49627, 504 | 49633, 49639, 49663, 49667, 49669, 49681, 49697, 49711, 49727, 49739, 505 | 49741, 49747, 49757, 49783, 49787, 49789, 49801, 49807, 49811, 49823, 506 | 49831, 49843, 49853, 49871, 49877, 49891, 49919, 49921, 49927, 49937, 507 | 49939, 49943, 49957, 49991, 49993, 49999, 50021, 50023, 50033, 50047, 508 | 50051, 50053, 50069, 50077, 50087, 50093, 50101, 50111, 50119, 50123, 509 | 50129, 50131, 50147, 50153, 50159, 50177, 50207, 50221, 50227, 50231, 510 | 50261, 50263, 50273, 50287, 50291, 50311, 50321, 50329, 50333, 50341, 511 | 50359, 50363, 50377, 50383, 50387, 50411, 50417, 50423, 50441, 50459, 512 | 50461, 50497, 50503, 50513, 50527, 50539, 50543, 50549, 50551, 50581, 513 | 50587, 50591, 50593, 50599, 50627, 50647, 50651, 50671, 50683, 50707, 514 | 50723, 50741, 50753, 50767, 50773, 50777, 50789, 50821, 50833, 50839, 515 | 50849, 50857, 50867, 50873, 50891, 50893, 50909, 50923, 50929, 50951, 516 | 50957, 50969, 50971, 50989, 50993, 51001, 51031, 51043, 51047, 51059, 517 | 51061, 51071, 51109, 51131, 51133, 51137, 51151, 51157, 51169, 51193, 518 | 51197, 51199, 51203, 51217, 51229, 51239, 51241, 51257, 51263, 51283, 519 | 51287, 51307, 51329, 51341, 51343, 51347, 51349, 51361, 51383, 51407, 520 | 51413, 51419, 51421, 51427, 51431, 51437, 51439, 51449, 51461, 51473, 521 | 51479, 51481, 51487, 51503, 51511, 51517, 51521, 51539, 51551, 51563, 522 | 51577, 51581, 51593, 51599, 51607, 51613, 51631, 51637, 51647, 51659, 523 | 51673, 51679, 51683, 51691, 51713, 51719, 51721, 51749, 51767, 51769, 524 | 51787, 51797, 51803, 51817, 51827, 51829, 51839, 51853, 51859, 51869, 525 | 51871, 51893, 51899, 51907, 51913, 51929, 51941, 51949, 51971, 51973, 526 | 51977, 51991, 52009, 52021, 52027, 52051, 52057, 52067, 52069, 52081, 527 | 52103, 52121, 52127, 52147, 52153, 52163, 52177, 52181, 52183, 52189, 528 | 52201, 52223, 52237, 52249, 52253, 52259, 52267, 52289, 52291, 52301, 529 | 52313, 52321, 52361, 52363, 52369, 52379, 52387, 52391, 52433, 52453, 530 | 52457, 52489, 52501, 52511, 52517, 52529, 52541, 52543, 52553, 52561, 531 | 52567, 52571, 52579, 52583, 52609, 52627, 52631, 52639, 52667, 52673, 532 | 52691, 52697, 52709, 52711, 52721, 52727, 52733, 52747, 52757, 52769, 533 | 52783, 52807, 52813, 52817, 52837, 52859, 52861, 52879, 52883, 52889, 534 | 52901, 52903, 52919, 52937, 52951, 52957, 52963, 52967, 52973, 52981, 535 | 52999, 53003, 53017, 53047, 53051, 53069, 53077, 53087, 53089, 53093, 536 | 53101, 53113, 53117, 53129, 53147, 53149, 53161, 53171, 53173, 53189, 537 | 53197, 53201, 53231, 53233, 53239, 53267, 53269, 53279, 53281, 53299, 538 | 53309, 53323, 53327, 53353, 53359, 53377, 53381, 53401, 53407, 53411, 539 | 53419, 53437, 53441, 53453, 53479, 53503, 53507, 53527, 53549, 53551, 540 | 53569, 53591, 53593, 53597, 53609, 53611, 53617, 53623, 53629, 53633, 541 | 53639, 53653, 53657, 53681, 53693, 53699, 53717, 53719, 53731, 53759, 542 | 53773, 53777, 53783, 53791, 53813, 53819, 53831, 53849, 53857, 53861, 543 | 53881, 53887, 53891, 53897, 53899, 53917, 53923, 53927, 53939, 53951, 544 | 53959, 53987, 53993, 54001, 54011, 54013, 54037, 54049, 54059, 54083, 545 | 54091, 54101, 54121, 54133, 54139, 54151, 54163, 54167, 54181, 54193, 546 | 54217, 54251, 54269, 54277, 54287, 54293, 54311, 54319, 54323, 54331, 547 | 54347, 54361, 54367, 54371, 54377, 54401, 54403, 54409, 54413, 54419, 548 | 54421, 54437, 54443, 54449, 54469, 54493, 54497, 54499, 54503, 54517, 549 | 54521, 54539, 54541, 54547, 54559, 54563, 54577, 54581, 54583, 54601, 550 | 54617, 54623, 54629, 54631, 54647, 54667, 54673, 54679, 54709, 54713, 551 | 54721, 54727, 54751, 54767, 54773, 54779, 54787, 54799, 54829, 54833, 552 | 54851, 54869, 54877, 54881, 54907, 54917, 54919, 54941, 54949, 54959, 553 | 54973, 54979, 54983, 55001, 55009, 55021, 55049, 55051, 55057, 55061, 554 | 55073, 55079, 55103, 55109, 55117, 55127, 55147, 55163, 55171, 55201, 555 | 55207, 55213, 55217, 55219, 55229, 55243, 55249, 55259, 55291, 55313, 556 | 55331, 55333, 55337, 55339, 55343, 55351, 55373, 55381, 55399, 55411, 557 | 55439, 55441, 55457, 55469, 55487, 55501, 55511, 55529, 55541, 55547, 558 | 55579, 55589, 55603, 55609, 55619, 55621, 55631, 55633, 55639, 55661, 559 | 55663, 55667, 55673, 55681, 55691, 55697, 55711, 55717, 55721, 55733, 560 | 55763, 55787, 55793, 55799, 55807, 55813, 55817, 55819, 55823, 55829, 561 | 55837, 55843, 55849, 55871, 55889, 55897, 55901, 55903, 55921, 55927, 562 | 55931, 55933, 55949, 55967, 55987, 55997, 56003, 56009, 56039, 56041, 563 | 56053, 56081, 56087, 56093, 56099, 56101, 56113, 56123, 56131, 56149, 564 | 56167, 56171, 56179, 56197, 56207, 56209, 56237, 56239, 56249, 56263, 565 | 56267, 56269, 56299, 56311, 56333, 56359, 56369, 56377, 56383, 56393, 566 | 56401, 56417, 56431, 56437, 56443, 56453, 56467, 56473, 56477, 56479, 567 | 56489, 56501, 56503, 56509, 56519, 56527, 56531, 56533, 56543, 56569, 568 | 56591, 56597, 56599, 56611, 56629, 56633, 56659, 56663, 56671, 56681, 569 | 56687, 56701, 56711, 56713, 56731, 56737, 56747, 56767, 56773, 56779, 570 | 56783, 56807, 56809, 56813, 56821, 56827, 56843, 56857, 56873, 56891, 571 | 56893, 56897, 56909, 56911, 56921, 56923, 56929, 56941, 56951, 56957, 572 | 56963, 56983, 56989, 56993, 56999, 57037, 57041, 57047, 57059, 57073, 573 | 57077, 57089, 57097, 57107, 57119, 57131, 57139, 57143, 57149, 57163, 574 | 57173, 57179, 57191, 57193, 57203, 57221, 57223, 57241, 57251, 57259, 575 | 57269, 57271, 57283, 57287, 57301, 57329, 57331, 57347, 57349, 57367, 576 | 57373, 57383, 57389, 57397, 57413, 57427, 57457, 57467, 57487, 57493, 577 | 57503, 57527, 57529, 57557, 57559, 57571, 57587, 57593, 57601, 57637, 578 | 57641, 57649, 57653, 57667, 57679, 57689, 57697, 57709, 57713, 57719, 579 | 57727, 57731, 57737, 57751, 57773, 57781, 57787, 57791, 57793, 57803, 580 | 57809, 57829, 57839, 57847, 57853, 57859, 57881, 57899, 57901, 57917, 581 | 57923, 57943, 57947, 57973, 57977, 57991, 58013, 58027, 58031, 58043, 582 | 58049, 58057, 58061, 58067, 58073, 58099, 58109, 58111, 58129, 58147, 583 | 58151, 58153, 58169, 58171, 58189, 58193, 58199, 58207, 58211, 58217, 584 | 58229, 58231, 58237, 58243, 58271, 58309, 58313, 58321, 58337, 58363, 585 | 58367, 58369, 58379, 58391, 58393, 58403, 58411, 58417, 58427, 58439, 586 | 58441, 58451, 58453, 58477, 58481, 58511, 58537, 58543, 58549, 58567, 587 | 58573, 58579, 58601, 58603, 58613, 58631, 58657, 58661, 58679, 58687, 588 | 58693, 58699, 58711, 58727, 58733, 58741, 58757, 58763, 58771, 58787, 589 | 58789, 58831, 58889, 58897, 58901, 58907, 58909, 58913, 58921, 58937, 590 | 58943, 58963, 58967, 58979, 58991, 58997, 59009, 59011, 59021, 59023, 591 | 59029, 59051, 59053, 59063, 59069, 59077, 59083, 59093, 59107, 59113, 592 | 59119, 59123, 59141, 59149, 59159, 59167, 59183, 59197, 59207, 59209, 593 | 59219, 59221, 59233, 59239, 59243, 59263, 59273, 59281, 59333, 59341, 594 | 59351, 59357, 59359, 59369, 59377, 59387, 59393, 59399, 59407, 59417, 595 | 59419, 59441, 59443, 59447, 59453, 59467, 59471, 59473, 59497, 59509, 596 | 59513, 59539, 59557, 59561, 59567, 59581, 59611, 59617, 59621, 59627, 597 | 59629, 59651, 59659, 59663, 59669, 59671, 59693, 59699, 59707, 59723, 598 | 59729, 59743, 59747, 59753, 59771, 59779, 59791, 59797, 59809, 59833, 599 | 59863, 59879, 59887, 59921, 59929, 59951, 59957, 59971, 59981, 59999, 600 | 60013, 60017, 60029, 60037, 60041, 60077, 60083, 60089, 60091, 60101, 601 | 60103, 60107, 60127, 60133, 60139, 60149, 60161, 60167, 60169, 60209, 602 | 60217, 60223, 60251, 60257, 60259, 60271, 60289, 60293, 60317, 60331, 603 | 60337, 60343, 60353, 60373, 60383, 60397, 60413, 60427, 60443, 60449, 604 | 60457, 60493, 60497, 60509, 60521, 60527, 60539, 60589, 60601, 60607, 605 | 60611, 60617, 60623, 60631, 60637, 60647, 60649, 60659, 60661, 60679, 606 | 60689, 60703, 60719, 60727, 60733, 60737, 60757, 60761, 60763, 60773, 607 | 60779, 60793, 60811, 60821, 60859, 60869, 60887, 60889, 60899, 60901, 608 | 60913, 60917, 60919, 60923, 60937, 60943, 60953, 60961, 61001, 61007, 609 | 61027, 61031, 61043, 61051, 61057, 61091, 61099, 61121, 61129, 61141, 610 | 61151, 61153, 61169, 61211, 61223, 61231, 61253, 61261, 61283, 61291, 611 | 61297, 61331, 61333, 61339, 61343, 61357, 61363, 61379, 61381, 61403, 612 | 61409, 61417, 61441, 61463, 61469, 61471, 61483, 61487, 61493, 61507, 613 | 61511, 61519, 61543, 61547, 61553, 61559, 61561, 61583, 61603, 61609, 614 | 61613, 61627, 61631, 61637, 61643, 61651, 61657, 61667, 61673, 61681, 615 | 61687, 61703, 61717, 61723, 61729, 61751, 61757, 61781, 61813, 61819, 616 | 61837, 61843, 61861, 61871, 61879, 61909, 61927, 61933, 61949, 61961, 617 | 61967, 61979, 61981, 61987, 61991, 62003, 62011, 62017, 62039, 62047, 618 | 62053, 62057, 62071, 62081, 62099, 62119, 62129, 62131, 62137, 62141, 619 | 62143, 62171, 62189, 62191, 62201, 62207, 62213, 62219, 62233, 62273, 620 | 62297, 62299, 62303, 62311, 62323, 62327, 62347, 62351, 62383, 62401, 621 | 62417, 62423, 62459, 62467, 62473, 62477, 62483, 62497, 62501, 62507, 622 | 62533, 62539, 62549, 62563, 62581, 62591, 62597, 62603, 62617, 62627, 623 | 62633, 62639, 62653, 62659, 62683, 62687, 62701, 62723, 62731, 62743, 624 | 62753, 62761, 62773, 62791, 62801, 62819, 62827, 62851, 62861, 62869, 625 | 62873, 62897, 62903, 62921, 62927, 62929, 62939, 62969, 62971, 62981, 626 | 62983, 62987, 62989, 63029, 63031, 63059, 63067, 63073, 63079, 63097, 627 | 63103, 63113, 63127, 63131, 63149, 63179, 63197, 63199, 63211, 63241, 628 | 63247, 63277, 63281, 63299, 63311, 63313, 63317, 63331, 63337, 63347, 629 | 63353, 63361, 63367, 63377, 63389, 63391, 63397, 63409, 63419, 63421, 630 | 63439, 63443, 63463, 63467, 63473, 63487, 63493, 63499, 63521, 63527, 631 | 63533, 63541, 63559, 63577, 63587, 63589, 63599, 63601, 63607, 63611, 632 | 63617, 63629, 63647, 63649, 63659, 63667, 63671, 63689, 63691, 63697, 633 | 63703, 63709, 63719, 63727, 63737, 63743, 63761, 63773, 63781, 63793, 634 | 63799, 63803, 63809, 63823, 63839, 63841, 63853, 63857, 63863, 63901, 635 | 63907, 63913, 63929, 63949, 63977, 63997, 64007, 64013, 64019, 64033, 636 | 64037, 64063, 64067, 64081, 64091, 64109, 64123, 64151, 64153, 64157, 637 | 64171, 64187, 64189, 64217, 64223, 64231, 64237, 64271, 64279, 64283, 638 | 64301, 64303, 64319, 64327, 64333, 64373, 64381, 64399, 64403, 64433, 639 | 64439, 64451, 64453, 64483, 64489, 64499, 64513, 64553, 64567, 64577, 640 | 64579, 64591, 64601, 64609, 64613, 64621, 64627, 64633, 64661, 64663, 641 | 64667, 64679, 64693, 64709, 64717, 64747, 64763, 64781, 64783, 64793, 642 | 64811, 64817, 64849, 64853, 64871, 64877, 64879, 64891, 64901, 64919, 643 | 64921, 64927, 64937, 64951, 64969, 64997, 65003, 65011, 65027, 65029, 644 | 65033, 65053, 65063, 65071, 65089, 65099, 65101, 65111, 65119, 65123, 645 | 65129, 65141, 65147, 65167, 65171, 65173, 65179, 65183, 65203, 65213, 646 | 65239, 65257, 65267, 65269, 65287, 65293, 65309, 65323, 65327, 65353, 647 | 65357, 65371, 65381, 65393, 65407, 65413, 65419, 65423, 65437, 65447, 648 | 65449, 65479, 65497, 65519, 65521, 65537 }; 649 | 650 | class BigInt 651 | { 652 | public: 653 | int dataLength; 654 | 655 | BigInt(void); 656 | BigInt(uint64 value); 657 | BigInt(const BigInt &bi); 658 | BigInt(const uint inData[], int length); 659 | BigInt(const uint inData[], int length, bool direct); 660 | BigInt(const ubyte inData[], int length); 661 | 662 | ~BigInt(); 663 | 664 | BigInt abs(); 665 | BigInt modPow(BigInt exp, BigInt n); 666 | 667 | BigInt barrettReduction(BigInt x, BigInt n, BigInt constant); 668 | 669 | BigInt gcd(const BigInt &bi); 670 | void genRandomBits(int bits, Random &rnd); 671 | int bitCount(); 672 | bool fermatLittleTest(int confidence, Random &rnd); 673 | bool rabinMillerTest(int confidence, Random &rnd); 674 | bool solovayStrassenTest(int confidence, Random &rnd); 675 | bool lucasStrongTest(); 676 | bool isProbablePrime(int confidence, Random &rnd); 677 | bool isProbablePrime(); 678 | int intValue(); 679 | uint64 longValue(); 680 | BigInt genCoPrime(int bits, Random &rnd); 681 | BigInt modInverse(BigInt modulus); 682 | void setBit(uint bitNum); 683 | void unsetBit(uint bitNum); 684 | BigInt sqrt(); 685 | 686 | void getBytes(ubyte result[]); 687 | 688 | int getBytesRemovedZero(ubyte result[], int orgLength); 689 | 690 | friend BigInt operator +(const BigInt &bi1, const BigInt &bi2); 691 | friend BigInt operator ++(BigInt &bi); 692 | friend BigInt operator -(const BigInt &bi1, const BigInt &bi2); 693 | friend BigInt operator --(BigInt &bi); 694 | friend BigInt operator -=(BigInt &bi1, const BigInt &bi2); 695 | friend BigInt operator *(BigInt bi1, BigInt bi2); 696 | friend BigInt operator -(const BigInt& bi1); 697 | 698 | friend BigInt operator <<(const BigInt &bi, int offset); 699 | friend BigInt operator >>(const BigInt &bi, int offset); 700 | friend BigInt operator ~(const BigInt &bi1); 701 | 702 | friend bool operator ==(const BigInt &bi1, const BigInt &bi2); 703 | friend bool operator !=(const BigInt &bi1, const BigInt &bi2); 704 | friend bool operator >(const BigInt &bi1, const BigInt &bi2); 705 | friend bool operator <(const BigInt &bi1, const BigInt &bi2); 706 | friend bool operator >=(const BigInt &bi1, const BigInt &bi2); 707 | friend bool operator <=(const BigInt &bi1, const BigInt &bi2); 708 | 709 | static void multiByteDivide(BigInt bi1, BigInt bi2, BigInt& outQuotient, BigInt& outRemainder); 710 | static void singleByteDivide(BigInt bi1, BigInt bi2, BigInt& outQuotient, BigInt& outRemainder); 711 | 712 | friend BigInt operator /(BigInt bi1, BigInt bi2); 713 | friend BigInt operator %(BigInt bi1, BigInt bi2); 714 | friend BigInt operator &(const BigInt& bi1, const BigInt& bi2); 715 | friend BigInt operator |(const BigInt& bi1, const BigInt& bi2); 716 | friend BigInt operator ^(const BigInt& bi1, const BigInt& bi2); 717 | 718 | int jacobi(BigInt a, BigInt b); 719 | BigInt genPseudoPrime(int bits, int confidence, Random &rnd); 720 | BigInt* lucasSequence(BigInt P, BigInt Q, BigInt k, BigInt n); 721 | BigInt* lucasSequenceHelper(BigInt P, BigInt Q, BigInt k, BigInt n, BigInt constant, int s); 722 | 723 | int64 abs(int64 value); 724 | 725 | private: 726 | 727 | uint data[maxLength]; 728 | void init(void); 729 | static int shiftLeft(uint buffer[], int bufLen, int shiftVal); 730 | static int shiftRight(uint buffer[], int bufLen, int shiftVal); 731 | bool lucasStrongTestHelper(BigInt thisVal); 732 | }; 733 | 734 | } 735 | } 736 | -------------------------------------------------------------------------------- /src/utils/random.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "types.h" 7 | 8 | using namespace std; 9 | 10 | namespace crypto 11 | { 12 | namespace utils 13 | { 14 | 15 | class Random 16 | { 17 | private: 18 | random_device rd; 19 | 20 | public: 21 | 22 | uint next(uint min = 0, uint max = (numeric_limits::max)()) 23 | { 24 | mt19937 gen(rd()); 25 | std::uniform_int_distribution dis(min, max); 26 | return dis(gen); 27 | } 28 | }; 29 | 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/utils/types.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | typedef unsigned char ubyte; 4 | typedef unsigned short ushort; 5 | typedef unsigned int uint; 6 | typedef long long int64; 7 | typedef unsigned long long uint64; 8 | //typedef unsigned long long ulong; 9 | typedef long double float128; 10 | typedef long double real; 11 | -------------------------------------------------------------------------------- /src/utils/utility.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "types.h" 4 | 5 | namespace crypto 6 | { 7 | namespace utils 8 | { 9 | 10 | enum Endian 11 | { 12 | ENDIAN_LITTLE = 1234, 13 | ENDIAN_BIG = 4321 14 | }; 15 | 16 | class Utility 17 | { 18 | public: 19 | template 20 | static void writeIntToBytes(T value, ubyte* buffer, Endian endianness = ENDIAN_LITTLE) 21 | { 22 | if (endianness == ENDIAN_LITTLE) 23 | { 24 | buffer[0] = (ubyte)(value); 25 | buffer[1] = (ubyte)(value >> 8); 26 | buffer[2] = (ubyte)(value >> 16); 27 | buffer[3] = (ubyte)(value >> 24); 28 | } 29 | else 30 | { 31 | buffer[0] = (ubyte)(value >> 24); 32 | buffer[1] = (ubyte)(value >> 16); 33 | buffer[2] = (ubyte)(value >> 8); 34 | buffer[3] = (ubyte)(value); 35 | } 36 | } 37 | 38 | template 39 | static T readIntFromBytes(ubyte* buffer, Endian endianness = ENDIAN_LITTLE) 40 | { 41 | if (endianness == ENDIAN_LITTLE) 42 | return (T)(buffer[0] | buffer[1] << 8 | buffer[2] << 16 | buffer[3] << 24); 43 | else 44 | return (T)(buffer[0] << 24 | buffer[1] << 16 | buffer[2] << 8 | buffer[3]); 45 | } 46 | 47 | template 48 | static void writeShortToBytes(T value, ubyte* buffer, Endian endianness = ENDIAN_LITTLE) 49 | { 50 | if (endianness == ENDIAN_LITTLE) 51 | { 52 | buffer[0] = (ubyte)(value); 53 | buffer[1] = (ubyte)(value >> 8); 54 | } 55 | else 56 | { 57 | buffer[0] = (ubyte)(value >> 8); 58 | buffer[1] = (ubyte)(value); 59 | } 60 | } 61 | 62 | template 63 | static T readShortFromBytes(ubyte* buffer, Endian endianness = ENDIAN_LITTLE) 64 | { 65 | if (endianness == ENDIAN_LITTLE) 66 | return (T)(buffer[0] | buffer[1] << 8); 67 | else 68 | return (T)(buffer[0] << 8 | buffer[1]); 69 | } 70 | }; 71 | 72 | } 73 | } 74 | --------------------------------------------------------------------------------