Смекни!
smekni.com

Интегральная атака против блочного симметричного шифра Crypton (стр. 11 из 11)

(y)[3] = phi_13((x)[3])

u1byte p_box[3][16] =

{ { 15, 9, 6, 8, 9, 9, 4, 12, 6, 2, 6, 10, 1, 3, 5, 15 },

{ 10, 15, 4, 7, 5, 2, 14, 6, 9, 3, 12, 8, 13, 1, 11, 0 },

{ 0, 4, 8, 4, 2, 15, 8, 13, 1, 1, 15, 7, 2, 11, 14, 15 }

};

u4byte tab_gen = 0;

u1byte s_box[2][256];

u4byte s_tab[4][256];

u4byte l_key[104];

u4byte *e_key = l_key + 52;

u4byte *d_key = l_key;

void gen_tab(void)

{ u4byte i, xl, xr, yl, yr;

for(i = 0; i < 256; ++i)

{

xl = (i & 0xf0) >> 4; xr = i & 15;

yr = xr ^ p_box[1][xl ^ p_box[0][xr]];

yl = xl ^ p_box[0][xr] ^ p_box[2][yr];

yr |= (yl << 4); s_box[0][i] = (u1byte)yr; s_box[1][yr] = (u1byte)i;

xr = yr * 0x01010101; xl = i * 0x01010101;

s_tab[0][ i] = xr & 0x3fcff3fc;

s_tab[1][yr] = xl & 0xfc3fcff3;

s_tab[2][ i] = xr & 0xf3fc3fcf;

s_tab[3][yr] = xl & 0xcff3fc3f;

}

};

/* initialise the key schedule from the user supplied key */

u4byte kp[4] = { 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f };

u4byte kq[4] = { 0x9b05688c, 0x1f83d9ab, 0x5be0cd19, 0xcbbb9d5d };

#define h0_block(n,r0,r1) &bsol;

e_key[4 * n + 8] = rotl(e_key[4 * n + 0], r0); &bsol;

e_key[4 * n + 9] = rc ^ e_key[4 * n + 1]; &bsol;

e_key[4 * n + 10] = rotl(e_key[4 * n + 2], r1); &bsol;

e_key[4 * n + 11] = rc ^ e_key[4 * n + 3]

#define h1_block(n,r0,r1) &bsol;

e_key[4 * n + 8] = rc ^ e_key[4 * n + 0]; &bsol;

e_key[4 * n + 9] = rotl(e_key[4 * n + 1], r0); &bsol;

e_key[4 * n + 10] = rc ^ e_key[4 * n + 2]; &bsol;

e_key[4 * n + 11] = rotl(e_key[4 * n + 3], r1)

u4byte *set_key(const u4byte in_key[], const u4byte key_len)

