Browse Source

RandomHash2: new candidate, still WIP

Herman Schoenfeld 6 years ago
parent
commit
adfe26be11

+ 1 - 6
src/core/UCrypto.pas

@@ -822,12 +822,7 @@ begin
   if Length(ResultSha256) <> 32 then SetLength(ResultSha256, 32);
   SetLength(LInput, plength);
   Move(p^, LInput[0], plength);
-
-  if AHasher.HasCachedHash AND BytesEqual(AHasher.PeekCachedHash.Header, LInput) then
-    LResult := AHasher.PopCachedHash.Hash
-  else
-    LResult := AHasher.Compute(LInput); //AHasher.Hash(LInput);
-
+  LResult := AHasher.Hash(LInput);
   Move(LResult[0], ResultSha256[Low(ResultSha256)], 32);
 end;
 

+ 324 - 0
src/core/UPoolMinerThreads.pas

@@ -786,145 +786,469 @@ end;
 { TCPUOpenSSLMinerThread }
 
 procedure TCPUOpenSSLMinerThread.BCExecute;
+
 Var
+
   ts : Cardinal;
+
   i,roundsToDo, LRoundsPerformed : Integer;
+
   nonce : Cardinal;
+
   baseRealTC,baseHashingTC,finalHashingTC : TTickCount;
+
   resultPoW : TRawBytes;
+
   LRoundJobNum : Integer;
+
   AuxStats : TMinerStats;
+
   dstep : Integer;
+
   LUseRandomHash : boolean;
+
   LRandomHasher : TRandomHashFast;
+
   LRandomHasher2 : TRandomHash2;
+
   LDisposables : TDisposables;
+
 begin
+
   DebugStep := '----------';
+
   AuxStats := CT_TMinerStats_NULL;
+
   nonce := 0;
+
   dstep := 0;
+
   LRandomHasher := LDisposables.AddObject( TRandomHashFast.Create ) as TRandomHashFast;
+
   LRandomHasher2 := LDisposables.AddObject( TRandomHash2.Create ) as TRandomHash2;
+
   Try
+
     while (Not Terminated) And (Not FCPUDeviceThread.Terminated) do begin
+
       Try
+
       sleep(1);
+
       dstep := 1;
+
       AuxStats := CT_TMinerStats_NULL;
+
       If (FCPUDeviceThread.Paused) then sleep(1)
+
       else begin
+
         dstep := 2;
+
         FLock.Acquire;
+
         try
+
           LUseRandomHash := TPoolMinerThread.UseRandomHash(FCurrentMinerValuesForWork.version);
+
           if (LUseRandomHash) then begin
+
             if FCurrentMinerValuesForWork.version < CT_PROTOCOL_5 then
+
               roundsToDo := 20
+
             else
+
               roundsToDo := 200;
+
           end else begin
+
             roundsToDo := 10000;
+
           end;
+
           baseRealTC := TPlatform.GetTickCount;
+
           If (FResetNOnce) then begin
+
             FResetNOnce := False;
+
             If (nonce<FMinNOnce) Or (nonce>FMaxNOnce) then begin
+
               nonce:=FMinNOnce;
+
             end;
+
           end;
+
           // Timestamp
+
           ts := UnivDateTimeToUnix(DateTime2UnivDateTime(now));
+
           if ts<=FCurrentMinerValuesForWork.timestamp then ts := FCurrentMinerValuesForWork.timestamp+1;
 
+
+
           If FDigestStreamMsg.Size>8 then begin
+
             if FCPUDeviceThread.FUseOpenSSLFunctions OR LUseRandomHash then begin
+
               FDigestStreamMsg.Position:=FDigestStreamMsg.Size - 8;
+
               FDigestStreamMsg.Write(ts,4);
+
               baseHashingTC:=TPlatform.GetTickCount;
+
               dstep := 4;
+
               LRoundJobNum := FJobNum;
+
               LRoundsPerformed := 0;
+
               for i := 1 to roundsToDo do begin
+
                 if LRoundJobNum <> FJobNum then
+
                   break;
+
                 FDigestStreamMsg.Position := FDigestStreamMsg.Size - 4;
+
                 FDigestStreamMsg.Write(nonce,4);
+
                 if LUseRandomHash then begin
+
                   if (FCurrentMinerValuesForWork.version < CT_PROTOCOL_5) then begin
+
                     // Note if i > 1 then FDigestStreamMsg.Memory == LHasher.NextHeader (needs to be for CPU optimization to work)
