Sandboxie/SandboxieTools/ImBox/dc/crypto_small/serpent_small.c

531 lines
8.7 KiB
C

/*
*
* Copyright (c) 2010
* ntldr <ntldr@diskcryptor.net> PGP key ID - 0xC48251EB4F8E4E6E
*
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License version 3 as
published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef _M_ARM64
#include <stdlib.h>
#include <string.h>
#define __stosb memset
#define __movsb memmove
#else
#include <intrin.h>
#endif
#include "serpent_small.h"
#define LTf(_b) { \
_b[0] = _rotl(_b[0], 13); \
_b[2] = _rotl(_b[2], 3); \
_b[1] ^= _b[0] ^ _b[2]; \
_b[3] ^= _b[2] ^ (_b[0] << 3); \
_b[1] = _rotl(_b[1], 1); \
_b[3] = _rotl(_b[3], 7); \
_b[0] ^= _b[1] ^ _b[3]; \
_b[2] ^= _b[3] ^ (_b[1] << 7); \
_b[0] = _rotl(_b[0], 5); \
_b[2] = _rotl(_b[2], 22); \
}
#define ITf(_b) { \
_b[2] = _rotr(_b[2], 22); \
_b[0] = _rotr(_b[0], 5); \
_b[2] ^= _b[3] ^ (_b[1] << 7); \
_b[0] ^= _b[1] ^ _b[3]; \
_b[3] = _rotr(_b[3], 7); \
_b[1] = _rotr(_b[1], 1); \
_b[3] ^= _b[2] ^ (_b[0] << 3); \
_b[1] ^= _b[0] ^ _b[2]; \
_b[2] = _rotr(_b[2], 3); \
_b[0] = _rotr(_b[0], 13); \
}
#define PHI 0x9E3779B9
typedef void (*sbox_p)(unsigned long b[4]);
static void sE1(unsigned long b[4])
{
unsigned long t = b[1];
b[3] ^= b[0];
b[1] &= b[3];
t ^= b[2];
b[1] ^= b[0];
b[0] |= b[3];
b[0] ^= t;
t ^= b[3];
b[3] ^= b[2];
b[2] |= b[1];
b[2] ^= t;
t = ~t;
t |= b[1];
b[1] ^= b[3];
b[1] ^= t;
b[3] |= b[0];
b[1] ^= b[3];
t ^= b[3];
b[3] = b[0];
b[0] = b[1];
b[1] = t;
}
static void sE2(unsigned long b[4])
{
unsigned long t;
b[0] = ~b[0];
b[2] = ~b[2];
t = b[0];
b[0] &= b[1];
b[2] ^= b[0];
b[0] |= b[3];
b[3] ^= b[2];
b[1] ^= b[0];
b[0] ^= t;
t |= b[1];
b[1] ^= b[3];
b[2] |= b[0];
b[2] &= t;
b[0] ^= b[1];
b[1] &= b[2];
b[1] ^= b[0];
b[0] &= b[2];
t ^= b[0];
b[0] = b[2];
b[2] = b[3];
b[3] = b[1];
b[1] = t;
}
static void sE3(unsigned long b[4])
{
unsigned long t = b[0];
b[0] &= b[2];
b[0] ^= b[3];
b[2] ^= b[1];
b[2] ^= b[0];
b[3] |= t;
b[3] ^= b[1];
t ^= b[2];
b[1] = b[3];
b[3] |= t;
b[3] ^= b[0];
b[0] &= b[1];
t ^= b[0];
b[1] ^= b[3];
b[1] ^= t;
b[0] = b[2];
b[2] = b[1];
b[1] = b[3];
b[3] = ~t;
}
static void sE4(unsigned long b[4])
{
unsigned long t = b[0];
b[0] |= b[3];
b[3] ^= b[1];
b[1] &= t;
t ^= b[2];
b[2] ^= b[3];
b[3] &= b[0];
t |= b[1];
b[3] ^= t;
b[0] ^= b[1];
t &= b[0];
b[1] ^= b[3];
t ^= b[2];
b[1] |= b[0];
b[1] ^= b[2];
b[0] ^= b[3];
b[2] = b[1];
b[1] |= b[3];
b[0] ^= b[1];
b[1] = b[2];
b[2] = b[3];
b[3] = t;
}
static void sE5(unsigned long b[4])
{
unsigned long t;
b[1] ^= b[3];
b[3] = ~b[3];
b[2] ^= b[3];
b[3] ^= b[0];
t = b[1];
b[1] &= b[3];
b[1] ^= b[2];
t ^= b[3];
b[0] ^= t;
b[2] &= t;
b[2] ^= b[0];
b[0] &= b[1];
b[3] ^= b[0];
t |= b[1];
t ^= b[0];
b[0] |= b[3];
b[0] ^= b[2];
b[2] &= b[3];
b[0] = ~b[0];
t ^= b[2];
b[2] = b[0];
b[0] = b[1];
b[1] = t;
}
static void sE6(unsigned long b[4])
{
unsigned long t;
b[0] ^= b[1];
b[1] ^= b[3];
b[3] = ~b[3];
t = b[1];
b[1] &= b[0];
b[2] ^= b[3];
b[1] ^= b[2];
b[2] |= t;
t ^= b[3];
b[3] &= b[1];
b[3] ^= b[0];
t ^= b[1];
t ^= b[2];
b[2] ^= b[0];
b[0] &= b[3];
b[2] = ~b[2];
b[0] ^= t;
t |= b[3];
t ^= b[2];
b[2] = b[0];
b[0] = b[1];
b[1] = b[3];
b[3] = t;
}
static void sE7(unsigned long b[4])
{
unsigned long t = b[3];
b[2] = ~b[2];
b[3] &= b[0];
b[0] ^= t;
b[3] ^= b[2];
b[2] |= t;
b[1] ^= b[3];
b[2] ^= b[0];
b[0] |= b[1];
b[2] ^= b[1];
t ^= b[0];
b[0] |= b[3];
b[0] ^= b[2];
t ^= b[3];
t ^= b[0];
b[3] = ~b[3];
b[2] &= t;
b[3] ^= b[2];
b[2] = t;
}
static void sE8(unsigned long b[4])
{
unsigned long t = b[1];
b[1] |= b[2];
b[1] ^= b[3];
t ^= b[2];
b[2] ^= b[1];
b[3] |= t;
b[3] &= b[0];
t ^= b[2];
b[3] ^= b[1];
b[1] |= t;
b[1] ^= b[0];
b[0] |= t;
b[0] ^= b[2];
b[1] ^= t;
b[2] ^= b[1];
b[1] &= b[0];
b[1] ^= t;
b[2] = ~b[2];
b[2] |= b[0];
t ^= b[2];
b[2] = b[1];
b[1] = b[3];
b[3] = b[0];
b[0] = t;
}
static void sD1(unsigned long b[4])
{
unsigned long t = b[1];
b[2] = ~b[2];
b[1] |= b[0];
t = ~t;
b[1] ^= b[2];
b[2] |= t;
b[1] ^= b[3];
b[0] ^= t;
b[2] ^= b[0];
b[0] &= b[3];
t ^= b[0];
b[0] |= b[1];
b[0] ^= b[2];
b[3] ^= t;
b[2] ^= b[1];
b[3] ^= b[0];
b[3] ^= b[1];
b[2] &= b[3];
t ^= b[2];
b[2] = b[1];
b[1] = t;
}
static void sD2(unsigned long b[4])
{
unsigned long t = b[1];
b[1] ^= b[3];
b[3] &= b[1];
t ^= b[2];
b[3] ^= b[0];
b[0] |= b[1];
b[2] ^= b[3];
b[0] ^= t;
b[0] |= b[2];
b[1] ^= b[3];
b[0] ^= b[1];
b[1] |= b[3];
b[1] ^= b[0];
t = ~t;
t ^= b[1];
b[1] |= b[0];
b[1] ^= b[0];
b[1] |= t;
b[3] ^= b[1];
b[1] = b[0];
b[0] = t;
t = b[2];
b[2] = b[3];
b[3] = t;
}
static void sD3(unsigned long b[4])
{
unsigned long t;
b[2] ^= b[3];
b[3] ^= b[0];
t = b[3];
b[3] &= b[2];
b[3] ^= b[1];
b[1] |= b[2];
b[1] ^= t;
t &= b[3];
b[2] ^= b[3];
t &= b[0];
t ^= b[2];
b[2] &= b[1];
b[2] |= b[0];
b[3] = ~b[3];
b[2] ^= b[3];
b[0] ^= b[3];
b[0] &= b[1];
b[3] ^= t;
b[3] ^= b[0];
b[0] = b[1];
b[1] = t;
}
static void sD4(unsigned long b[4])
{
unsigned long t = b[2];
b[2] ^= b[1];
b[0] ^= b[2];
t &= b[2];
t ^= b[0];
b[0] &= b[1];
b[1] ^= b[3];
b[3] |= t;
b[2] ^= b[3];
b[0] ^= b[3];
b[1] ^= t;
b[3] &= b[2];
b[3] ^= b[1];
b[1] ^= b[0];
b[1] |= b[2];
b[0] ^= b[3];
b[1] ^= t;
b[0] ^= b[1];
t = b[0];
b[0] = b[2];
b[2] = b[3];
b[3] = t;
}
static void sD5(unsigned long b[4])
{
unsigned long t = b[2];
b[2] &= b[3];
b[2] ^= b[1];
b[1] |= b[3];
b[1] &= b[0];
t ^= b[2];
t ^= b[1];
b[1] &= b[2];
b[0] = ~b[0];
b[3] ^= t;
b[1] ^= b[3];
b[3] &= b[0];
b[3] ^= b[2];
b[0] ^= b[1];
b[2] &= b[0];
b[3] ^= b[0];
b[2] ^= t;
b[2] |= b[3];
b[3] ^= b[0];
b[2] ^= b[1];
b[1] = b[3];
b[3] = t;
}
static void sD6(unsigned long b[4])
{
unsigned long t = b[3];
b[1] = ~b[1];
b[2] ^= b[1];
b[3] |= b[0];
b[3] ^= b[2];
b[2] |= b[1];
b[2] &= b[0];
t ^= b[3];
b[2] ^= t;
t |= b[0];
t ^= b[1];
b[1] &= b[2];
b[1] ^= b[3];
t ^= b[2];
b[3] &= t;
t ^= b[1];
b[3] ^= t;
t = ~t;
b[3] ^= b[0];
b[0] = b[1];
b[1] = t;
t = b[3];
b[3] = b[2];
b[2] = t;
}
static void sD7(unsigned long b[4])
{
unsigned long t = b[2];
b[0] ^= b[2];
b[2] &= b[0];
t ^= b[3];
b[2] = ~b[2];
b[3] ^= b[1];
b[2] ^= b[3];
t |= b[0];
b[0] ^= b[2];
b[3] ^= t;
t ^= b[1];
b[1] &= b[3];
b[1] ^= b[0];
b[0] ^= b[3];
b[0] |= b[2];
b[3] ^= b[1];
t ^= b[0];
b[0] = b[1];
b[1] = b[2];
b[2] = t;
}
static void sD8(unsigned long b[4])
{
unsigned long t = b[2];
b[2] ^= b[0];
b[0] &= b[3];
t |= b[3];
b[2] = ~b[2];
b[3] ^= b[1];
b[1] |= b[0];
b[0] ^= b[2];
b[2] &= t;
b[3] &= t;
b[1] ^= b[2];
b[2] ^= b[0];
b[0] |= b[2];
t ^= b[1];
b[0] ^= b[3];
b[3] ^= t;
t |= b[0];
b[3] ^= b[2];
t ^= b[2];
b[2] = b[1];
b[1] = b[0];
b[0] = b[3];
b[3] = t;
}
static void __declspec(noinline) KXf(unsigned long *keys, unsigned long round, unsigned long b[4])
{
b[0] ^= keys[4*round ];
b[1] ^= keys[4*round+1];
b[2] ^= keys[4*round+2];
b[3] ^= keys[4*round+3];
}
static sbox_p se_tab[] = { sE1, sE2, sE3, sE4, sE5, sE6, sE7, sE8 };
static sbox_p sd_tab[] = { sD1, sD2, sD3, sD4, sD5, sD6, sD7, sD8 };
void serpent256_set_key(const unsigned char *key, serpent256_key *skey)
{
unsigned long W[140], i;
__movsb((unsigned char*)&W, key, SERPENT_KEY_SIZE);
for(i = 8; i != 140; ++i) {
W[i] = _rotl(W[i-8] ^ W[i-5] ^ W[i-3] ^ W[i-1] ^ PHI ^ (i-8), 11);
}
for (i = 8; i <= 136; i += 4) {
se_tab[7 - (((i / 4) + 2) % 8)](&W[i]);
}
__movsb((unsigned char*)&skey->expkey, (unsigned char*)(W+8), (SERPENT_EXPKEY_WORDS * sizeof(unsigned long)));
}
void serpent256_encrypt(const unsigned char *in, unsigned char *out, serpent256_key *key)
{
unsigned long b[4];
int i;
__movsb((unsigned char*)&b, in, SERPENT_BLOCK_SIZE);
for (i = 0; i < 32; i++) {
KXf(key->expkey, i, b); se_tab[i % 8](b);
if (i == 31) KXf(key->expkey, 32, b); else LTf(b);
}
__movsb(out, (const unsigned char*)&b, SERPENT_BLOCK_SIZE);
}
void serpent256_decrypt(const unsigned char *in, unsigned char *out, serpent256_key *key)
{
unsigned long b[4];
int i;
__movsb((unsigned char*)&b, in, SERPENT_BLOCK_SIZE);
for (i = 31; i >= 0; i--) {
if (i == 31) KXf(key->expkey, 32, b); else ITf(b);
sd_tab[i % 8](b); KXf(key->expkey, i, b);
}
__movsb(out, (const unsigned char*)&b, SERPENT_BLOCK_SIZE);
}