adding SHA3
This commit is contained in:
parent
262194ad9d
commit
23059ef0c3
|
@ -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);
|
||||
}
|
|
@ -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")
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
|
@ -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;
|
||||
|
||||
|
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue