#include #include #include #include #include "photon.h" byte PHOTON_key_state[D/2][D]; #define S 4 const byte ReductionPoly = 0x3; const byte WORDFILTER = ((byte) 1<>i)&1) ret ^= x; if((x>>(S-1))&1) { x <<= 1; x ^= ReductionPoly; } else x <<= 1; } return ret&WORDFILTER; } void PrintState(byte state[D][D]) { if(!DEBUG) return; int i, j; for(i = 0; i < D; i++){ for(j = 0; j < D; j++) printf("%2X ", state[i][j]); printf("\n"); } printf("\n"); } void PrintState_Column(CWord state[D]) { if(!DEBUG) return; int i, j; for(i = 0; i < D; i++){ for(j = 0; j < D; j++) printf("%2X ", (state[j]>>(i*S)) & WORDFILTER); printf("\n"); } printf("\n"); } void AddConstant(byte state[D][D], int round) { int i; for(i = 0; i < D; i++) state[i][0] = state[i][0] ^ IC[i] ^ RC[round]; } void SubCell(byte state[D][D]) { int i,j; for(i = 0; i < D; i++) for(j = 0; j < D; j++) state[i][j] = sbox[state[i][j]]; } void ShiftRow(byte state[D][D]) { int i, j; byte tmp[D]; for(i = 1; i < D; i++) { for(j = 0; j < D; j++) tmp[j] = state[i][j]; for(j = 0; j < D; j++) state[i][j] = tmp[(j+i)%D]; } } void MixColumn(byte state[D][D]) { int i, j, k; byte tmp[D]; for(j = 0; j < D; j++){ for(i = 0; i < D; i++) { byte sum = 0; for(k = 0; k < D; k++) sum ^= FieldMult(MixColMatrix[i][k], state[k][j]); tmp[i] = sum; } for(i = 0; i < D; i++) state[i][j] = tmp[i]; } } #ifdef _TABLE_ tword Table[D][1<>= S; } } } #endif void Step(byte state[D][D], byte tweak_state[D/2][D], int start_rnd, unsigned char domain) { int i; AddKey(state); PrintState(state); AddTweak(state, tweak_state); PrintState(state); for(i = start_rnd; i < start_rnd + STEP_INTER_ROUND_N; i++) { if(DEBUG) printf("--- Round %d ---\n", i); AddDomain(state, domain); PrintState(state); AddConstant(state, i); PrintState(state); #ifndef _TABLE_ SubCell(state); PrintState(state); ShiftRow(state); PrintState(state); MixColumn(state); #else SCShRMCS(state); #endif PrintState(state); } } void TEM_PHOTON_Permutation( unsigned char *state_inout, const unsigned char *tweak_in, unsigned char domain) { byte state[D][D]; byte tweak_state[D/2][D]; int i; int stp; for (i = 0; i < D * D; i++) { state[i / D][i % D] = (state_inout[i / 2] >> (4 * (i & 1))) & 0xf; } for (i = 0; i < (D / 2) * D; i++) { tweak_state[i / D][i % D] = (tweak_in[i / 2] >> (4 * (i & 1))) & 0xf; } for (stp = 0; stp < STEP_N; stp++) { Step(state, tweak_state, stp * STEP_INTER_ROUND_N, domain); } AddKey(state); PrintState(state); AddTweak(state, tweak_state); PrintState(state); memset(state_inout, 0, (D * D) / 2); for (i = 0; i < D * D; i++) { state_inout[i / 2] |= (state[i / D][i % D] & 0xf) << (4 * (i & 1)); } }