adding SHA3

This commit is contained in:
bg nerilex 2015-08-15 04:58:52 +02:00
parent 262194ad9d
commit 23059ef0c3
8 changed files with 482 additions and 0 deletions

View File

@ -0,0 +1,26 @@
def lfsr(i)
x = 0x80;
i.times {
v = x & 1;
x = x >> 1;
if v == 1
x = x ^ 0x8e;
end
}
return x >> 7;
end
def rc(r)
a = 0;
7.times { |j|
t = lfsr(j + 7 * r);
a |= t << ((1<<j) - 1)
}
return a
end
24.times { |r|
printf("16#%016x#, -- round %d\n", rc(r), r + 1);
}

View File

@ -0,0 +1,9 @@
t = [ [ 0, 36, 3, 105, 210], [1, 300, 10, 45, 66], [ 190, 6, 171, 15, 153], [28, 55, 1553, 21, 120], [91, 276, 231, 136, 78] ]
5.times { |x|
printf(" ( ")
5.times { |y|
printf("%2d, ", t[x][y] % 64)
}
printf(" )\n")
}

View File

@ -0,0 +1,150 @@
-- 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;
package body Keccak is
-- procedure Print_State(A : State_T; S : String := "" ) is
-- c : Natural := 1;
-- l : u8_Array(1 .. 8);
-- begin
-- if S'Length > 0 then
-- Put_Line(S);
-- end if;
-- for i in y_T'Range loop
-- for j in x_T'Range loop
-- Store_le(A => l,
-- value => A(j, i));
-- for z in l'Range loop
-- Put(To_Hex(l(z)));
-- Put(' ');
-- if c mod 16 = 0 then
-- New_Line;
-- end if;
-- c := c + 1;
-- end loop;
-- end loop;
-- end loop;
-- New_Line;
-- end;
procedure theta( A : in out State_T ) is
C : Array (x_T) of Word_T;
D : Array (x_T) of Word_T;
begin
for i in x_T'Range loop
C(i) := A(i, 0) xor A(i, 1) xor A(i, 2) xor A(i, 3) xor A(i, 4);
end loop;
for i in x_T'Range loop
D(i) := C(i - 1) xor Rotate_Left(C(i + 1), 1);
end loop;
for i in x_T'Range loop
for j in y_T'Range loop
A(i, j) := A(i, j) xor D(i);
end loop;
end loop;
end theta;
procedure rho( A : in out State_T ) is
Rotation_Table : constant Array (x_T, y_T) of z_T :=
(
( 0, 36, 3, 41, 18 ),
( 1, 44, 10, 45, 2 ),
( 62, 6, 43, 15, 61 ),
( 28, 55, 25, 21, 56 ),
( 27, 20, 39, 8, 14 )
);
begin
for i in x_T'Range loop
for j in y_T'Range loop
A(i, j) := Rotate_Left(A(i, j), Integer(Rotation_Table(i, j)));
end loop;
end loop;
end rho;
procedure pi( A : in out State_T ) is
Ax : constant State_T := A;
begin
for i in x_T'Range loop
for j in y_T'Range loop
A(i, j) := Ax(i + 3 * x_T(j), y_T(i));
end loop;
end loop;
end pi;
procedure chi( A : in out State_T ) is
Ax : constant State_T := A;
begin
for i in x_T'Range loop
for j in y_T'Range loop
A(i, j) := A(i, j) xor ((not Ax(i + 1, j)) and Ax(i + 2, j));
end loop;
end loop;
end chi;
procedure iota( A : in out State_T; round : Natural ) is
Round_Constants : constant Array(1 .. rounds) of Word_T :=
(
16#0000000000000001#, -- round 1
16#0000000000008082#, -- round 2
16#800000000000808a#, -- round 3
16#8000000080008000#, -- round 4
16#000000000000808b#, -- round 5
16#0000000080000001#, -- round 6
16#8000000080008081#, -- round 7
16#8000000000008009#, -- round 8
16#000000000000008a#, -- round 9
16#0000000000000088#, -- round 10
16#0000000080008009#, -- round 11
16#000000008000000a#, -- round 12
16#000000008000808b#, -- round 13
16#800000000000008b#, -- round 14
16#8000000000008089#, -- round 15
16#8000000000008003#, -- round 16
16#8000000000008002#, -- round 17
16#8000000000000080#, -- round 18
16#000000000000800a#, -- round 19
16#800000008000000a#, -- round 20
16#8000000080008081#, -- round 21
16#8000000000008080#, -- round 22
16#0000000080000001#, -- round 23
16#8000000080008008# -- round 24
);
begin
A(0, 0) := A(0, 0) xor Round_Constants(round);
end iota;
procedure Permute ( A : in out State_T ) is
begin
-- Print_State(A, "### Initial state:");
for i in 1 .. rounds loop
-- Put_Line("## Round " & Integer'Image(i) & ":");
theta(A);
-- Print_State(A, "After Theta:");
rho(A);
-- Print_State(A, "After Rho:");
pi(A);
-- Print_State(A, "After Pi:");
chi(A);
-- Print_State(A, "After Chi:");
iota(A, i);
-- Print_State(A, "After Iota:");
end loop;
end Permute;
end Keccak;

View File

@ -0,0 +1,35 @@
-- 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 Keccak_Parameters; use Keccak_Parameters;
use Crypto_Types.Crypto_Types_u8;
use Crypto_Types.Crypto_Types_u64;
package Keccak is
type State_T is Array (x_T, y_T) of Word_T;
procedure Permute(A : in out State_T);
private
rounds : constant := 12 + 2 * l;
end Keccak;

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/>.
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;
package Keccak_Parameters is
subtype Word_T is u64;
w : constant := 64;
l : constant := 6;
b : constant := 25 * w;
subtype Capacity_T is Natural range 0 .. b;
subtype Capacity_Bytes_T is Natural range 0 .. b / 8;
type x_T is mod 5;
type y_T is mod 5;
type z_T is mod w;
end Keccak_Parameters;

View File

@ -0,0 +1,25 @@
-- 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 SHA3_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);
end SHA3;

