(**************************************************************************)
(*                                                                        *)
(*  Part of encryption software                                           *)
(*  Copyright (C) 2022   Peter Moylan                                     *)
(*                                                                        *)
(*  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/>. *)
(*                                                                        *)
(*  To contact author:   http://www.pmoylan.org   peter@pmoylan.org       *)
(*                                                                        *)
(**************************************************************************)

IMPLEMENTATION MODULE Digests;

        (********************************************************)
        (*                                                      *)
        (*  Converting a message digest to a hexidecimal string *)
        (*  for the case where the data are already in          *)
        (*  big-endian form.                                    *)
        (*                                                      *)
        (*  Common code for a variety of digest procedures.     *)
        (*                                                      *)
        (*  Programmer:         P. Moylan                       *)
        (*  Started:            3 May 2021                      *)
        (*  Last edited:        17 February 2022                *)
        (*  Status:             OK                              *)
        (*                                                      *)
        (********************************************************)


FROM SYSTEM IMPORT
    (* type *)  CARD8, CARD32;

(********************************************************************************)
(*                         CONVERTING DIGEST TO STRING                          *)
(********************************************************************************)

PROCEDURE ConvertHex1 (value: CARD8;  VAR (*INOUT*) string: ARRAY OF CHAR;
                                         VAR (*INOUT*) pos: CARDINAL);

    (* Writes a one-digit hex number to string[pos], then increments pos.  If   *)
    (* there is not enough space, no result is produced.                        *)

    VAR ch: CHAR;

    BEGIN
        IF value < 10 THEN
            ch := CHR(ORD('0') + value);
        ELSE
            ch := CHR(ORD('a') + value - 10);
        END (*IF*);
        IF pos <= HIGH(string) THEN
            string[pos] := ch;  INC(pos);
        END (*IF*);
    END ConvertHex1;

(********************************************************************************)

PROCEDURE ConvertHex2 (value: CARDINAL;  VAR (*INOUT*) string: ARRAY OF CHAR;
                                         VAR (*INOUT*) pos: CARDINAL);

    (* Writes a two-digit hex number to string, starting at string[pos]. *)

    BEGIN
        ConvertHex1 (value DIV 16, string, pos);
        ConvertHex1 (value MOD 16, string, pos);
    END ConvertHex2;

(********************************************************************************)

PROCEDURE DigestToString (N: CARDINAL;  VAR (*IN*) digest: ARRAY OF CARD8;
                             VAR (*OUT*) result: ARRAY OF CHAR);

    (* Converts the digest to a 2*N-character string.  If there is not enough   *)
    (* space for the result, produces a leading substring of the full result.   *)

    VAR i: [0..63];  pos: CARDINAL;

    BEGIN
        pos := 0;
        FOR i := 0 TO N-1 DO
            ConvertHex2 (digest[i], result, pos);
        END (*FOR*);
        IF pos <= HIGH(result) THEN
            result[pos] := CHR(0);
        END (*IF*);
    END DigestToString;

(********************************************************************************)

END Digests.

