Skip to content

Commit be889f8

Browse files
authored
add runtime S-box selection for GOST hash (#40)
- add runtime S-box selection for GOST hash (TestParamSet / CryptoProParamSet)
1 parent 8554145 commit be889f8

4 files changed

Lines changed: 133 additions & 36 deletions

File tree

HashLib.Tests/src/CryptoTests.pas

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ interface
2121
HlpBlake2SParams,
2222
HlpBlake3,
2323
HlpHashLibTypes,
24+
HlpGost,
2425
TestVectors;
2526

2627
// Crypto
@@ -33,6 +34,15 @@ TTestGost = class(TCryptoAlgorithmTestCase)
3334

3435
end;
3536

37+
type
38+
TTestGost_CryptoProParamSet = class(TCryptoAlgorithmTestCase)
39+
40+
protected
41+
procedure SetUp; override;
42+
procedure TearDown; override;
43+
44+
end;
45+
3646
type
3747
TTestGOST3411_2012_256 = class(TCryptoAlgorithmTestCase)
3848

@@ -922,6 +932,34 @@ procedure TTestGost.TearDown;
922932
inherited;
923933
end;
924934

935+
{ TTestGost_CryptoProParamSet }
936+
937+
procedure TTestGost_CryptoProParamSet.SetUp;
938+
begin
939+
inherited;
940+
HashInstance := THashFactory.TCrypto.CreateGost(TGostSBox.gsbCryptoProParamSet);
941+
HMACInstance := THashFactory.THMAC.CreateHMAC(HashInstance);
942+
HashOfEmptyData :=
943+
'981E5F3CA30C841487830F84FB433E13AC1101569B9C13584AC483234CD656C0';
944+
HashOfDefaultData :=
945+
'7CBD0B4823450AAB69AA9A6A913ACACB147C29AA03FB7B7FDEF9D0107654C7D4';
946+
HashOfOnetoNine :=
947+
'8FC38C2C1911DF7986994F73F5CCA49520224A568F50610B12E47DCFFF4A2D20';
948+
HashOfABCDE :=
949+
'6FEA528ACC59F14581537A5DFB410ADC10983DCC4904DEA87A0AA7AD718D9632';
950+
HashOfDefaultDataHMACWithShortKey :=
951+
'3A85BF8460EAF9430F45926E7585C49EB7E14C5C4200FAB8424B4E837D296CF6';
952+
HashOfDefaultDataHMACWithLongKey :=
953+
'02DB400F81889DECE2DB429A34E1EA15A6C22C3960B14C2EDED079EDA6A86FD6';
954+
end;
955+
956+
procedure TTestGost_CryptoProParamSet.TearDown;
957+
begin
958+
HashInstance := Nil;
959+
HMACInstance := Nil;
960+
inherited;
961+
end;
962+
925963
{ TTestGrindahl256 }
926964

927965
procedure TTestGrindahl256.SetUp;
@@ -4023,6 +4061,7 @@ initialization
40234061
{$IFDEF FPC}
40244062
// Crypto
40254063
RegisterTest(TTestGost);
4064+
RegisterTest(TTestGost_CryptoProParamSet);
40264065
RegisterTest(TTestGOST3411_2012_256);
40274066
RegisterTest(TTestGOST3411_2012_512);
40284067
RegisterTest(TTestGrindahl256);
@@ -4111,6 +4150,7 @@ initialization
41114150
{$ELSE}
41124151
// Crypto
41134152
RegisterTest(TTestGost.Suite);
4153+
RegisterTest(TTestGost_CryptoProParamSet.Suite);
41144154
RegisterTest(TTestGOST3411_2012_256.Suite);
41154155
RegisterTest(TTestGOST3411_2012_512.Suite);
41164156
RegisterTest(TTestGrindahl256.Suite);

HashLib/src/Base/HlpHashFactory.pas

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,9 @@ TCrypto = class sealed(TObject)
365365
class function CreateHaval_4_256(): IHash; static;
366366
class function CreateHaval_5_256(): IHash; static;
367367

368-
class function CreateGost(): IHash; static;
368+
class function CreateGost(ASBoxType: TGostSBox = TGostSBox.gsbTestParamSet)
369+
: IHash; static;
370+
class function CreateGost_CryptoProParamSet(): IHash; static;
369371

370372
// Streebog 256
371373
class function CreateGOST3411_2012_256(): IHash; static;
@@ -855,9 +857,14 @@ class function THashFactory.THash128.CreateMurmurHash3_x64_128: IHashWithKey;
855857

856858
{ THashFactory.TCrypto }
857859

858-
class function THashFactory.TCrypto.CreateGost: IHash;
860+
class function THashFactory.TCrypto.CreateGost(ASBoxType: TGostSBox): IHash;
861+
begin
862+
Result := TGost.Create(ASBoxType);
863+
end;
864+
865+
class function THashFactory.TCrypto.CreateGost_CryptoProParamSet: IHash;
859866
begin
860-
Result := TGost.Create();
867+
Result := TGost.Create(TGostSBox.gsbCryptoProParamSet);
861868
end;
862869

863870
class function THashFactory.TCrypto.CreateGOST3411_2012_256: IHash;

HashLib/src/Crypto/HlpGost.pas

Lines changed: 80 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,28 @@ interface
1515

1616
type
1717

18+
{$SCOPEDENUMS ON}
19+
TGostSBox = (gsbTestParamSet, gsbCryptoProParamSet);
20+
{$SCOPEDENUMS OFF}
21+
1822
TGost = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
1923

2024
strict private
2125

2226
class var
2327

24-
FSBox1, FSBox2, FSBox3, FSBox4: THashLibUInt32Array;
28+
FSBox1_Test, FSBox2_Test, FSBox3_Test, FSBox4_Test: THashLibUInt32Array;
29+
FSBox1_CryptoPro, FSBox2_CryptoPro, FSBox3_CryptoPro,
30+
FSBox4_CryptoPro: THashLibUInt32Array;
2531

2632
var
2733
FState, FHash: THashLibUInt32Array;
34+
FSBox1, FSBox2, FSBox3, FSBox4: THashLibUInt32Array;
35+
FSBoxType: TGostSBox;
2836

2937
procedure Compress(APtr: PCardinal);
38+
class procedure ComputeSBoxes(const ASBox: THashLibMatrixUInt32Array;
39+
out ASBox1, ASBox2, ASBox3, ASBox4: THashLibUInt32Array); static;
3040
class constructor Gost();
3141

3242
strict protected
@@ -36,7 +46,7 @@ TGost = class sealed(TBlockHash, ICryptoNotBuildIn, ITransformBlock)
3646
AIndex: Int32); override;
3747

3848
public
39-
constructor Create();
49+
constructor Create(ASBoxType: TGostSBox = TGostSBox.gsbTestParamSet);
4050
procedure Initialize(); override;
4151
function Clone(): IHash; override;
4252

@@ -50,7 +60,7 @@ function TGost.Clone(): IHash;
5060
var
5161
LHashInstance: TGost;
5262
begin
53-
LHashInstance := TGost.Create();
63+
LHashInstance := TGost.Create(FSBoxType);
5464
LHashInstance.FState := System.Copy(FState);
5565
LHashInstance.FHash := System.Copy(FHash);
5666
LHashInstance.FBuffer := FBuffer.Clone();
@@ -336,11 +346,60 @@ procedure TGost.Compress(APtr: PCardinal);
336346

337347
end;
338348

339-
constructor TGost.Create;
349+
class procedure TGost.ComputeSBoxes(const ASBox: THashLibMatrixUInt32Array;
350+
out ASBox1, ASBox2, ASBox3, ASBox4: THashLibUInt32Array);
351+
var
352+
LIdx, LA, LB: Int32;
353+
ax, bx, cx, dx: UInt32;
354+
begin
355+
System.SetLength(ASBox1, 256);
356+
System.SetLength(ASBox2, 256);
357+
System.SetLength(ASBox3, 256);
358+
System.SetLength(ASBox4, 256);
359+
360+
LIdx := 0;
361+
362+
for LA := 0 to 15 do
363+
begin
364+
ax := ASBox[1, LA] shl 15;
365+
bx := ASBox[3, LA] shl 23;
366+
cx := ASBox[5, LA];
367+
cx := TBits.RotateRight32(cx, 1);
368+
dx := ASBox[7, LA] shl 7;
369+
370+
for LB := 0 to 15 do
371+
begin
372+
ASBox1[LIdx] := ax or (ASBox[0, LB] shl 11);
373+
ASBox2[LIdx] := bx or (ASBox[2, LB] shl 19);
374+
ASBox3[LIdx] := cx or (ASBox[4, LB] shl 27);
375+
ASBox4[LIdx] := dx or (ASBox[6, LB] shl 3);
376+
System.Inc(LIdx);
377+
end;
378+
end;
379+
end;
380+
381+
constructor TGost.Create(ASBoxType: TGostSBox);
340382
begin
341383
Inherited Create(32, 32);
342384
System.SetLength(FState, 8);
343385
System.SetLength(FHash, 8);
386+
FSBoxType := ASBoxType;
387+
case ASBoxType of
388+
TGostSBox.gsbTestParamSet:
389+
begin
390+
FSBox1 := FSBox1_Test;
391+
FSBox2 := FSBox2_Test;
392+
FSBox3 := FSBox3_Test;
393+
FSBox4 := FSBox4_Test;
394+
end;
395+
TGostSBox.gsbCryptoProParamSet:
396+
begin
397+
FSBox1 := FSBox1_CryptoPro;
398+
FSBox2 := FSBox2_CryptoPro;
399+
FSBox3 := FSBox3_CryptoPro;
400+
FSBox4 := FSBox4_CryptoPro;
401+
end;
402+
end;
344403
end;
345404

