Subversion Repositories decoder

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 daniel-mar 1
{Copyright:      Hagen Reddmann  HaReddmann at T-Online dot de
2
 Author:         Hagen Reddmann
3
 Remarks:        freeware, but this Copyright must be included
4
 known Problems: none
5
 Version:        5.1,  Part I from Delphi Encryption Compendium  ( DEC Part I)
6
                 Delphi 5
7
 
8
 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
9
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
11
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
12
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
13
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
14
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
15
 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
16
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
17
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
18
 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
19
 
20
}
21
 
22
unit DECHash;
23
 
24
interface
25
 
26
uses SysUtils, Classes, DECUtil, DECFmt;
27
 
28
{$I VER.INC}
29
 
30
type
31
{all Hash Classes}
32
  THash_MD2             = class;  {$DEFINE THash_MD2_asm}
33
  THash_MD4             = class;  {$DEFINE THash_MD4_asm}
34
  THash_MD5             = class;  {$DEFINE THash_MD5_asm}
35
  THash_RipeMD128       = class;  {$DEFINE THash_RipeMD128_asm}
36
  THash_RipeMD160       = class;  {$DEFINE THash_RipeMD160_asm}
37
  THash_RipeMD256       = class;  {$DEFINE THash_RipeMD256_asm}
38
  THash_RipeMD320       = class;  {$DEFINE THash_RipeMD320_asm}
39
  THash_SHA             = class;  {$DEFINE THash_SHA_asm}
40
  THash_SHA1            = class;
41
  THash_SHA256          = class;  {.$DEFINE THash_SHA256_asm}
42
  THash_SHA384          = class;  {$DEFINE THash_SHA384_asm}
43
  THash_SHA512          = class;
44
  THash_Haval128        = class;  {$DEFINE THashBaseHaval_asm}
45
  THash_Haval160        = class;
46
  THash_Haval192        = class;
47
  THash_Haval224        = class;
48
  THash_Haval256        = class;
49
  THash_Tiger           = class;  {$DEFINE THash_Tiger_asm}
50
  THash_Panama          = class;  {.$DEFINE THash_Panama_asm}
51
  THash_Whirlpool       = class;  {$DEFINE THashBaseWhirlpool_asm}
52
  THash_Whirlpool1      = class;
53
  THash_Square          = class;  {$DEFINE THash_Square_asm}
54
  THash_Snefru128       = class;  {$DEFINE THash_Snefru128_asm}
55
  THash_Snefru256       = class;  {$DEFINE THash_Snefru256_asm}
56
  THash_Sapphire        = class;  {$DEFINE THash_Sapphire_asm}
57
 
58
  TDECHashClass = class of TDECHash;
59
 
60
  TDECHash = class(TDECObject)
61
  protected
62
    FCount: array[0..7] of LongWord;
63
    FBuffer: PByteArray;
64
    FBufferSize: Integer;
65
    FBufferIndex: Integer;
66
    FPaddingByte: Byte;
67
    procedure DoTransform(Buffer: PLongArray); virtual; abstract;
68
    procedure DoInit; virtual; abstract;
69
    procedure DoDone; virtual; abstract;
70
  public
71
    destructor Destroy; override;
72
 
73
    procedure Init;
74
    procedure Calc(const Data; DataSize: Integer); virtual;
75
    procedure Done;
76
 
77
    function Digest: PByteArray; virtual; abstract;
78
    function DigestStr(Format: TDECFormatClass = nil): Binary; virtual;
79
 
80
    class function DigestSize: Integer; virtual; abstract;
81
    class function BlockSize: Integer; virtual; abstract;
82
 
83
    class function CalcBuffer(const Buffer; BufferSize: Integer; Format: TDECFormatClass = nil): Binary;
84
    class function CalcStream(const Stream: TStream; Size: Int64; Format: TDECFormatClass = nil; const Progress: IDECProgress = nil): Binary;
85
    class function CalcBinary(const Data: Binary; Format: TDECFormatClass = nil): Binary;
86
    class function CalcFile(const FileName: String; Format: TDECFormatClass = nil; const Progress: IDECProgress = nil): Binary;
87
 
88
    class function MGF1(const Data: Binary; MaskSize: Integer; Format: TDECFormatClass = nil): Binary; overload;
89
    class function MGF1(const Data; DataSize, MaskSize: Integer; Format: TDECFormatClass = nil): Binary; overload;
90
    class function KDF2(const Data,Seed: Binary; MaskSize: Integer; Format: TDECFormatClass = nil): Binary; overload;
91
    class function KDF2(const Data; DataSize: Integer; const Seed; SeedSize, MaskSize: Integer; Format: TDECFormatClass = nil): Binary; overload;
92
   // DEC's own KDF+MGF
