Sha_0_process_data_test (sha_0_process_data_test.adb):


--  © Copyright 1999, John Halleck,  All Rights Reserved
--  Test the SHA package
--  This is part of a project at http://www.cc.utah.edu/~nahaj/

with Ada.Text_IO;      use Ada.Text_IO;

with Interfaces;       use Interfaces;  --  We need bit rotates...

with Ada.Command_Line; use Ada.Command_Line;

with SHA_0;              use SHA_0;              -- Definition of a digest.
with SHA_0.Strings;      use SHA_0.Strings;      -- Convert Digest to String.
with SHA_0.Process_Data; use SHA_0.Process_Data; -- Compute Digests.


procedure SHA_0_Process_Data_TEST is

   Expected : Digest :=
       (16#0164B8A9#, 16#14CD2A5E#, 16#74C4F7FF#, 16#082C4D97#, 16#F1EDF880#);

   Computed : Digest;
   Actual   : Digest;


   type Test_Index is new Natural range 0 .. ((256 * 8) - 1);
   Buffer : array (Test_Index) of Boolean;


   Result    : Exit_Status := Success;

   procedure Verify (Assumed, Given : Digest);
   --  (Keep over agressive style checkers happy.)
   procedure Verify (Assumed, Given : Digest) is
   begin
      if Assumed = Given then
         Put_Line (" Passed!");
      else
         Put_Line (" *** FAILED ***");
         Put ("     Expected: ");
         Put_Line (String (Hex_From_SHA (Assumed)));
         Put ("          Got: ");
         Put_Line (String (Hex_From_SHA (Given)));
         Result := Failure;
      end if;
   end Verify;

   function Get_Byte (Index : Test_Index) return Byte;
   function Get_Byte (Index : Test_Index) return Byte is
      Result : Byte := 0;
   begin
      for I in 0 .. Test_Index (8 - 1) loop
         Result := Result * 2;
         if Buffer (I + Index) then
            Result := Result + 1;
         end if;
      end loop;
      return Result;
   end Get_Byte;

   function Get_Word (Index : Test_Index) return Word;
   function Get_Word (Index : Test_Index) return Word is
      Result : Word := 0;
   begin
      for I in 0 .. Test_Index (16 - 1) loop
         Result := Result * 2;
         if Buffer (I + Index) then
            Result := Result + 1;
         end if;
      end loop;
      return Result;
   end Get_Word;

   function Get_Long (Index : Test_Index) return Long;
   function Get_Long (Index : Test_Index) return Long is
      Result : Long := 0;
   begin
      for I in 0 .. Test_Index (32 - 1) loop
         Result := Result * 2;
         if Buffer (I + Index) then
            Result := Result + 1;
         end if;
      end loop;
      return Result;
   end Get_Long;

   function Get_Integer (Index : Test_Index; Size : Positive)
      return Unsigned_32;
   function Get_Integer (Index : Test_Index; Size : Positive)
      return   Unsigned_32 is
      Result : Unsigned_32 := 0;
   begin
      for I in Index .. Index + Test_Index (Size - 1) loop
         Result := Result * 2;
         if Buffer (I + Index) then
            Result := Result + 1;
         end if;
      end loop;
      return Result;
   end Get_Integer;

   procedure Put_Byte (Index : Test_Index; Given : Unsigned_8);
   procedure Put_Byte (Index : Test_Index; Given : Unsigned_8) is
   begin
      for I in 0 .. 7 loop
         Buffer (Test_Index (I) + Index) := (Given and 2 ** (7 - I)) /= 0;
      end loop;
   end Put_Byte;

   procedure Set_Bit (Which : Boolean);
   procedure Set_Bit (Which : Boolean) is
   begin
      if Which then Add (Bit (1)); else Add (Bit (0)); end if;
   end Set_Bit;

begin

   Put_Line ("SHA_0.Process_Data test [Secure Hash Algorithm] starting ...");

   Put_Line (" The test given in FIPS PUB 180 (the Standard) ... ");

   Actual := Digest_A_String ("abc");
   Verify (Expected, Actual);

   --  This isn't much of a test, but is all the standard gave.
   --  However this code was tested more closely when it was an
   --  option under the full SHA code.

   --  The rest of the tests are now more or less consistancy checks.


   --  What should the answer be?
   Initialize;
   for I in 0 .. 255 loop
      Add (Byte (I));
   end loop;
   Actual := Finalize;
   --  We've just tested the byte versions, so we will use them as a reference.

   --  Ok, Fill in the bits.
   for I in 0 .. 255 loop
      Put_Byte (Test_Index (I * 8), Unsigned_8 (I));
   end loop;
   Put_Line (" (Reference value computed)");

   --  And what do we get with just adding bits?
   Initialize;
   Put ("   Testing hash of single bits...");
   for I in Test_Index loop
      Set_Bit (Buffer (I));
   end loop;
   Computed := Finalize;
   Verify (Actual, Computed);

--  If this worked, we know that the main bit add on works...

   Put ("   Testing hash of generated bytes...");
   Initialize;
   for I in Test_Index'First .. Test_Index'Last / 8 loop
      Add (Get_Byte (I * 8));
   end loop;
   Computed := Finalize;
   Verify (Actual, Computed);
--  We know know that the byte primitives in this file work.
   Put ("   Testing hash of generated words...");
   Initialize;
   for I in Test_Index'First .. Test_Index'Last / 16 loop
      Add (Get_Word (I * 16));
   end loop;
   Computed := Finalize;
   Verify (Actual, Computed);
--  We know that the word primitives work.
   Put ("   Testing hash of generated Long...");
   Initialize;
   for I in Test_Index'First .. Test_Index'Last / 32 loop
      Add (Get_Long (I * 32));
   end loop;
   Computed := Finalize;
   Verify (Actual, Computed);
--  OK, without partical word alignment the longs work too...

--  OK, now for the acid test.  Do part word operations all work correctly?

--  We will force all alignments on byte operations.
   Put_Line ("   Testing Byte offsets:");
   for I in 0 .. Test_Index (8 - 1) loop
      Put ("      Testing byte with offset of ");
      Put (Integer'Image (Integer (I)));
      Put (" ...");
      Initialize;
      for J in 0 .. I - 1 loop
         Set_Bit (Buffer (J));
      end loop;
      for J in 0 .. Test_Index'Last / 8 - 1 loop
         Add (Get_Byte (I  +  J * 8));
      end loop;
      for J in Test_Index'Last - Test_Index (8 - I) + 1 .. Test_Index'Last loop
         Set_Bit (Buffer (J));
      end loop;
      Computed := Finalize;
      Verify (Actual, Computed);
   end loop;

--  And word offsets.
   Put_Line ("   Testing Word Alignments:");
   for I in 0 .. Test_Index (16 - 1) loop
      Put ("      Testing word with offset of ");
      Put (Integer'Image (Integer (I)));
      Put (" ...");
      Initialize;
      for J in 0 .. I - 1 loop
         Set_Bit (Buffer (J));
      end loop;
      for J in 0 .. Test_Index'Last / 16 - 1 loop
         Add (Get_Word (I  +  J * 16));
      end loop;
      for J in Test_Index'Last - Test_Index (16 - I) + 1 ..
               Test_Index'Last loop
         Set_Bit (Buffer (J));
      end loop;
      Computed := Finalize;
      Verify (Actual, Computed);
   end loop;
--  And long word offsets
   Put_Line ("   Testing Long Word Alignments:");
   for I in 0 .. Test_Index (32 - 1) loop
      Put ("      Testing Long Word with offset of ");
      Put (Integer'Image (Integer (I)));
      Put (" ...");
      Initialize;
      for J in 0 .. I - 1 loop
         Set_Bit (Buffer (J));
      end loop;
      for J in 0 .. Test_Index'Last / 32 - 1 loop
         Add (Get_Long (I  +  J * 32));
      end loop;
      for J in Test_Index'Last - Test_Index (32 - I) + 1 ..
               Test_Index'Last loop
         Set_Bit (Buffer (J));
      end loop;
      Computed := Finalize;
      Verify (Actual, Computed);
   end loop;



   --  -- -------------------   Cleanup. -----------------


   Put ("SHA_0.Process_Data test ");
   if Result = Success then
      Put ("Passed!");
   else
      Put ("*** FAILED ****");
   end if;
   New_Line;

   Set_Exit_Status (Result);

end SHA_0_Process_Data_TEST;

Go to ...


This page is http://www.cc.utah.edu/~nahaj/ada/sha/sha-0/sha_0_process_data_test.adb.html
© Copyright 2000 by John Halleck, All Rights Reserved.
This snapshot was last modified on August 23rd, 2000