346405
procedure TGost.Finish;
@@ -375,9 +434,8 @@ function TGost.GetResult: THashLibByteArray;
375434
class constructor TGost.Gost;
376435
var
377436
LSBox: THashLibMatrixUInt32Array;
378-
LIdx, LA, LB: Int32;
379-
ax, bx, cx, dx: UInt32;
380437
begin
438+
// DSbox_Test (id-GostR3411-94-TestParamSet)
381439
LSBox := THashLibMatrixUInt32Array.Create(THashLibUInt32Array.Create(4, 10, 9,
382440
2, 13, 8, 0, 14, 6, 11, 1, 12, 7, 15, 5, 3), THashLibUInt32Array.Create(14,
383441
11, 4, 12, 6, 13, 15, 10, 2, 3, 8, 1, 0, 7, 5, 9),
@@ -389,31 +447,22 @@ function TGost.GetResult: THashLibByteArray;
389447
9, 0, 10, 14, 7, 6, 8, 2, 12), THashLibUInt32Array.Create(1, 15, 13, 0, 5,
390448
7, 10, 4, 9, 2, 3, 14, 6, 11, 8, 12));
391449

392-
System.SetLength(FSBox1, 256);
393-
System.SetLength(FSBox2, 256);
394-
System.SetLength(FSBox3, 256);
395-
System.SetLength(FSBox4, 256);
396-
397-
LIdx := 0;
398-
399-
for LA := 0 to 15 do
400-
begin
401-
ax := LSBox[1, LA] shl 15;
402-
bx := LSBox[3, LA] shl 23;
403-
cx := LSBox[5, LA];
404-
cx := TBits.RotateRight32(cx, 1);
405-
dx := LSBox[7, LA] shl 7;
406-
407-
for LB := 0 to 15 do
408-
begin
409-
FSBox1[LIdx] := ax or (LSBox[0, LB] shl 11);
410-
FSBox2[LIdx] := bx or (LSBox[2, LB] shl 19);
411-
FSBox3[LIdx] := cx or (LSBox[4, LB] shl 27);
412-
FSBox4[LIdx] := dx or (LSBox[6, LB] shl 3);
413-
System.Inc(LIdx);
414-
end;
415-
end;
416-
450+
ComputeSBoxes(LSBox, FSBox1_Test, FSBox2_Test, FSBox3_Test, FSBox4_Test);
451+
452+
// DSbox_A (id-GostR3411-94-CryptoProParamSet)
453+
LSBox := THashLibMatrixUInt32Array.Create(THashLibUInt32Array.Create(10, 4, 5,
454+
6, 8, 1, 3, 7, 13, 12, 14, 0, 9, 2, 11, 15), THashLibUInt32Array.Create(5,
455+
15, 4, 0, 2, 13, 11, 9, 1, 7, 6, 3, 12, 14, 10, 8),
456+
THashLibUInt32Array.Create(7, 15, 12, 14, 9, 4, 1, 0, 3, 11, 5, 2, 6, 10, 8,
457+
13), THashLibUInt32Array.Create(4, 10, 7, 12, 0, 15, 2, 8, 14, 1, 6, 5, 13,
458+
11, 9, 3), THashLibUInt32Array.Create(7, 6, 4, 11, 9, 12, 2, 10, 1, 8, 0,
459+
14, 15, 13, 3, 5), THashLibUInt32Array.Create(7, 6, 2, 4, 13, 9, 15, 0, 10,
460+
1, 5, 11, 8, 14, 12, 3), THashLibUInt32Array.Create(13, 14, 4, 1, 7, 0, 5,
461+
10, 3, 12, 8, 15, 6, 2, 9, 11), THashLibUInt32Array.Create(1, 3, 10, 9, 5,
462+
11, 4, 15, 8, 6, 7, 14, 13, 0, 2, 12));
463+
464+
ComputeSBoxes(LSBox, FSBox1_CryptoPro, FSBox2_CryptoPro, FSBox3_CryptoPro,
465+
FSBox4_CryptoPro);
417466
end;
418467

419468
procedure TGost.Initialize;

HashLib/src/Packages/FPC/HashLib4PascalPackage.lpk

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<CONFIG>
3-
<Package Version="4">
3+
<Package Version="5">
44
<PathDelim Value="\"/>
55
<Name Value="HashLib4PascalPackage"/>
66
<Type Value="RunTimeOnly"/>
@@ -22,7 +22,7 @@
2222
<Description Value="HashLib4Pascal is a Delphi/FPC compatible library that provides an easy to use interface for computing hashes and checksums of strings (with a specified encoding), files, streams, byte arrays and untyped data to mention but a few.
2323
"/>
2424
<License Value="MIT License"/>
25-
<Version Major="4" Minor="2"/>
25+
<Version Major="4" Minor="3"/>
2626
<Files Count="104">
2727
<Item1>
2828
<Filename Value="..\..\Base\HlpHash.pas"/>
@@ -441,6 +441,7 @@
441441
<UnitName Value="HlpBlake3"/>
442442
</Item104>
443443
</Files>
444+
<CompatibilityMode Value="True"/>
444445
<LazDoc PackageName="(default)"/>
445446
<RequiredPkgs Count="1">
446447
<Item1>

0 commit comments

Comments
 (0)