93
    class function MGFx(const Data; DataSize, MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary; overload;
94
    class function MGFx(const Data: Binary; MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary; overload;
95
    class function KDFx(const Data,Seed: Binary; MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary; overload;
96
    class function KDFx(const Data; DataSize: Integer; const Seed; SeedSize, MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary; overload;
97
  published
98
    property PaddingByte: Byte read FPaddingByte write FPaddingByte;
99
  end;
100
 
101
  THash_MD2 = class(TDECHash)
102
  private
103
    FDigest: array[0..63] of Byte;
104
  protected
105
    procedure DoTransform(Buffer: PLongArray); override;
106
    procedure DoInit; override;
107
    procedure DoDone; override;
108
  public
109
    class function DigestSize: Integer; override;
110
    class function BlockSize: Integer; override;
111
    function Digest: PByteArray; override;
112
  end;
113
 
114
  THashBaseMD4 = class(TDECHash)
115
  private
116
    FDigest: array[0..9] of LongWord;
117
  protected
118
    procedure DoInit; override;
119
    procedure DoDone; override;
120
  public
121
    class function DigestSize: Integer; override;
122
    class function BlockSize: Integer; override;
123
    function Digest: PByteArray; override;
124
  end;
125
 
126
  THash_MD4 = class(THashBaseMD4)
127
  protected
128
    procedure DoTransform(Buffer: PLongArray); override;
129
  end;
130
 
131
  THash_MD5 = class(THashBaseMD4)
132
  protected
133
    procedure DoTransform(Buffer: PLongArray); override;
134
  end;
135
 
136
  THash_RipeMD128 = class(THashBaseMD4)
137
  protected
138
    procedure DoTransform(Buffer: PLongArray); override;
139
  end;
140
 
141
  THash_RipeMD160 = class(THashBaseMD4)
142
  protected
143
    procedure DoTransform(Buffer: PLongArray); override;
144
  public
145
    class function DigestSize: Integer; override;
146
  end;
147
 
148
  THash_RipeMD256 = class(THashBaseMD4)
149
  protected
150
    procedure DoTransform(Buffer: PLongArray); override;
151
    procedure DoInit; override;
152
  public
153
    class function DigestSize: Integer; override;
154
  end;
155
 
156
  THash_RipeMD320 = class(THashBaseMD4)
157
  protected
158
    procedure DoTransform(Buffer: PLongArray); override;
159
  public
160
    class function DigestSize: Integer; override;
161
  end;
162
 
163
  THash_SHA = class(THashBaseMD4)
164
  protected
165
    procedure DoTransform(Buffer: PLongArray); override;
166
    procedure DoDone; override;
167
  public
168
    class function DigestSize: Integer; override;
169
  end;
170
 
171
  THash_SHA1 = class(THash_SHA);
172
 
173
  THash_SHA256 = class(THash_SHA)
174
  protected
175
    procedure DoTransform(Buffer: PLongArray); override;
176
    procedure DoInit; override;
177
  public
178
    class function DigestSize: Integer; override;
179
  end;
180
 
181
  THash_SHA384 = class(TDECHash)
182
  private
183
    FDigest: array[0..7] of Int64;
184
  protected
185
    procedure DoTransform(Buffer: PLongArray); override;
186
    procedure DoInit; override;
187
    procedure DoDone; override;
188
  public
189
    class function DigestSize: Integer; override;
190
    class function BlockSize: Integer; override; // 128
191
    function Digest: PByteArray; override;
192
  end;
193
 
194
  THash_SHA512 = class(THash_SHA384)
195
  protected
196
    procedure DoInit; override;
197
  public
198
    class function DigestSize: Integer; override;
199
  end;
200
 
201
  THashBaseHaval = class(TDECHash)
202
  private
203
    FDigest: array[0..7] of LongWord;
204
    FRounds: Integer; {3 - 5}
205
    FTransform: procedure(Buffer: PLongArray) of object;
206
    procedure SetRounds(Value: Integer);
207
  protected
208
    procedure DoTransform (Buffer: PLongArray); override;
209
    procedure DoTransform3(Buffer: PLongArray);
210
    procedure DoTransform4(Buffer: PLongArray);
211
    procedure DoTransform5(Buffer: PLongArray);
212
    procedure DoInit; override;
213
    procedure DoDone; override;
214
  public
215
    class function BlockSize: Integer; override;
216
    function Digest: PByteArray; override;
217
  published
218
    property Rounds: Integer read FRounds write SetRounds;
219
  end;
220
 
221
  THash_Haval128 = class(THashBaseHaval)
222
  public
223
    class function DigestSize: Integer; override;
224
  end;
225
 
226
  THash_Haval160 = class(THashBaseHaval)
227
  public
228
    class function DigestSize: Integer; override;
229
  end;
230
 
231
  THash_Haval192 = class(THashBaseHaval)
232
  public
233
    class function DigestSize: Integer; override;
234
  end;
235
 
236
  THash_Haval224 = class(THashBaseHaval)
237
  public
238
    class function DigestSize: Integer; override;
239
  end;
240
 
241
  THash_Haval256 = class(THashBaseHaval)
242
  public
243
    class function DigestSize: Integer; override;
244
  end;
245
 
246
  THash_Tiger = class(THashBaseMD4)
247
  private
248
    FRounds: Integer;
249
    procedure SetRounds(Value: Integer);
250
  protected
251
    procedure DoTransform(Buffer: PLongArray); override;
252
    procedure DoInit; override;
253
  public
254
    class function DigestSize: Integer; override;
255
  published
256
    property Rounds: Integer read FRounds write SetRounds;
257
  end;
258
 
259
  THash_Panama = class(TDECHash)
260
  private
261
    FLFSRBuffer: array[0..31, 0..7] of LongWord;
262
    FDigest: array[0..16] of LongWord;
263
    FTap: LongWord;
264
  protected
265
    procedure DoInit; override;
266
    procedure DoDone; override;
267
    procedure DoPull;
268
    procedure DoTransform(Buffer: PLongArray); override;
269
  public
270
    class function DigestSize: Integer; override;
271
    class function BlockSize: Integer; override; // 32
272
    function Digest: PByteArray; override;
273
  end;
274
 
275
  THashBaseWhirlpool = class(TDECHash)
276
  private
277
    FDigest: array[0..15] of LongWord;
278
    FTableC: Pointer;
279
    FTableR: Pointer;
280
  protected
281
    procedure DoTransform(Buffer: PLongArray); override;
282
    procedure DoDone; override;
283
  public
284
    class function DigestSize: Integer; override;
285
    class function BlockSize: Integer; override;
286
    function Digest: PByteArray; override;
287
  end;
288
 
289
  THash_Whirlpool = class(THashBaseWhirlpool)
290
  protected
291
    procedure DoInit; override;
292
  end;
293
 
294
  THash_Whirlpool1 = class(THashBaseWhirlpool)
295
  protected
296
    procedure DoInit; override;
297
  end;
298
 
299
  THash_Square = class(TDECHash)
300
  private
301
    FDigest: array[0..3] of LongWord;
302
  protected
303
    procedure DoInit; override;
304
    procedure DoDone; override;
305
    procedure DoTransform(Buffer: PLongArray); override;
306
  public
307
    class function DigestSize: Integer; override;
308
    class function BlockSize: Integer; override;
309
    function Digest: PByteArray; override;
310
  end;
311
 
312
  THashBaseSnefru = class(TDECHash)  {"derived from the Xerox Secure Hash Function"}
313
  private
314
    FDigest: array[0..23] of LongWord;
315
    FSecurity_Level: Integer;
316
    procedure SetSecurity_Level(Value: Integer);
317
  protected
318
    procedure DoInit; override;
319
    procedure DoDone; override;
320
  public
321
    function Digest: PByteArray; override;
322
  published
323
    property Security_Level: Integer read FSecurity_Level write SetSecurity_Level; // can set from 2 to 8, default is 8
324
  end;
325
 
326
  THash_Snefru128 = class(THashBaseSnefru)
327
  protected
328
    procedure DoTransform(Buffer: PLongArray); override;
329
  public
330
    class function DigestSize: Integer; override;
331
    class function BlockSize: Integer; override; // 48
332
  end;
333
 
334
  THash_Snefru256 = class(THashBaseSnefru)
335
  protected
336
    procedure DoTransform(Buffer: PLongArray); override;
337
  public
338
    class function DigestSize: Integer; override;
339
    class function BlockSize: Integer; override;  // 32
340
  end;
341
 
342
  THash_Sapphire = class(TDECHash)
343
  private
344
    FCards: array[0..255] of LongWord;
345
    FDigest: array[0..15] of LongWord;
346
    FRotor: LongWord;                 // don't change order
347
    FRatchet: LongWord;
348
    FAvalanche: LongWord;
349
    FPlain: LongWord;
350
    FCipher: LongWord;
351
    FDigestSize: Integer;
352
  protected
353
    procedure DoInit; override;
354
    procedure DoDone; override;
355
  public
356
    class function BlockSize: Integer; override;
357
    class function DigestSize: Integer; override;
358
    function Digest: PByteArray; override;
359
    function DigestStr(Format: TDECFormatClass = nil): Binary; override;
360
    procedure Calc(const Data; DataSize: Integer); override;
361
  published
362
    property RequestedDigestSize: Integer read FDigestSize write FDigestSize;
363
  end;
364
 
365
function  ValidHash(HashClass: TDECHashClass = nil): TDECHashClass;
366
function  HashByName(const Name: String): TDECHashClass;
367
function  HashByIdentity(Identity: LongWord): TDECHashClass;
368
procedure SetDefaultHashClass(HashClass: TDECHashClass);
369
 
370
var
371
  StreamBufferSize: Integer = 8192;
372
 
373
implementation
374
 
375
uses DECData;
376
 
377
{$I *.inc}
378
 
379
{                                        assembler                             pascal
380
THash_SHA512        :       85.1 cycles/byte      17.62 Mb/sec      220.9 cycles/byte       6.79 Mb/sec  159%
381
THash_SHA384        :       85.2 cycles/byte      17.61 Mb/sec      220.0 cycles/byte       6.82 Mb/sec  158%
382
THash_Tiger         :       24.6 cycles/byte      60.98 Mb/sec       60.7 cycles/byte      24.69 Mb/sec  147%
383
THash_Haval128      :       13.3 cycles/byte     112.55 Mb/sec       26.0 cycles/byte      57.77 Mb/sec   95%
384
THash_SHA1          :       20.1 cycles/byte      74.80 Mb/sec       36.1 cycles/byte      41.51 Mb/sec   80%
385
THash_SHA           :       20.0 cycles/byte      75.03 Mb/sec       35.5 cycles/byte      42.21 Mb/sec   78%
386
THash_Haval160      :       13.2 cycles/byte     113.30 Mb/sec       22.7 cycles/byte      66.12 Mb/sec   71%
387
THash_Haval256      :       25.9 cycles/byte      57.84 Mb/sec       40.5 cycles/byte      37.07 Mb/sec   56%
388
THash_Snefru128     :      159.7 cycles/byte       9.39 Mb/sec      248.2 cycles/byte       6.04 Mb/sec   55%
389
THash_Snefru256     :      239.3 cycles/byte       6.27 Mb/sec      367.9 cycles/byte       4.08 Mb/sec   54%
390
THash_RipeMD256     :       14.5 cycles/byte     103.16 Mb/sec       21.4 cycles/byte      70.08 Mb/sec   47%
391
THash_MD4           :        5.8 cycles/byte     256.73 Mb/sec        8.5 cycles/byte     176.92 Mb/sec   45%
392
 
393
THash_MD2           :      251.6 cycles/byte       5.96 Mb/sec      366.1 cycles/byte       4.10 Mb/sec   45%
394
THash_RipeMD128     :       15.2 cycles/byte      98.89 Mb/sec       21.2 cycles/byte      70.61 Mb/sec   40%
395
THash_RipeMD320     :       25.5 cycles/byte      58.73 Mb/sec       35.8 cycles/byte      41.87 Mb/sec   40%
396
THash_MD5           :        8.9 cycles/byte     169.43 Mb/sec       11.4 cycles/byte     131.01 Mb/sec   29%
397
THash_RipeMD160     :       26.5 cycles/byte      56.66 Mb/sec       31.4 cycles/byte      47.79 Mb/sec   19%
398
THash_Square        :       44.7 cycles/byte      33.58 Mb/sec       53.1 cycles/byte      28.23 Mb/sec   19%
399
THash_Haval192      :       32.5 cycles/byte      46.17 Mb/sec       37.6 cycles/byte      39.87 Mb/sec   18%
400
THash_Whirlpool1    :      104.9 cycles/byte      14.30 Mb/sec      122.8 cycles/byte      12.22 Mb/sec   17%
401
THash_Whirlpool     :      104.7 cycles/byte      14.33 Mb/sec      119.9 cycles/byte      12.51 Mb/sec   15%
402
THash_Sapphire      :       52.9 cycles/byte      28.35 Mb/sec       53.8 cycles/byte      27.86 Mb/sec    2%
403
THash_Haval224      :       32.0 cycles/byte      46.82 Mb/sec       32.3 cycles/byte      46.46 Mb/sec    1%
404
THash_SHA256        :       47.8 cycles/byte      31.35 Mb/sec       47.8 cycles/byte      31.39 Mb/sec    0%
405
THash_Panama        :        8.9 cycles/byte     169.01 Mb/sec        7.3 cycles/byte     206.55 Mb/sec  -18%
406
}
407
 
408
resourcestring
409
  sHashingOverflowError = 'Hash function have to many bits processed';
410
  sHashNotInitialized   = 'Hash must be initialized';
411
  sHashNoDefault        = 'No default hash are registered';
412
 
413
var
414
  FDefaultHashClass: TDECHashClass = nil;
415
 
416
 
417
function ValidHash(HashClass: TDECHashClass): TDECHashClass;
418
begin
419
  if HashClass <> nil then Result := HashClass
420
    else Result := FDefaultHashClass;
421
  if Result = nil then raise EDECException.Create(sHashNoDefault);
422
end;
423
 
424
function HashByName(const Name: String): TDECHashClass;
425
begin
426
  Result := TDECHashClass(DECClassByName(Name, TDECHash));
427
end;
428
 
429
function HashByIdentity(Identity: LongWord): TDECHashClass;
430
begin
431
  Result := TDECHashClass(DECClassByIdentity(Identity, TDECHash));
432
end;
433
 
434
procedure SetDefaultHashClass(HashClass: TDECHashClass);
435
begin
436
  if HashClass <> nil then HashClass.Register;
437
  FDefaultHashClass := HashClass;
438
end;
439
 
440
// .TDECHash
441
destructor TDECHash.Destroy;
442
begin
443
  ProtectBuffer(Digest^, DigestSize);
444
  ProtectBuffer(FBuffer^, FBufferSize);
445
  ReallocMem(FBuffer, 0);
446
  inherited Destroy;
447
end;
448
 
449
procedure TDECHash.Init;
450
begin
451
  FBufferIndex := 0;
452
  FBufferSize := BlockSize;
453
  ReallocMem(FBuffer, FBufferSize);
454
  FillChar(FBuffer^, FBufferSize, 0);
455
  FillChar(FCount, SizeOf(FCount), 0);
456
  DoInit;
457
end;
458
 
459
procedure TDECHash.Done;
460
begin
461
  DoDone;
462
  ProtectBuffer(FBuffer^, FBufferSize);
463
  FBufferSize := 0;
464
  ReallocMem(FBuffer, 0);
465
end;
466
 
467
procedure HashingOverflowError;
468
begin
469
  raise EDECException.Create(sHashingOverflowError);
470
end;
471
 
472
procedure HashNotInitialized;
473
begin
474
  raise EDECException.Create(sHashNotInitialized);
475
end;
476
 
477
procedure Increment8(var Value; Add: LongWord);
478
// Value := Value + 8 * Add
479
// Value: array[0..7] of LongWord
480
asm
481
    MOV  ECX,EDX
482
    LEA  EDX,[EDX * 8]
483
    SHR  ECX,25
484
    ADD  [EAX].DWord[ 0],EDX
485
    ADC  [EAX].DWord[ 4],ECX
486
    ADC  [EAX].DWord[ 8],0
487
    ADC  [EAX].DWord[12],0
488
    ADC  [EAX].DWord[16],0
489
    ADC  [EAX].DWord[20],0
490
    ADC  [EAX].DWord[24],0
491
    ADC  [EAX].DWord[28],0
492
    JC   HashingOverflowError
493
end;
494
 
495
procedure TDECHash.Calc(const Data; DataSize: Integer);
496
var
497
  Remain: Integer;
498
  Source: PByte;
499
begin
500
  if DataSize <= 0 then Exit;
501
  if FBuffer = nil then HashNotInitialized;
502
  Increment8(FCount, DataSize);
503
  Source := @TByteArray(Data)[0];
504
  if FBufferIndex > 0 then
505
  begin
506
    Remain := FBufferSize - FBufferIndex;
507
    if DataSize < Remain then
508
    begin
509
      Move(Source^, FBuffer[FBufferIndex], DataSize);
510
      Inc(FBufferIndex, DataSize);
511
      Exit;
512
    end;
513
    Move(Source^, FBuffer[FBufferIndex], Remain);
514
    DoTransform(Pointer(FBuffer));
515
    Dec(DataSize, Remain);
516
    Inc(Source, Remain);
517
  end;
518
  while DataSize >= FBufferSize do
519
  begin
520
    DoTransform(Pointer(Source));
521
    Inc(Source, FBufferSize);
522
    Dec(DataSize, FBufferSize);
523
  end;
524
  Move(Source^, FBuffer^, DataSize);
525
  FBufferIndex := DataSize;
526
end;
527
 
528
function TDECHash.DigestStr(Format: TDECFormatClass): Binary;
529
begin
530
  Result := ValidFormat(Format).Encode(Digest[0], DigestSize);
531
end;
532
 
533
class function TDECHash.CalcStream(const Stream: TStream; Size: Int64; Format: TDECFormatClass; const Progress: IDECProgress): Binary;
534
var
535
  Buffer: Binary;
536
  Bytes: Integer;
537
  Min,Max,Pos: Int64;
538
begin
539
  Min := 0;
540
  Max := 0;
541
  with Create do
542
  try
543
    Init;
544
    if StreamBufferSize <= 0 then StreamBufferSize := 8192;
545
    if Size < 0 then
546
    begin
547
      Stream.Position := 0;
548
      Size := Stream.Size;
549
      Pos := 0;
550
    end else Pos := Stream.Position;
551
    Bytes := StreamBufferSize mod FBufferSize;
552
    if Bytes = 0 then Bytes := StreamBufferSize
553
      else Bytes := StreamBufferSize + FBufferSize - Bytes;
554
    if Bytes > Size then SetLength(Buffer, Size)
555
      else SetLength(Buffer, Bytes);
556
    Min := Pos;
557
    Max := Pos + Size;
558
    while Size > 0 do
559
    begin
560
      if Assigned(Progress) then Progress.Process(Min, Max, Pos);
561
      Bytes := Length(Buffer);
562
      if Bytes > Size then Bytes := Size;
563
      Stream.ReadBuffer(Buffer[1], Bytes);
564
      Calc(Buffer[1], Bytes);
565
      Dec(Size, Bytes);
566
      Inc(Pos, Bytes);
567
    end;
568
    Done;
569
    Result := DigestStr(Format);
570
  finally
571
    Free;
572
    ProtectBinary(Buffer);
573
    if Assigned(Progress) then Progress.Process(Min, Max, Max);
574
  end;
575
end;
576
 
577
class function TDECHash.CalcBinary(const Data: Binary; Format: TDECFormatClass): Binary;
578
begin
579
  Result := CalcBuffer(Data[1], Length(Data), Format);
580
end;
581
 
582
class function TDECHash.CalcFile(const FileName: String; Format: TDECFormatClass; const Progress: IDECProgress): Binary;
583
var
584
  S: TFileStream;
585
begin
586
  S := TFileStream.Create(FileName, fmOpenRead or fmShareDenyNone);
587
  try
588
    Result := CalcStream(S, S.Size, Format, Progress);
589
  finally
590
    S.Free;
591
  end;
592
end;
593
 
594
class function TDECHash.CalcBuffer(const Buffer; BufferSize: Integer; Format: TDECFormatClass): Binary;
595
begin
596
  with Create do
597
  try
598
    Init;
599
    Calc(Buffer, BufferSize);
600
    Done;
601
    Result := DigestStr(Format);
602
  finally
603
    Free;
604
  end;
605
end;
606
 
607
class function TDECHash.MGF1(const Data; DataSize, MaskSize: Integer; Format: TDECFormatClass = nil): Binary;
608
// indexed Mask generation function, IEEE P1363 Working Group
609
// equal to KDF2 except without Seed
610
begin
611
  Result := KDF2(Data, DataSize, EmptyStr[1], 0, MaskSize, Format);
612
end;
613
 
614
class function TDECHash.MGF1(const Data: Binary; MaskSize: Integer; Format: TDECFormatClass = nil): Binary;
615
begin
616
  Result := KDF2(Data, Length(Data), EmptyStr[1], 0, MaskSize, Format);
617
end;
618
 
619
class function TDECHash.KDF2(const Data; DataSize: Integer; const Seed; SeedSize, MaskSize: Integer; Format: TDECFormatClass = nil): Binary;
620
// Key Generation Function 2, IEEE P1363 Working Group
621
var
622
  I,Rounds,DigestBytes: Integer;
623
  Dest: PByteArray;
624
  Count: LongWord;
625
begin
626
  DigestBytes := DigestSize;
627
  Assert(MaskSize >= 0);
628
  Assert(DataSize >= 0);
629
  Assert(SeedSize >= 0);
630
  Assert(DigestBytes >= 0);
631
  with Create do
632
  try
633
    Rounds := (MaskSize + DigestBytes -1) div DigestBytes;
634
    SetLength(Result, Rounds * DigestBytes);
635
    Dest := @Result[1];
636
    for I := 0 to Rounds -1 do
637
    begin
638
      Count := SwapLong(I);
639
      Init;
640
      Calc(Data, DataSize);
641
      Calc(Count, SizeOf(Count));
642
      Calc(Seed, SeedSize);
643
      Done;
644
      Move(Digest[0], Dest[I * DigestBytes], DigestBytes);
645
    end;
646
  finally
647
    Free;
648
  end;
649
  SetLength(Result, MaskSize);
650
  Result := ValidFormat(Format).Encode(Result[1], MaskSize);
651
end;
652
 
653
class function TDECHash.KDF2(const Data, Seed: Binary; MaskSize: Integer; Format: TDECFormatClass = nil): Binary;
654
begin
655
  Result := KDF2(Data[1], Length(Data), Seed[1], Length(Seed), MaskSize, Format);
656
end;
657
 
658
class function TDECHash.KDFx(const Data; DataSize: Integer; const Seed; SeedSize, MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
659
// DEC's own KDF, even stronger
660
var
661
  I,J: Integer;
662
  Count: LongWord;
663
  R: Byte;
664
begin
665
  Assert(MaskSize >= 0);
666
  Assert(DataSize >= 0);
667
  Assert(SeedSize >= 0);
668
  Assert(DigestSize >= 0);
669
 
670
  SetLength(Result, MaskSize);
671
  Index := SwapLong(Index);
672
  with Create do
673
  try
674
    for I := 0 to MaskSize -1 do
675
    begin
676
      Init;
677
 
678
      Count := SwapLong(I);
679
      Calc(Count, SizeOf(Count));
680
      Calc(Result[1], I);
681
 
682
      Calc(Index, SizeOf(Index));
683
 
684
      Count := SwapLong(SeedSize);
685
      Calc(Count, SizeOf(Count));
686
      Calc(Seed, SeedSize);
687
 
688
      Count := SwapLong(DataSize);
689
      Calc(Count, SizeOf(Count));
690
      Calc(Data, DataSize);
691
 
692
      Done;
693
 
694
      R := 0;
695
      for J := 0 to DigestSize -1 do
696
        R := R xor Digest[J];
697
 
698
      Result[I +1] := Char(R);
699
    end;
700
  finally
701
    Free;
702
  end;
703
  Result := ValidFormat(Format).Encode(Result[1], MaskSize);
704
end;
705
 
706
class function TDECHash.KDFx(const Data, Seed: Binary; MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
707
begin
708
  Result := KDFx(Data[1], Length(Data), Seed[1], Length(Seed), MaskSize, Format, Index);
709
end;
710
 
711
class function TDECHash.MGFx(const Data; DataSize, MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
712
begin
713
  Result := KDFx(Data, DataSize, EmptyStr[1], 0, MaskSize, Format, Index);
714
end;
715
 
716
class function TDECHash.MGFx(const Data: Binary; MaskSize: Integer; Format: TDECFormatClass = nil; Index: LongWord = 1): Binary;
717
begin
718
  Result := KDFx(Data[1], Length(Data), EmptyStr[1], 0, MaskSize, Format, Index);
719
end;
720
 
721
// .THash_MD2
722
class function THash_MD2.DigestSize: Integer;
723
begin
724
  Result := 16;
725
end;
726
 
727
class function THash_MD2.BlockSize: Integer;
728
begin
729
  Result := 16;
730
end;
731
 
732
function THash_MD2.Digest: PByteArray;
733
begin
734
  Result := @FDigest;
735
end;
736
 
737
{$IFNDEF THash_MD2_asm}
738
procedure THash_MD2.DoTransform(Buffer: PLongArray);
739
var
740
  I,J,T: LongWord;
741
begin
742
  for I := 0 to 3 do
743
  begin
744
    PLongArray(@FDigest[16])[I] := Buffer[I];
745
    PLongArray(@FDigest[32])[I] := PLongArray(@FDigest[0])[I] xor PLongArray(@FDigest[16])[I];
746
  end;
747
  T := FDigest[63];
748
  for I := 0 to 15 do
749
  begin
750
    T := FDigest[I + 48] xor MD2_PISubst[FDigest[I + 16] xor Byte(T)];
751
    FDigest[I + 48] := Byte(T);
752
  end;
753
  T := 0;
754
  for I := 0 to 17 do
755
  begin
756
    for J := 0 to 47 do
757
    begin
758
      T := FDigest[J] xor MD2_PISubst[T];
759
      FDigest[J] := Byte(T);
760
    end;
761
    T := (T + I) and $FF;
762
  end;
763
end;
764
{$ENDIF}
765
 
766
procedure THash_MD2.DoInit;
767
begin
768
  FillChar(FDigest, SizeOf(FDigest), 0);
769
end;
770
 
771
procedure THash_MD2.DoDone;
772
var
773
  Remain: Integer;
774
begin
775
  Remain := FBufferSize - FBufferIndex;
776
  FillChar(FBuffer[FBufferIndex], Remain, Remain);
777
  DoTransform(Pointer(FBuffer));
778
  Move(FDigest[48], FBuffer^, FBufferSize);
779
  DoTransform(Pointer(FBuffer));
780
end;
781
 
782
// .THashBaseMD4
783
class function THashBaseMD4.DigestSize: Integer;
784
begin
785
  Result := 16;
786
end;
787
 
788
class function THashBaseMD4.BlockSize: Integer;
789
begin
790
  Result := 64;
791
end;
792
 
793
function THashBaseMD4.Digest: PByteArray;
794
begin
795
  Result := @FDigest;
796
end;
797
 
798
procedure THashBaseMD4.DoInit;
799
begin
800
  FDigest[0] := $67452301;
801
  FDigest[1] := $EFCDAB89;
802
  FDigest[2] := $98BADCFE;
803
  FDigest[3] := $10325476;
804
  FDigest[4] := $C3D2E1F0;
805
  FDigest[5] := $76543210;
806
  FDigest[6] := $FEDCBA98;
807
  FDigest[7] := $89ABCDEF;
808
  FDigest[8] := $01234567;
809
  FDigest[9] := $3C2D1E0F;
810
end;
811
 
812
procedure THashBaseMD4.DoDone;
813
begin
814
  if FCount[2] or FCount[3] <> 0 then HashingOverflowError;
815
  if FPaddingByte = 0 then FPaddingByte := $80;
816
  FBuffer[FBufferIndex] := FPaddingByte;
817
  Inc(FBufferIndex);
818
  if FBufferIndex > FBufferSize - 8 then
819
  begin
820
    FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
821
    DoTransform(Pointer(FBuffer));
822
    FBufferIndex := 0;
823
  end;
824
  FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
825
  Move(FCount, FBuffer[FBufferSize - 8], 8);
826
  DoTransform(Pointer(FBuffer));
827
end;
828
 
829
// .THash_MD4
830
{$IFNDEF THash_MD4_asm}
831
procedure THash_MD4.DoTransform(Buffer: PLongArray);
832
const
833
  S1 = $5A827999;
834
  S2 = $6ED9EBA1;
835
var
836
  A,B,C,D: LongWord;
837
begin
838
  A := FDigest[0];
839
  B := FDigest[1];
840
  C := FDigest[2];
841
  D := FDigest[3];
842
 
843
  Inc(A, B and C or not B and D + Buffer[ 0]); A := A shl  3 or A shr 29;
844
  Inc(D, A and B or not A and C + Buffer[ 1]); D := D shl  7 or D shr 25;
845
  Inc(C, D and A or not D and B + Buffer[ 2]); C := C shl 11 or C shr 21;
846
  Inc(B, C and D or not C and A + Buffer[ 3]); B := B shl 19 or B shr 13;
847
  Inc(A, B and C or not B and D + Buffer[ 4]); A := A shl  3 or A shr 29;
848
  Inc(D, A and B or not A and C + Buffer[ 5]); D := D shl  7 or D shr 25;
849
  Inc(C, D and A or not D and B + Buffer[ 6]); C := C shl 11 or C shr 21;
850
  Inc(B, C and D or not C and A + Buffer[ 7]); B := B shl 19 or B shr 13;
851
  Inc(A, B and C or not B and D + Buffer[ 8]); A := A shl  3 or A shr 29;
852
  Inc(D, A and B or not A and C + Buffer[ 9]); D := D shl  7 or D shr 25;
853
  Inc(C, D and A or not D and B + Buffer[10]); C := C shl 11 or C shr 21;
854
  Inc(B, C and D or not C and A + Buffer[11]); B := B shl 19 or B shr 13;
855
  Inc(A, B and C or not B and D + Buffer[12]); A := A shl  3 or A shr 29;
856
  Inc(D, A and B or not A and C + Buffer[13]); D := D shl  7 or D shr 25;
857
  Inc(C, D and A or not D and B + Buffer[14]); C := C shl 11 or C shr 21;
858
  Inc(B, C and D or not C and A + Buffer[15]); B := B shl 19 or B shr 13;
859
 
860
  Inc(A, B and C or B and D or C and D + Buffer[ 0] + S1); A := A shl  3 or A shr 29;
861
  Inc(D, A and B or A and C or B and C + Buffer[ 4] + S1); D := D shl  5 or D shr 27;
862
  Inc(C, D and A or D and B or A and B + Buffer[ 8] + S1); C := C shl  9 or C shr 23;
863
  Inc(B, C and D or C and A or D and A + Buffer[12] + S1); B := B shl 13 or B shr 19;
864
  Inc(A, B and C or B and D or C and D + Buffer[ 1] + S1); A := A shl  3 or A shr 29;
865
  Inc(D, A and B or A and C or B and C + Buffer[ 5] + S1); D := D shl  5 or D shr 27;
866
  Inc(C, D and A or D and B or A and B + Buffer[ 9] + S1); C := C shl  9 or C shr 23;
867
  Inc(B, C and D or C and A or D and A + Buffer[13] + S1); B := B shl 13 or B shr 19;
868
  Inc(A, B and C or B and D or C and D + Buffer[ 2] + S1); A := A shl  3 or A shr 29;
869
  Inc(D, A and B or A and C or B and C + Buffer[ 6] + S1); D := D shl  5 or D shr 27;
870
  Inc(C, D and A or D and B or A and B + Buffer[10] + S1); C := C shl  9 or C shr 23;
871
  Inc(B, C and D or C and A or D and A + Buffer[14] + S1); B := B shl 13 or B shr 19;
872
  Inc(A, B and C or B and D or C and D + Buffer[ 3] + S1); A := A shl  3 or A shr 29;
873
  Inc(D, A and B or A and C or B and C + Buffer[ 7] + S1); D := D shl  5 or D shr 27;
874
  Inc(C, D and A or D and B or A and B + Buffer[11] + S1); C := C shl  9 or C shr 23;
875
  Inc(B, C and D or C and A or D and A + Buffer[15] + S1); B := B shl 13 or B shr 19;
876
 
877
  Inc(A, B xor C xor D + Buffer[ 0] + S2); A := A shl  3 or A shr 29;
878
  Inc(D, A xor B xor C + Buffer[ 8] + S2); D := D shl  9 or D shr 23;
879
  Inc(C, D xor A xor B + Buffer[ 4] + S2); C := C shl 11 or C shr 21;
880
  Inc(B, C xor D xor A + Buffer[12] + S2); B := B shl 15 or B shr 17;
881
  Inc(A, B xor C xor D + Buffer[ 2] + S2); A := A shl  3 or A shr 29;
882
  Inc(D, A xor B xor C + Buffer[10] + S2); D := D shl  9 or D shr 23;
883
  Inc(C, D xor A xor B + Buffer[ 6] + S2); C := C shl 11 or C shr 21;
884
  Inc(B, C xor D xor A + Buffer[14] + S2); B := B shl 15 or B shr 17;
885
  Inc(A, B xor C xor D + Buffer[ 1] + S2); A := A shl  3 or A shr 29;
886
  Inc(D, A xor B xor C + Buffer[ 9] + S2); D := D shl  9 or D shr 23;
887
  Inc(C, D xor A xor B + Buffer[ 5] + S2); C := C shl 11 or C shr 21;
888
  Inc(B, C xor D xor A + Buffer[13] + S2); B := B shl 15 or B shr 17;
889
  Inc(A, B xor C xor D + Buffer[ 3] + S2); A := A shl  3 or A shr 29;
890
  Inc(D, A xor B xor C + Buffer[11] + S2); D := D shl  9 or D shr 23;
891
  Inc(C, D xor A xor B + Buffer[ 7] + S2); C := C shl 11 or C shr 21;
892
  Inc(B, C xor D xor A + Buffer[15] + S2); B := B shl 15 or B shr 17;
893
 
894
  Inc(FDigest[0], A);
895
  Inc(FDigest[1], B);
896
  Inc(FDigest[2], C);
897
  Inc(FDigest[3], D);
898
end;
899
{$ENDIF}
900
 
901
// .THash_MD5
902
{$IFNDEF THash_MD5_asm}
903
procedure THash_MD5.DoTransform(Buffer: PLongArray);
904
var
905
  A,B,C,D: LongWord;
906
begin
907
  A := FDigest[0];
908
  B := FDigest[1];
909
  C := FDigest[2];
910
  D := FDigest[3];
911
 
912
  Inc(A, Buffer[ 0] + $D76AA478 + (D xor (B and (C xor D)))); A := A shl  7 or A shr 25 + B;
913
  Inc(D, Buffer[ 1] + $E8C7B756 + (C xor (A and (B xor C)))); D := D shl 12 or D shr 20 + A;
914
  Inc(C, Buffer[ 2] + $242070DB + (B xor (D and (A xor B)))); C := C shl 17 or C shr 15 + D;
915
  Inc(B, Buffer[ 3] + $C1BDCEEE + (A xor (C and (D xor A)))); B := B shl 22 or B shr 10 + C;
916
  Inc(A, Buffer[ 4] + $F57C0FAF + (D xor (B and (C xor D)))); A := A shl  7 or A shr 25 + B;
917
  Inc(D, Buffer[ 5] + $4787C62A + (C xor (A and (B xor C)))); D := D shl 12 or D shr 20 + A;
918
  Inc(C, Buffer[ 6] + $A8304613 + (B xor (D and (A xor B)))); C := C shl 17 or C shr 15 + D;
919
  Inc(B, Buffer[ 7] + $FD469501 + (A xor (C and (D xor A)))); B := B shl 22 or B shr 10 + C;
920
  Inc(A, Buffer[ 8] + $698098D8 + (D xor (B and (C xor D)))); A := A shl  7 or A shr 25 + B;
921
  Inc(D, Buffer[ 9] + $8B44F7AF + (C xor (A and (B xor C)))); D := D shl 12 or D shr 20 + A;
922
  Inc(C, Buffer[10] + $FFFF5BB1 + (B xor (D and (A xor B)))); C := C shl 17 or C shr 15 + D;
923
  Inc(B, Buffer[11] + $895CD7BE + (A xor (C and (D xor A)))); B := B shl 22 or B shr 10 + C;
924
  Inc(A, Buffer[12] + $6B901122 + (D xor (B and (C xor D)))); A := A shl  7 or A shr 25 + B;
925
  Inc(D, Buffer[13] + $FD987193 + (C xor (A and (B xor C)))); D := D shl 12 or D shr 20 + A;
926
  Inc(C, Buffer[14] + $A679438E + (B xor (D and (A xor B)))); C := C shl 17 or C shr 15 + D;
927
  Inc(B, Buffer[15] + $49B40821 + (A xor (C and (D xor A)))); B := B shl 22 or B shr 10 + C;
928
 
929
  Inc(A, Buffer[ 1] + $F61E2562 + (C xor (D and (B xor C)))); A := A shl  5 or A shr 27 + B;
930
  Inc(D, Buffer[ 6] + $C040B340 + (B xor (C and (A xor B)))); D := D shl  9 or D shr 23 + A;
931
  Inc(C, Buffer[11] + $265E5A51 + (A xor (B and (D xor A)))); C := C shl 14 or C shr 18 + D;
932
  Inc(B, Buffer[ 0] + $E9B6C7AA + (D xor (A and (C xor D)))); B := B shl 20 or B shr 12 + C;
933
  Inc(A, Buffer[ 5] + $D62F105D + (C xor (D and (B xor C)))); A := A shl  5 or A shr 27 + B;
934
  Inc(D, Buffer[10] + $02441453 + (B xor (C and (A xor B)))); D := D shl  9 or D shr 23 + A;
935
  Inc(C, Buffer[15] + $D8A1E681 + (A xor (B and (D xor A)))); C := C shl 14 or C shr 18 + D;
936
  Inc(B, Buffer[ 4] + $E7D3FBC8 + (D xor (A and (C xor D)))); B := B shl 20 or B shr 12 + C;
937
  Inc(A, Buffer[ 9] + $21E1CDE6 + (C xor (D and (B xor C)))); A := A shl  5 or A shr 27 + B;
938
  Inc(D, Buffer[14] + $C33707D6 + (B xor (C and (A xor B)))); D := D shl  9 or D shr 23 + A;
939
  Inc(C, Buffer[ 3] + $F4D50D87 + (A xor (B and (D xor A)))); C := C shl 14 or C shr 18 + D;
940
  Inc(B, Buffer[ 8] + $455A14ED + (D xor (A and (C xor D)))); B := B shl 20 or B shr 12 + C;
941
  Inc(A, Buffer[13] + $A9E3E905 + (C xor (D and (B xor C)))); A := A shl  5 or A shr 27 + B;
942
  Inc(D, Buffer[ 2] + $FCEFA3F8 + (B xor (C and (A xor B)))); D := D shl  9 or D shr 23 + A;
943
  Inc(C, Buffer[ 7] + $676F02D9 + (A xor (B and (D xor A)))); C := C shl 14 or C shr 18 + D;
944
  Inc(B, Buffer[12] + $8D2A4C8A + (D xor (A and (C xor D)))); B := B shl 20 or B shr 12 + C;
945
 
946
  Inc(A, Buffer[ 5] + $FFFA3942 + (B xor C xor D)); A := A shl  4 or A shr 28 + B;
947
  Inc(D, Buffer[ 8] + $8771F681 + (A xor B xor C)); D := D shl 11 or D shr 21 + A;
948
  Inc(C, Buffer[11] + $6D9D6122 + (D xor A xor B)); C := C shl 16 or C shr 16 + D;
949
  Inc(B, Buffer[14] + $FDE5380C + (C xor D xor A)); B := B shl 23 or B shr  9 + C;
950
  Inc(A, Buffer[ 1] + $A4BEEA44 + (B xor C xor D)); A := A shl  4 or A shr 28 + B;
951
  Inc(D, Buffer[ 4] + $4BDECFA9 + (A xor B xor C)); D := D shl 11 or D shr 21 + A;
952
  Inc(C, Buffer[ 7] + $F6BB4B60 + (D xor A xor B)); C := C shl 16 or C shr 16 + D;
953
  Inc(B, Buffer[10] + $BEBFBC70 + (C xor D xor A)); B := B shl 23 or B shr  9 + C;
954
  Inc(A, Buffer[13] + $289B7EC6 + (B xor C xor D)); A := A shl  4 or A shr 28 + B;
955
  Inc(D, Buffer[ 0] + $EAA127FA + (A xor B xor C)); D := D shl 11 or D shr 21 + A;
956
  Inc(C, Buffer[ 3] + $D4EF3085 + (D xor A xor B)); C := C shl 16 or C shr 16 + D;
957
  Inc(B, Buffer[ 6] + $04881D05 + (C xor D xor A)); B := B shl 23 or B shr  9 + C;
958
  Inc(A, Buffer[ 9] + $D9D4D039 + (B xor C xor D)); A := A shl  4 or A shr 28 + B;
959
  Inc(D, Buffer[12] + $E6DB99E5 + (A xor B xor C)); D := D shl 11 or D shr 21 + A;
960
  Inc(C, Buffer[15] + $1FA27CF8 + (D xor A xor B)); C := C shl 16 or C shr 16 + D;
961
  Inc(B, Buffer[ 2] + $C4AC5665 + (C xor D xor A)); B := B shl 23 or B shr  9 + C;
962
 
963
  Inc(A, Buffer[ 0] + $F4292244 + (C xor (B or not D))); A := A shl  6 or A shr 26 + B;
964
  Inc(D, Buffer[ 7] + $432AFF97 + (B xor (A or not C))); D := D shl 10 or D shr 22 + A;
965
  Inc(C, Buffer[14] + $AB9423A7 + (A xor (D or not B))); C := C shl 15 or C shr 17 + D;
966
  Inc(B, Buffer[ 5] + $FC93A039 + (D xor (C or not A))); B := B shl 21 or B shr 11 + C;
967
  Inc(A, Buffer[12] + $655B59C3 + (C xor (B or not D))); A := A shl  6 or A shr 26 + B;
968
  Inc(D, Buffer[ 3] + $8F0CCC92 + (B xor (A or not C))); D := D shl 10 or D shr 22 + A;
969
  Inc(C, Buffer[10] + $FFEFF47D + (A xor (D or not B))); C := C shl 15 or C shr 17 + D;
970
  Inc(B, Buffer[ 1] + $85845DD1 + (D xor (C or not A))); B := B shl 21 or B shr 11 + C;
971
  Inc(A, Buffer[ 8] + $6FA87E4F + (C xor (B or not D))); A := A shl  6 or A shr 26 + B;
972
  Inc(D, Buffer[15] + $FE2CE6E0 + (B xor (A or not C))); D := D shl 10 or D shr 22 + A;
973
  Inc(C, Buffer[ 6] + $A3014314 + (A xor (D or not B))); C := C shl 15 or C shr 17 + D;
974
  Inc(B, Buffer[13] + $4E0811A1 + (D xor (C or not A))); B := B shl 21 or B shr 11 + C;
975
  Inc(A, Buffer[ 4] + $F7537E82 + (C xor (B or not D))); A := A shl  6 or A shr 26 + B;
976
  Inc(D, Buffer[11] + $BD3AF235 + (B xor (A or not C))); D := D shl 10 or D shr 22 + A;
977
  Inc(C, Buffer[ 2] + $2AD7D2BB + (A xor (D or not B))); C := C shl 15 or C shr 17 + D;
978
  Inc(B, Buffer[ 9] + $EB86D391 + (D xor (C or not A))); B := B shl 21 or B shr 11 + C;
979
 
980
  Inc(FDigest[0], A);
981
  Inc(FDigest[1], B);
982
  Inc(FDigest[2], C);
983
  Inc(FDigest[3], D);
984
end;
985
{$ENDIF}
986
 
987
// .THash_RipeMD128
988
const
989
  RipeS1 = $5A827999;
990
  RipeS2 = $6ED9EBA1;
991
  RipeS3 = $8F1BBCDC;
992
  RipeS4 = $A953FD4E;
993
  RipeS5 = $50A28BE6;
994
  RipeS6 = $5C4DD124;
995
  RipeS7 = $6D703EF3;
996
  RipeS8 = $7A6D76E9;
997
 
998
{$IFNDEF THash_RipeMD128_asm}
999
procedure THash_RipeMD128.DoTransform(Buffer: PLongArray);
1000
var
1001
  A1,B1,C1,D1: LongWord;
1002
  A2,B2,C2,D2: LongWord;
1003
  T: LongWord;
1004
begin
1005
  A1 := FDigest[0];
1006
  B1 := FDigest[1];
1007
  C1 := FDigest[2];
1008
  D1 := FDigest[3];
1009
  A2 := FDigest[0];
1010
  B2 := FDigest[1];
1011
  C2 := FDigest[2];
1012
  D2 := FDigest[3];
1013
 
1014
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 0]); A1 := A1 shl 11 or A1 shr 21;
1015
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 1]); D1 := D1 shl 14 or D1 shr 18;
1016
  Inc(C1, D1 xor A1 xor B1 + Buffer[ 2]); C1 := C1 shl 15 or C1 shr 17;
1017
  Inc(B1, C1 xor D1 xor A1 + Buffer[ 3]); B1 := B1 shl 12 or B1 shr 20;
1018
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 4]); A1 := A1 shl  5 or A1 shr 27;
1019
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 5]); D1 := D1 shl  8 or D1 shr 24;
1020
  Inc(C1, D1 xor A1 xor B1 + Buffer[ 6]); C1 := C1 shl  7 or C1 shr 25;
1021
  Inc(B1, C1 xor D1 xor A1 + Buffer[ 7]); B1 := B1 shl  9 or B1 shr 23;
1022
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 11 or A1 shr 21;
1023
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 9]); D1 := D1 shl 13 or D1 shr 19;
1024
  Inc(C1, D1 xor A1 xor B1 + Buffer[10]); C1 := C1 shl 14 or C1 shr 18;
1025
  Inc(B1, C1 xor D1 xor A1 + Buffer[11]); B1 := B1 shl 15 or B1 shr 17;
1026
  Inc(A1, B1 xor C1 xor D1 + Buffer[12]); A1 := A1 shl  6 or A1 shr 26;
1027
  Inc(D1, A1 xor B1 xor C1 + Buffer[13]); D1 := D1 shl  7 or D1 shr 25;
1028
  Inc(C1, D1 xor A1 xor B1 + Buffer[14]); C1 := C1 shl  9 or C1 shr 23;
1029
  Inc(B1, C1 xor D1 xor A1 + Buffer[15]); B1 := B1 shl  8 or B1 shr 24;
1030
 
1031
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 7] + RipeS1); A1 := A1 shl  7 or A1 shr 25;
1032
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 4] + RipeS1); D1 := D1 shl  6 or D1 shr 26;
1033
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[13] + RipeS1); C1 := C1 shl  8 or C1 shr 24;
1034
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 1] + RipeS1); B1 := B1 shl 13 or B1 shr 19;
1035
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS1); A1 := A1 shl 11 or A1 shr 21;
1036
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 6] + RipeS1); D1 := D1 shl  9 or D1 shr 23;
1037
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[15] + RipeS1); C1 := C1 shl  7 or C1 shr 25;
1038
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 3] + RipeS1); B1 := B1 shl 15 or B1 shr 17;
1039
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[12] + RipeS1); A1 := A1 shl  7 or A1 shr 25;
1040
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 0] + RipeS1); D1 := D1 shl 12 or D1 shr 20;
1041
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 9] + RipeS1); C1 := C1 shl 15 or C1 shr 17;
1042
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 5] + RipeS1); B1 := B1 shl  9 or B1 shr 23;
1043
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 2] + RipeS1); A1 := A1 shl 11 or A1 shr 21;
1044
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[14] + RipeS1); D1 := D1 shl  7 or D1 shr 25;
1045
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[11] + RipeS1); C1 := C1 shl 13 or C1 shr 19;
1046
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 8] + RipeS1); B1 := B1 shl 12 or B1 shr 20;
1047
 
1048
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 3] + RipeS2); A1 := A1 shl 11 or A1 shr 21;
1049
  Inc(D1, A1 or not B1 xor C1 + Buffer[10] + RipeS2); D1 := D1 shl 13 or D1 shr 19;
1050
  Inc(C1, D1 or not A1 xor B1 + Buffer[14] + RipeS2); C1 := C1 shl  6 or C1 shr 26;
1051
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 4] + RipeS2); B1 := B1 shl  7 or B1 shr 25;
1052
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 9] + RipeS2); A1 := A1 shl 14 or A1 shr 18;
1053
  Inc(D1, A1 or not B1 xor C1 + Buffer[15] + RipeS2); D1 := D1 shl  9 or D1 shr 23;
1054
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 8] + RipeS2); C1 := C1 shl 13 or C1 shr 19;
1055
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 1] + RipeS2); B1 := B1 shl 15 or B1 shr 17;
1056
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 2] + RipeS2); A1 := A1 shl 14 or A1 shr 18;
1057
  Inc(D1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS2); D1 := D1 shl  8 or D1 shr 24;
1058
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 0] + RipeS2); C1 := C1 shl 13 or C1 shr 19;
1059
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 6] + RipeS2); B1 := B1 shl  6 or B1 shr 26;
1060
  Inc(A1, B1 or not C1 xor D1 + Buffer[13] + RipeS2); A1 := A1 shl  5 or A1 shr 27;
1061
  Inc(D1, A1 or not B1 xor C1 + Buffer[11] + RipeS2); D1 := D1 shl 12 or D1 shr 20;
1062
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 5] + RipeS2); C1 := C1 shl  7 or C1 shr 25;
1063
  Inc(B1, C1 or not D1 xor A1 + Buffer[12] + RipeS2); B1 := B1 shl  5 or B1 shr 27;
1064
 
1065
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS3); A1 := A1 shl 11 or A1 shr 21;
1066
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 9] + RipeS3); D1 := D1 shl 12 or D1 shr 20;
1067
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[11] + RipeS3); C1 := C1 shl 14 or C1 shr 18;
1068
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[10] + RipeS3); B1 := B1 shl 15 or B1 shr 17;
1069
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 0] + RipeS3); A1 := A1 shl 14 or A1 shr 18;
1070
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 8] + RipeS3); D1 := D1 shl 15 or D1 shr 17;
1071
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[12] + RipeS3); C1 := C1 shl  9 or C1 shr 23;
1072
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 4] + RipeS3); B1 := B1 shl  8 or B1 shr 24;
1073
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[13] + RipeS3); A1 := A1 shl  9 or A1 shr 23;
1074
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 3] + RipeS3); D1 := D1 shl 14 or D1 shr 18;
1075
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 7] + RipeS3); C1 := C1 shl  5 or C1 shr 27;
1076
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[15] + RipeS3); B1 := B1 shl  6 or B1 shr 26;
1077
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[14] + RipeS3); A1 := A1 shl  8 or A1 shr 24;
1078
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 5] + RipeS3); D1 := D1 shl  6 or D1 shr 26;
1079
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 6] + RipeS3); C1 := C1 shl  5 or C1 shr 27;
1080
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 2] + RipeS3); B1 := B1 shl 12 or B1 shr 20;
1081
 
1082
  T := A1; A1 := A2; A2 := T;
1083
  T := B1; B1 := B2; B2 := T;
1084
  T := C1; C1 := C2; C2 := T;
1085
  T := D1; D1 := D2; D2 := T;
1086
 
1087
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 5] + RipeS5); A1 := A1 shl  8 or A1 shr 24;
1088
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[14] + RipeS5); D1 := D1 shl  9 or D1 shr 23;
1089
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 7] + RipeS5); C1 := C1 shl  9 or C1 shr 23;
1090
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 0] + RipeS5); B1 := B1 shl 11 or B1 shr 21;
1091
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 9] + RipeS5); A1 := A1 shl 13 or A1 shr 19;
1092
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 2] + RipeS5); D1 := D1 shl 15 or D1 shr 17;
1093
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[11] + RipeS5); C1 := C1 shl 15 or C1 shr 17;
1094
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 4] + RipeS5); B1 := B1 shl  5 or B1 shr 27;
1095
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[13] + RipeS5); A1 := A1 shl  7 or A1 shr 25;
1096
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 6] + RipeS5); D1 := D1 shl  7 or D1 shr 25;
1097
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[15] + RipeS5); C1 := C1 shl  8 or C1 shr 24;
1098
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 8] + RipeS5); B1 := B1 shl 11 or B1 shr 21;
1099
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS5); A1 := A1 shl 14 or A1 shr 18;
1100
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[10] + RipeS5); D1 := D1 shl 14 or D1 shr 18;
1101
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 3] + RipeS5); C1 := C1 shl 12 or C1 shr 20;
1102
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[12] + RipeS5); B1 := B1 shl  6 or B1 shr 26;
1103
 
1104
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 6] + RipeS6); A1 := A1 shl  9 or A1 shr 23;
1105
  Inc(D1, A1 or not B1 xor C1 + Buffer[11] + RipeS6); D1 := D1 shl 13 or D1 shr 19;
1106
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 3] + RipeS6); C1 := C1 shl 15 or C1 shr 17;
1107
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 7] + RipeS6); B1 := B1 shl  7 or B1 shr 25;
1108
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 0] + RipeS6); A1 := A1 shl 12 or A1 shr 20;
1109
  Inc(D1, A1 or not B1 xor C1 + Buffer[13] + RipeS6); D1 := D1 shl  8 or D1 shr 24;
1110
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 5] + RipeS6); C1 := C1 shl  9 or C1 shr 23;
1111
  Inc(B1, C1 or not D1 xor A1 + Buffer[10] + RipeS6); B1 := B1 shl 11 or B1 shr 21;
1112
  Inc(A1, B1 or not C1 xor D1 + Buffer[14] + RipeS6); A1 := A1 shl  7 or A1 shr 25;
1113
  Inc(D1, A1 or not B1 xor C1 + Buffer[15] + RipeS6); D1 := D1 shl  7 or D1 shr 25;
1114
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 8] + RipeS6); C1 := C1 shl 12 or C1 shr 20;
1115
  Inc(B1, C1 or not D1 xor A1 + Buffer[12] + RipeS6); B1 := B1 shl  7 or B1 shr 25;
1116
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 4] + RipeS6); A1 := A1 shl  6 or A1 shr 26;
1117
  Inc(D1, A1 or not B1 xor C1 + Buffer[ 9] + RipeS6); D1 := D1 shl 15 or D1 shr 17;
1118
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 1] + RipeS6); C1 := C1 shl 13 or C1 shr 19;
1119
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 2] + RipeS6); B1 := B1 shl 11 or B1 shr 21;
1120
 
1121
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[15] + RipeS7); A1 := A1 shl  9 or A1 shr 23;
1122
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 5] + RipeS7); D1 := D1 shl  7 or D1 shr 25;
1123
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 1] + RipeS7); C1 := C1 shl 15 or C1 shr 17;
1124
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 3] + RipeS7); B1 := B1 shl 11 or B1 shr 21;
1125
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 7] + RipeS7); A1 := A1 shl  8 or A1 shr 24;
1126
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[14] + RipeS7); D1 := D1 shl  6 or D1 shr 26;
1127
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 6] + RipeS7); C1 := C1 shl  6 or C1 shr 26;
1128
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 9] + RipeS7); B1 := B1 shl 14 or B1 shr 18;
1129
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[11] + RipeS7); A1 := A1 shl 12 or A1 shr 20;
1130
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 8] + RipeS7); D1 := D1 shl 13 or D1 shr 19;
1131
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[12] + RipeS7); C1 := C1 shl  5 or C1 shr 27;
1132
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 2] + RipeS7); B1 := B1 shl 14 or B1 shr 18;
1133
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS7); A1 := A1 shl 13 or A1 shr 19;
1134
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 0] + RipeS7); D1 := D1 shl 13 or D1 shr 19;
1135
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 4] + RipeS7); C1 := C1 shl  7 or C1 shr 25;
1136
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[13] + RipeS7); B1 := B1 shl  5 or B1 shr 27;
1137
 
1138
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 15 or A1 shr 17;
1139
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 6]); D1 := D1 shl  5 or D1 shr 27;
1140
  Inc(C1, D1 xor A1 xor B1 + Buffer[ 4]); C1 := C1 shl  8 or C1 shr 24;
1141
  Inc(B1, C1 xor D1 xor A1 + Buffer[ 1]); B1 := B1 shl 11 or B1 shr 21;
1142
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 3]); A1 := A1 shl 14 or A1 shr 18;
1143
  Inc(D1, A1 xor B1 xor C1 + Buffer[11]); D1 := D1 shl 14 or D1 shr 18;
1144
  Inc(C1, D1 xor A1 xor B1 + Buffer[15]); C1 := C1 shl  6 or C1 shr 26;
1145
  Inc(B1, C1 xor D1 xor A1 + Buffer[ 0]); B1 := B1 shl 14 or B1 shr 18;
1146
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 5]); A1 := A1 shl  6 or A1 shr 26;
1147
  Inc(D1, A1 xor B1 xor C1 + Buffer[12]); D1 := D1 shl  9 or D1 shr 23;
1148
  Inc(C1, D1 xor A1 xor B1 + Buffer[ 2]); C1 := C1 shl 12 or C1 shr 20;
1149
  Inc(B1, C1 xor D1 xor A1 + Buffer[13]); B1 := B1 shl  9 or B1 shr 23;
1150
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 9]); A1 := A1 shl 12 or A1 shr 20;
1151
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 7]); D1 := D1 shl  5 or D1 shr 27;
1152
  Inc(C1, D1 xor A1 xor B1 + Buffer[10]); C1 := C1 shl 15 or C1 shr 17;
1153
  Inc(B1, C1 xor D1 xor A1 + Buffer[14]); B1 := B1 shl  8 or B1 shr 24;
1154
 
1155
  Inc(D1, C2 + FDigest[1]);
1156
  FDigest[1] := FDigest[2] + D2 + A1;
1157
  FDigest[2] := FDigest[3] + A2 + B1;
1158
  FDigest[3] := FDIgest[0] + B2 + C1;
1159
  FDigest[0] := D1;
1160
end;
1161
{$ENDIF}
1162
 
1163
// .THash_RipeMD160
1164
{$IFNDEF THash_RipeMD160_asm}
1165
procedure THash_RipeMD160.DoTransform(Buffer: PLongArray);
1166
var
1167
  A1,B1,C1,D1,E1: LongWord;
1168
  A2,B2,C2,D2,E2: LongWord;
1169
  T: LongWord;
1170
begin
1171
  A1 := FDigest[0];
1172
  B1 := FDigest[1];
1173
  C1 := FDigest[2];
1174
  D1 := FDigest[3];
1175
  E1 := FDigest[4];
1176
 
1177
  A2 := FDigest[0];
1178
  B2 := FDigest[1];
1179
  C2 := FDigest[2];
1180
  D2 := FDigest[3];
1181
  E2 := FDigest[4];
1182
 
1183
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 0]); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22;
1184
  Inc(E1, A1 xor B1 xor C1 + Buffer[ 1]); E1 := E1 shl 14 or E1 shr 18 + D1; B1 := B1 shl 10 or B1 shr 22;
1185
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 2]); D1 := D1 shl 15 or D1 shr 17 + C1; A1 := A1 shl 10 or A1 shr 22;
1186
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 3]); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1187
  Inc(B1, C1 xor D1 xor E1 + Buffer[ 4]); B1 := B1 shl  5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22;
1188
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 5]); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1189
  Inc(E1, A1 xor B1 xor C1 + Buffer[ 6]); E1 := E1 shl  7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22;
1190
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 7]); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1191
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 8]); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1192
  Inc(B1, C1 xor D1 xor E1 + Buffer[ 9]); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1193
  Inc(A1, B1 xor C1 xor D1 + Buffer[10]); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1194
  Inc(E1, A1 xor B1 xor C1 + Buffer[11]); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1195
  Inc(D1, E1 xor A1 xor B1 + Buffer[12]); D1 := D1 shl  6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22;
1196
  Inc(C1, D1 xor E1 xor A1 + Buffer[13]); C1 := C1 shl  7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22;
1197
  Inc(B1, C1 xor D1 xor E1 + Buffer[14]); B1 := B1 shl  9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22;
1198
  Inc(A1, B1 xor C1 xor D1 + Buffer[15]); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1199
 
1200
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 7] + RipeS1); E1 := E1 shl  7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22;
1201
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 4] + RipeS1); D1 := D1 shl  6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22;
1202
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[13] + RipeS1); C1 := C1 shl  8 or C1 shr 24 + B1; E1 := E1 shl 10 or E1 shr 22;
1203
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[ 1] + RipeS1); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1204
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS1); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22;
1205
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 6] + RipeS1); E1 := E1 shl  9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22;
1206
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[15] + RipeS1); D1 := D1 shl  7 or D1 shr 25 + C1; A1 := A1 shl 10 or A1 shr 22;
1207
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 3] + RipeS1); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22;
1208
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[12] + RipeS1); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1209
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 0] + RipeS1); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1210
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 9] + RipeS1); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1211
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 5] + RipeS1); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1212
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 2] + RipeS1); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1213
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[14] + RipeS1); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1214
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[11] + RipeS1); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22;
1215
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 8] + RipeS1); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22;
1216
 
1217
  Inc(D1, E1 or not A1 xor B1 + Buffer[ 3] + RipeS2); D1 := D1 shl 11 or D1 shr 21 + C1; A1 := A1 shl 10 or A1 shr 22;
1218
  Inc(C1, D1 or not E1 xor A1 + Buffer[10] + RipeS2); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22;
1219
  Inc(B1, C1 or not D1 xor E1 + Buffer[14] + RipeS2); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1220
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 4] + RipeS2); A1 := A1 shl  7 or A1 shr 25 + E1; C1 := C1 shl 10 or C1 shr 22;
1221
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 9] + RipeS2); E1 := E1 shl 14 or E1 shr 18 + D1; B1 := B1 shl 10 or B1 shr 22;
1222
  Inc(D1, E1 or not A1 xor B1 + Buffer[15] + RipeS2); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1223
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 8] + RipeS2); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22;
1224
  Inc(B1, C1 or not D1 xor E1 + Buffer[ 1] + RipeS2); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22;
1225
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 2] + RipeS2); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1226
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS2); E1 := E1 shl  8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22;
1227
  Inc(D1, E1 or not A1 xor B1 + Buffer[ 0] + RipeS2); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22;
1228
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 6] + RipeS2); C1 := C1 shl  6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22;
1229
  Inc(B1, C1 or not D1 xor E1 + Buffer[13] + RipeS2); B1 := B1 shl  5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22;
1230
  Inc(A1, B1 or not C1 xor D1 + Buffer[11] + RipeS2); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1231
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 5] + RipeS2); E1 := E1 shl  7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22;
1232
  Inc(D1, E1 or not A1 xor B1 + Buffer[12] + RipeS2); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1233
 
1234
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 1] + RipeS3); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1235
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 9] + RipeS3); B1 := B1 shl 12 or B1 shr 20 + A1; D1 := D1 shl 10 or D1 shr 22;
1236
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[11] + RipeS3); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1237
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[10] + RipeS3); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1238
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 0] + RipeS3); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22;
1239
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 8] + RipeS3); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22;
1240
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[12] + RipeS3); B1 := B1 shl  9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22;
1241
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 4] + RipeS3); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1242
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[13] + RipeS3); E1 := E1 shl  9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22;
1243
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 3] + RipeS3); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22;
1244
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 7] + RipeS3); C1 := C1 shl  5 or C1 shr 27 + B1; E1 := E1 shl 10 or E1 shr 22;
1245
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[15] + RipeS3); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1246
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[14] + RipeS3); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1247
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 5] + RipeS3); E1 := E1 shl  6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22;
1248
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 6] + RipeS3); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1249
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 2] + RipeS3); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1250
 
1251
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 4] + RipeS4); B1 := B1 shl  9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22;
1252
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 0] + RipeS4); A1 := A1 shl 15 or A1 shr 17 + E1; C1 := C1 shl 10 or C1 shr 22;
1253
  Inc(E1, B1 or not C1 xor A1 + Buffer[ 5] + RipeS4); E1 := E1 shl  5 or E1 shr 27 + D1; B1 := B1 shl 10 or B1 shr 22;
1254
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 9] + RipeS4); D1 := D1 shl 11 or D1 shr 21 + C1; A1 := A1 shl 10 or A1 shr 22;
1255
  Inc(C1, E1 or not A1 xor D1 + Buffer[ 7] + RipeS4); C1 := C1 shl  6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22;
1256
  Inc(B1, D1 or not E1 xor C1 + Buffer[12] + RipeS4); B1 := B1 shl  8 or B1 shr 24 + A1; D1 := D1 shl 10 or D1 shr 22;
1257
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 2] + RipeS4); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22;
1258
  Inc(E1, B1 or not C1 xor A1 + Buffer[10] + RipeS4); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22;
1259
  Inc(D1, A1 or not B1 xor E1 + Buffer[14] + RipeS4); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1260
  Inc(C1, E1 or not A1 xor D1 + Buffer[ 1] + RipeS4); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1261
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 3] + RipeS4); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1262
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 8] + RipeS4); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1263
  Inc(E1, B1 or not C1 xor A1 + Buffer[11] + RipeS4); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22;
1264
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 6] + RipeS4); D1 := D1 shl  8 or D1 shr 24 + C1; A1 := A1 shl 10 or A1 shr 22;
1265
  Inc(C1, E1 or not A1 xor D1 + Buffer[15] + RipeS4); C1 := C1 shl  5 or C1 shr 27 + B1; E1 := E1 shl 10 or E1 shr 22;
1266
  Inc(B1, D1 or not E1 xor C1 + Buffer[13] + RipeS4); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1267
 
1268
  T := A1; A1 := A2; A2 := T;
1269
  T := B1; B1 := B2; B2 := T;
1270
  T := C1; C1 := C2; C2 := T;
1271
  T := D1; D1 := D2; D2 := T;
1272
  T := E1; E1 := E2; E2 := T;
1273
 
1274
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 5] + RipeS5); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1275
  Inc(E1, B1 or not C1 xor A1 + Buffer[14] + RipeS5); E1 := E1 shl  9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22;
1276
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 7] + RipeS5); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1277
  Inc(C1, E1 or not A1 xor D1 + Buffer[ 0] + RipeS5); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1278
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 9] + RipeS5); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1279
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 2] + RipeS5); A1 := A1 shl 15 or A1 shr 17 + E1; C1 := C1 shl 10 or C1 shr 22;
1280
  Inc(E1, B1 or not C1 xor A1 + Buffer[11] + RipeS5); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1281
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 4] + RipeS5); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1282
  Inc(C1, E1 or not A1 xor D1 + Buffer[13] + RipeS5); C1 := C1 shl  7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22;
1283
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 6] + RipeS5); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1284
  Inc(A1, C1 or not D1 xor B1 + Buffer[15] + RipeS5); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1285
  Inc(E1, B1 or not C1 xor A1 + Buffer[ 8] + RipeS5); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22;
1286
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 1] + RipeS5); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22;
1287
  Inc(C1, E1 or not A1 xor D1 + Buffer[10] + RipeS5); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22;
1288
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 3] + RipeS5); B1 := B1 shl 12 or B1 shr 20 + A1; D1 := D1 shl 10 or D1 shr 22;
1289
  Inc(A1, C1 or not D1 xor B1 + Buffer[12] + RipeS5); A1 := A1 shl  6 or A1 shr 26 + E1; C1 := C1 shl 10 or C1 shr 22;
1290
 
1291
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 6] + RipeS6); E1 := E1 shl  9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22;
1292
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[11] + RipeS6); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22;
1293
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 3] + RipeS6); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22;
1294
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 7] + RipeS6); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1295
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 0] + RipeS6); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1296
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[13] + RipeS6); E1 := E1 shl  8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22;
1297
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 5] + RipeS6); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1298
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[10] + RipeS6); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1299
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[14] + RipeS6); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1300
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[15] + RipeS6); A1 := A1 shl  7 or A1 shr 25 + E1; C1 := C1 shl 10 or C1 shr 22;
1301
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 8] + RipeS6); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22;
1302
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[12] + RipeS6); D1 := D1 shl  7 or D1 shr 25 + C1; A1 := A1 shl 10 or A1 shr 22;
1303
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 4] + RipeS6); C1 := C1 shl  6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22;
1304
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 9] + RipeS6); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22;
1305
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS6); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22;
1306
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 2] + RipeS6); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22;
1307
 
1308
  Inc(D1, E1 or not A1 xor B1 + Buffer[15] + RipeS7); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1309
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 5] + RipeS7); C1 := C1 shl  7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22;
1310
  Inc(B1, C1 or not D1 xor E1 + Buffer[ 1] + RipeS7); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22;
1311
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 3] + RipeS7); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22;
1312
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS7); E1 := E1 shl  8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22;
1313
  Inc(D1, E1 or not A1 xor B1 + Buffer[14] + RipeS7); D1 := D1 shl  6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22;
1314
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 6] + RipeS7); C1 := C1 shl  6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22;
1315
  Inc(B1, C1 or not D1 xor E1 + Buffer[ 9] + RipeS7); B1 := B1 shl 14 or B1 shr 18 + A1; D1 := D1 shl 10 or D1 shr 22;
1316
  Inc(A1, B1 or not C1 xor D1 + Buffer[11] + RipeS7); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1317
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 8] + RipeS7); E1 := E1 shl 13 or E1 shr 19 + D1; B1 := B1 shl 10 or B1 shr 22;
1318
  Inc(D1, E1 or not A1 xor B1 + Buffer[12] + RipeS7); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1319
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 2] + RipeS7); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22;
1320
  Inc(B1, C1 or not D1 xor E1 + Buffer[10] + RipeS7); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1321
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 0] + RipeS7); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22;
1322
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 4] + RipeS7); E1 := E1 shl  7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22;
1323
  Inc(D1, E1 or not A1 xor B1 + Buffer[13] + RipeS7); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1324
 
1325
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 8] + RipeS8); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22;
1326
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[ 6] + RipeS8); B1 := B1 shl  5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22;
1327
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 4] + RipeS8); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1328
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 1] + RipeS8); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22;
1329
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 3] + RipeS8); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22;
1330
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[11] + RipeS8); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22;
1331
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[15] + RipeS8); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1332
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 0] + RipeS8); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1333
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 5] + RipeS8); E1 := E1 shl  6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22;
1334
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[12] + RipeS8); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1335
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 2] + RipeS8); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1336
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[13] + RipeS8); B1 := B1 shl  9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22;
1337
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 9] + RipeS8); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1338
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 7] + RipeS8); E1 := E1 shl  5 or E1 shr 27 + D1; B1 := B1 shl 10 or B1 shr 22;
1339
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[10] + RipeS8); D1 := D1 shl 15 or D1 shr 17 + C1; A1 := A1 shl 10 or A1 shr 22;
1340
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[14] + RipeS8); C1 := C1 shl  8 or C1 shr 24 + B1; E1 := E1 shl 10 or E1 shr 22;
1341
 
1342
  Inc(B1, C1 xor D1 xor E1 + Buffer[12]); B1 := B1 shl  8 or B1 shr 24 + A1; D1 := D1 shl 10 or D1 shr 22;
1343
  Inc(A1, B1 xor C1 xor D1 + Buffer[15]); A1 := A1 shl  5 or A1 shr 27 + E1; C1 := C1 shl 10 or C1 shr 22;
1344
  Inc(E1, A1 xor B1 xor C1 + Buffer[10]); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22;
1345
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 4]); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1346
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 1]); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1347
  Inc(B1, C1 xor D1 xor E1 + Buffer[ 5]); B1 := B1 shl  5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22;
1348
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1349
  Inc(E1, A1 xor B1 xor C1 + Buffer[ 7]); E1 := E1 shl  6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22;
1350
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 6]); D1 := D1 shl  8 or D1 shr 24 + C1; A1 := A1 shl 10 or A1 shr 22;
1351
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 2]); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22;
1352
  Inc(B1, C1 xor D1 xor E1 + Buffer[13]); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1353
  Inc(A1, B1 xor C1 xor D1 + Buffer[14]); A1 := A1 shl  5 or A1 shr 27 + E1; C1 := C1 shl 10 or C1 shr 22;
1354
  Inc(E1, A1 xor B1 xor C1 + Buffer[ 0]); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1355
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 3]); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22;
1356
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 9]); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1357
  Inc(B1, C1 xor D1 xor E1 + Buffer[11]); B1 := B1 shl 11 or B1 shr 21 + A1; D1 := D1 shl 10 or D1 shr 22;
1358
 
1359
  Inc(D1, C2 + FDigest[1]);
1360
  FDigest[1] := FDigest[2] + D2 + E1;
1361
  FDigest[2] := FDigest[3] + E2 + A1;
1362
  FDigest[3] := FDigest[4] + A2 + B1;
1363
  FDigest[4] := FDigest[0] + B2 + C1;
1364
  FDigest[0] := D1;
1365
end;
1366
{$ENDIF}
1367
 
