{*****************************************************************************
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;
///
/// Number of times this test needs to be run to produce the final test data
///
property RepeatCount:UInt32
read GetRunCount;
///
/// Input data for the test
///
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}']
///
/// Specifies the length of the hash value generated for those hash classes
/// which support configurable output lengths.
///
///
/// Length of the calculated hash value in byte
///
procedure SetRequiredDigestSize(const aValue:UInt32);
///
/// 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.
///
procedure SetPaddingByte(const aValue:Byte);
///
/// 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.
///
///
/// Number of bits of the last byte within the test data to process
///
procedure SetFinalBitLength(const aValue: Int16);
///
/// Specifies the length of the hash value generated for those hash classes
/// which support configurable output lengths. The length is specified in
/// byte.
///
property RequiredDigestSize : UInt32
Write SetRequiredDigestSize;
///
/// 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.
///
property PaddingByte : Byte
Write SetPaddingByte;
///
/// 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.
///
property FinalBitLength : Int16
write SetFinalBitLength;
end;
IHashTestDataRow = interface(ITestDataRow)
['{73ED2877-967A-410B-8493-636F099FBA60}']
///
/// Gets the length of the hash value generated for those hash classes
/// which support configurable output lengths.
///
///
/// Length of the calculated hash value in byte
///
function GetRequiredDigestSize:UInt32;
///
/// 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.
///
function GetPaddingByte:Byte;
///
/// 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.
///
function GetFinalBitLength:Int16;
///
/// Gets the length in bytes of the hash value generated for those
/// hash classes which support configurable output lengths.
///
property RequiredDigestSize : UInt32
read GetRequiredDigestSize;
///
/// 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.
///
property PaddingByte : Byte
read GetPaddingByte;
///
/// 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.
///
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;
///
/// 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
///
TTestDataInputVectorList = class(TInterfacedObject, ITestDataInputVectorList)
private
///
/// List of all the input values for the tests
///
FVectors : TInterfaceList;
protected // ITestDataInputVectorContainer
///
/// Returns the number of test data entries (vectors) stored in the list
///
function GetCount:Integer;
///
/// Returns the test data vector specified by the index
///
///
/// Index of the vector which shall be returned
///
///
/// Test data entry
///
function GetVector(aIndex:Integer):ITestDataInputVector;
///
/// Adds an input vector for one test to the list
///
///
/// Test data for the vector
///
///
/// Number of times the test shall be repeated on the data given, default = 1
///
///
/// Number of times aData is being concatenated to form the real input data
/// for this test vector
///
///
{ 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...
///
///
/// An interface to the generated test vector
///
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
///
/// Gets the length of the hash value generated for those hash classes
/// which support configurable output lengths.
///
///
/// Length of the calculated hash value in byte
///
function GetRequiredDigestSize:UInt32;
///
/// 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.
///
function GetPaddingByte:Byte;
function GetFinalBitLength:Int16;
protected // IHashTestDataRowSetup
///
/// Specifies the length of the hash value generated for those hash classes
/// which support configurable output lengths.
///
///
/// Length of the calculated hash value in byte
///
procedure SetRequiredDigestSize(const aValue:UInt32);
///
/// 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.
///
procedure SetPaddingByte(const aValue:Byte);
///
/// 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.
///
///
/// Number of bits of the last byte within the test data to process
///
procedure SetFinalBitLength(const aValue: Int16);
public
constructor Create;
destructor Destroy; override;
end;
///
/// List of all the test vectors of a unit test for one of the hash classes
///
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.