static const unsigned rotation_offsets[5][5] = { { 0, 1, 62, 28, 27 }, { 36, 44, 6, 55, 20 }, { 3, 10, 43, 25, 39 }, { 41, 45, 15, 21, 8 }, { 18, 2, 61, 56, 14 } }; #define A(x,y) (A.o + ((x) + (y)*5)*z) #define B(x,y) (B.o + ((x) + (y)*5)*z) #define C(x) (C.o + (x)*z) #define D(x) (D.o + (x)*z) const struct operation keccak_round[] = { /* θ step */ #define t0(x) { XOR, z, t.o, A(x,0), A(x,1) }, \ { XOR, z, t.o, t.o, A(x,2) }, \ { XOR, z, t.o, t.o, A(x,3) }, \ { XOR, z, C(x), t.o, A(x,4) } t0(0), t0(1), t0(2), t0(3), t0(4), #define t1(x) { ROT, z, t.o, C(((x)+1)%5), 1 }, \ { XOR, z, D(x), C(((x)+5-1)%5), t.o } t1(0), t1(1), t1(2), t1(3), t1(4), #define t2(x,y) { XOR, z, A(x,y), A(x,y), D(x) } t2(0,0), t2(1,0), t2(2,0), t2(3,0), t2(4,0), t2(0,1), t2(1,1), t2(2,1), t2(3,1), t2(4,1), t2(0,2), t2(1,2), t2(2,2), t2(3,2), t2(4,2), t2(0,3), t2(1,3), t2(2,3), t2(3,3), t2(4,3), t2(0,4), t2(1,4), t2(2,4), t2(3,4), t2(4,4), /* ρ and π steps */ #define rp(x,y) { ROT, z, B(y,(2*x+3*y)%5), A(x,y), rotation_offsets[y][x] } rp(0,0), rp(1,0), rp(2,0), rp(3,0), rp(4,0), rp(0,1), rp(1,1), rp(2,1), rp(3,1), rp(4,1), rp(0,2), rp(1,2), rp(2,2), rp(3,2), rp(4,2), rp(0,3), rp(1,3), rp(2,3), rp(3,3), rp(4,3), rp(0,4), rp(1,4), rp(2,4), rp(3,4), rp(4,4), /* χ step */ #define xi(x,y) { NOT, z, t.o, B(((x)+1)%5,y) }, \ { AND, z, t.o, t.o, B(((x)+2)%5,y) }, \ { XOR, z, A(x,y), B(x,y), t.o } xi(0,0), xi(1,0), xi(2,0), xi(3,0), xi(4,0), xi(0,1), xi(1,1), xi(2,1), xi(3,1), xi(4,1), xi(0,2), xi(1,2), xi(2,2), xi(3,2), xi(4,2), xi(0,3), xi(1,3), xi(2,3), xi(3,3), xi(4,3), xi(0,4), xi(1,4), xi(2,4), xi(3,4), xi(4,4), /* ι step */ { XOR, z, A(0,0), r.o }, };