Peguei o algoritmo RC6, já implementado em C, para implementar a
criptografia em handhelds - PocketPC.
Só que não estou sabendo usar direito as funções no programa.
O programa está todo no fim deste email. Sao dois arquivos, rc6.
c e o outro std_defs.h.
O código é BEM, MUITO simples mas nao estou conseguindo utiliza-
lo corretamente. São três funções apenas: set_key, encrypt e decrypt.
O código dentro do main() fui eu que fiz para tentar testar o
algoritmo. Parece que está dando certo, mas ele está encriptando e
descriptando corretamente mesmo sem eu rodar a função set_key! Pra
que serve essa função ? Como a utilizo corretamente ?
E como faço para encriptar aquivos .txt utilizando esse código ?
As entradas e saídas são unsigned long, como faço para encriptar
letras/caracteres de arquivos .txt ?
Preciso de uma resposta o mais rápido possível.
Desde já, agradeço a quem puder me ajudar.
Grato,
André Gabriel
/* RC6.c */
#include "std_defs.h"
static char *alg_name[] = { "rc6", "rc6.c", "rc6" };
char **cipher_name()
{
return alg_name;
}
#define f_rnd(i,a,b,c,d) \
u = rotl(d * (d + d + 1), 5); \
t = rotl(b * (b + b + 1), 5); \
a = rotl(a ^ t, u) + l_key[i]; \
c = rotl(c ^ u, t) + l_key[i + 1]
#define i_rnd(i,a,b,c,d) \
u = rotl(d * (d + d + 1), 5); \
t = rotl(b * (b + b + 1), 5); \
c = rotr(c - l_key[i + 1], t) ^ u; \
a = rotr(a - l_key[i], u) ^ t
u4byte l_key[44]; /* storage for the key schedule */
/* initialise the key schedule from the user supplied key */
u4byte *set_key(const u4byte in_key[], const u4byte key_len)
{ u4byte i, j, k, a, b, l[8], t;
l_key[0] = 0xb7e15163;
for(k = 1; k < 44; ++k)
l_key[k] = l_key[k - 1] + 0x9e3779b9;
for(k = 0; k < key_len / 32; ++k)
l[k] = in_key[k];
t = (key_len / 32) - 1; // t = (key_len / 32);
a = b = i = j = 0;
for(k = 0; k < 132; ++k)
{ a = rotl(l_key[i] + a + b, 3); b += a;
b = rotl(l[j] + b, b);
l_key[i] = a; l[j] = b;
i = (i == 43 ? 0 : i + 1); // i = (i + 1) % 44;
j = (j == t ? 0 : j + 1); // j = (j + 1) % t;
}
return l_key;
};
/* encrypt a block of text */
void encrypt(const u4byte in_blk[4], u4byte out_blk[4])
{ u4byte a,b,c,d,t,u;
a = in_blk[0]; b = in_blk[1] + l_key[0];
c = in_blk[2]; d = in_blk[3] + l_key[1];
f_rnd( 2,a,b,c,d); f_rnd( 4,b,c,d,a);
f_rnd( 6,c,d,a,b); f_rnd( 8,d,a,b,c);
f_rnd(10,a,b,c,d); f_rnd(12,b,c,d,a);
f_rnd(14,c,d,a,b); f_rnd(16,d,a,b,c);
f_rnd(18,a,b,c,d); f_rnd(20,b,c,d,a);
f_rnd(22,c,d,a,b); f_rnd(24,d,a,b,c);
f_rnd(26,a,b,c,d); f_rnd(28,b,c,d,a);
f_rnd(30,c,d,a,b); f_rnd(32,d,a,b,c);
f_rnd(34,a,b,c,d); f_rnd(36,b,c,d,a);
f_rnd(38,c,d,a,b); f_rnd(40,d,a,b,c);
out_blk[0] = a + l_key[42]; out_blk[1] = b;
out_blk[2] = c + l_key[43]; out_blk[3] = d;
};
/* decrypt a block of text */
void decrypt(const u4byte in_blk[4], u4byte out_blk[4])
{ u4byte a,b,c,d,t,u;
d = in_blk[3]; c = in_blk[2] - l_key[43];
b = in_blk[1]; a = in_blk[0] - l_key[42];
i_rnd(40,d,a,b,c); i_rnd(38,c,d,a,b);
i_rnd(36,b,c,d,a); i_rnd(34,a,b,c,d);
i_rnd(32,d,a,b,c); i_rnd(30,c,d,a,b);
i_rnd(28,b,c,d,a); i_rnd(26,a,b,c,d);
i_rnd(24,d,a,b,c); i_rnd(22,c,d,a,b);
i_rnd(20,b,c,d,a); i_rnd(18,a,b,c,d);
i_rnd(16,d,a,b,c); i_rnd(14,c,d,a,b);
i_rnd(12,b,c,d,a); i_rnd(10,a,b,c,d);
i_rnd( 8,d,a,b,c); i_rnd( 6,c,d,a,b);
i_rnd( 4,b,c,d,a); i_rnd( 2,a,b,c,d);
out_blk[3] = d - l_key[1]; out_blk[2] = c;
out_blk[1] = b - l_key[0]; out_blk[0] = a;
};
int main()
{
u4byte Entrada[4],Saida[4],SaidaD[4], Chave[16];
int i;
Entrada[0] = 0100;
Entrada[1] = 0000;
Entrada[2] = 0000;
Entrada[3] = 0000;
for (i = 0; i < 16; i++)
Chave[i] = 0;
set_key(Chave,sizeof(Chave));
printf("%x %x %x %x\n",Entrada[0], Entrada[1], Entrada[2],Entrada
[3]);
encrypt(Entrada,Saida);
printf("%x %x %x %x\n",Saida[0], Saida[1], Saida[2],Saida[3]);
decrypt(Saida,SaidaD);
printf("%x %x %x %x",SaidaD[0], SaidaD[1], SaidaD[2],SaidaD[3]);
system("pause");
return 0;
}
/ ********************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) \
((u4byte*)(x))[0] = io_swap(in_blk[3]); \
((u4byte*)(x))[1] = io_swap(in_blk[2]); \
((u4byte*)(x))[2] = io_swap(in_blk[1]); \
((u4byte*)(x))[3] = io_swap(in_blk[0])
#define put_block(x) \
out_blk[3] = io_swap(((u4byte*)(x))[0]); \
out_blk[2] = io_swap(((u4byte*)(x))[1]); \
out_blk[1] = io_swap(((u4byte*)(x))[2]); \
out_blk[0] = io_swap(((u4byte*)(x))[3])
#define get_key(x,len) \
((u4byte*)(x))[4] = ((u4byte*)(x))[5] = \
((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0; \
switch((((len) + 63) / 64)) { \
case 2: \
((u4byte*)(x))[0] = io_swap(in_key[3]); \
((u4byte*)(x))[1] = io_swap(in_key[2]); \
((u4byte*)(x))[2] = io_swap(in_key[1]); \
((u4byte*)(x))[3] = io_swap(in_key[0]); \
break; \
case 3: \
((u4byte*)(x))[0] = io_swap(in_key[5]); \
((u4byte*)(x))[1] = io_swap(in_key[4]); \
((u4byte*)(x))[2] = io_swap(in_key[3]); \
((u4byte*)(x))[3] = io_swap(in_key[2]); \
((u4byte*)(x))[4] = io_swap(in_key[1]); \
((u4byte*)(x))[5] = io_swap(in_key[0]); \
break; \
case 4: \
((u4byte*)(x))[0] = io_swap(in_key[7]); \
((u4byte*)(x))[1] = io_swap(in_key[6]); \
((u4byte*)(x))[2] = io_swap(in_key[5]); \
((u4byte*)(x))[3] = io_swap(in_key[4]); \
((u4byte*)(x))[4] = io_swap(in_key[3]); \
((u4byte*)(x))[5] = io_swap(in_key[2]); \
((u4byte*)(x))[6] = io_swap(in_key[1]); \
((u4byte*)(x))[7] = io_swap(in_key[0]); \
}
#else
#define get_block(x) \
((u4byte*)(x))[0] = io_swap(in_blk[0]); \
((u4byte*)(x))[1] = io_swap(in_blk[1]); \
((u4byte*)(x))[2] = io_swap(in_blk[2]); \
((u4byte*)(x))[3] = io_swap(in_blk[3])
#define put_block(x) \
out_blk[0] = io_swap(((u4byte*)(x))[0]); \
out_blk[1] = io_swap(((u4byte*)(x))[1]); \
out_blk[2] = io_swap(((u4byte*)(x))[2]); \
out_blk[3] = io_swap(((u4byte*)(x))[3])
#define get_key(x,len) \
((u4byte*)(x))[4] = ((u4byte*)(x))[5] = \
((u4byte*)(x))[6] = ((u4byte*)(x))[7] = 0; \
switch((((len) + 63) / 64)) { \
case 4: \
((u4byte*)(x))[6] = io_swap(in_key[6]); \
((u4byte*)(x))[7] = io_swap(in_key[7]); \
case 3: \
((u4byte*)(x))[4] = io_swap(in_key[4]); \
((u4byte*)(x))[5] = io_swap(in_key[5]); \
case 2: \
((u4byte*)(x))[0] = io_swap(in_key[0]); \
((u4byte*)(x))[1] = io_swap(in_key[1]); \
((u4byte*)(x))[2] = io_swap(in_key[2]); \
((u4byte*)(x))[3] = io_swap(in_key[3]); \
}
#endif