HlpHAS160.pas 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. unit HlpHAS160;
  2. {$I ..\Include\HashLib.inc}
  3. interface
  4. uses
  5. {$IFDEF DELPHI2010}
  6. SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
  7. {$ENDIF DELPHI2010}
  8. HlpHashLibTypes,
  9. {$IFDEF DELPHI}
  10. HlpHashBuffer,
  11. HlpBitConverter,
  12. {$ENDIF DELPHI}
  13. HlpConverters,
  14. HlpIHashInfo,
  15. HlpHashCryptoNotBuildIn;
  16. type
  17. THAS160 = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
  18. strict private
  19. Fm_hash: THashLibUInt32Array;
  20. {$REGION 'Consts'}
  21. const
  22. s_rot: array [0 .. 19] of Int32 = (5, 11, 7, 15, 6, 13, 8, 14, 7, 12, 9, 11,
  23. 8, 15, 6, 12, 9, 14, 5, 13);
  24. s_tor: array [0 .. 19] of Int32 = (27, 21, 25, 17, 26, 19, 24, 18, 25, 20,
  25. 23, 21, 24, 17, 26, 20, 23, 18, 27, 19);
  26. s_index: array [0 .. 79] of Int32 = (18, 0, 1, 2, 3, 19, 4, 5, 6, 7, 16, 8,
  27. 9, 10, 11, 17, 12, 13, 14, 15, 18, 3, 6, 9, 12, 19, 15, 2, 5, 8, 16, 11,
  28. 14, 1, 4, 17, 7, 10, 13, 0, 18, 12, 5, 14, 7, 19, 0, 9, 2, 11, 16, 4, 13,
  29. 6, 15, 17, 8, 1, 10, 3, 18, 7, 2, 13, 8, 19, 3, 14, 9, 4, 16, 15, 10, 5,
  30. 0, 17, 11, 6, 1, 12);
  31. {$ENDREGION}
  32. strict protected
  33. procedure Finish(); override;
  34. function GetResult(): THashLibByteArray; override;
  35. procedure TransformBlock(a_data: PByte; a_data_length: Int32;
  36. a_index: Int32); override;
  37. public
  38. constructor Create();
  39. procedure Initialize(); override;
  40. end;
  41. implementation
  42. { THAS160 }
  43. constructor THAS160.Create;
  44. begin
  45. Inherited Create(20, 64);
  46. System.SetLength(Fm_hash, 5);
  47. end;
  48. procedure THAS160.Finish;
  49. var
  50. pad_index: Int32;
  51. bits: UInt64;
  52. pad: THashLibByteArray;
  53. begin
  54. bits := Fm_processed_bytes * 8;
  55. if (Fm_buffer.Pos < 56) then
  56. pad_index := (56 - Fm_buffer.Pos)
  57. else
  58. pad_index := (120 - Fm_buffer.Pos);
  59. System.SetLength(pad, pad_index + 8);
  60. pad[0] := $80;
  61. bits := TConverters.le2me_64(bits);
  62. TConverters.ReadUInt64AsBytesLE(bits, pad, pad_index);
  63. pad_index := pad_index + 8;
  64. TransformBytes(pad, 0, pad_index);
  65. end;
  66. function THAS160.GetResult: THashLibByteArray;
  67. begin
  68. System.SetLength(result, 5 * System.SizeOf(UInt32));
  69. TConverters.le32_copy(PCardinal(Fm_hash), 0, PByte(result), 0,
  70. System.Length(result));
  71. end;
  72. procedure THAS160.Initialize;
  73. begin
  74. Fm_hash[0] := $67452301;
  75. Fm_hash[1] := $EFCDAB89;
  76. Fm_hash[2] := $98BADCFE;
  77. Fm_hash[3] := $10325476;
  78. Fm_hash[4] := $C3D2E1F0;
  79. Inherited Initialize();
  80. end;
  81. procedure THAS160.TransformBlock(a_data: PByte; a_data_length: Int32;
  82. a_index: Int32);
  83. var
  84. A, B, C, D, E, T: UInt32;
  85. r: Int32;
  86. data: array [0 .. 19] of UInt32;
  87. begin
  88. A := Fm_hash[0];
  89. B := Fm_hash[1];
  90. C := Fm_hash[2];
  91. D := Fm_hash[3];
  92. E := Fm_hash[4];
  93. TConverters.le32_copy(a_data, a_index, @(data[0]), 0, a_data_length);
  94. data[16] := data[0] xor data[1] xor data[2] xor data[3];
  95. data[17] := data[4] xor data[5] xor data[6] xor data[7];
  96. data[18] := data[8] xor data[9] xor data[10] xor data[11];
  97. data[19] := data[12] xor data[13] xor data[14] xor data[15];
  98. r := 0;
  99. while r < 20 do
  100. begin
  101. T := data[s_index[r]] + (A shl s_rot[r] or A shr s_tor[r]) +
  102. ((B and C) or (not B and D)) + E;
  103. E := D;
  104. D := C;
  105. C := B shl 10 or B shr 22;
  106. B := A;
  107. A := T;
  108. System.Inc(r);
  109. end;
  110. data[16] := data[3] xor data[6] xor data[9] xor data[12];
  111. data[17] := data[2] xor data[5] xor data[8] xor data[15];
  112. data[18] := data[1] xor data[4] xor data[11] xor data[14];
  113. data[19] := data[0] xor data[7] xor data[10] xor data[13];
  114. r := 20;
  115. while r < 40 do
  116. begin
  117. T := data[s_index[r]] + $5A827999 +
  118. (A shl s_rot[r - 20] or A shr s_tor[r - 20]) + (B xor C xor D) + E;
  119. E := D;
  120. D := C;
  121. C := B shl 17 or B shr 15;
  122. B := A;
  123. A := T;
  124. System.Inc(r);
  125. end;
  126. data[16] := data[5] xor data[7] xor data[12] xor data[14];
  127. data[17] := data[0] xor data[2] xor data[9] xor data[11];
  128. data[18] := data[4] xor data[6] xor data[13] xor data[15];
  129. data[19] := data[1] xor data[3] xor data[8] xor data[10];
  130. r := 40;
  131. while r < 60 do
  132. begin
  133. T := data[s_index[r]] + $6ED9EBA1 +
  134. (A shl s_rot[r - 40] or A shr s_tor[r - 40]) + (C xor (B or not D)) + E;
  135. E := D;
  136. D := C;
  137. C := B shl 25 or B shr 7;
  138. B := A;
  139. A := T;
  140. System.Inc(r);
  141. end;
  142. data[16] := data[2] xor data[7] xor data[8] xor data[13];
  143. data[17] := data[3] xor data[4] xor data[9] xor data[14];
  144. data[18] := data[0] xor data[5] xor data[10] xor data[15];
  145. data[19] := data[1] xor data[6] xor data[11] xor data[12];
  146. r := 60;
  147. while r < 80 do
  148. begin
  149. T := data[s_index[r]] + $8F1BBCDC +
  150. (A shl s_rot[r - 60] or A shr s_tor[r - 60]) + (B xor C xor D) + E;
  151. E := D;
  152. D := C;
  153. C := B shl 30 or B shr 2;
  154. B := A;
  155. A := T;
  156. System.Inc(r);
  157. end;
  158. Fm_hash[0] := Fm_hash[0] + A;
  159. Fm_hash[1] := Fm_hash[1] + B;
  160. Fm_hash[2] := Fm_hash[2] + C;
  161. Fm_hash[3] := Fm_hash[3] + D;
  162. Fm_hash[4] := Fm_hash[4] + E;
  163. System.FillChar(data, System.SizeOf(data), 0);
  164. end;
  165. end.