home *** CD-ROM | disk | FTP | other *** search
- #include "crypt.h"
- #include "hash.h"
- #include "util.h"
-
- void key_schedule(uint64_t* const k, const uint32_t initial_key, const int n)
- {
- uint8_t* const kbuf = reinterpret_cast<uint8_t*>(k);
-
- uint32_t key = initial_key;
- for (int i = 0; i < n; ++i) {
- const uint8_t x = key & 0xFF;
- key = (x << (n - 8)) | (key >> 8);
- kbuf[i] = x;
- }
-
- memcpy(kbuf + n, kbuf, n);
- memcpy(kbuf + (n << 1), kbuf, (n << 1) & ~0x1);
- memcpy(kbuf + (n << 2), kbuf, (n << 2) & ~0x3);
- }
-
- uint32_t checksum(const void* const data, const size_t size)
- {
- const uint32_t result = ~crc32_0x04c11db7(0, data, size);
- return result;
- }
-
- uint32_t shuffle_bits(const uint32_t data)
- {
- uint32_t x = data;
- uint32_t crc = 0;
- for (int i = 0; i < 4; ++i) {
- crc = (crc << 8) ^ kCRC32_TAB_0x04C11DB7[(rotl(x ^ crc, 10) & 0x3FC) >> 2];
- x <<= 8;
- }
- return ~crc;
- }
-
- uint32_t crypt_block(const uint32_t x, const uint32_t y)
- {
- const uint32_t result = x ^ shuffle_bits(y);
- return result;
- }
-
- uint32_t xor_shift_loop(const uint32_t x, const uint32_t y)
- {
- uint32_t result = x;
- for (int i = 0; i < 32; ++i) {
- const uint32_t upper_bit = result & 0x80000000u;
- result <<= 1;
- if (upper_bit)
- result ^= y;
- }
- return result;
- }
-
- uint32_t inversed_xor_shift_loop(const uint32_t x, const uint32_t y)
- {
- const uint32_t result = ~xor_shift_loop(x, y);
- return result;
- }
-
- bool block_crypt(const void* const src, void* const dst, const size_t size)
- {
- const uint32_t* src_block = static_cast<const uint32_t*>(src);
- const uint32_t* const src_block_end = src_block + size / sizeof(uint32_t);
- if (src_block + 1 >= src_block_end)
- return false;
- uint32_t* dst_block = static_cast<uint32_t*>(dst);
-
- uint32_t prev = host_to_big(*src_block++);
- *dst_block++ = big_to_host(prev);
-
- while (src_block < src_block_end) {
- const uint32_t cur = host_to_big(*src_block++);
- *dst_block++ = big_to_host(crypt_block(cur, prev));
- prev = cur;
- }
-
- return true;
- }
-
- void data_keygen(const char* seed, const uint32_t* const key, const uint32_t x, uint32_t* const out_key)
- {
- uint32_t c0 = checksum(seed, strlen(seed)) ^ x;
- uint32_t c1 = inversed_xor_shift_loop(c0, key[0]);
- uint32_t c2 = inversed_xor_shift_loop(c1, key[1]);
- uint32_t c3 = inversed_xor_shift_loop(c2, key[2]);
- uint32_t c4 = inversed_xor_shift_loop(c3, key[3]);
-
- c1 &= 0x1FFFFu;
- c2 &= 0x7FFFFu;
- c3 &= 0x7FFFFFu;
- c4 &= 0x1FFFFFFFu;
-
- out_key[0] = c1;
- out_key[1] = c2;
- out_key[2] = c3;
- out_key[3] = c4;
- }
-
- void data_crypt(const uint32_t* const key, const void* const src, void* const dst, const size_t size)
- {
- uint32_t c1 = key[0];
- uint32_t c2 = key[1];
- uint32_t c3 = key[2];
- uint32_t c4 = key[3];
-
- const uint8_t* src_byte = static_cast<const uint8_t*>(src);
- const uint8_t* const src_byte_end = src_byte + size;
- uint8_t* dst_byte = static_cast<uint8_t*>(dst);
-
- while (src_byte < src_byte_end) {
- *dst_byte++ = (((c1 ^ c2) ^ *src_byte++) ^ (c3 ^ c4)) & 0xFF;
- c1 = ((rotl(c1, 9) & 0x1FE00u) | (c1 >> 8));
- c2 = ((rotl(c2, 11) & 0x7F800u) | (c2 >> 8));
- c3 = ((rotl(c3, 15) & 0x7F8000u) | (c3 >> 8));
- c4 = ((rotl(c4, 21) & 0x1FE00000u) | (c4 >> 8));
- }
- }
-