# Overview

prim_keccak is a single round implementation of the permutation stage in SHA3 algorithm. Keccak primitive module assumes the number of rounds is less than or equal to 12 + 2L. It supports all combinations of the data width described in the spec. This implementation is not currently hardened against side-channel or fault injection attacks. It implements the Keccak_p function.

## Parameters

Name Type Description
Width int state width in bits. can be 25, 50, 100, 200, 400, 800, or 1600

### Derived Parameters

The parameters below are derived parameter from Width parameter.

Name Type Description
W int number of slices in state. Width/25
L int log2 of W
MaxRound int maximum allowed round value. 12 + 2L
RndW int bit-width to represent MaxRound. log2 of MaxRound

## Signal Interfaces

Signal Type Description
rnd_i input [RndW] current round number [0..(MaxRound-1)]
s_i input [Width] state input
s_o output[Width] permutated state output

s_i and s_o are little-endian bitarrays. The SHA3 spec shows how to convert the bitstream into the 5x5xW state cube. For instance, bit 0 of the stream maps to A[0,0,0]. The bit 0 in the spec is the first bit of the bitstream. In prim_keccak, s_i[0] is the first bit and s_i[Width-1] is the last bit.

# Theory of Operations

         |                                                          |
rnd_i    |                                                          |
---/---->| -----------------------------------------\               |
[RndW]  |                                          |               |
|                                          |               |
s_i      |                                          V               | s_o
===/====>| bit2s() -> chi(pi(rho(theta))) -> iota( ,rnd) -> s2bit() |==/==>
[Width] |            |-----------keccak_p--------------|           |[Width]
|                                                          |


prim_keccak implements “Step Mappings” section in SHA3 spec. It is composed of five unique permutation functions, theta, rho, pi, chi, and iota. Also it has functions that converts bitstream of Width into 5x5xW state and vice versa.

Three constant parameters are defined inside the keccak primitive module. The rotate position described in phi function is hard-coded as below. The value is described in the SHA3 specification.

localparam int PiRotate [5][5] = '{
//y  0    1    2    3    4     x
'{   0,   3,   1,   4,   2},// 0
'{   1,   4,   2,   0,   3},// 1
'{   2,   0,   3,   1,   4},// 2
'{   3,   1,   4,   2,   0},// 3
'{   4,   2,   0,   3,   1} // 4
};


The shift amount in rho function is defined as RhoOffset parameter. The value is same as in the specification, but it is used as RhoOffset % W. For instance, RhoOffset[2][2] is 171. If Width is 1600, the value used in the design is 171%64, which is 43.

The round constant is calculated by the tool hw/ip/prim/util/keccak_rc.py. The recommended default value of 24 rounds is used in this design, but an argument (changed with the -r flag) is provided for reference. The keccak_rc.py script creates 64 bit of constants and the prim_keccak module uses only lower bits of the constants if the Width is less than 1600. For instance, if Width is 800, lower 32bits of the round constant are used.