Browse Source

add keccak support in HashLib.

Ugochukwu Mmaduekwe 7 years ago
parent
commit
42d237cf29

+ 43 - 18
src/libraries/hashlib4pascal/HlpHashFactory.pas

@@ -370,6 +370,11 @@ type
       class function CreateSHA3_384(): IHash; static;
       class function CreateSHA3_512(): IHash; static;
 
+      class function CreateKeccak_224(): IHash; static;
+      class function CreateKeccak_256(): IHash; static;
+      class function CreateKeccak_384(): IHash; static;
+      class function CreateKeccak_512(): IHash; static;
+
       class function CreateBlake2B(const config: IBlake2BConfig = Nil)
         : IHash; static;
 
@@ -684,49 +689,49 @@ class function THashFactory.TCrypto.CreateHaval(a_rounds: THashRounds;
   a_hash_size: THashSize): IHash;
 begin
   case a_rounds of
-    hrRounds3:
+    THashRounds.hrRounds3:
       case a_hash_size of
-        hsHashSize128:
+        THashSize.hsHashSize128:
           Result := CreateHaval_3_128();
-        hsHashSize160:
+        THashSize.hsHashSize160:
           Result := CreateHaval_3_160();
-        hsHashSize192:
+        THashSize.hsHashSize192:
           Result := CreateHaval_3_192();
-        hsHashSize224:
+        THashSize.hsHashSize224:
           Result := CreateHaval_3_224();
-        hsHashSize256:
+        THashSize.hsHashSize256:
           Result := CreateHaval_3_256();
       else
         raise EArgumentHashLibException.CreateRes(@SInvalidHavalHashSize);
       end;
 
-    hrRounds4:
+    THashRounds.hrRounds4:
       case a_hash_size of
-        hsHashSize128:
+        THashSize.hsHashSize128:
           Result := CreateHaval_4_128();
-        hsHashSize160:
+        THashSize.hsHashSize160:
           Result := CreateHaval_4_160();
-        hsHashSize192:
+        THashSize.hsHashSize192:
           Result := CreateHaval_4_192();
-        hsHashSize224:
+        THashSize.hsHashSize224:
           Result := CreateHaval_4_224();
-        hsHashSize256:
+        THashSize.hsHashSize256:
           Result := CreateHaval_4_256();
       else
         raise EArgumentHashLibException.CreateRes(@SInvalidHavalHashSize);
       end;
 
-    hrRounds5:
+    THashRounds.hrRounds5:
       case a_hash_size of
-        hsHashSize128:
+        THashSize.hsHashSize128:
           Result := CreateHaval_5_128();
-        hsHashSize160:
+        THashSize.hsHashSize160:
           Result := CreateHaval_5_160();
-        hsHashSize192:
+        THashSize.hsHashSize192:
           Result := CreateHaval_5_192();
-        hsHashSize224:
+        THashSize.hsHashSize224:
           Result := CreateHaval_5_224();
-        hsHashSize256:
+        THashSize.hsHashSize256:
           Result := CreateHaval_5_256();
       else
         raise EArgumentHashLibException.CreateRes(@SInvalidHavalHashSize);
@@ -927,6 +932,26 @@ begin
   Result := TSHA3_512.Create();
 end;
 
+class function THashFactory.TCrypto.CreateKeccak_224: IHash;
+begin
+  Result := TKeccak_224.Create();
+end;
+
+class function THashFactory.TCrypto.CreateKeccak_256: IHash;
+begin
+  Result := TKeccak_256.Create();
+end;
+
+class function THashFactory.TCrypto.CreateKeccak_384: IHash;
+begin
+  Result := TKeccak_384.Create();
+end;
+
+class function THashFactory.TCrypto.CreateKeccak_512: IHash;
+begin
+  Result := TKeccak_512.Create();
+end;
+
 class function THashFactory.TCrypto.CreateBlake2B(const config
   : IBlake2BConfig): IHash;
 begin

+ 2 - 0
src/libraries/hashlib4pascal/HlpHashRounds.pas

@@ -5,7 +5,9 @@ unit HlpHashRounds;
 interface
 
 type
+{$SCOPEDENUMS ON}
   THashRounds = (hrRounds3 = 3, hrRounds4 = 4, hrRounds5 = 5, hrRounds8 = 8);