View File

@ -0,0 +1,137 @@
-- 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 Sha3_Generic is
procedure Initialize(Context : out Context_T) is
begin
Context.A := (others => (others => 0));
end Initialize;
procedure Next_Block(Context : in out Context_T; Block : in Block_T) is
temp : u64;
begin
for i in 0 .. Rate_Bytes / 8 - 1 loop
temp := Load_le(Block(Block'First + i * 8 .. Block'First + i * 8 + 7));
Context.A(x_T(i mod 5), y_T(i / 5)) := Context.A(x_T(i mod 5), y_T(i / 5)) xor temp;
end loop;
Permute(Context.A);
end Next_Block;
procedure Append_Bit(Context : in out Context_T; Index : in out Capacity_T; Value : in Bit) is
begin
Context.A(x_t((Index / w) mod 5), y_t(Index / w / 5)) := Context.A(x_t((Index / w) mod 5), y_t(Index / w / 5)) xor Shift_Left(Word_T(Value), Index mod w);
Index := Index + 1;
if Index = Rate_Bits then
Permute(Context.A);
Index := 0;
end if;
end Append_Bit;
procedure Append_Byte(Context : in out Context_T; Index : in out Capacity_T; Value : in u8) is
begin
if Index mod 8 /= 0 then
raise Constraint_Error;
end if;
Context.A(x_t((Index / w) mod 5), y_t(Index / w / 5)) := Context.A(x_t((Index / w) mod 5), y_t(Index / w / 5)) xor Shift_Left(Word_T(Value), Index mod w);
Index := Index + 8;
if Index = Rate_Bits then
Permute(Context.A);
Index := 0;
end if;
end Append_Byte;
procedure Last_Block(Context : in out Context_T; Block : in u8_Array; Bits : in Integer := -1) is
Length : Natural;
Index : Integer := Block'First;
Dest_Index : Natural := 0;
begin
if Bits < 0 then
Length := Block'Length * 8;
else
Length := Bits;
end if;
while Length >= Rate_Bits loop
Next_Block(Context, Block(Index .. Index + Rate_Bytes - 1));
Index := Index + Rate_Bytes;
Length := Length - Rate_bits;
end loop;
-- append trailing bytes
while Length >= 8 loop
Append_Byte(Context, Dest_Index, Block(Index));
Index := Index + 1;
Length := Length - 8;
end loop;
-- append trailing bits
for j in 0 .. Length - 1 loop
Append_Bit(Context, Dest_Index, Bit(Shift_Right(Block(Index), j) mod 2));
end loop;
-- append suffix
for j in 0 .. Suffix_Bit_Length - 1 loop
Append_Bit(Context, Dest_Index, Bit(Shift_Right(Suffix, Natural(j)) mod 2));
end loop;
-- insert Padding
Append_Bit(Context, Dest_Index, 1);
Dest_Index := Rate_Bits - 1;
Append_Bit(Context, Dest_Index, 1);
end Last_Block;
procedure Squeeze(Context : in out Context_T; Data : out u8_Array) is
Temp : u8_Array(1 .. 8);
Length_A : Integer := Data'First;
Length_B : Integer;
j : Natural;
begin
for i in 0 .. Data'Length / Rate_Bytes loop
Length_B := Length_A + Rate_Bytes - 1;
if Length_B > Data'Last then
Length_B := Data'Last;
end if;
j := 0;
while Length_A + 8 <= Length_B loop
Store_le(Data(Length_A .. Length_A + 7), Context.A(x_t(j mod 5), y_t(j / 5)));
Length_A := Length_A + 8;
j := j + 1;
end loop;
if Length_A <= Length_B then
Store_le(Temp, Context.A(x_t(j mod 5), y_t(j / 5)));
Data(Length_A .. Length_B) := Temp(Temp'First .. Temp'First + Length_B - Length_A);
end if;
Length_A := Length_B;
if Length_B < Data'Last then
Permute(Context.A);
end if;
end loop;
end Squeeze;
procedure Get_Digest(Context : in out Context_T; Digest : out Digest_T) is
begin
Squeeze(Context, Digest);
end Get_Digest;
procedure Hash(Data : in u8_array; Digest : out Digest_T; Bits : in Integer := -1) is
Ctx : Context_T;
begin
Initialize(Ctx);
Last_Block(Ctx, Data, Bits);
Get_Digest(Ctx, Digest);
end Hash;
end Sha3_Generic;