1368
class function THash_RipeMD160.DigestSize: Integer;
1369
begin
1370
  Result := 20;
1371
end;
1372
 
1373
// .THash_RipeMD256
1374
{$IFNDEF THash_RipeMD256_asm}
1375
procedure THash_RipeMD256.DoTransform(Buffer: PLongArray);
1376
var
1377
  A1,B1,C1,D1: LongWord;
1378
  A2,B2,C2,D2: LongWord;
1379
  T: LongWord;
1380
begin
1381
  A1 := FDigest[0];
1382
  B1 := FDigest[1];
1383
  C1 := FDigest[2];
1384
  D1 := FDigest[3];
1385
 
1386
  A2 := FDigest[4];
1387
  B2 := FDigest[5];
1388
  C2 := FDigest[6];
1389
  D2 := FDigest[7];
1390
 
1391
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 0]); A1 := A1 shl 11 or A1 shr 21;
1392
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 1]); D1 := D1 shl 14 or D1 shr 18;
1393
  Inc(C1, D1 xor A1 xor B1 + Buffer[ 2]); C1 := C1 shl 15 or C1 shr 17;
1394
  Inc(B1, C1 xor D1 xor A1 + Buffer[ 3]); B1 := B1 shl 12 or B1 shr 20;
1395
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 4]); A1 := A1 shl  5 or A1 shr 27;
1396
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 5]); D1 := D1 shl  8 or D1 shr 24;
1397
  Inc(C1, D1 xor A1 xor B1 + Buffer[ 6]); C1 := C1 shl  7 or C1 shr 25;
1398
  Inc(B1, C1 xor D1 xor A1 + Buffer[ 7]); B1 := B1 shl  9 or B1 shr 23;
1399
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 11 or A1 shr 21;
1400
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 9]); D1 := D1 shl 13 or D1 shr 19;
1401
  Inc(C1, D1 xor A1 xor B1 + Buffer[10]); C1 := C1 shl 14 or C1 shr 18;
1402
  Inc(B1, C1 xor D1 xor A1 + Buffer[11]); B1 := B1 shl 15 or B1 shr 17;
1403
  Inc(A1, B1 xor C1 xor D1 + Buffer[12]); A1 := A1 shl  6 or A1 shr 26;
1404
  Inc(D1, A1 xor B1 xor C1 + Buffer[13]); D1 := D1 shl  7 or D1 shr 25;
1405
  Inc(C1, D1 xor A1 xor B1 + Buffer[14]); C1 := C1 shl  9 or C1 shr 23;
1406
  Inc(B1, C1 xor D1 xor A1 + Buffer[15]); B1 := B1 shl  8 or B1 shr 24;
1407
 
1408
  T := A1; A1 := A2; A2 := T;
1409
  T := B1; B1 := B2; B2 := T;
1410
  T := C1; C1 := C2; C2 := T;
1411
  T := D1; D1 := D2; D2 := T;
1412
 
1413
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 5] + RipeS5); A1 := A1 shl  8 or A1 shr 24;
1414
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[14] + RipeS5); D1 := D1 shl  9 or D1 shr 23;
1415
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 7] + RipeS5); C1 := C1 shl  9 or C1 shr 23;
1416
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 0] + RipeS5); B1 := B1 shl 11 or B1 shr 21;
1417
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 9] + RipeS5); A1 := A1 shl 13 or A1 shr 19;
1418
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 2] + RipeS5); D1 := D1 shl 15 or D1 shr 17;
1419
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[11] + RipeS5); C1 := C1 shl 15 or C1 shr 17;
1420
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 4] + RipeS5); B1 := B1 shl  5 or B1 shr 27;
1421
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[13] + RipeS5); A1 := A1 shl  7 or A1 shr 25;
1422
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 6] + RipeS5); D1 := D1 shl  7 or D1 shr 25;
1423
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[15] + RipeS5); C1 := C1 shl  8 or C1 shr 24;
1424
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 8] + RipeS5); B1 := B1 shl 11 or B1 shr 21;
1425
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS5); A1 := A1 shl 14 or A1 shr 18;
1426
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[10] + RipeS5); D1 := D1 shl 14 or D1 shr 18;
1427
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 3] + RipeS5); C1 := C1 shl 12 or C1 shr 20;
1428
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[12] + RipeS5); B1 := B1 shl  6 or B1 shr 26;
1429
 
1430
  T := B1; B1 := B2; B2 := T;
1431
  T := C1; C1 := C2; C2 := T;
1432
  T := D1; D1 := D2; D2 := T;
1433
 
1434
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 7] + RipeS1); A1 := A1 shl  7 or A1 shr 25;
1435
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 4] + RipeS1); D1 := D1 shl  6 or D1 shr 26;
1436
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[13] + RipeS1); C1 := C1 shl  8 or C1 shr 24;
1437
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 1] + RipeS1); B1 := B1 shl 13 or B1 shr 19;
1438
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS1); A1 := A1 shl 11 or A1 shr 21;
1439
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 6] + RipeS1); D1 := D1 shl  9 or D1 shr 23;
1440
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[15] + RipeS1); C1 := C1 shl  7 or C1 shr 25;
1441
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 3] + RipeS1); B1 := B1 shl 15 or B1 shr 17;
1442
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[12] + RipeS1); A1 := A1 shl  7 or A1 shr 25;
1443
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 0] + RipeS1); D1 := D1 shl 12 or D1 shr 20;
1444
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 9] + RipeS1); C1 := C1 shl 15 or C1 shr 17;
1445
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 5] + RipeS1); B1 := B1 shl  9 or B1 shr 23;
1446
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 2] + RipeS1); A1 := A1 shl 11 or A1 shr 21;
1447
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[14] + RipeS1); D1 := D1 shl  7 or D1 shr 25;
1448
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[11] + RipeS1); C1 := C1 shl 13 or C1 shr 19;
1449
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 8] + RipeS1); B1 := B1 shl 12 or B1 shr 20;
1450
 
1451
  T := A1; A1 := A2; A2 := T;
1452
  T := B1; B1 := B2; B2 := T;
1453
  T := C1; C1 := C2; C2 := T;
1454
  T := D1; D1 := D2; D2 := T;
1455
 
1456
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 6] + RipeS6); A1 := A1 shl  9 or A1 shr 23;
1457
  Inc(D1, A1 or not B1 xor C1 + Buffer[11] + RipeS6); D1 := D1 shl 13 or D1 shr 19;
1458
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 3] + RipeS6); C1 := C1 shl 15 or C1 shr 17;
1459
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 7] + RipeS6); B1 := B1 shl  7 or B1 shr 25;
1460
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 0] + RipeS6); A1 := A1 shl 12 or A1 shr 20;
1461
  Inc(D1, A1 or not B1 xor C1 + Buffer[13] + RipeS6); D1 := D1 shl  8 or D1 shr 24;
1462
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 5] + RipeS6); C1 := C1 shl  9 or C1 shr 23;
1463
  Inc(B1, C1 or not D1 xor A1 + Buffer[10] + RipeS6); B1 := B1 shl 11 or B1 shr 21;
1464
  Inc(A1, B1 or not C1 xor D1 + Buffer[14] + RipeS6); A1 := A1 shl  7 or A1 shr 25;
1465
  Inc(D1, A1 or not B1 xor C1 + Buffer[15] + RipeS6); D1 := D1 shl  7 or D1 shr 25;
1466
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 8] + RipeS6); C1 := C1 shl 12 or C1 shr 20;
1467
  Inc(B1, C1 or not D1 xor A1 + Buffer[12] + RipeS6); B1 := B1 shl  7 or B1 shr 25;
1468
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 4] + RipeS6); A1 := A1 shl  6 or A1 shr 26;
1469
  Inc(D1, A1 or not B1 xor C1 + Buffer[ 9] + RipeS6); D1 := D1 shl 15 or D1 shr 17;
1470
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 1] + RipeS6); C1 := C1 shl 13 or C1 shr 19;
1471
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 2] + RipeS6); B1 := B1 shl 11 or B1 shr 21;
1472
 
1473
  T := A1; A1 := A2; A2 := T;
1474
  T := C1; C1 := C2; C2 := T;
1475
  T := D1; D1 := D2; D2 := T;
1476
 
1477
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 3] + RipeS2); A1 := A1 shl 11 or A1 shr 21;
1478
  Inc(D1, A1 or not B1 xor C1 + Buffer[10] + RipeS2); D1 := D1 shl 13 or D1 shr 19;
1479
  Inc(C1, D1 or not A1 xor B1 + Buffer[14] + RipeS2); C1 := C1 shl  6 or C1 shr 26;
1480
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 4] + RipeS2); B1 := B1 shl  7 or B1 shr 25;
1481
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 9] + RipeS2); A1 := A1 shl 14 or A1 shr 18;
1482
  Inc(D1, A1 or not B1 xor C1 + Buffer[15] + RipeS2); D1 := D1 shl  9 or D1 shr 23;
1483
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 8] + RipeS2); C1 := C1 shl 13 or C1 shr 19;
1484
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 1] + RipeS2); B1 := B1 shl 15 or B1 shr 17;
1485
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 2] + RipeS2); A1 := A1 shl 14 or A1 shr 18;
1486
  Inc(D1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS2); D1 := D1 shl  8 or D1 shr 24;
1487
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 0] + RipeS2); C1 := C1 shl 13 or C1 shr 19;
1488
  Inc(B1, C1 or not D1 xor A1 + Buffer[ 6] + RipeS2); B1 := B1 shl  6 or B1 shr 26;
1489
  Inc(A1, B1 or not C1 xor D1 + Buffer[13] + RipeS2); A1 := A1 shl  5 or A1 shr 27;
1490
  Inc(D1, A1 or not B1 xor C1 + Buffer[11] + RipeS2); D1 := D1 shl 12 or D1 shr 20;
1491
  Inc(C1, D1 or not A1 xor B1 + Buffer[ 5] + RipeS2); C1 := C1 shl  7 or C1 shr 25;
1492
  Inc(B1, C1 or not D1 xor A1 + Buffer[12] + RipeS2); B1 := B1 shl  5 or B1 shr 27;
1493
 
1494
  T := A1; A1 := A2; A2 := T;
1495
  T := B1; B1 := B2; B2 := T;
1496
  T := C1; C1 := C2; C2 := T;
1497
  T := D1; D1 := D2; D2 := T;
1498
 
1499
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[15] + RipeS7); A1 := A1 shl  9 or A1 shr 23;
1500
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 5] + RipeS7); D1 := D1 shl  7 or D1 shr 25;
1501
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 1] + RipeS7); C1 := C1 shl 15 or C1 shr 17;
1502
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 3] + RipeS7); B1 := B1 shl 11 or B1 shr 21;
1503
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 7] + RipeS7); A1 := A1 shl  8 or A1 shr 24;
1504
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[14] + RipeS7); D1 := D1 shl  6 or D1 shr 26;
1505
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 6] + RipeS7); C1 := C1 shl  6 or C1 shr 26;
1506
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 9] + RipeS7); B1 := B1 shl 14 or B1 shr 18;
1507
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[11] + RipeS7); A1 := A1 shl 12 or A1 shr 20;
1508
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 8] + RipeS7); D1 := D1 shl 13 or D1 shr 19;
1509
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[12] + RipeS7); C1 := C1 shl  5 or C1 shr 27;
1510
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[ 2] + RipeS7); B1 := B1 shl 14 or B1 shr 18;
1511
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS7); A1 := A1 shl 13 or A1 shr 19;
1512
  Inc(D1, A1 and B1 or not A1 and C1 + Buffer[ 0] + RipeS7); D1 := D1 shl 13 or D1 shr 19;
1513
  Inc(C1, D1 and A1 or not D1 and B1 + Buffer[ 4] + RipeS7); C1 := C1 shl  7 or C1 shr 25;
1514
  Inc(B1, C1 and D1 or not C1 and A1 + Buffer[13] + RipeS7); B1 := B1 shl  5 or B1 shr 27;
1515
 
1516
  T := A1; A1 := A2; A2 := T;
1517
  T := B1; B1 := B2; B2 := T;
1518
  T := D1; D1 := D2; D2 := T;
1519
 
1520
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS3); A1 := A1 shl 11 or A1 shr 21;
1521
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 9] + RipeS3); D1 := D1 shl 12 or D1 shr 20;
1522
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[11] + RipeS3); C1 := C1 shl 14 or C1 shr 18;
1523
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[10] + RipeS3); B1 := B1 shl 15 or B1 shr 17;
1524
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 0] + RipeS3); A1 := A1 shl 14 or A1 shr 18;
1525
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 8] + RipeS3); D1 := D1 shl 15 or D1 shr 17;
1526
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[12] + RipeS3); C1 := C1 shl  9 or C1 shr 23;
1527
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 4] + RipeS3); B1 := B1 shl  8 or B1 shr 24;
1528
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[13] + RipeS3); A1 := A1 shl  9 or A1 shr 23;
1529
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 3] + RipeS3); D1 := D1 shl 14 or D1 shr 18;
1530
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 7] + RipeS3); C1 := C1 shl  5 or C1 shr 27;
1531
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[15] + RipeS3); B1 := B1 shl  6 or B1 shr 26;
1532
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[14] + RipeS3); A1 := A1 shl  8 or A1 shr 24;
1533
  Inc(D1, A1 and C1 or B1 and not C1 + Buffer[ 5] + RipeS3); D1 := D1 shl  6 or D1 shr 26;
1534
  Inc(C1, D1 and B1 or A1 and not B1 + Buffer[ 6] + RipeS3); C1 := C1 shl  5 or C1 shr 27;
1535
  Inc(B1, C1 and A1 or D1 and not A1 + Buffer[ 2] + RipeS3); B1 := B1 shl 12 or B1 shr 20;
1536
 
1537
  T := A1; A1 := A2; A2 := T;
1538
  T := B1; B1 := B2; B2 := T;
1539
  T := C1; C1 := C2; C2 := T;
1540
  T := D1; D1 := D2; D2 := T;
1541
 
1542
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 15 or A1 shr 17;
1543
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 6]); D1 := D1 shl  5 or D1 shr 27;
1544
  Inc(C1, D1 xor A1 xor B1 + Buffer[ 4]); C1 := C1 shl  8 or C1 shr 24;
1545
  Inc(B1, C1 xor D1 xor A1 + Buffer[ 1]); B1 := B1 shl 11 or B1 shr 21;
1546
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 3]); A1 := A1 shl 14 or A1 shr 18;
1547
  Inc(D1, A1 xor B1 xor C1 + Buffer[11]); D1 := D1 shl 14 or D1 shr 18;
1548
  Inc(C1, D1 xor A1 xor B1 + Buffer[15]); C1 := C1 shl  6 or C1 shr 26;
1549
  Inc(B1, C1 xor D1 xor A1 + Buffer[ 0]); B1 := B1 shl 14 or B1 shr 18;
1550
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 5]); A1 := A1 shl  6 or A1 shr 26;
1551
  Inc(D1, A1 xor B1 xor C1 + Buffer[12]); D1 := D1 shl  9 or D1 shr 23;
1552
  Inc(C1, D1 xor A1 xor B1 + Buffer[ 2]); C1 := C1 shl 12 or C1 shr 20;
1553
  Inc(B1, C1 xor D1 xor A1 + Buffer[13]); B1 := B1 shl  9 or B1 shr 23;
1554
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 9]); A1 := A1 shl 12 or A1 shr 20;
1555
  Inc(D1, A1 xor B1 xor C1 + Buffer[ 7]); D1 := D1 shl  5 or D1 shr 27;
1556
  Inc(C1, D1 xor A1 xor B1 + Buffer[10]); C1 := C1 shl 15 or C1 shr 17;
1557
  Inc(B1, C1 xor D1 xor A1 + Buffer[14]); B1 := B1 shl  8 or B1 shr 24;
1558
 
1559
  Inc(FDigest[0], A2);
1560
  Inc(FDigest[1], B2);
1561
  Inc(FDigest[2], C2);
1562
  Inc(FDigest[3], D1);
1563
 
1564
  Inc(FDigest[4], A1);
1565
  Inc(FDigest[5], B1);
1566
  Inc(FDigest[6], C1);
1567
  Inc(FDigest[7], D2);
1568
end;
1569
{$ENDIF}
1570
 
1571
procedure THash_RipeMD256.DoInit;
1572
begin
1573
  FDigest[0] := $67452301;
1574
  FDigest[1] := $EFCDAB89;
1575
  FDigest[2] := $98BADCFE;
1576
  FDigest[3] := $10325476;
1577
  FDigest[4] := $76543210;
1578
  FDigest[5] := $FEDCBA98;
1579
  FDigest[6] := $89ABCDEF;
1580
  FDigest[7] := $01234567;
1581
  FDigest[8] := $01234567;
1582
  FDigest[9] := $3C2D1E0F;
1583
end;
1584
 
1585
class function THash_RipeMD256.DigestSize: Integer;
1586
begin
1587
  Result := 32;
1588
end;
1589
 
1590
// .THash_RipeMD320
1591
{$IFNDEF THash_RipeMD320_asm}
1592
procedure THash_RipeMD320.DoTransform(Buffer: PLongArray);
1593
var
1594
  A1,B1,C1,D1,E1: LongWord;
1595
  A2,B2,C2,D2,E2: LongWord;
1596
  T: LongWord;
1597
begin
1598
  A1 := FDigest[0];
1599
  B1 := FDigest[1];
1600
  C1 := FDigest[2];
1601
  D1 := FDigest[3];
1602
  E1 := FDigest[4];
1603
  A2 := FDigest[5];
1604
  B2 := FDigest[6];
1605
  C2 := FDigest[7];
1606
  D2 := FDigest[8];
1607
  E2 := FDigest[9];
1608
 
1609
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 0]); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22;
1610
  Inc(E1, A1 xor B1 xor C1 + Buffer[ 1]); E1 := E1 shl 14 or E1 shr 18 + D1; B1 := B1 shl 10 or B1 shr 22;
1611
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 2]); D1 := D1 shl 15 or D1 shr 17 + C1; A1 := A1 shl 10 or A1 shr 22;
1612
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 3]); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1613
  Inc(B1, C1 xor D1 xor E1 + Buffer[ 4]); B1 := B1 shl  5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22;
1614
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 5]); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1615
  Inc(E1, A1 xor B1 xor C1 + Buffer[ 6]); E1 := E1 shl  7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22;
1616
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 7]); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1617
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 8]); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1618
  Inc(B1, C1 xor D1 xor E1 + Buffer[ 9]); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1619
  Inc(A1, B1 xor C1 xor D1 + Buffer[10]); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1620
  Inc(E1, A1 xor B1 xor C1 + Buffer[11]); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1621
  Inc(D1, E1 xor A1 xor B1 + Buffer[12]); D1 := D1 shl  6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22;
1622
  Inc(C1, D1 xor E1 xor A1 + Buffer[13]); C1 := C1 shl  7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22;
1623
  Inc(B1, C1 xor D1 xor E1 + Buffer[14]); B1 := B1 shl  9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22;
1624
  Inc(A1, B1 xor C1 xor D1 + Buffer[15]); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1625
 
1626
  T := A1; A1 := A2; A2 := T;
1627
  T := B1; B1 := B2; B2 := T;
1628
  T := C1; C1 := C2; C2 := T;
1629
  T := D1; D1 := D2; D2 := T;
1630
  T := E1; E1 := E2; E2 := T;
1631
 
1632
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 5] + RipeS5); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1633
  Inc(E1, B1 or not C1 xor A1 + Buffer[14] + RipeS5); E1 := E1 shl  9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22;
1634
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 7] + RipeS5); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1635
  Inc(C1, E1 or not A1 xor D1 + Buffer[ 0] + RipeS5); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1636
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 9] + RipeS5); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1637
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 2] + RipeS5); A1 := A1 shl 15 or A1 shr 17 + E1; C1 := C1 shl 10 or C1 shr 22;
1638
  Inc(E1, B1 or not C1 xor A1 + Buffer[11] + RipeS5); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1639
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 4] + RipeS5); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1640
  Inc(C1, E1 or not A1 xor D1 + Buffer[13] + RipeS5); C1 := C1 shl  7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22;
1641
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 6] + RipeS5); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1642
  Inc(A1, C1 or not D1 xor B1 + Buffer[15] + RipeS5); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1643
  Inc(E1, B1 or not C1 xor A1 + Buffer[ 8] + RipeS5); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22;
1644
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 1] + RipeS5); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22;
1645
  Inc(C1, E1 or not A1 xor D1 + Buffer[10] + RipeS5); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22;
1646
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 3] + RipeS5); B1 := B1 shl 12 or B1 shr 20 + A1; D1 := D1 shl 10 or D1 shr 22;
1647
  Inc(A1, C1 or not D1 xor B1 + Buffer[12] + RipeS5); A1 := A1 shl  6 or A1 shr 26 + E1; C1 := C1 shl 10 or C1 shr 22;
1648
 
1649
  T := B1; B1 := B2; B2 := T;
1650
  T := C1; C1 := C2; C2 := T;
1651
  T := D1; D1 := D2; D2 := T;
1652
  T := E1; E1 := E2; E2 := T;
1653
 
1654
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 7] + RipeS1); E1 := E1 shl  7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22;
1655
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 4] + RipeS1); D1 := D1 shl  6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22;
1656
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[13] + RipeS1); C1 := C1 shl  8 or C1 shr 24 + B1; E1 := E1 shl 10 or E1 shr 22;
1657
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[ 1] + RipeS1); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1658
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[10] + RipeS1); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22;
1659
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 6] + RipeS1); E1 := E1 shl  9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22;
1660
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[15] + RipeS1); D1 := D1 shl  7 or D1 shr 25 + C1; A1 := A1 shl 10 or A1 shr 22;
1661
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 3] + RipeS1); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22;
1662
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[12] + RipeS1); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1663
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 0] + RipeS1); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1664
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 9] + RipeS1); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1665
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 5] + RipeS1); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1666
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 2] + RipeS1); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1667
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[14] + RipeS1); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1668
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[11] + RipeS1); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22;
1669
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 8] + RipeS1); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22;
1670
 
1671
  T := A1; A1 := A2; A2 := T;
1672
  T := B1; B1 := B2; B2 := T;
1673
  T := C1; C1 := C2; C2 := T;
1674
  T := D1; D1 := D2; D2 := T;
1675
  T := E1; E1 := E2; E2 := T;
1676
 
1677
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 6] + RipeS6); E1 := E1 shl  9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22;
1678
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[11] + RipeS6); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22;
1679
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 3] + RipeS6); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22;
1680
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 7] + RipeS6); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1681
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 0] + RipeS6); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1682
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[13] + RipeS6); E1 := E1 shl  8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22;
1683
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 5] + RipeS6); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1684
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[10] + RipeS6); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1685
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[14] + RipeS6); B1 := B1 shl  7 or B1 shr 25 + A1; D1 := D1 shl 10 or D1 shr 22;
1686
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[15] + RipeS6); A1 := A1 shl  7 or A1 shr 25 + E1; C1 := C1 shl 10 or C1 shr 22;
1687
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 8] + RipeS6); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22;
1688
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[12] + RipeS6); D1 := D1 shl  7 or D1 shr 25 + C1; A1 := A1 shl 10 or A1 shr 22;
1689
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 4] + RipeS6); C1 := C1 shl  6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22;
1690
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 9] + RipeS6); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22;
1691
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 1] + RipeS6); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22;
1692
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 2] + RipeS6); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22;
1693
 
1694
  T := A1; A1 := A2; A2 := T;
1695
  T := C1; C1 := C2; C2 := T;
1696
  T := D1; D1 := D2; D2 := T;
1697
  T := E1; E1 := E2; E2 := T;
1698
 
1699
  Inc(D1, E1 or not A1 xor B1 + Buffer[ 3] + RipeS2); D1 := D1 shl 11 or D1 shr 21 + C1; A1 := A1 shl 10 or A1 shr 22;
1700
  Inc(C1, D1 or not E1 xor A1 + Buffer[10] + RipeS2); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22;
1701
  Inc(B1, C1 or not D1 xor E1 + Buffer[14] + RipeS2); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1702
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 4] + RipeS2); A1 := A1 shl  7 or A1 shr 25 + E1; C1 := C1 shl 10 or C1 shr 22;
1703
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 9] + RipeS2); E1 := E1 shl 14 or E1 shr 18 + D1; B1 := B1 shl 10 or B1 shr 22;
1704
  Inc(D1, E1 or not A1 xor B1 + Buffer[15] + RipeS2); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1705
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 8] + RipeS2); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22;
1706
  Inc(B1, C1 or not D1 xor E1 + Buffer[ 1] + RipeS2); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22;
1707
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 2] + RipeS2); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1708
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS2); E1 := E1 shl  8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22;
1709
  Inc(D1, E1 or not A1 xor B1 + Buffer[ 0] + RipeS2); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22;
1710
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 6] + RipeS2); C1 := C1 shl  6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22;
1711
  Inc(B1, C1 or not D1 xor E1 + Buffer[13] + RipeS2); B1 := B1 shl  5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22;
1712
  Inc(A1, B1 or not C1 xor D1 + Buffer[11] + RipeS2); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1713
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 5] + RipeS2); E1 := E1 shl  7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22;
1714
  Inc(D1, E1 or not A1 xor B1 + Buffer[12] + RipeS2); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1715
 
1716
  T := A1; A1 := A2; A2 := T;
1717
  T := B1; B1 := B2; B2 := T;
1718
  T := C1; C1 := C2; C2 := T;
1719
  T := D1; D1 := D2; D2 := T;
1720
  T := E1; E1 := E2; E2 := T;
1721
 
1722
  Inc(D1, E1 or not A1 xor B1 + Buffer[15] + RipeS7); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1723
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 5] + RipeS7); C1 := C1 shl  7 or C1 shr 25 + B1; E1 := E1 shl 10 or E1 shr 22;
1724
  Inc(B1, C1 or not D1 xor E1 + Buffer[ 1] + RipeS7); B1 := B1 shl 15 or B1 shr 17 + A1; D1 := D1 shl 10 or D1 shr 22;