+{$SCOPEDENUMS OFF}
 
 implementation
 

+ 2 - 0
src/libraries/hashlib4pascal/HlpHashSize.pas

@@ -5,9 +5,11 @@ unit HlpHashSize;
 interface
 
 type
+{$SCOPEDENUMS ON}
   THashSize = (hsHashSize128 = 16, hsHashSize160 = 20, hsHashSize192 = 24,
     hsHashSize224 = 28, hsHashSize256 = 32, hsHashSize384 = 48,
     hsHashSize512 = 64);
+{$SCOPEDENUMS OFF}
 
 implementation
 

+ 166 - 15
src/libraries/hashlib4pascal/HlpSHA3.pas

@@ -5,9 +5,11 @@ unit HlpSHA3;
 interface
 
 uses
-{$IFDEF DELPHI2010}
-  SysUtils, // to get rid of compiler hint "not inlined" on Delphi 2010.
-{$ENDIF DELPHI2010}
+{$IFDEF HAS_UNITSCOPE}
+  System.SysUtils,
+{$ELSE}
+  SysUtils,
+{$ENDIF HAS_UNITSCOPE}
   HlpBits,
 {$IFDEF DELPHI}
   HlpHashBuffer,
@@ -21,12 +23,21 @@ uses
   HlpHashSize,
   HlpHashLibTypes;
 