View File

@ -0,0 +1,64 @@
-- 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 Keccak_Parameters; use Keccak_Parameters;
with Keccak; use Keccak;
use Crypto_Types.Crypto_Types_u8;
use Crypto_Types.Crypto_Types_u64;
generic
Capacity_Bits : Capacity_T;
Suffix : u64 := 2#10#;
Suffix_Bit_Length : u8 := 2;
package Sha3_Generic is
type Context_T is private;
BlockSize_Bits : constant Natural := b - Capacity_Bits;
DigestSize_Bits : constant Natural := Capacity_Bits / 2;
BlockSize_Bytes : constant Natural := BlockSize_Bits / 8;
DigestSize_Bytes : constant Natural := DigestSize_Bits / 8;
subtype Block_T is u8_Array(1 .. BlockSize_Bytes);
subtype Digest_T is u8_Array(1 .. DigestSize_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 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);
private
Rate_Bits : constant Capacity_T := b - Capacity_Bits;
Capacity_Bytes : constant Capacity_Bytes_T := Capacity_Bits / 8;
Rate_Bytes : constant Capacity_Bytes_T := Rate_Bits / 8;
Digest_Bits : constant Natural := Capacity_Bits / 2;
Digest_Bytes : constant Natural := Digest_Bits / 8;
type Context_T is record
A : State_T;
end record;
end Sha3_Generic;