Skipjack分组加密算法是由美国国家安全局(NSA)从1985年开始设计,1990年完成评估,于1993年由美国政府正式对外宣布的,是"Capstone"(美国政府根据1987年国会通过的计算机安全法案所订立的长远计划)中的一个项目(另外三个项目分别是数字签名标准(DSA)、安全散列函数(SHA)及密钥交换方法)。Skipjack算法曾经被列为“机密”等级。
  Skipjack加密方法被应用在由NSA设计的Clipper芯片中。
  Skipjack算法使用80位密钥,对64位明文分组加密,在加密、解密过程中各包括了32轮重复的运算,可以采用4种操纵模式:ECB、CFB、OFB、CBC。
  Skipjack加密具体操作如下:
  先采用8步规则A的步进,再采用8步规则B的步进,再采用8步规则A的步进,最后采用8步规则B的步进。
  解密操作则相反:
  先采用8步规则B的步进,再采用8步规则A的步进,再采用8步规则B的步进,最后采用8步规则A的步进。
  规则A和规则B都使用了G置换。
  G置换(加密):输入g1,g2,输出g5,g6。(单位:字节)
  g(i+2)=F(g(i+1) XOR key(4k+i-1) ) XOR g(i) i=1,2,3,4
  G置换(解密):输入g5,g6,输出g1,g2。(单位:字节)
  g(i-2)=F(g(i-1) XOR key(4k+i-3) ) XOR g(i) i=1,2,3,4
  k为计数器,加密时每个步进加1,解密时减1。
  以上的函数F()为置换函数(具体如下)。
       x0    x1    x2    x3    x4    x5      x6    x7      x8    x9    xa    xb    xc      xd    xe    xf   
  0x 0xa3,0xd7,0x09,0x83,0xf8, 0x48,0xf6, 0xf4,  0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9
  1x 0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca, 0x2e, 0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28
  2x 0x0a,0xdf, 0x02,0xa0,0x17,0xf1, 0x60,0x68, 0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0xed,0x53
  3x 0x96,0x84,0x6b,0xba,0xf2, 0x63,0x9a,0x19, 0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2
  4x 0x39,0xb6,0x7b,0x0f, 0xc1,0x93,0x81, 0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8
  5x 0x55,0xb9,0xda,0x85,0x3f, 0x41,0xbf, 0xe0, 0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90
  6x 0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65, 0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76
  7x 0x97,0xfc, 0xb2,0xc2,0xb0,0xfe, 0xdb, 0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d
  8x 0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd, 0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18
  9x 0x89,0xcb,0x30,0x1f, 0x8d,0xc6,0x8f,  0xaa,0xc8,0x74,0xdc, 0xc9,0x5d,0x5c,0x31,0xa4
  ax 0x70,0x88,0x61,0x2c,0x9f, 0x0d,0x2b, 0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40
  bx 0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,  0x3b,0xcc, 0xfb, 0x7f, 0xab,0xe6,0x3e,0x5b,0xa5
  cx 0xad,0x04,0x23,0x9c,0x14,0x51,0x22, 0xf0, 0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2
  dx 0x0c,0xef, 0xbc,0x72,0x75,0x6f, 0x37, 0xa1,0xec,0xd3, 0x8e,0x62,0x8b,0x86,0x10,0xc8
  ex 0x08,0x77,0x11,0xbe,0x92,0x4f, 0x24, 0xc5,0x32,0x36,0x9d,0xcf,0xf
3,0xa6,0xbb,0xac
  fx 0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5, 0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46
  规则A(加密):输入w1,w2,w3,w4,输出r1,r2,r3,r4 单位:字=2字节 使用加密G置换
  r1=G(w1) XOR r4 XOR k;r2=G(w1); r3=w2; r4=w3;
  规则A(解密):输入w1,w2,w3,w4,输出r1,r2,r3,r4 单位:字=2字节 使用解密G置换
  r1=G(w2); r2=w3; r3=w4; r4=w1 XOR w2 XOR k-1
  规则B(加密):输入w1,w2,w3,w4,输出r1,r2,r3,r4 单位:字=2字节 使用加密G置换
  r1=w4; r2=G(w1); r3=w1 XOR w2 XOR k; r4=w3;
  规则B(加密):输入w1,w2,w3,w4,输出r1,r2,r3,r4 单位:字=2字节 使用解密G置换
  r1=G(w2); r2=G(w2) XOR w3 XOR k-1; r3=w4; r4=w1;
