-
+ DC5CFF0B04CFAB46A536021938AFCD0649409872771B21800D10175028DF61751AA6E919D9EBD3F07C16327A467510FCF48F02BA5CCB52CF5E989DBF6C5FED0B
smg_comms/src/keccak.ads
(0 . 0)(1 . 135)
650 -- S.MG implementation of Keccak-f permutations
651
652 -- (Based on The Keccak Reference, Version 3.0, January 14, 2011, by
653 -- Guido Bertoni, Joan Daemen, Michael Peeters and Gilles Van Assche)
654
655 -- S.MG, 2018
656
657 package Keccak is
658 pragma Pure(Keccak); --stateless, no side effects -> can cache calls
659
660 --knobs (can change as per keccak design but fixed here for S.MG purposes)--
661 Keccak_L: constant := 6; --gives keccak z (word) dimension of 2^6=64 and
662 --therefore keccak function 1600 with current
663 --constants (5*5*2^6)
664
665 Default_Bitrate: constant := 1344; --max bits the sponge can eat/spit without
666 --needing to scramble the state
667
668 --constants: dimensions of keccak state and number of rounds
669 XY_Length: constant := 5;
670 Z_Length: constant := 2**Keccak_L;
671 Width: constant := XY_Length * XY_Length * Z_Length;
672 N_Rounds: constant := 12 + 2*Keccak_L;
673
674 --types
675 type XYCoord is mod XY_Length;
676 type ZCoord is mod Z_Length;
677 type Round_Index is mod N_Rounds;
678
679 type ZWord is mod 2**Z_Length; --"lane" in keccak ref
680 type Plane is array(XYCoord) of ZWord; --a "horizontal slice" of keccak state
681 type State is array(XYCoord, XYCoord) of ZWord; --the full keccak state
682
683 type Round_Constants is array(Round_Index) of ZWord; --magic keccak constants
684
685 -- rate can be chosen by caller at each call, between 1 and width of state
686 -- higher rate means sponge "eats" more bits at a time but has fewer bits in
687 -- the "secret" part of the state (i.e. lower capacity)
688 subtype Keccak_Rate is Positive range 1..Width; -- capacity = width - rate
689
690 type Bit is mod 2;
691 type Bitstream is array( Natural range <> ) of Bit; -- any length; message
692 subtype Bitword is Bitstream( 0..Z_Length - 1 ); -- bits of one state "word"
693
694 -- type conversions
695 function BitsToWord( BWord : in Bitword ) return ZWord;
696 function WordToBits( Word : in ZWord ) return Bitword;
697
698 -- flip input octets (i.e. groups of 8 bits)
699 function FlipOctets( BWord : in Bitword ) return Bitword;
700
701 -- public function, the sponge itself
702 -- Keccak sponge structure using Keccak_Function, Pad and a given bitrate;
703 -- Input - the stream of bits to hash (the message)
704 -- Output - a bitstream of desired size for holding output
705 -- Block_Len - the bitrate to use; this is effectively the block length
706 -- for splitting Input AND squeezing output between scrambles
707 procedure Sponge(Input : in Bitstream;
708 Output : out Bitstream;
709 Block_Len : in Keccak_Rate := Default_Bitrate );
710
711 private
712 -- these are internals of the keccak implementation, not meant to be directly
713 -- accessed/used
714
715 -- this will squeeze Block'Length bits out of state S
716 -- NO scramble of state in here!
717 -- NB: make SURE that Block'Length is the correct bitrate for this sponge
718 -- specifically: Block'Length should be a correct bitrate aka LESS than Width
719 procedure SqueezeBlock( Block: out Bitstream; S: in State);
720
721 -- This absorbs into sponge the given block, modifying the state accordingly
722 -- NO scramble of state in here so make sure the whole Block fits in state!
723 -- NB: make SURE that Block'Length is *the correct bitrate* for this sponge
724 -- specifically: Block'Length should be a correct bitrate aka LESS than Width
725 procedure AbsorbBlock( Block: in Bitstream; S: in out State );
726
727 --Keccak magic numbers
728 RC : constant Round_Constants :=
729 (
730 16#0000_0000_0000_0001#,
731 16#0000_0000_0000_8082#,
732 16#8000_0000_0000_808A#,
733 16#8000_0000_8000_8000#,
734 16#0000_0000_0000_808B#,
735 16#0000_0000_8000_0001#,
736 16#8000_0000_8000_8081#,
737 16#8000_0000_0000_8009#,
738 16#0000_0000_0000_008A#,
739 16#0000_0000_0000_0088#,
740 16#0000_0000_8000_8009#,
741 16#0000_0000_8000_000A#,
742 16#0000_0000_8000_808B#,
743 16#8000_0000_0000_008B#,
744 16#8000_0000_0000_8089#,
745 16#8000_0000_0000_8003#,
746 16#8000_0000_0000_8002#,
747 16#8000_0000_0000_0080#,
748 16#0000_0000_0000_800A#,
749 16#8000_0000_8000_000A#,
750 16#8000_0000_8000_8081#,
751 16#8000_0000_0000_8080#,
752 16#0000_0000_8000_0001#,
753 16#8000_0000_8000_8008#
754 );
755
756 --gnat-specific methods to have bit-ops for modular types
757 function Rotate_Left( Value : ZWord;
758 Amount : Natural)
759 return ZWord;
760 pragma Import(Intrinsic, Rotate_Left);
761
762 function Shift_Right( Value : ZWord;
763 Amount : Natural)
764 return ZWord;
765 pragma Import(Intrinsic, Shift_Right);
766
767 function Shift_Left( Value : ZWord;
768 Amount : Natural)
769 return ZWord;
770 pragma Import(Intrinsic, Shift_Left);
771
772 --Keccak transformations of the internal state
773 function Theta ( Input : in State) return State;
774 function Rho ( Input : in State) return State;
775 function Pi ( Input : in State) return State;
776 function Chi ( Input : in State) return State;
777 function Iota ( Round_Const : in ZWord; Input : in State) return State;
778
779 --Keccak function with block width currently 1600 (Width constant above)
780 --this simply applies *all* keccak transformations in the correct order,
781 -- using the keccak magic numbers (round constants) as per keccak reference
782 function Keccak_Function(Input: in State) return State;
783
784 end Keccak;