{ u4byte i, rc, t0, t1, tmp[4];

if(!tab_gen)

{

gen_tab(); tab_gen = 1;

}

e_key[2] = e_key[3] = e_key[6] = e_key[7] = 0;

switch((key_len + 63) / 64)

{

case 4: e_key[3] = in_key[6]; e_key[7] = in_key[7];

case 3: e_key[2] = in_key[4]; e_key[6] = in_key[5];

case 2: e_key[0] = in_key[0]; e_key[4] = in_key[1];

e_key[1] = in_key[2]; e_key[5] = in_key[3];

}

tmp[0] = pi(e_key, 0, 1, 2, 3) ^ kp[0];

tmp[1] = pi(e_key, 1, 2, 3, 0) ^ kp[1];

tmp[2] = pi(e_key, 2, 3, 0, 1) ^ kp[2];

tmp[3] = pi(e_key, 3, 0, 1, 2) ^ kp[3];

gamma_tau(e_key[0], tmp, 0, 0, 1);

gamma_tau(e_key[1], tmp, 1, 1, 0);

gamma_tau(e_key[2], tmp, 2, 0, 1);

gamma_tau(e_key[3], tmp, 3, 1, 0);

tmp[0] = pi(e_key + 4, 1, 2, 3, 0) ^ kq[0];

tmp[1] = pi(e_key + 4, 2, 3, 0, 1) ^ kq[1];

tmp[2] = pi(e_key + 4, 3, 0, 1, 2) ^ kq[2];

tmp[3] = pi(e_key + 4, 0, 1, 2, 3) ^ kq[3];

gamma_tau(e_key[4], tmp, 0, 1, 0);

gamma_tau(e_key[5], tmp, 1, 0, 1);

gamma_tau(e_key[6], tmp, 2, 1, 0);

gamma_tau(e_key[7], tmp, 3, 0, 1);

t0 = e_key[0] ^ e_key[1] ^ e_key[2] ^ e_key[3];

t1 = e_key[4] ^ e_key[5] ^ e_key[6] ^ e_key[7];

e_key[0] ^= t1; e_key[1] ^= t1;

e_key[2] ^= t1; e_key[3] ^= t1;

e_key[4] ^= t0; e_key[5] ^= t0;

e_key[6] ^= t0; e_key[7] ^= t0;

rc = 0x01010101;

h0_block( 0, 8, 16); h1_block(1, 16, 24); rc <<= 1;

h1_block( 2, 24, 8); h0_block(3, 8, 16); rc <<= 1;

h0_block( 4, 16, 24); h1_block(5, 24, 8); rc <<= 1;

h1_block( 6, 8, 16); h0_block(7, 16, 24); rc <<= 1;

h0_block( 8, 24, 8); h1_block(9, 8, 16); rc <<= 1;

h1_block(10, 16, 24);

for(i = 0; i < 13; ++i)

{

if(i & 1)

{

phi0(e_key + 4 * i, d_key + 48 - 4 * i);

}

else

{

phi1(e_key + 4 * i, d_key + 48 - 4 * i);

}

}

phi1(e_key + 48, e_key + 48);

phi1(d_key + 48, d_key + 48);

return l_key;

};

/* encrypt a block of text */

#define fr0(i,k) &bsol;

b1[i] = s_tab[ (i) ][byte(b0[0],i)] ^ &bsol;

s_tab[((i) + 1) & 3][byte(b0[1],i)] ^ &bsol;

s_tab[((i) + 2) & 3][byte(b0[2],i)] ^ &bsol;

s_tab[((i) + 3) & 3][byte(b0[3],i)] ^ (k)

#define fr1(i,k) &bsol;

b0[i] = s_tab[((i) + 1) & 3][byte(b1[0],i)] ^ &bsol;

s_tab[((i) + 2) & 3][byte(b1[1],i)] ^ &bsol;

s_tab[((i) + 3) & 3][byte(b1[2],i)] ^ &bsol;

s_tab[(i) ][byte(b1[3],i)] ^ (k)

#define f0_rnd(kp) &bsol;

fr0(0,(kp)[0]); fr0(1,(kp)[1]); &bsol;

fr0(2,(kp)[2]); fr0(3,(kp)[3])

#define f1_rnd(kp) &bsol;

fr1(0,(kp)[0]); fr1(1,(kp)[1]); &bsol;

fr1(2,(kp)[2]); fr1(3,(kp)[3])

void encrypt(const u4byte in_blk[4], u4byte out_blk[4])

{ u4byte b0[4], b1[4];

b0[0] = in_blk[0] ^ e_key[0];

b0[1] = in_blk[1] ^ e_key[1];

b0[2] = in_blk[2] ^ e_key[2];

b0[3] = in_blk[3] ^ e_key[3];

f0_rnd(e_key + 4); f1_rnd(e_key + 8);

f0_rnd(e_key + 12); f1_rnd(e_key + 16);

f0_rnd(e_key + 20); f1_rnd(e_key + 24);

f0_rnd(e_key + 28); f1_rnd(e_key + 32);

f0_rnd(e_key + 36); f1_rnd(e_key + 40);

f0_rnd(e_key + 44);

gamma_tau(b0[0], b1, 0, 1, 0);

gamma_tau(b0[1], b1, 1, 0, 1);

gamma_tau(b0[2], b1, 2, 1, 0);

gamma_tau(b0[3], b1, 3, 0, 1);

out_blk[0] = b0[0] ^ e_key[48];

out_blk[1] = b0[1] ^ e_key[49];

out_blk[2] = b0[2] ^ e_key[50];

out_blk[3] = b0[3] ^ e_key[51];

};

/* decrypt a block of text */

void decrypt(const u4byte in_blk[4], u4byte out_blk[4])

{ u4byte b0[4], b1[4];

b0[0] = in_blk[0] ^ d_key[0];

b0[1] = in_blk[1] ^ d_key[1];

b0[2] = in_blk[2] ^ d_key[2];

b0[3] = in_blk[3] ^ d_key[3];

f0_rnd(d_key + 4); f1_rnd(d_key + 8);

f0_rnd(d_key + 12); f1_rnd(d_key + 16);

f0_rnd(d_key + 20); f1_rnd(d_key + 24);

f0_rnd(d_key + 28); f1_rnd(d_key + 32);

f0_rnd(d_key + 36); f1_rnd(d_key + 40);

f0_rnd(d_key + 44);

gamma_tau(b0[0], b1, 0, 1, 0);

gamma_tau(b0[1], b1, 1, 0, 1);

gamma_tau(b0[2], b1, 2, 1, 0);

gamma_tau(b0[3], b1, 3, 0, 1);

out_blk[0] = b0[0] ^ d_key[48];

out_blk[1] = b0[1] ^ d_key[49];

out_blk[2] = b0[2] ^ d_key[50];

out_blk[3] = b0[3] ^ d_key[51];

}

Файл <STD_DEFS.H>

/* 1. Standard types for AES cryptography source code */

typedef unsigned char u1byte; /* an 8 bit unsigned character type */

typedef unsigned short u2byte; /* a 16 bit unsigned integer type */

typedef unsigned long u4byte; /* a 32 bit unsigned integer type */

typedef signed char s1byte; /* an 8 bit signed character type */

typedef signed short s2byte; /* a 16 bit signed integer type */

typedef signed long s4byte; /* a 32 bit signed integer type */

/* 2. Standard interface for AES cryptographic routines */

/* These are all based on 32 bit unsigned values and will therefore */

/* require endian conversions for big-endian architectures */

#ifdef __cplusplus

extern "C"

{

#endif

char **cipher_name(void);

u4byte *set_key(const u4byte in_key[], const u4byte key_len);

void encrypt(const u4byte in_blk[4], u4byte out_blk[4]);

void decrypt(const u4byte in_blk[4], u4byte out_blk[4]);

#ifdef __cplusplus

};

#endif

/* 3. Basic macros for speeding up generic operations */

/* Circular rotate of 32 bit values */

#ifdef _MSC_VER

# include <stdlib.h>

# pragma intrinsic(_lrotr,_lrotl)

# define rotr(x,n) _lrotr(x,n)

# define rotl(x,n) _lrotl(x,n)

#else

#define rotr(x,n) (((x) >> ((int)(n))) | ((x) << (32 - (int)(n))))

#define rotl(x,n) (((x) << ((int)(n))) | ((x) >> (32 - (int)(n))))

#endif

/* Invert byte order in a 32 bit variable */

#define bswap(x) (rotl(x, 8) & 0x00ff00ff | rotr(x, 8) & 0xff00ff00)

/* Extract byte from a 32 bit quantity (little endian notation) */

#define byte(x,n) ((u1byte)((x) >> (8 * n)))

/* For inverting byte order in input/output 32 bit words if needed */

#ifdef BLOCK_SWAP

#define BYTE_SWAP

#define WORD_SWAP

#endif

#ifdef BYTE_SWAP

#define io_swap(x) bswap(x)

#else

#define io_swap(x) (x)

