home *** CD-ROM | disk | FTP | other *** search
- ^X# include <stdio.h>
- ^X# include "table.i"
- ^X# ifdef DOS
- ^X# include <fcntl.h>
- ^X# include <io.h>
- ^X# endif
- ^X
- ^X# ifdef DOS
- ^X# define TTY "con"
- ^X# else
- ^X# define TTY "/dev/tty"
- ^X# endif
- ^X
- ^X# define Over(x) for (x = 0; x < order; x++)
- ^X# define Times(a,b) ((long)(a) * (long)(b) % 257)
- ^X
- ^Xint mode;
- ^X
- ^Xchar key[256];
- ^Xint matkey[16][16];
- ^Xint invec[16];
- ^Xint outvec[16];
- ^Xint order;
- ^X
- ^X
- ^Xsetup(argc, argv)
- ^Xint argc; char **argv;
- ^X {
- ^X FILE *tty;
- ^X
- ^X if (strcmp(argv[1], "-e") == 0)
- ^X mode = 'e';
- ^X else if (strcmp(argv[1], "-d") == 0)
- ^X mode = 'd';
- ^X else {
- ^X fprintf(stderr, "usage: hill -e [key]\n or: hill -d [key]\n");
- ^X exit(1);
- ^X }
- ^X if (argc > 2)
- ^X strcpy(key, argv[2]);
- ^X else {
- ^X tty = fopen(TTY, "r+");
- ^X setbuf(tty, NULL);
- ^X fprintf(tty, "Key? ");
- ^X fgets(key, sizeof(key), tty);
- ^X key[strlen(key) - 1] = 0;
- ^X fclose(tty);
- ^X }
- ^X }
- ^X
- ^Xmakemat()
- ^X {
- ^X int i, j, k;
- ^X int n = 0;
- ^X FILE *tty;
- ^X
- ^X setorder();
- ^X Over(i) Over(j)
- ^X matkey[i][j] = key[n++];
- ^X for (i = 0; i < strlen(key); i++)
- ^X key[i] = 0;
- ^X square();
- ^X while ((k = invert()) != EOF)
- ^X matkey[k][k] = (matkey[k][k] + 1) % 257;
- ^X }
- ^X
- ^Xsetorder()
- ^X {
- ^X int n = strlen(key);
- ^X
- ^X for (order = 0; order < 17; order++)
- ^X if (order*order > n) break;
- ^X order--;
- ^X if (order < 3) {
- ^X fprintf(stderr, "key size < 9\n");
- ^X exit(1);
- ^X }
- ^X }
- ^X
- ^Xsquare()
- ^X {
- ^X int result[16][16];
- ^X int i, j, k;
- ^X
- ^X Over(i) Over(j)
- ^X result[i][j] = 0;
- ^X Over(i) Over(j) Over(k)
- ^X result[i][j] += Times(matkey[i][k], matkey[k][j]);
- ^X Over(i) Over(j)
- ^X matkey[i][j] = result[i][j] % 257;
- ^X }
- ^X
- ^Xint invert()
- ^X {
- ^X int matrix[16][16];
- ^X int inverse[16][16];
- ^X int i, j, k;
- ^X int t;
- ^X int pivot;
- ^X
- ^X Over(i) Over(j) {
- ^X matrix[i][j] = matkey[i][j];
- ^X inverse[i][j] = 0;
- ^X }
- ^X Over(k)
- ^X inverse[k][k] = 1;
- ^X
- ^X Over(k) {
- ^X if (matrix[k][k] == 0) {
- ^X for (i = k + 1; i < order; i++)
- ^X if (matrix[i][k]) {
- ^X Over(j) {
- ^X t = matrix[i][j];
- ^X matrix[i][j] = matrix[k][j];
- ^X matrix[k][j] = t;
- ^X t = inverse[i][j];
- ^X inverse[i][j] = inverse[k][j];
- ^X inverse[k][j] = t;
- ^X }
- ^X break;
- ^X }
- ^X if (i == order) return(k);
- ^X }
- ^X
- ^X pivot = inverses[matrix[k][k]];
- ^X Over(j) {
- ^X matrix[k][j] = Times(matrix[k][j], pivot);
- ^X inverse[k][j] = Times(inverse[k][j], pivot);
- ^X }
- ^X Over(i) if (i != k) {
- ^X pivot = matrix[i][k];
- ^X Over(j) {
- ^X matrix[i][j] -= Times(pivot, matrix[k][j]);
- ^X if (matrix[i][j] < 0) matrix[i][j] += 257;
- ^X inverse[i][j] -= Times(pivot, inverse[k][j]);
- ^X if (inverse[i][j] < 0) inverse[i][j] += 257;
- ^X }
- ^X }
- ^X }
- ^X
- ^X if (mode == 'd') Over(i) Over(j)
- ^X matkey[i][j] = inverse[i][j];
- ^X return(EOF);
- ^X }
- ^X
- ^X
- ^Xint getvec()
- ^X {
- ^X int i;
- ^X int padf = 0;
- ^X
- ^X Over(i)
- ^X if ((invec[i] = getchar()) == EOF) {
- ^X if (i == 0) return(0);
- ^X else if (padf) invec[i] = rand() % 257;
- ^X else { invec[i] = 256; padf++; }
- ^X }
- ^X else if (invec[i] == 255 && mode == 'd')
- ^X invec[i] += getchar();
- ^X return(i);
- ^X }
- ^X
- ^Xputvec()
- ^X {
- ^X int j;
- ^X
- ^X Over(j)
- ^X switch(outvec[j]) {
- ^X case 256:
- ^X if (mode == 'd') return;
- ^X else putchar(255), putchar(1);
- ^X break;
- ^X case 255:
- ^X putchar(255);
- ^X if (mode == 'e') putchar(0);
- ^X break;
- ^X default:
- ^X putchar(outvec[j]);
- ^X }
- ^X }
- ^X
- ^Xmatmul()
- ^X {
- ^X int i, j, k;
- ^X
- ^X Over(i) {
- ^X outvec[i] = 0;
- ^X Over(j)
- ^X outvec[i] += Times(invec[j], matkey[i][j]);
- ^X outvec[i] %= 257;
- ^X }
- ^X }
- ^X
- ^Xmain(argc, argv)
- ^Xint argc; char **argv;
- ^X {
- ^X long tloc;
- ^X
- ^X# ifdef DOS
- ^X;setmode(fileno(stdin), O_BINARY);
- ^X setmode(fileno(stdout), O_BINARY);
- ^X# endif
- ^X time(&tloc);
- ^X srand((int) tloc);
- ^X setup(argc, argv);
- ^X makemat();
- ^X while(getvec()) {
- ^X; matmul();
- ^X; putvec();
- ^X;;}
- ^X }
-