/* print state with a prefix string */ void pstate2(const unsigned char *str, const byte* state) { #ifdef _PRINT printf("%s\n", str); if(state) pstate(state, STATE_LEN); #endif }
void print_cxt(const ae_cxt* cxt) { printf("user key of %d bytes:\n", cxt->klen); pstate(cxt->userkey, cxt->klen); printf("associated data of %llu bytes:\n", cxt->adlen); pstate(cxt->ad, cxt->adlen); printf("nonce of %llu bytes:\n", cxt->nlen); pstate(cxt->nonce, cxt->nlen); printf("plaintext of %llu bytes:\n", cxt->ptlen); pstate(cxt->pt, cxt->ptlen); printf("ciphertext of %llu bytes:\n", cxt->ctlen); pstate(cxt->ct, cxt->ctlen); printf("MAC of %d bytes:\n", cxt->tlen); pstate(cxt->tag, cxt->tlen); }
/** Encryption **/ void Encode(uint8 text[8], uint8 cipher[8]) { #ifdef _PRINT printf("Twine input: "); pstate(text, 8); #endif uint8 i; uint8 data1[16], tmp, t_data[16]; //Set plaintext data1[0] = text[0]>>4; data1[1] = text[0]&0xf; data1[2] = text[1]>>4; data1[3] = text[1]&0xf; data1[4] = text[2]>>4; data1[5] = text[2]&0xf; data1[6] = text[3]>>4; data1[7] = text[3]&0xf; data1[8] = text[4]>>4; data1[9] = text[4]&0xf; data1[10] = text[5]>>4; data1[11] = text[5]&0xf; data1[12] = text[6]>>4; data1[13] = text[6]&0xf; data1[14] = text[7]>>4; data1[15] = text[7]&0xf; //Round functions for(i=0; ; i++) { data1[1] ^= S[data1[0] ^ ek[i][0]]; data1[3] ^= S[data1[2] ^ ek[i][1]]; data1[5] ^= S[data1[4] ^ ek[i][2]]; data1[7] ^= S[data1[6] ^ ek[i][3]]; data1[9] ^= S[data1[8] ^ ek[i][4]]; data1[11] ^= S[data1[10] ^ ek[i][5]]; data1[13] ^= S[data1[12] ^ ek[i][6]]; data1[15] ^= S[data1[14] ^ ek[i][7]]; if(pswitch){ t_data[0] = data1[1]; t_data[1] = data1[2]; t_data[2] = data1[11]; t_data[3] = data1[6]; t_data[4] = data1[3]; t_data[5] = data1[0]; t_data[6] = data1[9]; t_data[7] = data1[4]; t_data[8] = data1[7]; t_data[9] = data1[10]; t_data[10] = data1[13]; t_data[11] = data1[14]; t_data[12] = data1[5]; t_data[13] = data1[8]; t_data[14] = data1[15]; t_data[15] = data1[12]; printf("ROUND %02d: ", i); pstate3(t_data, 16); } i++; data1[2] ^= S[data1[1] ^ ek[i][0]]; data1[6] ^= S[data1[11] ^ ek[i][1]]; data1[0] ^= S[data1[3] ^ ek[i][2]]; data1[4] ^= S[data1[9] ^ ek[i][3]]; data1[10] ^= S[data1[7] ^ ek[i][4]]; data1[14] ^= S[data1[13] ^ ek[i][5]]; data1[8] ^= S[data1[5] ^ ek[i][6]]; data1[12] ^= S[data1[15] ^ ek[i][7]]; if(i == (ROUND-1)) break; tmp = data1[0]; data1[0] = data1[2]; data1[2] = data1[14]; data1[14] = data1[12]; data1[12] = tmp; tmp = data1[1]; data1[1] = data1[11]; data1[11] = data1[15]; data1[15] = data1[5]; data1[5] = tmp; tmp = data1[3]; data1[3] = data1[9]; data1[9] = data1[13]; data1[13] = data1[7]; data1[7] = tmp; tmp = data1[4]; data1[4] = data1[6]; data1[6] = data1[10]; data1[10] = data1[8]; data1[8] = tmp; if(pswitch){ printf("ROUND %02d: ", i); pstate3(data1, 16); } } //Set ciphertext cipher[0] = (data1[1]<<4) ^ data1[2]; cipher[1] = (data1[11]<<4) ^ data1[6]; cipher[2] = (data1[3]<<4) ^ data1[0]; cipher[3] = (data1[9]<<4) ^ data1[4]; cipher[4] = (data1[7]<<4) ^ data1[10]; cipher[5] = (data1[13]<<4) ^ data1[14]; cipher[6] = (data1[5]<<4) ^ data1[8]; cipher[7] = (data1[15]<<4) ^ data1[12]; #ifdef _PRINT printf("Twine output: "); pstate(cipher, 8); #endif }
void cgoto(void) { int i, j, s; int npos, curpos, n; int tryit; uint8_t tch[NCH]; int tst[NCH]; uint8_t *q; /* generate initial state, for each start condition */ Bprint(&fout,"int yyvstop[] = {\n0,\n"); while(stnum < 2 || stnum/2 < sptr){ for(i = 0; i<tptr; i++) tmpstat[i] = 0; count = 0; if(tptr > 0)first(tptr-1); add(state,stnum); # ifdef DEBUG if(debug){ if(stnum > 1) print("%s:\n",sname[stnum/2]); pstate(stnum); } # endif stnum++; } stnum--; /* even stnum = might not be at line begin */ /* odd stnum = must be at line begin */ /* even states can occur anywhere, odd states only at line begin */ for(s = 0; s <= stnum; s++){ tryit = FALSE; cpackflg[s] = FALSE; sfall[s] = -1; acompute(s); for(i=0;i<NCH;i++) symbol[i] = 0; npos = *state[s]; for(i = 1; i<=npos; i++){ curpos = *(state[s]+i); if(name[curpos] < NCH) symbol[name[curpos]] = TRUE; else switch(name[curpos]){ case RCCL: tryit = TRUE; q = ptr[curpos]; while(*q){ for(j=1;j<NCH;j++) if(cindex[j] == *q) symbol[j] = TRUE; q++; } break; case RSTR: symbol[right[curpos]] = TRUE; break; # ifdef DEBUG case RNULLS: case FINAL: case S1FINAL: case S2FINAL: break; default: warning("bad switch cgoto %d state %d",curpos,s); break; # endif } } # ifdef DEBUG if(debug){ print("State %d transitions on:\n\t",s); charc = 0; for(i = 1; i<NCH; i++){ if(symbol[i]) allprint(i); if(charc > LINESIZE){ charc = 0; print("\n\t"); } } print("\n"); } # endif /* for each char, calculate next state */ n = 0; for(i = 1; i<NCH; i++){ if(symbol[i]){ nextstate(s,i); /* executed for each state, transition pair */ xstate = notin(stnum); if(xstate == -2) warning("bad state %d %o",s,i); else if(xstate == -1){ if(stnum >= nstates) error("Too many states %s",(nstates == NSTATES ? "\nTry using %n num":"")); add(state,++stnum); # ifdef DEBUG if(debug)pstate(stnum); # endif tch[n] = i; tst[n++] = stnum; } else { /* xstate >= 0 ==> state exists */ tch[n] = i; tst[n++] = xstate; } } } tch[n] = 0; tst[n] = -1; /* pack transitions into permanent array */ if(n > 0) packtrans(s,tch,tst,n,tryit); else gotof[s] = -1; } Bprint(&fout,"0};\n"); }
/** Decryption **/ void Decode(uint8 cipher[8], uint8 text[8]) { uint8 i, tmp; uint8 data1[16]; //Set ciphertext data1[0] = cipher[0]>>4; data1[1] = cipher[0]&0xf; data1[2] = cipher[1]>>4; data1[3] = cipher[1]&0xf; data1[4] = cipher[2]>>4; data1[5] = cipher[2]&0xf; data1[6] = cipher[3]>>4; data1[7] = cipher[3]&0xf; data1[8] = cipher[4]>>4; data1[9] = cipher[4]&0xf; data1[10] = cipher[5]>>4; data1[11] = cipher[5]&0xf; data1[12] = cipher[6]>>4; data1[13] = cipher[6]&0xf; data1[14] = cipher[7]>>4; data1[15] = cipher[7]&0xf; //Round functions for(i=ROUND-1; ; i--) { data1[1] ^= S[data1[0] ^ ek[i][0]]; data1[3] ^= S[data1[2] ^ ek[i][1]]; data1[5] ^= S[data1[4] ^ ek[i][2]]; data1[7] ^= S[data1[6] ^ ek[i][3]]; data1[9] ^= S[data1[8] ^ ek[i][4]]; data1[11] ^= S[data1[10] ^ ek[i][5]]; data1[13] ^= S[data1[12] ^ ek[i][6]]; data1[15] ^= S[data1[14] ^ ek[i][7]]; i--; data1[0] ^= S[data1[5] ^ ek[i][0]]; data1[4] ^= S[data1[1] ^ ek[i][1]]; data1[12] ^= S[data1[7] ^ ek[i][2]]; data1[8] ^= S[data1[3] ^ ek[i][3]]; data1[6] ^= S[data1[13] ^ ek[i][4]]; data1[2] ^= S[data1[9] ^ ek[i][5]]; data1[10] ^= S[data1[15] ^ ek[i][6]]; data1[14] ^= S[data1[11] ^ ek[i][7]]; if(i == 0) break; tmp = data1[1]; data1[1] = data1[5]; data1[5] = data1[15]; data1[15] = data1[11]; data1[11] = tmp; tmp = data1[3]; data1[3] = data1[7]; data1[7] = data1[13]; data1[13] = data1[9]; data1[9] = tmp; tmp = data1[0]; data1[0] = data1[12]; data1[12] = data1[14]; data1[14] = data1[2]; data1[2] = tmp; tmp = data1[4]; data1[4] = data1[8]; data1[8] = data1[10]; data1[10] = data1[6]; data1[6] = tmp; } //Set plaintext text[0] = (data1[5]<<4) ^ data1[0]; text[1] = (data1[1]<<4) ^ data1[4]; text[2] = (data1[7]<<4) ^ data1[12]; text[3] = (data1[3]<<4) ^ data1[8]; text[4] = (data1[13]<<4) ^ data1[6]; text[5] = (data1[9]<<4) ^ data1[2]; text[6] = (data1[15]<<4) ^ data1[10]; text[7] = (data1[11]<<4) ^ data1[14]; #ifdef _PRINT printf("Twine (decode) output: "); pstate(text, 8); #endif }