raw
eucrypt_ch8_bit_k...    1  -- S.MG bit-level implementation of Keccak-f permutations
eucrypt_ch8_bit_k... 2 -- (Based on The Keccak Reference, Version 3.0, January 14, 2011, by
eucrypt_ch8_bit_k... 3 -- Guido Bertoni, Joan Daemen, Michael Peeters and Gilles Van Assche)
eucrypt_ch8_bit_k... 4
eucrypt_ch8_bit_k... 5 -- S.MG, 2018
eucrypt_ch8_bit_k... 6
eucrypt_ch8_bit_k... 7 package SMG_Bit_Keccak is
eucrypt_ch8_bit_k... 8 pragma Pure(SMG_Bit_Keccak); --stateless, no side effects -> can cache calls
eucrypt_ch8_bit_k... 9
eucrypt_ch8_bit_k... 10 --knobs (can change as per keccak design but fixed here for S.MG purposes)--
eucrypt_ch8_bit_k... 11 Keccak_L: constant := 6; --gives keccak z dimension of 2^6=64 bits and
eucrypt_ch8_bit_k... 12 --therefore keccak function 1600 with current
eucrypt_ch8_bit_k... 13 --constants (5*5*2^6)
eucrypt_ch8_bit_k... 14
eucrypt_ch8_bit_k... 15 --constants: dimensions of keccak state and number of rounds
eucrypt_ch8_bit_k... 16 XY_Length: constant := 5;
eucrypt_ch8_bit_k... 17 Z_Length: constant := 2 ** Keccak_L;
eucrypt_ch8_bit_k... 18 Width: constant := XY_Length * XY_Length * Z_Length;
eucrypt_ch8_bit_k... 19 N_Rounds: constant := 12 + 2 * Keccak_L;
eucrypt_ch8_bit_k... 20
eucrypt_ch8_bit_k... 21 --types
eucrypt_ch8_bit_k... 22 type XYCoord is mod XY_Length;
eucrypt_ch8_bit_k... 23 type ZCoord is mod Z_Length;
eucrypt_ch8_bit_k... 24 type Round_Index is mod N_Rounds;
eucrypt_ch8_bit_k... 25
eucrypt_ch8_bit_k... 26 type Bit is mod 2;
eucrypt_ch8_bit_k... 27 type Bitstream is array( Natural range <> ) of Bit; -- any length; message
eucrypt_ch8_bit_k... 28 type Bitword is array( ZCoord ) of Bit; -- a keccak "word" of bits
eucrypt_ch8_bit_k... 29
eucrypt_ch8_bit_k... 30 type State is array( XYCoord, XYCoord ) of Bitword; -- the full keccak state
eucrypt_ch8_bit_k... 31
eucrypt_ch8_bit_k... 32 type Round_Constants is array(Round_Index) of Bitword; --magic keccak values
eucrypt_ch8_bit_k... 33
eucrypt_ch8_bit_k... 34 -- rate can be chosen by caller at each call, between 1 and width of state
eucrypt_ch8_bit_k... 35 -- higher rate means sponge "eats" more bits at a time but has fewer bits in
eucrypt_ch8_bit_k... 36 -- the "secret" part of the state (i.e. lower capacity)
eucrypt_ch8_bit_k... 37 subtype Keccak_Rate is Positive range 1..Width; -- capacity = width - rate
eucrypt_ch8_bit_k... 38
eucrypt_ch8_bit_k... 39 -- public function, the sponge itself
eucrypt_ch8_bit_k... 40 -- Keccak sponge structure using Keccak_Function, Pad and a given bitrate;
eucrypt_ch8_bit_k... 41 -- Input - the stream of bits to hash (the message)
eucrypt_ch8_bit_k... 42 -- Block_Len - the bitrate to use; this is effectively the block length
eucrypt_ch8_bit_k... 43 -- for splitting Input AND squeezing output between scrambles
eucrypt_ch8_bit_k... 44 -- Output - a bitstream of desired size for holding output
eucrypt_ch8_bit_k... 45 procedure Sponge(Input : in Bitstream;
eucrypt_ch8_bit_k... 46 Block_Len : in Keccak_Rate;
eucrypt_ch8_bit_k... 47 Output : out Bitstream);
eucrypt_ch8_bit_k... 48
eucrypt_ch8_bit_k... 49 private
eucrypt_ch8_bit_k... 50 -- these are internals of the keccak implementation, not meant to be directly
eucrypt_ch8_bit_k... 51 -- accessed/used
eucrypt_ch8_bit_k... 52 -- moving one bit forwards in Keccak state
eucrypt_ch8_bit_k... 53 procedure Next_Pos( X : in out XYCoord;
eucrypt_ch8_bit_k... 54 Y : in out XYCoord;
eucrypt_ch8_bit_k... 55 Z : in out ZCoord
eucrypt_ch8_bit_k... 56 );
eucrypt_ch8_bit_k... 57 -- set coordinates to first bit of Keccak state
eucrypt_ch8_bit_k... 58 procedure First_Pos( X : out XYCoord;
eucrypt_ch8_bit_k... 59 Y : out XYCoord;
eucrypt_ch8_bit_k... 60 Z : out ZCoord
eucrypt_ch8_bit_k... 61 );
eucrypt_ch8_bit_k... 62
eucrypt_ch8_bit_k... 63 -- operations with Bitwords
eucrypt_ch8_bit_k... 64 function BWRotate_Left( Input: in Bitword;
eucrypt_ch8_bit_k... 65 Count: in Natural)
eucrypt_ch8_bit_k... 66 return Bitword;
eucrypt_ch8_bit_k... 67
eucrypt_ch8_bit_k... 68 -- this will squeeze Block'Length bits out of state S
eucrypt_ch8_bit_k... 69 -- NO scramble of state in here!
eucrypt_ch8_bit_k... 70 -- NB: make SURE that Block'Length is the correct bitrate for this sponge
eucrypt_ch8_bit_k... 71 -- in particular, Block'Length should be a correct bitrate aka LESS than Width
eucrypt_ch8_bit_k... 72 procedure SqueezeBlock( Block: out Bitstream; S: in State);
eucrypt_ch8_bit_k... 73
eucrypt_ch8_bit_k... 74 -- This absorbs into sponge the given block, modifying the state accordingly
eucrypt_ch8_bit_k... 75 -- NO scramble of state in here so make sure the whole Block fits in state!
eucrypt_ch8_bit_k... 76 -- NB: make SURE that Block'Length is *the correct bitrate* for this sponge
eucrypt_ch8_bit_k... 77 -- in particular, Block'Length should be a correct bitrate aka LESS than Width
eucrypt_ch8_bit_k... 78 procedure AbsorbBlock( Block: in Bitstream; S: in out State );
eucrypt_ch8_bit_k... 79
eucrypt_ch8_bit_k... 80 -- Keccak magic bitwords
eucrypt_ch8_bit_k... 81 RC : constant Round_Constants :=
eucrypt_ch8_bit_k... 82 (
eucrypt_ch8_bit_k... 83 -- 16#0000_0000_0000_0001#, round 0
eucrypt_ch8_bit_k... 84 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 85 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 86 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 87 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1),
eucrypt_ch8_bit_k... 88 -- 16#0000_0000_0000_8082#, round 1
eucrypt_ch8_bit_k... 89 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 90 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 91 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 92 1,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,1,0),
eucrypt_ch8_bit_k... 93 -- 16#8000_0000_0000_808A#, round 2
eucrypt_ch8_bit_k... 94 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 95 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 96 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 97 1,0,0,0, 0,0,0,0, 1,0,0,0, 1,0,1,0),
eucrypt_ch8_bit_k... 98
eucrypt_ch8_bit_k... 99 -- 16#8000_0000_8000_8000#, round 3
eucrypt_ch8_bit_k... 100 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 101 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 102 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 103 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0),
eucrypt_ch8_bit_k... 104
eucrypt_ch8_bit_k... 105 -- 16#0000_0000_0000_808B#, round 4
eucrypt_ch8_bit_k... 106 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 107 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 108 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 109 1,0,0,0, 0,0,0,0, 1,0,0,0, 1,0,1,1),
eucrypt_ch8_bit_k... 110
eucrypt_ch8_bit_k... 111 -- 16#0000_0000_8000_0001#, round 5
eucrypt_ch8_bit_k... 112 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 113 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 114 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 115 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1),
eucrypt_ch8_bit_k... 116
eucrypt_ch8_bit_k... 117 -- 16#8000_0000_8000_8081#, round 6
eucrypt_ch8_bit_k... 118 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 119 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 120 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 121 1,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,1),
eucrypt_ch8_bit_k... 122
eucrypt_ch8_bit_k... 123 -- 16#8000_0000_0000_8009#, round 7
eucrypt_ch8_bit_k... 124 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 125 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 126 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 127 1,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,0,1),
eucrypt_ch8_bit_k... 128
eucrypt_ch8_bit_k... 129 -- 16#0000_0000_0000_008A#, round 8
eucrypt_ch8_bit_k... 130 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 131 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 132 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 133 0,0,0,0, 0,0,0,0, 1,0,0,0, 1,0,1,0),
eucrypt_ch8_bit_k... 134
eucrypt_ch8_bit_k... 135 -- 16#0000_0000_0000_0088#, round 9
eucrypt_ch8_bit_k... 136 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 137 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 138 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 139 0,0,0,0, 0,0,0,0, 1,0,0,0, 1,0,0,0),
eucrypt_ch8_bit_k... 140
eucrypt_ch8_bit_k... 141 -- 16#0000_0000_8000_8009#, round 10
eucrypt_ch8_bit_k... 142 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 143 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 144 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 145 1,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,0,1),
eucrypt_ch8_bit_k... 146
eucrypt_ch8_bit_k... 147 -- 16#0000_0000_8000_000A#, round 11
eucrypt_ch8_bit_k... 148 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 149 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 150 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 151 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,1,0),
eucrypt_ch8_bit_k... 152
eucrypt_ch8_bit_k... 153 -- 16#0000_0000_8000_808B#, round 12
eucrypt_ch8_bit_k... 154 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 155 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 156 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 157 1,0,0,0, 0,0,0,0, 1,0,0,0, 1,0,1,1),
eucrypt_ch8_bit_k... 158
eucrypt_ch8_bit_k... 159 -- 16#8000_0000_0000_008B#, round 13
eucrypt_ch8_bit_k... 160 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 161 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 162 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 163 0,0,0,0, 0,0,0,0, 1,0,0,0, 1,0,1,1),
eucrypt_ch8_bit_k... 164
eucrypt_ch8_bit_k... 165 -- 16#8000_0000_0000_8089#, round 14
eucrypt_ch8_bit_k... 166 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 167 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 168 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 169 1,0,0,0, 0,0,0,0, 1,0,0,0, 1,0,0,1),
eucrypt_ch8_bit_k... 170
eucrypt_ch8_bit_k... 171 -- 16#8000_0000_0000_8003#, round 15
eucrypt_ch8_bit_k... 172 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 173 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 174 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 175 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,1),
eucrypt_ch8_bit_k... 176
eucrypt_ch8_bit_k... 177 -- 16#8000_0000_0000_8002#, round 16
eucrypt_ch8_bit_k... 178 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 179 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 180 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 181 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,1,0),
eucrypt_ch8_bit_k... 182
eucrypt_ch8_bit_k... 183 -- 16#8000_0000_0000_0080#, round 17
eucrypt_ch8_bit_k... 184 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 185 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 186 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 187 0,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0),
eucrypt_ch8_bit_k... 188
eucrypt_ch8_bit_k... 189 -- 16#0000_0000_0000_800A#, round 18
eucrypt_ch8_bit_k... 190 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 191 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 192 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 193 1,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,1,0),
eucrypt_ch8_bit_k... 194
eucrypt_ch8_bit_k... 195 -- 16#8000_0000_8000_000A#, round 19
eucrypt_ch8_bit_k... 196 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 197 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 198 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 199 0,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,1,0),
eucrypt_ch8_bit_k... 200
eucrypt_ch8_bit_k... 201 -- 16#8000_0000_8000_8081#, round 20
eucrypt_ch8_bit_k... 202 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 203 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 204 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 205 1,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,1),
eucrypt_ch8_bit_k... 206
eucrypt_ch8_bit_k... 207 -- 16#8000_0000_0000_8080#, round 21
eucrypt_ch8_bit_k... 208 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 209 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 210 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 211 1,0,0,0, 0,0,0,0, 1,0,0,0, 0,0,0,0),
eucrypt_ch8_bit_k... 212
eucrypt_ch8_bit_k... 213 -- 16#0000_0000_8000_0001#, round 22
eucrypt_ch8_bit_k... 214 (0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 215 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 216 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 217 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1),
eucrypt_ch8_bit_k... 218
eucrypt_ch8_bit_k... 219 -- 16#8000_0000_8000_8008#, round 23
eucrypt_ch8_bit_k... 220 (1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 221 0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 222 1,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,0,
eucrypt_ch8_bit_k... 223 1,0,0,0, 0,0,0,0, 0,0,0,0, 1,0,0,0)
eucrypt_ch8_bit_k... 224 );
eucrypt_ch8_bit_k... 225
eucrypt_ch8_bit_k... 226 -- Keccak transformations of the internal state
eucrypt_ch8_bit_k... 227 function Theta ( Input : in State ) return State;
eucrypt_ch8_bit_k... 228 function Rho ( Input : in State ) return State;
eucrypt_ch8_bit_k... 229 function Pi ( Input : in State ) return State;
eucrypt_ch8_bit_k... 230 function Chi ( Input : in State ) return State;
eucrypt_ch8_bit_k... 231 function Iota ( Round_Const : in Bitword; Input : in State ) return State;
eucrypt_ch8_bit_k... 232
eucrypt_ch8_bit_k... 233 -- Keccak function with block width currently 1600 (Width constant above)
eucrypt_ch8_bit_k... 234 -- It simply applies *all* keccak transformations in the correct order, using
eucrypt_ch8_bit_k... 235 -- the keccak magic numbers (round constants) as per keccak reference
eucrypt_ch8_bit_k... 236 function Keccak_Function(Input: in State) return State;
eucrypt_ch8_bit_k... 237
eucrypt_ch8_bit_k... 238 end SMG_Bit_Keccak;
eucrypt_ch8_bit_k... 239