1725
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 3] + RipeS7); A1 := A1 shl 11 or A1 shr 21 + E1; C1 := C1 shl 10 or C1 shr 22;
1726
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 7] + RipeS7); E1 := E1 shl  8 or E1 shr 24 + D1; B1 := B1 shl 10 or B1 shr 22;
1727
  Inc(D1, E1 or not A1 xor B1 + Buffer[14] + RipeS7); D1 := D1 shl  6 or D1 shr 26 + C1; A1 := A1 shl 10 or A1 shr 22;
1728
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 6] + RipeS7); C1 := C1 shl  6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22;
1729
  Inc(B1, C1 or not D1 xor E1 + Buffer[ 9] + RipeS7); B1 := B1 shl 14 or B1 shr 18 + A1; D1 := D1 shl 10 or D1 shr 22;
1730
  Inc(A1, B1 or not C1 xor D1 + Buffer[11] + RipeS7); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1731
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 8] + RipeS7); E1 := E1 shl 13 or E1 shr 19 + D1; B1 := B1 shl 10 or B1 shr 22;
1732
  Inc(D1, E1 or not A1 xor B1 + Buffer[12] + RipeS7); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1733
  Inc(C1, D1 or not E1 xor A1 + Buffer[ 2] + RipeS7); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22;
1734
  Inc(B1, C1 or not D1 xor E1 + Buffer[10] + RipeS7); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1735
  Inc(A1, B1 or not C1 xor D1 + Buffer[ 0] + RipeS7); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22;
1736
  Inc(E1, A1 or not B1 xor C1 + Buffer[ 4] + RipeS7); E1 := E1 shl  7 or E1 shr 25 + D1; B1 := B1 shl 10 or B1 shr 22;
1737
  Inc(D1, E1 or not A1 xor B1 + Buffer[13] + RipeS7); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1738
 
1739
  T := A1; A1 := A2; A2 := T;
1740
  T := B1; B1 := B2; B2 := T;
1741
  T := D1; D1 := D2; D2 := T;
1742
  T := E1; E1 := E2; E2 := T;
1743
 
1744
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 1] + RipeS3); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1745
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[ 9] + RipeS3); B1 := B1 shl 12 or B1 shr 20 + A1; D1 := D1 shl 10 or D1 shr 22;
1746
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[11] + RipeS3); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1747
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[10] + RipeS3); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1748
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 0] + RipeS3); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22;
1749
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 8] + RipeS3); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22;
1750
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[12] + RipeS3); B1 := B1 shl  9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22;
1751
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[ 4] + RipeS3); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1752
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[13] + RipeS3); E1 := E1 shl  9 or E1 shr 23 + D1; B1 := B1 shl 10 or B1 shr 22;
1753
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 3] + RipeS3); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22;
1754
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 7] + RipeS3); C1 := C1 shl  5 or C1 shr 27 + B1; E1 := E1 shl 10 or E1 shr 22;
1755
  Inc(B1, C1 and E1 or D1 and not E1 + Buffer[15] + RipeS3); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1756
  Inc(A1, B1 and D1 or C1 and not D1 + Buffer[14] + RipeS3); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1757
  Inc(E1, A1 and C1 or B1 and not C1 + Buffer[ 5] + RipeS3); E1 := E1 shl  6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22;
1758
  Inc(D1, E1 and B1 or A1 and not B1 + Buffer[ 6] + RipeS3); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1759
  Inc(C1, D1 and A1 or E1 and not A1 + Buffer[ 2] + RipeS3); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1760
 
1761
  T := A1; A1 := A2; A2 := T;
1762
  T := B1; B1 := B2; B2 := T;
1763
  T := C1; C1 := C2; C2 := T;
1764
  T := D1; D1 := D2; D2 := T;
1765
  T := E1; E1 := E2; E2 := T;
1766
 
1767
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 8] + RipeS8); C1 := C1 shl 15 or C1 shr 17 + B1; E1 := E1 shl 10 or E1 shr 22;
1768
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[ 6] + RipeS8); B1 := B1 shl  5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22;
1769
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 4] + RipeS8); A1 := A1 shl  8 or A1 shr 24 + E1; C1 := C1 shl 10 or C1 shr 22;
1770
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 1] + RipeS8); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22;
1771
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[ 3] + RipeS8); D1 := D1 shl 14 or D1 shr 18 + C1; A1 := A1 shl 10 or A1 shr 22;
1772
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[11] + RipeS8); C1 := C1 shl 14 or C1 shr 18 + B1; E1 := E1 shl 10 or E1 shr 22;
1773
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[15] + RipeS8); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1774
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 0] + RipeS8); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1775
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 5] + RipeS8); E1 := E1 shl  6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22;
1776
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[12] + RipeS8); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1777
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[ 2] + RipeS8); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1778
  Inc(B1, C1 and D1 or not C1 and E1 + Buffer[13] + RipeS8); B1 := B1 shl  9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22;
1779
  Inc(A1, B1 and C1 or not B1 and D1 + Buffer[ 9] + RipeS8); A1 := A1 shl 12 or A1 shr 20 + E1; C1 := C1 shl 10 or C1 shr 22;
1780
  Inc(E1, A1 and B1 or not A1 and C1 + Buffer[ 7] + RipeS8); E1 := E1 shl  5 or E1 shr 27 + D1; B1 := B1 shl 10 or B1 shr 22;
1781
  Inc(D1, E1 and A1 or not E1 and B1 + Buffer[10] + RipeS8); D1 := D1 shl 15 or D1 shr 17 + C1; A1 := A1 shl 10 or A1 shr 22;
1782
  Inc(C1, D1 and E1 or not D1 and A1 + Buffer[14] + RipeS8); C1 := C1 shl  8 or C1 shr 24 + B1; E1 := E1 shl 10 or E1 shr 22;
1783
 
1784
  T := A1; A1 := A2; A2 := T;
1785
  T := B1; B1 := B2; B2 := T;
1786
  T := C1; C1 := C2; C2 := T;
1787
  T := E1; E1 := E2; E2 := T;
1788
 
1789
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 4] + RipeS4); B1 := B1 shl  9 or B1 shr 23 + A1; D1 := D1 shl 10 or D1 shr 22;
1790
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 0] + RipeS4); A1 := A1 shl 15 or A1 shr 17 + E1; C1 := C1 shl 10 or C1 shr 22;
1791
  Inc(E1, B1 or not C1 xor A1 + Buffer[ 5] + RipeS4); E1 := E1 shl  5 or E1 shr 27 + D1; B1 := B1 shl 10 or B1 shr 22;
1792
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 9] + RipeS4); D1 := D1 shl 11 or D1 shr 21 + C1; A1 := A1 shl 10 or A1 shr 22;
1793
  Inc(C1, E1 or not A1 xor D1 + Buffer[ 7] + RipeS4); C1 := C1 shl  6 or C1 shr 26 + B1; E1 := E1 shl 10 or E1 shr 22;
1794
  Inc(B1, D1 or not E1 xor C1 + Buffer[12] + RipeS4); B1 := B1 shl  8 or B1 shr 24 + A1; D1 := D1 shl 10 or D1 shr 22;
1795
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 2] + RipeS4); A1 := A1 shl 13 or A1 shr 19 + E1; C1 := C1 shl 10 or C1 shr 22;
1796
  Inc(E1, B1 or not C1 xor A1 + Buffer[10] + RipeS4); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22;
1797
  Inc(D1, A1 or not B1 xor E1 + Buffer[14] + RipeS4); D1 := D1 shl  5 or D1 shr 27 + C1; A1 := A1 shl 10 or A1 shr 22;
1798
  Inc(C1, E1 or not A1 xor D1 + Buffer[ 1] + RipeS4); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1799
  Inc(B1, D1 or not E1 xor C1 + Buffer[ 3] + RipeS4); B1 := B1 shl 13 or B1 shr 19 + A1; D1 := D1 shl 10 or D1 shr 22;
1800
  Inc(A1, C1 or not D1 xor B1 + Buffer[ 8] + RipeS4); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1801
  Inc(E1, B1 or not C1 xor A1 + Buffer[11] + RipeS4); E1 := E1 shl 11 or E1 shr 21 + D1; B1 := B1 shl 10 or B1 shr 22;
1802
  Inc(D1, A1 or not B1 xor E1 + Buffer[ 6] + RipeS4); D1 := D1 shl  8 or D1 shr 24 + C1; A1 := A1 shl 10 or A1 shr 22;
1803
  Inc(C1, E1 or not A1 xor D1 + Buffer[15] + RipeS4); C1 := C1 shl  5 or C1 shr 27 + B1; E1 := E1 shl 10 or E1 shr 22;
1804
  Inc(B1, D1 or not E1 xor C1 + Buffer[13] + RipeS4); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1805
 
1806
  T := A1; A1 := A2; A2 := T;
1807
  T := B1; B1 := B2; B2 := T;
1808
  T := C1; C1 := C2; C2 := T;
1809
  T := D1; D1 := D2; D2 := T;
1810
  T := E1; E1 := E2; E2 := T;
1811
 
1812
  Inc(B1, C1 xor D1 xor E1 + Buffer[12]); B1 := B1 shl  8 or B1 shr 24 + A1; D1 := D1 shl 10 or D1 shr 22;
1813
  Inc(A1, B1 xor C1 xor D1 + Buffer[15]); A1 := A1 shl  5 or A1 shr 27 + E1; C1 := C1 shl 10 or C1 shr 22;
1814
  Inc(E1, A1 xor B1 xor C1 + Buffer[10]); E1 := E1 shl 12 or E1 shr 20 + D1; B1 := B1 shl 10 or B1 shr 22;
1815
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 4]); D1 := D1 shl  9 or D1 shr 23 + C1; A1 := A1 shl 10 or A1 shr 22;
1816
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 1]); C1 := C1 shl 12 or C1 shr 20 + B1; E1 := E1 shl 10 or E1 shr 22;
1817
  Inc(B1, C1 xor D1 xor E1 + Buffer[ 5]); B1 := B1 shl  5 or B1 shr 27 + A1; D1 := D1 shl 10 or D1 shr 22;
1818
  Inc(A1, B1 xor C1 xor D1 + Buffer[ 8]); A1 := A1 shl 14 or A1 shr 18 + E1; C1 := C1 shl 10 or C1 shr 22;
1819
  Inc(E1, A1 xor B1 xor C1 + Buffer[ 7]); E1 := E1 shl  6 or E1 shr 26 + D1; B1 := B1 shl 10 or B1 shr 22;
1820
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 6]); D1 := D1 shl  8 or D1 shr 24 + C1; A1 := A1 shl 10 or A1 shr 22;
1821
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 2]); C1 := C1 shl 13 or C1 shr 19 + B1; E1 := E1 shl 10 or E1 shr 22;
1822
  Inc(B1, C1 xor D1 xor E1 + Buffer[13]); B1 := B1 shl  6 or B1 shr 26 + A1; D1 := D1 shl 10 or D1 shr 22;
1823
  Inc(A1, B1 xor C1 xor D1 + Buffer[14]); A1 := A1 shl  5 or A1 shr 27 + E1; C1 := C1 shl 10 or C1 shr 22;
1824
  Inc(E1, A1 xor B1 xor C1 + Buffer[ 0]); E1 := E1 shl 15 or E1 shr 17 + D1; B1 := B1 shl 10 or B1 shr 22;
1825
  Inc(D1, E1 xor A1 xor B1 + Buffer[ 3]); D1 := D1 shl 13 or D1 shr 19 + C1; A1 := A1 shl 10 or A1 shr 22;
1826
  Inc(C1, D1 xor E1 xor A1 + Buffer[ 9]); C1 := C1 shl 11 or C1 shr 21 + B1; E1 := E1 shl 10 or E1 shr 22;
1827
  Inc(B1, C1 xor D1 xor E1 + Buffer[11]); B1 := B1 shl 11 or B1 shr 21 + A1; D1 := D1 shl 10 or D1 shr 22;
1828
 
1829
  Inc(FDigest[0], A2);
1830
  Inc(FDigest[1], B2);
1831
  Inc(FDigest[2], C2);
1832
  Inc(FDigest[3], D2);
1833
  Inc(FDigest[4], E1);
1834
  Inc(FDigest[5], A1);
1835
  Inc(FDigest[6], B1);
1836
  Inc(FDigest[7], C1);
1837
  Inc(FDigest[8], D1);
1838
  Inc(FDigest[9], E2);
1839
end;
1840
{$ENDIF}
1841
 
1842
class function THash_RipeMD320.DigestSize: Integer;
1843
begin
1844
  Result := 40;
1845
end;
1846
 
1847
// .THash_SHA
1848
class function THash_SHA.DigestSize: Integer;
1849
begin
1850
  Result := 20;
1851
end;
1852
{$IFNDEF THash_SHA_asm}
1853
procedure THash_SHA.DoTransform(Buffer: PLongArray);
1854
var
1855
  A,B,C,D,E,T: LongWord;
1856
  W: array[0..79] of LongWord;
1857
  I: Integer;
1858
begin
1859
  SwapLongBuffer(Buffer[0], W, 16);
1860
  if ClassType = THash_SHA then
1861
    for I := 16 to 79 do
1862
    begin
1863
      T := W[I - 3] xor W[I - 8] xor W[I - 14] xor W[I - 16];
1864
      W[I] := T;
1865
    end
1866
  else
1867
    for I := 16 to 79 do
1868
    begin
1869
      T := W[I - 3] xor W[I - 8] xor W[I - 14] xor W[I - 16];
1870
      W[I] := T shl 1 or T shr 31;
1871
    end;
1872
 
1873
  A := FDigest[0];
1874
  B := FDigest[1];
1875
  C := FDigest[2];
1876
  D := FDigest[3];
1877
  E := FDigest[4];
1878
 
1879
  Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[ 0] + $5A827999); B := B shr 2 or B shl 30;
1880
  Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[ 1] + $5A827999); A := A shr 2 or A shl 30;
1881
  Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[ 2] + $5A827999); E := E shr 2 or E shl 30;
1882
  Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[ 3] + $5A827999); D := D shr 2 or D shl 30;
1883
  Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[ 4] + $5A827999); C := C shr 2 or C shl 30;
1884
  Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[ 5] + $5A827999); B := B shr 2 or B shl 30;
1885
  Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[ 6] + $5A827999); A := A shr 2 or A shl 30;
1886
  Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[ 7] + $5A827999); E := E shr 2 or E shl 30;
1887
  Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[ 8] + $5A827999); D := D shr 2 or D shl 30;
1888
  Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[ 9] + $5A827999); C := C shr 2 or C shl 30;
1889
  Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[10] + $5A827999); B := B shr 2 or B shl 30;
1890
  Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[11] + $5A827999); A := A shr 2 or A shl 30;
1891
  Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[12] + $5A827999); E := E shr 2 or E shl 30;
1892
  Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[13] + $5A827999); D := D shr 2 or D shl 30;
1893
  Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[14] + $5A827999); C := C shr 2 or C shl 30;
1894
  Inc(E, (A shl 5 or A shr 27) + (D xor (B and (C xor D))) + W[15] + $5A827999); B := B shr 2 or B shl 30;
1895
  Inc(D, (E shl 5 or E shr 27) + (C xor (A and (B xor C))) + W[16] + $5A827999); A := A shr 2 or A shl 30;
1896
  Inc(C, (D shl 5 or D shr 27) + (B xor (E and (A xor B))) + W[17] + $5A827999); E := E shr 2 or E shl 30;
1897
  Inc(B, (C shl 5 or C shr 27) + (A xor (D and (E xor A))) + W[18] + $5A827999); D := D shr 2 or D shl 30;
1898
  Inc(A, (B shl 5 or B shr 27) + (E xor (C and (D xor E))) + W[19] + $5A827999); C := C shr 2 or C shl 30;
1899
 
1900
  Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[20] + $6ED9EBA1); B := B shr 2 or B shl 30;
1901
  Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[21] + $6ED9EBA1); A := A shr 2 or A shl 30;
1902
  Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[22] + $6ED9EBA1); E := E shr 2 or E shl 30;
1903
  Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[23] + $6ED9EBA1); D := D shr 2 or D shl 30;
1904
  Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[24] + $6ED9EBA1); C := C shr 2 or C shl 30;
1905
  Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[25] + $6ED9EBA1); B := B shr 2 or B shl 30;
1906
  Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[26] + $6ED9EBA1); A := A shr 2 or A shl 30;
1907
  Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[27] + $6ED9EBA1); E := E shr 2 or E shl 30;
1908
  Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[28] + $6ED9EBA1); D := D shr 2 or D shl 30;
1909
  Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[29] + $6ED9EBA1); C := C shr 2 or C shl 30;
1910
  Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[30] + $6ED9EBA1); B := B shr 2 or B shl 30;
1911
  Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[31] + $6ED9EBA1); A := A shr 2 or A shl 30;
1912
  Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[32] + $6ED9EBA1); E := E shr 2 or E shl 30;
1913
  Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[33] + $6ED9EBA1); D := D shr 2 or D shl 30;
1914
  Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[34] + $6ED9EBA1); C := C shr 2 or C shl 30;
1915
  Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[35] + $6ED9EBA1); B := B shr 2 or B shl 30;
1916
  Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[36] + $6ED9EBA1); A := A shr 2 or A shl 30;
1917
  Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[37] + $6ED9EBA1); E := E shr 2 or E shl 30;
1918
  Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[38] + $6ED9EBA1); D := D shr 2 or D shl 30;
1919
  Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[39] + $6ED9EBA1); C := C shr 2 or C shl 30;
1920
 
1921
  Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[40] + $8F1BBCDC); B := B shr 2 or B shl 30;
1922
  Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[41] + $8F1BBCDC); A := A shr 2 or A shl 30;
1923
  Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[42] + $8F1BBCDC); E := E shr 2 or E shl 30;
1924
  Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[43] + $8F1BBCDC); D := D shr 2 or D shl 30;
1925
  Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[44] + $8F1BBCDC); C := C shr 2 or C shl 30;
1926
  Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[45] + $8F1BBCDC); B := B shr 2 or B shl 30;
1927
  Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[46] + $8F1BBCDC); A := A shr 2 or A shl 30;
1928
  Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[47] + $8F1BBCDC); E := E shr 2 or E shl 30;
1929
  Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[48] + $8F1BBCDC); D := D shr 2 or D shl 30;
1930
  Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[49] + $8F1BBCDC); C := C shr 2 or C shl 30;
1931
  Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[50] + $8F1BBCDC); B := B shr 2 or B shl 30;
1932
  Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[51] + $8F1BBCDC); A := A shr 2 or A shl 30;
1933
  Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[52] + $8F1BBCDC); E := E shr 2 or E shl 30;
1934
  Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[53] + $8F1BBCDC); D := D shr 2 or D shl 30;
1935
  Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[54] + $8F1BBCDC); C := C shr 2 or C shl 30;
1936
  Inc(E, (A shl 5 or A shr 27) + ((B and C) or (D and (B or C))) + W[55] + $8F1BBCDC); B := B shr 2 or B shl 30;
1937
  Inc(D, (E shl 5 or E shr 27) + ((A and B) or (C and (A or B))) + W[56] + $8F1BBCDC); A := A shr 2 or A shl 30;
1938
  Inc(C, (D shl 5 or D shr 27) + ((E and A) or (B and (E or A))) + W[57] + $8F1BBCDC); E := E shr 2 or E shl 30;
1939
  Inc(B, (C shl 5 or C shr 27) + ((D and E) or (A and (D or E))) + W[58] + $8F1BBCDC); D := D shr 2 or D shl 30;
1940
  Inc(A, (B shl 5 or B shr 27) + ((C and D) or (E and (C or D))) + W[59] + $8F1BBCDC); C := C shr 2 or C shl 30;
1941
 
1942
  Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[60] + $CA62C1D6); B := B shr 2 or B shl 30;
1943
  Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[61] + $CA62C1D6); A := A shr 2 or A shl 30;
1944
  Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[62] + $CA62C1D6); E := E shr 2 or E shl 30;
1945
  Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[63] + $CA62C1D6); D := D shr 2 or D shl 30;
1946
  Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[64] + $CA62C1D6); C := C shr 2 or C shl 30;
1947
  Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[65] + $CA62C1D6); B := B shr 2 or B shl 30;
1948
  Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[66] + $CA62C1D6); A := A shr 2 or A shl 30;
1949
  Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[67] + $CA62C1D6); E := E shr 2 or E shl 30;
1950
  Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[68] + $CA62C1D6); D := D shr 2 or D shl 30;
1951
  Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[69] + $CA62C1D6); C := C shr 2 or C shl 30;
1952
  Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[70] + $CA62C1D6); B := B shr 2 or B shl 30;
1953
  Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[71] + $CA62C1D6); A := A shr 2 or A shl 30;
1954
  Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[72] + $CA62C1D6); E := E shr 2 or E shl 30;
1955
  Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[73] + $CA62C1D6); D := D shr 2 or D shl 30;
1956
  Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[74] + $CA62C1D6); C := C shr 2 or C shl 30;
1957
  Inc(E, (A shl 5 or A shr 27) + (D xor B xor C) + W[75] + $CA62C1D6); B := B shr 2 or B shl 30;
1958
  Inc(D, (E shl 5 or E shr 27) + (C xor A xor B) + W[76] + $CA62C1D6); A := A shr 2 or A shl 30;
1959
  Inc(C, (D shl 5 or D shr 27) + (B xor E xor A) + W[77] + $CA62C1D6); E := E shr 2 or E shl 30;
1960
  Inc(B, (C shl 5 or C shr 27) + (A xor D xor E) + W[78] + $CA62C1D6); D := D shr 2 or D shl 30;
1961
  Inc(A, (B shl 5 or B shr 27) + (E xor C xor D) + W[79] + $CA62C1D6); C := C shr 2 or C shl 30;
1962
 
1963
  Inc(FDigest[0], A);
1964
  Inc(FDigest[1], B);
1965
  Inc(FDigest[2], C);
1966
  Inc(FDigest[3], D);
1967
  Inc(FDigest[4], E);
1968
end;
1969
{$ENDIF}
1970
 
1971
procedure THash_SHA.DoDone;
1972
begin
1973
  if FCount[2] or FCount[3] <> 0 then HashingOverflowError;
1974
  if FPaddingByte = 0 then FPaddingByte := $80;
1975
  FBuffer[FBufferIndex] := FPaddingByte;
1976
  Inc(FBufferIndex);
1977
  if FBufferIndex > FBufferSize - 8 then
1978
  begin
1979
    FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
1980
    DoTransform(Pointer(FBuffer));
1981
    FBufferIndex := 0;
1982
  end;
1983
  FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
1984
  PLongWord(@FBuffer[FBufferSize - 8])^ := SwapLong(FCount[1]);
1985
  PLongWord(@FBuffer[FBufferSize - 4])^ := SwapLong(FCount[0]);
1986
  DoTransform(Pointer(FBuffer));
1987
  SwapLongBuffer(FDigest, FDigest, SizeOf(FDigest) div 4);
1988
end;
1989
 
1990
// .THash_SHA256
1991
class function THash_SHA256.DigestSize: Integer;
1992
begin
1993
  Result := 32;
1994
end;
1995
 
1996
procedure THash_SHA256.DoInit;
1997
begin
1998
  FDigest[0]:= $6A09E667;
1999
  FDigest[1]:= $BB67AE85;
2000
  FDigest[2]:= $3C6EF372;
2001
  FDigest[3]:= $A54FF53A;
2002
  FDigest[4]:= $510E527F;
2003
  FDigest[5]:= $9B05688C;
2004
  FDigest[6]:= $1F83D9AB;
2005
  FDigest[7]:= $5BE0CD19;
2006
end;
2007
 
2008
{$IFNDEF THash_SHA256_asm}
2009
procedure THash_SHA256.DoTransform(Buffer: PLongArray);
2010
var
2011
  I: Integer;
2012
  A,B,C,D,E,F,G,H: LongWord;
2013
  T1,T2: LongWord;
2014
  W: array[0..63] of LongWord;
2015
begin
2016
  SwapLongBuffer(Buffer[0], W, 16);
2017
 
2018
  for I := 16 to 63 do
2019
  begin
2020
    T1 := W[I - 15];
2021
    T2 := W[I - 2];
2022
    W[I] := W[I - 16] + W[I - 7] +
2023
           ((T1 shr  7 or T1 shl 25) xor (T1 shr 18 or T1 shl 14) xor (T1 shr  3)) +
2024
           ((T2 shr 17 or T2 shl 15) xor (T2 shr 19 or T2 shl 13) xor (T2 shr 10));
2025
  end;
2026
 
2027
  // calculate new hash values
2028
  A := FDigest[0];
2029
  B := FDigest[1];
2030
  C := FDigest[2];
2031
  D := FDigest[3];
2032
  E := FDigest[4];
2033
  F := FDigest[5];
2034
  G := FDigest[6];
2035
  H := FDigest[7];
2036
  for I := 0 to 63 do
2037
  begin
2038
    T1 := ((E shr 6 or E shl 26) xor (E shr 11 or E shl 21) xor
2039
           (E shr 25 or E shl 7)) + H + (((F xor G) and E) xor G) + SHA_256K[I] + W[I];
2040
    T2 := ((A shr 2 or A shl 30) xor (A shr 13 or A shl 19) xor
2041
           (A shr 22 or A shl 10)) + (((B or C) and A) or (B and C));
2042
    H := G; G := F; F := E; E := D + T1; D := C; C := B; B := A; A := T1 + T2;
2043
  end;
2044
  Inc(FDigest[0], A);
2045
  Inc(FDigest[1], B);
2046
  Inc(FDigest[2], C);
2047
  Inc(FDigest[3], D);
2048
  Inc(FDigest[4], E);
2049
  Inc(FDigest[5], F);
2050
  Inc(FDigest[6], G);
2051
  Inc(FDigest[7], H);
2052
end;
2053
{$ENDIF}
2054
 
2055
// .THash_SHA384
2056
class function THash_SHA384.DigestSize: Integer;
2057
begin
2058
  Result := 48;
2059
end;
2060
 
2061
class function THash_SHA384.BlockSize: Integer;
2062
begin
2063
  Result := 128;
2064
end;
2065
 
2066
function THash_SHA384.Digest: PByteArray;
2067
begin
2068
  Result := @FDigest;
