diff --git a/src/abstraction/block_cipher_generic.ads b/src/abstraction/block_cipher_generic.ads new file mode 100644 index 0000000..2f1d593 --- /dev/null +++ b/src/abstraction/block_cipher_generic.ads @@ -0,0 +1,49 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; + +generic + + Name_Intern : String; + + type Context_T_Intern is private; + + Block_Size_Bits_Intern : Natural; + Key_Size_Bits_Intern : Natural; + + with procedure Initialize_Intern(Context : out Context_T_Intern; Key : in u8_Array); + with procedure Encrypt_Intern(Context : in Context_T_Intern; Block : in out u8_Array); + with procedure Decrypt_Intern(Context : in Context_T_Intern; Block : in out u8_Array); + +package Block_Cipher_Generic is + + Name : String renames Name_Intern; + + subtype Context_T is Context_T_Intern; + + Block_Size_Bits : Natural renames Block_Size_Bits_Intern; + Key_Size_Bits : Natural renames Key_Size_Bits_Intern; + + Block_Size_Bytes : Natural := (Block_Size_Bits) / 8; + Key_Size_Bytes : Natural := (Key_Size_Bits) / 8; + + procedure Initialize(Context : out Context_T_Intern; Key : in u8_Array) renames Initialize_Intern; + procedure Encrypt(Context : in Context_T_Intern; Block : in out u8_Array) renames Encrypt_Intern; + procedure Decrypt(Context : in Context_T_Intern; Block : in out u8_Array) renames Decrypt_Intern; + +private + +end Block_Cipher_Generic; diff --git a/src/abstraction/hash_generic.adb b/src/abstraction/hash_generic.adb new file mode 100644 index 0000000..3bd3338 --- /dev/null +++ b/src/abstraction/hash_generic.adb @@ -0,0 +1,36 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +package body Hash_Generic is + + procedure Hash(Data : in u8_Array; Digest : out u8_Array; Bits : in Integer := -1) is + Context : Context_T_Intern; + Counter : Natural := Data'Length * 8; + Index : Integer := Data'First; + begin + if Bits >= 0 then + Counter := Bits; + end if; + Initialize(Context); + while Counter > Block_Size_Bits loop + Next_Block(Context, Data(Index .. Index + Block_Size_Bytes - 1)); + Index := Index + Block_Size_Bytes; + Counter := Counter - Block_Size_Bits; + end loop; + Last_Block(Context, Data(Index .. Data'Last), Counter); + Get_Digest(Context, Digest); + end; + +end Hash_Generic; diff --git a/src/abstraction/hash_generic.ads b/src/abstraction/hash_generic.ads new file mode 100644 index 0000000..295e8ae --- /dev/null +++ b/src/abstraction/hash_generic.ads @@ -0,0 +1,53 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; + +generic + + Name_Intern : String; + + type Context_T_Intern is private; + + Block_Size_Bits_Intern : Natural; + Digest_Size_Bits_Intern : Natural; + + with procedure Initialize_Intern(Context : out Context_T_Intern); + with procedure Next_Block_Intern(Context : in out Context_T_Intern; Block : in u8_Array); + with procedure Last_Block_Intern(Context : in out Context_T_Intern; Block : in u8_Array; Bits : in Integer := -1); + with procedure Get_Digest_Intern(Context : in out Context_T_Intern; Digest : out u8_Array); + +package Hash_Generic is + + Name : String renames Name_Intern; + + subtype Context_T is Context_T_Intern; + + Block_Size_Bits : Natural renames Block_Size_Bits_Intern; + Digest_Size_Bits : Natural renames Digest_Size_Bits_Intern; + + Block_Size_Bytes : Natural := (Block_Size_Bits) / 8; + Digest_Size_Bytes : Natural := (Digest_Size_Bits) / 8; + + procedure Initialize(Context : out Context_T_Intern) renames Initialize_Intern; + procedure Next_Block(Context : in out Context_T_Intern; Block : in u8_Array) renames Next_Block_Intern; + procedure Last_Block(Context : in out Context_T_Intern; Block : in u8_Array; Bits : in Integer := -1) renames Last_Block_Intern; + procedure Get_Digest(Context : in out Context_T_Intern; Digest : out u8_Array) renames Get_Digest_Intern; + + procedure Hash(Data : in u8_Array; Digest : out u8_Array; Bits : in Integer := -1); + +private + +end Hash_Generic; diff --git a/src/algorithms/aes/aes.ads b/src/algorithms/aes/aes.ads index dcd3ea6..e1145a6 100644 --- a/src/algorithms/aes/aes.ads +++ b/src/algorithms/aes/aes.ads @@ -13,58 +13,37 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . +with Block_Cipher_Generic; with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; +with AES_Spec; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; package AES is - subtype Key_128_T is Block_128_Bit; - subtype Key_192_T is Block_192_Bit; - subtype Key_256_T is Block_256_Bit; + package AES_128 is new Block_Cipher_Generic( Name_Intern => "AES-128", + Context_T_Intern => AES_Spec.Context_128_T, + Block_Size_Bits_Intern => 128, + Key_Size_Bits_Intern => 128, + Initialize_Intern => AES_Spec.Initialize, + Encrypt_Intern => AES_Spec.Encrypt, + Decrypt_Intern => AES_Spec.Decrypt ); - type Context_128_T is private; - type Context_192_T is private; - type Context_256_T is private; + package AES_192 is new Block_Cipher_Generic( Name_Intern => "AES-192", + Context_T_Intern => AES_Spec.Context_192_T, + Block_Size_Bits_Intern => 128, + Key_Size_Bits_Intern => 192, + Initialize_Intern => AES_Spec.Initialize, + Encrypt_Intern => AES_Spec.Encrypt, + Decrypt_Intern => AES_Spec.Decrypt ); - subtype Block_T is Block_128_Bit; - - procedure Initialize(Context : out Context_128_T; Key : in Key_128_T); - procedure Encrypt(Context : in Context_128_T; Block: in out Block_T); - procedure Decrypt(Context : in Context_128_T; Block: in out Block_T); - - - procedure Initialize(Context : out Context_192_T; Key : in Key_192_T); - procedure Encrypt(Context : in Context_192_T; Block: in out Block_T); - procedure Decrypt(Context : in Context_192_T; Block: in out Block_T); - - procedure Initialize(Context : out Context_256_T; Key : in Key_256_T); - procedure Encrypt(Context : in Context_256_T; Block: in out Block_T); - procedure Decrypt(Context : in Context_256_T; Block: in out Block_T); - -private - - subtype RoundKey_T is Block_128_Bit; - type RoundKeys_T is Array (Integer range <>) of RoundKey_T; - - subtype Num_RoundKeys_T is Integer range 11 .. 15; - - type Context_T(Num_RoundKeys : Num_RoundKeys_T := 15) is record - RoundKeys : RoundKeys_T(1 .. Num_RoundKeys); - end record; - - type Context_128_T is new Context_T(11); - type Context_192_T is new Context_T(13); - type Context_256_T is new Context_T(15); - - Nb : constant Integer := 4; - polynom : constant u8 := 16#1B#; - function gf256mul(a, b : u8) return u8; - - generic - type T_In(<>) is new u8_Array; - type T_Out(<>) is new Context_T; - procedure Initialize_Generic(Key : T_In; Context : out T_Out); + package AES_256 is new Block_Cipher_Generic( Name_Intern => "AES-256", + Context_T_Intern => AES_Spec.Context_256_T, + Block_Size_Bits_Intern => 128, + Key_Size_Bits_Intern => 256, + Initialize_Intern => AES_Spec.Initialize, + Encrypt_Intern => AES_Spec.Encrypt, + Decrypt_Intern => AES_Spec.Decrypt ); end AES; diff --git a/src/algorithms/aes/aes.adb b/src/algorithms/aes/aes_spec.adb similarity index 99% rename from src/algorithms/aes/aes.adb rename to src/algorithms/aes/aes_spec.adb index e731998..df2ca60 100644 --- a/src/algorithms/aes/aes.adb +++ b/src/algorithms/aes/aes_spec.adb @@ -13,7 +13,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -package body AES is +package body AES_Spec is Sbox : constant array (u8 range 0 .. 255) of u8 := ( 16#63#, 16#7c#, 16#77#, 16#7b#, 16#f2#, 16#6b#, 16#6f#, 16#c5#, 16#30#, 16#01#, 16#67#, 16#2b#, 16#fe#, 16#d7#, 16#ab#, 16#76#, @@ -275,4 +275,4 @@ package body AES is Decrypt_Generic(Context_T(Context), Block); end Decrypt; -end AES; +end AES_Spec; diff --git a/src/algorithms/aes/aes_spec.ads b/src/algorithms/aes/aes_spec.ads new file mode 100644 index 0000000..f800e48 --- /dev/null +++ b/src/algorithms/aes/aes_spec.ads @@ -0,0 +1,70 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; + +use Crypto_Types.Crypto_Utils_u8; + +package AES_Spec is + + subtype Key_128_T is Block_128_Bit; + subtype Key_192_T is Block_192_Bit; + subtype Key_256_T is Block_256_Bit; + + type Context_128_T is private; + type Context_192_T is private; + type Context_256_T is private; + + subtype Block_T is Block_128_Bit; + + procedure Initialize(Context : out Context_128_T; Key : in Key_128_T); + procedure Encrypt(Context : in Context_128_T; Block: in out Block_T); + procedure Decrypt(Context : in Context_128_T; Block: in out Block_T); + + + procedure Initialize(Context : out Context_192_T; Key : in Key_192_T); + procedure Encrypt(Context : in Context_192_T; Block: in out Block_T); + procedure Decrypt(Context : in Context_192_T; Block: in out Block_T); + + procedure Initialize(Context : out Context_256_T; Key : in Key_256_T); + procedure Encrypt(Context : in Context_256_T; Block: in out Block_T); + procedure Decrypt(Context : in Context_256_T; Block: in out Block_T); + +private + + subtype RoundKey_T is Block_128_Bit; + type RoundKeys_T is Array (Integer range <>) of RoundKey_T; + + subtype Num_RoundKeys_T is Integer range 11 .. 15; + + type Context_T(Num_RoundKeys : Num_RoundKeys_T := 15) is record + RoundKeys : RoundKeys_T(1 .. Num_RoundKeys); + end record; + + type Context_128_T is new Context_T(11); + type Context_192_T is new Context_T(13); + type Context_256_T is new Context_T(15); + + Nb : constant Integer := 4; + polynom : constant u8 := 16#1B#; + function gf256mul(a, b : u8) return u8; + + generic + type T_In(<>) is new u8_Array; + type T_Out(<>) is new Context_T; + procedure Initialize_Generic(Key : T_In; Context : out T_Out); + +end AES_Spec; diff --git a/src/algorithms/aria/aria.ads b/src/algorithms/aria/aria.ads index c807afb..aa27ca4 100644 --- a/src/algorithms/aria/aria.ads +++ b/src/algorithms/aria/aria.ads @@ -13,40 +13,37 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . +with Block_Cipher_Generic; with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; +with ARIA_Spec; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; package ARIA is - type Key_128 is new Block_128_Bit; - type Key_192 is new Block_192_Bit; - type Key_256 is new Block_256_Bit; + package ARIA_128 is new Block_Cipher_Generic( Name_Intern => "ARIA-128", + Context_T_Intern => ARIA_Spec.Context_T, + Block_Size_Bits_Intern => 128, + Key_Size_Bits_Intern => 128, + Initialize_Intern => ARIA_Spec.Initialize, + Encrypt_Intern => ARIA_Spec.Encrypt, + Decrypt_Intern => ARIA_Spec.Decrypt ); - type Context_T is private; + package ARIA_192 is new Block_Cipher_Generic( Name_Intern => "ARIA-192", + Context_T_Intern => ARIA_Spec.Context_T, + Block_Size_Bits_Intern => 128, + Key_Size_Bits_Intern => 192, + Initialize_Intern => ARIA_Spec.Initialize, + Encrypt_Intern => ARIA_Spec.Encrypt, + Decrypt_Intern => ARIA_Spec.Decrypt ); - type Plaintext is new Block_128_Bit; - type Ciphertext is new Block_128_Bit; - - - - procedure Initialize(Context : out Context_T; Key : in Key_128); - procedure Initialize(Context : out Context_T; Key : in Key_192); - procedure Initialize(Context : out Context_T; Key : in Key_256); - procedure Encrypt(Context : in Context_T; Block: in out Block_128_Bit); - procedure Decrypt(Context : in Context_T; Block: in out Block_128_Bit); - - -private - - type PreKey_T is new Block_128_Bit; - type PreKeys_T is Array (1 .. 4) of PreKey_T; - type Num_Rounds is range 1 .. 16; - - type Context_T is record - W : PreKeys_T; - Rounds : Num_Rounds; - end record; + package ARIA_256 is new Block_Cipher_Generic( Name_Intern => "ARIA-256", + Context_T_Intern => ARIA_Spec.Context_T, + Block_Size_Bits_Intern => 128, + Key_Size_Bits_Intern => 256, + Initialize_Intern => ARIA_Spec.Initialize, + Encrypt_Intern => ARIA_Spec.Encrypt, + Decrypt_Intern => ARIA_Spec.Decrypt ); end ARIA; diff --git a/src/algorithms/aria/aria.adb b/src/algorithms/aria/aria_spec.adb similarity index 96% rename from src/algorithms/aria/aria.adb rename to src/algorithms/aria/aria_spec.adb index f503521..6221093 100644 --- a/src/algorithms/aria/aria.adb +++ b/src/algorithms/aria/aria_spec.adb @@ -13,7 +13,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -package body ARIA is +package body ARIA_Spec is SBox : constant array (Integer range 1 .. 4, u8 range 0 .. 255) of u8 := ( ( 16#63#, 16#7c#, 16#77#, 16#7b#, 16#f2#, 16#6b#, 16#6f#, 16#c5#, 16#30#, 16#01#, 16#67#, 16#2b#, 16#fe#, 16#d7#, 16#ab#, 16#76#, @@ -157,7 +157,7 @@ package body ARIA is A(Block); end F_Even; - procedure Initialize(Key : in u8_Array; Context : out Context_T) is + procedure Initialize(Context : out Context_T; Key : in u8_Array) is C_Select : Array (1 .. 3) of Natural range 1 .. 3; begin case Key'Length is @@ -170,7 +170,7 @@ package body ARIA is when 32 => C_Select := (3, 1, 2); Context.Rounds := 16; - when others => raise Constraint_Error; + when others => raise Invalid_Key_Size; end case; Context.W(1) := PreKey_T(Key(1 .. 16)); Context.W(2) := Context.W(1); @@ -189,21 +189,6 @@ package body ARIA is Context.W(4) := PreKey_T(u8_Array(Context.W(4)) xor u8_Array(Context.W(2))); end Initialize; - procedure Initialize(Context : out Context_T; Key : in Key_128) is - begin - Initialize(u8_Array(Key), Context); - end Initialize; - - procedure Initialize(Context : out Context_T; Key : in Key_192) is - begin - Initialize(u8_Array(Key), Context); - end Initialize; - - procedure Initialize(Context : out Context_T; Key : in Key_256) is - begin - Initialize(u8_Array(Key), Context); - end Initialize; - procedure Encrypt(Context : in Context_T; Block: in out Block_128_Bit) is temp_key : Block_128_Bit; n : Integer; @@ -254,4 +239,4 @@ package body ARIA is end Decrypt; -end ARIA; +end ARIA_Spec; diff --git a/src/algorithms/aria/aria_spec.ads b/src/algorithms/aria/aria_spec.ads new file mode 100644 index 0000000..2bea61f --- /dev/null +++ b/src/algorithms/aria/aria_spec.ads @@ -0,0 +1,50 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; + +use Crypto_Types.Crypto_Utils_u8; + +package ARIA_Spec is + + subtype Key_128 is Block_128_Bit; + subtype Key_192 is Block_192_Bit; + subtype Key_256 is Block_256_Bit; + + type Context_T is private; + + type Plaintext is new Block_128_Bit; + type Ciphertext is new Block_128_Bit; + + + + procedure Initialize(Context : out Context_T; Key : in u8_Array); + procedure Encrypt(Context : in Context_T; Block: in out Block_128_Bit); + procedure Decrypt(Context : in Context_T; Block: in out Block_128_Bit); + + +private + + type PreKey_T is new Block_128_Bit; + type PreKeys_T is Array (1 .. 4) of PreKey_T; + type Num_Rounds is range 1 .. 16; + + type Context_T is record + W : PreKeys_T; + Rounds : Num_Rounds; + end record; + +end ARIA_Spec; diff --git a/src/algorithms/des/des.ads b/src/algorithms/des/des.ads index aec8eff..f3fe1a2 100644 --- a/src/algorithms/des/des.ads +++ b/src/algorithms/des/des.ads @@ -13,27 +13,18 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . +with Block_Cipher_Generic; with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; +with DES_Spec; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u32; +use Crypto_Types.Crypto_Utils_u8; -package DES is + package DES is new Block_Cipher_Generic( Name_Intern => "DES", + Context_T_Intern => DES_Spec.Context_T, + Block_Size_Bits_Intern => 64, + Key_Size_Bits_Intern => 64, + Initialize_Intern => DES_Spec.Initialize, + Encrypt_Intern => DES_Spec.Encrypt, + Decrypt_Intern => DES_Spec.Decrypt ); - type Context_T is private; - - subtype Key_T is Block_64_Bit; - subtype Block_T is Block_64_Bit; - - procedure Initialize(Context : out Context_T; Key : in Key_T); - procedure Encrypt(Context : in Context_T; Block: in out Block_64_Bit); - procedure Decrypt(Context : in Context_T; Block: in out Block_64_Bit); - -private - type Context_T is record - Key : Block_56_Bit; - end record; - - -end DES; diff --git a/src/algorithms/des/des.adb b/src/algorithms/des/des_spec.adb similarity index 99% rename from src/algorithms/des/des.adb rename to src/algorithms/des/des_spec.adb index db04d91..9b764c6 100644 --- a/src/algorithms/des/des.adb +++ b/src/algorithms/des/des_spec.adb @@ -15,7 +15,7 @@ with System; -package body DES is +package body DES_Spec is function SBox(X : Block_48_Bit) return Block_32_Bit is function Map_To_Index(X : u8) return u8 is @@ -321,4 +321,4 @@ package body DES is end; -end DES; +end DES_Spec; diff --git a/src/algorithms/des/des_spec.ads b/src/algorithms/des/des_spec.ads new file mode 100644 index 0000000..e0dffde --- /dev/null +++ b/src/algorithms/des/des_spec.ads @@ -0,0 +1,39 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; + +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u32; + +package DES_Spec is + + type Context_T is private; + + subtype Key_T is Block_64_Bit; + subtype Block_T is Block_64_Bit; + + procedure Initialize(Context : out Context_T; Key : in Key_T); + procedure Encrypt(Context : in Context_T; Block: in out Block_64_Bit); + procedure Decrypt(Context : in Context_T; Block: in out Block_64_Bit); + +private + type Context_T is record + Key : Block_56_Bit; + end record; + + +end DES_Spec; diff --git a/src/algorithms/des/tdes.ads b/src/algorithms/des/tdes.ads index 2ee38d5..b60b75f 100644 --- a/src/algorithms/des/tdes.ads +++ b/src/algorithms/des/tdes.ads @@ -13,31 +13,29 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . +with Block_Cipher_Generic; with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; +with TDES_Spec; -with DES; - -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u32; +use Crypto_Types.Crypto_Utils_u8; package TDES is - type Context_T is private; + package TDES_Two_Key is new Block_Cipher_Generic( Name_Intern => "Triple-DES (two keys)", + Context_T_Intern => TDES_Spec.Context_T, + Block_Size_Bits_Intern => 64, + Key_Size_Bits_Intern => 128, + Initialize_Intern => TDES_Spec.Initialize, + Encrypt_Intern => TDES_Spec.Encrypt, + Decrypt_Intern => TDES_Spec.Decrypt ); - subtype Key_128_T is Block_128_Bit; - subtype Key_192_T is Block_192_Bit; - subtype Block_T is Block_64_Bit; - - procedure Initialize(Context : out Context_T; Key : in u8_Array); - procedure Encrypt(Context : in Context_T; Block: in out Block_64_Bit); - procedure Decrypt(Context : in Context_T; Block: in out Block_64_Bit); - -private - type Context_T is record - Ctx1 : DES.Context_T; - Ctx2 : DES.Context_T; - Ctx3 : DES.Context_T; - end record; + package TDES_Three_Key is new Block_Cipher_Generic( Name_Intern => "Triple-DES (three keys)", + Context_T_Intern => TDES_Spec.Context_T, + Block_Size_Bits_Intern => 64, + Key_Size_Bits_Intern => 192, + Initialize_Intern => TDES_Spec.Initialize, + Encrypt_Intern => TDES_Spec.Encrypt, + Decrypt_Intern => TDES_Spec.Decrypt ); end TDES; diff --git a/src/algorithms/des/tdes.adb b/src/algorithms/des/tdes_spec.adb similarity index 58% rename from src/algorithms/des/tdes.adb rename to src/algorithms/des/tdes_spec.adb index f938134..7c3079d 100644 --- a/src/algorithms/des/tdes.adb +++ b/src/algorithms/des/tdes_spec.adb @@ -13,18 +13,18 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -package body TDES is +package body TDES_Spec is procedure Initialize(Context : out Context_T; Key : in u8_Array) is begin if Key'Length = 16 then - DES.Initialize(Context.Ctx1, Key(Key'First + 0 .. Key'First + 7)); - DES.Initialize(Context.Ctx2, Key(Key'First + 8 .. Key'First + 15)); - DES.Initialize(Context.Ctx3, Key(Key'First + 0 .. Key'First + 7)); + DES_Spec.Initialize(Context.Ctx1, Key(Key'First + 0 .. Key'First + 7)); + DES_Spec.Initialize(Context.Ctx2, Key(Key'First + 8 .. Key'First + 15)); + DES_Spec.Initialize(Context.Ctx3, Key(Key'First + 0 .. Key'First + 7)); elsif Key'Length = 24 then - DES.Initialize(Context.Ctx1, Key(Key'First + 0 .. Key'First + 7)); - DES.Initialize(Context.Ctx2, Key(Key'First + 8 .. Key'First + 15)); - DES.Initialize(Context.Ctx3, Key(Key'First + 16 .. Key'First + 23)); + DES_Spec.Initialize(Context.Ctx1, Key(Key'First + 0 .. Key'First + 7)); + DES_Spec.Initialize(Context.Ctx2, Key(Key'First + 8 .. Key'First + 15)); + DES_Spec.Initialize(Context.Ctx3, Key(Key'First + 16 .. Key'First + 23)); else raise Invalid_Key_Size; end if; @@ -32,16 +32,16 @@ package body TDES is procedure Encrypt(Context : in Context_T; Block: in out Block_64_Bit) is begin - DES.Encrypt(Context.Ctx1, Block); - DES.Decrypt(Context.Ctx2, Block); - DES.Encrypt(Context.Ctx3, Block); + DES_Spec.Encrypt(Context.Ctx1, Block); + DES_Spec.Decrypt(Context.Ctx2, Block); + DES_Spec.Encrypt(Context.Ctx3, Block); end Encrypt; procedure Decrypt(Context : in Context_T; Block: in out Block_64_Bit) is begin - DES.Decrypt(Context.Ctx3, Block); - DES.Encrypt(Context.Ctx2, Block); - DES.Decrypt(Context.Ctx1, Block); + DES_Spec.Decrypt(Context.Ctx3, Block); + DES_Spec.Encrypt(Context.Ctx2, Block); + DES_Spec.Decrypt(Context.Ctx1, Block); end Decrypt; -end TDES; +end TDES_Spec; diff --git a/src/algorithms/des/tdes_spec.ads b/src/algorithms/des/tdes_spec.ads new file mode 100644 index 0000000..756f89c --- /dev/null +++ b/src/algorithms/des/tdes_spec.ads @@ -0,0 +1,43 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; + +with DES_Spec; + +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u32; + +package TDES_Spec is + + type Context_T is private; + + subtype Key_128_T is Block_128_Bit; + subtype Key_192_T is Block_192_Bit; + subtype Block_T is Block_64_Bit; + + procedure Initialize(Context : out Context_T; Key : in u8_Array); + procedure Encrypt(Context : in Context_T; Block: in out Block_64_Bit); + procedure Decrypt(Context : in Context_T; Block: in out Block_64_Bit); + +private + type Context_T is record + Ctx1 : DES_Spec.Context_T; + Ctx2 : DES_Spec.Context_T; + Ctx3 : DES_Spec.Context_T; + end record; + +end TDES_Spec; diff --git a/src/algorithms/gcm/gcm128_spec.adb b/src/algorithms/gcm/gcm128_spec.adb new file mode 100644 index 0000000..51b8bc6 --- /dev/null +++ b/src/algorithms/gcm/gcm128_spec.adb @@ -0,0 +1,202 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Types; use Crypto_Types; +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u32; +use Crypto_Types.Crypto_Utils_u64; +with System; use System; + +with Ada.Text_IO; use Ada.Text_IO; + +package body GCM128_Spec is + + function GFmul(X,Y : Block_128_Bit) return Block_128_Bit is + Mask : constant array(Bit) of u8 := (0, 2#1110_0001#); + V : array (Bit) of Block_128_Bit := ( (others => 0), Y); + Z : Block_128_Bit := (others => 0); + Temp : Bit; + begin + for i in 0 .. 127 loop + Z := Z xor V(Bit_Get(X, i, High_Order_First)); + Temp := Bit_Get(V(1), 127, High_Order_First); + V(1) := Shift_be(V(1), -1); + V(1)(1) := V(1)(1) xor Mask(Temp); + end loop; + return Z; + end GFmul; + + function GHash(Key : in Block_128_Bit; Data : in u8_Array; Seed : Block_128_Bit := (others => 0)) return Block_128_Bit is + A : Block_128_Bit := Seed; + Index : Integer := Data'First; + Length : Integer := Data'Length * 8; + begin + -- for each complete block + for i in 1 .. Length / Block_Size_Bits loop + A := A xor Data(Index .. Index + Block_Size_Bytes - 1); + Index := Index + Block_Size_Bytes; + Length := Length - Block_Size_Bits; + A := GFmul(A, Key); + end loop; + if Length > 0 then + A(1 .. Length / 8) := A(1 .. Length / 8) xor Data(Index .. Index + Length / 8 - 1); + if Length mod 8 /= 0 then + A(Length / 8 + 1) := A(Length / 8 + 1) xor (Data(Index + Length / 8) and not Shift_Right(u8'(16#FF#), Length mod 8)); + end if; + A := GFmul(A, Key); + end if; + return A; + end; + + procedure Inc_32(A : in out Block_128_Bit) is + c : u32; + begin + c := Load_be(A(13 .. 16)); + c := c + 1; + Store_be(A(13 .. 16), c); + end Inc_32; + + procedure Initialize(Context : out Context_T; Key : in u8_Array; IV : in u8_Array) is + begin + Cipher.Initialize(Context.Cipher_Ctx, Key); + Context.Header_Length := 0; + Context.Plaintext_Length := 0; + Context.Y := (others => 0); + Context.H := (others => 0); + Cipher.Encrypt(Context.Cipher_Ctx, Context.H); + if IV'Length = 96 / 8 then + Context.J0( 1 .. 12) := IV; + Context.J0(13 .. 16) := (0, 0, 0, 1); + else + declare + IV_Length_Block : Block_64_Bit; + begin + Context.J0 := GHash(Context.H, IV); + Store_be(IV_Length_Block, u64(IV'Length * 8)); + Context.J0(9 .. 16) := Context.J0(9 .. 16) xor IV_Length_Block; + Context.J0 := GHash(Context.H, Context.J0); + end; + end if; + Context.ICB := Context.J0; + -- encrypt J0 for final XOR on tag + Cipher.Encrypt(Context.Cipher_Ctx, Context.J0); + end Initialize; + + procedure Header_Next_Block(Context : in out Context_T; Header : in u8_Array) is + begin + if Header'Length mod Block_Size_Bytes /= 0 then + raise Format_Violation; + end if; + Context.Y := GHash(Context.H, Header, Seed => Context.Y); + Context.Header_Length := Context.Header_Length + Header'Length * 8; + end; + + procedure Header_Last_Block(Context : in out Context_T; Header : in u8_Array) is + begin + Context.Y := GHash(Context.H, Header, Seed => Context.Y); + Context.Header_Length := Context.Header_Length + Header'Length * 8; + end; + + procedure Encrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array) is + Temp : Block_128_Bit; + begin + if Block'Length /= Block_Size_Bytes then + raise Format_Violation; + end if; + Inc_32(Context.ICB); + Temp := Context.ICB; + Cipher.Encrypt(Context.Cipher_Ctx, Temp); + Block := Block xor Temp; + Context.Y := GHash(Context.H, Block, Seed => Context.Y); + Context.Plaintext_Length := Context.Plaintext_Length + u64(Block_Size_Bits); + end; + + procedure Encrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array) is + Length : Integer := Block'Length * 8; + Index : Integer := Block'First; + Temp : Block_128_Bit := (others => 0); + Fin_Block : Block_128_Bit; + begin + while Length >= Block_Size_Bits loop + Encrypt_Next_Block(Context, Block(Index .. Index + Block_Size_Bytes - 1)); + Length := Length - Block_Size_Bits; + Index := Index + Block_Size_Bytes; + end loop; + if Length > 0 then + Inc_32(Context.ICB); + Temp := Context.ICB; + Cipher.Encrypt(Context.Cipher_Ctx, Temp); + Block(Index .. Index + (Length + 7) / 8 - 1) := Block(Index .. Index + (Length + 7) / 8 - 1) xor Temp(1 .. 1 + (Length + 7) / 8 - 1); + Context.Y := GHash(Context.H, Block(Index .. Index + (Length + 7) / 8 - 1), Seed => Context.Y); + Context.Plaintext_Length := Context.Plaintext_Length + u64(Length); + Put_Line("DBG: Trailing Length: " & Integer'Image(Length)); + end if; + Store_be(Fin_Block(1 .. 8), Context.Header_Length); + Store_be(Fin_Block(9 .. 16), Context.Plaintext_Length); + Context.Y := GHash(Context.H, Fin_Block, Seed => Context.Y); + end; + + procedure Decrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array) is + Temp : Block_128_Bit; + begin + if Block'Length /= Block_Size_Bytes then + raise Format_Violation; + end if; + Context.Y := GHash(Context.H, Block, Seed => Context.Y); + Context.Plaintext_Length := Context.Plaintext_Length + u64(Block_Size_Bits); + Inc_32(Context.ICB); + Temp := Context.ICB; + Cipher.Encrypt(Context.Cipher_Ctx, Temp); + Block := Block xor Temp; + end; + + procedure Decrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array) is + Length : Integer := Block'Length * 8; + Index : Integer := Block'First; + Temp : Block_128_Bit := (others => 0); + Fin_Block : Block_128_Bit; + begin + while Length >= Block_Size_Bits loop + Decrypt_Next_Block(Context, Block(Index .. Index + Block_Size_Bytes - 1)); + Length := Length - Block_Size_Bits; + Index := Index + Block_Size_Bytes; + end loop; + if Length > 0 then + Context.Y := GHash(Context.H, Block(Index .. Index + (Length + 7) / 8 - 1), Seed => Context.Y); + Context.Plaintext_Length := Context.Plaintext_Length + u64(Length); + Inc_32(Context.ICB); + Temp := Context.ICB; + Cipher.Encrypt(Context.Cipher_Ctx, Temp); + Block(Index .. Index + (Length + 7) / 8 - 1) := Block(Index .. Index + (Length + 7) / 8 - 1) xor Temp(1 .. 1 + (Length + 7) / 8 - 1); + end if; + Store_be(Fin_Block(1 .. 8), Context.Header_Length); + Store_be(Fin_Block(9 .. 16), Context.Plaintext_Length); + Context.Y := GHash(Context.H, Fin_Block, Seed => Context.Y); + end; + + procedure Get_Tag(Context : in Context_T; Tag : out u8_Array) is + begin + Tag := Context.J0(1 .. Tag'Length) xor Context.Y(1 .. Tag'Length); + end Get_Tag; + + function Is_Valid(Context : in Context_T; Tag : in u8_Array) return Boolean is + Is_Tag : u8_Array(Tag'Range); + begin + Get_Tag(Context, Is_Tag); + return Is_Tag = Tag; + end; + + +end GCM128_Spec; diff --git a/src/algorithms/gcm/gcm128_spec.ads b/src/algorithms/gcm/gcm128_spec.ads new file mode 100644 index 0000000..93a063c --- /dev/null +++ b/src/algorithms/gcm/gcm128_spec.ads @@ -0,0 +1,50 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Block_Cipher_Generic; +with Crypto_Core_Types; use Crypto_Core_Types; + +generic + with package Cipher is new Block_Cipher_Generic(<>); + +package GCM128_Spec is + type Context_T is private; + + Key_Size_Bits : Natural := Cipher.Key_Size_Bits; + Block_Size_Bits : Natural := Cipher.Block_Size_Bits; + Key_Size_Bytes : Natural := Cipher.Key_Size_Bytes; + Block_Size_Bytes : Natural := Cipher.Block_Size_Bytes; + + procedure Initialize(Context : out Context_T; Key : in u8_Array; IV : in u8_Array); + procedure Header_Next_Block(Context : in out Context_T; Header : in u8_Array); + procedure Header_Last_Block(Context : in out Context_T; Header : in u8_Array); + procedure Encrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array); + procedure Encrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array); + procedure Decrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array); + procedure Decrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array); + procedure Get_Tag(Context : in Context_T; Tag : out u8_Array); + function Is_Valid(Context : in Context_T; Tag : in u8_Array) return Boolean; + +private + + type Context_T is record + ICB, J0, H, Y : Block_128_Bit; + Header_Length : u64; + Plaintext_Length : u64; + Cipher_Ctx : Cipher.Context_T; + end record; + + +end GCM128_Spec; diff --git a/src/algorithms/pi-cipher/pi16cipher_spec.adb b/src/algorithms/pi-cipher/pi16cipher_spec.adb new file mode 100644 index 0000000..b71d361 --- /dev/null +++ b/src/algorithms/pi-cipher/pi16cipher_spec.adb @@ -0,0 +1,363 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Types; use Crypto_Types; +use Crypto_Types.Crypto_Utils_u16; +use Crypto_Types.Crypto_Utils_u64; +with System; use System; + +with Ada.Text_IO; use Ada.Text_IO; + +package body Pi16Cipher_Spec is + + subtype Rotation_Ammount_T is Integer range 0 .. Word_T'Size - 1; + subtype Chunk_Index_T is Integer range Chunk_T'Range; + subtype Rate_Block is u8_Array(1 .. Rate_Bytes); + + type Phi_Constants is array (1 .. 4) of Word_T; + type Phi_Rotation_Constants is array (1 .. 4) of Rotation_Ammount_T; + type Phi_V_Constants is array (1 .. 4) of Chunk_Index_T; + + Mu_Constants : constant Phi_Constants := ( 16#F0E8#, 16#E4E2#, 16#E1D8#, 16#D4D2# ); + Mu_Rotation_Constants : constant Phi_Rotation_Constants := ( 1, 4, 9, 11 ); + Nu_Constants : constant Phi_Constants := ( 16#D1CC#, 16#CAC9#, 16#C6C5#, 16#C3B8# ); + Nu_Rotation_Constants : constant Phi_Rotation_Constants := ( 2, 5, 7, 13 ); + + Mu_V_Constants : constant Phi_V_Constants := ( 4, 3, 2, 1 ); + Nu_V_Constants : constant Phi_V_Constants := ( 2, 1, 4, 3 ); + + Pi_Constants : constant array (1 .. 2 * R) of Chunk_T := + ( + ( 16#B4B2#, 16#B1AC#, 16#AAA9#, 16#A6A5# ), + ( 16#A39C#, 16#9A99#, 16#9695#, 16#938E# ), + ( 16#8D8B#, 16#8778#, 16#7472#, 16#716C# ), + ( 16#6A69#, 16#6665#, 16#635C#, 16#5A59# ), + ( 16#5655#, 16#534E#, 16#4D4B#, 16#473C# ), + ( 16#3A39#, 16#3635#, 16#332E#, 16#2D2B# ) + ); + + generic + Constants : Phi_Constants; + Rotation_Constants : Phi_Rotation_Constants; + V_Constants : Phi_V_Constants; + function Phi(Chunk : in Chunk_T) return Chunk_T; + + function Phi(Chunk : in Chunk_T) return Chunk_T is + Ret : Chunk_T; + Sum : Word_T; + begin + Sum := 0 + Chunk; + for i in Chunk'Range loop + Ret(i) := Rotate_Left(Constants(i) + Sum - Chunk(V_Constants(i)), Rotation_Constants(i)); + end loop; + Sum := 0 xor Ret; + Ret := Ret xor Sum; + return Ret; + end Phi; + + function Nu is new Phi (Constants => Nu_Constants, Rotation_Constants => Nu_Rotation_Constants, V_Constants => Nu_V_Constants); + + function Mu(Chunk : Chunk_T) return Chunk_T is + function foo is new Phi (Constants => Mu_Constants, Rotation_Constants => Mu_Rotation_Constants, V_Constants => Mu_V_Constants); + Ret : Chunk_T; + begin + Ret := foo(Chunk); + Ret := Rotate_Array_Left(Ret, 2); + return Ret; + end Mu; + + function "*" (X : Chunk_T; Y : Chunk_T) return Chunk_T is + Ret : Chunk_T; + begin + Ret := Mu(X) + Nu(Y); + Ret := Rotate_Array_Left(Ret, 1); + return Ret; + end "*"; + + function E1 (C : Chunk_T; I : State_T) return State_T is + J : State_T; + begin + J(1) := C * I(1); + for index in 2 .. N loop + J(index) := J(index - 1) * I(index); + end loop; + return J; + end E1; + + function E2 (C : Chunk_T; I : State_T) return State_T is + J : State_T; + begin + J(N) := I(N) * C; + for index in reverse 1 .. N - 1 loop + J(index) := I(index) * J(index + 1); + end loop; + return J; + end E2; + + function Pi (State : State_T) return State_T is + Ret : State_T := State; + begin + for round in 0 .. R - 1 loop + Ret := E1(Pi_Constants(2 * round + 1), Ret); + Ret := E2(Pi_Constants(2 * round + 2), Ret); + end loop; + return Ret; + end Pi; + + procedure Dump(State : in State_T) is + begin + Put_Line("State:"); + for i in State'Range loop + Put(" [ "); + for j in State(i)'Range loop + Put(To_Hex(State(i)(j))); + Put(' '); + end loop; + Put_Line("]"); + end loop; + end; + + procedure Initialize(Context : out Context_T; Key : in u8_Array; Public_Nonce : in u8_Array) is + Scratch : u8_Array(1 .. IS_Bytes) := (others => 0); + Index : Integer := Scratch'First; + begin + if Key'Length + Public_Nonce'Length >= Scratch'Length then + raise Invalid_Key_Size; + end if; + Context.Tag := (others => 0); + Scratch(1 .. Key'Length) := Key; + Scratch(Key'Length + 1 .. Key'Length + Public_Nonce'Length) := Public_Nonce; + Scratch(Key'Length + Public_Nonce'Length + 1) := 1; + for i in Context.State'Range loop + Context.State(i) := Load_LE(Scratch(Index .. Index + Chunk_T'Length * Word_T'Size / 8 - 1)); + Index := Index + Chunk_T'Length * Word_T'Size / 8; + end loop; + Context.State := pi(Context.State); + Context.Counter := 0; + for i in 1 .. 64 / Word_T'Size loop + Context.Counter := Context.Counter or Shift_Left(u64(Context.State(2)(i)), (i - 1) * Word_T'Size); + end loop; + end Initialize; + + function "+" (Context : Context_T; Block_Number : Block_Number_T) return State_T is + Counter : u64 := Context.Counter + u64(Block_Number); + Ret : State_T := Context.State; + begin + for i in 1 .. 64 / Word_T'Size loop + Ret(1)(i) := Ret(1)(i) xor Word_T( Counter and (Shift_Left(u64'(1), Word_T'Size) - 1)); + Counter := Shift_Right(Counter, Word_T'Size); + end loop; + return Ret; + end "+"; + + function Extract(State : State_T) return Rate_Block is + Data : Rate_Block; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Store_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1), State(2 * i + 1)); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Data; + end Extract; + + function Extract(State : State_T) return Tag_Int_T is + Tag : Tag_Int_T; + begin + for i in 0 .. N / 2 - 1 loop + Tag(Tag'First + i * 4 .. Tag'First + i * 4 + 3) := State(2 * i + 1); + end loop; + return Tag; + end Extract; + + function "xor" (State : State_T; Data : Rate_Block) return State_T is + Ret : State_T := State; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Ret(2 * i + 1) xor Chunk_T'(Load_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1))); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Ret; + end "xor"; + + function "xor" (State : State_T; Tag : Tag_Int_T) return State_T is + Ret : State_T := State; + Index : Positive := Tag'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Ret(2 * i + 1) xor Tag(Index .. Index + 3); + Index := Index + 4; + end loop; + return Ret; + end "xor"; + + function set (State : State_T; Data : Rate_Block) return State_T is + Ret : State_T := State; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Chunk_T'(Load_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1))); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Ret; + end set; + + function "+" (Tag : Tag_Int_T) return Tag_T is + Ret : Tag_T; + begin + Store_LE(Ret, Tag); + return Ret; + end "+"; + + function Pad (Data : u8_Array) return Block_T is + Ret : Block_T := (others => 0); + begin + if Data'Length >= Block_T'Length then + raise Constraint_Error; + end if; + Ret(Ret'First .. Ret'First + Data'Length -1 ) := Data; + Ret(Ret'First + Data'Length) := 1; + return Ret; + end Pad; + + procedure Process_Header_Block (Context : in out Context_T; Block : Block_T; Block_Number : Block_Number_T) is + begin + Context.Tag := Context.Tag + Extract(Pi(Pi(Context + Block_Number) xor Block)); + end Process_Header_Block; + + procedure Process_Header_Last_Block (Context : in out Context_T; Block : u8_Array; Block_Number : Block_Number_T) is + Num : Block_Number_T := Block_Number; + Index : Integer := Block'First; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Process_Header_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Num := Num + 1; + Index := Index + Block_Bytes; + end loop; + Process_Header_Block(Context, Pad(Block(Index .. Block'Last)), Num); + Context.State := Pi(Context.State xor Context.Tag); + Context.Counter := Context.Counter + u64(Num); + end Process_Header_Last_Block; + + procedure Encrypt_Secret_Message_Number(Context : in out Context_T; Block : in out Block_T) is + State : constant State_T := Pi(Context + Block_Number_T'(1)) xor Block; + begin + Block := Extract(State); + Context.State := Pi(State); + Context.Tag := Context.Tag + Extract(Context.State); + Context.Counter := Context.Counter + 1; + end Encrypt_Secret_Message_Number; + + procedure Decrypt_Secret_Message_Number(Context : in out Context_T; Block : in out Block_T) is + State : constant State_T := Pi(Context + Block_Number_T'(1)) xor Block; + Block_In : constant Block_T := Block; + begin + Block := Extract(State); + Context.State := Pi(set(State, Block_In)); + Context.Tag := Context.Tag + Extract(Context.State); + Context.Counter := Context.Counter + 1; + end Decrypt_Secret_Message_Number; + + procedure Encrypt_Block(Context : in out Context_T; Block : in out Block_T; Block_Number : Block_Number_T) is + State : State_T := Pi(Context + Block_Number) xor Block; + begin + Block := Extract(State); + State := Pi(State); + Context.Tag := Context.Tag + Extract(State); + end Encrypt_Block; + + procedure Decrypt_Block(Context : in out Context_T; Block : in out Block_T; Block_Number : Block_Number_T) is + State : State_T := Pi(Context + Block_Number) xor Block; + In_Block : constant Block_T := Block; + begin + Block := Extract(State); + State := Pi(set(State, In_Block)); + Context.Tag := Context.Tag + Extract(State); + end Decrypt_Block; + + procedure Encrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array; Block_Number : Block_Number_T) is + State : State_T; + Index : Integer := Block'First; + Num : Block_Number_T := Block_Number; + Temp_Block : Block_T; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Encrypt_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Index := Index + Block_Bytes; + Num := Num + 1; + end loop; + Temp_Block := Pad(Block(Index .. Block'Last)); + State := Pi(Context + Num) xor Temp_Block; + Temp_Block := Extract(State); + Block(Index .. Block'Last) := Temp_Block(Temp_Block'First .. Temp_Block'First + Block'Last - Index); + State := Pi(State); + Context.Tag := Context.Tag + Extract(State); + end Encrypt_Last_Block; + + procedure Decrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array; Block_Number : Block_Number_T) is + State : State_T; + Index : Integer := Block'First; + Num : Block_Number_T := Block_Number; + Temp_Block : Block_T; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Decrypt_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Index := Index + Block_Bytes; + Num := Num + 1; + end loop; + Temp_Block := Pad(Block(Index .. Block'Last)); + State := Pi(Context + Num) xor Temp_Block; + Block(Index .. Block'Last) := Extract(State)(Temp_Block'First .. Temp_Block'First + Block'Last - Index); + Temp_Block(Temp_Block'First + Block'Last - Index + 1 .. Temp_Block'Last) := Extract(State)(Temp_Block'First + Block'Last - Index + 1 .. Temp_Block'Last); + State := Pi(set(State, Temp_Block)); + Context.Tag := Context.Tag + Extract(State); + end Decrypt_Last_Block; + + function Get_Tag(Context : Context_T) return Tag_T is + begin + return +Context.Tag; + end Get_Tag; + + function Encrypt(Msg : u8_Array; AD : u8_Array; Public_Nonce : u8_Array; Secret_Nonce : Block_T; Key : u8_Array) return u8_Array is + Crypt : u8_Array(1 .. Secret_Nonce'Length + Msg'Length + Tag_Bytes); + Ctx : Context_T; + begin + Initialize(Context => Ctx, Key => Key, Public_Nonce => Public_Nonce); + Process_Header_Last_Block(Context => Ctx, Block => AD, Block_Number => 1); + Crypt(Crypt'First .. Crypt'First + Secret_Message_Number_Bytes - 1) := Secret_Nonce; + Crypt(Crypt'First + Secret_Message_Number_Bytes .. Crypt'Last - Tag_Bytes) := Msg; + Encrypt_Secret_Message_Number(Context => Ctx, Block => Crypt(Crypt'First .. Crypt'First + Secret_Message_Number_Bytes - 1)); + Encrypt_Last_Block(Context => Ctx, Block => Crypt(Crypt'First + Secret_Message_Number_Bytes .. Crypt'Last - Tag_Bytes), Block_Number => 1); + Crypt(Crypt'Last - Tag_Bytes + 1 .. Crypt'Last) := Get_Tag(Ctx); + return Crypt; + end Encrypt; + + procedure Decrypt(Is_Valid : out Boolean; Msg : out u8_Array; Secret_Nonce : out Block_T; Cipher : in u8_Array; AD : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array) is + Tag : Tag_T; + Ctx : Context_T; + begin + Initialize(Context => Ctx, Key => Key, Public_Nonce => Public_Nonce); + Process_Header_Last_Block(Context => Ctx, Block => AD, Block_Number => 1); + Secret_Nonce := Cipher(Cipher'First .. Cipher'First + Secret_Message_Number_Bytes - 1); + Msg := Cipher(Cipher'First + Secret_Message_Number_Bytes .. Cipher'Last - Tag_Bytes); + Decrypt_Secret_Message_Number(Context => Ctx, Block => Secret_Nonce); + Decrypt_Last_Block(Context => Ctx, Block => Msg, Block_Number => 1); + Tag := Get_Tag(Ctx); + Is_Valid := Tag = Cipher(Cipher'Last - Tag_Bytes + 1 .. Cipher'Last); + end Decrypt; + +end Pi16Cipher_Spec; + diff --git a/src/algorithms/pi-cipher/pi16cipher_spec.ads b/src/algorithms/pi-cipher/pi16cipher_spec.ads new file mode 100644 index 0000000..c8405e6 --- /dev/null +++ b/src/algorithms/pi-cipher/pi16cipher_spec.ads @@ -0,0 +1,75 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; + +package Pi16Cipher_Spec is + + type Context_T is private; + + Cipher_Name : constant String := "pi16cipher"; + Width_Bits : constant := 16; + + N : constant := 4; + R : constant := 3; + + IS_Bits : constant := (N * 4 * Width_Bits); + IS_Bytes : constant := IS_Bits / 8; + Rate_Bits : constant := IS_Bits / 2; + Rate_Bytes : constant := Rate_Bits / 8; + Capacity_Bits : constant := IS_Bits - Rate_Bits; + Capacity_Bytes : constant := Capacity_Bits / 8; + Block_Bits : constant := Rate_Bits; + Block_Bytes : constant := Block_Bits / 8; + Tag_Bits : constant := Rate_Bits; + Tag_Bytes : constant := Tag_Bits / 8; + Secret_Message_Number_Bits : constant := Block_Bits; + Secret_Message_Number_Bytes : constant := Secret_Message_Number_Bits / 8; + + subtype Block_Number_T is Natural; + + subtype Block_T is u8_Array (1 .. Rate_Bytes); + + procedure Initialize(Context : out Context_T; Key : in u8_Array; Public_Nonce : in u8_Array); +-- procedure Encrypt_Secret_Message_Number(Context : in out Context; Secret_Message_Number : in u8_Array); +-- procedure Header_Next_Block(Context : in out Context_T; Header : in u8_Array); +-- procedure Header_Last_Block(Context : in out Context_T; Header : in u8_Array); +-- procedure Encrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Encrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Decrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Decrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Get_Tag(Context : in Context_T; Tag : out u8_Array); +-- function Is_Valid(Context : in Context_T; Tag : in u8_Array) return Boolean; + + function Encrypt(Msg : u8_Array; AD : u8_Array; Public_Nonce : u8_Array; Secret_Nonce : Block_T; Key : u8_Array) return u8_Array; + procedure Decrypt(Is_Valid : out Boolean; Msg : out u8_Array; Secret_Nonce : out Block_T; Cipher : in u8_Array; AD : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array); + + +private + + subtype Word_T is u16; + subtype Chunk_T is u16_Array(1 .. 4); + subtype Tag_Int_T is u16_Array(1 .. 4 * N / 2); + subtype Tag_T is u8_Array(1 .. Rate_Bytes); + + type State_T is array (1 .. N) of Chunk_T; + + type Context_T is record + State : State_T; + Tag : Tag_Int_T; + Counter : u64; + end record; + +end Pi16Cipher_Spec; diff --git a/src/algorithms/pi-cipher/pi32cipher_spec.adb b/src/algorithms/pi-cipher/pi32cipher_spec.adb new file mode 100644 index 0000000..d6f2acc --- /dev/null +++ b/src/algorithms/pi-cipher/pi32cipher_spec.adb @@ -0,0 +1,363 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Types; use Crypto_Types; +use Crypto_Types.Crypto_Utils_u32; +use Crypto_Types.Crypto_Utils_u64; +with System; use System; + +with Ada.Text_IO; use Ada.Text_IO; + +package body Pi32Cipher_Spec is + + subtype Rotation_Ammount_T is Integer range 0 .. Word_T'Size - 1; + subtype Chunk_Index_T is Integer range Chunk_T'Range; + subtype Rate_Block is u8_Array(1 .. Rate_Bytes); + + type Phi_Constants is array (1 .. 4) of Word_T; + type Phi_Rotation_Constants is array (1 .. 4) of Rotation_Ammount_T; + type Phi_V_Constants is array (1 .. 4) of Chunk_Index_T; + + Mu_Constants : constant Phi_Constants := ( 16#F0E8E4E2#, 16#E1D8D4D2#, 16#D1CCCAC9#, 16#C6C5C3B8# ); + Mu_Rotation_Constants : constant Phi_Rotation_Constants := ( 5, 11, 17, 23 ); + Nu_Constants : constant Phi_Constants := ( 16#B4B2B1AC#, 16#AAA9A6A5#, 16#A39C9A99#, 16#9695938E# ); + Nu_Rotation_Constants : constant Phi_Rotation_Constants := ( 3, 10, 19, 29 ); + + Mu_V_Constants : constant Phi_V_Constants := ( 4, 3, 2, 1 ); + Nu_V_Constants : constant Phi_V_Constants := ( 2, 1, 4, 3 ); + + Pi_Constants : constant array (1 .. 2 * R) of Chunk_T := + ( + ( 16#8D8B8778#, 16#7472716C#, 16#6A696665#, 16#635C5A59# ), + ( 16#5655534E#, 16#4D4B473C#, 16#3A393635#, 16#332E2D2B# ), + ( 16#271E1D1B#, 16#170FF0E8#, 16#E4E2E1D8#, 16#D4D2D1CC# ), + ( 16#CAC9C6C5#, 16#C3B8B4B2#, 16#B1ACAAA9#, 16#A6A5A39C# ), + ( 16#9A999695#, 16#938E8D8B#, 16#87787472#, 16#716C6A69# ), + ( 16#6665635C#, 16#5A595655#, 16#534E4D4B#, 16#473C3A39# ) + ); + + generic + Constants : Phi_Constants; + Rotation_Constants : Phi_Rotation_Constants; + V_Constants : Phi_V_Constants; + function Phi(Chunk : in Chunk_T) return Chunk_T; + + function Phi(Chunk : in Chunk_T) return Chunk_T is + Ret : Chunk_T; + Sum : Word_T; + begin + Sum := 0 + Chunk; + for i in Chunk'Range loop + Ret(i) := Rotate_Left(Constants(i) + Sum - Chunk(V_Constants(i)), Rotation_Constants(i)); + end loop; + Sum := 0 xor Ret; + Ret := Ret xor Sum; + return Ret; + end Phi; + + function Nu is new Phi (Constants => Nu_Constants, Rotation_Constants => Nu_Rotation_Constants, V_Constants => Nu_V_Constants); + + function Mu(Chunk : Chunk_T) return Chunk_T is + function foo is new Phi (Constants => Mu_Constants, Rotation_Constants => Mu_Rotation_Constants, V_Constants => Mu_V_Constants); + Ret : Chunk_T; + begin + Ret := foo(Chunk); + Ret := Rotate_Array_Left(Ret, 2); + return Ret; + end Mu; + + function "*" (X : Chunk_T; Y : Chunk_T) return Chunk_T is + Ret : Chunk_T; + begin + Ret := Mu(X) + Nu(Y); + Ret := Rotate_Array_Left(Ret, 1); + return Ret; + end "*"; + + function E1 (C : Chunk_T; I : State_T) return State_T is + J : State_T; + begin + J(1) := C * I(1); + for index in 2 .. N loop + J(index) := J(index - 1) * I(index); + end loop; + return J; + end E1; + + function E2 (C : Chunk_T; I : State_T) return State_T is + J : State_T; + begin + J(N) := I(N) * C; + for index in reverse 1 .. N - 1 loop + J(index) := I(index) * J(index + 1); + end loop; + return J; + end E2; + + function Pi (State : State_T) return State_T is + Ret : State_T := State; + begin + for round in 0 .. R - 1 loop + Ret := E1(Pi_Constants(2 * round + 1), Ret); + Ret := E2(Pi_Constants(2 * round + 2), Ret); + end loop; + return Ret; + end Pi; + + procedure Dump(State : in State_T) is + begin + Put_Line("State:"); + for i in State'Range loop + Put(" [ "); + for j in State(i)'Range loop + Put(To_Hex(State(i)(j))); + Put(' '); + end loop; + Put_Line("]"); + end loop; + end; + + procedure Initialize(Context : out Context_T; Key : in u8_Array; Public_Nonce : in u8_Array) is + Scratch : u8_Array(1 .. IS_Bytes) := (others => 0); + Index : Integer := Scratch'First; + begin + if Key'Length + Public_Nonce'Length >= Scratch'Length then + raise Invalid_Key_Size; + end if; + Context.Tag := (others => 0); + Scratch(1 .. Key'Length) := Key; + Scratch(Key'Length + 1 .. Key'Length + Public_Nonce'Length) := Public_Nonce; + Scratch(Key'Length + Public_Nonce'Length + 1) := 1; + for i in Context.State'Range loop + Context.State(i) := Load_LE(Scratch(Index .. Index + Chunk_T'Length * Word_T'Size / 8 - 1)); + Index := Index + Chunk_T'Length * Word_T'Size / 8; + end loop; + Context.State := pi(Context.State); + Context.Counter := 0; + for i in 1 .. 64 / Word_T'Size loop + Context.Counter := Context.Counter or Shift_Left(u64(Context.State(2)(i)), (i - 1) * Word_T'Size); + end loop; + end Initialize; + + function "+" (Context : Context_T; Block_Number : Block_Number_T) return State_T is + Counter : u64 := Context.Counter + u64(Block_Number); + Ret : State_T := Context.State; + begin + for i in 1 .. 64 / Word_T'Size loop + Ret(1)(i) := Ret(1)(i) xor Word_T( Counter and (Shift_Left(u64'(1), Word_T'Size) - 1)); + Counter := Shift_Right(Counter, Word_T'Size); + end loop; + return Ret; + end "+"; + + function Extract(State : State_T) return Rate_Block is + Data : Rate_Block; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Store_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1), State(2 * i + 1)); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Data; + end Extract; + + function Extract(State : State_T) return Tag_Int_T is + Tag : Tag_Int_T; + begin + for i in 0 .. N / 2 - 1 loop + Tag(Tag'First + i * 4 .. Tag'First + i * 4 + 3) := State(2 * i + 1); + end loop; + return Tag; + end Extract; + + function "xor" (State : State_T; Data : Rate_Block) return State_T is + Ret : State_T := State; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Ret(2 * i + 1) xor Chunk_T'(Load_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1))); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Ret; + end "xor"; + + function "xor" (State : State_T; Tag : Tag_Int_T) return State_T is + Ret : State_T := State; + Index : Positive := Tag'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Ret(2 * i + 1) xor Tag(Index .. Index + 3); + Index := Index + 4; + end loop; + return Ret; + end "xor"; + + function set (State : State_T; Data : Rate_Block) return State_T is + Ret : State_T := State; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Chunk_T'(Load_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1))); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Ret; + end set; + + function "+" (Tag : Tag_Int_T) return Tag_T is + Ret : Tag_T; + begin + Store_LE(Ret, Tag); + return Ret; + end "+"; + + function Pad (Data : u8_Array) return Block_T is + Ret : Block_T := (others => 0); + begin + if Data'Length >= Block_T'Length then + raise Constraint_Error; + end if; + Ret(Ret'First .. Ret'First + Data'Length -1 ) := Data; + Ret(Ret'First + Data'Length) := 1; + return Ret; + end Pad; + + procedure Process_Header_Block (Context : in out Context_T; Block : Block_T; Block_Number : Block_Number_T) is + begin + Context.Tag := Context.Tag + Extract(Pi(Pi(Context + Block_Number) xor Block)); + end Process_Header_Block; + + procedure Process_Header_Last_Block (Context : in out Context_T; Block : u8_Array; Block_Number : Block_Number_T) is + Num : Block_Number_T := Block_Number; + Index : Integer := Block'First; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Process_Header_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Num := Num + 1; + Index := Index + Block_Bytes; + end loop; + Process_Header_Block(Context, Pad(Block(Index .. Block'Last)), Num); + Context.State := Pi(Context.State xor Context.Tag); + Context.Counter := Context.Counter + u64(Num); + end Process_Header_Last_Block; + + procedure Encrypt_Secret_Message_Number(Context : in out Context_T; Block : in out Block_T) is + State : constant State_T := Pi(Context + Block_Number_T'(1)) xor Block; + begin + Block := Extract(State); + Context.State := Pi(State); + Context.Tag := Context.Tag + Extract(Context.State); + Context.Counter := Context.Counter + 1; + end Encrypt_Secret_Message_Number; + + procedure Decrypt_Secret_Message_Number(Context : in out Context_T; Block : in out Block_T) is + State : constant State_T := Pi(Context + Block_Number_T'(1)) xor Block; + Block_In : constant Block_T := Block; + begin + Block := Extract(State); + Context.State := Pi(set(State, Block_In)); + Context.Tag := Context.Tag + Extract(Context.State); + Context.Counter := Context.Counter + 1; + end Decrypt_Secret_Message_Number; + + procedure Encrypt_Block(Context : in out Context_T; Block : in out Block_T; Block_Number : Block_Number_T) is + State : State_T := Pi(Context + Block_Number) xor Block; + begin + Block := Extract(State); + State := Pi(State); + Context.Tag := Context.Tag + Extract(State); + end Encrypt_Block; + + procedure Decrypt_Block(Context : in out Context_T; Block : in out Block_T; Block_Number : Block_Number_T) is + State : State_T := Pi(Context + Block_Number) xor Block; + In_Block : constant Block_T := Block; + begin + Block := Extract(State); + State := Pi(set(State, In_Block)); + Context.Tag := Context.Tag + Extract(State); + end Decrypt_Block; + + procedure Encrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array; Block_Number : Block_Number_T) is + State : State_T; + Index : Integer := Block'First; + Num : Block_Number_T := Block_Number; + Temp_Block : Block_T; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Encrypt_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Index := Index + Block_Bytes; + Num := Num + 1; + end loop; + Temp_Block := Pad(Block(Index .. Block'Last)); + State := Pi(Context + Num) xor Temp_Block; + Temp_Block := Extract(State); + Block(Index .. Block'Last) := Temp_Block(Temp_Block'First .. Temp_Block'First + Block'Last - Index); + State := Pi(State); + Context.Tag := Context.Tag + Extract(State); + end Encrypt_Last_Block; + + procedure Decrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array; Block_Number : Block_Number_T) is + State : State_T; + Index : Integer := Block'First; + Num : Block_Number_T := Block_Number; + Temp_Block : Block_T; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Decrypt_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Index := Index + Block_Bytes; + Num := Num + 1; + end loop; + Temp_Block := Pad(Block(Index .. Block'Last)); + State := Pi(Context + Num) xor Temp_Block; + Block(Index .. Block'Last) := Extract(State)(Temp_Block'First .. Temp_Block'First + Block'Last - Index); + Temp_Block(Temp_Block'First + Block'Last - Index + 1 .. Temp_Block'Last) := Extract(State)(Temp_Block'First + Block'Last - Index + 1 .. Temp_Block'Last); + State := Pi(set(State, Temp_Block)); + Context.Tag := Context.Tag + Extract(State); + end Decrypt_Last_Block; + + function Get_Tag(Context : Context_T) return Tag_T is + begin + return +Context.Tag; + end Get_Tag; + + function Encrypt(Msg : u8_Array; AD : u8_Array; Public_Nonce : u8_Array; Secret_Nonce : Block_T; Key : u8_Array) return u8_Array is + Crypt : u8_Array(1 .. Secret_Nonce'Length + Msg'Length + Tag_Bytes); + Ctx : Context_T; + begin + Initialize(Context => Ctx, Key => Key, Public_Nonce => Public_Nonce); + Process_Header_Last_Block(Context => Ctx, Block => AD, Block_Number => 1); + Crypt(Crypt'First .. Crypt'First + Secret_Message_Number_Bytes - 1) := Secret_Nonce; + Crypt(Crypt'First + Secret_Message_Number_Bytes .. Crypt'Last - Tag_Bytes) := Msg; + Encrypt_Secret_Message_Number(Context => Ctx, Block => Crypt(Crypt'First .. Crypt'First + Secret_Message_Number_Bytes - 1)); + Encrypt_Last_Block(Context => Ctx, Block => Crypt(Crypt'First + Secret_Message_Number_Bytes .. Crypt'Last - Tag_Bytes), Block_Number => 1); + Crypt(Crypt'Last - Tag_Bytes + 1 .. Crypt'Last) := Get_Tag(Ctx); + return Crypt; + end Encrypt; + + procedure Decrypt(Is_Valid : out Boolean; Msg : out u8_Array; Secret_Nonce : out Block_T; Cipher : in u8_Array; AD : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array) is + Tag : Tag_T; + Ctx : Context_T; + begin + Initialize(Context => Ctx, Key => Key, Public_Nonce => Public_Nonce); + Process_Header_Last_Block(Context => Ctx, Block => AD, Block_Number => 1); + Secret_Nonce := Cipher(Cipher'First .. Cipher'First + Secret_Message_Number_Bytes - 1); + Msg := Cipher(Cipher'First + Secret_Message_Number_Bytes .. Cipher'Last - Tag_Bytes); + Decrypt_Secret_Message_Number(Context => Ctx, Block => Secret_Nonce); + Decrypt_Last_Block(Context => Ctx, Block => Msg, Block_Number => 1); + Tag := Get_Tag(Ctx); + Is_Valid := Tag = Cipher(Cipher'Last - Tag_Bytes + 1 .. Cipher'Last); + end Decrypt; + +end Pi32Cipher_Spec; + diff --git a/src/algorithms/pi-cipher/pi32cipher_spec.ads b/src/algorithms/pi-cipher/pi32cipher_spec.ads new file mode 100644 index 0000000..6725771 --- /dev/null +++ b/src/algorithms/pi-cipher/pi32cipher_spec.ads @@ -0,0 +1,75 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; + +package Pi32Cipher_Spec is + + type Context_T is private; + + Cipher_Name : constant String := "pi32cipher"; + Width_Bits : constant := 32; + + N : constant := 4; + R : constant := 3; + + IS_Bits : constant := (N * 4 * Width_Bits); + IS_Bytes : constant := IS_Bits / 8; + Rate_Bits : constant := IS_Bits / 2; + Rate_Bytes : constant := Rate_Bits / 8; + Capacity_Bits : constant := IS_Bits - Rate_Bits; + Capacity_Bytes : constant := Capacity_Bits / 8; + Block_Bits : constant := Rate_Bits; + Block_Bytes : constant := Block_Bits / 8; + Tag_Bits : constant := Rate_Bits; + Tag_Bytes : constant := Tag_Bits / 8; + Secret_Message_Number_Bits : constant := Block_Bits; + Secret_Message_Number_Bytes : constant := Secret_Message_Number_Bits / 8; + + subtype Block_Number_T is Natural; + + subtype Block_T is u8_Array (1 .. Rate_Bytes); + + procedure Initialize(Context : out Context_T; Key : in u8_Array; Public_Nonce : in u8_Array); +-- procedure Encrypt_Secret_Message_Number(Context : in out Context; Secret_Message_Number : in u8_Array); +-- procedure Header_Next_Block(Context : in out Context_T; Header : in u8_Array); +-- procedure Header_Last_Block(Context : in out Context_T; Header : in u8_Array); +-- procedure Encrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Encrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Decrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Decrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Get_Tag(Context : in Context_T; Tag : out u8_Array); +-- function Is_Valid(Context : in Context_T; Tag : in u8_Array) return Boolean; + + function Encrypt(Msg : u8_Array; AD : u8_Array; Public_Nonce : u8_Array; Secret_Nonce : Block_T; Key : u8_Array) return u8_Array; + procedure Decrypt(Is_Valid : out Boolean; Msg : out u8_Array; Secret_Nonce : out Block_T; Cipher : in u8_Array; AD : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array); + + +private + + subtype Word_T is u32; + subtype Chunk_T is u32_Array(1 .. 4); + subtype Tag_Int_T is u32_Array(1 .. 4 * N / 2); + subtype Tag_T is u8_Array(1 .. Rate_Bytes); + + type State_T is array (1 .. N) of Chunk_T; + + type Context_T is record + State : State_T; + Tag : Tag_Int_T; + Counter : u64; + end record; + +end Pi32Cipher_Spec; diff --git a/src/algorithms/pi-cipher/pi64cipher_spec.adb b/src/algorithms/pi-cipher/pi64cipher_spec.adb new file mode 100644 index 0000000..bcaa7f7 --- /dev/null +++ b/src/algorithms/pi-cipher/pi64cipher_spec.adb @@ -0,0 +1,371 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Types; use Crypto_Types; +use Crypto_Types.Crypto_Utils_u16; +use Crypto_Types.Crypto_Utils_u64; +with System; use System; + +with Ada.Text_IO; use Ada.Text_IO; + +package body Pi64Cipher_Spec is + + subtype Rotation_Ammount_T is Integer range 0 .. Word_T'Size - 1; + subtype Chunk_Index_T is Integer range Chunk_T'Range; + subtype Rate_Block is u8_Array(1 .. Rate_Bytes); + + type Phi_Constants is array (1 .. 4) of Word_T; + type Phi_Rotation_Constants is array (1 .. 4) of Rotation_Ammount_T; + type Phi_V_Constants is array (1 .. 4) of Chunk_Index_T; + + Mu_Constants : constant Phi_Constants := ( + 16#F0E8E4E2E1D8D4D2#, + 16#D1CCCAC9C6C5C3B8#, + 16#B4B2B1ACAAA9A6A5#, + 16#A39C9A999695938E# ); + + Mu_Rotation_Constants : constant Phi_Rotation_Constants := ( 7, 19, 31, 53 ); + Nu_Constants : constant Phi_Constants := ( 16#8D8B87787472716C#, + 16#6A696665635C5A59#, + 16#5655534E4D4B473C#, + 16#3A393635332E2D2B# ); + Nu_Rotation_Constants : constant Phi_Rotation_Constants := ( 11, 23, 37, 59 ); + + Mu_V_Constants : constant Phi_V_Constants := ( 4, 3, 2, 1 ); + Nu_V_Constants : constant Phi_V_Constants := ( 2, 1, 4, 3 ); + + Pi_Constants : constant array (1 .. 2 * R) of Chunk_T := + ( + ( 16#271E1D1B170FF0E8#, 16#E4E2E1D8D4D2D1CC#, 16#CAC9C6C5C3B8B4B2#, 16#B1ACAAA9A6A5A39C# ), + ( 16#9A999695938E8D8B#, 16#87787472716C6A69#, 16#6665635C5A595655#, 16#534E4D4B473C3A39# ), + ( 16#3635332E2D2B271E#, 16#1D1B170FF0E8E4E2#, 16#E1D8D4D2D1CCCAC9#, 16#C6C5C3B8B4B2B1AC# ), + ( 16#AAA9A6A5A39C9A99#, 16#9695938E8D8B8778#, 16#7472716C6A696665#, 16#635C5A595655534E# ), + ( 16#4D4B473C3A393635#, 16#332E2D2B271E1D1B#, 16#170FF0E8E4E2E1D8#, 16#D4D2D1CCCAC9C6C5# ), + ( 16#C3B8B4B2B1ACAAA9#, 16#A6A5A39C9A999695#, 16#938E8D8B87787472#, 16#716C6A696665635C# ) + ); + + generic + Constants : Phi_Constants; + Rotation_Constants : Phi_Rotation_Constants; + V_Constants : Phi_V_Constants; + function Phi(Chunk : in Chunk_T) return Chunk_T; + + function Phi(Chunk : in Chunk_T) return Chunk_T is + Ret : Chunk_T; + Sum : Word_T; + begin + Sum := 0 + Chunk; + for i in Chunk'Range loop + Ret(i) := Rotate_Left(Constants(i) + Sum - Chunk(V_Constants(i)), Rotation_Constants(i)); + end loop; + Sum := 0 xor Ret; + Ret := Ret xor Sum; + return Ret; + end Phi; + + function Nu is new Phi (Constants => Nu_Constants, Rotation_Constants => Nu_Rotation_Constants, V_Constants => Nu_V_Constants); + + function Mu(Chunk : Chunk_T) return Chunk_T is + function foo is new Phi (Constants => Mu_Constants, Rotation_Constants => Mu_Rotation_Constants, V_Constants => Mu_V_Constants); + Ret : Chunk_T; + begin + Ret := foo(Chunk); + Ret := Rotate_Array_Left(Ret, 2); + return Ret; + end Mu; + + function "*" (X : Chunk_T; Y : Chunk_T) return Chunk_T is + Ret : Chunk_T; + begin + Ret := Mu(X) + Nu(Y); + Ret := Rotate_Array_Left(Ret, 1); + return Ret; + end "*"; + + function E1 (C : Chunk_T; I : State_T) return State_T is + J : State_T; + begin + J(1) := C * I(1); + for index in 2 .. N loop + J(index) := J(index - 1) * I(index); + end loop; + return J; + end E1; + + function E2 (C : Chunk_T; I : State_T) return State_T is + J : State_T; + begin + J(N) := I(N) * C; + for index in reverse 1 .. N - 1 loop + J(index) := I(index) * J(index + 1); + end loop; + return J; + end E2; + + function Pi (State : State_T) return State_T is + Ret : State_T := State; + begin + for round in 0 .. R - 1 loop + Ret := E1(Pi_Constants(2 * round + 1), Ret); + Ret := E2(Pi_Constants(2 * round + 2), Ret); + end loop; + return Ret; + end Pi; + + procedure Dump(State : in State_T) is + begin + Put_Line("State:"); + for i in State'Range loop + Put(" [ "); + for j in State(i)'Range loop + Put(To_Hex(State(i)(j))); + Put(' '); + end loop; + Put_Line("]"); + end loop; + end; + + procedure Initialize(Context : out Context_T; Key : in u8_Array; Public_Nonce : in u8_Array) is + Scratch : u8_Array(1 .. IS_Bytes) := (others => 0); + Index : Integer := Scratch'First; + begin + if Key'Length + Public_Nonce'Length >= Scratch'Length then + raise Invalid_Key_Size; + end if; + Context.Tag := (others => 0); + Scratch(1 .. Key'Length) := Key; + Scratch(Key'Length + 1 .. Key'Length + Public_Nonce'Length) := Public_Nonce; + Scratch(Key'Length + Public_Nonce'Length + 1) := 1; + for i in Context.State'Range loop + Context.State(i) := Load_LE(Scratch(Index .. Index + Chunk_T'Length * Word_T'Size / 8 - 1)); + Index := Index + Chunk_T'Length * Word_T'Size / 8; + end loop; + Context.State := pi(Context.State); + Context.Counter := 0; + for i in 1 .. 64 / Word_T'Size loop + Context.Counter := Context.Counter or Shift_Left(u64(Context.State(2)(i)), (i - 1) * Word_T'Size); + end loop; + end Initialize; + + function "+" (Context : Context_T; Block_Number : Block_Number_T) return State_T is + Counter : u64 := Context.Counter + u64(Block_Number); + Ret : State_T := Context.State; + begin + for i in 1 .. 64 / Word_T'Size loop + Ret(1)(i) := Ret(1)(i) xor Word_T( Counter and (Shift_Left(u64'(1), Word_T'Size) - 1)); + Counter := Shift_Right(Counter, Word_T'Size); + end loop; + return Ret; + end "+"; + + function Extract(State : State_T) return Rate_Block is + Data : Rate_Block; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Store_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1), State(2 * i + 1)); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Data; + end Extract; + + function Extract(State : State_T) return Tag_Int_T is + Tag : Tag_Int_T; + begin + for i in 0 .. N / 2 - 1 loop + Tag(Tag'First + i * 4 .. Tag'First + i * 4 + 3) := State(2 * i + 1); + end loop; + return Tag; + end Extract; + + function "xor" (State : State_T; Data : Rate_Block) return State_T is + Ret : State_T := State; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Ret(2 * i + 1) xor Chunk_T'(Load_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1))); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Ret; + end "xor"; + + function "xor" (State : State_T; Tag : Tag_Int_T) return State_T is + Ret : State_T := State; + Index : Positive := Tag'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Ret(2 * i + 1) xor Tag(Index .. Index + 3); + Index := Index + 4; + end loop; + return Ret; + end "xor"; + + function set (State : State_T; Data : Rate_Block) return State_T is + Ret : State_T := State; + Index : Positive := Data'First; + begin + for i in 0 .. N / 2 - 1 loop + Ret(2 * i + 1) := Chunk_T'(Load_LE(Data(Index .. Index + 4 * Word_T'Size / 8 - 1))); + Index := Index + 4 * Word_T'Size / 8; + end loop; + return Ret; + end set; + + function "+" (Tag : Tag_Int_T) return Tag_T is + Ret : Tag_T; + begin + Store_LE(Ret, Tag); + return Ret; + end "+"; + + function Pad (Data : u8_Array) return Block_T is + Ret : Block_T := (others => 0); + begin + if Data'Length >= Block_T'Length then + raise Constraint_Error; + end if; + Ret(Ret'First .. Ret'First + Data'Length -1 ) := Data; + Ret(Ret'First + Data'Length) := 1; + return Ret; + end Pad; + + procedure Process_Header_Block (Context : in out Context_T; Block : Block_T; Block_Number : Block_Number_T) is + begin + Context.Tag := Context.Tag + Extract(Pi(Pi(Context + Block_Number) xor Block)); + end Process_Header_Block; + + procedure Process_Header_Last_Block (Context : in out Context_T; Block : u8_Array; Block_Number : Block_Number_T) is + Num : Block_Number_T := Block_Number; + Index : Integer := Block'First; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Process_Header_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Num := Num + 1; + Index := Index + Block_Bytes; + end loop; + Process_Header_Block(Context, Pad(Block(Index .. Block'Last)), Num); + Context.State := Pi(Context.State xor Context.Tag); + Context.Counter := Context.Counter + u64(Num); + end Process_Header_Last_Block; + + procedure Encrypt_Secret_Message_Number(Context : in out Context_T; Block : in out Block_T) is + State : constant State_T := Pi(Context + Block_Number_T'(1)) xor Block; + begin + Block := Extract(State); + Context.State := Pi(State); + Context.Tag := Context.Tag + Extract(Context.State); + Context.Counter := Context.Counter + 1; + end Encrypt_Secret_Message_Number; + + procedure Decrypt_Secret_Message_Number(Context : in out Context_T; Block : in out Block_T) is + State : constant State_T := Pi(Context + Block_Number_T'(1)) xor Block; + Block_In : constant Block_T := Block; + begin + Block := Extract(State); + Context.State := Pi(set(State, Block_In)); + Context.Tag := Context.Tag + Extract(Context.State); + Context.Counter := Context.Counter + 1; + end Decrypt_Secret_Message_Number; + + procedure Encrypt_Block(Context : in out Context_T; Block : in out Block_T; Block_Number : Block_Number_T) is + State : State_T := Pi(Context + Block_Number) xor Block; + begin + Block := Extract(State); + State := Pi(State); + Context.Tag := Context.Tag + Extract(State); + end Encrypt_Block; + + procedure Decrypt_Block(Context : in out Context_T; Block : in out Block_T; Block_Number : Block_Number_T) is + State : State_T := Pi(Context + Block_Number) xor Block; + In_Block : constant Block_T := Block; + begin + Block := Extract(State); + State := Pi(set(State, In_Block)); + Context.Tag := Context.Tag + Extract(State); + end Decrypt_Block; + + procedure Encrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array; Block_Number : Block_Number_T) is + State : State_T; + Index : Integer := Block'First; + Num : Block_Number_T := Block_Number; + Temp_Block : Block_T; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Encrypt_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Index := Index + Block_Bytes; + Num := Num + 1; + end loop; + Temp_Block := Pad(Block(Index .. Block'Last)); + State := Pi(Context + Num) xor Temp_Block; + Temp_Block := Extract(State); + Block(Index .. Block'Last) := Temp_Block(Temp_Block'First .. Temp_Block'First + Block'Last - Index); + State := Pi(State); + Context.Tag := Context.Tag + Extract(State); + end Encrypt_Last_Block; + + procedure Decrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array; Block_Number : Block_Number_T) is + State : State_T; + Index : Integer := Block'First; + Num : Block_Number_T := Block_Number; + Temp_Block : Block_T; + begin + for i in 1 .. Block'Length / Block_Bytes loop + Decrypt_Block(Context, Block(Index .. Index + Block_Bytes - 1), Num); + Index := Index + Block_Bytes; + Num := Num + 1; + end loop; + Temp_Block := Pad(Block(Index .. Block'Last)); + State := Pi(Context + Num) xor Temp_Block; + Block(Index .. Block'Last) := Extract(State)(Temp_Block'First .. Temp_Block'First + Block'Last - Index); + Temp_Block(Temp_Block'First + Block'Last - Index + 1 .. Temp_Block'Last) := Extract(State)(Temp_Block'First + Block'Last - Index + 1 .. Temp_Block'Last); + State := Pi(set(State, Temp_Block)); + Context.Tag := Context.Tag + Extract(State); + end Decrypt_Last_Block; + + function Get_Tag(Context : Context_T) return Tag_T is + begin + return +Context.Tag; + end Get_Tag; + + function Encrypt(Msg : u8_Array; AD : u8_Array; Public_Nonce : u8_Array; Secret_Nonce : Block_T; Key : u8_Array) return u8_Array is + Crypt : u8_Array(1 .. Secret_Nonce'Length + Msg'Length + Tag_Bytes); + Ctx : Context_T; + begin + Initialize(Context => Ctx, Key => Key, Public_Nonce => Public_Nonce); + Process_Header_Last_Block(Context => Ctx, Block => AD, Block_Number => 1); + Crypt(Crypt'First .. Crypt'First + Secret_Message_Number_Bytes - 1) := Secret_Nonce; + Crypt(Crypt'First + Secret_Message_Number_Bytes .. Crypt'Last - Tag_Bytes) := Msg; + Encrypt_Secret_Message_Number(Context => Ctx, Block => Crypt(Crypt'First .. Crypt'First + Secret_Message_Number_Bytes - 1)); + Encrypt_Last_Block(Context => Ctx, Block => Crypt(Crypt'First + Secret_Message_Number_Bytes .. Crypt'Last - Tag_Bytes), Block_Number => 1); + Crypt(Crypt'Last - Tag_Bytes + 1 .. Crypt'Last) := Get_Tag(Ctx); + return Crypt; + end Encrypt; + + procedure Decrypt(Is_Valid : out Boolean; Msg : out u8_Array; Secret_Nonce : out Block_T; Cipher : in u8_Array; AD : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array) is + Tag : Tag_T; + Ctx : Context_T; + begin + Initialize(Context => Ctx, Key => Key, Public_Nonce => Public_Nonce); + Process_Header_Last_Block(Context => Ctx, Block => AD, Block_Number => 1); + Secret_Nonce := Cipher(Cipher'First .. Cipher'First + Secret_Message_Number_Bytes - 1); + Msg := Cipher(Cipher'First + Secret_Message_Number_Bytes .. Cipher'Last - Tag_Bytes); + Decrypt_Secret_Message_Number(Context => Ctx, Block => Secret_Nonce); + Decrypt_Last_Block(Context => Ctx, Block => Msg, Block_Number => 1); + Tag := Get_Tag(Ctx); + Is_Valid := Tag = Cipher(Cipher'Last - Tag_Bytes + 1 .. Cipher'Last); + end Decrypt; + +end Pi64Cipher_Spec; + diff --git a/src/algorithms/pi-cipher/pi64cipher_spec.ads b/src/algorithms/pi-cipher/pi64cipher_spec.ads new file mode 100644 index 0000000..a8d2aa8 --- /dev/null +++ b/src/algorithms/pi-cipher/pi64cipher_spec.ads @@ -0,0 +1,75 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; + +package Pi64Cipher_Spec is + + type Context_T is private; + + Cipher_Name : constant String := "pi64cipher"; + Width_Bits : constant := 64; + + N : constant := 4; + R : constant := 3; + + IS_Bits : constant := (N * 4 * Width_Bits); + IS_Bytes : constant := IS_Bits / 8; + Rate_Bits : constant := IS_Bits / 2; + Rate_Bytes : constant := Rate_Bits / 8; + Capacity_Bits : constant := IS_Bits - Rate_Bits; + Capacity_Bytes : constant := Capacity_Bits / 8; + Block_Bits : constant := Rate_Bits; + Block_Bytes : constant := Block_Bits / 8; + Tag_Bits : constant := Rate_Bits; + Tag_Bytes : constant := Tag_Bits / 8; + Secret_Message_Number_Bits : constant := Block_Bits; + Secret_Message_Number_Bytes : constant := Secret_Message_Number_Bits / 8; + + subtype Block_Number_T is Natural; + + subtype Block_T is u8_Array (1 .. Rate_Bytes); + + procedure Initialize(Context : out Context_T; Key : in u8_Array; Public_Nonce : in u8_Array); +-- procedure Encrypt_Secret_Message_Number(Context : in out Context; Secret_Message_Number : in u8_Array); +-- procedure Header_Next_Block(Context : in out Context_T; Header : in u8_Array); +-- procedure Header_Last_Block(Context : in out Context_T; Header : in u8_Array); +-- procedure Encrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Encrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Decrypt_Next_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Decrypt_Last_Block(Context : in out Context_T; Block : in out u8_Array); +-- procedure Get_Tag(Context : in Context_T; Tag : out u8_Array); +-- function Is_Valid(Context : in Context_T; Tag : in u8_Array) return Boolean; + + function Encrypt(Msg : u8_Array; AD : u8_Array; Public_Nonce : u8_Array; Secret_Nonce : Block_T; Key : u8_Array) return u8_Array; + procedure Decrypt(Is_Valid : out Boolean; Msg : out u8_Array; Secret_Nonce : out Block_T; Cipher : in u8_Array; AD : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array); + + +private + + subtype Word_T is u64; + subtype Chunk_T is u64_Array(1 .. 4); + subtype Tag_Int_T is u64_Array(1 .. 4 * N / 2); + subtype Tag_T is u8_Array(1 .. Rate_Bytes); + + type State_T is array (1 .. N) of Chunk_T; + + type Context_T is record + State : State_T; + Tag : Tag_Int_T; + Counter : u64; + end record; + +end Pi64Cipher_Spec; diff --git a/src/algorithms/sha2/sha2_224.ads b/src/algorithms/sha2/sha2_224.ads index e7078e6..590d224 100644 --- a/src/algorithms/sha2/sha2_224.ads +++ b/src/algorithms/sha2/sha2_224.ads @@ -13,32 +13,15 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; -with Sha2_Small; +with SHA2_224_Spec; use SHA2_224_Spec; +with Hash_Generic; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u32; +package SHA2_224 is new Hash_Generic( Name_Intern => Name, + Context_T_Intern => Context_T, + Digest_Size_Bits_Intern => Digest_Size_Bits, + Block_Size_Bits_Intern => Block_Size_Bits, + Initialize_Intern => Initialize, + Next_Block_Intern => Next_Block, + Last_Block_Intern => Last_Block, + Get_Digest_Intern => Get_Digest ); -package SHA2_224 is - - type Context_T is private; - - Block_Size_Bits : constant := 512; - Digest_Size_Bits : constant := 224; - - Block_Size_Bytes : constant := (Block_Size_Bits) / 8; - Digest_Size_Bytes : constant := (Digest_Size_Bits) / 8; - - procedure Initialize(Context : out Context_T); - procedure Next_Block(Context : in out Context_T; Block : in Block_512_Bit); - procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); - procedure Get_Digest(Context : in out Context_T; Digest : out Block_224_Bit); - - procedure Hash(Data : in u8_array; Digest : out Block_224_Bit; Bits : in Integer := -1); - -private - - type Context_T is new Sha2_Small.Context_T; - -end SHA2_224; diff --git a/src/algorithms/sha2/sha2_224.adb b/src/algorithms/sha2/sha2_224_spec.adb similarity index 84% rename from src/algorithms/sha2/sha2_224.adb rename to src/algorithms/sha2/sha2_224_spec.adb index 0c18849..2feaa69 100644 --- a/src/algorithms/sha2/sha2_224.adb +++ b/src/algorithms/sha2/sha2_224_spec.adb @@ -13,7 +13,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -package body SHA2_224 is +package body SHA2_224_Spec is IV : constant u32_Array(1 .. 8) := ( @@ -42,15 +42,4 @@ package body SHA2_224 is Store_BE(Digest, Context.H(1 .. 7)); end; - - procedure Hash(Data : in u8_Array; Digest : out Block_224_Bit; Bits : in Integer := -1) is - Context : Context_T; - begin - Initialize(Context); - Last_Block(Context, Data, Bits); - Get_Digest(Context, Digest); - end; - - - -end SHA2_224; +end SHA2_224_Spec; diff --git a/src/algorithms/sha2/sha2_224_spec.ads b/src/algorithms/sha2/sha2_224_spec.ads new file mode 100644 index 0000000..80ca65f --- /dev/null +++ b/src/algorithms/sha2/sha2_224_spec.ads @@ -0,0 +1,44 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; +with Sha2_Small; + +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u32; + +package SHA2_224_Spec is + + Name : constant String := "SHA2-224"; + + type Context_T is private; + + Block_Size_Bits : constant := 512; + Digest_Size_Bits : constant := 224; + + Block_Size_Bytes : constant := (Block_Size_Bits) / 8; + Digest_Size_Bytes : constant := (Digest_Size_Bits) / 8; + + procedure Initialize(Context : out Context_T); + procedure Next_Block(Context : in out Context_T; Block : in Block_512_Bit); + procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); + procedure Get_Digest(Context : in out Context_T; Digest : out Block_224_Bit); + +private + + type Context_T is new Sha2_Small.Context_T; + +end SHA2_224_Spec; diff --git a/src/algorithms/sha2/sha2_256.ads b/src/algorithms/sha2/sha2_256.ads index f21af6d..fb26812 100644 --- a/src/algorithms/sha2/sha2_256.ads +++ b/src/algorithms/sha2/sha2_256.ads @@ -13,35 +13,15 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; -with Sha2_Small; +with SHA2_256_Spec; use SHA2_256_Spec; +with Hash_Generic; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u32; +package SHA2_256 is new Hash_Generic( Name_Intern => Name, + Context_T_Intern => Context_T, + Digest_Size_Bits_Intern => Digest_Size_Bits, + Block_Size_Bits_Intern => Block_Size_Bits, + Initialize_Intern => Initialize, + Next_Block_Intern => Next_Block, + Last_Block_Intern => Last_Block, + Get_Digest_Intern => Get_Digest ); -package SHA2_256 is - - type Context_T is private; - - Block_Size_Bits : constant := 512; - Digest_Size_Bits : constant := 256; - - Block_Size_Bytes : constant := (Block_Size_Bits) / 8; - Digest_Size_Bytes : constant := (Digest_Size_Bits) / 8; - - subtype Block_T is u8_Array(1 .. Block_Size_Bytes); - subtype Digest_T is u8_Array(1 .. Digest_Size_Bytes); - - procedure Initialize(Context : out Context_T); - procedure Next_Block(Context : in out Context_T; Block : in Block_T); - procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); - procedure Get_Digest(Context : in out Context_T; Digest : out Digest_T); - - procedure Hash(Data : in u8_array; Digest : out Digest_T; Bits : in Integer := -1); - -private - - type Context_T is new Sha2_Small.Context_T; - -end SHA2_256; diff --git a/src/algorithms/sha2/sha2_256.adb b/src/algorithms/sha2/sha2_256_spec.adb similarity index 84% rename from src/algorithms/sha2/sha2_256.adb rename to src/algorithms/sha2/sha2_256_spec.adb index b1cbeac..0dd1ab8 100644 --- a/src/algorithms/sha2/sha2_256.adb +++ b/src/algorithms/sha2/sha2_256_spec.adb @@ -13,7 +13,11 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -package body SHA2_256 is +with Crypto_Types; + +package body SHA2_256_Spec is + + use Crypto_Types.Crypto_Utils_u32; IV : constant u32_Array(1 .. 8) := ( @@ -42,15 +46,4 @@ package body SHA2_256 is Store_BE(Digest, Context.H); end; - - procedure Hash(Data : in u8_Array; Digest : out Block_256_Bit; Bits : in Integer := -1) is - Context : Context_T; - begin - Initialize(Context); - Last_Block(Context, Data, Bits); - Get_Digest(Context, Digest); - end; - - - -end SHA2_256; +end SHA2_256_Spec; diff --git a/src/algorithms/sha2/sha2_256_spec.ads b/src/algorithms/sha2/sha2_256_spec.ads new file mode 100644 index 0000000..74c30a2 --- /dev/null +++ b/src/algorithms/sha2/sha2_256_spec.ads @@ -0,0 +1,44 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Sha2_Small; + +package SHA2_256_Spec is + + Name : constant String := "SHA2-256"; + + type Context_T is private; + + Block_Size_Bits : constant := 512; + Digest_Size_Bits : constant := 256; + + Block_Size_Bytes : constant := (Block_Size_Bits) / 8; + Digest_Size_Bytes : constant := (Digest_Size_Bits) / 8; + + subtype Block_T is u8_Array(1 .. Block_Size_Bytes); + subtype Digest_T is u8_Array(1 .. Digest_Size_Bytes); + + procedure Initialize(Context : out Context_T); + procedure Next_Block(Context : in out Context_T; Block : in Block_T); + procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); + procedure Get_Digest(Context : in out Context_T; Digest : out Digest_T); + + +private + + type Context_T is new Sha2_Small.Context_T; + +end SHA2_256_Spec; diff --git a/src/algorithms/sha2/sha2_384.ads b/src/algorithms/sha2/sha2_384.ads index 6302e48..66b6a4a 100644 --- a/src/algorithms/sha2/sha2_384.ads +++ b/src/algorithms/sha2/sha2_384.ads @@ -13,32 +13,15 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; -with Sha2_Large; +with SHA2_384_Spec; use SHA2_384_Spec; +with Hash_Generic; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u64; +package SHA2_384 is new Hash_Generic( Name_Intern => Name, + Context_T_Intern => Context_T, + Digest_Size_Bits_Intern => Digest_Size_Bits, + Block_Size_Bits_Intern => Block_Size_Bits, + Initialize_Intern => Initialize, + Next_Block_Intern => Next_Block, + Last_Block_Intern => Last_Block, + Get_Digest_Intern => Get_Digest ); -package SHA2_384 is - - type Context_T is private; - - Block_Size_Bits : constant := 1024; - Digest_Size_Bits : constant := 384; - - Block_Size_Bytes : constant := (Block_Size_Bits) / 8; - Digest_Size_Bytes : constant := (Digest_Size_Bits) / 8; - - procedure Initialize(Context : out Context_T); - procedure Next_Block(Context : in out Context_T; Block : in Block_1024_Bit); - procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); - procedure Get_Digest(Context : in out Context_T; Digest : out Block_384_Bit); - - procedure Hash(Data : in u8_array; Digest : out Block_384_Bit; Bits : in Integer := -1); - -private - - type Context_T is new Sha2_Large.Context_T; - -end SHA2_384; diff --git a/src/algorithms/sha2/sha2_384.adb b/src/algorithms/sha2/sha2_384_spec.adb similarity index 84% rename from src/algorithms/sha2/sha2_384.adb rename to src/algorithms/sha2/sha2_384_spec.adb index ef04668..62deaf2 100644 --- a/src/algorithms/sha2/sha2_384.adb +++ b/src/algorithms/sha2/sha2_384_spec.adb @@ -13,7 +13,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -package body SHA2_384 is +package body SHA2_384_Spec is IV : constant u64_Array(1 .. 8) := ( @@ -42,15 +42,4 @@ package body SHA2_384 is Store_BE(Digest, Context.H(1 .. 6)); end; - - procedure Hash(Data : in u8_Array; Digest : out Block_384_Bit; Bits : in Integer := -1) is - Context : Context_T; - begin - Initialize(Context); - Last_Block(Context, Data, Bits); - Get_Digest(Context, Digest); - end; - - - -end SHA2_384; +end SHA2_384_Spec; diff --git a/src/algorithms/sha2/sha2_384_spec.ads b/src/algorithms/sha2/sha2_384_spec.ads new file mode 100644 index 0000000..759925f --- /dev/null +++ b/src/algorithms/sha2/sha2_384_spec.ads @@ -0,0 +1,44 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; +with Sha2_Large; + +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u64; + +package SHA2_384_Spec is + + Name : constant String := "SHA2-384"; + + type Context_T is private; + + Block_Size_Bits : constant := 1024; + Digest_Size_Bits : constant := 384; + + Block_Size_Bytes : constant := (Block_Size_Bits) / 8; + Digest_Size_Bytes : constant := (Digest_Size_Bits) / 8; + + procedure Initialize(Context : out Context_T); + procedure Next_Block(Context : in out Context_T; Block : in Block_1024_Bit); + procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); + procedure Get_Digest(Context : in out Context_T; Digest : out Block_384_Bit); + +private + + type Context_T is new Sha2_Large.Context_T; + +end SHA2_384_Spec; diff --git a/src/algorithms/sha2/sha2_512.ads b/src/algorithms/sha2/sha2_512.ads index a4027bc..6648916 100644 --- a/src/algorithms/sha2/sha2_512.ads +++ b/src/algorithms/sha2/sha2_512.ads @@ -13,32 +13,15 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; -with Sha2_Large; +with SHA2_512_Spec; use SHA2_512_Spec; +with Hash_Generic; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u64; +package SHA2_512 is new Hash_Generic( Name_Intern => Name, + Context_T_Intern => Context_T, + Digest_Size_Bits_Intern => Digest_Size_Bits, + Block_Size_Bits_Intern => Block_Size_Bits, + Initialize_Intern => Initialize, + Next_Block_Intern => Next_Block, + Last_Block_Intern => Last_Block, + Get_Digest_Intern => Get_Digest ); -package SHA2_512 is - - type Context_T is private; - - Block_Size_Bits : constant := 1024; - Digest_Size_Bits : constant := 512; - - Block_Size_Bytes : constant := (Block_Size_Bits) / 8; - Digest_Size_Bytes : constant := (Digest_Size_Bits) / 8; - - procedure Initialize(Context : out Context_T); - procedure Next_Block(Context : in out Context_T; Block : in Block_1024_Bit); - procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); - procedure Get_Digest(Context : in out Context_T; Digest : out Block_512_Bit); - - procedure Hash(Data : in u8_array; Digest : out Block_512_Bit; Bits : in Integer := -1); - -private - - type Context_T is new Sha2_Large.Context_T; - -end SHA2_512; diff --git a/src/algorithms/sha2/sha2_512.adb b/src/algorithms/sha2/sha2_512_spec.adb similarity index 84% rename from src/algorithms/sha2/sha2_512.adb rename to src/algorithms/sha2/sha2_512_spec.adb index 22c9c5c..24289f8 100644 --- a/src/algorithms/sha2/sha2_512.adb +++ b/src/algorithms/sha2/sha2_512_spec.adb @@ -13,7 +13,7 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -package body SHA2_512 is +package body SHA2_512_Spec is IV : constant u64_Array(1 .. 8) := ( @@ -42,15 +42,4 @@ package body SHA2_512 is Store_BE(Digest, Context.H); end; - - procedure Hash(Data : in u8_Array; Digest : out Block_512_Bit; Bits : in Integer := -1) is - Context : Context_T; - begin - Initialize(Context); - Last_Block(Context, Data, Bits); - Get_Digest(Context, Digest); - end; - - - -end SHA2_512; +end SHA2_512_Spec; diff --git a/src/algorithms/sha2/sha2_512_spec.ads b/src/algorithms/sha2/sha2_512_spec.ads new file mode 100644 index 0000000..42833a5 --- /dev/null +++ b/src/algorithms/sha2/sha2_512_spec.ads @@ -0,0 +1,44 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; +with Sha2_Large; + +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u64; + +package SHA2_512_Spec is + + Name : constant String := "SHA2-512"; + + type Context_T is private; + + Block_Size_Bits : constant := 1024; + Digest_Size_Bits : constant := 512; + + Block_Size_Bytes : constant := (Block_Size_Bits) / 8; + Digest_Size_Bytes : constant := (Digest_Size_Bits) / 8; + + procedure Initialize(Context : out Context_T); + procedure Next_Block(Context : in out Context_T; Block : in Block_1024_Bit); + procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); + procedure Get_Digest(Context : in out Context_T; Digest : out Block_512_Bit); + +private + + type Context_T is new Sha2_Large.Context_T; + +end SHA2_512_Spec; diff --git a/src/algorithms/sha2/sha2_large.ads b/src/algorithms/sha2/sha2_large.ads index 9516a28..da875ca 100644 --- a/src/algorithms/sha2/sha2_large.ads +++ b/src/algorithms/sha2/sha2_large.ads @@ -16,8 +16,8 @@ with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u64; +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u64; package SHA2_Large is diff --git a/src/algorithms/sha2/sha2_small.adb b/src/algorithms/sha2/sha2_small.adb index 7cc8936..42626aa 100644 --- a/src/algorithms/sha2/sha2_small.adb +++ b/src/algorithms/sha2/sha2_small.adb @@ -13,6 +13,10 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . +with Crypto_Types; use Crypto_Types; +use Crypto_Types.Crypto_Utils_u32; +use Crypto_Types.Crypto_Utils_u64; + package body SHA2_Small is K : constant u32_Array(1 .. 64) := diff --git a/src/algorithms/sha2/sha2_small.ads b/src/algorithms/sha2/sha2_small.ads index e5bedcc..dda864b 100644 --- a/src/algorithms/sha2/sha2_small.ads +++ b/src/algorithms/sha2/sha2_small.ads @@ -14,11 +14,6 @@ -- along with this program. If not, see . with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; - -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u32; -use Crypto_Types.Crypto_Types_u64; package SHA2_Small is diff --git a/src/algorithms/sha3/keccak.adb b/src/algorithms/sha3/keccak.adb index 161c811..984a93f 100644 --- a/src/algorithms/sha3/keccak.adb +++ b/src/algorithms/sha3/keccak.adb @@ -121,7 +121,7 @@ package body Keccak is 16#8000000080008081#, -- round 21 16#8000000000008080#, -- round 22 16#0000000080000001#, -- round 23 - 16#8000000080008008# -- round 24 + 16#8000000080008008# -- round 24 ); begin A(0, 0) := A(0, 0) xor Round_Constants(round); diff --git a/src/algorithms/sha3/keccak.ads b/src/algorithms/sha3/keccak.ads index 7a250e1..c3906a7 100644 --- a/src/algorithms/sha3/keccak.ads +++ b/src/algorithms/sha3/keccak.ads @@ -17,8 +17,8 @@ with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; with Keccak_Parameters; use Keccak_Parameters; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u64; +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u64; package Keccak is diff --git a/src/algorithms/sha3/keccak_parameters.ads b/src/algorithms/sha3/keccak_parameters.ads index 463015b..8189877 100644 --- a/src/algorithms/sha3/keccak_parameters.ads +++ b/src/algorithms/sha3/keccak_parameters.ads @@ -16,8 +16,8 @@ with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u64; +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u64; package Keccak_Parameters is diff --git a/src/algorithms/sha3/sha3.ads b/src/algorithms/sha3/sha3.ads index 1673dca..f1573c9 100644 --- a/src/algorithms/sha3/sha3.ads +++ b/src/algorithms/sha3/sha3.ads @@ -14,12 +14,49 @@ -- along with this program. If not, see . with SHA3_Generic; +with Hash_Generic; package SHA3 is - package SHA3_224 is new SHA3_Generic(Capacity_Bits => 448); - package SHA3_256 is new SHA3_Generic(Capacity_Bits => 512); - package SHA3_384 is new SHA3_Generic(Capacity_Bits => 768); - package SHA3_512 is new SHA3_Generic(Capacity_Bits => 1024); + package SHA3_224_Spec is new SHA3_Generic(Capacity_Bits => 448); + package SHA3_256_Spec is new SHA3_Generic(Capacity_Bits => 512); + package SHA3_384_Spec is new SHA3_Generic(Capacity_Bits => 768); + package SHA3_512_Spec is new SHA3_Generic(Capacity_Bits => 1024); + + package SHA3_224 is new Hash_Generic( Name_Intern => "SHA3-224", + Context_T_Intern => SHA3_224_Spec.Context_T, + Digest_Size_Bits_Intern => SHA3_224_Spec.Digest_Size_Bits, + Block_Size_Bits_Intern => SHA3_224_Spec.Block_Size_Bits, + Initialize_Intern => SHA3_224_Spec.Initialize, + Next_Block_Intern => SHA3_224_Spec.Next_Block, + Last_Block_Intern => SHA3_224_Spec.Last_Block, + Get_Digest_Intern => SHA3_224_Spec.Get_Digest ); + + package SHA3_256 is new Hash_Generic( Name_Intern => "SHA3-256", + Context_T_Intern => SHA3_256_Spec.Context_T, + Digest_Size_Bits_Intern => SHA3_256_Spec.Digest_Size_Bits, + Block_Size_Bits_Intern => SHA3_256_Spec.Block_Size_Bits, + Initialize_Intern => SHA3_256_Spec.Initialize, + Next_Block_Intern => SHA3_256_Spec.Next_Block, + Last_Block_Intern => SHA3_256_Spec.Last_Block, + Get_Digest_Intern => SHA3_256_Spec.Get_Digest ); + + package SHA3_384 is new Hash_Generic( Name_Intern => "SHA3-384", + Context_T_Intern => SHA3_384_Spec.Context_T, + Digest_Size_Bits_Intern => SHA3_384_Spec.Digest_Size_Bits, + Block_Size_Bits_Intern => SHA3_384_Spec.Block_Size_Bits, + Initialize_Intern => SHA3_384_Spec.Initialize, + Next_Block_Intern => SHA3_384_Spec.Next_Block, + Last_Block_Intern => SHA3_384_Spec.Last_Block, + Get_Digest_Intern => SHA3_384_Spec.Get_Digest ); + + package SHA3_512 is new Hash_Generic( Name_Intern => "SHA3-512", + Context_T_Intern => SHA3_512_Spec.Context_T, + Digest_Size_Bits_Intern => SHA3_512_Spec.Digest_Size_Bits, + Block_Size_Bits_Intern => SHA3_512_Spec.Block_Size_Bits, + Initialize_Intern => SHA3_512_Spec.Initialize, + Next_Block_Intern => SHA3_512_Spec.Next_Block, + Last_Block_Intern => SHA3_512_Spec.Last_Block, + Get_Digest_Intern => SHA3_512_Spec.Get_Digest ); end SHA3; diff --git a/src/algorithms/sha3/sha3_generic.adb b/src/algorithms/sha3/sha3_generic.adb index 065985d..3a9d9cf 100644 --- a/src/algorithms/sha3/sha3_generic.adb +++ b/src/algorithms/sha3/sha3_generic.adb @@ -124,7 +124,7 @@ package body Sha3_Generic is Squeeze(Context, Digest); end Get_Digest; - procedure Hash(Data : in u8_array; Digest : out Digest_T; Bits : in Integer := -1) is + procedure Hash(Data : in u8_Array; Digest : out Digest_T; Bits : in Integer := -1) is Ctx : Context_T; begin Initialize(Ctx); diff --git a/src/algorithms/sha3/sha3_generic.ads b/src/algorithms/sha3/sha3_generic.ads index cb6a859..22d0637 100644 --- a/src/algorithms/sha3/sha3_generic.ads +++ b/src/algorithms/sha3/sha3_generic.ads @@ -18,8 +18,8 @@ with Crypto_Types; use Crypto_Types; with Keccak_Parameters; use Keccak_Parameters; with Keccak; use Keccak; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u64; +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u64; generic Capacity_Bits : Capacity_T; @@ -44,7 +44,7 @@ package Sha3_Generic is procedure Squeeze(Context : in out Context_T; Data : out u8_Array); procedure Get_Digest(Context : in out Context_T; Digest : out Digest_T); - procedure Hash(Data : in u8_array; Digest : out Digest_T; Bits : in Integer := -1); + procedure Hash(Data : in u8_Array; Digest : out Digest_T; Bits : in Integer := -1); private diff --git a/src/algorithms/spritz/spritz.ads b/src/algorithms/spritz/spritz.ads index e71734e..26b77da 100644 --- a/src/algorithms/spritz/spritz.ads +++ b/src/algorithms/spritz/spritz.ads @@ -16,7 +16,7 @@ with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; package Spritz is diff --git a/src/algorithms/spritz/spritz_aead.ads b/src/algorithms/spritz/spritz_aead.ads index 500ae98..955e022 100644 --- a/src/algorithms/spritz/spritz_aead.ads +++ b/src/algorithms/spritz/spritz_aead.ads @@ -17,7 +17,7 @@ with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; with Spritz; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; package Spritz_AEAD is diff --git a/src/algorithms/spritz/spritz_hash.ads b/src/algorithms/spritz/spritz_hash.ads index 307d8fe..e07e72c 100644 --- a/src/algorithms/spritz/spritz_hash.ads +++ b/src/algorithms/spritz/spritz_hash.ads @@ -17,7 +17,7 @@ with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; with Spritz; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; package Spritz_Hash is @@ -36,5 +36,4 @@ private ctx : Spritz.Context; end record; - end Spritz_Hash; \ No newline at end of file diff --git a/src/algorithms/spritz/spritz_stream.ads b/src/algorithms/spritz/spritz_stream.ads index b11b79b..ba09f54 100644 --- a/src/algorithms/spritz/spritz_stream.ads +++ b/src/algorithms/spritz/spritz_stream.ads @@ -17,7 +17,7 @@ with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; with Spritz; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; package Spritz_Stream is diff --git a/src/main.adb b/src/main.adb deleted file mode 100644 index ae3828a..0000000 --- a/src/main.adb +++ /dev/null @@ -1,222 +0,0 @@ --- Copyright (C) 2015 Daniel Otte --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -with Ada.Text_IO; use Ada.Text_IO; --- with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; -with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; - -with Spritz_Stream; -with Spritz_Hash; - -with AES; - -with ARIA; - -with SHA2_256; - -use Crypto_Types.Crypto_Types_u8; - -procedure main is --- package u8_IO is new Crypto_Types.u8_Sequential_IO; - - procedure Print_Hex(value : in u8) is - hex_table : constant array (0 .. 15) of Character := - ( '0', '1', '2', '3', - '4', '5', '6', '7', - '8', '9', 'a', 'b', - 'c', 'd', 'e', 'f'); - begin - Put(hex_table(Integer(Shift_Right(value, 4)))); - Put(hex_table(Integer(value and 16#F#))); - end; - - procedure Print_Hex(value : in u8_Array) is - begin - for i in value'Range loop - print_hex(value(i)); - Put(" "); - end loop; - end; - - procedure test_spritz_stream(s : in String) is - ctx : Spritz_Stream.Context; - z : u8_Array(1 .. 8) := (others => 0); - begin - Spritz_Stream.Initialize(ctx, key => s); - Put(s); - for i in 0 .. 6 - s'Length loop - Put(" "); - end loop; - Put(": "); - Spritz_Stream.Encrypt(ctx, z); - print_hex(z); - New_Line; - end test_spritz_stream; - - procedure test_spritz_hash(s : in String) is - ctx : Spritz_Hash.Context; - hash : u8_Array(1 .. 32); - begin - Spritz_Hash.Initialize(ctx); - Spritz_Hash.Add_Data(ctx, s); - Spritz_Hash.Extract_Hash(ctx => ctx, Hash => hash); - Put(s); - for i in 0 .. 6 - s'Length loop - Put(" "); - end loop; - Put(": "); - print_hex(hash(1 .. 8)); - New_Line; - end test_spritz_hash; - - procedure test_aes is - key : AES.Key_256_T; - block : AES.Block_T; - ctx128 : AES.Context_128_T; - ctx192 : AES.Context_192_T; - ctx256 : AES.Context_256_T; - begin - for i in key'Range loop - key(i) := u8(i - 1); - end loop; - block(block'First) := 0; - for i in block'First + 1 .. block'Last loop - block(i) := u8(block(i - 1) + 16#11#); - end loop; - AES.Initialize(ctx128, key(1 .. 16)); - AES.Encrypt(ctx128, block); - print_hex(block); New_Line; - AES.Decrypt(ctx128, block); - print_hex(block); New_Line; - - AES.Initialize(ctx192, key(1 .. 24)); - AES.Encrypt(ctx192, block); - print_hex(block); New_Line; - AES.Decrypt(ctx192, block); - print_hex(block); New_Line; - - AES.Initialize(ctx256, key); - AES.Encrypt(ctx256, block); - print_hex(block); New_Line; - AES.Decrypt(ctx256, block); - print_hex(block); New_Line; - end test_aes; - --- --- procedure test_aes_128b is --- key : constant AES.Key_128 := ( --- 16#2b#, 16#7e#, 16#15#, 16#16#, --- 16#28#, 16#ae#, 16#d2#, 16#a6#, --- 16#ab#, 16#f7#, 16#15#, 16#88#, --- 16#09#, 16#cf#, 16#4f#, 16#3c# ); --- block : Block_128_bit := ( --- 16#32#, 16#43#, 16#f6#, 16#a8#, --- 16#88#, 16#5a#, 16#30#, 16#8d#, --- 16#31#, 16#31#, 16#98#, 16#a2#, --- 16#e0#, 16#37#, 16#07#, 16#34# ); --- ctx : AES.Context_128; --- begin --- AES.Initialize(key, ctx); --- AES.Encrypt(ctx, block); --- print_hex(block); --- end test_aes_128b; - - procedure test_aria is - Context : Aria.Context_T; - key : Aria.Key_256; - Block : Block_128_Bit := (others => 0); - begin - for i in Key'Range loop - Key(i) := u8(i - 1); - end loop; - - for i in 2 .. Block'Last loop - Block(i) := Block(i - 1) + 16#11#; - end loop; - Aria.Initialize(Key => ARIA.Key_128(key(1 .. 16)), Context => Context); - Put("Plaintext: "); print_hex(Block); New_Line; - Aria.Encrypt(Block => Block, Context => Context); - Put("Ciphertext: "); print_hex(Block); New_Line; - Aria.Decrypt(Block => Block, Context => Context); - Put("Plaintext: "); print_hex(Block); New_Line; - New_Line; - - Block(1) := 0; - for i in 2 .. Block'Last loop - Block(i) := Block(i - 1) + 16#11#; - end loop; - Aria.Initialize(Key => ARIA.Key_192(key(1 .. 24)), Context => Context); - Put("Plaintext: "); print_hex(Block); New_Line; - Aria.Encrypt(Block => Block, Context => Context); - Put("Ciphertext: "); print_hex(Block); New_Line; - Aria.Decrypt(Block => Block, Context => Context); - Put("Plaintext: "); print_hex(Block); New_Line; - New_Line; - - Block(1) := 0; - for i in 2 .. Block'Last loop - Block(i) := Block(i - 1) + 16#11#; - end loop; - Aria.Initialize(Key => key, Context => Context); - Put("Plaintext: "); print_hex(Block); New_Line; - Aria.Encrypt(Block => Block, Context => Context); - Put("Ciphertext: "); print_hex(Block); New_Line; - Aria.Decrypt(Block => Block, Context => Context); - Put("Plaintext: "); print_hex(Block); New_Line; - New_Line; - end; - - procedure test_sha256(Msg : String) is - Data : u8_Array(1 .. Msg'Length); - Digest : Block_256_Bit; - begin - Put("""" & Msg & """: "); - for i in data'Range loop - Data(i) := u8(Character'Pos(Msg(Msg'First + i - Data'First))); - end loop; - Sha2_256.Hash(Data, Digest); - Print_Hex(Digest); - New_Line; - end test_sha256; - - --- Random_File : File_Type; -begin - test_spritz_stream("ABC"); - test_spritz_stream("spam"); - test_spritz_stream("arcfour"); - New_Line; - - test_spritz_hash("ABC"); - test_spritz_hash("spam"); - test_spritz_hash("arcfour"); - New_Line; - - Put_Line("AES.Context_128'Size: " & Integer'Image(AES.Context_128_T'Size / 8)); - Put_Line("AES.Context_192'Size: " & Integer'Image(AES.Context_192_T'Size / 8)); - Put_Line("AES.Context_256'Size: " & Integer'Image(AES.Context_256_T'Size / 8)); - test_aes; - New_Line; - - Put_Line("ARIA.Context_T'Size: " & Integer'Image(ARIA.Context_T'Size / 8)); - test_aria; - New_Line; - - Put_Line("SHA2_256.Context_T'Size: " & Integer'Image(SHA2_256.Context_T'Size / 8)); - test_sha256("abc"); - test_sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); - New_Line; -end main; diff --git a/src/tests/nessie_bc_test_generator.adb b/src/test_modules/nessie_bc_test_generator.adb similarity index 97% rename from src/tests/nessie_bc_test_generator.adb rename to src/test_modules/nessie_bc_test_generator.adb index ec79c97..f2ffb6c 100644 --- a/src/tests/nessie_bc_test_generator.adb +++ b/src/test_modules/nessie_bc_test_generator.adb @@ -20,7 +20,7 @@ with Ada.Strings; use Ada.Strings; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Crypto_Types; use Crypto_Types; with System; use System; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; -- ******************************************************************************** @@ -54,6 +54,7 @@ use Crypto_Types.Crypto_Types_u8; package body Nessie_BC_Test_Generator is + use Cipher; Total_Number_Of_Encrypts : constant Natural := (Key_Size_Bits + Block_Size_Bits + 256 + 2) * (1 + 1000 + 1); @@ -85,8 +86,8 @@ package body Nessie_BC_Test_Generator is Put_Line("* SteelCrypt - NESSIE TestVectors *"); Put_Line("********************************************************************************"); New_Line; - Put_Line("Primitive Name: " & Name); - Put_Line((16 + Name'Length) * '='); + Put_Line("Primitive Name: " & Cipher.Name); + Put_Line((16 + Cipher.Name'Length) * '='); Put_Line("Key size:" & Integer'Image(Key_Size_Bits) & " bits"); Put_Line("Block size:" & Integer'Image(Block_Size_Bits) & " bits"); New_Line; @@ -191,7 +192,7 @@ package body Nessie_BC_Test_Generator is if Verbose then -- Set_Col(File => Standard_Error, To => 1); Put(File => Standard_Error, - Item => Character'Val(13) & " ==> " & Name & ": "); + Item => Character'Val(13) & " ==> " & Cipher.Name & ": "); -- Put(File => Standard_Error, Item => Float'Image(100.0 * Float(Step) / Float(Total_Number_Of_Primitive_Runs)) & "%"); Put(File => Standard_Error, Item => 100.0 * Float(Step) / Float(Total_Number_Of_Primitive_Runs), @@ -315,7 +316,7 @@ package body Nessie_BC_Test_Generator is procedure Run_File is begin - Run(Name & Default_Suffix); + Run(Cipher.Name & Default_Suffix); end Run_File; diff --git a/src/tests/nessie_bc_test_generator.ads b/src/test_modules/nessie_bc_test_generator.ads similarity index 76% rename from src/tests/nessie_bc_test_generator.ads rename to src/test_modules/nessie_bc_test_generator.ads index a2ae125..1607d6b 100644 --- a/src/tests/nessie_bc_test_generator.ads +++ b/src/test_modules/nessie_bc_test_generator.ads @@ -14,7 +14,7 @@ -- along with this program. If not, see . with Crypto_Core_Types; use Crypto_Core_Types; - +with Block_Cipher_Generic; -- -- ******************************************************************************** @@ -48,13 +48,7 @@ with Crypto_Core_Types; use Crypto_Core_Types; generic - Name : String; - Key_Size_Bits : Natural; - Block_Size_Bits : Natural; - type Context_T is private; - with procedure Initialize(Context : out Context_T; Key : in u8_Array); - with procedure Encrypt(Context : in Context_T; Block : in out u8_Array); - with procedure Decrypt(Context : in Context_T; Block : in out u8_Array); + with package Cipher is new Block_Cipher_Generic(<>); package Nessie_BC_Test_Generator is @@ -67,10 +61,7 @@ package Nessie_BC_Test_Generator is private - Key_Size_Bytes : constant Natural := (Key_Size_Bits + 7) / 8; - Block_Size_Bytes : constant Natural := (Block_Size_Bits + 7) / 8; - - subtype Key_T is u8_Array( 1 .. Key_Size_Bytes ); - subtype Block_T is u8_Array( 1 .. Block_Size_Bytes ); + subtype Key_T is u8_Array( 1 .. Cipher.Key_Size_Bytes ); + subtype Block_T is u8_Array( 1 .. Cipher.Block_Size_Bytes ); end Nessie_BC_Test_Generator; diff --git a/src/tests/nessie_hash_test_generator.adb b/src/test_modules/nessie_hash_test_generator.adb similarity index 75% rename from src/tests/nessie_hash_test_generator.adb rename to src/test_modules/nessie_hash_test_generator.adb index 288c1c2..d43de05 100644 --- a/src/tests/nessie_hash_test_generator.adb +++ b/src/test_modules/nessie_hash_test_generator.adb @@ -14,66 +14,17 @@ -- along with this program. If not, see . with Ada.Text_IO; use Ada.Text_IO; -with Ada.Float_Text_IO; use Ada.Float_Text_IO; with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; with Ada.Strings; use Ada.Strings; with Ada.Strings.Fixed; use Ada.Strings.Fixed; with Crypto_Types; use Crypto_Types; with System; use System; -use Crypto_Types.Crypto_Types_u8; - --- Test vectors -- set 1 --- ===================== --- --- Set 1, vector# 0: --- message="" (empty string) --- hash=E3B0C44298FC1C149AFBF4C8996FB924 --- 27AE41E4649B934CA495991B7852B855 --- --- Set 1, vector# 1: --- message="a" --- hash=CA978112CA1BBDCAFAC231B39A23DC4D --- A786EFF8147C4E72B9807785AFEE48BB --- --- Set 1, vector# 2: --- message="abc" --- hash=BA7816BF8F01CFEA414140DE5DAE2223 --- B00361A396177A9CB410FF61F20015AD --- --- Set 1, vector# 3: --- message="message digest" --- hash=F7846F55CF23E14EEBEAB5B4E1550CAD --- 5B509E3348FBC4EFA3A1413D393CB650 --- --- Set 1, vector# 4: --- message="abcdefghijklmnopqrstuvwxyz" --- hash=71C480DF93D6AE2F1EFAD1447C66C952 --- 5E316218CF51FC8D9ED832F2DAF18B73 --- --- Set 1, vector# 5: --- message="abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" --- hash=248D6A61D20638B8E5C026930C3E6039 --- A33CE45964FF2167F6ECEDD419DB06C1 --- --- Set 1, vector# 6: --- message="A...Za...z0...9" --- hash=DB4BFCBD4DA0CD85A60C3C37D3FBD880 --- 5C77F15FC6B1FDFE614EE0A7C8FDB4C0 --- --- Set 1, vector# 7: --- message=8 times "1234567890" --- hash=F371BC4A311F2B009EEF952DD83CA80E --- 2B60026C8E935592D0F9C308453C813E --- --- Set 1, vector# 8: --- message=1 million times "a" --- hash=CDC76E5C9914FB9281A1C7E284D73E67 --- F1809A48A497200E046D39CCC7112CD0 - - +use Crypto_Types.Crypto_Utils_u8; package body Nessie_Hash_Test_Generator is + use Hash; + Set_1_Labels : constant array (1 .. 9) of access constant String := ( new String'("""" & """" & " (empty string)"), @@ -100,19 +51,15 @@ package body Nessie_Hash_Test_Generator is "1234567890123456789012345678901234567890") ); - - Step : Natural; - - procedure Print_Header is begin Put_Line("********************************************************************************"); Put_Line("* SteelCrypt - NESSIE TestVectors *"); Put_Line("********************************************************************************"); New_Line; - Put_Line("Primitive Name: " & Name); - Put_Line((16 + Name'Length) * '='); - Put_Line("Hash size:" & Integer'Image(Digest_Size_Bits) & " bits"); + Put_Line("Primitive Name: " & Hash.Name); + Put_Line((16 + Hash.Name'Length) * '='); + Put_Line("Hash size:" & Integer'Image(Hash.Digest_Size_Bits) & " bits"); New_Line; end Print_Header; @@ -168,7 +115,7 @@ package body Nessie_Hash_Test_Generator is procedure Hash_Test(Data : in u8_Array; Bits : in Integer := -1) is Digest : u8_Array(1 .. Digest_Size_Bytes); begin - Hash(Data => Data, Digest => Digest, Bits => Bits); + Hash.Hash(Data => Data, Digest => Digest, Bits => Bits); Print_Item("hash", Digest); end Hash_Test; @@ -177,32 +124,6 @@ package body Nessie_Hash_Test_Generator is Hash_Test(From_Ascii(Data)); end; - - procedure Initialize_Display is - begin - Step := 0; - if Verbose then - New_Line(File => Standard_Error); - end if; - end Initialize_Display; - - procedure Update_Display is - begin - if Verbose then --- Put(File => Standard_Error, --- Item => Character'Val(13) & " ==> " & Name & ": "); --- -- Put(File => Standard_Error, Item => Float'Image(100.0 * Float(Step) / Float(Total_Number_Of_Primitive_Runs)) & "%"); --- Put(File => Standard_Error, --- Item => 100.0 * Float(Step) / Float(Total_Number_Of_Primitive_Runs), --- Fore => 3, --- Aft => 2, --- Exp => 0 ); --- Put(File => Standard_Error, --- Item => '%' ); - null; - end if; - end Update_Display; - procedure Set_1_Vector_8 is Block : constant u8_Array(1 .. Block_Size_Bytes) := (others => Character'Pos('a')); Ctx : Context_T; @@ -279,7 +200,7 @@ package body Nessie_Hash_Test_Generator is Print_Item("message", Trim(Integer'Image(Digest_Size_Bits), Both) & " zero bits"); Hash_Test(Digest); for i in 1 .. 100_000 loop - Hash(Digest, Digest); + Hash.Hash(Digest, Digest); end loop; Print_Item("iterated 100000 times", Digest); New_Line; @@ -289,7 +210,6 @@ package body Nessie_Hash_Test_Generator is File : File_Type; Redirected : Boolean := False; begin --- Initialize_Display; if FileName /= "" and FileName /= "-" then Redirected := True; Create(File => File, Name => FileName, Mode => Out_File); @@ -311,8 +231,7 @@ package body Nessie_Hash_Test_Generator is procedure Run_File is begin - Run(Name & Default_Suffix); + Run(Hash.Name & Default_Suffix); end Run_File; - end Nessie_Hash_Test_Generator; diff --git a/src/tests/nessie_hash_test_generator.ads b/src/test_modules/nessie_hash_test_generator.ads similarity index 60% rename from src/tests/nessie_hash_test_generator.ads rename to src/test_modules/nessie_hash_test_generator.ads index 74fb563..f950138 100644 --- a/src/tests/nessie_hash_test_generator.ads +++ b/src/test_modules/nessie_hash_test_generator.ads @@ -14,17 +14,10 @@ -- along with this program. If not, see . with Crypto_Core_Types; use Crypto_Core_Types; +with Hash_Generic; generic - Name : String; - Digest_Size_Bits : Natural; - Block_Size_Bits : Natural; - type Context_T is private; - with procedure Initialize(Context : out Context_T); - with procedure Next_Block(Context : in out Context_T; Block : in u8_Array); - with procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1); - with procedure Get_Digest(Context : in out Context_T; Digest : out u8_Array); - with procedure Hash(Data : in u8_Array; Digest : out u8_Array; Bits : in Integer := -1); + with package Hash is new Hash_Generic(<>); package Nessie_Hash_Test_Generator is @@ -36,7 +29,4 @@ package Nessie_Hash_Test_Generator is private - Digest_Size_Bytes : constant Natural := (Digest_Size_Bits + 7) / 8; - Block_Size_Bytes : constant Natural := (Block_Size_Bits + 7) / 8; - end Nessie_Hash_Test_Generator; diff --git a/src/test_modules/nist_test_io.adb b/src/test_modules/nist_test_io.adb new file mode 100644 index 0000000..1b7495e --- /dev/null +++ b/src/test_modules/nist_test_io.adb @@ -0,0 +1,62 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . +with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; +with Ada.Strings; use Ada.Strings; +with Ada.Strings.Unbounded; use Ada.Strings.Unbounded; +with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO; + +-- +-- # CAVS 11.0 +-- # "SHA-256 ShortMsg" information +-- # SHA-256 tests are configured for BIT oriented implementations +-- # Generated on Tue Mar 15 08:29:11 2011 +-- +-- [L = 32] +-- +-- Len = 0 +-- Msg = 00 +-- MD = e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +-- +-- Len = 1 +-- Msg = 00 +-- MD = bd4f9e98beb68c6ead3243b1b4c7fed75fa4feaab1f84795cbd8a98676a2a375 +-- +-- Len = 2 +-- Msg = 80 +-- MD = 18f331f626210ff9bad6995d8cff6e891adba50eb2fdbddcaa921221cdc333ae +-- +-- Len = 3 +-- Msg = 60 +-- MD = 1f7794d4b0b67d3a6edcd17aba2144a95828032f7943ed26bf0c7c7628945f48 +-- + +package body Nist_Test_IO is + + procedure Open(Context : out Context_T; File_Name : in String) is + begin + Open(Context.File, In_File, File_Name); + end Open; + + procedure Get_Next(Context : in out Context_T; Parameters : out Parameters_T) is + Line : Unbounded_String; + begin + while not End_of_File(Context.File) loop + Line := Trim(Source => Get_Line(Context.File), + Side => Both); + end loop; + + end Get_Next; + +end Nist_Test_IO; diff --git a/src/test_modules/nist_test_io.ads b/src/test_modules/nist_test_io.ads new file mode 100644 index 0000000..da88148 --- /dev/null +++ b/src/test_modules/nist_test_io.ads @@ -0,0 +1,54 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Ada.Text_IO; use Ada.Text_IO; +with Crypto_Core_Types; use Crypto_Core_Types; + +generic + + type Global_Blob_T is (<>); + type Global_Integer_T is (<>); + type Local_Blob_T is (<>); + type Local_Integer_T is (<>); + +package Nist_Test_IO is + + type Context_T is limited private; + + type Global_Blob_Parameters is array (Global_Blob_T) of access u8_Array; + type Global_Integer_Parameters is array (Global_Integer_T) of Integer; + type Local_Blob_Parameters is array (Local_Blob_T) of access u8_Array; + type Local_Integer_Parameters is array (Local_Integer_T) of Integer; + + type Parameters_T is record + Valid : Boolean; + Global_Blob : Global_Blob_Parameters; + Global_Integer : Global_Integer_Parameters; + Local_Blob : Local_Blob_Parameters; + Local_Integer : Local_Integer_Parameters; + end record; + + procedure Open (Context : out Context_T; File_Name : String); + procedure Get_Next(Context : in out Context_T; Parameters : out Parameters_T); + +private + + type Context_T is record + File : File_Type; + Global_Blob : Global_Blob_Parameters; + Global_Integer : Global_Integer_Parameters; + end record; + +end Nist_Test_IO; diff --git a/src/tests/sha_test_io.adb b/src/test_modules/sha_test_io.adb similarity index 100% rename from src/tests/sha_test_io.adb rename to src/test_modules/sha_test_io.adb diff --git a/src/tests/sha_test_io.ads b/src/test_modules/sha_test_io.ads similarity index 100% rename from src/tests/sha_test_io.ads rename to src/test_modules/sha_test_io.ads diff --git a/src/tests/main.adb b/src/tests/main.adb new file mode 100644 index 0000000..ea5b762 --- /dev/null +++ b/src/tests/main.adb @@ -0,0 +1,301 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Ada.Text_IO; use Ada.Text_IO; +-- with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; +with Crypto_Core_Types; use Crypto_Core_Types; + +with Spritz_Stream; +with Spritz_Hash; + +with AES; use AES; + +with ARIA; use ARIA; + +with SHA2_256; + +with GCM128_Spec; + +procedure main is +-- package u8_IO is new Crypto_Types.u8_Sequential_IO; + + procedure Print_Hex(value : in u8) is + hex_table : constant array (0 .. 15) of Character := + ( '0', '1', '2', '3', + '4', '5', '6', '7', + '8', '9', 'a', 'b', + 'c', 'd', 'e', 'f'); + begin + Put(hex_table(Integer(Shift_Right(value, 4)))); + Put(hex_table(Integer(value and 16#F#))); + end; + + procedure Print_Hex(value : in u8_Array) is + begin + for i in value'Range loop + print_hex(value(i)); + Put(" "); + end loop; + end; + + procedure test_spritz_stream(s : in String) is + ctx : Spritz_Stream.Context; + z : u8_Array(1 .. 8) := (others => 0); + begin + Spritz_Stream.Initialize(ctx, key => s); + Put(s); + for i in 0 .. 6 - s'Length loop + Put(" "); + end loop; + Put(": "); + Spritz_Stream.Encrypt(ctx, z); + print_hex(z); + New_Line; + end test_spritz_stream; + + procedure test_spritz_hash(s : in String) is + ctx : Spritz_Hash.Context; + hash : u8_Array(1 .. 32); + begin + Spritz_Hash.Initialize(ctx); + Spritz_Hash.Add_Data(ctx, s); + Spritz_Hash.Extract_Hash(ctx => ctx, Hash => hash); + Put(s); + for i in 0 .. 6 - s'Length loop + Put(" "); + end loop; + Put(": "); + print_hex(hash(1 .. 8)); + New_Line; + end test_spritz_hash; + + procedure test_aes is + key : Block_256_Bit; + block : Block_128_Bit; + ctx128 : AES_128.Context_T; + ctx192 : AES_192.Context_T; + ctx256 : AES_256.Context_T; + begin + for i in key'Range loop + key(i) := u8(i - 1); + end loop; + block(block'First) := 0; + for i in block'First + 1 .. block'Last loop + block(i) := u8(block(i - 1) + 16#11#); + end loop; + AES_128.Initialize(ctx128, key(1 .. 16)); + AES_128.Encrypt(ctx128, block); + print_hex(block); New_Line; + AES_128.Decrypt(ctx128, block); + print_hex(block); New_Line; + + AES_192.Initialize(ctx192, key(1 .. 24)); + AES_192.Encrypt(ctx192, block); + print_hex(block); New_Line; + AES_192.Decrypt(ctx192, block); + print_hex(block); New_Line; + + AES_256.Initialize(ctx256, key); + AES_256.Encrypt(ctx256, block); + print_hex(block); New_Line; + AES_256.Decrypt(ctx256, block); + print_hex(block); New_Line; + end test_aes; + +-- +-- procedure test_aes_128b is +-- key : constant AES.Key_128 := ( +-- 16#2b#, 16#7e#, 16#15#, 16#16#, +-- 16#28#, 16#ae#, 16#d2#, 16#a6#, +-- 16#ab#, 16#f7#, 16#15#, 16#88#, +-- 16#09#, 16#cf#, 16#4f#, 16#3c# ); +-- block : Block_128_bit := ( +-- 16#32#, 16#43#, 16#f6#, 16#a8#, +-- 16#88#, 16#5a#, 16#30#, 16#8d#, +-- 16#31#, 16#31#, 16#98#, 16#a2#, +-- 16#e0#, 16#37#, 16#07#, 16#34# ); +-- ctx : AES.Context_128; +-- begin +-- AES.Initialize(key, ctx); +-- AES.Encrypt(ctx, block); +-- print_hex(block); +-- end test_aes_128b; + + procedure test_aria is + Context : Aria_256.Context_T; + key : Block_256_Bit; + Block : Block_128_Bit := (others => 0); + begin + for i in Key'Range loop + Key(i) := u8(i - 1); + end loop; + + for i in 2 .. Block'Last loop + Block(i) := Block(i - 1) + 16#11#; + end loop; + Aria_128.Initialize(Key => key(1 .. 16), Context => Context); + Put("Plaintext: "); print_hex(Block); New_Line; + Aria_128.Encrypt(Block => Block, Context => Context); + Put("Ciphertext: "); print_hex(Block); New_Line; + Aria_128.Decrypt(Block => Block, Context => Context); + Put("Plaintext: "); print_hex(Block); New_Line; + New_Line; + + Block(1) := 0; + for i in 2 .. Block'Last loop + Block(i) := Block(i - 1) + 16#11#; + end loop; + Aria_192.Initialize(Key => key(1 .. 24), Context => Context); + Put("Plaintext: "); print_hex(Block); New_Line; + Aria_192.Encrypt(Block => Block, Context => Context); + Put("Ciphertext: "); print_hex(Block); New_Line; + Aria_192.Decrypt(Block => Block, Context => Context); + Put("Plaintext: "); print_hex(Block); New_Line; + New_Line; + + Block(1) := 0; + for i in 2 .. Block'Last loop + Block(i) := Block(i - 1) + 16#11#; + end loop; + Aria_256.Initialize(Key => key, Context => Context); + Put("Plaintext: "); print_hex(Block); New_Line; + Aria_256.Encrypt(Block => Block, Context => Context); + Put("Ciphertext: "); print_hex(Block); New_Line; + Aria_256.Decrypt(Block => Block, Context => Context); + Put("Plaintext: "); print_hex(Block); New_Line; + New_Line; + end; + + procedure test_sha256(Msg : String) is + Data : u8_Array(1 .. Msg'Length); + Digest : Block_256_Bit; + begin + Put("""" & Msg & """: "); + for i in data'Range loop + Data(i) := u8(Character'Pos(Msg(Msg'First + i - Data'First))); + end loop; + Sha2_256.Hash(Data, Digest); + Print_Hex(Digest); + New_Line; + end test_sha256; + + procedure test_gcm(pKey : String; pIV : String; pHeader : String; pMsg : String) is + Key : constant Block_128_Bit := From_Hex(pKey); + IV : constant u8_Array := From_Hex(pIV); + Header : constant u8_Array := From_Hex(pHeader); + Msg : u8_Array := From_Hex(pMsg); + package gcm is new GCM128_Spec(AES_128); + ctx : gcm.Context_T; + Tag : Block_128_Bit; + begin + Put_Line("Key: " & To_Hex(Key)); + Put_Line("IV: " & To_Hex(IV)); + Put_Line("Header: " & To_Hex(Header)); + Put_Line("Plaintext: " & To_Hex(Msg)); + gcm.Initialize(ctx, Key, IV); + gcm.Header_Last_Block(ctx, Header); + gcm.Encrypt_Last_Block(ctx, Msg); + Put_Line("Ciphertext: " & To_Hex(Msg)); + gcm.Get_Tag(ctx, Tag); + Put_Line("Tag (A): " & To_Hex(Tag)); + gcm.Initialize(ctx, Key, IV); + gcm.Header_Last_Block(ctx, Header); + gcm.Decrypt_Last_Block(ctx, Msg); + Put_Line("Plaintext: " & To_Hex(Msg)); + gcm.Get_Tag(ctx, Tag); + Put_Line("Tag (B): " & To_Hex(Tag)); + New_Line; + end; + + +-- Random_File : File_Type; +begin + test_spritz_stream("ABC"); + test_spritz_stream("spam"); + test_spritz_stream("arcfour"); + New_Line; + + test_spritz_hash("ABC"); + test_spritz_hash("spam"); + test_spritz_hash("arcfour"); + New_Line; + + Put_Line("AES_128.Context_T'Size / 8: " & Integer'Image(AES_128.Context_T'Size / 8)); + Put_Line("AES_192.Context_T'Size / 8: " & Integer'Image(AES_192.Context_T'Size / 8)); + Put_Line("AES_256.Context_T'Size / 8: " & Integer'Image(AES_256.Context_T'Size / 8)); + test_aes; + New_Line; + + Put_Line("ARIA_128.Context_T'Size / 8: " & Integer'Image(ARIA_128.Context_T'Size / 8)); + test_aria; + New_Line; + + Put_Line("SHA2_256.Context_T'Size: " & Integer'Image(SHA2_256.Context_T'Size / 8)); + test_sha256("abc"); + test_sha256("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"); + New_Line; + + test_gcm("11754cd72aec309bf52f7687212e8957", "3c819d9a9bed087615030b65", "", ""); + --Count = 0 +-- Key = da0b615656135194ba6d3c851099bc48 +-- IV = d39d4b4d3cc927885090e6c3 +-- PT = +-- AAD = e7e5e6f8dac913036cb2ff29e8625e0e +-- CT = +-- Tag = ab967711a5770461724460b07237e2 + test_gcm(pKey => "da0b615656135194ba6d3c851099bc48", + pIV => "d39d4b4d3cc927885090e6c3", + pHeader => "e7e5e6f8dac913036cb2ff29e8625e0e", + pMsg => ""); + +-- Count = 0 +-- Key = 9bf406339fcef9675bbcf156aa1a0661 +-- IV = 8be4a9543d40f542abacac95 +-- PT = +-- AAD = 7167cbf56971793186333a6685bbd58d47d379b3 +-- CT = +-- Tag = 5e7968d7bbd5ba58cfcc750e2ef8f1 + test_gcm(pKey => "9bf406339fcef9675bbcf156aa1a0661", + pIV => "8be4a9543d40f542abacac95", + pHeader => "7167cbf56971793186333a6685bbd58d47d379b3", + pMsg => ""); + +-- Count = 0 +-- Key = 7fddb57453c241d03efbed3ac44e371c +-- IV = ee283a3fc75575e33efd4887 +-- PT = d5de42b461646c255c87bd2962d3b9a2 +-- AAD = +-- CT = 2ccda4a5415cb91e135c2a0f78c9b2fd +-- Tag = b36d1df9b9d5e596f83e8b7f52971cb3 + test_gcm(pKey => "7fddb57453c241d03efbed3ac44e371c", + pIV => "ee283a3fc75575e33efd4887", + pHeader => "", + pMsg => "d5de42b461646c255c87bd2962d3b9a2"); + + +-- Count = 14 +-- Key = 0e00c76561d2bd9b40c3c15427e2b08f +-- IV = 492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e74cbb921d8326631631fc6a5d304f39166daf7ea15fa1977f101819adb510b50fe9932e12c5a85aa3fd1e73d8d760af218be829903a77c63359d75edd91b4f6ed5465a72662f5055999e059e7654a8edc921aa0d496 +-- PT = fef03c2d7fb15bf0d2df18007d99f967c878ad59359034f7bb2c19af120685d78e32f6b8b83b032019956ca9c0195721476b85 +-- AAD = d8f1163d8c840292a2b2dacf4ac7c36aff8733f18fabb4fa5594544125e03d1e6e5d6d0fd61656c8d8f327c92839ae5539bb469c9257f109ebff85aad7bd220fdaa95c022dbd0c7bb2d878ad504122c943045d3c5eba8f1f56c0 +-- CT = 4f6cf471be7cbd2575cd5a1747aea8fe9dea83e51936beac3e68f66206922060c697ffa7af80ad6bb68f2cf4fc97416ee52abe +-- Tag = e20b6655 +-- + test_gcm(pKey => "0e00c76561d2bd9b40c3c15427e2b08f", + pIV => "492cadaccd3ca3fbc9cf9f06eb3325c4e159850b0dbe98199b89b7af528806610b6f63998e1eae80c348e74cbb921d8326631631fc6a5d304f39166daf7ea15fa1977f101819adb510b50fe9932e12c5a85aa3fd1e73d8d760af218be829903a77c63359d75edd91b4f6ed5465a72662f5055999e059e7654a8edc921aa0d496", + pHeader => "d8f1163d8c840292a2b2dacf4ac7c36aff8733f18fabb4fa5594544125e03d1e6e5d6d0fd61656c8d8f327c92839ae5539bb469c9257f109ebff85aad7bd220fdaa95c022dbd0c7bb2d878ad504122c943045d3c5eba8f1f56c0", + pMsg => "fef03c2d7fb15bf0d2df18007d99f967c878ad59359034f7bb2c19af120685d78e32f6b8b83b032019956ca9c0195721476b85"); + New_Line; +end main; diff --git a/src/tests/test_aes.adb b/src/tests/test_aes.adb deleted file mode 100644 index 81f3556..0000000 --- a/src/tests/test_aes.adb +++ /dev/null @@ -1,61 +0,0 @@ --- Copyright (C) 2015 Daniel Otte --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; -use Crypto_Types.Crypto_Types_u8; - -with Ada.Text_IO; use Ada.Text_IO; -with Ada.Strings.Fixed; use Ada.Strings.Fixed; - -with Nessie_BC_Test_Generator; -with AES; - -procedure Test_AES is - - package Nessie_Test_128 is new Nessie_BC_Test_Generator( - Name => "AES-128", - Key_Size_Bits => AES.Key_128_T'Length * 8, - Block_Size_Bits => AES.Block_T'Length * 8, - Context_T => AES.Context_128_T, - Initialize => AES.Initialize, - Encrypt => AES.Encrypt, - Decrypt => AES.Decrypt ); - - package Nessie_Test_192 is new Nessie_BC_Test_Generator( - Name => "AES-192", - Key_Size_Bits => AES.Key_192_T'Length * 8, - Block_Size_Bits => AES.Block_T'Length * 8, - Context_T => AES.Context_192_T, - Initialize => AES.Initialize, - Encrypt => AES.Encrypt, - Decrypt => AES.Decrypt ); - - package Nessie_Test_256 is new Nessie_BC_Test_Generator( - Name => "AES-256", - Key_Size_Bits => AES.Key_256_T'Length * 8, - Block_Size_Bits => AES.Block_T'Length * 8, - Context_T => AES.Context_256_T, - Initialize => AES.Initialize, - Encrypt => AES.Encrypt, - Decrypt => AES.Decrypt ); - -begin - - Nessie_Test_128.Run_File; - Nessie_Test_192.Run_File; - Nessie_Test_256.Run_File; - -end Test_AES; diff --git a/src/tests/test_aes_nessie.adb b/src/tests/test_aes_nessie.adb new file mode 100644 index 0000000..e52200d --- /dev/null +++ b/src/tests/test_aes_nessie.adb @@ -0,0 +1,37 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; +use Crypto_Types.Crypto_Utils_u8; + +with Nessie_BC_Test_Generator; +with AES; + +procedure Test_AES_Nessie is + + package Nessie_Test_128 is new Nessie_BC_Test_Generator(AES.AES_128); + + package Nessie_Test_192 is new Nessie_BC_Test_Generator(AES.AES_192); + + package Nessie_Test_256 is new Nessie_BC_Test_Generator(AES.AES_256); + +begin + + Nessie_Test_128.Run_File; + Nessie_Test_192.Run_File; + Nessie_Test_256.Run_File; + +end Test_AES_Nessie; diff --git a/src/tests/test_des.adb b/src/tests/test_des_nessie.adb similarity index 57% rename from src/tests/test_des.adb rename to src/tests/test_des_nessie.adb index b29291c..45574bd 100644 --- a/src/tests/test_des.adb +++ b/src/tests/test_des_nessie.adb @@ -17,24 +17,17 @@ -- with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; with Crypto_Core_Types; use Crypto_Core_Types; with Crypto_Types; use Crypto_Types; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; with Nessie_BC_Test_Generator; with DES; -procedure Test_DES is +procedure Test_DES_Nessie is - package Nessie_Test is new Nessie_BC_Test_Generator( - Name => "DES", - Key_Size_Bits => DES.Key_T'Length * 8, - Block_Size_Bits => DES.Block_T'Length * 8, - Context_T => DES.Context_T, - Initialize => DES.Initialize, - Encrypt => DES.Encrypt, - Decrypt => DES.Decrypt ); + package Nessie_Test is new Nessie_BC_Test_Generator(DES); begin Nessie_Test.Run_File; -end Test_DES; +end Test_DES_Nessie; diff --git a/src/tests/test_keccak.adb b/src/tests/test_keccak.adb index 8c71e90..83a2445 100644 --- a/src/tests/test_keccak.adb +++ b/src/tests/test_keccak.adb @@ -20,8 +20,8 @@ with Crypto_Types; use Crypto_Types; with Sha3_Generic; -use Crypto_Types.Crypto_Types_u8; -use Crypto_Types.Crypto_Types_u64; +use Crypto_Types.Crypto_Utils_u8; +use Crypto_Types.Crypto_Utils_u64; procedure Test_Keccak is -- procedure Print_State(A : State_T) is diff --git a/src/tests/test_pi16cipher.adb b/src/tests/test_pi16cipher.adb new file mode 100644 index 0000000..23436e8 --- /dev/null +++ b/src/tests/test_pi16cipher.adb @@ -0,0 +1,204 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Strings; use Ada.Strings; +with Ada.Strings.Fixed; use Ada.Strings.Fixed; +with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; + +use Crypto_Types.Crypto_Utils_u8; + +with Pi16Cipher_Spec; + +procedure Test_Pi16Cipher is + + package PiCipher renames Pi16Cipher_Spec; + + type Arcfour_SBox_T is array (u8) of u8; + + type Arcfour_Context_T is record + S : Arcfour_SBox_T; + I : u8; + J : u8; + end record; + + Prng : Arcfour_Context_T; + + procedure Initialize_Prng(Key : in u8_Array) is + j : u8 := 0; + begin + for i in u8'Range loop + Prng.S(i) := i; + end loop; + for i in u8'Range loop + j := j + Prng.S(i) + Key(Key'First + Integer(i) mod Key'Length); + Swap(Prng.S(i), Prng.S(j)); + end loop; + Prng.I := 0; + Prng.J := 0; + end; + + function Random_Byte return u8 is + begin + Prng.I := Prng.I + 1; + Prng.J := Prng.J + Prng.S(Prng.I); + Swap(Prng.S(Prng.I), Prng.S(Prng.J)); + return Prng.S(Prng.S(Prng.I) + Prng.S(Prng.J)); + end; + + procedure Random_Fill(Data : out u8_Array) is + begin + for i in Data'Range loop + Data(i) := Random_Byte; + end loop; + end; + + procedure Test_Pi16(pKey : String; pIvPub : String; pIvSec : String; pHeader : String; pMsg : String) is + Key : constant Block_128_Bit := From_Ascii(pKey); + IvPub : constant u8_Array := From_Ascii(pIvPub); + IvSec : u8_Array := From_Ascii(pIvSec); + Header : constant u8_Array := From_Ascii(pHeader); + Msg : u8_Array := From_Ascii(pMsg); + Crypt : constant u8_Array := PiCipher.Encrypt(Msg => Msg, AD => Header, Public_Nonce => IvPub, Secret_Nonce => IvSec, Key => Key); + Is_Valid : Boolean; + -- Tag : Block_128_Bit; + begin + Put_Line("Key: " & To_Hex(Key)); + Put_Line("public IV: " & To_Hex(IvPub)); + Put_Line("secret IV: " & To_Hex(IvSec)); + Put_Line("Header: " & To_Hex(Header)); + Put_Line("Plaintext: " & To_Hex(Msg)); + Put_Line("Ciphertext: " & To_Hex(Crypt, True)); + New_Line; + PiCipher.Decrypt(Is_Valid, Msg, IvSec, Crypt, Header, IvPub, Key); + if Is_Valid then + Put_Line(">>valid<<"); + else + Put_Line(">>! verfication failed<<"); + end if; + Put_Line("Key: " & To_Hex(Key)); + Put_Line("public IV: " & To_Hex(IvPub)); + Put_Line("secret IV: " & To_Hex(IvSec)); + Put_Line("Header: " & To_Hex(Header)); + Put_Line("Plaintext: " & To_Hex(Msg)); + Put_Line("Ciphertext: " & To_Hex(Crypt, True)); + New_Line; + end; + +-- # Testvectors for pi16cipher +-- # key size: 128 bits +-- # nonce size: 32 bits +-- +-- [msg_len = 0] +-- [ad_len = 0] +-- +-- [vector #1 (1)] +-- KEY (16) = CBD22AFCA1FF4BAD5C61A952FE18BC5C +-- NPUB (4) = 622A8AF6 +-- NSEC (16) = 5A09C39778CF5F90584ED1E1BF96F54B +-- MSG (0) = +-- AD (0) = +-- CIPHER (32) = 8BD575EF6F87B779270F20F3A80CC00756C4837822E68235FB78072863E40BE1 +-- +-- [vector #2 (2)] +-- KEY (16) = 314806E77041E7776173CE80464A648E +-- NPUB (4) = 2300F6B9 +-- NSEC (16) = C7C8CCEF2C18ECADA87DEB5F4F27E3EE +-- MSG (0) = +-- AD (0) = +-- CIPHER (32) = 47BFA83DDA97EBF0F1693810235E13CF0671BBD99B891FA7970A888FB0C047FA +-- + + procedure Print_Item(Label : in String; Data : in u8_Array) is + begin + Put_Line(Label & " (" & Trim(Source => Integer'Image(Data'Length), Side => Both) & ") = " & To_Hex(A => Data, Upper_Case => True)); + end; + + procedure Single_Testvector(Msg : in u8_Array; AD : in u8_Array; Secret_Nonce : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array) is + Msg_Check : u8_Array(Msg'Range); + Smn_Check : PiCipher.Block_T; + Is_Valid : Boolean; + Crypt : constant u8_Array := PiCipher.Encrypt(Msg => Msg, AD => AD, Public_Nonce => Public_Nonce, Secret_Nonce => Secret_Nonce, Key => Key); + begin + Print_Item("KEY", Key); + Print_Item("NPUB", Public_Nonce); + Print_Item("NSEC", Secret_Nonce); + Print_Item("MSG", Msg); + Print_Item("AD", AD); + Print_Item("CIPHER", Crypt); + PiCipher.Decrypt(Is_Valid => Is_Valid, Msg => Msg_Check, Secret_Nonce => Smn_Check, Cipher => Crypt, AD => AD, Public_Nonce => Public_Nonce, Key => Key); + if not Is_Valid then + Put_Line("! Error: verification failed!"); + end if; + New_Line; + end; + + procedure Testvectors(Key_Length : in Natural; Public_Nonce_Length : in Natural) is + Msg : u8_Array(1 .. 3 * PiCipher.Block_Bytes / 2); + AD : u8_Array(1 .. 3 * PiCipher.Block_Bytes / 2); + Public_Nonce : u8_Array(1 .. Public_Nonce_Length); + Secret_Nonce : u8_Array(1 .. PiCipher.Secret_Message_Number_Bytes); + Key : u8_Array(1 .. Key_Length); + Counter : Positive := 1; + begin + declare + Key_Bits : constant String := Trim(Source => Integer'Image(Key_Length * 8), Side => Both); + Seed : constant String := PiCipher.Cipher_Name & ((3 - Key_Bits'Length) * "0") & Key_Bits & "v2 (" & Trim(Source => Integer'Image(Public_Nonce_Length), Side => Both) & " byte nonce)"; + begin + Initialize_Prng(From_Ascii(Seed)); + end; + + for Msg_Len in 0 .. Msg'Last loop + for AD_Len in 0 .. AD'Last loop + Put_Line("[msg_len = " & Trim(Integer'Image(Msg_Len), Both) & "]"); + Put_Line("[ad_len = " & Trim(Integer'Image(AD_Len), Both) & "]"); + New_Line; + for i in 1 .. 8 loop + Put_Line("[vector #" & Trim(Integer'Image(Counter), Both) & " (" & Trim(Integer'Image(i), Both) & ")]"); + Counter := Counter + 1; + Random_Fill(Key); + Random_Fill(Public_Nonce); + Random_Fill(Secret_Nonce); + Random_Fill(AD(1 .. AD_Len)); + Random_Fill(Msg(1 .. Msg_Len)); + Single_Testvector(Msg => Msg(1 .. Msg_Len), AD => AD(1 .. AD_Len), Secret_Nonce => Secret_Nonce, Public_Nonce => Public_Nonce, Key => Key); + end loop; + end loop; + end loop; + + end; + + + Key_Sizes : constant array (1 .. 2) of Natural := ( 96, 128 ); + Public_Nonce_Length : constant := 4; + File : File_Type; +begin +-- Test_Pi16("0123456789ABCDEF", "ABCD", "FEDCBA9876543210", "Header", "PlaintextPlaintext"); + for i in Key_Sizes'Range loop + Create(File => File, Name => "testvectors/pi-cipher/" & PiCipher.Cipher_Name & Trim(Integer'Image(Key_Sizes(i)), Both) + & "_" & Trim(Integer'Image(Public_Nonce_Length), Both) & ".test-vectors", Mode => Out_File); + Set_Output(File); + Put_Line("# Testvectors for " & PiCipher.Cipher_Name); + Put_Line("# key size: " & Trim(Integer'Image(Key_Sizes(i)), Both) & " bits"); + Put_Line("# nonce size: " & Trim(Integer'Image(Public_Nonce_Length * 8), Both) & " bits"); + New_Line; + Testvectors(Key_Sizes(i) / 8, Public_Nonce_Length); + Close(File); + Set_Output(Standard_Output); + end loop; + +end Test_Pi16Cipher; diff --git a/src/tests/test_pi32cipher.adb b/src/tests/test_pi32cipher.adb new file mode 100644 index 0000000..320a336 --- /dev/null +++ b/src/tests/test_pi32cipher.adb @@ -0,0 +1,146 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Strings; use Ada.Strings; +with Ada.Strings.Fixed; use Ada.Strings.Fixed; +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; + +use Crypto_Types.Crypto_Utils_u8; + +with Pi32Cipher_Spec; + +procedure Test_Pi32Cipher is + + package PiCipher renames Pi32Cipher_Spec; + + type Arcfour_SBox_T is array (u8) of u8; + + type Arcfour_Context_T is record + S : Arcfour_SBox_T; + I : u8; + J : u8; + end record; + + Prng : Arcfour_Context_T; + + procedure Initialize_Prng(Key : in u8_Array) is + j : u8 := 0; + begin + for i in u8'Range loop + Prng.S(i) := i; + end loop; + for i in u8'Range loop + j := j + Prng.S(i) + Key(Key'First + Integer(i) mod Key'Length); + Swap(Prng.S(i), Prng.S(j)); + end loop; + Prng.I := 0; + Prng.J := 0; + end; + + function Random_Byte return u8 is + begin + Prng.I := Prng.I + 1; + Prng.J := Prng.J + Prng.S(Prng.I); + Swap(Prng.S(Prng.I), Prng.S(Prng.J)); + return Prng.S(Prng.S(Prng.I) + Prng.S(Prng.J)); + end; + + procedure Random_Fill(Data : out u8_Array) is + begin + for i in Data'Range loop + Data(i) := Random_Byte; + end loop; + end; + + procedure Print_Item(Label : in String; Data : in u8_Array) is + begin + Put_Line(Label & " (" & Trim(Source => Integer'Image(Data'Length), Side => Both) & ") = " & To_Hex(A => Data, Upper_Case => True)); + end; + + procedure Single_Testvector(Msg : in u8_Array; AD : in u8_Array; Secret_Nonce : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array) is + Msg_Check : u8_Array(Msg'Range); + Smn_Check : PiCipher.Block_T; + Is_Valid : Boolean; + Crypt : constant u8_Array := PiCipher.Encrypt(Msg => Msg, AD => AD, Public_Nonce => Public_Nonce, Secret_Nonce => Secret_Nonce, Key => Key); + begin + Print_Item("KEY", Key); + Print_Item("NPUB", Public_Nonce); + Print_Item("NSEC", Secret_Nonce); + Print_Item("MSG", Msg); + Print_Item("AD", AD); + Print_Item("CIPHER", Crypt); + PiCipher.Decrypt(Is_Valid => Is_Valid, Msg => Msg_Check, Secret_Nonce => Smn_Check, Cipher => Crypt, AD => AD, Public_Nonce => Public_Nonce, Key => Key); + if not Is_Valid then + Put_Line("! Error: verification failed!"); + end if; + New_Line; + end; + + procedure Testvectors(Key_Length : in Natural; Public_Nonce_Length : in Natural) is + Msg : u8_Array(1 .. 3 * PiCipher.Block_Bytes / 2); + AD : u8_Array(1 .. 3 * PiCipher.Block_Bytes / 2); + Public_Nonce : u8_Array(1 .. Public_Nonce_Length); + Secret_Nonce : u8_Array(1 .. PiCipher.Secret_Message_Number_Bytes); + Key : u8_Array(1 .. Key_Length); + Counter : Positive := 1; + begin + declare + Key_Bits : constant String := Trim(Source => Integer'Image(Key_Length * 8), Side => Both); + Seed : constant String := PiCipher.Cipher_Name & ((3 - Key_Bits'Length) * "0") & Key_Bits & "v2 (" & Trim(Source => Integer'Image(Public_Nonce_Length), Side => Both) & " byte nonce)"; + begin + Initialize_Prng(From_Ascii(Seed)); + end; + + for Msg_Len in 0 .. Msg'Last loop + for AD_Len in 0 .. AD'Last loop + Put_Line("[msg_len = " & Trim(Integer'Image(Msg_Len), Both) & "]"); + Put_Line("[ad_len = " & Trim(Integer'Image(AD_Len), Both) & "]"); + New_Line; + for i in 1 .. 8 loop + Put_Line("[vector #" & Trim(Integer'Image(Counter), Both) & " (" & Trim(Integer'Image(i), Both) & ")]"); + Counter := Counter + 1; + Random_Fill(Key); + Random_Fill(Public_Nonce); + Random_Fill(Secret_Nonce); + Random_Fill(AD(1 .. AD_Len)); + Random_Fill(Msg(1 .. Msg_Len)); + Single_Testvector(Msg => Msg(1 .. Msg_Len), AD => AD(1 .. AD_Len), Secret_Nonce => Secret_Nonce, Public_Nonce => Public_Nonce, Key => Key); + end loop; + end loop; + end loop; + + end; + + + Key_Sizes : constant array (1 .. 2) of Natural := ( 128, 256 ); + Public_Nonce_Length : constant := 16; + File : File_Type; +begin + for i in Key_Sizes'Range loop + Create(File => File, Name => "testvectors/pi-cipher/" & PiCipher.Cipher_Name & Trim(Integer'Image(Key_Sizes(i)), Both) + & "_" & Trim(Integer'Image(Public_Nonce_Length), Both) & ".test-vectors", Mode => Out_File); + Set_Output(File); + Put_Line("# Testvectors for " & PiCipher.Cipher_Name); + Put_Line("# key size: " & Trim(Integer'Image(Key_Sizes(i)), Both) & " bits"); + Put_Line("# nonce size: " & Trim(Integer'Image(Public_Nonce_Length * 8), Both) & " bits"); + New_Line; + Testvectors(Key_Sizes(i) / 8, Public_Nonce_Length); + Close(File); + Set_Output(Standard_Output); + end loop; + +end Test_Pi32Cipher; diff --git a/src/tests/test_pi64cipher.adb b/src/tests/test_pi64cipher.adb new file mode 100644 index 0000000..e911e4c --- /dev/null +++ b/src/tests/test_pi64cipher.adb @@ -0,0 +1,204 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Ada.Text_IO; use Ada.Text_IO; +with Ada.Strings; use Ada.Strings; +with Ada.Strings.Fixed; use Ada.Strings.Fixed; +with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; + +use Crypto_Types.Crypto_Utils_u8; + +with Pi64Cipher_Spec; + +procedure Test_Pi64Cipher is + + package PiCipher renames Pi64Cipher_Spec; + + type Arcfour_SBox_T is array (u8) of u8; + + type Arcfour_Context_T is record + S : Arcfour_SBox_T; + I : u8; + J : u8; + end record; + + Prng : Arcfour_Context_T; + + procedure Initialize_Prng(Key : in u8_Array) is + j : u8 := 0; + begin + for i in u8'Range loop + Prng.S(i) := i; + end loop; + for i in u8'Range loop + j := j + Prng.S(i) + Key(Key'First + Integer(i) mod Key'Length); + Swap(Prng.S(i), Prng.S(j)); + end loop; + Prng.I := 0; + Prng.J := 0; + end; + + function Random_Byte return u8 is + begin + Prng.I := Prng.I + 1; + Prng.J := Prng.J + Prng.S(Prng.I); + Swap(Prng.S(Prng.I), Prng.S(Prng.J)); + return Prng.S(Prng.S(Prng.I) + Prng.S(Prng.J)); + end; + + procedure Random_Fill(Data : out u8_Array) is + begin + for i in Data'Range loop + Data(i) := Random_Byte; + end loop; + end; + + procedure Test_Pi16(pKey : String; pIvPub : String; pIvSec : String; pHeader : String; pMsg : String) is + Key : constant Block_128_Bit := From_Ascii(pKey); + IvPub : constant u8_Array := From_Ascii(pIvPub); + IvSec : u8_Array := From_Ascii(pIvSec); + Header : constant u8_Array := From_Ascii(pHeader); + Msg : u8_Array := From_Ascii(pMsg); + Crypt : constant u8_Array := PiCipher.Encrypt(Msg => Msg, AD => Header, Public_Nonce => IvPub, Secret_Nonce => IvSec, Key => Key); + Is_Valid : Boolean; + -- Tag : Block_128_Bit; + begin + Put_Line("Key: " & To_Hex(Key)); + Put_Line("public IV: " & To_Hex(IvPub)); + Put_Line("secret IV: " & To_Hex(IvSec)); + Put_Line("Header: " & To_Hex(Header)); + Put_Line("Plaintext: " & To_Hex(Msg)); + Put_Line("Ciphertext: " & To_Hex(Crypt, True)); + New_Line; + PiCipher.Decrypt(Is_Valid, Msg, IvSec, Crypt, Header, IvPub, Key); + if Is_Valid then + Put_Line(">>valid<<"); + else + Put_Line(">>! verfication failed<<"); + end if; + Put_Line("Key: " & To_Hex(Key)); + Put_Line("public IV: " & To_Hex(IvPub)); + Put_Line("secret IV: " & To_Hex(IvSec)); + Put_Line("Header: " & To_Hex(Header)); + Put_Line("Plaintext: " & To_Hex(Msg)); + Put_Line("Ciphertext: " & To_Hex(Crypt, True)); + New_Line; + end; + +-- # Testvectors for pi16cipher +-- # key size: 128 bits +-- # nonce size: 32 bits +-- +-- [msg_len = 0] +-- [ad_len = 0] +-- +-- [vector #1 (1)] +-- KEY (16) = CBD22AFCA1FF4BAD5C61A952FE18BC5C +-- NPUB (4) = 622A8AF6 +-- NSEC (16) = 5A09C39778CF5F90584ED1E1BF96F54B +-- MSG (0) = +-- AD (0) = +-- CIPHER (32) = 8BD575EF6F87B779270F20F3A80CC00756C4837822E68235FB78072863E40BE1 +-- +-- [vector #2 (2)] +-- KEY (16) = 314806E77041E7776173CE80464A648E +-- NPUB (4) = 2300F6B9 +-- NSEC (16) = C7C8CCEF2C18ECADA87DEB5F4F27E3EE +-- MSG (0) = +-- AD (0) = +-- CIPHER (32) = 47BFA83DDA97EBF0F1693810235E13CF0671BBD99B891FA7970A888FB0C047FA +-- + + procedure Print_Item(Label : in String; Data : in u8_Array) is + begin + Put_Line(Label & " (" & Trim(Source => Integer'Image(Data'Length), Side => Both) & ") = " & To_Hex(A => Data, Upper_Case => True)); + end; + + procedure Single_Testvector(Msg : in u8_Array; AD : in u8_Array; Secret_Nonce : in u8_Array; Public_Nonce : in u8_Array; Key : in u8_Array) is + Msg_Check : u8_Array(Msg'Range); + Smn_Check : PiCipher.Block_T; + Is_Valid : Boolean; + Crypt : constant u8_Array := PiCipher.Encrypt(Msg => Msg, AD => AD, Public_Nonce => Public_Nonce, Secret_Nonce => Secret_Nonce, Key => Key); + begin + Print_Item("KEY", Key); + Print_Item("NPUB", Public_Nonce); + Print_Item("NSEC", Secret_Nonce); + Print_Item("MSG", Msg); + Print_Item("AD", AD); + Print_Item("CIPHER", Crypt); + PiCipher.Decrypt(Is_Valid => Is_Valid, Msg => Msg_Check, Secret_Nonce => Smn_Check, Cipher => Crypt, AD => AD, Public_Nonce => Public_Nonce, Key => Key); + if not Is_Valid then + Put_Line("! Error: verification failed!"); + end if; + New_Line; + end; + + procedure Testvectors(Key_Length : in Natural; Public_Nonce_Length : in Natural) is + Msg : u8_Array(1 .. 3 * PiCipher.Block_Bytes / 2); + AD : u8_Array(1 .. 3 * PiCipher.Block_Bytes / 2); + Public_Nonce : u8_Array(1 .. Public_Nonce_Length); + Secret_Nonce : u8_Array(1 .. PiCipher.Secret_Message_Number_Bytes); + Key : u8_Array(1 .. Key_Length); + Counter : Positive := 1; + begin + declare + Key_Bits : constant String := Trim(Source => Integer'Image(Key_Length * 8), Side => Both); + Seed : constant String := PiCipher.Cipher_Name & ((3 - Key_Bits'Length) * "0") & Key_Bits & "v2 (" & Trim(Source => Integer'Image(Public_Nonce_Length), Side => Both) & " byte nonce)"; + begin + Initialize_Prng(From_Ascii(Seed)); + end; + + for Msg_Len in 0 .. Msg'Last loop + for AD_Len in 0 .. AD'Last loop + Put_Line("[msg_len = " & Trim(Integer'Image(Msg_Len), Both) & "]"); + Put_Line("[ad_len = " & Trim(Integer'Image(AD_Len), Both) & "]"); + New_Line; + for i in 1 .. 8 loop + Put_Line("[vector #" & Trim(Integer'Image(Counter), Both) & " (" & Trim(Integer'Image(i), Both) & ")]"); + Counter := Counter + 1; + Random_Fill(Key); + Random_Fill(Public_Nonce); + Random_Fill(Secret_Nonce); + Random_Fill(AD(1 .. AD_Len)); + Random_Fill(Msg(1 .. Msg_Len)); + Single_Testvector(Msg => Msg(1 .. Msg_Len), AD => AD(1 .. AD_Len), Secret_Nonce => Secret_Nonce, Public_Nonce => Public_Nonce, Key => Key); + end loop; + end loop; + end loop; + + end; + + + Key_Sizes : constant array (1 .. 2) of Natural := ( 128, 256 ); + Public_Nonce_Length : constant := 16; + File : File_Type; +begin +-- Test_Pi16("0123456789ABCDEF", "ABCD", "FEDCBA9876543210", "Header", "PlaintextPlaintext"); + for i in Key_Sizes'Range loop + Create(File => File, Name => "testvectors/pi-cipher/" & PiCipher.Cipher_Name & Trim(Integer'Image(Key_Sizes(i)), Both) + & "_" & Trim(Integer'Image(Public_Nonce_Length), Both) & ".test-vectors", Mode => Out_File); + Set_Output(File); + Put_Line("# Testvectors for " & PiCipher.Cipher_Name); + Put_Line("# key size: " & Trim(Integer'Image(Key_Sizes(i)), Both) & " bits"); + Put_Line("# nonce size: " & Trim(Integer'Image(Public_Nonce_Length * 8), Both) & " bits"); + New_Line; + Testvectors(Key_Sizes(i) / 8, Public_Nonce_Length); + Close(File); + Set_Output(Standard_Output); + end loop; + +end Test_Pi64Cipher; diff --git a/src/tests/test_sha2.adb b/src/tests/test_sha2.adb deleted file mode 100644 index ae2f0d2..0000000 --- a/src/tests/test_sha2.adb +++ /dev/null @@ -1,120 +0,0 @@ --- Copyright (C) 2015 Daniel Otte --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - -with Ada.Text_IO; use Ada.Text_IO; -with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; - -with Sha_Test_IO; - -with Nessie_Hash_Test_Generator; - -with SHA2_224; -with SHA2_256; -with SHA2_384; -with SHA2_512; - -use Crypto_Types.Crypto_Types_u8; - -procedure Test_SHA2 is - - procedure test_sha224_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA2_224.Digest_Size_Bits, Hash => SHA2_224.Hash); - procedure test_sha256_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA2_256.Digest_Size_Bits, Hash => SHA2_256.Hash); - procedure test_sha384_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA2_384.Digest_Size_Bits, Hash => SHA2_384.Hash); - procedure test_sha512_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA2_512.Digest_Size_Bits, Hash => SHA2_512.Hash); - - package Nessie_Test_Sha224 is new Nessie_Hash_Test_Generator( - Name => "SHA-224", - Digest_Size_Bits => SHA2_224.Digest_Size_Bits, - Block_Size_Bits => SHA2_224.Block_Size_Bits, - Context_T => SHA2_224.Context_T, - Initialize => SHA2_224.Initialize, - Next_Block => SHA2_224.Next_Block, - Last_Block => SHA2_224.Last_Block, - Get_Digest => SHA2_224.Get_Digest, - Hash => SHA2_224.Hash); - package Nessie_Test_Sha256 is new Nessie_Hash_Test_Generator( - Name => "SHA-256", - Digest_Size_Bits => SHA2_256.Digest_Size_Bits, - Block_Size_Bits => SHA2_256.Block_Size_Bits, - Context_T => SHA2_256.Context_T, - Initialize => SHA2_256.Initialize, - Next_Block => SHA2_256.Next_Block, - Last_Block => SHA2_256.Last_Block, - Get_Digest => SHA2_256.Get_Digest, - Hash => SHA2_256.Hash); - package Nessie_Test_Sha384 is new Nessie_Hash_Test_Generator( - Name => "SHA-384", - Digest_Size_Bits => SHA2_384.Digest_Size_Bits, - Block_Size_Bits => SHA2_384.Block_Size_Bits, - Context_T => SHA2_384.Context_T, - Initialize => SHA2_384.Initialize, - Next_Block => SHA2_384.Next_Block, - Last_Block => SHA2_384.Last_Block, - Get_Digest => SHA2_384.Get_Digest, - Hash => SHA2_384.Hash); - package Nessie_Test_Sha512 is new Nessie_Hash_Test_Generator( - Name => "SHA-512", - Digest_Size_Bits => SHA2_512.Digest_Size_Bits, - Block_Size_Bits => SHA2_512.Block_Size_Bits, - Context_T => SHA2_512.Context_T, - Initialize => SHA2_512.Initialize, - Next_Block => SHA2_512.Next_Block, - Last_Block => SHA2_512.Last_Block, - Get_Digest => SHA2_512.Get_Digest, - Hash => SHA2_512.Hash); - -begin - - Nessie_Test_Sha224.Run_File; - Nessie_Test_Sha256.Run_File; - Nessie_Test_Sha384.Run_File; - Nessie_Test_Sha512.Run_File; - --- New_Line; --- test_sha224_with_File("testvectors/sha2/bit/SHA224ShortMsg.rsp"); --- test_sha224_with_File("testvectors/sha2/bit/SHA224LongMsg.rsp"); --- test_sha224_with_File("testvectors/sha2/bit/SHA224Monte.rsp"); --- test_sha224_with_File("testvectors/sha2/byte/SHA224ShortMsg.rsp"); --- test_sha224_with_File("testvectors/sha2/byte/SHA224LongMsg.rsp"); --- test_sha224_with_File("testvectors/sha2/byte/SHA224Monte.rsp"); --- --- New_Line; --- test_sha256_with_File("testvectors/sha2/bit/SHA256ShortMsg.rsp"); --- test_sha256_with_File("testvectors/sha2/bit/SHA256LongMsg.rsp"); --- test_sha256_with_File("testvectors/sha2/bit/SHA256Monte.rsp"); --- test_sha256_with_File("testvectors/sha2/byte/SHA256ShortMsg.rsp"); --- test_sha256_with_File("testvectors/sha2/byte/SHA256LongMsg.rsp"); --- test_sha256_with_File("testvectors/sha2/byte/SHA256Monte.rsp"); --- --- New_Line; --- test_sha384_with_File("testvectors/sha2/bit/SHA384ShortMsg.rsp"); --- test_sha384_with_File("testvectors/sha2/bit/SHA384LongMsg.rsp"); --- test_sha384_with_File("testvectors/sha2/bit/SHA384Monte.rsp"); --- test_sha384_with_File("testvectors/sha2/byte/SHA384ShortMsg.rsp"); --- test_sha384_with_File("testvectors/sha2/byte/SHA384LongMsg.rsp"); --- test_sha384_with_File("testvectors/sha2/byte/SHA384Monte.rsp"); --- --- New_Line; --- test_sha512_with_File("testvectors/sha2/bit/SHA512ShortMsg.rsp"); --- test_sha512_with_File("testvectors/sha2/bit/SHA512LongMsg.rsp"); --- test_sha512_with_File("testvectors/sha2/bit/SHA512Monte.rsp"); --- test_sha512_with_File("testvectors/sha2/byte/SHA512ShortMsg.rsp"); --- test_sha512_with_File("testvectors/sha2/byte/SHA512LongMsg.rsp"); --- test_sha512_with_File("testvectors/sha2/byte/SHA512Monte.rsp"); - - New_Line; - -end Test_SHA2; diff --git a/src/tests/test_sha224.adb b/src/tests/test_sha224.adb index 6a780f3..cacbdec 100644 --- a/src/tests/test_sha224.adb +++ b/src/tests/test_sha224.adb @@ -20,7 +20,7 @@ with Crypto_Types; use Crypto_Types; with SHA2_224; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; procedure Test_SHA224 is -- package u8_IO is new Crypto_Types.u8_Sequential_IO; diff --git a/src/tests/test_sha256.adb b/src/tests/test_sha256.adb index c2f0a55..3cbed0d 100644 --- a/src/tests/test_sha256.adb +++ b/src/tests/test_sha256.adb @@ -20,7 +20,7 @@ with Crypto_Types; use Crypto_Types; with Sha_Test_IO; with SHA2_256; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; procedure Test_SHA256 is diff --git a/src/tests/test_sha2_nessie.adb b/src/tests/test_sha2_nessie.adb new file mode 100644 index 0000000..da04e00 --- /dev/null +++ b/src/tests/test_sha2_nessie.adb @@ -0,0 +1,45 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Ada.Text_IO; use Ada.Text_IO; +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; + +with Nessie_Hash_Test_Generator; + +with SHA2_224; +with SHA2_256; +with SHA2_384; +with SHA2_512; + +use Crypto_Types.Crypto_Utils_u8; + +procedure Test_SHA2_Nessie is + + package Nessie_Test_Sha224 is new Nessie_Hash_Test_Generator(SHA2_224); + package Nessie_Test_Sha256 is new Nessie_Hash_Test_Generator(SHA2_256); + package Nessie_Test_Sha384 is new Nessie_Hash_Test_Generator(SHA2_384); + package Nessie_Test_Sha512 is new Nessie_Hash_Test_Generator(SHA2_512); + +begin + + Nessie_Test_Sha224.Run_File; + Nessie_Test_Sha256.Run_File; + Nessie_Test_Sha384.Run_File; + Nessie_Test_Sha512.Run_File; + + New_Line; + +end Test_SHA2_Nessie; diff --git a/src/tests/test_sha2_nist.adb b/src/tests/test_sha2_nist.adb new file mode 100644 index 0000000..2d3b2c8 --- /dev/null +++ b/src/tests/test_sha2_nist.adb @@ -0,0 +1,72 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Ada.Text_IO; use Ada.Text_IO; +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; + +with Sha_Test_IO; + +with SHA2_224; +with SHA2_256; +with SHA2_384; +with SHA2_512; + +use Crypto_Types.Crypto_Utils_u8; + +procedure Test_SHA2_Nist is + + procedure test_sha224_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA2_224.Digest_Size_Bits, Hash => SHA2_224.Hash); + procedure test_sha256_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA2_256.Digest_Size_Bits, Hash => SHA2_256.Hash); + procedure test_sha384_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA2_384.Digest_Size_Bits, Hash => SHA2_384.Hash); + procedure test_sha512_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA2_512.Digest_Size_Bits, Hash => SHA2_512.Hash); + +begin + + New_Line; + test_sha224_with_File("testvectors/sha2/bit/SHA224ShortMsg.rsp"); + test_sha224_with_File("testvectors/sha2/bit/SHA224LongMsg.rsp"); + test_sha224_with_File("testvectors/sha2/bit/SHA224Monte.rsp"); + test_sha224_with_File("testvectors/sha2/byte/SHA224ShortMsg.rsp"); + test_sha224_with_File("testvectors/sha2/byte/SHA224LongMsg.rsp"); + test_sha224_with_File("testvectors/sha2/byte/SHA224Monte.rsp"); + + New_Line; + test_sha256_with_File("testvectors/sha2/bit/SHA256ShortMsg.rsp"); + test_sha256_with_File("testvectors/sha2/bit/SHA256LongMsg.rsp"); + test_sha256_with_File("testvectors/sha2/bit/SHA256Monte.rsp"); + test_sha256_with_File("testvectors/sha2/byte/SHA256ShortMsg.rsp"); + test_sha256_with_File("testvectors/sha2/byte/SHA256LongMsg.rsp"); + test_sha256_with_File("testvectors/sha2/byte/SHA256Monte.rsp"); + + New_Line; + test_sha384_with_File("testvectors/sha2/bit/SHA384ShortMsg.rsp"); + test_sha384_with_File("testvectors/sha2/bit/SHA384LongMsg.rsp"); + test_sha384_with_File("testvectors/sha2/bit/SHA384Monte.rsp"); + test_sha384_with_File("testvectors/sha2/byte/SHA384ShortMsg.rsp"); + test_sha384_with_File("testvectors/sha2/byte/SHA384LongMsg.rsp"); + test_sha384_with_File("testvectors/sha2/byte/SHA384Monte.rsp"); + + New_Line; + test_sha512_with_File("testvectors/sha2/bit/SHA512ShortMsg.rsp"); + test_sha512_with_File("testvectors/sha2/bit/SHA512LongMsg.rsp"); + test_sha512_with_File("testvectors/sha2/bit/SHA512Monte.rsp"); + test_sha512_with_File("testvectors/sha2/byte/SHA512ShortMsg.rsp"); + test_sha512_with_File("testvectors/sha2/byte/SHA512LongMsg.rsp"); + test_sha512_with_File("testvectors/sha2/byte/SHA512Monte.rsp"); + + New_Line; + +end Test_SHA2_Nist; diff --git a/src/tests/test_sha384.adb b/src/tests/test_sha384.adb index 8d71ff6..2167ce1 100644 --- a/src/tests/test_sha384.adb +++ b/src/tests/test_sha384.adb @@ -20,7 +20,7 @@ with Crypto_Types; use Crypto_Types; with SHA2_384; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; procedure Test_SHA384 is -- package u8_IO is new Crypto_Types.u8_Sequential_IO; diff --git a/src/tests/test_sha3_nessie.adb b/src/tests/test_sha3_nessie.adb new file mode 100644 index 0000000..147ec23 --- /dev/null +++ b/src/tests/test_sha3_nessie.adb @@ -0,0 +1,42 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +with Ada.Text_IO; use Ada.Text_IO; +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; + +with Nessie_Hash_Test_Generator; + +with SHA3; + +use Crypto_Types.Crypto_Utils_u8; + +procedure Test_SHA3_Nessie is + + package Nessie_Test_Sha224 is new Nessie_Hash_Test_Generator(SHA3.SHA3_224); + package Nessie_Test_Sha256 is new Nessie_Hash_Test_Generator(SHA3.SHA3_256); + package Nessie_Test_Sha384 is new Nessie_Hash_Test_Generator(SHA3.SHA3_384); + package Nessie_Test_Sha512 is new Nessie_Hash_Test_Generator(SHA3.SHA3_512); + +begin + + Nessie_Test_Sha224.Run_File; + Nessie_Test_Sha256.Run_File; + Nessie_Test_Sha384.Run_File; + Nessie_Test_Sha512.Run_File; + + New_Line; + +end Test_SHA3_Nessie; diff --git a/src/tests/test_sha3.adb b/src/tests/test_sha3_nist.adb similarity index 97% rename from src/tests/test_sha3.adb rename to src/tests/test_sha3_nist.adb index 289220e..cc4e331 100644 --- a/src/tests/test_sha3.adb +++ b/src/tests/test_sha3_nist.adb @@ -21,9 +21,9 @@ with Sha_Test_IO; with SHA3; use SHA3; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; -procedure Test_SHA3 is +procedure Test_SHA3_Nist is procedure test_sha3_224_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA3_224.Digest_Size_Bits, Hash => SHA3_224.Hash); procedure test_sha3_256_with_File is new Sha_Test_IO.Test_With_File(Digest_Size_Bits => SHA3_256.Digest_Size_Bits, Hash => SHA3_256.Hash); @@ -72,4 +72,4 @@ begin New_Line; -end Test_SHA3; +end Test_SHA3_Nist; diff --git a/src/tests/test_sha512.adb b/src/tests/test_sha512.adb index 8e9169f..434f9d0 100644 --- a/src/tests/test_sha512.adb +++ b/src/tests/test_sha512.adb @@ -20,7 +20,7 @@ with Crypto_Types; use Crypto_Types; with SHA2_512; -use Crypto_Types.Crypto_Types_u8; +use Crypto_Types.Crypto_Utils_u8; procedure Test_SHA512 is -- package u8_IO is new Crypto_Types.u8_Sequential_IO; diff --git a/src/tests/test_tdes.adb b/src/tests/test_tdes.adb deleted file mode 100644 index 4ff891a..0000000 --- a/src/tests/test_tdes.adb +++ /dev/null @@ -1,52 +0,0 @@ --- Copyright (C) 2015 Daniel Otte --- --- This program is free software: you can redistribute it and/or modify --- it under the terms of the GNU General Public License as published by --- the Free Software Foundation, either version 3 of the License, or --- (at your option) any later version. --- --- This program is distributed in the hope that it will be useful, --- but WITHOUT ANY WARRANTY; without even the implied warranty of --- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the --- GNU General Public License for more details. --- --- You should have received a copy of the GNU General Public License --- along with this program. If not, see . - --- with Ada.Text_IO; use Ada.Text_IO; --- with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; -with Crypto_Core_Types; use Crypto_Core_Types; -with Crypto_Types; use Crypto_Types; -use Crypto_Types.Crypto_Types_u8; - -with Nessie_BC_Test_Generator; -with TDES; - -procedure Test_TDES is - - package Nessie_Test_2 is new Nessie_BC_Test_Generator( - Name => "Triple-DES (two keys)", - Key_Size_Bits => TDES.Key_128_T'Length * 8, - Block_Size_Bits => TDES.Block_T'Length * 8, - Context_T => TDES.Context_T, - Initialize => TDES.Initialize, - Encrypt => TDES.Encrypt, - Decrypt => TDES.Decrypt ); - - package Nessie_Test_3 is new Nessie_BC_Test_Generator( - Name => "Triple-DES (three keys)", - Key_Size_Bits => TDES.Key_192_T'Length * 8, - Block_Size_Bits => TDES.Block_T'Length * 8, - Context_T => TDES.Context_T, - Initialize => TDES.Initialize, - Encrypt => TDES.Encrypt, - Decrypt => TDES.Decrypt ); - -begin - - Nessie_Test_2.Verbose := True; - Nessie_Test_2.Run_File; - Nessie_Test_3.Verbose := True; - Nessie_Test_3.Run_File; - -end Test_TDES; diff --git a/src/tests/test_tdes_nessie.adb b/src/tests/test_tdes_nessie.adb new file mode 100644 index 0000000..8b59b02 --- /dev/null +++ b/src/tests/test_tdes_nessie.adb @@ -0,0 +1,38 @@ +-- Copyright (C) 2015 Daniel Otte +-- +-- This program is free software: you can redistribute it and/or modify +-- it under the terms of the GNU General Public License as published by +-- the Free Software Foundation, either version 3 of the License, or +-- (at your option) any later version. +-- +-- This program is distributed in the hope that it will be useful, +-- but WITHOUT ANY WARRANTY; without even the implied warranty of +-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +-- GNU General Public License for more details. +-- +-- You should have received a copy of the GNU General Public License +-- along with this program. If not, see . + +-- with Ada.Text_IO; use Ada.Text_IO; +-- with Ada.Integer_Text_IO; use Ada.Integer_Text_IO; +with Crypto_Core_Types; use Crypto_Core_Types; +with Crypto_Types; use Crypto_Types; +use Crypto_Types.Crypto_Utils_u8; + +with Nessie_BC_Test_Generator; +with TDES; + +procedure Test_TDES_Nessie is + + package Nessie_Test_2 is new Nessie_BC_Test_Generator(TDES.TDES_Two_Key); + + package Nessie_Test_3 is new Nessie_BC_Test_Generator(TDES.TDES_Three_Key); + +begin + + Nessie_Test_2.Verbose := True; + Nessie_Test_2.Run_File; + Nessie_Test_3.Verbose := True; + Nessie_Test_3.Run_File; + +end Test_TDES_Nessie; diff --git a/src/crypto_core_types.adb b/src/types/crypto_core_types.adb similarity index 75% rename from src/crypto_core_types.adb rename to src/types/crypto_core_types.adb index 2365a70..c239373 100644 --- a/src/crypto_core_types.adb +++ b/src/types/crypto_core_types.adb @@ -124,35 +124,4 @@ package body Crypto_Core_Types is return A; end From_Ascii; --- procedure Bit_Clear(Buffer : in out u8_Array; Index : in Positive) is --- begin --- Buffer(Buffer'First + Integer(Index / 8)) := Buffer(Buffer'First + Integer(Index / 8)) and (not Shift_Left(1, 7 - (Index - 1) mod 8)); --- end Bit_Clear; --- --- procedure Bit_Set(Buffer : in out u8_Array; Index : in Positive) is --- begin --- Buffer(Integer(Buffer'First + Index / 8)) := Buffer(Buffer'First + Integer(Index / 8)) or Shift_Left(1, 7 - (Index - 1) mod 8); --- end Bit_Set; --- --- procedure Bit_Toggle(Buffer : in out u8_Array; Index : in Positive) is --- begin --- Buffer(Integer(Buffer'First + Index / 8)) := Buffer(Buffer'First + Integer(Index / 8)) xor Shift_Left(1, 7 - (Index - 1) mod 8); --- end Bit_Toggle; --- --- --- procedure Bit_Set(Buffer : in out u8_Array; Index : in Positive; Value : in Bit) is --- begin --- if Value = 1 then --- Bit_Set(Buffer, Index); --- else --- Bit_Clear(Buffer, Index); --- end if; --- end Bit_Set; --- --- function Bit_Get(Buffer : in u8_Array; Index : in Positive) return Bit is --- begin --- return Bit(Shift_Right(Buffer(Buffer'First + Index / 8), 7 - (Index - 1) mod 8) and 1); --- end Bit_Get; - - end Crypto_Core_types; diff --git a/src/crypto_core_types.ads b/src/types/crypto_core_types.ads similarity index 90% rename from src/crypto_core_types.ads rename to src/types/crypto_core_types.ads index 01bca51..ad459e2 100644 --- a/src/crypto_core_types.ads +++ b/src/types/crypto_core_types.ads @@ -37,11 +37,6 @@ package Crypto_Core_Types is type u32_Array is Array (Integer range <>) of u32; type u64_Array is Array (Integer range <>) of u64; - type u8_Array_Access is access all u8_Array; - type u16_Array_Access is access all u16_Array; - type u32_Array_Access is access all u32_Array; - type u64_Array_Access is access all u64_Array; - subtype Block_32_Bit is u8_Array(1 .. 32 / 8); subtype Block_48_Bit is u8_Array(1 .. 48 / 8); subtype Block_56_Bit is u8_Array(1 .. 56 / 8); @@ -66,7 +61,6 @@ package Crypto_Core_Types is Format_Violation : exception; Invalid_Key_Size : exception; - function To_Hex(A : u8; Upper_Case : Boolean := false) return String; function To_Hex(A : u8_Array; Upper_Case : Boolean := false; Spacing : Natural := 0) return String; function From_Hex(S : String) return u8_Array; function From_Ascii(S : String) return u8_Array; diff --git a/src/crypto_generic_types.adb b/src/types/crypto_generic_utils.adb similarity index 98% rename from src/crypto_generic_types.adb rename to src/types/crypto_generic_utils.adb index 71dd1af..640c4ac 100644 --- a/src/crypto_generic_types.adb +++ b/src/types/crypto_generic_utils.adb @@ -20,7 +20,7 @@ -- -------------------------- -- - Functions / Procedures - -- -------------------------- -package body Crypto_Generic_Types is +package body Crypto_Generic_Utils is -- compare two array with timing independent of content -- function "="(Left, Right : T_Array ) return Boolean is @@ -660,6 +660,12 @@ package body Crypto_Generic_Types is A := A xor B; end; + function To_Hex(A : T; Upper_Case : Boolean := false) return String is + Temp : u8_Array(1 .. T'Size / 8); + begin + Store_be(A => Temp, Value => A); + return To_Hex(Temp, Upper_Case => Upper_Case); + end; -end Crypto_Generic_Types; +end Crypto_Generic_Utils; diff --git a/src/crypto_generic_types.ads b/src/types/crypto_generic_utils.ads similarity index 85% rename from src/crypto_generic_types.ads rename to src/types/crypto_generic_utils.ads index 3d24f5d..d4c7456 100644 --- a/src/crypto_generic_types.ads +++ b/src/types/crypto_generic_utils.ads @@ -41,12 +41,10 @@ generic type T_Array is Array (Integer range <>) of T; - type T_Array_Access is access T_Array; - -- -------------------------- -- - Functions / Procedures - -- -------------------------- -package Crypto_Generic_Types is +package Crypto_Generic_Utils is subtype Bit_Address_T is Natural range 0 .. T'Size - 1; @@ -99,6 +97,13 @@ package Crypto_Generic_Types is -- subtract from each element on the left the element on the right function "-"(Left : T_Array; Right : T ) return T_Array; + -- rotate the Array to the left without changing the values of the elements + function Rotate_Array_Left(A : T_Array; Amount : Natural) return T_Array; + + -- rotate the Array to the right without changing the values of the elements + function Rotate_Array_Right(A : T_Array; Amount : Natural) return T_Array; + + -- rotate the whole Array as continues big-endian integer; positive Amount rotates left (towards lower address) function Rotate_be(A : T_Array; Amount : Integer) return T_Array; @@ -171,5 +176,32 @@ package Crypto_Generic_Types is -- swap two Arrays procedure Swap(A, B : in out T_Array); + -- FIXME + function To_Hex(A : T; Upper_Case : Boolean := false) return String; -end Crypto_Generic_Types; + + pragma Inline ("xor"); + pragma Inline ("and"); + pragma Inline ("or"); + pragma Inline ("+"); + pragma Inline ("-"); + pragma Inline (Rotate_be); + pragma Inline (Rotate_le); + pragma Inline (Rotate_each); + pragma Inline (Rotate_Array_Left); + pragma Inline (Rotate_Array_Right); + pragma Inline (Shift_be); + pragma Inline (Shift_le); + pragma Inline (Shift_each); + pragma Inline (Load_be); + pragma Inline (Load_le); + pragma Inline (Store_be); + pragma Inline (Store_le); + pragma Inline (Bit_Get); + pragma Inline (Bit_Clear); + pragma Inline (Bit_Set); + pragma Inline (Bit_Toggle); + pragma Inline (Swap); + pragma Inline (To_Hex); + +end Crypto_Generic_Utils; diff --git a/src/crypto_types.ads b/src/types/crypto_types.ads similarity index 71% rename from src/crypto_types.ads rename to src/types/crypto_types.ads index 60087aa..ad99de2 100644 --- a/src/crypto_types.ads +++ b/src/types/crypto_types.ads @@ -13,18 +13,21 @@ -- You should have received a copy of the GNU General Public License -- along with this program. If not, see . -with Crypto_Generic_Types; +with Crypto_Generic_Utils; with Crypto_Core_Types; use Crypto_Core_Types; +with System; with Ada.Direct_IO; with Ada.Sequential_IO; package Crypto_Types is - package Crypto_Types_u8 is new Crypto_Generic_Types(T => u8, T_Array => u8_Array, T_Array_Access => u8_Array_Access); - package Crypto_Types_u16 is new Crypto_Generic_Types(T => u16, T_Array => u16_Array, T_Array_Access => u16_Array_Access); - package Crypto_Types_u32 is new Crypto_Generic_Types(T => u32, T_Array => u32_Array, T_Array_Access => u32_Array_Access); - package Crypto_Types_u64 is new Crypto_Generic_Types(T => u64, T_Array => u64_Array, T_Array_Access => u64_Array_Access); + subtype Bit_Order is System.Bit_Order; + + package Crypto_Utils_u8 is new Crypto_Generic_Utils(T => u8, T_Array => u8_Array); + package Crypto_Utils_u16 is new Crypto_Generic_Utils(T => u16, T_Array => u16_Array); + package Crypto_Utils_u32 is new Crypto_Generic_Utils(T => u32, T_Array => u32_Array); + package Crypto_Utils_u64 is new Crypto_Generic_Utils(T => u64, T_Array => u64_Array); package u8_Direct_IO is new Ada.Direct_IO( u8); package u16_Direct_IO is new Ada.Direct_IO(u16); diff --git a/steelcrypt.gpr b/steelcrypt.gpr index d95a10b..ba0f642 100644 --- a/steelcrypt.gpr +++ b/steelcrypt.gpr @@ -1,57 +1,64 @@ project Steelcrypt is - type Build_Modes is - ("Release", "Debug"); - Mode : Build_Modes := external ("BUILD", "Debug"); - for Main use ( - "main.adb", - "test_aes.adb", - "test_des.adb", - "test_tdes.adb", - "test_sha2.adb", - "test_sha3.adb", - "test_sha224.adb", - "test_sha256.adb", - "test_sha384.adb", - "test_sha512.adb", - "test_keccak.adb"); + type Build_Modes is + ("Release", "Debug"); + Mode : Build_Modes := external ("BUILD", "Debug"); + for Main use ( + "main.adb", + "test_pi16cipher.adb", + "test_pi32cipher.adb", + "test_pi64cipher.adb", + "test_aes_nessie.adb", + "test_des_nessie.adb", + "test_tdes_nessie.adb", + "test_sha2_nessie.adb", + "test_sha3_nessie.adb", + "test_sha2_nist.adb", + "test_sha3_nist.adb", + "test_sha224.adb", + "test_sha256.adb", + "test_sha384.adb", + "test_sha512.adb", + "test_keccak.adb" ); - case Mode is - - when "Release" => - for Source_Dirs use ("src/**"); - for Object_Dir use "obj_release"; - - when "Debug" => - for Source_Dirs use ("src/**"); - for Object_Dir use "obj_debug"; - end case; - - package Compiler is - - case Mode is + case Mode is when "Release" => - for Default_Switches ("ada") use ("-gnatQ", "-gnatn", "-O2", "-gnat05"); + for Source_Dirs use ("src/**"); + for Object_Dir use "obj_release"; when "Debug" => - for Default_Switches ("ada") use ("-g", "-gnato", "-gnatwa", "-gnatQ", "-gnat05"); - end case; - end Compiler; + for Source_Dirs use ("src/**"); + for Object_Dir use "obj_debug"; + end case; - package Builder is + package Compiler is - case Mode is + case Mode is - when "Release" => - for Default_Switches ("ada") use (); + when "Release" => + for Default_Switches ("ada") use ("-gnatQ", "-gnatn", "-O2", "-gnat05"); - when "Debug" => - for Default_Switches ("ada") use ("-g"); - end case; - end Builder; + when "Debug" => + for Default_Switches ("ada") use ("-g", "-O2", "-gnato", "-gnatwa", "-gnatQ", "-gnat05"); + end case; + end Compiler; - package Ide is - end Ide; + package Builder is + + case Mode is + + when "Release" => + for Default_Switches ("ada") use (); + + when "Debug" => + for Default_Switches ("ada") use ("-g"); + end case; + end Builder; + + package Ide is + for Compiler_Command ("ada") use "gnatmake"; + for Compiler_Command ("c") use "gcc"; + end Ide; end Steelcrypt;