raw
keccak                  1  -- S.MG implementation of Keccak-f permutations
keccak 2
keccak 3 -- (Based on The Keccak Reference, Version 3.0, January 14, 2011, by
keccak 4 -- Guido Bertoni, Joan Daemen, Michael Peeters and Gilles Van Assche)
keccak 5
keccak 6 -- S.MG, 2018
keccak 7
keccak 8 package SMG_Keccak is
keccak 9 pragma Pure(SMG_Keccak); --stateless, no side effects -> can cache calls
keccak 10
keccak 11 --knobs (can change as per keccak design but fixed here for S.MG purposes)--
keccak 12 Keccak_L: constant := 6; --gives keccak z (word) dimension of 2^6=64 and
keccak 13 --therefore keccak function 1600 with current
keccak 14 --constants (5*5*2^6)
keccak 15
keccak 16 Default_Bitrate: constant := 1344; --max bits the sponge can eat/spit without
keccak 17 --needing to scramble the state
keccak 18
keccak 19 --constants: dimensions of keccak state and number of rounds
keccak 20 XY_Length: constant := 5;
keccak 21 Z_Length: constant := 2**Keccak_L;
keccak 22 Width: constant := XY_Length * XY_Length * Z_Length;
keccak 23 N_Rounds: constant := 12 + 2*Keccak_L;
keccak 24
keccak 25 --types
keccak 26 type XYCoord is mod XY_Length;
keccak 27 type ZCoord is mod Z_Length;
keccak 28 type Round_Index is mod N_Rounds;
keccak 29
keccak 30 type ZWord is mod 2**Z_Length; --"lane" in keccak ref
keccak 31 type Plane is array(XYCoord) of ZWord; --a "horizontal slice" of keccak state
keccak 32 type State is array(XYCoord, XYCoord) of ZWord; --the full keccak state
keccak 33
keccak 34 type Round_Constants is array(Round_Index) of ZWord; --magic keccak constants
keccak 35
keccak 36 -- rate can be chosen by caller at each call, between 1 and width of state
keccak 37 -- higher rate means sponge "eats" more bits at a time but has fewer bits in
keccak 38 -- the "secret" part of the state (i.e. lower capacity)
keccak 39 subtype Keccak_Rate is Positive range 1..Width; -- capacity = width - rate
keccak 40
keccak 41 type Bit is mod 2;
keccak 42 type Bitstream is array( Natural range <> ) of Bit; -- any length; message
keccak 43 subtype Bitword is Bitstream( 0..Z_Length - 1 ); -- bits of one state "word"
keccak 44
keccak 45 -- type conversions
keccak 46 function BitsToWord( BWord : in Bitword ) return ZWord;
keccak 47 function WordToBits( Word : in ZWord ) return Bitword;
keccak 48
keccak 49 -- flip input octets (i.e. groups of 8 bits)
keccak 50 function FlipOctets( BWord : in Bitword ) return Bitword;
keccak 51
keccak 52 -- public function, the sponge itself
keccak 53 -- Keccak sponge structure using Keccak_Function, Pad and a given bitrate;
keccak 54 -- Input - the stream of bits to hash (the message)
keccak 55 -- Output - a bitstream of desired size for holding output
keccak 56 -- Block_Len - the bitrate to use; this is effectively the block length
keccak 57 -- for splitting Input AND squeezing output between scrambles
keccak 58 procedure Sponge(Input : in Bitstream;
keccak 59 Output : out Bitstream;
keccak 60 Block_Len : in Keccak_Rate := Default_Bitrate );
keccak 61
vdiff_keccak 62 -- state based Sponge
vdiff_keccak 63 type Keccak_Context (Block_Len: Keccak_Rate := Default_Bitrate) is
vdiff_keccak 64 record
vdiff_keccak 65 Internal: State := (others => (others => 0));
vdiff_keccak 66 Block: Bitstream(1..Block_Len) := (others => 0);
vdiff_keccak 67 Pos: Natural;
vdiff_keccak 68 end record;
vdiff_keccak 69
vdiff_keccak 70 procedure KeccakBegin(Ctx: in out Keccak_Context);
vdiff_keccak 71 procedure KeccakHash(Ctx: in out Keccak_Context;
vdiff_keccak 72 Input: Bitstream);
vdiff_keccak 73 procedure KeccakEnd(Ctx: in out Keccak_Context;
vdiff_keccak 74 Output: out Bitstream);
vdiff_keccak 75
keccak 76 private
keccak 77 -- these are internals of the keccak implementation, not meant to be directly
keccak 78 -- accessed/used
keccak 79
keccak 80 -- this will squeeze Block'Length bits out of state S
keccak 81 -- NO scramble of state in here!
keccak 82 -- NB: make SURE that Block'Length is the correct bitrate for this sponge
keccak 83 -- in particular, Block'Length should be a correct bitrate aka LESS than Width
keccak 84 procedure SqueezeBlock( Block: out Bitstream; S: in State);
keccak 85
keccak 86 -- This absorbs into sponge the given block, modifying the state accordingly
keccak 87 -- NO scramble of state in here so make sure the whole Block fits in state!
keccak 88 -- NB: make SURE that Block'Length is *the correct bitrate* for this sponge
keccak 89 -- in particular, Block'Length should be a correct bitrate aka LESS than Width
keccak 90 procedure AbsorbBlock( Block: in Bitstream; S: in out State );
keccak 91
keccak 92 --Keccak magic numbers
keccak 93 RC : constant Round_Constants :=
keccak 94 (
keccak 95 16#0000_0000_0000_0001#,
keccak 96 16#0000_0000_0000_8082#,
keccak 97 16#8000_0000_0000_808A#,
keccak 98 16#8000_0000_8000_8000#,
keccak 99 16#0000_0000_0000_808B#,
keccak 100 16#0000_0000_8000_0001#,
keccak 101 16#8000_0000_8000_8081#,
keccak 102 16#8000_0000_0000_8009#,
keccak 103 16#0000_0000_0000_008A#,
keccak 104 16#0000_0000_0000_0088#,
keccak 105 16#0000_0000_8000_8009#,
keccak 106 16#0000_0000_8000_000A#,
keccak 107 16#0000_0000_8000_808B#,
keccak 108 16#8000_0000_0000_008B#,
keccak 109 16#8000_0000_0000_8089#,
keccak 110 16#8000_0000_0000_8003#,
keccak 111 16#8000_0000_0000_8002#,
keccak 112 16#8000_0000_0000_0080#,
keccak 113 16#0000_0000_0000_800A#,
keccak 114 16#8000_0000_8000_000A#,
keccak 115 16#8000_0000_8000_8081#,
keccak 116 16#8000_0000_0000_8080#,
keccak 117 16#0000_0000_8000_0001#,
keccak 118 16#8000_0000_8000_8008#
keccak 119 );
keccak 120
keccak 121 --gnat-specific methods to have bit-ops for modular types
keccak 122 function Rotate_Left( Value : ZWord;
keccak 123 Amount : Natural)
keccak 124 return ZWord;
keccak 125 pragma Import(Intrinsic, Rotate_Left);
keccak 126
keccak 127 function Shift_Right( Value : ZWord;
keccak 128 Amount : Natural)
keccak 129 return ZWord;
keccak 130 pragma Import(Intrinsic, Shift_Right);
keccak 131
keccak 132 function Shift_Left( Value : ZWord;
keccak 133 Amount : Natural)
keccak 134 return ZWord;
keccak 135 pragma Import(Intrinsic, Shift_Left);
keccak 136
keccak 137 --Keccak transformations of the internal state
keccak 138 function Theta ( Input : in State) return State;
keccak 139 function Rho ( Input : in State) return State;
keccak 140 function Pi ( Input : in State) return State;
keccak 141 function Chi ( Input : in State) return State;
keccak 142 function Iota ( Round_Const : in ZWord; Input : in State) return State;
keccak 143
keccak 144 --Keccak function with block width currently 1600 (Width constant above)
keccak 145 --this simply applies *all* keccak transformations in the correct order, using
keccak 146 -- the keccak magic numbers (round constants) as per keccak reference
keccak 147 function Keccak_Function(Input: in State) return State;
keccak 148
keccak 149 end SMG_Keccak;