2069
end;
2070
 
2071
{$IFNDEF THash_SHA384_asm}
2072
procedure THash_SHA384.DoTransform(Buffer: PLongArray);
2073
var
2074
  A,B,C,D,E,F,G,H: Int64;
2075
  T1,T2: Int64;
2076
  I: Integer;
2077
  W: array [0..79] of Int64;
2078
begin
2079
  SwapInt64Buffer(Buffer[0], W, 16);
2080
 
2081
  // calculate other 64 uint64
2082
  for I := 16 to 79 do
2083
  begin
2084
    T1 := W[I - 15];
2085
    T2 := W[I - 2];
2086
    W[I] := W[I - 16] + W[I - 7]  +
2087
             ((T1 shr  1 or T1 shl 63) xor (T1 shr  8 or T1 shl 56) xor (T1 shr  7)) +
2088
             ((T2 shr 19 or T2 shl 45) xor (T2 shr 61 or T2 shl  3) xor (T2 shr  6));
2089
  end;
2090
 
2091
  // calculate new hash values
2092
  A := FDigest[0];
2093
  B := FDigest[1];
2094
  C := FDigest[2];
2095
  D := FDigest[3];
2096
  E := FDigest[4];
2097
  F := FDigest[5];
2098
  G := FDigest[6];
2099
  H := FDigest[7];
2100
  for I := 0 to 79 do
2101
  begin
2102
    T1 := ((E shr 14 or E shl 50) xor (E shr 18 or E shl 46) xor
2103
           (E shr 41 or E shl 23)) + H + (((F xor G) and E) xor G) + SHA_512K[I] + W[I];
2104
    T2 := ((A shr 28 or A shl 36) xor (A shr 34 or A shl 30) xor
2105
           (A shr 39 or A shl 25)) + (((B or C) and A) or (B and C));
2106
    H := G;
2107
    G := F;
2108
    F := E;
2109
    E := D + T1;
2110
    D := C;
2111
    C := B;
2112
    B := A;
2113
    A := T1 + T2;
2114
  end;
2115
  Inc(FDigest[0], A);
2116
  Inc(FDigest[1], B);
2117
  Inc(FDigest[2], C);
2118
  Inc(FDigest[3], D);
2119
  Inc(FDigest[4], E);
2120
  Inc(FDigest[5], F);
2121
  Inc(FDigest[6], G);
2122
  Inc(FDigest[7], H);
2123
end;
2124
{$ENDIF}
2125
 
2126
procedure THash_SHA384.DoInit;
2127
begin
2128
  FDigest[0] := $CBBB9D5DC1059ED8;
2129
  FDigest[1] := $629A292A367CD507;
2130
  FDigest[2] := $9159015A3070DD17;
2131
  FDigest[3] := $152FECD8F70E5939;
2132
  FDigest[4] := $67332667FFC00B31;
2133
  FDigest[5] := $8EB44A8768581511;
2134
  FDigest[6] := $DB0C2E0D64F98FA7;
2135
  FDigest[7] := $47B5481DBEFA4FA4;
2136
end;
2137
 
2138
procedure THash_SHA384.DoDone;
2139
begin
2140
  if FPaddingByte = 0 then FPaddingByte := $80;
2141
  FBuffer[FBufferIndex] := FPaddingByte;
2142
  Inc(FBufferIndex);
2143
  if FBufferIndex > FBufferSize - 16 then
2144
  begin
2145
    FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
2146
    DoTransform(Pointer(FBuffer));
2147
    FBufferIndex := 0;
2148
  end;
2149
  FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
2150
  SwapLongBuffer(FCount, FCount, 4);
2151
  PLongWord(@FBuffer[FBufferSize - 16])^ := FCount[3];
2152
  PLongWord(@FBuffer[FBufferSize - 12])^ := FCount[2];
2153
  PLongWord(@FBuffer[FBufferSize -  8])^ := FCount[1];
2154
  PLongWord(@FBuffer[FBufferSize -  4])^ := FCount[0];
2155
  DoTransform(Pointer(FBuffer));
2156
  SwapInt64Buffer(FDigest, FDigest, SizeOf(FDigest) div 8);
2157
end;
2158
 
2159
// .THash_SHA512
2160
class function THash_SHA512.DigestSize: Integer;
2161
begin
2162
  Result := 64;
2163
end;
2164
 
2165
procedure THash_SHA512.DoInit;
2166
begin
2167
  FDigest[0] := $6A09E667F3BCC908;
2168
  FDigest[1] := $BB67AE8584CAA73B;
2169
  FDigest[2] := $3C6EF372FE94F82B;
2170
  FDigest[3] := $A54FF53A5F1D36F1;
2171
  FDigest[4] := $510E527FADE682D1;
2172
  FDigest[5] := $9B05688C2B3E6C1F;
2173
  FDigest[6] := $1F83D9ABFB41BD6B;
2174
  FDigest[7] := $5BE0CD19137E2179;
2175
end;
2176
 
2177
// .THashBaseHaval
2178
procedure THashBaseHaval.SetRounds(Value: Integer);
2179
begin
2180
  if (Value < 3) or (Value > 5) then
2181
    if DigestSize <= 20 then Value := 3 else
2182
      if DigestSize <= 28 then Value := 4
2183
        else Value := 5;
2184
  FRounds := Value;
2185
  case FRounds of
2186
    3: FTransform := DoTransform3;
2187
    4: FTransform := DoTransform4;
2188
    5: FTransform := DoTransform5;
2189
  end;
2190
end;
2191
 
2192
procedure THashBaseHaval.DoTransform(Buffer: PLongArray);
2193
begin
2194
  FTRansform(Buffer);
2195
end;
2196
 
2197
{$IFNDEF THashBaseHaval_asm}
2198
procedure THashBaseHaval.DoTransform3(Buffer: PLongArray);
2199
var
2200
  A,B,C,D,E,F,G,H,I,T: LongWord;
2201
  Data: PLongWord;
2202
  Offset: PByte;
2203
begin
2204
  Offset := @Haval_Offset;
2205
  Data   := @Haval_Data;
2206
 
2207
  A := FDigest[0];
2208
  B := FDigest[1];
2209
  C := FDigest[2];
2210
  D := FDigest[3];
2211
  E := FDigest[4];
2212
  F := FDigest[5];
2213
  G := FDigest[6];
2214
  H := FDigest[7];
2215
 
2216
  for I := 0 to 31 do
2217
  begin
2218
    T := C and (E xor D) xor G and A xor F and B xor E;
2219
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[I];
2220
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2221
  end;
2222
  for I := 0 to 31 do
2223
  begin
2224
    T := F and (D and not A xor B and C xor E xor G) xor B and (D xor C) xor A and C xor G;
2225
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2226
    Inc(Offset); Inc(Data);
2227
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2228
  end;
2229
  for I := 0 to 31 do
2230
  begin
2231
    T := D and (F and E xor G xor A) xor F and C xor E and B xor A;
2232
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2233
    Inc(Offset); Inc(Data);
2234
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2235
  end;
2236
 
2237
  Inc(FDigest[0], A);
2238
  Inc(FDigest[1], B);
2239
  Inc(FDigest[2], C);
2240
  Inc(FDigest[3], D);
2241
  Inc(FDigest[4], E);
2242
  Inc(FDigest[5], F);
2243
  Inc(FDigest[6], G);
2244
  Inc(FDigest[7], H);
2245
end;
2246
 
2247
procedure THashBaseHaval.DoTransform4(Buffer: PLongArray);
2248
var
2249
  A,B,C,D,E,F,G,H,I,T: LongWord;
2250
  Data: PLongWord;
2251
  Offset: PByte;
2252
begin
2253
  Offset := @Haval_Offset;
2254
  Data   := @Haval_Data;
2255
 
2256
  A := FDigest[0];
2257
  B := FDigest[1];
2258
  C := FDigest[2];
2259
  D := FDigest[3];
2260
  E := FDigest[4];
2261
  F := FDigest[5];
2262
  G := FDigest[6];
2263
  H := FDigest[7];
2264
 
2265
  for I := 0 to 31 do
2266
  begin
2267
    T := D and (A xor B) xor F and G xor E and C xor A;
2268
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[I];
2269
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2270
  end;
2271
  for I := 0 to 31 do
2272
  begin
2273
    T := B and (G and not A xor C and F xor D xor E) xor C and (G xor F) xor A and F xor E;
2274
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2275
    Inc(Offset); Inc(Data);
2276
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2277
  end;
2278
  for I := 0 to 31 do
2279
  begin
2280
    T := G and (C and A xor B xor F) xor C and D xor A and E xor F;
2281
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2282
    Inc(Offset); Inc(Data);
2283
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2284
  end;
2285
  for I := 0 to 31 do
2286
  begin
2287
    T := A and (E and not C xor F and not G xor B xor G xor D) xor F and
2288
        (B and C xor E xor G) xor C and G xor D;
2289
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2290
    Inc(Offset); Inc(Data);
2291
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2292
  end;
2293
 
2294
  Inc(FDigest[0], A);
2295
  Inc(FDigest[1], B);
2296
  Inc(FDigest[2], C);
2297
  Inc(FDigest[3], D);
2298
  Inc(FDigest[4], E);
2299
  Inc(FDigest[5], F);
2300
  Inc(FDigest[6], G);
2301
  Inc(FDigest[7], H);
2302
end;
2303
 
2304
 
2305
procedure THashBaseHaval.DoTransform5(Buffer: PLongArray);
2306
var
2307
  A,B,C,D,E,F,G,H,I,T: LongWord;
2308
  Data: PLongWord;
2309
  Offset: PByte;
2310
begin
2311
  Offset := @Haval_Offset;
2312
  Data   := @Haval_Data;
2313
 
2314
  A := FDigest[0];
2315
  B := FDigest[1];
2316
  C := FDigest[2];
2317
  D := FDigest[3];
2318
  E := FDigest[4];
2319
  F := FDigest[5];
2320
  G := FDigest[6];
2321
  H := FDigest[7];
2322
 
2323
  for I := 0 to 31 do
2324
  begin
2325
    T := C and (G xor B) xor F and E xor A and D xor G;
2326
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[I];
2327
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2328
  end;
2329
  for I := 0 to 31 do
2330
  begin
2331
    T := D and (E and not A xor B and C xor G xor F) xor B and (E xor C) xor A and C xor F;
2332
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2333
    Inc(Offset); Inc(Data);
2334
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2335
  end;
2336
  for I := 0 to 31 do
2337
  begin
2338
    T := E and (B and D xor C xor F) xor B and A xor D and G xor F;
2339
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2340
    Inc(Offset); Inc(Data);
2341
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2342
  end;
2343
  for I := 0 to 31 do
2344
  begin
2345
    T := D and (F and not A xor C and not B xor E xor B xor G) xor C and
2346
        (E and A xor F xor B) xor A and B xor G;
2347
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2348
    Inc(Offset); Inc(Data);
2349
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2350
  end;
2351
  for I := 0 to 31 do
2352
  begin
2353
    T := B and (D and E and G xor not F) xor D and A xor E and F xor G and C;
2354
    T := (T shr 7 or T shl 25) + (H shr 11 or H shl 21) + Buffer[Offset^] + Data^;
2355
    Inc(Offset); Inc(Data);
2356
    H := G; G := F; F := E; E := D; D := C; C := B; B := A; A := T;
2357
  end;
2358
 
2359
  Inc(FDigest[0], A);
2360
  Inc(FDigest[1], B);
2361
  Inc(FDigest[2], C);
2362
  Inc(FDigest[3], D);
2363
  Inc(FDigest[4], E);
2364
  Inc(FDigest[5], F);
2365
  Inc(FDigest[6], G);
2366
  Inc(FDigest[7], H);
2367
end;
2368
{$ENDIF}
2369
 
2370
procedure THashBaseHaval.DoInit;
2371
begin
2372
  SetRounds(FRounds);
2373
  FDigest[0] := $243F6A88;
2374
  FDigest[1] := $85A308D3;
2375
  FDigest[2] := $13198A2E;
2376
  FDigest[3] := $03707344;
2377
  FDigest[4] := $A4093822;
2378
  FDigest[5] := $299F31D0;
2379
  FDigest[6] := $082EFA98;
2380
  FDigest[7] := $EC4E6C89;
2381
end;
2382
 
2383
procedure THashBaseHaval.DoDone;
2384
 
2385
  function ROR(Value,Count: LongWord): LongWord;
2386
  asm
2387
     MOV  ECX,EDX
2388
     ROR  EAX,CL
2389
  end;
2390
 
2391
var
2392
  T: Word;
2393
begin
2394
  if FCount[2] or FCount[3] <> 0 then HashingOverflowError;
2395
  if FPaddingByte = 0 then FPaddingByte := $01;
2396
  FBuffer[FBufferIndex] := FPaddingByte;
2397
  Inc(FBufferIndex);
2398
  if FBufferIndex > FBufferSize -10 then
2399
  begin
2400
    FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex - 10, 0);
2401
    DoTransform(Pointer(FBuffer));
2402
    FBufferIndex := 0;
2403
  end;
2404
  FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex -10, 0);
2405
  T := DigestSize shl 9 or FRounds shl 3 or 1;
2406
  Move(T, FBuffer[FBufferSize - 10], SizeOf(T));
2407
  Move(FCount, FBuffer[FBufferSize - 8], 8);
2408
  DoTransform(Pointer(FBuffer));
2409
 
2410
  case DigestSize of
2411
    16: begin
2412
          Inc(FDigest[0], ROR(FDigest[7] and $000000FF or
2413
                              FDigest[6] and $FF000000 or
2414
                              FDigest[5] and $00FF0000 or
2415
                              FDigest[4] and $0000FF00, 8));
2416
          Inc(FDigest[1], ROR(FDigest[7] and $0000FF00 or
2417
                              FDigest[6] and $000000FF or
2418
                              FDigest[5] and $FF000000 or
2419
                              FDigest[4] and $00FF0000, 16));
2420
          Inc(FDigest[2], ROR(FDigest[7] and $00FF0000 or
2421
                              FDigest[6] and $0000FF00 or
2422
                              FDigest[5] and $000000FF or
2423
                              FDigest[4] and $FF000000, 24));
2424
          Inc(FDigest[3],     FDigest[7] and $FF000000 or
2425
                              FDigest[6] and $00FF0000 or
2426
                              FDigest[5] and $0000FF00 or
2427
                              FDigest[4] and $000000FF);
2428
        end;
2429
    20: begin
2430
          Inc(FDigest[0], ROR(FDigest[7] and ($3F) or
2431
                              FDigest[6] and ($7F shl 25) or
2432
                              FDigest[5] and ($3F shl 19), 19));
2433
          Inc(FDigest[1], ROR(FDigest[7] and ($3F shl 6) or
2434
                              FDigest[6] and ($3F) or
2435
                              FDigest[5] and ($7F shl 25), 25));
2436
          Inc(FDigest[2],     FDigest[7] and ($7F shl 12) or
2437
                              FDigest[6] and ($3F shl  6) or
2438
                              FDigest[5] and ($3F));
2439
          Inc(FDigest[3],    (FDigest[7] and ($3F shl 19) or
2440
                              FDigest[6] and ($7F shl 12) or
2441
                              FDigest[5] and ($3F shl  6)) shr 6);
2442
          Inc(FDigest[4],    (FDigest[7] and ($7F shl 25) or
2443
                              FDigest[6] and ($3F shl 19) or
2444
                              FDigest[5] and ($7F shl 12)) shr 12);
2445
        end;
2446
    24: begin
2447
          Inc(FDigest[0], ROR(FDigest[7] and ($1F) or
2448
                              FDigest[6] and ($3F shl 26), 26));
2449
          Inc(FDigest[1],     FDigest[7] and ($1F shl 5) or
2450
                              FDigest[6] and ($1F));
2451
          Inc(FDigest[2],    (FDigest[7] and ($3F shl 10) or
2452
                              FDigest[6] and ($1F shl  5)) shr 5);
2453
          Inc(FDigest[3],    (FDigest[7] and ($1F shl 16) or
2454
                              FDigest[6] and ($3F shl 10)) shr 10);
2455
          Inc(FDigest[4],    (FDigest[7] and ($1F shl 21) or
2456
                              FDigest[6] and ($1F shl 16)) shr 16);
2457
          Inc(FDigest[5],    (FDigest[7] and ($3F shl 26) or
2458
                              FDigest[6] and ($1F shl 21)) shr 21);
2459
        end;
2460
    28: begin
2461
          Inc(FDigest[0], FDigest[7] shr 27 and $1F);
2462
          Inc(FDigest[1], FDigest[7] shr 22 and $1F);
2463
          Inc(FDigest[2], FDigest[7] shr 18 and $0F);
2464
          Inc(FDigest[3], FDigest[7] shr 13 and $1F);
2465
          Inc(FDigest[4], FDigest[7] shr  9 and $0F);
2466
          Inc(FDigest[5], FDigest[7] shr  4 and $1F);
2467
          Inc(FDigest[6], FDigest[7]        and $0F);
2468
        end;
2469
  end;
2470
end;
2471
 
2472
class function THashBaseHaval.BlockSize: Integer;
2473
begin
2474
  Result := 128;
2475
end;
2476
 
2477
function THashBaseHaval.Digest: PByteArray;
2478
begin
2479
  Result := @FDigest;
2480
end;
2481
 
2482
class function THash_Haval128.DigestSize: Integer;
2483
begin
2484
  Result := 16;
2485
end;
2486
 
2487
class function THash_Haval160.DigestSize: Integer;
2488
begin
2489
  Result := 20;
2490
end;
2491
 
2492
class function THash_Haval192.DigestSize: Integer;
2493
begin
2494
  Result := 24;
2495
end;
2496
 
2497
class function THash_Haval224.DigestSize: Integer;
2498
begin
2499
  Result := 28;
2500
end;
2501
 
2502
class function THash_Haval256.DigestSize: Integer;
2503
begin
2504
  Result := 32;
2505
end;
2506
 
2507
// .THash_Tiger
2508
class function THash_Tiger.DigestSize: Integer;
2509
begin
2510
  Result := 24;
2511
end;
2512
 
2513
procedure THash_Tiger.SetRounds(Value: Integer);
2514
begin
2515
  if (Value < 3) or (Value > 32) then Value := 3;
2516
  FRounds := Value;
2517
end;
2518
 
2519
{$IFNDEF THash_Tiger_asm}
2520
procedure THash_Tiger.DoTransform(Buffer: PLongArray);
2521
type
2522
  PTiger_Data = ^TTiger_Data;
2523
  TTiger_Data = array[0..3, 0..255] of Int64;
2524
 
2525
  PInt64Array = ^TInt64Array;
2526
  TInt64Array = array[0..7] of Int64;
2527
 
2528
var
2529
  A,B,C,T: Int64;
2530
  x0,x1,x2,x3,x4,x5,x6,x7: Int64;
2531
  I: Integer;
2532
begin
2533
  A  := PInt64Array(@FDigest)[0];
2534
  B  := PInt64Array(@FDigest)[1];
2535
  C  := PInt64Array(@FDigest)[2];
2536
  x0 := PInt64Array(Buffer)[0];
2537
  x1 := PInt64Array(Buffer)[1];
2538
  x2 := PInt64Array(Buffer)[2];
2539
  x3 := PInt64Array(Buffer)[3];
2540
  x4 := PInt64Array(Buffer)[4];
2541
  x5 := PInt64Array(Buffer)[5];
2542
  x6 := PInt64Array(Buffer)[6];
2543
  x7 := PInt64Array(Buffer)[7];
2544
 
