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.
Name | Type | Description |
---|---|---|
Width | int | state width in bits. can be 25, 50, 100, 200, 400, 800, or 1600 |
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 | Type | Description |
---|---|---|
rnd_i | input [RndW] | current round number [0..(MaxRound-1)] |
s_i | input [Width] | state input |
s_o | output[Width] | permuted 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.
| |
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.