#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SIZE 262144
int h3[16][256];
int h4[16][256];
typedef union uni {
unsigned long long int dd[2];
unsigned int cc[4];
unsigned short ss[8];
unsigned char m[16];
} on;
unsigned long long int ff;
unsigned long long int f;
unsigned long long int g[256][2],g2[256][2];
unsigned int f2=0xffffffff;
unsigned long long int G[16][16][2];
on c1,c2,u,u1,a,b,GG,H,dd,de,IV,VI;
unsigned char buf[32]={0};
unsigned char buf1[16]={0};
unsigned char buf2[16]={0};
unsigned long long int c3[5];
unsigned char e[32];
unsigned char buff[SIZE];
int pp;
int N=256;
int K=16;
unsigned char gf[256]={0,1,2,4,8,16,32,64,128,29,58,116,232,205,135,19,38,76,152,45,90,180,117,234,201,143,3,6,12,24,48,96,192,157,39,78,156,37,74,148,53,106,212,181,119,238,193,159,35,70,140,5,10,20,40,80,160,93,186,105,210,185,111,222,161,95,190,97,194,153,47,94,188,101,202,137,15,30,60,120,240,253,231,211,187,107,214,177,127,254,225,223,163,91,182,113,226,217,175,67,134,17,34,68,136,13,26,52,104,208,189,103,206,129,31,62,124,248,237,199,147,59,118,236,197,151,51,102,204,133,23,46,92,184,109,218,169,79,158,33,66,132,21,42,84,168,77,154,41,82,164,85,170,73,146,57,114,228,213,183,115,230,209,191,99,198,145,63,126,252,229,215,179,123,246,241,255,227,219,171,75,150,49,98,196,149,55,110,220,165,87,174,65,130,25,50,100,200,141,7,14,28,56,112,224,221,167,83,166,81,162,89,178,121,242,249,239,195,155,43,86,172,69,138,9,18,36,72,144,61,122,244,245,247,243,251,235,203,139,11,22,44,88,176,125,250,233,207,131,27,54,108,216,173,71,142};
unsigned char fg[256]={0,1,2,26,3,51,27,199,4,224,52,239,28,105,200,76,5,101,225,15,53,142,240,130,29,194,106,249,201,9,77,114,6,139,102,48,226,37,16,34,54,148,143,219,241,19,131,70,30,182,195,126,107,40,250,186,202,155,10,121,78,229,115,167,7,192,140,99,103,222,49,254,227,153,38,180,17,146,35,137,55,209,149,207,144,151,220,190,242,211,20,93,132,57,71,65,31,67,183,164,196,73,127,111,108,59,41,85,251,134,187,62,203,95,156,160,11,22,122,44,79,213,230,173,116,244,168,88,8,113,193,248,141,129,100,14,104,75,223,238,50,198,255,25,228,166,154,120,39,185,181,125,18,69,147,218,36,33,138,47,56,64,210,92,150,189,208,206,145,136,152,179,221,253,191,98,243,87,212,172,21,43,94,159,133,61,58,84,72,110,66,163,32,46,68,217,184,124,165,119,197,24,74,237,128,13,112,247,109,162,60,83,42,158,86,171,252,97,135,178,188,205,63,91,204,90,96,177,157,170,161,82,12,246,23,236,123,118,45,216,80,175,214,234,231,232,174,233,117,215,245,235,169,81,89,176};
unsigned char gg[16];
unsigned char F[16];
void fi(){
int i,j;
for(i=0;i<N;i++){
for(j=0;j<N;j++){
if(gf[j]==i)
printf("%u,",j);
}
}
}
int mlt(int x, int y){
if(x==0||y==0)
return 0;
return ((x+y-2)%(N-1))+1;
}
int mltn(int n,int x){
int i,j;
i=x;
for(j=0;j<n-1;j++)
i=mlt(i,x);
return i;
}
int dv(int x,int y){
if(x==0)
return 0;
return ((x-y+(N-1))%(N-1))+1;
}
int code (char str[256]){
int i,c,d;
unsigned long long int u=0;
i=0;
do
{
c = str[i] & 0xff;
e[i]=c;
if((c & 0x80) > 0)
{
++i;
d = str[i] & 0xff;
e[i]=d;
c^=(d<<8);
}
else
{
}
++i;
}while(c != '\0');
for(i=0;i<8;i++){
u=(u<<8)^e[i];
}
c3[0]=u;u=0;
for(i=8;i<16;i++)
u=(u<<8)^e[i];
c3[1]=u;u=0;
for(i=16;i<24;i++)
u=(u<<8)^e[i];
c3[2]=u;u=0;
for(i=24;i<32;i++)
u=(u<<8)^e[i];
c3[3]=u;
return 0;
}
int cd(char str[256]){
int i,c,d;
unsigned long long int u=0;
i=0;
do
{
c = str[i] & 0xff;
e[i]=c;
if((c & 0x80) > 0)
{
++i;
d = str[i] & 0xff;
e[i]=d;
c^=(d<<8);
}
++i;
}while(c != '\0');
return e[0];
}
void init(unsigned long long int uu[4]){
u.dd[0]=0;
u.dd[1]=0;
u1.dd[0]=0;
u1.dd[1]=0;
c1.cc[0]=2183266401UL;
c1.cc[1]=2186346530UL;
c1.cc[2]=2183266313UL;
c1.cc[3]=2188574773UL;
c2.cc[0]=2212298975UL;
c2.cc[1]=2211905752UL;
c2.cc[2]=2198339796UL;
c2.cc[3]=2210398243UL;
u.dd[0]=uu[0];
u.dd[1]=uu[1];
u1.dd[0]=uu[2];
u1.dd[1]=uu[3];
ff=0xf0f0f0f0f0f0f0f0ULL;
f=0x0f0f0f0f0f0f0f0fULL;
}
void g64(int n){
int i,j;
for(i=0;i<n;i++){
for(j=0;j<8;j++){
g[i][0]=(g[i][0]<<(j*8))^h3[j][i];
g2[i][0]=(g2[i][0]<<(i*8))^h4[j][i];
}
for(j=8;j<16;j++){
g[i][1]=(g[i][1]<<((j-8)*8))^h3[j][i];
g2[i][1]=(g2[i][1]<<((j-8)*8))^h4[j][i];
}
}
}
on s5(on cc){
int a[16]={7,3,15,11,5,1,13,9,6,2,14,10,4,0,12,8};
int i,j;
unsigned int b=0,c;
for(i=0;i<16;i++)
GG.m[a[i]]=cc.m[i];
for(i=0;i<4;i++)
b^=(GG.m[i]<<(8*i));
c=b&0x1f;
b=(b>>5)^(c<<27);
for(i=0;i<4;i++){
GG.m[i]=b&0xff;
b=(b>>8);
}
return GG;
}
void ul(unsigned long long int un[4]){
un[0]=(u.dd[0]^un[0])&ff;
un[1]=(u.dd[1]^un[1])&f;
un[2]=(u1.dd[0]^un[2])&ff;
un[3]=(u1.dd[1]^un[3])&f;
u.dd[1]^=un[pp&0x3];
u.dd[0]^=un[(pp+1)&0x3];
u1.dd[1]^=un[(pp+2)&0x3];
u1.dd[0]^=un[(pp+3)&0x3];
pp++;
u=s5(u);
u1=s5(u1);
}
void hash(unsigned char fin[256]){
int i,j;
char fout[256];
int line=0,k=0,n=0,read_size;
unsigned long long int z,zz;
g64(256);
code(fin);
if(c3[0]>0 && c3[1]==0){
printf("a鍵が短すぎます\n");
exit(1);
}
init(c3);
dd.dd[0]=c3[0];
dd.dd[1]=c3[1];
de.dd[0]=c3[2];
de.dd[1]=c3[3];
while(k<100){
if(de.dd[0]>0){
for(i=0;i<4;i++){
c1.cc[i]=(c1.cc[i]+dd.cc[i]&f2)^c1.cc[(i+1)&0x3];
c2.cc[i]=(c2.cc[i]+de.cc[i]&f2)^c2.cc[(i+1)&0x3];
}
}
if(de.dd[0]==0){
for(i=0;i<4;i++){
c1.cc[i]=(c1.cc[i]+dd.cc[i]&f2)^c1.cc[(i+1)&0x3];
c2.cc[i]=(c2.cc[i]+dd.cc[i]&f2)^c2.cc[(i+1)&0x3];
}
}
z=(c1.dd[0]&&ff)^((c1.dd[1]&ff)>>4);
i=c1.cc[0]%256;
c1.dd[0]^=g[i][0];
c1.dd[1]^=g[i][1];
i=c2.dd[0]%64;
zz=(c2.dd[0]&&ff)^((c2.dd[1]&ff)>>4);
c2.dd[0]^=g[i][0];
c2.dd[1]^=g[i][1];
c1=s5(c1);
c2=s5(c2);
if(u1.dd[0]==0){
for(i=0;i<2;i++){
c1.dd[i]^=u.dd[i];
c2.dd[i]^=u.dd[i];
}
}
if(u1.dd[0]>0){
for(i=0;i<2;i++){
c1.dd[i]^=u.dd[i];
c2.dd[i]^=u1.dd[i];
}
}
k++;
}
c3[0]=c1.dd[0];
c3[1]=c1.dd[1];
c3[2]=c2.dd[0];
c3[3]=c2.dd[1];
i=0;j=0;k=0;
}
void genkey(unsigned char str[256],unsigned char tt[256]){
FILE *fp;
int i;
for(i=0;i<16;i++)
c1.m[i]=0;
for(i=0;i<16;i++)
c2.m[i]=0;
printf("tt is %s \n",tt);
printf("str is %s \n",str);
hash(tt);
printf("genkey\n");
fp=fopen("key.bin","wb");
printf("sizeof c1.m %d end",(int)sizeof(c1.m));
fwrite(c1.m,1,16,fp);
fwrite(c2.m,1,16,fp);
for(i=0;i<16;i++)
printf("%d ",c1.m[i]);
printf("\n");
for(i=0;i<16;i++)
printf("%d ",c2.m[i]);
printf("\n");
hash(str);
fwrite(c1.dd,1,16,fp);
fwrite(c2.dd,1,16,fp);
fclose(fp);
}
void lk(unsigned char t[256]){
unsigned int o=0,x,a,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,c[17],d[2],l[17];
int i,j,read_size,n;
unsigned char e[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char r[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
FILE *fp;
unsigned char str[16],s[256],m[32];
for(i=0;i<256;i++){
s[i]=0;
}
fp=fopen("key.bin","rb");
read_size=fread(gg,1,16,fp);
for(i=1;i<16;i++){
c[i]=gg[i];
}
c[16]=1;
for(x=0;x<N;x++){
a16=gf[mltn(16,fg[x])];
a15=gf[mlt(gg[15],mltn(15,fg[x]))];
a14=gf[mlt(gg[14],mltn(14,fg[x]))];
a13=gf[mlt(gg[13],mltn(13,fg[x]))];
a12=gf[mlt(gg[12],mltn(12,fg[x]))];
a11=gf[mlt(gg[11],mltn(11,fg[x]))];
a10=gf[mlt(gg[10],mltn(10,fg[x]))];
a9=gf[mlt(gg[9],mltn(9,fg[x]))];
a8=gf[mlt(gg[8],mltn(8,fg[x]))];
a7=gf[mlt(gg[7],mltn(7,fg[x]))];
a6=gf[mlt(gg[6],mltn(6,fg[x]))];
a5=gf[mlt(mlt(mlt(fg[x],fg[x]),mlt(fg[x],fg[x])),mlt(gg[5],fg[x]))];
a4=gf[mlt(mlt(mlt(fg[x],fg[x]),mlt(fg[x],fg[x])),gg[4])];
a3=gf[mlt(mlt(fg[x],fg[x]),mlt(fg[x],gg[3]))];
a2=gf[mlt(mlt(fg[x],fg[x]),gg[2])];
a=gf[mlt(fg[x],gg[1])]^gg[0];
a=a^a2^a3^a4^a5^a6^a7^a8^a9^a10^a11^a12^a13^a14^a15^a16;
if(a==0){
printf("lx=%u trace 0\n",x);
for(i=0;i<16;i++){
s[i]=c1.m[i];
s[i+16]=c2.m[i];
}
genkey(s,t);
lk(t);
fclose(fp);
; break; }
}
for(x=0;x<N;x++){
c[0]=gg[0]^a;
d[0]=x;
d[1]=1;
e[15]=1;
for(i=0;i<15;i++)
e[i]=0;
i=K;
while(i>0){
r[i]=gf[mlt(fg[d[1]],fg[e[i-1]])];
r[i-1]=gf[mlt(fg[d[0]],fg[e[i-1]])];
j=K;
while(j>-1){
c[j]=r[j]^gf[fg[c[j]]];
j=j-1;
}
r[i]=c[i];
if(i-2>-1){
e[i-2]=c[i-1];
}
i=i-1;
}
for(i=0;i<K;i++){
h3[i][x]=gf[mlt(fg[e[K-1-i]],dv(1,fg[a]))];
}
}
}
void kk(){
unsigned int o=0,x,a,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,c[17],d[2],l[17];
int i,j,read_size,n;
unsigned char e[16]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
unsigned char r[17]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
FILE *fp;
unsigned char str[16],s[256],t[256],m[32];
fp=fopen("key.bin","rb");
read_size=fread(gg,1,16,fp);
read_size=fread(F,1,16,fp);
for(i=0;i<16;i++){
c[i]=F[i];
}
c[16]=1;
for(x=0;x<N;x++){
a16=gf[mltn(16,fg[x])];
a15=gf[mlt(F[15],mltn(15,fg[x]))];
a14=gf[mlt(F[14],mltn(14,fg[x]))];
a13=gf[mlt(F[13],mltn(13,fg[x]))];
a12=gf[mlt(F[12],mltn(12,fg[x]))];
a11=gf[mlt(F[11],mltn(11,fg[x]))];
a10=gf[mlt(F[10],mltn(10,fg[x]))];
a9=gf[mlt(F[9],mltn(9,fg[x]))];
a8=gf[mlt(F[8],mltn(8,fg[x]))];
a7=gf[mlt(F[7],mltn(7,fg[x]))];
a6=gf[mlt(F[6],mltn(6,fg[x]))];
a5=gf[mlt(mlt(mlt(fg[x],fg[x]),mlt(fg[x],fg[x])),mlt(F[5],fg[x]))];
a4=gf[mlt(mlt(mlt(fg[x],fg[x]),mlt(fg[x],fg[x])),F[4])];
a3=gf[mlt(mlt(fg[x],fg[x]),mlt(fg[x],F[3]))];
a2=gf[mlt(mlt(fg[x],fg[x]),F[2])];
a=gf[mlt(fg[x],F[1])]^F[0];
a=a^a2^a3^a4^a5^a6^a7^a8^a9^a10^a11^a12^a13^a14^a15^a16;
while(a==0){
printf("kx=%u trace 0\n",x);
for(i=0;i<16;i++){
s[i]=c1.m[i];
s[i+16]=c2.m[i];
}
genkey(s,t);
lk(t);
printf("k鍵生成をしました");
fclose(fp);
break;
}
c[0]=F[0]^a;
d[0]=x;
d[1]=1;
e[15]=1;
for(i=0;i<15;i++)
e[i]=0;
i=K;
while(i>0){
r[i]=gf[mlt(fg[d[1]],fg[e[i-1]])];
r[i-1]=gf[mlt(fg[d[0]],fg[e[i-1]])];
j=K;
while(j>-1){
c[j]=r[j]^gf[fg[c[j]]];
j=j-1;
}
r[i]=c[i];
if(i-2>-1){
e[i-2]=c[i-1];
}
i=i-1;
}
for(i=0;i<K;i++)
h4[i][x]=gf[mlt(fg[e[K-1-i]],dv(1,fg[a]))];
}
}
int strrep(char *buf, char *mae, char *ato)
{
char *mituke;
size_t maelen, atolen;
maelen = strlen(mae);
atolen = strlen(ato);
if (maelen == 0 || (mituke = strstr(buf, mae)) == NULL) return 0;
memmove(mituke + atolen, mituke + maelen, strlen(buf) - (mituke + maelen - buf ) + 1);
memcpy(mituke, ato, atolen);
return 1;
}
void p128(int argc,char *argv[]){
int i,j,f;
FILE *fq,*fp;
unsigned char fin[80],fout[80],buf1[16],*buf2[32],buf3[32],*c,s[256],t[256],ss[256],tt[256],m[32];
int line=0,k=0,n=0,read_size;
unsigned long long int z,zz,W1,W2;
short bc;
for(i=0;i<256;i++){
s[i]=0;
t[i]=0;
ss[i]=0;
tt[i]=0;
}
printf("128-bit mode\n");
buf2[32]="--------------------128-Encrypt";
fp=fopen("key.bin","rb");
if(fp==NULL){
printf("認証子を生成します。パスワードを入力してください。\n");
scanf("%s",t);
printf("鍵生成します。ランダムにキーボードを打ってください。");
scanf("%s",s);
genkey(s,t);
lk(t);
printf("l鍵生成をしました\n");
exit(1);
}
fclose(fp);
fp=fopen("key.bin","rb");
if(fp!=NULL){
printf("パスワードを入力してください\n");
scanf("%s",tt);
hash(tt);
fread(ss,1,32,fp);
for(i=0;i<16;i++)
printf("%u ",c1.m[i]);
printf("\n");
for(i=0;i<16;i++)
printf("%u ",ss[i]);
printf("\n");
for(i=0;i<16;i++)
printf("%u ",c2.m[i]);
printf("\n");
for(i=16;i<32;i++)
printf("%u ",ss[i]);
printf("\n");
for(i=0;i<16;i++){
if(ss[i]!=c1.m[i] || ss[i+16]!=c2.m[i]){
printf("a認証に失敗しました\n");
printf("[%d] %u %u %u %u\n",i,ss[i],c1.m[i],ss[i+16],c2.m[i],i);
exit(1);
}
}
read_size=fread(gg,1,16,fp);
lk(t);
}
g64(256);
if(argv[1]==NULL){
printf("perm.exe Version 0.03β\n");
printf("ファイル名が指定されていません。\n");
printf("使い方:動作モード(暗号化 e, 復号化 d) 入力ファイル名 出力ファイル名 パスワード(省略可)\n");
exit(1);
}
f=cd(argv[1]);
fq=fopen(argv[2],"rb");
switch(f){
case 'e':
if(fq==NULL){
printf("入力ファイルが存在しません。\n");
exit(1);
}
sprintf(fout,"%s.bin",argv[2]);
fp=fopen(fout,"wb");
if(argv[3]==NULL){
printf("パスワードが設定されてません\n");
printf("use default password\n");
argv[3]="use default passwprd";
}
code(argv[3]);
if(c3[0]>0 && c3[1]==0){
printf("b鍵が短すぎます\n");
exit(1);
}
if(c3[1]>0 && c3[2]==0){
printf("鍵の長さは128ビットです\n");
}
if(c3[2]>0 && c3[3]==0){
printf("鍵の長さは192ビットです\n");
}
if(c3[3]>0){
printf("鍵の長さは256ビットです\n");
}
init(c3);
dd.dd[0]=c3[0];
dd.dd[1]=c3[1];
de.dd[0]=c3[2];
de.dd[1]=c3[3];
fwrite(buf2[32],1,32,fp);
fwrite(c3,1,32,fp);
fclose(fp);
break;
case 'd':
if(fq==NULL){
printf("入力ファイルが存在しません。\n");
exit(1);
}
strrep(argv[2],".bin","");
sprintf(fout,"%s.out",argv[2]);
printf("%s\n",fout);
fp=fopen(fout,"wb");
fread(buf3,1,32,fq);
fread(c3,1,32,fq);
fclose(fp);
if(strcmp(buf2[32],buf3)){
printf("暗号化ファイルではありません\n");
exit(1);
}
printf("復号処理に入ります\n");
init(c3);
dd.dd[0]=c3[0];
dd.dd[1]=c3[1];
de.dd[0]=c3[2];
de.dd[1]=c3[3];
break;
default:
printf("指定されたモードは存在しません。\n");
exit(1);
}
pp=0;
while((read_size=fread(buff,1,SIZE,fq))){
for(k=0;k<SIZE/16;k++){
for(i=0;i<16;i++)
buf1[i]=buff[k*16+i];
ul(c3);
for(i=0;i<4;i++){
c1.cc[i]=(c1.cc[i]+dd.cc[i]&f2)^u.cc[i]^c1.cc[(i+1)&0x3];
c2.cc[i]=(c2.cc[i]+de.cc[i]&f2)^u1.cc[i]^c2.cc[(i+1)&0x3];
}
W1=0; W2=0;
for(i=0;i<16;i++){
W1^=g[c1.m[i]][0];
W2^=g[c1.m[i]][1];
}
c1.dd[0]^=W1;
c1.dd[1]^=W2;
c1=s5(c1);
for(i=0;i<16;i++){
buf1[i]^=c1.m[i];
}
for(i=0;i<16;i++)
buff[k*16+i]=buf1[i];
}
fwrite(buff,1,read_size,fp);
}
printf("処理が終了しました\n");
fclose(fp);
fclose(fq);
}
int main(int argc ,char *argv[]){
int i ,j,n;
if(argv[1]==NULL){
printf("perm 128-bit version 0.03α\n");
printf("使い方:perm 動作モード(e or d) filename password\n");
exit(1);
}
p128(argc,argv);
}