|
|
View previous topic :: View next topic |
Author |
Message |
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
TEA - Tiny Encryption Algorithm |
Posted: Tue Feb 07, 2006 4:58 pm |
|
|
Here is the library, tea.c:
Code: |
/*************************************************************/
/* */
/* TEA - TINY ENCRYPTION ALGORITHM */
/* */
/* Written by: Aurelian Nichita */
/* Compiler: CCS PIC C Compiler 3.242 */
/* Contact: nicksubzero@yahoo.com */
/* Source: http://www.simonshepherd.supanet.com/tea.htm */
/* */
/* */
/* Benchmark (one encipher/decipher cycle, 8 bytes) */
/* */
/* - PIC 16F877, 8 MHz, 32 iterations, */
/* ROM 946 bytes, RAM 33 bytes, time required 10.0405 ms */
/* */
/* - PIC 18F452, 32 MHz, 32 iterations, */
/* ROM 1548 bytes, RAM 37 bytes, time required 1.8455 ms */
/* */
/*************************************************************/
/* Number of iterations.
32 is ample, 16 is sufficient,
as few as eight should be OK for most applications. */
const signed int8 TEA_ITERATIONS = 32;
/* The Golden ratio */
const unsigned int32 TEA_DELTA = 0x9E3779B9;
/* Starting sum for decryption */
const unsigned int32 TEA_DEC_SUM = 0xC6EF3720;
/* Enciphers 8 bytes using a 16-byte (128-bit) key.
"in" and "out" are arrays of two int32's,
"key" is an array of four int32's. */
#separate
void tea_encipher (unsigned int32 * in,
unsigned int32 * out,
unsigned int32 * key)
{
unsigned int32 y, z, a, b, c, d, sum = 0;
signed int8 n = TEA_ITERATIONS;
y = in[0]; z = in[1];
a = key[0]; b = key[1];
c = key[2]; d = key[3];
while(n > 0) {
sum += TEA_DELTA;
y += z<<4;
y += a^z;
y += sum^(z>>5);
y += b;
z += y<<4;
z += c^y;
z += sum^(y>>5);
z += d;
n--;
}
out[0] = y;
out[1] = z;
}
/* Deciphers 8 bytes using a 16-byte (128-bit) key.
"in" and "out" are arrays of two int32's,
"key" is an array of four int32's. */
#separate
void tea_decipher (unsigned int32 * in,
unsigned int32 * out,
unsigned int32 * key)
{
unsigned int32 y, z, a, b, c, d,
sum = TEA_DEC_SUM;
signed int8 n = TEA_ITERATIONS;
y = in[0]; z = in[1];
a = key[0]; b = key[1];
c = key[2]; d = key[3];
while(n > 0) {
z -= y<<4;
z -= c^y;
z -= sum^(y>>5);
z -= d;
y -= z<<4;
y -= a^z;
y -= sum^(z>>5);
y -= b;
sum -= TEA_DELTA;
n--;
}
out[0] = y;
out[1] = z;
} |
The benchmark program for 16F877, test_tea16.c:
Code: | #define CLKSPEED 8000000
#include <16F877.h>
#fuses HS,PUT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=CLKSPEED)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#include "lcd.c"
#include "tea.c"
#include "string.h"
unsigned int16 t1cnt;
union tea_union {
char string[16];
unsigned int32 i32[4];
} in, out;
union tea_key {
char string[16];
unsigned int32 i32[4];
} key;
#int_timer1
void timer1_isr() {
t1cnt++;
}
#pragma zero_ram
void main() {
signed int8 i;
unsigned int16 ticks;
float time;
t1cnt = 0;
ticks = 0;
set_tris_a(0b11111111);
set_tris_b(0b11111111);
set_tris_c(0b00011111);
set_tris_e(0b11111111);
lcd_init();
strcpy(in.string, "-TEA-Benchmark-");
strcpy(key.string, "MyVerySecretKey");
// Triggers every (1/8000000)*4*1*65536 = 32.768 ms
// 1 unit = 0.0005 ms
setup_timer_1(T1_INTERNAL | T1_DIV_BY_1);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer1(0);
tea_encipher(in.i32, out.i32, key.i32);
tea_encipher(in.i32+2, out.i32+2, key.i32);
tea_decipher(out.i32, in.i32, key.i32);
tea_decipher(out.i32+2, in.i32+2, key.i32);
ticks = get_timer1();
disable_interrupts(INT_TIMER1);
disable_interrupts(GLOBAL);
time = (float)t1cnt * 32.768 + (float)ticks * 0.0005;
printf(lcd_putc, "\f %f ms", time);
delay_ms(5000);
printf(lcd_putc, "\fEnc: %s", out.string);
printf(lcd_putc, "\nDec: %s", in.string);
while (1) ;
}
|
The benchmark program for 18F452, test_tea18.c:
Code: | #define CLKSPEED 32000000
#include <18F452.h>
#fuses H4,PUT,NOWDT,NOPROTECT,NOLVP
#use delay(clock=CLKSPEED)
#use fast_io(A)
#use fast_io(B)
#use fast_io(C)
#use fast_io(D)
#use fast_io(E)
#include "lcd.c"
#include "tea.c"
#include "string.h"
unsigned int16 t1cnt;
union tea_union {
char string[16];
unsigned int32 i32[4];
} in, out;
union tea_key {
char string[16];
unsigned int32 i32[4];
} key;
#int_timer1
void timer1_isr() {
t1cnt++;
}
#pragma zero_ram
void main() {
signed int8 i;
unsigned int16 ticks;
float time;
t1cnt = 0;
ticks = 0;
set_tris_a(0b11111111);
set_tris_b(0b11111111);
set_tris_c(0b00011111);
set_tris_e(0b11111111);
lcd_init();
strcpy(in.string, "-TEA-Benchmark-");
strcpy(key.string, "MyVerySecretKey");
// Triggers every (1/32000000)*4*4*65536 = 32.768 ms
// 1 unit = 0.0005 ms
setup_timer_1(T1_INTERNAL | T1_DIV_BY_4);
enable_interrupts(INT_TIMER1);
enable_interrupts(GLOBAL);
set_timer1(0);
tea_encipher(in.i32, out.i32, key.i32);
tea_encipher(in.i32+2, out.i32+2, key.i32);
tea_decipher(out.i32, in.i32, key.i32);
tea_decipher(out.i32+2, in.i32+2, key.i32);
ticks = get_timer1();
disable_interrupts(INT_TIMER1);
disable_interrupts(GLOBAL);
time = (float)t1cnt * 32.768 + (float)ticks * 0.0005;
printf(lcd_putc, "\f %f ms", time);
delay_ms(5000);
printf(lcd_putc, "\fEnc: %s", out.string);
printf(lcd_putc, "\nDec: %s", in.string);
while (1) ;
} |
|
|
|
VanHauser
Joined: 03 Oct 2005 Posts: 88 Location: Ploiesti, Romania
|
XTEA - eXtended Tiny Encryption Algorithm |
Posted: Thu Feb 09, 2006 2:32 am |
|
|
I noticed on the forum a library for the XTEA encryption, a little more secure that TEA, so it is said. Here is an optimised version of that library. To test it, take the benchmarks from my post above and change "tea" to "xtea" everywhere.
xtea.c
Code: |
/*************************************************************/
/* */
/* XTEA - eXtended Tiny Encryption Algorithm */
/* */
/* Written by: Aurelian Nichita */
/* Compiler: CCS PIC C Compiler 3.242 */
/* Contact: nicksubzero@yahoo.com */
/* Source: http://en.wikipedia.org/wiki/XTEA */
/* */
/* */
/* Benchmark (one encipher/decipher cycle, 8 bytes) */
/* */
/* - PIC 16F877, 8 MHz, 32 iterations, */
/* ROM 776 bytes, RAM 26 bytes, time required 10.0175 ms */
/* */
/* - PIC 18F452, 32 MHz, 32 iterations, */
/* ROM 1296 bytes, RAM 30 bytes, time required 2.008 ms */
/* */
/* Code is optimised for size, RAM use and speed, */
/* it's 17% to 25% faster than the original XTEA code. */
/* It even fits in an 12F675, with quite some space left! */
/* */
/*************************************************************/
/* Number of iterations.
32 is ample, 16 is sufficient,
as few as eight should be OK for most applications. */
const signed int8 XTEA_ITERATIONS = 32;
/* The Golden ratio */
const unsigned int32 XTEA_DELTA = 0x9E3779B9;
/* Starting sum for decryption */
const unsigned int32 XTEA_DEC_SUM = 0xC6EF3720;
/* Enciphers 8 bytes using a 16-byte (128-bit) key.
"in" and "out" are arrays of two int32's,
"key" is an array of four int32's. */
#separate
void xtea_encipher (unsigned int32 * in,
unsigned int32 * out,
unsigned int32 * key)
{
unsigned int32 v0, v1, x, y, sum = 0;
signed int8 n = XTEA_ITERATIONS;
unsigned int8 i;
v0 = in[0]; v1 = in[1];
while(n > 0) {
x = v1 << 4;
y = v1 >> 5;
x ^= y;
x += v1;
i = make8(sum, 0); i &= 0x03;
y = sum + key[i];
x ^= y;
v0 += x;
sum += XTEA_DELTA;
x = v0 << 4;
y = v0 >> 5;
x ^= y;
x += v0;
i = make8(sum, 1); i >>= 3; i &= 0x03;
y = sum + key[i];
x ^= y;
v1 += x;
n--;
}
out[0] = v0;
out[1] = v1;
}
/* Deciphers 8 bytes using a 16-byte (128-bit) key.
"in" and "out" are arrays of two int32's,
"key" is an array of four int32's. */
#separate
void xtea_decipher (unsigned int32 * in,
unsigned int32 * out,
unsigned int32 * key)
{
unsigned int32 v0, v1, x, y, sum = XTEA_DEC_SUM;
signed int8 n = XTEA_ITERATIONS;
unsigned int8 i;
v0 = in[0]; v1 = in[1];
while(n > 0) {
x = v0 << 4;
y = v0 >> 5;
x ^= y;
x += v0;
i = make8(sum, 1); i >>= 3; i &= 0x03;
y = sum + key[i];
x ^= y;
v1 -= x;
sum -= XTEA_DELTA;
x = v1 << 4;
y = v1 >> 5;
x ^= y;
x += v1;
i = make8(sum, 0); i &= 0x03;
y = sum + key[i];
x ^= y;
v0 -= x;
n--;
}
out[0] = v0;
out[1] = v1;
}
|
|
|
|
marianoT
Joined: 16 Sep 2009 Posts: 1
|
TEA code error |
Posted: Wed Sep 16, 2009 2:09 pm |
|
|
Be careful this code don't work fine, operation y>>5 works unsigned and it produce a bad encryption. I compare the result of this encryption with one from a PC and is different. For that reason use
Code: |
for(i=0;i<5;i++)
shift_right(&v,4,sign);
|
instead where sign is 1 when signed a 0 when unsigned.
bye |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|