/* nanoka-gen.c - Block cipher generator - Don Yang (uguu.org) 01/02/05 */ #include #include #include #include #include"nanoka-core.h" static void WriteByteOrderConvert(FILE *outfile, int blocksize); static void WriteDecoderDriver(FILE *outfile, int blocksize); static void WriteDecoderFunc(FILE *outfile, Round *x, int rounds, int iter); static void WriteDecoderHeader(FILE *outfile); static void WriteEncoderDriver(FILE *outfile, int blocksize); static void WriteEncoderFunc(FILE *outfile, Round *x, int rounds, int iter); static void WriteEncoderHeader(FILE *outfile); static void WriteFunction(FILE *outfile, Func *f, int size); static void WriteFunction0(FILE *outfile, Func *f, int index, int end, int *x); static void WriteGraph(FILE *outfile, Round *r, int rounds, int iter, int blocksize); static void WriteTable(FILE *outfile, char *name, unsigned int *table, int size, int reverse); static void WriteTestDriver(FILE *outfile, int blocksize); static void WriteTestHeader(FILE *outfile); static void WriteTestHelper(FILE *outfile, int blocksize); /******************************************************************** main */ int main(int argc, char **argv) { Cipher *c; int a; FILE *file; if( argc < 2 ) { return printf( "%s [-e ] [-d ] [-t ] [-g ]\n\n" " File containing encryption/decryption key\n" "-e Write C encoder source to \n" "-d Write C decoder source to \n" "-t Write C diffusion test source to \n" "-g Write PostScript graph to \n", *argv); } /* Generate */ if( (file = fopen(argv[1], "rb")) == NULL ) return printf("Can not open %s\n", argv[1]); c = GenerateCipher(file); (void)fclose(file); if( c == NULL ) return puts("Out of memory"); printf("blocksize = %d, rounds = %d * %d, funcsize = %d\n", c->blocksize * 4, c->rounds, c->iter, c->funcsize); /* Output */ for(a = 2; a < argc; a++) { if( argv[a][0] != '-' ) continue; if( a + 1 >= argc ) { printf("not enough arguments for %s\n", argv[a - 1]); break; } switch( argv[a][1] ) { case 'e': case 'E': /* Encoder */ if( (file = fopen(argv[++a], "wb+")) == NULL ) { printf("Can not create %s\n", argv[a]); break; } WriteEncoderHeader(file); WriteTable(file, S_TABLE, c->s_table, 32, 0); WriteTable(file, K_TABLE, c->k_table, c->rounds * c->iter, 0); WriteFunction(file, c->f, c->funcsize); WriteEncoderFunc(file, c->r, c->rounds, c->iter); WriteByteOrderConvert(file, c->blocksize); WriteEncoderDriver(file, c->blocksize); (void)fclose(file); break; case 'd': case 'D': /* Decoder */ if( (file = fopen(argv[++a], "wb+")) == NULL ) { printf("Can not create %s\n", argv[a]); break; } WriteDecoderHeader(file); WriteTable(file, S_TABLE, c->s_table, 32, 0); WriteTable(file, K_TABLE, c->k_table, c->rounds * c->iter, 1); WriteFunction(file, c->f, c->funcsize); WriteDecoderFunc(file, c->r, c->rounds, c->iter); WriteByteOrderConvert(file, c->blocksize); WriteDecoderDriver(file, c->blocksize); (void)fclose(file); break; case 't': case 'T': /* Test */ if( (file = fopen(argv[++a], "wb+")) == NULL ) { printf("Can not create %s\n", argv[a]); break; } WriteTestHeader(file); WriteTable(file, S_TABLE, c->s_table, 32, 0); WriteTable(file, K_TABLE, c->k_table, c->rounds * c->iter, 0); WriteTestHelper(file, c->blocksize); WriteFunction(file, c->f, c->funcsize); WriteEncoderFunc(file, c->r, c->rounds, c->iter); WriteTestDriver(file, c->blocksize); (void)fclose(file); break; case 'g': case 'G': /* Graph */ if( (file = fopen(argv[++a], "wb+")) == NULL ) { printf("Can not create %s\n", argv[a]); break; } WriteGraph(file, c->r, c->rounds, c->iter, c->blocksize); (void)fclose(file); break; default: break; } } FreeCipher(c); return 0; } /*************************************************** WriteByteOrderConvert */ static void WriteByteOrderConvert(FILE *outfile, int blocksize) { fprintf(outfile, "#ifdef BIG_ENDIAN\n" "static void Bswap(unsigned int *d)\n" "{\n" "\tint i;\n" "\tfor(i = 0; i < %d; i++)\n" "\t{\n" "\t\t*d = ((*d >> 24) & 0x000000ff)\n" "\t\t | ((*d >> 8) & 0x0000ff00)\n" "\t\t | ((*d << 8) & 0x00ff0000)\n" "\t\t | ((*d << 24) & 0xff000000);\n" "\t\td++;\n" "\t}\n" "}\n" "#endif\n", blocksize); } /****************************************************** WriteDecoderDriver */ static void WriteDecoderDriver(FILE *outfile, int blocksize) { int bytesize; bytesize = blocksize * 4; /* Block reader and byte order conversion */ fprintf(outfile, "static void ReadBlock(FILE *infile, /*@out@*/unsigned int *d)\n" "{\n" "\t(void)fread(d, %d, 1, infile);\n" "\t#ifdef BIG_ENDIAN\n" "\t\tBswap(d);\n" "\t#endif\n" "}\n", bytesize); /* Header */ fprintf(outfile, "int main(int argc, char **argv)\n" "{\n" "\tunsigned int d[2][%d], p[%d], filesize, i, b;\n" "\tFILE *infile, *outfile;\n" "\tif( argc < 3 )\n" "\t\treturn printf(\"%%s \\n\", *argv);\n" "\tif( (infile = fopen(*++argv, \"rb\")) == NULL )\n" "\t\treturn printf(\"Can not open %%s\\n\", *argv);\n" "\tif( (outfile = fopen(*++argv, \"wb+\")) == NULL )\n" "\t\treturn printf(\"Can not create %%s\\n\", *argv);\n", blocksize, blocksize); /* Get file size */ fprintf(outfile, "\t(void)fseek(infile, 0, SEEK_END);\n" "\tfilesize = (unsigned int)ftell(infile);\n" "\t(void)fseek(infile, 0, SEEK_SET);\n" "\tif( filesize < %d || (filesize %% %d) != 0 )\n" "\t\treturn puts(\"Decrypt error\");\n", bytesize, bytesize); /* Read initialization vector */ fprintf(outfile, "\tReadBlock(infile, d[0]);\n" "\tD(d[b = 0]);\n" "\tmemcpy(p, d[0], %d);\n", bytesize); /* Check file size */ fprintf(outfile, "\tif( p[%d] <= filesize - %d || " "p[%d] > filesize - %d )\n" "\t\treturn puts(\"Decrypt error\");\n" "\tfilesize = p[%d];\n", blocksize - 1, bytesize * 2, blocksize - 1, bytesize, blocksize - 1); /* Read padding */ fprintf(outfile, "\tif( (filesize %% %d) != 0 )\n" "\t{\n" "\t\tReadBlock(infile, d[1]);\n" "\t\tmemcpy(p, d[b = 1], %d);\n" "\t\tD(p);\n" "\t\tfor(i = 0; i < %d; i++)\n" "\t\t\tp[i] ^= d[0][i];\n" "\t\ti = filesize %% %d;\n" "\t\t#ifdef BIG_ENDIAN\n" "\t\t\tBswap(p);\n" "\t\t#endif\n" "\t\t(void)fwrite((unsigned char*)p + %d - i, (size_t)i, 1, outfile);\n" "\t\tfilesize -= i;\n" "\t}\n", bytesize, bytesize, blocksize, bytesize, bytesize); /* Decrypt contents */ fprintf(outfile, "\tfor(; filesize > 0; filesize -= %d)\n" "\t{\n" "\t\tReadBlock(infile, d[b ^= 1]);\n" "\t\tmemcpy(p, d[b], %d);\n" "\t\tD(p);\n" "\t\tfor(i = 0; i < %d; i++)\n" "\t\t\tp[i] ^= d[b ^ 1][i];\n" "\t\t(void)fwrite(p, %d, 1, outfile);\n" "\t}\n", bytesize, bytesize, blocksize, bytesize); /* Footer */ (void)fputs( "\t(void)fclose(infile);\n" "\t(void)fclose(outfile);\n" "\treturn 0;\n" "}\n", outfile); } /******************************************************** WriteDecoderFunc */ static void WriteDecoderFunc(FILE *outfile, Round *x, int rounds, int iter) { int i; fprintf(outfile, "static void D(unsigned int *d)\n" "{\n" "\tunsigned int i, x, *k;\n" "\tk = "K_TABLE";\n" "\tfor(i = 0; i < %d; i++)\n" "\t{\n", iter); x += rounds - 1; for(i = rounds - 1; i >= 0; i--) { fprintf(outfile, "\t\tx = d[%d] %c F(*k++, d[%d]); " "d[%d] = d[%d]; d[%d] = x;\n", x->in, (x->xor != 0) ? '^' : '-', x->out, x->in, x->out, x->out); x--; } (void)fputs("\t}\n}\n\n", outfile); } /****************************************************** WriteDecoderHeader */ void WriteDecoderHeader(FILE *outfile) { (void)fputs( "#include\n" "#include\n" "#include\n\n", outfile); } /****************************************************** WriteEncoderDriver */ static void WriteEncoderDriver(FILE *outfile, int blocksize) { int bytesize; bytesize = blocksize * 4; /* Block reader and byte order conversion */ fprintf(outfile, "static void WriteBlock(FILE *outfile, unsigned int *d)\n" "{\n" "\t#ifdef BIG_ENDIAN\n" "\t\tunsigned int t[%d];\n" "\t\tmemcpy(t, d, %d);\n" "\t\tBswap(t);\n" "\t\t(void)fwrite(t, %d, 1, outfile);\n" "\t#else\n" "\t\t(void)fwrite(d, %d, 1, outfile);\n" "\t#endif\n" "}\n", blocksize, bytesize, bytesize, bytesize); /* Header */ fprintf(outfile, "int main(int argc, char **argv)\n" "{\n" "\tunsigned int d[2][%d], filesize, i, b;\n" "\tFILE *infile, *outfile;\n" "\tif( argc < 3 )\n" "\t\treturn printf(\"%%s \\n\", *argv);\n" "\tif( (infile = fopen(*++argv, \"rb\")) == NULL )\n" "\t\treturn printf(\"Can not open %%s\\n\", *argv);\n" "\tif( (outfile = fopen(*++argv, \"wb+\")) == NULL )\n" "\t\treturn printf(\"Can not create %%s\\n\", *argv);\n", blocksize); /* Generate initialization vector */ fprintf(outfile, "\tsrand((unsigned)time(NULL) ^ "K_TABLE"[0]);\n" "\tfor(i = 0; i < %d; d[0][i++] = (unsigned int)rand());\n", blocksize - 1); /* Get file size, save it in last cell of initial vector */ (void)fputs( "\t(void)fseek(infile, 0, SEEK_END);\n" "\td[0][i] = filesize = (unsigned int)ftell(infile);\n" "\t(void)fseek(infile, 0, SEEK_SET);\n", outfile); /* Write initialization vector */ fprintf(outfile, "\tmemcpy(d[1], d[0], %d);\n" "\tE(d[1]);\n" "\tWriteBlock(outfile, d[1]);\n" "\tb = 0;\n", bytesize); /* Write padding block */ fprintf(outfile, "\tif( (filesize %% %d) != 0 )\n" "\t{\n" "\t\tfor(i = 0; i < %d; d[1][i++] = (unsigned int)rand());\n" "\t\ti = filesize %% %d;\n" "\t\t(void)fread((unsigned char*)d[1] + %d - i, (size_t)i, 1, infile);\n" "\t\t#ifdef BIG_ENDIAN\n" "\t\t\tBswap(d[1]);\n" "\t\t#endif\n" "\t\tfor(i = 0; i < %d; i++)\n" "\t\t\td[1][i] ^= d[0][i];\n" "\t\tE(d[b = 1]);\n" "\t\tWriteBlock(outfile, d[1]);\n" "\t\tfilesize -= filesize %% %d;\n" "\t}\n", bytesize, blocksize, bytesize, bytesize, blocksize, bytesize); /* Encrypt contents */ fprintf(outfile, "\tfor(; filesize > 0; filesize -= %d)\n" "\t{\n" "\t\t(void)fread(d[b ^= 1], %d, 1, infile);\n" "\t\tfor(i = 0; i < %d; i++)\n" "\t\t\td[b][i] ^= d[b^1][i];\n" "\t\tE(d[b]);\n" "\t\tWriteBlock(outfile, d[b]);\n" "\t}\n", bytesize, bytesize, blocksize); /* Footer */ (void)fputs( "\t(void)fclose(infile);\n" "\t(void)fclose(outfile);\n" "\treturn 0;\n" "}\n", outfile); } /******************************************************** WriteEncoderFunc */ static void WriteEncoderFunc(FILE *outfile, Round *x, int rounds, int iter) { int i; fprintf(outfile, "static void E(unsigned int *d)\n" "{\n" "\tunsigned int i, x, *k;\n" "\tk = "K_TABLE";\n" "\tfor(i = 0; i < %d; i++)\n" "\t{\n", iter); for(i = 0; i < rounds; i++) { fprintf(outfile, "\t\tx = d[%d] %c F(*k++, d[%d]); " "d[%d] = d[%d]; d[%d] = x;\n", x->out, (x->xor != 0) ? '^' : '+', x->in, x->out, x->in, x->in); x++; } (void)fputs("\t}\n}\n\n", outfile); } /****************************************************** WriteEncoderHeader */ void WriteEncoderHeader(FILE *outfile) { (void)fputs( "#include\n" "#include\n" "#include\n" "#include\n\n", outfile); } /*********************************************************** WriteFunction */ static void WriteFunction(FILE *outfile, Func *f, int size) { int leaf; (void)fputs( "#define X(a, b) ((a) ^ (b))\n" "#define M(a, b) ((a) * (b) + 1)\n" "#define A(a, b) ((a) + (b))\n" "#define S(a, b) ((a) - (b))\n" "#define b5(_) (unsigned int)((_) & 31)\n" "#define T(a, b) ((a) ^ "S_TABLE"[b5(b)])\n" "#define R(a, b) (((a) << b5(b)) | ((a) >> (unsigned)(31 - b5(b))))\n" "static unsigned int F(unsigned int k, unsigned int d)\n" "{\n" "\treturn k^", outfile); leaf = 0; WriteFunction0(outfile, f, 0, size - 1, &leaf); assert(leaf == size); (void)fputs(";\n}\n\n", outfile); } static void WriteFunction0(FILE *outfile, Func *f, int index, int end, int *x) { static const char op[OPCOUNT] = {'X', 'M', 'A', 'S', 'T', 'R'}; if( index >= end ) { (void)fputc(f[*x].term != 0 ? 'd' : 'k', outfile); ++*x; return; } fprintf(outfile, "%c(", op[f[index].op]); WriteFunction0(outfile, f, index * 2 + 1, end, x); (void)fputc(',', outfile); WriteFunction0(outfile, f, index * 2 + 2, end, x); (void)fputc(')', outfile); } /************************************************************** WriteGraph */ static void WriteGraph( FILE *outfile, Round *r, int rounds, int iter, int blocksize) { static const int page_width = 612, page_height = 792, margin = 72; static const int font_size = 8, font_height = 6; static const int font_xoffset = 1, font_yoffset = 2; double xspacing, yspacing, pagetop, marksize, xi, xo, y, yn; int i, j; /* Header */ fprintf(outfile, "%%!PS-Adobe-2.0\n" "%%%%BoundingBox: 0 0 %d %d\n" "%%%%Pages: 1\n" "%%%%EndComments\n" "%%%%Page: 1 1\n\n" "/Helvetica findfont %d scalefont setfont 1 setlinewidth\n" "erasepage\n", page_width, page_height, font_size); /* Macros */ xspacing = (double)(page_width - margin * 2) / (double)(blocksize + 1); yspacing = (double)(page_height - margin * 2) / (double)(rounds + 2); pagetop = (double)(page_height - margin - font_height); marksize = yspacing * 0.12; fprintf(outfile, "/OpCross { 2 copy moveto -%f 0 rmoveto %f 0 rlineto stroke " "moveto 0 -%f rmoveto 0 %f rlineto stroke } bind def\n" "/OpXor { 2 copy %f 0 360 arc stroke OpCross } bind def\n" "/OpAdd { 2 copy moveto -%f -%f rmoveto " "%f 0 rlineto 0 %f rlineto -%f 0 rlineto closepath stroke " "OpCross } bind def\n" "/CText { dup stringwidth pop 2 div neg 0 rmoveto show } bind def\n", marksize * 0.7, marksize * 1.4, marksize * 0.7, marksize * 1.4, marksize, marksize, marksize, marksize * 2.0, marksize * 2.0, marksize * 2.0); /* Input labels */ (void)fputs("\n0 0.5 0 setrgbcolor\n", outfile); for(i = 0; i < blocksize; i++) { fprintf(outfile, "%f %f moveto (%d) CText\n", (double)i * xspacing + margin, pagetop + font_yoffset, i); } /* Rounds */ (void)fputs("\n0 0 0 setrgbcolor\n", outfile); for(i = 0; i < rounds; i++) { fprintf(outfile, "%% %d\n", i); /* Untouched paths */ y = pagetop - i * yspacing; yn = pagetop - (i + 1) * yspacing; for(j = 0; j < blocksize; j++) { if( j != r[i].in && j != r[i].out ) { fprintf(outfile, "%f %f moveto %f %f lineto stroke\n", j * xspacing + margin, y, j * xspacing + margin, yn); } } /* Transformed paths */ xi = r[i].in * xspacing + margin; xo = r[i].out * xspacing + margin; if( r[i].out < r[i].in ) { /* out <--K-- in */ fprintf(outfile, "%f %f moveto %f %f lineto %f %f lineto %f %f lineto stroke\n", xi, y, xi, y - yspacing * 0.7, xo + xspacing * 0.5, y - yspacing * 0.7, xo, yn); fprintf(outfile, "%f %f moveto %f %f lineto stroke\n", xo, y, xo, y - yspacing * 0.35 + marksize); fprintf(outfile, "%f %f moveto %f %f lineto %f %f lineto %f %f lineto stroke\n", xo, y - yspacing * 0.35 - marksize, xo, y - yspacing * 0.7, xo + xspacing * 0.5, yn, xi, yn); fprintf(outfile, "%f %f moveto %f %f lineto stroke\n", xi, y - yspacing * 0.35, xi - xspacing * 0.1, y - yspacing * 0.35); fprintf(outfile, "%f (%d) stringwidth pop sub %f moveto %f %f lineto " "%f %f rlineto stroke\n", xi - xspacing * 0.1 - font_xoffset * 2, i, y - yspacing * 0.35, xo + marksize * 1.1, y - yspacing * 0.35, marksize, marksize); } else { /* in --K--> out */ fprintf(outfile, "%f %f moveto %f %f lineto %f %f lineto %f %f lineto stroke\n", xi, y, xi, y - yspacing * 0.7, xo - xspacing * 0.5, y - yspacing * 0.7, xo, yn); fprintf(outfile, "%f %f moveto %f %f lineto stroke\n", xo, y, xo, y - yspacing * 0.35 + marksize); fprintf(outfile, "%f %f moveto %f %f lineto %f %f lineto %f %f lineto stroke\n", xo, y - yspacing * 0.35 - marksize, xo, y - yspacing * 0.7, xo - xspacing * 0.5, yn, xi, yn); fprintf(outfile, "%f %f moveto %f %f lineto stroke\n", xi, y - yspacing * 0.35, xi + xspacing * 0.1, y - yspacing * 0.35); fprintf(outfile, "%f (%d) stringwidth pop add %f moveto %f %f lineto " "-%f %f rlineto stroke\n", xi + xspacing * 0.1 + font_xoffset * 2, i, y - yspacing * 0.35, xo - marksize * 1.1, y - yspacing * 0.35, marksize, marksize); } fprintf(outfile, "%f %f %s\n", xo, y - yspacing * 0.35, (r[i].xor != 0) ? "OpXor" : "OpAdd"); } /* Extra empty round at the end */ y = pagetop - rounds * yspacing; yn = pagetop - (rounds + 1) * yspacing; (void)fputc('\n', outfile); for(i = 0; i < blocksize; i++) { fprintf(outfile, "%f %f moveto %f %f lineto stroke\n", i * xspacing + margin, y, i * xspacing + margin, yn); } /* Key labels */ (void)fputs("\n0.5 0 0 setrgbcolor\n", outfile); for(i = 0; i < rounds; i++) { y = pagetop - i * yspacing - yspacing * 0.35 - font_height * 0.5; xi = r[i].in * xspacing + margin; if( r[i].out < r[i].in ) { /* out <--K-- in */ fprintf(outfile, "%f (%d) stringwidth pop sub %f moveto (%d) show\n", xi - xspacing * 0.1 - font_xoffset, i, y, i); } else { /* in --K--> out */ fprintf(outfile, "%f %f moveto (%d) show\n", xi + xspacing * 0.1 + font_xoffset, y, i); } } /* Multiplier label */ xo = blocksize * xspacing + margin; fprintf(outfile, "\n0 1 0 setrgbcolor\n" "%f %f moveto %f %f lineto %f %f lineto %f %f lineto stroke\n", xo - xspacing * 0.2, pagetop, xo, pagetop, xo, pagetop - (rounds + 1) * yspacing, xo - xspacing * 0.2, pagetop - (rounds + 1) * yspacing); fprintf(outfile, "0 0 0 setrgbcolor\n" "%f %f moveto (x %d) show\n", xo + marksize * 2, pagetop - (rounds + 1) * yspacing * 0.5, iter); /* Output labels */ (void)fputs("\n0 0 0.5 setrgbcolor\n", outfile); y = pagetop - font_yoffset - font_height - (rounds + 1) * yspacing; for(i = 0; i < blocksize; i++) { fprintf(outfile, "%f %f moveto (%d) CText\n", i * xspacing + margin, y, i); } /* Footer */ (void)fputs("showpage\n", outfile); } /************************************************************** WriteTable */ static void WriteTable(FILE *outfile, char *name, unsigned int *table, int size, int reverse) { static const int columns = 5; int i; fprintf(outfile, "static unsigned int %s[%d] =\n{\n", name, size); for(i = 0; i < size; i++) { if( (i % columns) == 0 ) (void)fputc('\t', outfile); fprintf(outfile, "0x%08xU", (reverse != 0) ? table[size - i - 1] : table[i]); if( i + 1 < size ) (void)fputc(',', outfile); if( ((i + 1) % columns) == 0 ) (void)fputc('\n', outfile); } if( (i % columns) != 0 ) (void)fputc('\n', outfile); (void)fputs("};\n\n", outfile); } /********************************************************* WriteTestDriver */ static void WriteTestDriver(FILE *outfile, int blocksize) { int bytesize; bytesize = blocksize * 4; /* Test header */ fprintf(outfile, "#ifdef _WIN32\n" "\tstatic DWORD WINAPI ProcessThread(ThreadArg *a)\n" "#else\n" "\tstatic unsigned int ProcessThread(ThreadArg *a)\n" "#endif\n" "{\n" "\tunsigned int rand_seed[55], rand_idx;\n" "\tunsigned int in[%d], out0[%d], out[%d], i, j, x;\n" "\tunsigned char *b;\n", blocksize, blocksize, blocksize); /* Initialize PRNG */ (void)fputs( "\tInitRand(rand_seed, a->seed);\n" "\trand_idx = a->seed % 55;\n", outfile); /* Test loop */ (void)fputs( "\twhile( *(a->run) != 0 )\n" "\t{\n", outfile); /* Create block */ fprintf(outfile, "\t\tfor(i = 0; i < %d; i++)\n" "\t\t{\n" "\t\t\trand_idx = (rand_idx + 1) %% 55;\n" "\t\t\tin[i] = (rand_seed[rand_idx] += rand_seed[(rand_idx+24) %% 55]);\n" "\t\t}\n", blocksize); /* Encrypt reference block */ fprintf(outfile, "\t\tmemcpy(out0, in, %d);\n" "\t\tE(out0);\n", bytesize); /* Walk bits */ fprintf(outfile, "\t\tfor(i = 0; i < %d; i++)\n" "\t\t{\n" "\t\t\tfor(j = 0; j < 32; j++)\n" "\t\t\t{\n" "\t\t\t\tin[i] ^= (1 << j);\n" "\t\t\t\tmemcpy(out, in, %d);\n" "\t\t\t\tE(out);\n", blocksize, bytesize); /* Count change in bits */ fprintf(outfile, "\t\t\t\ta->total += %d;\n" "\t\t\t\ta->change += CountDiff(out0, out);\n", blocksize * 32); /* Count frequency of output */ fprintf(outfile, "\t\t\t\tb = (unsigned char*)out;\n" "\t\t\t\tfor(x = 0; x < %d; x++)\n" "\t\t\t\t\ta->freq[*(b++)]++;\n" "\t\t\t\tin[i] ^= (1 << j);\n" "\t\t\t}\n" "\t\t}\n" "\t}\n", bytesize); /* Test footer */ (void)fputs( "\treturn 0;\n" "}\n\n", outfile); /* Main header */ (void)fputs( "int main(int argc, char **argv)\n" "{\n" "\tThreadArg *a;\n" "\tunsigned int x, i, c, t, run;\n" "\tdouble e, p;\n" "\tif( argc < 3 )\n" "\t\treturn printf(\"%s