+resourcestring
+  SInvalidHashMode = 'Only "[%s]" HashModes are Supported';
+
 type
   TSHA3 = class abstract(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
 
+  type
+{$SCOPEDENUMS ON}
+    THashMode = (hmKeccak = $1, hmSHA3 = $6);
+{$SCOPEDENUMS OFF}
   strict protected
+
     Fm_state: THashLibUInt64Array;
     FHashSize, FBlockSize: Int32;
+    FHashMode: THashMode;
 
     (*
       {$REGION 'Consts'}
@@ -45,6 +56,7 @@ type
 
       {$ENDREGION}
     *)
+    function GetName: String; override;
     constructor Create(a_hash_size: THashSize);
 
     procedure Finish(); override;
@@ -97,6 +109,46 @@ type
     function Clone(): IHash; override;
   end;
 
+type
+
+  TKeccak_224 = class sealed(TSHA3)
+
+  public
+
+    constructor Create();
+    function Clone(): IHash; override;
+  end;
+
+type
+
+  TKeccak_256 = class sealed(TSHA3)
+
+  public
+
+    constructor Create();
+    function Clone(): IHash; override;
+  end;
+
+type
+
+  TKeccak_384 = class sealed(TSHA3)
+
+  public
+
+    constructor Create();
+    function Clone(): IHash; override;
+  end;
+
+type
+
+  TKeccak_512 = class sealed(TSHA3)
+
+  public
+
+    constructor Create();
+    function Clone(): IHash; override;
+  end;
+
 implementation
 
 { TSHA3 }
@@ -120,7 +172,7 @@ begin
   buffer_pos := Fm_buffer.Pos;
   block := Fm_buffer.GetBytesZeroPadded();
 
-  block[buffer_pos] := $6;
+  block[buffer_pos] := Int32(FHashMode);
   block[FBlockSize - 1] := block[FBlockSize - 1] xor $80;
 
   TransformBlock(PByte(block), System.Length(block), 0);
@@ -133,13 +185,28 @@ begin
 
 end;
 
+function TSHA3.GetName: String;
+begin
+  case FHashMode of
+    TSHA3.THashMode.hmKeccak:
+      Result := Format('%s_%u', ['TKeccak', Self.HashSize * 8]);
+    TSHA3.THashMode.hmSHA3:
+      Result := Self.ClassName;
+  else
+    begin
+      raise EArgumentInvalidHashLibException.CreateResFmt(@SInvalidHashMode,
+        ['hmKeccak, hmSHA3']);
+    end;
+  end;
+end;
+
 function TSHA3.GetResult: THashLibByteArray;
 begin
 
-  System.SetLength(result, FHashSize);
+  System.SetLength(Result, FHashSize);
 
-  TConverters.le64_copy(PUInt64(Fm_state), 0, PByte(result), 0,
-    System.Length(result));
+  TConverters.le64_copy(PUInt64(Fm_state), 0, PByte(Result), 0,
+    System.Length(Result));
 
 end;
 
@@ -2796,13 +2863,14 @@ begin
   HashInstance.Fm_state := System.Copy(Fm_state);
   HashInstance.Fm_buffer := Fm_buffer.Clone();
   HashInstance.Fm_processed_bytes := Fm_processed_bytes;
-  result := HashInstance as IHash;
-  result.BufferSize := BufferSize;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
 end;
 
 constructor TSHA3_224.Create;
 begin
   Inherited Create(THashSize.hsHashSize224);
+  FHashMode := THashMode.hmSHA3;
 end;
 
 { TSHA3_256 }
@@ -2815,13 +2883,14 @@ begin
   HashInstance.Fm_state := System.Copy(Fm_state);
   HashInstance.Fm_buffer := Fm_buffer.Clone();
   HashInstance.Fm_processed_bytes := Fm_processed_bytes;
-  result := HashInstance as IHash;
-  result.BufferSize := BufferSize;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
 end;
 
 constructor TSHA3_256.Create;
 begin
   Inherited Create(THashSize.hsHashSize256);
+  FHashMode := THashMode.hmSHA3;
 end;
 
 { TSHA3_384 }
@@ -2834,13 +2903,14 @@ begin
   HashInstance.Fm_state := System.Copy(Fm_state);
   HashInstance.Fm_buffer := Fm_buffer.Clone();
   HashInstance.Fm_processed_bytes := Fm_processed_bytes;
-  result := HashInstance as IHash;
-  result.BufferSize := BufferSize;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
 end;
 
 constructor TSHA3_384.Create;
 begin
   Inherited Create(THashSize.hsHashSize384);
+  FHashMode := THashMode.hmSHA3;
 end;
 
 { TSHA3_512 }
@@ -2853,13 +2923,94 @@ begin
   HashInstance.Fm_state := System.Copy(Fm_state);
   HashInstance.Fm_buffer := Fm_buffer.Clone();
   HashInstance.Fm_processed_bytes := Fm_processed_bytes;
-  result := HashInstance as IHash;
-  result.BufferSize := BufferSize;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
 end;
 
 constructor TSHA3_512.Create;
 begin
   Inherited Create(THashSize.hsHashSize512);
+  FHashMode := THashMode.hmSHA3;
+end;
+
+{ TKeccak_224 }
+
+function TKeccak_224.Clone(): IHash;
+var
+  HashInstance: TKeccak_224;
+begin
+  HashInstance := TKeccak_224.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
+constructor TKeccak_224.Create;
+begin
+  Inherited Create(THashSize.hsHashSize224);
+  FHashMode := THashMode.hmKeccak;
+end;
+
+{ TKeccak_256 }
+
+function TKeccak_256.Clone(): IHash;
+var
+  HashInstance: TKeccak_256;
+begin
+  HashInstance := TKeccak_256.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
+constructor TKeccak_256.Create;
+begin
+  Inherited Create(THashSize.hsHashSize256);
+  FHashMode := THashMode.hmKeccak;
+end;
+
+{ TKeccak_384 }
+
+function TKeccak_384.Clone(): IHash;
+var
+  HashInstance: TKeccak_384;
+begin
+  HashInstance := TKeccak_384.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
+constructor TKeccak_384.Create;
+begin
+  Inherited Create(THashSize.hsHashSize384);
+  FHashMode := THashMode.hmKeccak;
+end;
+
+{ TKeccak_512 }
+
+function TKeccak_512.Clone(): IHash;
+var
+  HashInstance: TKeccak_512;
+begin
+  HashInstance := TKeccak_512.Create();
+  HashInstance.Fm_state := System.Copy(Fm_state);
+  HashInstance.Fm_buffer := Fm_buffer.Clone();
+  HashInstance.Fm_processed_bytes := Fm_processed_bytes;
+  Result := HashInstance as IHash;
+  Result.BufferSize := BufferSize;
+end;
+
+constructor TKeccak_512.Create;
+begin
+  Inherited Create(THashSize.hsHashSize512);
+  FHashMode := THashMode.hmKeccak;
 end;
 
 end.