source upload

This commit is contained in:
Razor12911
2022-01-17 22:16:47 +02:00
parent 12936d065b
commit 098e8c48de
1778 changed files with 1206749 additions and 0 deletions

View File

@@ -0,0 +1,287 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECBaseClass;
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
interface
uses
System.SysUtils, System.Classes, Generics.Collections,
{$IFDEF DUnitX}
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
DECBaseClass;
type
// Test methods for class TDECClassList
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTDECClassList = class(TTestCase)
strict private
FDECFormatClassList : TDECClassList;
FDECHashClassList : TDECClassList;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestClassByName;
procedure TestClassByIdentity;
procedure TestGetClassList;
end;
// Test methods for class TDECObject
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTDECObject = class(TTestCase)
strict private
FDECObject: TDECObject;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestIdentity;
procedure TestRegisterClass;
procedure TestUnregisterClass;
procedure TestGetShortClassNameFromName;
procedure TestGetShortClassNameFromName2;
procedure TestGetShortClassName;
procedure TestGetShortClassName2;
procedure TestGetShortClassNameDoubleUnderscore;
end;
implementation
uses
DECFormat,
DECHash;
procedure TestTDECClassList.SetUp;
begin
FDECFormatClassList := TDECClassList.Create;
FDECFormatClassList.Add(TFormat_HEX.Identity, TFormat_HEX);
FDECFormatClassList.Add(TFormat_HEXL.Identity, TFormat_HEXL);
FDECFormatClassList.Add(TFormat_DECMIME32.Identity, TFormat_DECMIME32);
FDECFormatClassList.Add(TFormat_Base64.Identity, TFormat_Base64);
FDECFormatClassList.Add(TFormat_UU.Identity, TFormat_UU);
FDECFormatClassList.Add(TFormat_XX.Identity, TFormat_XX);
FDECFormatClassList.Add(TFormat_ESCAPE.Identity, TFormat_ESCAPE);
FDECHashClassList := TDECClassList.Create;
FDECHashClassList.Add(THash_MD5.Identity, THash_MD5);
FDECHashClassList.Add(THash_SHA256.Identity, THash_SHA256);
FDECHashClassList.Add(THash_SHA3_256.Identity, THash_SHA3_256);
end;
procedure TestTDECClassList.TearDown;
begin
FDECFormatClassList.Free;
FDECHashClassList.Free;
end;
procedure TestTDECClassList.TestClassByIdentity;
var
ReturnValue: TDECClass;
begin
ReturnValue := FDECFormatClassList.ClassByIdentity(TFormat_HEX.Identity);
CheckEquals(ReturnValue, TFormat_HEX);
CheckNotEquals(ReturnValue = TFormat_HEXL, true);
ReturnValue := FDECFormatClassList.ClassByIdentity(TFormat_Base64.Identity);
CheckEquals(ReturnValue, TFormat_Base64);
ReturnValue := FDECFormatClassList.ClassByIdentity(TFormat_ESCAPE.Identity);
CheckEquals(ReturnValue, TFormat_ESCAPE);
ReturnValue := FDECHashClassList.ClassByIdentity(THash_MD5.Identity);
CheckEquals(ReturnValue, THash_MD5);
ReturnValue := FDECHashClassList.ClassByIdentity(THash_SHA256.Identity);
CheckEquals(ReturnValue, THash_SHA256);
ReturnValue := FDECHashClassList.ClassByIdentity(THash_SHA3_256.Identity);
CheckEquals(ReturnValue, THash_SHA3_256);
end;
procedure TestTDECClassList.TestClassByName;
var
ReturnValue: TDECClass;
begin
ReturnValue := FDECFormatClassList.ClassByName('TFormat_HEX');
CheckEquals(ReturnValue, TFormat_HEX);
ReturnValue := FDECFormatClassList.ClassByName('TFormat_hex');
CheckEquals(ReturnValue, TFormat_HEX);
ReturnValue := FDECFormatClassList.ClassByName('TFormat_HEXL');
CheckEquals(ReturnValue, TFormat_HEXL);
ReturnValue := FDECFormatClassList.ClassByName('TFormat_ESCAPE');
CheckEquals(ReturnValue, TFormat_ESCAPE);
ReturnValue := FDECHashClassList.ClassByName('THash_MD5');
CheckEquals(ReturnValue, THash_MD5);
ReturnValue := FDECHashClassList.ClassByName('THash_SHA256');
CheckEquals(ReturnValue, THash_SHA256);
ReturnValue := FDECHashClassList.ClassByName('THash_SHA3_256');
CheckEquals(ReturnValue, THash_SHA3_256);
end;
procedure TestTDECClassList.TestGetClassList;
var
sl : TStringList;
begin
sl := TStringList.Create;
try
FDECFormatClassList.GetClassList(sl);
CheckEquals(sl.Count, 7, 'Wrong number of registered classes');
CheckEquals(sl.IndexOf('TFormat_HEX') >= 0, true);
CheckEquals(sl.IndexOf('TFormat_HEXL') >= 0, true);
CheckEquals(sl.IndexOf('TFormat_DECMIME32') >= 0, true);
CheckEquals(sl.IndexOf('TFormat_Base64') >= 0, true);
CheckEquals(sl.IndexOf('TFormat_UU') >= 0, true);
CheckEquals(sl.IndexOf('TFormat_XX') >= 0, true);
CheckEquals(sl.IndexOf('TFormat_ESCAPE') >= 0, true);
finally
sl.Free;
end;
end;
procedure TestTDECObject.TestGetShortClassName;
begin
CheckEquals(TFormat_HEXL.GetShortClassName,
'HEXL');
end;
procedure TestTDECObject.TestGetShortClassName2;
begin
CheckEquals(THash_MD5.GetShortClassName,
'MD5');
end;
procedure TestTDECObject.TestGetShortClassNameDoubleUnderscore;
begin
CheckEquals(THash_SHA256.GetShortClassName,
'SHA256');
CheckEquals(THash_SHA3_256.GetShortClassName,
'SHA3_256');
end;
procedure TestTDECObject.TestGetShortClassNameFromName;
begin
CheckEquals(TDECClass.GetShortClassNameFromName('TFormat_HEXL'),
'HEXL');
end;
procedure TestTDECObject.TestGetShortClassNameFromName2;
begin
CheckEquals(TDECClass.GetShortClassNameFromName('TCipher_Skipjack'),
'Skipjack');
end;
procedure TestTDECObject.SetUp;
begin
FDECObject := TDECObject.Create;
end;
procedure TestTDECObject.TearDown;
begin
FDECObject.Free;
FDECObject := nil;
end;
procedure TestTDECObject.TestIdentity;
var
ReturnValue: Int64;
begin
// We do test the normal identity format, not the "special" one from DEC V5.2
ReturnValue := FDECObject.Identity;
CheckEquals(3520275915, ReturnValue, 'Wrong Identity Value');
ReturnValue := TFormat_Hex.Identity;
CheckEquals(3786628779, ReturnValue, 'Wrong Identity Value');
end;
procedure TestTDECObject.TestRegisterClass;
var
ClassList : TDECClassList;
ReturnValue : Boolean;
begin
ClassList := TDECClassList.Create(4);
try
FDECObject.RegisterClass(ClassList);
ReturnValue := ClassList.ContainsValue(TDECObject);
CheckEquals(true, ReturnValue, 'Class TDECObject has not been registered in class list');
CheckEquals(1, ClassList.Count, 'Invalid number of registered classes');
TFormat_HEX.RegisterClass(ClassList);
ReturnValue := ClassList.ContainsValue(TFormat_HEX);
CheckEquals(true, ReturnValue, 'Class TFormat_HEX has not been registered in class list');
ReturnValue := ClassList.ContainsValue(TDECObject);
CheckEquals(true, ReturnValue, 'Class TDECObject has not been registered in class list');
CheckEquals(2, ClassList.Count, 'Invalid number of registered classes');
finally
ClassList.Free;
end;
end;
procedure TestTDECObject.TestUnregisterClass;
var
ClassList : TDECClassList;
ReturnValue : Boolean;
begin
ClassList := TDECClassList.Create(4);
try
FDECObject.RegisterClass(ClassList);
TFormat_HEX.RegisterClass(ClassList);
CheckEquals(2, ClassList.Count, 'Invalid number of registered classes');
FDECObject.UnregisterClass(ClassList);
ReturnValue := ClassList.ContainsValue(TFormat_HEX);
CheckEquals(true, ReturnValue, 'Wrong class has ben deregistered from class list');
CheckEquals(1, ClassList.Count, 'Invalid number of registered classes');
finally
ClassList.Free;
end;
end;
initialization
// Register any test cases with the test runner
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TestTDECClassList);
TDUnitX.RegisterTestFixture(TestTDECObject);
{$ELSE}
RegisterTests('DECBaseClass', [TestTDECClassList.Suite, TestTDECObject.Suite]);
{$ENDIF}
end.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,690 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECCipherFormats;
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
interface
uses
{$IFDEF DUnitX}
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
System.Classes, System.SysUtils,
DECCipherBase, DECCiphers, DECCipherFormats;
type
/// <summary>
/// All known testvectors use the same filler byte and the same cmCTSx mode
/// </summary>
TCipherTestData = record
PlainTextData : RawByteString;
EncryptedTextData : RawByteString;
EncryptedUTF16TextData : string;
Key : RawByteString;
InitVector : RawByteString;
Filler : Byte;
Mode : TCipherMode;
end;
// Test methods for class TDECClassList
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTDECCipherFormats = class(TTestCase)
strict private
FCipherTwoFish : TDECFormattedCipher;
/// <summary>
/// Array with the test data
/// </summary>
FTestData : array of TCipherTestData;
/// <summary>
/// Ensures that a given key is not longer then the KeySize passed
/// </summary>
/// <param name="Key">
/// Key to be checked. if it is longer than KeySize it will be cut off.
/// </param>
/// <param name="KeySize">
/// Maximum size of a key for the given cipher algorithm
/// </param>
procedure LimitKeyLength(var Key:RawByteString; KeySize: Integer);
/// <summary>
/// Initialization routine which sets the properties of the crypto object
/// as specified in the test data record with the given index.
/// </summary>
/// <param name="Index">
/// Index of the test data record to be used for this test run initialization
/// </param>
procedure Init(Index: Integer);
{$IFDEF ANSISTRINGSUPPORTED}
/// <summary>
/// Copies the bytes of the buffer into an AnsiString
/// </summary>
/// <param name="Bytes">
/// Byte buffer to be converted to an AnsiString
/// </param>
/// <returns>
/// AnsiString converted buffer. If the buffer passed has a length of 0
/// an empty string will be returned
/// </returns>
function AnsiStringOf(const Bytes: TBytes): AnsiString;
{$ENDIF}
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestEncodeBytes;
procedure TestDecodeBytes;
procedure TestEncodeStream;
procedure TestDecodeStream;
// procedure TestCalculateStringData;
// Currently commented out because it would require a file as external dependency
// procedure TestEncodeFile(const SourceFileName, DestFileName: string;
// const Progress: IDECProgress = nil);
// procedure TestDecodeFile(const SourceFileName, DestFileName: string;
// const Progress: IDECProgress = nil);
procedure TestEncodeStringToBytes;
procedure TestEncodeRawByteStringToBytes;
procedure TestEncodeStringToString;
procedure TestEncodeRawByteStringToString;
procedure TestDecodeStringToBytes;
procedure TestDecodeRawByteStringToBytes;
procedure TestDecodeStringToString;
procedure TestDecodeRawByteStringToString;
{$IFDEF ANSISTRINGSUPPORTED}
procedure TestEncodeAnsiStringToBytes;
procedure TestEncodeAnsiStringToString;
procedure TestDecodeAnsiStringToBytes;
procedure TestDecodeAnsiStringToString;
{$ENDIF}
{$IFNDEF NEXTGEN}
procedure TestEncodeWideStringToBytes;
procedure TestEncodeWideStringToString;
procedure TestDecodeWideStringToBytes;
procedure TestDecodeWideStringToString;
{$ENDIF}
end;
implementation
uses
DECBaseClass, DECFormat, DECUtil;
{ TestTDECCipherFormats }
procedure TestTDECCipherFormats.LimitKeyLength(var Key: RawByteString;
KeySize: Integer);
begin
if Length(Key) > KeySize then
Delete(Key, KeySize + 1, length(Key));
end;
{$IFDEF ANSISTRINGSUPPORTED}
function TestTDECCipherFormats.AnsiStringOf(const Bytes: TBytes): AnsiString;
begin
if Assigned(Bytes) then
begin
SetLength(Result, length(Bytes));
{$IF CompilerVersion >= 24.0}
Move(Bytes[0], Result[low(Result)], length(Bytes));
{$ELSE}
Move(Bytes[0], Result[1], length(Bytes));
{$IFEND}
end
else
Result := '';
end;
{$ENDIF}
procedure TestTDECCipherFormats.TestDecodeRawByteStringToBytes;
var
i : Integer;
result : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
result := FCipherTwoFish.DecodeStringToBytes(TFormat_HexL.Decode(FTestData[i].EncryptedTextData));
CheckEquals(FTestData[i].PlainTextData,
RawByteString(StringOf(result)),
'Failure in TestDecodeRawByteStringToBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestDecodeStringToBytes;
var
i : Integer;
result : TBytes;
InputStr : string;
ExpStr : string;
ResStr : string;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
result := TFormat_HexL.Decode(BytesOf(FTestData[i].EncryptedUTF16TextData));
InputStr := StringOf(result);
result := FCipherTwoFish.DecodeStringToBytes(InputStr);
ResStr := WideStringOf(result);
ExpStr := string(FTestData[i].PlainTextData);
CheckEquals(ExpStr, ResStr, 'Failure in TestDecodeStringToBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.Init(Index: Integer);
begin
LimitKeyLength(FTestData[Index].Key, FCipherTwoFish.Context.KeySize);
FCipherTwoFish.Mode := FTestData[Index].Mode;
FCipherTwoFish.Init(BytesOf(FTestData[Index].Key),
BytesOf(FTestData[Index].InitVector),
FTestData[Index].Filler);
end;
procedure TestTDECCipherFormats.SetUp;
begin
FCipherTwoFish := TCipher_Twofish.Create;
SetLength(FTestData, 1);
FTestData[0].EncryptedTextData := 'e81674f9bc69442188c949bb52e1e47874171177e99' +
'dbbe9880875094f8dfe21';
FTestData[0].PlainTextData := TFormat_ESCAPE.Decode('\x30\x44\xED\x6E\x45\xA4' +
'\x96\xF5\xF6\x35\xA2\xEB' +
'\x3D\x1A\x5D\xD6\xCB\x1D' +
'\x09\x82\x2D\xBD\xF5\x60' +
'\xC2\xB8\x58\xA1\x91\xF9' +
'\x81\xB1');
// In this first test case simply the RawByteString based test data filled up
// with a 0 in each char to form a UTF16 char
FTestData[0].EncryptedUTF16TextData := 'ebc6a21d2a7d8341f643a0bf494057d5a5c38f' +
'0ae72bd4ced90b5e6467de24c7d06b88207a41' +
'f9d32126e38ab49024c98788b8619c3cbeb7fa' +
'ad2cd9b7e40480';
FTestData[0].Key := 'TCipher_Twofish';
FTestData[0].InitVector := '';
FTestData[0].Filler := $FF;
FTestData[0].Mode := cmCTSx;
end;
procedure TestTDECCipherFormats.TearDown;
begin
FCipherTwoFish.Free;
end;
{$IFDEF ANSISTRINGSUPPORTED}
procedure TestTDECCipherFormats.TestDecodeAnsiStringToBytes;
var
i : Integer;
result : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
result := FCipherTwoFish.DecodeStringToBytes(AnsiString(TFormat_HexL.Decode(FTestData[i].EncryptedTextData)));
CheckEquals(FTestData[i].PlainTextData,
AnsiStringOf(result),
'Failure in TestDecodeAnsiStringToBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestDecodeAnsiStringToString;
var
i : Integer;
result : AnsiString;
InputStr : AnsiString;
StrArr : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
StrArr := BytesOf(FTestData[i].EncryptedTextData);
StrArr := TFormat_HexL.Decode(StrArr);
InputStr := AnsiStringOf(StrArr);
result := FCipherTwoFish.DecodeStringToString(InputStr);
CheckEquals(AnsiString(FTestData[i].PlainTextData),
result,
'Failure in TestDecodeAnsiStringToString ' + IntToStr(i));
end;
end;
{$ENDIF}
procedure TestTDECCipherFormats.TestDecodeBytes;
var
i : Integer;
result : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
result := FCipherTwoFish.DecodeBytes(
BytesOf(TFormat_HexL.Decode(FTestData[i].EncryptedTextData)));
CheckEquals(FTestData[i].PlainTextData,
RawByteString(StringOf(result)),
'Failure in TestDecodeBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestDecodeRawByteStringToString;
var
i : Integer;
result : RawByteString;
InputStr : RawByteString;
StrArr : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
StrArr := BytesOf(FTestData[i].EncryptedTextData);
StrArr := TFormat_HexL.Decode(StrArr);
InputStr := BytesToRawString(StrArr);
result := FCipherTwoFish.DecodeStringToString(InputStr);
CheckEquals(FTestData[i].PlainTextData,
result,
'Failure in TestDecodeRawByteStringToString ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestDecodeStream;
var
Src, Dest : TMemoryStream;
SrcBuf : TBytes;
i : Integer;
result : TBytes;
begin
Src := TMemoryStream.Create;
try
Dest := TMemoryStream.Create;
try
for i := 0 to High(FTestData) do
begin
Init(i);
SrcBuf := BytesOf(TFormat_HexL.Decode(FTestData[i].EncryptedTextData));
Src.Clear;
{$IF CompilerVersion >= 25.0}
Src.WriteData(SrcBuf, length(SrcBuf));
{$ELSE}
Src.Write(SrcBuf[0], Length(SrcBuf));
{$IFEND}
Src.Seek(0, TSeekOrigin.soBeginning);
FCipherTwoFish.DecodeStream(Src, Dest, Src.Size, nil);
Dest.Seek(0, TSeekOrigin.soBeginning);
SetLength(result, Dest.Size);
{$IF CompilerVersion >= 25.0}
Dest.Read(result, 0, Dest.Size);
{$ELSE}
Dest.Read(Result[0], Dest.Size);
{$IFEND}
CheckEquals(FTestData[i].PlainTextData,
RawByteString(StringOf(result)),
'Failure in TestDecodeStream ' + IntToStr(i));
end;
finally
Dest.Free;
end;
finally
Src.Free;
end;
end;
procedure TestTDECCipherFormats.TestDecodeStringToString;
var
i : Integer;
result : string;
InputStr : string;
StrArr : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
StrArr := BytesOf(FTestData[i].EncryptedUTF16TextData);
StrArr := TFormat_HexL.Decode(StrArr);
InputStr := StringOf(StrArr);
result := FCipherTwoFish.DecodeStringToString(InputStr);
CheckEquals(string(FTestData[i].PlainTextData),
result,
'Failure in TestDecodeStringToString ' + IntToStr(i));
end;
end;
{$IFNDEF NEXTGEN}
procedure TestTDECCipherFormats.TestDecodeWideStringToBytes;
var
i : Integer;
result : TBytes;
InputStr : WideString;
ExpStr : WideString;
ResStr : WideString;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
result := TFormat_HexL.Decode(BytesOf(FTestData[i].EncryptedUTF16TextData));
InputStr := StringOf(result);
result := FCipherTwoFish.DecodeStringToBytes(InputStr);
ResStr := WideStringOf(result);
ExpStr := string(FTestData[i].PlainTextData);
CheckEquals(ExpStr, ResStr, 'Failure in TestDecodeWideStringToBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestDecodeWideStringToString;
var
i : Integer;
result : WideString;
InputStr : WideString;
StrArr : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
StrArr := BytesOf(FTestData[i].EncryptedUTF16TextData);
StrArr := TFormat_HexL.Decode(StrArr);
InputStr := StringOf(StrArr);
result := FCipherTwoFish.DecodeStringToString(InputStr);
CheckEquals(string(FTestData[i].PlainTextData),
string(result),
'Failure in TestDecodeWideStringToString ' + IntToStr(i));
end;
end;
{$ENDIF}
{$IFDEF NEXTGEN}
procedure TestTDECCipherFormats.TestEncodeAnsiStringToBytes;
var
i : Integer;
result : TBytes;
InputStr : AnsiString;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
InputStr := AnsiString(FTestData[i].PlainTextData);
result := FCipherTwoFish.EncodeStringToBytes(InputStr);
CheckEquals(FTestData[i].EncryptedTextData,
AnsiStringOf(TFormat_HexL.Encode(result)),
'Failure in TestEncodeAnsiStringToBytes ' + IntToString(i));
end;
end;
procedure TestTDECCipherFormats.TestEncodeAnsiStringToString;
var
i : Integer;
result : AnsiString;
InputStr : AnsiString;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
InputStr := FTestData[i].PlainTextData;
result := FCipherTwoFish.EncodeStringToString(InputStr);
CheckEquals(AnsiString(FTestData[i].EncryptedTextData),
AnsiStringOf(TFormat_HexL.Encode(BytesOf(result))),
'Failure in TestEncodeAnsiStringToString ' + IntToString(i));
end;
end;
{$ENDIF}
procedure TestTDECCipherFormats.TestEncodeBytes;
var
i : Integer;
result : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
result := FCipherTwoFish.EncodeBytes(BytesOf(FTestData[i].PlainTextData));
CheckEquals(FTestData[i].EncryptedTextData,
RawByteString(StringOf(TFormat_HexL.Encode(result))),
'Failure in TestEncodeBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestEncodeRawByteStringToBytes;
var
i : Integer;
result : TBytes;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
result := FCipherTwoFish.EncodeStringToBytes(FTestData[i].PlainTextData);
CheckEquals(FTestData[i].EncryptedTextData,
RawByteString(StringOf(TFormat_HexL.Encode(result))),
'Failure in TestEncodeRawByteStringToBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestEncodeRawByteStringToString;
var
i : Integer;
result : RawByteString;
InputStr : RawByteString;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
InputStr := FTestData[i].PlainTextData;
result := FCipherTwoFish.EncodeStringToString(InputStr);
CheckEquals(FTestData[i].EncryptedTextData,
BytesToRawString(TFormat_HexL.Encode(BytesOf(result))),
'Failure in TestEncodeRawByteStringToString ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestEncodeStream;
var
Src, Dest : TMemoryStream;
SrcBuf : TBytes;
i : Integer;
result : TBytes;
begin
Src := TMemoryStream.Create;
try
Dest := TMemoryStream.Create;
try
for i := 0 to High(FTestData) do
begin
Init(i);
SrcBuf := BytesOf(FTestData[i].PlainTextData);
Src.Clear;
{$IF CompilerVersion >= 25.0}
Src.WriteData(SrcBuf, length(SrcBuf));
{$ELSE}
Src.Write(SrcBuf[0], Length(SrcBuf));
{$IFEND}
Src.Seek(0, TSeekOrigin.soBeginning);
FCipherTwoFish.EncodeStream(Src, Dest, Src.Size, nil);
Dest.Seek(0, TSeekOrigin.soBeginning);
SetLength(result, Dest.Size);
{$IF CompilerVersion >= 25.0}
Dest.Read(result, 0, Dest.Size);
{$ELSE}
Dest.Read(Result[0], Dest.Size);
{$IFEND}
CheckEquals(FTestData[i].EncryptedTextData,
RawByteString(StringOf(TFormat_HexL.Encode(result))),
'Failure in TestEncodeStream ' + IntToStr(i));
end;
finally
Dest.Free;
end;
finally
Src.Free;
end;
end;
procedure TestTDECCipherFormats.TestEncodeStringToBytes;
var
i : Integer;
result : TBytes;
InputStr : string;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
InputStr := string(FTestData[i].PlainTextData);
result := FCipherTwoFish.EncodeStringToBytes(InputStr);
CheckEquals(FTestData[i].EncryptedUTF16TextData,
string(RawByteString(StringOf(TFormat_HexL.Encode(result)))),
'Failure in TestEncodeStringToBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestEncodeStringToString;
var
i : Integer;
result : string;
InputStr : string;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
InputStr := string(FTestData[i].PlainTextData);
result := FCipherTwoFish.EncodeStringToString(InputStr);
CheckEquals(FTestData[i].EncryptedUTF16TextData,
StringOf(TFormat_HexL.Encode(BytesOf(result))),
'Failure in TestEncodeStringToString ' + IntToStr(i));
end;
end;
{$IFNDEF NEXTGEN}
procedure TestTDECCipherFormats.TestEncodeWideStringToBytes;
var
i : Integer;
result : TBytes;
InputStr : WideString;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
InputStr := WideString(FTestData[i].PlainTextData);
result := FCipherTwoFish.EncodeStringToBytes(InputStr);
CheckEquals(FTestData[i].EncryptedUTF16TextData,
string(RawByteString(StringOf(TFormat_HexL.Encode(result)))),
'Failure in TestEncodeWideStringToBytes ' + IntToStr(i));
end;
end;
procedure TestTDECCipherFormats.TestEncodeWideStringToString;
var
i : Integer;
result : WideString;
InputStr : WideString;
begin
for i := 0 to High(FTestData) do
begin
Init(i);
InputStr := WideString(FTestData[i].PlainTextData);
result := FCipherTwoFish.EncodeStringToString(InputStr);
CheckEquals(FTestData[i].EncryptedUTF16TextData,
StringOf(TFormat_HexL.Encode(BytesOf(result))),
'Failure in TestEncodeWideStringToString ' + IntToStr(i));
end;
end;
{$ENDIF}
initialization
// Register any test cases with the test runner
{$IFNDEF DUnitX}
RegisterTest(TestTDECCipherFormats.Suite);
{$ELSE}
TDUnitX.RegisterTestFixture(TestTDECCipherFormats);
{$ENDIF}
end.

View File

@@ -0,0 +1,510 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECCipherModes;
interface
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
uses
{$IFDEF DUnitX}
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
System.SysUtils,
DECCipherBase, DECCipherModes, DECCipherFormats, DECCiphers;
type
/// <summary>
/// Class reference to be abe to specify duifferent cipher classes for
/// carrying out the different tests.
/// </summary>
TFormattedCipherClass = class of TDECFormattedCipher;
/// <summary>
/// One entry in a list of tests
/// </summary>
TTestEntry = record
/// <summary>
/// Input value, needs to be of block size length or a multiple of it
/// </summary>
Input : RawByteString;
/// <summary>
/// Expected output value, needs to be of block size length or a multiple of it
/// </summary>
Output : RawByteString;
/// <summary>
/// Expected output value which is used if Output is empty. Contains the
/// output in hexadecimal notation.
/// </summary>
OutputHex : RawByteString;
/// <summary>
/// Init Vektor f<>r den ersten Test
/// </summary>
InitVector : RawByteString;
/// <summary>
/// Class reference for the cipher class used for this test.
/// </summary>
TestClass : TFormattedCipherClass;
/// <summary>
/// Block concatenating/padding mode
/// </summary>
Mode : TCipherMode;
end;
/// <summary>
/// Prototype for a function to be passed to the generic test method
/// </summary>
TTestFunction = procedure(Source, Dest: PByteArray; Size: Integer) of object;
/// <summary>
/// Testmethoden f<>r Klasse TDECCipherModes
/// </summary>
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTDECCipherModes = class(TTestCase)
strict private
const
Data: array[1..27] of TTestEntry = ((Input: 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output: 'ABCDEFGHIJKLMNOPQRSTUVWX';
TestClass: TCipher_Null;
Mode: TCipherMode.cmECBx),
(Input: '000000000000000000000000';
Output: '000000000000000000000000';
TestClass: TCipher_Null;
Mode: TCipherMode.cmECBx),
(Input: '12345678';
Output: '12345678';
TestClass: TCipher_Null;
Mode: TCipherMode.cmECBx),
(Input: 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output: '';
OutputHex: 'FE5A89A7A1F4BD29DFFADFCF2239E1F581106DA64C0AE704';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmOFB8),
(Input: '000000000000000000000000';
Output: '';
OutputHex: '8F28FAD3D482CA51A680A4B35F479E95E0720EC2296C806C';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmOFB8),
(Input: '12345678';
Output: '';
OutputHex: '8E2AF9D7D184CD59';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmOFB8),
(Input: 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output: '';
OutputHex: 'FE604D3DF9C2AE3D7839AF5BDEE8FD9078544A1996EC4F1C';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFB8),
(Input: '000000000000000000000000';
Output: '';
OutputHex: '8FD637FC449CF89F1E5EEBB66BED15C7F8C63B4481F74C5A';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFB8),
(Input: '12345678';
Output: '';
OutputHex: '8EF08D6414063543';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFB8),
(Input: 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output: '';
OutputHex: 'FEAB3839BBA059FC1FECBF798CEF537803F10F15967E3ABD';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFS8),
(Input: '000000000000000000000000';
Output: '';
OutputHex: '8F9661B53B06D611BA916562F4420DA4B6EFD550BF01DA2C';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFS8),
(Input: '12345678';
Output: '';
OutputHex: '8EEA2F2F86159953';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFS8),
(Input: 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output: '';
OutputHex: 'FED41297FD52669B4221F913AF978D77292C958B2A9E289A';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmOFBx),
(Input: '000000000000000000000000';
Output: '';
OutputHex: '8FA661E3882411E33B5B826FD2E9F217484EF6EF4FF84FF2';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmOFBx),
(Input: '12345678';
Output: '';
OutputHex: '8EA462E78D2216EB';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmOFBx),
(Input: 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output: '';
OutputHex: 'FED41297FD52669B0DEC818A383ADA358E469BE634B7AFBC';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFSx),
(Input: '000000000000000000000000';
Output: '';
OutputHex: '8FA661E3882411E3DB7258A29424D11F2BB6B4607D24D5DB';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFSx),
(Input: '12345678';
Output: '';
OutputHex: '8EA462E78D2216EB';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFSx),
(Input : 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output : 'qsqwqsq'+#$7f+'89:;<=>/ikioikiw';
InitVector: '01234567';
TestClass : TCipher_NULL;
Mode : TCipherMode.cmCBCx),
(Input : '000000000000000000000000';
Output : '00000000' + #0#0#0#0#0#0#0#0 + '00000000';
InitVector: #0#0#0#0#0#0#0#0;
TestClass : TCipher_NULL;
Mode : TCipherMode.cmCBCx),
(Input : '000000000000000000000000';
Output : #0#1#2#3#4#5#6#7 + '01234567' + #0#1#2#3#4#5#6#7;
InitVector: '01234567';
TestClass : TCipher_NULL;
Mode : TCipherMode.cmCBCx),
(Input: 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output: '';
OutputHex: 'FD73DA2F279926A19A65EFA8EBA5EEB67A778C6CD73294F5';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCTSx),
(Input: '000000000000000000000000';
Output: '';
OutputHex: '1D538CCCF38138A6BD4655272CC67443A0E32865EB422745';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCTSx),
(Input: '12345678';
Output: '';
OutputHex: '8EE274B893296F9E';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCTSx),
(Input: 'ABCDEFGHIJKLMNOPQRSTUVWX';
Output: '';
OutputHex: 'FED41297FD52669BF5361295F3BD937EF0644802ED92DC21';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFBx),
(Input: '000000000000000000000000';
Output: '';
OutputHex: '8FA661E3882411E35337C15BAE99B7CBDD988AC4FABB3368';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFBx),
(Input: '12345678';
Output: '';
OutputHex: '8EA462E78D2216EB';
TestClass: TCipher_1DES;
Mode: TCipherMode.cmCFBx));
/// <summary>
/// Carries out the actual encode test
/// </summary>
/// <param name="Data">
/// Array with the data definint inputs and outputs for the tests
/// </param>
/// <param name="Mode">
/// Cipher mode which shall be tested
/// </param>
/// <param name="TestAllModes">
/// if true parameter Mode will be ignored and tests for all modes be
/// carried out
/// </param>
procedure DoTestEncode(Data: array of TTestEntry; Mode: TCipherMode; TestAllModes: Boolean = false);
/// <summary>
/// Carries out the actual decode test
/// </summary>
/// <param name="Data">
/// Array with the data definint inputs and outputs for the tests
/// </param>
/// <param name="Mode">
/// Cipher mode which shall be tested
/// </param>
/// <param name="TestAllModes">
/// if true parameter Mode will be ignored and tests for all modes be
/// carried out
/// </param>
procedure DoTestDecode(Data: array of TTestEntry; Mode: TCipherMode; TestAllModes: Boolean = false);
published
procedure TestEncodeECBx;
procedure TestEncodeOFB8;
procedure TestEncodeCFB8;
procedure TestEncodeCFS8;
procedure TestEncodeCFBx;
procedure TestEncodeOFBx;
procedure TestEncodeCFSx;
procedure TestEncodeCBCx;
procedure TestEncodeCTSx;
procedure TestDecodeECBx;
procedure TestDecodeOFB8;
procedure TestDecodeCFB8;
procedure TestDecodeCFS8;
procedure TestDecodeCFBx;
procedure TestDecodeOFBx;
procedure TestDecodeCFSx;
procedure TestDecodeCBCx;
procedure TestDecodeCTSx;
procedure TestEncode;
procedure TestDecode;
end;
implementation
uses
DECUtil;
procedure TestTDECCipherModes.DoTestEncode(Data: array of TTestEntry; Mode: TCipherMode; TestAllModes: Boolean = false);
var
Dest : TBytes;
Source : TBytes;
i, n : Integer;
Result : string;
Cipher : TDECCipherModes;
begin
for i := Low(Data) to High(Data) do
begin
if not TestAllModes then
// Skip data for other modes
if Data[i].Mode <> Mode then
Continue;
Cipher := Data[i].TestClass.Create;
Cipher.Mode := Data[i].Mode;
try
Cipher.Init(BytesOf(RawByteString('ABCDEFGH')), BytesOf(Data[i].InitVector), $FF);
SetLength(Source, Length(Data[i].Input));
FillChar(Source[0], Length(Source), $FF);
Move(Data[i].Input[1], Source[0], Length(Data[i].Input));
SetLength(Dest, length(Source));
Cipher.Encode(Source[0], Dest[0], length(Source));
// Output is noted non hexadecimal
if Data[i].Output <> '' then
begin
for n := Low(Dest) to High(Dest) do
begin
CheckEquals(Ord(Data[i].Output[n+1]), Dest[n],
IntToStr(n+1) + '. position is wrong. ' +
IntToStr(i) + '. test series. Expected: ' +
string(Data[i].Output) + ' was: ' + string(DECUtil.BytesToRawString(Dest)));
end;
end
else
begin
// Output is noted in hex
Result := '';
for n := Low(Dest) to High(Dest) do
Result := Result + IntToHex(Dest[n], 2);
{$IF CompilerVersion >= 24.0}
for n := Low(Result) to High(Result) do
CheckEquals(char(Data[i].OutputHex[n]), Result[n],
IntToStr(n+1) + '. position is wrong. ' +
IntToStr(i) + '. test series. Expected: ' +
string(Data[i].OutputHex) + ' was: ' + Result);
{$ELSE}
for n := 1 to Length(Result) do
CheckEquals(char(Data[i].OutputHex[n]), Result[n],
IntToStr(n+1) + '. position is wrong. ' +
IntToStr(i) + '. test series. Expected: ' +
string(Data[i].OutputHex) + ' was: ' + Result);
{$IFEND}
end;
finally
Cipher.Free;
end;
end;
end;
procedure TestTDECCipherModes.DoTestDecode(Data: array of TTestEntry; Mode: TCipherMode; TestAllModes: Boolean = false);
var
Dest : TBytes;
Source : TBytes;
i, n, m : Integer;
Cipher : TDECCipherModes;
begin
for i := Low(Data) to High(Data) do
begin
if not TestAllModes then
// Skip data for other modes
if Data[i].Mode <> Mode then
Continue;
Cipher := Data[i].TestClass.Create;
Cipher.Mode := Data[i].Mode;
try
Cipher.Init(BytesOf(RawByteString('ABCDEFGH')), BytesOf(Data[i].InitVector), $FF);
if (Data[i].Output <> '') then
begin
SetLength(Source, Length(Data[i].Output));
FillChar(Source[0], Length(Source), $FF);
Move(Data[i].Output[1], Source[0], Length(Data[i].Output));
end
else
begin
SetLength(Source, Length(Data[i].OutputHex) div 2);
FillChar(Source[0], Length(Source), $FF);
n := 1; m := 0;
repeat
Source[m] := StrToInt('$' + char(Data[i].OutputHex[n]) + char(Data[i].OutputHex[n +1]));
inc(n, 2);
inc(m);
until (n > Length(Data[i].OutputHex));
end;
SetLength(Dest, length(Source));
Cipher.Decode(Source[0], Dest[0], length(Source));
for n := Low(Dest) to High(Dest) do
begin
CheckEquals(Ord(Data[i].Input[n+1]), Dest[n],
IntToStr(n+1) + '. position is wrong. ' +
IntToStr(i) + '. test series. Expected: ' +
string(Data[i].Input) + ' was: ' + string(DECUtil.BytesToRawString(Dest)));
end;
finally
Cipher.Free;
end;
end;
end;
procedure TestTDECCipherModes.TestEncodeECBx;
begin
DoTestEncode(Data, TCipherMode.cmECBx);
end;
procedure TestTDECCipherModes.TestEncodeOFB8;
begin
DoTestEncode(Data, TCipherMode.cmOFB8);
end;
procedure TestTDECCipherModes.TestEncodeCFB8;
begin
DoTestEncode(Data, TCipherMode.cmCFB8);
end;
procedure TestTDECCipherModes.TestEncodeCFS8;
begin
DoTestEncode(Data, TCipherMode.cmCFS8);
end;
procedure TestTDECCipherModes.TestEncodeCFBx;
begin
DoTestEncode(Data, TCipherMode.cmCFBx);
end;
procedure TestTDECCipherModes.TestEncodeOFBx;
begin
DoTestEncode(Data, TCipherMode.cmOFBx);
end;
procedure TestTDECCipherModes.TestEncodeCFSx;
begin
DoTestEncode(Data, TCipherMode.cmCFSx);
end;
procedure TestTDECCipherModes.TestEncodeCBCx;
begin
DoTestEncode(Data, TCipherMode.cmCBCx);
end;
procedure TestTDECCipherModes.TestEncodeCTSx;
begin
DoTestEncode(Data, TCipherMode.cmCTSx);
end;
procedure TestTDECCipherModes.TestDecodeECBx;
begin
DoTestDecode(Data, TCipherMode.cmECBx);
end;
procedure TestTDECCipherModes.TestDecodeOFB8;
begin
DoTestDecode(Data, TCipherMode.cmOFB8);
end;
procedure TestTDECCipherModes.TestDecodeCFB8;
begin
DoTestDecode(Data, TCipherMode.cmCFB8);
end;
procedure TestTDECCipherModes.TestDecodeCFS8;
begin
DoTestDecode(Data, TCipherMode.cmCFS8);
end;
procedure TestTDECCipherModes.TestDecodeCFBx;
begin
DoTestDecode(Data, TCipherMode.cmCFBx);
end;
procedure TestTDECCipherModes.TestDecodeOFBx;
begin
DoTestDecode(Data, TCipherMode.cmOFBx);
end;
procedure TestTDECCipherModes.TestDecodeCFSx;
begin
DoTestDecode(Data, TCipherMode.cmCFSx);
end;
procedure TestTDECCipherModes.TestDecodeCBCx;
begin
DoTestDecode(Data, TCipherMode.cmCBCx);
end;
procedure TestTDECCipherModes.TestDecodeCTSx;
begin
DoTestDecode(Data, TCipherMode.cmCTSx);
end;
procedure TestTDECCipherModes.TestEncode;
begin
DoTestEncode(Data, TCipherMode.cmCTSx, true);
end;
procedure TestTDECCipherModes.TestDecode;
begin
DoTestDecode(Data, TCipherMode.cmCTSx, true);
end;
initialization
// Register all test cases to be run
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TestTDECCipherModes);
{$ELSE}
RegisterTest(TestTDECCipherModes.Suite);
{$ENDIF}
end.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,460 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECFormatBase;
interface
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
uses
{$IFDEF DUnitX}
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
System.SysUtils, System.Classes,
DECUtil, DECBaseClass, DECFormatBase;
type
// Test methods for class TFormat_Copy
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTFormat = class(TTestCase)
strict private
/// <summary>
/// Method needed because CheckException only allows procedure methods and
/// not functions as parameter
/// </summary>
procedure TestClassByInvalidIdentityHelper;
/// <summary>
/// Method needed because CheckException only allows procedure methods and
/// not functions as parameter
/// </summary>
procedure TestFormatByInvalidIdentityHelper;
/// <summary>
/// Method needed because CheckException only allows procedure methods and
/// not functions as parameter
/// </summary>
procedure TestClassByInvalidNameHelperEmpty;
/// <summary>
/// Method needed because CheckException only allows procedure methods and
/// not functions as parameter
/// </summary>
procedure TestClassByInvalidNameHelperWrong;
/// <summary>
/// Method needed because CheckException only allows procedure methods and
/// not functions as parameter
/// </summary>
procedure TestFormatByInvalidNameHelperEmpty;
/// <summary>
/// Method needed because CheckException only allows procedure methods and
/// not functions as parameter
/// </summary>
procedure TestFormatByInvalidNameHelperWrong;
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestUpCaseBinary;
procedure TestTableFindBinary;
procedure TestIsClassListCreated;
procedure TestClassByName;
procedure TestClassByInvalidName;
procedure TestClassByIdentity;
procedure TestClassByInvalidIdentity;
procedure TestValidFormat;
procedure TestFormatByName;
procedure TestFormatByInvalidName;
procedure TestFormatByIdentity;
procedure TestFormatByInvalidIdentity;
end;
// Test methods for class TFormat_Copy
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTFormat_Copy = class(TTestCase)
strict private
FFormat_Copy: TFormat_Copy;
private
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestEncodeBytes;
procedure TestEncodeRawByteString;
procedure TestEncodeTypeless;
procedure TestDecodeBytes;
procedure TestDecodeRawByteString;
procedure TestDecodeTypeless;
procedure TestIsValidTypeless;
procedure TestIsValidTBytes;
procedure TestIsValidRawByteString;
end;
implementation
uses
DECFormat;
type
TestRecTableFindBinary = record
Value: Byte;
Table: RawByteString;
Len : Integer;
Index: Integer;
end;
procedure TestTFormat_Copy.SetUp;
begin
FFormat_Copy := TFormat_Copy.Create;
end;
procedure TestTFormat_Copy.TearDown;
begin
FFormat_Copy.Free;
FFormat_Copy := nil;
end;
procedure TestTFormat_Copy.TestDecodeBytes;
var
SrcBuf,
DestBuf : TBytes;
begin
SrcBuf := BytesOf(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'));
DestBuf := TFormat_Copy.Decode(SrcBuf);
CheckEquals('1234567890abcdefghijklmnopqrstuvwxyz@!$',
string(BytesToRawString(DestBuf)));
end;
procedure TestTFormat_Copy.TestDecodeRawByteString;
var
SrcString,
DestString : RawByteString;
begin
SrcString := '1234567890abcdefghijklmnopqrstuvwxyz@!$';
DestString := TFormat_Copy.Decode(SrcString);
CheckEquals(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'),
DestString);
end;
procedure TestTFormat_Copy.TestDecodeTypeless;
var
SrcBuf : TBytes;
DestString : RawByteString;
begin
SrcBuf := BytesOf(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'));
DestString := TFormat_Copy.Encode(SrcBuf[0], length(SrcBuf));
CheckEquals(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'),
DestString);
end;
procedure TestTFormat_Copy.TestEncodeBytes;
var
SrcBuf,
DestBuf : TBytes;
begin
SrcBuf := BytesOf(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'));
DestBuf := TFormat_Copy.Encode(SrcBuf);
CheckEquals('1234567890abcdefghijklmnopqrstuvwxyz@!$',
string(BytesToRawString(DestBuf)));
end;
procedure TestTFormat_Copy.TestEncodeRawByteString;
var
SrcString,
DestString : RawByteString;
begin
SrcString := '1234567890abcdefghijklmnopqrstuvwxyz@!$';
DestString := TFormat_Copy.Encode(SrcString);
CheckEquals(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'),
DestString);
end;
procedure TestTFormat_Copy.TestEncodeTypeless;
var
SrcBuf : TBytes;
DestString : RawByteString;
begin
SrcBuf := BytesOf(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'));
DestString := TFormat_Copy.Encode(SrcBuf[0], length(SrcBuf));
CheckEquals(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'),
DestString);
end;
procedure TestTFormat_Copy.TestIsValidRawByteString;
begin
CheckEquals(true, TFormat_Copy.IsValid(BytesOf('abcdefghijklmnopqrstuvwxyz')));
CheckEquals(true, TFormat_Copy.IsValid(BytesOf('')));
end;
procedure TestTFormat_Copy.TestIsValidTBytes;
var
SrcBuf : TBytes;
begin
SrcBuf := BytesOf(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'));
CheckEquals(true, TFormat_Copy.IsValid(SrcBuf));
SetLength(SrcBuf, 0);
CheckEquals(true, TFormat_Copy.IsValid(SrcBuf));
end;
procedure TestTFormat_Copy.TestIsValidTypeless;
var
SrcBuf : TBytes;
P : ^Byte;
begin
SrcBuf := BytesOf(RawByteString('1234567890abcdefghijklmnopqrstuvwxyz@!$'));
CheckEquals(true, TFormat_Copy.IsValid(SrcBuf[0], Length(SrcBuf)));
P := nil;
CheckEquals(true, TFormat_Copy.IsValid(P^, 0));
CheckEquals(false, TFormat_Copy.IsValid(SrcBuf[0], -1));
end;
{ TestTFormat }
procedure TestTFormat.SetUp;
begin
inherited;
end;
procedure TestTFormat.TearDown;
begin
inherited;
end;
procedure TestTFormat.TestUpCaseBinary;
const
InputChars = ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'[\]^_`abcdefghijklmnopqrstuvwxyz{|}~';
OutputChars = ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
'[\]^_`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~';
var
i : Integer;
b, exp, res : Byte;
begin
{$IF CompilerVersion >= 24.0}
for i := Low(InputChars) to High(InputChars) do
begin
b := ord(InputChars[i]);
exp := ord(OutputChars[i]);
res := TDECFormat.UpCaseBinary(b);
CheckEquals(exp, res);
end;
{$ELSE}
for i := 1 to Length(InputChars) do
begin
b := ord(InputChars[i]);
exp := ord(OutputChars[i]);
res := TDECFormat.UpCaseBinary(b);
CheckEquals(exp, res);
end;
{$IFEND}
end;
procedure TestTFormat.TestValidFormat;
var
result : Boolean;
begin
result := ValidFormat(nil) = TFormat_Copy;
CheckEquals(true, result, 'ValidFormat(nil) must be TFormat_Copy');
result := ValidFormat(TFormat_ESCAPE) = TFormat_ESCAPE;
CheckEquals(true, result, 'ValidFormat(TFormat_ESCAPE) must be TFormat_ESCAPE');
end;
procedure TestTFormat.TestTableFindBinary;
const
Data : array[1..8] of TestRecTableFindBinary = (
(Value: 0;
Table: '';
Len: 10;
Index: -1),
(Value: 0;
Table: '';
Len: -10;
Index: -1),
(Value: $31;
Table: '12345678901';
Len: 100;
Index: 0),
(Value: $32;
Table: '12345678901';
Len: 100;
Index: 1),
(Value: $30;
Table: '12345678901';
Len: 100;
Index: 9),
(Value: $29;
Table: '12345678901';
Len: 100;
Index: -1),
(Value: $30;
Table: '12345678901';
Len: 9;
Index: 9),
(Value: $30;
Table: '12345678901';
Len: 8;
Index: -1)
);
var
i : Integer;
Idx : Integer;
begin
for i := Low(Data) to High(Data) do
begin
Idx := TDECFormat.TableFindBinary(Data[i].Value,
BytesOf(RawByteString(Data[i].Table)),
Data[i].Len);
CheckEquals(Data[i].Index, Idx);
end;
end;
procedure TestTFormat.TestFormatByIdentity;
var
result : Boolean;
begin
result := FormatByIdentity(1178647993) = TFormat_Copy;
CheckEquals(true, result, 'TFormat_Copy must have Identity value 1178647993');
result := FormatByIdentity(3786628779) = TFormat_HEX;
CheckEquals(true, result, 'TFormat_HEX must have Identity value 3786628779');
result := FormatByIdentity(970117517) = TFormat_HEXL;
CheckEquals(true, result, 'TFormat_HEXL must have Identity value 970117517');
end;
procedure TestTFormat.TestFormatByInvalidIdentity;
begin
CheckException(TestFormatByInvalidIdentityHelper, EDECClassNotRegisteredException);
end;
procedure TestTFormat.TestFormatByInvalidIdentityHelper;
begin
FormatByIdentity(0);
end;
procedure TestTFormat.TestClassByIdentity;
var
result : Boolean;
begin
result := TDECFormat.ClassByIdentity(1178647993) = TFormat_Copy;
CheckEquals(true, result, 'TFormat_Copy must have Identity value 1178647993');
result := TDECFormat.ClassByIdentity(3786628779) = TFormat_HEX;
CheckEquals(true, result, 'TFormat_HEX must have Identity value 3786628779');
result := TDECFormat.ClassByIdentity(970117517) = TFormat_HEXL;
CheckEquals(true, result, 'TFormat_HEXL must have Identity value 970117517');
end;
procedure TestTFormat.TestClassByInvalidIdentity;
begin
CheckException(TestClassByInvalidIdentityHelper, EDECClassNotRegisteredException);
end;
procedure TestTFormat.TestClassByInvalidIdentityHelper;
begin
TDECFormat.ClassByIdentity(0);
end;
procedure TestTFormat.TestClassByName;
var
result : Boolean;
begin
result := TDECFormat.ClassByName('TFormat_HEX') = TFormat_HEX;
CheckEquals(true, result, 'Class TFormat_HEX not found');
result := TDECFormat.ClassByName('TFormat_HEXL') = TFormat_HEXL;
CheckEquals(true, result, 'Class TFormat_HEXL not found');
end;
procedure TestTFormat.TestClassByInvalidName;
begin
CheckException(TestClassByInvalidNameHelperEmpty, EDECClassNotRegisteredException);
CheckException(TestClassByInvalidNameHelperWrong, EDECClassNotRegisteredException);
end;
procedure TestTFormat.TestClassByInvalidNameHelperEmpty;
begin
TDECFormat.ClassByName('');
end;
procedure TestTFormat.TestClassByInvalidNameHelperWrong;
begin
TDECFormat.ClassByName('Foo');
end;
procedure TestTFormat.TestFormatByName;
var
result : Boolean;
begin
result := FormatByName('TFormat_HEX') = TFormat_HEX;
CheckEquals(true, result, 'Class TFormat_HEX not found');
result := FormatByName('TFormat_HEXL') = TFormat_HEXL;
CheckEquals(true, result, 'Class TFormat_HEXL not found');
end;
procedure TestTFormat.TestFormatByInvalidName;
begin
CheckException(TestFormatByInvalidNameHelperEmpty, EDECClassNotRegisteredException);
CheckException(TestFormatByInvalidNameHelperWrong, EDECClassNotRegisteredException);
end;
procedure TestTFormat.TestFormatByInvalidNameHelperEmpty;
begin
FormatByName('');
end;
procedure TestTFormat.TestFormatByInvalidNameHelperWrong;
begin
FormatByName('Foo');
end;
procedure TestTFormat.TestIsClassListCreated;
begin
CheckEquals(true, assigned(TDECFormat.ClassList), 'Class list has not been created in initialization');
end;
initialization
// Register any test cases with the test runner
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TestTFormat);
TDUnitX.RegisterTestFixture(TestTFormat_Copy);
{$ELSE}
RegisterTests('DECFormatBase', [TestTFormat.Suite, TestTFormat_Copy.Suite]);
{$ENDIF}
end.

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,656 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECHashKDF;
interface
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
{$INCLUDE ..\..\Source\DECOptions.inc}
uses
System.Classes, System.SysUtils, Generics.Collections,
{$IFDEF DUnitX}
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
TestDECTestDataContainer, DECTypes, DECBaseClass, DECHash, DECHashBase,
DECHashAuthentication, DECUtil, DECFormatBase;
type
/// <summary>
/// Meta class to store class references in the list as there is no pointer
/// to class methods as it seems
/// </summary>
THashClass = class of TDECHash;
/// <summary>
/// Type of the KDF or MGF variant to be tested
/// </summary>
TKDFMGFAlgorithm = (ktKDF1, ktKDF2, ktKDF3, ktKDFx, ktMGF1, ktMGFx);
/// <summary>
/// Record containing everything necessary for a single key deviation
/// method test
/// </summary>
TKeyDeviationTestData = record
/// <summary>
/// Test data as normal text
/// </summary>
InputData : RawByteString;
/// <summary>
/// Optional parameter for some key deviation tests.
/// </summary>
SeedData : RawByteString;
/// <summary>
/// Test output in hexadecimal format
/// </summary>
OutputData : RawByteString;
/// <summary>
/// Requested output length
/// </summary>
MaskSize : Integer;
/// <summary>
/// If the entry is for a KDF1-KDF3 or KDFx test define which test method to call
/// </summary>
Algorithm : TKDFMGFAlgorithm;
/// <summary>
/// Class reference containing the class methods to be tested
/// </summary>
HashClass : TDECHashAuthenticationClass;
/// <summary>
/// Index, which i being used for the KDFx and MGFx variants of the
/// original author of DEC
/// </summary>
Index : UInt32;
end;
/// <summary>
/// List of all the test cases
/// </summary>
TKeyDeviationTestList = class(TList<TKeyDeviationTestData>)
public
/// <summary>
/// Add one entry to the list
/// </summary>
/// <param name="InputData">
/// Test data as normal text
/// </param>
/// <param name="OutputData">
/// Test output in hexadecimal format
/// </param>
/// <param name="MaskSize">
/// Requested output length
/// </param>
/// <param name="HashClass">
/// Class reference containing the class methods to be tested
/// </param>
/// <param name="AlgorithmType">
/// Algorithm for which the test data specified is
/// </param>
/// <param name="Index">
/// Index, which i being used for the KDFx and MGFx variants of the
/// original author of DEC
/// </param>
procedure Add(const InputData, OutputData: RawByteString;
MaskSize : Integer; HashClass: TDECHashAuthenticationClass;
AlgorithmType : TKDFMGFAlgorithm = ktKDF1;
Index : UInt32 = 1); overload;
/// <summary>
/// Add one entry to the list
/// </summary>
/// <param name="InputData">
/// Test data as normal text
/// </param>
/// <param name="SeedData">
/// Optional parameter for some tests. Given in hexadecimal format.
/// </param>
/// <param name="OutputData">
/// Test output in hexadecimal format
/// </param>
/// <param name="MaskSize">
/// Requested output length
/// </param>
/// <param name="HashClass">
/// Class reference containing the class methods to be tested
/// </param>
/// <param name="AlgorithmType">
/// Algorithm for which the test data specified is
/// </param>
/// <param name="Index">
/// Index, which i being used for the KDFx and MGFx variants of the
/// original author of DEC
/// </param>
procedure Add(const InputData, SeedData, OutputData: RawByteString;
MaskSize : Integer; HashClass: TDECHashAuthenticationClass;
AlgorithmType : TKDFMGFAlgorithm = ktKDF1;
Index : UInt32 = 1); overload;
end;
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
/// <summary>
/// All test cases for the MGF1 class methods. These are in this class rather
/// than in TestTDECHash as the MGF1 class methods can only be called on a
/// concrete hash class as they use the DigestSize and would otherwise fail.
/// We currently mostly have test data for the SHA1 (= SHA with 128 bit length)
/// algorithm, but the MGF1 method is universally useable so the tests got
/// separated here.
/// </summary>
TestTHash_MGF1 = class(TTestCase)
strict protected
// List of test cases, defined in such a way that input, length,
// output and hash class to be used shall be spoecified.
FTestData : TKeyDeviationTestList;
public
procedure SetUp; override;
procedure TearDown; override;
procedure TestTBytesInternal(Algorithm : TKDFMGFAlgorithm);
procedure TestRawMemoryInternal(Algorithm : TKDFMGFAlgorithm);
published
procedure TestMGF1TBytes;
procedure TestMGF1RawMemory;
procedure TestMGFxTBytes;
procedure TestMGFxRawMemory;
end;
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
/// <summary>
/// All test cases for the KDF class methods. These are in this class rather
/// than in TestTDECHash as the KDF class methods can only be called on a
/// concrete hash class as they use the DigestSize and would otherwise fail.
/// We currently mostly have test data for the SHA and SHA256 algorithms,
/// but the MGF1 method is universally useable so the tests got separated here.
/// </summary>
TestTHash_KDF = class(TTestCase)
strict protected
// List of test cases, defined in such a way that input, length,
// output and hash class to be used shall be spoecified.
FTestData : TKeyDeviationTestList;
procedure InternalTest(KDFType: TKDFMGFAlgorithm);
procedure InternalTestTBytes(KDFType: TKDFMGFAlgorithm);
public
procedure SetUp; override;
procedure TearDown; override;
published
procedure TestKDF1;
procedure TestKDF1TBytes;
procedure TestKDF2;
procedure TestKDF2TBytes;
procedure TestKDF3;
procedure TestKDF3TBytes;
procedure TestKDFx;
procedure TestKDFxTBytes;
end;
implementation
uses
DECFormat;
{ TKeyDeviationTestList }
procedure TKeyDeviationTestList.Add(const InputData, OutputData: RawByteString;
MaskSize: Integer; HashClass: TDECHashAuthenticationClass;
AlgorithmType : TKDFMGFAlgorithm = ktKDF1;
Index : UInt32 = 1);
var
Data: TKeyDeviationTestData;
begin
Data.InputData := InputData;
Data.OutputData := OutputData;
Data.MaskSize := MaskSize;
Data.HashClass := HashClass;
Data.Algorithm := AlgorithmType;
Data.Index := Index;
self.Add(Data);
end;
procedure TKeyDeviationTestList.Add(const InputData, SeedData,
OutputData: RawByteString; MaskSize: Integer; HashClass: TDECHashAuthenticationClass;
AlgorithmType : TKDFMGFAlgorithm = ktKDF1;
Index : UInt32 = 1);
var
Data: TKeyDeviationTestData;
begin
Data.InputData := InputData;
Data.SeedData := SeedData; //SysUtils.BytesOf(TFormat_HexL.Decode(SeedData));
Data.OutputData := OutputData;
Data.MaskSize := MaskSize;
Data.HashClass := HashClass;
Data.Algorithm := AlgorithmType;
Data.Index := Index;
self.Add(Data);
end;
{ TestTHash_KDF }
procedure TestTHash_KDF.InternalTest(KDFType: TKDFMGFAlgorithm);
var
TestData : TKeyDeviationTestData;
Result, ExpResult, Data, Seed : TBytes;
begin
for TestData in FTestData do
begin
if (TestData.Algorithm = KDFType) then
begin
Data := System.SysUtils.BytesOf(TestData.InputData);
Seed := System.SysUtils.BytesOf(TestData.SeedData);
ExpResult := System.SysUtils.BytesOf(TestData.OutputData);
case KDFType of
ktKDF1 : if (length(Seed) = 0) then
Result := TestData.HashClass.KDF1(Data[0], length(Data),
NullStr, 0, TestData.MaskSize)
else
Result := TestData.HashClass.KDF1(Data[0], length(Data),
Seed[0], length(Seed), TestData.MaskSize);
ktKDF2 : if (length(Seed) = 0) then
Result := TestData.HashClass.KDF2(Data[0], length(Data),
NullStr, 0, TestData.MaskSize)
else
Result := TestData.HashClass.KDF2(Data[0], length(Data),
Seed[0], length(Seed), TestData.MaskSize);
ktKDF3 : if (length(Seed) = 0) then
Result := TestData.HashClass.KDF3(Data[0], length(Data),
NullStr, 0, TestData.MaskSize)
else
Result := TestData.HashClass.KDF3(Data[0], length(Data),
Seed[0], length(Seed), TestData.MaskSize);
ktKDFx : if (length(Seed) = 0) then
Result := TestData.HashClass.KDFx(Data[0], length(Data),
NullStr, 0,
TestData.MaskSize,
TestData.Index)
else
Result := TestData.HashClass.KDFx(Data[0], length(Data),
Seed[0], length(Seed),
TestData.MaskSize,
TestData.Index);
end;
CheckEquals(DECUtil.BytesToRawString(ExpResult),
DECUtil.BytesToRawString(Result));
end;
end;
end;
procedure TestTHash_KDF.InternalTestTBytes(KDFType: TKDFMGFAlgorithm);
var
TestData : TKeyDeviationTestData;
Result, ExpResult, Data, Seed : TBytes;
begin
for TestData in FTestData do
begin
if (TestData.Algorithm = KDFType) then
begin
Data := System.SysUtils.BytesOf(TestData.InputData);
Seed := System.SysUtils.BytesOf(TestData.SeedData);
ExpResult := System.SysUtils.BytesOf(TestData.OutputData);
if (KDFType = ktKDF1) then
Result := TestData.HashClass.KDF1(Data, Seed, TestData.MaskSize);
if (KDFType = ktKDF2) then
Result := TestData.HashClass.KDF2(Data, Seed, TestData.MaskSize);
if (KDFType = ktKDF3) then
Result := TestData.HashClass.KDF3(Data, Seed, TestData.MaskSize);
if (KDFType = ktKDFx) then
Result := TestData.HashClass.KDFx(Data, Seed, TestData.MaskSize, TestData.Index);
CheckEquals(DECUtil.BytesToRawString(ExpResult),
DECUtil.BytesToRawString(Result));
end;
end;
end;
procedure TestTHash_KDF.SetUp;
begin
inherited;
FTestData := TKeyDeviationTestList.Create;
FTestData.Add(TFormat_HexL.Decode('0001020304'),
TFormat_HexL.Decode('0506070809'),
TFormat_HexL.Decode('f52b'),
2, THash_MD2, ktKDF1);
// Test data from Wolfgang Erhard's library
FTestData.Add(TFormat_HexL.Decode('deadbeeffeebdaed'),
'',
TFormat_HexL.Decode('b0ad565b14b478cad4763856ff3016b1' +
'a93d840f87261bede7ddf0f9305a6e44'),
32, THash_SHA1, ktKDF1);
FTestData.Add(TFormat_HexL.Decode('deadbeeffeebdaed'),
'',
TFormat_HexL.Decode('87261bede7ddf0f9305a6e44a74e6a08' +
'46dede27f48205c6b141888742b0ce2c'),
32, THash_SHA1, ktKDF2);
FTestData.Add(TFormat_HexL.Decode('deadbeeffeebdaed'),
'',
TFormat_HexL.Decode('60cef67059af33f6aebce1e10188f434' +
'f80306ac0360470aeb41f81bafb35790'),
32, THash_SHA1, ktKDF3);
FTestData.Add(TFormat_HexL.Decode('032e45326fa859a72ec235acff929b15' +
'd1372e30b207255f0611b8f785d76437' +
'4152e0ac009e509e7ba30cd2f1778e11' +
'3b64e135cf4e2292c75efe5288edfda4'),
'',
TFormat_HexL.Decode('10a2403db42a8743cb989de86e668d16' +
'8cbe6046e23ff26f741e87949a3bba13' +
'11ac179f819a3d18412e9eb45668f292' +
'3c087c1299005f8d5fd42ca257bc93e8' +
'fee0c5a0d2a8aa70185401fbbd99379e' +
'c76c663e9a29d0b70f3fe261a59cdc24' +
'875a60b4aacb1319fa11c3365a8b79a4' +
'4669f26fba933d012db213d7e3b16349'),
128, THash_SHA256, ktKDF2);
FTestData.Add(TFormat_HexL.Decode('032e45326fa859a72ec235acff929b15' +
'd1372e30b207255f0611b8f785d76437' +
'4152e0ac009e509e7ba30cd2f1778e11' +
'3b64e135cf4e2292c75efe5288edfda4'),
'',
TFormat_HexL.Decode('0e6a26eb7b956ccb8b3bdc1ca975bc57' +
'c3989e8fbad31a224655d800c4695484' +
'0ff32052cdf0d640562bdfadfa263cfc' +
'cf3c52b29f2af4a1869959bc77f854cf' +
'15bd7a25192985a842dbff8e13efee5b' +
'7e7e55bbe4d389647c686a9a9ab3fb88' +
'9b2d7767d3837eea4e0a2f04b53ca8f5' +
'0fb31225c1be2d0126c8c7a4753b0807'),
128, THash_SHA1, ktKDF2);
FTestData.Add(TFormat_HexL.Decode('ca7c0f8c3ffa87a96e1b74ac8e6af594' +
'347bb40a'),
'',
TFormat_HexL.Decode('744ab703f5bc082e59185f6d049d2d36' +
'7db245c2'),
20, THash_SHA1, ktKDF2);
FTestData.Add(TFormat_HexL.Decode('0499b502fc8b5bafb0f4047e731d1f9f' +
'd8cd0d8881'),
'',
TFormat_HexL.Decode('03c62280c894e103c680b13cd4b4ae74' +
'0a5ef0c72547292f82dc6b1777f47d63' +
'ba9d1ea732dbf386'),
40, THash_SHA1, ktKDF2);
// Test vector #1, ANSI X9.63
FTestData.Add(TFormat_HexL.Decode('96c05619d56c328ab95fe84b18264b08' +
'725b85e33fd34f08'),
'',
TFormat_HexL.Decode('443024c3dae66b95e6f5670601558f71'),
16, THash_SHA256, ktKDF2);
// Test vector #2, ANSI X9.63
FTestData.Add(TFormat_HexL.Decode('96f600b73ad6ac5629577eced51743dd' +
'2c24c21b1ac83ee4'),
'',
TFormat_HexL.Decode('b6295162a7804f5667ba9070f82fa522'),
16, THash_SHA256, ktKDF2);
// Test vector #3, ANSI X9.63
FTestData.Add(TFormat_HexL.Decode('22518b10e70f2a3f243810ae3254139e' +
'fbee04aa57c7af7d'),
TFormat_HexL.Decode('75eef81aa3041e33b80971203d2c0c52'),
TFormat_HexL.Decode('c498af77161cc59f2962b9a713e2b215' +
'152d139766ce34a776df11866a69bf2e' +
'52a13d9c7c6fc878c50c5ea0bc7b00e0' +
'da2447cfd874f6cf92f30d0097111485' +
'500c90c3af8b487872d04685d14c8d1d' +
'c8d7fa08beb0ce0ababc11f0bd496269' +
'142d43525a78e5bc79a17f59676a5706' +
'dc54d54d4d1f0bd7e386128ec26afc21'),
128, THash_SHA256, ktKDF2);
// Test vector #4, ANSI X9.63
FTestData.Add(TFormat_HexL.Decode('7e335afa4b31d772c0635c7b0e06f26f' +
'cd781df947d2990a'),
TFormat_HexL.Decode('d65a4812733f8cdbcdfb4b2f4c191d87'),
TFormat_HexL.Decode('c0bd9e38a8f9de14c2acd35b2f3410c6' +
'988cf02400543631e0d6a4c1d030365a' +
'cbf398115e51aaddebdc9590664210f9' +
'aa9fed770d4c57edeafa0b8c14f93300' +
'865251218c262d63dadc47dfa0e02848' +
'26793985137e0a544ec80abf2fdf5ab9' +
'0bdaea66204012efe34971dc431d625c' +
'd9a329b8217cc8fd0d9f02b13f2f6b0b'),
128, THash_SHA256, ktKDF2);
// Test for DEC's own KDFx variant, testdata synthesised and verified against
// DEC V5.2
FTestData.Add(TFormat_HexL.Decode('deadbeeffeebdaed'),
'',
TFormat_HexL.Decode('e473e6b6065219bab4fde9113bd80301'+
'6cc49979783559585b0c8bb5bbdfa4cd'),
32, THash_SHA1, ktKDFx, 1);
FTestData.Add(TFormat_HexL.Decode('deadbeeffeebdaed'),
'',
TFormat_HexL.Decode('2dfb9508c07cd1521849d8dd92585ec0'+
'9499132de0f6b8d4ed2768ec1c83f0ed'),
32, THash_SHA1, ktKDFx, 2);
FTestData.Add(TFormat_HexL.Decode('7e335afa4b31d772c0635c7b0e06f26f' +
'cd781df947d2990a'),
TFormat_HexL.Decode('d65a4812733f8cdbcdfb4b2f4c191d87'),
TFormat_HexL.Decode('934006d019879d1ee2787b27ed57841b' +
'66433425d6a0f4ca6abb20f6967dc660' +
'd04f8577b13ec8d4ec54610a78e0881f' +
'2ae26f482c81053c6d8951e787b2e4a9' +
'9b3c2a95bc196948e1f1819c55ba08d6' +
'6a6ca395e9929eaee752b5dc324e980d' +
'71f0e8c1b244bb3b0c09b903ebc446e2' +
'925bf1a7041923a3910959e5dcd6afd2'),
128, THash_SHA256, ktKDFx, 1);
FTestData.Add(TFormat_HexL.Decode('7e335afa4b31d772c0635c7b0e06f26f' +
'cd781df947d2990a'),
TFormat_HexL.Decode('d65a4812733f8cdbcdfb4b2f4c191d87'),
TFormat_HexL.Decode('2c26a1303d2146d61384e689debf541f' +
'bcd832e9343f2771b7e28dd877f096d5' +
'95e0e12c768d74d72a91176908b34842' +
'a0a32d7b3f8293d169fa873a5a7e747e' +
'0e6e054e73c2ca1bb89a1772e4e5b0f6' +
'7cead338829bb02e7012254f4f79e63a' +
'619e6f14782af946e169c2870ec6ca3a' +
'68377d2ad42196987278f93674c7d861'),
128, THash_SHA256, ktKDFx, 2);
end;
procedure TestTHash_KDF.TearDown;
begin
FTestData.Free;
inherited;
end;
procedure TestTHash_KDF.TestKDF1;
begin
InternalTest(ktKDF1);
end;
procedure TestTHash_KDF.TestKDF1TBytes;
begin
InternalTestTBytes(ktKDF1);
end;
procedure TestTHash_KDF.TestKDF2;
begin
InternalTest(ktKDF2);
end;
procedure TestTHash_KDF.TestKDF2TBytes;
begin
InternalTestTBytes(ktKDF2);
end;
procedure TestTHash_KDF.TestKDF3;
begin
InternalTest(ktKDF3);
end;
procedure TestTHash_KDF.TestKDF3TBytes;
begin
InternalTestTBytes(ktKDF3);
end;
procedure TestTHash_KDF.TestKDFx;
begin
InternalTest(ktKDFx);
end;
procedure TestTHash_KDF.TestKDFxTBytes;
begin
InternalTestTBytes(ktKDFx);
end;
{ THash_TestMGF1 }
procedure TestTHash_MGF1.SetUp;
begin
inherited;
FTestData := TKeyDeviationTestList.Create;
FTestData.Add('foo', '1ac907', 3, THash_SHA1, ktMGF1);
FTestData.Add('foo', '1ac9075cd4', 5, THash_SHA1, ktMGF1);
FTestData.Add('bar', 'bc0c655e01', 5, THash_SHA1, ktMGF1);
FTestData.Add('bar', 'bc0c655e016bc2931d85a2e675181adcef7f581f76df2739da74f' +
'aac41627be2f7f415c89e983fd0ce80ced9878641cb4876', 50, THash_SHA1, ktMGF1);
FTestData.Add('bar', '382576a7841021cc28fc4c0948753fb8312090cea942ea4c4e735' +
'd10dc724b155f9f6069f289d61daca0cb814502ef04eae1', 50, THash_SHA256, ktMGF1);
FTestData.Add('foo', 'b2ae0e', 3, THash_SHA1, ktMGFx, 1);
FTestData.Add('foo', '44ffe3', 3, THash_SHA1, ktMGFx, 2);
FTestData.Add('foo', 'b2ae0e6e26', 5, THash_SHA1, ktMGFx, 1);
FTestData.Add('foo', '44ffe3a40b', 5, THash_SHA1, ktMGFx, 2);
FTestData.Add('bar', '21dfca12e1', 5, THash_SHA1, ktMGFx, 1);
FTestData.Add('bar', '596eb7fe1b', 5, THash_SHA1, ktMGFx, 2);
FTestData.Add('bar', '21dfca12e13ebcaa77a5b6c0ff7023266e0dd54498306070fc735' +
'ad7b0d88e14cb1acc887f564c7adb677a1b6b4b1e6b3f07', 50, THash_SHA1, ktMGFx, 1);
FTestData.Add('bar', '596eb7fe1ba0a133e7c445c745270bf6433dc88cef9f922840f75' +
'd4867a247ea37fc9458c934e4675bcd7300722ee8d07b37', 50, THash_SHA1, ktMGFx, 2);
FTestData.Add('bar', 'e01f7238400a2f1501bbaaf937d3d081bda4fe5bccc713134f5d3' +
'a580bd66783d379e6d91c6e91a1072744ae42fe4e182f32', 50, THash_SHA256, ktMGFx, 1);
FTestData.Add('bar', '816453f0040d4f0469ccfcb520bf63fbf4616e46adff6708d40b1' +
'63041b91a234baa7f8a1fb86b23ef81df6e1121233dd88e', 50, THash_SHA256, ktMGFx, 2);
end;
procedure TestTHash_MGF1.TearDown;
begin
FTestData.Free;
inherited;
end;
procedure TestTHash_MGF1.TestMGF1RawMemory;
begin
TestRawMemoryInternal(ktMGF1)
end;
procedure TestTHash_MGF1.TestMGF1TBytes;
begin
TestTBytesInternal(ktMGF1);
end;
procedure TestTHash_MGF1.TestMGFxRawMemory;
begin
TestRawMemoryInternal(ktMGFx)
end;
procedure TestTHash_MGF1.TestMGFxTBytes;
begin
TestTBytesInternal(ktMGFx);
end;
procedure TestTHash_MGF1.TestRawMemoryInternal(Algorithm : TKDFMGFAlgorithm);
var
InputData : TBytes;
OutputData : TBytes;
i : Integer;
begin
for i := 0 to FTestData.Count - 1 do
begin
InputData := BytesOf(FTestData[i].InputData);
// Skip tests which are not for the selected algorithm
if FTestData[i].Algorithm <> Algorithm then
Continue;
case FTestData[i].Algorithm of
ktMGF1 : OutputData := FTestData[i].HashClass.MGF1(InputData[0], length(InputData),
FTestData[i].MaskSize);
ktMGFx : OutputData := FTestData[i].HashClass.MGFx(InputData[0], length(InputData),
FTestData[i].MaskSize, FTestData[i].Index);
end;
CheckEquals(FTestData[i].OutputData,
DECUtil.BytesToRawString(TFormat_HEXL.Encode(OutputData)),
'MGFT1/MGFx test failed at index ' + IntToStr(i));
end;
end;
procedure TestTHash_MGF1.TestTBytesInternal(Algorithm : TKDFMGFAlgorithm);
var
InputData : TBytes;
OutputData : TBytes;
i : Integer;
begin
for i := 0 to FTestData.Count - 1 do
begin
InputData := BytesOf(FTestData[i].InputData);
// Skip tests which are not for the selected algorithm
if FTestData[i].Algorithm <> Algorithm then
Continue;
case FTestData[i].Algorithm of
ktMGF1 : OutputData := FTestData[i].HashClass.MGF1(InputData, FTestData[i].MaskSize);
ktMGFx : OutputData := FTestData[i].HashClass.MGFx(InputData, FTestData[i].MaskSize,
FTestData[i].Index);
end;
CheckEquals(FTestData[i].OutputData,
DECUtil.BytesToRawString(TFormat_HEXL.Encode(OutputData)),
'MGF1/MGFx test failed at index ' + IntToStr(i));
end;
end;
initialization
// Register any test cases with the test runner
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TestTHash_MGF1);
TDUnitX.RegisterTestFixture(TestTHash_KDF);
{$ELSE}
RegisterTests('DECHashKDF', [TestTHash_MGF1.Suite,
TestTHash_KDF.Suite]);
{$ENDIF}
end.

View File

@@ -0,0 +1,240 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECHashMAC;
interface
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
{$INCLUDE ..\..\Source\DECOptions.inc}
uses
System.Classes, System.SysUtils, Generics.Collections,
{$IFDEF DUnitX}
DUnitX.TestFramework, DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
TestDECTestDataContainer, DECBaseClass, DECHash, DECHashBase;
type
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
/// <summary>
/// All test cases for the HMAC class methods.
/// </summary>
TestTHash_HMAC = class(TTestCase)
published
procedure TestBytes;
procedure TestRawByteString;
procedure TestAAx80StringBytes;
procedure TestAAx80StringString;
end;
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
/// <summary>
/// All test cases for the HMAC class methods.
/// </summary>
TestTHash_PBKDF2 = class(TTestCase)
published
procedure TestBytes;
procedure TestRawByteString;
end;
implementation
uses
DECFormatBase, DECFormat;
{ TestTHash_HMAC }
procedure TestTHash_HMAC.TestAAx80StringBytes;
var
AAx80String : TBytes;
Result : TBytes;
begin
SetLength(AAx80String, 80);
FillChar(AAx80String[0], 80, $AA);
Result := THash_MD5.HMAC(AAx80String,
BytesOf('Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'));
CheckEquals('6F630FAD67CDA0EE1FB1F562DB3AA53E', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data');
Result := THash_MD5.HMAC(AAx80String, BytesOf('Test Using Larger Than Block-Size Key - Hash Key First'));
CheckEquals('6B1AB7FE4BD7BF8F0B62E6CE61B9D0CD', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'MD5 Test Using Larger Than Block-Size Key - Hash Key First');
Result := THash_SHA1.HMAC(AAx80String,
BytesOf('Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'));
CheckEquals('E8E99D0F45237D786D6BBAA7965C7808BBFF1A91', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data');
Result := THash_SHA1.HMAC(AAx80String,
BytesOf('Test Using Larger Than Block-Size Key - Hash Key First'));
CheckEquals('AA4AE5E15272D00E95705637CE8A3B55ED402112', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 Test Using Larger Than Block-Size Key - Hash Key First');
end;
procedure TestTHash_HMAC.TestAAx80StringString;
var
AAx80String : TBytes;
Result : TBytes;
begin
SetLength(AAx80String, 80);
FillChar(AAx80String[0], 80, $AA);
Result := THash_MD5.HMAC(RawByteString(StringOf(AAx80String)),
RawByteString('Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'));
CheckEquals('6F630FAD67CDA0EE1FB1F562DB3AA53E', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data');
Result := THash_MD5.HMAC(RawByteString(StringOf(AAx80String)),
RawByteString('Test Using Larger Than Block-Size Key - Hash Key First'));
CheckEquals('6B1AB7FE4BD7BF8F0B62E6CE61B9D0CD', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'MD5 Test Using Larger Than Block-Size Key - Hash Key First');
Result := THash_SHA1.HMAC(RawByteString(StringOf(AAx80String)),
RawByteString('Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data'));
CheckEquals('E8E99D0F45237D786D6BBAA7965C7808BBFF1A91', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data');
Result := THash_SHA1.HMAC(RawByteString(StringOf(AAx80String)),
RawByteString('Test Using Larger Than Block-Size Key - Hash Key First'));
CheckEquals('AA4AE5E15272D00E95705637CE8A3B55ED402112', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 Test Using Larger Than Block-Size Key - Hash Key First');
end;
procedure TestTHash_HMAC.TestBytes;
var
Res: TBytes;
begin
// test vectors from https://en.wikipedia.org/wiki/HMAC
Res := THash_MD5.HMAC(BytesOf('key'), BytesOf('The quick brown fox jumps over the lazy dog'));
CheckEquals('80070713463E7749B90C2DC24911E275', StringOf(ValidFormat(TFormat_HEX).Encode(Res)),
'MD5 failure in The quick...');
Res := THash_SHA1.HMAC(BytesOf('key'), BytesOf('The quick brown fox jumps over the lazy dog'));
CheckEquals('DE7C9B85B8B78AA6BC8A7A36F70A90701C9DB4D9', StringOf(ValidFormat(TFormat_HEX).Encode(Res)),
'SHA1 failure in The quick...');
Res := THash_SHA256.HMAC(BytesOf('key'), BytesOf('The quick brown fox jumps over the lazy dog'));
CheckEquals('F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8',
StringOf(ValidFormat(TFormat_HEX).Encode(Res)),
'SHA256 failure in The quick...');
end;
procedure TestTHash_HMAC.TestRawByteString;
var
Result: TBytes;
begin
// test vectors from https://en.wikipedia.org/wiki/HMAC
Result := THash_MD5.HMAC(RawByteString('key'), RawByteString('The quick brown fox jumps over the lazy dog'));
CheckEquals('80070713463E7749B90C2DC24911E275', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'MD5 failure in The quick...');
Result := THash_SHA1.HMAC(RawByteString('key'), RawByteString('The quick brown fox jumps over the lazy dog'));
CheckEquals('DE7C9B85B8B78AA6BC8A7A36F70A90701C9DB4D9', StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA1 failure in The quick...');
Result := THash_SHA256.HMAC(RawByteString('key'), RawByteString('The quick brown fox jumps over the lazy dog'));
CheckEquals('F7BC83F430538424B13298E6AA6FB143EF4D59A14946175997479DBC2D1A3CD8',
StringOf(ValidFormat(TFormat_HEX).Encode(Result)),
'SHA256 failure in The quick...');
end;
{ TestTHash_PBKDF2 }
procedure TestTHash_PBKDF2.TestBytes;
var
Result : string;
begin
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA1.PBKDF2(BytesOf('password'), BytesOf('salt'), 1, 20)));
CheckEquals('0C60C80F961F0E71F3A9B524AF6012062FE037A6', result, 'SHA1 password salt 1 20');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2(BytesOf('password'), BytesOf('salt'), 1, 32)));
CheckEquals('120FB6CFFCF8B32C43E7225256C4F837A86548C92CCC35480805987CB70BE17B', result, 'SHA256 password salt 1 32');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2(BytesOf('password'), BytesOf('salt'), 2, 32)));
CheckEquals('AE4D0C95AF6B46D32D0ADFF928F06DD02A303F8EF3C251DFD6E2D85A95474C43', result, 'SHA256 password salt 2 32');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2(BytesOf('password'), BytesOf('salt'), 4096, 32)));
CheckEquals('C5E478D59288C841AA530DB6845C4C8D962893A001CE4E11A4963873AA98134A', result, 'SHA256 password salt 4096 32');
// PBKDF2-HMAC-SHA512 test vectors from https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2(BytesOf('password'), BytesOf('salt'), 1, 64)));
CheckEquals('867F70CF1ADE02CFF3752599A3A53DC4AF34C7A669815AE5D513554E1C8CF252C02D470A285A0501BAD999BFE943C08F050235D7D68B1DA55E63F73B60A57FCE',
result, 'SHA512 password salt 1 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2(BytesOf('password'), BytesOf('salt'), 2, 64)));
CheckEquals('E1D9C16AA681708A45F5C7C4E215CEB66E011A2E9F0040713F18AEFDB866D53CF76CAB2868A39B9F7840EDCE4FEF5A82BE67335C77A6068E04112754F27CCF4E',
result, 'SHA512 password salt 2 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2(BytesOf('password'), BytesOf('salt'), 4096, 64)));
CheckEquals('D197B1B33DB0143E018B12F3D1D1479E6CDEBDCC97C5C0F87F6902E072F457B5143F30602641B3D55CD335988CB36B84376060ECD532E039B742A239434AF2D5',
result, 'SHA512 password salt 4096 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2(BytesOf('password'), BytesOf('salt'), 1000000, 32)));
CheckEquals('505112A590BE61AC9D3A235BF0A8EECEA40E54652EC0E3C257C227C9AA5E664C',
result, 'SHA256 password salt 1000000 32');
end;
procedure TestTHash_PBKDF2.TestRawByteString;
var
Result : string;
begin
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA1.PBKDF2('password', 'salt', 1, 20)));
CheckEquals('0C60C80F961F0E71F3A9B524AF6012062FE037A6', result, 'SHA1 password salt 1 20');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2('password', 'salt', 1, 32)));
CheckEquals('120FB6CFFCF8B32C43E7225256C4F837A86548C92CCC35480805987CB70BE17B', result, 'SHA256 password salt 1 32');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2('password', 'salt', 2, 32)));
CheckEquals('AE4D0C95AF6B46D32D0ADFF928F06DD02A303F8EF3C251DFD6E2D85A95474C43', result, 'SHA256 password salt 2 32');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2('password', 'salt', 4096, 32)));
CheckEquals('C5E478D59288C841AA530DB6845C4C8D962893A001CE4E11A4963873AA98134A', result, 'SHA256 password salt 4096 32');
// PBKDF2-HMAC-SHA512 test vectors from https://stackoverflow.com/questions/15593184/pbkdf2-hmac-sha-512-test-vectors
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2('password', 'salt', 1, 64)));
CheckEquals('867F70CF1ADE02CFF3752599A3A53DC4AF34C7A669815AE5D513554E1C8CF252C02D470A285A0501BAD999BFE943C08F050235D7D68B1DA55E63F73B60A57FCE',
result, 'SHA512 password salt 1 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2('password', 'salt', 2, 64)));
CheckEquals('E1D9C16AA681708A45F5C7C4E215CEB66E011A2E9F0040713F18AEFDB866D53CF76CAB2868A39B9F7840EDCE4FEF5A82BE67335C77A6068E04112754F27CCF4E',
result, 'SHA512 password salt 2 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA512.PBKDF2('password', 'salt', 4096, 64)));
CheckEquals('D197B1B33DB0143E018B12F3D1D1479E6CDEBDCC97C5C0F87F6902E072F457B5143F30602641B3D55CD335988CB36B84376060ECD532E039B742A239434AF2D5',
result, 'SHA512 password salt 4096 64');
result := StringOf(ValidFormat(TFormat_HEX).Encode(THash_SHA256.PBKDF2('password', 'salt', 1000000, 32)));
CheckEquals('505112A590BE61AC9D3A235BF0A8EECEA40E54652EC0E3C257C227C9AA5E664C',
result, 'SHA256 password salt 1000000 32');
end;
initialization
// Register any test cases with the test runner
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TestTHash_HMAC);
TDUnitX.RegisterTestFixture(TestTHash_PBKDF2);
{$ELSE}
RegisterTests('DECHashHMAC', [TestTHash_HMAC.Suite]);
RegisterTests('DECHashHMAC', [TestTHash_PBKDF2.Suite]);
{$ENDIF}
end.

View File

@@ -0,0 +1,995 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECHashSHA3;
interface
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
{$INCLUDE ..\..\Source\DECOptions.inc}
{$IF CompilerVersion >= 24.0} // Too many local constants for Delphi XE2 and older
uses
System.SysUtils, System.Classes, Generics.Collections,
{$IFDEF DUnitX}
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
TestDECTestDataContainer,
DECTypes, DECBaseClass, DECHash, DECHashBase, DECHashAuthentication, DECUtil,
DECFormatBase, DECHashBitBase, TestDECHash;
type
/// <summary>
/// Base class for the SHA3 tests, provides loading the test data from files
/// </summary>
TestTHash_SHA3_Base = class(THash_TestBase)
strict private
/// <summary>
/// Load the data of all test files specified for the test class
/// </summary>
procedure LoadTestFiles; inline;
/// <summary>
/// Calculate the Unicode hash value of the given test data
/// </summary>
/// <param name="TestData">
/// Test data as lower case Hex-Value
/// </param>
/// <param name="HashInst">
/// Instance of the hash algorithm used
/// </param>
/// <returns>
/// Calculated lower case hex formatted hash over the test data
/// </returns>
function CalcUnicodeHash(TestData : string;
HashInst : TDECHashAuthentication): RawByteString; inline;
strict protected
/// <summary>
/// List of test data files to laod
/// </summary>
FTestFileNames : TStringList;
/// <summary>
/// Overridden so that loading of the test data file only happens here
/// and not also for the metadata etc. tests as well
/// </summary>
procedure DoTestCalcBuffer(HashClass:TDECHash); override;
/// <summary>
/// Overridden so that loading of the test data file only happens here
/// and not also for the metadata etc. tests as well
/// </summary>
procedure DoTestCalcBytes(HashClass:TDECHash); override;
/// <summary>
/// Overridden so that loading of the test data file only happens here
/// and not also for the metadata etc. tests as well
/// </summary>
procedure DoTestCalcStream(HashClass:TDECHash); override;
/// <summary>
/// Overridden so that loading of the test data file only happens here
/// and not also for the metadata etc. tests as well
/// </summary>
procedure DoTestCalcUnicodeString(HashClass:TDECHash); override;
/// <summary>
/// Overridden so that loading of the test data file only happens here
/// and not also for the metadata etc. tests as well
/// </summary>
procedure DoTestCalcRawByteString(HashClass:TDECHash); override;
/// <summary>
/// Loads data stored in the rsp files provided by NIST into the test
/// data lists. Any exceptions will be caught and entries with wrong format
/// ignored.
/// </summary>
/// <param name="FileName">
/// Namne of the file to load
/// </param>
/// <param name="TestData">
/// Interface to the test data management instance
/// </param>
/// <param name="HashInst">
/// Instance of the hashing class to be tested for calculating the UTF-string
/// test data.
/// </param>
procedure LoadTestDataFile(FileName : string;
TestData : IHashTestDataContainer;
HashInst : TDECHashAuthentication);
public
/// <summary>
/// Create test file list
/// </summary>
procedure SetUp; override;
/// <summary>
/// Free test file lsit
/// </summary>
procedure TearDown; override;
end;
// Test methods for class THash_SHA3_224
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTHash_SHA3_224 = class(TestTHash_SHA3_Base)
strict protected
/// <summary>
/// Some tests need to set the SHA3 specific padding byte and final bit length
/// parameters
/// </summary>
procedure ConfigHashClass(HashClass: TDECHash; IdxTestData:Integer); override;
public
procedure SetUp; override;
published
procedure TestDigestSize;
procedure TestBlockSize;
procedure TestIsPasswordHash;
procedure TestClassByName;
procedure TestIdentity;
end;
// Test methods for class THash_SHA3_256
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTHash_SHA3_256 = class(TestTHash_SHA3_Base)
strict protected
/// <summary>
/// Some tests need to set the SHA3 specific padding byte and final bit length
/// parameters
/// </summary>
procedure ConfigHashClass(HashClass: TDECHash; IdxTestData:Integer); override;
public
procedure SetUp; override;
published
procedure TestDigestSize;
procedure TestBlockSize;
procedure TestIsPasswordHash;
procedure TestClassByName;
procedure TestIdentity;
end;
// Test methods for class THash_SHA3_384
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTHash_SHA3_384 = class(TestTHash_SHA3_Base)
strict protected
/// <summary>
/// Some tests need to set the SHA3 specific padding byte and final bit length
/// parameters
/// </summary>
procedure ConfigHashClass(HashClass: TDECHash; IdxTestData:Integer); override;
public
procedure SetUp; override;
published
procedure TestDigestSize;
procedure TestBlockSize;
procedure TestIsPasswordHash;
procedure TestClassByName;
procedure TestIdentity;
end;
// Test methods for class THash_SHA3_512
{$IFDEF DUnitX} [TestFixture] {$ENDIF}
TestTHash_SHA3_512 = class(TestTHash_SHA3_Base)
strict protected
/// <summary>
/// Some tests need to set the SHA3 specific padding byte and final bit length
/// parameters
/// </summary>
procedure ConfigHashClass(HashClass: TDECHash; IdxTestData:Integer); override;
public
procedure SetUp; override;
published
procedure TestDigestSize;
procedure TestBlockSize;
procedure TestIsPasswordHash;
procedure TestClassByName;
procedure TestIdentity;
end;
implementation
uses
DECFormat;
{ TestTHash_SHA3_Base }
procedure TestTHash_SHA3_Base.SetUp;
begin
inherited;
FTestFileNames := TStringList.Create;
end;
procedure TestTHash_SHA3_Base.TearDown;
begin
inherited;
FTestFileNames.Free;
end;
procedure TestTHash_SHA3_Base.LoadTestFiles;
var
FileName : string;
begin
for FIleName in FTestFIleNames do
LoadTestDataFile(FileName, FTestData, FHash);
end;
procedure TestTHash_SHA3_Base.DoTestCalcBuffer(HashClass:TDECHash);
begin
LoadTestFiles;
inherited;
end;
procedure TestTHash_SHA3_Base.DoTestCalcBytes(HashClass:TDECHash);
begin
LoadTestFiles;
inherited;
end;
procedure TestTHash_SHA3_Base.DoTestCalcStream(HashClass:TDECHash);
begin
LoadTestFiles;
inherited;
end;
procedure TestTHash_SHA3_Base.DoTestCalcUnicodeString(HashClass:TDECHash);
begin
LoadTestFiles;
inherited;
end;
procedure TestTHash_SHA3_Base.DoTestCalcRawByteString(HashClass:TDECHash);
begin
LoadTestFiles;
inherited;
end;
procedure TestTHash_SHA3_Base.LoadTestDataFile(FileName : string;
TestData : IHashTestDataContainer;
HashInst : TDECHashAuthentication);
var
Contents : TStringList;
FileRow,
FileRowTrim,
s1 : string;
Len : Int32;
FinalByteLen : Int16;
lDataRow : IHashTestDataRowSetup;
begin
Len := 0;
Contents := TStringList.Create;
try
Contents.LoadFromFile(FileName);
for FileRow in Contents do
begin
FileRowTrim := LowerCase(Trim(FileRow));
if (Pos('len', FileRowTrim) = 1) then
begin
lDataRow := FTestData.AddRow;
s1 := FileRowTrim;
Delete(s1, 1, 6);
Len := StrToInt(s1);
FinalByteLen := Len mod 8;
lDataRow.FinalBitLength := FinalByteLen;
THash_SHA3Base(HashInst).FinalByteLength := FinalByteLen;
Continue;
end;
if (Pos('msg', FileRowTrim) = 1) then
begin
s1 := FileRowTrim;
Delete(s1, 1, 6);
if (Len > 0) then
begin
lDataRow.AddInputVector(TFormat_HexL.Decode(RawByteString(s1)));
lDataRow.ExpectedOutputUTFStrTest := CalcUnicodeHash(s1, HashInst);
end
else
begin
lDataRow.AddInputVector('');
lDataRow.ExpectedOutputUTFStrTest := CalcUnicodeHash('', HashInst);
end;
Continue;
end;
if (Pos('md', FileRowTrim) = 1) then
begin
s1 := FileRowTrim;
Delete(s1, 1, 5);
lDataRow.ExpectedOutput := RawByteString(s1);
Continue;
end;
end;
finally
Contents.Free;
end;
end;
function TestTHash_SHA3_Base.CalcUnicodeHash(TestData : string;
HashInst : TDECHashAuthentication): RawByteString;
begin
Result := BytesToRawString(TFormat_HEXL.Encode(
System.SysUtils.BytesOf(HashInst.CalcString(
string(TFormat_HexL.Decode(RawByteString(TestData)))))));
end;
{ TestTHash_SHA3_224 }
procedure TestTHash_SHA3_224.ConfigHashClass(HashClass: TDECHash;
IdxTestData: Integer);
begin
inherited;
THash_SHA3_224(FHash).FinalByteLength := FTestData[IdxTestData].FinalByteLength;
THash_SHA3_224(FHash).PaddingByte := FTestData[IdxTestData].PaddingByte;
end;
procedure TestTHash_SHA3_224.SetUp;
var
lDataRow : IHashTestDataRowSetup;
i : Integer;
s : RawByteString;
begin
// All specified data sources are for the non unicode expected outputs
inherited;
FHash := THash_SHA3_224.Create;
//Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-
// Validation-Program/documents/sha3/sha-3bittestvectors.zip
FTestFileNames.Add('..\..\Unit Tests\Data\SHA3_224ShortMsg.rsp');
FTestFileNames.Add('..\..\Unit Tests\Data\SHA3_224LongMsg.rsp');
// SourceEnd
// Source: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-224_1600.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '9376816aba503f72f96ce7eb65ac095deee3be4b' +
'f9bbc2a1cb7e11e0';
lDataRow.ExpectedOutputUTFStrTest := '28a4a80fded04a676674687c8330422eedeb18c9' +
'dba976234a9e007a';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3), 1, 20);
lDataRow.FinalBitLength := 0;
// Source: https://emn178.github.io/online-tools/sha3_224.html
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '32eb6a4121daebe223db1987740814e1dd9d9ddb' +
'ddfd466feff5c9b4';
lDataRow.ExpectedOutputUTFStrTest := '0f1ad8cd5a85fe68319b67427e1f0b685498bc24' +
'6a81a1f595c89e4e';
lDataRow.AddInputVector(RawByteString('e21et2e2et1208e7t12e07812te08127et1028e' +
'7t1208e7gd81d872t178r02tr370823'), 1, 10);
lDataRow.FinalBitLength := 0;
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'f7fc914c8fe4827d866b02df2459840260f4adb0' +
'db4deb9fa661756c';
lDataRow.ExpectedOutputUTFStrTest := 'e4d44bbda0b8fc8a73b421f6795c6380c0e21d50' +
'539a7b43c20a7529';
for i := 1 to 10 do
s := s + 'e21et2e2et1208e7t12e07812te08127et1028e7t1208e7gd81d872t178r02tr370823';
s := s + 'TurboMagic';
s := s + s + s;
lDataRow.AddInputVector(s);
lDataRow.FinalBitLength := 0;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-224_Msg5.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'ffbad5da96bad71789330206dc6768ecaeb1b32d' +
'ca6b3301489674ab';
lDataRow.ExpectedOutputUTFStrTest := '3d0e88c1e4fe0f6577e921e50805155b0748b40a' +
'3ab368c96b63f686';
lDataRow.AddInputVector(#$13);
lDataRow.FinalBitLength := 5;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-224_Msg30.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'd666a514cc9dba25ac1ba69ed3930460deaac985' +
'1b5f0baab007df3b';
lDataRow.ExpectedOutputUTFStrTest := '098526f4e121e977c325078374bf13ee9b0f2ed3' +
'14ce743c5641cebe';
lDataRow.AddInputVector(#$53#$58#$7B#$19);
lDataRow.FinalBitLength := 6;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-224_Msg1605.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '22d2f7bb0b173fd8c19686f9173166e3ee627380' +
'47d7eadd69efb228';
lDataRow.ExpectedOutputUTFStrTest := 'a6871aef1c16c4c0fcaef97636711fb6216b1586' +
'26d4e2b7e9e7e962';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3));
lDataRow.FinalBitLength := 5;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-224_1630.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '4e907bb1057861f200a599e9d4f85b02d88453bf' +
'5b8ace9ac589134c';
lDataRow.ExpectedOutputUTFStrTest := '30a15a07d7f0a34e5b36de3bec18c31eac2c9495' +
'2b50820095c8807e';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3));
lDataRow.FinalBitLength := 6;
end;
procedure TestTHash_SHA3_224.TestBlockSize;
begin
CheckEquals(144, FHash.BlockSize);
end;
procedure TestTHash_SHA3_224.TestClassByName;
begin
DoTestClassByName('THash_SHA3_224', THash_SHA3_224);
end;
procedure TestTHash_SHA3_224.TestDigestSize;
begin
CheckEquals(28, FHash.DigestSize);
end;
procedure TestTHash_SHA3_224.TestIdentity;
begin
CheckEquals($D0579DA9, FHash.Identity);
end;
procedure TestTHash_SHA3_224.TestIsPasswordHash;
begin
CheckNotEquals(true, FHash.IsPasswordHash);
end;
{ TestTHash_SHA3_256 }
procedure TestTHash_SHA3_256.ConfigHashClass(HashClass: TDECHash;
IdxTestData: Integer);
begin
inherited;
THash_SHA3_256(FHash).FinalByteLength := FTestData[IdxTestData].FinalByteLength;
THash_SHA3_256(FHash).PaddingByte := FTestData[IdxTestData].PaddingByte;
end;
procedure TestTHash_SHA3_256.SetUp;
var
lDataRow:IHashTestDataRowSetup;
begin
// All specified data sources are for the non unicode expected outputs
inherited;
FHash := THash_SHA3_256.Create;
//Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-
// Validation-Program/documents/sha3/sha-3bittestvectors.zip
FTestFileNames.Add('..\..\Unit Tests\Data\SHA3_256ShortMsg.rsp');
FTestFileNames.Add('..\..\Unit Tests\Data\SHA3_256LongMsg.rsp');
// SourceEnd
// Source: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-256_Msg0.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'a7ffc6f8bf1ed76651c14756a061d662f580ff4d' +
'e43b49fa82d80a4b80f8434a';
lDataRow.ExpectedOutputUTFStrTest := 'a7ffc6f8bf1ed76651c14756a061d662f580ff4d' +
'e43b49fa82d80a4b80f8434a';
lDataRow.AddInputVector('');
// Source: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-224_1600.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '79f38adec5c20307a98ef76e8324afbfd46cfd81' +
'b22e3973c65fa1bd9de31787';
lDataRow.ExpectedOutputUTFStrTest := '06ea5e186dab1b3f99bcf91918b53748367674c0' +
'5baa627010fba06edb67f0ba';
lDataRow.AddInputVector(RawByteString(
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3), 1, 20);
lDataRow.FinalBitLength := 0;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-256_Msg5.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '7b0047cf5a456882363cbf0fb05322cf65f4b705' +
'9a46365e830132e3b5d957af';
lDataRow.ExpectedOutputUTFStrTest := 'f2771aed86eba40f0f20c80aed2efb2ccdcd2a45' +
'14a89642353dc4ab6f31a0a1';
lDataRow.AddInputVector(#$13);
lDataRow.FinalBitLength := 5;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-256_Msg30.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'c8242fef409e5ae9d1f1c857ae4dc624b92b1980' +
'9f62aa8c07411c54a078b1d0';
lDataRow.ExpectedOutputUTFStrTest := '0264f8f24160a1c2336453338772637b64864ce1' +
'3c3c4207c40b34d28d68cd23';
lDataRow.AddInputVector(#$53#$58#$7B#$19);
lDataRow.FinalBitLength := 6;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-256_Msg1605.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '81ee769bed0950862b1ddded2e84aaa6ab7bfdd3' +
'ceaa471be31163d40336363c';
lDataRow.ExpectedOutputUTFStrTest := '7a4185574238ca2e2550a9fa85a0c5a327811698' +
'c3a05531a70e0a7ec369e2e5';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3));
lDataRow.FinalBitLength := 5;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-256_1630.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '52860aa301214c610d922a6b6cab981ccd06012e' +
'54ef689d744021e738b9ed20';
lDataRow.ExpectedOutputUTFStrTest := '8f0bb49b3327e5a03dd69bded05a86c9e7d72a7d' +
'719dd354a873cf2a70c30354';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3));
lDataRow.FinalBitLength := 6;
end;
procedure TestTHash_SHA3_256.TestBlockSize;
begin
CheckEquals(136, FHash.BlockSize);
end;
procedure TestTHash_SHA3_256.TestClassByName;
begin
DoTestClassByName('THash_SHA3_256', THash_SHA3_256);
end;
procedure TestTHash_SHA3_256.TestDigestSize;
begin
CheckEquals(32, FHash.DigestSize);
end;
procedure TestTHash_SHA3_256.TestIdentity;
begin
CheckEquals($71186A42, FHash.Identity);
end;
procedure TestTHash_SHA3_256.TestIsPasswordHash;
begin
CheckNotEquals(true, FHash.IsPasswordHash);
end;
{ TestTHash_SHA3_384 }
procedure TestTHash_SHA3_384.ConfigHashClass(HashClass: TDECHash;
IdxTestData: Integer);
begin
inherited;
THash_SHA3_384(FHash).FinalByteLength := FTestData[IdxTestData].FinalByteLength;
THash_SHA3_384(FHash).PaddingByte := FTestData[IdxTestData].PaddingByte;
end;
procedure TestTHash_SHA3_384.SetUp;
var
lDataRow:IHashTestDataRowSetup;
begin
inherited;
FHash := THash_SHA3_384.Create;
//Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-
// Validation-Program/documents/sha3/sha-3bittestvectors.zip
FTestFileNames.Add('..\..\Unit Tests\Data\SHA3_384ShortMsg.rsp');
FTestFileNames.Add('..\..\Unit Tests\Data\SHA3_384LongMsg.rsp');
// SourceEnd
// Source: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-384_Msg0.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '0c63a75b845e4f7d01107d852e4c2485c51a50aa' +
'aa94fc61995e71bbee983a2ac3713831264adb47' +
'fb6bd1e058d5f004';
lDataRow.ExpectedOutputUTFStrTest := '0c63a75b845e4f7d01107d852e4c2485c51a50aa' +
'aa94fc61995e71bbee983a2ac3713831264adb47' +
'fb6bd1e058d5f004';
lDataRow.AddInputVector('');
// Source: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-384_1600.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '1881de2ca7e41ef95dc4732b8f5f002b189cc1e4' +
'2b74168ed1732649ce1dbcdd76197a31fd55ee98' +
'9f2d7050dd473e8f';
lDataRow.ExpectedOutputUTFStrTest := '50dd07a64dc6ff190db60e612d8511742baa8eb5' +
'a499a0a02e51cea3f4b922f8ecf72785dc0a2ef3' +
'8230340378d3d104';
lDataRow.AddInputVector(RawByteString(
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3), 1, 20);
lDataRow.FinalBitLength := 0;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-384_Msg5.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '737c9b491885e9bf7428e792741a7bf8dca96534' +
'71c3e148473f2c236b6a0a6455eb1dce9f779b4b' +
'6b237fef171b1c64';
lDataRow.ExpectedOutputUTFStrTest := 'c2ab721500b00f70be1f5adfcbe70cdf22581c35' +
'ed47d265538c1cbd939f1fe8290e58d096eb3378' +
'f3a75818d623ebb8';
lDataRow.AddInputVector(#$13);
lDataRow.FinalBitLength := 5;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-384_Msg30.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '955b4dd1be03261bd76f807a7efd432435c41736' +
'2811b8a50c564e7ee9585e1ac7626dde2fdc030f' +
'876196ea267f08c3';
lDataRow.ExpectedOutputUTFStrTest := '20243fac26472f874f31539f8b26c1eb226f0c02' +
'3f7f3affa688a471a1943c6fb00dbcbb928b5234' +
'e19423670f34c328';
lDataRow.AddInputVector(#$53#$58#$7B#$19);
lDataRow.FinalBitLength := 6;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-384_Msg1605.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'a31fdbd8d576551c21fb1191b54bda65b6c5fe97' +
'f0f4a69103424b43f7fdb835979fdbeae8b3fe16' +
'cb82e587381eb624';
lDataRow.ExpectedOutputUTFStrTest := 'f3c3516f2b9d8a07233fc3dd427f8aba27d8e2e5' +
'793a6054f5bcdf005ce6de90d8dc6c69a833f5a7' +
'9da35504fc3ea8bc';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3));
lDataRow.FinalBitLength := 5;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-384_1630.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '3485d3b280bd384cf4a777844e94678173055d1c' +
'bc40c7c2c3833d9ef12345172d6fcd31923bb879' +
'5ac81847d3d8855c';
lDataRow.ExpectedOutputUTFStrTest := '63f5d9652bc5a4619ea4b3baf70a43e9d43d0620' +
'20109c162265f84c95eeb5768a4ce055dbe64385' +
'324650c2cd9091d5';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3));
lDataRow.FinalBitLength := 6;
end;
procedure TestTHash_SHA3_384.TestBlockSize;
begin
CheckEquals(104, FHash.BlockSize);
end;
procedure TestTHash_SHA3_384.TestClassByName;
begin
DoTestClassByName('THash_SHA3_384', THash_SHA3_384);
end;
procedure TestTHash_SHA3_384.TestDigestSize;
begin
CheckEquals(48, FHash.DigestSize);
end;
procedure TestTHash_SHA3_384.TestIdentity;
begin
CheckEquals($2B7A1F14, FHash.Identity);
end;
procedure TestTHash_SHA3_384.TestIsPasswordHash;
begin
CheckNotEquals(true, FHash.IsPasswordHash);
end;
{ TestTHash_SHA3_512 }
procedure TestTHash_SHA3_512.ConfigHashClass(HashClass: TDECHash;
IdxTestData: Integer);
begin
inherited;
THash_SHA3_512(FHash).FinalByteLength := FTestData[IdxTestData].FinalByteLength;
THash_SHA3_512(FHash).PaddingByte := FTestData[IdxTestData].PaddingByte;
end;
procedure TestTHash_SHA3_512.SetUp;
var
lDataRow : IHashTestDataRowSetup;
begin
inherited;
FHash := THash_SHA3_512.Create;
//Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Algorithm-
// Validation-Program/documents/sha3/sha-3bittestvectors.zip
FTestFileNames.Add('..\..\Unit Tests\Data\SHA3_512ShortMsg.rsp');
FTestFileNames.Add('..\..\Unit Tests\Data\SHA3_512LongMsg.rsp');
// SourceEnd
// Source: https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-512_1600.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'e76dfad22084a8b1467fcf2ffa58361bec7628ed' +
'f5f3fdc0e4805dc48caeeca81b7c13c30adf52a3' +
'659584739a2df46be589c51ca1a4a8416df6545a' +
'1ce8ba00';
lDataRow.ExpectedOutputUTFStrTest := '54ab223a7cee7603f2b89596b54f8d838845e0a0' +
'af2be3e9ad2cd7acb111757cb0c41b3564c07778' +
'47684435da78577781eef8e6a6652c9844a85882' +
'e0fa8b28';
lDataRow.AddInputVector(RawByteString(
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3), 1, 20);
lDataRow.FinalBitLength := 0;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-512_Msg5.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'a13e01494114c09800622a70288c432121ce7003' +
'9d753cadd2e006e4d961cb27544c1481e5814bdc' +
'eb53be6733d5e099795e5e81918addb058e22a9f' +
'24883f37';
lDataRow.ExpectedOutputUTFStrTest := '6961fe7f75e0ad35aead16be49c711b373d22226' +
'ea2b7b2897df24048287a1b6d7b43bad246c8a44' +
'ddccb49263a688343fa60142650a3e06af2a87c9' +
'296438a8';
lDataRow.AddInputVector(#$13);
lDataRow.FinalBitLength := 5;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-512_Msg30.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := '9834c05a11e1c5d3da9c740e1c106d9e590a0e53' +
'0b6f6aaa7830525d075ca5db1bd8a6aa981a2861' +
'3ac334934a01823cd45f45e49b6d7e6917f2f167' +
'78067bab';
lDataRow.ExpectedOutputUTFStrTest := '7e59a0c8fca17a79c748f927c85408bfda1b158d' +
'7ab95df59f650a3bb773e1eb6c1112cd2c351b24' +
'b99a2f8e08688ec19816bfc292fba63305307571' +
'ce9360cf';
lDataRow.AddInputVector(#$53#$58#$7B#$19);
lDataRow.FinalBitLength := 6;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-512_Msg1605.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'fc4a167ccb31a937d698fde82b04348c9539b28f' +
'0c9d3b4505709c03812350e4990e9622974f6e57' +
'5c47861c0d2e638ccfc2023c365bb60a93f52855' +
'0698786b';
lDataRow.ExpectedOutputUTFStrTest := '7e65803342ce242fdc8cfd27019516669615327f' +
'679ced86453df7ee0a745267a453e7b94568c2ea' +
'dc4ce7a7de02f48a5c2204d03418542f1a64f7db' +
'78026218';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3));
lDataRow.FinalBitLength := 5;
// Source https://csrc.nist.gov/CSRC/media/Projects/Cryptographic-Standards-
// and-Guidelines/documents/examples/SHA3-512_1630.pdf
lDataRow := FTestData.AddRow;
lDataRow.ExpectedOutput := 'cf9a30ac1f1f6ac0916f9fef1919c595debe2ee8' +
'0c85421210fdf05f1c6af73aa9cac881d0f91db6' +
'd034a2bbadc1cf7fbcb2ecfa9d191d3a5016fb3f' +
'ad8709c9';
lDataRow.ExpectedOutputUTFStrTest := '55971e2e5d0182f25bc453364f9d3a77fef05e7e' +
'32c99e630a8586c37815aea5087a51aa3730f855' +
'df963c7740f4e6bd2b73f5079cf317031ed120c3' +
'3df4054d';
lDataRow.AddInputVector(RawByteString(#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3#$A3 +
#$A3#$A3#$A3#$A3));
lDataRow.FinalBitLength := 6;
end;
procedure TestTHash_SHA3_512.TestBlockSize;
begin
CheckEquals(72, FHash.BlockSize);
end;
procedure TestTHash_SHA3_512.TestClassByName;
begin
DoTestClassByName('THash_SHA3_512', THash_SHA3_512);
end;
procedure TestTHash_SHA3_512.TestDigestSize;
begin
CheckEquals(64, FHash.DigestSize);
end;
procedure TestTHash_SHA3_512.TestIdentity;
begin
CheckEquals($17567DDA, FHash.Identity);
end;
procedure TestTHash_SHA3_512.TestIsPasswordHash;
begin
CheckNotEquals(true, FHash.IsPasswordHash);
end;
initialization
// Register any test cases with the test runner
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TestTHash_SHA3_224);
TDUnitX.RegisterTestFixture(TestTHash_SHA3_256);
TDUnitX.RegisterTestFixture(TestTHash_SHA3_384);
TDUnitX.RegisterTestFixture(TestTHash_SHA3_512);
{$ELSE}
RegisterTests('DECHash', [TestTHash_SHA3_224.Suite,
TestTHash_SHA3_256.Suite,
TestTHash_SHA3_384.Suite,
TestTHash_SHA3_512.Suite]);
{$ENDIF}
{$ELSE}
implementation
{$IFEND}
end.

View File

@@ -0,0 +1,166 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECRandom;
interface
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
uses
System.SysUtils, System.Classes,
{$IFDEF DUnitX}
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
DECRandom;
type
/// <summary>
/// This can only implement a rough test of the default behavior of the PNRG.
/// We do not have access to the default seed value generation functions etc.
/// so we cannod test RandomSeed properly as we could provide our own
/// implementation of the default seed generators but couldn't resore the
/// default ones afterwards, which should be done to enable repeated test
/// runs in the same session.
/// </summary>
TTestRandom = class(TTestCase)
private
RandomNumbers: TBytes;
public
published
procedure TestRandomLong;
procedure TestRandomBytes;
procedure TestRandomBuffer;
procedure TestRandomBufferIncompletelyFilled;
end;
implementation
{ TTestRandom }
procedure TTestRandom.TestRandomBuffer;
var
Result : TBytes;
Expected : TBytes;
i : Integer;
begin
// Set up the seed with a known value of 0 so always the same known sequence
// results
RandomSeed(RandomNumbers, 0);
SetLength(Result, 5);
FillChar(Result[0], 5, 0);
RandomBuffer(Result[0], 5);
Expected := TBytes.Create(208, 208, 25, 65, 118);
for i := Low(Expected) to High(Expected) do
CheckEquals(Expected[i], Result[i],
'Wrong random number in known sequence at index ' + IntToStr(i));
SetLength(Result, 5);
FillChar(Result[0], 5, 0);
RandomBuffer(Result[0], 5);
Expected := TBytes.Create(107, 181, 127, 194, 179);
for i := Low(Expected) to High(Expected) do
CheckEquals(Expected[i], Result[i],
'Wrong random number in known sequence at index ' + IntToStr(i));
end;
procedure TTestRandom.TestRandomBufferIncompletelyFilled;
var
Result : TBytes;
Expected : TBytes;
i : Integer;
begin
// Set up the seed with a known value of 0 so always the same known sequence
// results
RandomSeed(RandomNumbers, 0);
SetLength(Result, 10);
FillChar(Result[0], 5, 0);
RandomBuffer(Result[0], 5);
Expected := TBytes.Create(208, 208, 25, 65, 118, 0, 0, 0, 0, 0);
for i := Low(Expected) to High(Expected) do
CheckEquals(Expected[i], Result[i],
'Wrong random number in known sequence at index ' + IntToStr(i));
SetLength(Result, 10);
FillChar(Result[0], 5, 0);
RandomBuffer(Result[0], 5);
Expected := TBytes.Create(107, 181, 127, 194, 179, 0, 0, 0, 0, 0);
for i := Low(Expected) to High(Expected) do
CheckEquals(Expected[i], Result[i],
'Wrong random number in known sequence at index ' + IntToStr(i));
end;
procedure TTestRandom.TestRandomBytes;
var
Result : TBytes;
Expected : TBytes;
i : Integer;
begin
// Set up the seed with a known value of 0 so always the same known sequence
// results
RandomSeed(RandomNumbers, 0);
Result := RandomBytes(5);
Expected := TBytes.Create(208, 208, 25, 65, 118);
for i := Low(Expected) to High(Expected) do
CheckEquals(Expected[i], Result[i],
'Wrong random number in known sequence at index ' + IntToStr(i));
Result := RandomBytes(5);
Expected := TBytes.Create(107, 181, 127, 194, 179);
for i := Low(Expected) to High(Expected) do
CheckEquals(Expected[i], Result[i],
'Wrong random number in known sequence at index ' + IntToStr(i));
end;
procedure TTestRandom.TestRandomLong;
begin
// Set up the seed with a known value of 0 so always the same known sequence
// results
RandomSeed(RandomNumbers, 0);
CheckEquals(1092210896, RandomLong, 'Wrong random number from known sequence');
CheckEquals(2142595958, RandomLong, 'Wrong random number from known sequence');
CheckEquals(1475261378, RandomLong, 'Wrong random number from known sequence');
end;
initialization
// Register any test cases with the test runner
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TTestRandom);
{$ELSE}
RegisterTests('DECRandom', [TTestRandom.Suite]);
{$ENDIF}
end.