+
                     TCrypto.DoRandomHash(LRandomHasher,FDigestStreamMsg.Memory,FDigestStreamMsg.Size,resultPoW);
+
                   end else begin
+
                     // Note if > 1 then FDigestStreamMsg.Memory == LRandomHash2.CachedHashes[0].Header (needs to be for CPU optimization to work)
+
                     TCrypto.DoRandomHash2(LRandomHasher2, FDigestStreamMsg.Memory, FDigestStreamMsg.Size, resultPoW)
+
                   end
+
                 end else begin
+
                   TCrypto.DoDoubleSha256(FDigestStreamMsg.Memory,FDigestStreamMsg.Size,resultPoW);
+
                 end;
+
                 Inc(LRoundsPerformed);
+
                 if (TBaseType.BinStrComp(resultPoW,FCurrentMinerValuesForWork.target_pow)<0) then begin
+
                   if (Terminated) Or (FCPUDeviceThread.Terminated) then exit;
+
                   dstep := 5;
+
                   FLock.Release;
+
                   try
+
                     dstep := 6;
+
                     FCPUDeviceThread.FoundNOnce(FCurrentMinerValuesForWork, ts, nonce);
+
                     dstep := 7;
+
                   finally
+
                     FLock.Acquire;
+
                   end;
+
                   dstep := 8;
+
                 end;
+
                 if LUseRandomHash then begin
+
                   if (FCurrentMinerValuesForWork.version < CT_PROTOCOL_5) then begin
+
                     nonce := LRandomHasher.NextNonce;
+
                   end else begin
+
                     if LRandomHasher2.HasCachedHash then
+
                       nonce := LRandomHasher2.PeekCachedHash.Nonce   // use this to test verification speed: Random(FMaxNOnce - FMinNOnce) + FMinNOnce
+
                     else nonce := Random(FMaxNOnce - FMinNOnce) + FMinNOnce;
+
                   end;
+
                 end else if (nonce)<FMaxNOnce then inc(nonce) else nonce := FMinNOnce;
+
               end;
+
               finalHashingTC:=TPlatform.GetTickCount;
+
             end else begin
+
               baseHashingTC:=TPlatform.GetTickCount;
+
               for i := 1 to roundsToDo do begin
+
                 PascalCoinExecuteLastChunkAndDoSha256(FInternalSha256,FInternalChunk,FChangeTimestampAndNOnceBytePos,nonce,ts,resultPoW); // Note: RandomHash is handled above
+
                 if (TBaseType.BinStrComp(resultPoW,FCurrentMinerValuesForWork.target_pow)<0) then begin
+
                   if Terminated then exit;
+
                   FLock.Release;
+
                   try
+
                     FCPUDeviceThread.FoundNOnce(FCurrentMinerValuesForWork, ts,nonce);
+
                   finally
+
                     FLock.Acquire;
+
                   end;
+
                 end;
+
                 if (nonce)<FMaxNOnce then inc(nonce) else nonce := FMinNOnce;
+
               end;
+
               finalHashingTC:=TPlatform.GetTickCount;
+
             end;
+
             AuxStats.Miners:=FCPUDeviceThread.FCPUs;
+
             AuxStats.RoundsCount:=LRoundsPerformed;
+
             AuxStats.WorkingMillisecondsTotal:=TPlatform.GetTickCount - baseRealTC;
+
             AuxStats.WorkingMillisecondsHashing:= finalHashingTC - baseHashingTC;
+
             dstep := 9;
+
             FCPUDeviceThread.UpdateDeviceStats(AuxStats);
+
           end; // FDigestStreamMsg.size>8
+
         finally
+
           FLock.Release;
+
         end;
+
       end; // Not paused
+
       Except
+
         On E:Exception do begin
+
           TLog.NewLog(ltError,ClassName,'EXCEPTION step:'+IntToStr(dstep)+' ' +E.ClassName+':'+E.Message);
+
         end;
+
       end;
+
     end; // while
+
   Finally
+
     DebugStep := IntToStr(dstep);
+
   End;
+
 end;
 
