mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-14 00:59:30 +02:00
fcl-hash: fixed fptlsbigint on i386
This commit is contained in:
parent
29881ee675
commit
2ec59db2fa
@ -873,7 +873,7 @@ begin
|
||||
// Note: directly into ZeroesHashSalt
|
||||
|
||||
// "3. If emLen < hLen + sLen + 2, error"
|
||||
if EncodedLen < HashLen + SaltLen + 2 then
|
||||
if EncodedLen < HashLen + DWord(SaltLen) + 2 then
|
||||
exit(20220501221837);
|
||||
|
||||
// "4. Generate a random octet string salt of length sLen; if sLen = 0,
|
||||
@ -883,7 +883,7 @@ begin
|
||||
// "5. Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt;
|
||||
// M' is an octet string of length 8 + hLen + sLen with eight
|
||||
// initial zero octets."
|
||||
SetLength(ZeroesHashSalt{%H-},8+HashLen+SaltLen);
|
||||
SetLength(ZeroesHashSalt{%H-},8+HashLen+DWord(SaltLen));
|
||||
FillByte(ZeroesHashSalt[0],8,0);
|
||||
MsgHashP:=@ZeroesHashSalt[8];
|
||||
HashFunc^.Func(Input,InLen,MsgHashP);
|
||||
@ -935,8 +935,7 @@ function EMSA_PSS_Verify(Msg: PByte; MsgLen: DWord; EncodedMsg: PByte;
|
||||
EncodedBits: DWord; HashFunc: PRSAHashFuncInfo; SaltLen: integer): int64;
|
||||
// RFC 3447 9.1.2 Verification operation
|
||||
var
|
||||
HashLen: Word;
|
||||
EncodedLen, DBLen, i, Padding: DWord;
|
||||
HashLen, EncodedLen, DBLen, i, Padding: DWord;
|
||||
MaskedDB, HashP, SaltP: PByte;
|
||||
MsgHash, DBMask, Msg2, Hash2, DB: TBytes;
|
||||
begin
|
||||
@ -966,7 +965,7 @@ begin
|
||||
begin
|
||||
if EncodedLen < HashLen + 2 then
|
||||
exit(20220502222313);
|
||||
end else if EncodedLen < HashLen + SaltLen + 2 then
|
||||
end else if EncodedLen < HashLen + DWord(SaltLen) + 2 then
|
||||
exit(20220502205834);
|
||||
|
||||
// "4. If the rightmost octet of EM does not have hexadecimal value 0xbc, error."
|
||||
@ -1024,7 +1023,7 @@ begin
|
||||
// "12. Let M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt ;
|
||||
// M' is an octet string of length 8 + hLen + sLen with eight
|
||||
// initial zero octets.
|
||||
SetLength(Msg2{%H-},8 + HashLen + SaltLen);
|
||||
SetLength(Msg2{%H-},8 + HashLen + DWord(SaltLen));
|
||||
FillByte(Msg2[0],8,0);
|
||||
System.Move(MsgHash[0],Msg2[8],HashLen);
|
||||
System.Move(SaltP^,Msg2[8+HashLen],SaltLen);
|
||||
|
@ -8,14 +8,17 @@
|
||||
{$h+}
|
||||
{$MODESWITCH advancedrecords}
|
||||
{$R-}
|
||||
{$Q-}
|
||||
|
||||
unit fpTLSBigInt;
|
||||
|
||||
{$WARN 6058 off : Call to subroutine "$1" marked as inline is not inlined}
|
||||
|
||||
interface
|
||||
|
||||
uses SysUtils;
|
||||
|
||||
{ $DEFINE BIGINT_DEBUG} // Enable debug output/functions for BitInt unit
|
||||
{off $DEFINE BIGINT_DEBUG} // Enable debug output/functions for BitInt unit
|
||||
|
||||
const
|
||||
// Maintain a number of precomputed variables when doing reduction
|
||||
@ -108,7 +111,10 @@ function BISquare(var Context: TBigIntContext; BI: PBigInt): PBigInt; inline;
|
||||
|
||||
function BICRT(var Context: TBigIntContext; BI, DP, DQ, P, Q, QInv: PBigInt): PBigInt;
|
||||
|
||||
procedure BItoString(BI: PBigInt; out S: AnsiString);
|
||||
// Convert a bigint to a string of hex characters @Result[BI.Size*2]
|
||||
function BIToString(BI: PBigInt): AnsiString; overload;
|
||||
function BIToDbgString(BI: PBigInt): AnsiString; overload;
|
||||
procedure BIToString(BI: PBigInt; out S: AnsiString); overload;
|
||||
function StringToBI(var Context: TBigIntContext; const Value: AnsiString): PBigInt;
|
||||
|
||||
implementation
|
||||
@ -260,10 +266,10 @@ begin
|
||||
Result := BIAllocate(Context, N + 1);
|
||||
R := Result^.Components;
|
||||
A := BIA^.Components;
|
||||
FillChar(R^, (N+1) * BIGINT_COMP_BYTE_SIZE, 0);
|
||||
FillByte(R^, (N+1) * BIGINT_COMP_BYTE_SIZE, 0);
|
||||
repeat
|
||||
Tmp := R^ + TBILongComponent(A[J]) * B + Carry; // Avoid overflow
|
||||
R^ := Tmp; // Downsize
|
||||
Tmp := TBILongComponent(R^) + TBILongComponent(A[J]) * B + Carry; // Avoid overflow
|
||||
R^ := DWord(Tmp and $ffffffff); // Downsize
|
||||
Inc(R);
|
||||
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
Inc(J);
|
||||
@ -287,7 +293,7 @@ begin
|
||||
R := 0;
|
||||
repeat
|
||||
R := (R shl BIGINT_COMP_BIT_SIZE) + BIR^.Components[I];
|
||||
BIR^.Components[I] := R div Denom;
|
||||
BIR^.Components[I] := DWord((R div Denom) and $ffffffff);
|
||||
R := R mod Denom;
|
||||
Dec(I);
|
||||
until I < 0;
|
||||
@ -391,8 +397,8 @@ begin
|
||||
repeat
|
||||
if (InnerPartial > 0) and (RIndex >= InnerPartial) then
|
||||
Break;
|
||||
Tmp := SR[RIndex] + TBILongComponent(SA[J]) * SB[I] + Carry; // Avoid overflow
|
||||
SR[RIndex] := Tmp; // Downsize
|
||||
Tmp := TBILongComponent(SR[RIndex]) + TBILongComponent(SA[J]) * SB[I] + Carry; // Avoid overflow
|
||||
SR[RIndex] := TBIComponent(Tmp and $ffffffff); // Downsize
|
||||
Inc(RIndex);
|
||||
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
Inc(J);
|
||||
@ -424,7 +430,7 @@ begin
|
||||
FillChar(W^,BIR^.Size * BIGINT_COMP_BYTE_SIZE,0);
|
||||
repeat
|
||||
Tmp := W[2*I] + TBILongComponent(X[I]) * X[I]; // Avoid overflow
|
||||
W[2 * I] := Tmp;
|
||||
W[2 * I] := DWord(Tmp and $ffffffff);
|
||||
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
J := I+1;
|
||||
while J < T do
|
||||
@ -440,14 +446,14 @@ begin
|
||||
if BIGINT_COMP_MAX-Tmp < Carry then
|
||||
C := 1;
|
||||
Tmp := Tmp + Carry;
|
||||
W[I + J] := Tmp;
|
||||
W[I + J] := DWord(Tmp and $ffffffff);
|
||||
Carry := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
if C > 0 then
|
||||
Carry := Carry + BIGINT_COMP_RADIX;
|
||||
Inc(J);
|
||||
end;
|
||||
Tmp := W[I+T]+Carry;
|
||||
W[I+T] := Tmp;
|
||||
W[I+T] := DWord(Tmp and $ffffffff);
|
||||
W[I+T+1] := Tmp shr BIGINT_COMP_BIT_SIZE;
|
||||
Inc(I);
|
||||
until I >= T;
|
||||
@ -658,7 +664,7 @@ end;
|
||||
function BIImport(var Context: TBigIntContext; const Data: AnsiString): PBigInt; overload;
|
||||
|
||||
begin
|
||||
Result:=BIImport(Context,TEncoding.UTF8.GetAnsiBytes(Data));
|
||||
Result:=BIImport(Context,@Data[1],length(Data));
|
||||
end;
|
||||
|
||||
|
||||
@ -783,7 +789,7 @@ end;
|
||||
// @IsMod: Determines if this is a normal division (False) or a reduction (True)}
|
||||
function BIDivide(var Context: TBigIntContext; U, V: PBigInt; IsMod: Boolean): PBigInt;
|
||||
|
||||
function BIDivide_V1(V:PBigInt):TBIComponent; inline;
|
||||
function BIDivide_V1(V: PBigInt): TBIComponent; inline;
|
||||
begin // V1 for division
|
||||
Result := V^.Components[V^.Size-1];
|
||||
end;
|
||||
@ -828,7 +834,7 @@ begin
|
||||
TmpU := BIAllocate(Context, N+1);
|
||||
BITrim(V); // Make sure we have no leading 0's
|
||||
D := BIGINT_COMP_RADIX div (TBILongComponent(BIDivide_V1(V)) + 1);
|
||||
FillChar(Quotient^.Components^, Quotient^.Size * BIGINT_COMP_BYTE_SIZE, 0);
|
||||
FillByte(Quotient^.Components^, Quotient^.Size * BIGINT_COMP_BYTE_SIZE, 0);
|
||||
if D > 1 then
|
||||
begin // Normalize
|
||||
U := BIIntMultiply(Context,U,D);
|
||||
@ -852,8 +858,11 @@ begin
|
||||
if (V^.Size > 1) and (BIDivide_V2(V) > 0) then
|
||||
begin
|
||||
// We are implementing the following: if (V2*q_dash > (((U(0)*COMP_RADIX + U(1) - q_dash*V1)*COMP_RADIX) + U(2))) ...
|
||||
Inner := BIGINT_COMP_RADIX * BIDivide_U(TmpU, 0) + BIDivide_U(TmpU, 1) - TBILongComponent(QDash) * BIDivide_V1(V); {Avoid overflow}
|
||||
if (TBILongComponent(BIDivide_V2(V)) * QDash) > (TBILongComponent(Inner) * BIGINT_COMP_RADIX + BIDivide_U(TmpU, 2)) then {Avoid overflow}
|
||||
Inner := (BIGINT_COMP_RADIX * BIDivide_U(TmpU, 0) + BIDivide_U(TmpU, 1)
|
||||
- TBILongComponent(QDash) * BIDivide_V1(V))
|
||||
and $ffffffff; {Avoid overflow}
|
||||
if (TBILongComponent(BIDivide_V2(V)) * QDash) >
|
||||
(TBILongComponent(Inner) * BIGINT_COMP_RADIX + BIDivide_U(TmpU, 2)) then {Avoid overflow}
|
||||
Dec(QDash);
|
||||
end;
|
||||
end;
|
||||
@ -882,7 +891,7 @@ begin
|
||||
BIRelease(Context, V);
|
||||
if IsMod then
|
||||
begin // Get the remainder
|
||||
BIRelease(Context, Quotient);;
|
||||
BIRelease(Context, Quotient);
|
||||
BITrim(U);
|
||||
Result := BIIntDivide(U, D);
|
||||
end else
|
||||
@ -1165,33 +1174,48 @@ begin
|
||||
Result := BIAdd(Context, M2, BIMultiply(Context, Q, H));
|
||||
end;
|
||||
|
||||
// Convert a bigint to a string of hex characters
|
||||
// @Result[BI.Size*2]
|
||||
procedure BItoString(BI: PBigInt; out S: AnsiString);
|
||||
function BIToString(BI: PBigInt): AnsiString;
|
||||
const
|
||||
Digits: Array[0..15] of char = ('0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F');
|
||||
var
|
||||
I,J,K: Integer;
|
||||
Num: TBIComponent;
|
||||
Mask: TBIComponent;
|
||||
begin
|
||||
S:='';
|
||||
Result:='';
|
||||
if BI = nil then
|
||||
Exit;
|
||||
SetLength(S,BI^.Size*BIGINT_COMP_NUM_NIBBLES);
|
||||
SetLength(Result,BI^.Size*BIGINT_COMP_NUM_NIBBLES);
|
||||
K:=1;
|
||||
for I := BI^.Size-1 downto 0 do
|
||||
begin
|
||||
for J := BIGINT_COMP_NUM_NIBBLES-1 downto 0 do
|
||||
begin
|
||||
Mask := $0F shl (J*4);
|
||||
Num := (BI^.Components[I] and Mask) shr (J*4);
|
||||
S[K]:=Digits[Num and $F];
|
||||
Num := (BI^.Components[I] shr (J*4)) and $F;
|
||||
Result[K]:=Digits[Num];
|
||||
inc(K);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function BIToDbgString(BI: PBigInt): AnsiString;
|
||||
var
|
||||
Num, I, J: Integer;
|
||||
begin
|
||||
Result:='';
|
||||
if BI=nil then
|
||||
exit;
|
||||
Num:=0;
|
||||
for I := BI^.Size-1 downto 0 do
|
||||
for J := BIGINT_COMP_NUM_NIBBLES-1 downto 0 do
|
||||
inc(Num, (BI^.Components[I] shr (J*4)) and $F);
|
||||
Result:='{'+IntToStr(Num)+'}'+BIToString(BI);
|
||||
end;
|
||||
|
||||
procedure BIToString(BI: PBigInt; out S: AnsiString);
|
||||
begin
|
||||
S:=BIToString(BI);
|
||||
end;
|
||||
|
||||
// Convert a string of hex characters to a bigint
|
||||
function StringToBI(var Context: TBigIntContext; const Value: AnsiString): PBigInt;
|
||||
const
|
||||
|
Loading…
Reference in New Issue
Block a user