diff --git a/.github/workflows/make.yml b/.github/workflows/make.yml index 869cf55d..ea026e6c 100644 --- a/.github/workflows/make.yml +++ b/.github/workflows/make.yml @@ -1,9 +1,8 @@ ---- name: Make on: schedule: - - cron: '0 0 1 * *' + - cron: '0 0 1 * *' push: branches: - "**" @@ -27,37 +26,43 @@ jobs: - windows-latest 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' diff --git a/CryptoLib/src/Interfaces/ClpIECC.pas b/CryptoLib/src/Interfaces/ClpIECC.pas index 89aa383b..7276e7d1 100644 --- a/CryptoLib/src/Interfaces/ClpIECC.pas +++ b/CryptoLib/src/Interfaces/ClpIECC.pas @@ -271,6 +271,8 @@ interface function ThreeTimes(): IECPoint; + function Clone: IECPoint; + function Equals(const other: IECPoint): Boolean; function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt; {$ENDIF DELPHI} function ToString(): String; diff --git a/CryptoLib/src/Math/EC/Abc/ClpTnaf.pas b/CryptoLib/src/Math/EC/Abc/ClpTnaf.pas index 0b21dc4a..700389ca 100644 --- a/CryptoLib/src/Math/EC/Abc/ClpTnaf.pas +++ b/CryptoLib/src/Math/EC/Abc/ClpTnaf.pas @@ -519,7 +519,7 @@ class function TTnaf.GetPreComp(const p: IAbstractF2mPoint; a: ShortInt) System.SetLength(pu, UInt32(System.Length(alphaTnaf) + 1) shr 1); - pu[0] := p; + pu[0] := p.Clone() as IAbstractF2mPoint; precompLen := UInt32(System.Length(alphaTnaf)); diff --git a/CryptoLib/src/Math/EC/ClpECAlgorithms.pas b/CryptoLib/src/Math/EC/ClpECAlgorithms.pas index eee35d59..f811dcca 100644 --- a/CryptoLib/src/Math/EC/ClpECAlgorithms.pas +++ b/CryptoLib/src/Math/EC/ClpECAlgorithms.pas @@ -394,11 +394,6 @@ class function TECAlgorithms.ImplShamirsTrickWNaf(const endomorphism result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ); - infoP.PreComp := Nil; // Review - infoP.PreCompNeg := Nil; // Review - infoQ.PreComp := Nil; // Review - infoQ.PreCompNeg := Nil; // Review - end; class function TECAlgorithms.ImplShamirsTrickWNaf(const p: IECPoint; @@ -435,10 +430,6 @@ class function TECAlgorithms.ImplShamirsTrickWNaf(const p: IECPoint; then begin result := ImplShamirsTrickFixedPoint(p, k, q, l); - infoP.PreComp := Nil; // Review - infoP.PreCompNeg := Nil; // Review - infoQ.PreComp := Nil; // Review - infoQ.PreCompNeg := Nil; // Review Exit; end; @@ -486,10 +477,6 @@ class function TECAlgorithms.ImplShamirsTrickWNaf(const p: IECPoint; result := ImplShamirsTrickWNaf(preCompP, preCompNegP, wnafP, preCompQ, preCompNegQ, wnafQ); - infoP.PreComp := Nil; // Review - infoP.PreCompNeg := Nil; // Review - infoQ.PreComp := Nil; // Review - infoQ.PreCompNeg := Nil; // Review end; class function TECAlgorithms.ImplShamirsTrickWNaf(const preCompP, @@ -642,13 +629,6 @@ class function TECAlgorithms.ImplSumOfMultiplies(const endomorphism end; 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; class function TECAlgorithms.ImplSumOfMultiplies @@ -684,13 +664,6 @@ class function TECAlgorithms.ImplSumOfMultiplies end; 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; class function TECAlgorithms.ImplSumOfMultiplies diff --git a/CryptoLib/src/Math/EC/ClpECC.pas b/CryptoLib/src/Math/EC/ClpECC.pas index 747af272..03c377a4 100644 --- a/CryptoLib/src/Math/EC/ClpECC.pas +++ b/CryptoLib/src/Math/EC/ClpECC.pas @@ -44,6 +44,10 @@ interface ClpTnaf, ClpValidityPreCompInfo, ClpIValidityPreCompInfo, + ClpIWNafPreCompInfo, + ClpIEndoPreCompInfo, + ClpIWTauNafPreCompInfo, + ClpIFixedPointPreCompInfo, ClpIECC, ClpIFiniteField, ClpIPreCompInfo; @@ -722,6 +726,8 @@ TSimpleLookupTable = class abstract(TAbstractECLookupTable, constructor Create(const points: TCryptoLibGenericArray; off, len: Int32); + destructor Destroy; override; + function Lookup(index: Int32): IECPoint; override; function LookupVar(index: Int32): IECPoint; override; @@ -744,6 +750,8 @@ TDefaultLookupTable = class(TAbstractECLookupTable, IDefaultLookupTable) constructor Create(const outer: IECCurve; const table: TCryptoLibByteArray; Size: Int32); + destructor Destroy; override; + function Lookup(index: Int32): IECPoint; override; function LookupVar(index: Int32): IECPoint; override; @@ -781,6 +789,8 @@ TDefaultF2mLookupTable = class(TAbstractECLookupTable, IDefaultF2mLookupTable) constructor Create(const outer: IF2mCurve; const table: TCryptoLibInt64Array; Size: Int32); + destructor Destroy; override; + function Lookup(index: Int32): IECPoint; override; function LookupVar(index: Int32): IECPoint; override; @@ -1222,6 +1232,8 @@ TValidityCallback = class(TInterfacedObject, IPreCompCallback, function ThreeTimes(): IECPoint; virtual; + function Clone(): IECPoint; virtual; + function Equals(const other: IECPoint): Boolean; reintroduce; function GetHashCode(): {$IFDEF DELPHI}Int32; {$ELSE}PtrInt; {$ENDIF DELPHI}override; @@ -2993,6 +3005,21 @@ procedure TECCurve.SetMultiplier(const Value: IECMultiplier); function TECCurve.Precompute(const point: IECPoint; const name: String; 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 table: TDictionary; existing: IPreCompInfo; @@ -3012,10 +3039,10 @@ function TECCurve.Precompute(const point: IECPoint; const name: String; 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 FLock.Release; @@ -3718,6 +3745,13 @@ function TDefaultLookupTable.CreatePoint(const x, y: TCryptoLibByteArray) result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false); end; +destructor TDefaultLookupTable.Destroy; +begin + Fm_outer := nil; + Fm_table := nil; + inherited; +end; + function TDefaultLookupTable.GetSize: Int32; begin result := Fm_size; @@ -3804,6 +3838,14 @@ function TDefaultF2mLookupTable.CreatePoint(const x, y: TCryptoLibInt64Array) result := Fm_outer.CreateRawPoint(XFieldElement, YFieldElement, false); end; + +destructor TDefaultF2mLookupTable.Destroy; +begin + Fm_outer := nil; + Fm_table := nil; + inherited; +end; + function TDefaultF2mLookupTable.GetSize: Int32; begin result := Fm_size; @@ -4084,12 +4126,23 @@ function TECPoint.CreateScaledPoint(const sx, sy: IECFieldElement): IECPoint; end; destructor TECPoint.Destroy; +var + Key: string; 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; end; + class constructor TECPoint.ECPoint; begin System.SetLength(FEMPTY_ZS, 0); @@ -4400,6 +4453,18 @@ function TECPoint.GetDetachedPoint: IECPoint; result := Normalize().Detach(); 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 } constructor TF2mPoint.Create(const curve: IECCurve; @@ -6703,6 +6768,19 @@ constructor TSimpleLookupTable.Create(const points FPoints := Copy(points, off, len); 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; begin result := System.Length(FPoints); diff --git a/CryptoLib/src/Math/EC/ClpECCompUtilities.pas b/CryptoLib/src/Math/EC/ClpECCompUtilities.pas index c1d53e98..bdd255d3 100644 --- a/CryptoLib/src/Math/EC/ClpECCompUtilities.pas +++ b/CryptoLib/src/Math/EC/ClpECCompUtilities.pas @@ -1041,7 +1041,7 @@ function TWNafUtilities.TWNafCallback.Precompute(const existing: IPreCompInfo) curPreCompLen := iniPreCompLen; if (curPreCompLen = 0) then begin - PreComp[0] := Fm_p; + PreComp[0] := Fm_p.Clone(); curPreCompLen := 1; end; diff --git a/CryptoLib/src/Math/EC/Endo/ClpEndoPreCompInfo.pas b/CryptoLib/src/Math/EC/Endo/ClpEndoPreCompInfo.pas index 0be0075f..9dc41348 100644 --- a/CryptoLib/src/Math/EC/Endo/ClpEndoPreCompInfo.pas +++ b/CryptoLib/src/Math/EC/Endo/ClpEndoPreCompInfo.pas @@ -43,6 +43,8 @@ TEndoPreCompInfo = class sealed(TInterfacedObject, IPreCompInfo, public + destructor Destroy; override; + property Endomorphism: IECEndomorphism read GetEndomorphism write SetEndomorphism; property MappedPoint: IECPoint read GetMappedPoint write SetMappedPoint; @@ -52,6 +54,13 @@ implementation { TEndoPreCompInfo } +destructor TEndoPreCompInfo.Destroy; +begin + FEndomorphism := nil; + FMappedPoint := nil; + inherited; +end; + function TEndoPreCompInfo.GetEndomorphism: IECEndomorphism; begin result := FEndomorphism; diff --git a/CryptoLib/src/Math/EC/Multiplier/ClpFixedPointPreCompInfo.pas b/CryptoLib/src/Math/EC/Multiplier/ClpFixedPointPreCompInfo.pas index 3618f386..59cf190e 100644 --- a/CryptoLib/src/Math/EC/Multiplier/ClpFixedPointPreCompInfo.pas +++ b/CryptoLib/src/Math/EC/Multiplier/ClpFixedPointPreCompInfo.pas @@ -64,6 +64,7 @@ TFixedPointPreCompInfo = class(TInterfacedObject, IPreCompInfo, public constructor Create(); + destructor Destroy; override; property Offset: IECPoint read GetOffset write SetOffset; property LookupTable: IECLookupTable read GetLookupTable write SetLookupTable; @@ -81,6 +82,13 @@ constructor TFixedPointPreCompInfo.Create; Fm_width := -1; end; +destructor TFixedPointPreCompInfo.Destroy; +begin + Fm_offset := nil; + Fm_lookupTable := nil; + inherited; +end; + function TFixedPointPreCompInfo.GetLookupTable: IECLookupTable; begin Result := Fm_lookupTable; diff --git a/CryptoLib/src/Math/EC/Multiplier/ClpMultipliers.pas b/CryptoLib/src/Math/EC/Multiplier/ClpMultipliers.pas index adb34c1e..b3f1eddd 100644 --- a/CryptoLib/src/Math/EC/Multiplier/ClpMultipliers.pas +++ b/CryptoLib/src/Math/EC/Multiplier/ClpMultipliers.pas @@ -201,7 +201,7 @@ TWTauNafCallback = class(TInterfacedObject, IPreCompCallback, implementation uses - ClpECAlgorithms; // included here to avoid circular dependency :) + ClpECAlgorithms; { TAbstractECMultiplier } @@ -466,9 +466,6 @@ function TWNafL2RMultiplier.MultiplyPositive(const p: IECPoint; result := R; - info.preComp := Nil; // Review - info.preCompNeg := Nil; // Review - end; { TWTauNafMultiplier } @@ -534,8 +531,6 @@ class function TWTauNafMultiplier.MultiplyFromWTnaf(const p: IAbstractF2mPoint; end; result := q; - pre.preComp := Nil; // Review - end; function TWTauNafMultiplier.MultiplyWTnaf(const p: IAbstractF2mPoint; @@ -606,12 +601,11 @@ function TWTauNafMultiplier.TWTauNafCallback.Precompute(const existing tempResult: IWTauNafPreCompInfo; 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.preComp := TTnaf.GetPreComp(Fm_p, Fm_a); diff --git a/CryptoLib/src/Math/EC/Multiplier/ClpWNafPreCompInfo.pas b/CryptoLib/src/Math/EC/Multiplier/ClpWNafPreCompInfo.pas index ba079507..b5971d1c 100644 --- a/CryptoLib/src/Math/EC/Multiplier/ClpWNafPreCompInfo.pas +++ b/CryptoLib/src/Math/EC/Multiplier/ClpWNafPreCompInfo.pas @@ -87,6 +87,7 @@ TWNafPreCompInfo = class sealed(TInterfacedObject, IPreCompInfo, public constructor Create(); + destructor Destroy; override; property PreComp: TCryptoLibGenericArray read GetPreComp write SetPreComp; property PreCompNeg: TCryptoLibGenericArray read GetPreCompNeg @@ -126,6 +127,30 @@ function TWNafPreCompInfo.DecrementPromotionCountdown: Int32; result := t; 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; begin result := FConfWidth; diff --git a/CryptoLib/src/Math/EC/Multiplier/ClpWTauNafPreCompInfo.pas b/CryptoLib/src/Math/EC/Multiplier/ClpWTauNafPreCompInfo.pas index bc96e1e4..e798e54e 100644 --- a/CryptoLib/src/Math/EC/Multiplier/ClpWTauNafPreCompInfo.pas +++ b/CryptoLib/src/Math/EC/Multiplier/ClpWTauNafPreCompInfo.pas @@ -50,6 +50,8 @@ TWTauNafPreCompInfo = class(TInterfacedObject, IPreCompInfo, Fm_preComp: TCryptoLibGenericArray; public + destructor Destroy; override; + property PreComp: TCryptoLibGenericArray read GetPreComp write SetPreComp; end; @@ -58,6 +60,19 @@ implementation { 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 : TCryptoLibGenericArray; begin