Browse Source

Fix memory leaks and ci pipeline (#53)

* fix memory leaks

* Use Chocolatey for Windows Lazarus Installation

* Install OpenSSL via Chocolatey

* Use OpenSSL Light

* Install OpenSSL Light v1.1.1.20181020
Ugochukwu Mmaduekwe 3 days ago
parent
commit
97402c12c8

+ 41 - 36
.github/workflows/make.yml

@@ -1,9 +1,8 @@
----
 name: Make
 name: Make
 
 
 on:
 on:
   schedule:
   schedule:
-    - cron:  '0 0 1 * *'
+    - cron: '0 0 1 * *'
   push:
   push:
     branches:
     branches:
       - "**"
       - "**"
@@ -27,37 +26,43 @@ jobs:
           - windows-latest
           - windows-latest
 
 
     steps:
     steps:
-    - name: Checkout
-      uses: actions/checkout@v4
-      with:
-        submodules: true
-
-    - name: Build on Linux
-      if: runner.os == 'Linux'
-      shell: bash
-      run: |
-        set -xeuo pipefail
-        sudo bash -c 'apt-get update; apt-get install -y lazarus' >/dev/null
-        instantfpc -Fu/usr/lib/lazarus/*/components/lazutils \
-          -B '.github/workflows/make.pas'
-
-    - name: Build on Windows
-      if: runner.os == 'Windows'
-      shell: powershell
-      run: |
-        $ErrorActionPreference = 'stop'
-        Set-PSDebug -Strict
-        New-Variable -Option Constant -Name VAR -Value @{
-          Uri =
-            'https://icolo.dl.sourceforge.net/project/lazarus/Lazarus%20Windows%2064%20bits/Lazarus%204.0/lazarus-4.0-fpc-3.2.2-win64.exe?viasf=1'
-          OutFile = (New-TemporaryFile).FullName + '.exe'
-        }
-        Invoke-WebRequest @VAR
-        & $VAR.OutFile.Replace('Temp', 'Temp\.') /SP- /VERYSILENT /NORESTART `
-          /SUPPRESSMSGBOXES | Out-Null
-        $Env:PATH+=';C:\Lazarus'
-        (Get-Command 'lazbuild').Source | Out-Host
-        $Env:PATH+=';C:\Lazarus\fpc\3.2.2\bin\x86_64-win64'
-        (Get-Command 'instantfpc').Source | Out-Host
-        instantfpc -FuC:\Lazarus\components\lazutils `
-          -B '.github/workflows/make.pas'
+      - name: Checkout
+        uses: actions/checkout@v4
+        with:
+          submodules: true
+
+      - name: Build on Linux
+        if: runner.os == 'Linux'
+        shell: bash
+        run: |
+          set -xeuo pipefail
+          sudo bash -c 'apt-get update; apt-get install -y lazarus' >/dev/null
+          instantfpc -Fu/usr/lib/lazarus/*/components/lazutils \
+            -B '.github/workflows/make.pas'
+
+      - name: Build on Windows
+        if: runner.os == 'Windows'
+        shell: powershell
+        run: |
+          $ErrorActionPreference = 'stop'
+          Set-PSDebug -Strict
+
+          Write-Host "Installing Lazarus and OpenSSL 1.1 via Chocolatey..."
+          choco upgrade chocolatey -y
+          choco install lazarus -y
+          choco install openssl.light --version=1.1.1.20181020 -y
+
+          Write-Host "Verifying installed packages..."
+          choco list
+
+          # Lazarus installs to C:\Lazarus by default
+          # Add Lazarus and OpenSSL paths for instantfpc
+          $env:Path += ';C:\Lazarus;C:\Lazarus\fpc\3.2.2\bin\x86_64-win64;C:\ProgramData\chocolatey\lib\openssl.light\tools'
+
+          Write-Host "Checking lazbuild and instantfpc availability..."
+          Get-Command lazbuild
+          Get-Command instantfpc
+
+          Write-Host "Building make.pas..."
+          instantfpc -FuC:\Lazarus\components\lazutils `
+            -B '.github/workflows/make.pas'

+ 2 - 0
CryptoLib/src/Interfaces/ClpIECC.pas

@@ -271,6 +271,8 @@ type
 
 
     function ThreeTimes(): IECPoint;
     function ThreeTimes(): IECPoint;
 
 
+    function Clone: IECPoint;
+
     function Equals(const other: IECPoint): Boolean;
     function Equals(const other: IECPoint): Boolean;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt; {$ENDIF DELPHI}
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt; {$ENDIF DELPHI}
     function ToString(): String;
     function ToString(): String;

+ 1 - 1
CryptoLib/src/Math/EC/Abc/ClpTnaf.pas

@@ -519,7 +519,7 @@ begin
 
 
   System.SetLength(pu, UInt32(System.Length(alphaTnaf) + 1) shr 1);
   System.SetLength(pu, UInt32(System.Length(alphaTnaf) + 1) shr 1);
 
 
-  pu[0] := p;
+  pu[0] := p.Clone() as IAbstractF2mPoint;
 
 
   precompLen := UInt32(System.Length(alphaTnaf));
   precompLen := UInt32(System.Length(alphaTnaf));
 
 

+ 0 - 27
CryptoLib/src/Math/EC/ClpECAlgorithms.pas

@@ -394,11 +394,6 @@ begin
   result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ,
   result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ,
     preCompNegQ, wnafQ);
     preCompNegQ, wnafQ);
 
 
-  infoP.PreComp := Nil; // Review
-  infoP.PreCompNeg := Nil; // Review
-  infoQ.PreComp := Nil; // Review
-  infoQ.PreCompNeg := Nil; // Review
-
 end;
 end;
 
 
 class function TECAlgorithms.ImplShamirsTrickWNaf(const p: IECPoint;
 class function TECAlgorithms.ImplShamirsTrickWNaf(const p: IECPoint;
@@ -435,10 +430,6 @@ begin
   then
   then
   begin
   begin
     result := ImplShamirsTrickFixedPoint(p, k, q, l);
     result := ImplShamirsTrickFixedPoint(p, k, q, l);
-    infoP.PreComp := Nil; // Review
-    infoP.PreCompNeg := Nil; // Review
-    infoQ.PreComp := Nil; // Review
-    infoQ.PreCompNeg := Nil; // Review
     Exit;
     Exit;
   end;
   end;
 
 
@@ -486,10 +477,6 @@ begin
 
 
   result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ,
   result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ,
     preCompNegQ, wnafQ);
     preCompNegQ, wnafQ);
-  infoP.PreComp := Nil; // Review
-  infoP.PreCompNeg := Nil; // Review
-  infoQ.PreComp := Nil; // Review
-  infoQ.PreCompNeg := Nil; // Review
 end;
 end;
 
 
 class function TECAlgorithms.ImplShamirsTrickWNaf(const preCompP,
 class function TECAlgorithms.ImplShamirsTrickWNaf(const preCompP,
@@ -642,13 +629,6 @@ begin
   end;
   end;
 
 
   result := ImplSumOfMultiplies(negs, infos, wnafs);
   result := ImplSumOfMultiplies(negs, infos, wnafs);
-
-  for i := System.Low(infos) to System.High(infos) do
-  begin
-    infos[i].PreComp := Nil; // Review
-    infos[i].PreCompNeg := Nil; // Review
-  end;
-
 end;
 end;
 
 
 class function TECAlgorithms.ImplSumOfMultiplies
 class function TECAlgorithms.ImplSumOfMultiplies
@@ -684,13 +664,6 @@ begin
   end;
   end;
 
 
   result := ImplSumOfMultiplies(negs, infos, wnafs);
   result := ImplSumOfMultiplies(negs, infos, wnafs);
-
-  for i := System.Low(infos) to System.High(infos) do
-  begin
-    infos[i].PreComp := Nil; // Review
-    infos[i].PreCompNeg := Nil; // Review
-  end;
-
 end;
 end;
 
 
 class function TECAlgorithms.ImplSumOfMultiplies
 class function TECAlgorithms.ImplSumOfMultiplies

+ 84 - 6
CryptoLib/src/Math/EC/ClpECC.pas

@@ -44,6 +44,10 @@ uses
   ClpTnaf,
   ClpTnaf,
   ClpValidityPreCompInfo,
   ClpValidityPreCompInfo,
   ClpIValidityPreCompInfo,
   ClpIValidityPreCompInfo,
+  ClpIWNafPreCompInfo,
+  ClpIEndoPreCompInfo,
+  ClpIWTauNafPreCompInfo,
+  ClpIFixedPointPreCompInfo,
   ClpIECC,
   ClpIECC,
   ClpIFiniteField,
   ClpIFiniteField,
   ClpIPreCompInfo;
   ClpIPreCompInfo;
@@ -722,6 +726,8 @@ type
     constructor Create(const points: TCryptoLibGenericArray<IECPoint>;
     constructor Create(const points: TCryptoLibGenericArray<IECPoint>;
       off, len: Int32);
       off, len: Int32);
 
 
+    destructor Destroy; override;
+
     function Lookup(index: Int32): IECPoint; override;
     function Lookup(index: Int32): IECPoint; override;
     function LookupVar(index: Int32): IECPoint; override;
     function LookupVar(index: Int32): IECPoint; override;
 
 
@@ -744,6 +750,8 @@ type
     constructor Create(const outer: IECCurve; const table: TCryptoLibByteArray;
     constructor Create(const outer: IECCurve; const table: TCryptoLibByteArray;
       Size: Int32);
       Size: Int32);
 
 
+      destructor Destroy; override;
+
     function Lookup(index: Int32): IECPoint; override;
     function Lookup(index: Int32): IECPoint; override;
     function LookupVar(index: Int32): IECPoint; override;
     function LookupVar(index: Int32): IECPoint; override;
 
 
@@ -781,6 +789,8 @@ type
     constructor Create(const outer: IF2mCurve;
     constructor Create(const outer: IF2mCurve;
       const table: TCryptoLibInt64Array; Size: Int32);
       const table: TCryptoLibInt64Array; Size: Int32);
 
 
+    destructor Destroy; override;
+
     function Lookup(index: Int32): IECPoint; override;
     function Lookup(index: Int32): IECPoint; override;
     function LookupVar(index: Int32): IECPoint; override;
     function LookupVar(index: Int32): IECPoint; override;
 
 
@@ -1222,6 +1232,8 @@ type
 
 
     function ThreeTimes(): IECPoint; virtual;
     function ThreeTimes(): IECPoint; virtual;
 
 
+    function Clone(): IECPoint; virtual;
+
     function Equals(const other: IECPoint): Boolean; reintroduce;
     function Equals(const other: IECPoint): Boolean; reintroduce;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
     function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt;
 {$ENDIF DELPHI}override;
 {$ENDIF DELPHI}override;
@@ -2993,6 +3005,21 @@ end;
 
 
 function TECCurve.Precompute(const point: IECPoint; const name: String;
 function TECCurve.Precompute(const point: IECPoint; const name: String;
   const callback: IPreCompCallback): IPreCompInfo;
   const callback: IPreCompCallback): IPreCompInfo;
+
+function IsHeavy(const info: IPreCompInfo): Boolean;
+var
+  wnaf: IWNafPreCompInfo;
+  wtnaf: IWTauNafPreCompInfo;
+  endo: IEndoPreCompInfo;
+  fixed: IFixedPointPreCompInfo;
+begin
+  Result :=
+    Supports(info, IWNafPreCompInfo, wnaf) or
+    Supports(info, IWTauNafPreCompInfo, wtnaf) or
+    Supports(info, IEndoPreCompInfo, endo) or
+    Supports(info, IFixedPointPreCompInfo, fixed);
+end;
+
 var
 var
   table: TDictionary<String, IPreCompInfo>;
   table: TDictionary<String, IPreCompInfo>;
   existing: IPreCompInfo;
   existing: IPreCompInfo;
@@ -3012,10 +3039,10 @@ begin
 
 
     result := callback.Precompute(existing);
     result := callback.Precompute(existing);
 
 
-    if (result <> existing) then
-    begin
-      table.AddOrSetValue(name, result);
-    end;
+   if (result <> existing) and ((existing <> Nil) or (not IsHeavy(result))) then
+   begin
+     table.AddOrSetValue(name, result);
+   end;
 
 
   finally
   finally
     FLock.Release;
     FLock.Release;
@@ -3718,6 +3745,13 @@ begin
   result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false);
   result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false);
 end;
 end;
 
 
+destructor TDefaultLookupTable.Destroy;
+begin
+  Fm_outer := nil;
+  Fm_table := nil;
+  inherited;
+end;
+
 function TDefaultLookupTable.GetSize: Int32;
 function TDefaultLookupTable.GetSize: Int32;
 begin
 begin
   result := Fm_size;
   result := Fm_size;
@@ -3804,6 +3838,14 @@ begin
   result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false);
   result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false);
 end;
 end;
 
 
+
+destructor TDefaultF2mLookupTable.Destroy;
+begin
+  Fm_outer := nil;
+  Fm_table := nil;
+  inherited;
+end;
+
 function TDefaultF2mLookupTable.GetSize: Int32;
 function TDefaultF2mLookupTable.GetSize: Int32;
 begin
 begin
   result := Fm_size;
   result := Fm_size;
@@ -4084,12 +4126,23 @@ begin
 end;
 end;
 
 
 destructor TECPoint.Destroy;
 destructor TECPoint.Destroy;
+var
+  Key: string;
 begin
 begin
-  TSetWeakRef.SetWeakReference(@Fm_curve, Nil);
-  Fm_preCompTable.Free;
+  TSetWeakRef.SetWeakReference(@Fm_curve, nil);
+
+  if Assigned(Fm_preCompTable) then
+  begin
+    for Key in Fm_preCompTable.Keys do
+      Fm_preCompTable[Key] := nil;
+
+    Fm_preCompTable.Free;
+  end;
+
   inherited Destroy;
   inherited Destroy;
 end;
 end;
 
 
+
 class constructor TECPoint.ECPoint;
 class constructor TECPoint.ECPoint;
 begin
 begin
   System.SetLength(FEMPTY_ZS, 0);
   System.SetLength(FEMPTY_ZS, 0);
@@ -4400,6 +4453,18 @@ begin
   result := Normalize().Detach();
   result := Normalize().Detach();
 end;
 end;
 
 
+function TECPoint.Clone: IECPoint;
+var
+ baseNorm: IECPoint;
+begin
+  baseNorm := Self.Normalize();
+  Result := Fm_curve.CreatePoint(
+          baseNorm.XCoord.ToBigInteger,
+          baseNorm.YCoord.ToBigInteger,
+          baseNorm.IsCompressed
+        );
+end;
+
 { TF2mPoint }
 { TF2mPoint }
 
 
 constructor TF2mPoint.Create(const curve: IECCurve;
 constructor TF2mPoint.Create(const curve: IECCurve;
@@ -6703,6 +6768,19 @@ begin
   FPoints := Copy(points, off, len);
   FPoints := Copy(points, off, len);
 end;
 end;
 
 
+destructor TSimpleLookupTable.Destroy;
+var
+  i: Integer;
+begin
+  if Assigned(FPoints) then
+  begin
+    for i := 0 to Length(FPoints) - 1 do
+      FPoints[i] := nil;
+    FPoints := nil;
+  end;
+  inherited;
+end;
+
 function TSimpleLookupTable.GetSize: Int32;
 function TSimpleLookupTable.GetSize: Int32;
 begin
 begin
   result := System.Length(FPoints);
   result := System.Length(FPoints);

+ 1 - 1
CryptoLib/src/Math/EC/ClpECCompUtilities.pas

@@ -1041,7 +1041,7 @@ begin
       curPreCompLen := iniPreCompLen;
       curPreCompLen := iniPreCompLen;
       if (curPreCompLen = 0) then
       if (curPreCompLen = 0) then
       begin
       begin
-        PreComp[0] := Fm_p;
+        PreComp[0] := Fm_p.Clone();
         curPreCompLen := 1;
         curPreCompLen := 1;
       end;
       end;
 
 

+ 9 - 0
CryptoLib/src/Math/EC/Endo/ClpEndoPreCompInfo.pas

@@ -43,6 +43,8 @@ type
 
 
   public
   public
 
 
+    destructor Destroy; override;
+
     property Endomorphism: IECEndomorphism read GetEndomorphism
     property Endomorphism: IECEndomorphism read GetEndomorphism
       write SetEndomorphism;
       write SetEndomorphism;
     property MappedPoint: IECPoint read GetMappedPoint write SetMappedPoint;
     property MappedPoint: IECPoint read GetMappedPoint write SetMappedPoint;
@@ -52,6 +54,13 @@ implementation
 
 
 { TEndoPreCompInfo }
 { TEndoPreCompInfo }
 
 
+destructor TEndoPreCompInfo.Destroy;
+begin
+  FEndomorphism := nil;
+  FMappedPoint := nil;
+  inherited;
+end;
+
 function TEndoPreCompInfo.GetEndomorphism: IECEndomorphism;
 function TEndoPreCompInfo.GetEndomorphism: IECEndomorphism;
 begin
 begin
   result := FEndomorphism;
   result := FEndomorphism;

+ 8 - 0
CryptoLib/src/Math/EC/Multiplier/ClpFixedPointPreCompInfo.pas

@@ -64,6 +64,7 @@ type
 
 
   public
   public
     constructor Create();
     constructor Create();
+    destructor Destroy; override;
     property Offset: IECPoint read GetOffset write SetOffset;
     property Offset: IECPoint read GetOffset write SetOffset;
     property LookupTable: IECLookupTable read GetLookupTable
     property LookupTable: IECLookupTable read GetLookupTable
       write SetLookupTable;
       write SetLookupTable;
@@ -81,6 +82,13 @@ begin
   Fm_width := -1;
   Fm_width := -1;
 end;
 end;
 
 
+destructor TFixedPointPreCompInfo.Destroy;
+begin
+  Fm_offset := nil;
+  Fm_lookupTable := nil;
+  inherited;
+end;
+
 function TFixedPointPreCompInfo.GetLookupTable: IECLookupTable;
 function TFixedPointPreCompInfo.GetLookupTable: IECLookupTable;
 begin
 begin
   Result := Fm_lookupTable;
   Result := Fm_lookupTable;

+ 6 - 12
CryptoLib/src/Math/EC/Multiplier/ClpMultipliers.pas

@@ -201,7 +201,7 @@ type
 implementation
 implementation
 
 
 uses
 uses
-  ClpECAlgorithms; // included here to avoid circular dependency :)
+  ClpECAlgorithms;
 
 
 { TAbstractECMultiplier }
 { TAbstractECMultiplier }
 
 
@@ -466,9 +466,6 @@ begin
 
 
   result := R;
   result := R;
 
 
-  info.preComp := Nil; // Review
-  info.preCompNeg := Nil; // Review
-
 end;
 end;
 
 
 { TWTauNafMultiplier }
 { TWTauNafMultiplier }
@@ -534,8 +531,6 @@ begin
   end;
   end;
   result := q;
   result := q;
 
 
-  pre.preComp := Nil; // Review
-
 end;
 end;
 
 
 function TWTauNafMultiplier.MultiplyWTnaf(const p: IAbstractF2mPoint;
 function TWTauNafMultiplier.MultiplyWTnaf(const p: IAbstractF2mPoint;
@@ -606,12 +601,11 @@ var
   tempResult: IWTauNafPreCompInfo;
   tempResult: IWTauNafPreCompInfo;
 begin
 begin
 
 
-  // Review uncomment
-  // if (Supports(existing, IWTauNafPreCompInfo)) then
-  // begin
-  // result := existing;
-  // Exit;
-  // end;
+   if (Supports(existing, IWTauNafPreCompInfo)) then
+   begin
+     result := existing;
+     Exit;
+   end;
 
 
   tempResult := TWTauNafPreCompInfo.Create();
   tempResult := TWTauNafPreCompInfo.Create();
   tempResult.preComp := TTnaf.GetPreComp(Fm_p, Fm_a);
   tempResult.preComp := TTnaf.GetPreComp(Fm_p, Fm_a);

+ 25 - 0
CryptoLib/src/Math/EC/Multiplier/ClpWNafPreCompInfo.pas

@@ -87,6 +87,7 @@ type
   public
   public
 
 
     constructor Create();
     constructor Create();
+    destructor Destroy; override;
     property PreComp: TCryptoLibGenericArray<IECPoint> read GetPreComp
     property PreComp: TCryptoLibGenericArray<IECPoint> read GetPreComp
       write SetPreComp;
       write SetPreComp;
     property PreCompNeg: TCryptoLibGenericArray<IECPoint> read GetPreCompNeg
     property PreCompNeg: TCryptoLibGenericArray<IECPoint> read GetPreCompNeg
@@ -126,6 +127,30 @@ begin
   result := t;
   result := t;
 end;
 end;
 
 
+destructor TWNafPreCompInfo.Destroy;
+var
+  i: Integer;
+begin
+  if Assigned(FPreComp) then
+  begin
+    for i := 0 to Length(FPreComp) - 1 do
+      FPreComp[i] := nil;
+    FPreComp := nil;
+  end;
+
+  if Assigned(FPreCompNeg) then
+  begin
+    for i := 0 to Length(FPreCompNeg) - 1 do
+      FPreCompNeg[i] := nil;
+    FPreCompNeg := nil;
+  end;
+
+  FTwice := nil;
+
+  inherited;
+end;
+
+
 function TWNafPreCompInfo.GetConfWidth: Int32;
 function TWNafPreCompInfo.GetConfWidth: Int32;
 begin
 begin
   result := FConfWidth;
   result := FConfWidth;

+ 15 - 0
CryptoLib/src/Math/EC/Multiplier/ClpWTauNafPreCompInfo.pas

@@ -50,6 +50,8 @@ type
     Fm_preComp: TCryptoLibGenericArray<IAbstractF2mPoint>;
     Fm_preComp: TCryptoLibGenericArray<IAbstractF2mPoint>;
 
 
   public
   public
+    destructor Destroy; override;
+
     property PreComp: TCryptoLibGenericArray<IAbstractF2mPoint> read GetPreComp
     property PreComp: TCryptoLibGenericArray<IAbstractF2mPoint> read GetPreComp
       write SetPreComp;
       write SetPreComp;
   end;
   end;
@@ -58,6 +60,19 @@ implementation
 
 
 { TWTauNafPreCompInfo }
 { TWTauNafPreCompInfo }
 
 
+destructor TWTauNafPreCompInfo.Destroy;
+var
+  i: Integer;
+begin
+  if Assigned(Fm_preComp) then
+  begin
+    for i := 0 to Length(Fm_preComp) - 1 do
+      Fm_preComp[i] := nil;
+    Fm_preComp := nil;
+  end;
+  inherited;
+end;
+
 function TWTauNafPreCompInfo.GetPreComp
 function TWTauNafPreCompInfo.GetPreComp
   : TCryptoLibGenericArray<IAbstractF2mPoint>;
   : TCryptoLibGenericArray<IAbstractF2mPoint>;
 begin
 begin