//skipjack.cpp
#include "skipjack.h"
void skipjack_encrypt(void *protext,void *ciptext,void *keytext)
{
unsigned short w[4],c=0;
unsigned char key[10];
memcpy(w,protext,8);
memcpy(key,keytext,10);
fa_encrypt(w,c,key, 0);fa_encrypt(w,c,key, 1);fa_encrypt(w,c,key, 2);fa_encrypt(w,c,key, 3);
fa_encrypt(w,c,key, 4);fa_encrypt(w,c,key, 5);fa_encrypt(w,c,key, 6);fa_encrypt(w,c,key, 7);
fb_encrypt(w,c,key, 8);fb_encrypt(w,c,key, 9);fb_encrypt(w,c,key,10);fb_encrypt(w,c,key,11);
fb_encrypt(w,c,key,12);fb_encrypt(w,c,key,13);fb_encrypt(w,c,key,14);fb_encrypt(w,c,key,15);
fa_encrypt(w,c,key,16);fa_encrypt(w,c,key,17);fa_encrypt(w,c,key,18);fa_encrypt(w,c,key,19);
fa_encrypt(w,c,key,20);fa_encrypt(w,c,key,21);fa_encrypt(w,c,key,22);fa_encrypt(w,c,key,23);
fb_encrypt(w,c,key,24);fb_encrypt(w,c,key,25);fb_encrypt(w,c,key,26);fb_encrypt(w,c,key,27);
fb_encrypt(w,c,key,28);fb_encrypt(w,c,key,29);fb_encrypt(w,c,key,30);
fb_encrypt(w,c,key,31);
memcpy(ciptext,w,8);
}
void skipjack_decrypt(void *protext,void *ciptext,void *keytext)
{
unsigned short w[4],c=32;
unsigned char key[10];
memcpy(w,ciptext,8);
memcpy(key,keytext,10);
fb_decrypt(w,c,key,31);fb_decrypt(w,c,key,30);fb_decrypt(w,c,key,29);fb_decrypt(w,c,key,28);
fb_decrypt(w,c,key,27);fb_decrypt(w,c,key,26);fb_decrypt(w,c,key,25);fb_decrypt(w,c,key,24);
fa_decrypt(w,c,key,23);fa_decrypt(w,c,key,22);fa_decrypt(w,c,key,21);fa_decrypt(w,c,key,20);
fa_decrypt(w,c,key,19);fa_decrypt(w,c,key,18);fa_decrypt(w,c,key,17);fa_decrypt(w,c,key,16);
fb_decrypt(w,c,key,15);fb_decrypt(w,c,key,14);fb_decrypt(w,c,key,13);fb_decrypt(w,c,key,12);
fb_decrypt(w,c,key,11);fb_decrypt(w,c,key,10);fb_decrypt(w,c,key, 9);fb_decrypt(w,c,key, 8);
fa_decrypt(w,c,key, 7);fa_decrypt(w,c,key, 6);fa_decrypt(w,c,key, 5);fa_decrypt(w,c,key, 4);
fa_decrypt(w,c,key, 3);fa_decrypt(w,c,key, 2);fa_decrypt(w,c,key, 1);fa_decrypt(w,c,key, 0);
memcpy(protext,w,8);
}
void fa_encrypt(unsigned short *w,unsigned short &c,unsigned char *key,int k)
{
unsigned short temp;
temp=w[1];
w[1]=g_encrypt(w[0],key,k);
w[0]=w[1]^w[3]^(c++);
w[3]=w[2];
w[2]=temp;
}
void fa_decrypt(unsigned short *w,unsigned short &c,unsigned char *key,int k)
{
unsigned short temp;
temp=w[3];
w[3]=w[0]^w[1]^(--c);
w[0]=g_decrypt(w[1],key,k);
w[1]=w[2];
w[2]=temp;
}
void fb_encrypt(unsigned short *w,unsigned short &c,unsigned char *key,int k)
{
unsigned short temp;
temp=w[2];
w[2]=w[0]^w[1]^(c++);
w[1]=g_encrypt(w[0],key,k);
w[0]=w[3];
w[3]=temp;
}
void fb_decrypt(unsigned short *w,unsigned short &c,unsigned char *key,int k)
{
unsigned short temp;
temp=w[0];
w[0]=g_decrypt(w[1],key,k);
w[1]=w[0]^w[2]^(--c);
w[2]=w[3];
w[3]=temp;
}
unsigned short g_encrypt(unsigned short a,unsigned char *key,int k)
{
unsigned char g[6];
memcpy(g,&a,2);
g[2]=f[g[1]^key[((k<<2)  )%10]]^g[0];
g[3]=f[g[2]^key[((k<<2)+1)%10]]^g[1];
g[4]=f[g[3]^key[((k<<2)+2)%10]]^g[2];
g[5]=f[g[4]^key[((k<<2)+3)%10]]^g[3];
memcpy(&a,&g[4],2);
return(a);
}
unsigned short g_decrypt(unsigned short a,unsigned char *key,int k)
{
unsigned char g[6];
4k电影源代码memcpy(&g[4],&a,2);
g[3]=f[g[4]^key[((k<<2)+3)%10]]^g[5];
g[2]=f[g[3]^key[((k<<2)+2)%10]]^g[4];
g[1]=f[g[2]^key[((k<<2)+1)%10]]^g[3];
g[0]=f[g[1]^key[((k<<2)  )%10]]^g[2];
memcpy(&a,g,2);
return(a);
}
//skipjack.h
#ifndef SKIPJACKH
#define SKIPJACKH
#include<string.h>
#include<stdlib.h>
const unsigned char f[256]=
{0xa3,0xd7,0x09,0x83,0xf8,0x48,0xf6,0xf4,0xb3,0x21,0x15,0x78,0x99,0xb1,0xaf,0xf9
,
0xe7,0x2d,0x4d,0x8a,0xce,0x4c,0xca,0x2e,0x52,0x95,0xd9,0x1e,0x4e,0x38,0x44,0x28
,0x0a,0xdf,0x02,0xa0,0x17,0xf1,0x60,0x68,0x12,0xb7,0x7a,0xc3,0xe9,0xfa,0xed,0x53
,0x96,0x84,0x6b,0xba,0xf2,0x63,0x9a,0x19,0x7c,0xae,0xe5,0xf5,0xf7,0x16,0x6a,0xa2
,0x39,0xb6,0x7b,0x0f,0xc1,0x93,0x81,0x1b,0xee,0xb4,0x1a,0xea,0xd0,0x91,0x2f,0xb8
,0x55,0xb9,0xda,0x85,0x3f,0x41,0xbf,0xe0,0x5a,0x58,0x80,0x5f,0x66,0x0b,0xd8,0x90
,0x35,0xd5,0xc0,0xa7,0x33,0x06,0x65,0x69,0x45,0x00,0x94,0x56,0x6d,0x98,0x9b,0x76
,0x97,0xfc,0xb2,0xc2,0xb0,0xfe,0xdb,0x20,0xe1,0xeb,0xd6,0xe4,0xdd,0x47,0x4a,0x1d
,0x42,0xed,0x9e,0x6e,0x49,0x3c,0xcd,0x43,0x27,0xd2,0x07,0xd4,0xde,0xc7,0x67,0x18
,0x89,0xcb,0x30,0x1f,0x8d,0xc6,0x8f,0xaa,0xc8,0x74,0xdc,0xc9,0x5d,0x5c,0x31,0xa4
,0x70,0x88,0x61,0x2c,0x9f,0x0d,0x2b,0x87,0x50,0x82,0x54,0x64,0x26,0x7d,0x03,0x40
,0x34,0x4b,0x1c,0x73,0xd1,0xc4,0xfd,0x3b,0xcc,0xfb,0x7f,0xab,0xe6,0x3e,0x5b,0xa5
,
0xad,0x04,0x23,0x9c,0x14,0x51,0x22,0xf0,0x29,0x79,0x71,0x7e,0xff,0x8c,0x0e,0xe2
,0x0c,0xef,0xbc,0x72,0x75,0x6f,0x37,0xa1,0xec,0xd3,0x8e,0x62,0x8b,0x86,0x10,0xc8
,0x08,0x77,0x11,0xbe,0x92,0x4f,0x24,0xc5,0x32,0x36,0x9d,0xcf,0xf3,0xa6,0xbb,0xac
,0x5e,0x6c,0xa9,0x13,0x57,0x25,0xb5,0xe3,0xbd,0xa8,0x3a,0x01,0x05,0x59,0x2a,0x46};
void skipjack_encrypt(void*,void*,void*);
void skipjack_decrypt(void*,void*,void*);
void fa_encrypt(unsigned short*,unsigned short&,unsigned char*,int);
void fa_decrypt(unsigned short*,unsigned short&,unsigned char*,int);
void fb_encrypt(unsigned short*,unsigned short&,unsigned char*,int);
void fb_decrypt(unsigned short*,unsigned short&,unsigned char*,int);
unsigned short g_encrypt(unsigned short
,
unsigned char*,int);
unsigned short g_decrypt(unsigned short,unsigned char*,int);
#endif