2545
  for I := 1 to FRounds do {a Loop is faster for PC's with small Cache}
2546
  begin
2547
    if I > 1 then {key schedule}
2548
    begin
2549
      Dec(x0, x7 xor $A5A5A5A5A5A5A5A5);
2550
      x1 := x1 xor x0;
2551
      Inc(x2, x1);
2552
      Dec(x3, x2 xor (not x1 shl 19));
2553
      x4 := x4 xor x3;
2554
      Inc(x5, x4);
2555
      Dec(x6, x5 xor (not x4 shr 23));
2556
      x7 := x7 xor x6;
2557
      Inc(x0, x7);
2558
      Dec(x1, x0 xor (not x7 shl 19));
2559
      x2 := x2 xor x1;
2560
      Inc(x3, x2);
2561
      Dec(x4, x3 xor (not x2 shr 23));
2562
      x5 := x5 xor x4;
2563
      Inc(x6, x5);
2564
      Dec(x7, x6 xor $0123456789ABCDEF);
2565
    end;
2566
 
2567
    C := C xor x0;
2568
    Dec(A, TTiger_Data(Tiger_Data)[0, LongWord(C)        and $FF] xor
2569
           TTiger_Data(Tiger_Data)[1, LongWord(C) shr 16 and $FF] xor
2570
           TTiger_Data(Tiger_Data)[2,          C  shr 32 and $FF] xor
2571
           TTiger_Data(Tiger_Data)[3, LongWord(C shr 32) shr 16 and $FF]);
2572
    Inc(B, TTiger_Data(Tiger_Data)[3, LongWord(C) shr  8 and $FF] xor
2573
           TTiger_Data(Tiger_Data)[2, LongWord(C) shr 24] xor
2574
           TTiger_Data(Tiger_Data)[1, LongWord(C shr 32) shr 8 and $FF] xor
2575
           TTiger_Data(Tiger_Data)[0, LongWord(C shr 32) shr 24]);
2576
    if I = 1 then B := B shl 2 + B else
2577
      if I = 2 then B := B shl 3 - B
2578
        else B := B shl 3 + B;
2579
 
2580
    A := A xor x1;
2581
    Dec(B, TTiger_Data(Tiger_Data)[0, LongWord(A)        and $FF] xor
2582
           TTiger_Data(Tiger_Data)[1, LongWord(A) shr 16 and $FF] xor
2583
           TTiger_Data(Tiger_Data)[2,          A  shr 32 and $FF] xor
2584
           TTiger_Data(Tiger_Data)[3, LongWord(A shr 32) shr 16 and $FF]);
2585
    Inc(C, TTiger_Data(Tiger_Data)[3, LongWord(A) shr  8 and $FF] xor
2586
           TTiger_Data(Tiger_Data)[2, LongWord(A) shr 24] xor
2587
           TTiger_Data(Tiger_Data)[1, LongWord(A shr 32) shr 8 and $FF] xor
2588
           TTiger_Data(Tiger_Data)[0, LongWord(A shr 32) shr 24]);
2589
    if I = 1 then C := C shl 2 + C else
2590
      if I = 2 then C := C shl 3 - C
2591
        else C := C shl 3 + C;
2592
 
2593
    B := B xor x2;
2594
    Dec(C, TTiger_Data(Tiger_Data)[0, LongWord(B)        and $FF] xor
2595
           TTiger_Data(Tiger_Data)[1, LongWord(B) shr 16 and $FF] xor
2596
           TTiger_Data(Tiger_Data)[2,          B  shr 32 and $FF] xor
2597
           TTiger_Data(Tiger_Data)[3, LongWord(B shr 32) shr 16 and $FF]);
2598
    Inc(A, TTiger_Data(Tiger_Data)[3, LongWord(B) shr  8 and $FF] xor
2599
           TTiger_Data(Tiger_Data)[2, LongWord(B) shr 24] xor
2600
           TTiger_Data(Tiger_Data)[1, LongWord(B shr 32) shr 8 and $FF] xor
2601
           TTiger_Data(Tiger_Data)[0, LongWord(B shr 32) shr 24]);
2602
    if I = 1 then A := A shl 2 + A else
2603
      if I = 2 then A := A shl 3 - A
2604
        else A := A shl 3 + A;
2605
 
2606
    C := C xor x3;
2607
    Dec(A, TTiger_Data(Tiger_Data)[0, LongWord(C)        and $FF] xor
2608
           TTiger_Data(Tiger_Data)[1, LongWord(C) shr 16 and $FF] xor
2609
           TTiger_Data(Tiger_Data)[2,          C  shr 32 and $FF] xor
2610
           TTiger_Data(Tiger_Data)[3, LongWord(C shr 32) shr 16 and $FF]);
2611
    Inc(B, TTiger_Data(Tiger_Data)[3, LongWord(C) shr  8 and $FF] xor
2612
           TTiger_Data(Tiger_Data)[2, LongWord(C) shr 24] xor
2613
           TTiger_Data(Tiger_Data)[1, LongWord(C shr 32) shr 8 and $FF] xor
2614
           TTiger_Data(Tiger_Data)[0, LongWord(C shr 32) shr 24]);
2615
    if I = 1 then B := B shl 2 + B else
2616
      if I = 2 then B := B shl 3 - B
2617
        else B := B shl 3 + B;
2618
 
2619
    A := A xor x4;
2620
    Dec(B, TTiger_Data(Tiger_Data)[0, LongWord(A)        and $FF] xor
2621
           TTiger_Data(Tiger_Data)[1, LongWord(A) shr 16 and $FF] xor
2622
           TTiger_Data(Tiger_Data)[2,          A  shr 32 and $FF] xor
2623
           TTiger_Data(Tiger_Data)[3, LongWord(A shr 32) shr 16 and $FF]);
2624
    Inc(C, TTiger_Data(Tiger_Data)[3, LongWord(A) shr  8 and $FF] xor
2625
           TTiger_Data(Tiger_Data)[2, LongWord(A) shr 24] xor
2626
           TTiger_Data(Tiger_Data)[1, LongWord(A shr 32) shr 8 and $FF] xor
2627
           TTiger_Data(Tiger_Data)[0, LongWord(A shr 32) shr 24]);
2628
    if I = 1 then C := C shl 2 + C else
2629
      if I = 2 then C := C shl 3 - C
2630
        else C := C shl 3 + C;
2631
 
2632
    B := B xor x5;
2633
    Dec(C, TTiger_Data(Tiger_Data)[0, LongWord(B)        and $FF] xor
2634
           TTiger_Data(Tiger_Data)[1, LongWord(B) shr 16 and $FF] xor
2635
           TTiger_Data(Tiger_Data)[2,          B  shr 32 and $FF] xor
2636
           TTiger_Data(Tiger_Data)[3, LongWord(B shr 32) shr 16 and $FF]);
2637
    Inc(A, TTiger_Data(Tiger_Data)[3, LongWord(B) shr  8 and $FF] xor
2638
           TTiger_Data(Tiger_Data)[2, LongWord(B) shr 24] xor
2639
           TTiger_Data(Tiger_Data)[1, LongWord(B shr 32) shr 8 and $FF] xor
2640
           TTiger_Data(Tiger_Data)[0, LongWord(B shr 32) shr 24]);
2641
    if I = 1 then A := A shl 2 + A else
2642
      if I = 2 then A := A shl 3 - A
2643
        else A := A shl 3 + A;
2644
 
2645
    C := C xor x6;
2646
    Dec(A, TTiger_Data(Tiger_Data)[0, LongWord(C)        and $FF] xor
2647
           TTiger_Data(Tiger_Data)[1, LongWord(C) shr 16 and $FF] xor
2648
           TTiger_Data(Tiger_Data)[2,          C  shr 32 and $FF] xor
2649
           TTiger_Data(Tiger_Data)[3, LongWord(C shr 32) shr 16 and $FF]);
2650
    Inc(B, TTiger_Data(Tiger_Data)[3, LongWord(C) shr  8 and $FF] xor
2651
           TTiger_Data(Tiger_Data)[2, LongWord(C) shr 24] xor
2652
           TTiger_Data(Tiger_Data)[1, LongWord(C shr 32) shr 8 and $FF] xor
2653
           TTiger_Data(Tiger_Data)[0, LongWord(C shr 32) shr 24]);
2654
    if I = 1 then B := B shl 2 + B else
2655
      if I = 2 then B := B shl 3 - B
2656
        else B := B shl 3 + B;
2657
 
2658
    A := A xor x7;
2659
    Dec(B, TTiger_Data(Tiger_Data)[0, LongWord(A)        and $FF] xor
2660
           TTiger_Data(Tiger_Data)[1, LongWord(A) shr 16 and $FF] xor
2661
           TTiger_Data(Tiger_Data)[2,          A  shr 32 and $FF] xor
2662
           TTiger_Data(Tiger_Data)[3, LongWord(A shr 32) shr 16 and $FF]);
2663
    Inc(C, TTiger_Data(Tiger_Data)[3, LongWord(A) shr  8 and $FF] xor
2664
           TTiger_Data(Tiger_Data)[2, LongWord(A) shr 24] xor
2665
           TTiger_Data(Tiger_Data)[1, LongWord(A shr 32) shr 8 and $FF] xor
2666
           TTiger_Data(Tiger_Data)[0, LongWord(A shr 32) shr 24]);
2667
    if I = 1 then C := C shl 2 + C else
2668
      if I = 2 then C := C shl 3 - C
2669
        else C := C shl 3 + C;
2670
 
2671
    T := A; A := C; C := B; B := T;
2672
  end;
2673
 
2674
  PInt64Array(@FDigest)[0] := A xor PInt64Array(@FDigest)[0];
2675
  PInt64Array(@FDigest)[1] := B  -  PInt64Array(@FDigest)[1];
2676
  PInt64Array(@FDigest)[2] := C  +  PInt64Array(@FDigest)[2];
2677
end;
2678
{$ENDIF}
2679
 
2680
procedure THash_Tiger.DoInit;
2681
begin
2682
  SetRounds(FRounds);
2683
  if FPaddingByte = 0 then FPaddingByte := $01;
2684
  FDigest[0] := $89ABCDEF;
2685
  FDigest[1] := $01234567;
2686
  FDigest[2] := $76543210;
2687
  FDigest[3] := $FEDCBA98;
2688
  FDigest[4] := $C3B2E187;
2689
  FDigest[5] := $F096A5B4;
2690
end;
2691
 
2692
// .THash_Panama
2693
class function THash_Panama.DigestSize: Integer;
2694
begin
2695
  Result := 32;
2696
end;
2697
 
2698
class function THash_Panama.BlockSize: Integer;
2699
begin
2700
  Result := 32
2701
end;
2702
 
2703
function THash_Panama.Digest: PByteArray;
2704
begin
2705
  Result := @FDigest;
2706
end;
2707
 
2708
procedure THash_Panama.DoInit;
2709
begin
2710
  FillChar(FLFSRBuffer, SizeOf(FLFSRBuffer), 0);
2711
  FillChar(FDigest, SizeOf(FDigest), 0);
2712
  FTap := 0;
2713
end;
2714
 
2715
procedure THash_Panama.DoDone;
2716
begin
2717
  if FPaddingByte = 0 then FPaddingByte := $01;
2718
  FBuffer[FBufferIndex] := FPaddingByte;
2719
  Inc(FBufferIndex);
2720
  FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
2721
  DoTransform(Pointer(FBuffer));
2722
  DoPull;
2723
  FillChar(FLFSRBuffer, SizeOf(FLFSRBuffer), 0);
2724
  FTap := 0;
2725
end;
2726
 
2727
{$IFNDEF THash_Panama_asm}
2728
procedure THash_Panama.DoPull;
2729
var
2730
  PBufL,PBufB,PTap0,PTap25: PLongArray;
2731
  T0,T1,T2,T3: LongWord;
2732
  I: Integer;
2733
begin
2734
  for I := 0 to 31 do
2735
  begin
2736
    // LFSR emulation
2737
    PBufL := @FLFSRBuffer[(FTap +  4) and 31];
2738
    PBufB := @FLFSRBuffer[(FTap + 16) and 31];
2739
    FTap := (FTap - 1) and 31;
2740
    PTap0  := @FLFSRBuffer[FTap];
2741
    PTap25 := @FLFSRBuffer[(FTap + 25) and 31];
2742
    // update the LFSR buffer (LAMBDA_PULL)
2743
    PTap25[ 0] := PTap25[ 0] xor PTap0[ 2];
2744
    PTap25[ 1] := PTap25[ 1] xor PTap0[ 3];
2745
    PTap25[ 2] := PTap25[ 2] xor PTap0[ 4];
2746
    PTap25[ 3] := PTap25[ 3] xor PTap0[ 5];
2747
    PTap25[ 4] := PTap25[ 4] xor PTap0[ 6];
2748
    PTap25[ 5] := PTap25[ 5] xor PTap0[ 7];
2749
    PTap25[ 6] := PTap25[ 6] xor PTap0[ 0];
2750
    PTap25[ 7] := PTap25[ 7] xor PTap0[ 1];
2751
    PTap0[ 0] := PTap0[ 0] xor FDigest[ 1];
2752
    PTap0[ 1] := PTap0[ 1] xor FDigest[ 2];
2753
    PTap0[ 2] := PTap0[ 2] xor FDigest[ 3];
2754
    PTap0[ 3] := PTap0[ 3] xor FDigest[ 4];
2755
    PTap0[ 4] := PTap0[ 4] xor FDigest[ 5];
2756
    PTap0[ 5] := PTap0[ 5] xor FDigest[ 6];
2757
    PTap0[ 6] := PTap0[ 6] xor FDigest[ 7];
2758
    PTap0[ 7] := PTap0[ 7] xor FDigest[ 8];
2759
    // perform non-linearity stage (GAMMA)
2760
    T0 := FDigest[ 0];
2761
    T1 := FDigest[ 1];
2762
    FDigest[ 0] := FDigest[ 0] xor (FDigest[ 1] or not FDigest[ 2]);
2763
    FDigest[ 1] := FDigest[ 1] xor (FDigest[ 2] or not FDigest[ 3]);
2764
    FDigest[ 2] := FDigest[ 2] xor (FDigest[ 3] or not FDigest[ 4]);
2765
    FDigest[ 3] := FDigest[ 3] xor (FDigest[ 4] or not FDigest[ 5]);
2766
    FDigest[ 4] := FDigest[ 4] xor (FDigest[ 5] or not FDigest[ 6]);
2767
    FDigest[ 5] := FDigest[ 5] xor (FDigest[ 6] or not FDigest[ 7]);
2768
    FDigest[ 6] := FDigest[ 6] xor (FDigest[ 7] or not FDigest[ 8]);
2769
    FDigest[ 7] := FDigest[ 7] xor (FDigest[ 8] or not FDigest[ 9]);
2770
    FDigest[ 8] := FDigest[ 8] xor (FDigest[ 9] or not FDigest[10]);
2771
    FDigest[ 9] := FDigest[ 9] xor (FDigest[10] or not FDigest[11]);
2772
    FDigest[10] := FDigest[10] xor (FDigest[11] or not FDigest[12]);
2773
    FDigest[11] := FDigest[11] xor (FDigest[12] or not FDigest[13]);
2774
    FDigest[12] := FDigest[12] xor (FDigest[13] or not FDigest[14]);
2775
    FDigest[13] := FDigest[13] xor (FDigest[14] or not FDigest[15]);
2776
    FDigest[14] := FDigest[14] xor (FDigest[15] or not FDigest[16]);
2777
    FDigest[15] := FDigest[15] xor (FDigest[16] or not T0);
2778
    FDigest[16] := FDigest[16] xor (T0 or not T1);
2779
 
2780
    // perform bit-dispersion stage (PI)
2781
    T0 := FDigest[ 1];
2782
    T1 := FDigest[ 7]; FDigest[ 1] := (T1 shl  1) or (T1 shr 31);
2783
    T1 := FDigest[ 5]; FDigest[ 5] := (T0 shl 15) or (T0 shr 17);
2784
    T0 := FDigest[ 8]; FDigest[ 8] := (T1 shl  4) or (T1 shr 28);
2785
    T1 := FDigest[ 6]; FDigest[ 6] := (T0 shl 21) or (T0 shr 11);
2786
    T0 := FDigest[13]; FDigest[13] := (T1 shl 27) or (T1 shr  5);
2787
    T1 := FDigest[14]; FDigest[14] := (T0 shl  9) or (T0 shr 23);
2788
    T0 := FDigest[ 2]; FDigest[ 2] := (T1 shl  3) or (T1 shr 29);
2789
    T1 := FDigest[10]; FDigest[10] := (T0 shl 23) or (T0 shr  9);
2790
    T0 := FDigest[16]; FDigest[16] := (T1 shl  8) or (T1 shr 24);
2791
    T1 := FDigest[12]; FDigest[12] := (T0 shl 14) or (T0 shr 18);
2792
    T0 := FDigest[ 9]; FDigest[ 9] := (T1 shl 13) or (T1 shr 19);
2793
    T1 := FDigest[11]; FDigest[11] := (T0 shl  2) or (T0 shr 30);
2794
    T0 := FDigest[ 4]; FDigest[ 4] := (T1 shl 10) or (T1 shr 22);
2795
    T1 := FDigest[ 3]; FDigest[ 3] := (T0 shl  6) or (T0 shr 26);
2796
    T0 := FDigest[15]; FDigest[15] := (T1 shl 24) or (T1 shr  8);
2797
    FDigest[ 7] := (T0 shl 28) or (T0 shr  4);
2798
 
2799
    // perform diffusion stage (THETA) + buffer injection stage (SIGMA)
2800
    T0 := FDigest[ 0];
2801
    T1 := FDigest[ 1];
2802
    T2 := FDigest[ 2];
2803
    T3 := FDigest[ 3];
2804
    FDigest[ 0] := FDigest[ 0] xor FDigest[ 1] xor FDigest[ 4] xor 1;
2805
    FDigest[ 1] := FDigest[ 1] xor FDigest[ 2] xor FDigest[ 5] xor PBufL[ 0];
2806
    FDigest[ 2] := FDigest[ 2] xor FDigest[ 3] xor FDigest[ 6] xor PBufL[ 1];
2807
    FDigest[ 3] := FDigest[ 3] xor FDigest[ 4] xor FDigest[ 7] xor PBufL[ 2];
2808
    FDigest[ 4] := FDigest[ 4] xor FDigest[ 5] xor FDigest[ 8] xor PBufL[ 3];
2809
    FDigest[ 5] := FDigest[ 5] xor FDigest[ 6] xor FDigest[ 9] xor PBufL[ 4];
2810
    FDigest[ 6] := FDigest[ 6] xor FDigest[ 7] xor FDigest[10] xor PBufL[ 5];
2811
    FDigest[ 7] := FDigest[ 7] xor FDigest[ 8] xor FDigest[11] xor PBufL[ 6];
2812
    FDigest[ 8] := FDigest[ 8] xor FDigest[ 9] xor FDigest[12] xor PBufL[ 7];
2813
    FDigest[ 9] := FDigest[ 9] xor FDigest[10] xor FDigest[13] xor PBufB[ 0];
2814
    FDigest[10] := FDigest[10] xor FDigest[11] xor FDigest[14] xor PBufB[ 1];
2815
    FDigest[11] := FDigest[11] xor FDigest[12] xor FDigest[15] xor PBufB[ 2];
2816
    FDigest[12] := FDigest[12] xor FDigest[13] xor FDigest[16] xor PBufB[ 3];
2817
    FDigest[13] := FDigest[13] xor FDigest[14] xor T0          xor PBufB[ 4];
2818
    FDigest[14] := FDigest[14] xor FDigest[15] xor T1          xor PBufB[ 5];
2819
    FDigest[15] := FDigest[15] xor FDigest[16] xor T2          xor PBufB[ 6];
2820
    FDigest[16] := FDigest[16] xor T0 xor T3                   xor PBufB[ 7];
2821
  end;
2822
  // move state to Digest buffer
2823
  FDigest[0] := FDigest[ 9];
2824
  FDigest[1] := FDigest[10];
2825
  FDigest[2] := FDigest[11];
2826
  FDigest[3] := FDigest[12];
2827
  FDigest[4] := FDigest[13];
2828
  FDigest[5] := FDigest[14];
2829
  FDigest[6] := FDigest[15];
2830
  FDigest[7] := FDigest[16];
2831
end;
2832
 
2833
procedure THash_Panama.DoTransform(Buffer: PLongArray);
2834
var
2835
  T0,T1,T2,T3 : LongWord;
2836
  PBufB,PTap0,PTap25: PLongArray;
2837
begin
2838
  // perform non-linearity stage (GAMMA)
2839
  T0 := FDigest[ 0];
2840
  T1 := FDigest[ 1];
2841
  FDigest[ 0] := FDigest[ 0] xor (FDigest[ 1] or not FDigest[ 2]);
2842
  FDigest[ 1] := FDigest[ 1] xor (FDigest[ 2] or not FDigest[ 3]);
2843
  FDigest[ 2] := FDigest[ 2] xor (FDigest[ 3] or not FDigest[ 4]);
2844
  FDigest[ 3] := FDigest[ 3] xor (FDigest[ 4] or not FDigest[ 5]);
2845
  FDigest[ 4] := FDigest[ 4] xor (FDigest[ 5] or not FDigest[ 6]);
2846
  FDigest[ 5] := FDigest[ 5] xor (FDigest[ 6] or not FDigest[ 7]);
2847
  FDigest[ 6] := FDigest[ 6] xor (FDigest[ 7] or not FDigest[ 8]);
2848
  FDigest[ 7] := FDigest[ 7] xor (FDigest[ 8] or not FDigest[ 9]);
2849
  FDigest[ 8] := FDigest[ 8] xor (FDigest[ 9] or not FDigest[10]);
2850
  FDigest[ 9] := FDigest[ 9] xor (FDigest[10] or not FDigest[11]);
2851
  FDigest[10] := FDigest[10] xor (FDigest[11] or not FDigest[12]);
2852
  FDigest[11] := FDigest[11] xor (FDigest[12] or not FDigest[13]);
2853
  FDigest[12] := FDigest[12] xor (FDigest[13] or not FDigest[14]);
2854
  FDigest[13] := FDigest[13] xor (FDigest[14] or not FDigest[15]);
2855
  FDigest[14] := FDigest[14] xor (FDigest[15] or not FDigest[16]);
2856
  FDigest[15] := FDigest[15] xor (FDigest[16] or not T0);
2857
  FDigest[16] := FDigest[16] xor (T0 or not T1);
2858
 
2859
  // perform bit-dispersion stage (PI)
2860
  T0 := FDigest[ 1];
2861
  T1 := FDigest[ 7]; FDigest[ 1] := (T1 shl  1) or (T1 shr 31);
2862
  T1 := FDigest[ 5]; FDigest[ 5] := (T0 shl 15) or (T0 shr 17);
2863
  T0 := FDigest[ 8]; FDigest[ 8] := (T1 shl  4) or (T1 shr 28);
2864
  T1 := FDigest[ 6]; FDigest[ 6] := (T0 shl 21) or (T0 shr 11);
2865
  T0 := FDigest[13]; FDigest[13] := (T1 shl 27) or (T1 shr  5);
2866
  T1 := FDigest[14]; FDigest[14] := (T0 shl  9) or (T0 shr 23);
2867
  T0 := FDigest[ 2]; FDigest[ 2] := (T1 shl  3) or (T1 shr 29);
2868
  T1 := FDigest[10]; FDigest[10] := (T0 shl 23) or (T0 shr  9);
2869
  T0 := FDigest[16]; FDigest[16] := (T1 shl  8) or (T1 shr 24);
2870
  T1 := FDigest[12]; FDigest[12] := (T0 shl 14) or (T0 shr 18);
2871
  T0 := FDigest[ 9]; FDigest[ 9] := (T1 shl 13) or (T1 shr 19);
2872
  T1 := FDigest[11]; FDigest[11] := (T0 shl  2) or (T0 shr 30);
2873
  T0 := FDigest[ 4]; FDigest[ 4] := (T1 shl 10) or (T1 shr 22);
2874
  T1 := FDigest[ 3]; FDigest[ 3] := (T0 shl  6) or (T0 shr 26);
2875
  T0 := FDigest[15]; FDigest[15] := (T1 shl 24) or (T1 shr  8);
2876
  FDigest[ 7] := (T0 shl 28) or (T0 shr  4);
2877
 
2878
  // LFSR emulation
2879
  PBufB  := @FLFSRBuffer[(FTap + 16) and 31];
2880
  FTap   := (FTap - 1) and 31;
2881
  PTap0  := @FLFSRBuffer[FTap];
2882
  PTap25 := @FLFSRBuffer[(FTap + 25) and 31];
2883
 
2884
  // update the LFSR buffer (LAMBDA_PUSH)
2885
  PTap25[ 0] := PTap25[ 0] xor PTap0[ 2];
2886
  PTap25[ 1] := PTap25[ 1] xor PTap0[ 3];
2887
  PTap25[ 2] := PTap25[ 2] xor PTap0[ 4];
2888
  PTap25[ 3] := PTap25[ 3] xor PTap0[ 5];
2889
  PTap25[ 4] := PTap25[ 4] xor PTap0[ 6];
2890
  PTap25[ 5] := PTap25[ 5] xor PTap0[ 7];
2891
  PTap25[ 6] := PTap25[ 6] xor PTap0[ 0];
2892
  PTap25[ 7] := PTap25[ 7] xor PTap0[ 1];
2893
  PTap0[ 0] := PTap0[ 0] xor Buffer[ 0];
2894
  PTap0[ 1] := PTap0[ 1] xor Buffer[ 1];
2895
  PTap0[ 2] := PTap0[ 2] xor Buffer[ 2];
2896
  PTap0[ 3] := PTap0[ 3] xor Buffer[ 3];
2897
  PTap0[ 4] := PTap0[ 4] xor Buffer[ 4];
2898
  PTap0[ 5] := PTap0[ 5] xor Buffer[ 5];
2899
  PTap0[ 6] := PTap0[ 6] xor Buffer[ 6];
2900
  PTap0[ 7] := PTap0[ 7] xor Buffer[ 7];
2901
 
2902
  // perform diffusion stage (THETA) + buffer injection stage (SIGMA)
2903
  T0 := FDigest[ 0];
2904
  T1 := FDigest[ 1];
2905
  T2 := FDigest[ 2];
2906
  T3 := FDigest[ 3];
2907
  FDigest[ 0] := FDigest[ 0] xor FDigest[ 1] xor FDigest[ 4] xor 1;
2908
  FDigest[ 1] := FDigest[ 1] xor FDigest[ 2] xor FDigest[ 5] xor Buffer[ 0];
2909
  FDigest[ 2] := FDigest[ 2] xor FDigest[ 3] xor FDigest[ 6] xor Buffer[ 1];
2910
  FDigest[ 3] := FDigest[ 3] xor FDigest[ 4] xor FDigest[ 7] xor Buffer[ 2];
2911
  FDigest[ 4] := FDigest[ 4] xor FDigest[ 5] xor FDigest[ 8] xor Buffer[ 3];
2912
  FDigest[ 5] := FDigest[ 5] xor FDigest[ 6] xor FDigest[ 9] xor Buffer[ 4];
2913
  FDigest[ 6] := FDigest[ 6] xor FDigest[ 7] xor FDigest[10] xor Buffer[ 5];
2914
  FDigest[ 7] := FDigest[ 7] xor FDigest[ 8] xor FDigest[11] xor Buffer[ 6];
2915
  FDigest[ 8] := FDigest[ 8] xor FDigest[ 9] xor FDigest[12] xor Buffer[ 7];
2916
 
2917
  FDigest[ 9] := FDigest[ 9] xor FDigest[10] xor FDigest[13] xor PBufB[ 0];
2918
  FDigest[10] := FDigest[10] xor FDigest[11] xor FDigest[14] xor PBufB[ 1];
2919
  FDigest[11] := FDigest[11] xor FDigest[12] xor FDigest[15] xor PBufB[ 2];
2920
  FDigest[12] := FDigest[12] xor FDigest[13] xor FDigest[16] xor PBufB[ 3];
2921
  FDigest[13] := FDigest[13] xor FDigest[14] xor T0          xor PBufB[ 4];
2922
  FDigest[14] := FDigest[14] xor FDigest[15] xor T1          xor PBufB[ 5];
2923
  FDigest[15] := FDigest[15] xor FDigest[16] xor T2          xor PBufB[ 6];
2924
  FDigest[16] := FDigest[16] xor T0          xor T3          xor PBufB[ 7];
2925
end;
2926
{$ENDIF}
2927
 
2928
// .THashBaseWhirlpool
2929
class function THashBaseWhirlpool.DigestSize: Integer;
2930
begin
2931
  Result := 64;
2932
end;
2933
 
2934
class function THashBaseWhirlpool.BlockSize: Integer;
2935
begin
2936
  Result := 64;
2937
end;
2938
 
2939
function THashBaseWhirlpool.Digest: PByteArray;
2940
begin
2941
  Result := @FDigest;
2942
end;
2943
 
2944
procedure THashBaseWhirlpool.DoDone;
2945
var
2946
  I: Integer;
2947
begin
2948
  if FPaddingByte = 0 then FPaddingByte := $80;
2949
  FBuffer[FBufferIndex] := FPaddingByte;
2950
  Inc(FBufferIndex);
2951
  if FBufferIndex > FBufferSize - 32 then
2952
  begin
2953
    FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
2954
    DoTransform(Pointer(FBuffer));
2955
    FBufferIndex := 0;
2956
  end;
2957
  FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
2958
  for I := 31 downto 0 do
2959
    FBuffer[63 - I] := PByteArray(@FCount)[I];
2960
  DoTransform(Pointer(FBuffer));
2961
end;
2962
 
2963
{$IFNDEF THashBaseWhirlpool_asm}
2964
procedure THashBaseWhirlpool.DoTransform(Buffer: PLongArray);
2965
type
2966
  PWhirlData = ^TWhirlData;
2967
  TWhirlData = array[0..15] of LongWord;
2968
  PWhirlTable = ^TWhirlTable;
2969
  TWhirlTable = array[0..7, 0..511] of LongWord;
2970
 
2971
  procedure Whirl(var L: TWhirlData; const K: TWhirlData; const T: PWhirlTable);
2972
  begin
2973
    L[0*2+0] := T[0, ((K[ 0] shl  1) and $1fe)] xor
2974
                T[1, ((K[14] shr  7) and $1fe)] xor
2975
                T[2, ((K[12] shr 15) and $1fe)] xor
2976
                T[3, ((K[10] shr 23) and $1fe)] xor
2977
                T[4, ((K[ 9] shl  1) and $1fe)] xor
2978
                T[5, ((K[ 7] shr  7) and $1fe)] xor
2979
                T[6, ((K[ 5] shr 15) and $1fe)] xor
2980
                T[7, ((K[ 3] shr 23) and $1fe)];
2981
    L[0*2+1] := T[0, ((K[ 0] shl  1) and $1fe)+1] xor
2982
                T[1, ((K[14] shr  7) and $1fe)+1] xor
2983
                T[2, ((K[12] shr 15) and $1fe)+1] xor
2984
                T[3, ((K[10] shr 23) and $1fe)+1] xor
2985
                T[4, ((K[ 9] shl  1) and $1fe)+1] xor
2986
                T[5, ((K[ 7] shr  7) and $1fe)+1] xor
2987
                T[6, ((K[ 5] shr 15) and $1fe)+1] xor
2988
                T[7, ((K[ 3] shr 23) and $1fe)+1];
2989
    L[1*2+0] := T[0, ((K[ 2] shl  1) and $1fe)] xor
2990
                T[1, ((K[ 0] shr  7) and $1fe)] xor
2991
                T[2, ((K[14] shr 15) and $1fe)] xor
2992
                T[3, ((K[12] shr 23) and $1fe)] xor
2993
                T[4, ((K[11] shl  1) and $1fe)] xor
2994
                T[5, ((K[ 9] shr  7) and $1fe)] xor
2995
                T[6, ((K[ 7] shr 15) and $1fe)] xor
2996
                T[7, ((K[ 5] shr 23) and $1fe)];
2997
    L[1*2+1] := T[0, ((K[ 2] shl  1) and $1fe)+1] xor
2998
                T[1, ((K[ 0] shr  7) and $1fe)+1] xor
2999
                T[2, ((K[14] shr 15) and $1fe)+1] xor
3000
                T[3, ((K[12] shr 23) and $1fe)+1] xor
3001
                T[4, ((K[11] shl  1) and $1fe)+1] xor
3002
                T[5, ((K[ 9] shr  7) and $1fe)+1] xor
3003
                T[6, ((K[ 7] shr 15) and $1fe)+1] xor
3004
                T[7, ((K[ 5] shr 23) and $1fe)+1];
3005
    L[2*2+0] := T[0, ((K[ 4] shl  1) and $1fe)] xor
3006
                T[1, ((K[ 2] shr  7) and $1fe)] xor
3007
                T[2, ((K[ 0] shr 15) and $1fe)] xor
3008
                T[3, ((K[14] shr 23) and $1fe)] xor
3009
                T[4, ((K[13] shl  1) and $1fe)] xor
3010
                T[5, ((K[11] shr  7) and $1fe)] xor
3011
                T[6, ((K[ 9] shr 15) and $1fe)] xor
3012
                T[7, ((K[ 7] shr 23) and $1fe)];
3013
    L[2*2+1] := T[0, ((K[ 4] shl  1) and $1fe)+1] xor
3014
                T[1, ((K[ 2] shr  7) and $1fe)+1] xor
3015
                T[2, ((K[ 0] shr 15) and $1fe)+1] xor
3016
                T[3, ((K[14] shr 23) and $1fe)+1] xor
3017
                T[4, ((K[13] shl  1) and $1fe)+1] xor
3018
                T[5, ((K[11] shr  7) and $1fe)+1] xor
3019
                T[6, ((K[ 9] shr 15) and $1fe)+1] xor
3020
                T[7, ((K[ 7] shr 23) and $1fe)+1];
3021
    L[3*2+0] := T[0, ((K[ 6] shl  1) and $1fe)] xor
3022
                T[1, ((K[ 4] shr  7) and $1fe)] xor
3023
                T[2, ((K[ 2] shr 15) and $1fe)] xor
3024
                T[3, ((K[ 0] shr 23) and $1fe)] xor
3025
                T[4, ((K[15] shl  1) and $1fe)] xor
3026
                T[5, ((K[13] shr  7) and $1fe)] xor
3027
                T[6, ((K[11] shr 15) and $1fe)] xor
3028
                T[7, ((K[ 9] shr 23) and $1fe)];
3029
    L[3*2+1] := T[0, ((K[ 6] shl  1) and $1fe)+1] xor
3030
                T[1, ((K[ 4] shr  7) and $1fe)+1] xor
3031
                T[2, ((K[ 2] shr 15) and $1fe)+1] xor
3032
                T[3, ((K[ 0] shr 23) and $1fe)+1] xor
3033
                T[4, ((K[15] shl  1) and $1fe)+1] xor
3034
                T[5, ((K[13] shr  7) and $1fe)+1] xor
3035
                T[6, ((K[11] shr 15) and $1fe)+1] xor
3036
                T[7, ((K[ 9] shr 23) and $1fe)+1];
3037
    L[4*2+0] := T[0, ((K[ 8] shl  1) and $1fe)] xor
3038
                T[1, ((K[ 6] shr  7) and $1fe)] xor
3039
                T[2, ((K[ 4] shr 15) and $1fe)] xor
3040
                T[3, ((K[ 2] shr 23) and $1fe)] xor
3041
                T[4, ((K[ 1] shl  1) and $1fe)] xor
3042
                T[5, ((K[15] shr  7) and $1fe)] xor
3043
                T[6, ((K[13] shr 15) and $1fe)] xor
3044
                T[7, ((K[11] shr 23) and $1fe)];
3045
    L[4*2+1] := T[0, ((K[ 8] shl  1) and $1fe)+1] xor
3046
                T[1, ((K[ 6] shr  7) and $1fe)+1] xor
3047
                T[2, ((K[ 4] shr 15) and $1fe)+1] xor
3048
                T[3, ((K[ 2] shr 23) and $1fe)+1] xor
3049
                T[4, ((K[ 1] shl  1) and $1fe)+1] xor
3050
                T[5, ((K[15] shr  7) and $1fe)+1] xor
3051
                T[6, ((K[13] shr 15) and $1fe)+1] xor
3052
                T[7, ((K[11] shr 23) and $1fe)+1];
3053
    L[5*2+0] := T[0, ((K[10] shl  1) and $1fe)] xor
3054
                T[1, ((K[ 8] shr  7) and $1fe)] xor
3055
                T[2, ((K[ 6] shr 15) and $1fe)] xor
3056
                T[3, ((K[ 4] shr 23) and $1fe)] xor
3057
                T[4, ((K[ 3] shl  1) and $1fe)] xor
3058
                T[5, ((K[ 1] shr  7) and $1fe)] xor
3059
                T[6, ((K[15] shr 15) and $1fe)] xor
3060
                T[7, ((K[13] shr 23) and $1fe)];
3061
    L[5*2+1] := T[0, ((K[10] shl  1) and $1fe)+1] xor
3062
                T[1, ((K[ 8] shr  7) and $1fe)+1] xor
3063
                T[2, ((K[ 6] shr 15) and $1fe)+1] xor
3064
                T[3, ((K[ 4] shr 23) and $1fe)+1] xor
3065
                T[4, ((K[ 3] shl  1) and $1fe)+1] xor
3066
                T[5, ((K[ 1] shr  7) and $1fe)+1] xor
3067
                T[6, ((K[15] shr 15) and $1fe)+1] xor
3068
                T[7, ((K[13] shr 23) and $1fe)+1];
3069
    L[6*2+0] := T[0, ((K[12] shl  1) and $1fe)] xor
3070
                T[1, ((K[10] shr  7) and $1fe)] xor
3071
                T[2, ((K[ 8] shr 15) and $1fe)] xor
3072
                T[3, ((K[ 6] shr 23) and $1fe)] xor
3073
                T[4, ((K[ 5] shl  1) and $1fe)] xor
3074
                T[5, ((K[ 3] shr  7) and $1fe)] xor
3075
                T[6, ((K[ 1] shr 15) and $1fe)] xor
3076
                T[7, ((K[15] shr 23) and $1fe)];
3077
    L[6*2+1] := T[0, ((K[12] shl  1) and $1fe)+1] xor
3078
                T[1, ((K[10] shr  7) and $1fe)+1] xor
3079
                T[2, ((K[ 8] shr 15) and $1fe)+1] xor
3080
                T[3, ((K[ 6] shr 23) and $1fe)+1] xor
3081
                T[4, ((K[ 5] shl  1) and $1fe)+1] xor
3082
                T[5, ((K[ 3] shr  7) and $1fe)+1] xor
3083
                T[6, ((K[ 1] shr 15) and $1fe)+1] xor
3084
                T[7, ((K[15] shr 23) and $1fe)+1];
3085
    L[7*2+0] := T[0, ((K[14] shl  1) and $1fe)] xor
3086
                T[1, ((K[12] shr  7) and $1fe)] xor
3087
                T[2, ((K[10] shr 15) and $1fe)] xor
3088
                T[3, ((K[ 8] shr 23) and $1fe)] xor
3089
                T[4, ((K[ 7] shl  1) and $1fe)] xor
3090
                T[5, ((K[ 5] shr  7) and $1fe)] xor
3091
                T[6, ((K[ 3] shr 15) and $1fe)] xor
3092
                T[7, ((K[ 1] shr 23) and $1fe)];
3093
    L[7*2+1] := T[0, ((K[14] shl  1) and $1fe)+1] xor
3094
                T[1, ((K[12] shr  7) and $1fe)+1] xor
3095
                T[2, ((K[10] shr 15) and $1fe)+1] xor
3096
                T[3, ((K[ 8] shr 23) and $1fe)+1] xor
3097
                T[4, ((K[ 7] shl  1) and $1fe)+1] xor
3098
                T[5, ((K[ 5] shr  7) and $1fe)+1] xor
3099
                T[6, ((K[ 3] shr 15) and $1fe)+1] xor
3100
                T[7, ((K[ 1] shr 23) and $1fe)+1];
3101
  end;
3102
 
3103
var
3104
  S,L,K: TWhirlData;
3105
  I: Integer;
3106
begin
3107
  Assert(not Odd(Whirlpool_Rounds));
3108
 
3109
  Move(FDigest, K, SizeOf(FDigest));
3110
  XORBuffers(FDigest, Buffer[0], SizeOf(FDigest), S);
3111
  // iterate over all rounds
3112
  for I := 0 to Whirlpool_Rounds div 2 - 1 do
3113
  begin
3114
    Whirl(L, K, FTableC);
3115
    L[0] := L[0] xor PLongArray(FTableR)[I*4+0];
3116
    L[1] := L[1] xor PLongArray(FTableR)[I*4+1];
3117
    Whirl(K, S, FTableC);
3118
    XORBuffers(L, K, SizeOf(S), S);
3119
 
3120
    Whirl(K, L, FTableC);
3121
    K[0] := K[0] xor PLongArray(FTableR)[I*4+2];
3122
    K[1] := K[1] xor PLongArray(FTableR)[I*4+3];
3123
    Whirl(L, S, FTableC);
3124
    XORBuffers(K, L, SizeOf(S), S);
3125
  end;
3126
  XORBuffers(S, Buffer[0], SizeOf(FDigest), S);
3127
  XORBuffers(S, FDigest, SizeOf(FDigest), FDigest);
3128
end;
3129
{$ENDIF}
3130
 
3131
// .THash_Whirlpool
3132
procedure THash_Whirlpool.DoInit;
3133
begin
3134
  FillChar(FDigest, SizeOf(FDigest), 0);
3135
  FTableC := @Whirlpool_C_U;
3136
  FTableR := @Whirlpool_RC_U
3137
end;
3138
 
3139
// .THash_Whirlpool1
3140
procedure THash_Whirlpool1.DoInit;
3141
begin
3142
  FillChar(FDigest, SizeOf(FDigest), 0);
3143
  FTableC := @Whirlpool_C_T;
3144
  FTableR := @Whirlpool_RC_T;
3145
end;
3146
 
3147
// .THash_Square
3148
class function THash_Square.DigestSize: Integer;
3149
begin
3150
  Result := 16;
3151
end;
3152
 
3153
class function THash_Square.BlockSize: Integer;
3154
begin
3155
  Result := 16;
3156
end;
3157
 
3158
function THash_Square.Digest: PByteArray;
3159
begin
3160
  Result := @FDigest;
3161
end;
3162
 
3163
procedure THash_Square.DoInit;
3164
begin
3165
  FillChar(FDigest, SizeOf(FDigest), 0);
3166
end;
3167
 
3168
procedure THash_Square.DoDone;
3169
var
3170
  I: Integer;
3171
begin
3172
  if FPaddingByte = 0 then FPaddingByte := $80;
3173
  FBuffer[FBufferIndex] := FPaddingByte;
3174
  Inc(FBufferIndex);
3175
  if FBufferIndex > FBufferSize - 8 then
3176
  begin
3177
    FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
3178
    DoTransform(Pointer(FBuffer));
3179
    FBufferIndex := 0;
3180
  end;
3181
  FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
3182
  for I := 7 downto 0 do
3183
    FBuffer[15 - I] := PByteArray(@FCount[0])[I];
3184
  DoTransform(Pointer(FBuffer));
3185
end;
3186
 
3187
{$IFNDEF THash_Square_asm}
3188
procedure THash_Square.DoTransform(Buffer: PLongArray);
3189
var
3190
  Key: array[0..8, 0..3] of LongWord;
3191
  A,B,C,D: LongWord;
3192
  AA,BB,CC,DD: LongWord;
3193
  I: Integer;
3194
begin
3195
{Build and expand the Key, Digest include the Key}
3196
  Key[0, 0] := FDigest[0];
3197
  Key[0, 1] := FDigest[1];
3198
  Key[0, 2] := FDigest[2];
3199
  Key[0, 3] := FDigest[3];
3200
  for I := 1 to 8 do
3201
  begin
3202
    Key[I, 0] := Key[I -1, 0] xor Key[I -1, 3] shr 8 xor Key[I -1, 3] shl 24 xor 1 shl (I - 1);
3203
    Key[I, 1] := Key[I -1, 1] xor Key[I, 0];
3204
    Key[I, 2] := Key[I -1, 2] xor Key[I, 1];
3205
    Key[I, 3] := Key[I -1, 3] xor Key[I, 2];
3206
 
3207
    Key[I -1, 0] := Square_PHIr[0, Key[I -1, 0]        and $FF] xor
3208
                    Square_PHIr[1, Key[I -1, 0] shr  8 and $FF] xor
3209
                    Square_PHIr[2, Key[I -1, 0] shr 16 and $FF] xor
3210
                    Square_PHIr[3, Key[I -1, 0] shr 24        ];
3211
    Key[I -1, 1] := Square_PHIr[0, Key[I -1, 1]        and $FF] xor
3212
                    Square_PHIr[1, Key[I -1, 1] shr  8 and $FF] xor
3213
                    Square_PHIr[2, Key[I -1, 1] shr 16 and $FF] xor
3214
                    Square_PHIr[3, Key[I -1, 1] shr 24        ];
3215
    Key[I -1, 2] := Square_PHIr[0, Key[I -1, 2]        and $FF] xor
3216
                    Square_PHIr[1, Key[I -1, 2] shr  8 and $FF] xor
3217
                    Square_PHIr[2, Key[I -1, 2] shr 16 and $FF] xor
3218
                    Square_PHIr[3, Key[I -1, 2] shr 24        ];
3219
    Key[I -1, 3] := Square_PHIr[0, Key[I -1, 3]        and $FF] xor
3220
                    Square_PHIr[1, Key[I -1, 3] shr  8 and $FF] xor
3221
                    Square_PHIr[2, Key[I -1, 3] shr 16 and $FF] xor
3222
                    Square_PHIr[3, Key[I -1, 3] shr 24        ];
3223
  end;
3224
{Encrypt begin here, same TCipher_Square.Encode}
3225
  A := Buffer[0] xor Key[0, 0];
3226
  B := Buffer[1] xor Key[0, 1];
3227
  C := Buffer[2] xor Key[0, 2];
3228
  D := Buffer[3] xor Key[0, 3];
3229
 
3230
  for I := 0 to 6 do
3231
  begin
3232
    AA := Square_TE[0, A        and $FF] xor
3233
          Square_TE[1, B        and $FF] xor
3234
          Square_TE[2, C        and $FF] xor
3235
          Square_TE[3, D        and $FF] xor Key[I + 1, 0];
3236
    BB := Square_TE[0, A shr  8 and $FF] xor
3237
          Square_TE[1, B shr  8 and $FF] xor
3238
          Square_TE[2, C shr  8 and $FF] xor
3239
          Square_TE[3, D shr  8 and $FF] xor Key[I + 1, 1];
3240
    CC := Square_TE[0, A shr 16 and $FF] xor
3241
          Square_TE[1, B shr 16 and $FF] xor
3242
          Square_TE[2, C shr 16 and $FF] xor
3243
          Square_TE[3, D shr 16 and $FF] xor Key[I + 1, 2];
3244
    DD := Square_TE[0, A shr 24        ] xor
3245
          Square_TE[1, B shr 24        ] xor
3246
          Square_TE[2, C shr 24        ] xor
3247
          Square_TE[3, D shr 24        ] xor Key[I + 1, 3];
3248
 
3249
    A := AA; B := BB; C := CC; D := DD;
3250
  end;
3251
 
3252
  FDigest[0] := Buffer[0] xor
3253
                Square_SEint[A        and $FF]        xor
3254
                Square_SEint[B        and $FF] shl  8 xor
3255
                Square_SEint[C        and $FF] shl 16 xor
3256
                Square_SEint[D        and $FF] shl 24 xor Key[8, 0];
3257
  FDigest[1] := Buffer[1] xor
3258
                Square_SEint[A shr  8 and $FF]        xor
3259
                Square_SEint[B shr  8 and $FF] shl  8 xor
3260
                Square_SEint[C shr  8 and $FF] shl 16 xor
3261
                Square_SEint[D shr  8 and $FF] shl 24 xor Key[8, 1];
3262
  FDigest[2] := Buffer[2] xor
3263
                Square_SEint[A shr 16 and $FF]        xor
3264
                Square_SEint[B shr 16 and $FF] shl  8 xor
3265
                Square_SEint[C shr 16 and $FF] shl 16 xor
3266
                Square_SEint[D shr 16 and $FF] shl 24 xor Key[8, 2];
3267
  FDigest[3] := Buffer[3] xor
3268
                Square_SEint[A shr 24        ]        xor
3269
                Square_SEint[B shr 24        ] shl  8 xor
3270
                Square_SEint[C shr 24        ] shl 16 xor
3271
                Square_SEint[D shr 24        ] shl 24 xor Key[8, 3];
3272
end;
3273
{$ENDIF}
3274
 
3275
// .THashBaseSnefru
3276
procedure THashBaseSnefru.SetSecurity_Level(Value: Integer);
3277
begin
3278
  if (Value < 2) or (Value > 8) then Value := 8;
3279
  FSecurity_Level := Value;
3280
end;
3281
 
3282
function THashBaseSnefru.Digest: PByteArray;
3283
begin
3284
  Result := @FDigest;
3285
end;
3286
 
3287
procedure THashBaseSnefru.DoInit;
3288
begin
3289
  FillChar(FDigest, SizeOf(FDigest), 0);
3290
  SetSecurity_Level(FSecurity_Level);
3291
end;
3292
 
3293
procedure THashBaseSnefru.DoDone;
3294
begin
3295
  if FBufferIndex > 0 then
3296
  begin
3297
    FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
3298
    DoTransform(Pointer(FBuffer));
3299
    FBufferIndex := 0;
3300
  end;
3301
  FillChar(FBuffer[FBufferIndex], FBufferSize - FBufferIndex, 0);
3302
  PLongWord(@FBuffer[FBufferSize - 8])^ := SwapLong(FCount[1]);
3303
  PLongWord(@FBuffer[FBufferSize - 4])^ := SwapLong(FCount[0]);
3304
  DoTransform(Pointer(FBuffer));
3305
  SwapLongBuffer(FDigest, FDigest, 8);
3306
end;
3307
 
3308
// .THash_Snefru128
3309
class function THash_Snefru128.DigestSize: Integer;
3310
begin
3311
  Result := 16;
3312
end;
3313
 
3314
class function THash_Snefru128.BlockSize: Integer;
3315
begin
3316
  Result := 48
3317
end;
3318
 
3319
{$IFNDEF THash_Snefru128_asm}
3320
procedure THash_Snefru128.DoTransform(Buffer: PLongArray);
3321
const
3322
  ShiftTable: array[0..3] of Integer = (16, 8, 16, 24);
3323
var
3324
  I,Index,ByteInWord,T,N,S,S0,S1: LongWord;
3325
  D,Box0,Box1: PLongArray;
3326
begin
3327
  D := @FDigest;
3328
  SwapLongBuffer(Buffer[0], D[4], 12);
3329
  Move(D[0], D[16], 16);
3330
  Box0 := @Snefru_Data[0];
3331
  Box1 := @Snefru_Data[1];
3332
  for Index := 0 to FSecurity_Level-1 do
3333
  begin
3334
    for ByteInWord := 0 to 3 do
3335
    begin
3336
      I := 0;
3337
      N := D[0];
3338
      while I < 16 do
3339
      begin
3340
        S0 := Box0[N and $FF];
3341
        T := (I +  1) and 15;    N := D[T] xor S0; D[T] := N;
3342
        T := (I + 15) and 15; D[T] := D[T] xor S0;
3343
        S1 := Box0[N and $FF];
3344
        T := (I +  2) and 15;    N := D[T] xor S1; D[T] := N;
3345
        T := (I + 16) and 15; D[T] := D[T] xor S1;
3346
        S0 := Box1[N and $FF];
3347
        T := (I +  3) and 15;    N := D[T] xor S0; D[T] := N;
3348
        T := (I + 17) and 15; D[T] := D[T] xor S0;
3349
        S1 := Box1[N and $FF];
3350
        T := (I +  4) and 15;    N := D[T] xor S1; D[T] := N;
3351
        T := (I + 18) and 15; D[T] := D[T] xor S1;
3352
        Inc(I, 4);
3353
      end;
3354
      T := ShiftTable[ByteInWord];
3355
      S := 32 - T;
3356
      for I := 0 to 15 do D[I] := D[I] shr T or D[I] shl S;
3357
    end;
3358
    Box0 := @Box0[512];
3359
    Box1 := @Box1[512];
3360
  end;
3361
  for I := 0 to 3 do D[I] := D[I + 16] xor D[15 - I];
3362
end;
3363
{$ENDIF}
3364
 
3365
// .THash_Snefru256
3366
class function THash_Snefru256.DigestSize: Integer;
3367
begin
3368
  Result := 32;
3369
end;
3370
 
3371
class function THash_Snefru256.BlockSize: Integer;
3372
begin
3373
  Result := 32
3374
end;
3375
 
3376
{$IFNDEF THash_Snefru256_asm}
3377
procedure THash_Snefru256.DoTransform(Buffer: PLongArray);
3378
const
3379
  ShiftTable: array[0..3] of Integer = (16, 8, 16, 24);
3380
var
3381
  I,Index,ByteInWord,T,N,S,S0,S1: LongWord;
3382
  D,Box0,Box1: PLongArray;
3383
begin
3384
  D := @FDigest;
3385
  SwapLongBuffer(Buffer[0], D[8], 8);
3386
  Move(D[0], D[16], 32);
3387
  Box0 := @Snefru_Data[0];
3388
  Box1 := @Snefru_Data[1];
3389
  for Index := 0 to FSecurity_Level-1 do
3390
  begin
3391
    for ByteInWord := 0 to 3 do
3392
    begin
3393
      I := 0;
3394
      N := D[0];
3395
      while I < 16 do
3396
      begin
3397
        S0 := Box0[N and $FF];
3398
        T := (I +  1) and 15;    N := D[T] xor S0; D[T] := N;
3399
        T := (I + 15) and 15; D[T] := D[T] xor S0;
3400
        S1 := Box0[N and $FF];
3401
        T := (I +  2) and 15;    N := D[T] xor S1; D[T] := N;
3402
        T := (I + 16) and 15; D[T] := D[T] xor S1;
3403
        S0 := Box1[N and $FF];
3404
        T := (I +  3) and 15;    N := D[T] xor S0; D[T] := N;
3405
        T := (I + 17) and 15; D[T] := D[T] xor S0;
3406
        S1 := Box1[N and $FF];
3407
        T := (I +  4) and 15;    N := D[T] xor S1; D[T] := N;
3408
        T := (I + 18) and 15; D[T] := D[T] xor S1;
3409
        Inc(I, 4);
3410
      end;
3411
      T := ShiftTable[ByteInWord];
3412
      S := 32 - T;
3413
      for I := 0 to 15 do D[I] := D[I] shr T or D[I] shl S;
3414
    end;
3415
    Box0 := @Box0[512];
3416
    Box1 := @Box1[512];
3417
  end;
3418
  for I := 0 to 7 do D[I] := D[I + 16] xor D[15 - I];
3419
end;
3420
{$ENDIF}
3421
 
3422
// .THashBaseSapphire
3423
class function THash_Sapphire.BlockSize: Integer;
3424
begin
3425
  Result := 1;
3426
end;
3427
 
3428
class function THash_Sapphire.DigestSize: Integer;
3429
begin
3430
  Result := 64;
3431
end;
3432
 
3433
function THash_Sapphire.Digest: PByteArray;
3434
begin
3435
  Result := @FDigest;
3436
end;
3437
 
3438
function THash_Sapphire.DigestStr(Format: TDECFormatClass = nil): Binary;
3439
var
3440
  Size: Integer;
3441
begin
3442
  if FDigestSize > 0 then Size := FDigestSize else Size := DigestSize;
3443
  Result := ValidFormat(Format).Encode(FDigest, Size);
3444
end;
3445
 
3446
procedure THash_Sapphire.DoInit;
3447
var
3448
  I: Integer;
3449
begin
3450
  FillChar(FDigest, SizeOf(FDigest), 0);
3451
  FRotor := 1;
3452
  FRatchet := 3;
3453
  FAvalanche := 5;
3454
  FPlain := 7;
3455
  FCipher := 11;
3456
  for I := 0 to 255 do FCards[I] := 255 - I;
3457
end;
3458
 
3459
procedure THash_Sapphire.DoDone;
3460
var
3461
  I: Integer;
3462
begin
3463
  for I := 255 downto 0 do Calc(I, 1);
3464
  for I := 0 to DigestSize -1 do
3465
  begin
3466
    Calc(#0#0, 1);
3467
    PByteArray(@FDigest)[I] := FCipher;
3468
  end;
3469
end;
3470
 
3471
{$IFNDEF THash_Sapphire_asm}
3472
procedure THash_Sapphire.Calc(const Data; DataSize: Integer);
3473
var
3474
  Cipher,Ratchet,Rotor,Plain,Avalanche,T: LongWord;
3475
  D: PByte;
3476
begin
3477
  D         := @Data;
3478
  Cipher    := FCipher;
3479
  Ratchet   := FRatchet;
3480
  Rotor     := FRotor;
3481
  Plain     := FPlain;
3482
  Avalanche := FAvalanche;
3483
  while DataSize > 0 do
3484
  begin
3485
    Dec(DataSize);
3486
    Ratchet := (Ratchet + FCards[Rotor]) and $FF;
3487
    Rotor := (Rotor + 1) and $FF;
3488
    T := FCards[Cipher];
3489
    FCards[Cipher] := FCards[Ratchet];
3490
    FCards[Ratchet] := FCards[Plain];
3491
    FCards[Plain] := FCards[Rotor];
3492
    FCards[Rotor] := T;
3493
    Avalanche := (Avalanche + FCards[T]) and $FF;
3494
    T := (FCards[Plain] + FCards[Cipher] + FCards[Avalanche]) and $FF;
3495
    Plain := D^; Inc(D);
3496
    Cipher := Plain xor FCards[FCards[T]] xor FCards[(FCards[Ratchet] + FCards[Rotor]) and $FF];
3497
  end;
3498
  FCipher    := Cipher;
3499
  FRatchet   := Ratchet;
3500
  FRotor     := Rotor;
3501
  FPlain     := Plain;
3502
  FAvalanche := Avalanche;
3503
end;
3504
{$ENDIF}
3505
 
3506
end.
3507
 
3508