mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 08:09:33 +02:00
fcl-hash: fixed freeing TBigIntContext.BIRadix and migrated to mode objfpc
This commit is contained in:
parent
67905957cb
commit
864b2ad3f3
@ -335,7 +335,7 @@ begin
|
||||
begin
|
||||
Line:=sl[i];
|
||||
if not PemLineIsBase64(Line) then
|
||||
exit;
|
||||
raise Exception.Create('20220428220523');
|
||||
TxtBase64:=TxtBase64+Line;
|
||||
end;
|
||||
Result:=basenenc.Base64.Decode(TxtBase64,True);
|
||||
|
@ -159,10 +159,9 @@ begin
|
||||
try
|
||||
ASNParse(PublicKeyDER,List);
|
||||
|
||||
//for i:=0 to List.Count-1 do begin
|
||||
// ASNParse_GetItem(List,i,ASNType,ASNSize);
|
||||
// writeln('X509RsaPublicKeyInitFromDER ',i,'/',List.Count,' ASNType=',hexstr(ASNType,2),' ASNSize=',ASNSize,' S="',List[i],'"');
|
||||
//end;
|
||||
{$IFDEF TLS_DEBUG}
|
||||
ASNDebugList('X509RsaPublicKeyInitFromDER',List);
|
||||
{$ENDIF}
|
||||
|
||||
if List.Count<7 then
|
||||
raise Exception.Create('20220428180055');
|
||||
@ -186,7 +185,6 @@ begin
|
||||
|
||||
// check null
|
||||
ASNParse_GetItem(List,3,ASNType,ASNSize);
|
||||
writeln('X509RsaPublicKeyInitFromDER ',ASNType,' ',ASNSize);
|
||||
if ASNType<>ASN1_NULL then
|
||||
raise Exception.Create('20220428181659');
|
||||
|
||||
@ -206,8 +204,8 @@ begin
|
||||
|
||||
{$IFDEF TLS_DEBUG}
|
||||
writeln('X509RsaPublicKeyInitFromDER: ');
|
||||
writeln(' Modulus=',BytesToHexStr(RSA.Modulus));
|
||||
writeln(' Exponent=',BytesToHexStr(RSA.Exponent));
|
||||
writeln(' Modulus=$',BytesToHexStr(RSA.Modulus));
|
||||
writeln(' Exponent=$',BytesToHexStr(RSA.Exponent));
|
||||
{$ENDIF}
|
||||
finally
|
||||
List.Free;
|
||||
@ -330,12 +328,12 @@ begin
|
||||
if Len > Size-11 then
|
||||
Exit;
|
||||
{$IFDEF CRYPTO_DEBUG}
|
||||
writeln('RSAEncryptSign - Len = ' + IntToStr(Len) + ' Size = ' + IntToStr(Size) + ' Padding = ' + IntToStr(Padding)); //To Do
|
||||
writeln('RSAEncryptSign - Len = ' + IntToStr(Len) + ' Size = ' + IntToStr(Size) + ' Padding = ' + IntToStr(Padding)); //To Do
|
||||
{$ENDIF}
|
||||
if Size > RSA_MODULUS_BYTES_MAX then
|
||||
Imported := GetMem(Size)
|
||||
else
|
||||
Imported := @Block;
|
||||
Imported := @Block[0];
|
||||
try
|
||||
// Leading zero to ensure encryption block is less than modulus (when converted to an integer)
|
||||
Imported[0]:=0;
|
||||
@ -373,14 +371,14 @@ begin
|
||||
if Sign then
|
||||
begin
|
||||
// Sign with Private Key
|
||||
Encrypted:=BICRT(RSA.Context,Decrypted,RSA.DP,RSA.DQ,RSA.P,RSA.Q,RSA.QInv);
|
||||
Encrypted:=BICRT(RSA.Context,Decrypted,RSA.DP,RSA.DQ,RSA.P,RSA.Q,RSA.QInv); // this releases Decrypted
|
||||
end else
|
||||
begin
|
||||
// Encrypt with Public Key
|
||||
RSA.Context.ModOffset:=BIGINT_M_OFFSET;
|
||||
Encrypted:=BIModPower(RSA.Context,Decrypted,RSA.E);
|
||||
Encrypted:=BIModPower(RSA.Context,Decrypted,RSA.E); // this releases Decrypted
|
||||
end;
|
||||
BIExport(RSA.Context,Encrypted,Output,Size);
|
||||
BIExport(RSA.Context,Encrypted,Output,Size); // this releases Encrypted
|
||||
|
||||
{$IFDEF CRYPTO_DEBUG}
|
||||
writeln('RSAEncryptSign - Output Size = ' + IntToStr(Size) + ' Output = ',Output,Size);
|
||||
|
@ -13,7 +13,7 @@ interface
|
||||
|
||||
uses SysUtils;
|
||||
|
||||
{ $DEFINE BIGINT_DEBUG} // Enable debug output/functions for BitInt unit
|
||||
{$DEFINE BIGINT_DEBUG} // Enable debug output/functions for BitInt unit
|
||||
|
||||
const
|
||||
// Maintain a number of precomputed variables when doing reduction
|
||||
@ -43,9 +43,6 @@ type
|
||||
PBISignedLongComponent = ^TBISignedLongComponent;
|
||||
TBISignedLongComponent = Int64; // A signed double precision component
|
||||
|
||||
PBIComponents = ^TBIComponents;
|
||||
TBIComponents = array[0..(MaxInt div SizeOf(TBIComponent))-1] of TBIComponent;
|
||||
|
||||
type
|
||||
PPBigInt = ^PBigInt;
|
||||
PBigInt = ^TBigInt;
|
||||
@ -57,8 +54,6 @@ type
|
||||
Components: PBIComponent; // A ptr to the actual component data
|
||||
procedure ToString(out S: AnsiString);
|
||||
end;
|
||||
PBigInts = ^TBigInts;
|
||||
TBigInts = array[0..(MaxInt div SizeOf(PBigInt)) - 1] of PBigInt;
|
||||
|
||||
{Maintains the state of the cache, and a number of variables used in reduction}
|
||||
PBigIntContext = ^TBigIntContext;
|
||||
@ -80,12 +75,12 @@ procedure BIInitialize(out Context: TBigIntContext);
|
||||
procedure BITerminate(var Context: TBigIntContext);
|
||||
procedure BIPermanent(BI: PBigInt);
|
||||
procedure BIDepermanent(BI: PBigInt);
|
||||
procedure BIRelease(var Context: TBigIntContext; BI:PBigInt);
|
||||
procedure BIRelease(var Context: TBigIntContext; BI: PBigInt);
|
||||
|
||||
function BICopy(BI: PBigInt): PBigInt;
|
||||
function BIClone(var Context: TBigIntContext; const BI: TBigInt): PBigInt;
|
||||
|
||||
procedure BIExport(var Context: TBigIntContext; BI: PBigInt; Data: PByte; Size: Integer);
|
||||
procedure BIExport(var Context: TBigIntContext; BI: PBigInt; Data: PByte; Size: Integer; Release: boolean = true);
|
||||
function BIImport(var Context: TBigIntContext; Data: PByte; const Size: Integer): PBigInt; overload;
|
||||
function BIImport(var Context: TBigIntContext; const Data: TBytes): PBigInt; overload;
|
||||
function BIImport(var Context: TBigIntContext; const Data: AnsiString): PBigInt; overload;
|
||||
@ -142,23 +137,19 @@ end;
|
||||
{Perform a sanity check on bi}
|
||||
function BICheck(const BI: TBigInt): Boolean; inline;
|
||||
begin
|
||||
{$IFDEF BIGINT_DEBUG}
|
||||
{$IFDEF BIGINT_DEBUG}
|
||||
if BI.References <= 0 then
|
||||
begin
|
||||
XLog(tlDebug, 'TLS', 'BICheck - Zero or negative References in TBigInt');
|
||||
Result := False;
|
||||
Exit;
|
||||
writeln('BICheck - Zero or negative References in TBigInt');
|
||||
raise Exception.Create('20220428201452');
|
||||
end;
|
||||
if BI.Next <> nil then
|
||||
begin
|
||||
XLog(tlDebug, 'TLS', 'BICheck - Attempt to use a TBigInt from the free list');
|
||||
Result := False;
|
||||
Exit;
|
||||
writeln('BICheck - Attempt to use a TBigInt from the free list');
|
||||
raise Exception.Create('20220428201508');
|
||||
end;
|
||||
{$ENDIF}
|
||||
Result:=True;
|
||||
{$ELSE}
|
||||
Result:=True;
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
// Delete any leading 0's (and allow for 0)
|
||||
@ -166,14 +157,11 @@ procedure BITrim(BI: PBigInt);
|
||||
begin
|
||||
if not BICheck(BI^) then
|
||||
Exit;
|
||||
while (PBIComponents(BI^.Components)^[BI^.Size-1] = 0) and (BI^.Size > 1) do
|
||||
while (BI^.Components[BI^.Size-1] = 0) and (BI^.Size > 1) do
|
||||
Dec(BI^.Size);
|
||||
end;
|
||||
|
||||
procedure BIAddComponents(var Context: TBigIntContext; BI: PBigInt; N: Integer);
|
||||
var
|
||||
OldComponents: PBIComponent;
|
||||
OldMaxComponents: Int32;
|
||||
procedure BIResizeComponents(BI: PBigInt; N: Integer);
|
||||
begin
|
||||
if N > BI^.MaxComponents then
|
||||
begin
|
||||
@ -181,7 +169,7 @@ begin
|
||||
ReAllocMem(BI^.Components, BI^.MaxComponents*BIGINT_COMP_BYTE_SIZE);
|
||||
end;
|
||||
if N > BI^.Size then
|
||||
FillChar(PBIComponents(BI^.Components)^[BI^.Size], (N-BI^.Size)*BIGINT_COMP_BYTE_SIZE, 0);
|
||||
FillByte(BI^.Components[BI^.Size], (N-BI^.Size)*BIGINT_COMP_BYTE_SIZE, 0);
|
||||
BI^.Size := N;
|
||||
end;
|
||||
|
||||
@ -190,21 +178,18 @@ begin
|
||||
if Context.FreeList <> nil then
|
||||
begin
|
||||
Result := Context.FreeList;
|
||||
if Result^.References <> 0 then
|
||||
raise Exception.Create('20220428200026');
|
||||
Context.FreeList := Result^.Next;
|
||||
Dec(Context.FreeCount);
|
||||
if Result^.References <> 0 then
|
||||
begin
|
||||
Result := nil;
|
||||
Exit;
|
||||
end;
|
||||
BIAddComponents(Context, Result, Size);
|
||||
BIResizeComponents(Result, Size);
|
||||
end else
|
||||
begin
|
||||
Result := AllocMem(SizeOf(TBigint));
|
||||
Result^.Components := AllocMem((Size*2)*BIGINT_COMP_BYTE_SIZE);
|
||||
Result^.MaxComponents := Size*2; // Allow space to expand
|
||||
Result^.Size := Size;
|
||||
end;
|
||||
Result^.Size := Size;
|
||||
Result^.References := 1;
|
||||
Result^.Next := nil;
|
||||
Inc(Context.ActiveCount);
|
||||
@ -218,7 +203,7 @@ var
|
||||
begin
|
||||
I := BIGINT_COMP_BIT_SIZE-1;
|
||||
Shift:=BIGINT_COMP_RADIX div 2;
|
||||
Test:=PBIComponents(BIExp^.Components)^[BIExp^.Size - 1]; {Assume no leading zeroes}
|
||||
Test:=BIExp^.Components[BIExp^.Size - 1]; {Assume no leading zeroes}
|
||||
if not BICheck(BIExp^) then
|
||||
begin
|
||||
Result:=-1;
|
||||
@ -242,12 +227,12 @@ var
|
||||
NumShifts: Integer;
|
||||
Shift, Test: TBIComponent;
|
||||
begin
|
||||
Test := PBIComponents(BIExp^.Components)^[Offset div BIGINT_COMP_BIT_SIZE];
|
||||
Test := BIExp^.Components[Offset div BIGINT_COMP_BIT_SIZE];
|
||||
NumShifts := Offset mod BIGINT_COMP_BIT_SIZE;
|
||||
if not BICheck(BIExp^) then
|
||||
begin
|
||||
Result := False;
|
||||
Exit;
|
||||
Result := False;
|
||||
Exit;
|
||||
end;
|
||||
Shift := 1 shl NumShifts;
|
||||
Result := (Test and Shift) <> 0;
|
||||
@ -274,7 +259,7 @@ begin
|
||||
A := BIA^.Components;
|
||||
FillChar(R^, (N+1) * BIGINT_COMP_BYTE_SIZE, 0);
|
||||
repeat
|
||||
Tmp := R^ + TBILongComponent(PBIComponents(A)^[J]) * B + Carry; // Avoid overflow
|
||||
Tmp := R^ + TBILongComponent(A[J]) * B + Carry; // Avoid overflow
|
||||
R^ := Tmp; // Downsize
|
||||
Inc(R);
|
||||
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
@ -285,7 +270,7 @@ begin
|
||||
BITrim(Result);
|
||||
end;
|
||||
|
||||
function BIIntDivide(var Context: TBigIntContext; BIR: PBigInt; Denom: TBIComponent): PBigInt;
|
||||
function BIIntDivide(BIR: PBigInt; Denom: TBIComponent): PBigInt;
|
||||
var
|
||||
I: Integer;
|
||||
R: TBILongComponent;
|
||||
@ -298,8 +283,8 @@ begin
|
||||
I := BIR^.Size-1;
|
||||
R := 0;
|
||||
repeat
|
||||
R := (R shl BIGINT_COMP_BIT_SIZE) + PBIComponents(BIR^.Components)^[I];
|
||||
PBIComponents(BIR^.Components)^[I] := R div Denom;
|
||||
R := (R shl BIGINT_COMP_BIT_SIZE) + BIR^.Components[I];
|
||||
BIR^.Components[I] := R div Denom;
|
||||
R := R mod Denom;
|
||||
Dec(I);
|
||||
until I < 0;
|
||||
@ -320,10 +305,10 @@ begin
|
||||
end;
|
||||
I := BIR^.Size-NumShifts;
|
||||
X := BIR^.Components;
|
||||
Y := @PBIComponents(BIR^.Components)^[NumShifts];
|
||||
Y := @BIR^.Components[NumShifts];
|
||||
if I <= 0 then // Have we completely right shifted?
|
||||
begin
|
||||
PBIComponents(BIR^.Components)^[0]:=0; {Return 0}
|
||||
BIR^.Components[0]:=0; {Return 0}
|
||||
BIR^.Size:=1;
|
||||
Result:=BIR;
|
||||
Exit;
|
||||
@ -339,7 +324,7 @@ begin
|
||||
end;
|
||||
|
||||
// Take each component and shift it up (in terms of components)
|
||||
function BICompLeftShift(var Context: TBigIntContext; BIR: PBigInt; NumShifts: Integer): PBigInt;
|
||||
function BICompLeftShift(BIR: PBigInt; NumShifts: Integer): PBigInt;
|
||||
var
|
||||
I: Integer;
|
||||
X: PBIComponent;
|
||||
@ -356,16 +341,16 @@ begin
|
||||
Result:=BIR;
|
||||
Exit;
|
||||
end;
|
||||
BIAddComponents(Context, BIR, BIR^.Size+NumShifts);
|
||||
X := @(PBIComponents(BIR^.Components)^[I + NumShifts]);
|
||||
Y := @(PBIComponents(BIR^.Components)^[I]);
|
||||
BIResizeComponents(BIR, BIR^.Size+NumShifts);
|
||||
X := @(BIR^.Components[I + NumShifts]);
|
||||
Y := @(BIR^.Components[I]);
|
||||
repeat
|
||||
X^ := Y^;
|
||||
Dec(X);
|
||||
Dec(Y);
|
||||
Dec(I);
|
||||
until I < 0;
|
||||
FillChar(BIR^.Components^, NumShifts*BIGINT_COMP_BYTE_SIZE, 0); // Zero least significant components
|
||||
FillByte(BIR^.Components^, NumShifts*BIGINT_COMP_BYTE_SIZE, 0); // Zero least significant components
|
||||
Result := BIR;
|
||||
end;
|
||||
|
||||
@ -390,7 +375,7 @@ begin
|
||||
SR := BIR^.Components;
|
||||
SA := BIA^.Components;
|
||||
SB := BIB^.Components;
|
||||
FillChar(BIR^.Components^, (N+T) * BIGINT_COMP_BYTE_SIZE, 0);
|
||||
FillByte(BIR^.Components^, (N+T) * BIGINT_COMP_BYTE_SIZE, 0);
|
||||
repeat
|
||||
Carry := 0;
|
||||
RIndex := I;
|
||||
@ -403,13 +388,13 @@ begin
|
||||
repeat
|
||||
if (InnerPartial > 0) and (RIndex >= InnerPartial) then
|
||||
Break;
|
||||
Tmp := PBIComponents(SR)^[RIndex] + TBILongComponent(PBIComponents(SA)^[J]) * PBIComponents(SB)^[I] + Carry; // Avoid overflow
|
||||
PBIComponents(SR)^[RIndex] := Tmp; // Downsize
|
||||
Tmp := SR[RIndex] + TBILongComponent(SA[J]) * SB[I] + Carry; // Avoid overflow
|
||||
SR[RIndex] := Tmp; // Downsize
|
||||
Inc(RIndex);
|
||||
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
Inc(J);
|
||||
until J >= N;
|
||||
PBIComponents(SR)^[RIndex] := Carry;
|
||||
SR[RIndex] := Carry;
|
||||
Inc(I);
|
||||
until I >= T;
|
||||
BIRelease(Context,BIA);
|
||||
@ -435,32 +420,32 @@ begin
|
||||
X := BI^.Components;
|
||||
FillChar(W^,BIR^.Size * BIGINT_COMP_BYTE_SIZE,0);
|
||||
repeat
|
||||
Tmp := PBIComponents(W)^[2*I] + TBILongComponent(PBIComponents(X)^[I]) * PBIComponents(X)^[I]; // Avoid overflow
|
||||
PBIComponents(W)^[2 * I] := Tmp;
|
||||
Tmp := W[2*I] + TBILongComponent(X[I]) * X[I]; // Avoid overflow
|
||||
W[2 * I] := Tmp;
|
||||
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
J := I+1;
|
||||
while J < T do
|
||||
begin
|
||||
C := 0;
|
||||
XX := TBILongComponent(PBIComponents(X)^[I]) * PBIComponents(X)^[J]; // Avoid overflow
|
||||
XX := TBILongComponent(X[I]) * X[J]; // Avoid overflow
|
||||
if BIGINT_COMP_MAX-XX < XX then
|
||||
C := 1;
|
||||
Tmp := XX shl 1;
|
||||
if BIGINT_COMP_MAX-Tmp < PBIComponents(W)^[I + J] then
|
||||
if BIGINT_COMP_MAX-Tmp < W[I + J] then
|
||||
C := 1;
|
||||
Tmp := Tmp + PBIComponents(W)^[I + J];
|
||||
Tmp := Tmp + W[I + J];
|
||||
if BIGINT_COMP_MAX-Tmp < Carry then
|
||||
C := 1;
|
||||
Tmp := Tmp + Carry;
|
||||
PBIComponents(W)^[I + J] := Tmp;
|
||||
W[I + J] := Tmp;
|
||||
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
if C > 0 then
|
||||
Carry := Carry + BIGINT_COMP_RADIX;
|
||||
Inc(J);
|
||||
end;
|
||||
Tmp := PBIComponents(W)^[I+T]+Carry;
|
||||
PBIComponents(W)^[I+T] := Tmp;
|
||||
PBIComponents(W)^[I+T+1] := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
Tmp := W[I+T]+Carry;
|
||||
W[I+T] := Tmp;
|
||||
W[I+T+1] := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
Inc(I);
|
||||
until I >= T;
|
||||
BIRelease(Context, BI);
|
||||
@ -495,44 +480,49 @@ begin
|
||||
Inc(I);
|
||||
end;
|
||||
Context.G := AllocMem(K*SizeOf(PBigInt));
|
||||
PBigInts(Context.G)^[0] := BIClone(Context, G1^);
|
||||
BIPermanent(PBigInts(Context.G)^[0]);
|
||||
G2 := BIResidue(Context, BISquare(Context, PBigInts(Context.G)^[0])); {g^2}
|
||||
Context.G[0] := BIClone(Context, G1^);
|
||||
BIPermanent(Context.G[0]);
|
||||
G2 := BIResidue(Context, BISquare(Context, Context.G[0])); {g^2}
|
||||
for I := 1 to K-1 do
|
||||
begin
|
||||
PBigInts(Context.G)^[I] := BIResidue(Context, BIMultiply(Context, PBigInts(Context.G)^[I-1], BICopy(G2)));
|
||||
BIPermanent(PBigInts(Context.G)^[I]);
|
||||
Context.G[I] := BIResidue(Context, BIMultiply(Context, Context.G[I-1], BICopy(G2)));
|
||||
BIPermanent(Context.G[I]);
|
||||
end;
|
||||
BIRelease(Context, G2);
|
||||
Context.Window := K;
|
||||
end;
|
||||
|
||||
procedure BIInitialize(out Context: TBigIntContext);
|
||||
var
|
||||
BIRadix: PBigInt;
|
||||
begin
|
||||
Context:=Default(TBigIntContext);
|
||||
Context.BIRadix := BIAllocate(Context, 2);
|
||||
PBIComponents(Context.BIRadix^.Components)^[0] := 0;
|
||||
PBIComponents(Context.BIRadix^.Components)^[1] := 1;
|
||||
BIPermanent(Context.BIRadix);
|
||||
BIRadix:=BIAllocate(Context, 2);
|
||||
Context.BIRadix := BIRadix;
|
||||
BIRadix^.Components[0] := 0;
|
||||
BIRadix^.Components[1] := 1;
|
||||
BIPermanent(BIRadix);
|
||||
end;
|
||||
|
||||
// Close the bigint context and free any resources
|
||||
procedure BITerminate(var Context: TBigIntContext);
|
||||
|
||||
Var
|
||||
BI,BN : PBigInt;
|
||||
BI,BNext : PBigInt;
|
||||
|
||||
begin
|
||||
FreeMem(Context.BIRadix);
|
||||
BIRelease(Context, Context.BIRadix);
|
||||
Context.BIRadix := nil;
|
||||
BI:=Context.FreeList;
|
||||
While BI<>Nil do
|
||||
begin
|
||||
BN:=BI^.Next;
|
||||
BNext:=BI^.Next;
|
||||
if BI^.Components<>Nil then
|
||||
FreeMem(BI^.Components);
|
||||
FreeMem(BI);
|
||||
BI:=BN;
|
||||
BI:=BNext;
|
||||
end;
|
||||
Context.FreeList:=nil;
|
||||
end;
|
||||
|
||||
// Make a bigint object "unfreeable" if BIFree() is called on it
|
||||
@ -541,24 +531,17 @@ begin
|
||||
if not BICheck(BI^) then
|
||||
Exit;
|
||||
if BI^.References <> 1 then
|
||||
begin
|
||||
//XLog(tlDebug, 'TLS', 'BIPermanent - References not equal to one');
|
||||
//To Do //Log Error /Raise Exception
|
||||
Exit;
|
||||
end;
|
||||
raise Exception.Create('20220428195735');
|
||||
BI^.References := BIGINT_PERMANENT;
|
||||
end;
|
||||
|
||||
// Take a permanent object and make it freeable
|
||||
procedure BIDepermanent(BI: PBigInt);
|
||||
begin
|
||||
if not BICHeck(BI^) then
|
||||
if not BICheck(BI^) then
|
||||
Exit;
|
||||
if BI^.References <> BIGINT_PERMANENT then
|
||||
begin
|
||||
// XLog(tlDebug, 'TLS', 'BIDepermanent - References not equal to BIGINT_PERMANENT');
|
||||
Exit;
|
||||
end;
|
||||
raise Exception.Create('20220428203636');
|
||||
BI^.References := 1;
|
||||
end;
|
||||
|
||||
@ -576,8 +559,10 @@ begin
|
||||
Context.FreeList := BI;
|
||||
Inc(Context.FreeCount);
|
||||
Dec(Context.ActiveCount);
|
||||
// if Context.ActiveCount < 0 then
|
||||
// XLog(tlWarning, 'TLS', 'BIFree - ActiveCount less than zero');
|
||||
{$IFDEF BIGINT_DEBUG}
|
||||
if Context.ActiveCount < 0 then
|
||||
raise Exception.Create('20220428203546');
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
{==============================================================================}
|
||||
@ -606,7 +591,8 @@ begin
|
||||
System.Move(BI.Components^, Result^.Components^, BI.Size*BIGINT_COMP_BYTE_SIZE);
|
||||
end;
|
||||
|
||||
procedure BIExport(var Context: TBigIntContext; BI: PBigInt; Data: PByte; Size: Integer);
|
||||
procedure BIExport(var Context: TBigIntContext; BI: PBigInt; Data: PByte;
|
||||
Size: Integer; Release: boolean);
|
||||
{Take a bigint and convert it into a byte sequence}
|
||||
{Context: The bigint session context}
|
||||
{BI: The bigint to be converted}
|
||||
@ -616,28 +602,25 @@ var
|
||||
I: Integer;
|
||||
J: Integer;
|
||||
K: Integer;
|
||||
Mask: TBIComponent;
|
||||
Num: Integer;
|
||||
begin
|
||||
if not BICheck(BI^) then
|
||||
Exit;
|
||||
FillChar(Data^,Size,0);
|
||||
FillByte(Data^,Size,0);
|
||||
K := Size-1;
|
||||
try
|
||||
for I := 0 to BI^.Size - 1 do
|
||||
begin
|
||||
for J := 0 to BIGINT_COMP_BYTE_SIZE - 1 do
|
||||
begin
|
||||
Mask := $FF shl (J * 8);
|
||||
Num := (PBIComponents(BI^.Components)^[I] and Mask) shr (J * 8);
|
||||
PByteArray(Data)^[K]:=Num;
|
||||
Data[K]:=(BI^.Components[I] shr (J * 8)) and $ff;
|
||||
Dec(K);
|
||||
if K < 0 then
|
||||
Exit;
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
BIRelease(Context,BI);
|
||||
if Release then
|
||||
BIRelease(Context,BI);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -651,10 +634,10 @@ begin
|
||||
J := 0;
|
||||
Offset := 0;
|
||||
Result := BIAllocate(Context, (Size+BIGINT_COMP_BYTE_SIZE-1) div BIGINT_COMP_BYTE_SIZE);
|
||||
FillChar(Result^.Components^, Result^.Size*BIGINT_COMP_BYTE_SIZE, 0);
|
||||
FillByte(Result^.Components^, Result^.Size*BIGINT_COMP_BYTE_SIZE, 0);
|
||||
for I := Size-1 downto 0 do
|
||||
begin
|
||||
PBIComponents(Result^.Components)^[Offset] := PBIComponents(Result^.Components)^[Offset] + (PByteArray(Data)^[I] shl (J * 8));
|
||||
Result^.Components[Offset] := Result^.Components[Offset] + (TBIComponent(Data[I]) shl (J * 8));
|
||||
Inc(J);
|
||||
if J = BIGINT_COMP_BYTE_SIZE then
|
||||
begin
|
||||
@ -666,7 +649,7 @@ end;
|
||||
|
||||
function BIImport(var Context: TBigIntContext; const Data: TBytes): PBigInt;
|
||||
begin
|
||||
Result := BIImport(Context, PByte(Data), Length(Data));
|
||||
Result := BIImport(Context, @Data[0], Length(Data));
|
||||
end;
|
||||
|
||||
function BIImport(var Context: TBigIntContext; const Data: AnsiString): PBigInt; overload;
|
||||
@ -681,7 +664,7 @@ end;
|
||||
function IntToBI(var Context: TBigIntContext; I: TBIComponent): PBigInt;
|
||||
begin
|
||||
Result := BIAllocate(Context,1);
|
||||
PBIComponents(Result^.Components)^[0] := I;
|
||||
Result^.Components[0] := I;
|
||||
end;
|
||||
|
||||
function BIAdd(var Context: TBigIntContext; BIA, BIB: PBigInt): PBigInt;
|
||||
@ -701,8 +684,8 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
N := Max(BIA^.Size, BIB^.Size);
|
||||
BIAddComponents(Context, BIA, N+1);
|
||||
BIAddComponents(Context, BIB, N);
|
||||
BIResizeComponents(BIA, N+1);
|
||||
BIResizeComponents(BIB, N);
|
||||
PA := BIA^.Components;
|
||||
PB := BIB^.Components;
|
||||
repeat
|
||||
@ -746,7 +729,7 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
N := BIA^.Size;
|
||||
BIAddComponents(Context, BIB, N);
|
||||
BIResizeComponents(BIB, N);
|
||||
PA := BIA^.Components;
|
||||
PB := BIB^.Components;
|
||||
repeat
|
||||
@ -780,17 +763,17 @@ function BIDivide(var Context: TBigIntContext; U, V: PBigInt; IsMod: Boolean): P
|
||||
|
||||
function BIDivide_V1(V:PBigInt):TBIComponent; inline;
|
||||
begin // V1 for division
|
||||
Result := PBIComponents(V^.Components)^[V^.Size-1];
|
||||
Result := V^.Components[V^.Size-1];
|
||||
end;
|
||||
|
||||
function BIDivide_V2(V: PBigInt): TBIComponent; inline;
|
||||
begin // V2 for division
|
||||
Result := PBIComponents(V^.Components)^[V^.Size-2];
|
||||
Result := V^.Components[V^.Size-2];
|
||||
end;
|
||||
|
||||
function BIDivide_U(TmpU: PBigInt; J: Integer): TBIComponent; inline;
|
||||
begin // U(J) for division
|
||||
Result := PBIComponents(TmpU^.Components)^[TmpU^.Size-J-1];
|
||||
Result := TmpU^.Components[TmpU^.Size-J-1];
|
||||
end;
|
||||
|
||||
var
|
||||
@ -833,10 +816,10 @@ begin
|
||||
V:=BIIntMultiply(Context,V,D);
|
||||
end;
|
||||
if OrigUSize = U^.Size then
|
||||
BIAddComponents(Context, U, OrigUSize+1); // New digit position u0
|
||||
BIResizeComponents(U, OrigUSize+1); // New digit position u0
|
||||
repeat
|
||||
// Get a temporary short version of u
|
||||
System.Move(PBIComponents(U^.Components)^[U^.Size-N-1-J], TmpU^.Components^, (N+1) * BIGINT_COMP_BYTE_SIZE);
|
||||
System.Move(U^.Components[U^.Size-N-1-J], TmpU^.Components^, (N+1) * BIGINT_COMP_BYTE_SIZE);
|
||||
// Calculate q'
|
||||
if BIDivide_U(TmpU, 0) = BIDivide_V1(V) then
|
||||
begin
|
||||
@ -855,11 +838,11 @@ begin
|
||||
if QDash > 0 then
|
||||
begin // Multiply and subtract
|
||||
TmpU := BISubtract(Context, TmpU, BIIntMultiply(Context, BICopy(V), QDash), IsNegative);
|
||||
BIAddComponents(Context, TmpU, N+1);
|
||||
PBIComponents(Quotient^.Components)^[Quotient^.Size-J-1] := QDash;
|
||||
BIResizeComponents(TmpU, N+1);
|
||||
Quotient^.Components[Quotient^.Size-J-1] := QDash;
|
||||
if IsNegative then
|
||||
begin // Add back
|
||||
Dec(PBIComponents(Quotient^.Components)^[Quotient^.Size-J-1]);
|
||||
Dec(Quotient^.Components[Quotient^.Size-J-1]);
|
||||
TmpU := BIAdd(Context, TmpU, BICopy(V));
|
||||
// Lop off the carry
|
||||
Dec(TmpU^.Size);
|
||||
@ -867,10 +850,10 @@ begin
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
PBIComponents(Quotient^.Components)^[Quotient^.Size-J-1] := 0;
|
||||
Quotient^.Components[Quotient^.Size-J-1] := 0;
|
||||
end;
|
||||
// Copy back to U
|
||||
System.Move(TmpU^.Components^, PBIComponents(U^.Components)^[U^.Size-N-1-J], (N+1) * BIGINT_COMP_BYTE_SIZE);
|
||||
System.Move(TmpU^.Components^, U^.Components[U^.Size-N-1-J], (N+1) * BIGINT_COMP_BYTE_SIZE);
|
||||
Inc(J);
|
||||
until J > M;
|
||||
BIRelease(Context, TmpU);
|
||||
@ -879,7 +862,7 @@ begin
|
||||
begin // Get the remainder
|
||||
BIRelease(Context, Quotient);;
|
||||
BITrim(U);
|
||||
Result := BIIntDivide(Context, U, D);
|
||||
Result := BIIntDivide(U, D);
|
||||
end else
|
||||
begin // Get the quotient
|
||||
BIRelease(Context, U);
|
||||
@ -950,7 +933,7 @@ begin
|
||||
Dec(J);
|
||||
end;
|
||||
PartExp := (PartExp-1) div 2; // Adjust for array
|
||||
BIR := BIResidue(Context, BIMultiply(Context, BIR, PBigInts(Context.G)^[PartExp]));
|
||||
BIR := BIResidue(Context, BIMultiply(Context, BIR, Context.G[PartExp]));
|
||||
I := L-1;
|
||||
end else
|
||||
begin // Square it
|
||||
@ -960,8 +943,8 @@ begin
|
||||
until I < 0;
|
||||
for I := 0 to Context.Window-1 do
|
||||
begin // Cleanup
|
||||
BIDepermanent(PBigInts(Context.G)^[I]);
|
||||
BIRelease(Context, PBigInts(Context.G)^[I]);
|
||||
BIDepermanent(Context.G[I]);
|
||||
BIRelease(Context, Context.G[I]);
|
||||
end;
|
||||
BIRelease(Context, BI);
|
||||
BIRelease(Context, BIExp);
|
||||
@ -1016,24 +999,17 @@ begin
|
||||
Result := -1;
|
||||
Exit;
|
||||
end;
|
||||
// Same number of components. Compare starting from the high end and working down
|
||||
A := BIA^.Components;
|
||||
B := BIB^.Components;
|
||||
// Same number of components. Compare starting from the high end and working down
|
||||
for I := BIA^.Size-1 downto 0 do
|
||||
begin
|
||||
if A[I] > B[I] then
|
||||
Exit(1)
|
||||
else if A[I] < B[I] then
|
||||
Exit(-1);
|
||||
end;
|
||||
Result := 0;
|
||||
I := BIA^.Size-1;
|
||||
repeat
|
||||
if PBIComponents(A)^[I] > PBIComponents(B)^[I] then
|
||||
begin
|
||||
Result := 1;
|
||||
Exit;
|
||||
end;
|
||||
if PBIComponents(A)^[I] < PBIComponents(B)^[I] then
|
||||
begin
|
||||
Result := -1;
|
||||
Exit;
|
||||
end;
|
||||
Dec(I);
|
||||
until I < 0;
|
||||
end;
|
||||
|
||||
// Pre-compute some of the expensive steps in reduction
|
||||
@ -1047,14 +1023,14 @@ var
|
||||
K: Integer;
|
||||
begin
|
||||
K := BIM^.Size;
|
||||
D := BIGINT_COMP_RADIX div (TBILongComponent(PBIComponents(BIM^.Components)^[K-1]) + 1);
|
||||
D := BIGINT_COMP_RADIX div (TBILongComponent(BIM^.Components[K-1]) + 1);
|
||||
Context.BIMod[ModOffset] := BIM;
|
||||
BIPermanent(Context.BIMod[ModOffset]);
|
||||
Context.BINormalisedMod[ModOffset] := BIIntMultiply(Context, BIM, D);
|
||||
BIPermanent(Context.BINormalisedMod[ModOffset]);
|
||||
Context.BImu[ModOffset] := BIDivide(Context, BICompLeftShift(Context, BIClone(Context, Context.BIRadix^), K*2-1), Context.BIMod[ModOffset], False);
|
||||
Context.BImu[ModOffset] := BIDivide(Context, BICompLeftShift(BIClone(Context, Context.BIRadix^), K*2-1), Context.BIMod[ModOffset], False);
|
||||
BIPermanent(Context.BImu[ModOffset]);
|
||||
Context.BIbk1[ModOffset] := BICompLeftShift(Context, IntToBI(Context,1), K+1);
|
||||
Context.BIbk1[ModOffset] := BICompLeftShift(IntToBI(Context,1), K+1);
|
||||
BIPermanent(Context.BIbk1[ModOffset]);
|
||||
end;
|
||||
|
||||
@ -1144,7 +1120,7 @@ begin
|
||||
end;
|
||||
Result := BIRegularSquare(Context, BI);
|
||||
{$ELSE}
|
||||
Result := BIMultiply(Context, BICopy(BI), BI)
|
||||
Result := BIMultiply(Context, BICopy(BI), BI);
|
||||
{$ENDIF}
|
||||
end;
|
||||
|
||||
@ -1187,7 +1163,7 @@ begin
|
||||
for J := BIGINT_COMP_NUM_NIBBLES-1 downto 0 do
|
||||
begin
|
||||
Mask := $0F shl (J*4);
|
||||
Num := (PBIComponents(BI^.Components)^[I] and Mask) shr (J*4);
|
||||
Num := (BI^.Components[I] and Mask) shr (J*4);
|
||||
S[K]:=Digits[Num and $F];
|
||||
inc(K);
|
||||
end;
|
||||
@ -1220,7 +1196,7 @@ begin
|
||||
Result := nil;
|
||||
Exit;
|
||||
end;
|
||||
PBIComponents(BIR^.Components)^[Offset] := PBIComponents(BIR^.Components)^[Offset] + LongWord(Num shl (J * 4));
|
||||
BIR^.Components[Offset] := BIR^.Components[Offset] + (LongWord(Num) shl (J * 4));
|
||||
Inc(J);
|
||||
if J = BIGINT_COMP_NUM_NIBBLES then
|
||||
begin
|
||||
|
Loading…
Reference in New Issue
Block a user