add SMS4 bit slice

16X SMS4 a time
This commit is contained in:
CXdickens
2018-05-21 15:17:54 +08:00
parent 58464004c9
commit 7c0ddf2e44
3 changed files with 977 additions and 0 deletions

893
crypto/sms4/sm4_bs.c Normal file
View File

@@ -0,0 +1,893 @@
#include <stdio.h>
#include "sm4_bs.h"
#define GF4_inver(a) ((a)^(((a)>>1)&0x1111111111111111))
#define bit_4bit(a) ((((bit_2bit(a)<<1)^(a))<<1)^(a))
#define bit_2bit(a) (((a)<<1)^(a))
#define GF4X2(a,b) (((b)&(bit_2bit((a)&0x1111111111111111)))^(((b)<<1)&(bit_4bit(((a)>>1)&0x1111111111111111)))^(0x7777777777777777&(bit_4bit((((a)&(b))>>1)&0x1111111111111111))))
#define GF16X2(a,b) (JZ2_4(GF4_2_X((JZ4_2((a))),(JZ4_2((b))))))
#define GB(a,b) ((a)>>(b))&0x1111111111111111
unsigned __int64 CKH[2][16][4]=
{
{
{0x0000000000000000,0x0000000000000000,0x0000000000000000,0x1111111111111111},
{0x1111111111111111,0x2222222222222222,0x2222222222222222,0x3333333333333333},
{0x3333333333333333,0x3333333333333333,0x4444444444444444,0x4444444444444444},
{0x5555555555555555,0x5555555555555555,0x6666666666666666,0x6666666666666666},
{0x7777777777777777,0x7777777777777777,0x7777777777777777,0x8888888888888888},
{0x8888888888888888,0x9999999999999999,0x9999999999999999,0xaaaaaaaaaaaaaaaa},
{0xaaaaaaaaaaaaaaaa,0xaaaaaaaaaaaaaaaa,0xbbbbbbbbbbbbbbbb,0xbbbbbbbbbbbbbbbb},
{0xcccccccccccccccc,0xcccccccccccccccc,0xdddddddddddddddd,0xdddddddddddddddd},
{0xeeeeeeeeeeeeeeee,0xeeeeeeeeeeeeeeee,0xeeeeeeeeeeeeeeee,0xffffffffffffffff},
{0xffffffffffffffff,0x0000000000000000,0x0000000000000000,0x1111111111111111},
{0x1111111111111111,0x1111111111111111,0x2222222222222222,0x2222222222222222},
{0x3333333333333333,0x3333333333333333,0x4444444444444444,0x4444444444444444},
{0x5555555555555555,0x5555555555555555,0x5555555555555555,0x6666666666666666},
{0x6666666666666666,0x7777777777777777,0x7777777777777777,0x8888888888888888},
{0x8888888888888888,0x8888888888888888,0x9999999999999999,0x9999999999999999},
{0xaaaaaaaaaaaaaaaa,0xaaaaaaaaaaaaaaaa,0xbbbbbbbbbbbbbbbb,0xbbbbbbbbbbbbbbbb}
},
{
{0xcccccccccccccccc,0xcccccccccccccccc,0xcccccccccccccccc,0xdddddddddddddddd},
{0xdddddddddddddddd,0xeeeeeeeeeeeeeeee,0xeeeeeeeeeeeeeeee,0xffffffffffffffff},
{0xffffffffffffffff,0xffffffffffffffff,0x0000000000000000,0x0000000000000000},
{0x1111111111111111,0x1111111111111111,0x2222222222222222,0x2222222222222222},
{0x3333333333333333,0x3333333333333333,0x3333333333333333,0x4444444444444444},
{0x4444444444444444,0x5555555555555555,0x5555555555555555,0x6666666666666666},
{0x6666666666666666,0x6666666666666666,0x7777777777777777,0x7777777777777777},
{0x8888888888888888,0x8888888888888888,0x9999999999999999,0x9999999999999999},
{0xaaaaaaaaaaaaaaaa,0xaaaaaaaaaaaaaaaa,0xaaaaaaaaaaaaaaaa,0xbbbbbbbbbbbbbbbb},
{0xbbbbbbbbbbbbbbbb,0xcccccccccccccccc,0xcccccccccccccccc,0xdddddddddddddddd},
{0xdddddddddddddddd,0xdddddddddddddddd,0xeeeeeeeeeeeeeeee,0xeeeeeeeeeeeeeeee},
{0xffffffffffffffff,0xffffffffffffffff,0x0000000000000000,0x0000000000000000},
{0x1111111111111111,0x1111111111111111,0x1111111111111111,0x2222222222222222},
{0x2222222222222222,0x3333333333333333,0x3333333333333333,0x4444444444444444},
{0x4444444444444444,0x4444444444444444,0x5555555555555555,0x5555555555555555},
{0x6666666666666666,0x6666666666666666,0x7777777777777777,0x7777777777777777}
}
};
unsigned __int64 CKL[2][16][4]=
{
{
{0x0000000000000000,0x7777777777777777,0xeeeeeeeeeeeeeeee,0x5555555555555555},
{0xcccccccccccccccc,0x3333333333333333,0xaaaaaaaaaaaaaaaa,0x1111111111111111},
{0x8888888888888888,0xffffffffffffffff,0x6666666666666666,0xdddddddddddddddd},
{0x4444444444444444,0xbbbbbbbbbbbbbbbb,0x2222222222222222,0x9999999999999999},
{0x0000000000000000,0x7777777777777777,0xeeeeeeeeeeeeeeee,0x5555555555555555},
{0xcccccccccccccccc,0x3333333333333333,0xaaaaaaaaaaaaaaaa,0x1111111111111111},
{0x8888888888888888,0xffffffffffffffff,0x6666666666666666,0xdddddddddddddddd},
{0x4444444444444444,0xbbbbbbbbbbbbbbbb,0x2222222222222222,0x9999999999999999},
{0x0000000000000000,0x7777777777777777,0xeeeeeeeeeeeeeeee,0x5555555555555555},
{0xcccccccccccccccc,0x3333333333333333,0xaaaaaaaaaaaaaaaa,0x1111111111111111},
{0x8888888888888888,0xffffffffffffffff,0x6666666666666666,0xdddddddddddddddd},
{0x4444444444444444,0xbbbbbbbbbbbbbbbb,0x2222222222222222,0x9999999999999999},
{0x0000000000000000,0x7777777777777777,0xeeeeeeeeeeeeeeee,0x5555555555555555},
{0xcccccccccccccccc,0x3333333333333333,0xaaaaaaaaaaaaaaaa,0x1111111111111111},
{0x8888888888888888,0xffffffffffffffff,0x6666666666666666,0xdddddddddddddddd},
{0x4444444444444444,0xbbbbbbbbbbbbbbbb,0x2222222222222222,0x9999999999999999}
},
{
{0x0000000000000000,0x7777777777777777,0xeeeeeeeeeeeeeeee,0x5555555555555555},
{0xcccccccccccccccc,0x3333333333333333,0xaaaaaaaaaaaaaaaa,0x1111111111111111},
{0x8888888888888888,0xffffffffffffffff,0x6666666666666666,0xdddddddddddddddd},
{0x4444444444444444,0xbbbbbbbbbbbbbbbb,0x2222222222222222,0x9999999999999999},
{0x0000000000000000,0x7777777777777777,0xeeeeeeeeeeeeeeee,0x5555555555555555},
{0xcccccccccccccccc,0x3333333333333333,0xaaaaaaaaaaaaaaaa,0x1111111111111111},
{0x8888888888888888,0xffffffffffffffff,0x6666666666666666,0xdddddddddddddddd},
{0x4444444444444444,0xbbbbbbbbbbbbbbbb,0x2222222222222222,0x9999999999999999},
{0x0000000000000000,0x7777777777777777,0xeeeeeeeeeeeeeeee,0x5555555555555555},
{0xcccccccccccccccc,0x3333333333333333,0xaaaaaaaaaaaaaaaa,0x1111111111111111},
{0x8888888888888888,0xffffffffffffffff,0x6666666666666666,0xdddddddddddddddd},
{0x4444444444444444,0xbbbbbbbbbbbbbbbb,0x2222222222222222,0x9999999999999999},
{0x0000000000000000,0x7777777777777777,0xeeeeeeeeeeeeeeee,0x5555555555555555},
{0xcccccccccccccccc,0x3333333333333333,0xaaaaaaaaaaaaaaaa,0x1111111111111111},
{0x8888888888888888,0xffffffffffffffff,0x6666666666666666,0xdddddddddddddddd},
{0x4444444444444444,0xbbbbbbbbbbbbbbbb,0x2222222222222222,0x9999999999999999}
}
};
unsigned __int64 JZ4_2(unsigned __int64 cin)//4 bit silce
{
unsigned __int64 t;
t=0;
t=t^((bit_4bit((cin>>(3))&0x1111111111111111))&(0xeeeeeeeeeeeeeeee));
t=t^((bit_4bit((cin>>(2))&0x1111111111111111))&(0x6666666666666666));
t=t^((bit_4bit((cin>>(1))&0x1111111111111111))&(0x4444444444444444));
t=t^((bit_4bit((cin>>(0))&0x1111111111111111))&(0x1111111111111111));
return t;
}
unsigned __int64 JZ2_4(unsigned __int64 cin)//4 bit silce
{
unsigned __int64 t;
t=0;
t=t^((bit_4bit((cin>>(3))&0x1111111111111111))&(0xcccccccccccccccc));
t=t^((bit_4bit((cin>>(2))&0x1111111111111111))&(0x2222222222222222));
t=t^((bit_4bit((cin>>(1))&0x1111111111111111))&(0x6666666666666666));
t=t^((bit_4bit((cin>>(0))&0x1111111111111111))&(0x1111111111111111));
return t;
}
unsigned __int64 GF4_2_X(unsigned __int64 a,unsigned __int64 b)//(4+4)*(4+4),//4 bit silce
{
unsigned __int64 a1,a0,b1,b0;
a1=(a>>2)&0x3333333333333333;
a0=a&0x3333333333333333;
b1=(b>>2)&0x3333333333333333;
b0=b&0x3333333333333333;
a1=((GF4X2(a0,b1)^GF4X2(a1,b0)^GF4X2(a1,b1))<<2)|(GF4X2(a0,b0)^GF4X2(0x2222222222222222,(GF4X2(a1,b1))));
return a1;//·½³Ìx^2+x+2
}
unsigned __int64 GF4X2_inver(unsigned __int64 in)//4+4bit invers//4 bit silce
{
unsigned __int64 a1,a0,dt,rdt;
a1=(in>>2)&0x3333333333333333;
a0=in&0x3333333333333333;
dt=GF4X2((a1^a0),a0)^GF4X2(GF4X2(0x2222222222222222,a1),a1);
dt=GF4_inver(dt);
return (GF4X2(a1,dt)<<2)|GF4X2(a1^a0,dt);
}
void bit256_16X2_bs(unsigned __int64 cinh,unsigned __int64 cinl,unsigned __int64 &th,unsigned __int64 &tl)//8 -> 4+4
{
th=0;
th=th^((bit_4bit((cinh>>(3))&0x1111111111111111))&(0x2222222222222222));
th=th^((bit_4bit((cinh>>(2))&0x1111111111111111))&(0xffffffffffffffff));
th=th^((bit_4bit((cinh>>(1))&0x1111111111111111))&(0x4444444444444444));
th=th^((bit_4bit((cinh>>(0))&0x1111111111111111))&(0xffffffffffffffff));
th=th^((bit_4bit((cinl>>(3))&0x1111111111111111))&(0xcccccccccccccccc));
th=th^((bit_4bit((cinl>>(2))&0x1111111111111111))&(0xcccccccccccccccc));
th=th^((bit_4bit((cinl>>(1))&0x1111111111111111))&(0x8888888888888888));
th=th^((bit_4bit((cinl>>(0))&0x1111111111111111))&(0x0000000000000000));
tl=0;
tl=tl^((bit_4bit((cinh>>(3))&0x1111111111111111))&(0x6666666666666666));
tl=tl^((bit_4bit((cinh>>(2))&0x1111111111111111))&(0xbbbbbbbbbbbbbbbb));
tl=tl^((bit_4bit((cinh>>(1))&0x1111111111111111))&(0xdddddddddddddddd));
tl=tl^((bit_4bit((cinh>>(0))&0x1111111111111111))&(0xffffffffffffffff));
tl=tl^((bit_4bit((cinl>>(3))&0x1111111111111111))&(0x3333333333333333));
tl=tl^((bit_4bit((cinl>>(2))&0x1111111111111111))&(0x1111111111111111));
tl=tl^((bit_4bit((cinl>>(1))&0x1111111111111111))&(0x6666666666666666));
tl=tl^((bit_4bit((cinl>>(0))&0x1111111111111111))&(0x1111111111111111));
}
void bit16X2_256_bs(unsigned __int64 cinh,unsigned __int64 cinl,unsigned __int64 &th,unsigned __int64 &tl)//4+4 -> 8
{
th=0;
th=th^((bit_4bit((cinh>>(3))&0x1111111111111111))&(0x5555555555555555));
th=th^((bit_4bit((cinh>>(2))&0x1111111111111111))&(0x5555555555555555));
th=th^((bit_4bit((cinh>>(1))&0x1111111111111111))&(0xdddddddddddddddd));
th=th^((bit_4bit((cinh>>(0))&0x1111111111111111))&(0xbbbbbbbbbbbbbbbb));
th=th^((bit_4bit((cinl>>(3))&0x1111111111111111))&(0x2222222222222222));
th=th^((bit_4bit((cinl>>(2))&0x1111111111111111))&(0x5555555555555555));
th=th^((bit_4bit((cinl>>(1))&0x1111111111111111))&(0x0000000000000000));
th=th^((bit_4bit((cinl>>(0))&0x1111111111111111))&(0x0000000000000000));
tl=0;
tl=tl^((bit_4bit((cinh>>(3))&0x1111111111111111))&(0xeeeeeeeeeeeeeeee));
tl=tl^((bit_4bit((cinh>>(2))&0x1111111111111111))&(0xbbbbbbbbbbbbbbbb));
tl=tl^((bit_4bit((cinh>>(1))&0x1111111111111111))&(0xcccccccccccccccc));
tl=tl^((bit_4bit((cinh>>(0))&0x1111111111111111))&(0xeeeeeeeeeeeeeeee));
tl=tl^((bit_4bit((cinl>>(3))&0x1111111111111111))&(0xaaaaaaaaaaaaaaaa));
tl=tl^((bit_4bit((cinl>>(2))&0x1111111111111111))&(0x0000000000000000));
tl=tl^((bit_4bit((cinl>>(1))&0x1111111111111111))&(0xcccccccccccccccc));
tl=tl^((bit_4bit((cinl>>(0))&0x1111111111111111))&(0x1111111111111111));
}
void GF16_2_inver_bs(unsigned __int64 a1,unsigned __int64 a0,unsigned __int64 &th,unsigned __int64 &tl)//2+2 invers
{
unsigned __int64 dt;
unsigned __int64 rdt,t;
dt=GF16X2((a1^a0),a0)^GF16X2(GF16X2(0x9999999999999999,a1),a1);
dt=JZ2_4(GF4X2_inver(JZ4_2(dt)));//
th=GF16X2(a1,dt);
tl=GF16X2(a1^a0,dt);
}
void S_BOX_bs(unsigned __int64 cinh,unsigned __int64 cinl,unsigned __int64 &th,unsigned __int64 &tl)
{
unsigned char temp;
th=0;
th=th^((bit_4bit((cinh>>(3))&0x1111111111111111))&0xeeeeeeeeeeeeeeee);
th=th^((bit_4bit((cinh>>(2))&0x1111111111111111))&0xffffffffffffffff);
th=th^((bit_4bit((cinh>>(1))&0x1111111111111111))&0x7777777777777777);
th=th^((bit_4bit((cinh>>(0))&0x1111111111111111))&0xbbbbbbbbbbbbbbbb);
th=th^((bit_4bit((cinl>>(3))&0x1111111111111111))&0x5555555555555555);
th=th^((bit_4bit((cinl>>(2))&0x1111111111111111))&0x2222222222222222);
th=th^((bit_4bit((cinl>>(1))&0x1111111111111111))&0x9999999999999999);
th=th^((bit_4bit((cinl>>(0))&0x1111111111111111))&0xcccccccccccccccc);
tl=0;
tl=tl^((bit_4bit((cinh>>(3))&0x1111111111111111))&0x5555555555555555);
tl=tl^((bit_4bit((cinh>>(2))&0x1111111111111111))&0x2222222222222222);
tl=tl^((bit_4bit((cinh>>(1))&0x1111111111111111))&0x9999999999999999);
tl=tl^((bit_4bit((cinh>>(0))&0x1111111111111111))&0xcccccccccccccccc);
tl=tl^((bit_4bit((cinl>>(3))&0x1111111111111111))&0xeeeeeeeeeeeeeeee);
tl=tl^((bit_4bit((cinl>>(2))&0x1111111111111111))&0xffffffffffffffff);
tl=tl^((bit_4bit((cinl>>(1))&0x1111111111111111))&0x7777777777777777);
tl=tl^((bit_4bit((cinl>>(0))&0x1111111111111111))&0xbbbbbbbbbbbbbbbb);
th=th^0xdddddddddddddddd;
tl=tl^0x3333333333333333;
bit256_16X2_bs(th,tl,cinh,cinl);
GF16_2_inver_bs(cinh,cinl,th,tl);
bit16X2_256_bs(th,tl,cinh,cinl);
th=0;
th=th^((bit_4bit((cinh>>(3))&0x1111111111111111))&0xeeeeeeeeeeeeeeee);
th=th^((bit_4bit((cinh>>(2))&0x1111111111111111))&0xffffffffffffffff);
th=th^((bit_4bit((cinh>>(1))&0x1111111111111111))&0x7777777777777777);
th=th^((bit_4bit((cinh>>(0))&0x1111111111111111))&0xbbbbbbbbbbbbbbbb);
th=th^((bit_4bit((cinl>>(3))&0x1111111111111111))&0x5555555555555555);
th=th^((bit_4bit((cinl>>(2))&0x1111111111111111))&0x2222222222222222);
th=th^((bit_4bit((cinl>>(1))&0x1111111111111111))&0x9999999999999999);
th=th^((bit_4bit((cinl>>(0))&0x1111111111111111))&0xcccccccccccccccc);
tl=0;
tl=tl^((bit_4bit((cinh>>(3))&0x1111111111111111))&0x5555555555555555);
tl=tl^((bit_4bit((cinh>>(2))&0x1111111111111111))&0x2222222222222222);
tl=tl^((bit_4bit((cinh>>(1))&0x1111111111111111))&0x9999999999999999);
tl=tl^((bit_4bit((cinh>>(0))&0x1111111111111111))&0xcccccccccccccccc);
tl=tl^((bit_4bit((cinl>>(3))&0x1111111111111111))&0xeeeeeeeeeeeeeeee);
tl=tl^((bit_4bit((cinl>>(2))&0x1111111111111111))&0xffffffffffffffff);
tl=tl^((bit_4bit((cinl>>(1))&0x1111111111111111))&0x7777777777777777);
tl=tl^((bit_4bit((cinl>>(0))&0x1111111111111111))&0xbbbbbbbbbbbbbbbb);
th=th^0xdddddddddddddddd;
tl=tl^0x3333333333333333;
}
void print_int(unsigned __int64 PH[4],unsigned __int64 PL[4],__int64 id)
{
__int64 i,j;
//printf("0x");
//for(i=0;i<4;i++)printf("%x%x",(PH[i]>>(id*4))&0xf,(PL[i]>>(id*4))&0xf);
//printf("\n");
for(i=0;i<4;i++)
{
for(j=3;j>=0;j--)
{
printf("%d",(((PH[i]>>(id*4))&0xf)>>j)&1);
}
printf(" ");
for(j=3;j>=0;j--)
{
printf("%d",(((PL[i]>>(id*4))&0xf)>>j)&1);
}
printf(" ");
}printf("\n");
}
void ENC_ROUND_BS0(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4],unsigned __int64 i,unsigned __int64 ii)
{
Xh[4][0]=Xh[1][0]^Xh[2][0]^Xh[3][0]^CKH[i][ii][0];
Xh[4][1]=Xh[1][1]^Xh[2][1]^Xh[3][1]^CKH[i][ii][1];
Xh[4][2]=Xh[1][2]^Xh[2][2]^Xh[3][2]^CKH[i][ii][2];
Xh[4][3]=Xh[1][3]^Xh[2][3]^Xh[3][3]^CKH[i][ii][3];
Xl[4][0]=Xl[1][0]^Xl[2][0]^Xl[3][0]^CKL[i][ii][0];
Xl[4][1]=Xl[1][1]^Xl[2][1]^Xl[3][1]^CKL[i][ii][1];
Xl[4][2]=Xl[1][2]^Xl[2][2]^Xl[3][2]^CKL[i][ii][2];
Xl[4][3]=Xl[1][3]^Xl[2][3]^Xl[3][3]^CKL[i][ii][3];
S_BOX_bs(Xh[4][0],Xl[4][0],Xh[4][0],Xl[4][0]);
S_BOX_bs(Xh[4][1],Xl[4][1],Xh[4][1],Xl[4][1]);
S_BOX_bs(Xh[4][2],Xl[4][2],Xh[4][2],Xl[4][2]);
S_BOX_bs(Xh[4][3],Xl[4][3],Xh[4][3],Xl[4][3]);
RKH[0]=Xh[0][0]^Xh[4][0]^((Xl[4][1]&0x7777777777777777)<<1)^((Xh[4][2]>>3)&0x1111111111111111)^((Xl[4][2]&0x1111111111111111)<<3)^((Xh[4][3]>>1)&0x7777777777777777);
RKH[1]=Xh[0][1]^Xh[4][1]^((Xl[4][2]&0x7777777777777777)<<1)^((Xh[4][3]>>3)&0x1111111111111111)^((Xl[4][3]&0x1111111111111111)<<3)^((Xh[4][0]>>1)&0x7777777777777777);
RKH[2]=Xh[0][2]^Xh[4][2]^((Xl[4][3]&0x7777777777777777)<<1)^((Xh[4][0]>>3)&0x1111111111111111)^((Xl[4][0]&0x1111111111111111)<<3)^((Xh[4][1]>>1)&0x7777777777777777);
RKH[3]=Xh[0][3]^Xh[4][3]^((Xl[4][0]&0x7777777777777777)<<1)^((Xh[4][1]>>3)&0x1111111111111111)^((Xl[4][1]&0x1111111111111111)<<3)^((Xh[4][2]>>1)&0x7777777777777777);
RKL[0]=Xl[0][0]^Xl[4][0]^((Xh[4][2]&0x7777777777777777)<<1)^((Xl[4][2]>>3)&0x1111111111111111)^((Xh[4][3]&0x1111111111111111)<<3)^((Xl[4][3]>>1)&0x7777777777777777);
RKL[1]=Xl[0][1]^Xl[4][1]^((Xh[4][3]&0x7777777777777777)<<1)^((Xl[4][3]>>3)&0x1111111111111111)^((Xh[4][0]&0x1111111111111111)<<3)^((Xl[4][0]>>1)&0x7777777777777777);
RKL[2]=Xl[0][2]^Xl[4][2]^((Xh[4][0]&0x7777777777777777)<<1)^((Xl[4][0]>>3)&0x1111111111111111)^((Xh[4][1]&0x1111111111111111)<<3)^((Xl[4][1]>>1)&0x7777777777777777);
RKL[3]=Xl[0][3]^Xl[4][3]^((Xh[4][1]&0x7777777777777777)<<1)^((Xl[4][1]>>3)&0x1111111111111111)^((Xh[4][2]&0x1111111111111111)<<3)^((Xl[4][2]>>1)&0x7777777777777777);
Xh[4][0]=RKH[0];
Xh[4][1]=RKH[1];
Xh[4][2]=RKH[2];
Xh[4][3]=RKH[3];
Xl[4][0]=RKL[0];
Xl[4][1]=RKL[1];
Xl[4][2]=RKL[2];
Xl[4][3]=RKL[3];
}
void ENC_ROUND_BS1(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4],unsigned __int64 i,unsigned __int64 ii)
{
Xh[0][0]=Xh[2][0]^Xh[3][0]^Xh[4][0]^CKH[i][ii][0];
Xh[0][1]=Xh[2][1]^Xh[3][1]^Xh[4][1]^CKH[i][ii][1];
Xh[0][2]=Xh[2][2]^Xh[3][2]^Xh[4][2]^CKH[i][ii][2];
Xh[0][3]=Xh[2][3]^Xh[3][3]^Xh[4][3]^CKH[i][ii][3];
Xl[0][0]=Xl[2][0]^Xl[3][0]^Xl[4][0]^CKL[i][ii][0];
Xl[0][1]=Xl[2][1]^Xl[3][1]^Xl[4][1]^CKL[i][ii][1];
Xl[0][2]=Xl[2][2]^Xl[3][2]^Xl[4][2]^CKL[i][ii][2];
Xl[0][3]=Xl[2][3]^Xl[3][3]^Xl[4][3]^CKL[i][ii][3];
S_BOX_bs(Xh[0][0],Xl[0][0],Xh[0][0],Xl[0][0]);
S_BOX_bs(Xh[0][1],Xl[0][1],Xh[0][1],Xl[0][1]);
S_BOX_bs(Xh[0][2],Xl[0][2],Xh[0][2],Xl[0][2]);
S_BOX_bs(Xh[0][3],Xl[0][3],Xh[0][3],Xl[0][3]);
RKH[0]=Xh[1][0]^Xh[0][0]^((Xl[0][1]&0x7777777777777777)<<1)^((Xh[0][2]>>3)&0x1111111111111111)^((Xl[0][2]&0x1111111111111111)<<3)^((Xh[0][3]>>1)&0x7777777777777777);
RKH[1]=Xh[1][1]^Xh[0][1]^((Xl[0][2]&0x7777777777777777)<<1)^((Xh[0][3]>>3)&0x1111111111111111)^((Xl[0][3]&0x1111111111111111)<<3)^((Xh[0][0]>>1)&0x7777777777777777);
RKH[2]=Xh[1][2]^Xh[0][2]^((Xl[0][3]&0x7777777777777777)<<1)^((Xh[0][0]>>3)&0x1111111111111111)^((Xl[0][0]&0x1111111111111111)<<3)^((Xh[0][1]>>1)&0x7777777777777777);
RKH[3]=Xh[1][3]^Xh[0][3]^((Xl[0][0]&0x7777777777777777)<<1)^((Xh[0][1]>>3)&0x1111111111111111)^((Xl[0][1]&0x1111111111111111)<<3)^((Xh[0][2]>>1)&0x7777777777777777);
RKL[0]=Xl[1][0]^Xl[0][0]^((Xh[0][2]&0x7777777777777777)<<1)^((Xl[0][2]>>3)&0x1111111111111111)^((Xh[0][3]&0x1111111111111111)<<3)^((Xl[0][3]>>1)&0x7777777777777777);
RKL[1]=Xl[1][1]^Xl[0][1]^((Xh[0][3]&0x7777777777777777)<<1)^((Xl[0][3]>>3)&0x1111111111111111)^((Xh[0][0]&0x1111111111111111)<<3)^((Xl[0][0]>>1)&0x7777777777777777);
RKL[2]=Xl[1][2]^Xl[0][2]^((Xh[0][0]&0x7777777777777777)<<1)^((Xl[0][0]>>3)&0x1111111111111111)^((Xh[0][1]&0x1111111111111111)<<3)^((Xl[0][1]>>1)&0x7777777777777777);
RKL[3]=Xl[1][3]^Xl[0][3]^((Xh[0][1]&0x7777777777777777)<<1)^((Xl[0][1]>>3)&0x1111111111111111)^((Xh[0][2]&0x1111111111111111)<<3)^((Xl[0][2]>>1)&0x7777777777777777);
Xh[0][0]=RKH[0];
Xh[0][1]=RKH[1];
Xh[0][2]=RKH[2];
Xh[0][3]=RKH[3];
Xl[0][0]=RKL[0];
Xl[0][1]=RKL[1];
Xl[0][2]=RKL[2];
Xl[0][3]=RKL[3];
}
void ENC_ROUND_BS2(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4],unsigned __int64 i,unsigned __int64 ii)
{
Xh[1][0]=Xh[3][0]^Xh[4][0]^Xh[0][0]^CKH[i][ii][0];
Xh[1][1]=Xh[3][1]^Xh[4][1]^Xh[0][1]^CKH[i][ii][1];
Xh[1][2]=Xh[3][2]^Xh[4][2]^Xh[0][2]^CKH[i][ii][2];
Xh[1][3]=Xh[3][3]^Xh[4][3]^Xh[0][3]^CKH[i][ii][3];
Xl[1][0]=Xl[3][0]^Xl[4][0]^Xl[0][0]^CKL[i][ii][0];
Xl[1][1]=Xl[3][1]^Xl[4][1]^Xl[0][1]^CKL[i][ii][1];
Xl[1][2]=Xl[3][2]^Xl[4][2]^Xl[0][2]^CKL[i][ii][2];
Xl[1][3]=Xl[3][3]^Xl[4][3]^Xl[0][3]^CKL[i][ii][3];
S_BOX_bs(Xh[1][0],Xl[1][0],Xh[1][0],Xl[1][0]);
S_BOX_bs(Xh[1][1],Xl[1][1],Xh[1][1],Xl[1][1]);
S_BOX_bs(Xh[1][2],Xl[1][2],Xh[1][2],Xl[1][2]);
S_BOX_bs(Xh[1][3],Xl[1][3],Xh[1][3],Xl[1][3]);
RKH[0]=Xh[2][0]^Xh[1][0]^((Xl[1][1]&0x7777777777777777)<<1)^((Xh[1][2]>>3)&0x1111111111111111)^((Xl[1][2]&0x1111111111111111)<<3)^((Xh[1][3]>>1)&0x7777777777777777);
RKH[1]=Xh[2][1]^Xh[1][1]^((Xl[1][2]&0x7777777777777777)<<1)^((Xh[1][3]>>3)&0x1111111111111111)^((Xl[1][3]&0x1111111111111111)<<3)^((Xh[1][0]>>1)&0x7777777777777777);
RKH[2]=Xh[2][2]^Xh[1][2]^((Xl[1][3]&0x7777777777777777)<<1)^((Xh[1][0]>>3)&0x1111111111111111)^((Xl[1][0]&0x1111111111111111)<<3)^((Xh[1][1]>>1)&0x7777777777777777);
RKH[3]=Xh[2][3]^Xh[1][3]^((Xl[1][0]&0x7777777777777777)<<1)^((Xh[1][1]>>3)&0x1111111111111111)^((Xl[1][1]&0x1111111111111111)<<3)^((Xh[1][2]>>1)&0x7777777777777777);
RKL[0]=Xl[2][0]^Xl[1][0]^((Xh[1][2]&0x7777777777777777)<<1)^((Xl[1][2]>>3)&0x1111111111111111)^((Xh[1][3]&0x1111111111111111)<<3)^((Xl[1][3]>>1)&0x7777777777777777);
RKL[1]=Xl[2][1]^Xl[1][1]^((Xh[1][3]&0x7777777777777777)<<1)^((Xl[1][3]>>3)&0x1111111111111111)^((Xh[1][0]&0x1111111111111111)<<3)^((Xl[1][0]>>1)&0x7777777777777777);
RKL[2]=Xl[2][2]^Xl[1][2]^((Xh[1][0]&0x7777777777777777)<<1)^((Xl[1][0]>>3)&0x1111111111111111)^((Xh[1][1]&0x1111111111111111)<<3)^((Xl[1][1]>>1)&0x7777777777777777);
RKL[3]=Xl[2][3]^Xl[1][3]^((Xh[1][1]&0x7777777777777777)<<1)^((Xl[1][1]>>3)&0x1111111111111111)^((Xh[1][2]&0x1111111111111111)<<3)^((Xl[1][2]>>1)&0x7777777777777777);
Xh[1][0]=RKH[0];
Xh[1][1]=RKH[1];
Xh[1][2]=RKH[2];
Xh[1][3]=RKH[3];
Xl[1][0]=RKL[0];
Xl[1][1]=RKL[1];
Xl[1][2]=RKL[2];
Xl[1][3]=RKL[3];
}
void ENC_ROUND_BS3(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4],unsigned __int64 i,unsigned __int64 ii)
{
Xh[2][0]=Xh[4][0]^Xh[0][0]^Xh[1][0]^CKH[i][ii][0];
Xh[2][1]=Xh[4][1]^Xh[0][1]^Xh[1][1]^CKH[i][ii][1];
Xh[2][2]=Xh[4][2]^Xh[0][2]^Xh[1][2]^CKH[i][ii][2];
Xh[2][3]=Xh[4][3]^Xh[0][3]^Xh[1][3]^CKH[i][ii][3];
Xl[2][0]=Xl[4][0]^Xl[0][0]^Xl[1][0]^CKL[i][ii][0];
Xl[2][1]=Xl[4][1]^Xl[0][1]^Xl[1][1]^CKL[i][ii][1];
Xl[2][2]=Xl[4][2]^Xl[0][2]^Xl[1][2]^CKL[i][ii][2];
Xl[2][3]=Xl[4][3]^Xl[0][3]^Xl[1][3]^CKL[i][ii][3];
S_BOX_bs(Xh[2][0],Xl[2][0],Xh[2][0],Xl[2][0]);
S_BOX_bs(Xh[2][1],Xl[2][1],Xh[2][1],Xl[2][1]);
S_BOX_bs(Xh[2][2],Xl[2][2],Xh[2][2],Xl[2][2]);
S_BOX_bs(Xh[2][3],Xl[2][3],Xh[2][3],Xl[2][3]);
RKH[0]=Xh[3][0]^Xh[2][0]^((Xl[2][1]&0x7777777777777777)<<1)^((Xh[2][2]>>3)&0x1111111111111111)^((Xl[2][2]&0x1111111111111111)<<3)^((Xh[2][3]>>1)&0x7777777777777777);
RKH[1]=Xh[3][1]^Xh[2][1]^((Xl[2][2]&0x7777777777777777)<<1)^((Xh[2][3]>>3)&0x1111111111111111)^((Xl[2][3]&0x1111111111111111)<<3)^((Xh[2][0]>>1)&0x7777777777777777);
RKH[2]=Xh[3][2]^Xh[2][2]^((Xl[2][3]&0x7777777777777777)<<1)^((Xh[2][0]>>3)&0x1111111111111111)^((Xl[2][0]&0x1111111111111111)<<3)^((Xh[2][1]>>1)&0x7777777777777777);
RKH[3]=Xh[3][3]^Xh[2][3]^((Xl[2][0]&0x7777777777777777)<<1)^((Xh[2][1]>>3)&0x1111111111111111)^((Xl[2][1]&0x1111111111111111)<<3)^((Xh[2][2]>>1)&0x7777777777777777);
RKL[0]=Xl[3][0]^Xl[2][0]^((Xh[2][2]&0x7777777777777777)<<1)^((Xl[2][2]>>3)&0x1111111111111111)^((Xh[2][3]&0x1111111111111111)<<3)^((Xl[2][3]>>1)&0x7777777777777777);
RKL[1]=Xl[3][1]^Xl[2][1]^((Xh[2][3]&0x7777777777777777)<<1)^((Xl[2][3]>>3)&0x1111111111111111)^((Xh[2][0]&0x1111111111111111)<<3)^((Xl[2][0]>>1)&0x7777777777777777);
RKL[2]=Xl[3][2]^Xl[2][2]^((Xh[2][0]&0x7777777777777777)<<1)^((Xl[2][0]>>3)&0x1111111111111111)^((Xh[2][1]&0x1111111111111111)<<3)^((Xl[2][1]>>1)&0x7777777777777777);
RKL[3]=Xl[3][3]^Xl[2][3]^((Xh[2][1]&0x7777777777777777)<<1)^((Xl[2][1]>>3)&0x1111111111111111)^((Xh[2][2]&0x1111111111111111)<<3)^((Xl[2][2]>>1)&0x7777777777777777);
Xh[2][0]=RKH[0];
Xh[2][1]=RKH[1];
Xh[2][2]=RKH[2];
Xh[2][3]=RKH[3];
Xl[2][0]=RKL[0];
Xl[2][1]=RKL[1];
Xl[2][2]=RKL[2];
Xl[2][3]=RKL[3];
}
void ENC_ROUND_BS4(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4],unsigned __int64 i,unsigned __int64 ii)
{
Xh[3][0]=Xh[0][0]^Xh[1][0]^Xh[2][0]^CKH[i][ii][0];
Xh[3][1]=Xh[0][1]^Xh[1][1]^Xh[2][1]^CKH[i][ii][1];
Xh[3][2]=Xh[0][2]^Xh[1][2]^Xh[2][2]^CKH[i][ii][2];
Xh[3][3]=Xh[0][3]^Xh[1][3]^Xh[2][3]^CKH[i][ii][3];
Xl[3][0]=Xl[0][0]^Xl[1][0]^Xl[2][0]^CKL[i][ii][0];
Xl[3][1]=Xl[0][1]^Xl[1][1]^Xl[2][1]^CKL[i][ii][1];
Xl[3][2]=Xl[0][2]^Xl[1][2]^Xl[2][2]^CKL[i][ii][2];
Xl[3][3]=Xl[0][3]^Xl[1][3]^Xl[2][3]^CKL[i][ii][3];
S_BOX_bs(Xh[3][0],Xl[3][0],Xh[3][0],Xl[3][0]);
S_BOX_bs(Xh[3][1],Xl[3][1],Xh[3][1],Xl[3][1]);
S_BOX_bs(Xh[3][2],Xl[3][2],Xh[3][2],Xl[3][2]);
S_BOX_bs(Xh[3][3],Xl[3][3],Xh[3][3],Xl[3][3]);
RKH[0]=Xh[4][0]^Xh[3][0]^((Xl[3][1]&0x7777777777777777)<<1)^((Xh[3][2]>>3)&0x1111111111111111)^((Xl[3][2]&0x1111111111111111)<<3)^((Xh[3][3]>>1)&0x7777777777777777);
RKH[1]=Xh[4][1]^Xh[3][1]^((Xl[3][2]&0x7777777777777777)<<1)^((Xh[3][3]>>3)&0x1111111111111111)^((Xl[3][3]&0x1111111111111111)<<3)^((Xh[3][0]>>1)&0x7777777777777777);
RKH[2]=Xh[4][2]^Xh[3][2]^((Xl[3][3]&0x7777777777777777)<<1)^((Xh[3][0]>>3)&0x1111111111111111)^((Xl[3][0]&0x1111111111111111)<<3)^((Xh[3][1]>>1)&0x7777777777777777);
RKH[3]=Xh[4][3]^Xh[3][3]^((Xl[3][0]&0x7777777777777777)<<1)^((Xh[3][1]>>3)&0x1111111111111111)^((Xl[3][1]&0x1111111111111111)<<3)^((Xh[3][2]>>1)&0x7777777777777777);
RKL[0]=Xl[4][0]^Xl[3][0]^((Xh[3][2]&0x7777777777777777)<<1)^((Xl[3][2]>>3)&0x1111111111111111)^((Xh[3][3]&0x1111111111111111)<<3)^((Xl[3][3]>>1)&0x7777777777777777);
RKL[1]=Xl[4][1]^Xl[3][1]^((Xh[3][3]&0x7777777777777777)<<1)^((Xl[3][3]>>3)&0x1111111111111111)^((Xh[3][0]&0x1111111111111111)<<3)^((Xl[3][0]>>1)&0x7777777777777777);
RKL[2]=Xl[4][2]^Xl[3][2]^((Xh[3][0]&0x7777777777777777)<<1)^((Xl[3][0]>>3)&0x1111111111111111)^((Xh[3][1]&0x1111111111111111)<<3)^((Xl[3][1]>>1)&0x7777777777777777);
RKL[3]=Xl[4][3]^Xl[3][3]^((Xh[3][1]&0x7777777777777777)<<1)^((Xl[3][1]>>3)&0x1111111111111111)^((Xh[3][2]&0x1111111111111111)<<3)^((Xl[3][2]>>1)&0x7777777777777777);
Xh[3][0]=RKH[0];
Xh[3][1]=RKH[1];
Xh[3][2]=RKH[2];
Xh[3][3]=RKH[3];
Xl[3][0]=RKL[0];
Xl[3][1]=RKL[1];
Xl[3][2]=RKL[2];
Xl[3][3]=RKL[3];
}
void ROUND_BS0(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4])
{
unsigned __int64 TH[4];
unsigned __int64 TL[4];
Xh[4][0]=Xh[1][0]^Xh[2][0]^Xh[3][0]^RKH[0];
Xh[4][1]=Xh[1][1]^Xh[2][1]^Xh[3][1]^RKH[1];
Xh[4][2]=Xh[1][2]^Xh[2][2]^Xh[3][2]^RKH[2];
Xh[4][3]=Xh[1][3]^Xh[2][3]^Xh[3][3]^RKH[3];
Xl[4][0]=Xl[1][0]^Xl[2][0]^Xl[3][0]^RKL[0];
Xl[4][1]=Xl[1][1]^Xl[2][1]^Xl[3][1]^RKL[1];
Xl[4][2]=Xl[1][2]^Xl[2][2]^Xl[3][2]^RKL[2];
Xl[4][3]=Xl[1][3]^Xl[2][3]^Xl[3][3]^RKL[3];
S_BOX_bs(Xh[4][0],Xl[4][0],Xh[4][0],Xl[4][0]);
S_BOX_bs(Xh[4][1],Xl[4][1],Xh[4][1],Xl[4][1]);
S_BOX_bs(Xh[4][2],Xl[4][2],Xh[4][2],Xl[4][2]);
S_BOX_bs(Xh[4][3],Xl[4][3],Xh[4][3],Xl[4][3]);
TH[0]=Xh[0][0]^Xh[4][0]^((Xh[4][0]&0x3333333333333333)<<2)^((Xl[4][0]>>2)&0x3333333333333333)^((Xh[4][1]&0x3333333333333333)<<2)^((Xl[4][1]>>2)&0x3333333333333333)^((Xh[4][2]&0x3333333333333333)<<2)^((Xl[4][2]>>2)&0x3333333333333333)^((Xh[4][3]&0xffffffffffffffff)<<0)^((Xl[4][3]>>4)&0x0000000000000000);
TH[1]=Xh[0][1]^Xh[4][1]^((Xh[4][1]&0x3333333333333333)<<2)^((Xl[4][1]>>2)&0x3333333333333333)^((Xh[4][2]&0x3333333333333333)<<2)^((Xl[4][2]>>2)&0x3333333333333333)^((Xh[4][3]&0x3333333333333333)<<2)^((Xl[4][3]>>2)&0x3333333333333333)^((Xh[4][0]&0xffffffffffffffff)<<0)^((Xl[4][0]>>4)&0x0000000000000000);
TH[2]=Xh[0][2]^Xh[4][2]^((Xh[4][2]&0x3333333333333333)<<2)^((Xl[4][2]>>2)&0x3333333333333333)^((Xh[4][3]&0x3333333333333333)<<2)^((Xl[4][3]>>2)&0x3333333333333333)^((Xh[4][0]&0x3333333333333333)<<2)^((Xl[4][0]>>2)&0x3333333333333333)^((Xh[4][1]&0xffffffffffffffff)<<0)^((Xl[4][1]>>4)&0x0000000000000000);
TH[3]=Xh[0][3]^Xh[4][3]^((Xh[4][3]&0x3333333333333333)<<2)^((Xl[4][3]>>2)&0x3333333333333333)^((Xh[4][0]&0x3333333333333333)<<2)^((Xl[4][0]>>2)&0x3333333333333333)^((Xh[4][1]&0x3333333333333333)<<2)^((Xl[4][1]>>2)&0x3333333333333333)^((Xh[4][2]&0xffffffffffffffff)<<0)^((Xl[4][2]>>4)&0x0000000000000000);
TL[0]=Xl[0][0]^Xl[4][0]^((Xl[4][0]&0x3333333333333333)<<2)^((Xh[4][1]>>2)&0x3333333333333333)^((Xl[4][1]&0x3333333333333333)<<2)^((Xh[4][2]>>2)&0x3333333333333333)^((Xl[4][2]&0x3333333333333333)<<2)^((Xh[4][3]>>2)&0x3333333333333333)^((Xl[4][3]&0xffffffffffffffff)<<0)^((Xh[4][3]>>4)&0x0000000000000000);
TL[1]=Xl[0][1]^Xl[4][1]^((Xl[4][1]&0x3333333333333333)<<2)^((Xh[4][2]>>2)&0x3333333333333333)^((Xl[4][2]&0x3333333333333333)<<2)^((Xh[4][3]>>2)&0x3333333333333333)^((Xl[4][3]&0x3333333333333333)<<2)^((Xh[4][0]>>2)&0x3333333333333333)^((Xl[4][0]&0xffffffffffffffff)<<0)^((Xh[4][0]>>4)&0x0000000000000000);
TL[2]=Xl[0][2]^Xl[4][2]^((Xl[4][2]&0x3333333333333333)<<2)^((Xh[4][3]>>2)&0x3333333333333333)^((Xl[4][3]&0x3333333333333333)<<2)^((Xh[4][0]>>2)&0x3333333333333333)^((Xl[4][0]&0x3333333333333333)<<2)^((Xh[4][1]>>2)&0x3333333333333333)^((Xl[4][1]&0xffffffffffffffff)<<0)^((Xh[4][1]>>4)&0x0000000000000000);
TL[3]=Xl[0][3]^Xl[4][3]^((Xl[4][3]&0x3333333333333333)<<2)^((Xh[4][0]>>2)&0x3333333333333333)^((Xl[4][0]&0x3333333333333333)<<2)^((Xh[4][1]>>2)&0x3333333333333333)^((Xl[4][1]&0x3333333333333333)<<2)^((Xh[4][2]>>2)&0x3333333333333333)^((Xl[4][2]&0xffffffffffffffff)<<0)^((Xh[4][2]>>4)&0x0000000000000000);
Xh[4][0]=TH[0];
Xh[4][1]=TH[1];
Xh[4][2]=TH[2];
Xh[4][3]=TH[3];
Xl[4][0]=TL[0];
Xl[4][1]=TL[1];
Xl[4][2]=TL[2];
Xl[4][3]=TL[3];
}
void ROUND_BS1(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4])
{
unsigned __int64 TH[4];
unsigned __int64 TL[4];
Xh[0][0]=Xh[2][0]^Xh[3][0]^Xh[4][0]^RKH[0];
Xh[0][1]=Xh[2][1]^Xh[3][1]^Xh[4][1]^RKH[1];
Xh[0][2]=Xh[2][2]^Xh[3][2]^Xh[4][2]^RKH[2];
Xh[0][3]=Xh[2][3]^Xh[3][3]^Xh[4][3]^RKH[3];
Xl[0][0]=Xl[2][0]^Xl[3][0]^Xl[4][0]^RKL[0];
Xl[0][1]=Xl[2][1]^Xl[3][1]^Xl[4][1]^RKL[1];
Xl[0][2]=Xl[2][2]^Xl[3][2]^Xl[4][2]^RKL[2];
Xl[0][3]=Xl[2][3]^Xl[3][3]^Xl[4][3]^RKL[3];
S_BOX_bs(Xh[0][0],Xl[0][0],Xh[0][0],Xl[0][0]);
S_BOX_bs(Xh[0][1],Xl[0][1],Xh[0][1],Xl[0][1]);
S_BOX_bs(Xh[0][2],Xl[0][2],Xh[0][2],Xl[0][2]);
S_BOX_bs(Xh[0][3],Xl[0][3],Xh[0][3],Xl[0][3]);
TH[0]=Xh[1][0]^Xh[0][0]^((Xh[0][0]&0x3333333333333333)<<2)^((Xl[0][0]>>2)&0x3333333333333333)^((Xh[0][1]&0x3333333333333333)<<2)^((Xl[0][1]>>2)&0x3333333333333333)^((Xh[0][2]&0x3333333333333333)<<2)^((Xl[0][2]>>2)&0x3333333333333333)^((Xh[0][3]&0xffffffffffffffff)<<0)^((Xl[0][3]>>4)&0x0000000000000000);
TH[1]=Xh[1][1]^Xh[0][1]^((Xh[0][1]&0x3333333333333333)<<2)^((Xl[0][1]>>2)&0x3333333333333333)^((Xh[0][2]&0x3333333333333333)<<2)^((Xl[0][2]>>2)&0x3333333333333333)^((Xh[0][3]&0x3333333333333333)<<2)^((Xl[0][3]>>2)&0x3333333333333333)^((Xh[0][0]&0xffffffffffffffff)<<0)^((Xl[0][0]>>4)&0x0000000000000000);
TH[2]=Xh[1][2]^Xh[0][2]^((Xh[0][2]&0x3333333333333333)<<2)^((Xl[0][2]>>2)&0x3333333333333333)^((Xh[0][3]&0x3333333333333333)<<2)^((Xl[0][3]>>2)&0x3333333333333333)^((Xh[0][0]&0x3333333333333333)<<2)^((Xl[0][0]>>2)&0x3333333333333333)^((Xh[0][1]&0xffffffffffffffff)<<0)^((Xl[0][1]>>4)&0x0000000000000000);
TH[3]=Xh[1][3]^Xh[0][3]^((Xh[0][3]&0x3333333333333333)<<2)^((Xl[0][3]>>2)&0x3333333333333333)^((Xh[0][0]&0x3333333333333333)<<2)^((Xl[0][0]>>2)&0x3333333333333333)^((Xh[0][1]&0x3333333333333333)<<2)^((Xl[0][1]>>2)&0x3333333333333333)^((Xh[0][2]&0xffffffffffffffff)<<0)^((Xl[0][2]>>4)&0x0000000000000000);
TL[0]=Xl[1][0]^Xl[0][0]^((Xl[0][0]&0x3333333333333333)<<2)^((Xh[0][1]>>2)&0x3333333333333333)^((Xl[0][1]&0x3333333333333333)<<2)^((Xh[0][2]>>2)&0x3333333333333333)^((Xl[0][2]&0x3333333333333333)<<2)^((Xh[0][3]>>2)&0x3333333333333333)^((Xl[0][3]&0xffffffffffffffff)<<0)^((Xh[0][3]>>4)&0x0000000000000000);
TL[1]=Xl[1][1]^Xl[0][1]^((Xl[0][1]&0x3333333333333333)<<2)^((Xh[0][2]>>2)&0x3333333333333333)^((Xl[0][2]&0x3333333333333333)<<2)^((Xh[0][3]>>2)&0x3333333333333333)^((Xl[0][3]&0x3333333333333333)<<2)^((Xh[0][0]>>2)&0x3333333333333333)^((Xl[0][0]&0xffffffffffffffff)<<0)^((Xh[0][0]>>4)&0x0000000000000000);
TL[2]=Xl[1][2]^Xl[0][2]^((Xl[0][2]&0x3333333333333333)<<2)^((Xh[0][3]>>2)&0x3333333333333333)^((Xl[0][3]&0x3333333333333333)<<2)^((Xh[0][0]>>2)&0x3333333333333333)^((Xl[0][0]&0x3333333333333333)<<2)^((Xh[0][1]>>2)&0x3333333333333333)^((Xl[0][1]&0xffffffffffffffff)<<0)^((Xh[0][1]>>4)&0x0000000000000000);
TL[3]=Xl[1][3]^Xl[0][3]^((Xl[0][3]&0x3333333333333333)<<2)^((Xh[0][0]>>2)&0x3333333333333333)^((Xl[0][0]&0x3333333333333333)<<2)^((Xh[0][1]>>2)&0x3333333333333333)^((Xl[0][1]&0x3333333333333333)<<2)^((Xh[0][2]>>2)&0x3333333333333333)^((Xl[0][2]&0xffffffffffffffff)<<0)^((Xh[0][2]>>4)&0x0000000000000000);
Xh[0][0]=TH[0];
Xh[0][1]=TH[1];
Xh[0][2]=TH[2];
Xh[0][3]=TH[3];
Xl[0][0]=TL[0];
Xl[0][1]=TL[1];
Xl[0][2]=TL[2];
Xl[0][3]=TL[3];
}
void ROUND_BS2(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4])
{
unsigned __int64 TH[4];
unsigned __int64 TL[4];
Xh[1][0]=Xh[3][0]^Xh[4][0]^Xh[0][0]^RKH[0];
Xh[1][1]=Xh[3][1]^Xh[4][1]^Xh[0][1]^RKH[1];
Xh[1][2]=Xh[3][2]^Xh[4][2]^Xh[0][2]^RKH[2];
Xh[1][3]=Xh[3][3]^Xh[4][3]^Xh[0][3]^RKH[3];
Xl[1][0]=Xl[3][0]^Xl[4][0]^Xl[0][0]^RKL[0];
Xl[1][1]=Xl[3][1]^Xl[4][1]^Xl[0][1]^RKL[1];
Xl[1][2]=Xl[3][2]^Xl[4][2]^Xl[0][2]^RKL[2];
Xl[1][3]=Xl[3][3]^Xl[4][3]^Xl[0][3]^RKL[3];
S_BOX_bs(Xh[1][0],Xl[1][0],Xh[1][0],Xl[1][0]);
S_BOX_bs(Xh[1][1],Xl[1][1],Xh[1][1],Xl[1][1]);
S_BOX_bs(Xh[1][2],Xl[1][2],Xh[1][2],Xl[1][2]);
S_BOX_bs(Xh[1][3],Xl[1][3],Xh[1][3],Xl[1][3]);
TH[0]=Xh[2][0]^Xh[1][0]^((Xh[1][0]&0x3333333333333333)<<2)^((Xl[1][0]>>2)&0x3333333333333333)^((Xh[1][1]&0x3333333333333333)<<2)^((Xl[1][1]>>2)&0x3333333333333333)^((Xh[1][2]&0x3333333333333333)<<2)^((Xl[1][2]>>2)&0x3333333333333333)^((Xh[1][3]&0xffffffffffffffff)<<0)^((Xl[1][3]>>4)&0x0000000000000000);
TH[1]=Xh[2][1]^Xh[1][1]^((Xh[1][1]&0x3333333333333333)<<2)^((Xl[1][1]>>2)&0x3333333333333333)^((Xh[1][2]&0x3333333333333333)<<2)^((Xl[1][2]>>2)&0x3333333333333333)^((Xh[1][3]&0x3333333333333333)<<2)^((Xl[1][3]>>2)&0x3333333333333333)^((Xh[1][0]&0xffffffffffffffff)<<0)^((Xl[1][0]>>4)&0x0000000000000000);
TH[2]=Xh[2][2]^Xh[1][2]^((Xh[1][2]&0x3333333333333333)<<2)^((Xl[1][2]>>2)&0x3333333333333333)^((Xh[1][3]&0x3333333333333333)<<2)^((Xl[1][3]>>2)&0x3333333333333333)^((Xh[1][0]&0x3333333333333333)<<2)^((Xl[1][0]>>2)&0x3333333333333333)^((Xh[1][1]&0xffffffffffffffff)<<0)^((Xl[1][1]>>4)&0x0000000000000000);
TH[3]=Xh[2][3]^Xh[1][3]^((Xh[1][3]&0x3333333333333333)<<2)^((Xl[1][3]>>2)&0x3333333333333333)^((Xh[1][0]&0x3333333333333333)<<2)^((Xl[1][0]>>2)&0x3333333333333333)^((Xh[1][1]&0x3333333333333333)<<2)^((Xl[1][1]>>2)&0x3333333333333333)^((Xh[1][2]&0xffffffffffffffff)<<0)^((Xl[1][2]>>4)&0x0000000000000000);
TL[0]=Xl[2][0]^Xl[1][0]^((Xl[1][0]&0x3333333333333333)<<2)^((Xh[1][1]>>2)&0x3333333333333333)^((Xl[1][1]&0x3333333333333333)<<2)^((Xh[1][2]>>2)&0x3333333333333333)^((Xl[1][2]&0x3333333333333333)<<2)^((Xh[1][3]>>2)&0x3333333333333333)^((Xl[1][3]&0xffffffffffffffff)<<0)^((Xh[1][3]>>4)&0x0000000000000000);
TL[1]=Xl[2][1]^Xl[1][1]^((Xl[1][1]&0x3333333333333333)<<2)^((Xh[1][2]>>2)&0x3333333333333333)^((Xl[1][2]&0x3333333333333333)<<2)^((Xh[1][3]>>2)&0x3333333333333333)^((Xl[1][3]&0x3333333333333333)<<2)^((Xh[1][0]>>2)&0x3333333333333333)^((Xl[1][0]&0xffffffffffffffff)<<0)^((Xh[1][0]>>4)&0x0000000000000000);
TL[2]=Xl[2][2]^Xl[1][2]^((Xl[1][2]&0x3333333333333333)<<2)^((Xh[1][3]>>2)&0x3333333333333333)^((Xl[1][3]&0x3333333333333333)<<2)^((Xh[1][0]>>2)&0x3333333333333333)^((Xl[1][0]&0x3333333333333333)<<2)^((Xh[1][1]>>2)&0x3333333333333333)^((Xl[1][1]&0xffffffffffffffff)<<0)^((Xh[1][1]>>4)&0x0000000000000000);
TL[3]=Xl[2][3]^Xl[1][3]^((Xl[1][3]&0x3333333333333333)<<2)^((Xh[1][0]>>2)&0x3333333333333333)^((Xl[1][0]&0x3333333333333333)<<2)^((Xh[1][1]>>2)&0x3333333333333333)^((Xl[1][1]&0x3333333333333333)<<2)^((Xh[1][2]>>2)&0x3333333333333333)^((Xl[1][2]&0xffffffffffffffff)<<0)^((Xh[1][2]>>4)&0x0000000000000000);
Xh[1][0]=TH[0];
Xh[1][1]=TH[1];
Xh[1][2]=TH[2];
Xh[1][3]=TH[3];
Xl[1][0]=TL[0];
Xl[1][1]=TL[1];
Xl[1][2]=TL[2];
Xl[1][3]=TL[3];
}
void ROUND_BS3(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4])
{
unsigned __int64 TH[4];
unsigned __int64 TL[4];
Xh[2][0]=Xh[4][0]^Xh[0][0]^Xh[1][0]^RKH[0];
Xh[2][1]=Xh[4][1]^Xh[0][1]^Xh[1][1]^RKH[1];
Xh[2][2]=Xh[4][2]^Xh[0][2]^Xh[1][2]^RKH[2];
Xh[2][3]=Xh[4][3]^Xh[0][3]^Xh[1][3]^RKH[3];
Xl[2][0]=Xl[4][0]^Xl[0][0]^Xl[1][0]^RKL[0];
Xl[2][1]=Xl[4][1]^Xl[0][1]^Xl[1][1]^RKL[1];
Xl[2][2]=Xl[4][2]^Xl[0][2]^Xl[1][2]^RKL[2];
Xl[2][3]=Xl[4][3]^Xl[0][3]^Xl[1][3]^RKL[3];
S_BOX_bs(Xh[2][0],Xl[2][0],Xh[2][0],Xl[2][0]);
S_BOX_bs(Xh[2][1],Xl[2][1],Xh[2][1],Xl[2][1]);
S_BOX_bs(Xh[2][2],Xl[2][2],Xh[2][2],Xl[2][2]);
S_BOX_bs(Xh[2][3],Xl[2][3],Xh[2][3],Xl[2][3]);
TH[0]=Xh[3][0]^Xh[2][0]^((Xh[2][0]&0x3333333333333333)<<2)^((Xl[2][0]>>2)&0x3333333333333333)^((Xh[2][1]&0x3333333333333333)<<2)^((Xl[2][1]>>2)&0x3333333333333333)^((Xh[2][2]&0x3333333333333333)<<2)^((Xl[2][2]>>2)&0x3333333333333333)^((Xh[2][3]&0xffffffffffffffff)<<0)^((Xl[2][3]>>4)&0x0000000000000000);
TH[1]=Xh[3][1]^Xh[2][1]^((Xh[2][1]&0x3333333333333333)<<2)^((Xl[2][1]>>2)&0x3333333333333333)^((Xh[2][2]&0x3333333333333333)<<2)^((Xl[2][2]>>2)&0x3333333333333333)^((Xh[2][3]&0x3333333333333333)<<2)^((Xl[2][3]>>2)&0x3333333333333333)^((Xh[2][0]&0xffffffffffffffff)<<0)^((Xl[2][0]>>4)&0x0000000000000000);
TH[2]=Xh[3][2]^Xh[2][2]^((Xh[2][2]&0x3333333333333333)<<2)^((Xl[2][2]>>2)&0x3333333333333333)^((Xh[2][3]&0x3333333333333333)<<2)^((Xl[2][3]>>2)&0x3333333333333333)^((Xh[2][0]&0x3333333333333333)<<2)^((Xl[2][0]>>2)&0x3333333333333333)^((Xh[2][1]&0xffffffffffffffff)<<0)^((Xl[2][1]>>4)&0x0000000000000000);
TH[3]=Xh[3][3]^Xh[2][3]^((Xh[2][3]&0x3333333333333333)<<2)^((Xl[2][3]>>2)&0x3333333333333333)^((Xh[2][0]&0x3333333333333333)<<2)^((Xl[2][0]>>2)&0x3333333333333333)^((Xh[2][1]&0x3333333333333333)<<2)^((Xl[2][1]>>2)&0x3333333333333333)^((Xh[2][2]&0xffffffffffffffff)<<0)^((Xl[2][2]>>4)&0x0000000000000000);
TL[0]=Xl[3][0]^Xl[2][0]^((Xl[2][0]&0x3333333333333333)<<2)^((Xh[2][1]>>2)&0x3333333333333333)^((Xl[2][1]&0x3333333333333333)<<2)^((Xh[2][2]>>2)&0x3333333333333333)^((Xl[2][2]&0x3333333333333333)<<2)^((Xh[2][3]>>2)&0x3333333333333333)^((Xl[2][3]&0xffffffffffffffff)<<0)^((Xh[2][3]>>4)&0x0000000000000000);
TL[1]=Xl[3][1]^Xl[2][1]^((Xl[2][1]&0x3333333333333333)<<2)^((Xh[2][2]>>2)&0x3333333333333333)^((Xl[2][2]&0x3333333333333333)<<2)^((Xh[2][3]>>2)&0x3333333333333333)^((Xl[2][3]&0x3333333333333333)<<2)^((Xh[2][0]>>2)&0x3333333333333333)^((Xl[2][0]&0xffffffffffffffff)<<0)^((Xh[2][0]>>4)&0x0000000000000000);
TL[2]=Xl[3][2]^Xl[2][2]^((Xl[2][2]&0x3333333333333333)<<2)^((Xh[2][3]>>2)&0x3333333333333333)^((Xl[2][3]&0x3333333333333333)<<2)^((Xh[2][0]>>2)&0x3333333333333333)^((Xl[2][0]&0x3333333333333333)<<2)^((Xh[2][1]>>2)&0x3333333333333333)^((Xl[2][1]&0xffffffffffffffff)<<0)^((Xh[2][1]>>4)&0x0000000000000000);
TL[3]=Xl[3][3]^Xl[2][3]^((Xl[2][3]&0x3333333333333333)<<2)^((Xh[2][0]>>2)&0x3333333333333333)^((Xl[2][0]&0x3333333333333333)<<2)^((Xh[2][1]>>2)&0x3333333333333333)^((Xl[2][1]&0x3333333333333333)<<2)^((Xh[2][2]>>2)&0x3333333333333333)^((Xl[2][2]&0xffffffffffffffff)<<0)^((Xh[2][2]>>4)&0x0000000000000000);
Xh[2][0]=TH[0];
Xh[2][1]=TH[1];
Xh[2][2]=TH[2];
Xh[2][3]=TH[3];
Xl[2][0]=TL[0];
Xl[2][1]=TL[1];
Xl[2][2]=TL[2];
Xl[2][3]=TL[3];
}
void ROUND_BS4(unsigned __int64 Xh[5][4],unsigned __int64 Xl[5][4],unsigned __int64 RKH[4],unsigned __int64 RKL[4])
{
unsigned __int64 TH[4];
unsigned __int64 TL[4];
Xh[3][0]=Xh[0][0]^Xh[1][0]^Xh[2][0]^RKH[0];
Xh[3][1]=Xh[0][1]^Xh[1][1]^Xh[2][1]^RKH[1];
Xh[3][2]=Xh[0][2]^Xh[1][2]^Xh[2][2]^RKH[2];
Xh[3][3]=Xh[0][3]^Xh[1][3]^Xh[2][3]^RKH[3];
Xl[3][0]=Xl[0][0]^Xl[1][0]^Xl[2][0]^RKL[0];
Xl[3][1]=Xl[0][1]^Xl[1][1]^Xl[2][1]^RKL[1];
Xl[3][2]=Xl[0][2]^Xl[1][2]^Xl[2][2]^RKL[2];
Xl[3][3]=Xl[0][3]^Xl[1][3]^Xl[2][3]^RKL[3];
S_BOX_bs(Xh[3][0],Xl[3][0],Xh[3][0],Xl[3][0]);
S_BOX_bs(Xh[3][1],Xl[3][1],Xh[3][1],Xl[3][1]);
S_BOX_bs(Xh[3][2],Xl[3][2],Xh[3][2],Xl[3][2]);
S_BOX_bs(Xh[3][3],Xl[3][3],Xh[3][3],Xl[3][3]);
TH[0]=Xh[4][0]^Xh[3][0]^((Xh[3][0]&0x3333333333333333)<<2)^((Xl[3][0]>>2)&0x3333333333333333)^((Xh[3][1]&0x3333333333333333)<<2)^((Xl[3][1]>>2)&0x3333333333333333)^((Xh[3][2]&0x3333333333333333)<<2)^((Xl[3][2]>>2)&0x3333333333333333)^((Xh[3][3]&0xffffffffffffffff)<<0)^((Xl[3][3]>>4)&0x0000000000000000);
TH[1]=Xh[4][1]^Xh[3][1]^((Xh[3][1]&0x3333333333333333)<<2)^((Xl[3][1]>>2)&0x3333333333333333)^((Xh[3][2]&0x3333333333333333)<<2)^((Xl[3][2]>>2)&0x3333333333333333)^((Xh[3][3]&0x3333333333333333)<<2)^((Xl[3][3]>>2)&0x3333333333333333)^((Xh[3][0]&0xffffffffffffffff)<<0)^((Xl[3][0]>>4)&0x0000000000000000);
TH[2]=Xh[4][2]^Xh[3][2]^((Xh[3][2]&0x3333333333333333)<<2)^((Xl[3][2]>>2)&0x3333333333333333)^((Xh[3][3]&0x3333333333333333)<<2)^((Xl[3][3]>>2)&0x3333333333333333)^((Xh[3][0]&0x3333333333333333)<<2)^((Xl[3][0]>>2)&0x3333333333333333)^((Xh[3][1]&0xffffffffffffffff)<<0)^((Xl[3][1]>>4)&0x0000000000000000);
TH[3]=Xh[4][3]^Xh[3][3]^((Xh[3][3]&0x3333333333333333)<<2)^((Xl[3][3]>>2)&0x3333333333333333)^((Xh[3][0]&0x3333333333333333)<<2)^((Xl[3][0]>>2)&0x3333333333333333)^((Xh[3][1]&0x3333333333333333)<<2)^((Xl[3][1]>>2)&0x3333333333333333)^((Xh[3][2]&0xffffffffffffffff)<<0)^((Xl[3][2]>>4)&0x0000000000000000);
TL[0]=Xl[4][0]^Xl[3][0]^((Xl[3][0]&0x3333333333333333)<<2)^((Xh[3][1]>>2)&0x3333333333333333)^((Xl[3][1]&0x3333333333333333)<<2)^((Xh[3][2]>>2)&0x3333333333333333)^((Xl[3][2]&0x3333333333333333)<<2)^((Xh[3][3]>>2)&0x3333333333333333)^((Xl[3][3]&0xffffffffffffffff)<<0)^((Xh[3][3]>>4)&0x0000000000000000);
TL[1]=Xl[4][1]^Xl[3][1]^((Xl[3][1]&0x3333333333333333)<<2)^((Xh[3][2]>>2)&0x3333333333333333)^((Xl[3][2]&0x3333333333333333)<<2)^((Xh[3][3]>>2)&0x3333333333333333)^((Xl[3][3]&0x3333333333333333)<<2)^((Xh[3][0]>>2)&0x3333333333333333)^((Xl[3][0]&0xffffffffffffffff)<<0)^((Xh[3][0]>>4)&0x0000000000000000);
TL[2]=Xl[4][2]^Xl[3][2]^((Xl[3][2]&0x3333333333333333)<<2)^((Xh[3][3]>>2)&0x3333333333333333)^((Xl[3][3]&0x3333333333333333)<<2)^((Xh[3][0]>>2)&0x3333333333333333)^((Xl[3][0]&0x3333333333333333)<<2)^((Xh[3][1]>>2)&0x3333333333333333)^((Xl[3][1]&0xffffffffffffffff)<<0)^((Xh[3][1]>>4)&0x0000000000000000);
TL[3]=Xl[4][3]^Xl[3][3]^((Xl[3][3]&0x3333333333333333)<<2)^((Xh[3][0]>>2)&0x3333333333333333)^((Xl[3][0]&0x3333333333333333)<<2)^((Xh[3][1]>>2)&0x3333333333333333)^((Xl[3][1]&0x3333333333333333)<<2)^((Xh[3][2]>>2)&0x3333333333333333)^((Xl[3][2]&0xffffffffffffffff)<<0)^((Xh[3][2]>>4)&0x0000000000000000);
Xh[3][0]=TH[0];
Xh[3][1]=TH[1];
Xh[3][2]=TH[2];
Xh[3][3]=TH[3];
Xl[3][0]=TL[0];
Xl[3][1]=TL[1];
Xl[3][2]=TL[2];
Xl[3][3]=TL[3];
}
void print_bit(unsigned __int64 x)
{
__int64 i;
for(i=0;i<32;i++){printf("%d",(x>>(31-i))&1);if(i%4==3)printf(" ");}printf("\n");
}
void sms4_set_encrypt_key_bs(sms4_key_t_bs *key,unsigned __int64 *user_keyh,unsigned __int64 *user_keyl)
{
unsigned __int64 Xh[5][4],Xl[5][4],ckh[4],ckl[4];
unsigned __int64 *RKh,*RKl;
RKh=&(key->rkh[0][0]);
RKl=&(key->rkl[0][0]);
Xh[0][0]=user_keyh[0]^FK_BS00h;
Xh[0][1]=user_keyh[1]^FK_BS01h;
Xh[0][2]=user_keyh[2]^FK_BS02h;
Xh[0][3]=user_keyh[3]^FK_BS03h;
Xl[0][0]=user_keyl[0]^FK_BS00l;
Xl[0][1]=user_keyl[1]^FK_BS01l;
Xl[0][2]=user_keyl[2]^FK_BS02l;
Xl[0][3]=user_keyl[3]^FK_BS03l;
Xh[1][0]=user_keyh[4]^FK_BS10h;
Xh[1][1]=user_keyh[5]^FK_BS11h;
Xh[1][2]=user_keyh[6]^FK_BS12h;
Xh[1][3]=user_keyh[7]^FK_BS13h;
Xl[1][0]=user_keyl[4]^FK_BS10l;
Xl[1][1]=user_keyl[5]^FK_BS11l;
Xl[1][2]=user_keyl[6]^FK_BS12l;
Xl[1][3]=user_keyl[7]^FK_BS13l;
Xh[2][0]=user_keyh[8 ]^FK_BS20h;
Xh[2][1]=user_keyh[9 ]^FK_BS21h;
Xh[2][2]=user_keyh[10]^FK_BS22h;
Xh[2][3]=user_keyh[11]^FK_BS23h;
Xl[2][0]=user_keyl[8 ]^FK_BS20l;
Xl[2][1]=user_keyl[9 ]^FK_BS21l;
Xl[2][2]=user_keyl[10]^FK_BS22l;
Xl[2][3]=user_keyl[11]^FK_BS23l;
Xh[3][0]=user_keyh[12]^FK_BS30h;
Xh[3][1]=user_keyh[13]^FK_BS31h;
Xh[3][2]=user_keyh[14]^FK_BS32h;
Xh[3][3]=user_keyh[15]^FK_BS33h;
Xl[3][0]=user_keyl[12]^FK_BS30l;
Xl[3][1]=user_keyl[13]^FK_BS31l;
Xl[3][2]=user_keyl[14]^FK_BS32l;
Xl[3][3]=user_keyl[15]^FK_BS33l;
ENC_ROUND_BS0(Xh,Xl,RKh,RKl,0,0);
RKh+=4;RKl+=4;
ENC_ROUND_BS1(Xh,Xl,RKh,RKl,0,1);
RKh+=4;RKl+=4;
ENC_ROUND_BS2(Xh,Xl,RKh,RKl,0,2);
RKh+=4;RKl+=4;
ENC_ROUND_BS3(Xh,Xl,RKh,RKl,0,3);
RKh+=4;RKl+=4;
ENC_ROUND_BS4(Xh,Xl,RKh,RKl,0,4);
RKh+=4;RKl+=4;
ENC_ROUND_BS0(Xh,Xl,RKh,RKl,0,5);
RKh+=4;RKl+=4;
ENC_ROUND_BS1(Xh,Xl,RKh,RKl,0,6);
RKh+=4;RKl+=4;
ENC_ROUND_BS2(Xh,Xl,RKh,RKl,0,7);
RKh+=4;RKl+=4;
ENC_ROUND_BS3(Xh,Xl,RKh,RKl,0,8);
RKh+=4;RKl+=4;
ENC_ROUND_BS4(Xh,Xl,RKh,RKl,0,9);
RKh+=4;RKl+=4;
ENC_ROUND_BS0(Xh,Xl,RKh,RKl,0,10);
RKh+=4;RKl+=4;
ENC_ROUND_BS1(Xh,Xl,RKh,RKl,0,11);
RKh+=4;RKl+=4;
ENC_ROUND_BS2(Xh,Xl,RKh,RKl,0,12);
RKh+=4;RKl+=4;
ENC_ROUND_BS3(Xh,Xl,RKh,RKl,0,13);
RKh+=4;RKl+=4;
ENC_ROUND_BS4(Xh,Xl,RKh,RKl,0,14);
RKh+=4;RKl+=4;
ENC_ROUND_BS0(Xh,Xl,RKh,RKl,0,15);
RKh+=4;RKl+=4;
ENC_ROUND_BS1(Xh,Xl,RKh,RKl,1,0);
RKh+=4;RKl+=4;
ENC_ROUND_BS2(Xh,Xl,RKh,RKl,1,1);
RKh+=4;RKl+=4;
ENC_ROUND_BS3(Xh,Xl,RKh,RKl,1,2);
RKh+=4;RKl+=4;
ENC_ROUND_BS4(Xh,Xl,RKh,RKl,1,3);
RKh+=4;RKl+=4;
ENC_ROUND_BS0(Xh,Xl,RKh,RKl,1,4);
RKh+=4;RKl+=4;
ENC_ROUND_BS1(Xh,Xl,RKh,RKl,1,5);
RKh+=4;RKl+=4;
ENC_ROUND_BS2(Xh,Xl,RKh,RKl,1,6);
RKh+=4;RKl+=4;
ENC_ROUND_BS3(Xh,Xl,RKh,RKl,1,7);
RKh+=4;RKl+=4;
ENC_ROUND_BS4(Xh,Xl,RKh,RKl,1,8);
RKh+=4;RKl+=4;
ENC_ROUND_BS0(Xh,Xl,RKh,RKl,1,9);
RKh+=4;RKl+=4;
ENC_ROUND_BS1(Xh,Xl,RKh,RKl,1,10);
RKh+=4;RKl+=4;
ENC_ROUND_BS2(Xh,Xl,RKh,RKl,1,11);
RKh+=4;RKl+=4;
ENC_ROUND_BS3(Xh,Xl,RKh,RKl,1,12);
RKh+=4;RKl+=4;
ENC_ROUND_BS4(Xh,Xl,RKh,RKl,1,13);
RKh+=4;RKl+=4;
ENC_ROUND_BS0(Xh,Xl,RKh,RKl,1,14);
RKh+=4;RKl+=4;
ENC_ROUND_BS1(Xh,Xl,RKh,RKl,1,15);
}
void SMS4_encrypt_bs(sms4_key_t_bs *key,unsigned __int64 *INh,unsigned __int64 *INl,unsigned __int64 *OUTh,unsigned __int64 *OUTl)
{
unsigned __int64 Xh[5][4],Xl[5][4],ckh[4],ckl[4];
unsigned __int64 *RKh,*RKl;
RKh=&(key->rkh[0][0]);
RKl=&(key->rkl[0][0]);
Xh[0][0]=INh[0];
Xh[0][1]=INh[1];
Xh[0][2]=INh[2];
Xh[0][3]=INh[3];
Xl[0][0]=INl[0];
Xl[0][1]=INl[1];
Xl[0][2]=INl[2];
Xl[0][3]=INl[3];
Xh[1][0]=INh[4];
Xh[1][1]=INh[5];
Xh[1][2]=INh[6];
Xh[1][3]=INh[7];
Xl[1][0]=INl[4];
Xl[1][1]=INl[5];
Xl[1][2]=INl[6];
Xl[1][3]=INl[7];
Xh[2][0]=INh[8 ];
Xh[2][1]=INh[9 ];
Xh[2][2]=INh[10];
Xh[2][3]=INh[11];
Xl[2][0]=INl[8 ];
Xl[2][1]=INl[9 ];
Xl[2][2]=INl[10];
Xl[2][3]=INl[11];
Xh[3][0]=INh[12];
Xh[3][1]=INh[13];
Xh[3][2]=INh[14];
Xh[3][3]=INh[15];
Xl[3][0]=INl[12];
Xl[3][1]=INl[13];
Xl[3][2]=INl[14];
Xl[3][3]=INl[15];
ROUND_BS0(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS1(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS2(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS3(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS4(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS0(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS1(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS2(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS3(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS4(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS0(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS1(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS2(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS3(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS4(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS0(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS1(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS2(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS3(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS4(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS0(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS1(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS2(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS3(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS4(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS0(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS1(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS2(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS3(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS4(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS0(Xh,Xl,RKh,RKl);
RKh+=4;RKl+=4;
ROUND_BS1(Xh,Xl,RKh,RKl);
OUTh[0]=Xh[0][0];
OUTh[1]=Xh[0][1];
OUTh[2]=Xh[0][2];
OUTh[3]=Xh[0][3];
OUTl[0]=Xl[0][0];
OUTl[1]=Xl[0][1];
OUTl[2]=Xl[0][2];
OUTl[3]=Xl[0][3];
OUTh[4]=Xh[4][0];
OUTh[5]=Xh[4][1];
OUTh[6]=Xh[4][2];
OUTh[7]=Xh[4][3];
OUTl[4]=Xl[4][0];
OUTl[5]=Xl[4][1];
OUTl[6]=Xl[4][2];
OUTl[7]=Xl[4][3];
OUTh[8 ]=Xh[3][0];
OUTh[9 ]=Xh[3][1];
OUTh[10]=Xh[3][2];
OUTh[11]=Xh[3][3];
OUTl[8 ]=Xl[3][0];
OUTl[9 ]=Xl[3][1];
OUTl[10]=Xl[3][2];
OUTl[11]=Xl[3][3];
OUTh[12]=Xh[2][0];
OUTh[13]=Xh[2][1];
OUTh[14]=Xh[2][2];
OUTh[15]=Xh[2][3];
OUTl[12]=Xl[2][0];
OUTl[13]=Xl[2][1];
OUTl[14]=Xl[2][2];
OUTl[15]=Xl[2][3];
}

55
include/openssl/sm4_bs.h Normal file
View File

@@ -0,0 +1,55 @@
#define SMS4_NUM_ROUNDS_BS 32
typedef struct
{
unsigned __int64 rkh[SMS4_NUM_ROUNDS_BS][4];
unsigned __int64 rkl[SMS4_NUM_ROUNDS_BS][4];
} sms4_key_t_bs;
#define FK_BS00h (0xaaaaaaaaaaaaaaaa)
#define FK_BS00l (0x3333333333333333)
#define FK_BS01h (0xbbbbbbbbbbbbbbbb)
#define FK_BS01l (0x1111111111111111)
#define FK_BS02h (0xbbbbbbbbbbbbbbbb)
#define FK_BS02l (0xaaaaaaaaaaaaaaaa)
#define FK_BS03h (0xcccccccccccccccc)
#define FK_BS03l (0x6666666666666666)
#define FK_BS10h (0x5555555555555555)
#define FK_BS10l (0x6666666666666666)
#define FK_BS11h (0xaaaaaaaaaaaaaaaa)
#define FK_BS11l (0xaaaaaaaaaaaaaaaa)
#define FK_BS12h (0x3333333333333333)
#define FK_BS12l (0x3333333333333333)
#define FK_BS13h (0x5555555555555555)
#define FK_BS13l (0x0000000000000000)
//0x677d9197, 0xb27022dc,
#define FK_BS20h (0x6666666666666666)
#define FK_BS20l (0x7777777777777777)
#define FK_BS21h (0x7777777777777777)
#define FK_BS21l (0xdddddddddddddddd)
#define FK_BS22h (0x9999999999999999)
#define FK_BS22l (0x1111111111111111)
#define FK_BS23h (0x9999999999999999)
#define FK_BS23l (0x7777777777777777)
#define FK_BS30h (0xbbbbbbbbbbbbbbbb)
#define FK_BS30l (0x2222222222222222)
#define FK_BS31h (0x7777777777777777)
#define FK_BS31l (0x0000000000000000)
#define FK_BS32h (0x2222222222222222)
#define FK_BS32l (0x2222222222222222)
#define FK_BS33h (0xdddddddddddddddd)
#define FK_BS33l (0xcccccccccccccccc)
void sms4_set_encrypt_key_bs(sms4_key_t_bs *key,unsigned __int64 *user_keyh,unsigned __int64 *user_keyl);
void SMS4_encrypt_bs(sms4_key_t_bs *key,unsigned __int64 *INh,unsigned __int64 *INl,unsigned __int64 *OUTh,unsigned __int64 *OUTl);

29
test/sm4_bs_test.c Normal file
View File

@@ -0,0 +1,29 @@
#include <stdio.h>
#include <time.h>
#include "sm4_bs.h"
unsigned __int64 ukeyh[16]={0x0000000000000000,0x2222222222222222,0x4444444444444444,0x6666666666666666,0x8888888888888888,0xAAAAAAAAAAAAAAAA,0xCCCCCCCCCCCCCCCC,0xEEEEEEEEEEEEEEEE,0xFFFFFFFFFFFFFFFF,0xDDDDDDDDDDDDDDDD,0xBBBBBBBBBBBBBBBB,0x9999999999999999,0x7777777777777777,0x5555555555555555,0x3333333333333333,0x1111111111111111};
unsigned __int64 ukeyl[16]={0x1111111111111111,0x3333333333333333,0x5555555555555555,0x7777777777777777,0x9999999999999999,0xBBBBBBBBBBBBBBBB,0xDDDDDDDDDDDDDDDD,0xFFFFFFFFFFFFFFFF,0xEEEEEEEEEEEEEEEE,0xCCCCCCCCCCCCCCCC,0xAAAAAAAAAAAAAAAA,0x8888888888888888,0x6666666666666666,0x4444444444444444,0x2222222222222222,0x0000000000000000};
unsigned __int64 inh[16]={0x0000000000000000,0x2222222222222222,0x4444444444444444,0x6666666666666666,0x8888888888888888,0xAAAAAAAAAAAAAAAA,0xCCCCCCCCCCCCCCCC,0xEEEEEEEEEEEEEEEE,0xFFFFFFFFFFFFFFFF,0xDDDDDDDDDDDDDDDD,0xBBBBBBBBBBBBBBBB,0x9999999999999999,0x7777777777777777,0x5555555555555555,0x3333333333333333,0x1111111111111111};
unsigned __int64 inl[16]={0x1111111111111111,0x3333333333333333,0x5555555555555555,0x7777777777777777,0x9999999999999999,0xBBBBBBBBBBBBBBBB,0xDDDDDDDDDDDDDDDD,0xFFFFFFFFFFFFFFFF,0xEEEEEEEEEEEEEEEE,0xCCCCCCCCCCCCCCCC,0xAAAAAAAAAAAAAAAA,0x8888888888888888,0x6666666666666666,0x4444444444444444,0x2222222222222222,0x0000000000000000};
void main()
{
clock_t t1,t2;
unsigned int p;
int i,j;
sms4_key_t_bs keybs;
printf("pai:\n");
scanf("%d",&p);
sms4_set_encrypt_key_bs(&keybs,ukeyh,ukeyl);
t1 = clock();
for(i=0;i<p;i++)
{
SMS4_encrypt_bs(&keybs,inh,inl,inh,inl);
}
t2 = clock();
printf(" %f %f %f B/s\n",(double)(t2-t1)/CLOCKS_PER_SEC,(16.0*p)/((double)(t2-t1)/CLOCKS_PER_SEC),(16.0*p*16)/((double)(t2-t1)/CLOCKS_PER_SEC));
for(j=0;j<16;j++){for(i=0;i<16;i++){printf("%x%x,",(unsigned char)(inh[i]>>j*4)&0xf,(unsigned char)(inl[i]>>j*4)&0xf);}printf("\n");}
//68,1e,df,34,d2,06,96,5e,86,b3,e9,4f,53,6e,42,46,
}