-- © Copyright 2000 by John Halleck, All rights reserved.
-- Basic Routines of NSA's Secure Hash Algorithm.
-- This is part of a project at http://www.cc.utah.edu/~nahaj/
package SHA_0.Process_Data is
-- Note that the standard is not defined for data more than 2 ** 64 bits
-- long. (The count wraps at the point.) This code doesn't actually
-- check for that problem.
-- Default Context to use if you are only Hashing one thing at a time.
type Context is private; -- Current state of the operation.
type Context_Pointer is access all Context;
Default_Buffer : constant Context_Pointer;
-- What we can put in a buffer.
type Bit is mod 2 ** 1;
type Byte is mod 2 ** 8;
type Word is mod 2 ** 16;
type Long is mod 2 ** 32;
type Bit_Index is new Natural range 0 .. Bits_In_Word;
-- Most folk just want to Digest a string, so we will have this entry
-- Point to keep it simple.
function Digest_A_String (Given : String) return Digest;
-- -- -- --
-- For those that want more control, we provide actual entry points.
-- Start out the buffer.
procedure Initialize (Given : access Context := Default_Buffer);
-- Procedures to add to the data being hashed.
-- The standard really does define the hash in terms of bits.
-- So, in opposition to common practice, I'm providing routines
-- that can process Bytes or Non_Bytes.
-- You may freely mix the sizes, even if it means partial word
-- alignment in the actual buffer.
procedure Add (Data : Bit;
Given : access Context := Default_Buffer);
SHA_Not_Initialized : exception;
procedure Add (Data : Byte;
Given : access Context := Default_Buffer);
procedure Add (Data : Word;
Given : access Context := Default_Buffer);
procedure Add (Data : Long;
Given : access Context := Default_Buffer);
-- Add arbitrary sized data.
procedure Add (Data : Long;
Size : Bit_Index;
Given : access Context := Default_Buffer);
-- Get the final digest.
function Finalize (Given : access Context := Default_Buffer)
return Digest;
private
Initial_Context : constant Digest := -- Directly from the standard.
(16#67452301#, 16#EFCDAB89#, 16#98BADCFE#, 16#10325476#, 16#C3D2E1F0#);
Words_In_Buffer : constant := 16;
type Word_Range is new Natural range 0 .. Words_In_Buffer - 1;
type Word_Index is new Natural range 1 .. Words_In_Buffer;
type Data_Buffer is array (Word_Range) of Unsigned_32;
type Context is record
Data : Data_Buffer := (others => 0);
Count : Unsigned_64 := 0;
Remaining_Bits : Bit_Index := 32;
Next_Word : Word_Range := 0;
Current : Digest := Initial_Context;
Initialized : Boolean := False;
end record;
-- Note that on machine that don't have Unsigned_64, you could
-- implement Count as two Unsigned_32's, since the only operation
-- is adding a number <= 32;
-- In that case the declaration for Count above should be
-- Count : array (0, 1) of Unsigned_32 := (0,0);
-- If you are only hashing one thing at a time, having a canned default
-- buffer makes all the calls simpler.
A_Default_Buffer : aliased Context;
Default_Buffer : constant Context_Pointer := A_Default_Buffer'Access;
end SHA_0.Process_Data;
This page is http://www.cc.utah.edu/~nahaj/ada/sha/sha-0/sha_0-process_data.ads.html
© Copyright 2000 by John Halleck, All Rights Reserved.
This snapshot was last modified on August 23rd, 2000