turtle.c.svn-base
上传用户:market2
上传日期:2018-11-18
资源大小:18786k
文件大小:6k
- /*
- * turtle.c
- * Matt Blaze, September, 1996
- *
- * This is the basic turtle/hare cipher reference implementation
- * with a simple key schedule.
- *
- * Turtle blocksize can be any power of two words >= 4;
- * the wordsize is hardcoded in turtle.h. 8 bits is the default.
- *
- * This code turtle encrypts 8-word blocks on a pl00 at about 3Mbps. It
- * can probably be made a couple times faster by unrolling the recursive
- * calls. Hare runs at about 9Mbps.
- */
- #include <stdio.h>
- #include "turtle.h"
- static int r;
- static void keyperm(TURTLEWORD sbox[][NTURTLEWORDS], TURTLEWORD *key, int len, int n);
- static int r_turtle_encrypt(TURTLEWORD *in, TURTLEWORD *out, int n, TK *key);
- /*
- * Basic turtle encrypt
- * (encrypts blk in place)
- */
- int turtle_encrypt(TURTLEWORD *blk, TK *key) {
- int nn, i;
- TURTLEWORD buf[TURTLEMAXN];
- if ((key==NULL)||(blk==NULL)) return -1;
- r=0;
- nn=key->n/2;
- r_turtle_encrypt(&(blk[0]),buf,nn,key);
- for (i=0; i<nn; i++) blk[i+nn] ^= buf[i];
- r_turtle_encrypt(&(blk[nn]),buf,nn,key);
- for (i=0; i<nn; i++) blk[i] ^= buf[i];
- r_turtle_encrypt(&(blk[0]),buf,nn,key);
- for (i=0; i<nn; i++) blk[i+nn] ^= buf[i];
- r_turtle_encrypt(&(blk[nn]),buf,nn,key);
- for (i=0; i<nn; i++) blk[i] ^= buf[i];
- return 0;
- }
- /*
- * Basic turtle decrypt
- * (decrypts blk in place)
- */
- int turtle_decrypt(TURTLEWORD *blk, TK *key) {
- int nn, i;
- unsigned char buf[TURTLEMAXN];
- if ((key==NULL)||(blk==NULL)) return -1;
- nn=key->n/2;
- r=key->rr[3]; /* we have to use the key schedule backwards */
- /* but only for the OUTERMOST recursive shell */
- r_turtle_encrypt(&(blk[nn]),buf,nn,key);
- for (i=0; i<nn; i++)
- blk[i] ^= buf[i];
- r=key->rr[2];
- r_turtle_encrypt(&(blk[0]),buf,nn,key);
- for (i=0; i<nn; i++) blk[i+nn] ^= buf[i];
- r=key->rr[1];
- r_turtle_encrypt(&(blk[nn]),buf,nn,key);
- for (i=0; i<nn; i++) blk[i] ^= buf[i];
- r=0;
- r_turtle_encrypt(&(blk[0]),buf,nn,key);
- for (i=0; i<nn; i++) blk[i+nn] ^= buf[i];
- return 0;
- }
- /*
- * create turtle key from short key.
- * n must be a power of 2 and >= 4.
- */
- int turtle_key(TURTLEWORD *shortkey, int len, TK *key, int n) {
- int i, j, nn;
- TURTLEWORD other, t;
- HK harekey;
- if ((n<4)||(n>TURTLEMAXN)||(key == NULL)||(shortkey == NULL)) return -1;
- nn=n*n;
- /* first create a hare key from the shortkey */
- hare_key(shortkey,len,&harekey);
- /* use hare to permute the real sboxes */
- for (j=0; j<nn; j++) {
- for (i=0; i<NTURTLEWORDS; i++) {
- key->sbox[j][i] = i;
- }
- for (i=0; i<NTURTLEWORDS; i++) {
- other = hare_stream(&harekey);
- t = key->sbox[j][i];
- key->sbox[j][i] = key->sbox[j][other];
- key->sbox[j][other] = t;
- }
- }
- key->n=n;
- key->rr[3] = nn/4*3;
- key->rr[2] = nn/4*2;
- key->rr[1] = nn/4;
- key->rr[0] = 0;
- return 0;
- }
- /*
- * Basic hare stream generator
- * (returns one TURTLEWORD)
- */
- TURTLEWORD hare_stream(HK *key) {
- TURTLEWORD r, l, t;
- int table, otable;
- r = key->r;
- l = key->l;
- table = key->table;
- otable = 1-table;
- r^=key->sbox[table][0][l];
- l^=key->sbox[table][1][r];
- r^=key->sbox[table][2][l];
- l^=key->sbox[table][3][r];
- t = key->sbox[otable][key->r][key->l];
- key->sbox[otable][key->r][key->l] = key->sbox[otable][key->r][r];
- key->sbox[otable][key->r][r] = t;
- key->l = (key->l + 1) % NTURTLEWORDS;
- if (key->l == 0) {
- key->r = (key->r + 1) % NTURTLEWORDS;
- }
- if (key->r > 3) {
- key->r = 0;
- key->l = 0;
- key->table = otable;
- }
- return l;
- }
- /*
- * create hare key from short key
- */
- int hare_key(TURTLEWORD *shortkey, int len, HK *key) {
- if ((key == NULL)||(shortkey == NULL)) return -1;
- /* first create the tables from the shortkey */
- keyperm(key->sbox[0],shortkey,len,4);
- /* do it again for the other set */
- keyperm(key->sbox[1],shortkey,len,4);
- key->table = 0;
- key->r = 0;
- key->l = 0;
- return 0;
- }
- /*********************************************
- * support functions - not part of interface *
- *********************************************/
- /*
- * recursive turtle function
- */
- static int r_turtle_encrypt(TURTLEWORD *in, TURTLEWORD *out, int n, TK *key) {
- int nn, i;
- TURTLEWORD buf[TURTLEMAXN];
- if (n==2) { /* this is the basic lookup */
- out[1] = in[1] ^ key->sbox[r++][in[0]];
- out[0] = in[0] ^ key->sbox[r++][out[1]];
- out[1] ^= key->sbox[r++][out[0]];
- out[0] ^= key->sbox[r++][out[1]];
- } else { /* recurse */
- nn=n/2;
- r_turtle_encrypt(&(in[0]),buf,nn,key);
- for (i=0; i<nn; i++) out[i+nn] = in[i+nn] ^ buf[i];
- r_turtle_encrypt(&(out[nn]),buf,nn,key);
- for (i=0; i<nn; i++) out[i] = in[i] ^ buf[i];
- r_turtle_encrypt(&(out[0]),buf,nn,key);
- for (i=0; i<nn; i++) out[i+nn] ^= buf[i];
- r_turtle_encrypt(&(out[nn]),buf,nn,key);
- for (i=0; i<nn; i++) out[i] ^= buf[i];
- }
- return 0;
- }
- /* Simple key permutation expand function.
- * This is really more of an example than anything else.
- * Generate n permutations on 2^WORDBITS elements from the cryptovariable.
- * This is approximately similar to the RC-4 permutation generator, but
- * we go through each table WORDBITS times, which smoothes out the early
- * swaps and does a total of x log x swaps in each permutation.
- */
- static void keyperm(TURTLEWORD sbox[][NTURTLEWORDS], TURTLEWORD *key, int len, int n) {
- int a, b, i, j, k;
- TURTLEWORD t;
- for (b=0; b<n; b++) {
- for (i=0; i<NTURTLEWORDS; i++) {
- sbox[b][i]=i;
- }
- }
- j=len;
- k=0;
- for (b=0; b<n; b++) { /* for each keygen sbox */
- for (a=0; a<TURTLEBITS; a++) { /* n times around for each */
- for (i=0; i<NTURTLEWORDS; i++) { /* swap w/ element */
- j = (j + key[k] + sbox[b][(a*b+i)%NTURTLEWORDS]) %NTURTLEWORDS;
- t = sbox[b][i];
- sbox[b][i] = sbox[b][j];
- sbox[b][j] = t;
- k=(k+1)%len;
- }
- }
- }
- }