View File

@@ -0,0 +1,610 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
unit TestDECTestDataContainer;
interface
type
ITestDataInputVector = interface
['{CEC7AE49-DA2D-438A-BE8B-2BC2FA1DBCD0}']
function GetRunCount:UInt32;
function GetData:RawByteString;
/// <summary>
/// Number of times this test needs to be run to produce the final test data
/// </summary>
property RepeatCount:UInt32
read GetRunCount;
/// <summary>
/// Input data for the test
/// </summary>
property Data:RawByteString
read GetData;
end;
ITestDataInputVectorList = interface
['{34CEDD4B-4249-4C69-A0CC-C89F90A9B4E3}']
function GetCount:Integer;
function GetVector(aIndex:Integer):ITestDataInputVector;
property Count:Integer
read GetCount;
property Vectors[aIndex:integer]:ITestDataInputVector
read GetVector; default;
function AddInputVector(const aData:RawByteString; const aRunCount:UInt32=1;
const aConcatCount:UInt32=1;
const aFinalBitCount:UInt32 = 0):ITestDataInputVector;
end;
ITestDataRow = interface
['{A105BADC-46E9-4A1D-B338-5C8E60305823}']
function GetInputData:RawByteString;
function GetInputVectors:ITestDataInputVectorList;
function GetOutputData:RawByteString;
function GetOutputUTFStrTest:RawByteString;
property InputData : RawByteString
read GetInputData;
property InputDataVectors : ITestDataInputVectorList
read GetInputVectors;
property ExpectedOutput : RawByteString
read GetOutputData;
property ExpectedOutputUTFStrTest : RawByteString
read GetOutputUTFStrTest;
end;
ITestDataRowSetup = interface
['{DCB0F980-7120-41A6-BD02-118B594E2AB6}']
procedure SetExpectedOutput(const aValue:RawByteString);
procedure SetExpectedOutputUTFStrTest(const aValue:RawByteString);
property ExpectedOutput : RawByteString
Write SetExpectedOutput;
property ExpectedOutputUTFStrTest : RawByteString
Write SetExpectedOutputUTFStrTest;
procedure AddInputVector(const aData:RawByteString; const aRunCount:UInt32=1;
const aConcatCount:UInt32=1);
end;
ITestDataContainer = interface
['{65205874-94D9-424C-8314-4816D33CECA4}']
function GetCount:Integer;
property Count:Integer
read GetCount;
procedure Clear;
end;
// ---------------------------------------------------------------------------
IHashTestDataRowSetup = interface(ITestDataRowSetup)
['{ADB4AFA2-4199-47F4-86F6-E84A20C3AA8E}']
/// <summary>
/// Specifies the length of the hash value generated for those hash classes
/// which support configurable output lengths.
/// </summary>
/// <param name="aValue">
/// Length of the calculated hash value in byte
/// </param>
procedure SetRequiredDigestSize(const aValue:UInt32);
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. The SHA3 tests using this require to specify what this last
/// byte contains if it is not contained in the test data itsself already
/// (because that would influence the length of that test data)
/// </summary>
/// <param name="aValue">
/// Value which is used in the finalization of the hash calculation if
/// SHA3's feature of bit length specification of the input data is being
/// used.
/// </param>
procedure SetPaddingByte(const aValue:Byte);
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. This property specifies how many bits of the last byte shall
/// be processed.
/// </summary>
/// <param name="aValue">
/// Number of bits of the last byte within the test data to process
/// </param>
procedure SetFinalBitLength(const aValue: Int16);
/// <summary>
/// Specifies the length of the hash value generated for those hash classes
/// which support configurable output lengths. The length is specified in
/// byte.
/// </summary>
property RequiredDigestSize : UInt32
Write SetRequiredDigestSize;
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. This property specifies how many bits of the last byte shall
/// be processed.
/// </summary>
property PaddingByte : Byte
Write SetPaddingByte;
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. This property specifies how many bits of the last byte shall
/// be processed.
/// </summary>
property FinalBitLength : Int16
write SetFinalBitLength;
end;
IHashTestDataRow = interface(ITestDataRow)
['{73ED2877-967A-410B-8493-636F099FBA60}']
/// <summary>
/// Gets the length of the hash value generated for those hash classes
/// which support configurable output lengths.
/// </summary>
/// <returns>
/// Length of the calculated hash value in byte
/// </returns>
function GetRequiredDigestSize:UInt32;
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. The SHA3 tests using this require to specify what this last
/// byte contains if it is not contained in the test data itsself already
/// (because that would influence the length of that test data)
/// </summary>
/// <returns>
/// Value which is used in the finalization of the hash calculation if
/// SHA3's feature of bit length specification of the input data is being
/// used.
/// </returns>
function GetPaddingByte:Byte;
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. This property specifies how many bits of the last byte shall
/// be processed.
/// </summary>
function GetFinalBitLength:Int16;
/// <summary>
/// Gets the length in bytes of the hash value generated for those
/// hash classes which support configurable output lengths.
/// </summary>
property RequiredDigestSize : UInt32
read GetRequiredDigestSize;
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. The SHA3 tests using this require to specify what this last
/// byte contains if it is not contained in the test data itsself already
/// (because that would influence the length of that test data).
///
/// Value which is used in the finalization of the hash calculation if
/// SHA3's feature of bit length specification of the input data is being
/// used.
/// </summary>
property PaddingByte : Byte
read GetPaddingByte;
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. This property specifies how many bits of the last byte shall
/// be processed.
/// </summary>
property FinalByteLength : Int16
read GetFinalBitLength;
end;
IHashTestDataContainer = interface(ITestDataContainer)
['{BDF2082D-3133-48D8-B9AA-87F3485FD91F}']
function GetRows(aIndex:Integer):IHashTestDataRow;
property Rows[aIndex:Integer]:IHashTestDataRow
read GetRows; default;
function AddRow:IHashTestDataRowSetup;
end;
function CreateTestDataContainer:ITestDataContainer;
implementation
uses
Classes;
type
TTestDataInputVector = class(TInterfacedObject, ITestDataInputVector)
private
FData : RawByteString;
FRunCount : UInt32;
FFinalBitCount : UInt32;
protected // ITestDataInputVector
function GetRunCount:UInt32;
function GetData:RawByteString;
public
constructor Create(const aData:RawByteString; const aRunCount:UInt32; const aFinalBitCOunt: UInt32);
end;
/// <summary>
/// All methods are protected by design so that nobody directly uses this class.
/// It shall be used via the ITestDataInputVectorContainer interface, which
/// automatically makes the methods allowed to be used externally public
/// </summary>
TTestDataInputVectorList = class(TInterfacedObject, ITestDataInputVectorList)
private
/// <summary>
/// List of all the input values for the tests
/// </summary>
FVectors : TInterfaceList;
protected // ITestDataInputVectorContainer
/// <summary>
/// Returns the number of test data entries (vectors) stored in the list
/// </summary>
function GetCount:Integer;
/// <summary>
/// Returns the test data vector specified by the index
/// </summary>
/// <param name="aIndex">
/// Index of the vector which shall be returned
/// </param>
/// <returns>
/// Test data entry
/// </returns>
function GetVector(aIndex:Integer):ITestDataInputVector;
/// <summary>
/// Adds an input vector for one test to the list
/// </summary>
/// <param name="aData">
/// Test data for the vector
/// </param>
/// <param name="aRunCount">
/// Number of times the test shall be repeated on the data given, default = 1
/// </param>
/// <param name="aConcatCount">
/// Number of times aData is being concatenated to form the real input data
/// for this test vector
/// </param>
/// <param name="aFinalBitCount">
{ TODO : Rework comment as far as necessary after implementing this }
/// some hash algorithms allow to specify the size of the data to calculate
/// the hash from in bits. If this parameter is set to a value > 0 the last
/// byte of the data specified in aData is not hashed with the "Calc" method
/// but the aFinalBitCount number of bits from it are hashed in Done or so...
/// </param>
/// <returns>
/// An interface to the generated test vector
/// </returns>
function AddInputVector(const aData:RawByteString;
const aRunCount:UInt32=1;
const aConcatCount:UInt32=1;
const aFinalBitCount:UInt32 = 0):ITestDataInputVector;
public
constructor Create;
destructor Destroy; override;
end;
THashTestDataRow = class(TInterfacedObject, ITestDataRow, ITestDataRowSetup,
IHashTestDataRow, IHashTestDataRowSetup)
private
FInputData:RawByteString;
FInputVectors:ITestDataInputVectorList;
FOutputData:RawByteString;
FOutputUTFStrTest:RawByteString;
FReqDigSize:UInt32;
FPaddingByte:Byte;
FFinalBitLength: Int16;
protected // ITestDataRow
function GetInputData:RawByteString;
function GetInputVectors:ITestDataInputVectorList;
function GetOutputData:RawByteString;
function GetOutputUTFStrTest:RawByteString;
protected // ITestDataRowSetup
procedure SetExpectedOutput(const aValue:RawByteString);
procedure SetExpectedOutputUTFStrTest(const aValue:RawByteString);
procedure AddInputVector(const aData:RawByteString; const aRunCount:UInt32=1;
const aConcatCount:UInt32=1);
protected // IHashTestDataRow
/// <summary>
/// Gets the length of the hash value generated for those hash classes
/// which support configurable output lengths.
/// </summary>
/// <returns>
/// Length of the calculated hash value in byte
/// </returns>
function GetRequiredDigestSize:UInt32;
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. The SHA3 tests using this require to specify what this last
/// byte contains if it is not contained in the test data itsself already
/// (because that would influence the length of that test data)
/// </summary>
/// <returns>
/// Value which is used in the finalization of the hash calculation if
/// SHA3's feature of bit length specification of the input data is being
/// used.
/// </returns>
function GetPaddingByte:Byte;
function GetFinalBitLength:Int16;
protected // IHashTestDataRowSetup
/// <summary>
/// Specifies the length of the hash value generated for those hash classes
/// which support configurable output lengths.
/// </summary>
/// <param name="aValue">
/// Length of the calculated hash value in byte
/// </param>
procedure SetRequiredDigestSize(const aValue:UInt32);
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. The SHA3 tests using this require to specify what this last
/// byte contains if it is not contained in the test data itsself already
/// (because that would influence the length of that test data)
/// </summary>
/// <param name="aValue">
/// Value which is used in the finalization of the hash calculation if
/// SHA3's feature of bit length specification of the input data is being
/// used.
/// </param>
procedure SetPaddingByte(const aValue:Byte);
/// <summary>
/// Required parameter for SHA3 tests: SHA3 allows to specify the number of
/// bits of the input bytes which shall be processed. This can lead to the
/// situation that the last byte of the input data shall not be processed
/// completely. This property specifies how many bits of the last byte shall
/// be processed.
/// </summary>
/// <param name="aValue">
/// Number of bits of the last byte within the test data to process
/// </param>
procedure SetFinalBitLength(const aValue: Int16);
public
constructor Create;
destructor Destroy; override;
end;
/// <summary>
/// List of all the test vectors of a unit test for one of the hash classes
/// </summary>
TTestDataList = class(TInterfacedObject, ITestDataContainer, IHashTestDataContainer)
private
FDataRows:TInterfaceList;
protected // ITestDataContainer
function GetCount:Integer;
function GetRows(aIndex:Integer):ITestDataRow;
procedure Clear;
protected // IHashTestDataContainer
function HASH_AddRow:IHashTestDataRowSetup; function IHashTestDataContainer.AddRow = HASH_Addrow;
function HASH_GetRows(aIndex:Integer):IHashTestDataRow; function IHashTestDataContainer.GetRows = HASH_GetRows;
public
constructor Create;
destructor Destroy; override;
end;
function CreateTestDataContainer:ITestDataContainer;
begin
result := TTestDataList.Create;
end;
{ TTestDataContainer }
procedure TTestDataList.Clear;
begin
FDataRows.Clear;
end;
constructor TTestDataList.Create;
begin
inherited Create;
FDataRows := TInterfaceList.Create;
end;
destructor TTestDataList.Destroy;
begin
FDataRows.Free;
inherited;
end;
function TTestDataList.GetCount: Integer;
begin
result := FDataRows.Count;
end;
function TTestDataList.GetRows(aIndex: Integer): ITestDataRow;
begin
result := FDataRows.Items[aIndex] as ITestDataRow;
end;
function TTestDataList.HASH_AddRow: IHashTestDataRowSetup;
begin
Result := THashTestDataRow.Create;
FDataRows.Add(Result);
end;
function TTestDataList.HASH_GetRows(aIndex: Integer): IHashTestDataRow;
begin
result := FDataRows.Items[aIndex] as IHashTestDataRow;
end;
{ TTestDataRow }
procedure THashTestDataRow.AddInputVector(const aData: RawByteString; const aRunCount, aConcatCount: UInt32);
var
lData:RawByteString;
Idx:Integer;
lVector:ITestDataInputVector;
begin
lVector := FInputVectors.AddInputVector(aData, aRunCount, aConcatCount);
lData := '';
for Idx := 1 to lVector.RepeatCount do
begin
lData := lData + lVector.Data;
end;
FInputData := FInputData + lData;
end;
constructor THashTestDataRow.Create;
begin
inherited Create;
FInputVectors := TTestDataInputVectorList.Create;
end;
destructor THashTestDataRow.Destroy;
begin
FInputVectors := NIL;
inherited;
end;
function THashTestDataRow.GetFinalBitLength: Int16;
begin
result := FFinalBitLength;
end;
function THashTestDataRow.GetInputData: RawByteString;
begin
result := FInputData;
end;
function THashTestDataRow.GetInputVectors: ITestDataInputVectorList;
begin
result := FInputVectors;
end;
function THashTestDataRow.GetOutputData: RawByteString;
begin
result := FOutputData;
end;
function THashTestDataRow.GetOutputUTFStrTest: RawByteString;
begin
result := FOutputUTFStrTest;
end;
function THashTestDataRow.GetPaddingByte: Byte;
begin
result := FPaddingByte;
end;
function THashTestDataRow.GetRequiredDigestSize: UInt32;
begin
result := FReqDigSize;
end;
procedure THashTestDataRow.SetExpectedOutput(const aValue: RawByteString);
begin
FOutputData := aValue;
end;
procedure THashTestDataRow.SetExpectedOutputUTFStrTest(const aValue: RawByteString);
begin
FOutputUTFStrTest := aValue;
end;
procedure THashTestDataRow.SetFinalBitLength(const aValue: Int16);
begin
FFinalBitLength := aValue;
end;
procedure THashTestDataRow.SetPaddingByte(const aValue: Byte);
begin
FPaddingByte := aValue;
end;
procedure THashTestDataRow.SetRequiredDigestSize(const aValue: UInt32);
begin
FReqDigSize := aValue;
end;
{ TTestDataInputVectorContainer }
function TTestDataInputVectorList.AddInputVector(const aData:RawByteString;
const aRunCount:UInt32=1; const aConcatCount:UInt32=1;
const aFinalBitCount:UInt32 = 0):ITestDataInputVector;
var
lData : RawByteString;
Idx : Integer;
begin
lData := '';
for Idx := 1 to aConcatCount do
begin
lData := lData + aData;
end;
Result := TTestDataInputVector.Create(lData, aRunCount, aFinalBitCount);
FVectors.Add(Result);
end;
constructor TTestDataInputVectorList.Create;
begin
inherited Create;
FVectors := TInterfaceList.Create;
end;
destructor TTestDataInputVectorList.Destroy;
begin
FVectors.Free;
inherited;
end;
function TTestDataInputVectorList.GetCount: Integer;
begin
result := FVectors.Count;
end;
function TTestDataInputVectorList.GetVector(aIndex: Integer): ITestDataInputVector;
begin
result := FVectors.Items[aIndex] as ITestDataInputVector;
end;
{ TTestDataInputVector }
constructor TTestDataInputVector.Create(const aData: RawByteString;
const aRunCount: UInt32;
const aFinalBitCOunt: UInt32);
begin
inherited Create;
FData := aData;
FRunCount := aRunCount;
FFinalBitCount := aFinalBitCount;
end;
function TTestDataInputVector.GetData: RawByteString;
begin
result := FData;
end;
function TTestDataInputVector.GetRunCount: UInt32;
begin
result := FRunCount;
end;
end.

