-
+ 7503D06B8F87F1CD8A4246A7BAF27BA9431646E65F07FEA64173F24852BE71DC493C3E866D5C16F6723F80C6E6ED1479A46FAC9DEA5FDF02B0387724BDB99E08vtools/src/smg_keccak.ads(0 . 0)(1 . 135)
287 -- S.MG implementation of Keccak-f permutations
288
289 -- (Based on The Keccak Reference, Version 3.0, January 14, 2011, by
290 -- Guido Bertoni, Joan Daemen, Michael Peeters and Gilles Van Assche)
291
292 -- S.MG, 2018
293
294 package SMG_Keccak is
295 pragma Pure(SMG_Keccak); --stateless, no side effects -> can cache calls
296
297 --knobs (can change as per keccak design but fixed here for S.MG purposes)--
298 Keccak_L: constant := 6; --gives keccak z (word) dimension of 2^6=64 and
299 --therefore keccak function 1600 with current
300 --constants (5*5*2^6)
301
302 Default_Bitrate: constant := 1344; --max bits the sponge can eat/spit without
303 --needing to scramble the state
304
305 --constants: dimensions of keccak state and number of rounds
306 XY_Length: constant := 5;
307 Z_Length: constant := 2**Keccak_L;
308 Width: constant := XY_Length * XY_Length * Z_Length;
309 N_Rounds: constant := 12 + 2*Keccak_L;
310
311 --types
312 type XYCoord is mod XY_Length;
313 type ZCoord is mod Z_Length;
314 type Round_Index is mod N_Rounds;
315
316 type ZWord is mod 2**Z_Length; --"lane" in keccak ref
317 type Plane is array(XYCoord) of ZWord; --a "horizontal slice" of keccak state
318 type State is array(XYCoord, XYCoord) of ZWord; --the full keccak state
319
320 type Round_Constants is array(Round_Index) of ZWord; --magic keccak constants
321
322 -- rate can be chosen by caller at each call, between 1 and width of state
323 -- higher rate means sponge "eats" more bits at a time but has fewer bits in
324 -- the "secret" part of the state (i.e. lower capacity)
325 subtype Keccak_Rate is Positive range 1..Width; -- capacity = width - rate
326
327 type Bit is mod 2;
328 type Bitstream is array( Natural range <> ) of Bit; -- any length; message
329 subtype Bitword is Bitstream( 0..Z_Length - 1 ); -- bits of one state "word"
330
331 -- type conversions
332 function BitsToWord( BWord : in Bitword ) return ZWord;
333 function WordToBits( Word : in ZWord ) return Bitword;
334
335 -- flip input octets (i.e. groups of 8 bits)
336 function FlipOctets( BWord : in Bitword ) return Bitword;
337
338 -- public function, the sponge itself
339 -- Keccak sponge structure using Keccak_Function, Pad and a given bitrate;
340 -- Input - the stream of bits to hash (the message)
341 -- Output - a bitstream of desired size for holding output
342 -- Block_Len - the bitrate to use; this is effectively the block length
343 -- for splitting Input AND squeezing output between scrambles
344 procedure Sponge(Input : in Bitstream;
345 Output : out Bitstream;
346 Block_Len : in Keccak_Rate := Default_Bitrate );
347
348 private
349 -- these are internals of the keccak implementation, not meant to be directly
350 -- accessed/used
351
352 -- this will squeeze Block'Length bits out of state S
353 -- NO scramble of state in here!
354 -- NB: make SURE that Block'Length is the correct bitrate for this sponge
355 -- in particular, Block'Length should be a correct bitrate aka LESS than Width
356 procedure SqueezeBlock( Block: out Bitstream; S: in State);
357
358 -- This absorbs into sponge the given block, modifying the state accordingly
359 -- NO scramble of state in here so make sure the whole Block fits in state!
360 -- NB: make SURE that Block'Length is *the correct bitrate* for this sponge
361 -- in particular, Block'Length should be a correct bitrate aka LESS than Width
362 procedure AbsorbBlock( Block: in Bitstream; S: in out State );
363
364 --Keccak magic numbers
365 RC : constant Round_Constants :=
366 (
367 16#0000_0000_0000_0001#,
368 16#0000_0000_0000_8082#,
369 16#8000_0000_0000_808A#,
370 16#8000_0000_8000_8000#,
371 16#0000_0000_0000_808B#,
372 16#0000_0000_8000_0001#,
373 16#8000_0000_8000_8081#,
374 16#8000_0000_0000_8009#,
375 16#0000_0000_0000_008A#,
376 16#0000_0000_0000_0088#,
377 16#0000_0000_8000_8009#,
378 16#0000_0000_8000_000A#,
379 16#0000_0000_8000_808B#,
380 16#8000_0000_0000_008B#,
381 16#8000_0000_0000_8089#,
382 16#8000_0000_0000_8003#,
383 16#8000_0000_0000_8002#,
384 16#8000_0000_0000_0080#,
385 16#0000_0000_0000_800A#,
386 16#8000_0000_8000_000A#,
387 16#8000_0000_8000_8081#,
388 16#8000_0000_0000_8080#,
389 16#0000_0000_8000_0001#,
390 16#8000_0000_8000_8008#
391 );
392
393 --gnat-specific methods to have bit-ops for modular types
394 function Rotate_Left( Value : ZWord;
395 Amount : Natural)
396 return ZWord;
397 pragma Import(Intrinsic, Rotate_Left);
398
399 function Shift_Right( Value : ZWord;
400 Amount : Natural)
401 return ZWord;
402 pragma Import(Intrinsic, Shift_Right);
403
404 function Shift_Left( Value : ZWord;
405 Amount : Natural)
406 return ZWord;
407 pragma Import(Intrinsic, Shift_Left);
408
409 --Keccak transformations of the internal state
410 function Theta ( Input : in State) return State;
411 function Rho ( Input : in State) return State;
412 function Pi ( Input : in State) return State;
413 function Chi ( Input : in State) return State;
414 function Iota ( Round_Const : in ZWord; Input : in State) return State;
415
416 --Keccak function with block width currently 1600 (Width constant above)
417 --this simply applies *all* keccak transformations in the correct order, using
418 -- the keccak magic numbers (round constants) as per keccak reference
419 function Keccak_Function(Input: in State) return State;
420
421 end SMG_Keccak;