tree checksum vpatch file split hunks

all signers: diana_coman

antecedents: eucrypt_ch6_keccak_permutations

press order:

eucrypt_genesisdiana_coman
eucrypt_ch6_keccak_permutationsdiana_coman
eucrypt_ch7_keccak_spongediana_coman

patch:

- 49E31942E59726FDE97368B5651502C78EFA7602B31E77BDCE9AE745FAB817CBCACF9C166022805BB20BA25AD693CFCF5CF9841252044F5BEA30C89792E1A1E5
+ 87241E219925CCE47CD73892DC728607F14BD01324BA0B08D04DB6F2D7F2469958D4C65A5F3C26F2DB1857841857DCD3204FDC78238CAE3126905BB5A3CECC99
eucrypt/smg_keccak/smg_keccak.adb
(2 . 6)(2 . 166)
5
6 package body SMG_Keccak is
7
8 -- public function, sponge
9 procedure Sponge( Input : in Bitstream;
10 Block_Len : in Keccak_Rate;
11 Output : out Bitstream) is
12 Internal : State := (others => (others => 0));
13 begin
14 --absorb input into sponge in a loop on available blocks, including padding
15 declare
16 -- number of input blocks after padding (between 2 and block_len bits pad)
17 Padded_Blocks : constant Positive := 1 + (Input'Length + 1) / Block_Len;
18 Padded : Bitstream ( 1 .. Padded_Blocks * Block_Len );
19 Block : Bitstream ( 1 .. Block_Len );
20 begin
21 -- initialise Padded with 0 everywhere
22 Padded := ( others => 0 );
23 -- copy and pad input with rule 10*1
24 Padded( Padded'First .. Padded'First + Input'Length - 1 ) := Input;
25 Padded( Padded'First + Input'Length ) := 1;
26 Padded( Padded'Last ) := 1;
27
28 -- loop through padded input and absorb block by block into sponge
29 -- padded input IS a multiple of blocks, so no stray bits left
30 for B in 0 .. Padded_Blocks - 1 loop
31 -- first get the current block to absorb
32 Block := Padded( Padded'First + B * Block_Len ..
33 Padded'First + (B+1) * Block_Len - 1 );
34 AbsorbBlock( Block, Internal );
35 -- scramble state with Keccak function
36 Internal := Keccak_Function( Internal );
37
38 end loop; -- end absorb loop for blocks
39 end; -- end absorb stage
40
41 --squeeze required bits from sponge in a loop as needed
42 declare
43 -- full blocks per output
44 BPO : constant Natural := Output'Length / Block_Len;
45 -- stray bits per output
46 SPO : constant Natural := Output'Length mod Block_Len;
47 Block : Bitstream( 1 .. Block_Len );
48 begin
49 -- squeeze block by block (if at least one full block is needed)
50 for I in 0 .. BPO - 1 loop
51 SqueezeBlock( Block, Internal );
52 Output( Output'First + I * Block_Len ..
53 Output'First + (I + 1) * Block_Len -1) := Block;
54
55 -- scramble state
56 Internal := Keccak_Function( Internal );
57 end loop; -- end squeezing full blocks
58
59 -- squeeze any partial block needed (stray bits)
60 if SPO > 0 then
61 SqueezeBlock( Block, Internal );
62 Output( Output'Last - SPO + 1 .. Output'Last ) :=
63 Block( Block'First .. Block'First + SPO - 1 );
64 end if; -- end squeezing partial last block (stray bits)
65
66 end; -- end squeeze stage
67 end Sponge;
68
69 -- convert from a bitstream of ZWord size to an actual ZWord number
70 -- first bit of bitstream will be most significant bit of ZWord
71 function BitsToWord( Bits: in Bitword ) return ZWord is
72 W: ZWord;
73 P: Natural;
74 begin
75 W := 0;
76 P := 0;
77 for I in reverse Bitword'Range loop
78 W := W + ZWord( Bits(I) ) * ( 2**P );
79 P := P + 1;
80 end loop;
81 return W;
82 end BitsToWord;
83
84 -- convert from a ZWord (lane of state) to a bitstream of ZWord size
85 -- most significant bit of ZWord will be left most bit of bitstream
86 function WordToBits( Word: in ZWord ) return Bitword is
87 Bits: Bitword := (others => 0);
88 W: ZWord;
89 begin
90 W := Word;
91 for I in reverse Bitword'Range loop
92 Bits( I ) := Bit( W mod 2 );
93 W := W / 2;
94 end loop;
95 return Bits;
96 end WordToBits;
97
98 -- helper procedures for sponge absorb/squeeze
99
100 -- NO scramble here, this will absorb ALL given block, make sure it fits!
101 procedure AbsorbBlock( Block: in Bitstream; S: in out State ) is
102 WPB: constant Natural := Block'Length / Z_Length; -- words per block
103 SBB: constant Natural := Block'Length mod Z_Length; -- stray bits
104 FromPos, ToPos : Natural;
105 X, Y : XYCoord;
106 Word : ZWord;
107 BWord : Bitword;
108 begin
109 -- xor current block into first Block'Length bits of state
110 -- a block can consist in more than one word
111 X := 0;
112 Y := 0;
113 for I in 0..WPB-1 loop
114 FromPos := Block'First + I * Z_Length;
115 ToPos := FromPos + Z_Length - 1;
116 Word := BitsToWord( Block( FromPos .. ToPos ) );
117 S( X, Y ) := S( X, Y ) xor Word;
118 -- move on to next word in state
119 X := X + 1;
120 if X = 0 then
121 Y := Y + 1;
122 end if;
123 end loop;
124 -- absorb also any remaining bits from block
125 if SBB > 0 then
126 ToPos := Block'Last;
127 FromPos := ToPos - SBB + 1;
128 BWord := (others => 0);
129 BWord(Bitword'First .. Bitword'First + SBB - 1) := Block(ToPos..FromPos);
130 Word := BitsToWord( BWord );
131 S( X, Y ) := S( X, Y ) xor Word;
132 end if;
133 end AbsorbBlock;
134
135 -- NO scramble here, this will squeeze Block'Length bits out of *same* state S
136 procedure SqueezeBlock( Block: out Bitstream; S: in State) is
137 X, Y : XYCoord;
138 BWord : Bitword;
139 FromPos : Natural;
140 Len : Natural;
141 begin
142 X := 0;
143 Y := 0;
144 FromPos := Block'First;
145
146 while FromPos <= Block'Last loop
147 BWord := WordToBits( S(X, Y) );
148
149 X := X + 1;
150 if X = 0 then
151 Y := Y + 1;
152 end if;
153
154 -- copy full word if it fits or
155 -- only as many bits as are still needed to fill the block
156 Len := Block'Last - FromPos + 1;
157 if Len > Z_Length then
158 Len := Z_Length;
159 end if;
160
161 Block(FromPos..FromPos+Len-1) := BWord(BWord'First..BWord'First+Len-1);
162 FromPos := FromPos + Len;
163 end loop;
164 end SqueezeBlock;
165
166
167 -- private, internal transformations
168 function Theta(Input : in State) return State is
169 Output : State;
170 C : Plane;
- 1E1EAA78ECCAFFA4235EC739A63D20EE3F399BDD94386915B44CE58212032988CE67481EB2E558C846DFCDCDD8748BDA6E276D20512B487F5A3B86C44C946A40
+ 9356ACB04F2091A9A611331387E055BCB8E58E7B28AE7FE4E0562486C802598AD3F24BBC20F05E539A3DB6274E75CD02F5A31DAC5BB2499F3CF2BF094994DDC0
eucrypt/smg_keccak/smg_keccak.ads
(30 . 10)(30 . 45)
175
176 type Round_Constants is array(Round_Index) of ZWord; --magic keccak constants
177
178 -- rate can be chosen by caller at each call, between 1 and width of state
179 -- higher rate means sponge "eats" more bits at a time but has fewer bits in
180 -- the "secret" part of the state (i.e. lower capacity)
181 subtype Keccak_Rate is Positive range 1..Width; -- capacity = width - rate
182
183 type Bit is mod 2;
184 type Bitstream is array( Natural range <> ) of Bit; -- any length; message
185 subtype Bitword is Bitstream( 0..Z_Length - 1 ); -- bits of one state "word"
186
187 -- type conversions
188 function BitsToWord( Bits: in Bitword ) return ZWord;
189 function WordToBits( Word: in ZWord ) return Bitword;
190
191 -- public function, the sponge itself
192 -- Keccak sponge structure using Keccak_Function, Pad and a given bitrate;
193 -- Input - the stream of bits to hash (the message)
194 -- Block_Len - the bitrate to use; this is effectively the block length
195 -- for splitting Input AND squeezing output between scrambles
196 -- Output - a bitstream of desired size for holding output
197 procedure Sponge(Input : in Bitstream;
198 Block_Len : in Keccak_Rate;
199 Output : out Bitstream);
200
201 private
202 -- these are internals of the keccak implementation, not meant to be directly
203 -- accessed/used
204
205 -- this will squeeze Block'Length bits out of state S
206 -- NO scramble of state in here!
207 -- NB: make SURE that Block'Length is the correct bitrate for this sponge
208 -- in particular, Block'Length should be a correct bitrate aka LESS than Width
209 procedure SqueezeBlock( Block: out Bitstream; S: in State);
210
211 -- This absorbs into sponge the given block, modifying the state accordingly
212 -- NO scramble of state in here so make sure the whole Block fits in state!
213 -- NB: make SURE that Block'Length is *the correct bitrate* for this sponge
214 -- in particular, Block'Length should be a correct bitrate aka LESS than Width
215 procedure AbsorbBlock( Block: in Bitstream; S: in out State );
216
217 --Keccak magic numbers
218 RC : constant Round_Constants :=
219 (
(74 . 15)(109 . 15)
221 return ZWord;
222 pragma Import(Intrinsic, Shift_Right);
223
224 --Keccak permutations
225 --Keccak transformations of the internal state
226 function Theta ( Input : in State) return State;
227 function Rho ( Input : in State) return State;
228 function Pi ( Input : in State) return State;
229 function Chi ( Input : in State) return State;
230 function Iota ( Round_Const : in ZWord; Input : in State) return State;
231
232 --Keccak full function with block width currently 1600 (Width constant above)
233 --this simply applies *all* keccak permutations in the correct order and using
234 --Keccak function with block width currently 1600 (Width constant above)
235 --this simply applies *all* keccak transformations in the correct order, using
236 -- the keccak magic numbers (round constants) as per keccak reference
237 function Keccak_Function(Input: in State) return State;
238
- E0071E8372C50670886565CC5EF6F69E310AB5F4922ABD6CB20FA281087C6790CE0EC1980AF4A2504DCB189A8009CF5354D7581CF9B4F4D1F515086ECD08B248
+ B91E0448A3D5EC419C7E47701E8A3BFC53082601B860AC093EDD13606C093D1C6F112F514A8A90C0825713B45B5C273145D67D90D291631D6AAF940300DF9386
eucrypt/smg_keccak/tests/smg_keccak-test.adb
(11 . 7)(11 . 6)
243 type Test_Round is array(Round_Index) of Test_Vector;
244
245 --helper methods
246
247 procedure print_state(S: in State; Title: in String) is
248 Hex: array(0..15) of Character := ("0123456789ABCDEF");
249 Len: constant Natural := Z_Length / 4;
(32 . 6)(31 . 24)
251 end loop;
252 end;
253
254 procedure print_bitstream(B: in Bitstream; Title: in String) is
255 Hex : array(0..15) of Character := ("0123456789ABCDEF");
256 HexString : String(1..B'Length/4);
257 C : Natural;
258 Pos : Natural;
259 begin
260 for I in 1..B'Length/4 loop
261 Pos := (I-1)*4 + B'First;
262 C := Natural( B(Pos) ) * 8 +
263 Natural( B(Pos + 1) ) * 4 +
264 Natural( B(Pos + 2) ) * 2 +
265 Natural( B(Pos + 3) );
266 HexString(I) := Hex(C);
267 end loop;
268 Put_Line("---" & Title & "---");
269 Put_Line(HexString);
270 end print_bitstream;
271
272 function read_state(File: in FILE_TYPE; Oct: Positive :=8) return State is
273 S: State;
274 Line1: String := "0000000000000000 " &
(140 . 6)(157 . 117)
276 Input := Expected;
277 end loop;
278 end test_one_round;
279
280 procedure test_bits_to_word_conversion is
281 bits: Bitword := (others => 0);
282 obtained_bits: Bitword := (others => 0);
283 expected: ZWord;
284 obtained: ZWord;
285 begin
286 expected := 16#E7DDE140798F25F1#;
287 bits := (1,1,1,0, 0,1,1,1, 1,1,0,1, 1,1,0,1, 1,1,1,0, 0,0,0,1, 0,1,0,0,
288 0,0,0,0, 0,1,1,1, 1,0,0,1, 1,0,0,0, 1,1,1,1, 0,0,1,0, 0,1,0,1,
289 1,1,1,1, 0,0,0,1);
290 obtained := BitsToWord(bits);
291 obtained_bits := WordToBits(expected);
292
293 if obtained /= expected then
294 Put_Line("FAIL: bits to word");
295 Put_Line("Expected: " & ZWord'Image(expected));
296 Put_Line("Obtained: " & ZWord'Image(obtained));
297 else
298 Put_Line("PASSED: bits to word");
299 end if;
300
301 if obtained_bits /= bits then
302 Put_Line("FAIL: word to bits");
303 Put("Expected: ");
304 for I in Bitword'Range loop
305 Put(Bit'Image(bits(I)));
306 end loop;
307 Put_Line("");
308 Put_Line("Obtained: ");
309 for I in Bitword'Range loop
310 Put(Bit'Image(obtained_bits(I)));
311 end loop;
312 Put_Line("");
313 else
314 Put_Line("PASSED: word to bits");
315 end if;
316 end test_bits_to_word_conversion;
317
318 procedure test_sponge is
319 Bitrate : constant Keccak_Rate := 1344;
320 Input : Bitstream(1..5) := (1, 1, 0, 0, 1);
321 Output : Bitstream(1..Bitrate*2);
322 Hex : array(0..15) of Character := ("0123456789ABCDEF");
323 HexString : String(1..Bitrate/2);
324 C : Natural;
325 ExpHex : String(1..Bitrate/2);
326 Error : Natural;
327 Pos : Natural;
328 begin
329 ExpHex := "B57B7DAED6330F79BA5783C5D45EABFFA1461FAC6CEA09BD"&
330 "AAC114F17E23E5B349EECBC907E07FA36ECF8374079811E8"&
331 "5E49243D04182C389E68C733BE698468423DB9891D3A7B10"&
332 "320E0356AB4AB916F68C0EA20365A1D4DBA48218CA89CBB8"&
333 "6D08A34E04544D4100FFE9CB138EADC2D3FC0E8CC2BC15A7"&
334 "5B950776970BFC310F33BF609630D73CAD918CF54657589E"&
335 "42CF7CBF20DE677D2AB7E49389F6F6C3B3FE2992905325CE"&
336 "60931C1515043595ADC1619CB7E034EF52BDC485D03B7FDD"&
337 "7345E849FFB4C4426195C8D88C1E7BF9ADA41B92E006C3DA"&
338 "F1ED0FD63ADD9408A3FC815F727457692727637687C1F79D"&
339 "837DE20798E64C878181C02DF56A533F684459E8A03C8EF6"&
340 "234854531110E6CD9BDEFEA85E35C802B1ACDDF29C9332E2"&
341 "53C0FA72F3ED1ABA274838CFE6EF8BD572E89E1C2135F6A7"&
342 "5BC5D6EA4F85C9A757E68E561A56AC0FC19F1F086C43272F";
343
344 Put_Line("---sponge test---");
345 Sponge(Input, Bitrate, Output);
346 Put_Line("Input is:");
347 for I of Input loop
348 Put(Bit'Image(I));
349 end loop;
350 new_line(1);
351
352 Put_Line("Output is:");
353 for I of Output loop
354 Put(Bit'Image(I));
355 end loop;
356 new_line(1);
357
358 Error := 0;
359 for I in 1..Output'Length/4 loop
360 Pos := Output'First + (I-1)*4;
361 C := Natural( Output( Pos ) ) * 8 +
362 Natural( Output( Pos + 1 ) ) * 4 +
363 Natural( Output( Pos + 2 ) ) * 2 +
364 Natural( Output( Pos + 3 ) );
365 Hexstring(I) := Hex(C);
366 if Hexstring(I) /= ExpHex(I) then
367 Error := Error + 1;
368 end if;
369 end loop;
370 Put_Line("Expected: ");
371 Put_Line(ExpHex);
372 Put_Line("Obtained: ");
373 Put_Line(Hexstring);
374 Put_Line("Errors found: " & Natural'Image(Error));
375
376 end test_sponge;
377
378 procedure test_keccak_function(T: in Test_Round) is
379 S: State;
380 begin
381 Put_Line("---Full Keccak Function test---");
382 S := Keccak_Function(T(Round_Index'First)(None));
383 if S /= T(Round_Index'Last)(Iota) then
384 Put_Line("FAILED: full keccak function test");
385 else
386 Put_Line("PASSED: full keccak function test");
387 end if;
388 end test_keccak_function;
389
390 -- end of helper methods
391
392 --variables
(155 . 6)(283 . 9)
394 test_one_round(T(I), I);
395 end loop;
396
397 -- test also Keccak_Function as a whole --
398 test_keccak_function(T);
399
400 Put_Line("-----Testing with non-zero state as input------");
401 if (not read_from_file("testvectorsnonzero.txt", T)) then
402 return;
(165 . 4)(296 . 13)
404 test_one_round(T(I), I);
405 end loop;
406
407 -- test also Keccak_Function as a whole --
408 test_keccak_function(T);
409
410 -- test BitsToWord and WordToBits
411 test_bits_to_word_conversion;
412
413 -- test Sponge construction
414 test_sponge;
415
416 end SMG_Keccak.Test;