+(*procedure TCPUOpenSSLMinerThread.BCExecute;
+
+type
+  TNonceResult = record
+    Nonce : UInt32;
+    PoW : TBytes;
+  end;
+
+Var
+  ts : Cardinal;
+  i, j, roundsToDo, LRoundsPerformed : Integer;
+  nonce : Cardinal;
+  baseRealTC,baseHashingTC,finalHashingTC : TTickCount;
+  resultPoW : TRawBytes;
+  LRoundJobNum : Integer;
+  AuxStats : TMinerStats;
+  dstep : Integer;
+  LUseRandomHash : boolean;
+  LRandomHasher : TRandomHashFast;
+  LRandomHasher2 : TRandomHash2;
+  LCachedItem : TRandomHash2.TCachedHash;
+  LNonceResult : TNonceResult;
+  LResultsToCheck : TList<TNonceResult>;
+  LDisposables : TDisposables;
+begin
+  DebugStep := '----------';
+  AuxStats := CT_TMinerStats_NULL;
+  nonce := 0;
+  dstep := 0;
+  LRandomHasher := LDisposables.AddObject( TRandomHashFast.Create ) as TRandomHashFast;
+  LRandomHasher2 := LDisposables.AddObject( TRandomHash2.Create ) as TRandomHash2;
+  LResultsToCheck := LDisposables.AddObject( TList<TNonceResult>.Create ) as TList<TNonceResult>;
+  Try
+    while (Not Terminated) And (Not FCPUDeviceThread.Terminated) do begin
+      Try
+      sleep(1);
+      dstep := 1;
+      AuxStats := CT_TMinerStats_NULL;
+      If (FCPUDeviceThread.Paused) then sleep(1)
+      else begin
+        dstep := 2;
+        FLock.Acquire;
+        try
+          LUseRandomHash := TPoolMinerThread.UseRandomHash(FCurrentMinerValuesForWork.version);
+          if (LUseRandomHash) then begin
+            if FCurrentMinerValuesForWork.version < CT_PROTOCOL_5 then
+              roundsToDo := 20
+            else
+              roundsToDo := 200;
+          end else begin
+            roundsToDo := 10000;
+          end;
+          baseRealTC := TPlatform.GetTickCount;
+          If (FResetNOnce) then begin
+            FResetNOnce := False;
+            If (nonce<FMinNOnce) Or (nonce>FMaxNOnce) then begin
+              nonce:=FMinNOnce;
+            end;
+          end;
+          // Timestamp
+          ts := UnivDateTimeToUnix(DateTime2UnivDateTime(now));
+          if ts<=FCurrentMinerValuesForWork.timestamp then ts := FCurrentMinerValuesForWork.timestamp+1;
+
+          If FDigestStreamMsg.Size>8 then begin
+            if FCPUDeviceThread.FUseOpenSSLFunctions OR LUseRandomHash then begin
+
+              // update timestamp
+              FDigestStreamMsg.Position:=FDigestStreamMsg.Size - 8;
+              FDigestStreamMsg.Write(ts,4);
+
+              baseHashingTC:=TPlatform.GetTickCount;
+              dstep := 4;
+              LRoundJobNum := FJobNum;
+              LRoundsPerformed := 0;
+              for i := 1 to roundsToDo do begin
+                LResultsToCheck.Clear;
+                if LRoundJobNum <> FJobNum then
+                  break;
+
+                // write nonce
+                FDigestStreamMsg.Position := FDigestStreamMsg.Size - 4;
+                FDigestStreamMsg.Write(nonce,4);
+
+                // perform the hash
+                if LUseRandomHash then begin
+                  if (FCurrentMinerValuesForWork.version < CT_PROTOCOL_5) then begin
+                    // Note if i > 1 then FDigestStreamMsg.Memory == LHasher.NextHeader (needs to be for CPU optimization to work)
+                    TCrypto.DoRandomHash(LRandomHasher,FDigestStreamMsg.Memory,FDigestStreamMsg.Size,resultPoW);
+                    LNonceResult.Nonce := nonce;
+                    LNonceResult.PoW := resultPoW;
+                    LResultsToCheck.Add(LNonceResult);
+                    Inc(LRoundsPerformed);
+                  end else begin
+                    // Note if > 1 then FDigestStreamMsg.Memory == LRandomHash2.CachedHashes[0].Header (needs to be for CPU optimization to work)
+                    TCrypto.DoRandomHash2(LRandomHasher2, FDigestStreamMsg.Memory, FDigestStreamMsg.Size, resultPoW);
+                    LNonceResult.Nonce := nonce;
+                    LNonceResult.PoW := resultPoW;
+                    //TFileTool.AppendText('d:/temp/nonceresult.txt', Format('Added Nonce: %d PoW: %s', [LNonceResult.Nonce, TCrypto.ToHexaString( LNonceResult.PoW )]));
+                    LResultsToCheck.Add(LNonceResult);
+                    Inc(LRoundsPerformed);
+                   // while LRandomHasher2.HasCachedHash do begin
+                   //   LCachedItem := LRandomHasher2.PopCachedHash;
+                   //   LNonceResult.Nonce := LCachedItem.Nonce;
+                   //   LNonceResult.PoW := LCachedItem.Hash;
+                   //   LResultsToCheck.Add(LNonceResult);
+                   //   Inc(LRoundsPerformed);
+                   // end;
+                  end
+                end else begin
+                  TCrypto.DoDoubleSha256(FDigestStreamMsg.Memory,FDigestStreamMsg.Size,resultPoW);
+                  LNonceResult.Nonce := nonce;
+                  LNonceResult.PoW := resultPoW;
+                  LResultsToCheck.Add(LNonceResult);
+                  Inc(LRoundsPerformed);
+                  TFileTool.AppendText('d:/temp/nonceresult.txt', Format('Added Nonce: %d PoW: %s', [LNonceResult.Nonce, TCrypto.ToHexaString( LNonceResult.PoW )]));
+                end;
+
+                // check results
+                for j:= 0 to LResultsToCheck.Count - 1 do begin
+                  TFileTool.AppendText('d:/temp/nonceresult.txt', Format('Checking Nonce: %d PoW: %s', [LResultsToCheck[j].Nonce, TCrypto.ToHexaString( LResultsToCheck[j].PoW )]));
+                  if (TBaseType.BinStrComp(LResultsToCheck[j].PoW,FCurrentMinerValuesForWork.target_pow)<0) then begin
+                    if (Terminated) Or (FCPUDeviceThread.Terminated) then exit;
+                    dstep := 5;
+                    FLock.Release;
+                    try
+                      dstep := 6;
+                      FCPUDeviceThread.FoundNOnce(FCurrentMinerValuesForWork, ts, LResultsToCheck[j].Nonce);
+                      dstep := 7;
+                    finally
+                      FLock.Acquire;
+                    end;
+                    dstep := 8;
+                  end;
+                end;
+
+                // select next nonce
+                if LUseRandomHash then begin
+
+                  if (FCurrentMinerValuesForWork.version < CT_PROTOCOL_5) then begin
+                    nonce := LRandomHasher.NextNonce;
+                  end else begin
+                    if LRandomHasher2.HasCachedHash then
+                      nonce := Random(FMaxNOnce - FMinNOnce) + FMinNOnce
+                    else nonce := Random(FMaxNOnce - FMinNOnce) + FMinNOnce;
+                  end;
+                end else if (nonce)<FMaxNOnce then inc(nonce) else nonce := FMinNOnce;
+              end;
+            end else begin
+              baseHashingTC:=TPlatform.GetTickCount;
+              for i := 1 to roundsToDo do begin
+                PascalCoinExecuteLastChunkAndDoSha256(FInternalSha256,FInternalChunk,FChangeTimestampAndNOnceBytePos,nonce,ts,resultPoW); // Note: RandomHash is handled above
+                if (TBaseType.BinStrComp(resultPoW,FCurrentMinerValuesForWork.target_pow)<0) then begin
+                  if Terminated then exit;
+                  FLock.Release;
+                  try
+                    FCPUDeviceThread.FoundNOnce(FCurrentMinerValuesForWork, ts,nonce);
+                  finally
+                    FLock.Acquire;
+                  end;
+                end;
+                if(nonce)<FMaxNOnce then inc(nonce) else nonce := FMinNOnce;
+              end;
+              finalHashingTC:=TPlatform.GetTickCount;
+            end;
+            AuxStats.Miners:=FCPUDeviceThread.FCPUs;
+            AuxStats.RoundsCount:=LRoundsPerformed;
+            AuxStats.WorkingMillisecondsTotal:=TPlatform.GetTickCount - baseRealTC;
+            AuxStats.WorkingMillisecondsHashing:= finalHashingTC - baseHashingTC;
+            dstep := 9;
+            FCPUDeviceThread.UpdateDeviceStats(AuxStats);
+          end; // FDigestStreamMsg.size>8
+        finally
+          FLock.Release;
+        end;
+      end; // Not paused
+      Except
+        On E:Exception do begin
+          TLog.NewLog(ltError,ClassName,'EXCEPTION step:'+IntToStr(dstep)+' ' +E.ClassName+':'+E.Message);
+        end;
+      end;
+    end; // while
+  Finally
+    DebugStep := IntToStr(dstep);
+  End;
+end;        *)
+
 constructor TCPUOpenSSLMinerThread.Create(CPUDeviceThread : TCPUDeviceThread);
 begin
   FCPUDeviceThread := CPUDeviceThread;

