573 lines
18 KiB
C++
573 lines
18 KiB
C++
// diamond.cpp - modified by Wei Dai from:
|
|
|
|
/* diamond2.c - Encryption designed to exceed DES in security.
|
|
This file and the Diamond2 and Diamond2 Lite Block Ciphers
|
|
described herein are hereby dedicated to the Public Domain by the
|
|
author and inventor, Michael Paul Johnson. Feel free to use these
|
|
for any purpose that is legally and morally right. The names
|
|
"Diamond2 Block Cipher" and "Diamond2 Lite Block Cipher" should only
|
|
be used to describe the algorithms described in this file, to avoid
|
|
confusion.
|
|
|
|
Disclaimers: the following comes with no warranty, expressed or
|
|
implied. You, the user, must determine the suitability of this
|
|
information to your own uses. You must also find out what legal
|
|
requirements exist with respect to this data and programs using
|
|
it, and comply with whatever valid requirements exist.
|
|
*/
|
|
|
|
#include "pch.h"
|
|
#include "diamond.h"
|
|
#include "crc.h"
|
|
|
|
NAMESPACE_BEGIN(CryptoPP)
|
|
|
|
class Diamond2SboxMaker
|
|
{
|
|
public:
|
|
Diamond2SboxMaker(const byte *external_key, unsigned int key_size,
|
|
unsigned int rounds, bool lite);
|
|
|
|
void MakeSbox(byte *sbox, CipherDir direction);
|
|
|
|
private:
|
|
unsigned int keyrand(unsigned int max_value, const byte *prevSbox);
|
|
void makeonebox(byte *s, unsigned int i, unsigned int j);
|
|
|
|
CRC32 crc;
|
|
const byte *const key;
|
|
const unsigned keysize;
|
|
unsigned keyindex;
|
|
const unsigned numrounds;
|
|
const unsigned roundsize; // Number of bytes in one round of substitution boxes
|
|
const unsigned blocksize;
|
|
};
|
|
|
|
Diamond2SboxMaker::Diamond2SboxMaker(const byte *external_key, unsigned int key_size, unsigned int rounds,
|
|
bool lite)
|
|
: key(external_key),
|
|
keysize(key_size),
|
|
keyindex(0),
|
|
numrounds(rounds),
|
|
roundsize(lite ? 2048 : 4096),
|
|
blocksize(lite ? 8 : 16)
|
|
{
|
|
assert((rounds * blocksize) <= 255);
|
|
}
|
|
|
|
// Returns uniformly distributed pseudorandom value based on key[], sized keysize
|
|
inline unsigned int Diamond2SboxMaker::keyrand(unsigned int max_value, const byte *prevSbox)
|
|
{
|
|
assert(max_value <= 255);
|
|
|
|
if (!max_value) return 0;
|
|
|
|
unsigned int mask, prandvalue, i;
|
|
|
|
// Create a mask to get the minimum number of
|
|
// bits to cover the range 0 to max_value.
|
|
for (i=max_value, mask=0; i > 0; i = i >> 1)
|
|
mask = (mask << 1) | 1;
|
|
|
|
assert(i==0);
|
|
do
|
|
{
|
|
if (prevSbox)
|
|
crc.UpdateByte(prevSbox[key[keyindex++]]);
|
|
else
|
|
crc.UpdateByte(key[keyindex++]);
|
|
|
|
if (keyindex >= keysize)
|
|
{
|
|
keyindex = 0; /* Recycle thru the key */
|
|
crc.UpdateByte(byte(keysize));
|
|
crc.UpdateByte(byte(keysize >> 8));
|
|
}
|
|
prandvalue = crc.GetCrcByte(0) & mask;
|
|
if ((++i>97) && (prandvalue > max_value)) /* Don't loop forever. */
|
|
prandvalue -= max_value; /* Introduce negligible bias. */
|
|
}
|
|
while (prandvalue > max_value); /* Discard out of range values. */
|
|
return prandvalue;
|
|
}
|
|
|
|
void Diamond2SboxMaker::makeonebox(byte *s, unsigned int i, unsigned int j)
|
|
{
|
|
bool filled[256];
|
|
byte *sbox = s + (roundsize*i) + (256*j);
|
|
byte *prevSbox = (i||j) ? sbox-256 : 0;
|
|
|
|
unsigned m;
|
|
for (m = 0; m < 256; m++) /* The filled array is used to make sure that */
|
|
filled[m] = false; /* each byte of the array is filled only once. */
|
|
for (int n = 255; n >= 0 ; n--) /* n counts the number of bytes left to fill */
|
|
{
|
|
// pos is the position among the UNFILLED
|
|
// components of the s array that the number n should be placed.
|
|
unsigned pos = keyrand(n, prevSbox);
|
|
unsigned p=0;
|
|
while (filled[p]) p++;
|
|
for (m=0; m<pos; m++)
|
|
{
|
|
p++;
|
|
while (filled[p]) p++;
|
|
}
|
|
assert(p<256);
|
|
sbox[p] = n;
|
|
filled[p] = true;
|
|
}
|
|
}
|
|
|
|
void Diamond2SboxMaker::MakeSbox(byte *s, CipherDir direction)
|
|
{
|
|
unsigned int i, j, k;
|
|
|
|
for (i = 0; i < numrounds; i++)
|
|
for (j = 0; j < blocksize; j++)
|
|
makeonebox(s, i, j);
|
|
|
|
if (direction==DECRYPTION)
|
|
{
|
|
SecByteBlock si(numrounds * roundsize);
|
|
for (i = 0; i < numrounds; i++)
|
|
for (j = 0; j < blocksize; j++)
|
|
for (k = 0; k < 256; k++)
|
|
*(si + (roundsize * i) + (256 * j) + *(s + (roundsize * i) + (256 * j) + k)) = k;
|
|
memcpy(s, si, numrounds * roundsize);
|
|
}
|
|
}
|
|
|
|
void Diamond2::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds)
|
|
{
|
|
AssertValidKeyLength(length);
|
|
|
|
numrounds = rounds;
|
|
s.New(numrounds * ROUNDSIZE);
|
|
|
|
Diamond2SboxMaker m(userKey, length, rounds, false);
|
|
m.MakeSbox(s, direction);
|
|
}
|
|
|
|
inline void Diamond2::Base::substitute(int round, byte *x, const byte *y) const
|
|
{
|
|
const byte *sbox = s + (ROUNDSIZE*round);
|
|
x[0] = sbox[0*256+y[0]];
|
|
x[1] = sbox[1*256+y[1]];
|
|
x[2] = sbox[2*256+y[2]];
|
|
x[3] = sbox[3*256+y[3]];
|
|
x[4] = sbox[4*256+y[4]];
|
|
x[5] = sbox[5*256+y[5]];
|
|
x[6] = sbox[6*256+y[6]];
|
|
x[7] = sbox[7*256+y[7]];
|
|
x[8] = sbox[8*256+y[8]];
|
|
x[9] = sbox[9*256+y[9]];
|
|
x[10] = sbox[10*256+y[10]];
|
|
x[11] = sbox[11*256+y[11]];
|
|
x[12] = sbox[12*256+y[12]];
|
|
x[13] = sbox[13*256+y[13]];
|
|
x[14] = sbox[14*256+y[14]];
|
|
x[15] = sbox[15*256+y[15]];
|
|
}
|
|
|
|
#ifdef DIAMOND_USE_PERMTABLE
|
|
|
|
inline void Diamond2::Base::permute(byte *a)
|
|
{
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
word32 temp0 = (a[0] | (word32(a[10])<<24)) & 0x80000001;
|
|
#else
|
|
word32 temp0 = ((word32(a[0])<<24) | a[10]) & 0x01000080;
|
|
#endif
|
|
temp0 |= permtable[0][a[1]] |
|
|
permtable[1][a[2]] | permtable[2][a[3]] |
|
|
permtable[3][a[4]] | permtable[4][a[5]] |
|
|
permtable[5][a[6]] | permtable[6][a[7]] |
|
|
permtable[7][a[8]] | permtable[8][a[9]];
|
|
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
word32 temp1 = (a[4] | (word32(a[14])<<24)) & 0x80000001;
|
|
#else
|
|
word32 temp1 = ((word32(a[4])<<24) | a[14]) & 0x01000080;
|
|
#endif
|
|
temp1 |= permtable[0][a[5]] |
|
|
permtable[1][a[6]] | permtable[2][a[7]] |
|
|
permtable[3][a[8]] | permtable[4][a[9]] |
|
|
permtable[5][a[10]] | permtable[6][a[11]] |
|
|
permtable[7][a[12]] | permtable[8][a[13]];
|
|
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
word32 temp2 = (a[8] | (word32(a[2])<<24)) & 0x80000001;
|
|
#else
|
|
word32 temp2 = ((word32(a[8])<<24) | a[2]) & 0x01000080;
|
|
#endif
|
|
temp2 |= permtable[0][a[9]] |
|
|
permtable[1][a[10]] | permtable[2][a[11]] |
|
|
permtable[3][a[12]] | permtable[4][a[13]] |
|
|
permtable[5][a[14]] | permtable[6][a[15]] |
|
|
permtable[7][a[0]] | permtable[8][a[1]];
|
|
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
word32 temp3 = (a[12] | (word32(a[6])<<24)) & 0x80000001;
|
|
#else
|
|
word32 temp3 = ((word32(a[12])<<24) | a[6]) & 0x01000080;
|
|
#endif
|
|
((word32 *)a)[3] = temp3 | permtable[0][a[13]] |
|
|
permtable[1][a[14]] | permtable[2][a[15]] |
|
|
permtable[3][a[0]] | permtable[4][a[1]] |
|
|
permtable[5][a[2]] | permtable[6][a[3]] |
|
|
permtable[7][a[4]] | permtable[8][a[5]];
|
|
|
|
((word32 *)a)[0] = temp0;
|
|
((word32 *)a)[1] = temp1;
|
|
((word32 *)a)[2] = temp2;
|
|
}
|
|
|
|
inline void Diamond2::Base::ipermute(byte *a)
|
|
{
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
word32 temp0 = (a[9] | (word32(a[3])<<24)) & 0x01000080;
|
|
#else
|
|
word32 temp0 = ((word32(a[9])<<24) | a[3]) & 0x80000001;
|
|
#endif
|
|
temp0 |= ipermtable[0][a[2]] |
|
|
ipermtable[1][a[1]] | ipermtable[2][a[0]] |
|
|
ipermtable[3][a[15]] | ipermtable[4][a[14]] |
|
|
ipermtable[5][a[13]] | ipermtable[6][a[12]] |
|
|
ipermtable[7][a[11]] | ipermtable[8][a[10]];
|
|
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
word32 temp1 = (a[13] | (word32(a[7])<<24)) & 0x01000080;
|
|
#else
|
|
word32 temp1 = ((word32(a[13])<<24) | a[7]) & 0x80000001;
|
|
#endif
|
|
temp1 |= ipermtable[0][a[6]] |
|
|
ipermtable[1][a[5]] | ipermtable[2][a[4]] |
|
|
ipermtable[3][a[3]] | ipermtable[4][a[2]] |
|
|
ipermtable[5][a[1]] | ipermtable[6][a[0]] |
|
|
ipermtable[7][a[15]] | ipermtable[8][a[14]];
|
|
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
word32 temp2 = (a[1] | (word32(a[11])<<24)) & 0x01000080;
|
|
#else
|
|
word32 temp2 = ((word32(a[1])<<24) | a[11]) & 0x80000001;
|
|
#endif
|
|
temp2 |= ipermtable[0][a[10]] |
|
|
ipermtable[1][a[9]] | ipermtable[2][a[8]] |
|
|
ipermtable[3][a[7]] | ipermtable[4][a[6]] |
|
|
ipermtable[5][a[5]] | ipermtable[6][a[4]] |
|
|
ipermtable[7][a[3]] | ipermtable[8][a[2]];
|
|
|
|
#ifdef IS_LITTLE_ENDIAN
|
|
word32 temp3 = (a[5] | (word32(a[15])<<24)) & 0x01000080;
|
|
#else
|
|
word32 temp3 = ((word32(a[5])<<24) | a[15]) & 0x80000001;
|
|
#endif
|
|
((word32 *)a)[3] = temp3 | ipermtable[0][a[14]] |
|
|
ipermtable[1][a[13]] | ipermtable[2][a[12]] |
|
|
ipermtable[3][a[11]] | ipermtable[4][a[10]] |
|
|
ipermtable[5][a[9]] | ipermtable[6][a[8]] |
|
|
ipermtable[7][a[7]] | ipermtable[8][a[6]];
|
|
|
|
((word32 *)a)[0] = temp0;
|
|
((word32 *)a)[1] = temp1;
|
|
((word32 *)a)[2] = temp2;
|
|
}
|
|
|
|
#else // DIAMOND_USE_PERMTABLE
|
|
|
|
inline void Diamond2::Base::permute(byte *x)
|
|
{
|
|
byte y[16];
|
|
|
|
y[0] = (x[0] & 1) | (x[1] & 2) | (x[2] & 4) |
|
|
(x[3] & 8) | (x[4] & 16) | (x[5] & 32) |
|
|
(x[6] & 64) | (x[7] & 128);
|
|
y[1] = (x[1] & 1) | (x[2] & 2) | (x[3] & 4) |
|
|
(x[4] & 8) | (x[5] & 16) | (x[6] & 32) |
|
|
(x[7] & 64) | (x[8] & 128);
|
|
y[2] = (x[2] & 1) | (x[3] & 2) | (x[4] & 4) |
|
|
(x[5] & 8) | (x[6] & 16) | (x[7] & 32) |
|
|
(x[8] & 64) | (x[9] & 128);
|
|
y[3] = (x[3] & 1) | (x[4] & 2) | (x[5] & 4) |
|
|
(x[6] & 8) | (x[7] & 16) | (x[8] & 32) |
|
|
(x[9] & 64) | (x[10] & 128);
|
|
y[4] = (x[4] & 1) | (x[5] & 2) | (x[6] & 4) |
|
|
(x[7] & 8) | (x[8] & 16) | (x[9] & 32) |
|
|
(x[10] & 64) | (x[11] & 128);
|
|
y[5] = (x[5] & 1) | (x[6] & 2) | (x[7] & 4) |
|
|
(x[8] & 8) | (x[9] & 16) | (x[10] & 32) |
|
|
(x[11] & 64) | (x[12] & 128);
|
|
y[6] = (x[6] & 1) | (x[7] & 2) | (x[8] & 4) |
|
|
(x[9] & 8) | (x[10] & 16) | (x[11] & 32) |
|
|
(x[12] & 64) | (x[13] & 128);
|
|
y[7] = (x[7] & 1) | (x[8] & 2) | (x[9] & 4) |
|
|
(x[10] & 8) | (x[11] & 16) | (x[12] & 32) |
|
|
(x[13] & 64) | (x[14] & 128);
|
|
y[8] = (x[8] & 1) | (x[9] & 2) | (x[10] & 4) |
|
|
(x[11] & 8) | (x[12] & 16) | (x[13] & 32) |
|
|
(x[14] & 64) | (x[15] & 128);
|
|
y[9] = (x[9] & 1) | (x[10] & 2) | (x[11] & 4) |
|
|
(x[12] & 8) | (x[13] & 16) | (x[14] & 32) |
|
|
(x[15] & 64) | (x[0] & 128);
|
|
y[10] = (x[10] & 1) | (x[11] & 2) | (x[12] & 4) |
|
|
(x[13] & 8) | (x[14] & 16) | (x[15] & 32) |
|
|
(x[0] & 64) | (x[1] & 128);
|
|
y[11] = (x[11] & 1) | (x[12] & 2) | (x[13] & 4) |
|
|
(x[14] & 8) | (x[15] & 16) | (x[0] & 32) |
|
|
(x[1] & 64) | (x[2] & 128);
|
|
y[12] = (x[12] & 1) | (x[13] & 2) | (x[14] & 4) |
|
|
(x[15] & 8) | (x[0] & 16) | (x[1] & 32) |
|
|
(x[2] & 64) | (x[3] & 128);
|
|
y[13] = (x[13] & 1) | (x[14] & 2) | (x[15] & 4) |
|
|
(x[0] & 8) | (x[1] & 16) | (x[2] & 32) |
|
|
(x[3] & 64) | (x[4] & 128);
|
|
y[14] = (x[14] & 1) | (x[15] & 2) | (x[0] & 4) |
|
|
(x[1] & 8) | (x[2] & 16) | (x[3] & 32) |
|
|
(x[4] & 64) | (x[5] & 128);
|
|
y[15] = (x[15] & 1) | (x[0] & 2) | (x[1] & 4) |
|
|
(x[2] & 8) | (x[3] & 16) | (x[4] & 32) |
|
|
(x[5] & 64) | (x[6] & 128);
|
|
|
|
memcpy(x, y, 16);
|
|
}
|
|
|
|
inline void Diamond2::Base::ipermute(byte *x)
|
|
{
|
|
byte y[16];
|
|
|
|
y[0] = (x[0] & 1) | (x[15] & 2) | (x[14] & 4) |
|
|
(x[13] & 8) | (x[12] & 16) | (x[11] & 32) |
|
|
(x[10] & 64) | (x[9] & 128);
|
|
y[1] = (x[1] & 1) | (x[0] & 2) | (x[15] & 4) |
|
|
(x[14] & 8) | (x[13] & 16) | (x[12] & 32) |
|
|
(x[11] & 64) | (x[10] & 128);
|
|
y[2] = (x[2] & 1) | (x[1] & 2) | (x[0] & 4) |
|
|
(x[15] & 8) | (x[14] & 16) | (x[13] & 32) |
|
|
(x[12] & 64) | (x[11] & 128);
|
|
y[3] = (x[3] & 1) | (x[2] & 2) | (x[1] & 4) |
|
|
(x[0] & 8) | (x[15] & 16) | (x[14] & 32) |
|
|
(x[13] & 64) | (x[12] & 128);
|
|
y[4] = (x[4] & 1) | (x[3] & 2) | (x[2] & 4) |
|
|
(x[1] & 8) | (x[0] & 16) | (x[15] & 32) |
|
|
(x[14] & 64) | (x[13] & 128);
|
|
y[5] = (x[5] & 1) | (x[4] & 2) | (x[3] & 4) |
|
|
(x[2] & 8) | (x[1] & 16) | (x[0] & 32) |
|
|
(x[15] & 64) | (x[14] & 128);
|
|
y[6] = (x[6] & 1) | (x[5] & 2) | (x[4] & 4) |
|
|
(x[3] & 8) | (x[2] & 16) | (x[1] & 32) |
|
|
(x[0] & 64) | (x[15] & 128);
|
|
y[7] = (x[7] & 1) | (x[6] & 2) | (x[5] & 4) |
|
|
(x[4] & 8) | (x[3] & 16) | (x[2] & 32) |
|
|
(x[1] & 64) | (x[0] & 128);
|
|
y[8] = (x[8] & 1) | (x[7] & 2) | (x[6] & 4) |
|
|
(x[5] & 8) | (x[4] & 16) | (x[3] & 32) |
|
|
(x[2] & 64) | (x[1] & 128);
|
|
y[9] = (x[9] & 1) | (x[8] & 2) | (x[7] & 4) |
|
|
(x[6] & 8) | (x[5] & 16) | (x[4] & 32) |
|
|
(x[3] & 64) | (x[2] & 128);
|
|
y[10] = (x[10] & 1) | (x[9] & 2) | (x[8] & 4) |
|
|
(x[7] & 8) | (x[6] & 16) | (x[5] & 32) |
|
|
(x[4] & 64) | (x[3] & 128);
|
|
y[11] = (x[11] & 1) | (x[10] & 2) | (x[9] & 4) |
|
|
(x[8] & 8) | (x[7] & 16) | (x[6] & 32) |
|
|
(x[5] & 64) | (x[4] & 128);
|
|
y[12] = (x[12] & 1) | (x[11] & 2) | (x[10] & 4) |
|
|
(x[9] & 8) | (x[8] & 16) | (x[7] & 32) |
|
|
(x[6] & 64) | (x[5] & 128);
|
|
y[13] = (x[13] & 1) | (x[12] & 2) | (x[11] & 4) |
|
|
(x[10] & 8) | (x[9] & 16) | (x[8] & 32) |
|
|
(x[7] & 64) | (x[6] & 128);
|
|
y[14] = (x[14] & 1) | (x[13] & 2) | (x[12] & 4) |
|
|
(x[11] & 8) | (x[10] & 16) | (x[9] & 32) |
|
|
(x[8] & 64) | (x[7] & 128);
|
|
y[15] = (x[15] & 1) | (x[14] & 2) | (x[13] & 4) |
|
|
(x[12] & 8) | (x[11] & 16) | (x[10] & 32) |
|
|
(x[9] & 64) | (x[8] & 128);
|
|
|
|
memcpy(x, y, 16);
|
|
}
|
|
|
|
#endif // DIAMOND_USE_PERMTABLE
|
|
|
|
void Diamond2::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
|
{
|
|
const byte *x = inBlock;
|
|
byte y[16];
|
|
|
|
substitute(0, y, x);
|
|
for (int round=1; round < numrounds; round++)
|
|
{
|
|
permute(y);
|
|
substitute(round, y, y);
|
|
}
|
|
|
|
if (xorBlock)
|
|
xorbuf(outBlock, xorBlock, y, BLOCKSIZE);
|
|
else
|
|
memcpy(outBlock, y, BLOCKSIZE);
|
|
}
|
|
|
|
void Diamond2::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
|
{
|
|
const byte *x = inBlock;
|
|
byte y[16];
|
|
|
|
substitute(numrounds-1, y, x);
|
|
for (int round=numrounds-2; round >= 0; round--)
|
|
{
|
|
ipermute(y);
|
|
substitute(round, y, y);
|
|
}
|
|
|
|
if (xorBlock)
|
|
xorbuf(outBlock, xorBlock, y, BLOCKSIZE);
|
|
else
|
|
memcpy(outBlock, y, BLOCKSIZE);
|
|
}
|
|
|
|
void Diamond2Lite::Base::UncheckedSetKey(CipherDir direction, const byte *userKey, unsigned int length, unsigned int rounds)
|
|
{
|
|
AssertValidKeyLength(length);
|
|
|
|
numrounds = rounds;
|
|
s.New(numrounds * ROUNDSIZE);
|
|
|
|
Diamond2SboxMaker m(userKey, length, rounds, true);
|
|
m.MakeSbox(s, direction);
|
|
}
|
|
|
|
inline void Diamond2Lite::Base::substitute(int round, byte *x, const byte *y) const
|
|
{
|
|
const byte *sbox = s + (ROUNDSIZE*round);
|
|
x[0] = sbox[0*256+y[0]];
|
|
x[1] = sbox[1*256+y[1]];
|
|
x[2] = sbox[2*256+y[2]];
|
|
x[3] = sbox[3*256+y[3]];
|
|
x[4] = sbox[4*256+y[4]];
|
|
x[5] = sbox[5*256+y[5]];
|
|
x[6] = sbox[6*256+y[6]];
|
|
x[7] = sbox[7*256+y[7]];
|
|
}
|
|
|
|
#ifdef DIAMOND_USE_PERMTABLE
|
|
|
|
inline void Diamond2Lite::Base::permute(byte *a)
|
|
{
|
|
word32 temp = permtable[0][a[0]] | permtable[1][a[1]] |
|
|
permtable[2][a[2]] | permtable[3][a[3]] |
|
|
permtable[4][a[4]] | permtable[5][a[5]] |
|
|
permtable[6][a[6]] | permtable[7][a[7]];
|
|
|
|
((word32 *)a)[1] = permtable[0][a[4]] | permtable[1][a[5]] |
|
|
permtable[2][a[6]] | permtable[3][a[7]] |
|
|
permtable[4][a[0]] | permtable[5][a[1]] |
|
|
permtable[6][a[2]] | permtable[7][a[3]];
|
|
|
|
((word32 *)a)[0] = temp;
|
|
}
|
|
|
|
inline void Diamond2Lite::Base::ipermute(byte *a)
|
|
{
|
|
word32 temp = ipermtable[0][a[0]] | ipermtable[1][a[1]] |
|
|
ipermtable[2][a[2]] | ipermtable[3][a[3]] |
|
|
ipermtable[4][a[4]] | ipermtable[5][a[5]] |
|
|
ipermtable[6][a[6]] | ipermtable[7][a[7]];
|
|
|
|
((word32 *)a)[1] = ipermtable[0][a[4]] | ipermtable[1][a[5]] |
|
|
ipermtable[2][a[6]] | ipermtable[3][a[7]] |
|
|
ipermtable[4][a[0]] | ipermtable[5][a[1]] |
|
|
ipermtable[6][a[2]] | ipermtable[7][a[3]];
|
|
|
|
((word32 *)a)[0] = temp;
|
|
}
|
|
|
|
#else
|
|
|
|
inline void Diamond2Lite::Base::permute(byte *a)
|
|
{
|
|
byte b[8];
|
|
|
|
b[0] = (a[0] & 1) + (a[1] & 2) + (a[2] & 4) + (a[3] & 8) + (a[4] & 0x10) +
|
|
(a[5] & 0x20) + (a[6] & 0x40) + (a[7] & 0x80);
|
|
b[1] = (a[1] & 1) + (a[2] & 2) + (a[3] & 4) + (a[4] & 8) + (a[5] & 0x10) +
|
|
(a[6] & 0x20) + (a[7] & 0x40) + (a[0] & 0x80);
|
|
b[2] = (a[2] & 1) + (a[3] & 2) + (a[4] & 4) + (a[5] & 8) + (a[6] & 0x10) +
|
|
(a[7] & 0x20) + (a[0] & 0x40) + (a[1] & 0x80);
|
|
b[3] = (a[3] & 1) + (a[4] & 2) + (a[5] & 4) + (a[6] & 8) + (a[7] & 0x10) +
|
|
(a[0] & 0x20) + (a[1] & 0x40) + (a[2] & 0x80);
|
|
b[4] = (a[4] & 1) + (a[5] & 2) + (a[6] & 4) + (a[7] & 8) + (a[0] & 0x10) +
|
|
(a[1] & 0x20) + (a[2] & 0x40) + (a[3] & 0x80);
|
|
b[5] = (a[5] & 1) + (a[6] & 2) + (a[7] & 4) + (a[0] & 8) + (a[1] & 0x10) +
|
|
(a[2] & 0x20) + (a[3] & 0x40) + (a[4] & 0x80);
|
|
b[6] = (a[6] & 1) + (a[7] & 2) + (a[0] & 4) + (a[1] & 8) + (a[2] & 0x10) +
|
|
(a[3] & 0x20) + (a[4] & 0x40) + (a[5] & 0x80);
|
|
b[7] = (a[7] & 1) + (a[0] & 2) + (a[1] & 4) + (a[2] & 8) + (a[3] & 0x10) +
|
|
(a[4] & 0x20) + (a[5] & 0x40) + (a[6] & 0x80);
|
|
|
|
memcpy(a, b, 8);
|
|
}
|
|
|
|
inline void Diamond2Lite::Base::ipermute(byte *b)
|
|
{
|
|
byte a[8];
|
|
|
|
a[0] = (b[0] & 1) + (b[7] & 2) + (b[6] & 4) + (b[5] & 8) + (b[4] & 0x10) +
|
|
(b[3] & 0x20) + (b[2] & 0x40) + (b[1] & 0x80);
|
|
a[1] = (b[1] & 1) + (b[0] & 2) + (b[7] & 4) + (b[6] & 8) + (b[5] & 0x10) +
|
|
(b[4] & 0x20) + (b[3] & 0x40) + (b[2] & 0x80);
|
|
a[2] = (b[2] & 1) + (b[1] & 2) + (b[0] & 4) + (b[7] & 8) + (b[6] & 0x10) +
|
|
(b[5] & 0x20) + (b[4] & 0x40) + (b[3] & 0x80);
|
|
a[3] = (b[3] & 1) + (b[2] & 2) + (b[1] & 4) + (b[0] & 8) + (b[7] & 0x10) +
|
|
(b[6] & 0x20) + (b[5] & 0x40) + (b[4] & 0x80);
|
|
a[4] = (b[4] & 1) + (b[3] & 2) + (b[2] & 4) + (b[1] & 8) + (b[0] & 0x10) +
|
|
(b[7] & 0x20) + (b[6] & 0x40) + (b[5] & 0x80);
|
|
a[5] = (b[5] & 1) + (b[4] & 2) + (b[3] & 4) + (b[2] & 8) + (b[1] & 0x10) +
|
|
(b[0] & 0x20) + (b[7] & 0x40) + (b[6] & 0x80);
|
|
a[6] = (b[6] & 1) + (b[5] & 2) + (b[4] & 4) + (b[3] & 8) + (b[2] & 0x10) +
|
|
(b[1] & 0x20) + (b[0] & 0x40) + (b[7] & 0x80);
|
|
a[7] = (b[7] & 1) + (b[6] & 2) + (b[5] & 4) + (b[4] & 8) + (b[3] & 0x10) +
|
|
(b[2] & 0x20) + (b[1] & 0x40) + (b[0] & 0x80);
|
|
|
|
memcpy(b, a, 8);
|
|
}
|
|
|
|
#endif // DIAMOND_USE_PERMTABLE
|
|
|
|
void Diamond2Lite::Enc::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
|
{
|
|
const byte *x = inBlock;
|
|
byte y[8];
|
|
|
|
substitute(0, y, x);
|
|
for (int round=1; round < numrounds; round++)
|
|
{
|
|
permute(y);
|
|
substitute(round, y, y);
|
|
}
|
|
|
|
if (xorBlock)
|
|
xorbuf(outBlock, xorBlock, y, BLOCKSIZE);
|
|
else
|
|
memcpy(outBlock, y, BLOCKSIZE);
|
|
}
|
|
|
|
void Diamond2Lite::Dec::ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const
|
|
{
|
|
const byte *x = inBlock;
|
|
byte y[8];
|
|
|
|
substitute(numrounds-1, y, x);
|
|
for (int round=numrounds-2; round >= 0; round--)
|
|
{
|
|
ipermute(y);
|
|
substitute(round, y, y);
|
|
}
|
|
|
|
if (xorBlock)
|
|
xorbuf(outBlock, xorBlock, y, BLOCKSIZE);
|
|
else
|
|
memcpy(outBlock, y, BLOCKSIZE);
|
|
}
|
|
|
|
NAMESPACE_END
|