#include <avr/io.h>
#include <avr/pgmspace.h>
-#define SKIPJACK_CNT_BIG
+#if NESSIE_COMPAT
+#define SKIPJACK_CNT_BIG 1
+#else
+#define SKIPJACK_CNT_BIG 0
+#endif
-#ifdef SKIPJACK_CNT_BIG
+#if SKIPJACK_CNT_BIG
#define SKIPJACK_CNT_SHIFT <<8
#else
#define SKIPJACK_CNT_SHIFT
/*****************************************************************************/
-uint8_t skipjack_ftable[] PROGMEM ={
+const uint8_t skipjack_ftable[] PROGMEM ={
0xa3, 0xd7, 0x09, 0x83, 0xf8, 0x48, 0xf6, 0xf4,
0xb3, 0x21, 0x15, 0x78, 0x99, 0xb1, 0xaf, 0xf9,
0xe7, 0x2d, 0x4d, 0x8a, 0xce, 0x4c, 0xca, 0x2e,
};
/*****************************************************************************/
+static
+uint16_t skipjack_sub_g(uint8_t g, uint8_t k, uint8_t *key){
+ return pgm_read_byte(&(skipjack_ftable[g ^ key[9 - k % 10]]));
+}
+static
uint16_t skipjack_g(uint16_t g, uint8_t k, uint8_t *key){
- #define G1 (((uint8_t*)&g)[0])
- #define G2 (((uint8_t*)&g)[1])
+ #define G1 (((uint8_t*)&g)[1])
+ #define G2 (((uint8_t*)&g)[0])
/* this could also be rolled up */
- G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+0)%10]]));
- G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+1)%10]]));
- G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+2)%10]]));
- G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+3)%10]]));
+ k *= 4;
+ G1 ^= skipjack_sub_g(G2, k + 0, key);
+ G2 ^= skipjack_sub_g(G1, k + 1, key);
+ G1 ^= skipjack_sub_g(G2, k + 2, key);
+ G2 ^= skipjack_sub_g(G1, k + 3, key);
return g;
}
/*****************************************************************************/
-
+static
uint16_t skipjack_g_inv(uint16_t g, uint8_t k, uint8_t *key){
// #define G1 (((uint8_t)&g)[1])
// #define G2 (((uint8_t)&g)[0])
/* this could also be rolled up */
- G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+3)%10]]));
- G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+2)%10]]));
- G2 ^= pgm_read_byte_near(&(skipjack_ftable[G1 ^ key[(4*k+1)%10]]));
- G1 ^= pgm_read_byte_near(&(skipjack_ftable[G2 ^ key[(4*k+0)%10]]));
- return g;
+ k *= 4;
+ G2 ^= skipjack_sub_g(G1, k + 3, key);
+ G1 ^= skipjack_sub_g(G2, k + 2, key);
+ G2 ^= skipjack_sub_g(G1, k + 1, key);
+ G1 ^= skipjack_sub_g(G2, k + 0, key);
+ return g;
}
/*****************************************************************************/
-
+static
void skipjack_a(uint16_t* w, uint8_t k, uint8_t* key){
uint16_t t;
-
- t = w[3];
- w[3] = w[2];
- w[2] = w[1];
- w[1] = skipjack_g(w[0],k-1,key);
- w[0] = t ^ w[1] ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
+ t = w[0];
+ w[0] = w[1];
+ w[1] = w[2];
+ w[2] = skipjack_g(w[3],k,key);
+ w[3] = t ^ w[2] ^ (((uint16_t)k+1)SKIPJACK_CNT_SHIFT);
}
/*****************************************************************************/
-
+static
void skipjack_a_inv(uint16_t* w, uint8_t k, uint8_t* key){
uint16_t t;
- t = w[0] ^ w[1];
- w[0] = skipjack_g_inv(w[1],k-1,key);
- w[1] = w[2];
- w[2] = w[3];
- w[3] = t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
+ t = w[3] ^ w[2];
+ w[3] = skipjack_g_inv(w[2],k,key);
+ w[2] = w[1];
+ w[1] = w[0];
+ w[0] = t ^ (((uint16_t)k+1)SKIPJACK_CNT_SHIFT);
}
/*****************************************************************************/
-
+static
void skipjack_b(uint16_t* w, uint8_t k, uint8_t* key){
uint16_t t;
- t = w[0];
- w[0] = w[3];
- w[3] = w[2];
- w[2] = t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT) ^ w[1];
- w[1] = skipjack_g(t,k-1,key);
+ t = w[3];
+ w[3] = w[0];
+ w[0] = w[1];
+ w[1] = t ^ (((uint16_t)k+1)SKIPJACK_CNT_SHIFT) ^ w[2];
+ w[2] = skipjack_g(t,k,key);
}
/*****************************************************************************/
-
+static
void skipjack_b_inv(uint16_t* w, uint8_t k, uint8_t* key){
uint16_t t;
- t = w[2];
- w[2] = w[3];
- w[3] = w[0];
- w[0] = skipjack_g_inv(w[1],k-1,key);
- w[1] = w[0] ^ t ^ (((uint16_t)k)SKIPJACK_CNT_SHIFT);
+ t = w[1];
+ w[1] = w[0];
+ w[0] = w[3];
+ w[3] = skipjack_g_inv(w[2],k,key);
+ w[2] = w[3] ^ t ^ (((uint16_t)k+1)SKIPJACK_CNT_SHIFT);
}
/*****************************************************************************/
uint8_t k;
for(k=0; k<32; ++k){
if(k & 0x08){
- skipjack_b((uint16_t*)block, k+1, key);
+ skipjack_b((uint16_t*)block, k, key);
} else {
- skipjack_a((uint16_t*)block, k+1, key);
+ skipjack_a((uint16_t*)block, k, key);
}
}
}
-
/*****************************************************************************/
/**
* block is 64 bits (=8 bytes) in size, key is 80 bits (=10 bytes) in size.
int8_t k;
for(k=31; k>=0; --k){
if(k & 0x08){
- skipjack_b_inv((uint16_t*)block, k+1, key);
+ skipjack_b_inv((uint16_t*)block, k, key);
} else {
- skipjack_a_inv((uint16_t*)block, k+1, key);
+ skipjack_a_inv((uint16_t*)block, k, key);
}
}
}