Fresheyeball Fresheyeball - 4 months ago 22
Pascal Question

Understanding legacy pascal

So I need to understand what this code is doing. I don't know pascal or cryptography, and am struggling to understand what is going on in here. I need to reverse engineer

SHA1DigestToHex
into scala and am totally lost beyond learning pascal. Can you tell me what this function is doing? Or how I can go about figuring it out?

Function SHA1DigestToHex (const Digest : T160BitDigest) : String;
Begin
Result := DigestToHex (Digest, Sizeof (Digest));
End;

Function DigestToHex (const Digest; const Size : Integer) : String;
Begin
SetLength (Result, Size * 2);
DigestToHexBuf (Digest, Size, Pointer (Result)^);
End;

Procedure DigestToHexBuf (const Digest; const Size : Integer; const Buf);
const s_HexDigitsLower : String [16] = '0123456789abcdef';
var I : Integer;
P : PChar;
Q : PByte;
Begin
P := @Buf;;
Assert (Assigned (P), 'Assigned (Buf)');
Q := @Digest;
Assert (Assigned (Q), 'Assigned (Digest)');
For I := 0 to Size - 1 do
begin
P^ := s_HexDigitsLower [Q^ shr 4 + 1];
Inc (P);
P^ := s_HexDigitsLower [Q^ and 15 + 1];
Inc (P);
Inc (Q);
end;
End;





UPDATE



type
PByte = ^Byte;
PWord = ^Word;
PLongWord = ^LongWord;
T128BitDigest = record
case integer of
0 : (Int64s : Array [0..1] of Int64);
1 : (Longs : Array [0..3] of LongWord);
2 : (Words : Array [0..7] of Word);
3 : (Bytes : Array [0..15] of Byte);
end;
P128BitDigest = ^T128BitDigest;
T160BitDigest = record
case integer of
0 : (Longs : Array [0..4] of LongWord);
1 : (Words : Array [0..9] of Word);
2 : (Bytes : Array [0..19] of Byte);
end;
P160BitDigest = ^T160BitDigest;

const
MaxHashDigestSize = Sizeof (T160BitDigest);

Procedure DigestToHexBuf (const Digest; const Size : Integer; const Buf);
Function DigestToHex (const Digest; const Size : Integer) : String;
Function Digest128Equal (const Digest1, Digest2 : T128BitDigest) : Boolean;
Function Digest160Equal (const Digest1, Digest2 : T160BitDigest) : Boolean;

Answer

It merely converts the bytes of the binary buffer passed in as Buf into a string of hexadecimal digits representing the same bytes in Digest.

So e.g. if Buf is the byte array (0x12, 0x34, 0x56), then afterwards Digest will be '123456'.

Here's a simpler Pascal (Delphi) version that does the same thing:

  function SHA1DigestToHex2(const Digest : T160BitDigest) : string;
  const s_HexDigitsLower : array[0..15] of char = '0123456789abcdef';
  var
    i, j: Integer;
  Begin
    SetLength(Result, sizeof(Digest) * 2);
    i := 1;
    j := 0;
    while j < sizeof(Digest) do begin
      Result[i] := s_HexDigitsLower[Digest.Bytes[j] shr 4];
      Result[i+1] := s_HexDigitsLower[Digest.Bytes[j] and $F];
      inc(i, 2);
      inc(j);
    end;
  End;