generic update + PiCipherV2

This commit is contained in:
bg nerilex 2015-09-19 20:07:46 +02:00
parent 26a4a506cf
commit 8e4081389a
82 changed files with 3640 additions and 1021 deletions

View File

@ -0,0 +1,49 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,36 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,53 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -13,58 +13,37 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -13,7 +13,7 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,70 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -13,40 +13,37 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -13,7 +13,7 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,50 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -13,27 +13,18 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -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;

View File

@ -0,0 +1,39 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -13,31 +13,29 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -13,18 +13,18 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,43 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,202 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,50 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,363 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,75 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,363 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,75 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,371 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,75 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -13,32 +13,15 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -13,7 +13,7 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,44 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -13,35 +13,15 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -13,7 +13,11 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,44 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -13,32 +13,15 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -13,7 +13,7 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,44 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -13,32 +13,15 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -13,7 +13,7 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,44 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -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

View File

@ -13,6 +13,10 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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) :=

View File

@ -14,11 +14,6 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -14,12 +14,49 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -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);

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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

View File

@ -1,222 +0,0 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -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;

View File

@ -14,7 +14,7 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -14,66 +14,17 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -14,17 +14,10 @@
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,62 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,54 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

301
src/tests/main.adb Normal file
View File

@ -0,0 +1,301 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -1,61 +0,0 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,37 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -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;

View File

@ -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

View File

@ -0,0 +1,204 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,146 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,204 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -1,120 +0,0 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -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;

View File

@ -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

View File

@ -0,0 +1,45 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -0,0 +1,72 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -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;

View File

@ -0,0 +1,42 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
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;

View File

@ -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;

View File

@ -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;

View File

@ -1,52 +0,0 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
-- 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;

View File

@ -0,0 +1,38 @@
-- Copyright (C) 2015 Daniel Otte <bg@nerilex.org>
--
-- 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 <http://www.gnu.org/licenses/>.
-- 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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -13,18 +13,21 @@
-- You should have received a copy of the GNU General Public License
-- along with this program. If not, see <http://www.gnu.org/licenses/>.
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);

View File

@ -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;