diff -uNr a/eucrypt/smg_keccak/smg_keccak.adb b/eucrypt/smg_keccak/smg_keccak.adb --- a/eucrypt/smg_keccak/smg_keccak.adb 87241e219925cce47cd73892dc728607f14bd01324ba0b08d04db6f2d7f2469958d4c65a5f3c26f2db1857841857dcd3204fdc78238cae3126905bb5a3cecc99 +++ b/eucrypt/smg_keccak/smg_keccak.adb 589991a191e8d120f9338fd279017cad6c04aaace3045c9fcf337ac156c7df9aae8d8d353fa32c08439d005a8cb30d309e957eb26d5a1cb8bea2d4fadd44c8c6 @@ -1,4 +1,5 @@ -- S.MG, 2018 +with System; use System; -- for Bit_Order package body SMG_Keccak is @@ -64,34 +65,58 @@ end Sponge; -- convert from a bitstream of ZWord size to an actual ZWord number - -- first bit of bitstream will be most significant bit of ZWord - function BitsToWord( Bits: in Bitword ) return ZWord is - W: ZWord; - P: Natural; + function BitsToWord( BWord: in Bitword ) return ZWord is + W : ZWord; + Bits: Bitword; begin + -- just copy octets if machine is little endian + -- flip octets if machine is big endian + if Default_Bit_Order = Low_Order_First then + Bits := BWord; + else + Bits := FlipOctets( BWord ); + end if; + -- actual bits to word conversion W := 0; - P := 0; + -- LSB bit order (inside octet) as per Keccak spec for I in reverse Bitword'Range loop - W := W + ZWord( Bits(I) ) * ( 2**P ); - P := P + 1; + W := Shift_Left( W, 1 ) + ZWord( Bits( I ) ); end loop; return W; end BitsToWord; -- convert from a ZWord (lane of state) to a bitstream of ZWord size - -- most significant bit of ZWord will be left most bit of bitstream function WordToBits( Word: in ZWord ) return Bitword is Bits: Bitword := (others => 0); W: ZWord; begin W := Word; - for I in reverse Bitword'Range loop + for I in Bitword'Range loop Bits( I ) := Bit( W mod 2 ); - W := W / 2; + W := Shift_Right( W, 1 ); end loop; + + -- flip octets if machine is big endian + if Default_Bit_Order = High_Order_First then + Bits := FlipOctets( Bits ); + end if; + return Bits; end WordToBits; + -- flip given octets (i.e. groups of 8 bits) + function FlipOctets( BWord : in Bitword ) return Bitword is + Bits : Bitword; + begin + -- copy groups of 8 octets changing their order in the array + -- i.e. 1st octet in BWord becomes last octet in Bits and so on + for I in 0 .. ( Bitword'Length / 8 - 1 ) loop + Bits ( Bits'First + I * 8 .. Bits'First + I * 8 + 7 ) := + BWord( BWord'Last - I * 8 - 7 .. BWord'Last - I * 8); + end loop; + return Bits; + end FlipOctets; + -- helper procedures for sponge absorb/squeeze -- NO scramble here, this will absorb ALL given block, make sure it fits! diff -uNr a/eucrypt/smg_keccak/smg_keccak.ads b/eucrypt/smg_keccak/smg_keccak.ads --- a/eucrypt/smg_keccak/smg_keccak.ads 9356acb04f2091a9a611331387e055bcb8e58e7b28ae7fe4e0562486c802598ad3f24bbc20f05e539a3db6274e75cd02f5a31dac5bb2499f3cf2bf094994ddc0 +++ b/eucrypt/smg_keccak/smg_keccak.ads 63a6a9f8168017265c7ccf9b3d7dffd7c3cd21f529ae88993c3b05e0dcaff9530c68b3420b58f643ff2425f575c66e9e0df19ed25c8a38f56a0d1e713e27b15c @@ -40,8 +40,11 @@ subtype Bitword is Bitstream( 0..Z_Length - 1 ); -- bits of one state "word" -- type conversions - function BitsToWord( Bits: in Bitword ) return ZWord; - function WordToBits( Word: in ZWord ) return Bitword; + function BitsToWord( BWord : in Bitword ) return ZWord; + function WordToBits( Word : in ZWord ) return Bitword; + + -- flip input octets (i.e. groups of 8 bits) + function FlipOctets( BWord : in Bitword ) return Bitword; -- public function, the sponge itself -- Keccak sponge structure using Keccak_Function, Pad and a given bitrate; @@ -109,6 +112,11 @@ return ZWord; pragma Import(Intrinsic, Shift_Right); + function Shift_Left( Value : ZWord; + Amount : Natural) + return ZWord; + pragma Import(Intrinsic, Shift_Left); + --Keccak transformations of the internal state function Theta ( Input : in State) return State; function Rho ( Input : in State) return State; diff -uNr a/eucrypt/smg_keccak/tests/smg_keccak-test.adb b/eucrypt/smg_keccak/tests/smg_keccak-test.adb --- a/eucrypt/smg_keccak/tests/smg_keccak-test.adb b91e0448a3d5ec419c7e47701e8a3bfc53082601b860ac093edd13606c093d1c6f112f514a8a90c0825713b45b5c273145d67d90d291631d6aaf940300df9386 +++ b/eucrypt/smg_keccak/tests/smg_keccak-test.adb f90807132cf1ad922f6b901a4cd35190646baad554e0cbae71c570909af0025260ded9bd163657917af4b08f5b29aeb704076d4f5949d8f6b1d14f60c837800b @@ -164,7 +164,7 @@ expected: ZWord; obtained: ZWord; begin - expected := 16#E7DDE140798F25F1#; + expected := 16#8FA4F19E0287BBE7#; 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, 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, 1,1,1,1, 0,0,0,1); @@ -196,32 +196,77 @@ end if; end test_bits_to_word_conversion; + procedure test_flip is + B: constant Bitword := (1, 0, 1, 1, 1, 1, 0, 0, + 1, 1, 1, 0, 0, 0, 0, 1, + 0, 1, 1, 0, 0, 0, 1, 0, + 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 0, 1, 1, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 1, 0, 0, 0); + Expected: Bitword := (0, 0, 0, 1, 1, 0, 0, 0, + 0, 0, 1, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 0, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, + 0, 1, 1, 0, 0, 0, 1, 0, + 1, 1, 1, 0, 0, 0, 0, 1, + 1, 0, 1, 1, 1, 1, 0, 0); + Output : Bitword; + begin + Output := FlipOctets( B ); + if Output /= Expected then + Put_Line( "FAILED: flip octets" ); + Put_Line( "Expected: " ); + for I of Expected loop + Put(Bit'Image(I)); + end loop; + new_line(1); + Put_Line( "Output: " ); + for I of Output loop + Put(Bit'Image(I)); + end loop; + new_line(1); + else + Put_Line( "PASSED: flip octets" ); + end if; + end test_flip; + procedure test_sponge is Bitrate : constant Keccak_Rate := 1344; Input : Bitstream(1..5) := (1, 1, 0, 0, 1); - Output : Bitstream(1..Bitrate*2); Hex : array(0..15) of Character := ("0123456789ABCDEF"); - HexString : String(1..Bitrate/2); C : Natural; - ExpHex : String(1..Bitrate/2); + HexPos : Natural; Error : Natural; Pos : Natural; + ExpHex : constant String := + "CB7FFB7CE7572A06C537858A0090FC2888C3C6BA9A3ADAB4"& + "FE7C9AB4EFE7A1E619B834C843A5A79E23F3F7E314AA597D"& + "9DAD376E8413A005984D00CF954F62F59EF30B050C99EA64"& + "E958335DAE684195D439B6E6DFD0E402518B5E7A227C48CF"& + "239CEA1C391241D7605733A9F4B8F3FFBE74EE45A40730ED"& + "1E2FDEFCCA941F518708CBB5B6D5A69C30263267B97D7B29"& + "AC87043880AE43033B1017EFB75C33248E2962892CE69DA8"& + "BAF1DF4C0902B16C64A1ADD42FF458C94C4D3B0B32711BBA"& + "22104989982543D1EF1661AFAF2573687D588C81113ED7FA"& + "F7DDF912021FC03D0E98ACC0200A9F7A0E9629DBA33BA0A3"& + "C03CCA5A7D3560A6DB589422AC64882EF14A62AD9807B353"& + "8DEE1548194DBD456F92B568CE76827F41E0FB3C7F25F3A4"& + "C707AD825B289730FEBDFD22A3E742C6FB7125DE0E38B130"& + "F3059450CA6185156A7EEE2AB7C8E4709956DC6D5E9F99D5"& + "0A19473EA7D737AC934815D68C0710235483DB8551FD8756"& + "45692B4E5E16BB9B1142AE300F5F69F43F0091D534F372E1"& + "FFC2E522E71003E4D27EF6ACCD36B2756FB5FF02DBF0C96B"& + "CAE68E7D6427810582F87051590F6FB65D7B948A9C9D6C93"& + "AF4562367A0AD79109D6F3087C775FE6D60D66B74F8D29FB"& + "4BA80D0168693A748812EA0CD3CA23854CC84D4E716F4C1A"& + "A3B340B1DED2F304DFDBACC1D792C8AC9A1426913E3F67DB"& + "790FD5CFB77DAA29"; + Output : Bitstream( 1 .. ExpHex'Length * 4 ); + HexString : String( 1 .. ExpHex'Length ); begin - ExpHex := "B57B7DAED6330F79BA5783C5D45EABFFA1461FAC6CEA09BD"& - "AAC114F17E23E5B349EECBC907E07FA36ECF8374079811E8"& - "5E49243D04182C389E68C733BE698468423DB9891D3A7B10"& - "320E0356AB4AB916F68C0EA20365A1D4DBA48218CA89CBB8"& - "6D08A34E04544D4100FFE9CB138EADC2D3FC0E8CC2BC15A7"& - "5B950776970BFC310F33BF609630D73CAD918CF54657589E"& - "42CF7CBF20DE677D2AB7E49389F6F6C3B3FE2992905325CE"& - "60931C1515043595ADC1619CB7E034EF52BDC485D03B7FDD"& - "7345E849FFB4C4426195C8D88C1E7BF9ADA41B92E006C3DA"& - "F1ED0FD63ADD9408A3FC815F727457692727637687C1F79D"& - "837DE20798E64C878181C02DF56A533F684459E8A03C8EF6"& - "234854531110E6CD9BDEFEA85E35C802B1ACDDF29C9332E2"& - "53C0FA72F3ED1ABA274838CFE6EF8BD572E89E1C2135F6A7"& - "5BC5D6EA4F85C9A757E68E561A56AC0FC19F1F086C43272F"; - Put_Line("---sponge test---"); Sponge(Input, Bitrate, Output); Put_Line("Input is:"); @@ -239,12 +284,13 @@ Error := 0; for I in 1..Output'Length/4 loop Pos := Output'First + (I-1)*4; - C := Natural( Output( Pos ) ) * 8 + - Natural( Output( Pos + 1 ) ) * 4 + - Natural( Output( Pos + 2 ) ) * 2 + - Natural( Output( Pos + 3 ) ); - Hexstring(I) := Hex(C); - if Hexstring(I) /= ExpHex(I) then + C := Natural( Output( Pos ) ) + + Natural( Output( Pos + 1 ) ) * 2 + + Natural( Output( Pos + 2 ) ) * 4 + + Natural( Output( Pos + 3 ) ) * 8; + HexPos := I + 2 * ( I mod 2 ) - 1; + Hexstring(HexPos) := Hex( C ); + if Hexstring(HexPos) /= ExpHex(HexPos) then Error := Error + 1; end if; end loop; @@ -305,4 +351,7 @@ -- test Sponge construction test_sponge; + -- test flipping octets + test_flip; + end SMG_Keccak.Test;