raw
eucrypt_ch6_kecca...    1  -- S.MG implementation of Keccak-f permutations
eucrypt_ch6_kecca... 2
eucrypt_ch6_kecca... 3 -- (Based on The Keccak Reference, Version 3.0, January 14, 2011, by
eucrypt_ch6_kecca... 4 -- Guido Bertoni, Joan Daemen, Michael Peeters and Gilles Van Assche)
eucrypt_ch6_kecca... 5
eucrypt_ch16_byte... 6 -- NB: this is a byte-level (octet) implementation!
eucrypt_ch16_byte... 7 -- Input/output are always multiple of octets, NOT bits.
eucrypt_ch16_byte... 8
eucrypt_ch6_kecca... 9 -- S.MG, 2018
eucrypt_ch16_byte... 10 with Ada.Unchecked_Conversion; --for byteword to zword
eucrypt_ch16_byte... 11 with Interfaces.C;
eucrypt_ch16_byte... 12 with Interfaces;
eucrypt_ch6_kecca... 13
eucrypt_ch6_kecca... 14 package SMG_Keccak is
eucrypt_ch6_kecca... 15 pragma Pure(SMG_Keccak); --stateless, no side effects -> can cache calls
eucrypt_ch6_kecca... 16
eucrypt_ch6_kecca... 17 --knobs (can change as per keccak design but fixed here for S.MG purposes)--
eucrypt_ch6_kecca... 18 Keccak_L: constant := 6; --gives keccak z (word) dimension of 2^6=64 and
eucrypt_ch6_kecca... 19 --therefore keccak function 1600 with current
eucrypt_ch6_kecca... 20 --constants (5*5*2^6)
eucrypt_ch6_kecca... 21
eucrypt_ch16_byte... 22 Default_Byterate: constant := 168;--max octets the sponge can eat/spit without
eucrypt_ch10_oaep... 23 --needing to scramble the state
eucrypt_ch10_oaep... 24
eucrypt_ch6_kecca... 25 --constants: dimensions of keccak state and number of rounds
eucrypt_ch6_kecca... 26 XY_Length: constant := 5;
eucrypt_ch6_kecca... 27 Z_Length: constant := 2**Keccak_L;
eucrypt_ch6_kecca... 28 Width: constant := XY_Length * XY_Length * Z_Length;
eucrypt_ch6_kecca... 29 N_Rounds: constant := 12 + 2*Keccak_L;
eucrypt_ch6_kecca... 30
eucrypt_ch6_kecca... 31 --types
eucrypt_ch6_kecca... 32 type XYCoord is mod XY_Length;
eucrypt_ch6_kecca... 33 type ZCoord is mod Z_Length;
eucrypt_ch6_kecca... 34 type Round_Index is mod N_Rounds;
eucrypt_ch6_kecca... 35
eucrypt_ch6_kecca... 36 type ZWord is mod 2**Z_Length; --"lane" in keccak ref
eucrypt_ch6_kecca... 37 type Plane is array(XYCoord) of ZWord; --a "horizontal slice" of keccak state
eucrypt_ch6_kecca... 38 type State is array(XYCoord, XYCoord) of ZWord; --the full keccak state
eucrypt_ch6_kecca... 39
eucrypt_ch6_kecca... 40 type Round_Constants is array(Round_Index) of ZWord; --magic keccak constants
eucrypt_ch6_kecca... 41
eucrypt_ch16_byte... 42 -- rate can be chosen by caller at each call, between 1 and width of state /8
eucrypt_ch16_byte... 43 -- higher rate means sponge "eats" more octets at a time but has fewer octets
eucrypt_ch16_byte... 44 -- in the "secret" part of the state (i.e. lower capacity)
eucrypt_ch16_byte... 45 subtype Keccak_Rate is Positive range 1..Width/8; -- capacity = width - rate
eucrypt_ch16_byte... 46
eucrypt_ch16_byte... 47 type Bytestream is array( Natural range <> ) of Interfaces.Unsigned_8;
eucrypt_ch16_byte... 48 subtype Byteword is Bytestream( 0..Z_Length/8-1); --octets of one state "word"
eucrypt_ch16_byte... 49 function Cast is new Ada.Unchecked_Conversion (Byteword, ZWord);
eucrypt_ch16_byte... 50 function Cast is new Ada.Unchecked_Conversion (ZWord, Byteword);
eucrypt_ch7_kecca... 51
eucrypt_ch7_kecca... 52 -- type conversions
eucrypt_ch16_byte... 53 -- NB: those are NOT perfect opposites!
eucrypt_ch16_byte... 54 -- BytesToWord assumes input is raw and in LSB order, will flip on MSB iron
eucrypt_ch16_byte... 55 -- WordToBytes assumes input is MSB and will flip on LSB
eucrypt_ch16_byte... 56 -- This is because the Sponge squeezes MSB but absorbs LSB...
eucrypt_ch16_byte... 57 function BytesToWordLE( BWord : in Byteword ) return ZWord;
eucrypt_ch16_byte... 58 function WordToBytesBE( Word : in ZWord ) return Byteword;
eucrypt_ch9_kecca... 59
eucrypt_ch9_kecca... 60 -- flip input octets (i.e. groups of 8 bits)
eucrypt_ch16_byte... 61 function FlipOctets( BWord : in Byteword ) return Byteword;
eucrypt_ch7_kecca... 62
eucrypt_ch7_kecca... 63 -- public function, the sponge itself
eucrypt_ch16_byte... 64 -- Keccak sponge structure using Keccak_Function, Pad and a given octetrate;
eucrypt_ch7_kecca... 65 -- Input - the stream of bits to hash (the message)
eucrypt_ch16_byte... 66 -- Output - a bytestream of desired size for holding output
eucrypt_ch16_byte... 67 -- Block_Len - the octetrate to use; this is effectively the block length
eucrypt_ch7_kecca... 68 -- for splitting Input AND squeezing output between scrambles
eucrypt_ch16_byte... 69 procedure Sponge(Input : in Bytestream;
eucrypt_ch16_byte... 70 Output : out Bytestream;
eucrypt_ch16_byte... 71 Block_Len : in Keccak_Rate := Default_Byterate );
eucrypt_ch16_byte... 72
eucrypt_ch16_byte... 73 Reverse_Table : constant array(0..255) of Interfaces.Unsigned_8 := (
eucrypt_ch16_byte... 74 16#00#, 16#80#, 16#40#, 16#C0#, 16#20#, 16#A0#, 16#60#, 16#E0#,
eucrypt_ch16_byte... 75 16#10#, 16#90#, 16#50#, 16#D0#, 16#30#, 16#B0#, 16#70#, 16#F0#,
eucrypt_ch16_byte... 76 16#08#, 16#88#, 16#48#, 16#C8#, 16#28#, 16#A8#, 16#68#, 16#E8#,
eucrypt_ch16_byte... 77 16#18#, 16#98#, 16#58#, 16#D8#, 16#38#, 16#B8#, 16#78#, 16#F8#,
eucrypt_ch16_byte... 78 16#04#, 16#84#, 16#44#, 16#C4#, 16#24#, 16#A4#, 16#64#, 16#E4#,
eucrypt_ch16_byte... 79 16#14#, 16#94#, 16#54#, 16#D4#, 16#34#, 16#B4#, 16#74#, 16#F4#,
eucrypt_ch16_byte... 80 16#0C#, 16#8C#, 16#4C#, 16#CC#, 16#2C#, 16#AC#, 16#6C#, 16#EC#,
eucrypt_ch16_byte... 81 16#1C#, 16#9C#, 16#5C#, 16#DC#, 16#3C#, 16#BC#, 16#7C#, 16#FC#,
eucrypt_ch16_byte... 82 16#02#, 16#82#, 16#42#, 16#C2#, 16#22#, 16#A2#, 16#62#, 16#E2#,
eucrypt_ch16_byte... 83 16#12#, 16#92#, 16#52#, 16#D2#, 16#32#, 16#B2#, 16#72#, 16#F2#,
eucrypt_ch16_byte... 84 16#0A#, 16#8A#, 16#4A#, 16#CA#, 16#2A#, 16#AA#, 16#6A#, 16#EA#,
eucrypt_ch16_byte... 85 16#1A#, 16#9A#, 16#5A#, 16#DA#, 16#3A#, 16#BA#, 16#7A#, 16#FA#,
eucrypt_ch16_byte... 86 16#06#, 16#86#, 16#46#, 16#C6#, 16#26#, 16#A6#, 16#66#, 16#E6#,
eucrypt_ch16_byte... 87 16#16#, 16#96#, 16#56#, 16#D6#, 16#36#, 16#B6#, 16#76#, 16#F6#,
eucrypt_ch16_byte... 88 16#0E#, 16#8E#, 16#4E#, 16#CE#, 16#2E#, 16#AE#, 16#6E#, 16#EE#,
eucrypt_ch16_byte... 89 16#1E#, 16#9E#, 16#5E#, 16#DE#, 16#3E#, 16#BE#, 16#7E#, 16#FE#,
eucrypt_ch16_byte... 90 16#01#, 16#81#, 16#41#, 16#C1#, 16#21#, 16#A1#, 16#61#, 16#E1#,
eucrypt_ch16_byte... 91 16#11#, 16#91#, 16#51#, 16#D1#, 16#31#, 16#B1#, 16#71#, 16#F1#,
eucrypt_ch16_byte... 92 16#09#, 16#89#, 16#49#, 16#C9#, 16#29#, 16#A9#, 16#69#, 16#E9#,
eucrypt_ch16_byte... 93 16#19#, 16#99#, 16#59#, 16#D9#, 16#39#, 16#B9#, 16#79#, 16#F9#,
eucrypt_ch16_byte... 94 16#05#, 16#85#, 16#45#, 16#C5#, 16#25#, 16#A5#, 16#65#, 16#E5#,
eucrypt_ch16_byte... 95 16#15#, 16#95#, 16#55#, 16#D5#, 16#35#, 16#B5#, 16#75#, 16#F5#,
eucrypt_ch16_byte... 96 16#0D#, 16#8D#, 16#4D#, 16#CD#, 16#2D#, 16#AD#, 16#6D#, 16#ED#,
eucrypt_ch16_byte... 97 16#1D#, 16#9D#, 16#5D#, 16#DD#, 16#3D#, 16#BD#, 16#7D#, 16#FD#,
eucrypt_ch16_byte... 98 16#03#, 16#83#, 16#43#, 16#C3#, 16#23#, 16#A3#, 16#63#, 16#E3#,
eucrypt_ch16_byte... 99 16#13#, 16#93#, 16#53#, 16#D3#, 16#33#, 16#B3#, 16#73#, 16#F3#,
eucrypt_ch16_byte... 100 16#0B#, 16#8B#, 16#4B#, 16#CB#, 16#2B#, 16#AB#, 16#6B#, 16#EB#,
eucrypt_ch16_byte... 101 16#1B#, 16#9B#, 16#5B#, 16#DB#, 16#3B#, 16#BB#, 16#7B#, 16#FB#,
eucrypt_ch16_byte... 102 16#07#, 16#87#, 16#47#, 16#C7#, 16#27#, 16#A7#, 16#67#, 16#E7#,
eucrypt_ch16_byte... 103 16#17#, 16#97#, 16#57#, 16#D7#, 16#37#, 16#B7#, 16#77#, 16#F7#,
eucrypt_ch16_byte... 104 16#0F#, 16#8F#, 16#4F#, 16#CF#, 16#2F#, 16#AF#, 16#6F#, 16#EF#,
eucrypt_ch16_byte... 105 16#1F#, 16#9F#, 16#5F#, 16#DF#, 16#3F#, 16#BF#, 16#7F#, 16#FF#);
eucrypt_ch6_kecca... 106 private
eucrypt_ch6_kecca... 107 -- these are internals of the keccak implementation, not meant to be directly
eucrypt_ch6_kecca... 108 -- accessed/used
eucrypt_ch6_kecca... 109
eucrypt_ch16_byte... 110 -- this will squeeze Block'Length octets out of state S
eucrypt_ch7_kecca... 111 -- NO scramble of state in here!
eucrypt_ch16_byte... 112 -- NB: make SURE that Block'Length is the correct octetrate for this sponge
eucrypt_ch16_byte... 113 -- esp: Block'Length should be a correct octetrate aka LESS than Width/8
eucrypt_ch16_byte... 114 procedure SqueezeBlock( Block: out Bytestream; S: in State);
eucrypt_ch7_kecca... 115
eucrypt_ch7_kecca... 116 -- This absorbs into sponge the given block, modifying the state accordingly
eucrypt_ch7_kecca... 117 -- NO scramble of state in here so make sure the whole Block fits in state!
eucrypt_ch16_byte... 118 -- NB: make SURE that Block'Length is *the correct byterate* for this sponge
eucrypt_ch16_byte... 119 -- esp: Block'Length should be a correct byterate aka LESS than Width
eucrypt_ch16_byte... 120 procedure AbsorbBlock( Block: in Bytestream; S: in out State );
eucrypt_ch7_kecca... 121
eucrypt_ch6_kecca... 122 --Keccak magic numbers
eucrypt_ch6_kecca... 123 RC : constant Round_Constants :=
eucrypt_ch6_kecca... 124 (
eucrypt_ch6_kecca... 125 16#0000_0000_0000_0001#,
eucrypt_ch6_kecca... 126 16#0000_0000_0000_8082#,
eucrypt_ch6_kecca... 127 16#8000_0000_0000_808A#,
eucrypt_ch6_kecca... 128 16#8000_0000_8000_8000#,
eucrypt_ch6_kecca... 129 16#0000_0000_0000_808B#,
eucrypt_ch6_kecca... 130 16#0000_0000_8000_0001#,
eucrypt_ch6_kecca... 131 16#8000_0000_8000_8081#,
eucrypt_ch6_kecca... 132 16#8000_0000_0000_8009#,
eucrypt_ch6_kecca... 133 16#0000_0000_0000_008A#,
eucrypt_ch6_kecca... 134 16#0000_0000_0000_0088#,
eucrypt_ch6_kecca... 135 16#0000_0000_8000_8009#,
eucrypt_ch6_kecca... 136 16#0000_0000_8000_000A#,
eucrypt_ch6_kecca... 137 16#0000_0000_8000_808B#,
eucrypt_ch6_kecca... 138 16#8000_0000_0000_008B#,
eucrypt_ch6_kecca... 139 16#8000_0000_0000_8089#,
eucrypt_ch6_kecca... 140 16#8000_0000_0000_8003#,
eucrypt_ch6_kecca... 141 16#8000_0000_0000_8002#,
eucrypt_ch6_kecca... 142 16#8000_0000_0000_0080#,
eucrypt_ch6_kecca... 143 16#0000_0000_0000_800A#,
eucrypt_ch6_kecca... 144 16#8000_0000_8000_000A#,
eucrypt_ch6_kecca... 145 16#8000_0000_8000_8081#,
eucrypt_ch6_kecca... 146 16#8000_0000_0000_8080#,
eucrypt_ch6_kecca... 147 16#0000_0000_8000_0001#,
eucrypt_ch6_kecca... 148 16#8000_0000_8000_8008#
eucrypt_ch6_kecca... 149 );
eucrypt_ch6_kecca... 150
eucrypt_ch6_kecca... 151 --gnat-specific methods to have bit-ops for modular types
eucrypt_ch6_kecca... 152 function Rotate_Left( Value : ZWord;
eucrypt_ch6_kecca... 153 Amount : Natural)
eucrypt_ch6_kecca... 154 return ZWord;
eucrypt_ch6_kecca... 155 pragma Import(Intrinsic, Rotate_Left);
eucrypt_ch6_kecca... 156
eucrypt_ch6_kecca... 157 function Shift_Right( Value : ZWord;
eucrypt_ch6_kecca... 158 Amount : Natural)
eucrypt_ch6_kecca... 159 return ZWord;
eucrypt_ch6_kecca... 160 pragma Import(Intrinsic, Shift_Right);
eucrypt_ch6_kecca... 161
eucrypt_ch9_kecca... 162 function Shift_Left( Value : ZWord;
eucrypt_ch9_kecca... 163 Amount : Natural)
eucrypt_ch9_kecca... 164 return ZWord;
eucrypt_ch9_kecca... 165 pragma Import(Intrinsic, Shift_Left);
eucrypt_ch9_kecca... 166
eucrypt_ch7_kecca... 167 --Keccak transformations of the internal state
eucrypt_ch6_kecca... 168 function Theta ( Input : in State) return State;
eucrypt_ch6_kecca... 169 function Rho ( Input : in State) return State;
eucrypt_ch6_kecca... 170 function Pi ( Input : in State) return State;
eucrypt_ch6_kecca... 171 function Chi ( Input : in State) return State;
eucrypt_ch6_kecca... 172 function Iota ( Round_Const : in ZWord; Input : in State) return State;
eucrypt_ch6_kecca... 173
eucrypt_ch7_kecca... 174 --Keccak function with block width currently 1600 (Width constant above)
eucrypt_ch7_kecca... 175 --this simply applies *all* keccak transformations in the correct order, using
eucrypt_ch6_kecca... 176 -- the keccak magic numbers (round constants) as per keccak reference
eucrypt_ch6_kecca... 177 function Keccak_Function(Input: in State) return State;
eucrypt_ch6_kecca... 178
eucrypt_ch6_kecca... 179 end SMG_Keccak;