/* The eXtended Keccak Code Package (XKCP) https://github.com/XKCP/XKCP The Keccak-p permutations, designed by Guido Bertoni, Joan Daemen, Michaƫl Peeters and Gilles Van Assche. Implementation by Ronny Van Keer, hereby denoted as "the implementer". For more information, feedback or questions, please refer to the Keccak Team website: https://keccak.team/ To the extent possible under law, the implementer has waived all copyright and related or neighboring rights to the source code in this file. http://creativecommons.org/publicdomain/zero/1.0/ */ #define _b 0 #define _g 5 #define _k 10 #define _m 15 #define _s 20 #define _a 0 #define _e 1 #define _i 2 #define _o 3 #define _u 4 #define declareBCDE \ uint32_t Ba, Be, Bi, Bo, Bu; \ uint32_t Ca, Ce, Ci, Co, Cu; \ uint32_t Da, De, Di, Do, Du; \ uint32_t Estate[25]; \ #define prepareTheta \ Ca = Astate[_b+_a]^Astate[_g+_a]^Astate[_k+_a]^Astate[_m+_a]^Astate[_s+_a]; \ Ce = Astate[_b+_e]^Astate[_g+_e]^Astate[_k+_e]^Astate[_m+_e]^Astate[_s+_e]; \ Ci = Astate[_b+_i]^Astate[_g+_i]^Astate[_k+_i]^Astate[_m+_i]^Astate[_s+_i]; \ Co = Astate[_b+_o]^Astate[_g+_o]^Astate[_k+_o]^Astate[_m+_o]^Astate[_s+_o]; \ Cu = Astate[_b+_u]^Astate[_g+_u]^Astate[_k+_u]^Astate[_m+_u]^Astate[_s+_u]; \ #ifdef UseBebigokimisa /* --- Code for round, with prepare-theta (lane complementing pattern 'bebigokimisa') */ /* --- 32-bit lanes mapped to 32-bit words */ #define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ Da = Cu^ROL32(Ce, 1); \ De = Ca^ROL32(Ci, 1); \ Di = Ce^ROL32(Co, 1); \ Do = Ci^ROL32(Cu, 1); \ Du = Co^ROL32(Ca, 1); \ \ A##state[_b+_a] ^= Da; \ Ba = A##state[_b+_a]; \ A##state[_g+_e] ^= De; \ Be = ROL32(A##state[_g+_e], 12); \ A##state[_k+_i] ^= Di; \ Bi = ROL32(A##state[_k+_i], 11); \ A##state[_m+_o] ^= Do; \ Bo = ROL32(A##state[_m+_o], 21); \ A##state[_s+_u] ^= Du; \ Bu = ROL32(A##state[_s+_u], 14); \ E##state[_b+_a] = Ba ^( Be | Bi ); \ E##state[_b+_a] ^= KeccakF800RoundConstants[i]; \ Ca = E##state[_b+_a]; \ E##state[_b+_e] = Be ^((~Bi)| Bo ); \ Ce = E##state[_b+_e]; \ E##state[_b+_i] = Bi ^( Bo & Bu ); \ Ci = E##state[_b+_i]; \ E##state[_b+_o] = Bo ^( Bu | Ba ); \ Co = E##state[_b+_o]; \ E##state[_b+_u] = Bu ^( Ba & Be ); \ Cu = E##state[_b+_u]; \ \ A##state[_b+_o] ^= Do; \ Ba = ROL32(A##state[_b+_o], 28); \ A##state[_g+_u] ^= Du; \ Be = ROL32(A##state[_g+_u], 20); \ A##state[_k+_a] ^= Da; \ Bi = ROL32(A##state[_k+_a], 3); \ A##state[_m+_e] ^= De; \ Bo = ROL32(A##state[_m+_e], 13); \ A##state[_s+_i] ^= Di; \ Bu = ROL32(A##state[_s+_i], 29); \ E##state[_g+_a] = Ba ^( Be | Bi ); \ Ca ^= E##state[_g+_a]; \ E##state[_g+_e] = Be ^( Bi & Bo ); \ Ce ^= E##state[_g+_e]; \ E##state[_g+_i] = Bi ^( Bo |(~Bu)); \ Ci ^= E##state[_g+_i]; \ E##state[_g+_o] = Bo ^( Bu | Ba ); \ Co ^= E##state[_g+_o]; \ E##state[_g+_u] = Bu ^( Ba & Be ); \ Cu ^= E##state[_g+_u]; \ \ A##state[_b+_e] ^= De; \ Ba = ROL32(A##state[_b+_e], 1); \ A##state[_g+_i] ^= Di; \ Be = ROL32(A##state[_g+_i], 6); \ A##state[_k+_o] ^= Do; \ Bi = ROL32(A##state[_k+_o], 25); \ A##state[_m+_u] ^= Du; \ Bo = ROL32(A##state[_m+_u], 8); \ A##state[_s+_a] ^= Da; \ Bu = ROL32(A##state[_s+_a], 18); \ E##state[_k+_a] = Ba ^( Be | Bi ); \ Ca ^= E##state[_k+_a]; \ E##state[_k+_e] = Be ^( Bi & Bo ); \ Ce ^= E##state[_k+_e]; \ E##state[_k+_i] = Bi ^((~Bo)& Bu ); \ Ci ^= E##state[_k+_i]; \ E##state[_k+_o] = (~Bo)^( Bu | Ba ); \ Co ^= E##state[_k+_o]; \ E##state[_k+_u] = Bu ^( Ba & Be ); \ Cu ^= E##state[_k+_u]; \ \ A##state[_b+_u] ^= Du; \ Ba = ROL32(A##state[_b+_u], 27); \ A##state[_g+_a] ^= Da; \ Be = ROL32(A##state[_g+_a], 4); \ A##state[_k+_e] ^= De; \ Bi = ROL32(A##state[_k+_e], 10); \ A##state[_m+_i] ^= Di; \ Bo = ROL32(A##state[_m+_i], 15); \ A##state[_s+_o] ^= Do; \ Bu = ROL32(A##state[_s+_o], 24); \ E##state[_m+_a] = Ba ^( Be & Bi ); \ Ca ^= E##state[_m+_a]; \ E##state[_m+_e] = Be ^( Bi | Bo ); \ Ce ^= E##state[_m+_e]; \ E##state[_m+_i] = Bi ^((~Bo)| Bu ); \ Ci ^= E##state[_m+_i]; \ E##state[_m+_o] = (~Bo)^( Bu & Ba ); \ Co ^= E##state[_m+_o]; \ E##state[_m+_u] = Bu ^( Ba | Be ); \ Cu ^= E##state[_m+_u]; \ \ A##state[_b+_i] ^= Di; \ Ba = ROL32(A##state[_b+_i], 30); \ A##state[_g+_o] ^= Do; \ Be = ROL32(A##state[_g+_o], 23); \ A##state[_k+_u] ^= Du; \ Bi = ROL32(A##state[_k+_u], 7); \ A##state[_m+_a] ^= Da; \ Bo = ROL32(A##state[_m+_a], 9); \ A##state[_s+_e] ^= De; \ Bu = ROL32(A##state[_s+_e], 2); \ E##state[_s+_a] = Ba ^((~Be)& Bi ); \ Ca ^= E##state[_s+_a]; \ E##state[_s+_e] = (~Be)^( Bi | Bo ); \ Ce ^= E##state[_s+_e]; \ E##state[_s+_i] = Bi ^( Bo & Bu ); \ Ci ^= E##state[_s+_i]; \ E##state[_s+_o] = Bo ^( Bu | Ba ); \ Co ^= E##state[_s+_o]; \ E##state[_s+_u] = Bu ^( Ba & Be ); \ Cu ^= E##state[_s+_u]; \ \ /* --- Code for round (lane complementing pattern 'bebigokimisa') */ /* --- 32-bit lanes mapped to 32-bit words */ #define thetaRhoPiChiIota(i, A, E) \ Da = Cu^ROL32(Ce, 1); \ De = Ca^ROL32(Ci, 1); \ Di = Ce^ROL32(Co, 1); \ Do = Ci^ROL32(Cu, 1); \ Du = Co^ROL32(Ca, 1); \ \ A##state[_b+_a] ^= Da; \ Ba = A##state[_b+_a]; \ A##state[_g+_e] ^= De; \ Be = ROL32(A##state[_g+_e], 12); \ A##state[_k+_i] ^= Di; \ Bi = ROL32(A##state[_k+_i], 11); \ A##state[_m+_o] ^= Do; \ Bo = ROL32(A##state[_m+_o], 21); \ A##state[_s+_u] ^= Du; \ Bu = ROL32(A##state[_s+_u], 14); \ E##state[_b+_a] = Ba ^( Be | Bi ); \ E##state[_b+_a] ^= KeccakF800RoundConstants[i]; \ E##state[_b+_e] = Be ^((~Bi)| Bo ); \ E##state[_b+_i] = Bi ^( Bo & Bu ); \ E##state[_b+_o] = Bo ^( Bu | Ba ); \ E##state[_b+_u] = Bu ^( Ba & Be ); \ \ A##state[_b+_o] ^= Do; \ Ba = ROL32(A##state[_b+_o], 28); \ A##state[_g+_u] ^= Du; \ Be = ROL32(A##state[_g+_u], 20); \ A##state[_k+_a] ^= Da; \ Bi = ROL32(A##state[_k+_a], 3); \ A##state[_m+_e] ^= De; \ Bo = ROL32(A##state[_m+_e], 13); \ A##state[_s+_i] ^= Di; \ Bu = ROL32(A##state[_s+_i], 29); \ E##state[_g+_a] = Ba ^( Be | Bi ); \ E##state[_g+_e] = Be ^( Bi & Bo ); \ E##state[_g+_i] = Bi ^( Bo |(~Bu)); \ E##state[_g+_o] = Bo ^( Bu | Ba ); \ E##state[_g+_u] = Bu ^( Ba & Be ); \ \ A##state[_b+_e] ^= De; \ Ba = ROL32(A##state[_b+_e], 1); \ A##state[_g+_i] ^= Di; \ Be = ROL32(A##state[_g+_i], 6); \ A##state[_k+_o] ^= Do; \ Bi = ROL32(A##state[_k+_o], 25); \ A##state[_m+_u] ^= Du; \ Bo = ROL32(A##state[_m+_u], 8); \ A##state[_s+_a] ^= Da; \ Bu = ROL32(A##state[_s+_a], 18); \ E##state[_k+_a] = Ba ^( Be | Bi ); \ E##state[_k+_e] = Be ^( Bi & Bo ); \ E##state[_k+_i] = Bi ^((~Bo)& Bu ); \ E##state[_k+_o] = (~Bo)^( Bu | Ba ); \ E##state[_k+_u] = Bu ^( Ba & Be ); \ \ A##state[_b+_u] ^= Du; \ Ba = ROL32(A##state[_b+_u], 27); \ A##state[_g+_a] ^= Da; \ Be = ROL32(A##state[_g+_a], 4); \ A##state[_k+_e] ^= De; \ Bi = ROL32(A##state[_k+_e], 10); \ A##state[_m+_i] ^= Di; \ Bo = ROL32(A##state[_m+_i], 15); \ A##state[_s+_o] ^= Do; \ Bu = ROL32(A##state[_s+_o], 24); \ E##state[_m+_a] = Ba ^( Be & Bi ); \ E##state[_m+_e] = Be ^( Bi | Bo ); \ E##state[_m+_i] = Bi ^((~Bo)| Bu ); \ E##state[_m+_o] = (~Bo)^( Bu & Ba ); \ E##state[_m+_u] = Bu ^( Ba | Be ); \ \ A##state[_b+_i] ^= Di; \ Ba = ROL32(A##state[_b+_i], 30); \ A##state[_g+_o] ^= Do; \ Be = ROL32(A##state[_g+_o], 23); \ A##state[_k+_u] ^= Du; \ Bi = ROL32(A##state[_k+_u], 7); \ A##state[_m+_a] ^= Da; \ Bo = ROL32(A##state[_m+_a], 9); \ A##state[_s+_e] ^= De; \ Bu = ROL32(A##state[_s+_e], 2); \ E##state[_s+_a] = Ba ^((~Be)& Bi ); \ E##state[_s+_e] = (~Be)^( Bi | Bo ); \ E##state[_s+_i] = Bi ^( Bo & Bu ); \ E##state[_s+_o] = Bo ^( Bu | Ba ); \ E##state[_s+_u] = Bu ^( Ba & Be ); \ \ #else /* UseBebigokimisa */ /* --- Code for round, with prepare-theta */ /* --- 32-bit lanes mapped to 32-bit words */ #define thetaRhoPiChiIotaPrepareTheta(i, A, E) \ Da = Cu^ROL32(Ce, 1); \ De = Ca^ROL32(Ci, 1); \ Di = Ce^ROL32(Co, 1); \ Do = Ci^ROL32(Cu, 1); \ Du = Co^ROL32(Ca, 1); \ \ A##state[_b+_a] ^= Da; \ Ba = A##state[_b+_a]; \ A##state[_g+_e] ^= De; \ Be = ROL32(A##state[_g+_e], 12); \ A##state[_k+_i] ^= Di; \ Bi = ROL32(A##state[_k+_i], 11); \ A##state[_m+_o] ^= Do; \ Bo = ROL32(A##state[_m+_o], 21); \ A##state[_s+_u] ^= Du; \ Bu = ROL32(A##state[_s+_u], 14); \ E##state[_b+_a] = Ba ^((~Be)& Bi ); \ E##state[_b+_a] ^= KeccakF800RoundConstants[i]; \ Ca = E##state[_b+_a]; \ E##state[_b+_e] = Be ^((~Bi)& Bo ); \ Ce = E##state[_b+_e]; \ E##state[_b+_i] = Bi ^((~Bo)& Bu ); \ Ci = E##state[_b+_i]; \ E##state[_b+_o] = Bo ^((~Bu)& Ba ); \ Co = E##state[_b+_o]; \ E##state[_b+_u] = Bu ^((~Ba)& Be ); \ Cu = E##state[_b+_u]; \ \ A##state[_b+_o] ^= Do; \ Ba = ROL32(A##state[_b+_o], 28); \ A##state[_g+_u] ^= Du; \ Be = ROL32(A##state[_g+_u], 20); \ A##state[_k+_a] ^= Da; \ Bi = ROL32(A##state[_k+_a], 3); \ A##state[_m+_e] ^= De; \ Bo = ROL32(A##state[_m+_e], 13); \ A##state[_s+_i] ^= Di; \ Bu = ROL32(A##state[_s+_i], 29); \ E##state[_g+_a] = Ba ^((~Be)& Bi ); \ Ca ^= E##state[_g+_a]; \ E##state[_g+_e] = Be ^((~Bi)& Bo ); \ Ce ^= E##state[_g+_e]; \ E##state[_g+_i] = Bi ^((~Bo)& Bu ); \ Ci ^= E##state[_g+_i]; \ E##state[_g+_o] = Bo ^((~Bu)& Ba ); \ Co ^= E##state[_g+_o]; \ E##state[_g+_u] = Bu ^((~Ba)& Be ); \ Cu ^= E##state[_g+_u]; \ \ A##state[_b+_e] ^= De; \ Ba = ROL32(A##state[_b+_e], 1); \ A##state[_g+_i] ^= Di; \ Be = ROL32(A##state[_g+_i], 6); \ A##state[_k+_o] ^= Do; \ Bi = ROL32(A##state[_k+_o], 25); \ A##state[_m+_u] ^= Du; \ Bo = ROL32(A##state[_m+_u], 8); \ A##state[_s+_a] ^= Da; \ Bu = ROL32(A##state[_s+_a], 18); \ E##state[_k+_a] = Ba ^((~Be)& Bi ); \ Ca ^= E##state[_k+_a]; \ E##state[_k+_e] = Be ^((~Bi)& Bo ); \ Ce ^= E##state[_k+_e]; \ E##state[_k+_i] = Bi ^((~Bo)& Bu ); \ Ci ^= E##state[_k+_i]; \ E##state[_k+_o] = Bo ^((~Bu)& Ba ); \ Co ^= E##state[_k+_o]; \ E##state[_k+_u] = Bu ^((~Ba)& Be ); \ Cu ^= E##state[_k+_u]; \ \ A##state[_b+_u] ^= Du; \ Ba = ROL32(A##state[_b+_u], 27); \ A##state[_g+_a] ^= Da; \ Be = ROL32(A##state[_g+_a], 4); \ A##state[_k+_e] ^= De; \ Bi = ROL32(A##state[_k+_e], 10); \ A##state[_m+_i] ^= Di; \ Bo = ROL32(A##state[_m+_i], 15); \ A##state[_s+_o] ^= Do; \ Bu = ROL32(A##state[_s+_o], 24); \ E##state[_m+_a] = Ba ^((~Be)& Bi ); \ Ca ^= E##state[_m+_a]; \ E##state[_m+_e] = Be ^((~Bi)& Bo ); \ Ce ^= E##state[_m+_e]; \ E##state[_m+_i] = Bi ^((~Bo)& Bu ); \ Ci ^= E##state[_m+_i]; \ E##state[_m+_o] = Bo ^((~Bu)& Ba ); \ Co ^= E##state[_m+_o]; \ E##state[_m+_u] = Bu ^((~Ba)& Be ); \ Cu ^= E##state[_m+_u]; \ \ A##state[_b+_i] ^= Di; \ Ba = ROL32(A##state[_b+_i], 30); \ A##state[_g+_o] ^= Do; \ Be = ROL32(A##state[_g+_o], 23); \ A##state[_k+_u] ^= Du; \ Bi = ROL32(A##state[_k+_u], 7); \ A##state[_m+_a] ^= Da; \ Bo = ROL32(A##state[_m+_a], 9); \ A##state[_s+_e] ^= De; \ Bu = ROL32(A##state[_s+_e], 2); \ E##state[_s+_a] = Ba ^((~Be)& Bi ); \ Ca ^= E##state[_s+_a]; \ E##state[_s+_e] = Be ^((~Bi)& Bo ); \ Ce ^= E##state[_s+_e]; \ E##state[_s+_i] = Bi ^((~Bo)& Bu ); \ Ci ^= E##state[_s+_i]; \ E##state[_s+_o] = Bo ^((~Bu)& Ba ); \ Co ^= E##state[_s+_o]; \ E##state[_s+_u] = Bu ^((~Ba)& Be ); \ Cu ^= E##state[_s+_u]; \ \ /* --- Code for round */ /* --- 32-bit lanes mapped to 32-bit words */ #define thetaRhoPiChiIota(i, A, E) \ Da = Cu^ROL32(Ce, 1); \ De = Ca^ROL32(Ci, 1); \ Di = Ce^ROL32(Co, 1); \ Do = Ci^ROL32(Cu, 1); \ Du = Co^ROL32(Ca, 1); \ \ A##state[_b+_a] ^= Da; \ Ba = A##state[_b+_a]; \ A##state[_g+_e] ^= De; \ Be = ROL32(A##state[_g+_e], 12); \ A##state[_k+_i] ^= Di; \ Bi = ROL32(A##state[_k+_i], 11); \ A##state[_m+_o] ^= Do; \ Bo = ROL32(A##state[_m+_o], 21); \ A##state[_s+_u] ^= Du; \ Bu = ROL32(A##state[_s+_u], 14); \ E##state[_b+_a] = Ba ^((~Be)& Bi ); \ E##state[_b+_a] ^= KeccakF800RoundConstants[i]; \ E##state[_b+_e] = Be ^((~Bi)& Bo ); \ E##state[_b+_i] = Bi ^((~Bo)& Bu ); \ E##state[_b+_o] = Bo ^((~Bu)& Ba ); \ E##state[_b+_u] = Bu ^((~Ba)& Be ); \ \ A##state[_b+_o] ^= Do; \ Ba = ROL32(A##state[_b+_o], 28); \ A##state[_g+_u] ^= Du; \ Be = ROL32(A##state[_g+_u], 20); \ A##state[_k+_a] ^= Da; \ Bi = ROL32(A##state[_k+_a], 3); \ A##state[_m+_e] ^= De; \ Bo = ROL32(A##state[_m+_e], 13); \ A##state[_s+_i] ^= Di; \ Bu = ROL32(A##state[_s+_i], 29); \ E##state[_g+_a] = Ba ^((~Be)& Bi ); \ E##state[_g+_e] = Be ^((~Bi)& Bo ); \ E##state[_g+_i] = Bi ^((~Bo)& Bu ); \ E##state[_g+_o] = Bo ^((~Bu)& Ba ); \ E##state[_g+_u] = Bu ^((~Ba)& Be ); \ \ A##state[_b+_e] ^= De; \ Ba = ROL32(A##state[_b+_e], 1); \ A##state[_g+_i] ^= Di; \ Be = ROL32(A##state[_g+_i], 6); \ A##state[_k+_o] ^= Do; \ Bi = ROL32(A##state[_k+_o], 25); \ A##state[_m+_u] ^= Du; \ Bo = ROL32(A##state[_m+_u], 8); \ A##state[_s+_a] ^= Da; \ Bu = ROL32(A##state[_s+_a], 18); \ E##state[_k+_a] = Ba ^((~Be)& Bi ); \ E##state[_k+_e] = Be ^((~Bi)& Bo ); \ E##state[_k+_i] = Bi ^((~Bo)& Bu ); \ E##state[_k+_o] = Bo ^((~Bu)& Ba ); \ E##state[_k+_u] = Bu ^((~Ba)& Be ); \ \ A##state[_b+_u] ^= Du; \ Ba = ROL32(A##state[_b+_u], 27); \ A##state[_g+_a] ^= Da; \ Be = ROL32(A##state[_g+_a], 4); \ A##state[_k+_e] ^= De; \ Bi = ROL32(A##state[_k+_e], 10); \ A##state[_m+_i] ^= Di; \ Bo = ROL32(A##state[_m+_i], 15); \ A##state[_s+_o] ^= Do; \ Bu = ROL32(A##state[_s+_o], 24); \ E##state[_m+_a] = Ba ^((~Be)& Bi ); \ E##state[_m+_e] = Be ^((~Bi)& Bo ); \ E##state[_m+_i] = Bi ^((~Bo)& Bu ); \ E##state[_m+_o] = Bo ^((~Bu)& Ba ); \ E##state[_m+_u] = Bu ^((~Ba)& Be ); \ \ A##state[_b+_i] ^= Di; \ Ba = ROL32(A##state[_b+_i], 30); \ A##state[_g+_o] ^= Do; \ Be = ROL32(A##state[_g+_o], 23); \ A##state[_k+_u] ^= Du; \ Bi = ROL32(A##state[_k+_u], 7); \ A##state[_m+_a] ^= Da; \ Bo = ROL32(A##state[_m+_a], 9); \ A##state[_s+_e] ^= De; \ Bu = ROL32(A##state[_s+_e], 2); \ E##state[_s+_a] = Ba ^((~Be)& Bi ); \ E##state[_s+_e] = Be ^((~Bi)& Bo ); \ E##state[_s+_i] = Bi ^((~Bo)& Bu ); \ E##state[_s+_o] = Bo ^((~Bu)& Ba ); \ E##state[_s+_u] = Bu ^((~Ba)& Be ); \ \ #endif /* UseBebigokimisa */