Skip to content

Instantly share code, notes, and snippets.

@jaclas
Last active March 3, 2021 16:53
Show Gist options
  • Save jaclas/287562d49b455f39c097bb1e96da9f4d to your computer and use it in GitHub Desktop.
Save jaclas/287562d49b455f39c097bb1e96da9f4d to your computer and use it in GitHub Desktop.
DEC_test_code
program Project1;
{$APPTYPE CONSOLE}
{$R *.res}
uses
System.JSON,
System.Classes,
DECCipherFormats,
DECCiphers,
DECFormat,
DECCipherBase,
System.NetEncoding,
System.SysUtils;
type
TDECFormattedCipherClass = class of TDECFormattedCipher;
RMode = record
mode : TCipherMode;
modeAsStr : string;
end;
RCipherConf = record
cipher : TDECFormattedCipherClass;
cipherAsStr : string;
modes : TArray<RMode>;
end;
var
vCiphersConf : TArray<RCipherConf>;
procedure SetModes(var aCipher : RCipherConf);
var
m: Integer;
begin
// cmCBCx, // Cipher Block Chaining, with CFB8 padding of truncated final block
// cmCFB8, // 8bit Cipher Feedback mode
// cmCFBx, // CFB on Blocksize of Cipher
// cmOFB8, // 8bit Output Feedback mode
// cmOFBx, // OFB on Blocksize bytes
// cmCFS8, // 8Bit CFS, double CFB
// cmCFSx, // CFS on Blocksize bytes
// cmECBx // Electronic Code Book
SetLength(aCipher.modes, 4);
m := 0;
aCipher.modes[m].mode := TCipherMode.cmCBCx;
aCipher.modes[m].modeAsStr := 'CBC';
m := 1;
aCipher.modes[m].mode := TCipherMode.cmCFB8; //<- when set to cmCFBx then IDEA test has success
aCipher.modes[m].modeAsStr := 'CFB';
m := 2;
aCipher.modes[m].mode := TCipherMode.cmOFBx;
aCipher.modes[m].modeAsStr := 'OFB';
m := 3;
aCipher.modes[m].mode := TCipherMode.cmECBx;
aCipher.modes[m].modeAsStr := 'ECB';
end;
procedure AddCipher(aCipherClass : TDECFormattedCipherClass; const aCipherName : string);
var
a: Integer;
begin
a := Length(vCiphersConf);
SetLength(vCiphersConf, a + 1);
vCiphersConf[a].cipher := aCipherClass;
vCiphersConf[a].cipherAsStr := aCipherName;
SetModes(vCiphersConf[a]);
end;
procedure Config();
var
a: Integer;
m: Integer;
begin
AddCipher(TCipher_AES, 'AES');
AddCipher(TCipher_Blowfish, 'Blowfish');
AddCipher(TCipher_1DES, 'DES');
AddCipher(TCipher_Cast128, 'CAST');
AddCipher(TCipher_IDEA, 'IDEA');
AddCipher(TCipher_3TDES, 'TripleDES');
end;
function BytesToHex(const aBytes : TBytes) : string;
var
lTemp: TBytes;
begin
SetLength(lTemp, Length(aBytes) * 2);
BinToHex(aBytes, 0, lTemp, 0, Length(aBytes));
Result := TEncoding.ANSI.GetString(lTemp);
end;
function HexToBytes(const aHex : string) : TBytes;
var
lTemp: TArray<AnsiChar>;
begin
SetLength(Result, Length(aHex) div 2);
HexToBin(PChar(aHex), 0, Result, 0, Length(aHex));
SetLength(lTemp, Length(aHex) div 2);
Move(Result[0], lTemp[0], Length(aHex) div 2);
end;
function ReadJSONData() : TJSONObject;
var
InputStr: string;
lStr : TStringStream;
lJSON : TJSONObject;
begin
lStr := TStringStream.Create;
lStr.LoadFromFile('crypto_data.json');
InputStr := lStr.DataString;
lstr.Free;
lJSON := TJSONObject.ParseJSONValue(InputStr) as TJSONObject;
Result := lJSON;
end;
procedure Test;
var
lCipherConf: RCipherConf;
i: Integer;
lTestJson: TJSONObject;
lBitsS: string;
lCipherJson: TJSONObject;
lCipherO: TDECFormattedCipher;
lModeJ: TJSONObject;
lCodec : TCipher_AES;
lDataJ: TJSONObject;
lDecodec: TCipher_AES;
lDecodedBytes: TBytes;
lEncodedBytes: TBytes;
lInputAnsi: AnsiString;
lInputBytes: TBytes;
lIV: TBytes;
lIVs: string;
lKey: TBytes;
lKeyS: string;
lModeConf: RMode;
lNode: TJSONValue;
lOutputBytes: TBytes;
lPair: TJSONPair;
lResult: string;
lResultBytes: TBytes;
s: string;
begin
//{
// "AES": {
// "CBC": {
// "128": {
// "iv_hex": "30313233343536373839303132333435",
// "key_hex": "30313233343536373839303132333435",
// "plaintext": "abcdefghijklmnopqrstuv0123456789",
// "result_hex": "8859653CB4C4E4CA3ADD490015AC8860FA59D1E233301563B184FCCA95790C8C"
// },
Config();
lTestJson := ReadJSONData();
for lCipherConf in vCiphersConf do
begin
lCipherJson := lTestJson.Values[lCipherConf.cipherAsStr] as TJSONObject;
Writeln;
for lModeConf in lCipherConf.modes do
begin
lModeJ := lCipherJson.Values[lModeConf.modeAsStr] as TJSONObject;
for i := 0 to Pred(lModeJ.Count) do
begin
lPair := lModeJ.Pairs[i];
lBitsS := lPair.JsonString.Value;
lDataJ := lPair.JsonValue as TJSONObject;
lNode := lDataJ.GetValue('iv_hex');
if Assigned(lNode) then
begin
lIVs := (lNode as TJSONString).Value;
end;
lIV := HexToBytes(lIVs);
lKeyS := (lDataJ.GetValue('key_hex') as TJSONString).Value;
lKey := HexToBytes(lKeyS);
lInputAnsi := (lDataJ.GetValue('plaintext') as TJSONString).Value;
lInputBytes := BytesOf(lInputAnsi);
lResult := (lDataJ.GetValue('result_hex') as TJSONString).Value;
lResultBytes := HexToBytes(lResult);
lCipherO := lCipherConf.cipher.Create;
try
Write(Format('%s (%s/%s)', [lCipherConf.cipherAsStr, lModeConf.modeAsStr, lBitsS]));
lCipherO.Mode := lModeConf.mode;
lCipherO.Init(lKey, lIV);
try
lEncodedBytes := lCipherO.EncodeBytes(lInputBytes);
except
on E : Exception do
begin
WriteLn(' -> ', E.Message);
Continue;
end;
end;
s := BytesToHex(lEncodedBytes);
if not CompareMem(@lEncodedBytes[0], @lResultBytes[0], Length(lResultBytes)) then
begin
WriteLn(Format(' has different result [BAD]; expected is: %s, received is: %s', [lResult, BytesToHex(lEncodedBytes)]));
Writeln;
end else
begin
Writeln(Format(' has equal result [OK]', []));
end;
finally
lCipherO.Free;
end;
end;
end;
end;
end;
begin
try
Writeln('Begin of tests... ');
Test;
Writeln('End of tests... press any key');
Readln;
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment