Nist_support (nist_support.adb): (Specification)


--  © Copyright 2000 by John Halleck, All rights reserved.
--  Basic support routines needed to allow SHA and DSA routines to run
--  through the NIST tests.
--  It is part of a project at http://www.cc.utah.edu/~nahaj/

with SHA.Process_Data;        use SHA.Process_Data;
with SHA.Strings;             use SHA.Strings;
with Ada.Integer_Text_IO;     use Ada.Integer_Text_IO;
with Ada.Characters.Handling; use Ada.Characters.Handling;

package body NIST_Support is


   --  Copy a block of comments from one file to another.
   procedure Copy_Comments (Source, Destination : File_Type) is
      At_End  : Boolean;
      Current : Character;
      Next    : Character;
   begin
      while End_Of_Line (Source) and not End_Of_File (Source) loop
         Skip_Line (Source);
      end loop;
      if End_Of_File (Source) then return; end if;
      Look_Ahead (Source, Next, At_End);
      while not At_End and Next = '#' loop
         while not End_Of_Line (Source) loop
            Get (Source, Current);
            Put (Destination, Current);
         end loop;
         Skip_Line (Source);
         New_Line (Destination);
         Look_Ahead (Source, Next, At_End);
      end loop;
   end Copy_Comments;


   --  This searches for a specific string.  It is *NOT* a general search,
   --  since it can't find strings where the initial part appears repeatedly
   --  in the file but at overlapping positions.  This is just a quick hack.

   procedure Get_String (File : File_Type;
                        Given : String;
                       Reason : String) is

      Test : Character;
      Was_OK : Boolean;
      Line : Boolean;

   begin

      if Given'Length < 1 then raise Constraint_Error; end if;
      if End_Of_File (File) then
         Put (Standard_Error, "Looking for: """);
         Put (Standard_Error, Given);
         Put_Line (Standard_Error, """");
         Put (Standard_Error, "Past end of file. (");
         Put (Standard_Error, Reason);
         Put_Line (Standard_Error, ")");
         raise NIST_File_Format_Error;
      end if;

      while not End_Of_File (File) loop
         if End_Of_Line (File) then
            Skip_Line (File);
         else
            Look_Ahead (File, Test, Line);
            if Test /= Given (Given'First) then
               Get (File, Test);
            else
               Was_OK := True;
               for I in Given'First .. Given'Last loop
                  Get (File, Test);
                  if Given (I) /= Test then Was_OK := False; exit; end if;
               end loop;
               if Was_OK then
                  return;
               end if;
            end if;
         end if;
      end loop;

      Put (Standard_Error, "Unable to find string: """);
      Put (Standard_Error, Given);
      Put_Line (Standard_Error, """");
      Put (Standard_Error, "   (");
      Put (Standard_Error, Reason);
      Put_Line (Standard_Error, ")");
      raise NIST_File_Format_Error;

   end Get_String;



   procedure Add_Bit_String_To_Hash (File : File_Type) is
      Z, B : Integer;
      Input : Integer;
   begin
      Get (File, Z);
      Get (File, B);
      if B /= 0 and B /= 1 then
         Put_Line (Standard_Error,
            "Non-Binary initial binary value in bit string");
         raise NIST_Number_Format_Error;
      end if;

      for J in 1 .. Z loop
         Get (File, Input);

         for I in 1 .. Input loop
            Add (Bit (B));
         end loop;

         B := 1 - B;
      end loop;

   exception
      when Data_Error =>
         Put_Line (Standard_Error,
             "Unable to read Integer while reading bit string");
         raise;
   end Add_Bit_String_To_Hash;



   function Hash_Bit_String (File : File_Type) return Digest is
      Result : Digest;
   begin
      Initialize;
      Add_Bit_String_To_Hash (File);
      Finalize (Result);
      return Result;
   end Hash_Bit_String;



   function Find_Next_Bit_String (File : File_Type)  return Boolean is
      Got : Character;
      Line_End : Boolean;
   begin
      while not End_Of_File (File) loop
         if End_Of_Line (File) then
            Skip_Line (File);
         else
            Look_Ahead (File, Got, Line_End);
            if Is_Digit (Got) then return True;  end if;
            if Got = '<'      then return False; end if;
            Get (File, Got);
            if Got /= ' ' and Got /= '^' and not Is_Control (Got) then
               return False;
            end if;
         end if;
      end loop;
      return False;
   end Find_Next_Bit_String;


   function Find_Hash (File : File_Type) return Boolean is
      Got : Character;
      Line_End : Boolean;
   begin
      while not End_Of_File (File) loop
         if End_Of_Line (File) then
            Skip_Line (File);
         else
            Look_Ahead (File, Got, Line_End);
            if Is_Hexadecimal_Digit (Got) then return True;  end if;
            if Got = '<'                  then return False; end if;
            Get (File, Got);
            if Got /= ' ' and Got /= '^' and not Is_Control (Got) then
               return False;
            end if;
         end if;
      end loop;
      return False;
   end Find_Hash;


   procedure Compare_Hash (File : File_Type; Hash : Hex_SHA_String) is
      Got : Character;
   begin
      for I in Hash'First .. Hash'Last loop
         if End_Of_File (File)    then
            raise NIST_File_Format_Error;
         elsif End_Of_Line (File) then
            raise NIST_File_Format_Error;
         end if;
         Get (File, Got);
         if not Is_Hexadecimal_Digit (Got) then
            raise NIST_File_Format_Error;
         elsif Got /= Hash (I) then
            raise NIST_Test_Failed_Error;
         end if;
      end loop;
   end Compare_Hash;


end NIST_Support;

Go to ...


This page is http://www.cc.utah.edu/~nahaj/ada/sha/nist_support.adb.html
© Copyright 2000 by John Halleck, All Rights Reserved.
This snapshot was last modified on October 30th, 2000