View File

@@ -0,0 +1,451 @@
{*****************************************************************************
The DEC team (see file NOTICE.txt) licenses this file
to you under the Apache License, Version 2.0 (the
"License"); you may not use this file except in compliance
with the License. A copy of this licence is found in the root directory of
this project in the file LICENCE.txt or alternatively at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing,
software distributed under the License is distributed on an
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
*****************************************************************************}
{$M+} // DUnitX would add it anyway
unit TestDECUtil;
interface
// Needs to be included before any other statements
{$INCLUDE TestDefines.inc}
uses
System.SysUtils, System.Classes,
{$IFDEF DUnitX}
DUnitX.TestFramework,DUnitX.DUnitCompatibility,
{$ELSE}
TestFramework,
{$ENDIF}
DECUtil;
type
TTestBitTwiddling = class(TTestCase)
published
procedure ReverseBits32;
procedure ReverseBits8;
procedure SwapBytes;
procedure SwapLong;
procedure SwapLongBuffer;
procedure SwapInt64;
procedure SwapInt64Buffer;
procedure XORBuffers;
end;
TTestBufferProtection = class(TTestCase)
published
procedure ProtectBuffer;
procedure ProtectStream;
procedure ProtectStreamPartial;
procedure ProtectBytes;
procedure ProtectString;
{$IFDEF ANSISTRINGSUPPORTED}
procedure ProtectStringAnsi;
{$ENDIF}
{$IFNDEF NextGen}
procedure ProtectStringWide;
{$ENDIF}
{$IFDEF MSWINDOWS}
procedure ProtectStringRawByteString;
{$ENDIF}
procedure BytesToRawString;
procedure BytesToRawStringEmpty;
end;
implementation
type
TestRecUInt8 = record
Input : UInt8;
Result : UInt8;
end;
TestRecCardinal = record
Input: Cardinal;
Result: Cardinal;
end;
TestRecInt64 = record
Input : Int64;
Result: Int64;
end;
procedure TTestBitTwiddling.ReverseBits32;
const
ReverseBitArray: array[0..4] of TestRecCardinal = (
(Input: 0; Result: 0),
(Input: 256; Result: 8388608),
(Input: 1024; Result: 2097152),
(Input: 65536; Result: 32768),
(Input: 4294967295; Result: 4294967295)
);
var
i: Integer;
begin
for i := 0 to Length(ReverseBitArray) - 1 do
begin
CheckEquals(ReverseBitArray[i].Result, DECUtil.ReverseBits(ReverseBitArray[i].Input));
end;
end;
procedure TTestBitTwiddling.ReverseBits8;
const
ReverseBitArray: array[0..4] of TestRecUInt8 = (
(Input: 0; Result: 0),
(Input: 1; Result: 128),
(Input: 255; Result: 255),
(Input: 10; Result: $50),
(Input: 11; Result: $D0)
);
var
i: Integer;
begin
for i := 0 to Length(ReverseBitArray) - 1 do
begin
CheckEquals(ReverseBitArray[i].Result, DECUtil.ReverseBits(ReverseBitArray[i].Input));
end;
end;
procedure TTestBitTwiddling.SwapBytes;
const
Input: RawByteString = '0123456789';
Output: RawByteString = '9876543210';
var
s: RawByteString;
c: Cardinal;
begin
s := Input;
{$IF CompilerVersion >= 24.0}
DECUtil.SwapBytes(s[Low(s)], Length(s));
{$ELSE}
DECUtil.SwapBytes(s[1], Length(s));
{$IFEND}
CheckEquals(Output, s);
{$IF CompilerVersion >= 24.0}
DECUtil.SwapBytes(s[Low(s)], Length(s));
{$ELSE}
DECUtil.SwapBytes(s[1], Length(s));
{$IFEND}
CheckEquals(Input, s);
c := 123456789;
DECUtil.SwapBytes(c, SizeOf(UInt32));
CheckEquals(365779719, c);
c := High(Cardinal);
DECUtil.SwapBytes(c, SizeOf(UInt32));
CheckEquals(4294967295, c);
end;
procedure TTestBitTwiddling.SwapLong;
const
SwapLongArray: array[0..4] of TestRecCardinal = (
(Input: 0; Result: 0),
(Input: 256; Result: 65536),
(Input: 1024; Result: 262144),
(Input: 65536; Result: 256),
(Input: 4294967295; Result: 4294967295)
);
var
i: Integer;
begin
for i := 0 to Length(SwapLongArray) - 1 do
CheckEquals(SwapLongArray[i].Result, DECUtil.SwapUInt32(SwapLongArray[i].Input));
end;
procedure TTestBitTwiddling.SwapLongBuffer;
const
SwapLongArray: array[0..4] of TestRecCardinal = (
(Input: 0; Result: 0),
(Input: 256; Result: 65536),
(Input: 1024; Result: 262144),
(Input: 65536; Result: 256),
(Input: 4294967295; Result: 4294967295)
);
var
SrcBuf : array[0..length(SwapLongArray)] of UInt32;
DestBuf : array[0..length(SwapLongArray)] of UInt32;
i : Integer;
begin
for i := Low(SwapLongArray) to High(SwapLongArray) do
SrcBuf[i] := SwapLongArray[i].Input;
DECUtil.SwapUInt32Buffer(SrcBuf, DestBuf, Length(SrcBuf));
for i := Low(SwapLongArray) to High(SwapLongArray) do
CheckEquals(SwapLongArray[i].Result, DestBuf[i]);
end;
procedure TTestBitTwiddling.SwapInt64;
const
// Intel CPU is Little Endian
SwapInt64Array: array[0..6] of TestRecInt64 = (
(Input: 0; Result: 0),
(Input: 1; Result: 72057594037927936), // 2^56
(Input: 2; Result: 144115188075855872), // 2^57
(Input: 256; Result: 281474976710656), // 2^48
(Input: 65536; Result: 1099511627776), // 2^40
(Input: 16777216; Result: 4294967296), // 2^32
(Input: -1; Result: -1)
);
var
i : Integer;
begin
for i := Low(SwapInt64Array) to High(SwapInt64Array) do
CheckEquals(SwapInt64Array[i].Result, DECUtil.SwapInt64(SwapInt64Array[i].Input));
end;
procedure TTestBitTwiddling.SwapInt64Buffer;
const
// Intel CPU is Little Endian
SwapInt64Array: array[0..6] of TestRecInt64 = (
(Input: 0; Result: 0),
(Input: 1; Result: 72057594037927936), // 2^56
(Input: 2; Result: 144115188075855872), // 2^57
(Input: 256; Result: 281474976710656), // 2^48
(Input: 65536; Result: 1099511627776), // 2^40
(Input: 16777216; Result: 4294967296), // 2^32
(Input: -1; Result: -1)
);
var
SrcBuf : array[0..length(SwapInt64Array)] of Int64;
DestBuf : array[0..length(SwapInt64Array)] of Int64;
i : Integer;
begin
for i := Low(SwapInt64Array) to High(SwapInt64Array) do
SrcBuf[i] := SwapInt64Array[i].Input;
DECUtil.SwapInt64Buffer(SrcBuf, DestBuf, Length(SrcBuf));
for i := Low(SwapInt64Array) to High(SwapInt64Array) do
CheckEquals(SwapInt64Array[i].Result, DestBuf[i]);
end;
procedure TTestBitTwiddling.XORBuffers;
type
UInt32Rec = packed record
case Integer of
0: (UInt32: UInt32);
1: (Bytes: array [0..3] of Byte);
end;
var
LBuf, RBuf : TBytes;
DestBuf : TBytes;
CheckBuf :UInt32Rec;
i : Integer;
begin
SetLength(LBuf, 4);
SetLength(RBuf, 4);
SetLength(DestBuf, 4);
for i := 0 to 3 do
begin
LBuf[i] := i;
RBuf[i] := i;
end;
DECUtil.XORBuffers(LBuf[0], RBuf[0], Length(LBuf), DestBuf[0]);
for i := Low(DestBuf) to High(DestBuf) do
CheckBuf.Bytes[i] := DestBuf[i];
CheckEquals(0, CheckBuf.UInt32);
SetLength(LBuf, 4);
SetLength(RBuf, 4);
SetLength(DestBuf, 4);
for i := 0 to 3 do
begin
LBuf[i] := i;
RBuf[i] := 0;
end;
DECUtil.XORBuffers(LBuf[0], RBuf[0], Length(LBuf), DestBuf[0]);
for i := Low(DestBuf) to High(DestBuf) do
CheckBuf.Bytes[i] := DestBuf[i];
CheckEquals(50462976, CheckBuf.UInt32);
end;
procedure TTestBufferProtection.ProtectBuffer;
var
Buf : TBytes;
i : Integer;
begin
SetLength(Buf, 12);
for i := $40 to $40 + Length(Buf) - 1 do
Buf[i-$40] := i;
DECUtil.ProtectBuffer(Buf[0], Length(Buf));
CheckEquals(#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00,
string(DECUtil.BytesToRawString(Buf)));
end;
procedure TTestBufferProtection.ProtectStream;
var
Stream : TMemoryStream;
SrcBuf : TBytes;
DestBuf : TBytes;
i : Integer;
begin
SetLength(SrcBuf, 12);
for i := $40 to $40 + Length(SrcBuf) - 1 do
SrcBuf[i-$40] := i;
SetLength(DestBuf, Length(SrcBuf));
Stream := TMemoryStream.Create;
try
Stream.Write(SrcBuf[0], Length(SrcBuf));
Stream.Position := 0;
DECUtil.ProtectStream(Stream, Stream.Size);
Stream.Read(DestBuf[0], Stream.Size);
CheckEquals(#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00+#$00,
string(DECUtil.BytesToRawString(DestBuf)));
finally
Stream.Free;
end;
end;
procedure TTestBufferProtection.ProtectStreamPartial;
var
Stream : TMemoryStream;
SrcBuf : TBytes;
DestBuf : TBytes;
i : Integer;
begin
SetLength(SrcBuf, 12);
for i := $40 to $40 + Length(SrcBuf) - 1 do
SrcBuf[i-$40] := i;
SetLength(DestBuf, Length(SrcBuf));
Stream := TMemoryStream.Create;
try
Stream.Write(SrcBuf[0], Length(SrcBuf));
Stream.Position := 0;
DECUtil.ProtectStream(Stream, 2);
Stream.Read(DestBuf[0], Stream.Size);
CheckEquals(#$42+#$43+#$44+#$45+#$46+#$47+#$48+#$49+#$4A+#$4B+#$00+#$00,
string(DECUtil.BytesToRawString(DestBuf)));
finally
Stream.Free;
end;
end;
procedure TTestBufferProtection.ProtectBytes;
var
Buf : TBytes;
i : Integer;
begin
SetLength(Buf, 12);
for i := $40 to $40 + Length(Buf) - 1 do
Buf[i-$40] := i;
DecUtil.ProtectBytes(Buf);
CheckEquals('', string(DECUtil.BytesToRawString(Buf)));
end;
procedure TTestBufferProtection.ProtectString;
var
s : string;
begin
s := 'Hello';
DECUtil.ProtectString(s);
CheckEquals('', s);
end;
{$IFDEF ANSISTRINGSUPPORTED}
procedure TTestBufferProtection.ProtectStringAnsi;
var
s : AnsiString;
begin
s := 'Hello';
DECUtil.ProtectString(s);
CheckEquals('', string(s));
end;
{$ENDIF}
{$IFDEF MSWINDOWS}
procedure TTestBufferProtection.ProtectStringRawByteString;
var
s : RawByteString;
begin
s := 'Hello';
DECUtil.ProtectString(s);
CheckEquals('', string(s));
end;
{$ENDIF}
{$IFNDEF NextGen}
procedure TTestBufferProtection.ProtectStringWide;
var
s : WideString;
begin
s := 'Hello';
DECUtil.ProtectString(s);
CheckEquals('', string(s));
end;
{$ENDIF}
procedure TTestBufferProtection.BytesToRawString;
var
Buf: TBytes;
i : Integer;
result : RawByteString;
begin
SetLength(Buf, 43);
for i := 48 to 48 + length(Buf) - 1 do
Buf[i-48] := i;
result := DECUtil.BytesToRawString(Buf);
CheckEquals('0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ',
string(result));
end;
procedure TTestBufferProtection.BytesToRawStringEmpty;
var
Buf: TBytes;
begin
SetLength(Buf, 0);
CheckEquals('', string(DECUtil.BytesToRawString(Buf)));
end;
initialization
// Register any test cases with the test runner
{$IFDEF DUnitX}
TDUnitX.RegisterTestFixture(TTestBitTwiddling);
TDUnitX.RegisterTestFixture(TTestBufferProtection);
{$ELSE}
RegisterTests('DECUtil', [TTestBitTwiddling.Suite, TTestBufferProtection.Suite]);
{$ENDIF}
end.

View File

@@ -0,0 +1,5 @@
/// <summary>
/// When enabled the Unit tests can be run via DUnitX test framework but no
/// longer via DUnit test framework.
/// </summary>
{.$DEFINE DUnitX}