+ 22 - 34
src/core/URandomHash2.pas

@@ -1,4 +1,4 @@
-unit URandomHash2;
+unit URandomHash2;
 
 { Copyright (c) 2018 by Herman Schoenfeld
 
@@ -142,8 +142,8 @@ type
       function MemTransform6(const AChunk: TBytes): TBytes; inline;
       function MemTransform7(const AChunk: TBytes): TBytes; inline;
       function MemTransform8(const AChunk: TBytes): TBytes; inline;
-      function Expand(const AInput: TBytes; AExpansionFactor: Int32) : TBytes;
-      function Compress(const AInputs: TArray<TBytes>): TBytes; inline;
+      function Expand(const AInput: TBytes; AExpansionFactor: Int32; ASeed : UInt32) : TBytes;
+      function Compress(const AInputs: TArray<TBytes>; ASeed : UInt32): TBytes; inline;
       function SetLastDWordLE(const ABytes: TBytes; AValue: UInt32): TBytes; inline;
       function GetLastDWordLE(const ABytes: TBytes) : UInt32; inline;
       function ComputeVeneerRound(const ARoundOutputs : TArray<TBytes>) : TBytes; inline;
@@ -235,9 +235,12 @@ begin
 end;
 
 function TRandomHash2.ComputeVeneerRound(const ARoundOutputs : TArray<TBytes>) : TBytes;
+var
+  LSeed : UInt32;
 begin
-  // Final "veneer" round of RandomHash is a SHA2-256 of compresion of prior round outputs
-  Result := FHashAlg[0].ComputeBytes(Compress(ARoundOutputs)).GetBytes;
+  LSeed := GetLastDWordLE(ARoundOutputs[High(ARoundOutputs)]);
+  // Final "veneer" round of RandomHash is a SHA2-256 of compression of prior round outputs
+  Result := FHashAlg[0].ComputeBytes(Compress(ARoundOutputs, LSeed)).GetBytes;
 end;
 
 function TRandomHash2.Hash(const ABlockHeader: TBytes; ARound: Int32; out AFoundLastRound : Int32) : TArray<TBytes>;
@@ -295,16 +298,15 @@ begin
       end;
     end;
     // Compress the parent/neighbouring outputs to form this rounds input
-    LRoundInput := Compress( LRoundOutputs.ToArray );
+    LRoundInput := Compress( LRoundOutputs.ToArray, LGen.NextUInt32 );
   end;
 
-  // Select a random hash function and hash the input
-  // add this round output to outputs
+  // Select a random hash function and hash the input to find the output
   LHashFunc := FHashAlg[LGen.NextUInt32 mod NUM_HASH_ALGO];
   LOutput := LHashFunc.ComputeBytes(LRoundInput).GetBytes;
 
-  // Memory-expand the hash, add to output list and return
-  LOutput := Expand(LOutput, MAX_N - ARound);
+  // Memory-expand the output, add to output list and return output list
+  LOutput := Expand(LOutput, MAX_N - ARound, LGen.NextUInt32);
   LRoundOutputs.Add(LOutput);
   Result := LRoundOutputs.ToArray;
 
@@ -316,23 +318,21 @@ end;
 
 function TRandomHash2.SetLastDWordLE(const ABytes: TBytes;  AValue: UInt32): TBytes;
 var
-  LHeaderLength : Integer;
+  ABytesLength : Integer;
 begin
-  // NOTE: NONCE is last 4 bytes of header!
-
   // Clone the original header
   Result := Copy(ABytes);
 
   // If digest not big enough to contain a nonce, just return the clone
-  LHeaderLength := Length(ABytes);
-  if LHeaderLength < 4 then
+  ABytesLength := Length(ABytes);
+  if ABytesLength < 4 then
     exit;
 
   // Overwrite the nonce in little-endian
-  Result[LHeaderLength - 4] := Byte(AValue);
-  Result[LHeaderLength - 3] := (AValue SHR 8) AND 255;
-  Result[LHeaderLength - 2] := (AValue SHR 16) AND 255;
-  Result[LHeaderLength - 1] := (AValue SHR 24) AND 255;
+  Result[ABytesLength - 4] := Byte(AValue);
+  Result[ABytesLength - 3] := (AValue SHR 8) AND 255;
+  Result[ABytesLength - 2] := (AValue SHR 16) AND 255;
+  Result[ABytesLength - 1] := (AValue SHR 24) AND 255;
 end;
 
 function TRandomHash2.GetLastDWordLE(const ABytes: TBytes) : UInt32;
@@ -349,18 +349,8 @@ begin
            (ABytes[LLen - 1] SHL 24);
 end;
 
-(*function TRandomHash2.Checksum(const AInput: TBytes): UInt32;
-begin
-  Result := Checksum( TArray<TBytes>.Create( AInput ) );
-end;
-
-function TRandomHash2.Checksum(const AInput : TArray<TBytes>): UInt32;
-begin
-  // Checksum is the MurMur3 of the compression
-  Result := FMurmurHash3_x86_32.ComputeBytes(Compress(AInput)).GetUInt32;
-end;*)
 
-function TRandomHash2.Compress(const AInputs : TArray<TBytes>): TBytes;
+function TRandomHash2.Compress(const AInputs : TArray<TBytes>; ASeed : UInt32): TBytes;
 var
   i: Int32;
   LSeed: UInt32;
@@ -369,8 +359,7 @@ var
   LDisposables : TDisposables;
 begin
   SetLength(Result, 100);
-  LSeed :=  GetLastDWordLE(AInputs [High(AInputs)]);  // Seed using last 4 bytes
-  LGen := LDisposables.AddObject( TMersenne32.Create( LSeed ) ) as TMersenne32;
+  LGen := LDisposables.AddObject( TMersenne32.Create( ASeed ) ) as TMersenne32;
   for i := 0 to 99 do
   begin
     LSource := AInputs[LGen.NextUInt32 mod Length(AInputs)];
@@ -522,7 +511,7 @@ begin
     Result[i] := TBits.RotateRight8(AChunk[i], LChunkLength - i);
 end;
 
-function TRandomHash2.Expand(const AInput: TBytes; AExpansionFactor: Int32): TBytes;
+function TRandomHash2.Expand(const AInput: TBytes; AExpansionFactor: Int32; ASeed : UInt32): TBytes;
 var
   LSize, LBytesToAdd: Int32;
   LOutput, LNextChunk: TBytes;
@@ -530,7 +519,6 @@ var
   LGen: TMersenne32;
   LDisposables : TDisposables;
 begin
-  LSeed := GetLastDWordLE(AInput);
   LGen := LDisposables.AddObject( TMersenne32.Create (LSeed) ) as TMersenne32;
   LSize := Length(AInput) + (AExpansionFactor * M);
   LOutput := Copy(AInput);

+ 1 - 0
src/libraries/sphere10/UCommon.pas

@@ -1919,6 +1919,7 @@ begin
 end;
 
 { TFileStreamHelper }
+
 {$IFNDEF FPC}
 procedure TFileStreamHelper.WriteString(const AString : String);
 begin

+ 0 - 6
src/pascalcoin_miner.lpi

@@ -60,14 +60,8 @@
       <OtherUnitFiles Value="core;libraries\pasopencl;libraries\synapse;libraries\sphere10;libraries\hashlib4pascal;libraries\generics.collections;libraries\pascalcoin;libraries\paszlib"/>
       <UnitOutputDirectory Value="lib\$(TargetCPU)-$(TargetOS)"/>
     </SearchPaths>
-    <CodeGeneration>
-      <Optimizations>
-        <OptimizationLevel Value="4"/>
-      </Optimizations>
-    </CodeGeneration>
     <Linking>
       <Debugging>
-        <GenerateDebugInfo Value="False"/>
         <DebugInfoType Value="dsDwarf2Set"/>
         <UseValgrind Value="True"/>
       </Debugging>

+ 3 - 1
src/tests/URandomHash2.Tests.pas

@@ -55,11 +55,13 @@ begin
   LBuff := ParseBytes(DATA_BYTES);
   LHasher := LDisposables.AddObject( TRandomHash2.Create ) as TRandomHash2;
 
-  for i := 1 to 100 do begin
+  for i := 1 to 1000 do begin
     LBuff := LHasher.Hash(LBuff);
+    //TFileTool.AppendText('d:/temp/log.txt', Bytes2Hex(LBuff));
     while LHasher.HasCachedHash do begin
       LCachedHash := LHasher.PopCachedHash;
       AssertEquals(TRandomHash2.Compute(LCachedHash.Header), LCachedHash.Hash);
+      //TFileTool.AppendText('d:/temp/log.txt', '     ' +Bytes2Hex(LCachedHash.Hash));
     end;
   end;
 end;