svn: ecrypt/trunk/submissions/dicing/dicing.c
File:
[svn] /
ecrypt /
trunk /
submissions /
dicing / dicing.c
(
download)
(
as text)
Revision:
37,
Mon Aug 1 15:12:50 2005 UTC (7 years, 10 months ago) by
cdecanni
File size: 12071 byte(s)
* original submission after first automatic cleanup.
/*******************************************************************************
Synchronous Stream Cipher : DICING
author: Li An-Ping
*******************************************************************************/
#include "ecrypt-sync.h"
#define SL 64
static const u8 sbox[256]={
0xd5,0xbd,0x5,0x0,0xf0,0x68,0x3,0xb3,0xe5,0x6b,
0xa3,0xef,0x92,0x3b,0x36,0xdb,0xc7,0x98,0x1,0xe8,
0xb9,0xf1,0x7a,0xb0,0x50,0x4f,0xbf,0x34,0x4e,0xf9,
0xfd,0x78,0x2c,0xf8,0x59,0xc6,0x82,0x8c,0x2b,0xe0,
0x55,0x3f,0xb7,0x84,0x85,0xf6,0x61,0xc3,0xaf,0x20,
0x2f,0xdc,0x6f,0xc8,0xb5,0x1b,0x8b,0xc,0x12,0xac,
0xdd,0xe3,0x1f,0x49,0x26,0xba,0xf7,0x74,0x97,0x21,
0x60,0xb1,0xb6,0xf,0x4d,0x4c,0x5b,0x8e,0xd1,0xd2,
0x69,0xaa,0x67,0x58,0xd9,0x75,0xde,0x3d,0x47,0xa9,
0x83,0xc9,0x9c,0xa0,0x11,0xed,0x3a,0x4a,0x48,0x1a,
0xca,0x57,0xfb,0xee,0x5d,0x39,0x8a,0x96,0x13,0xf5,
0xf2,0x28,0xe9,0xe4,0x62,0x3c,0x30,0xfc,0x5f,0xcf,
0xa1,0xd3,0x66,0xcd,0xfa,0xe2,0xb4,0x27,0xd7,0x15,
0x6a,0x63,0x33,0x38,0x8,0x9d,0xd8,0x51,0xe7,0x7c,
0xe1,0x44,0x6d,0x16,0xa2,0x88,0x2a,0x70,0x5a,0x52,
0x73,0xa4,0x71,0x2d,0xfe,0x46,0x7d,0x29,0xec,0x41,
0x1e,0x7f,0x17,0x42,0x31,0x23,0x37,0xea,0x72,0x89,
0x94,0xae,0xc5,0xa7,0xab,0x9b,0xd6,0x76,0x19,0xd0,
0x9e,0x91,0x53,0x81,0x7e,0x8f,0x93,0x7b,0x18,0xa5,
0x40,0xf3,0x4b,0x35,0x2e,0x6e,0x45,0x80,0x32,0xa6,
0xad,0xda,0xd4,0x10,0x9f,0xbb,0x54,0xe6,0x14,0x4,
0x7,0xbc,0x79,0xff,0x43,0xeb,0xcb,0xa8,0x5c,0x64,
0xb8,0x1c,0xe,0x86,0xd,0xc2,0xb2,0x56,0x24,0x3e,
0x5e,0x9,0x25,0x6c,0xa,0x6,0x1d,0x99,0x2,0xf4,
0x77,0x87,0x90,0x95,0xcc,0xb,0xc4,0xbe,0x9a,0xc1,
0x8d,0xc0,0x65,0x22,0xce,0xdf
};
static const u32 ct[8]={
0xb17217f8,
0x8c9f53d5,
0xce020fbf,
0xf9139572,
0x99771dbc,
0xa428215a,
0xb5535e10,
0xbc71b030
};
void ECRYPT_init()
{
}
void ECRYPT_keysetup(ECRYPT_ctx* ctx, const u8* key, u32 keysize, u32 ivsize)
{
int i,length;
u8* pt;
ctx->key_size=keysize;
ctx->iv_size=ivsize;
length = keysize>>3;
pt=ctx->key;
for(i=0;i<length;i+=4)
*((u32*)(pt+i))=*((u32*)(key+i));
}
void ECRYPT_ivsetup(ECRYPT_ctx* ctx, const u8* iv)
{
initiate(ctx,iv);
selfcycl(ctx);
}
void ECRYPT_keystream_bytes( ECRYPT_ctx* ctx, u8* keystream, u32 length)
{
while(length>=16){
if(stream(ctx,keystream)>0){
length-=16;
keystream+=16;
}
}
while(length>0){
u8 temp[16]={0};
int i;
if(stream(ctx,temp)>0){
for(i=0;i<length;i++)
keystream[i]=temp[i];
length=0;
}
}
}
void ECRYPT_encrypt_bytes(ECRYPT_ctx* ctx,const u8* plaintext,u8* ciphertext,u32 msglen)
{
u8 temp[16];
int i;
while(msglen>=16){
if(stream(ctx,temp)>0){
for(i=0;i<16;i+=4)
*((u32*)(ciphertext+i))=*((u32*)(plaintext+i))^*((u32*)(temp+i));
msglen-=16;
plaintext+=16;
ciphertext+=16;
}
}
while(msglen>0){
if(stream(ctx,temp)>0){
for(i=0;i<msglen;i++)
*(ciphertext+i)=*(plaintext+i)^*(temp+i);
msglen=0;
}
}
}
void ECRYPT_decrypt_bytes(ECRYPT_ctx* ctx,const u8* ciphertext,u8* plaintext,u32 msglen)
{
u8 temp[16];
int i;
while(msglen>=16){
if(stream(ctx,temp)>0){
for(i=0;i<16;i+=4)
*((u32*)(plaintext+i))=*((u32*)(ciphertext+i))^*((u32*)(temp+i));
msglen-=16;
plaintext+=16;
ciphertext+=16;
}
}
while(msglen>0){
if(stream(ctx,temp)>0){
for(i=0;i<msglen;i++)
*(plaintext+i)=*(ciphertext+i)^*(temp+i);
msglen=0;
}
}
}
/*******************************************************************************
initialize function
*******************************************************************************/
void initiate(ECRYPT_ctx* ctx,const u8* iv)
{
int i;
for(i=0;i<16;i+=4)
*((u32*)(ctx->skey1+i))=*((u32*)(ctx->key+i))^*((u32*)(iv+i))^ct[(i>>2)];
if(ctx->key_size==256)
for(i=0;i<16;i+=4)
*((u32*)(ctx->skey2+i))=*((u32*)(ctx->key+16+i))^*((u32*)(iv+16+i))^ct[4+(i>>2)];
else {
for(i=0;i<16;i+=4)
*((u32*)(ctx->skey2+i))=(~(*((u32*)(ctx->key+i))^*((u32*)(iv+i))))^ct[4+(i>>2)];
}
for(i=0;i<16;i++)
{
ctx->skey1[i]=*(sbox+ctx->skey1[i]);
ctx->skey2[i]=*(sbox+ctx->skey2[i]);
}
u32 temp=0;
for(i=0;i<16;i+=4)
{
temp^=(*((u32*)(ctx->skey1+i))^*((u32*)(ctx->skey2+i)));
}
temp^=(temp>>16);
temp^=(temp>>8);
temp&=255;
temp=temp|(temp<<8)|(temp<<16)|(temp<<24);
for(i=0;i<16;i+=4)
{
*((u32*)(ctx->ckey1+i))=*((u32*)(ctx->skey1+i))^temp^(~ct[i>>2]);
*((u32*)(ctx->ckey2+i))=*((u32*)(ctx->skey2+i))^temp^(~ct[4+(i>>2)]);
}
*(ctx->skey1+15)&=127;
*(ctx->skey2+15)&=63;
for(i=0;i<16;i++)
{
ctx->ckey1[i]=*(sbox+ctx->ckey1[i]);
ctx->ckey2[i]=*(sbox+ctx->ckey2[i]);
}
}
/*******************************************************************************
self-cycling function
*******************************************************************************/
void selfcycl(ECRYPT_ctx* ctx)
{
int i,k;
u8 *ckey1,*ckey2;
ckey1=ctx->ckey1,ckey2=ctx->ckey2;
u8 *s1,*s2;
s1=ctx->skey1+64;
s2=ctx->skey2+64;
for(i=0;i<16;i+=4)
*((u32*)(s1+i))=*((u32*)(ctx->skey1+i));
for(i=0;i<16;i+=4)
*((u32*)(ctx->skey1+i))=0;
for(i=0;i<16;i+=4)
*((u32*)(s2+i))=*((u32*)(ctx->skey2+i));
for(i=0;i<16;i+=4)
*((u32*)(ctx->skey2+i))=0;
for(k=0;k<64;k++)
{
if(k<=32){
for(i=0;i<16;i+=4)
{
*((u32*)(ctx->mkey+i))&=(*((u32*)(s1+i))^*((u32*)(s2+i)));
*((u32*)(ctx->mkey+i))^=(*((u32*)(ckey1+i))^*((u32*)(ckey2+i)));
}
}
if(k==32){
for(i=0;i<16;i+=4)
*((u32*)(ctx->ch+i))=*((u32*)(ckey1+i))^*((u32*)(ckey2+i));
extendsbox(ctx);
}
s1--,s2--;
u32 temp,n1,n2;
temp=*((u32*)(s1+15));
temp>>=7;
n1=temp;
temp^=(temp<<3);
*((u32*)(s1))^=temp;
temp<<=1;
*((u32*)(s1+5))^=temp;
*((u32*)(s1+11))^=temp;
*((u32*)(s1+15))&=127;
temp=*((u32*)(s2+15));
temp>>=6;
n2=temp;
temp^=(temp<<7);
*((u32*)(s2))^=temp;
temp<<=3;
*((u32*)(s2+4))^=temp;
*((u32*)(s2+10))^=temp;
*((u32*)(s2+15))&=63;
int n,m;
n=(n1^n2)&15;
m=32-n;
if(n>0)
{
temp=0;
for(i=0;i<16;i+=4)
{
u32 z=*((u32*)(ckey1+i));
*((u32*)(ckey1+i))=temp^(z<<n);
temp=(z>>m);
}
u32 z=temp^(temp<<2)^(temp<<7);
*((u32*)(ckey1))^=z;
*((u32*)(ckey1+4))^=(z<<3);
*((u32*)(ckey1+7))^=(z<<1);
*((u32*)(ckey1+11))^=(z<<2);
}
n=(n1^n2)>>4;
m=32-n;
if(n>0)
{
temp=0;
for(i=0;i<16;i+=4)
{
u32 z=*((u32*)(ckey2+i));
*((u32*)(ckey2+i))=temp^(z<<n);
temp=(z>>m);
}
u32 z=temp^(temp<<1)^(temp<<7);
*((u32*)(ckey2))^=z;
*((u32*)(ckey2+3))^=(z<<3);
*((u32*)(ckey2+7))^=(z<<2);
*((u32*)(ckey2+12))^=(z<<1);
}
for(i=0;i<16;i+=4)
*((u32*)(ctx->var1+i))^=*((u32*)(ckey1+i));
for(i=0;i<16;i+=4)
*((u32*)(ctx->var2+i))^=*((u32*)(ckey2+i));
}
}
/*******************************************************************************
keystream function
*******************************************************************************/
int stream(ECRYPT_ctx* ctx,u8 *rkey)
{
static int cyl=0;
int i;
/*......Updading States......*/
if(cyl==0)
{
for(i=0;i<16;i+=4)
{
*((u32*)(ctx->skey1+i+SL))=*((u32*)(ctx->skey1+i));
*((u32*)(ctx->skey1+i))=0;
*((u32*)(ctx->skey2+i+SL))=*((u32*)(ctx->skey2+i));
*((u32*)(ctx->skey2+i))=0;
}
cyl=SL;
}
cyl-=1;
u8 *csk1,*csk2;
csk1=ctx->skey1+cyl;
csk2=ctx->skey2+cyl;
u32 n1,n2,temp;
temp=*((u32*)(csk1+15));
temp>>=7;
n1=temp;
temp^=(temp<<3);
*((u32*)(csk1))^=temp;
temp<<=1;
*((u32*)(csk1+5))^=temp;
*((u32*)(csk1+11))^=temp;
*((u32*)(csk1+15))&=127;
temp=*((u32*)(csk2+15));
temp>>=6;
n2=temp;
temp^=(temp<<7);
*((u32*)(csk2))^=temp;
temp<<=3;
*((u32*)(csk2+4))^=temp;
*((u32*)(csk2+10))^=temp;
*((u32*)(csk2+15))&=63;
csk1=ctx->ckey1,csk2=ctx->ckey2;
int n,m;
n=(n1^n2)&15;
m=32-n;
if(n>0)
{
temp=0;
for(i=0;i<16;i+=4)
{
u32 z=*((u32*)(csk1+i));
*((u32*)(csk1+i))=temp^(z<<n);
temp=(z>>m);
}
u32 z=temp^(temp<<2)^(temp<<7);
*((u32*)(csk1))^=z;
*((u32*)(csk1+4))^=(z<<3);
*((u32*)(csk1+7))^=(z<<1);
*((u32*)(csk1+11))^=(z<<2);
}
n=(n1^n2)>>4;
m=32-n;
if(n>0)
{
temp=0;
for(i=0;i<16;i+=4)
{
u32 z=*((u32*)(csk2+i));
*((u32*)(csk2+i))=temp^(z<<n);
temp=(z>>m);
}
u32 z=temp^(temp<<1)^(temp<<7);
*((u32*)(csk2))^=z;
*((u32*)(csk2+3))^=(z<<3);
*((u32*)(csk2+7))^=(z<<2);
*((u32*)(csk2+12))^=(z<<1);
}
for(i=0;i<16;i+=4)
*((u32*)(ctx->var1+i))^=*((u32*)(csk1+i));
for(i=0;i<16;i+=4)
*((u32*)(ctx->var2+i))^=*((u32*)(csk2+i));
/* ...... Updating end ...... */
/*......Combining sub-process......*/
if(n1>n2)
{
u8 c[16]={0};
u8 *pt1,*pt2,*pt3;
pt1=c,pt2=ctx->var1,pt3=ctx->var2;
*((u32*)(pt1))=*(ctx->sbox0+pt2[0])^*(ctx->sbox1+pt2[1])^*(ctx->sbox2+pt2[2])^*(ctx->sbox3+pt2[3])^*((u32*)(pt3));
pt1+=4,pt2+=4,pt3+=4;
*((u32*)(pt1))=*(ctx->sbox0+pt2[0])^*(ctx->sbox1+pt2[1])^*(ctx->sbox2+pt2[2])^*(ctx->sbox3+pt2[3])^*((u32*)(pt3));
pt1+=4,pt2+=4,pt3+=4;
*((u32*)(pt1))=*(ctx->sbox0+pt2[0])^*(ctx->sbox1+pt2[1])^*(ctx->sbox2+pt2[2])^*(ctx->sbox3+pt2[3])^*((u32*)(pt3));
pt1+=4,pt2+=4,pt3+=4;
*((u32*)(pt1))=*(ctx->sbox0+pt2[0])^*(ctx->sbox1+pt2[1])^*(ctx->sbox2+pt2[2])^*(ctx->sbox3+pt2[3])^*((u32*)(pt3));
pt1=rkey,pt2=ctx->ch;
*((u32*)(pt1))=*(ctx->sbox0+*(c+0))^*(ctx->sbox1+*(c+5))^*(ctx->sbox2+*(c+10))^*(ctx->sbox3+*(c+15))^*((u32*)(pt2));
pt1+=4,pt2+=4;
*((u32*)(pt1))=*(ctx->sbox0+*(c+4))^*(ctx->sbox1+*(c+9))^*(ctx->sbox2+*(c+14))^*(ctx->sbox3+*(c+3))^*((u32*)(pt2));
pt1+=4,pt2+=4;
*((u32*)(pt1))=*(ctx->sbox0+*(c+8))^*(ctx->sbox1+*(c+13))^*(ctx->sbox2+*(c+2))^*(ctx->sbox3+*(c+7))^*((u32*)(pt2));
pt1+=4,pt2+=4;
*((u32*)(pt1))=*(ctx->sbox0+*(c+12))^*(ctx->sbox1+*(c+1))^*(ctx->sbox2+*(c+6))^*(ctx->sbox3+*(c+11))^*((u32*)(pt2));
return(1);
}
else if(n1<n2)
{
u8 c[16]={0};
u8 *pt1,*pt2,*pt3;
pt1=c,pt2=ctx->var2,pt3=ctx->var1;
*((u32*)(pt1))=*(ctx->sbox0+pt2[0])^*(ctx->sbox1+pt2[1])^*(ctx->sbox2+pt2[2])^*(ctx->sbox3+pt2[3])^*((u32*)(pt3));
pt1+=4,pt2+=4,pt3+=4;
*((u32*)(pt1))=*(ctx->sbox0+pt2[0])^*(ctx->sbox1+pt2[1])^*(ctx->sbox2+pt2[2])^*(ctx->sbox3+pt2[3])^*((u32*)(pt3));
pt1+=4,pt2+=4,pt3+=4;
*((u32*)(pt1))=*(ctx->sbox0+pt2[0])^*(ctx->sbox1+pt2[1])^*(ctx->sbox2+pt2[2])^*(ctx->sbox3+pt2[3])^*((u32*)(pt3));
pt1+=4,pt2+=4,pt3+=4;
*((u32*)(pt1))=*(ctx->sbox0+pt2[0])^*(ctx->sbox1+pt2[1])^*(ctx->sbox2+pt2[2])^*(ctx->sbox3+pt2[3])^*((u32*)(pt3));
pt1=rkey,pt2=ctx->ch;
*((u32*)(pt1))=*(ctx->sbox0+*(c+0))^*(ctx->sbox1+*(c+5))^*(ctx->sbox2+*(c+10))^*(ctx->sbox3+*(c+15))^*((u32*)(pt2));
pt1+=4,pt2+=4;
*((u32*)(pt1))=*(ctx->sbox0+*(c+4))^*(ctx->sbox1+*(c+9))^*(ctx->sbox2+*(c+14))^*(ctx->sbox3+*(c+3))^*((u32*)(pt2));
pt1+=4,pt2+=4;
*((u32*)(pt1))=*(ctx->sbox0+*(c+8))^*(ctx->sbox1+*(c+13))^*(ctx->sbox2+*(c+2))^*(ctx->sbox3+*(c+7))^*((u32*)(pt2));
pt1+=4,pt2+=4;
*((u32*)(pt1))=*(ctx->sbox0+*(c+12))^*(ctx->sbox1+*(c+1))^*(ctx->sbox2+*(c+6))^*(ctx->sbox3+*(c+11))^*((u32*)(pt2));
return(1);
}
else return(0);
}
/*******************************************************************************
extending S-boxes function
*******************************************************************************/
void extendsbox(ECRYPT_ctx* ctx)
{
int i,k;
u8 x,z;
u8 w[8]={0},y[8]={0};
u8* mkey;
mkey=ctx->mkey;
x=1,z=254;
for(i=0;i<8;i++)
{
w[i]=(x^(mkey[i]&z));
y[i]=(x^(mkey[8+i]&z));
x<<=1;
z^=x;
}
for(k=7;k>=0;k--)
{
x=mkey[k];
for(i=0;i<k;i++)
{
if((x&1)==1)w[k]^=w[i];
x>>=1;
}
}
for(k=7;k>=0;k--)
{
x=mkey[8+k];
for(i=0;i<k;i++)
{
if((x&1)==1)y[k]^=y[i];
x>>=1;
}
}
u8 c1=0,c2=0;
x=1;
for(i=0;i<8;i++)
{
c1^=(mkey[i]&x);
x<<=1;
}
x=1;
for(i=0;i<8;i++)
{
c2^=(mkey[8+i]&x);
x<<=1;
}
u32 tabl[256]={0};
tabl[0]=c1|(c2<<8)|(c1<<16)|((c1^c2)<<24);
int n=1;
for(k=0;k<8;k++)
{
x= w[k],z=y[k];
u32 temp=x|(z<<8)|(x<<16)|((x^z)<<24);
for(i=0;i<n;i++)
{
*(tabl+(i|n))=*(tabl+i)^temp;
}
n<<=1;
}
for(k=0;k<256;k++)
{
u32 v=*(tabl+sbox[k]);
*(ctx->sbox0+k)=v;
*(ctx->sbox1+k)=(v>>8)|(v<<24);
*(ctx->sbox2+k)=(v>>16)|(v<<16);
*(ctx->sbox3+k)=(v>>24)|(v<<8);
}
}