metaforce/hecl/extern/blowfish/blowfish.c

129 lines
2.1 KiB
C
Raw Normal View History

2015-05-18 23:37:10 +00:00
#include <stdlib.h>
#include <stdint.h>
#include "blowfish.h"
#define N 16
2015-07-19 20:52:22 +00:00
extern const uint32_t BLOWFISH_P[N + 2];
extern const uint32_t BLOWFISH_S[4][256];
2015-05-18 23:37:10 +00:00
#define P BLOWFISH_P
#define S BLOWFISH_S
2015-05-18 23:37:10 +00:00
2015-07-19 20:52:22 +00:00
static uint32_t F(uint32_t x)
2015-05-18 23:37:10 +00:00
{
2015-07-19 20:52:22 +00:00
uint16_t a;
uint16_t b;
uint16_t c;
uint16_t d;
uint32_t y;
2015-05-18 23:37:10 +00:00
d = x & 0x00FF;
x >>= 8;
c = x & 0x00FF;
x >>= 8;
b = x & 0x00FF;
x >>= 8;
a = x & 0x00FF;
y = S[0][a] + S[1][b];
y = y ^ S[2][c];
y = y + S[3][d];
return y;
}
2015-07-19 20:52:22 +00:00
void Blowfish_encipher(uint32_t *xl, uint32_t *xr)
2015-05-18 23:37:10 +00:00
{
2015-07-19 20:52:22 +00:00
uint32_t Xl;
uint32_t Xr;
uint32_t temp;
2015-05-18 23:37:10 +00:00
short i;
Xl = *xl;
Xr = *xr;
for (i = 0; i < N; ++i) {
Xl = Xl ^ P[i];
Xr = F(Xl) ^ Xr;
temp = Xl;
Xl = Xr;
Xr = temp;
}
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ P[N];
Xl = Xl ^ P[N + 1];
*xl = Xl;
*xr = Xr;
}
2015-07-19 20:52:22 +00:00
void Blowfish_decipher(uint32_t *xl, uint32_t *xr)
2015-05-18 23:37:10 +00:00
{
2015-07-19 20:52:22 +00:00
uint32_t Xl;
uint32_t Xr;
uint32_t temp;
2015-05-18 23:37:10 +00:00
short i;
Xl = *xl;
Xr = *xr;
for (i = N + 1; i > 1; --i) {
Xl = Xl ^ P[i];
Xr = F(Xl) ^ Xr;
/* Exchange Xl and Xr */
temp = Xl;
Xl = Xr;
Xr = temp;
}
/* Exchange Xl and Xr */
temp = Xl;
Xl = Xr;
Xr = temp;
Xr = Xr ^ P[1];
Xl = Xl ^ P[0];
*xl = Xl;
*xr = Xr;
}
2015-07-22 19:14:50 +00:00
int64_t Blowfish_hash(const uint8_t* buf, size_t len)
2015-05-18 23:37:10 +00:00
{
unsigned i,j;
union
{
2015-07-19 20:52:22 +00:00
uint32_t h32[2];
int64_t h64;
2015-07-22 19:14:50 +00:00
} hash = {0,0};
2015-05-18 23:37:10 +00:00
for (i=0 ; i<len/4 ; ++i)
{
2015-07-19 20:52:22 +00:00
uint32_t block = *(uint32_t*)buf;
2015-05-18 23:37:10 +00:00
Blowfish_encipher(&hash.h32[i&1], &block);
buf += 4;
}
unsigned rem = len % 4;
if (rem)
{
union
{
2015-07-19 20:52:22 +00:00
uint32_t b32;
2015-05-18 23:37:10 +00:00
char b[4];
} block = {0};
for (j=0 ; j<rem ; ++j)
2015-07-19 20:52:22 +00:00
block.b[j] = *(char*)buf;
2015-05-18 23:37:10 +00:00
Blowfish_encipher(&hash.h32[i&1], &block.b32);
}
return hash.h64;
}