#endif

/* For inverting the byte order of input/output blocks if needed */

#ifdef WORD_SWAP

#define get_block(x) &bsol;

((u4byte*)(x))[0] = io_swap(in_blk[3]); &bsol;

((u4byte*)(x))[1] = io_swap(in_blk[2]); &bsol;

((u4byte*)(x))[2] = io_swap(in_blk[1]); &bsol;

((u4byte*)(x))[3] = io_swap(in_blk[0])

#define put_block(x) &bsol;

out_blk[3] = io_swap(((u4byte*)(x))[0]); &bsol;

out_blk[2] = io_swap(((u4byte*)(x))[1]); &bsol;

out_blk[1] = io_swap(((u4byte*)(x))[2]); &bsol;

out_blk[0] = io_swap(((u4byte*)(x))[3])

#define get_key(x,len) &bsol;

((u4byte*)(x))[4] = ((u4byte*)(x))[5] = &bsol;

((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0; &bsol;

switch((((len) + 63) / 64)) { &bsol;

case 2: &bsol;

((u4byte*)(x))[0] = io_swap(in_key[3]); &bsol;

((u4byte*)(x))[1] = io_swap(in_key[2]); &bsol;

((u4byte*)(x))[2] = io_swap(in_key[1]); &bsol;

((u4byte*)(x))[3] = io_swap(in_key[0]); &bsol;

break; &bsol;

case 3: &bsol;

((u4byte*)(x))[0] = io_swap(in_key[5]); &bsol;

((u4byte*)(x))[1] = io_swap(in_key[4]); &bsol;

((u4byte*)(x))[2] = io_swap(in_key[3]); &bsol;

((u4byte*)(x))[3] = io_swap(in_key[2]); &bsol;

((u4byte*)(x))[4] = io_swap(in_key[1]); &bsol;

((u4byte*)(x))[5] = io_swap(in_key[0]); &bsol;

break; &bsol;

case 4: &bsol;

((u4byte*)(x))[0] = io_swap(in_key[7]); &bsol;

((u4byte*)(x))[1] = io_swap(in_key[6]); &bsol;

((u4byte*)(x))[2] = io_swap(in_key[5]); &bsol;

((u4byte*)(x))[3] = io_swap(in_key[4]); &bsol;

((u4byte*)(x))[4] = io_swap(in_key[3]); &bsol;

((u4byte*)(x))[5] = io_swap(in_key[2]); &bsol;

((u4byte*)(x))[6] = io_swap(in_key[1]); &bsol;

((u4byte*)(x))[7] = io_swap(in_key[0]); &bsol;

}

#else

#define get_block(x) &bsol;

((u4byte*)(x))[0] = io_swap(in_blk[0]); &bsol;

((u4byte*)(x))[1] = io_swap(in_blk[1]); &bsol;

((u4byte*)(x))[2] = io_swap(in_blk[2]); &bsol;

((u4byte*)(x))[3] = io_swap(in_blk[3])

#define put_block(x) &bsol;

out_blk[0] = io_swap(((u4byte*)(x))[0]); &bsol;

out_blk[1] = io_swap(((u4byte*)(x))[1]); &bsol;

out_blk[2] = io_swap(((u4byte*)(x))[2]); &bsol;

out_blk[3] = io_swap(((u4byte*)(x))[3])

#define get_key(x,len) &bsol;

((u4byte*)(x))[4] = ((u4byte*)(x))[5] = &bsol;

((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0; &bsol;

switch((((len) + 63) / 64)) { &bsol;

case 4: &bsol;

((u4byte*)(x))[6] = io_swap(in_key[6]); &bsol;

((u4byte*)(x))[7] = io_swap(in_key[7]); &bsol;

case 3: &bsol;

((u4byte*)(x))[4] = io_swap(in_key[4]); &bsol;

((u4byte*)(x))[5] = io_swap(in_key[5]); &bsol;

case 2: &bsol;

((u4byte*)(x))[0] = io_swap(in_key[0]); &bsol;

((u4byte*)(x))[1] = io_swap(in_key[1]); &bsol;

((u4byte*)(x))[2] = io_swap(in_key[2]); &bsol;

((u4byte*)(x))[3] = io_swap(in_key[3]); &bsol;

}

#endif

#define beg /*

#define en */

Файл <АTACK.H>

#ifndef ATACH.H_H #define ATACH.H_H

#define ENCRYPT 0 #define DECRYPT 1

¦include "StdAfx.h" #include "Resource.h" ¦include "winaesDlg.h"

¦define ROTL(x) ( ( (x) "7) | ( (x) "1) )

¦define R0TL8 (x) ( ( (x) "8) | ( (x) "24) ) ¦define R0TL16(x) ( ( (x) "16) I ( (x) "16) ) ¦define ROTL24 (x) ( ( (x) "24) | ( (x) "8) )

int KeyExpansion(CWinaesDlg* dig, int nb,int nk, BYTE* key); void Encrypt(CWinaesDlg* dig, BYTE* buff, BYTE* result); void InvDecrypt(CWinaesDlg* dig, BYTE* buff, BYTE* result); void EquDecrypt(CWinaesDlg* dig, BYTE* buff, BYTE* result);

int blockEncrypt(CWinaesDlg* dig, BYTE *input, int inputLen, BYTE* result, int cipher_mode); int blockDecrypt(CWinaesDlg* dig, BYTE *input, int inputLen, BYTE* result, int decrypt_mode, int cipher_mode);

¦endif

ATACH.H.CPP

¦include <stdio.h> ¦include <stdlib.h> ¦include "Rijndael.h" ¦include "service.h"

¦define BPOLY (BYTE) Oxllb ¦define MPOLY (BYTE) 0x101

BYTE Co[4]={0x3,0xl,0xl,0x2};

BYTE InvCo[4]={0xB,0xD,0x9,0xE};

int N, Nk, Nb, Nr;

DWORD fkey[120];

DWORD ikey[120]; // inverse key

DWORD ekey[120]; // equivalent key

BYTE subbytes[256] ; BYTE invsubbytes[256] ;

BYTE shfts[3][4];

static char strTmp[260], Tmp[260]; static DWORD s[8];

void ResetShifts() {

for (int i=0; i<3; i++)

for (int j=0; j<4; j++)

if (i==2 && j==3) shfts[i][j]=4; else shfts[i][j]=j;

void shiftrow(BYTE* row, int n, int direct)

BYTE t; int j ;

if (n)

for (int i=0; i<n; i++) switch (direct)

case ENCRYPT:

t=row[0];

for (j=l; j<Nb; j++) row[j-l]=row[j] ; row [Nb-1 In¬break;

case DECRYPT:

t=row[Nb-l];

for (j = Nb-1; j>0; j--) row[j]=row[j-1] ,

row[0]=t;

break;

void ShifRows(BYTE* s, int direct)

BYTE temp[8]; int i, j;

for (i=0;i<4;i++)

for (j=0;j<Nb;j++) temp[j]=s[j*4+i];

shiftrow( temp, shfts[Nb/2-2][i], direct),

for (j=0;j<Nb;j++) s[j*4+i]=temp[j]; }

static DWORD pack(BYTE *b)

{

return ( (DWORD)b[3]"24) | ( (DWORD)b [2] "16) | ( (DWORD) b [1 ] "8) | (DWORD)b[0],

static void unpack(DWORD a,BYTE *b) {

b[0] = (BYTE)a;

b[l] = (BYTE) (a"8) ;

b[2] = (BYTE) (a"16) ;

b[3] = (BYTE) (a"24) ; }

static BYTE xtime(BYTE a, BYTE mod) {

return ( ( a & 0x80) ? a"lAmod

static BYTE add (BYTE a, BYTE b) {return алЬ;}

static BYTE bmul(BYTE a,BYTE b, BYTE mod) {

BYTE t,s, u;

u=b; t=a; s=0;

while (u) {

if(u & 1) эл=Ь;

u"=l ;

t=xtime(t, mod);

return (s); }

static BYTE square(BYTE a, BYTE mod) {

return (bmul(a,a, mod)); }

static BYTE product(DWORD x,DWORD y, BYTE mod) {

BYTE xb [ 4 ] , yb [ 4 ] ;

unpack(x,xb);

unpack(y,yb);

return bmul(xb[0],yb[0], mod)лЬти1(xb[1],yb[1], mod)лЬти1(xb[2],yb[2], mod)лЬти1(xb[3],yb[3], mod) ; }

static BYTE finv(const BYTE x, BYTE mod) {

BYTE result = x;

for (int i=l; i<7; i++) result = bmul(square(result , mod), x, mod);

return square(result, mod); }

BYTE SBinvModulo; BYTE SBmulModulo; BYTE SBmulConstl; BYTE SBmulConst2; BYTE SBaddConstl; BYTE SBaddConst2;

static BYTE ByteSubOLD(BYTE x) BYTE result=x;

result = finv( result , SBinvModulo);

result = bmul( SBmulConstl, result, SBmulModulo);

result = add( result, SBaddConstl);

return result; }

static BYTE InvByteSubOLD(BYTE x) BYTE result=x;

result = bmul( SBmulConst2, result, SBmulModulo); result = add(result, SBaddConst2); result = finv( result, SBinvModulo); return result;

void FillTables(int mode)

for (int i=0; i<256;

if (mode & 1) subbytes[i]= ByteSubOLD(i);

if (mode & 2) invsubbytes[i]= InvByteSubOLD(i)

void ResetTables()

Encrypt(dig, iv, block);

for (1 = k; (1 < (k + OFB_bits)) && (1 < (Nb"5) ) ; 1++) {

result[1 " 3] = (block[0] & 0x80U) " (1 & 7);

for (j = 0; j < (Nb"2)-1; j++) {

iv[j] = <iv[j] " 1) | (iv[j + 1] " 7);

block[j] = (block[j] " 1) | (block[j + 17);

1] " 1) | ((block[0] & 0x80U) " 7 );

} }

if (OFB_Debug) {

CharStr2HexStr((BYTE*)input, Tmp, Nb*4); sprintf(strTmp," in[%04u]=%s", i, Tmp); dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4); sprintf(strTmp,"out[%04u]=%s", i, Tmp); dlg->m_eDebug.AddString(strTmp); }

result += Nb"2;

input += Nb"2; }

free(iv); break;

case MODE_CTR:

iv = (BYTE*) malloc(Nb"2) ; memcpy(iv, cipher_IV, Nb"2);

for (i = 1; i <= numBlocks; i++) {

if (CTR_Debug) {

//CharStr2HexStr((BYTE*)s, Tmp, Nb*4);

sprintf(strTmp,"= CTR AES Nb=%u Nk=%u, block %04u encrypt ======================", Nb, Nk, i);

dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)iv, Tmp, Nb*4); sprintf(strTmp," IV[%04u]=%s", i, Tmp); dlg->m_eDebug.AddString(strTmp); }

Encrypt(dig, iv, result);

for (j=0; j < Nb; j++) ((DWORD*)result)[j] л= ((DWORD*)input)[j];

increase_counter ( iv, Nb"2);

if (CTR_Debug) {

CharStr2HexStr((BYTE*)input, Tmp, Nb*4);

sprintf(strTmp," in[%04u]=%s", i, Tmp);

dlg->m_eDebug.AddString(strTmp);

CharStr2HexStr((BYTE*)result, Tmp, Nb*4); sprintf(strTmp,"out[%04u]=%s", i, Tmp); dlg->m_eDebug.AddString(strTmp); }

input += Nb"2; result += Nb"2; }

free(iv); break; default:

return BAD_CIPHER_STATE; }

return 128*numBlocks;