Last active
March 3, 2021 16:53
-
-
Save jaclas/287562d49b455f39c097bb1e96da9f4d to your computer and use it in GitHub Desktop.
DEC_test_code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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