void SboxHardwareTI(uint8_t Ax, uint8_t Bx, uint8_t Cx, uint8_t* Ay, uint8_t* By, uint8_t* Cy){ // Variables 5th register uint8_t At0, At1, At2, At3, At4, At5, At6, At7 ; uint8_t Bt0, Bt1, Bt2, Bt3, Bt4, Bt5, Bt6, Bt7 ; uint8_t Ct0, Ct1, Ct2, Ct3, Ct4, Ct5, Ct6, Ct7 ; // Variables used in F G and Q uint8_t Ax0, Ax1, Ax2, Ax3, Ax4, Ax5, Ax6, Ax7, Axt ; uint8_t Bx0, Bx1, Bx2, Bx3, Bx4, Bx5, Bx6, Bx7, Bxt ; uint8_t Cx0, Cx1, Cx2, Cx3, Cx4, Cx5, Cx6, Cx7, Cxt ; // Variables of the feistel scheme uint8_t c_Ax0, c_Ax1, c_Ax2, c_Ax3, c_Ax4, c_Ax5, c_Ax6, c_Ax7, c_Axt ; uint8_t c_Bx0, c_Bx1, c_Bx2, c_Bx3, c_Bx4, c_Bx5, c_Bx6, c_Bx7, c_Bxt ; uint8_t c_Cx0, c_Cx1, c_Cx2, c_Cx3, c_Cx4, c_Cx5, c_Cx6, c_Cx7, c_Cxt ; // Intermediate variables (should be registers) // For Xor of feistel, maybe only the xor with ys should be registers uint8_t Ay0, Ay1, Ay2, Ay3, Ay4, Ay5, Ay6, Ay7, Ayt ; uint8_t By0, By1, By2, By3, By4, By5, By6, By7, Byt ; uint8_t Cy0, Cy1, Cy2, Cy3, Cy4, Cy5, Cy6, Cy7, Cyt ; c_Ax0 = Ax & 0x1 ; c_Ax1 = (Ax & 0x2) >> 1 ; c_Ax2 = (Ax & 0x4) >> 2 ; c_Ax3 = (Ax & 0x8) >> 3 ; c_Ax4 = (Ax & 0x10) >> 4 ; c_Ax5 = (Ax & 0x20) >> 5 ; c_Ax6 = (Ax & 0x40) >> 6 ; c_Ax7 = (Ax & 0x80) >> 7 ; c_Bx0 = Bx & 0x1 ; c_Bx1 = (Bx & 0x2) >> 1 ; c_Bx2 = (Bx & 0x4) >> 2 ; c_Bx3 = (Bx & 0x8) >> 3 ; c_Bx4 = (Bx & 0x10) >> 4 ; c_Bx5 = (Bx & 0x20) >> 5 ; c_Bx6 = (Bx & 0x40) >> 6 ; c_Bx7 = (Bx & 0x80) >> 7 ; c_Cx0 = Cx & 0x1 ; c_Cx1 = (Cx & 0x2) >> 1 ; c_Cx2 = (Cx & 0x4) >> 2 ; c_Cx3 = (Cx & 0x8) >> 3 ; c_Cx4 = (Cx & 0x10) >> 4 ; c_Cx5 = (Cx & 0x20) >> 5 ; c_Cx6 = (Cx & 0x40) >> 6 ; c_Cx7 = (Cx & 0x80) >> 7 ; // FoG // G // --- Ax0 = c_Ax0 ; // | Bx0 = c_Bx0 ; // | Cx0 = c_Cx0 ; // | Ax1 = c_Ax1 ; // | Bx1 = c_Bx1 ; // | Cx1 = c_Cx1 ; // | From Feistel, get main wires : Ax2 = c_Ax2 ; // | --> Free in harware, just wiring Bx2 = c_Bx2 ; // | Cx2 = c_Cx2 ; // | Ax3 = c_Ax3 ; // | Bx3 = c_Bx3 ; // | Cx3 = c_Cx3 ; // | // --- // --- At0 = (Bx1 & Bx2) ^ (Bx1 & Cx2) ^ (Cx1 & Bx2) ; // | Bt0 = (Cx1 & Cx2) ^ (Cx1 & Ax2) ^ (Ax1 & Cx2) ; // | Ct0 = (Ax1 & Ax2) ^ (Ax1 & Bx2) ^ (Bx1 & Ax2) ; // | // | G gates Ax0 = Ax0 ^ At0 ; // | Bx0 = Bx0 ^ Bt0 ; // | Cx0 = Cx0 ^ Ct0 ; // | // --- // --- Ay0 = Ax0 ; // | By0 = Bx0 ; // | Cy0 = Cx0 ; // | Ay1 = Ax1 ; // | By1 = Bx1 ; // | Cy1 = Cx1 ; // | Registers Ay2 = Ax2 ; // | By2 = Bx2 ; // | Cy2 = Cx2 ; // | Ay3 = Ax3 ; // | By3 = Bx3 ; // | Cy3 = Cx3 ; // | // --- // F // --- Ax0 = Ay0 ; // | Bx0 = By0 ; // | Cx0 = Cy0 ; // | Ax1 = Ay1 ; // | Bx1 = By1 ; // | Wiring from registers Cx1 = Cy1 ; // | --> Free Ax2 = Ay2 ; // | Bx2 = By2 ; // | Cx2 = Cy2 ; // | Ax3 = Ay3 ; // | Bx3 = By3 ; // | Cx3 = Cy3 ; // | // --- // --- Ax1 = Ax1 ^ Ax3 ; // | Bx1 = Bx1 ^ Bx3 ; // | Cx1 = Cx1 ^ Cx3 ; // | // | Axt = Ax0 ^ Ax2 ; // | Bxt = Bx0 ^ Bx2 ; // | Cxt = Cx0 ^ Cx2 ; // | // | Ax2 = Ax1 ^ Ax2 ; // | Bx2 = Bx1 ^ Bx2 ; // | Cx2 = Cx1 ^ Cx2 ; // | // | At0 = (Bx0 & Bx3) ^ (Bx0 & Cx3) ^ (Cx0 & Bx3) ; // | Bt0 = (Cx0 & Cx3) ^ (Cx0 & Ax3) ^ (Ax0 & Cx3) ; // | Ct0 = (Ax0 & Ax3) ^ (Ax0 & Bx3) ^ (Bx0 & Ax3) ; // | Ax0 = At0 ; // | F gates Bx0 = Bt0 ; // | Cx0 = Ct0 ; // | // | Ax3 = Ax3 ^ Axt ; // | Bx3 = Bx3 ^ Bxt ; // | Cx3 = Cx3 ^ Cxt ; // | // | At3 = (Bx3 & Bx2) ^ (Bx3 & Cx2) ^ (Cx3 & Bx2) ; // | Bt3 = (Cx3 & Cx2) ^ (Cx3 & Ax2) ^ (Ax3 & Cx2) ; // | Ct3 = (Ax3 & Ax2) ^ (Ax3 & Bx2) ^ (Bx3 & Ax2) ; // | Ax3 = At3 ; // | Bx3 = Bt3 ; // | Cx3 = Ct3 ; // | // | At1 = (Bx1 & Bxt) ^ (Bx1 & Cxt) ^ (Cx1 & Bxt) ; // | Bt1 = (Cx1 & Cxt) ^ (Cx1 & Axt) ^ (Ax1 & Cxt) ; // | Ct1 = (Ax1 & Axt) ^ (Ax1 & Bxt) ^ (Bx1 & Axt) ; // | // --- // --- Ay0 = Ax3 ; // | By0 = Bx3 ; // | Cy0 = Cx3 ; // | Ay1 = Axt ; // | By1 = Bxt ; // | Registers Cy1 = Cxt ; // | Ay2 = Ax0 ; // | By2 = Bx0 ; // | Cy2 = Cx0 ; // | Ay3 = At1 ; // | By3 = Bt1 ; // | Cy3 = Ct1 ; // | // --- // Xor --- c_Ax4 = c_Ax4 ^Ay0 ; // | c_Bx4 = c_Bx4 ^By0 ; // | c_Cx4 = c_Cx4 ^Cy0 ; // | c_Ax5 = c_Ax5 ^Ay1 ; // | c_Bx5 = c_Bx5 ^By1 ; // | c_Cx5 = c_Cx5 ^Cy1 ; // | First xor of the Feistel c_Ax6 = c_Ax6 ^Ay2 ; // | c_Bx6 = c_Bx6 ^By2 ; // | c_Cx6 = c_Cx6 ^Cy2 ; // | c_Ax7 = c_Ax7 ^Ay3 ; // | c_Bx7 = c_Bx7 ^By3 ; // | c_Cx7 = c_Cx7 ^Cy3 ; // | // --- // QoQ // Q // --- Ax4 = c_Ax4 ; // | Bx4 = c_Bx4 ; // | Cx4 = c_Cx4 ; // | Ax5 = c_Ax5 ; // | Bx5 = c_Bx5 ; // | From Feistel, get main wires : Cx5 = c_Cx5 ; // | --> Free in harware, just wiring Ax6 = c_Ax6 ; // | Bx6 = c_Bx6 ; // | Cx6 = c_Cx6 ; // | Ax7 = c_Ax7 ; // | Bx7 = c_Bx7 ; // | Cx7 = c_Cx7 ; // | // --- // --- Axt = (Bx4 & Bx7) ^ (Bx4 & Cx7) ^ (Cx4 & Bx7) ; // | Bxt = (Cx4 & Cx7) ^ (Cx4 & Ax7) ^ (Ax4 & Cx7) ; // | Cxt = (Ax4 & Ax7) ^ (Ax4 & Bx7) ^ (Bx4 & Ax7) ; // | // | Axt = Axt ^ Ax5 ; // | Bxt = Bxt ^ Bx5 ; // | Cxt = Cxt ^ Cx5 ; // | // | At5 = (Bx4 & Bx5) ^ (Bx4 & Cx5) ^ (Cx4 & Bx5) ; // | Q Gates Bt5 = (Cx4 & Cx5) ^ (Cx4 & Ax5) ^ (Ax4 & Cx5) ; // | Ct5 = (Ax4 & Ax5) ^ (Ax4 & Bx5) ^ (Bx4 & Ax5) ; // | Ax5 = At5 ; // | Bx5 = Bt5 ; // | Cx5 = Ct5 ; // | // | Ax6 = Ax6 ^ Ax5 ; // | Bx6 = Bx6 ^ Bx5 ; // | Cx6 = Cx6 ^ Cx5 ; // | // --- // --- Ay4 = Ax7 ; // | By4 = Bx7 ; // | Cy4 = Cx7 ; // | Ay5 = Axt ; // | By5 = Bxt ; // | Registers Cy5 = Cxt ; // | Ay6 = Ax4 ; // | By6 = Bx4 ; // | Cy6 = Cx4 ; // | Ay7 = Ax6 ; // | By7 = Bx6 ; // | Cy7 = Cx6 ; // | // --- // Wire Permutation // --- Ax4 = Ay7 ; // | Bx4 = By7 ; // | Cx4 = Cy7 ; // | Ax5 = Ay4 ; // | Bx5 = By4 ; // | Cx5 = Cy4 ; // | Wire permutation from registers Ax6 = Ay6 ; // | in order to reuse identical Q Bx6 = By6 ; // | --> Free in hardware, just wiring Cx6 = Cy6 ; // | Ax7 = Ay5 ; // | Bx7 = By5 ; // | Cx7 = Cy5 ; // | // --- // Q // --- Axt = (Bx4 & Bx7) ^ (Bx4 & Cx7) ^ (Cx4 & Bx7) ; // | Bxt = (Cx4 & Cx7) ^ (Cx4 & Ax7) ^ (Ax4 & Cx7) ; // | Cxt = (Ax4 & Ax7) ^ (Ax4 & Bx7) ^ (Bx4 & Ax7) ; // | // | Axt = Axt ^ Ax5 ; // | Bxt = Bxt ^ Bx5 ; // | Cxt = Cxt ^ Cx5 ; // | // | At5 = (Bx4 & Bx5) ^ (Bx4 & Cx5) ^ (Cx4 & Bx5) ; // | Q Gates Bt5 = (Cx4 & Cx5) ^ (Cx4 & Ax5) ^ (Ax4 & Cx5) ; // | Ct5 = (Ax4 & Ax5) ^ (Ax4 & Bx5) ^ (Bx4 & Ax5) ; // | Ax5 = At5 ; // | Bx5 = Bt5 ; // | Cx5 = Ct5 ; // | // | Ax6 = Ax6 ^ Ax5 ; // | Bx6 = Bx6 ^ Bx5 ; // | Cx6 = Cx6 ^ Cx5 ; // | // --- // --- Ay4 = Ax7 ; // | By4 = Bx7 ; // | Cy4 = Cx7 ; // | Ay5 = Axt ; // | By5 = Bxt ; // | Registers Cy5 = Cxt ; // | Ay6 = Ax4 ; // | By6 = Bx4 ; // | Cy6 = Cx4 ; // | Ay7 = Ax6 ; // | By7 = Bx6 ; // | Cy7 = Cx6 ; // | // --- // Xor // --- c_Ax0 = c_Ax0 ^ Ay4 ; // | c_Bx0 = c_Bx0 ^ By4 ; // | c_Cx0 = c_Cx0 ^ Cy4 ; // | c_Ax1 = c_Ax1 ^ Ay5 ; // | c_Bx1 = c_Bx1 ^ By5 ; // | Second xor of the Feistel c_Cx1 = c_Cx1 ^ Cy5 ; // | c_Ax2 = c_Ax2 ^ Ay6 ; // | c_Bx2 = c_Bx2 ^ By6 ; // | c_Cx2 = c_Cx2 ^ Cy6 ; // | c_Ax3 = c_Ax3 ^ Ay7 ; // | c_Bx3 = c_Bx3 ^ By7 ; // | c_Cx3 = c_Cx3 ^ Cy7 ; // | // --- // F^1oG // G // --- Ax0 = c_Ax0 ; // | Bx0 = c_Bx0 ; // | Cx0 = c_Cx0 ; // | Ax1 = c_Ax1 ; // | Bx1 = c_Bx1 ; // | From Feistel, get main wires : Cx1 = c_Cx1 ; // | --> Free in harware, just wiring Ax2 = c_Ax2 ; // | Bx2 = c_Bx2 ; // | Cx2 = c_Cx2 ; // | Ax3 = c_Ax3 ; // | Bx3 = c_Bx3 ; // | Cx3 = c_Cx3 ; // | // --- // --- At0 = (Bx1 & Bx2) ^ (Bx1 & Cx2) ^ (Cx1 & Bx2) ; // | Bt0 = (Cx1 & Cx2) ^ (Cx1 & Ax2) ^ (Ax1 & Cx2) ; // | Ct0 = (Ax1 & Ax2) ^ (Ax1 & Bx2) ^ (Bx1 & Ax2) ; // | G gates // | Ax0 = Ax0 ^ At0 ^ 1 ; // | <-- Not gate, only needed in 1 share Bx0 = Bx0 ^ Bt0 ; // | Cx0 = Cx0 ^ Ct0 ; // | // --- // --- Ay0 = Ax0 ; // | By0 = Bx0 ; // | Cy0 = Cx0 ; // | Ay1 = Ax1 ; // | By1 = Bx1 ; // | Cy1 = Cx1 ; // | Registers Ay2 = Ax2 ; // | By2 = Bx2 ; // | Cy2 = Cx2 ; // | Ay3 = Ax3 ; // | By3 = Bx3 ; // | Cy3 = Cx3 ; // | // --- // F Ax0 = Ay0 ; // | Bx0 = By0 ; // | Cx0 = Cy0 ; // | Ax1 = Ay1 ; // | Bx1 = By1 ; // | Wiring from registers Cx1 = Cy1 ; // | --> Free Ax2 = Ay2 ; // | Bx2 = By2 ; // | Cx2 = Cy2 ; // | Ax3 = Ay3 ; // | Bx3 = By3 ; // | Cx3 = Cy3 ; // | // --- // --- Ax1 = Ax1 ^ Ax3 ; // | Bx1 = Bx1 ^ Bx3 ; // | Cx1 = Cx1 ^ Cx3 ; // | // | Axt = Ax0 ^ Ax2 ; // | Bxt = Bx0 ^ Bx2 ; // | Cxt = Cx0 ^ Cx2 ; // | // | Ax2 = Ax1 ^ Ax2 ; // | Bx2 = Bx1 ^ Bx2 ; // | Cx2 = Cx1 ^ Cx2 ; // | // | At0 = (Bx0 & Bx3) ^ (Bx0 & Cx3) ^ (Cx0 & Bx3) ; // | Bt0 = (Cx0 & Cx3) ^ (Cx0 & Ax3) ^ (Ax0 & Cx3) ; // | Ct0 = (Ax0 & Ax3) ^ (Ax0 & Bx3) ^ (Bx0 & Ax3) ; // | Ax0 = At0 ; // | F gates Bx0 = Bt0 ; // | Cx0 = Ct0 ; // | // | Ax3 = Ax3 ^ Axt ; // | Bx3 = Bx3 ^ Bxt ; // | Cx3 = Cx3 ^ Cxt ; // | // | At3 = (Bx3 & Bx2) ^ (Bx3 & Cx2) ^ (Cx3 & Bx2) ; // | Bt3 = (Cx3 & Cx2) ^ (Cx3 & Ax2) ^ (Ax3 & Cx2) ; // | Ct3 = (Ax3 & Ax2) ^ (Ax3 & Bx2) ^ (Bx3 & Ax2) ; // | Ax3 = At3 ; // | Bx3 = Bt3 ; // | Cx3 = Ct3 ; // | // | At1 = (Bx1 & Bxt) ^ (Bx1 & Cxt) ^ (Cx1 & Bxt) ; // | Bt1 = (Cx1 & Cxt) ^ (Cx1 & Axt) ^ (Ax1 & Cxt) ; // | Ct1 = (Ax1 & Axt) ^ (Ax1 & Bxt) ^ (Bx1 & Axt) ; // | // --- // --- Ay0 = Ax3 ; // | By0 = Bx3 ; // | Cy0 = Cx3 ; // | Ay1 = Axt ; // | By1 = Bxt ; // | Registers Cy1 = Cxt ; // | Ay2 = Ax0 ; // | By2 = Bx0 ; // | Cy2 = Cx0 ; // | Ay3 = At1 ; // | By3 = Bt1 ; // | Cy3 = Ct1 ; // | // --- // Xor // --- c_Ax4 = c_Ax4 ^ Ay0 ; // | c_Bx4 = c_Bx4 ^ By0 ; // | c_Cx4 = c_Cx4 ^ Cy0 ; // | c_Ax5 = c_Ax5 ^ Ay1 ; // | c_Bx5 = c_Bx5 ^ By1 ; // | c_Cx5 = c_Cx5 ^ Cy1 ; // | Third xor of the Feistel c_Ax6 = c_Ax6 ^ Ay2 ; // | c_Bx6 = c_Bx6 ^ By2 ; // | c_Cx6 = c_Cx6 ^ Cy2 ; // | c_Ax7 = c_Ax7 ^ Ay3 ; // | c_Bx7 = c_Bx7 ^ By3 ; // | c_Cx7 = c_Cx7 ^ Cy3 ; // | // --- // --- Ay0 = c_Ax0 ; // | By0 = c_Bx0 ; // | Cy0 = c_Cx0 ; // | Ay1 = c_Ax1 ; // | By1 = c_Bx1 ; // | Cy1 = c_Cx1 ; // | Ay2 = c_Ax2 ; // | By2 = c_Bx2 ; // | Cy2 = c_Cx2 ; // | Ay3 = c_Ax3 ; // | By3 = c_Bx3 ; // | Cy3 = c_Cx3 ; // | Ay4 = c_Ax4 ; // | Last registers of end of Sbox By4 = c_Bx4 ; // | Cy4 = c_Cx4 ; // | Ay5 = c_Ax5 ; // | By5 = c_Bx5 ; // | Cy5 = c_Cx5 ; // | Ay6 = c_Ax6 ; // | By6 = c_Bx6 ; // | Cy6 = c_Cx6 ; // | Ay7 = c_Ax7 ; // | By7 = c_Bx7 ; // | Cy7 = c_Cx7 ; // | // --- (*Ay) = Ay0 ^ (Ay1 << 1) ^ (Ay2 << 2) ^ (Ay3 << 3) ^ (Ay4 << 4) ^ (Ay5 << 5) ^ (Ay6 << 6) ^ (Ay7 << 7) ; (*By) = By0 ^ (By1 << 1) ^ (By2 << 2) ^ (By3 << 3) ^ (By4 << 4) ^ (By5 << 5) ^ (By6 << 6) ^ (By7 << 7) ; (*Cy) = Cy0 ^ (Cy1 << 1) ^ (Cy2 << 2) ^ (Cy3 << 3) ^ (Cy4 << 4) ^ (Cy5 << 5) ^ (Cy6 << 6) ^ (Cy7 << 7) ; }